err_t EthernetClient::do_poll(void *arg, struct tcp_pcb *cpcb) { EthernetClient *client = static_cast<EthernetClient*>(arg); if(client->_connected) { if(cpcb->keep_cnt_sent++ > 4) { cpcb->keep_cnt_sent = 0; /* Stop polling */ tcp_poll(cpcb, NULL, 0); tcp_abort(cpcb); return ERR_OK; } /* Send tcp keep alive probe */ tcp_keepalive(cpcb); return ERR_OK; } /* We only end up here if the connection failed to close * in an earlier call to tcp_close */ err_t err = tcp_close(cpcb); if (err != ERR_OK) { /* error closing, try again later in poll (every 2 sec) */ tcp_poll(cpcb, do_poll, 4); return err; } return err; }
/*************************************************************************************************************************** **函数名称: ftp_poll **函数功能: **入口参数: **返回参数: ***************************************************************************************************************************/ void ftp_poll(FTP_INFO *pftpInfo,BYTE interval) { if(eRAW == pftpInfo->attri) { if(eCtr == pftpInfo->ctrOrMsg) { tcp_poll(pftpInfo->ftpRAWControl,pftpInfo->poll,interval); } else if(eMsg == pftpInfo->ctrOrMsg) { tcp_poll(pftpInfo->ftpRAWDataMsg,pftpInfo->poll,interval); } } }
/** * Internal helper function to close a TCP netconn: since this sometimes * doesn't work at the first attempt, this function is called from multiple * places. * * @param conn the TCP netconn to close */ static void do_close_internal(struct netconn *conn) { err_t err; LWIP_ASSERT("invalid conn", (conn != NULL)); LWIP_ASSERT("this is for tcp netconns only", (conn->type == NETCONN_TCP)); LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); /* Set back some callback pointers */ tcp_arg(conn->pcb.tcp, NULL); if (conn->pcb.tcp->state == LISTEN) { tcp_accept(conn->pcb.tcp, NULL); } else { tcp_recv(conn->pcb.tcp, NULL); tcp_accept(conn->pcb.tcp, NULL); /* some callbacks have to be reset if tcp_close is not successful */ tcp_sent(conn->pcb.tcp, NULL); tcp_poll(conn->pcb.tcp, NULL, 4); tcp_err(conn->pcb.tcp, NULL); } /* Try to close the connection */ err = tcp_close(conn->pcb.tcp); if (err == ERR_OK) { /* Closing succeeded */ conn->state = NETCONN_NONE; /* Set back some callback pointers as conn is going away */ conn->pcb.tcp = NULL; conn->err = ERR_OK; /* Trigger select() in socket layer. This send should something else so the errorfd is set, not the read and write fd! */ API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); /* wake up the application task */ sys_sem_signal(conn->op_completed); } else { /* Closing failed, restore some of the callbacks */ /* Closing of listen pcb will never fail! */ LWIP_ASSERT("Closing a listen pcb may not fail!", (conn->pcb.tcp->state != LISTEN)); tcp_sent(conn->pcb.tcp, sent_tcp); tcp_poll(conn->pcb.tcp, poll_tcp, 4); tcp_err(conn->pcb.tcp, err_tcp); tcp_arg(conn->pcb.tcp, conn); } /* If closing didn't succeed, we get called again either from poll_tcp or from sent_tcp */ }
void EthernetClient::stop() { if(cpcb == NULL) return; _connected = false; /* Stop frees any resources including any unread buffers */ err_t err; if(cpcb) { tcp_err(cpcb, NULL); if(cs->p) { tcp_recved(cpcb, cs->p->tot_len); pbuf_free(cs->p); cs->p = NULL; } err = tcp_close(cpcb); } if (err != ERR_OK) { /* Error closing, try again later in poll (every 2 sec) */ tcp_poll(cpcb, do_poll, 4); } else { cpcb = NULL; } }
static err_t altcp_tcp_close(struct altcp_pcb *conn) { struct tcp_pcb *pcb; if (conn == NULL) { return ERR_VAL; } ALTCP_TCP_ASSERT_CONN(conn); pcb = (struct tcp_pcb *)conn->state; if (pcb) { err_t err; tcp_poll_fn oldpoll = pcb->poll; altcp_tcp_remove_callbacks(pcb); err = tcp_close(pcb); if (err != ERR_OK) { /* not closed, set up all callbacks again */ altcp_tcp_setup_callbacks(conn, pcb); /* poll callback is not included in the above */ tcp_poll(pcb, oldpoll, pcb->pollinterval); return err; } conn->state = NULL; /* unsafe to reference pcb after tcp_close(). */ } altcp_free(conn); return ERR_OK; }
//lwIP tcp_accept()的回调函数 err_t tcp_server_accept(void *arg,struct tcp_pcb *newpcb,err_t err) { err_t ret_err; struct tcp_server_struct *es; LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); tcp_setprio(newpcb,TCP_PRIO_MIN);//设置新创建的pcb优先级 es=(struct tcp_server_struct*)mem_malloc(sizeof(struct tcp_server_struct)); //分配内存 if(es!=NULL) //内存分配成功 { es->state=ES_TCPSERVER_ACCEPTED; //接收连接 es->pcb=newpcb; es->p=NULL; tcp_arg(newpcb,es); tcp_recv(newpcb,tcp_server_recv); //初始化tcp_recv()的回调函数 tcp_err(newpcb,tcp_server_error); //初始化tcp_err()回调函数 tcp_poll(newpcb,tcp_server_poll,1); //初始化tcp_poll回调函数 tcp_sent(newpcb,tcp_server_sent); //初始化发送回调函数 tcp_server_flag|=1<<5; //标记有客户端连上了 lwipdev.remoteip[0]=newpcb->remote_ip.addr&0xff; //IADDR4 lwipdev.remoteip[1]=(newpcb->remote_ip.addr>>8)&0xff; //IADDR3 lwipdev.remoteip[2]=(newpcb->remote_ip.addr>>16)&0xff; //IADDR2 lwipdev.remoteip[3]=(newpcb->remote_ip.addr>>24)&0xff; //IADDR1 ret_err=ERR_OK; }else ret_err=ERR_MEM;
/****************************************************************************** * FunctionName : espconn_server_close * Description : The connection shall be actively closed. * Parameters : arg -- Additional argument to pass to the callback function * pcb -- the pcb to close * Returns : none *******************************************************************************/ static void ICACHE_FLASH_ATTR espconn_server_close(void *arg, struct tcp_pcb *pcb,uint8 type) { err_t err; espconn_msg *psclose = arg; psclose->pcommon.pcb = pcb; /*avoid recalling the disconnect function*/ tcp_recv(pcb, NULL); if(type ==0) err = tcp_close(pcb); else {tcp_abort(pcb); err = ERR_OK;} if (err != ERR_OK) { /* closing failed, try again later */ tcp_recv(pcb, espconn_server_recv); } else { /* closing succeeded */ tcp_poll(pcb, NULL, 0); tcp_sent(pcb, NULL); tcp_err(pcb, NULL); /*switch the state of espconn for application process*/ psclose->pespconn->state = ESPCONN_CLOSE; ets_post(espconn_TaskPrio, SIG_ESPCONN_CLOSE, (uint32_t)psclose); } }
/*-----------------------------------------------------------------------------------*/ static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct http_state *hs; /* Allocate memory for the structure that holds the state of the connection. */ hs = mem_malloc(sizeof(struct http_state)); if (hs == NULL) { return ERR_MEM; } /* Initialize the structure. */ hs->file = NULL; hs->left = 0; /* Tell TCP that this is the structure we wish to be passed for our callbacks. */ tcp_arg(pcb, hs); /* Tell TCP that we wish to be informed of incoming data by a call to the http_recv() function. */ tcp_recv(pcb, http_recv); tcp_err(pcb, conn_err); tcp_poll(pcb, http_poll, 10); return ERR_OK; }
// "Poll" (idle) callback to be called ASAP after accept callback // to execute Python callback function, as it can't be executed // from accept callback itself. STATIC err_t _lwip_tcp_accept_finished(void *arg, struct tcp_pcb *pcb) { lwip_socket_obj_t *socket = (lwip_socket_obj_t*)arg; tcp_poll(pcb, NULL, 0); exec_user_callback(socket); return ERR_OK; }
AsyncClient::AsyncClient(tcp_pcb* pcb) : _connect_cb(0) , _connect_cb_arg(0) , _discard_cb(0) , _discard_cb_arg(0) , _sent_cb(0) , _sent_cb_arg(0) , _error_cb(0) , _error_cb_arg(0) , _recv_cb(0) , _recv_cb_arg(0) , _timeout_cb(0) , _timeout_cb_arg(0) , _pcb_busy(false) , _pcb_sent_at(0) , _close_pcb(false) , _ack_pcb(true) , _rx_last_packet(0) , _rx_since_timeout(0) , _ack_timeout(ASYNC_MAX_ACK_TIME) , _connect_port(0) , prev(NULL) , next(NULL) , _in_lwip_thread(false) { _pcb = pcb; if(_pcb){ _rx_last_packet = millis(); tcp_arg(_pcb, this); tcp_recv(_pcb, &_tcp_recv); tcp_sent(_pcb, &_tcp_sent); tcp_err(_pcb, &_tcp_error); tcp_poll(_pcb, &_tcp_poll, 1); } }
static err_t http_accept(void *arg, tcp_pcb *pcb, err_t err) { LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); tcp_setprio(pcb, TCP_PRIO_MIN); //RepRapNetworkMessage("http_accept\n"); HttpState *hs = (HttpState*)mem_malloc(sizeof(HttpState)); if (hs == NULL) { RepRapNetworkMessage("Out of memory!\n"); return ERR_MEM; } /* Initialize the structure. */ hs->pcb = pcb; hs->file = NULL; hs->left = 0; hs->retries = 0; hs->sendingRs = NULL; tcp_accepted(listening_pcb); // tell TCP to accept further connections tcp_arg(pcb, hs); // tell TCP that this is the structure we wish to be passed for our callbacks tcp_recv(pcb, http_recv); // tell TCP that we wish to be informed of incoming data by a call to the http_recv() function tcp_err(pcb, conn_err); tcp_poll(pcb, http_poll, 4); return ERR_OK; }
void NetworkTransaction::Close() { tcp_pcb *pcb = cs->pcb; tcp_poll(pcb, NULL, 4); tcp_recv(pcb, NULL); closeRequested = true; }
int lwip_bind(int s, struct sockaddr *name, socklen_t namelen) { sockfd_t * fd; struct ip_addr ip; int port, rv = 0; s = sock_for_fd(s); if (s < 0) { errno = EBADF; return -1; } fd = fds + s; // Make sure it's an internet address we understand. if (namelen != sizeof(struct sockaddr_in)) { errno = ENAMETOOLONG; return -1; } // Get access mutex_lock(fd->mutex); // Copy it over memcpy(&fd->name, name, namelen); // Convert this to an lwIP-happy format ip.addr = ((struct sockaddr_in *)name)->sin_addr.s_addr; port = ((struct sockaddr_in *)name)->sin_port; // Are we TCP or UDP? switch (fd->type) { case SOCK_STREAM: fd->tcppcb = tcp_new(); tcp_arg(fd->tcppcb, (void *)s); tcp_recv(fd->tcppcb, recv_tcp); tcp_sent(fd->tcppcb, sent_tcp); tcp_poll(fd->tcppcb, poll_tcp, 4); // 4 == 4 TCP timer intervals tcp_err(fd->tcppcb, err_tcp); if (tcp_bind(fd->tcppcb, &ip, ntohs(port)) != ERR_OK) { if (tcp_close(fd->tcppcb) != ERR_OK) tcp_abort(fd->tcppcb); fd->tcppcb = NULL; errno = EINVAL; rv = -1; goto out; } break; case SOCK_DGRAM: fd->udppcb = udp_new(); udp_recv(fd->udppcb, recv_udp, (void *)s); udp_bind(fd->udppcb, &ip, ntohs(port)); break; default: assert( 0 ); errno = EINVAL; rv = -1; goto out; } out: mutex_unlock(fd->mutex); return rv; }
static err_t tcpecho_raw_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t ret_err; struct tcpecho_raw_state *es; LWIP_UNUSED_ARG(arg); if ((err != ERR_OK) || (newpcb == NULL)) { return ERR_VAL; } /* Unless this pcb should have NORMAL priority, set its priority now. When running out of pcbs, low priority pcbs can be aborted to create new pcbs of higher priority. */ tcp_setprio(newpcb, TCP_PRIO_MIN); es = (struct tcpecho_raw_state *)mem_malloc(sizeof(struct tcpecho_raw_state)); if (es != NULL) { es->state = ES_ACCEPTED; es->pcb = newpcb; es->retries = 0; es->p = NULL; /* pass newly allocated es to our callbacks */ tcp_arg(newpcb, es); tcp_recv(newpcb, tcpecho_raw_recv); tcp_err(newpcb, tcpecho_raw_error); tcp_poll(newpcb, tcpecho_raw_poll, 0); tcp_sent(newpcb, tcpecho_raw_sent); ret_err = ERR_OK; } else { ret_err = ERR_MEM; } return ret_err; }
/*-----------------------------------------------------------------------------------*/ static err_t ident_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct ident_state *hs; /* Allocate memory for the structure that holds the state of the connection. */ hs = mem_malloc(sizeof(struct ident_state)); if(hs == NULL) { printf("ident_accept: Out of memory\n"); return ERR_MEM; } /* Initialize the structure. */ memset (hs, 0, sizeof (*hs)); if (sizeof (hs->remote) != sizeof (pcb->remote_ip)) die ("sizeof (hs.remote) != sizeof (pcb->remote_ip)"); memcpy (&hs->remote, &pcb->remote_ip, sizeof (hs->remote)); /* Tell TCP that this is the structure we wish to be passed for our callbacks. */ tcp_arg(pcb, hs); /* Tell TCP that we wish to be informed of incoming data by a call to the ident_recv() function. */ tcp_recv(pcb, ident_recv); tcp_err(pcb, conn_err); tcp_poll(pcb, ident_poll, 10); return ERR_OK; }
void EthernetClient::stop() { /* Stop frees any resources including any unread buffers */ err_t err; INT_PROTECT_INIT(oldLevel); /* protect the code from preemption of the ethernet interrupt servicing */ INT_PROTECT(oldLevel); struct tcp_pcb * cpcb_copy = (tcp_pcb *) SYNC_FETCH_AND_NULL(&cs->cpcb); struct pbuf * p_copy = (pbuf *) SYNC_FETCH_AND_NULL(&cs->p); _connected = false; cs->port = 0; if (cpcb_copy) { tcp_err(cpcb_copy, NULL); if (p_copy) { tcp_recved(cpcb_copy, p_copy->tot_len); pbuf_free(p_copy); } err = tcp_close(cpcb_copy); if (err != ERR_OK) { /* Error closing, try again later in poll (every 2 sec) */ tcp_poll(cpcb_copy, do_poll, 4); } } INT_UNPROTECT(oldLevel); }
/** * @brief This function is the implementation of tcp_accept LwIP callback * @param arg: not used * @param newpcb: pointer on tcp_pcb struct for the newly created tcp connection * @param err: not used * @retval err_t: error status */ static err_t TCP_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t ret_err; TCP *es; LWIP_UNUSED_ARG(arg); LWIP_UNUSED_ARG(err); tcp_setprio(newpcb, TCP_PRIO_MIN); /* set priority for the newly accepted tcp connection newpcb */ es = (TCP *)mem_malloc(sizeof(TCP)); /* allocate structure es to maintain tcp connection informations */ if (es != NULL) { es->state = ES_ACCEPTED; es->pcb = newpcb; es->tx = NULL; es->rx = NULL; tcp_arg(newpcb, es); /* pass newly allocated es structure as argument to newpcb */ tcp_recv(newpcb, TCP_recv); /* initialize lwip tcp_recv callback function for newpcb */ tcp_err(newpcb, TCP_error); /* initialize lwip tcp_err callback function for newpcb */ tcp_poll(newpcb, TCP_poll, 1); /* initialize lwip tcp_poll callback function for newpcb */ es->io=((func*)arg)(NULL); // prvi klic if(es->io) { // tole je lahko tut drugace es->f=(func *)arg; _thread_add(es->f,es->io,"user app.",0); _thread_add(_tcp_flush,es,"tcp flush",0); } ret_err = ERR_OK; } else { ret_err = ERR_MEM; /* return memory error */ } return ret_err; }
// Called when a new connection was accepted. static err_t http_accept(void *arg, struct tcp_pcb *pcb, err_t err) { struct http_state *hs; CYG_TEST_INFO("Incoming connection"); tcp_setprio(pcb, TCP_PRIO_MIN); // Allocate memory for the structure that holds the state of the connection hs = mem_malloc(sizeof(struct http_state)); if (hs == NULL) return ERR_MEM; // Initialize the structure hs->file = NULL; hs->left = 0; hs->retries = 0; // Tell TCP that this is the structure we wish to be passed for our // callbacks tcp_arg(pcb, hs); // Register callbacks tcp_recv(pcb, http_recv); tcp_err(pcb, http_err); tcp_poll(pcb, http_poll, 4); CYG_TEST_INFO("Connection accepted"); return ERR_OK; }
AsyncClient::AsyncClient(tcp_pcb* pcb): _connect_cb(0) , _connect_cb_arg(0) , _discard_cb(0) , _discard_cb_arg(0) , _sent_cb(0) , _sent_cb_arg(0) , _error_cb(0) , _error_cb_arg(0) , _recv_cb(0) , _recv_cb_arg(0) , _timeout_cb(0) , _timeout_cb_arg(0) , _refcnt(0) , _pcb_busy(false) , _pcb_sent_at(0) , _close_pcb(false) , _rx_last_packet(0) , _rx_since_timeout(0) , prev(NULL) , next(NULL) { _pcb = pcb; if(pcb){ tcp_setprio(_pcb, TCP_PRIO_MIN); tcp_arg(_pcb, this); tcp_recv(_pcb, (tcp_recv_fn) &_s_recv); tcp_sent(_pcb, &_s_sent); tcp_err(_pcb, &_s_error); tcp_poll(_pcb, &_s_poll, 1); } }
err_t echo_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t ret_err; struct echo_state *es; /* commonly observed practive to call tcp_setprio(), why? */ tcp_setprio(newpcb, TCP_PRIO_MIN); es = mem_malloc(sizeof(struct echo_state)); if (es != NULL) { es->state = ES_ACCEPTED; es->pcb = newpcb; es->retries = 0; es->p = NULL; /* pass newly allocated es to our callbacks */ tcp_arg(newpcb, es); tcp_recv(newpcb, echo_recv); tcp_err(newpcb, echo_error); tcp_poll(newpcb, echo_poll, 0); ret_err = ERR_OK; } else { ret_err = ERR_MEM; } return ret_err; }
static void netio_close(void *arg, struct tcp_pcb *pcb) { err_t err; struct netio_state *ns = arg; ns->state = NETIO_STATE_DONE; tcp_recv(pcb, NULL); err = tcp_close(pcb); if (err != ERR_OK) { /* closing failed, try again later */ tcp_recv(pcb, netio_recv); } else { /* closing succeeded */ #if NETIO_USE_STATIC_BUF != 1 if(ns->buf_ptr != NULL){ mem_free(ns->buf_ptr); } #endif tcp_arg(pcb, NULL); tcp_poll(pcb, NULL, 0); tcp_sent(pcb, NULL); if (arg != NULL) { mem_free(arg); } } }
/** * @brief This function is used to close the tcp connection with server */ static void tcp_echoclient_connection_close(TM_TCPCLIENT_t* client, uint8_t success) { /* Remove callbacks from PCB */ if (client->pcb != NULL) { tcp_recv(client->pcb, NULL); tcp_sent(client->pcb, NULL); tcp_poll(client->pcb, NULL, 0); } /* Close tcp connection */ if (client->pcb != NULL) { tcp_close(client->pcb); } /* Free pcb */ mem_free(client->pcb); /* Increase number of connections */ TM_ETHERNET.ClientConnections++; /* In case connection was successfull */ if (success) { /* Increase successfull connections counter */ TM_ETHERNET.ClientSuccessfullConnections++; } /* Free client, it's not real free, only free flag is set */ /* Called before connection callback, so user can make a new connection */ /* inside connection closed callback */ tcp_client_free(client); /* Call user function if defined */ TM_ETHERNETCLIENT_ConnectionClosedCallback(client, success); }
/** This is called when a new client connects for an iperf tcp session */ static err_t lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) { lwiperf_state_tcp_t *s, *conn; if ((err != ERR_OK) || (newpcb == NULL) || (arg == NULL)) { return ERR_VAL; } s = (lwiperf_state_tcp_t*)arg; conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); if (conn == NULL) { return ERR_MEM; } memset(conn, 0, sizeof(lwiperf_state_tcp_t)); conn->base.tcp = 1; conn->base.server = 1; conn->base.related_server_state = &s->base; conn->server_pcb = s->server_pcb; conn->conn_pcb = newpcb; conn->time_started = sys_now(); conn->report_fn = s->report_fn; conn->report_arg = s->report_arg; /* setup the tcp rx connection */ tcp_arg(newpcb, conn); tcp_recv(newpcb, lwiperf_tcp_recv); tcp_poll(newpcb, lwiperf_tcp_poll, 2U); tcp_err(conn->conn_pcb, lwiperf_tcp_err); lwiperf_list_add(&conn->base); return ERR_OK; }
/** Close an iperf tcp session */ static void lwiperf_tcp_close(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type) { err_t err; lwip_tcp_conn_report(conn, report_type); lwiperf_list_remove(&conn->base); if (conn->conn_pcb != NULL) { tcp_arg(conn->conn_pcb, NULL); tcp_poll(conn->conn_pcb, NULL, 0); tcp_sent(conn->conn_pcb, NULL); tcp_recv(conn->conn_pcb, NULL); tcp_err(conn->conn_pcb, NULL); err = tcp_close(conn->conn_pcb); if (err != ERR_OK) { /* don't want to wait for free memory here... */ tcp_abort(conn->conn_pcb); } } else { /* no conn pcb, this is the server pcb */ err = tcp_close(conn->server_pcb); LWIP_ASSERT("error", err != ERR_OK); } LWIPERF_FREE(lwiperf_state_tcp_t, conn); }
/** * Start TCP transfer. */ static int atcp_start(struct ttcp* ttcp) { err_t err = ERR_OK; ttcp->tpcb = tcp_new(); if (ttcp->tpcb == NULL) { WARN("TTCP [%p]: could not allocate pcb\n", ttcp); return -1; } ttcp->payload = malloc(ttcp->buflen); if (ttcp->payload == NULL) { WARN("TTCP [%p]: could not allocate payload\n", ttcp); return -1; } tcp_arg(ttcp->tpcb, ttcp); atcp_init_pend_flags(); if (ttcp->mode == TTCP_MODE_TRANSMIT) { tcp_err(ttcp->tpcb, atcp_conn_cli_err_cb); tcp_recv(ttcp->tpcb, atcp_recv_cb); tcp_sent(ttcp->tpcb, tcp_data_sent); tcp_poll(ttcp->tpcb, atcp_poll_conn, 4); _connected = false; INFO_TCP("[tpcb]-%p payload:%p\n", ttcp->tpcb, ttcp->payload); DUMP_TCP_STATE(ttcp); if (tcp_connect(ttcp->tpcb, &ttcp->addr, ttcp->port, tcp_connect_cb) != ERR_OK) { WARN("TTCP [%p]: tcp connect failed\n", ttcp); return -1; } } else { INFO_TCP("BEFORE BIND ttcp:%p lpcb:%p pcb:%p\n", ttcp, ttcp->lpcb, ttcp->tpcb); INFO_TCP("[tpcb]-local:%d remote:%d state:%d\n", ttcp->tpcb->local_port, ttcp->tpcb->remote_port, ttcp->tpcb->state); err = tcp_bind(ttcp->tpcb, IP_ADDR_ANY, ttcp->port); if (err != ERR_OK){ WARN("TTCP [%p]: bind failed err=%d Port already used\n", ttcp, err); return -1; } ttcp->lpcb = tcp_listen(ttcp->tpcb); if (ttcp->lpcb == NULL) { WARN("TTCP [%p]: listen failed\n", ttcp); return -1; } if (ttcp->lpcb == ttcp->tpcb ) { WARN("TTCP [%p]: listen failed tpcb [%p] in listen mode\n", ttcp, ttcp->tpcb); return -1; } DUMP_TCP_STATE(ttcp); tcp_accept(ttcp->lpcb, atcp_accept_cb); } return 0; }
/** * @brief Function called when TCP connection established * @param tpcb: pointer on the connection contol block * @param err: when connection correctly established err should be ERR_OK * @retval err_t: returned error */ static err_t tcp_echoclient_connected(void *arg, struct tcp_pcb *tpcb, err_t err) { struct echoclient *es = NULL; if (err == ERR_OK) { /* allocate structure es to maintain tcp connection informations */ es = (struct echoclient *)mem_malloc(sizeof(struct echoclient)); if (es != NULL) { es->state = ES_CONNECTED; es->pcb = tpcb; sprintf((char*)data, "sending tcp client message %d", (int)message_count); /* allocate pbuf */ es->p_tx = pbuf_alloc(PBUF_TRANSPORT, strlen((char*)data) , PBUF_POOL); if (es->p_tx) { /* copy data to pbuf */ pbuf_take(es->p_tx, (char*)data, strlen((char*)data)); /* pass newly allocated es structure as argument to tpcb */ tcp_arg(tpcb, es); /* initialize LwIP tcp_recv callback function */ tcp_recv(tpcb, tcp_echoclient_recv); /* initialize LwIP tcp_sent callback function */ tcp_sent(tpcb, tcp_echoclient_sent); /* initialize LwIP tcp_poll callback function */ tcp_poll(tpcb, tcp_echoclient_poll, 1); /* send data */ tcp_echoclient_send(tpcb,es); return ERR_OK; } } else { /* close connection */ tcp_echoclient_connection_close(tpcb, es); /* return memory allocation error */ return ERR_MEM; } } else { /* close connection */ tcp_echoclient_connection_close(tpcb, es); } return err; }
/* "virtual" functions calling into tcp */ static void altcp_tcp_set_poll(struct altcp_pcb *conn, u8_t interval) { if (conn != NULL) { struct tcp_pcb *pcb = (struct tcp_pcb *)conn->state; ALTCP_TCP_ASSERT_CONN(conn); tcp_poll(pcb, altcp_tcp_poll, interval); } }
void TcpConnection::close() { if (tcp == NULL) return; debugf("TCP connection closing"); tcp_poll(tcp, staticOnPoll, 1); tcp_arg(tcp, NULL); // reset pointer to close connection on next callback tcp = NULL; }
static void altcp_tcp_remove_callbacks(struct tcp_pcb *tpcb) { tcp_arg(tpcb, NULL); tcp_recv(tpcb, NULL); tcp_sent(tpcb, NULL); tcp_err(tpcb, NULL); tcp_poll(tpcb, NULL, tpcb->pollinterval); }
/** * @brief Function called when TCP connection established */ static err_t tcp_echoclient_connected(void *arg, struct tcp_pcb *tpcb, err_t err) { uint16_t length; TM_TCPCLIENT_t* client; /* Client is passed as arguments */ client = (TM_TCPCLIENT_t *)arg; if (err == ERR_OK) { /* We are connected */ client->state = CLIENT_CONNECTED; /* Get HTTP request from user */ length = TM_ETHERNETCLIENT_CreateHeadersCallback(client, (char *)data, sizeof(data)); /* Check if length = 0 */ if (length == 0) { /* Close connection */ tcp_echoclient_connection_close(client, 1); /* Return */ return ERR_CONN; } /* Allocate pbuf */ client->p_tx = pbuf_alloc(PBUF_TRANSPORT, strlen((char *)data), PBUF_POOL); /* If we have memory for buffer */ if (client->p_tx) { /* Call user function */ TM_ETHERNETCLIENT_ConnectedCallback(client); /* copy data to pbuf */ pbuf_take(client->p_tx, (char *)data, length); /* initialize LwIP tcp_recv callback function */ tcp_recv(client->pcb, tcp_echoclient_recv); /* initialize LwIP tcp_sent callback function */ tcp_sent(client->pcb, tcp_echoclient_sent); /* initialize LwIP tcp_poll callback function */ tcp_poll(client->pcb, tcp_echoclient_poll, 1); /* Set new error handler */ tcp_err(client->pcb, tcp_echoclient_error); /* send data */ tcp_echoclient_send(client); /* Return OK */ TM_Client[0] = client[0]; return ERR_OK; } } else { /* close connection */ tcp_echoclient_connection_close(client, 0); } return err; }