MQTT Client: D:/my_data/GIT/network_apps/netapps/mqtt/common/mqtt_common.h Source File

Message Queuing Telemetry Transport Protocol

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  doxygen 1.7.4