Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers lwip_tools.cpp Source File

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