1 #ifndef _CORE_MQTT_H_
2 #define _CORE_MQTT_H_
3 
4 #if defined(__cplusplus)
5 extern "C" {
6 #endif
7 
8 #include "core_stdinc.h"
9 #include "core_list.h"
10 #include "core_string.h"
11 #include "core_log.h"
12 #include "core_auth.h"
13 #include "core_global.h"
14 #include "core_diag.h"
15 #include "aiot_state_api.h"
16 #include "aiot_sysdep_api.h"
17 #include "aiot_mqtt_api.h"
18 
19 /**
20  *
21  * MQTT3.1 Fixed Header
22  * | Bit       |          7 ~ 4           |            3 ~ 0            |
23  * | byte 1    | MQTT Control Packet Type | Flags specific to each Type |
24  * | byte 2... |             Remaining Length(1 ~ 4 bytes)              |
25  *
26  * MQTT3.1 UTF-8 Encoded Strings
27  * | Bit       |                         7 ~ 0                          |
28  * | byte 1    |                   String Length MSB                    |
29  * | byte 2    |                   String Length LSB                    |
30  * | byte 3... |              UTF-8 Encoded Character Data              |
31  *
32  */
33 
34 #define CORE_MQTT_FIXED_HEADER_LEN                  (1)
35 #define CORE_MQTT_REMAINLEN_MAXLEN                  (4)
36 #define CORE_MQTT_UTF8_STR_EXTRA_LEN                (2)
37 #define CORE_MQTT_PACKETID_LEN                      (2)
38 #define CORE_MQTT_REQUEST_QOS_LEN                   (1)
39 #define CORE_MQTT_QOS0                              (0x00)
40 #define CORE_MQTT_QOS1                              (0x01)
41 #define CORE_MQTT_QOS_MAX                           (1)
42 #define CORE_MQTT_TOPIC_MAXLEN                      (128)
43 #define CORE_MQTT_PAYLOAD_MAXLEN                    (1024 * 1024 + 1)
44 
45 
46 /* MQTT 3.1 Connect Packet */
47 #define CORE_MQTT_CONN_PKT_TYPE                     (0x10)
48 #define CORE_MQTT_CONN_FIXED_HEADER_LEN             (CORE_MQTT_FIXED_HEADER_LEN) /* value: 0x10 */
49 #define CORE_MQTT_CONN_REMAINLEN_MAXLEN             (CORE_MQTT_REMAINLEN_MAXLEN)
50 #define CORE_MQTT_CONN_PROTOCOL_NAME_LEN            (6) /* value: 0x00, 0x04, 0x4D, 0x51, 0x54, 0x54 */
51 #define CORE_MQTT_CONN_PROTOCOL_LEVEL_LEN           (1) /* value: 0x04 */
52 #define CORE_MQTT_CONN_CONNECT_FLAG_LEN             (1) /* value: 0xC0 */
53 #define CORE_MQTT_CONN_KEEP_ALIVE_LEN               (2) /* value: CORE_MQTT_conn_pkt_t.keep_alive */
54 #define CORE_MQTT_CONN_FIXED_HEADER_TOTAL_LEN       (CORE_MQTT_CONN_FIXED_HEADER_LEN + \
55         CORE_MQTT_CONN_REMAINLEN_MAXLEN + \
56         CORE_MQTT_CONN_PROTOCOL_NAME_LEN + \
57         CORE_MQTT_CONN_PROTOCOL_LEVEL_LEN + \
58         CORE_MQTT_CONN_CONNECT_FLAG_LEN + \
59         CORE_MQTT_CONN_KEEP_ALIVE_LEN)
60 #define CORE_MQTT_CONN_REMAINLEN_FIXED_LEN          (CORE_MQTT_CONN_PROTOCOL_NAME_LEN + \
61         CORE_MQTT_CONN_PROTOCOL_LEVEL_LEN + \
62         CORE_MQTT_CONN_CONNECT_FLAG_LEN + \
63         CORE_MQTT_CONN_KEEP_ALIVE_LEN)
64 
65 /* MQTT 3.1 Connect ACK Packet */
66 #define CORE_MQTT_CONNACK_PKT_TYPE                  (0x20)
67 #define CORE_MQTT_CONNACK_FIXED_HEADER_LEN          (CORE_MQTT_FIXED_HEADER_LEN) /* value: 0x20 */
68 #define CORE_MQTT_CONNACK_REMAINLEN_MAXLEN          (1) /* value: 0x02 */
69 #define CORE_MQTT_CONNACK_FLAGS_LEN                 (1) /* value: 0x00 */
70 #define CORE_MQTT_CONNACK_RETURN_CODE_LEN           (1)
71 #define CORE_MQTT_CONNACK_FIXED_HEADER_TOTAL_LEN    (CORE_MQTT_CONNACK_FIXED_HEADER_LEN + \
72         CORE_MQTT_CONNACK_REMAINLEN_MAXLEN + \
73         CORE_MQTT_CONNACK_FLAGS_LEN + \
74         CORE_MQTT_CONNACK_RETURN_CODE_LEN)
75 
76 #define CORE_MQTT_CONNACK_RCODE_ACCEPTED                            (0x00)
77 #define CORE_MQTT_CONNACK_RCODE_UNACCEPTABLE_PROTOCOL_VERSION       (0x01)
78 #define CORE_MQTT_CONNACK_RCODE_SERVER_UNAVAILABLE                  (0x02)
79 #define CORE_MQTT_CONNACK_RCODE_BAD_USERNAME_PASSWORD               (0x03)
80 #define CORE_MQTT_CONNACK_RCODE_NOT_AUTHORIZED                      (0x04)
81 
82 #define CORE_MQTT_DYNREG_CONNACK_RCODE_ACCEPTED                     (0x00)
83 #define CORE_MQTT_DYNREG_CONNACK_RCODE_IDENTIFIER_REJECTED          (0x02)
84 #define CORE_MQTT_DYNREG_CONNACK_RCODE_SERVER_UNAVAILABLE           (0x03)
85 #define CORE_MQTT_DYNREG_CONNACK_RCODE_BAD_USERNAME_PASSWORD        (0x04)
86 
87 /* MQTT 5.0 conack error code */
88 #define CORE_MQTT_V5_CONNACK_RCODE_UNACCEPTABLE_PROTOCOL_VERSION    (0x84)
89 #define CORE_MQTT_V5_CONNACK_RCODE_BAD_USERNAME_PASSWORD            (0x86)
90 #define CORE_MQTT_V5_CONNACK_RCODE_SERVER_UNAVAILABLE               (0x88)
91 #define CORE_MQTT_V5_CONNACK_RCODE_NOT_AUTHORIZED                   (0x87)
92 
93 /* MQTT 5.0 conack error code */
94 #define CORE_MQTT_V5_PROPERTY_ID_LEN                                 (1)
95 #define CORE_MQTT_V5_USER_PROPERTY_KEY_LEN                           (2)
96 #define CORE_MQTT_V5_USER_PROPERTY_VALUE_LEN                         (2)
97 #define CORE_MQTT_V5_TOPIC_ALIAS_LEN                                 (2)
98 #define CORE_MQTT_V5_TOPIC_ALIAS_MAX_LEN                             (2)
99 #define CORE_MQTT_V5_RECEIVE_MAX_LEN                                 (2)
100 #define CORE_MQTT_V5_RESPONSE_TOPIC_LEN                              (2)
101 #define CORE_MQTT_V5_CORELATION_DATA_LEN                             (2)
102 #define CORE_MQTT_V5_REASON_STRING_LEN                               (2)
103 #define CORE_MQTT_V5_DISCONNECT_REASON_CODE_LEN                      (1)
104 
105 /* MQTT 3.1 Disconnect Packet */
106 #define CORE_MQTT_DISCONNECT_PKT_TYPE               (0xE0)
107 
108 /* MQTT 3.1 Ping Request Packet */
109 #define CORE_MQTT_PINGREQ_PKT_TYPE                  (0xC0)
110 
111 /* MQTT 3.1 Ping Response Packet */
112 #define CORE_MQTT_PINGRESP_PKT_TYPE                 (0xD0)
113 #define CORE_MQTT_PINGRESP_FIXED_HEADER_LEN         (CORE_MQTT_FIXED_HEADER_LEN) /* value: 0xD0 */
114 #define CORE_MQTT_PINGRESP_REMAINLEN_MAXLEN         (1) /* value: 0x00 */
115 
116 /* MQTT 3.1 Publish Packet */
117 #define CORE_MQTT_PUBLISH_PKT_TYPE                  (0x30)
118 #define CORE_MQTT_PUBLISH_TOPICLEN_LEN              (2)
119 
120 /* MQTT 3.1 Publish ACK Packet */
121 #define CORE_MQTT_PUBACK_PKT_TYPE                   (0x40)
122 
123 /* MQTT 3.1 Subscribe Packet */
124 #define CORE_MQTT_SUB_PKT_TYPE                      (0x80)
125 #define CORE_MQTT_SUB_PKT_RESERVE                   (0x02)
126 #define CORE_MQTT_UNSUB_PKT_RESERVE                 (0x02)
127 
128 /* MQTT 3.1 Subscribe ACK Packet */
129 #define CORE_MQTT_SUBACK_PKT_TYPE                   (0x90)
130 
131 #define CORE_MQTT_SUBACK_RCODE_MAXQOS0              (0x00)
132 #define CORE_MQTT_SUBACK_RCODE_MAXQOS1              (0x01)
133 #define CORE_MQTT_SUBACK_RCODE_MAXQOS2              (0x02)
134 #define CORE_MQTT_SUBACK_RCODE_FAILURE              (0x80)
135 
136 /* MQTT 3.1 Unsubscribe Packet */
137 #define CORE_MQTT_UNSUB_PKT_TYPE                    (0xA0)
138 
139 /* MQTT 3.1 Unsubscribe ACK Packet */
140 #define CORE_MQTT_UNSUBACK_PKT_TYPE                 (0xB0)
141 
142 /* MQTT 3.1 unimplemented Packet */
143 #define CORE_MQTT_PUBREC_PKT_TYPE                   (0x50)
144 #define CORE_MQTT_PUBREL_PKT_TYPE                   (0x60)
145 #define CORE_MQTT_PUBCOMP_PKT_TYPE                  (0x70)
146 
147 /* MQTT 5.0 implemented Packet */
148 #define CORE_MQTT_SERVER_DISCONNECT_PKT_TYPE        (0xE0)
149 
150 typedef struct {
151     uint8_t    *buffer;
152     uint32_t    len;
153 } core_mqtt_buff_t;
154 
155 typedef struct {
156     aiot_mqtt_recv_handler_t handler;
157     void *userdata;
158     struct core_list_head linked_node;
159 } core_mqtt_sub_handler_node_t;
160 
161 typedef struct {
162     char *topic;
163     struct core_list_head linked_node;
164     struct core_list_head handle_list;
165 } core_mqtt_sub_node_t;
166 
167 typedef struct {
168     uint16_t packet_id;
169     uint8_t *packet;
170     uint32_t len;
171     uint64_t last_send_time;
172     struct core_list_head linked_node;
173 } core_mqtt_pub_node_t;
174 
175 typedef enum {
176     CORE_MQTTEVT_DEINIT
177 } core_mqtt_event_type_t;
178 
179 typedef struct {
180     core_mqtt_event_type_t type;
181 } core_mqtt_event_t;
182 
183 typedef void (*core_mqtt_process_handler_t)(void *context, aiot_mqtt_event_t *event, core_mqtt_event_t *core_event);
184 
185 typedef struct {
186     core_mqtt_process_handler_t handler;
187     void *context;
188 } core_mqtt_process_data_t;
189 
190 typedef struct {
191     core_mqtt_process_data_t process_data;
192     struct core_list_head linked_node;
193 } core_mqtt_process_data_node_t;
194 
195 typedef struct {
196     uint32_t    interval_ms;
197     uint8_t     max_lost_times;
198     uint32_t    lost_times;
199     uint64_t    last_send_time;
200 } core_mqtt_heartbeat_t;
201 
202 typedef struct {
203     uint8_t enabled;
204     uint32_t interval_ms;
205     uint64_t last_retry_time;
206 } core_mqtt_reconnect_t;
207 
208 typedef struct {
209     /* network info */
210     uint8_t network_type;       /* 0: TCP, 1: TLS */
211     uint64_t connect_timestamp;
212     uint32_t connect_time_used;
213     uint64_t failed_timestamp;
214     int32_t failed_error_code;
215 
216     /* heartbeat rtt info */
217     uint64_t rtt;
218 } core_mqtt_nwkstats_info_t;
219 
220 typedef struct {
221     aiot_sysdep_portfile_t *sysdep;
222     void *network_handle;
223     char *host;
224     uint16_t port;
225     char *product_key;
226     char *device_name;
227     char *device_secret;
228     char *username;
229     char *password;
230     char *clientid;
231     char *extend_clientid;
232     char *security_mode;
233     uint16_t keep_alive_s;
234     uint8_t clean_session;
235     uint8_t append_requestid;
236     uint32_t connect_timeout_ms;
237     core_mqtt_heartbeat_t heartbeat_params;
238     core_mqtt_reconnect_t reconnect_params;
239     uint32_t send_timeout_ms;
240     uint32_t recv_timeout_ms;
241     uint32_t repub_timeout_ms;
242     aiot_sysdep_network_cred_t *cred;
243     uint8_t has_connected;
244     uint8_t disconnected;
245     uint8_t disconnect_api_called;
246     uint8_t exec_enabled;
247     uint32_t exec_count;
248     uint32_t deinit_timeout_ms;
249     uint16_t packet_id;
250     void *data_mutex;
251     void *send_mutex;
252     void *recv_mutex;
253     void *sub_mutex;
254     void *pub_mutex;
255     void *process_handler_mutex;
256     struct core_list_head sub_list;
257     struct core_list_head pub_list;
258     struct core_list_head process_data_list;
259     aiot_mqtt_recv_handler_t recv_handler;
260     aiot_mqtt_event_handler_t event_handler;
261 
262     /* network info stats */
263     core_mqtt_nwkstats_info_t nwkstats_info;
264 
265     void *userdata;
266 
267     /* mqtt protovol version */
268     uint8_t protocol_version;
269 
270     /* mqtt 5.0 specific*/
271     void *topic_alias_mutex;
272     struct core_list_head rx_topic_alias_list;
273     struct core_list_head tx_topic_alias_list;
274     uint8_t *pre_connect_property;
275     uint8_t use_assigned_clientid;
276     uint32_t tx_packet_max_size;
277     uint32_t tx_topic_alias_max;
278     uint32_t tx_topic_alias;
279     uint16_t server_receive_max;
280     uint8_t flow_control_enabled;
281 } core_mqtt_handle_t;
282 
283 /* topic alias node. mqtt 5.0 specific*/
284 typedef struct {
285     char *topic;
286     uint16_t topic_alias;
287     struct core_list_head linked_node;
288 } core_mqtt_topic_alias_node_t;
289 
290 /**
291  * @brief MQTT5.0 属性的枚举
292  *
293  * @details
294  *
295  * 传入@ref conn_property_t 等数据结构的MQTT报文类型
296  *
297  */
298 typedef enum {
299     CORE_MQTTPROP_UNRESOLVED = 0x00,
300     CORE_MQTTPROP_PAYLOAD_FORMAT_INDICATOR = 0x01,
301     CORE_MQTTPROP_PUBLICATION_EXPIRY_INTERVAL = 0x2,
302     CORE_MQTTPROP_CONTENT_TYPE = 0x3,
303     CORE_MQTTPROP_RESPONSE_TOPIC = 0x8,
304     CORE_MQTTPROP_CORRELATION_DATA = 0x9,
305     CORE_MQTTPROP_SUBSCRIPTION_IDENTIFIER = 0xB,
306     CORE_MQTTPROP_SESSION_EXPIRY_INTERVAL = 0x11,
307     CORE_MQTTPROP_ASSIGNED_CLIENT_IDENTIFIER = 0x12,
308     CORE_MQTTPROP_SERVER_KEEP_ALIVE = 0x13,
309     CORE_MQTTPROP_AUTHENTICATION_METHOD = 0x15,
310     CORE_MQTTPROP_AUTHENTICATION_DATA = 0x16,
311     CORE_MQTTPROP_REQUEST_PROBLEM_INFORMATION = 0x17,
312     CORE_MQTTPROP_WILL_DELAY_INTERVAL = 0x18,
313     CORE_MQTTPROP_REQUEST_RESPONSE_INFORMATION = 0x19,
314     CORE_MQTTPROP_RESPONSE_INFORMATION = 0x1A,
315     CORE_MQTTPROP_SERVER_REFERENCE = 0x1C,
316     CORE_MQTTPROP_REASON_STRING = 0x1F,
317     CORE_MQTTPROP_RECEIVE_MAXIMUM = 0x21,
318     CORE_MQTTPROP_TOPIC_ALIAS_MAX = 0x22,
319     CORE_MQTTPROP_TOPIC_ALIAS = 0x23,
320     CORE_MQTTPROP_MAX_QOS = 0x24,
321     CORE_MQTTPROP_RETAIN_AVAILABLE = 0x25,
322     CORE_MQTTPROP_USER_PROPERTY = 0x26,
323     CORE_MQTTPROP_MAX_PACK_SIZE = 0x27,
324     CORE_MQTTPROP_WILDCARD_SUBSCRIPTION_AVAILABLE = 0x28,
325     CORE_MQTTPROP_SUBSCRIPTION_IDENTIFIER_AVAILABLE = 0x29,
326     CORE_MQTTPROP_SHARED_SUBSCRIPTION_AVAILABLE = 0x2A,
327     CORE_MQTTPROP_MAX,
328 } core_mqtt_property_t;
329 
330 /* tlv structure. mqtt 5.0 specific */
331 typedef struct {
332     core_mqtt_property_t type;
333     uint16_t len;
334     uint8_t  *value;
335 } type_len_value_t;
336 
337 /**
338  * @brief MQTT 5.0协议中, 上下行报文中所能携带属性
339  */
340 typedef struct {
341     uint8_t max_qos;
342     uint16_t topic_alias_max;           /* 服务端/设备端能够支持的topic alias最大值 */
343     uint8_t *assigned_clientid;
344     uint32_t max_packet_size;
345     uint8_t wildcard_subscription_available;
346     uint8_t subscription_identifier_available;
347     uint8_t shared_subscription_available;
348     uint32_t message_expire_interval;
349     uint16_t topic_alias;
350     len_value_t response_topic;          /*response topic */
351     len_value_t correlation_data;        /* 关联数据 */
352     uint32_t subscription_identifier;
353     user_property_t
354     *user_property[USER_PROPERTY_MAX];   /* 用户属性的列表 todo 改成**的结构 */
355     uint16_t server_receive_max;         /* 服务端的qos1流控值 */
356     uint16_t client_receive_max;         /* 设备端的qos1流控值 */
357     len_value_t *reason_string;
358 } general_property_t;
359 
360 /* default configuration */
361 #define CORE_MQTT_MODULE_NAME                      "MQTT"
362 #define CORE_MQTT_DEINIT_INTERVAL_MS               (100)
363 
364 #define CORE_MQTT_DEFAULT_KEEPALIVE_S              (1200)
365 #define CORE_MQTT_DEFAULT_CLEAN_SESSION            (1)
366 #define CORE_MQTT_DEFAULT_CONNECT_TIMEOUT_MS       (10 * 1000)
367 #define CORE_MQTT_DEFAULT_HEARTBEAT_INTERVAL_MS    (25 * 1000)
368 #define CORE_MQTT_DEFAULT_HEARTBEAT_MAX_LOST_TIMES (2)
369 #define CORE_MQTT_DEFAULT_SEND_TIMEOUT_MS          (5 * 1000)
370 #define CORE_MQTT_DEFAULT_RECV_TIMEOUT_MS          (5 * 1000)
371 #define CORE_MQTT_DEFAULT_REPUB_TIMEOUT_MS         (3 * 1000)
372 #define CORE_MQTT_DEFAULT_RECONN_ENABLED           (1)
373 #define CORE_MQTT_DEFAULT_RECONN_INTERVAL_MS       (2 * 1000)
374 #define CORE_MQTT_DEFAULT_DEINIT_TIMEOUT_MS        (2 * 1000)
375 
376 #define CORE_MQTT_DIAG_TLV_MQTT_CONNECTION         (0x0010)
377 #define CORE_MQTT_DIAG_TLV_MQTT_HEARTBEAT          (0x0020)
378 
379 #define CORE_MQTT_NWKSTATS_RTT_THRESHOLD           (10000)
380 
381 /* default settings for mqtt 5.0 */
382 #define CORE_TX_PKT_MAX_LENGTH                      (1024 * 256)
383 #define CORE_DEFAULT_SERVER_RECEIVE_MAX             (10)
384 #define CORE_MQTT_USER_PROPERTY_KEY_MAX_LEN         (128)  /* max key length for user property */
385 #define CORE_MQTT_USER_PROPERTY_VALUE_MAX_LEN       (128)  /* max value length for user property */
386 
387 typedef enum {
388     CORE_MQTTOPT_APPEND_PROCESS_HANDLER,
389     CORE_MQTTOPT_REMOVE_PROCESS_HANDLER,
390     CORE_MQTTOPT_MAX
391 } core_mqtt_option_t;
392 
393 int32_t core_mqtt_setopt(void *handle, core_mqtt_option_t option, void *data);
394 char *core_mqtt_get_product_key(void *handle);
395 char *core_mqtt_get_device_name(void *handle);
396 uint16_t core_mqtt_get_port(void *handle);
397 int32_t core_mqtt_get_nwkstats(void *handle, core_mqtt_nwkstats_info_t *nwk_stats_info);
398 
399 #if defined(__cplusplus)
400 }
401 #endif
402 
403 #endif
404 
405