LCOV - code coverage report
Current view: top level - zephyr/net - conn_mgr_connectivity_impl.h Hit Total Coverage
Test: new.info Lines: 24 24 100.0 %
Date: 2024-12-22 00:14:23

          Line data    Source code
       1           1 : /*
       2             :  * Copyright (c) 2023 Nordic Semiconductor ASA
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : 
       7             : /**
       8             :  * @file
       9             :  * @brief API for defining conn_mgr connectivity implementations (allowing ifaces to be used with
      10             :  * conn_mgr_connectivity).
      11             :  */
      12             : 
      13             : #ifndef ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_IMPL_H_
      14             : #define ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_IMPL_H_
      15             : 
      16             : #include <zephyr/device.h>
      17             : #include <zephyr/net/net_if.h>
      18             : #include <zephyr/sys/iterable_sections.h>
      19             : #include <zephyr/net/net_mgmt.h>
      20             : #include <zephyr/net/conn_mgr_connectivity.h>
      21             : 
      22             : #ifdef __cplusplus
      23             : extern "C" {
      24             : #endif
      25             : 
      26             : /**
      27             :  * @brief Connection Manager Connectivity Implementation API
      28             :  * @defgroup conn_mgr_connectivity_impl Connection Manager Connectivity Implementation API
      29             :  * @since 3.4
      30             :  * @version 0.1.0
      31             :  * @ingroup conn_mgr_connectivity
      32             :  * @{
      33             :  */
      34             : 
      35             : /* Forward declaration */
      36             : struct conn_mgr_conn_binding;
      37             : 
      38             : /**
      39             :  * @brief Connectivity Manager Connectivity API structure
      40             :  *
      41             :  * Used to provide generic access to network association parameters and procedures
      42             :  */
      43           1 : struct conn_mgr_conn_api {
      44             :         /**
      45             :          * @brief When called, the connectivity implementation should start attempting to
      46             :          * establish connectivity (association with a network) for the bound iface pointed
      47             :          * to by if_conn->iface.
      48             :          *
      49             :          * Must be non-blocking.
      50             :          *
      51             :          * Called by @ref conn_mgr_if_connect.
      52             :          */
      53           1 :         int (*connect)(struct conn_mgr_conn_binding *const binding);
      54             : 
      55             :         /**
      56             :          * @brief When called, the connectivity implementation should disconnect (disassociate), or
      57             :          * stop any in-progress attempts to associate to a network, the bound iface pointed to by
      58             :          * if_conn->iface.
      59             :          *
      60             :          * Must be non-blocking.
      61             :          *
      62             :          * Called by @ref conn_mgr_if_disconnect.
      63             :          */
      64           1 :         int (*disconnect)(struct conn_mgr_conn_binding *const binding);
      65             : 
      66             :         /**
      67             :          * @brief Called once for each iface that has been bound to a connectivity implementation
      68             :          * using this API.
      69             :          *
      70             :          * Connectivity implementations should use this callback to perform any required
      71             :          * per-bound-iface initialization.
      72             :          *
      73             :          * Implementations may choose to gracefully handle invalid buffer lengths with partial
      74             :          * writes, rather than raise errors, if deemed appropriate.
      75             :          */
      76           1 :         void (*init)(struct conn_mgr_conn_binding *const binding);
      77             : 
      78             :         /**
      79             :          * @brief Implementation callback for conn_mgr_if_set_opt.
      80             :          *
      81             :          * Used to set implementation-specific connectivity settings.
      82             :          *
      83             :          * Calls to conn_mgr_if_set_opt on an iface will result in calls to this callback with
      84             :          * the conn_mgr_conn_binding struct bound to that iface.
      85             :          *
      86             :          * It is up to the connectivity implementation to interpret optname. Options can be
      87             :          * specific to the bound iface (pointed to by if_conn->iface), or can apply to the whole
      88             :          * connectivity implementation.
      89             :          *
      90             :          * See the description of conn_mgr_if_set_opt for more details.
      91             :          * set_opt implementations should conform to that description.
      92             :          *
      93             :          * Implementations may choose to gracefully handle invalid buffer lengths with partial
      94             :          * reads, rather than raise errors, if deemed appropriate.
      95             :          */
      96           1 :         int (*set_opt)(struct conn_mgr_conn_binding *const binding,
      97             :                        int optname, const void *optval, size_t optlen);
      98             : 
      99             :         /**
     100             :          * @brief Implementation callback for conn_mgr_if_get_opt.
     101             :          *
     102             :          * Used to retrieve implementation-specific connectivity settings.
     103             :          *
     104             :          * Calls to conn_mgr_if_get_opt on an iface will result in calls to this callback with
     105             :          * the conn_mgr_conn_binding struct bound to that iface.
     106             :          *
     107             :          * It is up to the connectivity implementation to interpret optname. Options can be
     108             :          * specific to the bound iface (pointed to by if_conn->iface), or can apply to the whole
     109             :          * connectivity implementation.
     110             :          *
     111             :          * See the description of conn_mgr_if_get_opt for more details.
     112             :          * get_opt implementations should conform to that description.
     113             :          */
     114           1 :         int (*get_opt)(struct conn_mgr_conn_binding *const binding,
     115             :                        int optname, void *optval, size_t *optlen);
     116             : };
     117             : 
     118             : /** @cond INTERNAL_HIDDEN */
     119             : #define CONN_MGR_CONN_IMPL_GET_NAME(conn_id)            __conn_mgr_conn_##conn_id
     120             : #define CONN_MGR_CONN_IMPL_GET_CTX_TYPE(conn_id)        conn_id##_CTX_TYPE
     121             : /** @endcond */
     122             : 
     123             : /**
     124             :  * @brief Connectivity Implementation struct
     125             :  *
     126             :  * Declares a conn_mgr connectivity layer implementation with the provided API
     127             :  */
     128           1 : struct conn_mgr_conn_impl {
     129             :         /** The connectivity API used by the implementation */
     130           1 :         struct conn_mgr_conn_api *api;
     131             : };
     132             : 
     133             : /**
     134             :  * @brief Define a conn_mgr connectivity implementation that can be bound to network devices.
     135             :  *
     136             :  * @param conn_id The name of the new connectivity implementation
     137             :  * @param conn_api A pointer to a conn_mgr_conn_api struct
     138             :  */
     139           1 : #define CONN_MGR_CONN_DEFINE(conn_id, conn_api)                                         \
     140             :         const struct conn_mgr_conn_impl CONN_MGR_CONN_IMPL_GET_NAME(conn_id) = {        \
     141             :                 .api = conn_api,                                                        \
     142             :         };
     143             : 
     144             : /**
     145             :  * @brief Helper macro to make a conn_mgr connectivity implementation publicly available.
     146             :  */
     147           1 : #define CONN_MGR_CONN_DECLARE_PUBLIC(conn_id)                                           \
     148             :         extern const struct conn_mgr_conn_impl CONN_MGR_CONN_IMPL_GET_NAME(conn_id)
     149             : 
     150             : /** @cond INTERNAL_HIDDEN */
     151             : #define CONN_MGR_CONN_BINDING_GET_NAME(dev_id, sfx)     __conn_mgr_bndg_##dev_id##_##sfx
     152             : #define CONN_MGR_CONN_BINDING_GET_DATA(dev_id, sfx)     __conn_mgr_bndg_data_##dev_id##_##sfx
     153             : #define CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, sfx)    __conn_mgr_bndg_mutex_##dev_id##_##sfx
     154             : /** @endcond */
     155             : 
     156             : /**
     157             :  * @brief Connectivity Manager network interface binding structure
     158             :  *
     159             :  * Binds a conn_mgr connectivity implementation to an iface / network device.
     160             :  * Stores per-iface state for the connectivity implementation.
     161             :  */
     162           1 : struct conn_mgr_conn_binding {
     163             :         /** The network interface the connectivity implementation is bound to */
     164           1 :         struct net_if *iface;
     165             : 
     166             :         /** The connectivity implementation the network device is bound to */
     167           1 :         const struct conn_mgr_conn_impl *impl;
     168             : 
     169             :         /** Pointer to private, per-iface connectivity context */
     170           1 :         void *ctx;
     171             : 
     172             :         /**
     173             :          * @name Generic connectivity state
     174             :          * @{
     175             :          */
     176             : 
     177             :         /**
     178             :          * Connectivity flags
     179             :          *
     180             :          * Public boolean state and configuration values supported by all bindings.
     181             :          * See conn_mgr_if_flag for options.
     182             :          */
     183           1 :         uint32_t flags;
     184             : 
     185             :         /**
     186             :          * Timeout (seconds)
     187             :          *
     188             :          * Indicates to the connectivity implementation how long it should attempt to
     189             :          * establish connectivity for during a connection attempt before giving up.
     190             :          *
     191             :          * The connectivity implementation should give up on establishing connectivity after this
     192             :          * timeout, even if persistence is enabled.
     193             :          *
     194             :          * Set to @ref CONN_MGR_IF_NO_TIMEOUT to indicate that no timeout should be used.
     195             :          */
     196           1 :         int timeout;
     197             : 
     198             :         /** @} */
     199             : 
     200             : /** @cond INTERNAL_HIDDEN */
     201             :         /* Internal-use mutex for protecting access to the binding and API functions. */
     202             :         struct k_mutex *mutex;
     203             : /** @endcond */
     204             : };
     205             : 
     206             : /**
     207             :  * @brief Associate a connectivity implementation with an existing network device instance
     208             :  *
     209             :  * @param dev_id Network device id.
     210             :  * @param inst Network device instance.
     211             :  * @param conn_id Name of the connectivity implementation to associate.
     212             :  */
     213           1 : #define CONN_MGR_BIND_CONN_INST(dev_id, inst, conn_id)                                          \
     214             :         K_MUTEX_DEFINE(CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, inst));                          \
     215             :         static CONN_MGR_CONN_IMPL_GET_CTX_TYPE(conn_id)                                         \
     216             :                                         CONN_MGR_CONN_BINDING_GET_DATA(dev_id, inst);           \
     217             :         static STRUCT_SECTION_ITERABLE(conn_mgr_conn_binding,                                   \
     218             :                                         CONN_MGR_CONN_BINDING_GET_NAME(dev_id, inst)) = {       \
     219             :                 .iface = NET_IF_GET(dev_id, inst),                                              \
     220             :                 .impl = &(CONN_MGR_CONN_IMPL_GET_NAME(conn_id)),                            \
     221             :                 .ctx = &(CONN_MGR_CONN_BINDING_GET_DATA(dev_id, inst)),                             \
     222             :                 .mutex = &(CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, inst))                   \
     223             :         };
     224             : 
     225             : /**
     226             :  * @brief Associate a connectivity implementation with an existing network device
     227             :  *
     228             :  * @param dev_id Network device id.
     229             :  * @param conn_id Name of the connectivity implementation to associate.
     230             :  */
     231           1 : #define CONN_MGR_BIND_CONN(dev_id, conn_id)             \
     232             :         CONN_MGR_BIND_CONN_INST(dev_id, 0, conn_id)
     233             : 
     234             : /**
     235             :  * @brief Retrieves the conn_mgr binding struct for a provided iface if it exists.
     236             :  *
     237             :  * Bindings for connectivity implementations with missing API structs are ignored.
     238             :  *
     239             :  * For use only by connectivity implementations.
     240             :  *
     241             :  * @param iface - bound network interface to obtain the binding struct for.
     242             :  * @return struct conn_mgr_conn_binding* Pointer to the retrieved binding struct if it exists,
     243             :  *         NULL otherwise.
     244             :  */
     245           1 : static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface)
     246             : {
     247             :         STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) {
     248             :                 if (iface == binding->iface) {
     249             :                         if (binding->impl->api) {
     250             :                                 return binding;
     251             :                         }
     252             :                         return NULL;
     253             :                 }
     254             :         }
     255             :         return NULL;
     256             : }
     257             : 
     258             : /**
     259             :  * @brief Lock the passed-in binding, making it safe to access.
     260             :  *
     261             :  * Call this whenever accessing binding data, unless inside a conn_mgr_conn_api callback, where it
     262             :  * is called automatically by conn_mgr.
     263             :  *
     264             :  * Reentrant.
     265             :  *
     266             :  * For use only by connectivity implementations.
     267             :  *
     268             :  * @param binding - Binding to lock
     269             :  */
     270           1 : static inline void conn_mgr_binding_lock(struct conn_mgr_conn_binding *binding)
     271             : {
     272             :         (void)k_mutex_lock(binding->mutex, K_FOREVER);
     273             : }
     274             : 
     275             : /**
     276             :  * @brief Unlocks the passed-in binding.
     277             :  *
     278             :  * Call this after any call to @ref conn_mgr_binding_lock once done accessing binding data.
     279             :  *
     280             :  * Reentrant.
     281             :  *
     282             :  * For use only by connectivity implementations.
     283             :  *
     284             :  * @param binding - Binding to unlock
     285             :  */
     286           1 : static inline void conn_mgr_binding_unlock(struct conn_mgr_conn_binding *binding)
     287             : {
     288             :         (void)k_mutex_unlock(binding->mutex);
     289             : }
     290             : 
     291             : /**
     292             :  * @brief Set the value of the specified connectivity flag for the provided binding
     293             :  *
     294             :  * Can be used from any thread or callback without calling @ref conn_mgr_binding_lock.
     295             :  *
     296             :  * For use only by connectivity implementations
     297             :  *
     298             :  * @param binding The binding to check
     299             :  * @param flag The flag to check
     300             :  * @param value New value for the specified flag
     301             :  */
     302           1 : static inline void conn_mgr_binding_set_flag(struct conn_mgr_conn_binding *binding,
     303             :                                              enum conn_mgr_if_flag flag, bool value)
     304             : {
     305             :         conn_mgr_binding_lock(binding);
     306             : 
     307             :         binding->flags &= ~BIT(flag);
     308             :         if (value) {
     309             :                 binding->flags |= BIT(flag);
     310             :         }
     311             : 
     312             :         conn_mgr_binding_unlock(binding);
     313             : }
     314             : 
     315             : /**
     316             :  * @brief Check the value of the specified connectivity flag for the provided binding
     317             :  *
     318             :  * Can be used from any thread or callback without calling @ref conn_mgr_binding_lock.
     319             :  *
     320             :  * For use only by connectivity implementations
     321             :  *
     322             :  * @param binding The binding to check
     323             :  * @param flag The flag to check
     324             :  * @return bool The value of the specified flag
     325             :  */
     326           1 : static inline bool conn_mgr_binding_get_flag(struct conn_mgr_conn_binding *binding,
     327             :                                              enum conn_mgr_if_flag flag)
     328             : {
     329             :         bool value = false;
     330             : 
     331             :         conn_mgr_binding_lock(binding);
     332             : 
     333             :         value = !!(binding->flags & BIT(flag));
     334             : 
     335             :         conn_mgr_binding_unlock(binding);
     336             : 
     337             :         return value;
     338             : }
     339             : 
     340             : /**
     341             :  * @}
     342             :  */
     343             : 
     344             : #ifdef __cplusplus
     345             : }
     346             : #endif
     347             : 
     348             : #endif /* ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_IMPL_H_ */

Generated by: LCOV version 1.14