1 /* 2 * Copyright (c) 2022 G-Technologies Sdn. Bhd. 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef SHELL_MQTT_H__ 8 #define SHELL_MQTT_H__ 9 10 #include <zephyr/kernel.h> 11 #include <zephyr/shell/shell.h> 12 #include <zephyr/net/socket.h> 13 #include <zephyr/net/net_mgmt.h> 14 #include <zephyr/net/net_event.h> 15 #include <zephyr/net/conn_mgr_monitor.h> 16 #include <zephyr/net/mqtt.h> 17 #include <zephyr/sys/ring_buffer.h> 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 #define RX_RB_SIZE CONFIG_SHELL_MQTT_RX_BUF_SIZE 24 #define TX_BUF_SIZE CONFIG_SHELL_MQTT_TX_BUF_SIZE 25 #define SH_MQTT_BUFFER_SIZE 64 26 #define DEVICE_ID_BIN_MAX_SIZE 3 27 #define DEVICE_ID_HEX_MAX_SIZE ((DEVICE_ID_BIN_MAX_SIZE * 2) + 1) 28 #define SH_MQTT_TOPIC_MAX_SIZE DEVICE_ID_HEX_MAX_SIZE + 3 29 30 extern const struct shell_transport_api shell_mqtt_transport_api; 31 32 struct shell_mqtt_tx_buf { 33 /** tx buffer. */ 34 char buf[TX_BUF_SIZE]; 35 36 /** Current tx buf length. */ 37 uint16_t len; 38 }; 39 40 /** MQTT-based shell transport. */ 41 struct shell_mqtt { 42 char device_id[DEVICE_ID_HEX_MAX_SIZE]; 43 char sub_topic[SH_MQTT_TOPIC_MAX_SIZE]; 44 char pub_topic[SH_MQTT_TOPIC_MAX_SIZE]; 45 46 /** Handler function registered by shell. */ 47 shell_transport_handler_t shell_handler; 48 49 struct ring_buf rx_rb; 50 uint8_t rx_rb_buf[RX_RB_SIZE]; 51 uint8_t *rx_rb_ptr; 52 53 struct shell_mqtt_tx_buf tx_buf; 54 55 /** Context registered by shell. */ 56 void *shell_context; 57 58 /** The mqtt client struct */ 59 struct mqtt_client mqtt_cli; 60 61 /* Buffers for MQTT client. */ 62 struct buffer { 63 uint8_t rx[SH_MQTT_BUFFER_SIZE]; 64 uint8_t tx[SH_MQTT_BUFFER_SIZE]; 65 } buf; 66 67 struct k_mutex lock; 68 69 /** MQTT Broker details. */ 70 struct sockaddr_storage broker; 71 72 struct zsock_addrinfo *haddr; 73 struct zsock_pollfd fds[1]; 74 int nfds; 75 76 struct mqtt_publish_param pub_data; 77 78 struct net_mgmt_event_callback mgmt_cb; 79 80 /** work */ 81 struct k_work_q workq; 82 struct k_work net_disconnected_work; 83 struct k_work_delayable connect_dwork; 84 struct k_work_delayable subscribe_dwork; 85 struct k_work_delayable process_dwork; 86 struct k_work_delayable publish_dwork; 87 88 /** MQTT connection states */ 89 enum sh_mqtt_transport_state { 90 SHELL_MQTT_TRANSPORT_DISCONNECTED, 91 SHELL_MQTT_TRANSPORT_CONNECTED, 92 } transport_state; 93 94 /** MQTT subscription states */ 95 enum sh_mqtt_subscribe_state { 96 SHELL_MQTT_NOT_SUBSCRIBED, 97 SHELL_MQTT_SUBSCRIBED, 98 } subscribe_state; 99 100 /** Network states */ 101 enum sh_mqtt_network_state { 102 SHELL_MQTT_NETWORK_DISCONNECTED, 103 SHELL_MQTT_NETWORK_CONNECTED, 104 } network_state; 105 }; 106 107 #define SHELL_MQTT_DEFINE(_name) \ 108 static struct shell_mqtt _name##_shell_mqtt; \ 109 struct shell_transport _name = { .api = &shell_mqtt_transport_api, \ 110 .ctx = (struct shell_mqtt *)&_name##_shell_mqtt } 111 112 /** 113 * @brief This function provides pointer to shell mqtt backend instance. 114 * 115 * Function returns pointer to the shell mqtt instance. This instance can be 116 * next used with shell_execute_cmd function in order to test commands behavior. 117 * 118 * @returns Pointer to the shell instance. 119 */ 120 const struct shell *shell_backend_mqtt_get_ptr(void); 121 122 /** 123 * @brief Function to define the device ID (devid) for which the shell mqtt backend uses as a 124 * client ID when it connects to the broker. It will publish its output to devid_tx and subscribe 125 * to devid_rx for input . 126 * 127 * @note This is a weak-linked function, and can be overridden if desired. 128 * 129 * @param id Pointer to the devid buffer 130 * @param id_max_len Maximum size of the devid buffer defined by DEVICE_ID_HEX_MAX_SIZE 131 * 132 * @return true if length of devid > 0 133 */ 134 bool shell_mqtt_get_devid(char *id, int id_max_len); 135 136 #ifdef __cplusplus 137 } 138 #endif 139 140 #endif /* SHELL_MQTT_H__ */ 141