static err_t conn_poll(void *arg, tcp_pcb *pcb) { ConnectionState *cs = (ConnectionState*)arg; if (cs == sendingConnection) { // Data could not be sent last time, check if the connection has to be timed out sendingRetries++; if (sendingRetries == TCP_MAX_SEND_RETRIES) { reprap.GetPlatform().MessageF(UsbMessage, "Network: Could not transmit data after %.1f seconds\n", (double)((float)TCP_WRITE_TIMEOUT / 1000.0)); tcp_abort(pcb); return ERR_ABRT; } // Try to write the remaining data once again (if required) if (writeResult != ERR_OK) { writeResult = tcp_write(pcb, sendingWindow + (sendingWindowSize - sentDataOutstanding), sentDataOutstanding, 0); if (ERR_IS_FATAL(writeResult)) { reprap.GetPlatform().MessageF(UsbMessage, "Network: Failed to write data in conn_poll (code %d)\n", writeResult); tcp_abort(pcb); return ERR_ABRT; } if (writeResult != ERR_OK && reprap.Debug(moduleNetwork)) { reprap.GetPlatform().MessageF(UsbMessage, "Network: tcp_write resulted in error code %d\n", writeResult); } } // If that worked, try to output the remaining data (if required) if (outputResult != ERR_OK) { outputResult = tcp_output(pcb); if (ERR_IS_FATAL(outputResult)) { reprap.GetPlatform().MessageF(UsbMessage, "Network: Failed to output data in conn_poll (code %d)\n", outputResult); tcp_abort(pcb); return ERR_ABRT; } if (outputResult != ERR_OK && reprap.Debug(moduleNetwork)) { reprap.GetPlatform().MessageF(UsbMessage, "Network: tcp_output resulted in error code %d\n", outputResult); } } } else { reprap.GetPlatform().Message(UsbMessage, "Network: Mismatched pcb in conn_poll!\n"); } return ERR_OK; }
/** * Bind a pcb contained in a netconn * Called from netconn_bind. * * @param msg the api_msg_msg pointing to the connection and containing * the IP address and port to bind to */ void do_bind(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_VAL; if (msg->conn->pcb.tcp != NULL) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: msg->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: msg->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: msg->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); break; #endif /* LWIP_TCP */ default: break; } } } TCPIP_APIMSG_ACK(msg); }
/** * Join multicast groups for UDP netconns. * Called from netconn_join_leave_group * * @param msg the api_msg_msg pointing to the connection */ void do_join_leave_group(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { #if LWIP_UDP if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { msg->err = igmp_joingroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); } else { msg->err = igmp_leavegroup(msg->msg.jl.netif_addr, msg->msg.jl.multiaddr); } #endif /* LWIP_UDP */ #if (LWIP_TCP || LWIP_RAW) } else { msg->err = ERR_VAL; #endif /* (LWIP_TCP || LWIP_RAW) */ } } else { msg->err = ERR_CONN; } } TCPIP_APIMSG_ACK(msg); }
/** * Send some data on a RAW or UDP pcb contained in a netconn * Called from netconn_send * * @param msg the api_msg_msg pointing to the connection */ void do_send(struct api_msg_msg *msg) { if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: if (msg->msg.b->addr == NULL) { msg->conn->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); } else { msg->conn->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, msg->msg.b->addr); } break; #endif #if LWIP_UDP case NETCONN_UDP: if (msg->msg.b->addr == NULL) { msg->conn->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); } else { msg->conn->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->addr, msg->msg.b->port); } break; #endif /* LWIP_UDP */ default: break; } } } TCPIP_APIMSG_ACK(msg); }
/** * Send some data on a TCP pcb contained in a netconn * Called from netconn_write * * @param msg the api_msg_msg pointing to the connection */ void do_write(struct api_msg_msg *msg) { if (!ERR_IS_FATAL(msg->conn->err)) { if ((msg->conn->pcb.tcp != NULL) && (msg->conn->type == NETCONN_TCP)) { #if LWIP_TCP msg->conn->state = NETCONN_WRITE; /* set all the variables used by do_writemore */ LWIP_ASSERT("already writing", msg->conn->write_msg == NULL && msg->conn->write_offset == 0); msg->conn->write_msg = msg; msg->conn->write_offset = 0; #if LWIP_TCPIP_CORE_LOCKING msg->conn->write_delayed = 0; if (do_writemore(msg->conn) != ERR_OK) { LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); UNLOCK_TCPIP_CORE(); sys_arch_sem_wait(msg->conn->op_completed, 0); LOCK_TCPIP_CORE(); LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); } #else do_writemore(msg->conn); #endif /* for both cases: if do_writemore was called, don't ACK the APIMSG! */ return; #endif /* LWIP_TCP */ #if (LWIP_UDP || LWIP_RAW) } else { msg->conn->err = ERR_VAL; #endif /* (LWIP_UDP || LWIP_RAW) */ } } TCPIP_APIMSG_ACK(msg); }
/** * Set a TCP pcb contained in a netconn into listen mode * Called from netconn_listen. * * @param msg the api_msg_msg pointing to the connection */ void lwip_netconn_do_listen(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_CONN; if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { if (msg->conn->state == NETCONN_NONE) { struct tcp_pcb* lpcb; #if LWIP_IPV6 if ((msg->conn->flags & NETCONN_FLAG_IPV6_V6ONLY) == 0) { #if TCP_LISTEN_BACKLOG lpcb = tcp_listen_dual_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ lpcb = tcp_listen_dual(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ } else #endif /* LWIP_IPV6 */ { #if TCP_LISTEN_BACKLOG lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ lpcb = tcp_listen(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ } if (lpcb == NULL) { /* in this case, the old pcb is still allocated */ msg->err = ERR_MEM; } else { /* delete the recvmbox and allocate the acceptmbox */ if (sys_mbox_valid(&msg->conn->recvmbox)) { /** @todo: should we drain the recvmbox here? */ sys_mbox_free(&msg->conn->recvmbox); sys_mbox_set_invalid(&msg->conn->recvmbox); } msg->err = ERR_OK; if (!sys_mbox_valid(&msg->conn->acceptmbox)) { msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); } if (msg->err == ERR_OK) { msg->conn->state = NETCONN_LISTEN; msg->conn->pcb.tcp = lpcb; tcp_arg(msg->conn->pcb.tcp, msg->conn); tcp_accept(msg->conn->pcb.tcp, accept_function); } else { /* since the old pcb is already deallocated, free lpcb now */ tcp_close(lpcb); msg->conn->pcb.tcp = NULL; } } } } else { msg->err = ERR_ARG; } } } TCPIP_APIMSG_ACK(msg); }
/** * Send data on a TCP pcb */ static void net_do_write(void *ctx) { struct tls_net_msg *net_msg = (struct tls_net_msg *)ctx; struct tls_netconn *conn = net_msg->conn; struct tls_netconn *server_conn = NULL; //TLS_DBGPRT_INFO("s=%d,p=0x%x\n", conn->state, conn->pcb.tcp); #if 0 if (ERR_IS_FATAL(conn->last_err)) { net_msg->err = conn->last_err; } #endif if (conn->proto == TLS_NETCONN_TCP) { #if LWIP_TCP if (conn->state != NETCONN_STATE_CONNECTED) { /* netconn is connecting, closing or in blocking write */ net_msg->err = ERR_INPROGRESS; } else if (conn->pcb.tcp != NULL) { conn->write_state = true; //conn->write_offset = 0; net_msg->err = net_skt_tcp_send(net_msg); /* for both cases: if do_writemore was called, don't ACK the APIMSG since do_writemore ACKs it! */ } else { net_msg->err = ERR_CONN; TLS_DBGPRT_INFO("==>err=%d\n", net_msg->err); } if(conn->client && conn->idle_time > 0) { TLS_DBGPRT_INFO("conn->skt_num=%d, conn->client=%d\n", conn->skt_num, conn->client); // server_conn = dl_list_first(&conn->list, struct tls_netconn, list); server_conn = get_server_conn(conn); TLS_DBGPRT_INFO("server_conn=%p\n", server_conn); if(server_conn) { conn->idle_time = server_conn->idle_time; TLS_DBGPRT_INFO("update conn->idle_time %d\n", conn->idle_time); } } #else /* LWIP_TCP */ net_msg->err = ERR_VAL; #endif /* LWIP_TCP */ #if (LWIP_UDP || LWIP_RAW) } else { net_msg->err = ERR_VAL; #endif /* (LWIP_UDP || LWIP_RAW) */ } //tls_mem_free(net_msg->dataptr); //if(net_msg->err != ERR_OK) { //TLS_DBGPRT_INFO("conn->proto=%d, err=%d\n", conn->proto, net_msg->err); //TLS_DBGPRT_INFO("free net_msg->dataptr=%p\n", net_msg->dataptr); sys_sem_signal(conn->op_completed); } #if 0 tls_mem_free(net_msg); #endif }
/** * Bind a pcb contained in a netconn * Called from netconn_bind. * * @param msg the api_msg_msg pointing to the connection and containing * the IP address and port to bind to */ void do_bind(struct api_msg_msg *msg) { if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { //[MS_CHANGE] - make sure we are binding to a valid address u8_t validAddr = ip_addr_isany(msg->msg.bc.ipaddr); if(!validAddr) { struct netif *netif; for(netif = netif_list; netif != NULL; netif = netif->next) { /* network mask matches? */ if (netif_is_up(netif)) { if(ip_addr_cmp(msg->msg.bc.ipaddr, &netif->ip_addr)) { validAddr = 1; break; } } } } //[MS_CHANGE] - make sure we are binding to a valid address if(validAddr) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: msg->conn->err = raw_bind(msg->conn->pcb.raw, msg->msg.bc.ipaddr); break; #endif /* LWIP_RAW */ #if LWIP_UDP case NETCONN_UDP: msg->conn->err = udp_bind(msg->conn->pcb.udp, msg->msg.bc.ipaddr, msg->msg.bc.port); break; #endif /* LWIP_UDP */ #if LWIP_TCP case NETCONN_TCP: msg->conn->err = tcp_bind(msg->conn->pcb.tcp, msg->msg.bc.ipaddr, msg->msg.bc.port); break; #endif /* LWIP_TCP */ default: break; } } else { msg->conn->err = ERR_VAL; } } else { /* msg->conn->pcb is NULL */ msg->conn->err = ERR_VAL; } } TCPIP_APIMSG_ACK(msg); }
/** * Send some data on a TCP pcb contained in a netconn * Called from netconn_write * * @param msg the api_msg_msg pointing to the connection */ void do_write(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { if (msg->conn->type == NETCONN_TCP) { #if LWIP_TCP if (msg->conn->state != NETCONN_NONE) { /* netconn is connecting, closing or in blocking write */ msg->err = ERR_INPROGRESS; } else if (msg->conn->pcb.tcp != NULL) { msg->conn->state = NETCONN_WRITE; /* set all the variables used by do_writemore */ LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && msg->conn->write_offset == 0); LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); msg->conn->current_msg = msg; msg->conn->write_offset = 0; #if LWIP_TCPIP_CORE_LOCKING msg->conn->flags &= ~NETCONN_FLAG_WRITE_DELAYED; if (do_writemore(msg->conn) != ERR_OK) { LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); UNLOCK_TCPIP_CORE(); sys_arch_sem_wait(&msg->conn->op_completed, 0); LOCK_TCPIP_CORE(); LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); } #else /* LWIP_TCPIP_CORE_LOCKING */ do_writemore(msg->conn); #endif /* LWIP_TCPIP_CORE_LOCKING */ /* for both cases: if do_writemore was called, don't ACK the APIMSG since do_writemore ACKs it! */ return; } else { msg->err = ERR_CONN; } #else /* LWIP_TCP */ msg->err = ERR_VAL; #endif /* LWIP_TCP */ #if (LWIP_UDP || LWIP_RAW) } else { msg->err = ERR_VAL; #endif /* (LWIP_UDP || LWIP_RAW) */ } } TCPIP_APIMSG_ACK(msg); }
/** * Send some data on a RAW or UDP pcb contained in a netconn * Called from netconn_send * * @param msg the api_msg_msg pointing to the connection */ void do_send(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { msg->err = ERR_CONN; if (msg->conn->pcb.tcp != NULL) { switch (NETCONNTYPE_GROUP(msg->conn->type)) { #if LWIP_RAW case NETCONN_RAW: if (ip_addr_isany(&msg->msg.b->addr)) { msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); } else { msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); } break; #endif #if LWIP_UDP case NETCONN_UDP: #if LWIP_CHECKSUM_ON_COPY if (ip_addr_isany(&msg->msg.b->addr)) { msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); } else { msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port, msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); } #else /* LWIP_CHECKSUM_ON_COPY */ if (ip_addr_isany(&msg->msg.b->addr)) { msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); } else { msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); } #endif /* LWIP_CHECKSUM_ON_COPY */ break; #endif /* LWIP_UDP */ default: break; } } } TCPIP_APIMSG_ACK(msg); }
/** * Join multicast groups for UDP netconns. * Called from netconn_join_leave_group * * @param msg the api_msg_msg pointing to the connection */ void lwip_netconn_do_join_leave_group(struct api_msg_msg *msg) { if (ERR_IS_FATAL(msg->conn->last_err)) { msg->err = msg->conn->last_err; } else { if (msg->conn->pcb.tcp != NULL) { if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { #if LWIP_UDP #if LWIP_IPV6 && LWIP_IPV6_MLD if (PCB_ISIPV6(msg->conn->pcb.udp)) { if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { msg->err = mld6_joingroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); } else { msg->err = mld6_leavegroup(ipX_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); } } else #endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ { #if LWIP_IGMP if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { msg->err = igmp_joingroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); } else { msg->err = igmp_leavegroup(ipX_2_ip(API_EXPR_REF(msg->msg.jl.netif_addr)), ipX_2_ip(API_EXPR_REF(msg->msg.jl.multiaddr))); } #endif /* LWIP_IGMP */ } #endif /* LWIP_UDP */ #if (LWIP_TCP || LWIP_RAW) } else { msg->err = ERR_VAL; #endif /* (LWIP_TCP || LWIP_RAW) */ } } else { msg->err = ERR_CONN; } } TCPIP_APIMSG_ACK(msg); }
/** * Set a TCP pcb contained in a netconn into listen mode * Called from netconn_listen. * * @param msg the api_msg_msg pointing to the connection */ void do_listen(struct api_msg_msg *msg) { #if LWIP_TCP if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { if (msg->conn->type == NETCONN_TCP) { if (msg->conn->pcb.tcp->state == CLOSED) { #if TCP_LISTEN_BACKLOG struct tcp_pcb* lpcb = tcp_listen_with_backlog(msg->conn->pcb.tcp, msg->msg.lb.backlog); #else /* TCP_LISTEN_BACKLOG */ struct tcp_pcb* lpcb = tcp_listen(msg->conn->pcb.tcp); #endif /* TCP_LISTEN_BACKLOG */ if (lpcb == NULL) { msg->conn->err = ERR_MEM; } else { /* delete the recvmbox and allocate the acceptmbox */ if (msg->conn->recvmbox != SYS_MBOX_NULL) { /** @todo: should we drain the recvmbox here? */ sys_mbox_free(msg->conn->recvmbox); msg->conn->recvmbox = SYS_MBOX_NULL; } if (msg->conn->acceptmbox == SYS_MBOX_NULL) { if ((msg->conn->acceptmbox = sys_mbox_new(DEFAULT_ACCEPTMBOX_SIZE)) == SYS_MBOX_NULL) { msg->conn->err = ERR_MEM; } } if (msg->conn->err == ERR_OK) { msg->conn->state = NETCONN_LISTEN; msg->conn->pcb.tcp = lpcb; tcp_arg(msg->conn->pcb.tcp, msg->conn); tcp_accept(msg->conn->pcb.tcp, accept_function); } } } else { msg->conn->err = ERR_CONN; } } } } #endif /* LWIP_TCP */ TCPIP_APIMSG_ACK(msg); }
/** * Indicate data has been received from a TCP pcb contained in a netconn * Called from netconn_recv * * @param msg the api_msg_msg pointing to the connection */ void do_recv(struct api_msg_msg *msg) { #if LWIP_TCP if (!ERR_IS_FATAL(msg->conn->err)) { if (msg->conn->pcb.tcp != NULL) { if (msg->conn->type == NETCONN_TCP) { #if TCP_LISTEN_BACKLOG if (msg->conn->pcb.tcp->state == LISTEN) { tcp_accepted(msg->conn->pcb.tcp); } else #endif /* TCP_LISTEN_BACKLOG */ { tcp_recved(msg->conn->pcb.tcp, msg->msg.r.len); } } } } #endif /* LWIP_TCP */ TCPIP_APIMSG_ACK(msg); }
// Send exactly one TCP window of data and return true when this transaction can be released bool NetworkTransaction::Send() { // Free up this transaction if the connection is supposed to be closed if (closeRequested) { reprap.GetNetwork().ConnectionClosed(cs, true); // This will release the transaction too return false; } // Fill up the TCP window with some data chunks from our OutputBuffer instances size_t bytesBeingSent = 0, bytesLeftToSend = TCP_WND; while (sendBuffer != nullptr && bytesLeftToSend > 0) { size_t copyLength = min<size_t>(bytesLeftToSend, sendBuffer->BytesLeft()); memcpy(sendingWindow + bytesBeingSent, sendBuffer->Read(copyLength), copyLength); bytesBeingSent += copyLength; bytesLeftToSend -= copyLength; if (sendBuffer->BytesLeft() == 0) { sendBuffer = OutputBuffer::Release(sendBuffer); if (sendBuffer == nullptr) { sendBuffer = sendStack->Pop(); } } } // We also intend to send a file, so check if we can fill up the TCP window if (sendBuffer == nullptr && bytesLeftToSend != 0 && fileBeingSent != nullptr) { // For HSMCI efficiency, read from the file in multiples of 4 bytes except at the end. // This ensures that the second and subsequent chunks can be DMA'd directly into sendingWindow. size_t bytesToRead = bytesLeftToSend & (~3); if (bytesToRead != 0) { int bytesRead = fileBeingSent->Read(sendingWindow + bytesBeingSent, bytesToRead); if (bytesRead > 0) { bytesBeingSent += bytesRead; } if (bytesRead != (int)bytesToRead) { fileBeingSent->Close(); fileBeingSent = nullptr; } } } if (bytesBeingSent == 0) { // If we have no data to send, this connection can be closed next time if (!cs->persistConnection && nextWrite == nullptr) { Close(); return false; } // We want to send data from another transaction as well, so only free up this one cs->sendingTransaction = nextWrite; return true; } // The TCP window has been filled up as much as possible, so send it now. There is no need to check // the available space in the SNDBUF queue, because we really write only one TCP window at once. writeResult = tcp_write(cs->pcb, sendingWindow, bytesBeingSent, 0); if (ERR_IS_FATAL(writeResult)) { reprap.GetPlatform().MessageF(UsbMessage, "Network: Failed to write data in Send (code %d)\n", writeResult); tcp_abort(cs->pcb); return false; } outputResult = tcp_output(cs->pcb); if (ERR_IS_FATAL(outputResult)) { reprap.GetPlatform().MessageF(UsbMessage, "Network: Failed to output data in Send (code %d)\n", outputResult); tcp_abort(cs->pcb); return false; } if (outputResult != ERR_OK && reprap.Debug(moduleNetwork)) { reprap.GetPlatform().MessageF(UsbMessage, "Network: tcp_output resulted in error code %d\n", outputResult); } // Set LwIP callbacks for ACK and retransmission handling tcp_poll(cs->pcb, conn_poll, TCP_WRITE_TIMEOUT / TCP_SLOW_INTERVAL / TCP_MAX_SEND_RETRIES); tcp_sent(cs->pcb, conn_sent); // Set all values for the send process sendingConnection = cs; sendingRetries = 0; sendingWindowSize = sentDataOutstanding = bytesBeingSent; return false; }
void wanwuyun_task(void * pvParameters) { //创建Queue SENSOR_STRUCT *pRxSensorFrame; portBASE_TYPE xStatus; struct ip_addr WanWuYunIPaddr; static err_t err,recv_err; //网络相关结构体 struct netbuf *inbuf; uint8_t *buf; uint16_t buflen; //成功发送 = true,其他状态为 = false bool wan_send_success_flag = false; //创建Json的结构体 cJSON *DataUpReqJson, *RowJson, *DataUpResJson,*fld; char *DataOut; char double_string[]={0}; #if 0 cJSON *SignInReqJson ,*SignInResJson; SignInReqJson=cJSON_CreateObject(); cJSON_AddStringToObject(SignInReqJson, "username", "jackeyjiang"); cJSON_AddStringToObject(SignInReqJson, "accessid", "AMFJA2V5AMLHBMCXNDI5NZE2NDIXMTMW"); cJSON_AddStringToObject(SignInReqJson, "appid", "9785739981"); cJSON_AddStringToObject(SignInReqJson, "dev_id", "stm32_test"); DataOut = cJSON_Print(DataUpReqJson); cJSON_Delete(SignInReqJson); vPortFree(DataOut); DataUpReqJson=cJSON_CreateArray(); cJSON_AddItemToObject(DataUpReqJson,NULL,fld = cJSON_CreateObject()); cJSON_AddStringToObject(fld, "seckey", "HgqoOLTlav5jTsefyj3nL5AkRu8UAFRf"); cJSON_AddItemToObject(fld, "row", RowJson=cJSON_CreateObject()); cJSON_AddStringToObject(RowJson, "DEV_ID", "stm32_test"); cJSON_AddNumberToObject(RowJson, "TEMPERATURE", 12.5); cJSON_AddNumberToObject(RowJson, "LATITUDE", 12.7); cJSON_AddNumberToObject(RowJson, "LONGITUDE", 12.8); //转换数据为cJSON数据 DataOut = cJSON_Print(DataUpReqJson); cJSON_Delete(DataUpReqJson); printf("%s",DataOut); vPortFree(DataOut); //解析返回的Json数据 SignInResJson = cJSON_Parse(SignInResponse); if (!SignInResJson) vPrintString("Error before: [%s]\n",cJSON_GetErrorPtr()); else {}; DataUpResJson = cJSON_Parse(DataUpResponse); if (!DataUpResJson) vPrintString("Error before: [%s]\n",cJSON_GetErrorPtr()); else {}; #endif //创建传感器队列 pRxSensor_xQueue = xQueueCreate( 2, sizeof( struct _SENSOR_STRUCT * ) ); //建立短连接,接收到队列传过来的数据,将其打包成json数据传送到万物云。 IP4_ADDR( &WanWuYunIPaddr, WANWUYUN_IP_ADDR0, WANWUYUN_IP_ADDR1, WANWUYUN_IP_ADDR2, WANWUYUN_IP_ADDR3 ); while(1) { /* Create a new connection identifier. */ STM_EVAL_LEDOff(LED2); wanwuyun_clientconn = netconn_new_with_callback(NETCONN_TCP,wanwuyun_callback); //测试 if (wanwuyun_clientconn!=NULL) { /*built a connect to wanwuyun.com server*/ //netconn_set_nonblocking(wanwuyun_clientconn, 1); //测试 err = netconn_connect(wanwuyun_clientconn,&WanWuYunIPaddr,WANWUYUN_SERVER_PORT); if (err != ERR_OK) netconn_delete(wanwuyun_clientconn); else if (err == ERR_OK) { STM_EVAL_LEDOn(LED2); vPrintString("netconn_connect wanwuyun_clientconn\r\n"); /*timeout to wait for new data to be received <Avoid death etc.> */ netconn_set_sendtimeout(wanwuyun_clientconn,300); netconn_set_recvtimeout(wanwuyun_clientconn,700); while(!ERR_IS_FATAL(wanwuyun_clientconn->last_err)) { STM_EVAL_LEDToggle(LED3); xStatus = xQueueReceive(pRxSensor_xQueue,&(pRxSensorFrame),( portTickType ) 1 ); if(xStatus == pdPASS) { //提取结构体中的数据 DataUpReqJson=cJSON_CreateArray(); cJSON_AddItemToObject(DataUpReqJson,NULL,fld = cJSON_CreateObject()); cJSON_AddStringToObject(fld, "seckey", "HgqoOLTlav5jTsefyj3nL5AkRu8UAFRf"); cJSON_AddItemToObject(fld, "row", RowJson=cJSON_CreateObject()); cJSON_AddStringToObject(RowJson, "DEV_ID", "stm32_test"); sprintf(double_string,"%f",pRxSensorFrame->temperature[0]); cJSON_AddStringToObject(RowJson, "TEMPERATURE", double_string); sprintf(double_string,"%f",pRxSensorFrame->latitude[0]); cJSON_AddStringToObject(RowJson, "LATITUDE", double_string); sprintf(double_string,"%f",pRxSensorFrame->longitude[0]); cJSON_AddStringToObject(RowJson, "LONGITUDE", double_string); //转换数据为cJSON数据 DataOut = cJSON_Print(DataUpReqJson); //printf("%d",strlen(DataOut)); cJSON_Delete(DataUpReqJson); vPrintString("%s\r\n",DataOut); //vPortFree(DataOut); err=netconn_write(wanwuyun_clientconn,\ DataOut,strlen(DataOut),\ NETCONN_COPY); if(err != ERR_OK) { vPortFree(DataOut); vPrintString("StatuUploadReq erro code is %d\r\n",err); break; } else { wan_send_success_flag = true; //表示数据已经发送了 vPortFree(DataOut); } } //netconn_recved(wanwuyun_clientconn,100); //测试 recv_err = netconn_recv(wanwuyun_clientconn, &inbuf); if (recv_err == ERR_OK) { if (netconn_err(wanwuyun_clientconn) == ERR_OK) { netbuf_data(inbuf, (void**)&buf, &buflen); DataUpResJson = cJSON_Parse((char *)buf); DataOut = cJSON_Print(DataUpResJson); vPrintString("%s\r\n",DataOut); netbuf_delete(inbuf); wan_send_success_flag = false; //使用短链接,成功后跳出while(1) //break; } else { vPrintString("recv_err != ERR_OK \r\n"); } } #if 1 //测试当断开连接的时候的状态 else if((recv_err == ERR_TIMEOUT)&&(wan_send_success_flag == true)) { wan_send_success_flag = false; vPrintString("recv_err == %d\r\n",recv_err); netconn_close(wanwuyun_clientconn); netbuf_delete(inbuf); netconn_delete(wanwuyun_clientconn); //为发送的数据重新入队 xQueueSendToFront(pRxSensor_xQueue,&(pRxSensorFrame),( portTickType )1); break; } #endif } } } } }