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_netifapi.c Source File

lwip_netifapi.c

Go to the documentation of this file.
00001 /**
00002  * @file
00003  * Network Interface Sequential API module
00004  *
00005  * @defgroup netifapi NETIF API
00006  * @ingroup sequential_api
00007  * Thread-safe functions to be called from non-TCPIP threads
00008  *
00009  * @defgroup netifapi_netif NETIF related
00010  * @ingroup netifapi
00011  * To be called from non-TCPIP threads
00012  */
00013 
00014 /*
00015  * Redistribution and use in source and binary forms, with or without modification,
00016  * are permitted provided that the following conditions are met:
00017  *
00018  * 1. Redistributions of source code must retain the above copyright notice,
00019  *    this list of conditions and the following disclaimer.
00020  * 2. Redistributions in binary form must reproduce the above copyright notice,
00021  *    this list of conditions and the following disclaimer in the documentation
00022  *    and/or other materials provided with the distribution.
00023  * 3. The name of the author may not be used to endorse or promote products
00024  *    derived from this software without specific prior written permission.
00025  *
00026  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
00027  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00028  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
00029  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00031  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
00034  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
00035  * OF SUCH DAMAGE.
00036  *
00037  * This file is part of the lwIP TCP/IP stack.
00038  *
00039  */
00040 
00041 #include "lwip/opt.h"
00042 
00043 #if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */
00044 
00045 #include "lwip/etharp.h"
00046 #include "lwip/netifapi.h"
00047 #include "lwip/memp.h"
00048 #include "lwip/priv/tcpip_priv.h"
00049 
00050 #include <string.h> /* strncpy */
00051 
00052 #define NETIFAPI_VAR_REF(name)      API_VAR_REF(name)
00053 #define NETIFAPI_VAR_DECLARE(name)  API_VAR_DECLARE(struct netifapi_msg, name)
00054 #define NETIFAPI_VAR_ALLOC(name)    API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM)
00055 #define NETIFAPI_VAR_FREE(name)     API_VAR_FREE(MEMP_NETIFAPI_MSG, name)
00056 
00057 /**
00058  * Call netif_add() inside the tcpip_thread context.
00059  */
00060 static err_t
00061 netifapi_do_netif_add(struct tcpip_api_call_data *m)
00062 {
00063   /* cast through void* to silence alignment warnings.
00064    * We know it works because the structs have been instantiated as struct netifapi_msg */
00065   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
00066 
00067   if (!netif_add( msg->netif,
00068 #if LWIP_IPV4
00069                   API_EXPR_REF(msg->msg.add.ipaddr),
00070                   API_EXPR_REF(msg->msg.add.netmask),
00071                   API_EXPR_REF(msg->msg.add.gw),
00072 #endif /* LWIP_IPV4 */
00073                   msg->msg.add.state,
00074                   msg->msg.add.init,
00075                   msg->msg.add.input)) {
00076     return ERR_IF;
00077   } else {
00078     return ERR_OK;
00079   }
00080 }
00081 
00082 #if LWIP_IPV4
00083 /**
00084  * Call netif_set_addr() inside the tcpip_thread context.
00085  */
00086 static err_t
00087 netifapi_do_netif_set_addr(struct tcpip_api_call_data *m)
00088 {
00089   /* cast through void* to silence alignment warnings.
00090    * We know it works because the structs have been instantiated as struct netifapi_msg */
00091   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
00092 
00093   netif_set_addr( msg->netif,
00094                   API_EXPR_REF(msg->msg.add.ipaddr),
00095                   API_EXPR_REF(msg->msg.add.netmask),
00096                   API_EXPR_REF(msg->msg.add.gw));
00097   return ERR_OK;
00098 }
00099 #endif /* LWIP_IPV4 */
00100 
00101 /**
00102 * Call netif_name_to_index() inside the tcpip_thread context.
00103 */
00104 static err_t
00105 netifapi_do_name_to_index(struct tcpip_api_call_data *m)
00106 {
00107   /* cast through void* to silence alignment warnings.
00108    * We know it works because the structs have been instantiated as struct netifapi_msg */
00109   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
00110 
00111   msg->msg.ifs.index = netif_name_to_index(msg->msg.ifs.name);
00112   return ERR_OK;
00113 }
00114 
00115 /**
00116 * Call netif_index_to_name() inside the tcpip_thread context.
00117 */
00118 static err_t
00119 netifapi_do_index_to_name(struct tcpip_api_call_data *m)
00120 {
00121   /* cast through void* to silence alignment warnings.
00122    * We know it works because the structs have been instantiated as struct netifapi_msg */
00123   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
00124 
00125   if (!netif_index_to_name(msg->msg.ifs.index, msg->msg.ifs.name)) {
00126     /* return failure via empty name */
00127     msg->msg.ifs.name[0] = '\0';
00128   }
00129   return ERR_OK;
00130 }
00131 
00132 /**
00133  * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the
00134  * tcpip_thread context.
00135  */
00136 static err_t
00137 netifapi_do_netif_common(struct tcpip_api_call_data *m)
00138 {
00139   /* cast through void* to silence alignment warnings.
00140    * We know it works because the structs have been instantiated as struct netifapi_msg */
00141   struct netifapi_msg *msg = (struct netifapi_msg *)(void *)m;
00142 
00143   if (msg->msg.common.errtfunc != NULL) {
00144     return msg->msg.common.errtfunc(msg->netif);
00145   } else {
00146     msg->msg.common.voidfunc(msg->netif);
00147     return ERR_OK;
00148   }
00149 }
00150 
00151 #if LWIP_ARP && LWIP_IPV4
00152 /**
00153  * @ingroup netifapi_arp
00154  * Add or update an entry in the ARP cache.
00155  * For an update, ipaddr is used to find the cache entry.
00156  *
00157  * @param ipaddr IPv4 address of cache entry
00158  * @param ethaddr hardware address mapped to ipaddr
00159  * @param type type of ARP cache entry
00160  * @return ERR_OK: entry added/updated, else error from err_t
00161  */
00162 err_t
00163 netifapi_arp_add(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, enum netifapi_arp_entry type)
00164 {
00165   err_t err;
00166 
00167   /* We only support permanent entries currently */
00168   LWIP_UNUSED_ARG(type);
00169 
00170 #if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING
00171   LOCK_TCPIP_CORE();
00172   err = etharp_add_static_entry(ipaddr, ethaddr);
00173   UNLOCK_TCPIP_CORE();
00174 #else
00175   /* @todo add new vars to struct netifapi_msg and create a 'do' func */
00176   LWIP_UNUSED_ARG(ipaddr);
00177   LWIP_UNUSED_ARG(ethaddr);
00178   err = ERR_VAL;
00179 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */
00180 
00181   return err;
00182 }
00183 
00184 /**
00185  * @ingroup netifapi_arp
00186  * Remove an entry in the ARP cache identified by ipaddr
00187  *
00188  * @param ipaddr IPv4 address of cache entry
00189  * @param type type of ARP cache entry
00190  * @return ERR_OK: entry removed, else error from err_t
00191  */
00192 err_t
00193 netifapi_arp_remove(const ip4_addr_t *ipaddr, enum netifapi_arp_entry type)
00194 {
00195   err_t err;
00196 
00197   /* We only support permanent entries currently */
00198   LWIP_UNUSED_ARG(type);
00199 
00200 #if ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING
00201   LOCK_TCPIP_CORE();
00202   err = etharp_remove_static_entry(ipaddr);
00203   UNLOCK_TCPIP_CORE();
00204 #else
00205   /* @todo add new vars to struct netifapi_msg and create a 'do' func */
00206   LWIP_UNUSED_ARG(ipaddr);
00207   err = ERR_VAL;
00208 #endif /* ETHARP_SUPPORT_STATIC_ENTRIES && LWIP_TCPIP_CORE_LOCKING */
00209 
00210   return err;
00211 }
00212 #endif /* LWIP_ARP && LWIP_IPV4 */
00213 
00214 /**
00215  * @ingroup netifapi_netif
00216  * Call netif_add() in a thread-safe way by running that function inside the
00217  * tcpip_thread context.
00218  *
00219  * @note for params @see netif_add()
00220  */
00221 err_t
00222 netifapi_netif_add(struct netif *netif,
00223 #if LWIP_IPV4
00224                    const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
00225 #endif /* LWIP_IPV4 */
00226                    void *state, netif_init_fn init, netif_input_fn input)
00227 {
00228   err_t err;
00229   NETIFAPI_VAR_DECLARE(msg);
00230   NETIFAPI_VAR_ALLOC(msg);
00231 
00232 #if LWIP_IPV4
00233   if (ipaddr == NULL) {
00234     ipaddr = IP4_ADDR_ANY4;
00235   }
00236   if (netmask == NULL) {
00237     netmask = IP4_ADDR_ANY4;
00238   }
00239   if (gw == NULL) {
00240     gw = IP4_ADDR_ANY4;
00241   }
00242 #endif /* LWIP_IPV4 */
00243 
00244   NETIFAPI_VAR_REF(msg).netif = netif;
00245 #if LWIP_IPV4
00246   NETIFAPI_VAR_REF(msg).msg.add.ipaddr  = NETIFAPI_VAR_REF(ipaddr);
00247   NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
00248   NETIFAPI_VAR_REF(msg).msg.add.gw      = NETIFAPI_VAR_REF(gw);
00249 #endif /* LWIP_IPV4 */
00250   NETIFAPI_VAR_REF(msg).msg.add.state   = state;
00251   NETIFAPI_VAR_REF(msg).msg.add.init    = init;
00252   NETIFAPI_VAR_REF(msg).msg.add.input   = input;
00253   err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call);
00254   NETIFAPI_VAR_FREE(msg);
00255   return err;
00256 }
00257 
00258 #if LWIP_IPV4
00259 /**
00260  * @ingroup netifapi_netif
00261  * Call netif_set_addr() in a thread-safe way by running that function inside the
00262  * tcpip_thread context.
00263  *
00264  * @note for params @see netif_set_addr()
00265  */
00266 err_t
00267 netifapi_netif_set_addr(struct netif *netif,
00268                         const ip4_addr_t *ipaddr,
00269                         const ip4_addr_t *netmask,
00270                         const ip4_addr_t *gw)
00271 {
00272   err_t err;
00273   NETIFAPI_VAR_DECLARE(msg);
00274   NETIFAPI_VAR_ALLOC(msg);
00275 
00276   if (ipaddr == NULL) {
00277     ipaddr = IP4_ADDR_ANY4;
00278   }
00279   if (netmask == NULL) {
00280     netmask = IP4_ADDR_ANY4;
00281   }
00282   if (gw == NULL) {
00283     gw = IP4_ADDR_ANY4;
00284   }
00285 
00286   NETIFAPI_VAR_REF(msg).netif = netif;
00287   NETIFAPI_VAR_REF(msg).msg.add.ipaddr  = NETIFAPI_VAR_REF(ipaddr);
00288   NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask);
00289   NETIFAPI_VAR_REF(msg).msg.add.gw      = NETIFAPI_VAR_REF(gw);
00290   err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call);
00291   NETIFAPI_VAR_FREE(msg);
00292   return err;
00293 }
00294 #endif /* LWIP_IPV4 */
00295 
00296 /**
00297  * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe
00298  * way by running that function inside the tcpip_thread context.
00299  *
00300  * @note use only for functions where there is only "netif" parameter.
00301  */
00302 err_t
00303 netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc,
00304                       netifapi_errt_fn errtfunc)
00305 {
00306   err_t err;
00307   NETIFAPI_VAR_DECLARE(msg);
00308   NETIFAPI_VAR_ALLOC(msg);
00309 
00310   NETIFAPI_VAR_REF(msg).netif = netif;
00311   NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc;
00312   NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc;
00313   err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call);
00314   NETIFAPI_VAR_FREE(msg);
00315   return err;
00316 }
00317 
00318 /**
00319 * @ingroup netifapi_netif
00320 * Call netif_name_to_index() in a thread-safe way by running that function inside the
00321 * tcpip_thread context.
00322 *
00323 * @param name the interface name of the netif
00324 * @param idx output index of the found netif
00325 */
00326 err_t
00327 netifapi_netif_name_to_index(const char *name, u8_t *idx)
00328 {
00329   err_t err;
00330   NETIFAPI_VAR_DECLARE(msg);
00331   NETIFAPI_VAR_ALLOC(msg);
00332 
00333   *idx = 0;
00334 
00335 #if LWIP_MPU_COMPATIBLE
00336   strncpy(NETIFAPI_VAR_REF(msg).msg.ifs.name, name, NETIF_NAMESIZE - 1);
00337   NETIFAPI_VAR_REF(msg).msg.ifs.name[NETIF_NAMESIZE - 1] = '\0';
00338 #else
00339   NETIFAPI_VAR_REF(msg).msg.ifs.name = LWIP_CONST_CAST(char *, name);
00340 #endif /* LWIP_MPU_COMPATIBLE */
00341   err = tcpip_api_call(netifapi_do_name_to_index, &API_VAR_REF(msg).call);
00342   if (!err) {
00343     *idx = NETIFAPI_VAR_REF(msg).msg.ifs.index;
00344   }
00345   NETIFAPI_VAR_FREE(msg);
00346   return err;
00347 }
00348 
00349 /**
00350 * @ingroup netifapi_netif
00351 * Call netif_index_to_name() in a thread-safe way by running that function inside the
00352 * tcpip_thread context.
00353 *
00354 * @param idx the interface index of the netif
00355 * @param name output name of the found netif, empty '\0' string if netif not found.
00356 *             name should be of at least NETIF_NAMESIZE bytes
00357 */
00358 err_t
00359 netifapi_netif_index_to_name(u8_t idx, char *name)
00360 {
00361   err_t err;
00362   NETIFAPI_VAR_DECLARE(msg);
00363   NETIFAPI_VAR_ALLOC(msg);
00364 
00365   NETIFAPI_VAR_REF(msg).msg.ifs.index = idx;
00366 #if !LWIP_MPU_COMPATIBLE
00367   NETIFAPI_VAR_REF(msg).msg.ifs.name = name;
00368 #endif /* LWIP_MPU_COMPATIBLE */
00369   err = tcpip_api_call(netifapi_do_index_to_name, &API_VAR_REF(msg).call);
00370 #if LWIP_MPU_COMPATIBLE
00371   if (!err) {
00372     strncpy(name, NETIFAPI_VAR_REF(msg).msg.ifs.name, NETIF_NAMESIZE - 1);
00373     name[NETIF_NAMESIZE - 1] = '\0';
00374   }
00375 #endif /* LWIP_MPU_COMPATIBLE */
00376   NETIFAPI_VAR_FREE(msg);
00377   return err;
00378 }
00379 
00380 #endif /* LWIP_NETIF_API */