mirror of
https://github.com/ADElectronics/RTL00_WEB_VS.git
synced 2024-11-25 18:54:16 +00:00
189 lines
12 KiB
C
189 lines
12 KiB
C
|
#ifndef __TCP_SERV_CONN_H__
|
|||
|
/***********************************
|
|||
|
* FileName: tcp_srv_conn.h
|
|||
|
* Tcp сервачек для ESP8266
|
|||
|
* PV` ver1.0 20/12/2014
|
|||
|
* PV` ver1.0 29/10/2016 для RTL87xx
|
|||
|
***********************************/
|
|||
|
#define __TCP_SERV_CONN_H__
|
|||
|
|
|||
|
#include "user_config.h"
|
|||
|
#include "tcp.h"
|
|||
|
|
|||
|
#include "lwip/err.h"
|
|||
|
|
|||
|
#undef mMIN
|
|||
|
#define mMIN(a, b) ((a < b)? a : b)
|
|||
|
#define mMAX(a, b) ((a>b)?a:b)
|
|||
|
|
|||
|
|
|||
|
enum srvconn_state {
|
|||
|
SRVCONN_NONE =0,
|
|||
|
SRVCONN_CLOSEWAIT, // ожидает закрытия
|
|||
|
SRVCONN_LISTEN, // соединение открыто, ждет rx или tx
|
|||
|
SRVCONN_CONNECT, // соединение открыто, было rx или tx
|
|||
|
SRVCONN_CLOSED // соединение закрыто
|
|||
|
};
|
|||
|
|
|||
|
// приоритет pcb 1..127 1 - min, 127 - max
|
|||
|
#ifndef TCP_SRV_PRIO
|
|||
|
#define TCP_SRV_PRIO 99 // TCP_PRIO_MIN
|
|||
|
#endif
|
|||
|
|
|||
|
// максимальное кол-во TCP c TIME_WAIT
|
|||
|
#ifndef MAX_TIME_WAIT_PCB
|
|||
|
#define MAX_TIME_WAIT_PCB 10
|
|||
|
#endif
|
|||
|
|
|||
|
// кол-во одновременно открытых соединений по умолчанию
|
|||
|
#ifndef TCP_SRV_MAX_CONNECTIONS
|
|||
|
#define TCP_SRV_MAX_CONNECTIONS mMIN(MEMP_NUM_TCP_PCB, 10)
|
|||
|
#endif
|
|||
|
|
|||
|
// порт сервера по умолчанию
|
|||
|
#ifndef TCP_SRV_SERVER_PORT
|
|||
|
#define TCP_SRV_SERVER_PORT 80
|
|||
|
#endif
|
|||
|
|
|||
|
|
|||
|
#define SRV_WDGREFESH_IN_POOL // использовать WDGRefresh() в tcpsrv_poll()
|
|||
|
|
|||
|
// время (сек), по умолчанию, ожидания запроса (передачи пакета) от клиента, до авто-закрытия соединения,
|
|||
|
// при = 0 заменяется на эти 5 сек.
|
|||
|
#ifndef TCP_SRV_RECV_WAIT
|
|||
|
#define TCP_SRV_RECV_WAIT 5
|
|||
|
#endif
|
|||
|
// время (сек), по умолчанию, до авто-закрытия соединения после приема или передачи,
|
|||
|
// при = 0 заменяется на эти 5 сек.
|
|||
|
#ifndef TCP_SRV_END_WAIT
|
|||
|
#define TCP_SRV_END_WAIT 5
|
|||
|
#endif
|
|||
|
|
|||
|
// время (в сек) до повтора закрытия соединения (исполняется до 3-х раз).
|
|||
|
#define TCP_SRV_CLOSE_WAIT 5 // 5 сек
|
|||
|
|
|||
|
// минимальный размер heap по умолчанию, при открытии нового соединения, при = 0 заменяется на это:
|
|||
|
#define TCP_SRV_MIN_HEAP_SIZE 32768 // самый минимум от 6Kb
|
|||
|
|
|||
|
// максимальный размер выделяемого буфера в heap для приема порции
|
|||
|
#ifndef TCP_SRV_SERVER_MAX_RXBUF
|
|||
|
#define TCP_SRV_SERVER_MAX_RXBUF TCP_WND // (TCP_MSS*3) // 1460*2=2920, 1460*3=4380, 1460*4=5840
|
|||
|
#endif
|
|||
|
|
|||
|
// размер выделяемого буфера в heap для передачи при буферизированном выводе
|
|||
|
#ifndef TCP_SRV_SERVER_DEF_TXBUF
|
|||
|
#define TCP_SRV_SERVER_DEF_TXBUF TCP_SND_BUF //(TCP_MSS*3) // 1460*2=2920, 1460*3=4380, 1460*4=5840
|
|||
|
#endif
|
|||
|
|
|||
|
#define ID_CLIENTS_PORT 3 // до 3-х clients
|
|||
|
#define tcpsrv_init_client1() tcpsrv_init(1) // tcp2uart_client
|
|||
|
#define tcpsrv_init_client2() tcpsrv_init(2) // mdb_tcp_client
|
|||
|
#define tcpsrv_init_client3() tcpsrv_init(3)
|
|||
|
|
|||
|
#define TCP_CLIENT_NEXT_CONNECT_S 5 // syscfg.tcp_client_twait // 5000 // через 5 сек
|
|||
|
#define TCP_CLIENT_MAX_CONNECT_RETRY 7 // до 7 раз с интервалом TCP_CLIENT_NEXT_CONNECT_MS
|
|||
|
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
// Структура соединения
|
|||
|
//
|
|||
|
typedef struct t_tcpsrv_conn_flags {
|
|||
|
uint16 srv_reopen: 1; //0001 открытие нового соединения более max_conn ведет к закрытию наиболее старого соединения.
|
|||
|
uint16 pcb_time_wait_free: 1; //0002 проверка на макс кол-во и уничтожение pcb с TIME_WAIT при вызове disconnect() (иначе pcb TIME_WAIT 60 сек http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html)
|
|||
|
uint16 nagle_disabled: 1; //0004 выключение nagle
|
|||
|
uint16 rx_buf: 1; //0008 прием в буфер, используется ручное управление размером окна TCP
|
|||
|
uint16 rx_null: 1; //0010 отключение вызова func_received_data() и прием в null (устанавливается автоматически при вызове tcpsrv_disconnect())
|
|||
|
uint16 tx_null: 1; //0020 отключение вызова func_sent_callback() и передача в null (устанавливается автоматически при вызове tcpsrv_disconnect())
|
|||
|
uint16 wait_sent: 1; //0040 ожидет завершения/подтверждения передачи от lwip
|
|||
|
uint16 busy_bufo: 1; //0080 идет обработка bufo
|
|||
|
uint16 busy_bufi: 1; //0100 идет обработка bufi
|
|||
|
uint16 tmp0: 1; //0200 резерв
|
|||
|
uint16 tmp1: 1; //0400 резерв
|
|||
|
// далее идут биты не относящиеся к работе tcp_srv_conn
|
|||
|
uint16 user_flg1: 1; //0800 для нужд процедур уровнем выше (пока свободен)
|
|||
|
uint16 user_flg2: 1; //1000 для нужд процедур уровнем выше (пока свободен)
|
|||
|
uint16 user_option1: 1; //2000 для нужд процедур обработки переменных (использован для hexdump, xml_mdb в web_int_callbacks.c)
|
|||
|
uint16 user_option2: 1; //4000 для нужд процедур обработки переменных (использован для xml_mdb в web_int_callbacks.c)
|
|||
|
} __attribute__((packed)) tcpsrv_conn_flags;
|
|||
|
|
|||
|
typedef struct t_TCP_SERV_CONN {
|
|||
|
volatile tcpsrv_conn_flags flag;//+0 флаги соеднения
|
|||
|
enum srvconn_state state; //+4 состояние
|
|||
|
struct t_TCP_SERV_CFG *pcfg; //+8 указатель на базовую структуру сервера
|
|||
|
uint16 recv_check; //+12 счет тиков соединения в tcpsrv_poll
|
|||
|
uint16 remote_port; //+16 номер порта клиента
|
|||
|
union { //+20 ip клиента
|
|||
|
uint32 dw;
|
|||
|
uint8 b[4];
|
|||
|
} remote_ip;
|
|||
|
struct t_TCP_SERV_CONN *next; //+24 указатель на следующую структуру
|
|||
|
struct tcp_pcb *pcb; //+28 указатель на pcb в Lwip
|
|||
|
uint8 *pbufo; //+32 указатель на сегмент с передаваемыми данными
|
|||
|
uint8 *ptrtx; //+36 указатель на ещё не переданные данные
|
|||
|
uint8 *pbufi; //+40 указатель на сегмент буфера с принимаемыми данными
|
|||
|
uint16 sizeo; //+44 размер буфера передачи
|
|||
|
uint16 sizei; //+48 размер приемного буфера (кол-во принятых и ещё не обработанных байт)
|
|||
|
uint16 cntro; //+52 кол-во обработанных байт в буфере передачи
|
|||
|
uint16 cntri; //+56 кол-во обработанных байт в буфере приема
|
|||
|
uint16 unrecved_bytes; //+60 используется при ручном управлении TCP WIN / This can be used to throttle data reception
|
|||
|
// далее идут переменные не относящиеся к работе tcp_srv_conn
|
|||
|
uint8 *linkd; //+64 указатель на прилепленные данные пользователя (при закрытии соединения вызывается os_close(linkd), если linkd != NULL;
|
|||
|
} TCP_SERV_CONN;
|
|||
|
|
|||
|
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
// Вызываемые функции пользователя (calback-и)
|
|||
|
//
|
|||
|
typedef void (*func_disconect_calback)(TCP_SERV_CONN *ts_conn); // соединение закрыто
|
|||
|
typedef err_t (*func_listen)(TCP_SERV_CONN *ts_conn); // новый клиент
|
|||
|
typedef err_t (*func_received_data)(TCP_SERV_CONN *ts_conn); // принято всего ts_conn->sizei байт, лежат в буфере по ts_conn->pbufi, по выходу принимается обработанных ts_conn->cntri;
|
|||
|
typedef err_t (*func_sent_callback)(TCP_SERV_CONN *ts_conn); // блок данных передан
|
|||
|
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
// Структура конфигурации tcp сервера
|
|||
|
//
|
|||
|
typedef struct t_TCP_SERV_CFG {
|
|||
|
struct t_tcpsrv_conn_flags flag; // начальные флаги для соединения
|
|||
|
uint16 port; // номер порта
|
|||
|
uint16 min_heap; // минимальный размер heap при открытии нового соединения, при = 0 заменяется на 8192.
|
|||
|
uint8 max_conn; // максимальное кол-во одновременных соединений
|
|||
|
uint8 conn_count; // кол-во текущих соединений, при инициализации прописывает 0
|
|||
|
uint8 time_wait_rec; // время (сек) ожидания запроса (передачи пакета) от клиента, до авто-закрытия соединения, по умолчанию TCP_SRV_RECV_WAIT сек.
|
|||
|
uint8 time_wait_cls; // время (сек) до авто-закрытия соединения после приема или передачи, по умолчанию TCP_SRV_END_WAIT сек.
|
|||
|
TCP_SERV_CONN * conn_links; // указатель на цепочку активных соединений, при инициализации или отсуствии активных соединений = NULL
|
|||
|
struct tcp_pcb *pcb; // начальный pcb [LISTEN] если сервер, иначе NULL
|
|||
|
func_disconect_calback func_discon_cb; // функция вызываемая после закрытия соединения, если = NULL - не вызывается
|
|||
|
func_listen func_listen; // функция вызываемая при присоединении клиента или коннекта к серверу, если = NULL - не вызывается
|
|||
|
func_sent_callback func_sent_cb; // функция вызываемая после передачи данных или наличию места в ip стеке для следушей передачи данных, если = NULL - не вызывается (+см. флаги)
|
|||
|
func_received_data func_recv; // функция вызываемая при приеме данных, если = NULL - не вызывается (+см. флаги)
|
|||
|
struct t_TCP_SERV_CFG *next; // следующий экземпляр структуры сервера/клиента
|
|||
|
}TCP_SERV_CFG;
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
// Данные
|
|||
|
//
|
|||
|
extern TCP_SERV_CFG *phcfg; // указатель на цепочку TCP_SERV_CFG (стартовавших серверов)
|
|||
|
//--------------------------------------------------------------------------
|
|||
|
// Функции
|
|||
|
//
|
|||
|
err_t tcpsrv_int_sent_data(TCP_SERV_CONN * ts_conn, uint8 *psent, uint16 length); // передать length байт (внутрення функция - никаких проверок)
|
|||
|
void tcpsrv_disconnect(TCP_SERV_CONN * ts_conn); // закрыть соединение
|
|||
|
void tcpsrv_print_remote_info(TCP_SERV_CONN *ts_conn); // выводит remote_ip:remote_port [conn_count] os_printf("srv x.x.x.x:x [n] ")
|
|||
|
TCP_SERV_CFG * tcpsrv_server_port2pcfg(uint16 portn); // поиск структуры конфига по номеру порта
|
|||
|
void tcpsrv_unrecved_win(TCP_SERV_CONN *ts_conn); // Восстановить размер TCP WIN, если используется ручное управление размером окна TCP
|
|||
|
|
|||
|
void tcpsrv_disconnect_calback_default(TCP_SERV_CONN *ts_conn);
|
|||
|
err_t tcpsrv_listen_default(TCP_SERV_CONN *ts_conn);
|
|||
|
err_t tcpsrv_sent_callback_default(TCP_SERV_CONN *ts_conn);
|
|||
|
err_t tcpsrv_received_data_default(TCP_SERV_CONN *ts_conn);
|
|||
|
|
|||
|
TCP_SERV_CFG *tcpsrv_init(uint16 portn);
|
|||
|
err_t tcpsrv_start(TCP_SERV_CFG *p);
|
|||
|
err_t tcpsrv_close(TCP_SERV_CFG *p);
|
|||
|
err_t tcpsrv_close_port(uint16 portn);
|
|||
|
err_t tcpsrv_close_all(void);
|
|||
|
|
|||
|
const char * tspsrv_error_msg(err_t err);
|
|||
|
const char * tspsrv_tcp_state_msg(enum tcp_state state);
|
|||
|
const char * tspsrv_srvconn_state_msg(enum srvconn_state state);
|
|||
|
|
|||
|
#endif // __TCP_SERV_CONN_H__
|