// if (pespconn->proto.tcp->write_finish_fn != NULL) { // pespconn->proto.tcp->write_finish_fn(pespconn); // } // } // break; // case SIG_ESPCONN_ERRER: // /*remove the node from the client's active connection list*/ // espconn_list_delete(&plink_active, task_msg); // espconn_tcp_reconnect(task_msg); // break; // case SIG_ESPCONN_CLOSE: // /*remove the node from the client's active connection list*/ // espconn_list_delete(&plink_active, task_msg); // espconn_tcp_disconnect_successful(task_msg); // break; // default: // break; // } // } // } static void ICACHE_FLASH_ATTR espconn_Task(ETSEvent *events) { espconn_msg *task_msg = NULL; struct espconn *pespconn = NULL; printf("events->sig %d\n", events->sig); task_msg = (espconn_msg *) events->par; switch (events->sig) { case SIG_ESPCONN_WRITE: { pespconn = task_msg->pespconn; if (pespconn == NULL) { return; } if (pespconn->proto.tcp->write_finish_fn != NULL) { pespconn->proto.tcp->write_finish_fn(pespconn); } } break; case SIG_ESPCONN_ERRER: /*remove the node from the client's active connection list*/ espconn_list_delete(&plink_active, task_msg); espconn_tcp_reconnect(task_msg); break; case SIG_ESPCONN_CLOSE: /*remove the node from the client's active connection list*/ espconn_list_delete(&plink_active, task_msg); espconn_tcp_disconnect_successful(task_msg); break; default: break; } }
/****************************************************************************** * FunctionName : espconn_tcp_delete * Description : delete the server: delete a listening PCB and free it * Parameters : pdeletecon -- the espconn used to delete a server * Returns : none *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_delete(struct espconn *pdeletecon) { err_t err; remot_info *pinfo = NULL; espconn_msg *pdelete_msg = NULL; struct tcp_pcb *pcb = NULL; if (pdeletecon == NULL) return ESPCONN_ARG; espconn_get_connection_info(pdeletecon, &pinfo , 0); if (pdeletecon->link_cnt != 0) return ESPCONN_INPROGRESS; else { os_printf("espconn_tcp_delete %p\n",pdeletecon); pdelete_msg = pserver_list; while (pdelete_msg != NULL){ if (pdelete_msg->pespconn == pdeletecon){ /*remove the node from the client's active connection list*/ espconn_list_delete(&pserver_list, pdelete_msg); pcb = pdelete_msg->preverse; os_printf("espconn_tcp_delete %d\n",pcb->state); err = tcp_close(pcb); os_free(pdelete_msg); pdelete_msg = NULL; break; } pdelete_msg = pdelete_msg->pnext; } if (err == ERR_OK) return err; else return ESPCONN_ARG; } }
/****************************************************************************** * FunctionName : esponn_server_err * Description : The pcb had an error and is already deallocated. * The argument might still be valid (if != NULL). * Parameters : arg -- Additional argument to pass to the callback function * err -- Error code to indicate why the pcb has been closed * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR esponn_server_err(void *arg, err_t err) { espconn_msg *pserr_cb = arg; struct tcp_pcb *pcb = NULL; if (pserr_cb != NULL) { os_timer_disarm(&pserr_cb->pcommon.ptimer); pcb = pserr_cb->pcommon.pcb; pserr_cb->pespconn->state = ESPCONN_CLOSE; /*remove the node from the server's active connection list*/ espconn_list_delete(&plink_active, pserr_cb); if (err == ERR_ABRT) { switch (pcb->state) { case SYN_RCVD: if (pcb->nrtx == TCP_SYNMAXRTX) { pserr_cb->pcommon.err = ESPCONN_CONN; } else { pserr_cb->pcommon.err = err; } break; case ESTABLISHED: if (pcb->nrtx == TCP_MAXRTX) { pserr_cb->pcommon.err = ESPCONN_TIMEOUT; } else { pserr_cb->pcommon.err = err; } break; case CLOSE_WAIT: if (pcb->nrtx == TCP_MAXRTX) { pserr_cb->pcommon.err = ESPCONN_CLSD; } else { pserr_cb->pcommon.err = err; } break; case LAST_ACK: pserr_cb->pcommon.err = ESPCONN_CLSD; break; case CLOSED: pserr_cb->pcommon.err = ESPCONN_CONN; break; default : break; } } else { pserr_cb->pcommon.err = err; } os_timer_setfn(&pserr_cb->pcommon.ptimer, (os_timer_func_t *) espconn_tcp_reconnect, pserr_cb); os_timer_arm(&pserr_cb->pcommon.ptimer, 10, 0); } }
/****************************************************************************** * FunctionName : espconn_client_err * Description : The pcb had an error and is already deallocated. * The argument might still be valid (if != NULL). * Parameters : arg -- Additional argument to pass to the callback function * err -- Error code to indicate why the pcb has been closed * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_client_err(void *arg, err_t err) { espconn_msg *perr_cb = arg; struct tcp_pcb *pcb = NULL; LWIP_UNUSED_ARG(err); if (perr_cb != NULL) { os_timer_disarm(&perr_cb->pcommon.ptimer); pcb = perr_cb->pcommon.pcb; perr_cb->pespconn->state = ESPCONN_CLOSE; espconn_printf("espconn_client_err %d %d %d\n", pcb->state, pcb->nrtx, err); /*remove the node from the client's active connection list*/ espconn_list_delete(&plink_active, perr_cb); if (err == ERR_ABRT) { switch (pcb->state) { case SYN_SENT: if (pcb->nrtx == TCP_SYNMAXRTX) { perr_cb->pcommon.err = ESPCONN_CONN; } else { perr_cb->pcommon.err = err; } break; case ESTABLISHED: if (pcb->nrtx == TCP_MAXRTX) { perr_cb->pcommon.err = ESPCONN_TIMEOUT; } else { perr_cb->pcommon.err = err; } break; case FIN_WAIT_1: if (pcb->nrtx == TCP_MAXRTX) { perr_cb->pcommon.err = ESPCONN_CLSD; } else { perr_cb->pcommon.err = err; } break; case FIN_WAIT_2: perr_cb->pcommon.err = ESPCONN_CLSD; break; case CLOSED: perr_cb->pcommon.err = ESPCONN_CONN; break; } } else { perr_cb->pcommon.err = err; } os_timer_setfn(&perr_cb->pcommon.ptimer, (os_timer_func_t *) espconn_tcp_reconnect, perr_cb); os_timer_arm(&perr_cb->pcommon.ptimer, 10, 0); } }
/****************************************************************************** * FunctionName : espconn_tcp_client * Description : Initialize the client: set up a connect PCB and bind it to * the defined port * Parameters : espconn -- the espconn used to build client * Returns : none *******************************************************************************/ sint8 ICACHE_FLASH_ATTR espconn_tcp_client(struct espconn *espconn) { struct tcp_pcb *pcb = NULL; struct ip_addr ipaddr; espconn_msg *pclient = NULL; /*Creates a new client control message*/ pclient = (espconn_msg *)os_zalloc(sizeof(espconn_msg)); if (pclient == NULL){ return ESPCONN_MEM; } /*Set an IP address given for Little-endian.*/ IP4_ADDR(&ipaddr, espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1], espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3]); /*Creates a new TCP protocol control block*/ pcb = tcp_new(); if (pcb == NULL) { /*to prevent memory leaks, ensure that each allocated is deleted*/ os_free(pclient); pclient = NULL; return ESPCONN_MEM; } else { /*insert the node to the active connection list*/ espconn_list_creat(&plink_active, pclient); tcp_arg(pcb, (void *)pclient); tcp_err(pcb, espconn_client_err); pclient->preverse = NULL; pclient->pespconn = espconn; pclient->pespconn->state = ESPCONN_WAIT; pclient->pcommon.pcb = pcb; tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); /*Establish the connection*/ pclient->pcommon.err = tcp_connect(pcb, &ipaddr, pclient->pespconn->proto.tcp->remote_port, espconn_client_connect); if (pclient->pcommon.err == ERR_RTE){ /*remove the node from the client's active connection list*/ espconn_list_delete(&plink_active, pclient); espconn_kill_pcb(pcb->local_port); os_free(pclient); pclient = NULL; return ESPCONN_RTE; } return pclient->pcommon.err; } }
/****************************************************************************** * FunctionName : espconn_udp_disconnect * Description : A new incoming connection has been disconnected. * Parameters : espconn -- the espconn used to disconnect with host * Returns : none *******************************************************************************/ void ICACHE_FLASH_ATTR espconn_udp_disconnect(espconn_msg *pdiscon) { if (pdiscon == NULL) { return; } struct udp_pcb *upcb = pdiscon->pcommon.pcb; udp_disconnect(upcb); udp_remove(upcb); espconn_list_delete(&plink_active, pdiscon); os_free(pdiscon); pdiscon = NULL; }
/****************************************************************************** * FunctionName : espconn_closed * Description : The connection has been successfully closed. * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_sclose_cb(void *arg) { espconn_msg *psclose_cb = arg; if (psclose_cb == NULL) { return; } struct tcp_pcb *pcb = find_tcpsrv_pcb(psclose_cb); // added PV` // espconn_printf("espconn_sclose_cb %d %d\n", pcb->state, pcb->nrtx); if ((pcb == NULL) || (pcb->state == CLOSED) || (pcb->state == TIME_WAIT)) { // corrected PV` psclose_cb ->pespconn ->state = ESPCONN_CLOSE; /*remove the node from the server's active connection list*/ espconn_list_delete(&plink_active, psclose_cb); espconn_tcp_disconnect_successful(psclose_cb); } else { os_timer_arm(&psclose_cb->pcommon.ptimer, TCP_FAST_INTERVAL, 0); } }
/****************************************************************************** * FunctionName : espconn_closed * Description : The connection has been successfully closed. * Parameters : arg -- Additional argument to pass to the callback function * Returns : none *******************************************************************************/ static void espconn_sclose_cb(void *arg) { espconn_msg *psclose_cb = arg; if (psclose_cb == NULL) { return; } struct tcp_pcb *pcb = psclose_cb ->pcommon.pcb; espconn_printf("espconn_sclose_cb %d %d\n", pcb->state, pcb->nrtx); if (pcb->state == CLOSED || pcb->state == TIME_WAIT) { psclose_cb ->pespconn ->state = ESPCONN_CLOSE; /*remove the node from the server's active connection list*/ espconn_list_delete(&plink_active, psclose_cb); espconn_tcp_disconnect_successful(psclose_cb); } else { os_timer_arm(&psclose_cb->pcommon.ptimer, TCP_FAST_INTERVAL, 0); } }
sint8 ICACHE_FLASH_ATTR espconn_tcp_client(struct espconn *espconn) { struct tcp_pcb *pcb = NULL; ip_addr_t ipaddr; espconn_msg *pclient = NULL; /*Creates a new client control message*/ pclient = (espconn_msg *)malloc(sizeof(espconn_msg)); memset(pclient,0,sizeof(espconn_msg)); if (pclient == NULL){ return ESPCONN_MEM; } /*Set an IP address given for Little-endian.*/ ipaddr.type = IPADDR_TYPE_V4; IP4_ADDR(&ipaddr.u_addr.ip4, espconn->proto.tcp->remote_ip[0], espconn->proto.tcp->remote_ip[1], espconn->proto.tcp->remote_ip[2], espconn->proto.tcp->remote_ip[3]); // printf("espconn_tcp_client ipaddr %d:%d:%d:%d\n" // ,(uint8_t)(ipaddr.u_addr.ip4.addr) // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>8) // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>16) // ,(uint8_t)(ipaddr.u_addr.ip4.addr>>24)); /*Creates a new TCP protocol control block*/ pcb = tcp_new(); if (pcb == NULL) { /*to prevent memory leaks, ensure that each allocated is deleted*/ free(pclient); pclient = NULL; return ESPCONN_MEM; } else { /*insert the node to the active connection list*/ espconn_list_creat(&plink_active, pclient); //printf("espconn_msg 3: %p\n", pclient); tcp_arg(pcb, (void *)pclient); tcp_err(pcb, espconn_client_err); pclient->preverse = NULL; pclient->pespconn = espconn; pclient->pespconn->state = ESPCONN_WAIT; pclient->pcommon.pcb = pcb; tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); #if 0 pclient->pcommon.err = tcp_bind(pcb, IP_ADDR_ANY, pclient->pespconn->proto.tcp->local_port); if (pclient->pcommon.err != ERR_OK){ /*remove the node from the client's active connection list*/ espconn_list_delete(&plink_active, pclient); memp_free(MEMP_TCP_PCB, pcb); free(pclient); pclient = NULL; return ERR_USE; } #endif /*Establish the connection*/ pclient->pcommon.err = tcp_connect(pcb, &ipaddr, pclient->pespconn->proto.tcp->remote_port, espconn_client_connect); if (pclient->pcommon.err == ERR_RTE){ /*remove the node from the client's active connection list*/ printf("fail to connect %s\n",__FILE__); espconn_list_delete(&plink_active, pclient); espconn_kill_pcb(pcb->local_port); free(pclient); pclient = NULL; return ESPCONN_RTE; } return pclient->pcommon.err; } }