Update revision to use TI's mqtt and Freertos.

Dependencies:   mbed client server

Fork of cc3100_Test_mqtt_CM3 by David Fletcher

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mqtt_common.h Source File

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 
00027 /** @file mqtt_common.h 
00028     This file incorporates constructs that are common to both client and server
00029     implementation. 
00030 
00031     The applications are not expected to utlize the routines made available in
00032     this module module. 
00033 
00034     @note the routines in this module do not check for availability and 
00035     correctness of the input parameters
00036 
00037     @warning The module is expected to under-go changes whilst incorporating
00038     support for the server. Therefore, it is suggested that applications do
00039     not rely on the services provided in this module.
00040 */
00041 
00042 #include <stdio.h>
00043 #include <stdlib.h>
00044 #include <string.h>
00045 #include <stdbool.h>
00046 
00047 #include "platform.h"
00048 
00049 #ifdef __cplusplus
00050 extern "C"
00051 {
00052 #endif
00053 
00054 namespace mbed_mqtt {
00055 
00056 #define MQTT_COMMON_VERSTR "1.1.1" /**< Version of Common LIB */
00057 
00058 #define MIN(a, b) ((a > b)? b : a)
00059 
00060 /** MQTT Message Types */
00061 #define MQTT_CONNECT      0x01
00062 #define MQTT_CONNACK      0x02
00063 #define MQTT_PUBLISH      0x03
00064 #define MQTT_PUBACK       0x04
00065 #define MQTT_PUBREC       0x05
00066 #define MQTT_PUBREL       0x06
00067 #define MQTT_PUBCOMP      0x07
00068 #define MQTT_SUBSCRIBE    0x08
00069 #define MQTT_SUBACK       0x09
00070 #define MQTT_UNSUBSCRIBE  0x0A
00071 #define MQTT_UNSUBACK     0x0B
00072 #define MQTT_PINGREQ      0x0C
00073 #define MQTT_PINGRSP      0x0D
00074 #define MQTT_DISCONNECT   0x0E
00075 
00076 #define MAX_FH_LEN        0x05    /**< MAX Length of Fixed Header */
00077 
00078 /** Max number of bytes in remaining length field */
00079 #define MAX_REMLEN_BYTES  (MAX_FH_LEN - 1)  
00080 
00081 #define MAKE_FH_BYTE1(msg_type,  flags) (uint8_t)((msg_type << 4) | flags)
00082 
00083 #define MAKE_FH_FLAGS(bool_dup, enum_qos, bool_retain)                  \
00084         (uint8_t)(((bool_dup << 3) | (enum_qos << 1) | bool_retain) & 0xF)
00085 
00086 #define QID_VMASK           0x3
00087 #define QOS_VALUE(enum_qos) (uint8_t)(enum_qos & QID_VMASK)
00088 #define QFL_VALUE           0x80  /**< QOS Failure value (SUBACK) */
00089 
00090 #define DUP_FLAG_VAL(bool_val) (uint8_t)(bool_val << 3)
00091 
00092 #define BOOL_RETAIN(fh_byte1)  ((fh_byte1 & 0x1)? true : false)
00093 #define BOOL_DUP(fh_byte1)     ((fh_byte1 & 0x8)? true : false)
00094 #define ENUM_QOS(fh_byte1)     (enum mqtt_qos)((fh_byte1 & 0x6) >> 1)
00095 
00096 #define MSG_TYPE(fh_byte1)  (uint8_t)((fh_byte1 & 0xf0) >> 4)
00097 
00098 static inline uint32_t buf_wr_nbytes(uint8_t *dst, const uint8_t *src, uint32_t n)
00099 {
00100 //        printf("buf_wr_nbytes\r\n");
00101         uint32_t c = n; 
00102         while(c--)
00103                 *dst++ = *src++;
00104 
00105         return n;
00106 }
00107 
00108 static inline uint32_t buf_set(uint8_t *dst, uint8_t val, uint32_t n)
00109 {
00110         uint32_t c = n; 
00111         while(c--)
00112                 *dst++ = val;
00113 
00114         return n;
00115 }
00116 
00117 /** Writing 2 bytes entity in network byte order */
00118 static inline uint32_t buf_wr_nbo_2B(uint8_t *buf, uint16_t val)
00119 {
00120         buf[0] = (uint8_t)((val >> 8) & 0xFF); /* MSB */
00121         buf[1] = (uint8_t)((val)      & 0xFF); /* LSB */
00122         return 2;
00123 }
00124 
00125 /** Reading 2 bytes entity in network byte order */
00126 static inline uint32_t buf_rd_nbo_2B(const uint8_t *buf, uint16_t *val)
00127 {
00128         *val = (uint16_t)((buf[0] << 8) | (buf[1]));
00129         return 2;
00130 }
00131 
00132 /** @defgroup mqp_group MQTT Packet (MQP) Buffer structure
00133     The core construct to encapsulate, construct and process a message
00134 
00135     @{
00136 */
00137 struct mqtt_packet {
00138 
00139         uint8_t                     msg_type;   /**< MQTT  Message  Type */
00140         uint8_t                     fh_byte1;   /**< Fixed Header: Byte1 */
00141 
00142         uint16_t                    msg_id;     /**< Msg transaction  ID */
00143 
00144         uint8_t                     n_refs;     /**< # users of this msg */
00145         uint8_t                     pad[3];
00146 
00147         uint8_t                     offset;     /**< Start of data index */
00148         uint8_t                     fh_len;     /**< Fix Header Length   */
00149         uint16_t                    vh_len;     /**< Var Header Length   */
00150         uint32_t                    pl_len;     /**< Pay Load   Length   */
00151 
00152         uint32_t                    private_;
00153 
00154         uint32_t                    maxlen;     /**< Maximum buffer size */
00155         uint8_t                    *buffer;     /**< The attached buffer */
00156 
00157         /** Method to free this packet to a particular pool */
00158         void                  (*free)(struct mqtt_packet *mqp);
00159 
00160         struct mqtt_packet    *next;
00161 };
00162 
00163 /** @} */
00164 
00165 #define MQP_FHEADER_BUF(mqp)  (mqp->buffer + mqp->offset)
00166 #define MQP_VHEADER_BUF(mqp)  (MQP_FHEADER_BUF(mqp) + mqp->fh_len)
00167 #define MQP_PAYLOAD_BUF(mqp)  (MQP_VHEADER_BUF(mqp) + mqp->vh_len)
00168 
00169 #define MQP_CONTENT_LEN(mqp)  (mqp->fh_len + mqp->vh_len + mqp->pl_len)
00170 #define MQP_FREEBUF_LEN(mqp)  (mqp->maxlen - mqp->offset -      \
00171                                MQP_CONTENT_LEN(mqp))
00172 
00173 #define MQP_FHEADER_VAL(mqp)  (mqp->fh_byte1)
00174 #define MQP_FHEADER_MSG(mqp)  (MSG_TYPE(MQP_FHEADER_VAL(mqp)))
00175 #define MQP_FHEADER_FLG(mqp)  (MSG_FLAGS(MQP_FHEADER_VAL(mqp)))
00176 
00177 #define DEFINE_MQP_VEC(num_mqp, mqp_vec)                \
00178         static struct mqtt_packet mqp_vec[num_mqp];
00179 
00180 #define DEFINE_MQP_BUF_VEC(num_mqp, mqp_vec, buf_len, buf_vec)        \
00181         DEFINE_MQP_VEC(num_mqp, mqp_vec);                             \
00182         static uint8_t buf_vec[num_mqp][buf_len];
00183 
00184 /*---------------------------------------------------------------------
00185  * Heleper MACROS for PUBLISH-RX Message Processing
00186  *---------------------------------------------------------------------
00187  */
00188 
00189 /** @defgroup rxpub_help_group Helper Macros for RX PUBLISH
00190     @{
00191 */
00192 
00193 /** Yields pointer to topic content */
00194 #define MQP_PUB_TOP_BUF(mqp) (MQP_VHEADER_BUF(mqp) + 2)
00195 
00196 /** Length or size of topic content */
00197 #define MQP_PUB_TOP_LEN(mqp) (mqp->vh_len - 2 - (mqp->msg_id? 2 : 0))
00198 
00199 /** Yields pointer to payload data */
00200 #define MQP_PUB_PAY_BUF(mqp) (mqp->pl_len? MQP_PAYLOAD_BUF(mqp) : NULL)
00201 
00202 /** Length or size of payload data */
00203 #define MQP_PUB_PAY_LEN(mqp) (mqp->pl_len)
00204 
00205 /** @} */
00206 
00207 /** @cond
00208     CONNECT Message Flags, as outined in the MQTT Specification
00209 */
00210 #define WILL_RETAIN_VAL 0x20
00211 #define WILL_CONFIG_VAL 0x04
00212 #define CLEAN_START_VAL 0x02
00213 #define USER_NAME_OPVAL 0x80
00214 #define PASS_WORD_OPVAL 0x40
00215 /**
00216     @endcond
00217 */
00218 
00219 /** @cond
00220     CONNACK 8bit Return Code, as outlined in the MQTT Specification
00221 */
00222 #define CONNACK_RC_REQ_ACCEPT   0x00
00223 #define CONNACK_RC_BAD_PROTOV   0x01
00224 #define CONNACK_RC_CLI_REJECT   0x02
00225 #define CONNACK_RC_SVR_UNAVBL   0x03
00226 #define CONNACK_RC_BAD_USRPWD   0x04
00227 #define CONNACK_RC_NOT_AUTHED   0x05
00228 /**
00229    @endcond
00230 */
00231 
00232 /** @defgroup lib_err_group LIBRARY Generated Error Codes
00233     Library provides these codes as return values in several routines
00234 
00235     @{
00236 */
00237 #define MQP_ERR_NETWORK   (-1)  /**< Problem in network (sock err) */
00238 #define MQP_ERR_TIMEOUT   (-2)  /**< Net transaction has timed out */
00239 #define MQP_ERR_NET_OPS   (-3)  /**< Platform Net Ops un-available */
00240 #define MQP_ERR_FNPARAM   (-4)  /**< Invalid parameter(s) provided */
00241 #define MQP_ERR_PKT_AVL   (-5)  /**< No pkts are available in pool */
00242 #define MQP_ERR_PKT_LEN   (-6)  /**< Inadequate free buffer in pkt */
00243 #define MQP_ERR_NOTCONN   (-7)  /**< Lib isn't CONNECTED to server */
00244 #define MQP_ERR_BADCALL   (-8)  /**< Irrelevant call for LIB state */
00245 #define MQP_ERR_CONTENT   (-9)  /**< MSG / Data content has errors */
00246 #define MQP_ERR_LIBQUIT  (-10)  /**< Needs reboot library has quit */
00247 
00248 
00249 #define MQP_ERR_NOT_DEF  (-32)  /**< Value other than defined ones */
00250 
00251 /** @} */
00252 
00253 /*---------------------------------------------------------------------
00254  * Common Operations
00255  *---------------------------------------------------------------------
00256  */
00257 
00258 /** Free a MQTT Packet Buffer 
00259     Puts back the packet buffer in to the appropriate pool.
00260     
00261     @param[in] mqp packet buffer to be freed
00262     @return none
00263 */
00264 void mqp_free(struct mqtt_packet *mqp);
00265 
00266 /** Resets the attributes of MQTT Packet Holder to its init state
00267     Not all fields are reset - entities such as offset, n_refs in addition
00268     to buffer information are not updated.
00269 
00270     @param[in] mqp packet buffer to be reset
00271     @return none
00272 
00273     @see mqp_init
00274 */
00275 void mqp_reset(struct mqtt_packet *mqp);
00276 
00277 /** Initializes attributes of the MQTT Packet Holder.
00278     This routine sets number of users of the MQTT Packet Holder to 1. However,
00279     it leaves, if already provisioned, the reference to buffer and its size
00280     un-altered.
00281 
00282     @param[in] mqp packet buffer to be initialized
00283     @param[in] offset index in buffer to indicate start of the contents
00284     @return none
00285 */
00286 void mqp_init(struct mqtt_packet *mqp, uint8_t offset);
00287 
00288 /** Initialize MQTT Packet Holder and attach the buffer */
00289 static 
00290 inline void mqp_buffer_attach(struct mqtt_packet *mqp, uint8_t *buffer, uint32_t length,
00291                               uint8_t offset)
00292 {
00293         mqp_init(mqp, offset);
00294 
00295         mqp->buffer = buffer;
00296         mqp->maxlen = length;
00297         mqp->free   = NULL;
00298 
00299         return;
00300 }
00301 
00302 /** Description of UTF8 information as used by MQTT Library. */
00303 struct utf8_string {
00304         
00305         const char *buffer;   /**< Refers to UTF8 content */
00306         uint16_t       length;   /**< Length of UTF8 content */
00307 };
00308 
00309 /** Write UTF8 information into the buffer. 
00310     The UTF8 information includes content and its length.
00311 
00312     @warning The routine does not check for correctness of the paramters.
00313 
00314     @param[in] buf refers to memory to write UTF8 information into
00315     @param[in] utf8 contains UTF8 information to be written
00316     @return on success, number of bytes written, otherwise -1 on error.
00317 */
00318 int32_t mqp_buf_wr_utf8(uint8_t *buf, const struct utf8_string *utf8);
00319 
00320 /** Write the MQTT construct 'Remaining Length' into trailing end of buffer.
00321     The 'remaining length' is written in the format as outlined in the MQTT
00322     specification. 
00323 
00324     The implementation assumes availability of at-least 4 bytes in the buffer.
00325     Depending on the value of 'Remaining Length' appropriate trailing bytes in
00326     the buffer would be used.
00327     
00328     @param[in] buf refers to memory to tail-write 'Remaining Length' into
00329     @param[in] remlen The 'Remaining Length' value
00330     @return in success, number of trailing bytes used, otherwise -1 on error
00331 */
00332 int32_t mqp_buf_tail_wr_remlen(uint8_t *buf, uint32_t remlen);
00333 
00334 /** Read MQTT construct 'Remaining Length' from leading bytes of the buffer.
00335     The 'remaining length' is written in the format as outlined in the MQTT
00336     specification.
00337      
00338     @param[in] buf refers to memory to head-read 'Remaining Length' from
00339     @param[in] remlen place-holder for The 'Remaining Length' value
00340     @return in success, number of header bytes read, otherwise -1 on error
00341 */   
00342 int32_t mqp_buf_rd_remlen(uint8_t *buf, uint32_t *remlen);
00343 
00344 /** Include variable header Topic as part of PUB Message construction.
00345     Inclusion of a Topic also encompasses incorporation of the message ID.
00346 
00347     The topic refers to the subject for which data will be published by
00348     the client or the server. The topic entity must be appended into the
00349     packet buffer prior to the inclusion of the payload (data).
00350 
00351     @warning This routine does not check for correctness of the input
00352     parameters.
00353 
00354     @param[in] mqp packet buffer in which topic must be included.
00355     @param[in] topic UTF8 information
00356     @param[in] msg_id Message or Packet transaction ID
00357     @return on success, number of bytes appended, otherwise -1 on error.
00358 
00359     @note A 'topic' must be appended prior to inclusion of pulished data.
00360 */
00361 int32_t 
00362 mqp_pub_append_topic(struct mqtt_packet *mqp, const struct utf8_string *topic,
00363                      uint16_t msg_id);
00364 
00365 /** Include payload data for publishing
00366     The payload data is associated with a topic.
00367     
00368     @warning This routine does not check for correctness of the input
00369     parameters.
00370 
00371     @param[in] mqp packet buffer in which payload data must be included.
00372     @param[in] data_buf data to be included in the packet buffer
00373     @param[in] data_len length of the data to be included in the packet.
00374     @return on success, number of bytes appended, otherwise -1 on error.
00375 
00376     @note A 'topic' must be appended prior to inclusion of pulished data.
00377 */
00378 int32_t mqp_pub_append_data(struct mqtt_packet *mqp, const uint8_t *data_buf,
00379                         uint32_t data_len);
00380 
00381 /** Construct a packet for Message ID enabled ACK received from network
00382     Process the raw ACK message information to update the packet holder.
00383    
00384     @warning This routine does not check for correctness of the input
00385     parameters.
00386        
00387     @param[in] mqp_raw holds a raw buffer from the network
00388     @param[in] has_payload asserted, if ACK message should have a payload
00389     @return on success, true, otherwise false
00390 */
00391 bool mqp_proc_msg_id_ack_rx(struct mqtt_packet *mqp_raw, bool has_payload);
00392 
00393 /** Construct a packet for PUBLISH message received from the network
00394     Process the raw PUB message information to update the packet holder.
00395 
00396     @warning This routine does not check for correctness of the input
00397     parameters.
00398 
00399     @param[in] mqp_raw holds a raw buffer from the network
00400     @return on success, true, other wise false
00401 */
00402 bool mqp_proc_pub_rx(struct mqtt_packet *mqp_raw);
00403 
00404 /*
00405    Wait-List of MQTT Messages for which acknoledge is pending from remote node.
00406 */
00407 struct mqtt_ack_wlist {
00408         
00409         struct mqtt_packet *head;  /* Points to head of single linked-list. */
00410         struct mqtt_packet *tail;  /* Points to tail of single linked-list. */
00411 };
00412 
00413 static inline bool mqp_ack_wlist_is_empty(struct mqtt_ack_wlist *list)
00414 {
00415         return (NULL == list->head) ? true : false;
00416 }
00417 
00418 /*
00419    Add specified element into trailing end of list.
00420 
00421    Returns, on success, true, otherwise false.
00422 */
00423 bool mqp_ack_wlist_append(struct mqtt_ack_wlist *list,
00424                           struct mqtt_packet    *elem);
00425 
00426 /*
00427    Removes element that has specified msg_id from list. 
00428 
00429    Returns, on success, pointer to removed element, otherwise NULL.
00430 */
00431 struct mqtt_packet *mqp_ack_wlist_remove(struct mqtt_ack_wlist *list,
00432                                           uint16_t msg_id);
00433 /* 
00434    Removes and frees all elements in list. 
00435 */
00436 void mqp_ack_wlist_purge(struct mqtt_ack_wlist *list);
00437 
00438 static inline bool is_wlist_empty(const struct mqtt_ack_wlist *list)
00439 {
00440         return list->head? false : true;
00441 }
00442 
00443 /** Prepare the Fixed-Header of the MQTT Packet (before being sent to network)
00444     Based on the contents of the mqtt packet and the combination of DUP, QoS
00445     and Retain flags as outlined the MQTT specification, the routine updates,
00446     among others, significant internal fields such as 'remaining length' and
00447     'fixed header length' in the packet construct and embeds the fixed header,
00448     so created, in the packet buffer.
00449     
00450     This service must be utilized on a packet that has been already populated
00451     with all the payload data, topics and other contents. The fixed header
00452     must be the final step in the compostion of MQTT packet prior to its
00453     dispatch to the server.
00454     
00455     Returns size, in bytes, of the fixed-header, otherwise -1 on error.
00456 */
00457 int32_t mqp_prep_fh(struct mqtt_packet *mqp, uint8_t flags);
00458 
00459 /** MQTT Quality of Service */
00460 enum mqtt_qos {
00461         
00462         MQTT_QOS0,  /**< QoS Level 0 */
00463         MQTT_QOS1,  /**< QoS Level 1 */
00464         MQTT_QOS2   /**< QoS Level 2 */
00465 };
00466 
00467 /** Construct to create Topic to SUBSCRIBE */
00468 struct utf8_strqos {
00469 
00470         const char       *buffer;  /**< Refers to UTF8 content */
00471         uint16_t             length;  /**< Length of UTF8 content */
00472         enum mqtt_qos   qosreq;  /**< QoS Level  for content */
00473 };
00474 
00475 
00476 /** @defgroup mqtt_netsec_grp Information to establish a secure connection.
00477     This is implementation specific and is targeted for the network services.
00478 
00479     Specifically, the MQTT implementation makes no assumption or use of this
00480     construct. The client library merely passes information from the app to
00481     the network service layer.
00482     Note: value of n_file can vary from 1 to 4, with corresponding pointers to
00483     the files in files field. Value of 1(n_file) will assume the corresponding
00484     pointer is for CA File Name. Any other value of n_file expects the files to
00485     be in following order:
00486     1.  Private Key File
00487     2.  Certificate File Name
00488     3.  CA File Name
00489     4.  DH Key File Name
00490 
00491 example: 
00492 If you want to provide only CA File Name, following are the two way of doing it:
00493 for n_file = 1
00494 char *security_file_list[] = {"/cert/testcacert.der"};
00495 for n_file = 4
00496 char *security_file_list[] = {NULL, NULL, "/cert/testcacert.der", NULL};
00497 
00498 where files = security_file_list
00499     @{
00500 */
00501 struct secure_conn {
00502         
00503         void *method;  /**< Reference to information about protocol or methods */
00504         void *cipher;  /**< Reference to information about cryptograph ciphers */
00505         uint32_t   n_file;  /**< Count of secure connection related files, certs... */
00506         char   **files;  /**< Reference to array of file-names used for security */
00507 };
00508 
00509 /** @} */
00510 
00511 /* Initialize the struct secure_conn data */
00512 void secure_conn_struct_init(struct secure_conn *nw_security);
00513 
00514 /** @defgroup net_ops_group Abstraction of Network Services on a platform
00515     Services to enable the MQTT Client-Server communication over network
00516    
00517     These services are invoked by the MQTT Library.
00518     
00519     @{
00520 */ 
00521 struct device_net_services {
00522 
00523        /** @defgroup dev_netconn_opt_grp Options for platform to configure network
00524            @{
00525         */
00526 #define DEV_NETCONN_OPT_TCP  0x01  /**< Assert to indicate TCP net connection  */
00527 #define DEV_NETCONN_OPT_UDP  0x02  /**< Assert to create a local UDP port bind */
00528 #define DEV_NETCONN_OPT_IP6  0x04  /**< Assert for IPv6, otherwise it is IPv4  */
00529 #define DEV_NETCONN_OPT_URL  0x08  /**< Assert if the network address is a URL */
00530 #define DEV_NETCONN_OPT_SEC  0x10  /**< Assert to indicate a secure connection */
00531         /** @} */
00532 
00533         /** Set up a communication channel with a server or set up a local port.
00534             This routine opens up either a "connection oriented" communication
00535             channel with the specified server or set up a local configuration for
00536             "connectionless" transactions.
00537 
00538             @param[in] nwconn_opts Implementation specific construct to enumerate
00539             server address and / or connection related details
00540             @param[in] server_addr URL or IP address (string) or other server
00541             reference. For setting up a local (UDP) port, set it to NULL.
00542             @param[in] port_number Network port number, typically, 1883 or 8883
00543             for remote severs. For setting up a local (UDP) port, use an intended
00544             port number.
00545             @param[in] nw_security Information to establish a secure connection
00546             with server. Set it to NULL, if not used. @ref mqtt_netsec_grp
00547             @return a valid handle to connection, otherwise NULL
00548         */
00549         int32_t (*open)(uint32_t nwconn_opts, const char *server_addr, uint16_t port_number,
00550                     const struct secure_conn *nw_security);
00551 
00552         /** Send data onto the "connection oriented" network.
00553             The routine blocks till the time, the data has been copied into the
00554             network stack for dispatch on to the "connection oriented" network.
00555 
00556             @param[in] comm handle to network connection as returned by open().
00557             @param[in] buf refers to the data that is intended to be sent
00558             @param[in] len length of the data
00559             @param[in] ctx reference to the MQTT connection context
00560             @return on success, the number of bytes sent, 0 on connection reset,
00561             otherwise -1
00562         */
00563         int32_t   (*send)(int32_t comm, const uint8_t *buf, uint32_t len, void *ctx);
00564 
00565         /** Receive data from the "connection oriented" channel.
00566             The routine blocks till the time, there is either a data that has
00567             been received from the server or the time to await data from the
00568             server has expired.
00569 
00570             @param[in] comm Handle to network connection as returned by
00571             accept().
00572             @param[out] buf place-holder to which data from network should be
00573             written into.
00574             @param[in] len maximum length of 'buf'
00575             @param[in] wait_secs maximum time to await data from network. If
00576             exceeded, the routine returns error with the err_timeo flag set
00577             as true.
00578             @param[out] err_timeo if set, indicates that error is due to
00579             timeout.
00580             @param[in] ctx reference to the MQTT connection context
00581             @return on success, number of bytes received, 0 on connection reset,
00582             otherwise -1 on error. In case, error (-1) is due to the time-out,
00583             then the implementation should set flag err_timeo as true.
00584         */
00585         int32_t   (*recv)(int32_t comm, uint8_t *buf, uint32_t len, uint32_t wait_secs,
00586                       bool *err_timeo, void *ctx);
00587 
00588         /** Send data to particular port on the specified network element.
00589             The routine blocks till the time, the data has been copied into the
00590             network stack for dispatch to the "specified" network entity.
00591 
00592             @param[in] comm handle to network connection as returned by open().
00593             @param[in] buf refers to data that is intended to be sent
00594             @param[in] len length of the data
00595             @param[in] dest_port network port to which data is to be sent.
00596             @param[in] dest_ip IP address of the entity to which data is to be
00597             sent.
00598             @param[in] ip_len length of the destination IP address.
00599             @return on success, the number of bytes sent, 0 on connection reset,
00600             otherwise -1.
00601         */
00602         int32_t   (*send_dest)(int32_t comm, const uint8_t *buf, uint32_t len, uint16_t dest_port,
00603                            const uint8_t *dest_ip, uint32_t ip_len);
00604 
00605         /** Receive data on a local port sent by any network element.
00606             The routine blocks till the time, data has been received on the local
00607             port from any remote network element.
00608 
00609             @param[in] comm handle to network connection as return by open().
00610             @param[in] buf place-holder to which data from network should be
00611             written into.
00612             @param[in] len maximum lengh of 'buf'
00613             @param[out] from_port place-holder for the port of the sender network
00614             entity
00615             @param[out] from_ip place-holder to retrieve the IP address of the
00616             sender network entity. The memory space must be provisioned to store
00617             atleast 16 bytes.
00618             @param[in, out] ip_len length of IP address. It is provided by
00619             the caller to declare the length of the place holder and updated by
00620             routine to indicate the length of the remote network entity's IP
00621             address.
00622             @return on success, number of bytes received, 0 on connection reset,
00623             otherwise -1 on errir. 
00624         */
00625         int32_t   (*recv_from)(int32_t comm, uint8_t *buf, uint32_t len, uint16_t *from_port,
00626                            uint8_t *from_ip, uint32_t *ip_len);
00627 
00628         /** Close communication connection */
00629         int32_t   (*close)(int32_t comm);
00630 
00631         /** Listen to incoming connection from clients.
00632             This routine prepares the system to listen on the specified port
00633             for the incoming network connections from the remote clients.
00634 
00635             @param[in] nwconn_opts Implementation specific construct to
00636             enumerate server address and / or connection related details
00637             @param[in] port_number Network port number, typically, 1883 or 8883
00638             @param[in] nw_security Information to establish a secure connection
00639             with client. Set it to NULL, if not used. @ref mqtt_netsec_grp
00640             @return a valid handle to listening contruct, otherwise NULL
00641         */
00642         int32_t (*listen)(uint32_t nwconn_opts, uint16_t port_number,
00643                       const struct secure_conn *nw_security);
00644 
00645         /** Accept an incominng connection.
00646             This routine creates a new communication channel for the (remote)
00647             requesting client.
00648 
00649             @param[in] listen handle to listen for the incoming connection
00650             requests from the remote clients
00651             @param[out] client_ip IP address of the connected client. This value
00652             is valid only on successful return of the routine. The place holder
00653             must provide memory to store atleast 16 bytes.
00654             @param[in, out] ip_length Length of IP address. It is provided by
00655             the caller to declare the length of the place holder and updated by
00656             routine to indicate the length of the connected client's IP address.
00657             @return on success, a valid handle to the new connection, otherwise
00658             NULL
00659         */
00660         int32_t (*accept)(int32_t listen, uint8_t *client_ip, uint32_t *ip_length);
00661 
00662         /** Monitor activity on communication handles.
00663             The routine blocks for the specified period of time to monitor
00664             activity, if any, on each of the communication handle that has
00665             been provided in one or more vector sets. At the expiry of the
00666             wait time, this function must identify the handles, on which,
00667             acitvities were observed.
00668 
00669             A particular collection of communication handles are packed as
00670             an array or in a vector and is passed to the routine. A NULL
00671             handle in the vector indicates the termination of the vector
00672             and can effectively used to account for the size of the vector.
00673 
00674             Similarly, at end the end of the wait period, the routine must
00675             provide a vector of the handles for which activity was observed.
00676 
00677             @param[in, out] recv_hvec a vector of handles which must be
00678             monitored for receive activities. 
00679             @param[in, out] send_hvec a vector of handles which must be
00680             monitored for send activities.
00681             @param[in, out] rsvd_hvec reserved for future use.
00682             @param[in] wait_secs time to wait and monitor activity on
00683             communication handles provided in one or more sets. If set 
00684             to 0, the routine returns immediately.
00685             @return on success, the total number of handles for which activity
00686             was observed. This number can be 0, if no activity was observed on
00687             any of the provided handle in the specified time. Otherwise, -1 on
00688             error.
00689         */
00690         int32_t   (*io_mon)(int32_t *recv_cvec, int32_t *send_cvec,
00691                         int32_t *rsvd_cvec,  uint32_t wait_secs);
00692 
00693         /** Get Time (in seconds).
00694             Provides a monotonically incrementing value of a time  service in
00695             unit of seconds. The implementation should ensure that associated
00696             timer hardware or the clock module remains active through the low
00697             power states of the system. Such an arrangement ensures that MQTT
00698             Library is able to track the Keep-Alive time across the cycles of
00699             low power states. It would be typical of battery operated systems
00700             to transition to low power states during the period of inactivity
00701             or otherwise to conserve battery. 
00702 
00703             In the absence of a sustained time reference across the low power
00704             states, if the system transitions away from the active state, the
00705             MQTT Library, then may not be able to effectively monitor the Keep
00706             Alive duration.
00707 
00708             It is the responsbililty of the implementation to manage the roll-
00709             over problem of the hardware and ensure the integrity of the time
00710             value is maintained.
00711 
00712            @return time in seconds
00713         */
00714         uint32_t   (*time)(void);
00715 };
00716 
00717 /** @} */ /* device_net_services */
00718 
00719 /* Receive data from the specified network and read into the 'mqp' */
00720 int32_t mqp_recv(int32_t  net,     const struct device_net_services *net_ops,
00721              struct mqtt_packet *mqp, uint32_t wait_secs, bool *timed_out,
00722              void *ctx);
00723 
00724 /*-----------------------------------------------------------------------------
00725  * Data structure for managing the QoS2 PUB RX packets and follow-ups
00726  *---------------------------------------------------------------------------*/
00727 
00728 #define MAX_PUBREL_INFLT 8 /* Must be kept as a value of 2^n */
00729 
00730 struct pub_qos2_cq { /* Circular Queue CQ to track QOS2 PUB RX messages */
00731 
00732         uint16_t id_vec[MAX_PUBREL_INFLT];  /* Vector to store RX Message-IDs */
00733         uint8_t  n_free;                    /* Num of free elements in vector */
00734         uint8_t  rd_idx;                    /* Index to Read  next Message-ID */
00735         uint8_t  wr_idx;                    /* Index to Write next Message-ID */
00736 };
00737 
00738 /* Reset the specified Circular Queue (CQ) */
00739 void qos2_pub_cq_reset(struct pub_qos2_cq *cq);
00740 
00741 /* Append the message-id into the CQ tail. Return true on success, else false */
00742 bool qos2_pub_cq_logup(struct pub_qos2_cq *cq, uint16_t msg_id);
00743 
00744 /* Remove the message-id from the CQ head. Return true on success, else false */
00745 bool qos2_pub_cq_unlog(struct pub_qos2_cq *cq, uint16_t msg_id);
00746 
00747 /* Is the message-id available in the CQ ? Return true on success, else false */
00748 bool qos2_pub_cq_check(struct pub_qos2_cq *cq, uint16_t msg_id);
00749 
00750 /* Get the count of message-ID(s) availalbe in the CQ */
00751 static inline int32_t qos2_pub_cq_count(struct pub_qos2_cq *cq)
00752 {
00753         return MAX_PUBREL_INFLT - cq->n_free;
00754 }
00755 
00756 struct client_ctx {
00757 
00758         void        *usr;  /* Client Usr */
00759         int32_t          net;  /* Socket HND */
00760 
00761         uint8_t           remote_ip[16];
00762         uint32_t          ip_length;
00763 
00764         uint32_t          timeout;
00765         uint16_t          ka_secs;
00766 
00767         uint32_t          flags;
00768 
00769         struct client_ctx *next;
00770 };
00771 
00772 void cl_ctx_reset(struct client_ctx *cl_ctx);
00773 void cl_ctx_timeout_insert(struct client_ctx **head,
00774                            struct client_ctx *elem);
00775 
00776 void cl_ctx_remove(struct client_ctx **head,
00777                    struct client_ctx *elem);
00778 
00779 #define KA_TIMEOUT_NONE 0xffffffff  /* Different than KA SECS = 0 */
00780 void cl_ctx_timeout_update(struct client_ctx *cl_ctx, uint32_t now_secs);
00781 
00782 }//namespace mbed_mqtt 
00783 
00784 #ifdef __cplusplus  
00785 }
00786 #endif 
00787 
00788 #endif
00789