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

          Line data    Source code
       1           1 : /*
       2             :  * Copyright (c) 2023 Basalte bv
       3             :  *
       4             :  * SPDX-License-Identifier: Apache-2.0
       5             :  */
       6             : 
       7             : /** @file
       8             :  * @brief CoAP Service API
       9             :  *
      10             :  * An API for applications to respond to CoAP requests
      11             :  */
      12             : 
      13             : #ifndef ZEPHYR_INCLUDE_NET_COAP_SERVICE_H_
      14             : #define ZEPHYR_INCLUDE_NET_COAP_SERVICE_H_
      15             : 
      16             : #include <zephyr/net/coap.h>
      17             : #include <zephyr/sys/iterable_sections.h>
      18             : 
      19             : #ifdef __cplusplus
      20             : extern "C" {
      21             : #endif
      22             : 
      23             : /**
      24             :  * @brief CoAP Service API
      25             :  * @defgroup coap_service CoAP service API
      26             :  * @since 3.6
      27             :  * @version 0.1.0
      28             :  * @ingroup networking
      29             :  * @{
      30             :  */
      31             : 
      32             : /**
      33             :  * @name CoAP Service configuration flags
      34             :  * @anchor COAP_SERVICE_FLAGS
      35             :  * @{
      36             :  */
      37             : 
      38             : /** Start the service on boot. */
      39           1 : #define COAP_SERVICE_AUTOSTART          BIT(0)
      40             : 
      41             : /** @} */
      42             : 
      43             : /** @cond INTERNAL_HIDDEN */
      44             : 
      45             : struct coap_service_data {
      46             :         int sock_fd;
      47             :         struct coap_observer observers[CONFIG_COAP_SERVICE_OBSERVERS];
      48             :         struct coap_pending pending[CONFIG_COAP_SERVICE_PENDING_MESSAGES];
      49             : };
      50             : 
      51             : struct coap_service {
      52             :         const char *name;
      53             :         const char *host;
      54             :         uint16_t *port;
      55             :         uint8_t flags;
      56             :         struct coap_resource *res_begin;
      57             :         struct coap_resource *res_end;
      58             :         struct coap_service_data *data;
      59             : };
      60             : 
      61             : #define __z_coap_service_define(_name, _host, _port, _flags, _res_begin, _res_end)              \
      62             :         static struct coap_service_data _CONCAT(coap_service_data_, _name) = {                  \
      63             :                 .sock_fd = -1,                                                                  \
      64             :         };                                                                                      \
      65             :         const STRUCT_SECTION_ITERABLE(coap_service, _name) = {                                  \
      66             :                 .name = STRINGIFY(_name),                                                       \
      67             :                 .host = _host,                                                                  \
      68             :                 .port = (uint16_t *)(_port),                                                    \
      69             :                 .flags = _flags,                                                                \
      70             :                 .res_begin = (_res_begin),                                                      \
      71             :                 .res_end = (_res_end),                                                          \
      72             :                 .data = &_CONCAT(coap_service_data_, _name),                                        \
      73             :         }
      74             : 
      75             : /** @endcond */
      76             : 
      77             : /**
      78             :  * @brief Define a static CoAP resource owned by the service named @p _service .
      79             :  *
      80             :  * @note The handlers registered with the resource can return a CoAP response code to reply with
      81             :  * an acknowledge without any payload, nothing is sent if the return value is 0 or negative.
      82             :  * As seen in the example.
      83             :  *
      84             :  * @code{.c}
      85             :  *     static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(DT_ALIAS(led0), gpios);
      86             :  *
      87             :  *     static int led_put(struct coap_resource *resource, struct coap_packet *request,
      88             :  *                        struct sockaddr *addr, socklen_t addr_len)
      89             :  *     {
      90             :  *             const uint8_t *payload;
      91             :  *             uint16_t payload_len;
      92             :  *
      93             :  *             payload = coap_packet_get_payload(request, &payload_len);
      94             :  *             if (payload_len != 1) {
      95             :  *                     return COAP_RESPONSE_CODE_BAD_REQUEST;
      96             :  *             }
      97             :  *
      98             :  *             if (gpio_pin_set_dt(&led, payload[0]) < 0) {
      99             :  *                     return COAP_RESPONSE_CODE_INTERNAL_ERROR;
     100             :  *             }
     101             :  *
     102             :  *             return COAP_RESPONSE_CODE_CHANGED;
     103             :  *     }
     104             :  *
     105             :  *     COAP_RESOURCE_DEFINE(my_resource, my_service, {
     106             :  *             .put = led_put,
     107             :  *     });
     108             :  * @endcode
     109             :  *
     110             :  * @param _name Name of the resource.
     111             :  * @param _service Name of the associated service.
     112             :  */
     113           1 : #define COAP_RESOURCE_DEFINE(_name, _service, ...)                                              \
     114             :         STRUCT_SECTION_ITERABLE_ALTERNATE(_CONCAT(coap_resource_, _service), coap_resource,     \
     115             :                                           _name) = __VA_ARGS__
     116             : 
     117             : /**
     118             :  * @brief Define a CoAP service with static resources.
     119             :  *
     120             :  * @note The @p _host parameter can be `NULL`. If not, it is used to specify an IP address either in
     121             :  * IPv4 or IPv6 format a fully-qualified hostname or a virtual host, otherwise the any address is
     122             :  * used.
     123             :  *
     124             :  * @note The @p _port parameter must be non-`NULL`. It points to a location that specifies the port
     125             :  * number to use for the service. If the specified port number is zero, then an ephemeral port
     126             :  * number will be used and the actual port number assigned will be written back to memory. For
     127             :  * ephemeral port numbers, the memory pointed to by @p _port must be writeable.
     128             :  *
     129             :  * @param _name Name of the service.
     130             :  * @param _host IP address or hostname associated with the service.
     131             :  * @param[inout] _port Pointer to port associated with the service.
     132             :  * @param _flags Configuration flags @see @ref COAP_SERVICE_FLAGS.
     133             :  */
     134           1 : #define COAP_SERVICE_DEFINE(_name, _host, _port, _flags)                                        \
     135             :         extern struct coap_resource _CONCAT(_CONCAT(_coap_resource_, _name), _list_start)[];    \
     136             :         extern struct coap_resource _CONCAT(_CONCAT(_coap_resource_, _name), _list_end)[];      \
     137             :         __z_coap_service_define(_name, _host, _port, _flags,                                    \
     138             :                                 &_CONCAT(_CONCAT(_coap_resource_, _name), _list_start)[0],  \
     139             :                                 &_CONCAT(_CONCAT(_coap_resource_, _name), _list_end)[0])
     140             : 
     141             : /**
     142             :  * @brief Count the number of CoAP services.
     143             :  *
     144             :  * @param[out] _dst Pointer to location where result is written.
     145             :  */
     146           1 : #define COAP_SERVICE_COUNT(_dst) STRUCT_SECTION_COUNT(coap_service, _dst)
     147             : 
     148             : /**
     149             :  * @brief Count CoAP service static resources.
     150             :  *
     151             :  * @param _service Pointer to a service.
     152             :  */
     153           1 : #define COAP_SERVICE_RESOURCE_COUNT(_service) ((_service)->res_end - (_service)->res_begin)
     154             : 
     155             : /**
     156             :  * @brief Check if service has the specified resource.
     157             :  *
     158             :  * @param _service Pointer to a service.
     159             :  * @param _resource Pointer to a resource.
     160             :  */
     161           1 : #define COAP_SERVICE_HAS_RESOURCE(_service, _resource)                                          \
     162             :         ((_service)->res_begin <= _resource && _resource < (_service)->res_end)
     163             : 
     164             : /**
     165             :  * @brief Iterate over all CoAP services.
     166             :  *
     167             :  * @param _it Name of iterator (of type @ref coap_service)
     168             :  */
     169           1 : #define COAP_SERVICE_FOREACH(_it) STRUCT_SECTION_FOREACH(coap_service, _it)
     170             : 
     171             : /**
     172             :  * @brief Iterate over static CoAP resources associated with a given @p _service.
     173             :  *
     174             :  * @note This macro requires that @p _service is defined with @ref COAP_SERVICE_DEFINE.
     175             :  *
     176             :  * @param _service Name of CoAP service
     177             :  * @param _it Name of iterator (of type @ref coap_resource)
     178             :  */
     179           1 : #define COAP_RESOURCE_FOREACH(_service, _it)                                                    \
     180             :         STRUCT_SECTION_FOREACH_ALTERNATE(_CONCAT(coap_resource_, _service), coap_resource, _it)
     181             : 
     182             : /**
     183             :  * @brief Iterate over all static resources associated with @p _service .
     184             :  *
     185             :  * @note This macro is suitable for a @p _service defined with @ref COAP_SERVICE_DEFINE.
     186             :  *
     187             :  * @param _service Pointer to COAP service
     188             :  * @param _it Name of iterator (of type @ref coap_resource)
     189             :  */
     190           1 : #define COAP_SERVICE_FOREACH_RESOURCE(_service, _it)                                            \
     191             :         for (struct coap_resource *_it = (_service)->res_begin; ({                           \
     192             :                 __ASSERT(_it <= (_service)->res_end, "unexpected list end location");           \
     193             :                 _it < (_service)->res_end;                                                        \
     194             :         }); _it++)
     195             : 
     196             : /**
     197             :  * @brief Start the provided @p service .
     198             :  *
     199             :  * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE.
     200             :  *
     201             :  * @param service Pointer to CoAP service
     202             :  * @retval 0 in case of success.
     203             :  * @retval -EALREADY in case of an already running service.
     204             :  * @retval -ENOTSUP in case the server has no valid host and port configuration.
     205             :  */
     206           1 : int coap_service_start(const struct coap_service *service);
     207             : 
     208             : /**
     209             :  * @brief Stop the provided @p service .
     210             :  *
     211             :  * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE.
     212             :  *
     213             :  * @param service Pointer to CoAP service
     214             :  * @retval 0 in case of success.
     215             :  * @retval -EALREADY in case the service isn't running.
     216             :  */
     217           1 : int coap_service_stop(const struct coap_service *service);
     218             : 
     219             : /**
     220             :  * @brief Query the provided @p service running state.
     221             :  *
     222             :  * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE.
     223             :  *
     224             :  * @param service Pointer to CoAP service
     225             :  * @retval 1 if the service is running
     226             :  * @retval 0 if the service is stopped
     227             :  * @retval negative in case of an error.
     228             :  */
     229           1 : int coap_service_is_running(const struct coap_service *service);
     230             : 
     231             : /**
     232             :  * @brief Send a CoAP message from the provided @p service .
     233             :  *
     234             :  * @note This function is suitable for a @p service defined with @ref COAP_SERVICE_DEFINE.
     235             :  *
     236             :  * @param service Pointer to CoAP service
     237             :  * @param cpkt CoAP Packet to send
     238             :  * @param addr Peer address
     239             :  * @param addr_len Peer address length
     240             :  * @param params Pointer to transmission parameters structure or NULL to use default values.
     241             :  * @return 0 in case of success or negative in case of error.
     242             :  */
     243           1 : int coap_service_send(const struct coap_service *service, const struct coap_packet *cpkt,
     244             :                       const struct sockaddr *addr, socklen_t addr_len,
     245             :                       const struct coap_transmission_parameters *params);
     246             : 
     247             : /**
     248             :  * @brief Send a CoAP message from the provided @p resource .
     249             :  *
     250             :  * @note This function is suitable for a @p resource defined with @ref COAP_RESOURCE_DEFINE.
     251             :  *
     252             :  * @param resource Pointer to CoAP resource
     253             :  * @param cpkt CoAP Packet to send
     254             :  * @param addr Peer address
     255             :  * @param addr_len Peer address length
     256             :  * @param params Pointer to transmission parameters structure or NULL to use default values.
     257             :  * @return 0 in case of success or negative in case of error.
     258             :  */
     259           1 : int coap_resource_send(const struct coap_resource *resource, const struct coap_packet *cpkt,
     260             :                        const struct sockaddr *addr, socklen_t addr_len,
     261             :                        const struct coap_transmission_parameters *params);
     262             : 
     263             : /**
     264             :  * @brief Parse a CoAP observe request for the provided @p resource .
     265             :  *
     266             :  * @note This function is suitable for a @p resource defined with @ref COAP_RESOURCE_DEFINE.
     267             :  *
     268             :  * If the observe option value is equal to 0, an observer will be added, if the value is equal
     269             :  * to 1, an existing observer will be removed.
     270             :  *
     271             :  * @param resource Pointer to CoAP resource
     272             :  * @param request CoAP request to parse
     273             :  * @param addr Peer address
     274             :  * @return the observe option value in case of success or negative in case of error.
     275             :  */
     276           1 : int coap_resource_parse_observe(struct coap_resource *resource, const struct coap_packet *request,
     277             :                                 const struct sockaddr *addr);
     278             : 
     279             : /**
     280             :  * @brief Lookup an observer by address and remove it from the @p resource .
     281             :  *
     282             :  * @note This function is suitable for a @p resource defined with @ref COAP_RESOURCE_DEFINE.
     283             :  *
     284             :  * @param resource Pointer to CoAP resource
     285             :  * @param addr Peer address
     286             :  * @return 0 in case of success or negative in case of error.
     287             :  */
     288           1 : int coap_resource_remove_observer_by_addr(struct coap_resource *resource,
     289             :                                           const struct sockaddr *addr);
     290             : 
     291             : /**
     292             :  * @brief Lookup an observer by token and remove it from the @p resource .
     293             :  *
     294             :  * @note This function is suitable for a @p resource defined with @ref COAP_RESOURCE_DEFINE.
     295             :  *
     296             :  * @param resource Pointer to CoAP resource
     297             :  * @param token Pointer to the token
     298             :  * @param token_len Length of valid bytes in the token
     299             :  * @return 0 in case of success or negative in case of error.
     300             :  */
     301           1 : int coap_resource_remove_observer_by_token(struct coap_resource *resource,
     302             :                                            const uint8_t *token, uint8_t token_len);
     303             : 
     304             : /**
     305             :  * @}
     306             :  */
     307             : 
     308             : #ifdef __cplusplus
     309             : }
     310             : #endif
     311             : 
     312             : #endif /* ZEPHYR_INCLUDE_NET_COAP_SERVICE_H_ */

Generated by: LCOV version 1.14