LCOV - code coverage report
Current view: top level - zephyr/net - mqtt_sn.h Coverage Total Hit
Test: new.info Lines: 100.0 % 59 59
Test Date: 2025-09-05 22:20:39

            Line data    Source code
       1            1 : /*
       2              :  * Copyright (c) 2022 René Beckmann
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /** @file mqtt_sn.h
       8              :  *
       9              :  * @brief MQTT-SN Client Implementation
      10              :  *
      11              :  * @details
      12              :  * MQTT-SN Client's Application interface is defined in this header.
      13              :  * Targets protocol version 1.2.
      14              :  *
      15              :  * @defgroup mqtt_sn_socket MQTT-SN Client library
      16              :  * @since 3.3
      17              :  * @version 0.1.0
      18              :  * @ingroup networking
      19              :  * @{
      20              :  */
      21              : 
      22              : #ifndef ZEPHYR_INCLUDE_NET_MQTT_SN_H_
      23              : #define ZEPHYR_INCLUDE_NET_MQTT_SN_H_
      24              : 
      25              : #include <stddef.h>
      26              : 
      27              : #include <zephyr/net_buf.h>
      28              : #include <zephyr/types.h>
      29              : 
      30              : #include <sys/types.h>
      31              : 
      32              : #ifdef CONFIG_MQTT_SN_TRANSPORT_UDP
      33              : #include <zephyr/net/net_ip.h>
      34              : #endif
      35              : 
      36              : #ifdef __cplusplus
      37              : extern "C" {
      38              : #endif
      39              : 
      40              : /**
      41              :  * Quality of Service. QoS 0-2 work the same as basic MQTT, QoS -1 is an MQTT-SN addition.
      42              :  * QOS -1 is not supported yet.
      43              :  */
      44            1 : enum mqtt_sn_qos {
      45              :         MQTT_SN_QOS_0, /**< QOS 0 */
      46              :         MQTT_SN_QOS_1, /**< QOS 1 */
      47              :         MQTT_SN_QOS_2, /**< QOS 2 */
      48              :         MQTT_SN_QOS_M1 /**< QOS -1 */
      49              : };
      50              : 
      51              : /**
      52              :  * MQTT-SN topic types.
      53              :  */
      54            1 : enum mqtt_sn_topic_type {
      55              :         /**
      56              :          * Normal topic.
      57              :          * It allows usage of any valid UTF-8 string as a topic name.
      58              :          */
      59              :         MQTT_SN_TOPIC_TYPE_NORMAL,
      60              :         /**
      61              :          * Pre-defined topic.
      62              :          * It allows usage of a two-byte identifier representing a topic name for
      63              :          * which the corresponding topic name is known in advance by both the client
      64              :          * and the gateway/server.
      65              :          */
      66              :         MQTT_SN_TOPIC_TYPE_PREDEF,
      67              :         /**
      68              :          * Short topic.
      69              :          * It allows usage of a two-byte string as a topic name.
      70              :          */
      71              :         MQTT_SN_TOPIC_TYPE_SHORT
      72              : };
      73              : 
      74              : /**
      75              :  * MQTT-SN return codes.
      76              :  */
      77            1 : enum mqtt_sn_return_code {
      78              :         MQTT_SN_CODE_ACCEPTED = 0x00,            /**< Accepted */
      79              :         MQTT_SN_CODE_REJECTED_CONGESTION = 0x01, /**< Rejected: congestion */
      80              :         MQTT_SN_CODE_REJECTED_TOPIC_ID = 0x02,   /**< Rejected: Invalid Topic ID */
      81              :         MQTT_SN_CODE_REJECTED_NOTSUP = 0x03,     /**< Rejected: Not Supported */
      82              : };
      83              : 
      84              : /** @brief Abstracts memory buffers. */
      85            1 : struct mqtt_sn_data {
      86            1 :         const uint8_t *data; /**< Pointer to data. */
      87            1 :         size_t size;         /**< Size of data, in bytes. */
      88              : };
      89              : 
      90              : /**
      91              :  * @brief Initialize memory buffer from C literal string.
      92              :  *
      93              :  * Use it as follows:
      94              :  *
      95              :  * struct mqtt_sn_data topic = MQTT_SN_DATA_STRING_LITERAL("/zephyr");
      96              :  *
      97              :  * @param[in] literal Literal string from which to generate mqtt_sn_data object.
      98              :  */
      99            1 : #define MQTT_SN_DATA_STRING_LITERAL(literal) ((struct mqtt_sn_data){literal, sizeof(literal) - 1})
     100              : 
     101              : /**
     102              :  * @brief Initialize memory buffer from single bytes.
     103              :  *
     104              :  * Use it as follows:
     105              :  *
     106              :  * struct mqtt_sn_data data = MQTT_SN_DATA_BYTES(0x13, 0x37);
     107              :  */
     108            1 : #define MQTT_SN_DATA_BYTES(...)                                                                    \
     109              :         ((struct mqtt_sn_data){(uint8_t[]){__VA_ARGS__}, sizeof((uint8_t[]){__VA_ARGS__})})
     110              : 
     111              : /**
     112              :  * Event types that can be emitted by the library.
     113              :  */
     114            1 : enum mqtt_sn_evt_type {
     115              :         MQTT_SN_EVT_CONNECTED,    /**< Connected to a gateway */
     116              :         MQTT_SN_EVT_DISCONNECTED, /**< Disconnected */
     117              :         MQTT_SN_EVT_ASLEEP,       /**< Entered ASLEEP state */
     118              :         MQTT_SN_EVT_AWAKE,        /**< Entered AWAKE state */
     119              :         MQTT_SN_EVT_PUBLISH,      /**< Received a PUBLISH message */
     120              :         MQTT_SN_EVT_PINGRESP,     /**< Received a PINGRESP */
     121              :         MQTT_SN_EVT_ADVERTISE,    /**< Received a ADVERTISE */
     122              :         MQTT_SN_EVT_GWINFO,       /**< Received a GWINFO */
     123              :         MQTT_SN_EVT_SEARCHGW      /**< Received a SEARCHGW */
     124              : };
     125              : 
     126              : /**
     127              :  * Event metadata.
     128              :  */
     129            1 : union mqtt_sn_evt_param {
     130              :         /** Structure holding publish event details */
     131              :         struct {
     132              :                 /** The payload data associated with the event */
     133            1 :                 struct mqtt_sn_data data;
     134              :                 /** The type of topic for the event */
     135            1 :                 enum mqtt_sn_topic_type topic_type;
     136              :                 /** The identifier for the topic of the event */
     137            1 :                 uint16_t topic_id;
     138            1 :         } publish;
     139              : };
     140              : 
     141              : /**
     142              :  * MQTT-SN event structure to be handled by the event callback.
     143              :  */
     144            1 : struct mqtt_sn_evt {
     145              :         /** Event type */
     146            1 :         enum mqtt_sn_evt_type type;
     147              :         /** Event parameters */
     148            1 :         union mqtt_sn_evt_param param;
     149              : };
     150              : 
     151              : struct mqtt_sn_client;
     152              : 
     153              : /**
     154              :  * @brief Asynchronous event notification callback registered by the
     155              :  *        application.
     156              :  *
     157              :  * @param[in] client Identifies the client for which the event is notified.
     158              :  * @param[in] evt Event description along with result and associated
     159              :  *                parameters (if any).
     160              :  */
     161            1 : typedef void (*mqtt_sn_evt_cb_t)(struct mqtt_sn_client *client, const struct mqtt_sn_evt *evt);
     162              : 
     163              : /**
     164              :  * @brief Structure to describe an MQTT-SN transport.
     165              :  *
     166              :  * MQTT-SN does not require transports to be reliable or to hold a connection.
     167              :  * Transports just need to be frame-based, so you can use UDP, ZigBee, or even
     168              :  * a simple UART, given some kind of framing protocol is used.
     169              :  */
     170            1 : struct mqtt_sn_transport {
     171              :         /**
     172              :          * @brief Will be called once on client init to initialize the transport.
     173              :          *
     174              :          * Use this to open sockets or similar. May be NULL.
     175              :          */
     176            1 :         int (*init)(struct mqtt_sn_transport *transport);
     177              : 
     178              :         /**
     179              :          * @brief Will be called on client deinit
     180              :          *
     181              :          * Use this to close sockets or similar. May be NULL.
     182              :          */
     183            1 :         void (*deinit)(struct mqtt_sn_transport *transport);
     184              : 
     185              :         /**
     186              :          * @brief Will be called by the library when it wants to send a message.
     187              :          *
     188              :          * Implementations should follow sendto conventions with exceptions.
     189              :          * When dest_addr == NULL, message should be broadcast with addrlen being
     190              :          * the broadcast radius. This should also handle setting up/destroying
     191              :          * connections as required when the address changes.
     192              :          *
     193              :          * @return ENOERR on connection+transmission success, Negative values
     194              :          *              signal errors.
     195              :          */
     196            1 :         int (*sendto)(struct mqtt_sn_client *client, void *buf, size_t sz, const void *dest_addr,
     197              :                       size_t addrlen);
     198              : 
     199              :         /**
     200              :          * @brief Will be called by the library when it wants to receive a message.
     201              :          *
     202              :          * Implementations should follow recvfrom conventions with the exception
     203              :          * of a NULL src_addr being a broadcast message.
     204              :          */
     205            1 :         ssize_t (*recvfrom)(struct mqtt_sn_client *client, void *rx_buf, size_t rx_len,
     206              :                             void *src_addr, size_t *addrlen);
     207              : 
     208              :         /**
     209              :          * @brief Check if incoming data is available.
     210              :          *
     211              :          * If poll() returns a positive number, recv must not block.
     212              :          *
     213              :          * May be NULL, but recv should not block then either.
     214              :          *
     215              :          * @return Positive number if data is available, or zero if there is none.
     216              :          * Negative values signal errors.
     217              :          */
     218            1 :         int (*poll)(struct mqtt_sn_client *client);
     219              : };
     220              : 
     221              : #ifdef CONFIG_MQTT_SN_TRANSPORT_UDP
     222              : /**
     223              :  * Transport struct for UDP based transport.
     224              :  */
     225              : struct mqtt_sn_transport_udp {
     226              :         /** Parent struct */
     227              :         struct mqtt_sn_transport tp;
     228              : 
     229              :         /** Socket FD */
     230              :         int sock;
     231              : 
     232              :         /** Address of broadcasts */
     233              :         struct sockaddr bcaddr;
     234              :         socklen_t bcaddrlen;
     235              : };
     236              : 
     237              : #define UDP_TRANSPORT(transport) CONTAINER_OF(transport, struct mqtt_sn_transport_udp, tp)
     238              : 
     239              : /**
     240              :  * @brief Initialize the UDP transport.
     241              :  *
     242              :  * @param[in] udp The transport to be initialized
     243              :  * @param[in] gwaddr Pre-initialized gateway address
     244              :  * @param[in] addrlen Size of the gwaddr structure.
     245              :  */
     246              : int mqtt_sn_transport_udp_init(struct mqtt_sn_transport_udp *udp, struct sockaddr *gwaddr,
     247              :                                socklen_t addrlen);
     248              : #endif
     249              : 
     250              : /**
     251              :  * Structure describing an MQTT-SN client.
     252              :  */
     253            1 : struct mqtt_sn_client {
     254              :         /** 1-23 character unique client ID */
     255            1 :         struct mqtt_sn_data client_id;
     256              : 
     257              :         /** Topic for Will message.
     258              :          * Must be initialized before connecting with will=true
     259              :          */
     260            1 :         struct mqtt_sn_data will_topic;
     261              : 
     262              :         /** Will message.
     263              :          * Must be initialized before connecting with will=true
     264              :          */
     265            1 :         struct mqtt_sn_data will_msg;
     266              : 
     267              :         /** Quality of Service for the Will message */
     268            1 :         enum mqtt_sn_qos will_qos;
     269              : 
     270              :         /** Flag indicating if the will message should be retained by the broker */
     271            1 :         bool will_retain;
     272              : 
     273              :         /** Underlying transport to be used by the client */
     274            1 :         struct mqtt_sn_transport *transport;
     275              : 
     276              :         /** Buffer for outgoing data */
     277            1 :         struct net_buf_simple tx;
     278              : 
     279              :         /** Buffer for incoming data */
     280            1 :         struct net_buf_simple rx;
     281              : 
     282              :         /** Buffer for incoming data sender address */
     283            1 :         struct net_buf_simple rx_addr;
     284              : 
     285              :         /** Event callback */
     286            1 :         mqtt_sn_evt_cb_t evt_cb;
     287              : 
     288              :         /** Message ID for the next message to be sent */
     289            1 :         uint16_t next_msg_id;
     290              : 
     291              :         /** List of pending publish messages */
     292            1 :         sys_slist_t publish;
     293              : 
     294              :         /** List of registered topics */
     295            1 :         sys_slist_t topic;
     296              : 
     297              :         /** List of found gateways */
     298            1 :         sys_slist_t gateway;
     299              : 
     300              :         /** Current state of the MQTT-SN client */
     301            1 :         int state;
     302              : 
     303              :         /** Timestamp of the last ping request */
     304            1 :         int64_t last_ping;
     305              : 
     306              :         /** Number of retries for failed ping attempts */
     307            1 :         uint8_t ping_retries;
     308              : 
     309              :         /** Timestamp of the next SEARCHGW transmission */
     310            1 :         int64_t ts_searchgw;
     311              : 
     312              :         /** Timestamp of the next GWINFO transmission */
     313            1 :         int64_t ts_gwinfo;
     314              : 
     315              :         /** Radius of the next GWINFO transmission */
     316            1 :         int64_t radius_gwinfo;
     317              : 
     318              :         /** Delayable work structure for processing MQTT-SN events */
     319            1 :         struct k_work_delayable process_work;
     320              : };
     321              : 
     322              : /**
     323              :  * @brief Initialize a client.
     324              :  *
     325              :  * @param client        The MQTT-SN client to initialize.
     326              :  * @param client_id     The ID to be used by the client.
     327              :  * @param transport     The transport to be used by the client.
     328              :  * @param evt_cb        The event callback function for the client.
     329              :  * @param tx            Pointer to the transmit buffer.
     330              :  * @param txsz          Size of the transmit buffer.
     331              :  * @param rx            Pointer to the receive buffer.
     332              :  * @param rxsz          Size of the receive buffer.
     333              :  *
     334              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     335              :  */
     336            1 : int mqtt_sn_client_init(struct mqtt_sn_client *client, const struct mqtt_sn_data *client_id,
     337              :                         struct mqtt_sn_transport *transport, mqtt_sn_evt_cb_t evt_cb, void *tx,
     338              :                         size_t txsz, void *rx, size_t rxsz);
     339              : 
     340              : /**
     341              :  * @brief Deinitialize the client.
     342              :  *
     343              :  * This removes all topics and publishes, and also de-inits the transport.
     344              :  *
     345              :  * @param client        The MQTT-SN client to deinitialize.
     346              :  */
     347            1 : void mqtt_sn_client_deinit(struct mqtt_sn_client *client);
     348              : 
     349              : /**
     350              :  * @brief Manually add a Gateway, bypasing the normal search process.
     351              :  *
     352              :  * This function manually creates a gateway that is stored internal to the library.
     353              :  *
     354              :  * @param client      The MQTT-SN client to connect.
     355              :  * @param gw_id       Single byte Gateway Identifier
     356              :  * @param gw_addr     Address data structure to be used by the transport layer.
     357              :  *
     358              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     359              :  */
     360            1 : int mqtt_sn_add_gw(struct mqtt_sn_client *client, uint8_t gw_id, struct mqtt_sn_data gw_addr);
     361              : 
     362              : /**
     363              :  * @brief Initiate the MQTT-SN GW Search process.
     364              :  *
     365              :  * @param client     The MQTT-SN client to connect.
     366              :  * @param radius     Broadcast radius for the search message.
     367              :  *
     368              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     369              :  */
     370            1 : int mqtt_sn_search(struct mqtt_sn_client *client, uint8_t radius);
     371              : 
     372              : /**
     373              :  * @brief Connect the client.
     374              :  *
     375              :  * @param client            The MQTT-SN client to connect.
     376              :  * @param will              Flag indicating if a Will message should be sent.
     377              :  * @param clean_session     Flag indicating if a clean session should be started.
     378              :  *
     379              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     380              :  */
     381            1 : int mqtt_sn_connect(struct mqtt_sn_client *client, bool will, bool clean_session);
     382              : 
     383              : /**
     384              :  * @brief Disconnect the client.
     385              :  *
     386              :  * @param client            The MQTT-SN client to disconnect.
     387              :  *
     388              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     389              :  */
     390            1 : int mqtt_sn_disconnect(struct mqtt_sn_client *client);
     391              : 
     392              : /**
     393              :  * @brief Set the client into sleep state.
     394              :  *
     395              :  * @param client            The MQTT-SN client to be put to sleep.
     396              :  * @param duration          Sleep duration (in seconds).
     397              :  *
     398              :  * @return 0 on success, negative errno code on failure.
     399              :  */
     400            1 : int mqtt_sn_sleep(struct mqtt_sn_client *client, uint16_t duration);
     401              : 
     402              : /**
     403              :  * @brief Subscribe to a given topic.
     404              :  *
     405              :  * @param client            The MQTT-SN client that should subscribe.
     406              :  * @param qos               The desired quality of service for the subscription.
     407              :  * @param topic_name        The name of the topic to subscribe to.
     408              :  *
     409              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     410              :  */
     411            1 : int mqtt_sn_subscribe(struct mqtt_sn_client *client, enum mqtt_sn_qos qos,
     412              :                       struct mqtt_sn_data *topic_name);
     413              : 
     414              : /**
     415              :  * @brief Unsubscribe from a topic.
     416              :  *
     417              :  * @param client            The MQTT-SN client that should unsubscribe.
     418              :  * @param qos               The quality of service used when subscribing.
     419              :  * @param topic_name        The name of the topic to unsubscribe from.
     420              :  *
     421              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     422              :  */
     423            1 : int mqtt_sn_unsubscribe(struct mqtt_sn_client *client, enum mqtt_sn_qos qos,
     424              :                         struct mqtt_sn_data *topic_name);
     425              : 
     426              : /**
     427              :  * @brief Publish a value.
     428              :  *
     429              :  * If the topic is not yet registered with the gateway, the library takes care of it.
     430              :  *
     431              :  * @param client            The MQTT-SN client that should publish.
     432              :  * @param qos               The desired quality of service for the publish.
     433              :  * @param topic_name        The name of the topic to publish to.
     434              :  * @param retain            Flag indicating if the message should be retained by the broker.
     435              :  * @param data              The data to be published.
     436              :  *
     437              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     438              :  */
     439            1 : int mqtt_sn_publish(struct mqtt_sn_client *client, enum mqtt_sn_qos qos,
     440              :                     struct mqtt_sn_data *topic_name, bool retain, struct mqtt_sn_data *data);
     441              : 
     442              : /**
     443              :  * @brief Check the transport for new incoming data.
     444              :  *
     445              :  * Call this function periodically, or if you have good reason to believe there is any data.
     446              :  * If the client's transport struct contains a poll-function, this function is non-blocking.
     447              :  *
     448              :  * @param client            The MQTT-SN client to check for incoming data.
     449              :  *
     450              :  * @return 0 or a negative error code (errno.h) indicating reason of failure.
     451              :  */
     452            1 : int mqtt_sn_input(struct mqtt_sn_client *client);
     453              : 
     454              : /**
     455              :  * @brief Get topic name by topic ID.
     456              :  *
     457              :  * @param[in] client The MQTT-SN client that uses this topic.
     458              :  * @param[in] id Topic identifier.
     459              :  * @param[out] topic_name Will be assigned to topic name.
     460              :  *
     461              :  * @return 0 on success, -ENOENT if topic ID doesn't exist,
     462              :  * or -EINVAL on invalid arguments.
     463              :  */
     464            1 : int mqtt_sn_get_topic_name(struct mqtt_sn_client *client, uint16_t id,
     465              :                            struct mqtt_sn_data *topic_name);
     466              : 
     467              : #ifdef __cplusplus
     468              : }
     469              : #endif
     470              : 
     471              : #endif /* ZEPHYR_INCLUDE_NET_MQTT_SN_H_ */
     472              : 
     473              : /**@}  */
        

Generated by: LCOV version 2.0-1