Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
LWIPInterface.cpp
00001 /* Copyright (c) 2017 ARM Limited 00002 * 00003 * Licensed under the Apache License, Version 2.0 (the "License"); 00004 * you may not use this file except in compliance with the License. 00005 * You may obtain a copy of the License at 00006 * 00007 * http://www.apache.org/licenses/LICENSE-2.0 00008 * 00009 * Unless required by applicable law or agreed to in writing, software 00010 * distributed under the License is distributed on an "AS IS" BASIS, 00011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 * See the License for the specific language governing permissions and 00013 * limitations under the License. 00014 */ 00015 00016 #define __STDC_LIMIT_MACROS 00017 00018 #include "nsapi.h" 00019 #include "mbed_interface.h" 00020 #include "mbed_assert.h" 00021 #include <stdio.h> 00022 #include <stdbool.h> 00023 #include <string.h> 00024 #include <new> 00025 #include <stdint.h> 00026 00027 #include "lwip/opt.h" 00028 #include "lwip/api.h" 00029 #include "lwip/inet.h" 00030 #include "lwip/netif.h" 00031 #include "lwip/dhcp.h" 00032 #include "lwip/tcpip.h" 00033 #include "lwip/tcp.h" 00034 #include "lwip/ip.h" 00035 #include "lwip/mld6.h" 00036 #include "lwip/dns.h" 00037 #include "lwip/udp.h" 00038 00039 #include "LWIPStack.h" 00040 #include "lwip_tools.h" 00041 00042 LWIP::Interface *LWIP::Interface::list; 00043 00044 LWIP::Interface *LWIP::Interface::our_if_from_netif(struct netif *netif) 00045 { 00046 for (Interface *interface = list; interface; interface = interface->next) { 00047 if (netif == &interface->netif) { 00048 return interface; 00049 } 00050 } 00051 00052 return NULL; 00053 } 00054 00055 static void add_dns_addr_to_dns_list_index(const u8_t addr_type, const u8_t index, struct netif *netif) 00056 { 00057 #if LWIP_IPV6 00058 if (addr_type == IPADDR_TYPE_V6) { 00059 /* 2001:4860:4860::8888 google */ 00060 ip_addr_t ipv6_dns_addr = IPADDR6_INIT( 00061 PP_HTONL(0x20014860UL), 00062 PP_HTONL(0x48600000UL), 00063 PP_HTONL(0x00000000UL), 00064 PP_HTONL(0x00008888UL)); 00065 dns_setserver(index, &ipv6_dns_addr, netif); 00066 } 00067 #endif 00068 #if LWIP_IPV4 00069 if (addr_type == IPADDR_TYPE_V4) { 00070 /* 8.8.8.8 google */ 00071 ip_addr_t ipv4_dns_addr = IPADDR4_INIT(0x08080808); 00072 dns_setserver(index, &ipv4_dns_addr, netif); 00073 } 00074 #endif 00075 } 00076 00077 static int get_ip_addr_type(const ip_addr_t *ip_addr) 00078 { 00079 #if LWIP_IPV6 00080 if (IP_IS_V6(ip_addr)) { 00081 return IPADDR_TYPE_V6; 00082 } 00083 #endif 00084 #if LWIP_IPV4 00085 if (IP_IS_V4(ip_addr)) { 00086 return IPADDR_TYPE_V4; 00087 } 00088 #endif 00089 #if LWIP_IPV6 && LWIP_IPV4 00090 return IPADDR_TYPE_ANY; 00091 #endif 00092 } 00093 00094 void LWIP::add_dns_addr(struct netif *lwip_netif, const char *interface_name) 00095 { 00096 // Check for existing dns address 00097 for (char numdns = 0; numdns < DNS_MAX_SERVERS; numdns++) { 00098 const ip_addr_t *dns_ip_addr = dns_getserver(numdns, interface_name); 00099 if (!ip_addr_isany(dns_ip_addr)) { 00100 return; 00101 } 00102 } 00103 00104 // Get preferred ip version 00105 const ip_addr_t *ip_addr = get_ip_addr(false, lwip_netif); 00106 u8_t addr_type = IPADDR_TYPE_ANY; 00107 00108 // Add preferred ip version dns address to index 0 00109 if (ip_addr) { 00110 addr_type = get_ip_addr_type(ip_addr); 00111 add_dns_addr_to_dns_list_index(addr_type, 0, lwip_netif); 00112 } 00113 00114 #if LWIP_IPV4 && LWIP_IPV6 00115 if (!ip_addr) { 00116 // Get address for any ip version 00117 ip_addr = get_ip_addr(true, lwip_netif); 00118 if (!ip_addr) { 00119 return; 00120 } 00121 addr_type = get_ip_addr_type(ip_addr); 00122 // Add the dns address to index 0 00123 add_dns_addr_to_dns_list_index(addr_type, 0, lwip_netif); 00124 } 00125 00126 if (addr_type == IPADDR_TYPE_V4) { 00127 // If ipv4 is preferred and ipv6 is available add ipv6 dns address to index 1 00128 ip_addr = get_ipv6_addr(lwip_netif); 00129 } else if (addr_type == IPADDR_TYPE_V6) { 00130 // If ipv6 is preferred and ipv4 is available add ipv4 dns address to index 1 00131 ip_addr = get_ipv4_addr(lwip_netif); 00132 } else { 00133 ip_addr = NULL; 00134 } 00135 00136 if (ip_addr) { 00137 addr_type = get_ip_addr_type(ip_addr); 00138 add_dns_addr_to_dns_list_index(addr_type, 1, lwip_netif); 00139 } 00140 #endif 00141 } 00142 00143 nsapi_error_t LWIP::Interface::set_dhcp() 00144 { 00145 netif_set_up(&netif); 00146 00147 #if LWIP_DHCP 00148 if (dhcp_has_to_be_set) { 00149 err_t err = dhcp_start(&netif); 00150 dhcp_has_to_be_set = false; 00151 if (err) { 00152 connected = NSAPI_STATUS_DISCONNECTED ; 00153 if (client_callback) { 00154 client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , NSAPI_STATUS_DISCONNECTED ); 00155 } 00156 return NSAPI_ERROR_DHCP_FAILURE ; 00157 } 00158 dhcp_started = true; 00159 } 00160 #endif 00161 00162 return NSAPI_ERROR_OK ; 00163 } 00164 00165 void LWIP::Interface::netif_link_irq(struct netif *netif) 00166 { 00167 LWIP::Interface *interface = our_if_from_netif(netif); 00168 nsapi_connection_status_t connectedStatusPrev = interface->connected; 00169 00170 if (netif_is_link_up(&interface->netif) && interface->connected == NSAPI_STATUS_CONNECTING ) { 00171 nsapi_error_t dhcp_status = interface->set_dhcp(); 00172 00173 if (interface->blocking && dhcp_status == NSAPI_ERROR_OK ) { 00174 osSemaphoreRelease(interface->linked); 00175 } else if (dhcp_status != NSAPI_ERROR_OK ) { 00176 netif_set_down(&interface->netif); 00177 } 00178 } else { 00179 osSemaphoreRelease(interface->unlinked); 00180 if (netif_is_up(&interface->netif)) { 00181 interface->connected = NSAPI_STATUS_CONNECTING ; 00182 } 00183 netif_set_down(&interface->netif); 00184 } 00185 00186 if (interface->client_callback && connectedStatusPrev != interface->connected 00187 && interface->connected != NSAPI_STATUS_GLOBAL_UP /* advertised by netif_status_irq */ 00188 && interface->connected != NSAPI_STATUS_DISCONNECTED ) { /* advertised by bring_down */ 00189 interface->client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , interface->connected); 00190 } 00191 } 00192 00193 void LWIP::Interface::netif_status_irq(struct netif *netif) 00194 { 00195 LWIP::Interface *interface = our_if_from_netif(netif); 00196 nsapi_connection_status_t connectedStatusPrev = interface->connected; 00197 00198 if (netif_is_up(&interface->netif) && netif_is_link_up(&interface->netif)) { 00199 bool dns_addr_has_to_be_added = false; 00200 if (!(interface->has_addr_state & HAS_ANY_ADDR) && LWIP::get_ip_addr(true, netif)) { 00201 if (interface->blocking) { 00202 osSemaphoreRelease(interface->has_any_addr); 00203 } 00204 interface->has_addr_state |= HAS_ANY_ADDR; 00205 dns_addr_has_to_be_added = true; 00206 } 00207 #if PREF_ADDR_TIMEOUT 00208 if (!(interface->has_addr_state & HAS_PREF_ADDR) && LWIP::get_ip_addr(false, netif)) { 00209 if (interface->blocking) { 00210 osSemaphoreRelease(interface->has_pref_addr); 00211 } 00212 interface->has_addr_state |= HAS_PREF_ADDR; 00213 dns_addr_has_to_be_added = true; 00214 } 00215 #endif 00216 #if BOTH_ADDR_TIMEOUT 00217 if (!(interface->has_addr_state & HAS_BOTH_ADDR) && LWIP::get_ipv4_addr(netif) && LWIP::get_ipv6_addr(netif)) { 00218 if (interface->blocking) { 00219 osSemaphoreRelease(interface->has_both_addr); 00220 } 00221 interface->has_addr_state |= HAS_BOTH_ADDR; 00222 dns_addr_has_to_be_added = true; 00223 } 00224 #endif 00225 if (dns_addr_has_to_be_added && !interface->blocking) { 00226 add_dns_addr(&interface->netif, interface->get_interface_name(interface->_interface_name)); 00227 } 00228 00229 if (interface->has_addr_state & HAS_ANY_ADDR) { 00230 interface->connected = NSAPI_STATUS_GLOBAL_UP ; 00231 #if LWIP_IPV6 00232 if (ip_addr_islinklocal(get_ipv6_addr(netif))) { 00233 interface->connected = NSAPI_STATUS_LOCAL_UP ; 00234 } 00235 #endif 00236 } 00237 00238 } else if (!netif_is_up(&interface->netif) && netif_is_link_up(&interface->netif)) { 00239 interface->connected = NSAPI_STATUS_DISCONNECTED ; 00240 } 00241 00242 if (interface->client_callback && (connectedStatusPrev != interface->connected) 00243 && interface->connected != NSAPI_STATUS_DISCONNECTED ) { /* advertised by bring_down */ 00244 interface->client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , interface->connected); 00245 } 00246 } 00247 00248 void LWIP::Interface::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) 00249 { 00250 client_callback = status_cb; 00251 } 00252 00253 nsapi_connection_status_t LWIP::Interface::get_connection_status() const 00254 { 00255 return connected; 00256 } 00257 00258 #if LWIP_IPV6 00259 static void mbed_lwip_clear_ipv6_addresses(struct netif *netif) 00260 { 00261 for (u8_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00262 netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); 00263 } 00264 } 00265 #endif 00266 00267 char *LWIP::Interface::get_mac_address(char *buf, nsapi_size_t buflen) 00268 { 00269 (void) snprintf(buf, buflen, "%02x:%02x:%02x:%02x:%02x:%02x", 00270 netif.hwaddr[0], netif.hwaddr[1], netif.hwaddr[2], 00271 netif.hwaddr[3], netif.hwaddr[4], netif.hwaddr[5]); 00272 return buf; 00273 } 00274 00275 char *LWIP::Interface::get_interface_name(char *buf) 00276 { 00277 sprintf(buf, "%c%c%d", netif.name[0], netif.name[1], netif.num); 00278 return buf; 00279 } 00280 00281 nsapi_error_t LWIP::Interface::get_ipv6_link_local_address(SocketAddress *address) 00282 { 00283 #if LWIP_IPV6 00284 const ip_addr_t *addr = LWIP::get_ipv6_link_local_addr(&netif); 00285 nsapi_addr_t out; 00286 bool ret; 00287 00288 if (!addr) { 00289 return NSAPI_ERROR_PARAMETER ; 00290 } 00291 00292 ret = convert_lwip_addr_to_mbed(&out, addr); 00293 if (ret != true) { 00294 return NSAPI_ERROR_PARAMETER ; 00295 } 00296 00297 address->set_addr(out); 00298 00299 return NSAPI_ERROR_OK ; 00300 #else 00301 return NSAPI_ERROR_UNSUPPORTED ; 00302 #endif 00303 } 00304 00305 nsapi_error_t LWIP::Interface::get_ip_address(SocketAddress *address) 00306 { 00307 if (!address) { 00308 return NSAPI_ERROR_PARAMETER ; 00309 } 00310 const ip_addr_t *addr = LWIP::get_ip_addr(true, &netif); 00311 if (!addr) { 00312 return NSAPI_ERROR_NO_ADDRESS ; 00313 } 00314 #if LWIP_IPV6 00315 if (IP_IS_V6(addr)) { 00316 char buf[NSAPI_IPv6_SIZE]; 00317 address->set_ip_address(ip6addr_ntoa_r(ip_2_ip6(addr), buf, NSAPI_IPv6_SIZE)); 00318 return NSAPI_ERROR_OK ; 00319 } 00320 #endif 00321 #if LWIP_IPV4 00322 if (IP_IS_V4(addr)) { 00323 char buf[NSAPI_IPv4_SIZE]; 00324 address->set_ip_address(ip4addr_ntoa_r(ip_2_ip4(addr), buf, NSAPI_IPv4_SIZE)); 00325 return NSAPI_ERROR_OK ; 00326 } 00327 #endif 00328 return NSAPI_ERROR_UNSUPPORTED ; 00329 } 00330 00331 char *LWIP::Interface::get_ip_address(char *buf, nsapi_size_t buflen) 00332 { 00333 const ip_addr_t *addr = LWIP::get_ip_addr(true, &netif); 00334 if (!addr) { 00335 return NULL; 00336 } 00337 #if LWIP_IPV6 00338 if (IP_IS_V6(addr)) { 00339 return ip6addr_ntoa_r(ip_2_ip6(addr), buf, buflen); 00340 } 00341 #endif 00342 #if LWIP_IPV4 00343 if (IP_IS_V4(addr)) { 00344 return ip4addr_ntoa_r(ip_2_ip4(addr), buf, buflen); 00345 } 00346 #endif 00347 #if LWIP_IPV6 && LWIP_IPV4 00348 return NULL; 00349 #endif 00350 } 00351 00352 nsapi_error_t LWIP::Interface::get_netmask(SocketAddress *address) 00353 { 00354 if (!address) { 00355 return NSAPI_ERROR_PARAMETER ; 00356 } 00357 #if LWIP_IPV4 00358 const ip4_addr_t *addr = netif_ip4_netmask(&netif); 00359 if (!ip4_addr_isany(addr)) { 00360 char buf[NSAPI_IPv4_SIZE]; 00361 address->set_ip_address(ip4addr_ntoa_r(addr, buf, NSAPI_IPv4_SIZE)); 00362 return NSAPI_ERROR_OK ; 00363 } else { 00364 return NSAPI_ERROR_NO_ADDRESS ; 00365 } 00366 #else 00367 return NSAPI_ERROR_UNSUPPORTED ; 00368 #endif 00369 } 00370 00371 char *LWIP::Interface::get_netmask(char *buf, nsapi_size_t buflen) 00372 { 00373 #if LWIP_IPV4 00374 const ip4_addr_t *addr = netif_ip4_netmask(&netif); 00375 if (!ip4_addr_isany(addr)) { 00376 return ip4addr_ntoa_r(addr, buf, buflen); 00377 } else { 00378 return NULL; 00379 } 00380 #else 00381 return NULL; 00382 #endif 00383 } 00384 00385 nsapi_error_t LWIP::Interface::get_gateway(SocketAddress *address) 00386 { 00387 if (!address) { 00388 return NSAPI_ERROR_PARAMETER ; 00389 } 00390 #if LWIP_IPV4 00391 const ip4_addr_t *addr = netif_ip4_gw(&netif); 00392 if (!ip4_addr_isany(addr)) { 00393 char buf[NSAPI_IPv4_SIZE]; 00394 address->set_ip_address(ip4addr_ntoa_r(addr, buf, NSAPI_IPv4_SIZE)); 00395 return NSAPI_ERROR_OK ; 00396 } else { 00397 return NSAPI_ERROR_NO_ADDRESS ; 00398 } 00399 #else 00400 return NSAPI_ERROR_UNSUPPORTED ; 00401 #endif 00402 } 00403 00404 char *LWIP::Interface::get_gateway(char *buf, nsapi_size_t buflen) 00405 { 00406 #if LWIP_IPV4 00407 const ip4_addr_t *addr = netif_ip4_gw(&netif); 00408 if (!ip4_addr_isany(addr)) { 00409 return ip4addr_ntoa_r(addr, buf, buflen); 00410 } else { 00411 return NULL; 00412 } 00413 #else 00414 return NULL; 00415 #endif 00416 } 00417 00418 LWIP::Interface::Interface() : 00419 hw(NULL), has_addr_state(0), 00420 connected(NSAPI_STATUS_DISCONNECTED ), 00421 dhcp_started(false), dhcp_has_to_be_set(false), blocking(true), ppp_enabled(false) 00422 { 00423 memset(&netif, 0, sizeof netif); 00424 00425 osSemaphoreAttr_t attr; 00426 attr.name = NULL; 00427 attr.attr_bits = 0; 00428 00429 attr.cb_mem = &linked_sem; 00430 attr.cb_size = sizeof linked_sem; 00431 linked = osSemaphoreNew(UINT16_MAX, 0, &attr); 00432 00433 attr.cb_mem = &unlinked_sem; 00434 attr.cb_size = sizeof unlinked_sem; 00435 unlinked = osSemaphoreNew(UINT16_MAX, 0, &attr); 00436 00437 attr.cb_mem = &has_any_addr_sem; 00438 attr.cb_size = sizeof has_any_addr_sem; 00439 has_any_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); 00440 #if PREF_ADDR_TIMEOUT 00441 attr.cb_mem = &has_pref_addr_sem; 00442 attr.cb_size = sizeof has_pref_addr_sem; 00443 has_pref_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); 00444 #endif 00445 #if BOTH_ADDR_TIMEOUT 00446 attr.cb_mem = &has_both_addr_sem; 00447 attr.cb_size = sizeof has_both_addr_sem; 00448 has_both_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); 00449 #endif 00450 00451 next = list; 00452 list = this; 00453 } 00454 00455 nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) 00456 { 00457 #if LWIP_ETHERNET 00458 Interface *interface = new (std::nothrow) Interface(); 00459 if (!interface) { 00460 return NSAPI_ERROR_NO_MEMORY ; 00461 } 00462 interface->emac = &emac; 00463 interface->memory_manager = &memory_manager; 00464 interface->ppp_enabled = false; 00465 00466 #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) 00467 netif->interface.hwaddr[0] = MBED_MAC_ADDR_0; 00468 netif->interface.hwaddr[1] = MBED_MAC_ADDR_1; 00469 netif->interface.hwaddr[2] = MBED_MAC_ADDR_2; 00470 netif->interface.hwaddr[3] = MBED_MAC_ADDR_3; 00471 netif->interface.hwaddr[4] = MBED_MAC_ADDR_4; 00472 netif->interface.hwaddr[5] = MBED_MAC_ADDR_5; 00473 #else 00474 mbed_mac_address((char *) interface->netif.hwaddr); 00475 #endif 00476 00477 interface->netif.hwaddr_len = 6; 00478 00479 if (!netif_add(&interface->netif, 00480 #if LWIP_IPV4 00481 0, 0, 0, 00482 #endif 00483 interface, &LWIP::Interface::emac_if_init, tcpip_input)) { 00484 return NSAPI_ERROR_DEVICE_ERROR ; 00485 } 00486 00487 if (default_if) { 00488 netif_set_default(&interface->netif); 00489 default_interface = interface; 00490 } 00491 00492 netif_set_link_callback(&interface->netif, &LWIP::Interface::netif_link_irq); 00493 netif_set_status_callback(&interface->netif, &LWIP::Interface::netif_status_irq); 00494 00495 *interface_out = interface; 00496 00497 /* Use mac address as additional seed to random number generator */ 00498 uint64_t seed = interface->netif.hwaddr[0]; 00499 for (uint8_t i = 1; i < 8; i++) { 00500 seed <<= 8; 00501 seed |= interface->netif.hwaddr[i % 6]; 00502 } 00503 lwip_add_random_seed(seed); 00504 00505 return NSAPI_ERROR_OK ; 00506 #else 00507 return NSAPI_ERROR_UNSUPPORTED ; 00508 #endif //LWIP_ETHERNET 00509 } 00510 00511 00512 nsapi_error_t LWIP::add_l3ip_interface(L3IP &l3ip, bool default_if, OnboardNetworkStack::Interface **interface_out) 00513 { 00514 #if LWIP_L3IP 00515 Interface *interface = new (std::nothrow) Interface(); 00516 if (!interface) { 00517 return NSAPI_ERROR_NO_MEMORY ; 00518 } 00519 interface->l3ip = &l3ip; 00520 interface->memory_manager = &memory_manager; 00521 interface->ppp_enabled = false; 00522 00523 00524 00525 // interface->netif.hwaddr_len = 0; should we set? 00526 00527 if (!netif_add(&interface->netif, 00528 #if LWIP_IPV4 00529 0, 0, 0, 00530 #endif 00531 interface, &LWIP::Interface::l3ip_if_init, ip_input)) { 00532 return NSAPI_ERROR_DEVICE_ERROR ; 00533 } 00534 00535 if (default_if) { 00536 netif_set_default(&interface->netif); 00537 default_interface = interface; 00538 } 00539 00540 netif_set_link_callback(&interface->netif, &LWIP::Interface::netif_link_irq); 00541 netif_set_status_callback(&interface->netif, &LWIP::Interface::netif_status_irq); 00542 00543 *interface_out = interface; 00544 00545 00546 //lwip_add_random_seed(seed); to do? 00547 00548 return NSAPI_ERROR_OK ; 00549 00550 #else 00551 return NSAPI_ERROR_UNSUPPORTED ; 00552 00553 #endif //LWIP_L3IP 00554 } 00555 00556 nsapi_error_t LWIP::remove_l3ip_interface(OnboardNetworkStack::Interface **interface_out) 00557 { 00558 #if LWIP_L3IP 00559 if ((interface_out != NULL) && (*interface_out != NULL)) { 00560 00561 Interface *lwip = static_cast<Interface *>(*interface_out); 00562 Interface *node = lwip->list; 00563 00564 if (lwip->list != NULL) { 00565 if (lwip->list == lwip) { 00566 lwip->list = lwip->list->next; 00567 netif_remove(&node->netif); 00568 delete node; 00569 } else { 00570 while (node->next != NULL && node->next != lwip) { 00571 node = node->next; 00572 } 00573 if (node->next != NULL && node->next == lwip) { 00574 Interface *remove = node->next; 00575 node->next = node->next->next; 00576 remove->l3ip->power_down(); 00577 netif_remove(&remove->netif); 00578 delete remove; 00579 } 00580 } 00581 } 00582 } 00583 00584 return NSAPI_ERROR_OK ; 00585 #else 00586 return NSAPI_ERROR_UNSUPPORTED ; 00587 00588 #endif //LWIP_L3IP 00589 } 00590 00591 00592 nsapi_error_t LWIP::add_ppp_interface(PPP &ppp, bool default_if, OnboardNetworkStack::Interface **interface_out) 00593 { 00594 #if PPP_SUPPORT 00595 Interface *interface = new (std::nothrow) Interface(); 00596 if (!interface) { 00597 return NSAPI_ERROR_NO_MEMORY ; 00598 } 00599 interface->ppp = &ppp; 00600 interface->memory_manager = &memory_manager; 00601 interface->ppp_enabled = true; 00602 00603 // interface->netif.hwaddr_len = 0; should we set? 00604 00605 if (!netif_add(&interface->netif, 00606 #if LWIP_IPV4 00607 0, 0, 0, 00608 #endif 00609 interface, &LWIP::Interface::ppp_if_init, tcpip_input)) { 00610 return NSAPI_ERROR_DEVICE_ERROR ; 00611 } 00612 00613 if (default_if) { 00614 netif_set_default(&interface->netif); 00615 default_interface = interface; 00616 } 00617 00618 netif_set_link_callback(&interface->netif, &LWIP::Interface::netif_link_irq); 00619 netif_set_status_callback(&interface->netif, &LWIP::Interface::netif_status_irq); 00620 00621 *interface_out = interface; 00622 00623 //lwip_add_random_seed(seed); to do? 00624 00625 return NSAPI_ERROR_OK ; 00626 00627 #else 00628 return NSAPI_ERROR_UNSUPPORTED ; 00629 00630 #endif //PPP_SUPPORT 00631 } 00632 00633 nsapi_error_t LWIP::remove_ppp_interface(OnboardNetworkStack::Interface **interface_out) 00634 { 00635 #if PPP_SUPPORT 00636 if ((interface_out != NULL) && (*interface_out != NULL)) { 00637 00638 Interface *lwip = static_cast<Interface *>(*interface_out); 00639 Interface *node = lwip->list; 00640 00641 if (lwip->list != NULL) { 00642 if (lwip->list == lwip) { 00643 // Power down PPP service 00644 lwip->ppp->power_down(); 00645 if (netif_is_link_up(&lwip->netif)) { 00646 // Wait PPP service to report link down 00647 osSemaphoreAcquire(lwip->unlinked, osWaitForever); 00648 } 00649 netif_remove(&node->netif); 00650 lwip->list = lwip->list->next; 00651 delete node; 00652 } else { 00653 while (node->next != NULL && node->next != lwip) { 00654 node = node->next; 00655 } 00656 if (node->next != NULL && node->next == lwip) { 00657 Interface *remove = node->next; 00658 // Power down PPP service 00659 remove->ppp->power_down(); 00660 if (netif_is_link_up(&lwip->netif)) { 00661 // Wait PPP service to report link down 00662 osSemaphoreAcquire(lwip->unlinked, osWaitForever); 00663 } 00664 netif_remove(&remove->netif); 00665 node->next = node->next->next; 00666 delete remove; 00667 } 00668 } 00669 } 00670 } 00671 00672 return NSAPI_ERROR_OK ; 00673 #else 00674 return NSAPI_ERROR_UNSUPPORTED ; 00675 00676 #endif //PPP_SUPPORT 00677 } 00678 00679 void LWIP::set_default_interface(OnboardNetworkStack::Interface *interface) 00680 { 00681 if (interface) { 00682 default_interface = static_cast<LWIP::Interface *>(interface); 00683 netif_set_default(&default_interface->netif); 00684 } 00685 } 00686 00687 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) 00688 { 00689 // Check if we've already connected 00690 if (connected == NSAPI_STATUS_GLOBAL_UP ) { 00691 return NSAPI_ERROR_IS_CONNECTED ; 00692 } else if (connected == NSAPI_STATUS_CONNECTING ) { 00693 return NSAPI_ERROR_BUSY ; 00694 } 00695 00696 connected = NSAPI_STATUS_CONNECTING ; 00697 blocking = block; 00698 00699 #if LWIP_DHCP 00700 if (stack != IPV6_STACK && dhcp) { 00701 dhcp_has_to_be_set = true; 00702 } 00703 #endif 00704 00705 #if LWIP_IPV6 00706 if (stack != IPV4_STACK) { 00707 if (netif.hwaddr_len == 6) { 00708 netif_create_ip6_linklocal_address(&netif, 1/*from MAC*/); 00709 } 00710 #if LWIP_IPV6_MLD 00711 /* 00712 * For hardware/netifs that implement MAC filtering. 00713 * All-nodes link-local is handled by default, so we must let the hardware know 00714 * to allow multicast packets in. 00715 * Should set mld_mac_filter previously. */ 00716 if (netif.mld_mac_filter != NULL) { 00717 ip6_addr_t ip6_allnodes_ll; 00718 ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); 00719 netif.mld_mac_filter(&netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); 00720 } 00721 #endif /* LWIP_IPV6_MLD */ 00722 00723 #if LWIP_IPV6_AUTOCONFIG 00724 /* IPv6 address autoconfiguration not enabled by default */ 00725 netif.ip6_autoconfig_enabled = 1; 00726 #endif /* LWIP_IPV6_AUTOCONFIG */ 00727 } else { 00728 // Disable rourter solicitations 00729 netif.rs_count = 0; 00730 } 00731 #endif /* LWIP_IPV6 */ 00732 00733 #if LWIP_IPV4 00734 if (stack != IPV6_STACK) { 00735 if (!dhcp && !ppp_enabled) { 00736 ip4_addr_t ip_addr; 00737 ip4_addr_t netmask_addr; 00738 ip4_addr_t gw_addr; 00739 00740 if (!inet_aton(ip, &ip_addr) || 00741 !inet_aton(netmask, &netmask_addr) || 00742 !inet_aton(gw, &gw_addr)) { 00743 return NSAPI_ERROR_PARAMETER ; 00744 } 00745 00746 netif_set_addr(&netif, &ip_addr, &netmask_addr, &gw_addr); 00747 } 00748 } 00749 #endif 00750 00751 if (client_callback) { 00752 client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , NSAPI_STATUS_CONNECTING ); 00753 } 00754 00755 00756 if (!netif_is_link_up(&netif)) { 00757 if (blocking) { 00758 if (osSemaphoreAcquire(linked, LINK_TIMEOUT * 1000) != osOK) { 00759 return NSAPI_ERROR_NO_CONNECTION ; 00760 } 00761 } 00762 } else { 00763 nsapi_error_t ret = set_dhcp(); 00764 if (ret != NSAPI_ERROR_OK ) { 00765 return ret; 00766 } 00767 } 00768 00769 if (!blocking) { 00770 // Done enough - as addresses are acquired, there will be 00771 // connected callbacks. 00772 return NSAPI_ERROR_OK ; 00773 } 00774 00775 // If doesn't have address 00776 if (!LWIP::get_ip_addr(true, &netif)) { 00777 if (osSemaphoreAcquire(has_any_addr, DHCP_TIMEOUT * 1000) != osOK) { 00778 return NSAPI_ERROR_DHCP_FAILURE ; 00779 } 00780 } 00781 00782 #if PREF_ADDR_TIMEOUT 00783 if (stack != IPV4_STACK && stack != IPV6_STACK) { 00784 // If address is not for preferred stack waits a while to see 00785 // if preferred stack address is acquired 00786 if (!LWIP::get_ip_addr(false, &netif)) { 00787 osSemaphoreAcquire(has_pref_addr, PREF_ADDR_TIMEOUT * 1000); 00788 } 00789 } 00790 #endif 00791 #if BOTH_ADDR_TIMEOUT 00792 if (stack != IPV4_STACK && stack != IPV6_STACK) { 00793 // If addresses for both stacks are not available waits a while to 00794 // see if address for both stacks are acquired 00795 if (!(LWIP::get_ipv4_addr(&netif) && LWIP::get_ipv6_addr(&netif))) { 00796 osSemaphoreAcquire(has_both_addr, BOTH_ADDR_TIMEOUT * 1000); 00797 } 00798 } 00799 #endif 00800 00801 add_dns_addr(&netif, get_interface_name(_interface_name)); 00802 00803 return NSAPI_ERROR_OK ; 00804 } 00805 00806 nsapi_error_t LWIP::Interface::bringdown() 00807 { 00808 // Check if we've connected 00809 if (connected == NSAPI_STATUS_DISCONNECTED ) { 00810 return NSAPI_ERROR_NO_CONNECTION ; 00811 } 00812 00813 #if LWIP_DHCP 00814 // Disconnect from the network 00815 if (dhcp_started) { 00816 dhcp_release(&netif); 00817 dhcp_stop(&netif); 00818 dhcp_started = false; 00819 dhcp_has_to_be_set = false; 00820 } 00821 #endif 00822 00823 netif_set_down(&netif); 00824 00825 #if LWIP_IPV6 00826 mbed_lwip_clear_ipv6_addresses(&netif); 00827 #endif 00828 #if LWIP_IPV4 00829 ip_addr_set_zero(&(netif.ip_addr)); 00830 ip_addr_set_zero(&(netif.netmask)); 00831 ip_addr_set_zero(&(netif.gw)); 00832 #endif 00833 00834 osSemaphoreDelete(has_any_addr); 00835 osSemaphoreAttr_t attr; 00836 attr.name = NULL; 00837 attr.attr_bits = 0; 00838 attr.cb_mem = &has_any_addr_sem; 00839 attr.cb_size = sizeof has_any_addr_sem; 00840 has_any_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); 00841 #if PREF_ADDR_TIMEOUT 00842 osSemaphoreDelete(has_pref_addr); 00843 attr.cb_mem = &has_pref_addr_sem; 00844 attr.cb_size = sizeof has_pref_addr_sem; 00845 has_pref_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); 00846 #endif 00847 #if BOTH_ADDR_TIMEOUT 00848 osSemaphoreDelete(has_both_addr); 00849 attr.cb_mem = &has_both_addr_sem; 00850 attr.cb_size = sizeof has_both_addr_sem; 00851 has_both_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); 00852 #endif 00853 has_addr_state = 0; 00854 00855 connected = NSAPI_STATUS_DISCONNECTED ; 00856 if (client_callback) { 00857 client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE , connected); 00858 } 00859 return 0; 00860 }
Generated on Tue Jul 12 2022 13:54:31 by
1.7.2