nsapi_error_t mbed_lwip_bringdown_2(bool ppp) { // Check if we've connected if (lwip_connected == NSAPI_STATUS_DISCONNECTED) { return NSAPI_ERROR_PARAMETER; } #if LWIP_DHCP // Disconnect from the network if (lwip_dhcp) { dhcp_release(&lwip_netif); dhcp_stop(&lwip_netif); lwip_dhcp = false; lwip_dhcp_has_to_be_set = false; } #endif if (ppp) { /* this is a blocking call, returns when PPP is properly closed */ err_t err = ppp_lwip_disconnect(); if (err) { return mbed_lwip_err_remap(err); } MBED_ASSERT(!netif_is_link_up(&lwip_netif)); /*if (netif_is_link_up(&lwip_netif)) { if (sys_arch_sem_wait(&lwip_netif_unlinked, 15000) == SYS_ARCH_TIMEOUT) { return NSAPI_ERROR_DEVICE_ERROR; } }*/ } else { netif_set_down(&lwip_netif); } #if LWIP_IPV6 mbed_lwip_clear_ipv6_addresses(&lwip_netif); #endif sys_sem_free(&lwip_netif_has_any_addr); sys_sem_new(&lwip_netif_has_any_addr, 0); #if PREF_ADDR_TIMEOUT sys_sem_free(&lwip_netif_has_pref_addr); sys_sem_new(&lwip_netif_has_pref_addr, 0); #endif #if BOTH_ADDR_TIMEOUT sys_sem_free(&lwip_netif_has_both_addr); sys_sem_new(&lwip_netif_has_both_addr, 0); #endif lwip_has_addr_state = 0; lwip_connected = NSAPI_STATUS_DISCONNECTED; return 0; }
nsapi_error_t LWIP::Interface::bringdown() { // Check if we've connected if (connected == NSAPI_STATUS_DISCONNECTED) { return NSAPI_ERROR_NO_CONNECTION; } #if LWIP_DHCP // Disconnect from the network if (dhcp_started) { dhcp_release(&netif); dhcp_stop(&netif); dhcp_started = false; dhcp_has_to_be_set = false; } #endif if (ppp) { /* this is a blocking call, returns when PPP is properly closed */ err_t err = ppp_lwip_disconnect(hw); if (err) { return err_remap(err); } MBED_ASSERT(!netif_is_link_up(&netif)); /*if (netif_is_link_up(&netif)) { if (sys_arch_sem_wait(&unlinked, 15000) == SYS_ARCH_TIMEOUT) { return NSAPI_ERROR_DEVICE_ERROR; } }*/ } else { netif_set_down(&netif); } #if LWIP_IPV6 mbed_lwip_clear_ipv6_addresses(&netif); #endif #if LWIP_IPV4 ip_addr_set_zero(&(netif.ip_addr)); ip_addr_set_zero(&(netif.netmask)); ip_addr_set_zero(&(netif.gw)); #endif osSemaphoreDelete(has_any_addr); osSemaphoreAttr_t attr; attr.name = NULL; attr.attr_bits = 0; attr.cb_mem = &has_any_addr_sem; attr.cb_size = sizeof has_any_addr_sem; has_any_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); #if PREF_ADDR_TIMEOUT osSemaphoreDelete(has_pref_addr); attr.cb_mem = &has_pref_addr_sem; attr.cb_size = sizeof has_pref_addr_sem; has_pref_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); #endif #if BOTH_ADDR_TIMEOUT osSemaphoreDelete(has_both_addr); attr.cb_mem = &has_both_addr_sem; attr.cb_size = sizeof has_both_addr_sem; has_both_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); #endif has_addr_state = 0; connected = NSAPI_STATUS_DISCONNECTED; if (client_callback) { client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, connected); } return 0; }
nsapi_error_t LWIP::Interface::bringup(bool dhcp, const char *ip, const char *netmask, const char *gw, const nsapi_ip_stack_t stack, bool block) { // Check if we've already connected if (connected == NSAPI_STATUS_GLOBAL_UP) { return NSAPI_ERROR_IS_CONNECTED; } else if (connected == NSAPI_STATUS_CONNECTING) { return NSAPI_ERROR_ALREADY; } connected = NSAPI_STATUS_CONNECTING; blocking = block; #if LWIP_DHCP if (stack != IPV6_STACK && dhcp) { dhcp_has_to_be_set = true; } #endif #if LWIP_IPV6 if (stack != IPV4_STACK) { if (netif.hwaddr_len == 6) { netif_create_ip6_linklocal_address(&netif, 1/*from MAC*/); } #if LWIP_IPV6_MLD /* * For hardware/netifs that implement MAC filtering. * All-nodes link-local is handled by default, so we must let the hardware know * to allow multicast packets in. * Should set mld_mac_filter previously. */ if (netif.mld_mac_filter != NULL) { ip6_addr_t ip6_allnodes_ll; ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); netif.mld_mac_filter(&netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); } #endif /* LWIP_IPV6_MLD */ #if LWIP_IPV6_AUTOCONFIG /* IPv6 address autoconfiguration not enabled by default */ netif.ip6_autoconfig_enabled = 1; #endif /* LWIP_IPV6_AUTOCONFIG */ } else { // Disable rourter solicitations netif.rs_count = 0; } #endif /* LWIP_IPV6 */ #if LWIP_IPV4 if (stack != IPV6_STACK) { if (!dhcp && !ppp) { ip4_addr_t ip_addr; ip4_addr_t netmask_addr; ip4_addr_t gw_addr; if (!inet_aton(ip, &ip_addr) || !inet_aton(netmask, &netmask_addr) || !inet_aton(gw, &gw_addr)) { return NSAPI_ERROR_PARAMETER; } netif_set_addr(&netif, &ip_addr, &netmask_addr, &gw_addr); } } #endif if (client_callback) { client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING); } if (ppp) { err_t err = ppp_lwip_connect(hw); if (err) { connected = NSAPI_STATUS_DISCONNECTED; if (client_callback) { client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); } return err_remap(err); } } if (!netif_is_link_up(&netif)) { if (blocking) { if (osSemaphoreAcquire(linked, 15000) != osOK) { if (ppp) { (void) ppp_lwip_disconnect(hw); } return NSAPI_ERROR_NO_CONNECTION; } } } else { nsapi_error_t ret = set_dhcp(); if (ret != NSAPI_ERROR_OK) { return ret; } } if (!blocking) { // Done enough - as addresses are acquired, there will be // connected callbacks. // XXX shouldn't this be NSAPI_ERROR_IN_PROGRESS if in CONNECTING state? return NSAPI_ERROR_OK; } // If doesn't have address if (!LWIP::get_ip_addr(true, &netif)) { if (osSemaphoreAcquire(has_any_addr, DHCP_TIMEOUT * 1000) != osOK) { if (ppp) { (void) ppp_lwip_disconnect(hw); } return NSAPI_ERROR_DHCP_FAILURE; } } #if PREF_ADDR_TIMEOUT if (stack != IPV4_STACK && stack != IPV6_STACK) { // If address is not for preferred stack waits a while to see // if preferred stack address is acquired if (!LWIP::get_ip_addr(false, &netif)) { osSemaphoreAcquire(has_pref_addr, PREF_ADDR_TIMEOUT * 1000); } } #endif #if BOTH_ADDR_TIMEOUT if (stack != IPV4_STACK && stack != IPV6_STACK) { // If addresses for both stacks are not available waits a while to // see if address for both stacks are acquired if (!(LWIP::get_ipv4_addr(&netif) && LWIP::get_ipv6_addr(&netif))) { osSemaphoreAcquire(has_both_addr, BOTH_ADDR_TIMEOUT * 1000); } } #endif add_dns_addr(&netif); return NSAPI_ERROR_OK; }
nsapi_error_t mbed_lwip_bringup_2(bool dhcp, bool ppp, const char *ip, const char *netmask, const char *gw, const nsapi_ip_stack_t stack) { // Check if we've already connected if (lwip_connected == NSAPI_STATUS_GLOBAL_UP) { return NSAPI_ERROR_IS_CONNECTED; } else if (lwip_connected == NSAPI_STATUS_CONNECTING) { return NSAPI_ERROR_ALREADY; } lwip_connected = NSAPI_STATUS_CONNECTING; lwip_ppp = ppp; #if LWIP_DHCP lwip_dhcp_has_to_be_set = true; if (stack != IPV6_STACK) { lwip_dhcp = dhcp; } else { lwip_dhcp = false; } #endif mbed_lwip_core_init(); nsapi_error_t ret; if (netif_inited) { /* Can't cope with changing mode */ if (netif_is_ppp == ppp) { ret = NSAPI_ERROR_OK; } else { ret = NSAPI_ERROR_PARAMETER; } } else { if (ppp) { ret = ppp_lwip_if_init(&lwip_netif, stack); } else { ret = mbed_lwip_emac_init(NULL); } } if (ret != NSAPI_ERROR_OK) { lwip_connected = NSAPI_STATUS_DISCONNECTED; return ret; } if (lwip_client_callback) { lwip_client_callback(lwip_status_cb_handle, NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING); } netif_inited = true; if (ppp) { netif_is_ppp = ppp; } netif_set_default(&lwip_netif); netif_set_link_callback(&lwip_netif, mbed_lwip_netif_link_irq); netif_set_status_callback(&lwip_netif, mbed_lwip_netif_status_irq); #if LWIP_IPV6 if (stack != IPV4_STACK) { if (lwip_netif.hwaddr_len == ETH_HWADDR_LEN) { netif_create_ip6_linklocal_address(&lwip_netif, 1/*from MAC*/); } #if LWIP_IPV6_MLD /* * For hardware/netifs that implement MAC filtering. * All-nodes link-local is handled by default, so we must let the hardware know * to allow multicast packets in. * Should set mld_mac_filter previously. */ if (lwip_netif.mld_mac_filter != NULL) { ip6_addr_t ip6_allnodes_ll; ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); lwip_netif.mld_mac_filter(&lwip_netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); } #endif /* LWIP_IPV6_MLD */ #if LWIP_IPV6_AUTOCONFIG /* IPv6 address autoconfiguration not enabled by default */ lwip_netif.ip6_autoconfig_enabled = 1; } else { // Disable router solidifications lwip_netif.rs_count = 0; } #endif /* LWIP_IPV6_AUTOCONFIG */ #endif // LWIP_IPV6 #if LWIP_IPV4 if (stack != IPV6_STACK) { if (!dhcp && !ppp) { ip4_addr_t ip_addr; ip4_addr_t netmask_addr; ip4_addr_t gw_addr; if (!inet_aton(ip, &ip_addr) || !inet_aton(netmask, &netmask_addr) || !inet_aton(gw, &gw_addr)) { lwip_connected = NSAPI_STATUS_DISCONNECTED; if (lwip_client_callback) { lwip_client_callback(lwip_status_cb_handle, NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); } return NSAPI_ERROR_PARAMETER; } netif_set_addr(&lwip_netif, &ip_addr, &netmask_addr, &gw_addr); } } #endif if (ppp) { err_t err = ppp_lwip_connect(); if (err) { lwip_connected = NSAPI_STATUS_DISCONNECTED; if (lwip_client_callback) { lwip_client_callback(lwip_status_cb_handle, NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); } return mbed_lwip_err_remap(err); } } if (!netif_is_link_up(&lwip_netif)) { if (lwip_blocking) { if (sys_arch_sem_wait(&lwip_netif_linked, 15000) == SYS_ARCH_TIMEOUT) { if (ppp) { ppp_lwip_disconnect(); } return NSAPI_ERROR_NO_CONNECTION; } } } else { ret = mbed_set_dhcp(&lwip_netif); if (ret != NSAPI_ERROR_OK) { return ret; } } if (lwip_blocking) { // If doesn't have address if (!mbed_lwip_get_ip_addr(true, &lwip_netif)) { if (sys_arch_sem_wait(&lwip_netif_has_any_addr, DHCP_TIMEOUT * 1000) == SYS_ARCH_TIMEOUT) { if (ppp) { ppp_lwip_disconnect(); } return NSAPI_ERROR_DHCP_FAILURE; } } } else { return NSAPI_ERROR_OK; } #if PREF_ADDR_TIMEOUT if (stack != IPV4_STACK && stack != IPV6_STACK) { // If address is not for preferred stack waits a while to see // if preferred stack address is acquired if (!mbed_lwip_get_ip_addr(false, &lwip_netif)) { sys_arch_sem_wait(&lwip_netif_has_pref_addr, PREF_ADDR_TIMEOUT * 1000); } } #endif #if BOTH_ADDR_TIMEOUT if (stack != IPV4_STACK && stack != IPV6_STACK) { // If addresses for both stacks are not available waits a while to // see if address for both stacks are acquired if (!(mbed_lwip_get_ipv4_addr(&lwip_netif) && mbed_lwip_get_ipv6_addr(&lwip_netif))) { sys_arch_sem_wait(&lwip_netif_has_both_addr, BOTH_ADDR_TIMEOUT * 1000); } } #endif add_dns_addr(&lwip_netif); return NSAPI_ERROR_OK; }