Update revision to use TI's mqtt and Freertos.

Dependencies:   mbed client server

Fork of cc3100_Test_mqtt_CM3 by David Fletcher

Revision:
3:a8c249046181
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mqtt_V1/common/mqtt_common.h	Thu Sep 03 14:02:37 2015 +0000
@@ -0,0 +1,789 @@
+/******************************************************************************
+*
+*   Copyright (C) 2014 Texas Instruments Incorporated
+*
+*   All rights reserved. Property of Texas Instruments Incorporated.
+*   Restricted rights to use, duplicate or disclose this code are
+*   granted through contract.
+*
+*   The program may not be used without the written permission of
+*   Texas Instruments Incorporated or against the terms and conditions
+*   stipulated in the agreement under which this program has been supplied,
+*   and under no circumstances can it be used with non-TI connectivity device.
+*
+******************************************************************************/
+
+/*
+  mqtt_common.h
+
+  This module outlines the interfaces that are common to both client amd
+  server components. The applications are not expected to utilize the
+  services outlined in this module.
+*/
+
+#ifndef __MQTT_COMMON_H__
+#define __MQTT_COMMON_H__
+
+/** @file mqtt_common.h 
+    This file incorporates constructs that are common to both client and server
+    implementation. 
+
+    The applications are not expected to utlize the routines made available in
+    this module module. 
+
+    @note the routines in this module do not check for availability and 
+    correctness of the input parameters
+
+    @warning The module is expected to under-go changes whilst incorporating
+    support for the server. Therefore, it is suggested that applications do
+    not rely on the services provided in this module.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "platform.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+namespace mbed_mqtt {
+
+#define MQTT_COMMON_VERSTR "1.1.1" /**< Version of Common LIB */
+
+#define MIN(a, b) ((a > b)? b : a)
+
+/** MQTT Message Types */
+#define MQTT_CONNECT      0x01
+#define MQTT_CONNACK      0x02
+#define MQTT_PUBLISH      0x03
+#define MQTT_PUBACK       0x04
+#define MQTT_PUBREC       0x05
+#define MQTT_PUBREL       0x06
+#define MQTT_PUBCOMP      0x07
+#define MQTT_SUBSCRIBE    0x08
+#define MQTT_SUBACK       0x09
+#define MQTT_UNSUBSCRIBE  0x0A
+#define MQTT_UNSUBACK     0x0B
+#define MQTT_PINGREQ      0x0C
+#define MQTT_PINGRSP      0x0D
+#define MQTT_DISCONNECT   0x0E
+
+#define MAX_FH_LEN        0x05    /**< MAX Length of Fixed Header */
+
+/** Max number of bytes in remaining length field */
+#define MAX_REMLEN_BYTES  (MAX_FH_LEN - 1)  
+
+#define MAKE_FH_BYTE1(msg_type,  flags) (uint8_t)((msg_type << 4) | flags)
+
+#define MAKE_FH_FLAGS(bool_dup, enum_qos, bool_retain)                  \
+        (uint8_t)(((bool_dup << 3) | (enum_qos << 1) | bool_retain) & 0xF)
+
+#define QID_VMASK           0x3
+#define QOS_VALUE(enum_qos) (uint8_t)(enum_qos & QID_VMASK)
+#define QFL_VALUE           0x80  /**< QOS Failure value (SUBACK) */
+
+#define DUP_FLAG_VAL(bool_val) (uint8_t)(bool_val << 3)
+
+#define BOOL_RETAIN(fh_byte1)  ((fh_byte1 & 0x1)? true : false)
+#define BOOL_DUP(fh_byte1)     ((fh_byte1 & 0x8)? true : false)
+#define ENUM_QOS(fh_byte1)     (enum mqtt_qos)((fh_byte1 & 0x6) >> 1)
+
+#define MSG_TYPE(fh_byte1)  (uint8_t)((fh_byte1 & 0xf0) >> 4)
+
+static inline uint32_t buf_wr_nbytes(uint8_t *dst, const uint8_t *src, uint32_t n)
+{
+//        printf("buf_wr_nbytes\r\n");
+        uint32_t c = n; 
+        while(c--)
+                *dst++ = *src++;
+
+        return n;
+}
+
+static inline uint32_t buf_set(uint8_t *dst, uint8_t val, uint32_t n)
+{
+        uint32_t c = n; 
+        while(c--)
+                *dst++ = val;
+
+        return n;
+}
+
+/** Writing 2 bytes entity in network byte order */
+static inline uint32_t buf_wr_nbo_2B(uint8_t *buf, uint16_t val)
+{
+        buf[0] = (uint8_t)((val >> 8) & 0xFF); /* MSB */
+        buf[1] = (uint8_t)((val)      & 0xFF); /* LSB */
+        return 2;
+}
+
+/** Reading 2 bytes entity in network byte order */
+static inline uint32_t buf_rd_nbo_2B(const uint8_t *buf, uint16_t *val)
+{
+        *val = (uint16_t)((buf[0] << 8) | (buf[1]));
+        return 2;
+}
+
+/** @defgroup mqp_group MQTT Packet (MQP) Buffer structure
+    The core construct to encapsulate, construct and process a message
+
+    @{
+*/
+struct mqtt_packet {
+
+        uint8_t                     msg_type;   /**< MQTT  Message  Type */
+        uint8_t                     fh_byte1;   /**< Fixed Header: Byte1 */
+
+        uint16_t                    msg_id;     /**< Msg transaction  ID */
+
+        uint8_t                     n_refs;     /**< # users of this msg */
+        uint8_t                     pad[3];
+
+        uint8_t                     offset;     /**< Start of data index */
+        uint8_t                     fh_len;     /**< Fix Header Length   */
+        uint16_t                    vh_len;     /**< Var Header Length   */
+        uint32_t                    pl_len;     /**< Pay Load   Length   */
+
+        uint32_t                    private_;
+
+        uint32_t                    maxlen;     /**< Maximum buffer size */
+        uint8_t                    *buffer;     /**< The attached buffer */
+
+        /** Method to free this packet to a particular pool */
+        void                  (*free)(struct mqtt_packet *mqp);
+
+        struct mqtt_packet    *next;
+};
+
+/** @} */
+
+#define MQP_FHEADER_BUF(mqp)  (mqp->buffer + mqp->offset)
+#define MQP_VHEADER_BUF(mqp)  (MQP_FHEADER_BUF(mqp) + mqp->fh_len)
+#define MQP_PAYLOAD_BUF(mqp)  (MQP_VHEADER_BUF(mqp) + mqp->vh_len)
+
+#define MQP_CONTENT_LEN(mqp)  (mqp->fh_len + mqp->vh_len + mqp->pl_len)
+#define MQP_FREEBUF_LEN(mqp)  (mqp->maxlen - mqp->offset -      \
+                               MQP_CONTENT_LEN(mqp))
+
+#define MQP_FHEADER_VAL(mqp)  (mqp->fh_byte1)
+#define MQP_FHEADER_MSG(mqp)  (MSG_TYPE(MQP_FHEADER_VAL(mqp)))
+#define MQP_FHEADER_FLG(mqp)  (MSG_FLAGS(MQP_FHEADER_VAL(mqp)))
+
+#define DEFINE_MQP_VEC(num_mqp, mqp_vec)                \
+        static struct mqtt_packet mqp_vec[num_mqp];
+
+#define DEFINE_MQP_BUF_VEC(num_mqp, mqp_vec, buf_len, buf_vec)        \
+        DEFINE_MQP_VEC(num_mqp, mqp_vec);                             \
+        static uint8_t buf_vec[num_mqp][buf_len];
+
+/*---------------------------------------------------------------------
+ * Heleper MACROS for PUBLISH-RX Message Processing
+ *---------------------------------------------------------------------
+ */
+
+/** @defgroup rxpub_help_group Helper Macros for RX PUBLISH
+    @{
+*/
+
+/** Yields pointer to topic content */
+#define MQP_PUB_TOP_BUF(mqp) (MQP_VHEADER_BUF(mqp) + 2)
+
+/** Length or size of topic content */
+#define MQP_PUB_TOP_LEN(mqp) (mqp->vh_len - 2 - (mqp->msg_id? 2 : 0))
+
+/** Yields pointer to payload data */
+#define MQP_PUB_PAY_BUF(mqp) (mqp->pl_len? MQP_PAYLOAD_BUF(mqp) : NULL)
+
+/** Length or size of payload data */
+#define MQP_PUB_PAY_LEN(mqp) (mqp->pl_len)
+
+/** @} */
+
+/** @cond
+    CONNECT Message Flags, as outined in the MQTT Specification
+*/
+#define WILL_RETAIN_VAL 0x20
+#define WILL_CONFIG_VAL 0x04
+#define CLEAN_START_VAL 0x02
+#define USER_NAME_OPVAL 0x80
+#define PASS_WORD_OPVAL 0x40
+/**
+    @endcond
+*/
+
+/** @cond
+    CONNACK 8bit Return Code, as outlined in the MQTT Specification
+*/
+#define CONNACK_RC_REQ_ACCEPT   0x00
+#define CONNACK_RC_BAD_PROTOV   0x01
+#define CONNACK_RC_CLI_REJECT   0x02
+#define CONNACK_RC_SVR_UNAVBL   0x03
+#define CONNACK_RC_BAD_USRPWD   0x04
+#define CONNACK_RC_NOT_AUTHED   0x05
+/**
+   @endcond
+*/
+
+/** @defgroup lib_err_group LIBRARY Generated Error Codes
+    Library provides these codes as return values in several routines
+
+    @{
+*/
+#define MQP_ERR_NETWORK   (-1)  /**< Problem in network (sock err) */
+#define MQP_ERR_TIMEOUT   (-2)  /**< Net transaction has timed out */
+#define MQP_ERR_NET_OPS   (-3)  /**< Platform Net Ops un-available */
+#define MQP_ERR_FNPARAM   (-4)  /**< Invalid parameter(s) provided */
+#define MQP_ERR_PKT_AVL   (-5)  /**< No pkts are available in pool */
+#define MQP_ERR_PKT_LEN   (-6)  /**< Inadequate free buffer in pkt */
+#define MQP_ERR_NOTCONN   (-7)  /**< Lib isn't CONNECTED to server */
+#define MQP_ERR_BADCALL   (-8)  /**< Irrelevant call for LIB state */
+#define MQP_ERR_CONTENT   (-9)  /**< MSG / Data content has errors */
+#define MQP_ERR_LIBQUIT  (-10)  /**< Needs reboot library has quit */
+
+
+#define MQP_ERR_NOT_DEF  (-32)  /**< Value other than defined ones */
+
+/** @} */
+
+/*---------------------------------------------------------------------
+ * Common Operations
+ *---------------------------------------------------------------------
+ */
+
+/** Free a MQTT Packet Buffer 
+    Puts back the packet buffer in to the appropriate pool.
+    
+    @param[in] mqp packet buffer to be freed
+    @return none
+*/
+void mqp_free(struct mqtt_packet *mqp);
+
+/** Resets the attributes of MQTT Packet Holder to its init state
+    Not all fields are reset - entities such as offset, n_refs in addition
+    to buffer information are not updated.
+
+    @param[in] mqp packet buffer to be reset
+    @return none
+
+    @see mqp_init
+*/
+void mqp_reset(struct mqtt_packet *mqp);
+
+/** Initializes attributes of the MQTT Packet Holder.
+    This routine sets number of users of the MQTT Packet Holder to 1. However,
+    it leaves, if already provisioned, the reference to buffer and its size
+    un-altered.
+
+    @param[in] mqp packet buffer to be initialized
+    @param[in] offset index in buffer to indicate start of the contents
+    @return none
+*/
+void mqp_init(struct mqtt_packet *mqp, uint8_t offset);
+
+/** Initialize MQTT Packet Holder and attach the buffer */
+static 
+inline void mqp_buffer_attach(struct mqtt_packet *mqp, uint8_t *buffer, uint32_t length,
+                              uint8_t offset)
+{
+        mqp_init(mqp, offset);
+
+        mqp->buffer = buffer;
+        mqp->maxlen = length;
+        mqp->free   = NULL;
+
+        return;
+}
+
+/** Description of UTF8 information as used by MQTT Library. */
+struct utf8_string {
+        
+        const char *buffer;   /**< Refers to UTF8 content */
+        uint16_t       length;   /**< Length of UTF8 content */
+};
+
+/** Write UTF8 information into the buffer. 
+    The UTF8 information includes content and its length.
+
+    @warning The routine does not check for correctness of the paramters.
+
+    @param[in] buf refers to memory to write UTF8 information into
+    @param[in] utf8 contains UTF8 information to be written
+    @return on success, number of bytes written, otherwise -1 on error.
+*/
+int32_t mqp_buf_wr_utf8(uint8_t *buf, const struct utf8_string *utf8);
+
+/** Write the MQTT construct 'Remaining Length' into trailing end of buffer.
+    The 'remaining length' is written in the format as outlined in the MQTT
+    specification. 
+
+    The implementation assumes availability of at-least 4 bytes in the buffer.
+    Depending on the value of 'Remaining Length' appropriate trailing bytes in
+    the buffer would be used.
+    
+    @param[in] buf refers to memory to tail-write 'Remaining Length' into
+    @param[in] remlen The 'Remaining Length' value
+    @return in success, number of trailing bytes used, otherwise -1 on error
+*/
+int32_t mqp_buf_tail_wr_remlen(uint8_t *buf, uint32_t remlen);
+
+/** Read MQTT construct 'Remaining Length' from leading bytes of the buffer.
+    The 'remaining length' is written in the format as outlined in the MQTT
+    specification.
+     
+    @param[in] buf refers to memory to head-read 'Remaining Length' from
+    @param[in] remlen place-holder for The 'Remaining Length' value
+    @return in success, number of header bytes read, otherwise -1 on error
+*/   
+int32_t mqp_buf_rd_remlen(uint8_t *buf, uint32_t *remlen);
+
+/** Include variable header Topic as part of PUB Message construction.
+    Inclusion of a Topic also encompasses incorporation of the message ID.
+
+    The topic refers to the subject for which data will be published by
+    the client or the server. The topic entity must be appended into the
+    packet buffer prior to the inclusion of the payload (data).
+
+    @warning This routine does not check for correctness of the input
+    parameters.
+
+    @param[in] mqp packet buffer in which topic must be included.
+    @param[in] topic UTF8 information
+    @param[in] msg_id Message or Packet transaction ID
+    @return on success, number of bytes appended, otherwise -1 on error.
+
+    @note A 'topic' must be appended prior to inclusion of pulished data.
+*/
+int32_t 
+mqp_pub_append_topic(struct mqtt_packet *mqp, const struct utf8_string *topic,
+                     uint16_t msg_id);
+
+/** Include payload data for publishing
+    The payload data is associated with a topic.
+    
+    @warning This routine does not check for correctness of the input
+    parameters.
+
+    @param[in] mqp packet buffer in which payload data must be included.
+    @param[in] data_buf data to be included in the packet buffer
+    @param[in] data_len length of the data to be included in the packet.
+    @return on success, number of bytes appended, otherwise -1 on error.
+
+    @note A 'topic' must be appended prior to inclusion of pulished data.
+*/
+int32_t mqp_pub_append_data(struct mqtt_packet *mqp, const uint8_t *data_buf,
+                        uint32_t data_len);
+
+/** Construct a packet for Message ID enabled ACK received from network
+    Process the raw ACK message information to update the packet holder.
+   
+    @warning This routine does not check for correctness of the input
+    parameters.
+       
+    @param[in] mqp_raw holds a raw buffer from the network
+    @param[in] has_payload asserted, if ACK message should have a payload
+    @return on success, true, otherwise false
+*/
+bool mqp_proc_msg_id_ack_rx(struct mqtt_packet *mqp_raw, bool has_payload);
+
+/** Construct a packet for PUBLISH message received from the network
+    Process the raw PUB message information to update the packet holder.
+
+    @warning This routine does not check for correctness of the input
+    parameters.
+
+    @param[in] mqp_raw holds a raw buffer from the network
+    @return on success, true, other wise false
+*/
+bool mqp_proc_pub_rx(struct mqtt_packet *mqp_raw);
+
+/*
+   Wait-List of MQTT Messages for which acknoledge is pending from remote node.
+*/
+struct mqtt_ack_wlist {
+        
+        struct mqtt_packet *head;  /* Points to head of single linked-list. */
+        struct mqtt_packet *tail;  /* Points to tail of single linked-list. */
+};
+
+static inline bool mqp_ack_wlist_is_empty(struct mqtt_ack_wlist *list)
+{
+        return (NULL == list->head) ? true : false;
+}
+
+/*
+   Add specified element into trailing end of list.
+
+   Returns, on success, true, otherwise false.
+*/
+bool mqp_ack_wlist_append(struct mqtt_ack_wlist *list,
+                          struct mqtt_packet    *elem);
+
+/*
+   Removes element that has specified msg_id from list. 
+
+   Returns, on success, pointer to removed element, otherwise NULL.
+*/
+struct mqtt_packet *mqp_ack_wlist_remove(struct mqtt_ack_wlist *list,
+                                          uint16_t msg_id);
+/* 
+   Removes and frees all elements in list. 
+*/
+void mqp_ack_wlist_purge(struct mqtt_ack_wlist *list);
+
+static inline bool is_wlist_empty(const struct mqtt_ack_wlist *list)
+{
+        return list->head? false : true;
+}
+
+/** Prepare the Fixed-Header of the MQTT Packet (before being sent to network)
+    Based on the contents of the mqtt packet and the combination of DUP, QoS
+    and Retain flags as outlined the MQTT specification, the routine updates,
+    among others, significant internal fields such as 'remaining length' and
+    'fixed header length' in the packet construct and embeds the fixed header,
+    so created, in the packet buffer.
+    
+    This service must be utilized on a packet that has been already populated
+    with all the payload data, topics and other contents. The fixed header
+    must be the final step in the compostion of MQTT packet prior to its
+    dispatch to the server.
+    
+    Returns size, in bytes, of the fixed-header, otherwise -1 on error.
+*/
+int32_t mqp_prep_fh(struct mqtt_packet *mqp, uint8_t flags);
+
+/** MQTT Quality of Service */
+enum mqtt_qos {
+        
+        MQTT_QOS0,  /**< QoS Level 0 */
+        MQTT_QOS1,  /**< QoS Level 1 */
+        MQTT_QOS2   /**< QoS Level 2 */
+};
+
+/** Construct to create Topic to SUBSCRIBE */
+struct utf8_strqos {
+
+        const char       *buffer;  /**< Refers to UTF8 content */
+        uint16_t             length;  /**< Length of UTF8 content */
+        enum mqtt_qos   qosreq;  /**< QoS Level  for content */
+};
+
+
+/** @defgroup mqtt_netsec_grp Information to establish a secure connection.
+    This is implementation specific and is targeted for the network services.
+
+    Specifically, the MQTT implementation makes no assumption or use of this
+    construct. The client library merely passes information from the app to
+    the network service layer.
+    Note: value of n_file can vary from 1 to 4, with corresponding pointers to
+    the files in files field. Value of 1(n_file) will assume the corresponding
+    pointer is for CA File Name. Any other value of n_file expects the files to
+    be in following order:
+    1.  Private Key File
+    2.  Certificate File Name
+    3.  CA File Name
+    4.  DH Key File Name
+
+example: 
+If you want to provide only CA File Name, following are the two way of doing it:
+for n_file = 1
+char *security_file_list[] = {"/cert/testcacert.der"};
+for n_file = 4
+char *security_file_list[] = {NULL, NULL, "/cert/testcacert.der", NULL};
+
+where files = security_file_list
+    @{
+*/
+struct secure_conn {
+        
+        void *method;  /**< Reference to information about protocol or methods */
+        void *cipher;  /**< Reference to information about cryptograph ciphers */
+        uint32_t   n_file;  /**< Count of secure connection related files, certs... */
+        char   **files;  /**< Reference to array of file-names used for security */
+};
+
+/** @} */
+
+/* Initialize the struct secure_conn data */
+void secure_conn_struct_init(struct secure_conn *nw_security);
+
+/** @defgroup net_ops_group Abstraction of Network Services on a platform
+    Services to enable the MQTT Client-Server communication over network
+   
+    These services are invoked by the MQTT Library.
+    
+    @{
+*/ 
+struct device_net_services {
+
+       /** @defgroup dev_netconn_opt_grp Options for platform to configure network
+           @{
+        */
+#define DEV_NETCONN_OPT_TCP  0x01  /**< Assert to indicate TCP net connection  */
+#define DEV_NETCONN_OPT_UDP  0x02  /**< Assert to create a local UDP port bind */
+#define DEV_NETCONN_OPT_IP6  0x04  /**< Assert for IPv6, otherwise it is IPv4  */
+#define DEV_NETCONN_OPT_URL  0x08  /**< Assert if the network address is a URL */
+#define DEV_NETCONN_OPT_SEC  0x10  /**< Assert to indicate a secure connection */
+        /** @} */
+
+        /** Set up a communication channel with a server or set up a local port.
+            This routine opens up either a "connection oriented" communication
+            channel with the specified server or set up a local configuration for
+            "connectionless" transactions.
+
+            @param[in] nwconn_opts Implementation specific construct to enumerate
+            server address and / or connection related details
+            @param[in] server_addr URL or IP address (string) or other server
+            reference. For setting up a local (UDP) port, set it to NULL.
+            @param[in] port_number Network port number, typically, 1883 or 8883
+            for remote severs. For setting up a local (UDP) port, use an intended
+            port number.
+            @param[in] nw_security Information to establish a secure connection
+            with server. Set it to NULL, if not used. @ref mqtt_netsec_grp
+            @return a valid handle to connection, otherwise NULL
+        */
+        int32_t (*open)(uint32_t nwconn_opts, const char *server_addr, uint16_t port_number,
+                    const struct secure_conn *nw_security);
+
+        /** Send data onto the "connection oriented" network.
+            The routine blocks till the time, the data has been copied into the
+            network stack for dispatch on to the "connection oriented" network.
+
+            @param[in] comm handle to network connection as returned by open().
+            @param[in] buf refers to the data that is intended to be sent
+            @param[in] len length of the data
+            @param[in] ctx reference to the MQTT connection context
+            @return on success, the number of bytes sent, 0 on connection reset,
+            otherwise -1
+        */
+        int32_t   (*send)(int32_t comm, const uint8_t *buf, uint32_t len, void *ctx);
+
+        /** Receive data from the "connection oriented" channel.
+            The routine blocks till the time, there is either a data that has
+            been received from the server or the time to await data from the
+            server has expired.
+
+            @param[in] comm Handle to network connection as returned by
+            accept().
+            @param[out] buf place-holder to which data from network should be
+            written into.
+            @param[in] len maximum length of 'buf'
+            @param[in] wait_secs maximum time to await data from network. If
+            exceeded, the routine returns error with the err_timeo flag set
+            as true.
+            @param[out] err_timeo if set, indicates that error is due to
+            timeout.
+            @param[in] ctx reference to the MQTT connection context
+            @return on success, number of bytes received, 0 on connection reset,
+            otherwise -1 on error. In case, error (-1) is due to the time-out,
+            then the implementation should set flag err_timeo as true.
+        */
+        int32_t   (*recv)(int32_t comm, uint8_t *buf, uint32_t len, uint32_t wait_secs,
+                      bool *err_timeo, void *ctx);
+
+        /** Send data to particular port on the specified network element.
+            The routine blocks till the time, the data has been copied into the
+            network stack for dispatch to the "specified" network entity.
+
+            @param[in] comm handle to network connection as returned by open().
+            @param[in] buf refers to data that is intended to be sent
+            @param[in] len length of the data
+            @param[in] dest_port network port to which data is to be sent.
+            @param[in] dest_ip IP address of the entity to which data is to be
+            sent.
+            @param[in] ip_len length of the destination IP address.
+            @return on success, the number of bytes sent, 0 on connection reset,
+            otherwise -1.
+        */
+        int32_t   (*send_dest)(int32_t comm, const uint8_t *buf, uint32_t len, uint16_t dest_port,
+                           const uint8_t *dest_ip, uint32_t ip_len);
+
+        /** Receive data on a local port sent by any network element.
+            The routine blocks till the time, data has been received on the local
+            port from any remote network element.
+
+            @param[in] comm handle to network connection as return by open().
+            @param[in] buf place-holder to which data from network should be
+            written into.
+            @param[in] len maximum lengh of 'buf'
+            @param[out] from_port place-holder for the port of the sender network
+            entity
+            @param[out] from_ip place-holder to retrieve the IP address of the
+            sender network entity. The memory space must be provisioned to store
+            atleast 16 bytes.
+            @param[in, out] ip_len length of IP address. It is provided by
+            the caller to declare the length of the place holder and updated by
+            routine to indicate the length of the remote network entity's IP
+            address.
+            @return on success, number of bytes received, 0 on connection reset,
+            otherwise -1 on errir. 
+        */
+        int32_t   (*recv_from)(int32_t comm, uint8_t *buf, uint32_t len, uint16_t *from_port,
+                           uint8_t *from_ip, uint32_t *ip_len);
+
+        /** Close communication connection */
+        int32_t   (*close)(int32_t comm);
+
+        /** Listen to incoming connection from clients.
+            This routine prepares the system to listen on the specified port
+            for the incoming network connections from the remote clients.
+
+            @param[in] nwconn_opts Implementation specific construct to
+            enumerate server address and / or connection related details
+            @param[in] port_number Network port number, typically, 1883 or 8883
+            @param[in] nw_security Information to establish a secure connection
+            with client. Set it to NULL, if not used. @ref mqtt_netsec_grp
+            @return a valid handle to listening contruct, otherwise NULL
+        */
+        int32_t (*listen)(uint32_t nwconn_opts, uint16_t port_number,
+                      const struct secure_conn *nw_security);
+
+        /** Accept an incominng connection.
+            This routine creates a new communication channel for the (remote)
+            requesting client.
+
+            @param[in] listen handle to listen for the incoming connection
+            requests from the remote clients
+            @param[out] client_ip IP address of the connected client. This value
+            is valid only on successful return of the routine. The place holder
+            must provide memory to store atleast 16 bytes.
+            @param[in, out] ip_length Length of IP address. It is provided by
+            the caller to declare the length of the place holder and updated by
+            routine to indicate the length of the connected client's IP address.
+            @return on success, a valid handle to the new connection, otherwise
+            NULL
+        */
+        int32_t (*accept)(int32_t listen, uint8_t *client_ip, uint32_t *ip_length);
+
+        /** Monitor activity on communication handles.
+            The routine blocks for the specified period of time to monitor
+            activity, if any, on each of the communication handle that has
+            been provided in one or more vector sets. At the expiry of the
+            wait time, this function must identify the handles, on which,
+            acitvities were observed.
+
+            A particular collection of communication handles are packed as
+            an array or in a vector and is passed to the routine. A NULL
+            handle in the vector indicates the termination of the vector
+            and can effectively used to account for the size of the vector.
+
+            Similarly, at end the end of the wait period, the routine must
+            provide a vector of the handles for which activity was observed.
+
+            @param[in, out] recv_hvec a vector of handles which must be
+            monitored for receive activities. 
+            @param[in, out] send_hvec a vector of handles which must be
+            monitored for send activities.
+            @param[in, out] rsvd_hvec reserved for future use.
+            @param[in] wait_secs time to wait and monitor activity on
+            communication handles provided in one or more sets. If set 
+            to 0, the routine returns immediately.
+            @return on success, the total number of handles for which activity
+            was observed. This number can be 0, if no activity was observed on
+            any of the provided handle in the specified time. Otherwise, -1 on
+            error.
+        */
+        int32_t   (*io_mon)(int32_t *recv_cvec, int32_t *send_cvec,
+                        int32_t *rsvd_cvec,  uint32_t wait_secs);
+
+        /** Get Time (in seconds).
+            Provides a monotonically incrementing value of a time  service in
+            unit of seconds. The implementation should ensure that associated
+            timer hardware or the clock module remains active through the low
+            power states of the system. Such an arrangement ensures that MQTT
+            Library is able to track the Keep-Alive time across the cycles of
+            low power states. It would be typical of battery operated systems
+            to transition to low power states during the period of inactivity
+            or otherwise to conserve battery. 
+
+            In the absence of a sustained time reference across the low power
+            states, if the system transitions away from the active state, the
+            MQTT Library, then may not be able to effectively monitor the Keep
+            Alive duration.
+
+            It is the responsbililty of the implementation to manage the roll-
+            over problem of the hardware and ensure the integrity of the time
+            value is maintained.
+
+           @return time in seconds
+        */
+        uint32_t   (*time)(void);
+};
+
+/** @} */ /* device_net_services */
+
+/* Receive data from the specified network and read into the 'mqp' */
+int32_t mqp_recv(int32_t  net,     const struct device_net_services *net_ops,
+             struct mqtt_packet *mqp, uint32_t wait_secs, bool *timed_out,
+             void *ctx);
+
+/*-----------------------------------------------------------------------------
+ * Data structure for managing the QoS2 PUB RX packets and follow-ups
+ *---------------------------------------------------------------------------*/
+
+#define MAX_PUBREL_INFLT 8 /* Must be kept as a value of 2^n */
+
+struct pub_qos2_cq { /* Circular Queue CQ to track QOS2 PUB RX messages */
+
+        uint16_t id_vec[MAX_PUBREL_INFLT];  /* Vector to store RX Message-IDs */
+        uint8_t  n_free;                    /* Num of free elements in vector */
+        uint8_t  rd_idx;                    /* Index to Read  next Message-ID */
+        uint8_t  wr_idx;                    /* Index to Write next Message-ID */
+};
+
+/* Reset the specified Circular Queue (CQ) */
+void qos2_pub_cq_reset(struct pub_qos2_cq *cq);
+
+/* Append the message-id into the CQ tail. Return true on success, else false */
+bool qos2_pub_cq_logup(struct pub_qos2_cq *cq, uint16_t msg_id);
+
+/* Remove the message-id from the CQ head. Return true on success, else false */
+bool qos2_pub_cq_unlog(struct pub_qos2_cq *cq, uint16_t msg_id);
+
+/* Is the message-id available in the CQ ? Return true on success, else false */
+bool qos2_pub_cq_check(struct pub_qos2_cq *cq, uint16_t msg_id);
+
+/* Get the count of message-ID(s) availalbe in the CQ */
+static inline int32_t qos2_pub_cq_count(struct pub_qos2_cq *cq)
+{
+        return MAX_PUBREL_INFLT - cq->n_free;
+}
+
+struct client_ctx {
+
+        void        *usr;  /* Client Usr */
+        int32_t          net;  /* Socket HND */
+
+        uint8_t           remote_ip[16];
+        uint32_t          ip_length;
+
+        uint32_t          timeout;
+        uint16_t          ka_secs;
+
+        uint32_t          flags;
+
+        struct client_ctx *next;
+};
+
+void cl_ctx_reset(struct client_ctx *cl_ctx);
+void cl_ctx_timeout_insert(struct client_ctx **head,
+                           struct client_ctx *elem);
+
+void cl_ctx_remove(struct client_ctx **head,
+                   struct client_ctx *elem);
+
+#define KA_TIMEOUT_NONE 0xffffffff  /* Different than KA SECS = 0 */
+void cl_ctx_timeout_update(struct client_ctx *cl_ctx, uint32_t now_secs);
+
+}//namespace mbed_mqtt 
+
+#ifdef __cplusplus  
+}
+#endif 
+
+#endif
+