takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Wed Oct 10 00:33:53 2018 +0000
Revision:
0:8fdf9a60065b
how to make mbed librry

Who changed what in which revision?

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