/****************************************************************************** * FunctionName : espconn_tcp_accept * Description : A new incoming connection has been accepted. * Parameters : arg -- Additional argument to pass to the callback function * pcb -- The connection pcb which is accepted * err -- An unused error code, always ERR_OK currently * Returns : acception result *******************************************************************************/ static err_t ICACHE_FLASH_ATTR espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct espconn *espconn = arg; espconn_msg *paccept = NULL; remot_info *pinfo = NULL; LWIP_UNUSED_ARG(err); if(system_get_free_heap_size() < 8192) return ERR_MEM; // added PV` paccept = (espconn_msg *)os_zalloc(sizeof(espconn_msg)); tcp_arg(pcb, paccept); tcp_err(pcb, esponn_server_err); if (paccept == NULL) return ERR_MEM; /*insert the node to the active connection list*/ espconn_list_creat(&plink_active, paccept); paccept->preverse = espconn; paccept->pespconn = (struct espconn *)os_zalloc(sizeof(struct espconn)); if (paccept->pespconn == NULL) return ERR_MEM; paccept->pespconn->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp)); if (paccept->pespconn->proto.tcp == NULL) return ERR_MEM; //paccept->pcommon.timeout = 0x0a; //link_timer = 0x0a; paccept->pcommon.pcb = pcb; paccept->pcommon.remote_port = pcb->remote_port; paccept->pcommon.remote_ip[0] = ip4_addr1_16(&pcb->remote_ip); paccept->pcommon.remote_ip[1] = ip4_addr2_16(&pcb->remote_ip); paccept->pcommon.remote_ip[2] = ip4_addr3_16(&pcb->remote_ip); paccept->pcommon.remote_ip[3] = ip4_addr4_16(&pcb->remote_ip); os_memcpy(espconn->proto.tcp->remote_ip, paccept->pcommon.remote_ip, 4); espconn->proto.tcp->remote_port = pcb->remote_port; espconn->state = ESPCONN_CONNECT; espconn_copy_partial(paccept->pespconn, espconn); espconn_get_connection_info(espconn, &pinfo , 0); espconn_printf("espconn_tcp_accept link_cnt: %d\n", espconn->link_cnt); if (espconn->link_cnt == espconn_tcp_get_max_con_allow(espconn) + 1) return ERR_ISCONN; tcp_sent(pcb, espconn_server_sent); tcp_recv(pcb, espconn_server_recv); tcp_poll(pcb, espconn_server_poll, 8); /* every 1 seconds */ if (paccept->pespconn->proto.tcp->connect_callback != NULL) { paccept->pespconn->proto.tcp->connect_callback(paccept->pespconn); } return ERR_OK; }
/****************************************************************************** * FunctionName : espconn_tcp_reconnect * Description : reconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_tcp_reconnect(void *arg) { espconn_msg *precon_cb = arg; sint8 re_err = 0; espconn_buf *perr_buf = NULL; espconn_buf *perr_back = NULL; espconn_kill_oldest_pcb(); if (precon_cb != NULL) { struct espconn *espconn = precon_cb->preverse; re_err = precon_cb->pcommon.err; if (precon_cb->pespconn != NULL){ if (espconn != NULL){/*Process the server's message block*/ if (precon_cb->pespconn->proto.tcp != NULL){ espconn_copy_partial(espconn, precon_cb->pespconn); espconn_printf("server: %d.%d.%d.%d : %d reconnection\n", espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1],espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3],espconn->proto.tcp->remote_port); free(precon_cb->pespconn->proto.tcp); precon_cb->pespconn->proto.tcp = NULL; } free(precon_cb->pespconn); precon_cb->pespconn = NULL; } else {/*Process the client's message block*/ espconn = precon_cb->pespconn; espconn_printf("client: %d.%d.%d.%d : %d reconnection\n", espconn->proto.tcp->local_ip[0], espconn->proto.tcp->local_ip[1],espconn->proto.tcp->local_ip[2], espconn->proto.tcp->local_ip[3],espconn->proto.tcp->local_port); } } /*to prevent memory leaks, ensure that each allocated is deleted*/ perr_buf = precon_cb->pcommon.pbuf; while (perr_buf != NULL){ perr_back = perr_buf; perr_buf = perr_back->pnext; espconn_pbuf_delete(&precon_cb->pcommon.pbuf,perr_back); free(perr_back); perr_back = NULL; } bzero(&pktinfo[1], sizeof(struct espconn_packet)); memcpy(&pktinfo[1], (void*)&precon_cb->pcommon.packet_info, sizeof(struct espconn_packet)); free(precon_cb); precon_cb = NULL; if (espconn && espconn->proto.tcp && espconn->proto.tcp->reconnect_callback != NULL) { espconn->proto.tcp->reconnect_callback(espconn, re_err); } } else { espconn_printf("espconn_tcp_reconnect err\n"); } }
/****************************************************************************** * FunctionName : espconn_tcp_disconnect * Description : disconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_tcp_disconnect_successful(void *arg) { espconn_msg *pdiscon_cb = arg; sint8 dis_err = 0; if (pdiscon_cb != NULL) { struct espconn *espconn = pdiscon_cb->preverse; dis_err = pdiscon_cb->pcommon.err; if (pdiscon_cb->pespconn != NULL){ struct tcp_pcb *pcb = NULL; if (espconn != NULL){ if (pdiscon_cb->pespconn->proto.tcp != NULL){ espconn_copy_partial(espconn, pdiscon_cb->pespconn); espconn_printf("server: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1],espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3],espconn->proto.tcp->remote_port); os_free(pdiscon_cb->pespconn->proto.tcp); pdiscon_cb->pespconn->proto.tcp = NULL; } os_free(pdiscon_cb->pespconn); pdiscon_cb->pespconn = NULL; } else { espconn = pdiscon_cb->pespconn; espconn_printf("client: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->local_ip[0], espconn->proto.tcp->local_ip[1],espconn->proto.tcp->local_ip[2], espconn->proto.tcp->local_ip[3],espconn->proto.tcp->local_port); } pcb = find_tcpsrv_pcb(pdiscon_cb); // corrected PV` if(pcb != NULL) { // added PV` tcp_arg(pcb, NULL); tcp_err(pcb, NULL); } // added PV` /*delete TIME_WAIT State pcb after 2MSL time,for not all data received by application.*/ if (pdiscon_cb->pcommon.espconn_opt == ESPCONN_REUSEADDR){ if ((pcb != NULL)&&(pcb->state == TIME_WAIT)){ // corrected PV` tcp_pcb_remove(&tcp_tw_pcbs,pcb); memp_free(MEMP_TCP_PCB,pcb); } } } os_free(pdiscon_cb); pdiscon_cb = NULL; if (espconn->proto.tcp->disconnect_callback != NULL) { espconn->proto.tcp->disconnect_callback(espconn); } } else { espconn_printf("espconn_tcp_disconnect err\n"); } }
/****************************************************************************** * FunctionName : espconn_tcp_disconnect * Description : disconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ static void espconn_tcp_disconnect_successful(void *arg) { espconn_msg *pdiscon_cb = arg; sint8 dis_err = 0; if (pdiscon_cb != NULL) { struct espconn *espconn = pdiscon_cb->preverse; dis_err = pdiscon_cb->pcommon.err; if (pdiscon_cb->pespconn != NULL){ struct tcp_pcb *pcb = NULL; if (espconn != NULL){ if (pdiscon_cb->pespconn->proto.tcp != NULL){ espconn_copy_partial(espconn, pdiscon_cb->pespconn); espconn_printf("server: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1],espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3],espconn->proto.tcp->remote_port); os_free(pdiscon_cb->pespconn->proto.tcp); pdiscon_cb->pespconn->proto.tcp = NULL; } os_free(pdiscon_cb->pespconn); pdiscon_cb->pespconn = NULL; } else { espconn = pdiscon_cb->pespconn; espconn_printf("client: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->local_ip[0], espconn->proto.tcp->local_ip[1],espconn->proto.tcp->local_ip[2], espconn->proto.tcp->local_ip[3],espconn->proto.tcp->local_port); } pcb = pdiscon_cb->pcommon.pcb; tcp_arg(pcb, NULL); tcp_err(pcb, NULL); } os_free(pdiscon_cb); pdiscon_cb = NULL; if (espconn->proto.tcp->disconnect_callback != NULL) { espconn->proto.tcp->disconnect_callback(espconn); } } else { espconn_printf("espconn_tcp_disconnect err\n"); } }
/****************************************************************************** * FunctionName : espconn_tcp_reconnect * Description : reconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_tcp_reconnect(void *arg) { espconn_msg *precon_cb = arg; sint8 re_err = 0; if (precon_cb != NULL) { struct espconn *espconn = precon_cb->preverse; re_err = precon_cb->pcommon.err; if (precon_cb->pespconn != NULL){ if (espconn != NULL){ if (precon_cb->pespconn->proto.tcp != NULL){ espconn_copy_partial(espconn, precon_cb->pespconn); espconn_printf("server: %d.%d.%d.%d : %d reconnection\n", espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1],espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3],espconn->proto.tcp->remote_port); os_free(precon_cb->pespconn->proto.tcp); precon_cb->pespconn->proto.tcp = NULL; } os_free(precon_cb->pespconn); precon_cb->pespconn = NULL; } else { espconn = precon_cb->pespconn; espconn_printf("client: %d.%d.%d.%d : %d reconnection\n", espconn->proto.tcp->local_ip[0], espconn->proto.tcp->local_ip[1],espconn->proto.tcp->local_ip[2], espconn->proto.tcp->local_ip[3],espconn->proto.tcp->local_port); } } os_free(precon_cb); precon_cb = NULL; if (espconn->proto.tcp->reconnect_callback != NULL) { espconn->proto.tcp->reconnect_callback(espconn, re_err); } } else { espconn_printf("espconn_tcp_reconnect err\n"); } }
/****************************************************************************** * FunctionName : espconn_tcp_disconnect * Description : disconnect with host * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_tcp_disconnect_successful(void *arg) { espconn_msg *pdiscon_cb = arg; sint8 dis_err = 0; espconn_buf *pdis_buf = NULL; espconn_buf *pdis_back = NULL; espconn_kill_oldest_pcb(); if (pdiscon_cb != NULL) { struct espconn *espconn = pdiscon_cb->preverse; dis_err = pdiscon_cb->pcommon.err; if (pdiscon_cb->pespconn != NULL){ struct tcp_pcb *pcb = NULL; if (espconn != NULL){/*Process the server's message block*/ if (pdiscon_cb->pespconn->proto.tcp != NULL && espconn->proto.tcp){ espconn_copy_partial(espconn, pdiscon_cb->pespconn); espconn_printf("server: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1],espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3],espconn->proto.tcp->remote_port); free(pdiscon_cb->pespconn->proto.tcp); pdiscon_cb->pespconn->proto.tcp = NULL; } free(pdiscon_cb->pespconn); pdiscon_cb->pespconn = NULL; } else {/*Process the client's message block*/ espconn = pdiscon_cb->pespconn; espconn_printf("client: %d.%d.%d.%d : %d disconnect\n", espconn->proto.tcp->local_ip[0], espconn->proto.tcp->local_ip[1],espconn->proto.tcp->local_ip[2], espconn->proto.tcp->local_ip[3],espconn->proto.tcp->local_port); } /*process the current TCP block*/ pcb = espconn_find_current_pcb(pdiscon_cb); if (pcb != NULL){ if (espconn_reuse_disabled(pdiscon_cb)) { struct tcp_pcb *cpcb = NULL; struct tcp_pcb *prev = NULL; uint8_t pcb_remove; espconn_printf("espconn_tcp_disconnect_successful %d, %d\n", pcb->state, pcb->local_port); cpcb = tcp_tw_pcbs; while (cpcb != NULL) { pcb_remove = 0; if (cpcb->local_port == pcb->local_port) { ++pcb_remove; } /* If the PCB should be removed, do it. */ if (pcb_remove) { struct tcp_pcb *backup_pcb = NULL; tcp_pcb_purge(cpcb); /* Remove PCB from tcp_tw_pcbs list. */ if (prev != NULL) { LWIP_ASSERT("espconn_tcp_delete: middle cpcb != tcp_tw_pcbs",cpcb != tcp_tw_pcbs); prev->next = cpcb->next; } else { /* This PCB was the first. */ LWIP_ASSERT("espconn_tcp_delete: first cpcb == tcp_tw_pcbs",tcp_tw_pcbs == cpcb); tcp_tw_pcbs = cpcb->next; } backup_pcb = cpcb; cpcb = cpcb->next; memp_free(MEMP_TCP_PCB, backup_pcb); } else { prev = cpcb; cpcb = cpcb->next; } } } else { tcp_arg(pcb, NULL); tcp_err(pcb, NULL); } } } /*to prevent memory leaks, ensure that each allocated is deleted*/ pdis_buf = pdiscon_cb->pcommon.pbuf; while (pdis_buf != NULL) { pdis_back = pdis_buf; pdis_buf = pdis_back->pnext; espconn_pbuf_delete(&pdiscon_cb->pcommon.pbuf, pdis_back); free(pdis_back); pdis_back = NULL; } bzero(&pktinfo[0], sizeof(struct espconn_packet)); memcpy(&pktinfo[0], (void*)&pdiscon_cb->pcommon.packet_info, sizeof(struct espconn_packet)); free(pdiscon_cb); pdiscon_cb = NULL; if (espconn->proto.tcp && espconn->proto.tcp->disconnect_callback != NULL) { espconn->proto.tcp->disconnect_callback(espconn); } } else { espconn_printf("espconn_tcp_disconnect err\n"); } }
/****************************************************************************** * FunctionName : espconn_tcp_accept * Description : A new incoming connection has been accepted. * Parameters : arg -- Additional argument to pass to the callback function * pcb -- The connection pcb which is accepted * err -- An unused error code, always ERR_OK currently * Returns : acception result *******************************************************************************/ static err_t ICACHE_FLASH_ATTR espconn_tcp_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct espconn *espconn = arg; espconn_msg *paccept = NULL; remot_info *pinfo = NULL; LWIP_UNUSED_ARG(err); if (!espconn || !espconn->proto.tcp) { return ERR_ARG; } tcp_arg(pcb, paccept); tcp_err(pcb, esponn_server_err); /*Ensure the active connection is less than the count of active connections on the server*/ espconn_get_connection_info(espconn, &pinfo , 0); espconn_printf("espconn_tcp_accept link_cnt: %d\n", espconn->link_cnt); if (espconn->link_cnt == espconn_tcp_get_max_con_allow(espconn)) return ERR_ISCONN; /*Creates a new active connect control message*/ paccept = (espconn_msg *)malloc(sizeof(espconn_msg)); memset(paccept, 0, sizeof(espconn_msg)); tcp_arg(pcb, paccept); if (paccept == NULL) return ERR_MEM; /*Insert the node to the active connection list*/ espconn_list_creat(&plink_active, paccept); paccept->preverse = espconn; paccept->pespconn = (struct espconn *)malloc(sizeof(struct espconn)); if (paccept->pespconn == NULL) return ERR_MEM; paccept->pespconn->proto.tcp = (esp_tcp *)malloc(sizeof(esp_tcp)); if (paccept->pespconn->proto.tcp == NULL) return ERR_MEM; /*Reserve the remote information for current active connection*/ paccept->pcommon.pcb = pcb; paccept->pcommon.remote_port = pcb->remote_port; paccept->pcommon.remote_ip[0] = ip4_addr1_16(&pcb->remote_ip.u_addr.ip4); paccept->pcommon.remote_ip[1] = ip4_addr2_16(&pcb->remote_ip.u_addr.ip4); paccept->pcommon.remote_ip[2] = ip4_addr3_16(&pcb->remote_ip.u_addr.ip4); paccept->pcommon.remote_ip[3] = ip4_addr4_16(&pcb->remote_ip.u_addr.ip4); paccept->pcommon.write_flag = true; memcpy(espconn->proto.tcp->remote_ip, paccept->pcommon.remote_ip, 4); espconn->proto.tcp->remote_port = pcb->remote_port; espconn->state = ESPCONN_CONNECT; espconn_copy_partial(paccept->pespconn, espconn); /*Set the specify function that should be called * when TCP data has been successfully delivered, * when active connection receives data, * or periodically from active connection*/ tcp_sent(pcb, espconn_server_sent); tcp_recv(pcb, espconn_server_recv); tcp_poll(pcb, espconn_server_poll, 8); /* every 1 seconds */ /*Disable Nagle algorithm default*/ tcp_nagle_disable(pcb); /*Default set the total number of espconn_buf on the unsent lists for one*/ espconn_tcp_set_buf_count(paccept->pespconn, 1); if (paccept->pespconn->proto.tcp->connect_callback != NULL) { paccept->pespconn->proto.tcp->connect_callback(paccept->pespconn); } /*Enable keep alive option*/ if (espconn_keepalive_disabled(paccept)) espconn_keepalive_enable(pcb); return ERR_OK; }