MQTT Client 1.0.0
|
D:/my_data/GIT/network_apps/netapps/mqtt/common/mqtt_common.h
Go to the documentation of this file.
00001 /****************************************************************************** 00002 * 00003 * Copyright (C) 2014 Texas Instruments Incorporated 00004 * 00005 * All rights reserved. Property of Texas Instruments Incorporated. 00006 * Restricted rights to use, duplicate or disclose this code are 00007 * granted through contract. 00008 * 00009 * The program may not be used without the written permission of 00010 * Texas Instruments Incorporated or against the terms and conditions 00011 * stipulated in the agreement under which this program has been supplied, 00012 * and under no circumstances can it be used with non-TI connectivity device. 00013 * 00014 ******************************************************************************/ 00015 00016 /* 00017 mqtt_common.h 00018 00019 This module outlines the interfaces that are common to both client amd 00020 server components. The applications are not expected to utilize the 00021 services outlined in this module. 00022 */ 00023 00024 #ifndef __MQTT_COMMON_H__ 00025 #define __MQTT_COMMON_H__ 00026 00042 #include <stdbool.h> 00043 #include <stdlib.h> 00044 #include <stdio.h> 00045 00046 #define MQTT_COMMON_VERSTR "1.0.0" 00048 typedef int i32; 00049 typedef unsigned int u32; 00050 typedef unsigned char u8; 00051 typedef char i8; 00052 typedef unsigned short u16; 00053 typedef short i16; 00054 00055 #define MIN(a, b) ((a > b)? b : a) 00056 00058 #define MQTT_CONNECT 0x01 00059 #define MQTT_CONNACK 0x02 00060 #define MQTT_PUBLISH 0x03 00061 #define MQTT_PUBACK 0x04 00062 #define MQTT_PUBREC 0x05 00063 #define MQTT_PUBREL 0x06 00064 #define MQTT_PUBCOMP 0x07 00065 #define MQTT_SUBSCRIBE 0x08 00066 #define MQTT_SUBACK 0x09 00067 #define MQTT_UNSUBSCRIBE 0x0A 00068 #define MQTT_UNSUBACK 0x0B 00069 #define MQTT_PINGREQ 0x0C 00070 #define MQTT_PINGRSP 0x0D 00071 #define MQTT_DISCONNECT 0x0E 00072 00073 #define MAX_FH_LEN 0x05 00076 #define MAX_REMLEN_BYTES (MAX_FH_LEN - 1) 00077 00078 #define MAKE_FH_BYTE1(msg_type, flags) (u8)((msg_type << 4) | flags) 00079 00080 #define MAKE_FH_FLAGS(bool_dup, enum_qos, bool_retain) \ 00081 (u8)(((bool_dup << 3) | (enum_qos << 1) | bool_retain) & 0xF) 00082 00083 #define QOS_VALUE(enum_qos) (u8)(enum_qos & 0x3) 00084 #define QFL_VALUE 0x80 00086 #define DUP_FLAG_VAL(bool_val) (u8)(bool_val << 3) 00087 00088 #define BOOL_RETAIN(fh_byte1) ((fh_byte1 & 0x1)? true : false) 00089 #define BOOL_DUP(fh_byte1) ((fh_byte1 & 0x8)? true : false) 00090 #define ENUM_QOS(fh_byte1) (enum mqtt_qos)((fh_byte1 & 0x6) >> 1) 00091 00092 #define MSG_TYPE(fh_byte1) (u8)((fh_byte1 & 0xf0) >> 4) 00093 00094 static inline u32 buf_wr_nbytes(u8 *dst, const u8 *src, u32 n) 00095 { 00096 u32 c = n; 00097 while(c--) 00098 *dst++ = *src++; 00099 00100 return n; 00101 } 00102 00103 static inline u32 buf_set(u8 *dst, u8 val, u32 n) 00104 { 00105 u32 c = n; 00106 while(c--) 00107 *dst++ = val; 00108 00109 return n; 00110 } 00111 00113 static inline u32 buf_wr_nbo_2B(u8 *buf, u16 val) 00114 { 00115 buf[0] = (u8)((val >> 8) & 0xFF); /* MSB */ 00116 buf[1] = (u8)((val) & 0xFF); /* LSB */ 00117 return 2; 00118 } 00119 00121 static inline u32 buf_rd_nbo_2B(const u8 *buf, u16 *val) 00122 { 00123 *val = (u16)((buf[0] << 8) | (buf[1])); 00124 return 2; 00125 } 00126 00132 struct mqtt_packet { 00133 00134 u8 msg_type; 00135 u8 fh_byte1; 00137 u16 msg_id; 00139 u8 n_refs; 00140 u8 pad[3]; 00141 00142 u8 offset; 00143 u8 fh_len; 00144 u16 vh_len; 00145 u32 pl_len; 00147 u32 private; 00148 00149 u32 maxlen; 00150 u8 *buffer; 00153 void (*free)(struct mqtt_packet *mqp); 00154 00155 struct mqtt_packet *next; 00156 }; 00157 00160 #define MQP_FHEADER_BUF(mqp) (mqp->buffer + mqp->offset) 00161 #define MQP_VHEADER_BUF(mqp) (MQP_FHEADER_BUF(mqp) + mqp->fh_len) 00162 #define MQP_PAYLOAD_BUF(mqp) (MQP_VHEADER_BUF(mqp) + mqp->vh_len) 00163 00164 #define MQP_CONTENT_LEN(mqp) (mqp->fh_len + mqp->vh_len + mqp->pl_len) 00165 #define MQP_FREEBUF_LEN(mqp) (mqp->maxlen - mqp->offset - \ 00166 MQP_CONTENT_LEN(mqp)) 00167 00168 #define MQP_FHEADER_VAL(mqp) (mqp->fh_byte1) 00169 #define MQP_FHEADER_MSG(mqp) (MSG_TYPE(MQP_FHEADER_VAL(mqp))) 00170 #define MQP_FHEADER_FLG(mqp) (MSG_FLAGS(MQP_FHEADER_VAL(mqp))) 00171 00172 #define DEFINE_MQP_VEC(num_mqp, mqp_vec) \ 00173 static struct mqtt_packet mqp_vec[num_mqp]; 00174 00175 #define DEFINE_MQP_BUF_VEC(num_mqp, mqp_vec, buf_len, buf_vec) \ 00176 DEFINE_MQP_VEC(num_mqp, mqp_vec); \ 00177 static u8 buf_vec[num_mqp][buf_len]; 00178 00179 /*--------------------------------------------------------------------- 00180 * Heleper MACROS for PUBLISH-RX Message Processing 00181 *--------------------------------------------------------------------- 00182 */ 00183 00189 #define MQP_PUB_TOP_BUF(mqp) (MQP_VHEADER_BUF(mqp) + 2) 00190 00192 #define MQP_PUB_TOP_LEN(mqp) (mqp->vh_len - 2 - (mqp->msg_id? 2 : 0)) 00193 00195 #define MQP_PUB_PAY_BUF(mqp) (mqp->pl_len? MQP_PAYLOAD_BUF(mqp) : NULL) 00196 00198 #define MQP_PUB_PAY_LEN(mqp) (mqp->pl_len) 00199 00205 #define WILL_RETAIN_VAL 0x20 00206 #define WILL_CONFIG_VAL 0x04 00207 #define CLEAN_START_VAL 0x02 00208 #define USER_NAME_OPVAL 0x80 00209 #define PASS_WORD_OPVAL 0x40 00210 00219 #define MQP_ERR_NETWORK (-1) 00220 #define MQP_ERR_TIMEOUT (-2) 00221 #define MQP_ERR_NET_OPS (-3) 00222 #define MQP_ERR_FNPARAM (-4) 00223 #define MQP_ERR_PKT_AVL (-5) 00224 #define MQP_ERR_PKT_LEN (-6) 00225 #define MQP_ERR_NOTCONN (-7) 00226 #define MQP_ERR_BADCALL (-8) 00227 #define MQP_ERR_CONTENT (-9) 00228 #define MQP_ERR_LIBQUIT (-10) 00231 #define MQP_ERR_NOT_DEF (-32) 00235 /*--------------------------------------------------------------------- 00236 * Common Operations 00237 *--------------------------------------------------------------------- 00238 */ 00239 00246 void mqp_free(struct mqtt_packet *mqp); 00247 00257 void mqp_reset(struct mqtt_packet *mqp); 00258 00268 void mqp_init(struct mqtt_packet *mqp, u8 offset); 00269 00271 static 00272 inline void mqp_buffer_attach(struct mqtt_packet *mqp, u8 *buffer, u32 length, 00273 u8 offset) 00274 { 00275 mqp_init(mqp, offset); 00276 00277 mqp->buffer = buffer; 00278 mqp->maxlen = length; 00279 mqp->free = NULL; 00280 00281 return; 00282 } 00283 00285 struct utf8_string { 00286 00287 i8 *buffer; 00288 u16 length; 00289 }; 00290 00300 i32 mqp_buf_wr_utf8(u8 *buf, const struct utf8_string *utf8); 00301 00314 i32 mqp_buf_tail_wr_remlen(u8 *buf, u32 remlen); 00315 00324 i32 mqp_buf_rd_remlen(u8 *buf, u32 *remlen); 00325 00343 i32 00344 mqp_pub_append_topic(struct mqtt_packet *mqp, const struct utf8_string *topic, 00345 u16 msg_id); 00346 00360 i32 mqp_pub_append_data(struct mqtt_packet *mqp, const u8 *data_buf, 00361 u32 data_len); 00362 00373 bool mqp_proc_msg_id_ack_rx(struct mqtt_packet *mqp_raw, bool has_payload); 00374 00384 bool mqp_proc_pub_rx(struct mqtt_packet *mqp_raw); 00385 00386 /* 00387 Wait-List of MQTT Messages for which acknoledge is pending from remote node. 00388 */ 00389 struct mqtt_ack_wlist { 00390 00391 struct mqtt_packet *head; /* Points to head of single linked-list. */ 00392 struct mqtt_packet *tail; /* Points to tail of single linked-list. */ 00393 }; 00394 00395 static inline bool mqp_ack_wlist_is_empty(struct mqtt_ack_wlist *list) 00396 { 00397 return (NULL == list->head) ? true : false; 00398 } 00399 00400 /* 00401 Add specified element into trailing end of list. 00402 00403 Returns, on success, true, otherwise false. 00404 */ 00405 bool mqp_ack_wlist_append(struct mqtt_ack_wlist *list, 00406 struct mqtt_packet *elem); 00407 00408 /* 00409 Removes element that has specified msg_id from list. 00410 00411 Returns, on success, pointer to removed element, otherwise NULL. 00412 */ 00413 struct mqtt_packet *mqp_ack_wlist_remove(struct mqtt_ack_wlist *list, 00414 u16 msg_id); 00415 /* 00416 Removes and frees all elements in list. 00417 */ 00418 void mqp_ack_wlist_purge(struct mqtt_ack_wlist *list); 00419 00420 static inline bool is_wlist_empty(const struct mqtt_ack_wlist *list) 00421 { 00422 return list->head? false : true; 00423 } 00424 00439 i32 mqp_prep_fh(struct mqtt_packet *mqp, u8 flags); 00440 00442 enum mqtt_qos { 00443 00444 MQTT_QOS0, 00445 MQTT_QOS1, 00446 MQTT_QOS2 00447 }; 00448 00450 struct utf8_strqos { 00451 00452 i8 *buffer; 00453 u16 length; 00454 enum mqtt_qos qosreq; 00455 }; 00456 00457 00467 struct secure_conn { 00468 00469 void *method; 00470 void *cipher; 00471 u32 n_file; 00472 char **files; 00473 }; 00474 00484 struct device_net_services { 00485 00489 #define DEV_NETCONN_OPT_TCP 0x01 00490 #define DEV_NETCONN_OPT_UDP 0x02 00491 #define DEV_NETCONN_OPT_IP6 0x04 00492 #define DEV_NETCONN_OPT_URL 0x08 00493 #define DEV_NETCONN_OPT_SEC 0x10 00512 i32 (*open)(u32 nwconn_opts, const i8 *server_addr, u16 port_number, 00513 const struct secure_conn *nw_security); 00514 00526 i32 (*send)(i32 comm, const u8 *buf, u32 len, void *ctx); 00527 00548 i32 (*recv)(i32 comm, u8 *buf, u32 len, u32 wait_secs, 00549 bool *err_timeo, void *ctx); 00550 00565 i32 (*send_dest)(i32 comm, const u8 *buf, u32 len, u16 dest_port, 00566 const i8 *dest_ip, u32 ip_len); 00567 00588 i32 (*recv_from)(i32 comm, u8 *buf, u32 len, u16 *from_port, 00589 i8 *from_ip, u32 *ip_len); 00590 00592 i32 (*close)(i32 comm); 00593 00605 i32 (*listen)(u32 nwconn_opts, u16 port_number, 00606 const struct secure_conn *nw_security); 00607 00623 i32 (*accept)(i32 listen, i8 *client_ip, u32 *ip_length); 00624 00653 i32 (*io_mon)(i32 *recv_cvec, i32 *send_cvec, 00654 i32 *rsvd_cvec, u32 wait_secs); 00655 00677 u32 (*time)(void); 00678 }; 00679 /* device_net_services */ 00681 00682 /* Receive data from the specified network and read into the 'mqp' */ 00683 i32 mqp_recv(i32 net, const struct device_net_services *net_ops, 00684 struct mqtt_packet *mqp, u32 wait_secs, bool *timed_out, 00685 void *ctx); 00686 00687 /*----------------------------------------------------------------------------- 00688 * Data structure for managing the QoS2 PUB RX packets and follow-ups 00689 *---------------------------------------------------------------------------*/ 00690 00691 #define MAX_PUBREL_INFLT 8 /* Must be kept as a value of 2^n */ 00692 00693 struct pub_qos2_cq { /* Circular Queue CQ to track QOS2 PUB RX messages */ 00694 00695 u16 id_vec[MAX_PUBREL_INFLT]; /* Vector to store RX Message-IDs */ 00696 u8 n_free; /* Num of free elements in vector */ 00697 u8 rd_idx; /* Index to Read next Message-ID */ 00698 u8 wr_idx; /* Index to Write next Message-ID */ 00699 }; 00700 00701 /* Reset the specified Circular Queue (CQ) */ 00702 void qos2_pub_cq_reset(struct pub_qos2_cq *cq); 00703 00704 /* Append the message-id into the CQ tail. Return true on success, else false */ 00705 bool qos2_pub_cq_logup(struct pub_qos2_cq *cq, u16 msg_id); 00706 00707 /* Remove the message-id from the CQ head. Return true on success, else false */ 00708 bool qos2_pub_cq_unlog(struct pub_qos2_cq *cq, u16 msg_id); 00709 00710 /* Is the message-id available in the CQ ? Return true on success, else false */ 00711 bool qos2_pub_cq_check(struct pub_qos2_cq *cq, u16 msg_id); 00712 00713 /* Get the count of message-ID(s) availalbe in the CQ */ 00714 static inline i32 qos2_pub_cq_count(struct pub_qos2_cq *cq) 00715 { 00716 return MAX_PUBREL_INFLT - cq->n_free; 00717 } 00718 00719 struct client_ctx { 00720 00721 void *usr; /* Client Usr */ 00722 i32 net; /* Socket HND */ 00723 00724 i8 remote_ip[16]; 00725 u32 ip_length; 00726 00727 u32 timeout; 00728 u16 ka_secs; 00729 00730 u32 flags; 00731 00732 struct client_ctx *next; 00733 }; 00734 00735 void cl_ctx_reset(struct client_ctx *cl_ctx); 00736 void cl_ctx_timeout_insert(struct client_ctx **head, 00737 struct client_ctx *elem); 00738 00739 void cl_ctx_remove(struct client_ctx **head, 00740 struct client_ctx *elem); 00741 00742 #define KA_TIMEOUT_NONE 0xffffffff /* Different than KA SECS = 0 */ 00743 void cl_ctx_timeout_update(struct client_ctx *cl_ctx, u32 now_secs); 00744 00745 #endif
Generated on Mon Nov 17 2014 12:11:04 for MQTT Client by 1.7.4