RTC auf true
features/lwipstack/LWIPInterface.cpp@0:38ceb79fef03, 2018-11-28 (annotated)
- Committer:
- kevman
- Date:
- Wed Nov 28 15:10:15 2018 +0000
- Revision:
- 0:38ceb79fef03
RTC modified
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
kevman | 0:38ceb79fef03 | 1 | /* Copyright (c) 2017 ARM Limited |
kevman | 0:38ceb79fef03 | 2 | * |
kevman | 0:38ceb79fef03 | 3 | * Licensed under the Apache License, Version 2.0 (the "License"); |
kevman | 0:38ceb79fef03 | 4 | * you may not use this file except in compliance with the License. |
kevman | 0:38ceb79fef03 | 5 | * You may obtain a copy of the License at |
kevman | 0:38ceb79fef03 | 6 | * |
kevman | 0:38ceb79fef03 | 7 | * http://www.apache.org/licenses/LICENSE-2.0 |
kevman | 0:38ceb79fef03 | 8 | * |
kevman | 0:38ceb79fef03 | 9 | * Unless required by applicable law or agreed to in writing, software |
kevman | 0:38ceb79fef03 | 10 | * distributed under the License is distributed on an "AS IS" BASIS, |
kevman | 0:38ceb79fef03 | 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
kevman | 0:38ceb79fef03 | 12 | * See the License for the specific language governing permissions and |
kevman | 0:38ceb79fef03 | 13 | * limitations under the License. |
kevman | 0:38ceb79fef03 | 14 | */ |
kevman | 0:38ceb79fef03 | 15 | |
kevman | 0:38ceb79fef03 | 16 | #define __STDC_LIMIT_MACROS |
kevman | 0:38ceb79fef03 | 17 | |
kevman | 0:38ceb79fef03 | 18 | #include "nsapi.h" |
kevman | 0:38ceb79fef03 | 19 | #include "mbed_interface.h" |
kevman | 0:38ceb79fef03 | 20 | #include "mbed_assert.h" |
kevman | 0:38ceb79fef03 | 21 | #include <stdio.h> |
kevman | 0:38ceb79fef03 | 22 | #include <stdbool.h> |
kevman | 0:38ceb79fef03 | 23 | #include <string.h> |
kevman | 0:38ceb79fef03 | 24 | #include <new> |
kevman | 0:38ceb79fef03 | 25 | #include <stdint.h> |
kevman | 0:38ceb79fef03 | 26 | |
kevman | 0:38ceb79fef03 | 27 | #include "lwip/opt.h" |
kevman | 0:38ceb79fef03 | 28 | #include "lwip/api.h" |
kevman | 0:38ceb79fef03 | 29 | #include "lwip/inet.h" |
kevman | 0:38ceb79fef03 | 30 | #include "lwip/netif.h" |
kevman | 0:38ceb79fef03 | 31 | #include "lwip/dhcp.h" |
kevman | 0:38ceb79fef03 | 32 | #include "lwip/tcpip.h" |
kevman | 0:38ceb79fef03 | 33 | #include "lwip/tcp.h" |
kevman | 0:38ceb79fef03 | 34 | #include "lwip/ip.h" |
kevman | 0:38ceb79fef03 | 35 | #include "lwip/mld6.h" |
kevman | 0:38ceb79fef03 | 36 | #include "lwip/dns.h" |
kevman | 0:38ceb79fef03 | 37 | #include "lwip/udp.h" |
kevman | 0:38ceb79fef03 | 38 | |
kevman | 0:38ceb79fef03 | 39 | #include "ppp_lwip.h" |
kevman | 0:38ceb79fef03 | 40 | |
kevman | 0:38ceb79fef03 | 41 | #include "LWIPStack.h" |
kevman | 0:38ceb79fef03 | 42 | |
kevman | 0:38ceb79fef03 | 43 | LWIP::Interface *LWIP::Interface::list; |
kevman | 0:38ceb79fef03 | 44 | |
kevman | 0:38ceb79fef03 | 45 | LWIP::Interface *LWIP::Interface::our_if_from_netif(struct netif *netif) |
kevman | 0:38ceb79fef03 | 46 | { |
kevman | 0:38ceb79fef03 | 47 | for (Interface *interface = list; interface; interface = interface->next) { |
kevman | 0:38ceb79fef03 | 48 | if (netif == &interface->netif) { |
kevman | 0:38ceb79fef03 | 49 | return interface; |
kevman | 0:38ceb79fef03 | 50 | } |
kevman | 0:38ceb79fef03 | 51 | } |
kevman | 0:38ceb79fef03 | 52 | |
kevman | 0:38ceb79fef03 | 53 | return NULL; |
kevman | 0:38ceb79fef03 | 54 | } |
kevman | 0:38ceb79fef03 | 55 | |
kevman | 0:38ceb79fef03 | 56 | static void add_dns_addr_to_dns_list_index(const u8_t addr_type, const u8_t index) |
kevman | 0:38ceb79fef03 | 57 | { |
kevman | 0:38ceb79fef03 | 58 | #if LWIP_IPV6 |
kevman | 0:38ceb79fef03 | 59 | if (addr_type == IPADDR_TYPE_V6) { |
kevman | 0:38ceb79fef03 | 60 | /* 2001:4860:4860::8888 google */ |
kevman | 0:38ceb79fef03 | 61 | ip_addr_t ipv6_dns_addr = IPADDR6_INIT( |
kevman | 0:38ceb79fef03 | 62 | PP_HTONL(0x20014860UL), |
kevman | 0:38ceb79fef03 | 63 | PP_HTONL(0x48600000UL), |
kevman | 0:38ceb79fef03 | 64 | PP_HTONL(0x00000000UL), |
kevman | 0:38ceb79fef03 | 65 | PP_HTONL(0x00008888UL)); |
kevman | 0:38ceb79fef03 | 66 | dns_setserver(index, &ipv6_dns_addr); |
kevman | 0:38ceb79fef03 | 67 | } |
kevman | 0:38ceb79fef03 | 68 | #endif |
kevman | 0:38ceb79fef03 | 69 | #if LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 70 | if (addr_type == IPADDR_TYPE_V4) { |
kevman | 0:38ceb79fef03 | 71 | /* 8.8.8.8 google */ |
kevman | 0:38ceb79fef03 | 72 | ip_addr_t ipv4_dns_addr = IPADDR4_INIT(0x08080808); |
kevman | 0:38ceb79fef03 | 73 | dns_setserver(index, &ipv4_dns_addr); |
kevman | 0:38ceb79fef03 | 74 | } |
kevman | 0:38ceb79fef03 | 75 | #endif |
kevman | 0:38ceb79fef03 | 76 | } |
kevman | 0:38ceb79fef03 | 77 | |
kevman | 0:38ceb79fef03 | 78 | static int get_ip_addr_type(const ip_addr_t *ip_addr) |
kevman | 0:38ceb79fef03 | 79 | { |
kevman | 0:38ceb79fef03 | 80 | #if LWIP_IPV6 |
kevman | 0:38ceb79fef03 | 81 | if (IP_IS_V6(ip_addr)) { |
kevman | 0:38ceb79fef03 | 82 | return IPADDR_TYPE_V6; |
kevman | 0:38ceb79fef03 | 83 | } |
kevman | 0:38ceb79fef03 | 84 | #endif |
kevman | 0:38ceb79fef03 | 85 | #if LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 86 | if (IP_IS_V4(ip_addr)) { |
kevman | 0:38ceb79fef03 | 87 | return IPADDR_TYPE_V4; |
kevman | 0:38ceb79fef03 | 88 | } |
kevman | 0:38ceb79fef03 | 89 | #endif |
kevman | 0:38ceb79fef03 | 90 | #if LWIP_IPV6 && LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 91 | return IPADDR_TYPE_ANY; |
kevman | 0:38ceb79fef03 | 92 | #endif |
kevman | 0:38ceb79fef03 | 93 | } |
kevman | 0:38ceb79fef03 | 94 | |
kevman | 0:38ceb79fef03 | 95 | void LWIP::add_dns_addr(struct netif *lwip_netif) |
kevman | 0:38ceb79fef03 | 96 | { |
kevman | 0:38ceb79fef03 | 97 | // Check for existing dns address |
kevman | 0:38ceb79fef03 | 98 | for (char numdns = 0; numdns < DNS_MAX_SERVERS; numdns++) { |
kevman | 0:38ceb79fef03 | 99 | const ip_addr_t *dns_ip_addr = dns_getserver(numdns); |
kevman | 0:38ceb79fef03 | 100 | if (!ip_addr_isany(dns_ip_addr)) { |
kevman | 0:38ceb79fef03 | 101 | return; |
kevman | 0:38ceb79fef03 | 102 | } |
kevman | 0:38ceb79fef03 | 103 | } |
kevman | 0:38ceb79fef03 | 104 | |
kevman | 0:38ceb79fef03 | 105 | // Get preferred ip version |
kevman | 0:38ceb79fef03 | 106 | const ip_addr_t *ip_addr = get_ip_addr(false, lwip_netif); |
kevman | 0:38ceb79fef03 | 107 | u8_t addr_type = IPADDR_TYPE_ANY; |
kevman | 0:38ceb79fef03 | 108 | |
kevman | 0:38ceb79fef03 | 109 | // Add preferred ip version dns address to index 0 |
kevman | 0:38ceb79fef03 | 110 | if (ip_addr) { |
kevman | 0:38ceb79fef03 | 111 | addr_type = get_ip_addr_type(ip_addr); |
kevman | 0:38ceb79fef03 | 112 | add_dns_addr_to_dns_list_index(addr_type, 0); |
kevman | 0:38ceb79fef03 | 113 | } |
kevman | 0:38ceb79fef03 | 114 | |
kevman | 0:38ceb79fef03 | 115 | #if LWIP_IPV4 && LWIP_IPV6 |
kevman | 0:38ceb79fef03 | 116 | if (!ip_addr) { |
kevman | 0:38ceb79fef03 | 117 | // Get address for any ip version |
kevman | 0:38ceb79fef03 | 118 | ip_addr = get_ip_addr(true, lwip_netif); |
kevman | 0:38ceb79fef03 | 119 | if (!ip_addr) { |
kevman | 0:38ceb79fef03 | 120 | return; |
kevman | 0:38ceb79fef03 | 121 | } |
kevman | 0:38ceb79fef03 | 122 | addr_type = get_ip_addr_type(ip_addr); |
kevman | 0:38ceb79fef03 | 123 | // Add the dns address to index 0 |
kevman | 0:38ceb79fef03 | 124 | add_dns_addr_to_dns_list_index(addr_type, 0); |
kevman | 0:38ceb79fef03 | 125 | } |
kevman | 0:38ceb79fef03 | 126 | |
kevman | 0:38ceb79fef03 | 127 | if (addr_type == IPADDR_TYPE_V4) { |
kevman | 0:38ceb79fef03 | 128 | // If ipv4 is preferred and ipv6 is available add ipv6 dns address to index 1 |
kevman | 0:38ceb79fef03 | 129 | ip_addr = get_ipv6_addr(lwip_netif); |
kevman | 0:38ceb79fef03 | 130 | } else if (addr_type == IPADDR_TYPE_V6) { |
kevman | 0:38ceb79fef03 | 131 | // If ipv6 is preferred and ipv4 is available add ipv4 dns address to index 1 |
kevman | 0:38ceb79fef03 | 132 | ip_addr = get_ipv4_addr(lwip_netif); |
kevman | 0:38ceb79fef03 | 133 | } else { |
kevman | 0:38ceb79fef03 | 134 | ip_addr = NULL; |
kevman | 0:38ceb79fef03 | 135 | } |
kevman | 0:38ceb79fef03 | 136 | |
kevman | 0:38ceb79fef03 | 137 | if (ip_addr) { |
kevman | 0:38ceb79fef03 | 138 | addr_type = get_ip_addr_type(ip_addr); |
kevman | 0:38ceb79fef03 | 139 | add_dns_addr_to_dns_list_index(addr_type, 1); |
kevman | 0:38ceb79fef03 | 140 | } |
kevman | 0:38ceb79fef03 | 141 | #endif |
kevman | 0:38ceb79fef03 | 142 | } |
kevman | 0:38ceb79fef03 | 143 | |
kevman | 0:38ceb79fef03 | 144 | nsapi_error_t LWIP::Interface::set_dhcp() |
kevman | 0:38ceb79fef03 | 145 | { |
kevman | 0:38ceb79fef03 | 146 | netif_set_up(&netif); |
kevman | 0:38ceb79fef03 | 147 | |
kevman | 0:38ceb79fef03 | 148 | #if LWIP_DHCP |
kevman | 0:38ceb79fef03 | 149 | if (dhcp_has_to_be_set) { |
kevman | 0:38ceb79fef03 | 150 | err_t err = dhcp_start(&netif); |
kevman | 0:38ceb79fef03 | 151 | dhcp_has_to_be_set = false; |
kevman | 0:38ceb79fef03 | 152 | if (err) { |
kevman | 0:38ceb79fef03 | 153 | connected = NSAPI_STATUS_DISCONNECTED; |
kevman | 0:38ceb79fef03 | 154 | if (client_callback) { |
kevman | 0:38ceb79fef03 | 155 | client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); |
kevman | 0:38ceb79fef03 | 156 | } |
kevman | 0:38ceb79fef03 | 157 | return NSAPI_ERROR_DHCP_FAILURE; |
kevman | 0:38ceb79fef03 | 158 | } |
kevman | 0:38ceb79fef03 | 159 | dhcp_started = true; |
kevman | 0:38ceb79fef03 | 160 | } |
kevman | 0:38ceb79fef03 | 161 | #endif |
kevman | 0:38ceb79fef03 | 162 | |
kevman | 0:38ceb79fef03 | 163 | return NSAPI_ERROR_OK; |
kevman | 0:38ceb79fef03 | 164 | } |
kevman | 0:38ceb79fef03 | 165 | |
kevman | 0:38ceb79fef03 | 166 | void LWIP::Interface::netif_link_irq(struct netif *netif) |
kevman | 0:38ceb79fef03 | 167 | { |
kevman | 0:38ceb79fef03 | 168 | LWIP::Interface *interface = our_if_from_netif(netif); |
kevman | 0:38ceb79fef03 | 169 | nsapi_connection_status_t connectedStatusPrev = interface->connected; |
kevman | 0:38ceb79fef03 | 170 | |
kevman | 0:38ceb79fef03 | 171 | if (netif_is_link_up(&interface->netif) && interface->connected == NSAPI_STATUS_CONNECTING) { |
kevman | 0:38ceb79fef03 | 172 | nsapi_error_t dhcp_status = interface->set_dhcp(); |
kevman | 0:38ceb79fef03 | 173 | |
kevman | 0:38ceb79fef03 | 174 | if (interface->blocking && dhcp_status == NSAPI_ERROR_OK) { |
kevman | 0:38ceb79fef03 | 175 | osSemaphoreRelease(interface->linked); |
kevman | 0:38ceb79fef03 | 176 | } else if (dhcp_status != NSAPI_ERROR_OK) { |
kevman | 0:38ceb79fef03 | 177 | netif_set_down(&interface->netif); |
kevman | 0:38ceb79fef03 | 178 | } |
kevman | 0:38ceb79fef03 | 179 | } else { |
kevman | 0:38ceb79fef03 | 180 | osSemaphoreRelease(interface->unlinked); |
kevman | 0:38ceb79fef03 | 181 | if (netif_is_up(&interface->netif)) { |
kevman | 0:38ceb79fef03 | 182 | interface->connected = NSAPI_STATUS_CONNECTING; |
kevman | 0:38ceb79fef03 | 183 | } |
kevman | 0:38ceb79fef03 | 184 | netif_set_down(&interface->netif); |
kevman | 0:38ceb79fef03 | 185 | } |
kevman | 0:38ceb79fef03 | 186 | |
kevman | 0:38ceb79fef03 | 187 | if (interface->client_callback && connectedStatusPrev != interface->connected |
kevman | 0:38ceb79fef03 | 188 | && interface->connected != NSAPI_STATUS_GLOBAL_UP /* advertised by netif_status_irq */ |
kevman | 0:38ceb79fef03 | 189 | && interface->connected != NSAPI_STATUS_DISCONNECTED) /* advertised by bring_down */ { |
kevman | 0:38ceb79fef03 | 190 | interface->client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, interface->connected); |
kevman | 0:38ceb79fef03 | 191 | } |
kevman | 0:38ceb79fef03 | 192 | } |
kevman | 0:38ceb79fef03 | 193 | |
kevman | 0:38ceb79fef03 | 194 | void LWIP::Interface::netif_status_irq(struct netif *netif) |
kevman | 0:38ceb79fef03 | 195 | { |
kevman | 0:38ceb79fef03 | 196 | LWIP::Interface *interface = our_if_from_netif(netif); |
kevman | 0:38ceb79fef03 | 197 | nsapi_connection_status_t connectedStatusPrev = interface->connected; |
kevman | 0:38ceb79fef03 | 198 | |
kevman | 0:38ceb79fef03 | 199 | if (netif_is_up(&interface->netif) && netif_is_link_up(&interface->netif)) { |
kevman | 0:38ceb79fef03 | 200 | bool dns_addr_has_to_be_added = false; |
kevman | 0:38ceb79fef03 | 201 | if (!(interface->has_addr_state & HAS_ANY_ADDR) && LWIP::get_ip_addr(true, netif)) { |
kevman | 0:38ceb79fef03 | 202 | if (interface->blocking) { |
kevman | 0:38ceb79fef03 | 203 | osSemaphoreRelease(interface->has_any_addr); |
kevman | 0:38ceb79fef03 | 204 | } |
kevman | 0:38ceb79fef03 | 205 | interface->has_addr_state |= HAS_ANY_ADDR; |
kevman | 0:38ceb79fef03 | 206 | dns_addr_has_to_be_added = true; |
kevman | 0:38ceb79fef03 | 207 | } |
kevman | 0:38ceb79fef03 | 208 | #if PREF_ADDR_TIMEOUT |
kevman | 0:38ceb79fef03 | 209 | if (!(interface->has_addr_state & HAS_PREF_ADDR) && LWIP::get_ip_addr(false, netif)) { |
kevman | 0:38ceb79fef03 | 210 | if (interface->blocking) { |
kevman | 0:38ceb79fef03 | 211 | osSemaphoreRelease(interface->has_pref_addr); |
kevman | 0:38ceb79fef03 | 212 | } |
kevman | 0:38ceb79fef03 | 213 | interface->has_addr_state |= HAS_PREF_ADDR; |
kevman | 0:38ceb79fef03 | 214 | dns_addr_has_to_be_added = true; |
kevman | 0:38ceb79fef03 | 215 | } |
kevman | 0:38ceb79fef03 | 216 | #endif |
kevman | 0:38ceb79fef03 | 217 | #if BOTH_ADDR_TIMEOUT |
kevman | 0:38ceb79fef03 | 218 | if (!(interface->has_addr_state & HAS_BOTH_ADDR) && LWIP::get_ipv4_addr(netif) && LWIP::get_ipv6_addr(netif)) { |
kevman | 0:38ceb79fef03 | 219 | if (interface->blocking) { |
kevman | 0:38ceb79fef03 | 220 | osSemaphoreRelease(interface->has_both_addr); |
kevman | 0:38ceb79fef03 | 221 | } |
kevman | 0:38ceb79fef03 | 222 | interface->has_addr_state |= HAS_BOTH_ADDR; |
kevman | 0:38ceb79fef03 | 223 | dns_addr_has_to_be_added = true; |
kevman | 0:38ceb79fef03 | 224 | } |
kevman | 0:38ceb79fef03 | 225 | #endif |
kevman | 0:38ceb79fef03 | 226 | if (dns_addr_has_to_be_added && !interface->blocking) { |
kevman | 0:38ceb79fef03 | 227 | add_dns_addr(&interface->netif); |
kevman | 0:38ceb79fef03 | 228 | } |
kevman | 0:38ceb79fef03 | 229 | |
kevman | 0:38ceb79fef03 | 230 | if (interface->has_addr_state & HAS_ANY_ADDR) { |
kevman | 0:38ceb79fef03 | 231 | interface->connected = NSAPI_STATUS_GLOBAL_UP; |
kevman | 0:38ceb79fef03 | 232 | } |
kevman | 0:38ceb79fef03 | 233 | } else if (!netif_is_up(&interface->netif) && netif_is_link_up(&interface->netif)) { |
kevman | 0:38ceb79fef03 | 234 | interface->connected = NSAPI_STATUS_DISCONNECTED; |
kevman | 0:38ceb79fef03 | 235 | } |
kevman | 0:38ceb79fef03 | 236 | |
kevman | 0:38ceb79fef03 | 237 | if (interface->client_callback && (connectedStatusPrev != interface->connected) |
kevman | 0:38ceb79fef03 | 238 | && interface->connected != NSAPI_STATUS_DISCONNECTED) /* advertised by bring_down */ { |
kevman | 0:38ceb79fef03 | 239 | interface->client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, interface->connected); |
kevman | 0:38ceb79fef03 | 240 | } |
kevman | 0:38ceb79fef03 | 241 | } |
kevman | 0:38ceb79fef03 | 242 | |
kevman | 0:38ceb79fef03 | 243 | void LWIP::Interface::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb) |
kevman | 0:38ceb79fef03 | 244 | { |
kevman | 0:38ceb79fef03 | 245 | client_callback = status_cb; |
kevman | 0:38ceb79fef03 | 246 | } |
kevman | 0:38ceb79fef03 | 247 | |
kevman | 0:38ceb79fef03 | 248 | nsapi_connection_status_t LWIP::Interface::get_connection_status() const |
kevman | 0:38ceb79fef03 | 249 | { |
kevman | 0:38ceb79fef03 | 250 | return connected; |
kevman | 0:38ceb79fef03 | 251 | } |
kevman | 0:38ceb79fef03 | 252 | |
kevman | 0:38ceb79fef03 | 253 | #if LWIP_IPV6 |
kevman | 0:38ceb79fef03 | 254 | static void mbed_lwip_clear_ipv6_addresses(struct netif *netif) |
kevman | 0:38ceb79fef03 | 255 | { |
kevman | 0:38ceb79fef03 | 256 | for (u8_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { |
kevman | 0:38ceb79fef03 | 257 | netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); |
kevman | 0:38ceb79fef03 | 258 | } |
kevman | 0:38ceb79fef03 | 259 | } |
kevman | 0:38ceb79fef03 | 260 | #endif |
kevman | 0:38ceb79fef03 | 261 | |
kevman | 0:38ceb79fef03 | 262 | char *LWIP::Interface::get_mac_address(char *buf, nsapi_size_t buflen) |
kevman | 0:38ceb79fef03 | 263 | { |
kevman | 0:38ceb79fef03 | 264 | (void) snprintf(buf, buflen, "%02x:%02x:%02x:%02x:%02x:%02x", |
kevman | 0:38ceb79fef03 | 265 | netif.hwaddr[0], netif.hwaddr[1], netif.hwaddr[2], |
kevman | 0:38ceb79fef03 | 266 | netif.hwaddr[3], netif.hwaddr[4], netif.hwaddr[5]); |
kevman | 0:38ceb79fef03 | 267 | return buf; |
kevman | 0:38ceb79fef03 | 268 | } |
kevman | 0:38ceb79fef03 | 269 | |
kevman | 0:38ceb79fef03 | 270 | char *LWIP::Interface::get_ip_address(char *buf, nsapi_size_t buflen) |
kevman | 0:38ceb79fef03 | 271 | { |
kevman | 0:38ceb79fef03 | 272 | const ip_addr_t *addr = LWIP::get_ip_addr(true, &netif); |
kevman | 0:38ceb79fef03 | 273 | if (!addr) { |
kevman | 0:38ceb79fef03 | 274 | return NULL; |
kevman | 0:38ceb79fef03 | 275 | } |
kevman | 0:38ceb79fef03 | 276 | #if LWIP_IPV6 |
kevman | 0:38ceb79fef03 | 277 | if (IP_IS_V6(addr)) { |
kevman | 0:38ceb79fef03 | 278 | return ip6addr_ntoa_r(ip_2_ip6(addr), buf, buflen); |
kevman | 0:38ceb79fef03 | 279 | } |
kevman | 0:38ceb79fef03 | 280 | #endif |
kevman | 0:38ceb79fef03 | 281 | #if LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 282 | if (IP_IS_V4(addr)) { |
kevman | 0:38ceb79fef03 | 283 | return ip4addr_ntoa_r(ip_2_ip4(addr), buf, buflen); |
kevman | 0:38ceb79fef03 | 284 | } |
kevman | 0:38ceb79fef03 | 285 | #endif |
kevman | 0:38ceb79fef03 | 286 | #if LWIP_IPV6 && LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 287 | return NULL; |
kevman | 0:38ceb79fef03 | 288 | #endif |
kevman | 0:38ceb79fef03 | 289 | } |
kevman | 0:38ceb79fef03 | 290 | |
kevman | 0:38ceb79fef03 | 291 | char *LWIP::Interface::get_netmask(char *buf, nsapi_size_t buflen) |
kevman | 0:38ceb79fef03 | 292 | { |
kevman | 0:38ceb79fef03 | 293 | #if LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 294 | const ip4_addr_t *addr = netif_ip4_netmask(&netif); |
kevman | 0:38ceb79fef03 | 295 | if (!ip4_addr_isany(addr)) { |
kevman | 0:38ceb79fef03 | 296 | return ip4addr_ntoa_r(addr, buf, buflen); |
kevman | 0:38ceb79fef03 | 297 | } else { |
kevman | 0:38ceb79fef03 | 298 | return NULL; |
kevman | 0:38ceb79fef03 | 299 | } |
kevman | 0:38ceb79fef03 | 300 | #else |
kevman | 0:38ceb79fef03 | 301 | return NULL; |
kevman | 0:38ceb79fef03 | 302 | #endif |
kevman | 0:38ceb79fef03 | 303 | } |
kevman | 0:38ceb79fef03 | 304 | |
kevman | 0:38ceb79fef03 | 305 | char *LWIP::Interface::get_gateway(char *buf, nsapi_size_t buflen) |
kevman | 0:38ceb79fef03 | 306 | { |
kevman | 0:38ceb79fef03 | 307 | #if LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 308 | const ip4_addr_t *addr = netif_ip4_gw(&netif); |
kevman | 0:38ceb79fef03 | 309 | if (!ip4_addr_isany(addr)) { |
kevman | 0:38ceb79fef03 | 310 | return ip4addr_ntoa_r(addr, buf, buflen); |
kevman | 0:38ceb79fef03 | 311 | } else { |
kevman | 0:38ceb79fef03 | 312 | return NULL; |
kevman | 0:38ceb79fef03 | 313 | } |
kevman | 0:38ceb79fef03 | 314 | #else |
kevman | 0:38ceb79fef03 | 315 | return NULL; |
kevman | 0:38ceb79fef03 | 316 | #endif |
kevman | 0:38ceb79fef03 | 317 | } |
kevman | 0:38ceb79fef03 | 318 | |
kevman | 0:38ceb79fef03 | 319 | LWIP::Interface::Interface() : |
kevman | 0:38ceb79fef03 | 320 | hw(NULL), has_addr_state(0), |
kevman | 0:38ceb79fef03 | 321 | connected(NSAPI_STATUS_DISCONNECTED), |
kevman | 0:38ceb79fef03 | 322 | dhcp_started(false), dhcp_has_to_be_set(false), blocking(true), ppp(false) |
kevman | 0:38ceb79fef03 | 323 | { |
kevman | 0:38ceb79fef03 | 324 | memset(&netif, 0, sizeof netif); |
kevman | 0:38ceb79fef03 | 325 | |
kevman | 0:38ceb79fef03 | 326 | osSemaphoreAttr_t attr; |
kevman | 0:38ceb79fef03 | 327 | attr.name = NULL; |
kevman | 0:38ceb79fef03 | 328 | attr.attr_bits = 0; |
kevman | 0:38ceb79fef03 | 329 | |
kevman | 0:38ceb79fef03 | 330 | attr.cb_mem = &linked_sem; |
kevman | 0:38ceb79fef03 | 331 | attr.cb_size = sizeof linked_sem; |
kevman | 0:38ceb79fef03 | 332 | linked = osSemaphoreNew(UINT16_MAX, 0, &attr); |
kevman | 0:38ceb79fef03 | 333 | |
kevman | 0:38ceb79fef03 | 334 | attr.cb_mem = &unlinked_sem; |
kevman | 0:38ceb79fef03 | 335 | attr.cb_size = sizeof unlinked_sem; |
kevman | 0:38ceb79fef03 | 336 | unlinked = osSemaphoreNew(UINT16_MAX, 0, &attr); |
kevman | 0:38ceb79fef03 | 337 | |
kevman | 0:38ceb79fef03 | 338 | attr.cb_mem = &has_any_addr_sem; |
kevman | 0:38ceb79fef03 | 339 | attr.cb_size = sizeof has_any_addr_sem; |
kevman | 0:38ceb79fef03 | 340 | has_any_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); |
kevman | 0:38ceb79fef03 | 341 | #if PREF_ADDR_TIMEOUT |
kevman | 0:38ceb79fef03 | 342 | attr.cb_mem = &has_pref_addr_sem; |
kevman | 0:38ceb79fef03 | 343 | attr.cb_size = sizeof has_pref_addr_sem; |
kevman | 0:38ceb79fef03 | 344 | has_pref_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); |
kevman | 0:38ceb79fef03 | 345 | #endif |
kevman | 0:38ceb79fef03 | 346 | #if BOTH_ADDR_TIMEOUT |
kevman | 0:38ceb79fef03 | 347 | attr.cb_mem = &has_both_addr_sem; |
kevman | 0:38ceb79fef03 | 348 | attr.cb_size = sizeof has_both_addr_sem; |
kevman | 0:38ceb79fef03 | 349 | has_both_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); |
kevman | 0:38ceb79fef03 | 350 | #endif |
kevman | 0:38ceb79fef03 | 351 | |
kevman | 0:38ceb79fef03 | 352 | next = list; |
kevman | 0:38ceb79fef03 | 353 | list = this; |
kevman | 0:38ceb79fef03 | 354 | } |
kevman | 0:38ceb79fef03 | 355 | |
kevman | 0:38ceb79fef03 | 356 | nsapi_error_t LWIP::add_ethernet_interface(EMAC &emac, bool default_if, OnboardNetworkStack::Interface **interface_out) |
kevman | 0:38ceb79fef03 | 357 | { |
kevman | 0:38ceb79fef03 | 358 | #if LWIP_ETHERNET |
kevman | 0:38ceb79fef03 | 359 | Interface *interface = new (std::nothrow) Interface(); |
kevman | 0:38ceb79fef03 | 360 | if (!interface) { |
kevman | 0:38ceb79fef03 | 361 | return NSAPI_ERROR_NO_MEMORY; |
kevman | 0:38ceb79fef03 | 362 | } |
kevman | 0:38ceb79fef03 | 363 | interface->emac = &emac; |
kevman | 0:38ceb79fef03 | 364 | interface->memory_manager = &memory_manager; |
kevman | 0:38ceb79fef03 | 365 | interface->ppp = false; |
kevman | 0:38ceb79fef03 | 366 | |
kevman | 0:38ceb79fef03 | 367 | #if (MBED_MAC_ADDRESS_SUM != MBED_MAC_ADDR_INTERFACE) |
kevman | 0:38ceb79fef03 | 368 | netif->interface.hwaddr[0] = MBED_MAC_ADDR_0; |
kevman | 0:38ceb79fef03 | 369 | netif->interface.hwaddr[1] = MBED_MAC_ADDR_1; |
kevman | 0:38ceb79fef03 | 370 | netif->interface.hwaddr[2] = MBED_MAC_ADDR_2; |
kevman | 0:38ceb79fef03 | 371 | netif->interface.hwaddr[3] = MBED_MAC_ADDR_3; |
kevman | 0:38ceb79fef03 | 372 | netif->interface.hwaddr[4] = MBED_MAC_ADDR_4; |
kevman | 0:38ceb79fef03 | 373 | netif->interface.hwaddr[5] = MBED_MAC_ADDR_5; |
kevman | 0:38ceb79fef03 | 374 | #else |
kevman | 0:38ceb79fef03 | 375 | mbed_mac_address((char *) interface->netif.hwaddr); |
kevman | 0:38ceb79fef03 | 376 | #endif |
kevman | 0:38ceb79fef03 | 377 | |
kevman | 0:38ceb79fef03 | 378 | interface->netif.hwaddr_len = 6; |
kevman | 0:38ceb79fef03 | 379 | |
kevman | 0:38ceb79fef03 | 380 | if (!netif_add(&interface->netif, |
kevman | 0:38ceb79fef03 | 381 | #if LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 382 | 0, 0, 0, |
kevman | 0:38ceb79fef03 | 383 | #endif |
kevman | 0:38ceb79fef03 | 384 | interface, &LWIP::Interface::emac_if_init, tcpip_input)) { |
kevman | 0:38ceb79fef03 | 385 | return NSAPI_ERROR_DEVICE_ERROR; |
kevman | 0:38ceb79fef03 | 386 | } |
kevman | 0:38ceb79fef03 | 387 | |
kevman | 0:38ceb79fef03 | 388 | if (default_if) { |
kevman | 0:38ceb79fef03 | 389 | netif_set_default(&interface->netif); |
kevman | 0:38ceb79fef03 | 390 | default_interface = interface; |
kevman | 0:38ceb79fef03 | 391 | } |
kevman | 0:38ceb79fef03 | 392 | |
kevman | 0:38ceb79fef03 | 393 | netif_set_link_callback(&interface->netif, &LWIP::Interface::netif_link_irq); |
kevman | 0:38ceb79fef03 | 394 | netif_set_status_callback(&interface->netif, &LWIP::Interface::netif_status_irq); |
kevman | 0:38ceb79fef03 | 395 | |
kevman | 0:38ceb79fef03 | 396 | *interface_out = interface; |
kevman | 0:38ceb79fef03 | 397 | |
kevman | 0:38ceb79fef03 | 398 | /* Use mac address as additional seed to random number generator */ |
kevman | 0:38ceb79fef03 | 399 | uint64_t seed = interface->netif.hwaddr[0]; |
kevman | 0:38ceb79fef03 | 400 | for (uint8_t i = 1; i < 8; i++) { |
kevman | 0:38ceb79fef03 | 401 | seed <<= 8; |
kevman | 0:38ceb79fef03 | 402 | seed |= interface->netif.hwaddr[i % 6]; |
kevman | 0:38ceb79fef03 | 403 | } |
kevman | 0:38ceb79fef03 | 404 | lwip_add_random_seed(seed); |
kevman | 0:38ceb79fef03 | 405 | |
kevman | 0:38ceb79fef03 | 406 | return NSAPI_ERROR_OK; |
kevman | 0:38ceb79fef03 | 407 | #else |
kevman | 0:38ceb79fef03 | 408 | return NSAPI_ERROR_UNSUPPORTED; |
kevman | 0:38ceb79fef03 | 409 | #endif //LWIP_ETHERNET |
kevman | 0:38ceb79fef03 | 410 | } |
kevman | 0:38ceb79fef03 | 411 | |
kevman | 0:38ceb79fef03 | 412 | /* Internal API to preserve existing PPP functionality - revise to better match mbed_ipstak_add_ethernet_interface later */ |
kevman | 0:38ceb79fef03 | 413 | nsapi_error_t LWIP::_add_ppp_interface(void *hw, bool default_if, nsapi_ip_stack_t stack, LWIP::Interface **interface_out) |
kevman | 0:38ceb79fef03 | 414 | { |
kevman | 0:38ceb79fef03 | 415 | #if LWIP_PPP_API |
kevman | 0:38ceb79fef03 | 416 | Interface *interface = new (std::nothrow) Interface(); |
kevman | 0:38ceb79fef03 | 417 | if (!interface) { |
kevman | 0:38ceb79fef03 | 418 | return NSAPI_ERROR_NO_MEMORY; |
kevman | 0:38ceb79fef03 | 419 | } |
kevman | 0:38ceb79fef03 | 420 | interface->hw = hw; |
kevman | 0:38ceb79fef03 | 421 | interface->ppp = true; |
kevman | 0:38ceb79fef03 | 422 | |
kevman | 0:38ceb79fef03 | 423 | nsapi_error_t ret = ppp_lwip_if_init(hw, &interface->netif, stack); |
kevman | 0:38ceb79fef03 | 424 | if (ret != NSAPI_ERROR_OK) { |
kevman | 0:38ceb79fef03 | 425 | free(interface); |
kevman | 0:38ceb79fef03 | 426 | return ret; |
kevman | 0:38ceb79fef03 | 427 | } |
kevman | 0:38ceb79fef03 | 428 | |
kevman | 0:38ceb79fef03 | 429 | if (default_if) { |
kevman | 0:38ceb79fef03 | 430 | netif_set_default(&interface->netif); |
kevman | 0:38ceb79fef03 | 431 | default_interface = interface; |
kevman | 0:38ceb79fef03 | 432 | } |
kevman | 0:38ceb79fef03 | 433 | |
kevman | 0:38ceb79fef03 | 434 | netif_set_link_callback(&interface->netif, &LWIP::Interface::netif_link_irq); |
kevman | 0:38ceb79fef03 | 435 | netif_set_status_callback(&interface->netif, &LWIP::Interface::netif_status_irq); |
kevman | 0:38ceb79fef03 | 436 | |
kevman | 0:38ceb79fef03 | 437 | *interface_out = interface; |
kevman | 0:38ceb79fef03 | 438 | |
kevman | 0:38ceb79fef03 | 439 | return NSAPI_ERROR_OK; |
kevman | 0:38ceb79fef03 | 440 | #else |
kevman | 0:38ceb79fef03 | 441 | return NSAPI_ERROR_UNSUPPORTED; |
kevman | 0:38ceb79fef03 | 442 | #endif //LWIP_PPP_API |
kevman | 0:38ceb79fef03 | 443 | } |
kevman | 0:38ceb79fef03 | 444 | |
kevman | 0:38ceb79fef03 | 445 | |
kevman | 0:38ceb79fef03 | 446 | 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) |
kevman | 0:38ceb79fef03 | 447 | { |
kevman | 0:38ceb79fef03 | 448 | // Check if we've already connected |
kevman | 0:38ceb79fef03 | 449 | if (connected == NSAPI_STATUS_GLOBAL_UP) { |
kevman | 0:38ceb79fef03 | 450 | return NSAPI_ERROR_IS_CONNECTED; |
kevman | 0:38ceb79fef03 | 451 | } else if (connected == NSAPI_STATUS_CONNECTING) { |
kevman | 0:38ceb79fef03 | 452 | return NSAPI_ERROR_ALREADY; |
kevman | 0:38ceb79fef03 | 453 | } |
kevman | 0:38ceb79fef03 | 454 | |
kevman | 0:38ceb79fef03 | 455 | connected = NSAPI_STATUS_CONNECTING; |
kevman | 0:38ceb79fef03 | 456 | blocking = block; |
kevman | 0:38ceb79fef03 | 457 | |
kevman | 0:38ceb79fef03 | 458 | #if LWIP_DHCP |
kevman | 0:38ceb79fef03 | 459 | if (stack != IPV6_STACK && dhcp) { |
kevman | 0:38ceb79fef03 | 460 | dhcp_has_to_be_set = true; |
kevman | 0:38ceb79fef03 | 461 | } |
kevman | 0:38ceb79fef03 | 462 | #endif |
kevman | 0:38ceb79fef03 | 463 | |
kevman | 0:38ceb79fef03 | 464 | #if LWIP_IPV6 |
kevman | 0:38ceb79fef03 | 465 | if (stack != IPV4_STACK) { |
kevman | 0:38ceb79fef03 | 466 | if (netif.hwaddr_len == 6) { |
kevman | 0:38ceb79fef03 | 467 | netif_create_ip6_linklocal_address(&netif, 1/*from MAC*/); |
kevman | 0:38ceb79fef03 | 468 | } |
kevman | 0:38ceb79fef03 | 469 | #if LWIP_IPV6_MLD |
kevman | 0:38ceb79fef03 | 470 | /* |
kevman | 0:38ceb79fef03 | 471 | * For hardware/netifs that implement MAC filtering. |
kevman | 0:38ceb79fef03 | 472 | * All-nodes link-local is handled by default, so we must let the hardware know |
kevman | 0:38ceb79fef03 | 473 | * to allow multicast packets in. |
kevman | 0:38ceb79fef03 | 474 | * Should set mld_mac_filter previously. */ |
kevman | 0:38ceb79fef03 | 475 | if (netif.mld_mac_filter != NULL) { |
kevman | 0:38ceb79fef03 | 476 | ip6_addr_t ip6_allnodes_ll; |
kevman | 0:38ceb79fef03 | 477 | ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); |
kevman | 0:38ceb79fef03 | 478 | netif.mld_mac_filter(&netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); |
kevman | 0:38ceb79fef03 | 479 | } |
kevman | 0:38ceb79fef03 | 480 | #endif /* LWIP_IPV6_MLD */ |
kevman | 0:38ceb79fef03 | 481 | |
kevman | 0:38ceb79fef03 | 482 | #if LWIP_IPV6_AUTOCONFIG |
kevman | 0:38ceb79fef03 | 483 | /* IPv6 address autoconfiguration not enabled by default */ |
kevman | 0:38ceb79fef03 | 484 | netif.ip6_autoconfig_enabled = 1; |
kevman | 0:38ceb79fef03 | 485 | #endif /* LWIP_IPV6_AUTOCONFIG */ |
kevman | 0:38ceb79fef03 | 486 | } else { |
kevman | 0:38ceb79fef03 | 487 | // Disable rourter solicitations |
kevman | 0:38ceb79fef03 | 488 | netif.rs_count = 0; |
kevman | 0:38ceb79fef03 | 489 | } |
kevman | 0:38ceb79fef03 | 490 | #endif /* LWIP_IPV6 */ |
kevman | 0:38ceb79fef03 | 491 | |
kevman | 0:38ceb79fef03 | 492 | #if LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 493 | if (stack != IPV6_STACK) { |
kevman | 0:38ceb79fef03 | 494 | if (!dhcp && !ppp) { |
kevman | 0:38ceb79fef03 | 495 | ip4_addr_t ip_addr; |
kevman | 0:38ceb79fef03 | 496 | ip4_addr_t netmask_addr; |
kevman | 0:38ceb79fef03 | 497 | ip4_addr_t gw_addr; |
kevman | 0:38ceb79fef03 | 498 | |
kevman | 0:38ceb79fef03 | 499 | if (!inet_aton(ip, &ip_addr) || |
kevman | 0:38ceb79fef03 | 500 | !inet_aton(netmask, &netmask_addr) || |
kevman | 0:38ceb79fef03 | 501 | !inet_aton(gw, &gw_addr)) { |
kevman | 0:38ceb79fef03 | 502 | return NSAPI_ERROR_PARAMETER; |
kevman | 0:38ceb79fef03 | 503 | } |
kevman | 0:38ceb79fef03 | 504 | |
kevman | 0:38ceb79fef03 | 505 | netif_set_addr(&netif, &ip_addr, &netmask_addr, &gw_addr); |
kevman | 0:38ceb79fef03 | 506 | } |
kevman | 0:38ceb79fef03 | 507 | } |
kevman | 0:38ceb79fef03 | 508 | #endif |
kevman | 0:38ceb79fef03 | 509 | |
kevman | 0:38ceb79fef03 | 510 | if (client_callback) { |
kevman | 0:38ceb79fef03 | 511 | client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_CONNECTING); |
kevman | 0:38ceb79fef03 | 512 | } |
kevman | 0:38ceb79fef03 | 513 | |
kevman | 0:38ceb79fef03 | 514 | if (ppp) { |
kevman | 0:38ceb79fef03 | 515 | err_t err = ppp_lwip_connect(hw); |
kevman | 0:38ceb79fef03 | 516 | if (err) { |
kevman | 0:38ceb79fef03 | 517 | connected = NSAPI_STATUS_DISCONNECTED; |
kevman | 0:38ceb79fef03 | 518 | if (client_callback) { |
kevman | 0:38ceb79fef03 | 519 | client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, NSAPI_STATUS_DISCONNECTED); |
kevman | 0:38ceb79fef03 | 520 | } |
kevman | 0:38ceb79fef03 | 521 | return err_remap(err); |
kevman | 0:38ceb79fef03 | 522 | } |
kevman | 0:38ceb79fef03 | 523 | } |
kevman | 0:38ceb79fef03 | 524 | |
kevman | 0:38ceb79fef03 | 525 | if (!netif_is_link_up(&netif)) { |
kevman | 0:38ceb79fef03 | 526 | if (blocking) { |
kevman | 0:38ceb79fef03 | 527 | if (osSemaphoreAcquire(linked, 15000) != osOK) { |
kevman | 0:38ceb79fef03 | 528 | if (ppp) { |
kevman | 0:38ceb79fef03 | 529 | (void) ppp_lwip_disconnect(hw); |
kevman | 0:38ceb79fef03 | 530 | } |
kevman | 0:38ceb79fef03 | 531 | return NSAPI_ERROR_NO_CONNECTION; |
kevman | 0:38ceb79fef03 | 532 | } |
kevman | 0:38ceb79fef03 | 533 | } |
kevman | 0:38ceb79fef03 | 534 | } else { |
kevman | 0:38ceb79fef03 | 535 | nsapi_error_t ret = set_dhcp(); |
kevman | 0:38ceb79fef03 | 536 | if (ret != NSAPI_ERROR_OK) { |
kevman | 0:38ceb79fef03 | 537 | return ret; |
kevman | 0:38ceb79fef03 | 538 | } |
kevman | 0:38ceb79fef03 | 539 | } |
kevman | 0:38ceb79fef03 | 540 | |
kevman | 0:38ceb79fef03 | 541 | if (!blocking) { |
kevman | 0:38ceb79fef03 | 542 | // Done enough - as addresses are acquired, there will be |
kevman | 0:38ceb79fef03 | 543 | // connected callbacks. |
kevman | 0:38ceb79fef03 | 544 | // XXX shouldn't this be NSAPI_ERROR_IN_PROGRESS if in CONNECTING state? |
kevman | 0:38ceb79fef03 | 545 | return NSAPI_ERROR_OK; |
kevman | 0:38ceb79fef03 | 546 | } |
kevman | 0:38ceb79fef03 | 547 | |
kevman | 0:38ceb79fef03 | 548 | // If doesn't have address |
kevman | 0:38ceb79fef03 | 549 | if (!LWIP::get_ip_addr(true, &netif)) { |
kevman | 0:38ceb79fef03 | 550 | if (osSemaphoreAcquire(has_any_addr, DHCP_TIMEOUT * 1000) != osOK) { |
kevman | 0:38ceb79fef03 | 551 | if (ppp) { |
kevman | 0:38ceb79fef03 | 552 | (void) ppp_lwip_disconnect(hw); |
kevman | 0:38ceb79fef03 | 553 | } |
kevman | 0:38ceb79fef03 | 554 | return NSAPI_ERROR_DHCP_FAILURE; |
kevman | 0:38ceb79fef03 | 555 | } |
kevman | 0:38ceb79fef03 | 556 | } |
kevman | 0:38ceb79fef03 | 557 | |
kevman | 0:38ceb79fef03 | 558 | #if PREF_ADDR_TIMEOUT |
kevman | 0:38ceb79fef03 | 559 | if (stack != IPV4_STACK && stack != IPV6_STACK) { |
kevman | 0:38ceb79fef03 | 560 | // If address is not for preferred stack waits a while to see |
kevman | 0:38ceb79fef03 | 561 | // if preferred stack address is acquired |
kevman | 0:38ceb79fef03 | 562 | if (!LWIP::get_ip_addr(false, &netif)) { |
kevman | 0:38ceb79fef03 | 563 | osSemaphoreAcquire(has_pref_addr, PREF_ADDR_TIMEOUT * 1000); |
kevman | 0:38ceb79fef03 | 564 | } |
kevman | 0:38ceb79fef03 | 565 | } |
kevman | 0:38ceb79fef03 | 566 | #endif |
kevman | 0:38ceb79fef03 | 567 | #if BOTH_ADDR_TIMEOUT |
kevman | 0:38ceb79fef03 | 568 | if (stack != IPV4_STACK && stack != IPV6_STACK) { |
kevman | 0:38ceb79fef03 | 569 | // If addresses for both stacks are not available waits a while to |
kevman | 0:38ceb79fef03 | 570 | // see if address for both stacks are acquired |
kevman | 0:38ceb79fef03 | 571 | if (!(LWIP::get_ipv4_addr(&netif) && LWIP::get_ipv6_addr(&netif))) { |
kevman | 0:38ceb79fef03 | 572 | osSemaphoreAcquire(has_both_addr, BOTH_ADDR_TIMEOUT * 1000); |
kevman | 0:38ceb79fef03 | 573 | } |
kevman | 0:38ceb79fef03 | 574 | } |
kevman | 0:38ceb79fef03 | 575 | #endif |
kevman | 0:38ceb79fef03 | 576 | |
kevman | 0:38ceb79fef03 | 577 | add_dns_addr(&netif); |
kevman | 0:38ceb79fef03 | 578 | |
kevman | 0:38ceb79fef03 | 579 | return NSAPI_ERROR_OK; |
kevman | 0:38ceb79fef03 | 580 | } |
kevman | 0:38ceb79fef03 | 581 | |
kevman | 0:38ceb79fef03 | 582 | nsapi_error_t LWIP::Interface::bringdown() |
kevman | 0:38ceb79fef03 | 583 | { |
kevman | 0:38ceb79fef03 | 584 | // Check if we've connected |
kevman | 0:38ceb79fef03 | 585 | if (connected == NSAPI_STATUS_DISCONNECTED) { |
kevman | 0:38ceb79fef03 | 586 | return NSAPI_ERROR_PARAMETER; |
kevman | 0:38ceb79fef03 | 587 | } |
kevman | 0:38ceb79fef03 | 588 | |
kevman | 0:38ceb79fef03 | 589 | #if LWIP_DHCP |
kevman | 0:38ceb79fef03 | 590 | // Disconnect from the network |
kevman | 0:38ceb79fef03 | 591 | if (dhcp_started) { |
kevman | 0:38ceb79fef03 | 592 | dhcp_release(&netif); |
kevman | 0:38ceb79fef03 | 593 | dhcp_stop(&netif); |
kevman | 0:38ceb79fef03 | 594 | dhcp_started = false; |
kevman | 0:38ceb79fef03 | 595 | dhcp_has_to_be_set = false; |
kevman | 0:38ceb79fef03 | 596 | } |
kevman | 0:38ceb79fef03 | 597 | #endif |
kevman | 0:38ceb79fef03 | 598 | |
kevman | 0:38ceb79fef03 | 599 | if (ppp) { |
kevman | 0:38ceb79fef03 | 600 | /* this is a blocking call, returns when PPP is properly closed */ |
kevman | 0:38ceb79fef03 | 601 | err_t err = ppp_lwip_disconnect(hw); |
kevman | 0:38ceb79fef03 | 602 | if (err) { |
kevman | 0:38ceb79fef03 | 603 | return err_remap(err); |
kevman | 0:38ceb79fef03 | 604 | } |
kevman | 0:38ceb79fef03 | 605 | MBED_ASSERT(!netif_is_link_up(&netif)); |
kevman | 0:38ceb79fef03 | 606 | /*if (netif_is_link_up(&netif)) { |
kevman | 0:38ceb79fef03 | 607 | if (sys_arch_sem_wait(&unlinked, 15000) == SYS_ARCH_TIMEOUT) { |
kevman | 0:38ceb79fef03 | 608 | return NSAPI_ERROR_DEVICE_ERROR; |
kevman | 0:38ceb79fef03 | 609 | } |
kevman | 0:38ceb79fef03 | 610 | }*/ |
kevman | 0:38ceb79fef03 | 611 | } else { |
kevman | 0:38ceb79fef03 | 612 | netif_set_down(&netif); |
kevman | 0:38ceb79fef03 | 613 | } |
kevman | 0:38ceb79fef03 | 614 | |
kevman | 0:38ceb79fef03 | 615 | #if LWIP_IPV6 |
kevman | 0:38ceb79fef03 | 616 | mbed_lwip_clear_ipv6_addresses(&netif); |
kevman | 0:38ceb79fef03 | 617 | #endif |
kevman | 0:38ceb79fef03 | 618 | #if LWIP_IPV4 |
kevman | 0:38ceb79fef03 | 619 | ip_addr_set_zero(&(netif.ip_addr)); |
kevman | 0:38ceb79fef03 | 620 | ip_addr_set_zero(&(netif.netmask)); |
kevman | 0:38ceb79fef03 | 621 | ip_addr_set_zero(&(netif.gw)); |
kevman | 0:38ceb79fef03 | 622 | #endif |
kevman | 0:38ceb79fef03 | 623 | |
kevman | 0:38ceb79fef03 | 624 | osSemaphoreDelete(has_any_addr); |
kevman | 0:38ceb79fef03 | 625 | osSemaphoreAttr_t attr; |
kevman | 0:38ceb79fef03 | 626 | attr.name = NULL; |
kevman | 0:38ceb79fef03 | 627 | attr.attr_bits = 0; |
kevman | 0:38ceb79fef03 | 628 | attr.cb_mem = &has_any_addr_sem; |
kevman | 0:38ceb79fef03 | 629 | attr.cb_size = sizeof has_any_addr_sem; |
kevman | 0:38ceb79fef03 | 630 | has_any_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); |
kevman | 0:38ceb79fef03 | 631 | #if PREF_ADDR_TIMEOUT |
kevman | 0:38ceb79fef03 | 632 | osSemaphoreDelete(has_pref_addr); |
kevman | 0:38ceb79fef03 | 633 | attr.cb_mem = &has_pref_addr_sem; |
kevman | 0:38ceb79fef03 | 634 | attr.cb_size = sizeof has_pref_addr_sem; |
kevman | 0:38ceb79fef03 | 635 | has_pref_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); |
kevman | 0:38ceb79fef03 | 636 | #endif |
kevman | 0:38ceb79fef03 | 637 | #if BOTH_ADDR_TIMEOUT |
kevman | 0:38ceb79fef03 | 638 | osSemaphoreDelete(has_both_addr); |
kevman | 0:38ceb79fef03 | 639 | attr.cb_mem = &has_both_addr_sem; |
kevman | 0:38ceb79fef03 | 640 | attr.cb_size = sizeof has_both_addr_sem; |
kevman | 0:38ceb79fef03 | 641 | has_both_addr = osSemaphoreNew(UINT16_MAX, 0, &attr); |
kevman | 0:38ceb79fef03 | 642 | #endif |
kevman | 0:38ceb79fef03 | 643 | has_addr_state = 0; |
kevman | 0:38ceb79fef03 | 644 | |
kevman | 0:38ceb79fef03 | 645 | connected = NSAPI_STATUS_DISCONNECTED; |
kevman | 0:38ceb79fef03 | 646 | if (client_callback) { |
kevman | 0:38ceb79fef03 | 647 | client_callback(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, connected); |
kevman | 0:38ceb79fef03 | 648 | } |
kevman | 0:38ceb79fef03 | 649 | return 0; |
kevman | 0:38ceb79fef03 | 650 | } |