LCOV - code coverage report
Current view: top level - zephyr/net - conn_mgr_connectivity_impl.h Coverage Total Hit
Test: new.info Lines: 100.0 % 25 25
Test Date: 2025-10-20 12:20:01

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

Generated by: LCOV version 2.0-1