takashi kadono / Mbed OS Nucleo_446

Dependencies:   ssd1331

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 
00027 #include "netsocket/nsapi_types.h"
00028 
00029 /* LWIP error remapping */
00030 nsapi_error_t LWIP::err_remap(err_t err) {
00031     switch (err) {
00032         case ERR_OK:
00033         case ERR_CLSD:
00034             return 0;
00035         case ERR_MEM:
00036         case ERR_BUF:
00037             return NSAPI_ERROR_NO_MEMORY ;
00038         case ERR_CONN:
00039         case ERR_RST:
00040         case ERR_ABRT:
00041             return NSAPI_ERROR_NO_CONNECTION ;
00042         case ERR_TIMEOUT:
00043         case ERR_RTE:
00044         case ERR_WOULDBLOCK:
00045             return NSAPI_ERROR_WOULD_BLOCK ;
00046         case ERR_VAL:
00047         case ERR_USE:
00048         case ERR_ARG:
00049             return NSAPI_ERROR_PARAMETER ;
00050         case ERR_INPROGRESS:
00051             return NSAPI_ERROR_IN_PROGRESS ;
00052         case ERR_ALREADY:
00053             return NSAPI_ERROR_ALREADY ;
00054         case ERR_ISCONN:
00055             return NSAPI_ERROR_IS_CONNECTED ;
00056         default:
00057             return NSAPI_ERROR_DEVICE_ERROR ;
00058     }
00059 }
00060 
00061 #if LWIP_IPV4
00062 const ip_addr_t *LWIP::get_ipv4_addr(const struct netif *netif)
00063 {
00064     if (!netif_is_up(netif)) {
00065         return NULL;
00066     }
00067 
00068     if (!ip4_addr_isany(netif_ip4_addr(netif))) {
00069         return netif_ip_addr4(netif);
00070     }
00071 
00072     return NULL;
00073 }
00074 #endif
00075 
00076 #if LWIP_IPV6
00077 const ip_addr_t *LWIP::get_ipv6_addr(const struct netif *netif)
00078 {
00079     if (!netif_is_up(netif)) {
00080         return NULL;
00081     }
00082 
00083     for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
00084         if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
00085                 !ip6_addr_islinklocal(netif_ip6_addr(netif, i))) {
00086             return netif_ip_addr6(netif, i);
00087         }
00088     }
00089 
00090     return NULL;
00091 }
00092 #endif
00093 
00094 bool LWIP::is_local_addr(const ip_addr_t *ip_addr)
00095 {
00096     struct netif *netif;
00097 
00098     for (netif = netif_list; netif != NULL; netif = netif->next) {
00099         if (!netif_is_up(netif)) {
00100             continue;
00101         }
00102 #if LWIP_IPV6
00103         if (IP_IS_V6(ip_addr)) {
00104             for (int i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
00105                 if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) &&
00106                     ip6_addr_cmp(netif_ip6_addr(netif, i), ip_2_ip6(ip_addr))) {
00107                     return true;
00108                 }
00109             }
00110         }
00111 #endif
00112 
00113 #if LWIP_IPV4
00114         if (IP_IS_V4(ip_addr)) {
00115             if (!ip4_addr_isany(netif_ip4_addr(netif)) &&
00116                 ip4_addr_cmp(netif_ip4_addr(netif), ip_2_ip4(ip_addr))) {
00117                 return true;
00118             }
00119         }
00120 #endif
00121     }
00122     return false;
00123 }
00124 
00125 const ip_addr_t *LWIP::get_ip_addr(bool any_addr, const struct netif *netif)
00126 {
00127     const ip_addr_t *pref_ip_addr = 0;
00128     const ip_addr_t *npref_ip_addr = 0;
00129 
00130 #if LWIP_IPV4 && LWIP_IPV6
00131 #if IP_VERSION_PREF == PREF_IPV4
00132     pref_ip_addr = get_ipv4_addr(netif);
00133     npref_ip_addr = get_ipv6_addr(netif);
00134 #else
00135     pref_ip_addr = get_ipv6_addr(netif);
00136     npref_ip_addr = get_ipv4_addr(netif);
00137 #endif
00138 #elif LWIP_IPV6
00139     pref_ip_addr = get_ipv6_addr(netif);
00140 #elif LWIP_IPV4
00141     pref_ip_addr = get_ipv4_addr(netif);
00142 #endif
00143 
00144     if (pref_ip_addr) {
00145         return pref_ip_addr;
00146     } else if (npref_ip_addr && any_addr) {
00147         return npref_ip_addr;
00148     }
00149 
00150     return NULL;
00151 }
00152 
00153 void LWIP::arena_init(void)
00154 {
00155     memset(arena, 0, sizeof(arena));
00156 }
00157 
00158 struct LWIP::mbed_lwip_socket *LWIP::arena_alloc()
00159 {
00160     LWIP &lwip = LWIP::get_instance();
00161 
00162     lwip.adaptation.lock();
00163 
00164     for (int i = 0; i < MEMP_NUM_NETCONN; i++) {
00165         if (!arena[i].in_use) {
00166             struct mbed_lwip_socket *s = &arena[i];
00167             memset(s, 0, sizeof(*s));
00168             s->in_use = true;
00169             lwip.adaptation.unlock();
00170             return s;
00171         }
00172     }
00173 
00174     lwip.adaptation.unlock();
00175 
00176     return 0;
00177 }
00178 
00179 void LWIP::arena_dealloc(struct mbed_lwip_socket *s)
00180 {
00181     s->in_use = false;
00182 
00183     while (s->multicast_memberships_count > 0) {
00184         uint32_t index = 0;
00185         index = next_registered_multicast_member(s, index);
00186 
00187         setsockopt(s, NSAPI_SOCKET , NSAPI_DROP_MEMBERSHIP , &s->multicast_memberships[index],
00188             sizeof(s->multicast_memberships[index]));
00189         index++;
00190     }
00191 
00192     free(s->multicast_memberships);
00193     s->multicast_memberships = NULL;
00194 }