err_t mdns_responder_init(const struct mdns_service *services, int num_services, const char *txt_records[]) { err_t ret; memset(&mdns_state, 0, sizeof(mdns_state)); mdns_state.netif = &gs_net_if; setup_hostnames(&mdns_state, &gs_net_if); setup_txt_records(&mdns_state, txt_records); mdns_state.services = services; mdns_state.num_services = num_services; struct ip_addr ipgroup; IP4_ADDR(&ipgroup, 224, 0, 0, 251); mdns_state.sendpcb = udp_new(); if (mdns_state.sendpcb == NULL) return ERR_MEM; struct udp_pcb *pcb = udp_new(); if (pcb == NULL) { udp_remove(mdns_state.sendpcb); return ERR_MEM; } if ((ret = igmp_joingroup(IP_ADDR_ANY, &ipgroup)) != ERR_OK) return ret; ip_set_option(pcb, SOF_REUSEADDR); ip_set_option(mdns_state.sendpcb, SOF_REUSEADDR); if ((ret = udp_bind(pcb, IP_ADDR_ANY, MDNS_PORT)) != ERR_OK) goto error_exit; udp_recv(pcb, recv, &mdns_state); if ((ret = udp_bind(mdns_state.sendpcb, 0, MDNS_PORT)) != ERR_OK) goto error_exit; if ((ret = udp_connect(mdns_state.sendpcb, &ipgroup, MDNS_PORT)) != ERR_OK) goto error_exit; return ERR_OK; error_exit: udp_remove(pcb); udp_remove(mdns_state.sendpcb); return ret; }
STATIC mp_obj_t lwip_socket_setsockopt(mp_uint_t n_args, const mp_obj_t *args) { (void)n_args; // always 4 lwip_socket_obj_t *socket = args[0]; int opt = mp_obj_get_int(args[2]); if (opt == 20) { if (args[3] == mp_const_none) { socket->callback = MP_OBJ_NULL; } else { socket->callback = args[3]; } return mp_const_none; } // Integer options mp_int_t val = mp_obj_get_int(args[3]); switch (opt) { case SOF_REUSEADDR: // Options are common for UDP and TCP pcb's. if (val) { ip_set_option(socket->pcb.tcp, SOF_REUSEADDR); } else { ip_reset_option(socket->pcb.tcp, SOF_REUSEADDR); } break; default: printf("Warning: lwip.setsockopt() not implemented\n"); } return mp_const_none; }
int socks_tcp_bind(struct socks_data *data) { struct tcp_pcb *pcb; err_t ret; pcb = tcp_new(); if (!pcb) return -1; pcb->flags |= TF_NODELAY; ip_set_option(pcb, SOF_REUSEADDR); ret = tcp_bind(pcb, IP_ADDR_ANY, data->port); if (ret < 0) { tcp_abort(pcb); return -1; } data->pcb = tcp_listen(pcb); if (!data->pcb) { tcp_abort(pcb); return -1; } tcp_arg(data->pcb, data); tcp_accept(data->pcb, socks_tcp_accept); return 0; }
void vBasicWEBServer( void *pvParameters ) { struct netconn *pxNewConnection; //struct ip_addr xIpAddr, xNetMast, xGateway; extern err_t ethernetif_init( struct netif *netif ); int ret = ERR_OK; /* Parameters are not used - suppress compiler error. */ ( void )pvParameters; /* Create a new tcp connection handle */ pxHTTPListener = netconn_new( NETCONN_TCP ); ip_set_option(pxHTTPListener->pcb.ip, SOF_REUSEADDR); netconn_bind( pxHTTPListener, NULL, webHTTP_PORT ); netconn_listen( pxHTTPListener ); #if CONFIG_READ_FLASH /* Load wifi_config */ LoadWifiConfig(); RestartSoftAP(); #endif //printf("\r\n-0\n"); /* Loop forever */ for( ;; ) { if(webs_terminate) break; //printf("\r\n%d:-1\n", xTaskGetTickCount()); /* Wait for connection. */ // Evan mopdified for adapt two version lwip api diff port_netconn_accept( pxHTTPListener , pxNewConnection, ret); //printf("\r\n%d:-2\n", xTaskGetTickCount()); if( pxNewConnection != NULL && ret == ERR_OK) { /* Service connection. */ vProcessConnection( pxNewConnection ); while( netconn_delete( pxNewConnection ) != ERR_OK ) { vTaskDelay( webSHORT_DELAY ); } } //printf("\r\n%d:-3\n", xTaskGetTickCount()); } //printf("\r\n-4\n"); if(pxHTTPListener) { netconn_close(pxHTTPListener); netconn_delete(pxHTTPListener); pxHTTPListener = NULL; } //printf("\r\nExit Web Server Thread!\n"); xSemaphoreGive(webs_sema); }
STATIC mp_obj_t lwip_socket_setsockopt(size_t n_args, const mp_obj_t *args) { (void)n_args; // always 4 lwip_socket_obj_t *socket = args[0]; int opt = mp_obj_get_int(args[2]); if (opt == 20) { if (args[3] == mp_const_none) { socket->callback = MP_OBJ_NULL; } else { socket->callback = args[3]; } return mp_const_none; } switch (opt) { // level: SOL_SOCKET case SOF_REUSEADDR: { mp_int_t val = mp_obj_get_int(args[3]); // Options are common for UDP and TCP pcb's. if (val) { ip_set_option(socket->pcb.tcp, SOF_REUSEADDR); } else { ip_reset_option(socket->pcb.tcp, SOF_REUSEADDR); } break; } // level: IPPROTO_IP case IP_ADD_MEMBERSHIP: { mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); if (bufinfo.len != sizeof(ip_addr_t) * 2) { mp_raise_ValueError(NULL); } // POSIX setsockopt has order: group addr, if addr, lwIP has it vice-versa err_t err = igmp_joingroup((ip_addr_t*)bufinfo.buf + 1, bufinfo.buf); if (err != ERR_OK) { mp_raise_OSError(error_lookup_table[-err]); } break; } default: printf("Warning: lwip.setsockopt() not implemented\n"); } return mp_const_none; }
static nsapi_error_t mbed_lwip_setsockopt(nsapi_stack_t *stack, nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen) { struct lwip_socket *s = (struct lwip_socket *)handle; switch (optname) { #if LWIP_TCP case NSAPI_KEEPALIVE: if (optlen != sizeof(int) || s->conn->type != NETCONN_TCP) { return NSAPI_ERROR_UNSUPPORTED; } s->conn->pcb.tcp->so_options |= SOF_KEEPALIVE; return 0; case NSAPI_KEEPIDLE: if (optlen != sizeof(int) || s->conn->type != NETCONN_TCP) { return NSAPI_ERROR_UNSUPPORTED; } s->conn->pcb.tcp->keep_idle = *(int*)optval; return 0; case NSAPI_KEEPINTVL: if (optlen != sizeof(int) || s->conn->type != NETCONN_TCP) { return NSAPI_ERROR_UNSUPPORTED; } s->conn->pcb.tcp->keep_intvl = *(int*)optval; return 0; #endif case NSAPI_REUSEADDR: if (optlen != sizeof(int)) { return NSAPI_ERROR_UNSUPPORTED; } if (*(int *)optval) { ip_set_option(s->conn->pcb.ip, SOF_REUSEADDR); } else { ip_reset_option(s->conn->pcb.ip, SOF_REUSEADDR); } return 0; default: return NSAPI_ERROR_UNSUPPORTED; } }
/** Ensure DHCP PCB is allocated and bound */ static err_t dhcp6_inc_pcb_refcount(void) { if (dhcp6_pcb_refcount == 0) { LWIP_ASSERT("dhcp6_inc_pcb_refcount(): memory leak", dhcp6_pcb == NULL); /* allocate UDP PCB */ dhcp6_pcb = udp_new_ip6(); if (dhcp6_pcb == NULL) { return ERR_MEM; } ip_set_option(dhcp6_pcb, SOF_BROADCAST); /* set up local and remote port for the pcb -> listen on all interfaces on all src/dest IPs */ udp_bind(dhcp6_pcb, IP6_ADDR_ANY, DHCP6_CLIENT_PORT); udp_recv(dhcp6_pcb, dhcp6_recv, NULL); } dhcp6_pcb_refcount++; return ERR_OK; }
/** * Start create TCP connection */ static err_t net_tcp_start(struct tls_netconn *conn) { struct tcp_pcb *pcb; err_t err; u16 localportnum = conn->localport; //TLS_DBGPRT_INFO("=====>\n"); conn->pcb.tcp = tcp_new(); pcb = conn->pcb.tcp; if (pcb == NULL) { TLS_DBGPRT_INFO("could not allocate tcp pcb\n"); return ERR_VAL; } tcp_arg(pcb, conn); if (conn->client) { TLS_DBGPRT_INFO("pcb = 0x%x, conn->addr = 0x%x, port = %d, localport=%d\n", pcb, conn->addr.addr, conn->port, conn->localport); tcp_err(pcb, net_tcp_err_cb); tcp_recv(pcb, net_tcp_recv_cb); //tcp_nagle_disable(pcb); if (pcb->recv != NULL) { TLS_DBGPRT_INFO("pcb->recv != NULL\n"); } //tcp_sent(pcb, net_tcp_sent_cb); tcp_poll(pcb, net_tcp_poll_cb, 4); ip_set_option(pcb, SOF_KEEPALIVE); if(localportnum > 0 && localportnum <= 0xFFFF) { err = tcp_bind(pcb, IP_ADDR_ANY, localportnum); if (err != ERR_OK) { TLS_DBGPRT_INFO("tcp bind failed %d\n", err); return err; } } err = tcp_connect(pcb, &conn->addr, conn->port, net_tcp_connect_cb); if (err != ERR_OK) { TLS_DBGPRT_INFO("tcp connect failed %d\n", err); return err; } if (conn->localport == 0){ conn->localport = pcb->local_port; } } else { TLS_DBGPRT_INFO("pcb ptr = 0x%x, conn->port = %d\n", pcb, conn->port); err = tcp_bind(pcb, IP_ADDR_ANY, conn->port); if (err != ERR_OK) { TLS_DBGPRT_INFO("tcp bind failed %d\n", err); return err; } conn->pcb.tcp = tcp_listen(pcb); //ip_set_option(conn->pcb.tcp, SOF_KEEPALIVE); if (conn->pcb.tcp == NULL) { /* create tcp sever failed */ TLS_DBGPRT_INFO("tcp listen failed\n"); return ERR_VAL; } tcp_arg(conn->pcb.tcp, conn); tcp_accept(conn->pcb.tcp, net_tcp_accept_cb); } return ERR_OK; }
/** * Accept callback function for TCP netconns. */ static err_t net_tcp_accept_cb(void *arg, struct tcp_pcb *newpcb, err_t err) { err_t err_ret = ERR_OK; struct tls_netconn *conn = (struct tls_netconn *)arg; struct tls_netconn *newconn; struct tcp_pcb *pcb; u32 cpu_sr; //TLS_DBGPRT_INFO("=====>\n"); #if 0 if (conn->tcp_connect_cnt >= TLS_MAX_SOCKET_NUM) { return ERR_ABRT; } #endif newconn = net_alloc_socket(conn); if (!newconn) { /* connection aborted */ /* not happen */ tcp_abort(newpcb); //printf("\r\nnet_tcp_accept_cb err\r\n"); return ERR_ABRT; } if (conn){ tcp_accepted(conn->pcb.tcp); } //conn->tcp_connect_cnt++; newconn->used = true; newconn->pcb.tcp = newpcb; newconn->client = true; newconn->idle_time = conn->idle_time; newconn->proto = TLS_NETCONN_TCP; newconn->state = NETCONN_STATE_CONNECTED; pcb = newconn->pcb.tcp; ip_set_option(newconn->pcb.tcp, SOF_KEEPALIVE); newconn->skd = conn->skd; tcp_arg(pcb, newconn); tcp_recv(pcb, net_tcp_recv_cb); //tcp_sent(pcb, net_tcp_sent_cb); tcp_poll(pcb, net_tcp_poll_cb, 2); tcp_err(pcb, net_tcp_err_cb); cpu_sr = tls_os_set_critical(); dl_list_add_tail(&conn->list, &newconn->list); tls_os_release_critical(cpu_sr); newconn->port = host_to_le16(pcb->remote_port); newconn->localport = conn->localport; ip_addr_set(&newconn->addr, &pcb->remote_ip); net_send_event_to_hostif(newconn, NET_EVENT_TCP_JOINED); if(conn->skd->acceptf != NULL) { err_ret =conn->skd->acceptf(newconn->skt_num, err); if(err_ret == ERR_ABRT) { tcp_abort(pcb); } } //conn->state = NETCONN_STATE_CONNECTED; return err_ret; }
static nsapi_error_t mbed_lwip_setsockopt(nsapi_stack_t *stack, nsapi_socket_t handle, int level, int optname, const void *optval, unsigned optlen) { struct lwip_socket *s = (struct lwip_socket *)handle; switch (optname) { #if LWIP_TCP case NSAPI_KEEPALIVE: if (optlen != sizeof(int) || s->conn->type != NETCONN_TCP) { return NSAPI_ERROR_UNSUPPORTED; } s->conn->pcb.tcp->so_options |= SOF_KEEPALIVE; return 0; case NSAPI_KEEPIDLE: if (optlen != sizeof(int) || s->conn->type != NETCONN_TCP) { return NSAPI_ERROR_UNSUPPORTED; } s->conn->pcb.tcp->keep_idle = *(int*)optval; return 0; case NSAPI_KEEPINTVL: if (optlen != sizeof(int) || s->conn->type != NETCONN_TCP) { return NSAPI_ERROR_UNSUPPORTED; } s->conn->pcb.tcp->keep_intvl = *(int*)optval; return 0; #endif case NSAPI_REUSEADDR: if (optlen != sizeof(int)) { return NSAPI_ERROR_UNSUPPORTED; } if (*(int *)optval) { ip_set_option(s->conn->pcb.ip, SOF_REUSEADDR); } else { ip_reset_option(s->conn->pcb.ip, SOF_REUSEADDR); } return 0; case NSAPI_ADD_MEMBERSHIP: case NSAPI_DROP_MEMBERSHIP: { if (optlen != sizeof(nsapi_ip_mreq_t)) { return NSAPI_ERROR_PARAMETER; } err_t igmp_err; const nsapi_ip_mreq_t *imr = optval; /* Check interface address type matches group, or is unspecified */ if (imr->imr_interface.version != NSAPI_UNSPEC && imr->imr_interface.version != imr->imr_multiaddr.version) { return NSAPI_ERROR_PARAMETER; } ip_addr_t if_addr; ip_addr_t multi_addr; /* Convert the group address */ if (!convert_mbed_addr_to_lwip(&multi_addr, &imr->imr_multiaddr)) { return NSAPI_ERROR_PARAMETER; } /* Convert the interface address, or make sure it's the correct sort of "any" */ if (imr->imr_interface.version != NSAPI_UNSPEC) { if (!convert_mbed_addr_to_lwip(&if_addr, &imr->imr_interface)) { return NSAPI_ERROR_PARAMETER; } } else { ip_addr_set_any(IP_IS_V6(&if_addr), &if_addr); } igmp_err = ERR_USE; // Maps to NSAPI_ERROR_UNSUPPORTED int32_t member_pair_index = find_multicast_member(s, imr); if (optname == NSAPI_ADD_MEMBERSHIP) { if (!s->multicast_memberships) { // First multicast join on this socket, allocate space for membership tracking s->multicast_memberships = malloc(sizeof(nsapi_ip_mreq_t) * LWIP_SOCKET_MAX_MEMBERSHIPS); if (!s->multicast_memberships) { return NSAPI_ERROR_NO_MEMORY; } } else if(s->multicast_memberships_count == LWIP_SOCKET_MAX_MEMBERSHIPS) { return NSAPI_ERROR_NO_MEMORY; } if (member_pair_index != -1) { return NSAPI_ERROR_ADDRESS_IN_USE; } member_pair_index = next_free_multicast_member(s, 0); sys_prot_t prot = sys_arch_protect(); #if LWIP_IPV4 if (IP_IS_V4(&if_addr)) { igmp_err = igmp_joingroup(ip_2_ip4(&if_addr), ip_2_ip4(&multi_addr)); } #endif #if LWIP_IPV6 if (IP_IS_V6(&if_addr)) { igmp_err = mld6_joingroup(ip_2_ip6(&if_addr), ip_2_ip6(&multi_addr)); } #endif sys_arch_unprotect(prot); if (igmp_err == ERR_OK) { set_multicast_member_registry_bit(s, member_pair_index); s->multicast_memberships[member_pair_index] = *imr; s->multicast_memberships_count++; } } else { if (member_pair_index == -1) { return NSAPI_ERROR_NO_ADDRESS; } clear_multicast_member_registry_bit(s, member_pair_index); s->multicast_memberships_count--; sys_prot_t prot = sys_arch_protect(); #if LWIP_IPV4 if (IP_IS_V4(&if_addr)) { igmp_err = igmp_leavegroup(ip_2_ip4(&if_addr), ip_2_ip4(&multi_addr)); } #endif #if LWIP_IPV6 if (IP_IS_V6(&if_addr)) { igmp_err = mld6_leavegroup(ip_2_ip6(&if_addr), ip_2_ip6(&multi_addr)); } #endif sys_arch_unprotect(prot); } return mbed_lwip_err_remap(igmp_err); } default: return NSAPI_ERROR_UNSUPPORTED; } }
/** * @ingroup zepif * Set up a raw 6LowPAN netif and surround it with input- and output * functions for ZEP */ err_t zepif_init(struct netif *netif) { err_t err; struct zepif_init *init_state = (struct zepif_init *)netif->state; struct zepif_state *state = (struct zepif_state *)mem_malloc(sizeof(struct zepif_state)); LWIP_ASSERT("zepif needs an input callback", netif->input != NULL); if (state == NULL) { return ERR_MEM; } memset(state, 0, sizeof(struct zepif_state)); if (init_state != NULL) { memcpy(&state->init, init_state, sizeof(struct zepif_init)); } if (state->init.zep_src_udp_port == 0) { state->init.zep_src_udp_port = ZEPIF_DEFAULT_UDP_PORT; } if (state->init.zep_dst_udp_port == 0) { state->init.zep_dst_udp_port = ZEPIF_DEFAULT_UDP_PORT; } #if LWIP_IPV4 if (state->init.zep_dst_ip_addr == NULL) { /* With IPv4 enabled, default to broadcasting packets if no address is set */ state->init.zep_dst_ip_addr = IP_ADDR_BROADCAST; } #endif /* LWIP_IPV4 */ netif->state = NULL; state->pcb = udp_new_ip_type(IPADDR_TYPE_ANY); if (state->pcb == NULL) { err = ERR_MEM; goto err_ret; } err = udp_bind(state->pcb, state->init.zep_src_ip_addr, state->init.zep_src_udp_port); if (err != ERR_OK) { goto err_ret; } if (state->init.zep_netif != NULL) { udp_bind_netif(state->pcb, state->init.zep_netif); } LWIP_ASSERT("udp_bind(lowpan6_broadcast_pcb) failed", err == ERR_OK); ip_set_option(state->pcb, SOF_BROADCAST); udp_recv(state->pcb, zepif_udp_recv, netif); err = lowpan6_if_init(netif); LWIP_ASSERT("lowpan6_if_init set a state", netif->state == NULL); if (err == ERR_OK) { netif->state = state; netif->hwaddr_len = 6; if (init_state != NULL) { memcpy(netif->hwaddr, init_state->addr, 6); } else { u8_t i; for (i = 0; i < 6; i++) { netif->hwaddr[i] = i; } netif->hwaddr[0] &= 0xfc; } netif->linkoutput = zepif_linkoutput; if (!zep_lowpan_timer_running) { sys_timeout(LOWPAN6_TMR_INTERVAL, zep_lowpan_timer, NULL); zep_lowpan_timer_running = 1; } return ERR_OK; } err_ret: if (state->pcb != NULL) { udp_remove(state->pcb); } mem_free(state); return err; }