Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
lwip_tools.cpp
00001 /* LWIP common helpers 00002 * Copyright (c) 2017 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include <stdbool.h> 00018 #include <string.h> 00019 00020 #include "lwip/opt.h" 00021 #include "lwip/netif.h" 00022 #include "lwip/ip.h" 00023 #include "lwip/api.h" 00024 00025 #include "LWIPStack.h" 00026 #include "lwip_tools.h" 00027 00028 #include "netsocket/nsapi_types.h" 00029 00030 #if !LWIP_IPV4 || !LWIP_IPV6 00031 static bool all_zeros(const uint8_t *p, int len); 00032 #endif 00033 00034 /* LWIP error remapping */ 00035 nsapi_error_t LWIP::err_remap(err_t err) 00036 { 00037 switch (err) { 00038 case ERR_OK: 00039 case ERR_CLSD: 00040 return 0; 00041 case ERR_MEM: 00042 case ERR_BUF: 00043 return NSAPI_ERROR_NO_MEMORY ; 00044 case ERR_CONN: 00045 case ERR_RST: 00046 case ERR_ABRT: 00047 return NSAPI_ERROR_NO_CONNECTION ; 00048 case ERR_TIMEOUT: 00049 case ERR_RTE: 00050 case ERR_WOULDBLOCK: 00051 return NSAPI_ERROR_WOULD_BLOCK ; 00052 case ERR_VAL: 00053 case ERR_USE: 00054 case ERR_ARG: 00055 return NSAPI_ERROR_PARAMETER ; 00056 case ERR_INPROGRESS: 00057 return NSAPI_ERROR_IN_PROGRESS ; 00058 case ERR_ALREADY: 00059 return NSAPI_ERROR_ALREADY ; 00060 case ERR_ISCONN: 00061 return NSAPI_ERROR_IS_CONNECTED ; 00062 default: 00063 return NSAPI_ERROR_DEVICE_ERROR ; 00064 } 00065 } 00066 00067 00068 const ip_addr_t *LWIP::get_ipv4_addr(const struct netif *netif) 00069 { 00070 #if LWIP_IPV4 00071 if (!netif_is_up(netif)) { 00072 return NULL; 00073 } 00074 00075 if (!ip4_addr_isany(netif_ip4_addr(netif))) { 00076 return netif_ip_addr4(netif); 00077 } 00078 #endif 00079 return NULL; 00080 } 00081 00082 const ip_addr_t *LWIP::get_ipv6_link_local_addr(const struct netif *netif) 00083 { 00084 #if LWIP_IPV6 00085 if (!netif_is_up(netif)) { 00086 return NULL; 00087 } 00088 00089 for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00090 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 00091 ip6_addr_islinklocal(netif_ip6_addr(netif, i))) { 00092 return netif_ip_addr6(netif, i); 00093 } 00094 } 00095 #endif 00096 return NULL; 00097 } 00098 00099 const ip_addr_t *LWIP::get_ipv6_addr(const struct netif *netif) 00100 { 00101 #if LWIP_IPV6 00102 if (!netif_is_up(netif)) { 00103 return NULL; 00104 } 00105 00106 for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00107 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 00108 !ip6_addr_islinklocal(netif_ip6_addr(netif, i))) { 00109 return netif_ip_addr6(netif, i); 00110 } 00111 } 00112 00113 for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00114 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { 00115 return netif_ip_addr6(netif, i); 00116 } 00117 } 00118 #endif 00119 return NULL; 00120 } 00121 00122 bool LWIP::is_local_addr(const ip_addr_t *ip_addr) 00123 { 00124 struct netif *netif; 00125 00126 for (netif = netif_list; netif != NULL; netif = netif->next) { 00127 if (!netif_is_up(netif)) { 00128 continue; 00129 } 00130 #if LWIP_IPV6 00131 if (IP_IS_V6(ip_addr)) { 00132 for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { 00133 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && 00134 ip6_addr_cmp(netif_ip6_addr(netif, i), ip_2_ip6(ip_addr))) { 00135 return true; 00136 } 00137 } 00138 } 00139 #endif 00140 00141 #if LWIP_IPV4 00142 if (IP_IS_V4(ip_addr)) { 00143 if (!ip4_addr_isany(netif_ip4_addr(netif)) && 00144 ip4_addr_cmp(netif_ip4_addr(netif), ip_2_ip4(ip_addr))) { 00145 return true; 00146 } 00147 } 00148 #endif 00149 } 00150 return false; 00151 } 00152 00153 const ip_addr_t *LWIP::get_ip_addr(bool any_addr, const struct netif *netif) 00154 { 00155 const ip_addr_t *pref_ip_addr = 0; 00156 const ip_addr_t *npref_ip_addr = 0; 00157 00158 #if LWIP_IPV4 && LWIP_IPV6 00159 #if IP_VERSION_PREF == PREF_IPV4 00160 pref_ip_addr = get_ipv4_addr(netif); 00161 npref_ip_addr = get_ipv6_addr(netif); 00162 #else 00163 pref_ip_addr = get_ipv6_addr(netif); 00164 npref_ip_addr = get_ipv4_addr(netif); 00165 #endif 00166 #elif LWIP_IPV6 00167 pref_ip_addr = get_ipv6_addr(netif); 00168 #elif LWIP_IPV4 00169 pref_ip_addr = get_ipv4_addr(netif); 00170 #endif 00171 00172 if (pref_ip_addr) { 00173 return pref_ip_addr; 00174 } else if (npref_ip_addr && any_addr) { 00175 return npref_ip_addr; 00176 } 00177 00178 return NULL; 00179 } 00180 00181 void LWIP::arena_init(void) 00182 { 00183 memset(arena, 0, sizeof(arena)); 00184 } 00185 00186 struct LWIP::mbed_lwip_socket *LWIP::arena_alloc() 00187 { 00188 LWIP &lwip = LWIP::get_instance(); 00189 00190 lwip.adaptation.lock(); 00191 00192 for (int i = 0; i < MEMP_NUM_NETCONN; i++) { 00193 if (!arena[i].in_use) { 00194 struct mbed_lwip_socket *s = &arena[i]; 00195 memset(s, 0, sizeof(*s)); 00196 s->in_use = true; 00197 lwip.adaptation.unlock(); 00198 return s; 00199 } 00200 } 00201 00202 lwip.adaptation.unlock(); 00203 00204 return 0; 00205 } 00206 00207 void LWIP::arena_dealloc(struct mbed_lwip_socket *s) 00208 { 00209 s->in_use = false; 00210 00211 while (s->multicast_memberships_count > 0) { 00212 uint32_t index = 0; 00213 index = next_registered_multicast_member(s, index); 00214 00215 setsockopt(s, NSAPI_SOCKET , NSAPI_DROP_MEMBERSHIP , &s->multicast_memberships[index], 00216 sizeof(s->multicast_memberships[index])); 00217 index++; 00218 } 00219 00220 free(s->multicast_memberships); 00221 s->multicast_memberships = NULL; 00222 } 00223 00224 bool convert_lwip_addr_to_mbed(nsapi_addr_t *out, const ip_addr_t *in) 00225 { 00226 #if LWIP_IPV6 00227 if (IP_IS_V6(in)) { 00228 out->version = NSAPI_IPv6 ; 00229 SMEMCPY(out->bytes, ip_2_ip6(in), sizeof(ip6_addr_t)); 00230 return true; 00231 } 00232 #endif 00233 #if LWIP_IPV4 00234 if (IP_IS_V4(in)) { 00235 out->version = NSAPI_IPv4 ; 00236 SMEMCPY(out->bytes, ip_2_ip4(in), sizeof(ip4_addr_t)); 00237 return true; 00238 } 00239 #endif 00240 #if LWIP_IPV6 && LWIP_IPV4 00241 return false; 00242 #endif 00243 } 00244 00245 bool convert_mbed_addr_to_lwip(ip_addr_t *out, const nsapi_addr_t *in) 00246 { 00247 #if LWIP_IPV6 00248 if (in->version == NSAPI_IPv6 ) { 00249 IP_SET_TYPE(out, IPADDR_TYPE_V6); 00250 SMEMCPY(ip_2_ip6(out), in->bytes, sizeof(ip6_addr_t)); 00251 return true; 00252 } 00253 #if !LWIP_IPV4 00254 /* For bind() and other purposes, need to accept "null" of other type */ 00255 /* (People use IPv4 0.0.0.0 as a general null) */ 00256 if (in->version == NSAPI_UNSPEC || 00257 (in->version == NSAPI_IPv4 && all_zeros(in->bytes, 4))) { 00258 ip_addr_set_zero_ip6(out); 00259 return true; 00260 } 00261 #endif 00262 #endif 00263 00264 #if LWIP_IPV4 00265 if (in->version == NSAPI_IPv4 ) { 00266 IP_SET_TYPE(out, IPADDR_TYPE_V4); 00267 SMEMCPY(ip_2_ip4(out), in->bytes, sizeof(ip4_addr_t)); 00268 return true; 00269 } 00270 #if !LWIP_IPV6 00271 /* For symmetry with above, accept IPv6 :: as a general null */ 00272 if (in->version == NSAPI_UNSPEC || 00273 (in->version == NSAPI_IPv6 && all_zeros(in->bytes, 16))) { 00274 ip_addr_set_zero_ip4(out); 00275 return true; 00276 } 00277 #endif 00278 #endif 00279 00280 #if LWIP_IPV4 && LWIP_IPV6 00281 if (in->version == NSAPI_UNSPEC ) { 00282 ip6_addr_set_zero(ip_2_ip6(out)); 00283 IP_SET_TYPE(out, IPADDR_TYPE_ANY); 00284 return true; 00285 } 00286 #endif 00287 00288 return false; 00289 } 00290 00291 #if !LWIP_IPV4 || !LWIP_IPV6 00292 static bool all_zeros(const uint8_t *p, int len) 00293 { 00294 for (int i = 0; i < len; i++) { 00295 if (p[i]) { 00296 return false; 00297 } 00298 } 00299 00300 return true; 00301 } 00302 #endif
Generated on Tue Jul 12 2022 13:54:30 by
