diff --git a/src/AsyncTCP.cpp b/src/AsyncTCP.cpp index 174e8ac..f06cccc 100644 --- a/src/AsyncTCP.cpp +++ b/src/AsyncTCP.cpp @@ -256,7 +256,7 @@ static void _tcp_error(void * arg, int8_t err) { #include "lwip/priv/tcpip_priv.h" typedef struct { - struct tcpip_api_call call; + struct tcpip_api_call_data call; tcp_pcb * pcb; int8_t err; union { @@ -279,20 +279,24 @@ typedef struct { }; } tcp_api_call_t; -static err_t _tcp_output_api(struct tcpip_api_call *api_call_msg){ +static err_t _tcp_output_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; - msg->err = tcp_output(msg->pcb); + if(msg->pcb){ + msg->err = tcp_output(msg->pcb); + } else { + msg->err = 0; + } return msg->err; } static esp_err_t _tcp_output(tcp_pcb * pcb) { tcp_api_call_t msg; msg.pcb = pcb; - tcpip_api_call(_tcp_output_api, (struct tcpip_api_call*)&msg); + tcpip_api_call(_tcp_output_api, (struct tcpip_api_call_data*)&msg); return msg.err; } -static err_t _tcp_write_api(struct tcpip_api_call *api_call_msg){ +static err_t _tcp_write_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = tcp_write(msg->pcb, msg->write.data, msg->write.size, msg->write.apiflags); return msg->err; @@ -304,11 +308,11 @@ static esp_err_t _tcp_write(tcp_pcb * pcb, const char* data, size_t size, uint8_ msg.write.data = data; msg.write.size = size; msg.write.apiflags = apiflags; - tcpip_api_call(_tcp_write_api, (struct tcpip_api_call*)&msg); + tcpip_api_call(_tcp_write_api, (struct tcpip_api_call_data*)&msg); return msg.err; } -static err_t _tcp_recved_api(struct tcpip_api_call *api_call_msg){ +static err_t _tcp_recved_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = 0; tcp_recved(msg->pcb, msg->received); @@ -319,11 +323,11 @@ static esp_err_t _tcp_recved(tcp_pcb * pcb, size_t len) { tcp_api_call_t msg; msg.pcb = pcb; msg.received = len; - tcpip_api_call(_tcp_recved_api, (struct tcpip_api_call*)&msg); + tcpip_api_call(_tcp_recved_api, (struct tcpip_api_call_data*)&msg); return msg.err; } -static err_t _tcp_connect_api(struct tcpip_api_call *api_call_msg){ +static err_t _tcp_connect_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = tcp_connect(msg->pcb, msg->connect.addr, msg->connect.port, msg->connect.cb); return msg->err; @@ -335,11 +339,11 @@ static esp_err_t _tcp_connect(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port, tc msg.connect.addr = addr; msg.connect.port = port; msg.connect.cb = cb; - tcpip_api_call(_tcp_connect_api, (struct tcpip_api_call*)&msg); + tcpip_api_call(_tcp_connect_api, (struct tcpip_api_call_data*)&msg); return msg.err; } -static err_t _tcp_close_api(struct tcpip_api_call *api_call_msg){ +static err_t _tcp_close_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = tcp_close(msg->pcb); return msg->err; @@ -349,11 +353,11 @@ static esp_err_t _tcp_close(tcp_pcb * pcb) { tcp_api_call_t msg; msg.pcb = pcb; //ets_printf("close 0x%08x\n", (uint32_t)pcb); - tcpip_api_call(_tcp_close_api, (struct tcpip_api_call*)&msg); + tcpip_api_call(_tcp_close_api, (struct tcpip_api_call_data*)&msg); return msg.err; } -static err_t _tcp_abort_api(struct tcpip_api_call *api_call_msg){ +static err_t _tcp_abort_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = 0; tcp_abort(msg->pcb); @@ -364,11 +368,11 @@ static esp_err_t _tcp_abort(tcp_pcb * pcb) { tcp_api_call_t msg; msg.pcb = pcb; //ets_printf("abort 0x%08x\n", (uint32_t)pcb); - tcpip_api_call(_tcp_abort_api, (struct tcpip_api_call*)&msg); + tcpip_api_call(_tcp_abort_api, (struct tcpip_api_call_data*)&msg); return msg.err; } -static err_t _tcp_bind_api(struct tcpip_api_call *api_call_msg){ +static err_t _tcp_bind_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = tcp_bind(msg->pcb, msg->bind.addr, msg->bind.port); return msg->err; @@ -379,11 +383,11 @@ static esp_err_t _tcp_bind(tcp_pcb * pcb, ip_addr_t * addr, uint16_t port) { msg.pcb = pcb; msg.bind.addr = addr; msg.bind.port = port; - tcpip_api_call(_tcp_bind_api, (struct tcpip_api_call*)&msg); + tcpip_api_call(_tcp_bind_api, (struct tcpip_api_call_data*)&msg); return msg.err; } -static err_t _tcp_listen_api(struct tcpip_api_call *api_call_msg){ +static err_t _tcp_listen_api(struct tcpip_api_call_data *api_call_msg){ tcp_api_call_t * msg = (tcp_api_call_t *)api_call_msg; msg->err = 0; msg->pcb = tcp_listen_with_backlog(msg->pcb, msg->backlog); @@ -394,7 +398,7 @@ static tcp_pcb * _tcp_listen_with_backlog(tcp_pcb * pcb, uint8_t backlog) { tcp_api_call_t msg; msg.pcb = pcb; msg.backlog = backlog?backlog:0xFF; - tcpip_api_call(_tcp_listen_api, (struct tcpip_api_call*)&msg); + tcpip_api_call(_tcp_listen_api, (struct tcpip_api_call_data*)&msg); return msg.pcb; } #define _tcp_listen(p) _tcp_listen_with_backlog(p, 0xFF); @@ -432,6 +436,8 @@ AsyncClient::AsyncClient(tcp_pcb* pcb) , next(NULL) , _in_lwip_thread(false) { + //ets_printf("+: 0x%08x\n", (uint32_t)this); + _pcb = pcb; if(_pcb){ _rx_last_packet = millis(); @@ -447,6 +453,8 @@ AsyncClient::AsyncClient(tcp_pcb* pcb) AsyncClient::~AsyncClient(){ if(_pcb) _close(); + + //ets_printf("-: 0x%08x\n", (uint32_t)this); } bool AsyncClient::connect(IPAddress ip, uint16_t port){ @@ -512,6 +520,7 @@ int8_t AsyncClient::_connected(void* pcb, int8_t err){ } int8_t AsyncClient::_close(){ + //ets_printf("X: 0x%08x\n", (uint32_t)this); int8_t err = ERR_OK; if(_pcb) { //log_i(""); @@ -520,6 +529,7 @@ int8_t AsyncClient::_close(){ tcp_recv(_pcb, NULL); tcp_err(_pcb, NULL); tcp_poll(_pcb, NULL, 0); + _tcp_clear_events(this); if(_in_lwip_thread){ err = tcp_close(_pcb); } else { @@ -529,7 +539,6 @@ int8_t AsyncClient::_close(){ err = abort(); } _pcb = NULL; - _tcp_clear_events(this); if(_discard_cb) _discard_cb(_discard_cb_arg, this); } @@ -562,6 +571,13 @@ int8_t AsyncClient::_sent(tcp_pcb* pcb, uint16_t len) { } int8_t AsyncClient::_recv(tcp_pcb* pcb, pbuf* pb, int8_t err) { + if(!_pcb || pcb != _pcb){ + log_e("0x%08x != 0x%08x", (uint32_t)pcb, (uint32_t)_pcb); + if(pb){ + pbuf_free(pb); + } + return ERR_OK; + } _in_lwip_thread = false; if(pb == NULL){ return _close(); @@ -621,7 +637,7 @@ int8_t AsyncClient::_poll(tcp_pcb* pcb){ return ERR_OK; } -void AsyncClient::_dns_found(ip_addr_t *ipaddr){ +void AsyncClient::_dns_found(struct ip_addr *ipaddr){ _in_lwip_thread = true; if(ipaddr){ connect(IPAddress(ipaddr->u_addr.ip4.addr), _connect_port); @@ -943,31 +959,58 @@ void AsyncClient::onPoll(AcConnectHandler cb, void* arg){ } -void AsyncClient::_s_dns_found(const char * name, ip_addr_t * ipaddr, void * arg){ - reinterpret_cast(arg)->_dns_found(ipaddr); +void AsyncClient::_s_dns_found(const char * name, struct ip_addr * ipaddr, void * arg){ + if(arg){ + reinterpret_cast(arg)->_dns_found(ipaddr); + } else { + log_e("Bad Arg: 0x%08x", arg); + } } int8_t AsyncClient::_s_poll(void * arg, struct tcp_pcb * pcb) { - reinterpret_cast(arg)->_poll(pcb); + if(arg && pcb){ + reinterpret_cast(arg)->_poll(pcb); + } else { + log_e("Bad Args: 0x%08x 0x%08x", arg, pcb); + } return ERR_OK; } int8_t AsyncClient::_s_recv(void * arg, struct tcp_pcb * pcb, struct pbuf *pb, int8_t err) { - reinterpret_cast(arg)->_recv(pcb, pb, err); + if(arg && pcb){ + reinterpret_cast(arg)->_recv(pcb, pb, err); + } else { + if(pb){ + pbuf_free(pb); + } + log_e("Bad Args: 0x%08x 0x%08x", arg, pcb); + } return ERR_OK; } int8_t AsyncClient::_s_sent(void * arg, struct tcp_pcb * pcb, uint16_t len) { - reinterpret_cast(arg)->_sent(pcb, len); + if(arg && pcb){ + reinterpret_cast(arg)->_sent(pcb, len); + } else { + log_e("Bad Args: 0x%08x 0x%08x", arg, pcb); + } return ERR_OK; } void AsyncClient::_s_error(void * arg, int8_t err) { - reinterpret_cast(arg)->_error(err); + if(arg){ + reinterpret_cast(arg)->_error(err); + } else { + log_e("Bad Arg: 0x%08x", arg); + } } int8_t AsyncClient::_s_connected(void * arg, void * pcb, int8_t err){ - reinterpret_cast(arg)->_connected(pcb, err); + if(arg && pcb){ + reinterpret_cast(arg)->_connected(pcb, err); + } else { + log_e("Bad Args: 0x%08x 0x%08x", arg, pcb); + } return ERR_OK; } @@ -1122,9 +1165,9 @@ void AsyncServer::end(){ tcp_arg(_pcb, NULL); tcp_accept(_pcb, NULL); if(_in_lwip_thread){ - tcp_abort(_pcb); + tcp_close(_pcb); } else { - _tcp_abort(_pcb); + _tcp_close(_pcb); } _pcb = NULL; } diff --git a/src/AsyncTCP.h b/src/AsyncTCP.h index 79664bf..6cd0fca 100644 --- a/src/AsyncTCP.h +++ b/src/AsyncTCP.h @@ -43,7 +43,7 @@ typedef std::function AcPacketHandle typedef std::function AcTimeoutHandler; struct tcp_pcb; -struct _ip_addr; +struct ip_addr; class AsyncClient { protected: @@ -81,7 +81,7 @@ class AsyncClient { void _error(int8_t err); int8_t _poll(tcp_pcb* pcb); int8_t _sent(tcp_pcb* pcb, uint16_t len); - void _dns_found(struct _ip_addr *ipaddr); + void _dns_found(struct ip_addr *ipaddr); public: @@ -108,13 +108,13 @@ class AsyncClient { bool canSend();//ack is not pending size_t space(); - size_t add(const char* data, size_t size, uint8_t apiflags=0);//add for sending + size_t add(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY);//add for sending bool send();//send all data added with the method above size_t ack(size_t len); //ack data that you have not acked using the method below void ackLater(){ _ack_pcb = false; } //will not ack the current packet. Call from onData size_t write(const char* data); - size_t write(const char* data, size_t size, uint8_t apiflags=0); //only when canSend() == true + size_t write(const char* data, size_t size, uint8_t apiflags=ASYNC_WRITE_FLAG_COPY); //only when canSend() == true uint8_t state(); bool connecting(); @@ -161,7 +161,7 @@ class AsyncClient { static void _s_error(void *arg, int8_t err); static int8_t _s_sent(void *arg, struct tcp_pcb *tpcb, uint16_t len); static int8_t _s_connected(void* arg, void* tpcb, int8_t err); - static void _s_dns_found(const char *name, struct _ip_addr *ipaddr, void *arg); + static void _s_dns_found(const char *name, struct ip_addr *ipaddr, void *arg); bool _in_lwip_thread; };