RTL00_WEB_VS/RTLGDB/Project/tcpsrv/tcp_srv_conn.h

189 lines
12 KiB
C
Raw Permalink Normal View History

2017-11-28 19:31:40 +00:00
#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__