/** * @brief This function implements the tcp_poll callback function * @param arg: pointer on argument passed to callback * @param tpcb: tcp connection control block * @retval err_t: error code */ static err_t tcp_echoclient_poll(void *arg, struct tcp_pcb *tpcb) { err_t ret_err; struct echoclient *es; es = (struct echoclient*)arg; if (es != NULL) { if (es->p_tx != NULL) { /* there is a remaining pbuf (chain) , try to send data */ tcp_echoclient_send(tpcb, es); } else { /* no remaining pbuf (chain) */ if(es->state == ES_CLOSING) { /* close tcp connection */ tcp_echoclient_connection_close(tpcb, es); } } ret_err = ERR_OK; } else { /* nothing to be done */ tcp_abort(tpcb); ret_err = ERR_ABRT; } return ret_err; }
/** * @brief This function implements the tcp_poll callback function */ static err_t tcp_echoclient_poll(void *arg, struct tcp_pcb *tpcb) { err_t ret_err; TM_TCPCLIENT_t* client; /* Client is passed as arguments */ client = (TM_TCPCLIENT_t *)arg; /* Valid client */ if (client != NULL) { if (client->p_tx != NULL) { /* there is a remaining pbuf (chain), try to send data */ tcp_echoclient_send(client); } else { /* no remaining pbuf (chain) */ if (client->state == CLIENT_CLOSING) { /* Close tcp connection */ tcp_echoclient_connection_close(client, 1); } } ret_err = ERR_OK; } else { /* nothing to be done */ tcp_abort(tpcb); ret_err = ERR_ABRT; } return ret_err; }
/** * @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; }
/** * @brief tcp_receiv callback */ static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { struct pbuf* point_pbuf; err_t ret_err; TM_TCPCLIENT_t* client; /* Client is passed as arguments */ client = (TM_TCPCLIENT_t *)arg; /* Check all next buffers and pointers */ if (p != NULL && p->tot_len <= 1460) { /* Increase RX bytes */ TM_ETHERNET.Client_RX_Bytes += p->tot_len; for (point_pbuf = p; point_pbuf != NULL; point_pbuf = point_pbuf->next) { if (point_pbuf->len == 0) continue; /* Call user function if defined to respond to incoming data */ TM_ETHERNETCLIENT_ReceiveDataCallback(client, (uint8_t *) point_pbuf->payload, point_pbuf->len, point_pbuf->tot_len); } } /* if we receive an empty tcp frame from server => close connection */ if (p == NULL) { /* remote host closed connection */ client->state = CLIENT_CLOSING; if (client->p_tx == NULL) { /* we're done sending, close connection */ tcp_echoclient_connection_close(client, 1); } else { /* send remaining data*/ tcp_echoclient_send(client); } ret_err = ERR_OK; } else if (err != ERR_OK) {/* else : a non empty frame was received from echo server but for some reason err != ERR_OK */ /* free received pbuf*/ pbuf_free(p); ret_err = err; } else if (client->state == CLIENT_CONNECTED) { /* Acknowledge data reception */ tcp_recved(tpcb, p->tot_len); /* free pbuf and do nothing */ pbuf_free(p); //tcp_echoclient_connection_close(tpcb, es); ret_err = ERR_OK; } else {/* data received when connection already closed */ /* Acknowledge data reception */ tcp_recved(tpcb, p->tot_len); /* free pbuf and do nothing */ pbuf_free(p); ret_err = ERR_OK; } /* Return */ return ret_err; }
/** * @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; }
//用于发送数据,es由connect接口获取 void tcp_send_data(char *data,int len) { if(g_es!=NULL) { g_es->p_tx = pbuf_alloc(PBUF_TRANSPORT, len , PBUF_POOL); pbuf_take(g_es->p_tx, data, len); tcp_echoclient_send(g_es->pcb,g_es); } else printf("need connect first\n"); }
/** * @brief tcp_receiv callback * @param arg: argument to be passed to receive callback * @param tpcb: tcp connection control block * @param err: receive error code * @retval err_t: retuned error */ static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { struct echoclient *es; err_t ret_err; LWIP_ASSERT("arg != NULL",arg != NULL); es = (struct echoclient *)arg; Tcp_flag = 0; /* if we receive an empty tcp frame from server => close connection */ if (p == NULL) { /* remote host closed connection */ es->state = ES_CLOSING; if (es->p_tx == NULL) { /* we're done sending, close connection */ tcp_echoclient_connection_close(tpcb, es); } else { /* send remaining data*/ tcp_echoclient_send(tpcb, es); } ret_err = ERR_OK; } /* else : a non empty frame was received from echo server but for some reason err != ERR_OK */ else if (err != ERR_OK) { /* free received pbuf*/ if (p != NULL) { pbuf_free(p); } ret_err = err; } else if(es->state == ES_CONNECTED) { /* increment message count */ message_count++; /* Acknowledge data reception */ tcp_recved(tpcb, p->tot_len); pbuf_free(p); tcp_echoclient_connection_close(tpcb, es); ret_err = ERR_OK; } /* data received when connection already closed */ else { /* Acknowledge data reception */ tcp_recved(tpcb, p->tot_len); /* free pbuf and do nothing */ pbuf_free(p); ret_err = ERR_OK; } return ret_err; }
/** * @brief This function implements the tcp_sent LwIP callback (called when ACK * is received from remote host for sent data) */ static err_t tcp_echoclient_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) { TM_TCPCLIENT_t* client; /* Client is passed as arguments */ client = (TM_TCPCLIENT_t *)arg; if (client->p_tx != NULL) { /* still got pbufs to send */ tcp_echoclient_send(client); } return ERR_OK; }
/** * @brief This function implements the tcp_sent LwIP callback (called when ACK * is received from remote host for sent data) * @param arg: pointer on argument passed to callback * @param tcp_pcb: tcp connection control block * @param len: length of data sent * @retval err_t: returned error code */ static err_t tcp_echoclient_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) { struct echoclient *es; LWIP_UNUSED_ARG(len); es = (struct echoclient *)arg; if(es->p_tx != NULL) { /* still got pbufs to send */ tcp_echoclient_send(tpcb, es); } return ERR_OK; }
/** * @brief tcp_receiv callback * @param arg: argument to be passed to receive callback * @param tpcb: tcp connection control block * @param err: receive error code * @retval err_t: retuned error */ static err_t tcp_echoclient_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) { struct echoclient *es; err_t ret_err; int i; LWIP_ASSERT("arg != NULL",arg != NULL); es = (struct echoclient *)arg; /* if we receive an empty tcp frame from server => close connection */ if (p == NULL) { /* remote host closed connection */ es->state = ES_CLOSING; g_net_state = ES_CLOSING; if(es->p_tx == NULL) { /* we're done sending, close connection */ tcp_echoclient_connection_close(tpcb, es); } else { /* send remaining data*/ tcp_echoclient_send(tpcb, es); } ret_err = ERR_OK; } /* else : a non empty frame was received from echo server but for some reason err != ERR_OK */ else if(err != ERR_OK) { /* free received pbuf*/ pbuf_free(p); ret_err = err; } else if(es->state == ES_CONNECTED) { /* increment message count */ //message_count++; /* Acknowledge data reception */ tcp_recved(tpcb, p->tot_len); memcpy(recev_buf,p->payload,p->tot_len); for(i=0;i<p->tot_len;i++) printf("%c",recev_buf[i]); if(g_net_state==1) { sprintf((char*)data, "sending tcp client message %d\r\n",cnt++); tcp_send_data(data,strlen(data)); } pbuf_free(p); //tcp_echoclient_connection_close(tpcb, es); ret_err = ERR_OK; } /* data received when connection already closed */ else { /* Acknowledge data reception */ tcp_recved(tpcb, p->tot_len); /* free pbuf and do nothing */ pbuf_free(p); ret_err = ERR_OK; } return ret_err; }