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

          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 1.14