/*-----------------------------------------------------------------------------------*/ static void tcpecho_thread(void *arg) { struct netconn *conn, *newconn; err_t err; LWIP_UNUSED_ARG(arg); /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); /* Bind connection to well known port number 7. */ netconn_bind(conn, NULL, 7); /* Tell connection to go into listening mode. */ netconn_listen(conn); memset(data, 'F', DATA_SIZE); while (1) { /* Grab new connection. */ err = netconn_accept(conn, &newconn); /*printf("accepted new connection %p\n", newconn);*/ /* Process the new connection. */ if (err == ERR_OK) { err = netconn_write(newconn, data, DATA_SIZE, NETCONN_COPY); if (err != ERR_OK) { printf("tcpecho: netconn_write: error \"%s\"\n", lwip_strerr(err)); } netconn_close(newconn); netconn_delete(newconn); } } }
int TcpConnection::write(const char* data, int len, uint8_t apiflags /* = 0*/) { int original = len; err_t err; do { err = tcp_write(tcp, data, len, apiflags); if (err == ERR_MEM) { if ((tcp_sndbuf(tcp) == 0) || (tcp_sndqueuelen(tcp) >= TCP_SND_QUEUELEN)) { /* no need to try smaller sizes */ len = 1; } else { len /= 2; } } } while ((err == ERR_MEM) && (len > 1)); if (err == ERR_OK) { debugf("TCP connection send: %d (%d)", len, original); return len; } else { debugf("TCP connection failed with err %d (\"%s\")", err, lwip_strerr(err)); return -1; } }
static void ftpd_dataerr(void *arg, err_t err) { struct ftpd_datastate *fsd = arg; dbg_printf("ftpd_dataerr: %s (%i)\n", lwip_strerr(err), err); if (fsd == NULL) return; fsd->msgfs->datafs = NULL; fsd->msgfs->state = FTPD_IDLE; free(fsd); }
/** * The pcb had an error and is already deallocated. * The argument might still be valid (if != NULL). */ static void http_err(void *arg, err_t err) { struct http_state *hs = arg; LWIP_UNUSED_ARG(err); LWIP_DEBUGF(HTTPD_DEBUG, ("http_err: %s", lwip_strerr(err))); if (hs != NULL) { http_state_free(hs); } }
int TftpClient::connect(char *host, u16_t port) { if(connected == true){ error(lwip_strerr(ERR_ISCONN), false); } ipaddr_aton(host, &rem_host); rem_port = port; return 0; }
/** * The PCB had an error and is already deallocated. */ static void server_tcp_err(void* arg, err_t err) { struct server_tcp_state* ss = (struct server_tcp_state*)arg; LWIP_UNUSED_ARG(err); /* We are now most definitely disconnected */ ss->connected = DISCONNECTED; if (ss->pcb != NULL) { server_tcp_close_conn(ss->pcb, ss); } LWIP_DEBUGF(SERVER_TCP_DEBUG, ("server_tcp_err: %s", lwip_strerr(err))); }
/** * Try to send more data on this pcb. */ static void http_send_data(struct tcp_pcb *pcb, struct http_state *hs) { err_t err; u16_t len; u16_t snd_buf; LWIP_DEBUGF(HTTPD_DEBUG, ("http_send_data: pcb=0x%08X hs=0x%08X left=%d\n", pcb, hs, hs != NULL ? hs->left : 0)); if ((hs == NULL) || (hs->left == 0)) { /* Already closed or nothing more to send; be robust: close */ http_close_conn(pcb, hs); return; } /* We cannot send more data than space available in the send buffer. */ snd_buf = tcp_sndbuf(pcb); len = LWIP_MIN(snd_buf, hs->left); if (hs->left <= snd_buf) { LWIP_ASSERT((len == hs->left), "hs->left did not fit into u16_t!"); } #if HTTPD_USE_MAX_SEND_LIMIT /* upper send limit */ if (len > HTTPD_MAX_SEND_LIMIT(hs)) { len = HTTPD_MAX_SEND_LIMIT(hs); } #endif /* HTTPD_USE_MAX_SEND_LIMIT */ do { err = tcp_write(pcb, hs->file, len, HTTPD_FILE_IS_VOLATILE(hs)); LWIP_DEBUGF(HTTPD_DEBUG, ("http_send_data: tcp_write(%d) -> %s\n", len, lwip_strerr(err))); if (err == ERR_MEM) { len /= 2; } } while ((err == ERR_MEM) && (len > 1)); if (err == ERR_OK) { hs->file += len; LWIP_ASSERT((hs->left >= len), "hs->left >= len"); hs->left -= len; } if (hs->left <= 0) { LWIP_DEBUGF(HTTPD_DEBUG, ("http_send_data: file finished, closing\n")); http_close_conn(pcb, hs); } }
/** * Initialize the httpd: set up a listening PCB and bind it to the defined port */ void httpd_init(void) { struct tcp_pcb *pcb; err_t err; pcb = tcp_new(); LWIP_ASSERT(("httpd_init: tcp_new failed"), pcb != NULL); err = tcp_bind(pcb, IP_ADDR_ANY, HTTPD_SERVER_PORT); LWIP_ASSERT(("httpd_init: tcp_bind failed: %s", lwip_strerr(err)), err == ERR_OK); pcb = tcp_listen(pcb); LWIP_ASSERT(("httpd_init: tcp_listen failed"), pcb != NULL); /* initialize callback arg and accept callback */ tcp_arg(pcb, pcb); tcp_accept(pcb, http_accept); }
/*-----------------------------------------------------------------------------------*/ static void tcpecho_thread(void *arg) { struct netconn *conn, *newconn; err_t err; LWIP_UNUSED_ARG(arg); /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); /* Bind connection to well known port number TCP_ECHO_PORT. */ netconn_bind(conn, IP_ADDR_ANY, TCP_ECHO_PORT); /* Tell connection to go into listening mode. */ netconn_listen(conn); while (1) { /* Grab new connection. */ newconn = netconn_accept(conn); printf("accepted new connection %p\n", newconn); /* Process the new connection. */ if (newconn != NULL) { struct netbuf *buf; void *data; u16_t len; while ((buf = netconn_recv(newconn)) != NULL) { printf("Recved\n"); do { netbuf_data(buf, &data, &len); err = netconn_write(newconn, data, len, NETCONN_COPY); #if 0 if (err != ERR_OK) { printf("tcpecho: netconn_write: error \"%s\"\n", lwip_strerr(err)); } #endif } while (netbuf_next(buf) >= 0); netbuf_delete(buf); } printf("Got EOF, looping\n"); /* Close connection and discard connection identifier. */ netconn_close(newconn); netconn_delete(newconn); } } }
static void ftpd_msgerr(void *arg, err_t err) { struct ftpd_msgstate *fsm = arg; dbg_printf("ftpd_msgerr: %s (%i)\n", lwip_strerr(err), err); if (fsm == NULL) return; if (fsm->datafs) ftpd_dataclose(fsm->datapcb, fsm->datafs); sfifo_close(&fsm->fifo); vfs_close(fsm->vfs); fsm->vfs = NULL; if (fsm->renamefrom) free(fsm->renamefrom); fsm->renamefrom = NULL; free(fsm); }
/** * Data has been received on this pcb. * For HTTP 1.0, this should normally only happen once (if the request fits in one packet). */ static err_t http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) { err_t parsed = ERR_ABRT; struct http_state *hs = arg; LWIP_DEBUGF(HTTPD_DEBUG, ("http_recv: pcb=0x%08X pbuf=0x%08X err=%s\n", pcb, p, lwip_strerr(err))); if (p != NULL) { /* Inform TCP that we have taken the data. */ tcp_recved(pcb, p->tot_len); } if (hs == NULL) { /* be robust */ LWIP_DEBUGF(HTTPD_DEBUG, ("Error, http_recv: hs is NULL, abort\n")); http_close_conn(pcb, hs); return ERR_OK; } if ((err != ERR_OK) || (p == NULL)) { /* error or closed by other side */ if (p != NULL) { pbuf_free(p); } http_close_conn(pcb, hs); return ERR_OK; } if (hs->file == NULL) { parsed = http_parse_request(p, hs); } else { LWIP_DEBUGF(HTTPD_DEBUG, ("http_recv: already sending data\n")); } pbuf_free(p); if (parsed == ERR_OK) { LWIP_DEBUGF(HTTPD_DEBUG, ("http_recv: data %p len %ld\n", hs->file, hs->left)); http_send_data(pcb, hs); } else if (parsed == ERR_ABRT) { http_close_conn(pcb, hs); return ERR_OK; } return ERR_OK; }
/****************************************************************************** * FunctionName : espconn_client_connect * Description : A new incoming connection has been connected. * Parameters : arg -- Additional argument to pass to the callback function * tpcb -- The connection pcb which is connected * err -- An unused error code, always ERR_OK currently * Returns : connection result *******************************************************************************/ static err_t ICACHE_FLASH_ATTR espconn_client_connect(void *arg, struct tcp_pcb *tpcb, err_t err) { espconn_msg *pcon = arg; espconn_printf("espconn_client_connect pcon %p tpcb %p\n", pcon, tpcb); if (err == ERR_OK){ /*Reserve the remote information for current active connection*/ pcon->pespconn->state = ESPCONN_CONNECT; pcon->pcommon.err = err; pcon->pcommon.pcb = tpcb; pcon->pcommon.local_port = tpcb->local_port; pcon->pcommon.local_ip = tpcb->local_ip.u_addr.ip4.addr; pcon->pcommon.remote_port = tpcb->remote_port; pcon->pcommon.remote_ip[0] = ip4_addr1_16(&tpcb->remote_ip.u_addr.ip4); pcon->pcommon.remote_ip[1] = ip4_addr2_16(&tpcb->remote_ip.u_addr.ip4); pcon->pcommon.remote_ip[2] = ip4_addr3_16(&tpcb->remote_ip.u_addr.ip4); pcon->pcommon.remote_ip[3] = ip4_addr4_16(&tpcb->remote_ip.u_addr.ip4); pcon->pcommon.write_flag = true; tcp_arg(tpcb, (void *) pcon); /*Set the specify function that should be called * when TCP data has been successfully delivered, * when active connection receives data*/ tcp_sent(tpcb, espconn_client_sent); tcp_recv(tpcb, espconn_client_recv); /*Disable Nagle algorithm default*/ tcp_nagle_disable(tpcb); /*Default set the total number of espconn_buf on the unsent lists for one*/ espconn_tcp_set_buf_count(pcon->pespconn, 1); if (pcon->pespconn->proto.tcp->connect_callback != NULL) { pcon->pespconn->proto.tcp->connect_callback(pcon->pespconn); } /*Enable keep alive option*/ if (espconn_keepalive_disabled(pcon)) espconn_keepalive_enable(tpcb); } else{ printf("err in host connected (%s)\n",lwip_strerr(err)); } return err; }
int TftpClient::get(char *rem_file, char *loc_file) { struct udp_pcb * pcb = udp_new(); err = udp_bind(pcb, IP_ADDR_ANY, loc_port); if(err != ERR_OK){ error(lwip_strerr(err), false); return -1; } fd = open(loc_file, O_WRONLY); blkno = 1; // Craft the initial get request with appropriate mode int bufsize = strlen(rem_file) + 4 + (mode == MODE_NETASCII ? strlen("netascii") : strlen("octet")); char *pkt = (char *)safe_malloc(bufsize); memset(pkt, 0, bufsize); u16_t *opcode = (u16_t *) pkt; *opcode = htons(1); memcpy(pkt+2, rem_file, strlen(rem_file)+1); if(mode == MODE_NETASCII) memcpy(pkt+3+strlen(rem_file), "netascii", strlen("netascii")); else memcpy(pkt+3+strlen(rem_file), "octet", strlen("octet")); // Set the packet recv handler udp_recv(pcb, hndl_pkt, this); // Send the packet struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, bufsize, PBUF_ROM); p->payload = pkt; udp_sendto(pcb, p, &rem_host, rem_port); // Block the thread until the request is satisfied sys_sem_new(&get_wait, 0); sys_arch_sem_wait(&get_wait, 0); sys_sem_free(&get_wait); udp_remove(pcb); //pbuf_free(p); }
/** * Called when data has been received on this pcb. */ static err_t server_tcp_recv(void* arg, struct tcp_pcb* pcb, struct pbuf* p, err_t err) { struct server_tcp_state* ss = (struct server_tcp_state*)arg; struct pbuf* pp; LWIP_DEBUGF(SERVER_TCP_DEBUG | LWIP_DBG_TRACE, ("server_tcp_recv: pcb=%p pbuf=%p err=%s\n", (void*)pcb, (void*)p, lwip_strerr(err))); /* If there's an error */ if ((err != ERR_OK) || (p == NULL) || (ss == NULL)) { /* Error or closed by other side? */ if (p != NULL) { /* Inform TCP that we have taken the data. */ tcp_recved(pcb, p->tot_len); pbuf_free(p); } if (ss == NULL) { /* This should not happen, only to be robust */ LWIP_DEBUGF(SERVER_TCP_DEBUG, ("Error, server_tcp_recv: ss is NULL, close\n")); } server_tcp_close_conn(pcb, ss); return ERR_OK; } /* Make a secondary copy of the pbuf that we can traverse */ pp = p; /* Traverse the pbuf chain */ do { /* Parse this data in the http module */ parse_http_response_buffer(pp->payload, pp->len); } while((pp = pp->next)); /* While there's another item in the chain */ /* Inform TCP that we have taken the data. */ tcp_recved(pcb, p->tot_len); /* We're finished with the pbuf now */ pbuf_free(p); return ERR_OK; }
/****************************************************************************** * FunctionName : espconn_client_connect * Description : A new incoming connection has been connected. * Parameters : arg -- Additional argument to pass to the callback function * tpcb -- The connection pcb which is connected * err -- An unused error code, always ERR_OK currently * Returns : connection result *******************************************************************************/ static err_t ICACHE_FLASH_ATTR espconn_client_connect(void *arg, struct tcp_pcb *tpcb, err_t err) { espconn_msg *pcon = arg; espconn_printf("espconn_client_connect pcon %p tpcb %p\n", pcon, tpcb); if (err == ERR_OK){ pcon->pespconn->state = ESPCONN_CONNECT; pcon->pcommon.err = err; pcon->pcommon.pcb = tpcb; tcp_arg(tpcb, (void *)pcon); tcp_sent(tpcb, espconn_client_sent); tcp_recv(tpcb, espconn_client_recv); //tcp_poll(tpcb, espconn_client_poll, 1); if (pcon->pespconn->proto.tcp->connect_callback != NULL) { pcon->pespconn->proto.tcp->connect_callback(pcon->pespconn); } } else{ os_printf("err in host connected (%s)\n",lwip_strerr(err)); } return err; }
/** * The connection shall be actively closed. * Reset the sent- and recv-callbacks. */ static void http_close_conn(struct tcp_pcb *pcb, struct http_state *hs) { err_t err; LWIP_DEBUGF(HTTPD_DEBUG, ("http_close: pcb=0x%08X hs=0x%08X left=%d\n", pcb, hs, hs != NULL ? hs->left : 0)); tcp_recv(pcb, NULL); err = tcp_close(pcb); if (err != ERR_OK) { /* closing failed, try again later */ LWIP_DEBUGF(HTTPD_DEBUG, ("Error %s closing pcb=0x%08X\n", lwip_strerr(err), pcb)); tcp_recv(pcb, http_recv); } else { /* closing succeeded */ tcp_arg(pcb, NULL); tcp_poll(pcb, NULL, 0); tcp_sent(pcb, NULL); if (hs != NULL) { http_state_free(hs); } } }
int ICACHE_FLASH_ATTR user_dns_request(struct user_dns_param *param) { int err = EFAULT; if(!param) { DEBUG_WARNING("EINVAL\n"); return EINVAL; } DEBUG_INFO("%s\n", ipaddr_ntoa(¶m->ip)); err = dns_gethostbyname(param->hostname, ¶m->ip, on_found, param); DEBUG_INFO("dns_gethostbyname=%d | %s\n", err, lwip_strerr(err)); switch(err) { case ERR_INPROGRESS: DEBUG_NOTICE("wait for callback\n"); os_timer_setfn(¶m->tmr, (os_timer_func_t *)on_timer, param); os_timer_arm(¶m->tmr, 1000, 0); err = 0; break; case ERR_OK: DEBUG_NOTICE("is ipaddr\n"); os_timer_setfn(¶m->tmr, (os_timer_func_t *)on_timer, param); os_timer_arm(¶m->tmr, 1, 0); err = 0; break; default: DEBUG_WARNING("bad hostname\n"); break; } return err; }
/** * Processes ICMP input packets, called from ip_input(). * * Currently only processes icmp echo requests and sends * out the echo response. * * @param p the icmp echo request packet, p->payload pointing to the icmp header * @param inp the netif on which this packet was received */ void icmp_input(struct pbuf *p, struct netif *inp) { u8_t type; #ifdef LWIP_DEBUG u8_t code; #endif /* LWIP_DEBUG */ struct icmp_echo_hdr *iecho; const struct ip_hdr *iphdr_in; s16_t hlen; const ip4_addr_t* src; ICMP_STATS_INC(icmp.recv); MIB2_STATS_INC(mib2.icmpinmsgs); iphdr_in = ip4_current_header(); hlen = IPH_HL(iphdr_in) * 4; if (hlen < IP_HLEN) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%"S16_F" bytes) received\n", hlen)); goto lenerr; } if (p->len < sizeof(u16_t)*2) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); goto lenerr; } type = *((u8_t *)p->payload); #ifdef LWIP_DEBUG code = *(((u8_t *)p->payload)+1); #endif /* LWIP_DEBUG */ switch (type) { case ICMP_ER: /* This is OK, echo reply might have been parsed by a raw PCB (as obviously, an echo request has been sent, too). */ MIB2_STATS_INC(mib2.icmpinechoreps); break; case ICMP_ECHO: MIB2_STATS_INC(mib2.icmpinechos); src = ip4_current_dest_addr(); /* multicast destination address? */ if (ip4_addr_ismulticast(ip4_current_dest_addr())) { #if LWIP_MULTICAST_PING /* For multicast, use address of receiving interface as source address */ src = netif_ip4_addr(inp); #else /* LWIP_MULTICAST_PING */ LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n")); goto icmperr; #endif /* LWIP_MULTICAST_PING */ } /* broadcast destination address? */ if (ip4_addr_isbroadcast(ip4_current_dest_addr(), ip_current_netif())) { #if LWIP_BROADCAST_PING /* For broadcast, use address of receiving interface as source address */ src = netif_ip4_addr(inp); #else /* LWIP_BROADCAST_PING */ LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n")); goto icmperr; #endif /* LWIP_BROADCAST_PING */ } LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); if (p->tot_len < sizeof(struct icmp_echo_hdr)) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); goto lenerr; } #if CHECKSUM_CHECK_ICMP IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) { if (inet_chksum_pbuf(p) != 0) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); pbuf_free(p); ICMP_STATS_INC(icmp.chkerr); MIB2_STATS_INC(mib2.icmpinerrors); return; } } #endif #if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN if (pbuf_header(p, (hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) { /* p is not big enough to contain link headers * allocate a new one and copy p into it */ struct pbuf *r; /* allocate new packet buffer with space for link headers */ r = pbuf_alloc(PBUF_LINK, p->tot_len + hlen, PBUF_RAM); if (r == NULL) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n")); goto icmperr; } if (r->len < hlen + sizeof(struct icmp_echo_hdr)) { LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("first pbuf cannot hold the ICMP header")); pbuf_free(r); goto icmperr; } /* copy the ip header */ MEMCPY(r->payload, iphdr_in, hlen); /* switch r->payload back to icmp header (cannot fail) */ if (pbuf_header(r, -hlen)) { LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0); pbuf_free(r); goto icmperr; } /* copy the rest of the packet without ip header */ if (pbuf_copy(r, p) != ERR_OK) { LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("icmp_input: copying to new pbuf failed")); pbuf_free(r); goto icmperr; } /* free the original p */ pbuf_free(p); /* we now have an identical copy of p that has room for link headers */ p = r; } else { /* restore p->payload to point to icmp header (cannot fail) */ if (pbuf_header(p, -(s16_t)(hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) { LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); goto icmperr; } } #endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ /* At this point, all checks are OK. */ /* We generate an answer by switching the dest and src ip addresses, * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ iecho = (struct icmp_echo_hdr *)p->payload; if (pbuf_header(p, hlen)) { LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Can't move over header in packet")); } else { err_t ret; struct ip_hdr *iphdr = (struct ip_hdr*)p->payload; ip4_addr_copy(iphdr->src, *src); ip4_addr_copy(iphdr->dest, *ip4_current_src_addr()); ICMPH_TYPE_SET(iecho, ICMP_ER); #if CHECKSUM_GEN_ICMP IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) { /* adjust the checksum */ if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; } else { iecho->chksum += PP_HTONS(ICMP_ECHO << 8); } } #if LWIP_CHECKSUM_CTRL_PER_NETIF else { iecho->chksum = 0; } #endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ #else /* CHECKSUM_GEN_ICMP */ iecho->chksum = 0; #endif /* CHECKSUM_GEN_ICMP */ /* Set the correct TTL and recalculate the header checksum. */ IPH_TTL_SET(iphdr, ICMP_TTL); IPH_CHKSUM_SET(iphdr, 0); #if CHECKSUM_GEN_IP IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) { IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen)); } #endif /* CHECKSUM_GEN_IP */ ICMP_STATS_INC(icmp.xmit); /* increase number of messages attempted to send */ MIB2_STATS_INC(mib2.icmpoutmsgs); /* increase number of echo replies attempted to send */ MIB2_STATS_INC(mib2.icmpoutechoreps); /* send an ICMP packet */ ret = ip4_output_if(p, src, IP_HDRINCL, ICMP_TTL, 0, IP_PROTO_ICMP, inp); if (ret != ERR_OK) { LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret))); } }
/** Call tcp_write() in a loop trying smaller and smaller length * * @param pcb tcp_pcb to send * @param ptr Data to send * @param length Length of data to send (in/out: on return, contains the * amount of data sent) * @param apiflags directly passed to tcp_write * @return the return value of tcp_write */ static err_t server_tcp_write(struct tcp_pcb* pcb, const void* ptr, uint16_t* length, uint8_t apiflags) { uint16_t len; err_t err; LWIP_ASSERT("length != NULL", length != NULL); len = *length; do { LWIP_DEBUGF(SERVER_TCP_DEBUG | LWIP_DBG_TRACE, ("Trying to send %d bytes\n", len)); err = tcp_write(pcb, ptr, len, apiflags); /* If there's not enough memory to send this data */ if (err == ERR_MEM) { /* If there's no space in the buffers at all */ if ((tcp_sndbuf(pcb) == 0) || (tcp_sndqueuelen(pcb) >= TCP_SND_QUEUELEN)) { len = 1; /* No need to try smaller sizes, exit */ } else { len /= 2; } LWIP_DEBUGF(SERVER_TCP_DEBUG | LWIP_DBG_TRACE, ("Send failed, trying less (%d bytes)\n", len)); } } while ((err == ERR_MEM) && (len > 1)); if (err == ERR_OK) { LWIP_DEBUGF(SERVER_TCP_DEBUG | LWIP_DBG_TRACE, ("Sent %d bytes\n", len)); } else { LWIP_DEBUGF(SERVER_TCP_DEBUG | LWIP_DBG_TRACE, ("Send failed with err %d (\"%s\")\n", err, lwip_strerr(err))); } *length = len; return err; }
static void LwipInitTask(void* pvArguments) { err_t err; struct netif fsl_netif0; ip_addr_t fsl_netif0_ipaddr, fsl_netif0_netmask, fsl_netif0_gw; char msg[] = "This is my message"; (void)pvArguments; // Init lwip stack tcpip_init(NULL,NULL); printf("%s: lwip init called ..\n", __FUNCTION__); // Setup IP Config for DHCP ... IP4_ADDR(&fsl_netif0_ipaddr, 0,0,0,0); IP4_ADDR(&fsl_netif0_netmask, 0,0,0,0); IP4_ADDR(&fsl_netif0_gw, 0,0,0,0); /* Add a network interface to the list of lwIP netifs. */ netif_add(&fsl_netif0, &fsl_netif0_ipaddr, &fsl_netif0_netmask, &fsl_netif0_gw, NULL, ethernetif_init, ethernet_input); /* Set the network interface as the default network interface. */ netif_set_default(&fsl_netif0); /* obtain the IP address, default gateway and subnet mask by using DHCP*/ err = dhcp_start(&fsl_netif0); printf("%s : Started DCHP request (%s)\n", __FUNCTION__, lwip_strerr(err)); for(int i=0; i < DHCP_TIMEOUT && fsl_netif0.dhcp->state != DHCP_BOUND; i++) { printf("%s : Current DHCP State : %d\n", __FUNCTION__, fsl_netif0.dhcp->state); // Wait a second vTaskDelay(1000/portTICK_PERIOD_MS); } // Make it active ... netif_set_up(&fsl_netif0); printf("%s : Interface is up : %d\n", __FUNCTION__, fsl_netif0.dhcp->state); printf("%s : IP %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.ip_addr)); printf("%s : NM %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.netmask)); printf("%s : GW %s\n", __FUNCTION__, ipaddr_ntoa(&fsl_netif0.gw)); if (fsl_netif0.dhcp->state == DHCP_BOUND) { // Send out some UDP data struct netconn* pConnection; // Create UDP connection pConnection = netconn_new(NETCONN_UDP); // Connect to local port err = netconn_bind(pConnection, IP_ADDR_ANY, 12345); printf("%s : Bound to IP_ADDR_ANY port 12345 (%s)\n", __FUNCTION__, lwip_strerr(err)); err = netconn_connect(pConnection, IP_ADDR_BROADCAST, 12346 ); printf("%s : Connected to IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err)); for(int i = 0; i < 10; i++ ){ struct netbuf* buf = netbuf_new(); void* data = netbuf_alloc(buf, sizeof(msg)); memcpy (data, msg, sizeof (msg)); err = netconn_send(pConnection, buf); printf("%s : Sending to IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err)); netbuf_delete(buf); // De-allocate packet buffer // Wait a second vTaskDelay(1000/portTICK_PERIOD_MS); } err = netconn_disconnect(pConnection); printf("%s : Disconnected from IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err)); err = netconn_delete(pConnection); printf("%s : Deleted connection (%s)\n", __FUNCTION__, lwip_strerr(err)); } // Wait a second vTaskDelay(1000/portTICK_PERIOD_MS); /* finish the lease of the IP address */ err = dhcp_release(&fsl_netif0); printf("%s : DHCP Release (%s)\n", __FUNCTION__, lwip_strerr(err)); for(;;) {}; }
void broadcast_temperature(void *pvParameters) { uint8_t amount = 0; uint8_t sensors = 1; ds18b20_addr_t addrs[sensors]; float results[sensors]; // Use GPIO 13 as one wire pin. uint8_t GPIO_FOR_ONE_WIRE = 13; char msg[100]; // Broadcaster part err_t err; while(1) { // Send out some UDP data struct netconn* conn; // Create UDP connection conn = netconn_new(NETCONN_UDP); // Connect to local port err = netconn_bind(conn, IP_ADDR_ANY, 8004); if (err != ERR_OK) { netconn_delete(conn); printf("%s : Could not bind! (%s)\n", __FUNCTION__, lwip_strerr(err)); continue; } err = netconn_connect(conn, IP_ADDR_BROADCAST, 8005); if (err != ERR_OK) { netconn_delete(conn); printf("%s : Could not connect! (%s)\n", __FUNCTION__, lwip_strerr(err)); continue; } for(;;) { // Search all DS18B20, return its amount and feed 't' structure with result data. amount = ds18b20_scan_devices(GPIO_FOR_ONE_WIRE, addrs, sensors); if (amount < sensors){ printf("Something is wrong, I expect to see %d sensors \nbut just %d was detected!\n", sensors, amount); } ds18b20_measure_and_read_multi(GPIO_FOR_ONE_WIRE, addrs, sensors, results); for (int i = 0; i < sensors; ++i) { // ("\xC2\xB0" is the degree character (U+00B0) in UTF-8) sprintf(msg, "Sensor %08x%08x reports: %f \xC2\xB0""C\n", (uint32_t)(addrs[i] >> 32), (uint32_t)addrs[i], results[i]); printf("%s", msg); struct netbuf* buf = netbuf_new(); void* data = netbuf_alloc(buf, strlen(msg)); memcpy (data, msg, strlen(msg)); err = netconn_send(conn, buf); if (err != ERR_OK) { printf("%s : Could not send data!!! (%s)\n", __FUNCTION__, lwip_strerr(err)); continue; } netbuf_delete(buf); // De-allocate packet buffer } vTaskDelay(1000/portTICK_PERIOD_MS); } err = netconn_disconnect(conn); printf("%s : Disconnected from IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err)); err = netconn_delete(conn); printf("%s : Deleted connection (%s)\n", __FUNCTION__, lwip_strerr(err)); vTaskDelay(1000/portTICK_PERIOD_MS); } }
void broadcast_temperature(void *pvParameters) { uint8_t amount = 0; uint8_t sensors = 2; ds_sensor_t t[sensors]; // Use GPIO 13 as one wire pin. uint8_t GPIO_FOR_ONE_WIRE = 13; char msg[100]; // Broadcaster part err_t err; // Initialize one wire bus. onewire_init(GPIO_FOR_ONE_WIRE); while(1) { // Send out some UDP data struct netconn* conn; // Create UDP connection conn = netconn_new(NETCONN_UDP); // Connect to local port err = netconn_bind(conn, IP_ADDR_ANY, 8004); if (err != ERR_OK) { netconn_delete(conn); printf("%s : Could not bind! (%s)\n", __FUNCTION__, lwip_strerr(err)); continue; } err = netconn_connect(conn, IP_ADDR_BROADCAST, 8005); if (err != ERR_OK) { netconn_delete(conn); printf("%s : Could not connect! (%s)\n", __FUNCTION__, lwip_strerr(err)); continue; } for(;;) { // Search all DS18B20, return its amount and feed 't' structure with result data. amount = ds18b20_read_all(GPIO_FOR_ONE_WIRE, t); if (amount < sensors){ printf("Something is wrong, I expect to see %d sensors \nbut just %d was detected!\n", sensors, amount); } for (int i = 0; i < amount; ++i) { int intpart = (int)t[i].value; int fraction = (int)((t[i].value - intpart) * 100); // Multiple "" here is just to satisfy compiler and don`t raise 'hex escape sequence out of range' warning. sprintf(msg, "Sensor %d report: %d.%02d ""\xC2""\xB0""C\n",t[i].id, intpart, fraction); printf("%s", msg); struct netbuf* buf = netbuf_new(); void* data = netbuf_alloc(buf, strlen(msg)); memcpy (data, msg, strlen(msg)); err = netconn_send(conn, buf); if (err != ERR_OK) { printf("%s : Could not send data!!! (%s)\n", __FUNCTION__, lwip_strerr(err)); continue; } netbuf_delete(buf); // De-allocate packet buffer } vTaskDelay(1000/portTICK_RATE_MS); } err = netconn_disconnect(conn); printf("%s : Disconnected from IP_ADDR_BROADCAST port 12346 (%s)\n", __FUNCTION__, lwip_strerr(err)); err = netconn_delete(conn); printf("%s : Deleted connection (%s)\n", __FUNCTION__, lwip_strerr(err)); vTaskDelay(1000/portTICK_RATE_MS); } }
/** * Try send as many bytes as possible from output ring buffer * @param rb Output ring buffer * @param tpcb TCP connection handle */ static void mqtt_output_send(struct mqtt_ringbuf_t *rb, struct altcp_pcb *tpcb) { err_t err; u8_t wrap = 0; u16_t ringbuf_lin_len = mqtt_ringbuf_linear_read_length(rb); u16_t send_len = altcp_sndbuf(tpcb); LWIP_ASSERT("mqtt_output_send: tpcb != NULL", tpcb != NULL); if (send_len == 0 || ringbuf_lin_len == 0) { return; } LWIP_DEBUGF(MQTT_DEBUG_TRACE, ("mqtt_output_send: tcp_sndbuf: %d bytes, ringbuf_linear_available: %d, get %d, put %d\n", send_len, ringbuf_lin_len, rb->get, rb->put)); if (send_len > ringbuf_lin_len) { /* Space in TCP output buffer is larger than available in ring buffer linear portion */ send_len = ringbuf_lin_len; /* Wrap around if more data in ring buffer after linear portion */ wrap = (mqtt_ringbuf_len(rb) > ringbuf_lin_len); } err = altcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY | (wrap ? TCP_WRITE_FLAG_MORE : 0)); if ((err == ERR_OK) && wrap) { mqtt_ringbuf_advance_get_idx(rb, send_len); /* Use the lesser one of ring buffer linear length and TCP send buffer size */ send_len = LWIP_MIN(altcp_sndbuf(tpcb), mqtt_ringbuf_linear_read_length(rb)); err = altcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY); } if (err == ERR_OK) { mqtt_ringbuf_advance_get_idx(rb, send_len); /* Flush */ altcp_output(tpcb); } else { LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_output_send: Send failed with err %d (\"%s\")\n", err, lwip_strerr(err))); } }
int TftpClient::put(char *filename) { struct udp_pcb * pcb = udp_new(); err = udp_bind(pcb, IP_ADDR_ANY, loc_port); if(err != ERR_OK){ error(lwip_strerr(err), false); return -1; } if(mode == MODE_OCTET){ fd = open(filename, O_RDONLY); }else{ fd = netascii_open(filename, O_RDONLY); } sys_sem_new(&snd_nxt, 0); // Craft the initial get request with appropriate mode int bufsize = strlen(filename) + 4 + (mode == MODE_NETASCII ? strlen("netascii") : strlen("octet")); char *pkt = (char *)safe_malloc(bufsize); memset(pkt, 0, bufsize); u16_t *opcode = (u16_t *) pkt; *opcode = htons(2); memcpy(pkt+2, filename, strlen(filename)+1); if(mode == MODE_NETASCII) memcpy(pkt+3+strlen(filename), "netascii", strlen("netascii")); else memcpy(pkt+3+strlen(filename), "octet", strlen("octet")); blkno = 0; // Set the packet recv handler udp_recv(pcb, ack_recvr, this); // Send the packet u32_t w_ack; struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, bufsize, PBUF_ROM); p->payload = pkt; do{ err_t e = udp_sendto(pcb, p, &rem_host, rem_port); if(e != ERR_OK) error(lwip_strerr(e), false); w_ack = sys_arch_sem_wait(&snd_nxt, rtt); }while(w_ack == SYS_ARCH_TIMEOUT); pbuf_free(p); // Craft the next data packet char data[600]; u16_t *tmp; int kbytes; while(1){ tmp = (u16_t *)data; *tmp = htons(3); tmp = (u16_t *)(data+sizeof(u16_t)); *tmp = htons(blkno); kbytes = read(fd, data+4, 512); p = pbuf_alloc(PBUF_TRANSPORT, 4+kbytes, PBUF_ROM); p->payload = data; do{ err_t e = udp_sendto(pcb, p, &rem_host, sec_port); w_ack = sys_arch_sem_wait(&snd_nxt, rtt); }while(w_ack == SYS_ARCH_TIMEOUT); pbuf_free(p); if(kbytes < 512){ if(mode == MODE_OCTET){ close(fd); }else{ netascii_close(fd); } udp_remove(pcb); sec_port = 0; free(pkt); return 0; } } }
TftpClient::TftpClient(char *host, u16_t port) { err_t e = connect(host, port); if(e != ERR_OK) error(lwip_strerr(e), true); }
int main() { sys_sem_t sem; sys_init(); if(sys_sem_new(&sem, 0) != ERR_OK) { LWIP_ASSERT("failed to create semaphore", 0); } tcpip_init(tcpip_init_done, &sem); sys_sem_wait(&sem); sys_sem_free(&sem); /////////////////////////////////////////////////////////////////////////////////////////////////// struct netconn *conn, *newconn; err_t err; /* Create a new connection identifier. */ conn = netconn_new(NETCONN_TCP); netconn_set_noautorecved(conn, 0); tcp_nagle_disable(conn->pcb.tcp); /* Bind connection to well known port number 7. */ netconn_bind(conn, NULL, 80); /* Tell connection to go into listening mode. */ netconn_listen(conn); while (1) { /* Grab new connection. */ err = netconn_accept(conn, &newconn); printf("accepted new connection %p\n", newconn); /* Process the new connection. */ if (err == ERR_OK) { struct netbuf *buf; void *data; u16_t len; u64_t total_rcvd = 0; u64_t eal_tsc_resolution_hz = rte_get_timer_hz(); u64_t end = rte_get_timer_cycles() + eal_tsc_resolution_hz; while ((err = netconn_recv(newconn, &buf)) == ERR_OK) { netbuf_data(buf, &data, &len); if (len > 0) { total_rcvd += len; } if (rte_get_timer_cycles() >= end) { printf("%llu \n", (unsigned long long)total_rcvd); total_rcvd = 0; end = rte_get_timer_cycles() + eal_tsc_resolution_hz; } #if 0 if (err != ERR_OK) { printf("tcpecho: netconn_write: error \"%s\"\n", lwip_strerr(err)); } #endif //} while (netbuf_next(buf) >= 0); netbuf_delete(buf); } /*printf("Got EOF, looping\n");*/ /* Close connection and discard connection identifier. */ netconn_close(newconn); netconn_delete(newconn); } } while (1); }