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;

}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #6
0
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;
    }
}
Exemple #7
0
/** 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;
}
Exemple #8
0
/**
 * 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;
}
Exemple #9
0
/**
 * 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;
}
Exemple #10
0
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;
    }
}
Exemple #11
0
/**
 * @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;
}