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.
mbed-os/features/lwipstack/LWIPInterface.cpp@0:8fdf9a60065b, 2018-10-10 (annotated)
- 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?
| User | Revision | Line number | New 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 | } |