Add toolchain and mbtk source

Change-Id: Ie12546301367ea59240bf23d5e184ad7e36e40b3
diff --git a/mbtk/mbtk_mqtt/MQTTClient.c b/mbtk/mbtk_mqtt/MQTTClient.c
new file mode 100755
index 0000000..4a349a7
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTClient.c
@@ -0,0 +1,684 @@
+/*******************************************************************************
+ * Copyright (c) 2014 IBM Corp.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * and Eclipse Distribution License v1.0 which accompany this distribution.
+ *
+ * The Eclipse Public License is available at
+ *    http://www.eclipse.org/legal/epl-v10.html
+ * and the Eclipse Distribution License is available at
+ *   http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * Contributors:
+ *    Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+
+#include "MQTTClient.h"
+
+regnwl_info_t regnwl_info = {0};
+
+
+int core_json_value(const char *input, uint32_t input_len, const char *key, uint32_t key_len, char **value,
+                        uint32_t *value_len)
+{
+    int idx = 0;
+
+    for (idx = 0; idx < input_len; idx++) {
+        if (idx + key_len >= input_len) {
+            return -1;
+        }
+        if ((memcmp(&input[idx], key, key_len) == 0) &&
+            ((idx > 0) && (input[idx - 1] == '"')) &&
+            ((idx + key_len < input_len) && (input[idx + key_len] == '"'))) {
+            idx += key_len;
+            /* shortest ":x, or ":x} or ":x] */
+            if ((idx + 2 >= input_len) ||
+                (input[idx + 1] != ':')) {
+                return -1;
+            }
+            idx += 2;
+            if (input[idx] == '"') {
+                *value = (char *)&input[++idx];
+                for (; idx < input_len; idx++) {
+                    if ((input[idx] == '"')) {
+                        *value_len = (uint32_t)(idx - (*value - input));
+                        return SUCCESS;
+                    }
+                }
+            } else if (input[idx] == '{' || input[idx] == '[') {
+                char start = input[idx];
+                char end = (start == '{') ? ('}') : (']');
+                uint8_t count = 0;
+                *value = (char *)&input[idx];
+                for (; idx < input_len; idx++) {
+                    if ((input[idx] == start)) {
+                        count++;
+                    } else if ((input[idx] == end)) {
+                        if (--count == 0) {
+                            *value_len = (uint32_t)(idx - (*value - input) + 1);
+                            return SUCCESS;
+                        }
+                    }
+                }
+            } else {
+                *value = (char *)&input[idx];
+                for (; idx < input_len; idx++) {
+                    if ((input[idx] == ',' || input[idx] == ']' || input[idx] == '}')) {
+                        *value_len = (uint32_t)(idx - (*value - input));
+                        return SUCCESS;
+                    }
+                }
+            }
+        }
+    }
+
+    return -1;
+}
+
+
+void mbtk_ali_auth_regnwl_sava(MQTTMessage msg)
+{
+    printf("pub, payload: %d,%s\n", msg.payloadlen, msg.payload);
+    int32_t res = SUCCESS;
+
+    char *client_key = "clientId",*deviceToken_key="deviceToken";
+    uint32_t clientId_value_len = 0,deviceToken_value_len = 0;
+
+    char *client_value=NULL,*deviceToken_value=NULL;
+    if ((res = core_json_value((char *)msg.payload, msg.payloadlen,
+          client_key, strlen(client_key), &client_value, &clientId_value_len)) == SUCCESS)
+    {
+        memset(regnwl_info.clientId,0,clientId_value_len+1);
+        memcpy(regnwl_info.clientId,client_value,clientId_value_len);
+        printf("client_value:%s,\n regnwl_info->clientId:%s\n", client_value, regnwl_info.clientId);
+    }
+
+    if ((res = core_json_value((char *)msg.payload, msg.payloadlen,
+           deviceToken_key, strlen(deviceToken_key), &deviceToken_value, &deviceToken_value_len)) == SUCCESS)
+    {
+        memset(regnwl_info.deviceToken,0,deviceToken_value_len+1);
+        memcpy(regnwl_info.deviceToken,deviceToken_value,deviceToken_value_len);
+        printf("deviceToken_value:%s,\n regnwl_info->deviceToken:%s\n", deviceToken_value, regnwl_info.deviceToken);
+    }
+
+}
+
+
+void NewMessageData(MessageData* md, MQTTString* aTopicName, MQTTMessage* aMessgage) {
+    md->topicName = aTopicName;
+    md->message = aMessgage;
+}
+
+
+int getNextPacketId(Client *c) {
+    return c->next_packetid = (c->next_packetid == MAX_PACKET_ID) ? 1 : c->next_packetid + 1;
+}
+
+
+int sendPacket(Client* c, int length, Timer* timer)
+{
+    int rc = FAILURE, 
+        sent = 0;
+    
+    while (sent < length && !expired(timer))
+    {
+        rc = c->ipstack->mqttwrite(c->ipstack, &c->buf[sent], length, left_ms(timer));
+        if (rc < 0)  // there was an error writing the data
+            break;
+        sent += rc;
+    }
+    printf("rc ----%d,sent----%d,length----%d\n",rc,sent,length);
+    if (sent == length)
+    {
+        countdown(&c->ping_timer, c->keepAliveInterval); // record the fact that we have successfully sent the packet    
+        rc = SUCCESS;
+    }
+    else
+        rc = FAILURE;
+    return rc;
+}
+
+
+void MQTTClient(Client* c, Network* network, unsigned int command_timeout_ms, unsigned char* buf, size_t buf_size, unsigned char* readbuf, size_t readbuf_size)
+{
+    int i;
+    c->ipstack = network;
+    
+    for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+        c->messageHandlers[i].topicFilter = 0;
+    c->command_timeout_ms = command_timeout_ms;
+    c->buf = buf;
+    c->buf_size = buf_size;
+    c->readbuf = readbuf;
+    c->readbuf_size = readbuf_size;
+    c->isconnected = 0;
+    c->ping_outstanding = 0;
+    c->defaultMessageHandler = NULL;
+    InitTimer(&c->ping_timer);
+}
+
+
+int decodePacket(Client* c, int* value, int timeout)
+{
+    unsigned char i;
+    int multiplier = 1;
+    int len = 0;
+    const int MAX_NO_OF_REMAINING_LENGTH_BYTES = 4;
+
+    *value = 0;
+    do
+    {
+        int rc = MQTTPACKET_READ_ERROR;
+
+        if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)
+        {
+            rc = MQTTPACKET_READ_ERROR; /* bad data */
+            goto exit;
+        }
+        rc = c->ipstack->mqttread(c->ipstack, &i, 1, timeout);
+        if (rc != 1)
+            goto exit;
+        *value += (i & 127) * multiplier;
+        multiplier *= 128;
+    } while ((i & 128) != 0);
+exit:
+    return len;
+}
+
+
+int readPacket(Client* c, Timer* timer) 
+{
+    int rc = FAILURE;
+    MQTTHeader header = {0};
+    int len = 0;
+    int rem_len = 0;
+
+    /* 1. read the header byte.  This has the packet type in it */
+    memset(c->readbuf,0x0,c->readbuf_size);
+    if ((rc = c->ipstack->mqttread(c->ipstack, c->readbuf, 1, left_ms(timer))) != 1)
+        goto exit;
+
+    len = 1;
+    /* 2. read the remaining length.  This is variable in itself */
+    decodePacket(c, &rem_len, left_ms(timer));
+    len += MQTTPacket_encode(c->readbuf + 1, rem_len); /* put the original remaining length back into the buffer */
+
+    /* 3. read the rest of the buffer using a callback to supply the rest of the data */
+    if (rem_len > 0 && ((rc = c->ipstack->mqttread(c->ipstack, c->readbuf + len, rem_len, left_ms(timer)) )!= rem_len))
+        goto exit;
+
+    header.byte = c->readbuf[0];
+    rc = header.bits.type;
+exit:
+    return rc;
+}
+
+
+// assume topic filter and name is in correct format
+// # can only be at end
+// + and # can only be next to separator
+char isTopicMatched(char* topicFilter, MQTTString* topicName)
+{
+    char* curf = topicFilter;
+    char* curn = topicName->lenstring.data;
+    char* curn_end = curn + topicName->lenstring.len;
+    
+    while (*curf && curn < curn_end)
+    {
+        if (*curn == '/' && *curf != '/')
+            break;
+        if (*curf != '+' && *curf != '#' && *curf != *curn)
+            break;
+        if (*curf == '+')
+        {   // skip until we meet the next separator, or end of string
+            char* nextpos = curn + 1;
+            while (nextpos < curn_end && *nextpos != '/')
+                nextpos = ++curn + 1;
+        }
+        else if (*curf == '#')
+            curn = curn_end - 1;    // skip until end of string
+        curf++;
+        curn++;
+    };
+    
+    return (curn == curn_end) && (*curf == '\0');
+}
+
+
+int deliverMessage(Client* c, MQTTString* topicName, MQTTMessage* message)
+{
+    int i;
+    int rc = FAILURE;
+
+    // we have to find the right message handler - indexed by topic
+    for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+    {
+        if (c->messageHandlers[i].topicFilter != 0 && (MQTTPacket_equals(topicName, (char*)c->messageHandlers[i].topicFilter) ||
+                isTopicMatched((char*)c->messageHandlers[i].topicFilter, topicName)))
+        {
+            if (c->messageHandlers[i].fp != NULL)
+            {
+                MessageData md;
+                NewMessageData(&md, topicName, message);
+                c->messageHandlers[i].fp(&md);
+                rc = SUCCESS;
+            }
+        }
+    }
+    
+    if (rc == FAILURE && c->defaultMessageHandler != NULL) 
+    {
+        MessageData md;
+        NewMessageData(&md, topicName, message);
+        c->defaultMessageHandler(&md);
+        rc = SUCCESS;
+    }   
+    
+    return rc;
+}
+
+
+int keepalive(Client* c)
+{
+    int rc = SUCCESS;
+    if (c->keepAliveInterval == 0)
+    {
+        rc = SUCCESS;
+        goto exit;
+    }
+    
+    if (expired(&c->ping_timer))
+    {
+        if (!c->ping_outstanding)
+        {
+            Timer timer;
+            InitTimer(&timer);
+            countdown_ms(&timer, 1000);
+            int len = MQTTSerialize_pingreq(c->buf, c->buf_size);
+            printf("len %d\n",len);
+            if (len > 0 && (rc = sendPacket(c, len, &timer)) == SUCCESS) // send the ping packet
+                c->ping_outstanding = 1;
+            printf("sendPacket---------------------------------------------\n");
+        }
+    	else
+    	{
+    	    printf("fail_count-------------\n",c->fail_count);
+            ++(c->fail_count);
+            if (c->fail_count >= MAX_FAIL_ALLOWED)
+            {
+                rc = DISCONNECTED;
+                goto exit;
+            }
+
+    	}
+	 countdown(&(c->ping_timer), c->keepAliveInterval);
+    }
+    //printf("keepalive rc is %d\n",rc);
+exit:
+    return rc;
+}
+
+
+int cycle(Client* c, Timer* timer)
+{
+	int len = 0,
+	rc = SUCCESS;
+    // read the socket, see what work is due
+	short packet_type = readPacket(c, timer);
+
+	if(packet_type <= 0)
+	{
+		//printf("[%s][%d]readPacket retrun socket close \n",__FUNCTION__, __LINE__);
+        //printf("[%s]....packet_type = %d\n", __FUNCTION__, packet_type);
+		rc =  DISCONNECTED;
+		goto exit;
+	}
+    
+    switch (packet_type)
+    {
+        case CONNACK:
+        case PUBACK:
+        case SUBACK:
+            break;
+        case PUBLISH:
+        {
+            memset(regnwl_info.deviceToken,0,sizeof(regnwl_info.deviceToken));
+            memset(regnwl_info.clientId,0,sizeof(regnwl_info.clientId));
+            MQTTString topicName;
+            MQTTMessage msg;
+            if (MQTTDeserialize_publish((unsigned char*)&msg.dup, (int*)&msg.qos, (unsigned char*)&msg.retained, (unsigned short*)&msg.id, &topicName,
+               (unsigned char**)&msg.payload, (int*)&msg.payloadlen, c->readbuf, c->readbuf_size) != 1)
+                goto exit;
+           if(memcmp(topicName.lenstring.data,"/ext/regnwl",strlen("/ext/regnwl")) == 0)
+            {
+                mbtk_ali_auth_regnwl_sava(msg);
+            }
+            deliverMessage(c, &topicName, &msg);
+            if (msg.qos != QOS0)
+            {
+                if (msg.qos == QOS1)
+                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBACK, 0, msg.id);
+                else if (msg.qos == QOS2)
+                    len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREC, 0, msg.id);
+                if (len <= 0)
+                    rc = FAILURE;
+                   else
+                       rc = sendPacket(c, len, timer);
+                if (rc == FAILURE)
+                {
+                    goto exit; // there was a problem
+		   }
+
+            }
+            break;
+        }
+        case PUBREC:
+        {
+            unsigned short mypacketid;
+            unsigned char dup, type;
+            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
+                rc = FAILURE;
+            else if ((len = MQTTSerialize_ack(c->buf, c->buf_size, PUBREL, 0, mypacketid)) <= 0)
+                rc = FAILURE;
+            else if ((rc = sendPacket(c, len, timer)) != SUCCESS) // send the PUBREL packet
+                rc = FAILURE; // there was a problem
+            if (rc == FAILURE)
+            	{
+			 goto exit; // there was a problem
+		}
+
+            break;
+        }
+        case PUBCOMP:
+            break;
+        case PINGRESP:
+            c->ping_outstanding = 0;
+	     c->fail_count = 0;
+            break;
+    }
+
+exit:
+    if (rc == SUCCESS)
+        rc = packet_type;
+
+;
+    return rc;
+}
+
+
+int MQTTYield(Client* c, int timeout_ms)
+{
+    int rc = SUCCESS;
+    Timer timer;
+
+    InitTimer(&timer);    
+    countdown_ms(&timer, timeout_ms);
+    static int i = 0;
+    if (c->isconnected)
+    		rc = keepalive(c);
+    if(rc < 0)
+    {
+        return rc;
+    }
+/*
+    while (!expired(&timer))
+    {
+    	 rc = cycle(c, &timer);
+        if (rc == DISCONNECTED)
+        {
+            printf("cycle DISCONNECTED \n");
+            break;
+        }
+	 rc = SUCCESS;
+    }
+*/
+    do
+    {
+            if (expired(&timer)) 
+            break; // we timed out
+    }
+    while ((rc = cycle(c, &timer)) != PUBLISH);  
+    rc = SUCCESS;
+    return rc;
+}
+
+
+// only used in single-threaded mode where one command at a time is in process
+int waitfor(Client* c, int packet_type, Timer* timer)
+{
+    int rc = FAILURE;
+    do
+    {
+            if (expired(timer)) 
+            break; // we timed out
+    }
+    while ((rc = cycle(c, timer)) != packet_type &&  (rc = cycle(c, timer)) != DISCONNECTED);  
+    
+    return rc;
+}
+
+
+int MQTTConnect(Client* c, MQTTPacket_connectData* options)
+{
+    Timer connect_timer;
+    int rc = FAILURE;
+    MQTTPacket_connectData default_options = MQTTPacket_connectData_initializer;
+    int len = 0;
+    InitTimer(&connect_timer);
+    countdown_ms(&connect_timer, c->command_timeout_ms);
+
+    if (c->isconnected) // don't send connect packet again if we are already connected
+        goto exit;
+
+    if (options == 0)
+        options = &default_options; // set default options if none were supplied
+    
+    c->keepAliveInterval = options->keepAliveInterval;
+    countdown(&c->ping_timer, c->keepAliveInterval);
+    printf("[%s]c->keepAliveInterval = %d", __FUNCTION__,c->keepAliveInterval);
+    if ((len = MQTTSerialize_connect(c->buf, c->buf_size, options)) <= 0)
+        goto exit;
+    if ((rc = sendPacket(c, len, &connect_timer)) != SUCCESS)  // send the connect packet
+        goto exit; // there was a problem
+    
+    // this will be a blocking call, wait for the connack
+    if (waitfor(c, CONNACK, &connect_timer) == CONNACK)
+    {
+        unsigned char connack_rc = 255;
+        char sessionPresent = 0;
+        if (MQTTDeserialize_connack((unsigned char*)&sessionPresent, &connack_rc, c->readbuf, c->readbuf_size) == 1)
+            rc = connack_rc;
+        else
+            rc = FAILURE;
+    }
+    else
+        rc = FAILURE;
+    
+exit:
+    if (rc == SUCCESS)
+        c->isconnected = 1;
+    return rc;
+}
+
+
+int MQTTSubscribe(Client* c, const char* topicFilter, enum QoS qos, messageHandler messageHandler)
+{ 
+    int rc = FAILURE;  
+    Timer timer;
+    int len = 0;
+    MQTTString topic = MQTTString_initializer;
+    topic.cstring = (char *)topicFilter;
+    
+    InitTimer(&timer);
+    countdown_ms(&timer, c->command_timeout_ms);
+
+    if (!c->isconnected)
+        goto exit;
+    
+    len = MQTTSerialize_subscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic, (int*)&qos);
+    if (len <= 0)
+        goto exit;
+    if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
+        goto exit;             // there was a problem
+    
+    if (waitfor(c, SUBACK, &timer) == SUBACK)      // wait for suback 
+    {
+        int count = 0, grantedQoS = -1;
+        unsigned short mypacketid;
+        if (MQTTDeserialize_suback(&mypacketid, 1, &count, &grantedQoS, c->readbuf, c->readbuf_size) == 1)
+            rc = grantedQoS; // 0, 1, 2 or 0x80 
+        if (rc != 0x80)
+        {
+            int i;
+            for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+            {
+                if (c->messageHandlers[i].topicFilter == 0)
+                {
+                    c->messageHandlers[i].topicFilter = topicFilter;
+                    c->messageHandlers[i].fp = messageHandler;
+                    rc = 0;
+                    break;
+                }
+            }
+        }
+    }
+    else 
+        rc = FAILURE;
+        
+exit:
+    return rc;
+}
+
+int messageHandlersFindIndex(Client* c, const char* topicFilter)
+{
+    int i;
+    for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+    {
+        if ((c->messageHandlers[i].topicFilter != NULL)
+            && (strcmp(c->messageHandlers[i].topicFilter, topicFilter) == 0))
+        {
+            return i;
+        }
+    }
+    return -1;
+}
+
+int MQTTUnsubscribe(Client* c, const char* topicFilter)
+{   
+    int rc = FAILURE;
+    Timer timer;    
+    MQTTString topic = MQTTString_initializer;
+    topic.cstring = (char *)topicFilter;
+    int len = 0;
+
+    InitTimer(&timer);
+    countdown_ms(&timer, c->command_timeout_ms);
+    
+    if (!c->isconnected)
+        goto exit;
+    if(messageHandlersFindIndex(c,topicFilter) < 0)
+    {
+        printf("This topic is not subscribed and cannot be unsubscribed.\n");
+        goto exit;
+    }
+    if ((len = MQTTSerialize_unsubscribe(c->buf, c->buf_size, 0, getNextPacketId(c), 1, &topic)) <= 0)
+        goto exit;
+    if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
+        goto exit; // there was a problem
+    if (waitfor(c, UNSUBACK, &timer) == UNSUBACK)
+    {
+        unsigned short mypacketid;  // should be the same as the packetid above
+        if (MQTTDeserialize_unsuback(&mypacketid, c->readbuf, c->readbuf_size) == 1)
+        {
+            int i;
+            for (i = 0; i < MAX_MESSAGE_HANDLERS; ++i)
+            {
+                if ((c->messageHandlers[i].topicFilter != NULL)
+                && (strcmp(c->messageHandlers[i].topicFilter, topicFilter) == 0))
+                {
+                    c->messageHandlers[i].topicFilter=NULL;
+                    rc = 0; 
+                }
+            }
+        }
+    }
+    else
+        rc = FAILURE;
+    
+exit:
+    return rc;
+}
+
+
+int MQTTPublish(Client* c, const char* topicName, MQTTMessage* message)
+{
+    int rc = FAILURE;
+    Timer timer;   
+    MQTTString topic = MQTTString_initializer;
+    topic.cstring = (char *)topicName;
+    int len = 0;
+
+    InitTimer(&timer);
+    countdown_ms(&timer, c->command_timeout_ms);
+    
+    if (!c->isconnected)
+        goto exit;
+    if (message->qos == QOS1 || message->qos == QOS2)
+        message->id = getNextPacketId(c);
+    
+    len = MQTTSerialize_publish(c->buf, c->buf_size, 0, message->qos, message->retained, message->id, 
+              topic, (unsigned char*)message->payload, message->payloadlen);
+
+    if (len <= 0)
+        goto exit;
+    if ((rc = sendPacket(c, len, &timer)) != SUCCESS) // send the subscribe packet
+        goto exit; // there was a problem
+
+    if (message->qos == QOS1)
+    {
+        if (waitfor(c, PUBACK, &timer) == PUBACK)
+        {
+            unsigned short mypacketid;
+            unsigned char dup, type;
+            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
+                rc = FAILURE;
+        }
+        else
+            rc = FAILURE;
+    }
+    else if (message->qos == QOS2)
+    {
+        if (waitfor(c, PUBCOMP, &timer) == PUBCOMP)
+        {
+            unsigned short mypacketid;
+            unsigned char dup, type;
+            if (MQTTDeserialize_ack(&type, &dup, &mypacketid, c->readbuf, c->readbuf_size) != 1)
+                rc = FAILURE;
+        }
+        else
+            rc = FAILURE;
+    }
+    
+exit:
+    return rc;
+}
+
+
+int MQTTDisconnect(Client* c ,Network * n)
+{  
+    int rc = FAILURE;
+    Timer timer;     // we might wait for incomplete incoming publishes to complete
+    int len = MQTTSerialize_disconnect(c->buf, c->buf_size);
+
+    InitTimer(&timer);
+    countdown_ms(&timer, c->command_timeout_ms);
+
+    if (len > 0)
+        rc = sendPacket(c, len, &timer);            // send the disconnect packet
+        
+    c->isconnected = 0;
+    n->disconnect(n);
+    return rc;
+}
+
diff --git a/mbtk/mbtk_mqtt/MQTTClient.h b/mbtk/mbtk_mqtt/MQTTClient.h
new file mode 100755
index 0000000..890a11b
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTClient.h
@@ -0,0 +1,100 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Allan Stockdill-Mander/Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#ifndef __MQTT_CLIENT_C_

+#define __MQTT_CLIENT_C_

+

+#include "MQTTPacket.h"

+#include "stdio.h"

+#include "MQTTLinux.h" 

+

+#define MAX_PACKET_ID 65535

+#define MAX_MESSAGE_HANDLERS 5

+#define MAX_FAIL_ALLOWED  2

+

+enum QoS { QOS0, QOS1, QOS2 };

+

+// all failure return codes must be negative

+enum returnCode {DISCONNECTED = -3,  BUFFER_OVERFLOW = -2, FAILURE = -1, SUCCESS = 0 };

+

+void NewTimer(Timer*);

+

+typedef struct MQTTMessage MQTTMessage;

+

+typedef struct MessageData MessageData;

+

+struct MQTTMessage

+{

+    enum QoS qos;

+    char retained;

+    char dup;

+    unsigned short id;

+    void *payload;

+    size_t payloadlen;

+};

+

+struct MessageData

+{

+    MQTTMessage* message;

+    MQTTString* topicName;

+};

+

+typedef struct {

+    char clientId[255];

+    char deviceToken[255];

+} regnwl_info_t;

+

+typedef void (*messageHandler)(MessageData*);

+

+typedef struct Client Client;

+

+int MQTTConnect (Client*, MQTTPacket_connectData*);

+int MQTTPublish (Client*, const char*, MQTTMessage*);

+int MQTTSubscribe (Client*, const char*, enum QoS, messageHandler);

+int MQTTUnsubscribe (Client*, const char*);

+int MQTTDisconnect (Client*,Network*);

+int MQTTYield (Client*, int);

+

+void setDefaultMessageHandler(Client*, messageHandler);

+

+void MQTTClient(Client*, Network*, unsigned int, unsigned char*, size_t, unsigned char*, size_t);

+

+struct Client {

+    unsigned int next_packetid;

+    unsigned int command_timeout_ms;

+    size_t buf_size, readbuf_size;

+    unsigned char *buf;  

+    unsigned char *readbuf; 

+    unsigned int keepAliveInterval;

+    char ping_outstanding;

+    int fail_count;

+    int isconnected;

+

+    struct MessageHandlers

+    {

+        const char* topicFilter;

+        void (*fp) (MessageData*);

+    } messageHandlers[MAX_MESSAGE_HANDLERS];      // Message handlers are indexed by subscription topic

+    

+    void (*defaultMessageHandler) (MessageData*);

+    

+    Network* ipstack;

+    Timer ping_timer;

+};

+

+#define DefaultClient {0, 0, 0, 0, NULL, NULL, 0, 0, 0}

+

+#endif

diff --git a/mbtk/mbtk_mqtt/MQTTLinux.c b/mbtk/mbtk_mqtt/MQTTLinux.c
new file mode 100755
index 0000000..cdfd548
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTLinux.c
@@ -0,0 +1,204 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Allan Stockdill-Mander - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+// #include <openssl/ssl.h>

+// #include <openssl/err.h>

+#include "MQTTLinux.h"

+//#include "global.h"

+//#include "DC_iot_port.h"

+#include "mbtk_sock2.h"

+#define TIMEOUT 60*1000

+

+char expired(Timer* timer)

+{

+	struct timeval now, res;

+	gettimeofday(&now, NULL);

+	timersub(&timer->end_time, &now, &res);

+	return res.tv_sec < 0 || (res.tv_sec == 0 && res.tv_usec <= 0);

+}

+

+

+void countdown_ms(Timer* timer, unsigned int timeout)

+{

+	struct timeval now;

+	gettimeofday(&now, NULL);

+	struct timeval interval = {timeout / 1000, (timeout % 1000) * 1000};

+	timeradd(&now, &interval, &timer->end_time);

+}

+

+

+void countdown(Timer* timer, unsigned int timeout)

+{

+	struct timeval now;

+	gettimeofday(&now, NULL);

+	struct timeval interval = {timeout, 0};

+	timeradd(&now, &interval, &timer->end_time);

+}

+

+

+int left_ms(Timer* timer)

+{

+	struct timeval now, res;

+	gettimeofday(&now, NULL);

+	timersub(&timer->end_time, &now, &res);

+	//printf("left %d ms\n", (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000);

+	return (res.tv_sec < 0) ? 0 : res.tv_sec * 1000 + res.tv_usec / 1000;

+}

+

+

+void InitTimer(Timer* timer)

+{

+	timer->end_time = (struct timeval){0, 0};

+}

+

+

+int linux_read(Network* n, unsigned char* buffer, int len, int timeout_ms)

+{

+

+    int err;

+    int read_len = mbtk_sock_read(n->handle,n->my_socket, buffer, len, TIMEOUT, &err);

+    if(read_len < 0) {

+        if(err == MBTK_SOCK_ETIMEOUT) {

+            return -2;

+        } else {

+            return -1;

+        }

+    } else {

+        return read_len;

+    }

+

+

+

+#if 0

+

+	struct timeval interval = {timeout_ms / 1000, (timeout_ms % 1000) * 1000};

+	//mDEBUG("[%s]timeout_ms = %d \n", __FUNCTION__, timeout_ms);

+	if (interval.tv_sec < 0 || (interval.tv_sec == 0 && interval.tv_usec <= 0))

+	{

+		interval.tv_sec = 0;

+		interval.tv_usec = 100;

+	}

+

+	setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&interval, sizeof(struct timeval));

+

+	int bytes = 0;

+	while (bytes < len)

+	{

+

+		int rc = recv(n->my_socket, &buffer[bytes], (size_t)(len - bytes), 0);

+		//mDEBUG("[%s]socket recv rc = %d \n", __FUNCTION__, rc);

+

+		if(rc == 0)

+		{

+			 //mDEBUG("[%s]socket close \n", __FUNCTION__);

+			 bytes = 0;

+			 break;

+		}

+		

+		if (rc == -1)

+		{

+			if (errno != ENOTCONN && errno != ECONNRESET)

+			{

+				bytes = -1;

+				break;

+			}

+		}

+		else

+			bytes += rc;

+	}

+	return bytes;

+#endif

+}

+

+

+int linux_write(Network* n, unsigned char* buffer, int len, int timeout_ms)

+{

+

+    int err;

+    printf("Write[%d]:%s",len,(char*)buffer);

+    return mbtk_sock_write(n->handle, n->my_socket, buffer, len, TIMEOUT, &err);

+

+#if 0

+	struct timeval tv;

+

+	tv.tv_sec = 0;  /* 30 Secs Timeout */

+	tv.tv_usec = timeout_ms * 1000;  // Not init'ing this can cause strange errors

+

+	setsockopt(n->my_socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv,sizeof(struct timeval));

+

+	int	rc = write(n->my_socket, buffer, len);

+

+	return rc;

+#endif

+}

+

+

+void linux_disconnect(Network* n)

+{

+    int errno;

+    mbtk_sock_close(n->handle,n->my_socket,TIMEOUT,&errno);

+}

+

+

+void NewNetwork(Network* n)

+{

+

+	n->my_socket = 0;

+	n->mqttread = linux_read;

+	n->mqttwrite = linux_write;

+	n->disconnect = linux_disconnect;

+    n->ingnore_cert = true;

+    n->is_support_ssl = false;

+}

+

+

+int ConnectNetwork(Network* n, char* addr, int port, bool is_support_ssl, bool ingnore_cert)

+{

+    mbtk_init_info *info ;

+    mbtk_sock_info *sock_info;

+    int rc = 0;

+    int errno;

+    info = NULL;

+    sock_info = (mbtk_sock_info *)malloc(sizeof(mbtk_sock_info));

+    if(sock_info ==NULL)

+    {

+        rc = -1;

+        return rc;

+    }

+    memcpy(sock_info->address, addr, strlen(addr));

+    sock_info->port = port;

+    sock_info->is_support_ssl = is_support_ssl;

+    sock_info->ingnore_cert = ingnore_cert;

+

+    printf("host %s\nport %d\nis_support_ssl %d\ningnore_cert %d\n",sock_info->address,sock_info->port,sock_info->is_support_ssl,sock_info->ingnore_cert);

+

+	mbtk_sock_handle handle = mbtk_sock_init(info);

+    if (handle < 0 )

+    {

+        rc = -1;

+        return rc;

+    }

+

+    int fd  = mbtk_sock_open(handle, sock_info, TIMEOUT, &errno);

+    if(fd < 0)

+    {

+        rc = -1;

+        return rc;

+    }

+

+    n->my_socket = fd;

+    n->handle = handle;

+	return rc;

+}

diff --git a/mbtk/mbtk_mqtt/MQTTLinux.h b/mbtk/mbtk_mqtt/MQTTLinux.h
new file mode 100755
index 0000000..6ca888a
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTLinux.h
@@ -0,0 +1,74 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Allan Stockdill-Mander - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#ifndef __MQTT_LINUX_

+#define __MQTT_LINUX_

+

+#include <sys/types.h>

+#include <sys/socket.h>

+#include <sys/param.h>

+#include <sys/time.h>

+#include <sys/select.h>

+#include <netinet/in.h>

+#include <netinet/tcp.h>

+#include <arpa/inet.h>

+#include <netdb.h>

+#include <stdio.h>

+#include <unistd.h>

+#include <errno.h>

+#include <fcntl.h>

+#include <stdbool.h>

+#include <stdlib.h>

+#include <string.h>

+#include <signal.h>

+

+// #include <openssl/ssl.h>

+// #include <openssl/err.h>

+//#include "DC_iot_port.h"

+

+typedef struct Timer Timer;

+

+struct Timer {

+	struct timeval end_time;

+};

+

+typedef struct Network Network;

+struct Network

+{

+	int my_socket;

+    bool is_support_ssl;

+    bool ingnore_cert;

+    int handle;

+	int (*mqttread) (Network*, unsigned char*, int, int);

+	int (*mqttwrite) (Network*, unsigned char*, int, int);

+	void (*disconnect) (Network*);

+};

+

+char expired(Timer*);

+void countdown_ms(Timer*, unsigned int);

+void countdown(Timer*, unsigned int);

+int left_ms(Timer*);

+

+void InitTimer(Timer*);

+

+int linux_read(Network*, unsigned char*, int, int);

+int linux_write(Network*, unsigned char*, int, int);

+void linux_disconnect(Network*);

+void NewNetwork(Network*);

+

+int ConnectNetwork(Network*, char*, int, bool ,bool );

+

+#endif
\ No newline at end of file
diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnect.h b/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnect.h
new file mode 100755
index 0000000..d77f18c
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnect.h
@@ -0,0 +1,136 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *    Xiang Rong - 442039 Add makefile to Embedded C client

+ *******************************************************************************/

+

+#ifndef MQTTCONNECT_H_

+#define MQTTCONNECT_H_

+

+#if !defined(DLLImport)

+  #define DLLImport 

+#endif

+#if !defined(DLLExport)

+  #define DLLExport

+#endif

+

+

+typedef union

+{

+	unsigned char all;	/**< all connect flags */

+#if defined(REVERSED)

+	struct

+	{

+		unsigned int username : 1;			/**< 3.1 user name */

+		unsigned int password : 1; 			/**< 3.1 password */

+		unsigned int willRetain : 1;		/**< will retain setting */

+		unsigned int willQoS : 2;				/**< will QoS value */

+		unsigned int will : 1;			    /**< will flag */

+		unsigned int cleansession : 1;	  /**< clean session flag */

+		unsigned int : 1;	  	          /**< unused */

+	} bits;

+#else

+	struct

+	{

+		unsigned int : 1;	     					/**< unused */

+		unsigned int cleansession : 1;	  /**< cleansession flag */

+		unsigned int will : 1;			    /**< will flag */

+		unsigned int willQoS : 2;				/**< will QoS value */

+		unsigned int willRetain : 1;		/**< will retain setting */

+		unsigned int password : 1; 			/**< 3.1 password */

+		unsigned int username : 1;			/**< 3.1 user name */

+	} bits;

+#endif

+} MQTTConnectFlags;	/**< connect flags byte */

+

+

+

+/**

+ * Defines the MQTT "Last Will and Testament" (LWT) settings for

+ * the connect packet.

+ */

+typedef struct

+{

+	/** The eyecatcher for this structure.  must be MQTW. */

+	char struct_id[4];

+	/** The version number of this structure.  Must be 0 */

+	int struct_version;

+	/** The LWT topic to which the LWT message will be published. */

+	MQTTString topicName;

+	/** The LWT payload. */

+	MQTTString message;

+	/**

+      * The retained flag for the LWT message (see MQTTAsync_message.retained).

+      */

+	unsigned char retained;

+	/**

+      * The quality of service setting for the LWT message (see

+      * MQTTAsync_message.qos and @ref qos).

+      */

+	char qos;

+} MQTTPacket_willOptions;

+

+

+#define MQTTPacket_willOptions_initializer { {'M', 'Q', 'T', 'W'}, 0, {NULL, {0, NULL}}, {NULL, {0, NULL}}, 0, 0 }

+

+

+typedef struct

+{

+	/** The eyecatcher for this structure.  must be MQTC. */

+	char struct_id[4];

+	/** The version number of this structure.  Must be 0 */

+	int struct_version;

+	/** Version of MQTT to be used.  3 = 3.1 4 = 3.1.1

+	  */

+	unsigned char MQTTVersion;

+	MQTTString clientID;

+	unsigned short keepAliveInterval;

+	unsigned char cleansession;

+	unsigned char willFlag;

+	MQTTPacket_willOptions will;

+	MQTTString username;

+	MQTTString password;

+} MQTTPacket_connectData;

+

+typedef union

+{

+	unsigned char all;	/**< all connack flags */

+#if defined(REVERSED)

+	struct

+	{

+		unsigned int sessionpresent : 1;    /**< session present flag */

+		unsigned int : 7;	  	          /**< unused */

+	} bits;

+#else

+	struct

+	{

+		unsigned int : 7;	     			/**< unused */

+		unsigned int sessionpresent : 1;    /**< session present flag */

+	} bits;

+#endif

+} MQTTConnackFlags;	/**< connack flags byte */

+

+#define MQTTPacket_connectData_initializer { {'M', 'Q', 'T', 'C'}, 0, 4, {NULL, {0, NULL}}, 60, 1, 0, \

+		MQTTPacket_willOptions_initializer, {NULL, {0, NULL}}, {NULL, {0, NULL}} }

+

+DLLExport int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options);

+DLLExport int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len);

+

+DLLExport int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent);

+DLLExport int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen);

+

+DLLExport int MQTTSerialize_disconnect(unsigned char* buf, int buflen);

+DLLExport int MQTTSerialize_pingreq(unsigned char* buf, int buflen);

+

+#endif /* MQTTCONNECT_H_ */

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnectClient.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnectClient.c
new file mode 100755
index 0000000..405c23e
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnectClient.c
@@ -0,0 +1,211 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#include "MQTTPacket.h"

+#include "StackTrace.h"

+

+#include <string.h>

+

+/**

+  * Determines the length of the MQTT connect packet that would be produced using the supplied connect options.

+  * @param options the options to be used to build the connect packet

+  * @return the length of buffer needed to contain the serialized version of the packet

+  */

+int MQTTSerialize_connectLength(MQTTPacket_connectData* options)

+{

+	int len = 0;

+

+	FUNC_ENTRY;

+

+	if (options->MQTTVersion == 3)

+		len = 12; /* variable depending on MQTT or MQIsdp */

+	else if (options->MQTTVersion == 4)

+		len = 10;

+

+	len += MQTTstrlen(options->clientID)+2;

+	if (options->willFlag)

+		len += MQTTstrlen(options->will.topicName)+2 + MQTTstrlen(options->will.message)+2;

+	if (options->username.cstring || options->username.lenstring.data)

+		len += MQTTstrlen(options->username)+2;

+	if (options->password.cstring || options->password.lenstring.data)

+		len += MQTTstrlen(options->password)+2;

+

+	FUNC_EXIT_RC(len);

+	return len;

+}

+

+

+/**

+  * Serializes the connect options into the buffer.

+  * @param buf the buffer into which the packet will be serialized

+  * @param len the length in bytes of the supplied buffer

+  * @param options the options to be used to build the connect packet

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_connect(unsigned char* buf, int buflen, MQTTPacket_connectData* options)

+{

+	unsigned char *ptr = buf;

+	MQTTHeader header = {0};

+	MQTTConnectFlags flags = {0};

+	int len = 0;

+	int rc = -1;

+

+	FUNC_ENTRY;

+	if (MQTTPacket_len(len = MQTTSerialize_connectLength(options)) > buflen)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+

+	header.byte = 0;

+	header.bits.type = CONNECT;

+	writeChar(&ptr, header.byte); /* write header */

+	ptr += MQTTPacket_encode(ptr, len); /* write remaining length */

+	if (options->MQTTVersion == 4)

+	{

+		writeCString(&ptr, "MQTT");

+		writeChar(&ptr, (char) 4);

+	}

+	else

+	{

+		writeCString(&ptr, "MQIsdp");

+		writeChar(&ptr, (char) 3);

+	}

+

+	flags.all = 0;

+	flags.bits.cleansession = options->cleansession;

+	flags.bits.will = (options->willFlag) ? 1 : 0;

+	if (flags.bits.will)

+	{

+		flags.bits.willQoS = options->will.qos;

+		flags.bits.willRetain = options->will.retained;

+	}

+

+	if (options->username.cstring || options->username.lenstring.data)

+		flags.bits.username = 1;

+	if (options->password.cstring || options->password.lenstring.data)

+		flags.bits.password = 1;

+	writeChar(&ptr, flags.all);

+	writeInt(&ptr, options->keepAliveInterval);

+	writeMQTTString(&ptr, options->clientID);

+	if (options->willFlag)

+	{

+		writeMQTTString(&ptr, options->will.topicName);

+		writeMQTTString(&ptr, options->will.message);

+	}

+	if (flags.bits.username)

+		writeMQTTString(&ptr, options->username);

+	if (flags.bits.password)

+		writeMQTTString(&ptr, options->password);

+

+	rc = ptr - buf;

+    

+	exit: FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+  * Deserializes the supplied (wire) buffer into connack data - return code

+  * @param sessionPresent the session present flag returned (only for MQTT 3.1.1)

+  * @param connack_rc returned integer value of the connack return code

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param len the length in bytes of the data in the supplied buffer

+  * @return error code.  1 is success, 0 is failure

+  */

+int MQTTDeserialize_connack(unsigned char* sessionPresent, unsigned char* connack_rc, unsigned char* buf, int buflen)

+{

+	MQTTHeader header = {0};

+	unsigned char* curdata = buf;

+	unsigned char* enddata = NULL;

+	int rc = 0;

+	int mylen;

+	MQTTConnackFlags flags = {0};

+

+	FUNC_ENTRY;

+	header.byte = readChar(&curdata);

+	if (header.bits.type != CONNACK)

+		goto exit;

+

+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */

+	enddata = curdata + mylen;

+	if (enddata - curdata < 2)

+		goto exit;

+

+	flags.all = readChar(&curdata);

+	*sessionPresent = flags.bits.sessionpresent;

+	*connack_rc = readChar(&curdata);

+

+	rc = 1;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+  * Serializes a 0-length packet into the supplied buffer, ready for writing to a socket

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer, to avoid overruns

+  * @param packettype the message type

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_zero(unsigned char* buf, int buflen, unsigned char packettype)

+{

+	MQTTHeader header = {0};

+	int rc = -1;

+	unsigned char *ptr = buf;

+

+	FUNC_ENTRY;

+	if (buflen < 2)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+	header.byte = 0;

+	header.bits.type = packettype;

+	writeChar(&ptr, header.byte); /* write header */

+

+	ptr += MQTTPacket_encode(ptr, 0); /* write remaining length */

+	rc = ptr - buf;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+  * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer, to avoid overruns

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_disconnect(unsigned char* buf, int buflen)

+{

+	return MQTTSerialize_zero(buf, buflen, DISCONNECT);

+}

+

+

+/**

+  * Serializes a disconnect packet into the supplied buffer, ready for writing to a socket

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer, to avoid overruns

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_pingreq(unsigned char* buf, int buflen)

+{

+	return MQTTSerialize_zero(buf, buflen, PINGREQ);

+}

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnectServer.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnectServer.c
new file mode 100755
index 0000000..7c1fe50
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTConnectServer.c
@@ -0,0 +1,148 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#include "StackTrace.h"

+#include "MQTTPacket.h"

+#include <string.h>

+

+#define min(a, b) ((a < b) ? a : b)

+

+

+/**

+  * Validates MQTT protocol name and version combinations

+  * @param protocol the MQTT protocol name as an MQTTString

+  * @param version the MQTT protocol version number, as in the connect packet

+  * @return correct MQTT combination?  1 is true, 0 is false

+  */

+int MQTTPacket_checkVersion(MQTTString* protocol, int version)

+{

+	int rc = 0;

+

+	if (version == 3 && memcmp(protocol->lenstring.data, "MQIsdp",

+			min(6, protocol->lenstring.len)) == 0)

+		rc = 1;

+	else if (version == 4 && memcmp(protocol->lenstring.data, "MQTT",

+			min(4, protocol->lenstring.len)) == 0)

+		rc = 1;

+	return rc;

+}

+

+

+/**

+  * Deserializes the supplied (wire) buffer into connect data structure

+  * @param data the connect data structure to be filled out

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param len the length in bytes of the data in the supplied buffer

+  * @return error code.  1 is success, 0 is failure

+  */

+int MQTTDeserialize_connect(MQTTPacket_connectData* data, unsigned char* buf, int len)

+{

+	MQTTHeader header = {0};

+	MQTTConnectFlags flags = {0};

+	unsigned char* curdata = buf;

+	unsigned char* enddata = &buf[len];

+	int rc = 0;

+	MQTTString Protocol;

+	int version;

+	int mylen = 0;

+

+	FUNC_ENTRY;

+	header.byte = readChar(&curdata);

+	if (header.bits.type != CONNECT)

+		goto exit;

+

+	curdata += MQTTPacket_decodeBuf(curdata, &mylen); /* read remaining length */

+

+	if (!readMQTTLenString(&Protocol, &curdata, enddata) ||

+		enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */

+		goto exit;

+

+	version = (int)readChar(&curdata); /* Protocol version */

+	/* If we don't recognize the protocol version, we don't parse the connect packet on the

+	 * basis that we don't know what the format will be.

+	 */

+	if (MQTTPacket_checkVersion(&Protocol, version))

+	{

+		flags.all = readChar(&curdata);

+		data->cleansession = flags.bits.cleansession;

+		data->keepAliveInterval = readInt(&curdata);

+		if (!readMQTTLenString(&data->clientID, &curdata, enddata))

+			goto exit;

+		data->willFlag = flags.bits.will;

+		if (flags.bits.will)

+		{

+			data->will.qos = flags.bits.willQoS;

+			data->will.retained = flags.bits.willRetain;

+			if (!readMQTTLenString(&data->will.topicName, &curdata, enddata) ||

+				  !readMQTTLenString(&data->will.message, &curdata, enddata))

+				goto exit;

+		}

+		if (flags.bits.username)

+		{

+			if (enddata - curdata < 3 || !readMQTTLenString(&data->username, &curdata, enddata))

+				goto exit; /* username flag set, but no username supplied - invalid */

+			if (flags.bits.password &&

+				(enddata - curdata < 3 || !readMQTTLenString(&data->password, &curdata, enddata)))

+				goto exit; /* password flag set, but no password supplied - invalid */

+		}

+		else if (flags.bits.password)

+			goto exit; /* password flag set without username - invalid */

+		rc = 1;

+	}

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+  * Serializes the connack packet into the supplied buffer.

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer

+  * @param connack_rc the integer connack return code to be used 

+  * @param sessionPresent the MQTT 3.1.1 sessionPresent flag

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_connack(unsigned char* buf, int buflen, unsigned char connack_rc, unsigned char sessionPresent)

+{

+	MQTTHeader header = {0};

+	int rc = 0;

+	unsigned char *ptr = buf;

+	MQTTConnackFlags flags = {0};

+

+	FUNC_ENTRY;

+	if (buflen < 2)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+	header.byte = 0;

+	header.bits.type = CONNACK;

+	writeChar(&ptr, header.byte); /* write header */

+

+	ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */

+

+	flags.all = 0;

+	flags.bits.sessionpresent = sessionPresent;

+	writeChar(&ptr, flags.all); 

+	writeChar(&ptr, connack_rc);

+

+	rc = ptr - buf;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTDeserializePublish.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTDeserializePublish.c
new file mode 100755
index 0000000..dbc9e5d
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTDeserializePublish.c
@@ -0,0 +1,107 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#include "StackTrace.h"

+#include "MQTTPacket.h"

+#include <string.h>

+

+#define min(a, b) ((a < b) ? 1 : 0)

+

+/**

+  * Deserializes the supplied (wire) buffer into publish data

+  * @param dup returned integer - the MQTT dup flag

+  * @param qos returned integer - the MQTT QoS value

+  * @param retained returned integer - the MQTT retained flag

+  * @param packetid returned integer - the MQTT packet identifier

+  * @param topicName returned MQTTString - the MQTT topic in the publish

+  * @param payload returned byte buffer - the MQTT publish payload

+  * @param payloadlen returned integer - the length of the MQTT payload

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param buflen the length in bytes of the data in the supplied buffer

+  * @return error code.  1 is success

+  */

+int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,

+		unsigned char** payload, int* payloadlen, unsigned char* buf, int buflen)

+{

+	MQTTHeader header = {0};

+	unsigned char* curdata = buf;

+	unsigned char* enddata = NULL;

+	int rc = 0;

+	int mylen = 0;

+

+	FUNC_ENTRY;

+	header.byte = readChar(&curdata);

+	if (header.bits.type != PUBLISH)

+		goto exit;

+	*dup = header.bits.dup;

+	*qos = header.bits.qos;

+	*retained = header.bits.retain;

+

+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */

+	enddata = curdata + mylen;

+

+	if (!readMQTTLenString(topicName, &curdata, enddata) ||

+		enddata - curdata < 0) /* do we have enough data to read the protocol version byte? */

+		goto exit;

+

+	if (*qos > 0)

+		*packetid = readInt(&curdata);

+

+	*payloadlen = enddata - curdata;

+	*payload = curdata;

+	rc = 1;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+

+/**

+  * Deserializes the supplied (wire) buffer into an ack

+  * @param packettype returned integer - the MQTT packet type

+  * @param dup returned integer - the MQTT dup flag

+  * @param packetid returned integer - the MQTT packet identifier

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param buflen the length in bytes of the data in the supplied buffer

+  * @return error code.  1 is success, 0 is failure

+  */

+int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen)

+{

+	MQTTHeader header = {0};

+	unsigned char* curdata = buf;

+	unsigned char* enddata = NULL;

+	int rc = 0;

+	int mylen;

+

+	FUNC_ENTRY;

+	header.byte = readChar(&curdata);

+	*dup = header.bits.dup;

+	*packettype = header.bits.type;

+

+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */

+	enddata = curdata + mylen;

+

+	if (enddata - curdata < 2)

+		goto exit;

+	*packetid = readInt(&curdata);

+

+	rc = 1;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTFormat.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTFormat.c
new file mode 100755
index 0000000..3015a0e
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTFormat.c
@@ -0,0 +1,258 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#include "StackTrace.h"

+#include "MQTTPacket.h"

+

+#include <string.h>

+

+

+const char* MQTTPacket_names[] =

+{

+	"RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",

+	"PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",

+	"PINGREQ", "PINGRESP", "DISCONNECT"

+};

+

+

+const char* MQTTPacket_getName(unsigned short packetid)

+{

+	return MQTTPacket_names[packetid];

+}

+

+

+int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data)

+{

+	int strindex = 0;

+

+	strindex = snprintf(strbuf, strbuflen,

+			"CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",

+			(int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,

+			(int)data->cleansession, data->keepAliveInterval);

+	if (data->willFlag)

+		strindex += snprintf(&strbuf[strindex], strbuflen - strindex,

+				", will QoS %d, will retain %d, will topic %.*s, will message %.*s",

+				data->will.qos, data->will.retained,

+				data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,

+				data->will.message.lenstring.len, data->will.message.lenstring.data);

+	if (data->username.lenstring.data && data->username.lenstring.len > 0)

+		strindex += snprintf(&strbuf[strindex], strbuflen - strindex,

+				", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);

+	if (data->password.lenstring.data && data->password.lenstring.len > 0)

+		strindex += snprintf(&strbuf[strindex], strbuflen - strindex,

+				", password %.*s", data->password.lenstring.len, data->password.lenstring.data);

+	return strindex;

+}

+

+

+int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent)

+{

+	int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);

+	return strindex;

+}

+

+

+int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,

+		unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen)

+{

+	int strindex = snprintf(strbuf, strbuflen,

+				"PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",

+				dup, qos, retained, packetid,

+				(topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,

+				payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);

+	return strindex;

+}

+

+

+int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid)

+{

+	int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);

+	if (dup)

+		strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);

+	return strindex;

+}

+

+

+int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,

+		MQTTString topicFilters[], int requestedQoSs[])

+{

+	return snprintf(strbuf, strbuflen,

+		"SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",

+		dup, packetid, count,

+		topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,

+		requestedQoSs[0]);

+}

+

+

+int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs)

+{

+	return snprintf(strbuf, strbuflen,

+		"SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);

+}

+

+

+int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,

+		int count, MQTTString topicFilters[])

+{

+	return snprintf(strbuf, strbuflen,

+					"UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",

+					dup, packetid, count,

+					topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);

+}

+

+

+char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)

+{

+	int index = 0;

+	int rem_length = 0;

+	MQTTHeader header = {0};

+	int strindex = 0;

+

+	header.byte = buf[index++];

+	index += MQTTPacket_decodeBuf(&buf[index], &rem_length);

+

+	switch (header.bits.type)

+	{

+	case CONNACK:

+	{

+		unsigned char sessionPresent, connack_rc;

+		if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)

+			strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);

+	}

+	break;

+	case PUBLISH:

+	{

+		unsigned char dup, retained, *payload;

+		unsigned short packetid;

+		int qos, payloadlen;

+		MQTTString topicName = MQTTString_initializer;

+		if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,

+				&payload, &payloadlen, buf, buflen) == 1)

+			strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,

+					topicName, payload, payloadlen);

+	}

+	break;

+	case PUBACK:

+	case PUBREC:

+	case PUBREL:

+	case PUBCOMP:

+	{

+		unsigned char packettype, dup;

+		unsigned short packetid;

+		if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)

+			strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);

+	}

+	break;

+	case SUBACK:

+	{

+		unsigned short packetid;

+		int maxcount = 1, count = 0;

+		int grantedQoSs[1];

+		if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)

+			strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);

+	}

+	break;

+	case UNSUBACK:

+	{

+		unsigned short packetid;

+		if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)

+			strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);

+	}

+	break;

+	case PINGREQ:

+	case PINGRESP:

+	case DISCONNECT:

+		strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);

+		break;

+	}

+	return strbuf;

+}

+

+

+char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)

+{

+	int index = 0;

+	int rem_length = 0;

+	MQTTHeader header = {0};

+	int strindex = 0;

+

+	header.byte = buf[index++];

+	index += MQTTPacket_decodeBuf(&buf[index], &rem_length);

+

+	switch (header.bits.type)

+	{

+	case CONNECT:

+	{

+		MQTTPacket_connectData data;

+		int rc;

+		if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1)

+			strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data);

+	}

+	break;

+	case PUBLISH:

+	{

+		unsigned char dup, retained, *payload;

+		unsigned short packetid;

+		int qos, payloadlen;

+		MQTTString topicName = MQTTString_initializer;

+		if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,

+				&payload, &payloadlen, buf, buflen) == 1)

+			strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,

+					topicName, payload, payloadlen);

+	}

+	break;

+	case PUBACK:

+	case PUBREC:

+	case PUBREL:

+	case PUBCOMP:

+	{

+		unsigned char packettype, dup;

+		unsigned short packetid;

+		if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)

+			strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);

+	}

+	break;

+	case SUBSCRIBE:

+	{

+		unsigned char dup;

+		unsigned short packetid;

+		int maxcount = 1, count = 0;

+		MQTTString topicFilters[1];

+		int requestedQoSs[1];

+		if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,

+				topicFilters, requestedQoSs, buf, buflen) == 1)

+			strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;

+	}

+	break;

+	case UNSUBSCRIBE:

+	{

+		unsigned char dup;

+		unsigned short packetid;

+		int maxcount = 1, count = 0;

+		MQTTString topicFilters[1];

+		if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)

+			strindex =  MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);

+	}

+	break;

+	case PINGREQ:

+	case PINGRESP:

+	case DISCONNECT:

+		strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);

+		break;

+	}

+	strbuf[strbuflen] = '\0';

+	return strbuf;

+}

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTFormat.h b/mbtk/mbtk_mqtt/MQTTPacket/MQTTFormat.h
new file mode 100755
index 0000000..f7bd0d1
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTFormat.h
@@ -0,0 +1,37 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#if !defined(MQTTFORMAT_H)

+#define MQTTFORMAT_H

+

+#include "StackTrace.h"

+#include "MQTTPacket.h"

+

+const char* MQTTPacket_getName(unsigned short packetid);

+int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data);

+int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent);

+int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,

+		unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen);

+int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid);

+int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,

+		MQTTString topicFilters[], int requestedQoSs[]);

+int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs);

+int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,

+		int count, MQTTString topicFilters[]);

+char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);

+char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen);

+

+#endif

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTPacket.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTPacket.c
new file mode 100755
index 0000000..c100f55
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTPacket.c
@@ -0,0 +1,410 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *    Sergio R. Caprile - non-blocking packet read functions for stream transport

+ *******************************************************************************/

+

+#include "StackTrace.h"

+#include "MQTTPacket.h"

+

+#include <string.h>

+

+/**

+ * Encodes the message length according to the MQTT algorithm

+ * @param buf the buffer into which the encoded data is written

+ * @param length the length to be encoded

+ * @return the number of bytes written to buffer

+ */

+int MQTTPacket_encode(unsigned char* buf, int length)

+{

+	int rc = 0;

+

+	FUNC_ENTRY;

+	do

+	{

+		char d = length % 128;

+		length /= 128;

+		/* if there are more digits to encode, set the top bit of this digit */

+		if (length > 0)

+			d |= 0x80;

+		buf[rc++] = d;

+	} while (length > 0);

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+ * Decodes the message length according to the MQTT algorithm

+ * @param getcharfn pointer to function to read the next character from the data source

+ * @param value the decoded length returned

+ * @return the number of bytes read from the socket

+ */

+int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value)

+{

+	unsigned char c;

+	int multiplier = 1;

+	int len = 0;

+#define MAX_NO_OF_REMAINING_LENGTH_BYTES 4

+

+	FUNC_ENTRY;

+	*value = 0;

+	do

+	{

+		int rc = MQTTPACKET_READ_ERROR;

+

+		if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES)

+		{

+			rc = MQTTPACKET_READ_ERROR;	/* bad data */

+			goto exit;

+		}

+		rc = (*getcharfn)(&c, 1);

+		if (rc != 1)

+			goto exit;

+		*value += (c & 127) * multiplier;

+		multiplier *= 128;

+	} while ((c & 128) != 0);

+exit:

+	FUNC_EXIT_RC(len);

+	return len;

+}

+

+

+int MQTTPacket_len(int rem_len)

+{

+	rem_len += 1; /* header byte */

+

+	/* now remaining_length field */

+	if (rem_len < 128)

+		rem_len += 1;

+	else if (rem_len < 16384)

+		rem_len += 2;

+	else if (rem_len < 2097151)

+		rem_len += 3;

+	else

+		rem_len += 4;

+	return rem_len;

+}

+

+

+static unsigned char* bufptr;

+

+int bufchar(unsigned char* c, int count)

+{

+	int i;

+

+	for (i = 0; i < count; ++i)

+		*c = *bufptr++;

+	return count;

+}

+

+

+int MQTTPacket_decodeBuf(unsigned char* buf, int* value)

+{

+	bufptr = buf;

+	return MQTTPacket_decode(bufchar, value);

+}

+

+

+/**

+ * Calculates an integer from two bytes read from the input buffer

+ * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned

+ * @return the integer value calculated

+ */

+int readInt(unsigned char** pptr)

+{

+	unsigned char* ptr = *pptr;

+	int len = 256*(*ptr) + (*(ptr+1));

+	*pptr += 2;

+	return len;

+}

+

+

+/**

+ * Reads one character from the input buffer.

+ * @param pptr pointer to the input buffer - incremented by the number of bytes used & returned

+ * @return the character read

+ */

+char readChar(unsigned char** pptr)

+{

+	char c = **pptr;

+	(*pptr)++;

+	return c;

+}

+

+

+/**

+ * Writes one character to an output buffer.

+ * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned

+ * @param c the character to write

+ */

+void writeChar(unsigned char** pptr, char c)

+{

+	**pptr = c;

+	(*pptr)++;

+}

+

+

+/**

+ * Writes an integer as 2 bytes to an output buffer.

+ * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned

+ * @param anInt the integer to write

+ */

+void writeInt(unsigned char** pptr, int anInt)

+{

+	**pptr = (unsigned char)(anInt / 256);

+	(*pptr)++;

+	**pptr = (unsigned char)(anInt % 256);

+	(*pptr)++;

+}

+

+

+/**

+ * Writes a "UTF" string to an output buffer.  Converts C string to length-delimited.

+ * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned

+ * @param string the C string to write

+ */

+void writeCString(unsigned char** pptr, const char* string)

+{

+	int len = strlen(string);

+	writeInt(pptr, len);

+	memcpy(*pptr, string, len);

+	*pptr += len;

+}

+

+

+int getLenStringLen(char* ptr)

+{

+	int len = 256*((unsigned char)(*ptr)) + (unsigned char)(*(ptr+1));

+	return len;

+}

+

+

+void writeMQTTString(unsigned char** pptr, MQTTString mqttstring)

+{

+	if (mqttstring.lenstring.len > 0)

+	{

+		writeInt(pptr, mqttstring.lenstring.len);

+		memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len);

+		*pptr += mqttstring.lenstring.len;

+	}

+	else if (mqttstring.cstring)

+		writeCString(pptr, mqttstring.cstring);

+	else

+		writeInt(pptr, 0);

+}

+

+

+/**

+ * @param mqttstring the MQTTString structure into which the data is to be read

+ * @param pptr pointer to the output buffer - incremented by the number of bytes used & returned

+ * @param enddata pointer to the end of the data: do not read beyond

+ * @return 1 if successful, 0 if not

+ */

+int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata)

+{

+	int rc = 0;

+

+	FUNC_ENTRY;

+	/* the first two bytes are the length of the string */

+	if (enddata - (*pptr) > 1) /* enough length to read the integer? */

+	{

+		mqttstring->lenstring.len = readInt(pptr); /* increments pptr to point past length */

+		if (&(*pptr)[mqttstring->lenstring.len] <= enddata)

+		{

+			mqttstring->lenstring.data = (char*)*pptr;

+			*pptr += mqttstring->lenstring.len;

+			rc = 1;

+		}

+	}

+	mqttstring->cstring = NULL;

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+ * Return the length of the MQTTstring - C string if there is one, otherwise the length delimited string

+ * @param mqttstring the string to return the length of

+ * @return the length of the string

+ */

+int MQTTstrlen(MQTTString mqttstring)

+{

+	int rc = 0;

+

+	if (mqttstring.cstring)

+		rc = strlen(mqttstring.cstring);

+	else

+		rc = mqttstring.lenstring.len;

+	return rc;

+}

+

+

+/**

+ * Compares an MQTTString to a C string

+ * @param a the MQTTString to compare

+ * @param bptr the C string to compare

+ * @return boolean - equal or not

+ */

+int MQTTPacket_equals(MQTTString* a, char* bptr)

+{

+	int alen = 0,

+		blen = 0;

+	char *aptr;

+	

+	if (a->cstring)

+	{

+		aptr = a->cstring;

+		alen = strlen(a->cstring);

+	}

+	else

+	{

+		aptr = a->lenstring.data;

+		alen = a->lenstring.len;

+	}

+	blen = strlen(bptr);

+	

+	return (alen == blen) && (strncmp(aptr, bptr, alen) == 0);

+}

+

+

+/**

+ * Helper function to read packet data from some source into a buffer

+ * @param buf the buffer into which the packet will be serialized

+ * @param buflen the length in bytes of the supplied buffer

+ * @param getfn pointer to a function which will read any number of bytes from the needed source

+ * @return integer MQTT packet type, or -1 on error

+ * @note  the whole message must fit into the caller's buffer

+ */

+int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int))

+{

+	int rc = -1;

+	MQTTHeader header = {0};

+	int len = 0;

+	int rem_len = 0;

+

+	/* 1. read the header byte.  This has the packet type in it */

+	if ((*getfn)(buf, 1) != 1)

+		goto exit;

+

+	len = 1;

+	/* 2. read the remaining length.  This is variable in itself */

+	MQTTPacket_decode(getfn, &rem_len);

+	len += MQTTPacket_encode(buf + 1, rem_len); /* put the original remaining length back into the buffer */

+

+	/* 3. read the rest of the buffer using a callback to supply the rest of the data */

+	if((rem_len + len) > buflen)

+		goto exit;

+	if ((*getfn)(buf + len, rem_len) != rem_len)

+		goto exit;

+

+	header.byte = buf[0];

+	rc = header.bits.type;

+exit:

+	return rc;

+}

+

+/**

+ * Decodes the message length according to the MQTT algorithm, non-blocking

+ * @param trp pointer to a transport structure holding what is needed to solve getting data from it

+ * @param value the decoded length returned

+ * @return integer the number of bytes read from the socket, 0 for call again, or -1 on error

+ */

+static int MQTTPacket_decodenb(MQTTTransport *trp)

+{

+	unsigned char c;

+	int rc = MQTTPACKET_READ_ERROR;

+

+	FUNC_ENTRY;

+	if(trp->len == 0){		/* initialize on first call */

+		trp->multiplier = 1;

+		trp->rem_len = 0;

+	}

+	do {

+		int frc;

+		if (++(trp->len) > MAX_NO_OF_REMAINING_LENGTH_BYTES)

+			goto exit;

+		if ((frc=(*trp->getfn)(trp->sck, &c, 1)) == -1)

+			goto exit;

+		if (frc == 0){

+			rc = 0;

+			goto exit;

+		}

+		trp->rem_len += (c & 127) * trp->multiplier;

+		trp->multiplier *= 128;

+	} while ((c & 128) != 0);

+	rc = trp->len;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+/**

+ * Helper function to read packet data from some source into a buffer, non-blocking

+ * @param buf the buffer into which the packet will be serialized

+ * @param buflen the length in bytes of the supplied buffer

+ * @param trp pointer to a transport structure holding what is needed to solve getting data from it

+ * @return integer MQTT packet type, 0 for call again, or -1 on error

+ * @note  the whole message must fit into the caller's buffer

+ */

+int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp)

+{

+	int rc = -1, frc;

+	MQTTHeader header = {0};

+

+	switch(trp->state){

+	default:

+		trp->state = 0;

+		/*FALLTHROUGH*/

+	case 0:

+		/* read the header byte.  This has the packet type in it */

+		if ((frc=(*trp->getfn)(trp->sck, buf, 1)) == -1)

+			goto exit;

+		if (frc == 0)

+			return 0;

+		trp->len = 0;

+		++trp->state;

+		/*FALLTHROUGH*/

+		/* read the remaining length.  This is variable in itself */

+	case 1:

+		if((frc=MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)

+			goto exit;

+		if(frc == 0)

+			return 0;

+		trp->len = 1 + MQTTPacket_encode(buf + 1, trp->rem_len); /* put the original remaining length back into the buffer */

+		if((trp->rem_len + trp->len) > buflen)

+			goto exit;

+		++trp->state;

+		/*FALLTHROUGH*/

+	case 2:

+		/* read the rest of the buffer using a callback to supply the rest of the data */

+		if ((frc=(*trp->getfn)(trp->sck, buf + trp->len, trp->rem_len)) == -1)

+			goto exit;

+		if (frc == 0)

+			return 0;

+		trp->rem_len -= frc;

+		trp->len += frc;

+		if(trp->rem_len)

+			return 0;

+

+		header.byte = buf[0];

+		rc = header.bits.type;

+		break;

+	}

+

+exit:

+	trp->state = 0;

+	return rc;

+}

+

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTPacket.h b/mbtk/mbtk_mqtt/MQTTPacket/MQTTPacket.h
new file mode 100755
index 0000000..f417929
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTPacket.h
@@ -0,0 +1,133 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *    Xiang Rong - 442039 Add makefile to Embedded C client

+ *******************************************************************************/

+

+#ifndef MQTTPACKET_H_

+#define MQTTPACKET_H_

+

+#if defined(__cplusplus) /* If this is a C++ compiler, use C linkage */

+extern "C" {

+#endif

+

+#if defined(WIN32_DLL) || defined(WIN64_DLL)

+  #define DLLImport __declspec(dllimport)

+  #define DLLExport __declspec(dllexport)

+#elif defined(LINUX_SO)

+  #define DLLImport extern

+  #define DLLExport  __attribute__ ((visibility ("default")))

+#else

+  #define DLLImport

+  #define DLLExport  

+#endif

+

+enum errors

+{

+	MQTTPACKET_BUFFER_TOO_SHORT = -2,

+	MQTTPACKET_READ_ERROR = -1,

+	MQTTPACKET_READ_COMPLETE

+};

+

+enum msgTypes

+{

+	CONNECT = 1, CONNACK, PUBLISH, PUBACK, PUBREC, PUBREL,

+	PUBCOMP, SUBSCRIBE, SUBACK, UNSUBSCRIBE, UNSUBACK,

+	PINGREQ, PINGRESP, DISCONNECT

+};

+

+/**

+ * Bitfields for the MQTT header byte.

+ */

+typedef union

+{

+	unsigned char byte;	                /**< the whole byte */

+#if defined(REVERSED)

+	struct

+	{

+		unsigned int type : 4;			/**< message type nibble */

+		unsigned int dup : 1;				/**< DUP flag bit */

+		unsigned int qos : 2;				/**< QoS value, 0, 1 or 2 */

+		unsigned int retain : 1;		/**< retained flag bit */

+	} bits;

+#else

+	struct

+	{

+		unsigned int retain : 1;		/**< retained flag bit */

+		unsigned int qos : 2;				/**< QoS value, 0, 1 or 2 */

+		unsigned int dup : 1;				/**< DUP flag bit */

+		unsigned int type : 4;			/**< message type nibble */

+	} bits;

+#endif

+} MQTTHeader;

+

+typedef struct

+{

+	int len;

+	char* data;

+} MQTTLenString;

+

+typedef struct

+{

+	char* cstring;

+	MQTTLenString lenstring;

+} MQTTString;

+

+#define MQTTString_initializer {NULL, {0, NULL}}

+

+int MQTTstrlen(MQTTString mqttstring);

+

+#include "MQTTConnect.h"

+#include "MQTTPublish.h"

+#include "MQTTSubscribe.h"

+#include "MQTTUnsubscribe.h"

+#include "MQTTFormat.h"

+

+int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char type, unsigned char dup, unsigned short packetid);

+int MQTTDeserialize_ack(unsigned char* packettype, unsigned char* dup, unsigned short* packetid, unsigned char* buf, int buflen);

+

+int MQTTPacket_len(int rem_len);

+int MQTTPacket_equals(MQTTString* a, char* b);

+

+int MQTTPacket_encode(unsigned char* buf, int length);

+int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value);

+int MQTTPacket_decodeBuf(unsigned char* buf, int* value);

+

+int readInt(unsigned char** pptr);

+char readChar(unsigned char** pptr);

+void writeChar(unsigned char** pptr, char c);

+void writeInt(unsigned char** pptr, int anInt);

+int readMQTTLenString(MQTTString* mqttstring, unsigned char** pptr, unsigned char* enddata);

+void writeCString(unsigned char** pptr, const char* string);

+void writeMQTTString(unsigned char** pptr, MQTTString mqttstring);

+

+DLLExport int MQTTPacket_read(unsigned char* buf, int buflen, int (*getfn)(unsigned char*, int));

+

+typedef struct {

+	int (*getfn)(void *, unsigned char*, int); /* must return -1 for error, 0 for call again, or the number of bytes read */

+	void *sck;	/* pointer to whatever the system may use to identify the transport */

+	int multiplier;

+	int rem_len;

+	int len;

+	char state;

+}MQTTTransport;

+

+int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport *trp);

+

+#ifdef __cplusplus /* If this is a C++ compiler, use C linkage */

+}

+#endif

+

+

+#endif /* MQTTPACKET_H_ */

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTPublish.h b/mbtk/mbtk_mqtt/MQTTPacket/MQTTPublish.h
new file mode 100755
index 0000000..d62dddb
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTPublish.h
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *    Xiang Rong - 442039 Add makefile to Embedded C client

+ *******************************************************************************/

+

+#ifndef MQTTPUBLISH_H_

+#define MQTTPUBLISH_H_

+

+#if !defined(DLLImport)

+  #define DLLImport 

+#endif

+#if !defined(DLLExport)

+  #define DLLExport

+#endif

+

+DLLExport int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,

+		MQTTString topicName, unsigned char* payload, int payloadlen);

+

+DLLExport int MQTTDeserialize_publish(unsigned char* dup, int* qos, unsigned char* retained, unsigned short* packetid, MQTTString* topicName,

+		unsigned char** payload, int* payloadlen, unsigned char* buf, int len);

+

+DLLExport int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid);

+DLLExport int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid);

+DLLExport int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid);

+

+#endif /* MQTTPUBLISH_H_ */

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTSerializePublish.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTSerializePublish.c
new file mode 100755
index 0000000..236791f
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTSerializePublish.c
@@ -0,0 +1,169 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *    Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144

+ *******************************************************************************/

+

+#include "MQTTPacket.h"

+#include "StackTrace.h"

+

+#include <string.h>

+

+

+/**

+  * Determines the length of the MQTT publish packet that would be produced using the supplied parameters

+  * @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)

+  * @param topicName the topic name to be used in the publish  

+  * @param payloadlen the length of the payload to be sent

+  * @return the length of buffer needed to contain the serialized version of the packet

+  */

+int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen)

+{

+	int len = 0;

+

+	len += 2 + MQTTstrlen(topicName) + payloadlen;

+	if (qos > 0)

+		len += 2; /* packetid */

+	return len;

+}

+

+

+/**

+  * Serializes the supplied publish data into the supplied buffer, ready for sending

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer

+  * @param dup integer - the MQTT dup flag

+  * @param qos integer - the MQTT QoS value

+  * @param retained integer - the MQTT retained flag

+  * @param packetid integer - the MQTT packet identifier

+  * @param topicName MQTTString - the MQTT topic in the publish

+  * @param payload byte buffer - the MQTT publish payload

+  * @param payloadlen integer - the length of the MQTT payload

+  * @return the length of the serialized data.  <= 0 indicates error

+  */

+int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,

+		MQTTString topicName, unsigned char* payload, int payloadlen)

+{

+	unsigned char *ptr = buf;

+	MQTTHeader header = {0};

+	int rem_len = 0;

+	int rc = 0;

+

+	FUNC_ENTRY;

+	if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+

+	header.bits.type = PUBLISH;

+	header.bits.dup = dup;

+	header.bits.qos = qos;

+	header.bits.retain = retained;

+	writeChar(&ptr, header.byte); /* write header */

+

+	ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;

+

+	writeMQTTString(&ptr, topicName);

+

+	if (qos > 0)

+		writeInt(&ptr, packetid);

+

+	memcpy(ptr, payload, payloadlen);

+	ptr += payloadlen;

+

+	rc = ptr - buf;

+

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+

+/**

+  * Serializes the ack packet into the supplied buffer.

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer

+  * @param type the MQTT packet type

+  * @param dup the MQTT dup flag

+  * @param packetid the MQTT packet identifier

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid)

+{

+	MQTTHeader header = {0};

+	int rc = 0;

+	unsigned char *ptr = buf;

+

+	FUNC_ENTRY;

+	if (buflen < 4)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+	header.bits.type = packettype;

+	header.bits.dup = dup;

+	header.bits.qos = (packettype == PUBREL) ? 1 : 0;

+	writeChar(&ptr, header.byte); /* write header */

+

+	ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */

+	writeInt(&ptr, packetid);

+	rc = ptr - buf;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+  * Serializes a puback packet into the supplied buffer.

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer

+  * @param packetid integer - the MQTT packet identifier

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid)

+{

+	return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid);

+}

+

+

+/**

+  * Serializes a pubrel packet into the supplied buffer.

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer

+  * @param dup integer - the MQTT dup flag

+  * @param packetid integer - the MQTT packet identifier

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid)

+{

+	return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid);

+}

+

+

+/**

+  * Serializes a pubrel packet into the supplied buffer.

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer

+  * @param packetid integer - the MQTT packet identifier

+  * @return serialized length, or error if 0

+  */

+int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid)

+{

+	return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid);

+}

+

+

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribe.h b/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribe.h
new file mode 100755
index 0000000..383ca0d
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribe.h
@@ -0,0 +1,39 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *    Xiang Rong - 442039 Add makefile to Embedded C client

+ *******************************************************************************/

+

+#ifndef MQTTSUBSCRIBE_H_

+#define MQTTSUBSCRIBE_H_

+

+#if !defined(DLLImport)

+  #define DLLImport 

+#endif

+#if !defined(DLLExport)

+  #define DLLExport

+#endif

+

+DLLExport int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,

+		int count, MQTTString topicFilters[], int requestedQoSs[]);

+

+DLLExport int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid,

+		int maxcount, int* count, MQTTString topicFilters[], int requestedQoSs[], unsigned char* buf, int len);

+

+DLLExport int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs);

+

+DLLExport int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int len);

+

+

+#endif /* MQTTSUBSCRIBE_H_ */

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribeClient.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribeClient.c
new file mode 100755
index 0000000..5b1ca28
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribeClient.c
@@ -0,0 +1,137 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#include "MQTTPacket.h"

+#include "StackTrace.h"

+

+#include <string.h>

+

+/**

+  * Determines the length of the MQTT subscribe packet that would be produced using the supplied parameters

+  * @param count the number of topic filter strings in topicFilters

+  * @param topicFilters the array of topic filter strings to be used in the publish

+  * @return the length of buffer needed to contain the serialized version of the packet

+  */

+int MQTTSerialize_subscribeLength(int count, MQTTString topicFilters[])

+{

+	int i;

+	int len = 2; /* packetid */

+

+	for (i = 0; i < count; ++i)

+		len += 2 + MQTTstrlen(topicFilters[i]) + 1; /* length + topic + req_qos */

+	return len;

+}

+

+

+/**

+  * Serializes the supplied subscribe data into the supplied buffer, ready for sending

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied bufferr

+  * @param dup integer - the MQTT dup flag

+  * @param packetid integer - the MQTT packet identifier

+  * @param count - number of members in the topicFilters and reqQos arrays

+  * @param topicFilters - array of topic filter names

+  * @param requestedQoSs - array of requested QoS

+  * @return the length of the serialized data.  <= 0 indicates error

+  */

+int MQTTSerialize_subscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid, int count,

+		MQTTString topicFilters[], int requestedQoSs[])

+{

+	unsigned char *ptr = buf;

+	MQTTHeader header = {0};

+	int rem_len = 0;

+	int rc = 0;

+	int i = 0;

+

+	FUNC_ENTRY;

+	if (MQTTPacket_len(rem_len = MQTTSerialize_subscribeLength(count, topicFilters)) > buflen)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+

+	header.byte = 0;

+	header.bits.type = SUBSCRIBE;

+	header.bits.dup = dup;

+	header.bits.qos = 1;

+	writeChar(&ptr, header.byte); /* write header */

+

+	ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;

+

+	writeInt(&ptr, packetid);

+

+	for (i = 0; i < count; ++i)

+	{

+		writeMQTTString(&ptr, topicFilters[i]);

+		writeChar(&ptr, requestedQoSs[i]);

+	}

+

+	rc = ptr - buf;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+

+/**

+  * Deserializes the supplied (wire) buffer into suback data

+  * @param packetid returned integer - the MQTT packet identifier

+  * @param maxcount - the maximum number of members allowed in the grantedQoSs array

+  * @param count returned integer - number of members in the grantedQoSs array

+  * @param grantedQoSs returned array of integers - the granted qualities of service

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param buflen the length in bytes of the data in the supplied buffer

+  * @return error code.  1 is success, 0 is failure

+  */

+int MQTTDeserialize_suback(unsigned short* packetid, int maxcount, int* count, int grantedQoSs[], unsigned char* buf, int buflen)

+{

+	MQTTHeader header = {0};

+	unsigned char* curdata = buf;

+	unsigned char* enddata = NULL;

+	int rc = 0;

+	int mylen;

+

+	FUNC_ENTRY;

+	header.byte = readChar(&curdata);

+	if (header.bits.type != SUBACK)

+		goto exit;

+

+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */

+	enddata = curdata + mylen;

+	if (enddata - curdata < 2)

+		goto exit;

+

+	*packetid = readInt(&curdata);

+

+	*count = 0;

+	while (curdata < enddata)

+	{

+		if (*count > maxcount)

+		{

+			rc = -1;

+			goto exit;

+		}

+		grantedQoSs[(*count)++] = readChar(&curdata);

+	}

+

+	rc = 1;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribeServer.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribeServer.c
new file mode 100755
index 0000000..15bb15d
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTSubscribeServer.c
@@ -0,0 +1,112 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#include "MQTTPacket.h"

+#include "StackTrace.h"

+

+#include <string.h>

+

+

+/**

+  * Deserializes the supplied (wire) buffer into subscribe data

+  * @param dup integer returned - the MQTT dup flag

+  * @param packetid integer returned - the MQTT packet identifier

+  * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays

+  * @param count - number of members in the topicFilters and requestedQoSs arrays

+  * @param topicFilters - array of topic filter names

+  * @param requestedQoSs - array of requested QoS

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param buflen the length in bytes of the data in the supplied buffer

+  * @return the length of the serialized data.  <= 0 indicates error

+  */

+int MQTTDeserialize_subscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],

+	int requestedQoSs[], unsigned char* buf, int buflen)

+{

+	MQTTHeader header = {0};

+	unsigned char* curdata = buf;

+	unsigned char* enddata = NULL;

+	int rc = -1;

+	int mylen = 0;

+

+	FUNC_ENTRY;

+	header.byte = readChar(&curdata);

+	if (header.bits.type != SUBSCRIBE)

+		goto exit;

+	*dup = header.bits.dup;

+

+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */

+	enddata = curdata + mylen;

+

+	*packetid = readInt(&curdata);

+

+	*count = 0;

+	while (curdata < enddata)

+	{

+		if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))

+			goto exit;

+		if (curdata >= enddata) /* do we have enough data to read the req_qos version byte? */

+			goto exit;

+		requestedQoSs[*count] = readChar(&curdata);

+		(*count)++;

+	}

+

+	rc = 1;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+  * Serializes the supplied suback data into the supplied buffer, ready for sending

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer

+  * @param packetid integer - the MQTT packet identifier

+  * @param count - number of members in the grantedQoSs array

+  * @param grantedQoSs - array of granted QoS

+  * @return the length of the serialized data.  <= 0 indicates error

+  */

+int MQTTSerialize_suback(unsigned char* buf, int buflen, unsigned short packetid, int count, int* grantedQoSs)

+{

+	MQTTHeader header = {0};

+	int rc = -1;

+	unsigned char *ptr = buf;

+	int i;

+

+	FUNC_ENTRY;

+	if (buflen < 2 + count)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+	header.byte = 0;

+	header.bits.type = SUBACK;

+	writeChar(&ptr, header.byte); /* write header */

+

+	ptr += MQTTPacket_encode(ptr, 2 + count); /* write remaining length */

+

+	writeInt(&ptr, packetid);

+

+	for (i = 0; i < count; ++i)

+		writeChar(&ptr, grantedQoSs[i]);

+

+	rc = ptr - buf;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribe.h b/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribe.h
new file mode 100755
index 0000000..1644ae5
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribe.h
@@ -0,0 +1,38 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *    Xiang Rong - 442039 Add makefile to Embedded C client

+ *******************************************************************************/

+

+#ifndef MQTTUNSUBSCRIBE_H_

+#define MQTTUNSUBSCRIBE_H_

+

+#if !defined(DLLImport)

+  #define DLLImport 

+#endif

+#if !defined(DLLExport)

+  #define DLLExport

+#endif

+

+DLLExport int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,

+		int count, MQTTString topicFilters[]);

+

+DLLExport int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int max_count, int* count, MQTTString topicFilters[],

+		unsigned char* buf, int len);

+

+DLLExport int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid);

+

+DLLExport int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int len);

+

+#endif /* MQTTUNSUBSCRIBE_H_ */

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribeClient.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribeClient.c
new file mode 100755
index 0000000..0f8db7b
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribeClient.c
@@ -0,0 +1,106 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#include "MQTTPacket.h"

+#include "StackTrace.h"

+

+#include <string.h>

+

+/**

+  * Determines the length of the MQTT unsubscribe packet that would be produced using the supplied parameters

+  * @param count the number of topic filter strings in topicFilters

+  * @param topicFilters the array of topic filter strings to be used in the publish

+  * @return the length of buffer needed to contain the serialized version of the packet

+  */

+int MQTTSerialize_unsubscribeLength(int count, MQTTString topicFilters[])

+{

+	int i;

+	int len = 2; /* packetid */

+

+	for (i = 0; i < count; ++i)

+		len += 2 + MQTTstrlen(topicFilters[i]); /* length + topic*/

+	return len;

+}

+

+

+/**

+  * Serializes the supplied unsubscribe data into the supplied buffer, ready for sending

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param buflen the length in bytes of the data in the supplied buffer

+  * @param dup integer - the MQTT dup flag

+  * @param packetid integer - the MQTT packet identifier

+  * @param count - number of members in the topicFilters array

+  * @param topicFilters - array of topic filter names

+  * @return the length of the serialized data.  <= 0 indicates error

+  */

+int MQTTSerialize_unsubscribe(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid,

+		int count, MQTTString topicFilters[])

+{

+	unsigned char *ptr = buf;

+	MQTTHeader header = {0};

+	int rem_len = 0;

+	int rc = -1;

+	int i = 0;

+

+	FUNC_ENTRY;

+	if (MQTTPacket_len(rem_len = MQTTSerialize_unsubscribeLength(count, topicFilters)) > buflen)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+

+	header.byte = 0;

+	header.bits.type = UNSUBSCRIBE;

+	header.bits.dup = dup;

+	header.bits.qos = 1;

+	writeChar(&ptr, header.byte); /* write header */

+

+	ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;

+

+	writeInt(&ptr, packetid);

+

+	for (i = 0; i < count; ++i)

+		writeMQTTString(&ptr, topicFilters[i]);

+

+	rc = ptr - buf;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+  * Deserializes the supplied (wire) buffer into unsuback data

+  * @param packetid returned integer - the MQTT packet identifier

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param buflen the length in bytes of the data in the supplied buffer

+  * @return error code.  1 is success, 0 is failure

+  */

+int MQTTDeserialize_unsuback(unsigned short* packetid, unsigned char* buf, int buflen)

+{

+	unsigned char type = 0;

+	unsigned char dup = 0;

+	int rc = 0;

+

+	FUNC_ENTRY;

+	rc = MQTTDeserialize_ack(&type, &dup, packetid, buf, buflen);

+	if (type == UNSUBACK)

+		rc = 1;

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribeServer.c b/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribeServer.c
new file mode 100755
index 0000000..b0e427d
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/MQTTUnsubscribeServer.c
@@ -0,0 +1,102 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *******************************************************************************/

+

+#include "MQTTPacket.h"

+#include "StackTrace.h"

+

+#include <string.h>

+

+

+/**

+  * Deserializes the supplied (wire) buffer into unsubscribe data

+  * @param dup integer returned - the MQTT dup flag

+  * @param packetid integer returned - the MQTT packet identifier

+  * @param maxcount - the maximum number of members allowed in the topicFilters and requestedQoSs arrays

+  * @param count - number of members in the topicFilters and requestedQoSs arrays

+  * @param topicFilters - array of topic filter names

+  * @param buf the raw buffer data, of the correct length determined by the remaining length field

+  * @param buflen the length in bytes of the data in the supplied buffer

+  * @return the length of the serialized data.  <= 0 indicates error

+  */

+int MQTTDeserialize_unsubscribe(unsigned char* dup, unsigned short* packetid, int maxcount, int* count, MQTTString topicFilters[],

+		unsigned char* buf, int len)

+{

+	MQTTHeader header = {0};

+	unsigned char* curdata = buf;

+	unsigned char* enddata = NULL;

+	int rc = 0;

+	int mylen = 0;

+

+	FUNC_ENTRY;

+	header.byte = readChar(&curdata);

+	if (header.bits.type != UNSUBSCRIBE)

+		goto exit;

+	*dup = header.bits.dup;

+

+	curdata += (rc = MQTTPacket_decodeBuf(curdata, &mylen)); /* read remaining length */

+	enddata = curdata + mylen;

+

+	*packetid = readInt(&curdata);

+

+	*count = 0;

+	while (curdata < enddata)

+	{

+		if (!readMQTTLenString(&topicFilters[*count], &curdata, enddata))

+			goto exit;

+		(*count)++;

+	}

+

+	rc = 1;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

+/**

+  * Serializes the supplied unsuback data into the supplied buffer, ready for sending

+  * @param buf the buffer into which the packet will be serialized

+  * @param buflen the length in bytes of the supplied buffer

+  * @param packetid integer - the MQTT packet identifier

+  * @return the length of the serialized data.  <= 0 indicates error

+  */

+int MQTTSerialize_unsuback(unsigned char* buf, int buflen, unsigned short packetid)

+{

+	MQTTHeader header = {0};

+	int rc = 0;

+	unsigned char *ptr = buf;

+

+	FUNC_ENTRY;

+	if (buflen < 2)

+	{

+		rc = MQTTPACKET_BUFFER_TOO_SHORT;

+		goto exit;

+	}

+	header.byte = 0;

+	header.bits.type = UNSUBACK;

+	writeChar(&ptr, header.byte); /* write header */

+

+	ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */

+

+	writeInt(&ptr, packetid);

+

+	rc = ptr - buf;

+exit:

+	FUNC_EXIT_RC(rc);

+	return rc;

+}

+

+

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/StackTrace.h b/mbtk/mbtk_mqtt/MQTTPacket/StackTrace.h
new file mode 100755
index 0000000..c65a2ef
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/StackTrace.h
@@ -0,0 +1,78 @@
+/*******************************************************************************

+ * Copyright (c) 2014 IBM Corp.

+ *

+ * All rights reserved. This program and the accompanying materials

+ * are made available under the terms of the Eclipse Public License v1.0

+ * and Eclipse Distribution License v1.0 which accompany this distribution.

+ *

+ * The Eclipse Public License is available at

+ *    http://www.eclipse.org/legal/epl-v10.html

+ * and the Eclipse Distribution License is available at

+ *   http://www.eclipse.org/org/documents/edl-v10.php.

+ *

+ * Contributors:

+ *    Ian Craggs - initial API and implementation and/or initial documentation

+ *    Ian Craggs - fix for bug #434081

+ *******************************************************************************/

+

+#ifndef STACKTRACE_H_

+#define STACKTRACE_H_

+

+#include <stdio.h>

+#define NOSTACKTRACE 1

+

+#if defined(NOSTACKTRACE)

+#define FUNC_ENTRY

+#define FUNC_ENTRY_NOLOG

+#define FUNC_ENTRY_MED

+#define FUNC_ENTRY_MAX

+#define FUNC_EXIT

+#define FUNC_EXIT_NOLOG

+#define FUNC_EXIT_MED

+#define FUNC_EXIT_MAX

+#define FUNC_EXIT_RC(x)

+#define FUNC_EXIT_MED_RC(x)

+#define FUNC_EXIT_MAX_RC(x)

+

+#else

+

+#if defined(WIN32)

+#define inline __inline

+#define FUNC_ENTRY StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MINIMUM)

+#define FUNC_ENTRY_NOLOG StackTrace_entry(__FUNCTION__, __LINE__, -1)

+#define FUNC_ENTRY_MED StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MEDIUM)

+#define FUNC_ENTRY_MAX StackTrace_entry(__FUNCTION__, __LINE__, TRACE_MAXIMUM)

+#define FUNC_EXIT StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MINIMUM)

+#define FUNC_EXIT_NOLOG StackTrace_exit(__FUNCTION__, __LINE__, -1)

+#define FUNC_EXIT_MED StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MEDIUM)

+#define FUNC_EXIT_MAX StackTrace_exit(__FUNCTION__, __LINE__, NULL, TRACE_MAXIMUM)

+#define FUNC_EXIT_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MINIMUM)

+#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MEDIUM)

+#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__FUNCTION__, __LINE__, &x, TRACE_MAXIMUM)

+#else

+#define FUNC_ENTRY StackTrace_entry(__func__, __LINE__, TRACE_MINIMUM)

+#define FUNC_ENTRY_NOLOG StackTrace_entry(__func__, __LINE__, -1)

+#define FUNC_ENTRY_MED StackTrace_entry(__func__, __LINE__, TRACE_MEDIUM)

+#define FUNC_ENTRY_MAX StackTrace_entry(__func__, __LINE__, TRACE_MAXIMUM)

+#define FUNC_EXIT StackTrace_exit(__func__, __LINE__, NULL, TRACE_MINIMUM)

+#define FUNC_EXIT_NOLOG StackTrace_exit(__func__, __LINE__, NULL, -1)

+#define FUNC_EXIT_MED StackTrace_exit(__func__, __LINE__, NULL, TRACE_MEDIUM)

+#define FUNC_EXIT_MAX StackTrace_exit(__func__, __LINE__, NULL, TRACE_MAXIMUM)

+#define FUNC_EXIT_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MINIMUM)

+#define FUNC_EXIT_MED_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MEDIUM)

+#define FUNC_EXIT_MAX_RC(x) StackTrace_exit(__func__, __LINE__, &x, TRACE_MAXIMUM)

+

+void StackTrace_entry(const char* name, int line, int trace);

+void StackTrace_exit(const char* name, int line, void* return_value, int trace);

+

+void StackTrace_printStack(FILE* dest);

+char* StackTrace_get(unsigned long);

+

+#endif

+

+#endif

+

+

+

+

+#endif /* STACKTRACE_H_ */

diff --git a/mbtk/mbtk_mqtt/MQTTPacket/core_sha1.c b/mbtk/mbtk_mqtt/MQTTPacket/core_sha1.c
new file mode 100644
index 0000000..dfd3a3d
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/core_sha1.c
@@ -0,0 +1,425 @@
+/*
+ * Copyright (C) 2015-2018 Alibaba Group Holding Limited
+ */
+//#include "infra_config.h"
+
+//#ifdef INFRA_SHA1
+
+#include <stdlib.h>
+#include <string.h>
+#include "core_sha1.h"
+//#include "infra_sha1.h"
+
+#define SHA1_KEY_IOPAD_SIZE (64)
+#define SHA1_DIGEST_SIZE    (20)
+
+
+/* Implementation that should never be optimized out by the compiler */
+static void core_sha1_zeroize( void *v, uint32_t n ) {
+    volatile unsigned char *p = (unsigned char*)v; while( n-- ) *p++ = 0;
+}
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+void core_sha1_init(iot_sha1_context *ctx)
+{
+    memset(ctx, 0, sizeof(iot_sha1_context));
+}
+
+void core_sha1_free(iot_sha1_context *ctx)
+{
+    if (ctx == NULL) {
+        return;
+    }
+
+    core_sha1_zeroize(ctx, sizeof(iot_sha1_context));
+}
+
+void core_sha1_clone(iot_sha1_context *dst,
+                      const iot_sha1_context *src)
+{
+    *dst = *src;
+}
+
+/*
+ * SHA-1 context setup
+ */
+void core_sha1_starts(iot_sha1_context *ctx)
+{
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    ctx->state[0] = 0x67452301;
+    ctx->state[1] = 0xEFCDAB89;
+    ctx->state[2] = 0x98BADCFE;
+    ctx->state[3] = 0x10325476;
+    ctx->state[4] = 0xC3D2E1F0;
+}
+
+void core_sha1_process(iot_sha1_context *ctx, const unsigned char data[64])
+{
+    uint32_t temp, W[16], A, B, C, D, E;
+
+    GET_UINT32_BE( W[ 0], data,  0 );
+    GET_UINT32_BE( W[ 1], data,  4 );
+    GET_UINT32_BE( W[ 2], data,  8 );
+    GET_UINT32_BE( W[ 3], data, 12 );
+    GET_UINT32_BE( W[ 4], data, 16 );
+    GET_UINT32_BE( W[ 5], data, 20 );
+    GET_UINT32_BE( W[ 6], data, 24 );
+    GET_UINT32_BE( W[ 7], data, 28 );
+    GET_UINT32_BE( W[ 8], data, 32 );
+    GET_UINT32_BE( W[ 9], data, 36 );
+    GET_UINT32_BE( W[10], data, 40 );
+    GET_UINT32_BE( W[11], data, 44 );
+    GET_UINT32_BE( W[12], data, 48 );
+    GET_UINT32_BE( W[13], data, 52 );
+    GET_UINT32_BE( W[14], data, 56 );
+    GET_UINT32_BE( W[15], data, 60 );
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define R(t)                                            \
+(                                                       \
+    temp = W[( t -  3 ) & 0x0F] ^ W[( t - 8 ) & 0x0F] ^ \
+           W[( t - 14 ) & 0x0F] ^ W[  t       & 0x0F],  \
+    ( W[t & 0x0F] = S(temp,1) )                         \
+)
+
+#define P(a,b,c,d,e,x)                                  \
+{                                                       \
+    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
+}
+
+    A = ctx->state[0];
+    B = ctx->state[1];
+    C = ctx->state[2];
+    D = ctx->state[3];
+    E = ctx->state[4];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+    P( A, B, C, D, E, W[0]  );
+    P( E, A, B, C, D, W[1]  );
+    P( D, E, A, B, C, W[2]  );
+    P( C, D, E, A, B, W[3]  );
+    P( B, C, D, E, A, W[4]  );
+    P( A, B, C, D, E, W[5]  );
+    P( E, A, B, C, D, W[6]  );
+    P( D, E, A, B, C, W[7]  );
+    P( C, D, E, A, B, W[8]  );
+    P( B, C, D, E, A, W[9]  );
+    P( A, B, C, D, E, W[10] );
+    P( E, A, B, C, D, W[11] );
+    P( D, E, A, B, C, W[12] );
+    P( C, D, E, A, B, W[13] );
+    P( B, C, D, E, A, W[14] );
+    P( A, B, C, D, E, W[15] );
+    P( E, A, B, C, D, R(16) );
+    P( D, E, A, B, C, R(17) );
+    P( C, D, E, A, B, R(18) );
+    P( B, C, D, E, A, R(19) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+    P( A, B, C, D, E, R(20) );
+    P( E, A, B, C, D, R(21) );
+    P( D, E, A, B, C, R(22) );
+    P( C, D, E, A, B, R(23) );
+    P( B, C, D, E, A, R(24) );
+    P( A, B, C, D, E, R(25) );
+    P( E, A, B, C, D, R(26) );
+    P( D, E, A, B, C, R(27) );
+    P( C, D, E, A, B, R(28) );
+    P( B, C, D, E, A, R(29) );
+    P( A, B, C, D, E, R(30) );
+    P( E, A, B, C, D, R(31) );
+    P( D, E, A, B, C, R(32) );
+    P( C, D, E, A, B, R(33) );
+    P( B, C, D, E, A, R(34) );
+    P( A, B, C, D, E, R(35) );
+    P( E, A, B, C, D, R(36) );
+    P( D, E, A, B, C, R(37) );
+    P( C, D, E, A, B, R(38) );
+    P( B, C, D, E, A, R(39) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+    P( A, B, C, D, E, R(40) );
+    P( E, A, B, C, D, R(41) );
+    P( D, E, A, B, C, R(42) );
+    P( C, D, E, A, B, R(43) );
+    P( B, C, D, E, A, R(44) );
+    P( A, B, C, D, E, R(45) );
+    P( E, A, B, C, D, R(46) );
+    P( D, E, A, B, C, R(47) );
+    P( C, D, E, A, B, R(48) );
+    P( B, C, D, E, A, R(49) );
+    P( A, B, C, D, E, R(50) );
+    P( E, A, B, C, D, R(51) );
+    P( D, E, A, B, C, R(52) );
+    P( C, D, E, A, B, R(53) );
+    P( B, C, D, E, A, R(54) );
+    P( A, B, C, D, E, R(55) );
+    P( E, A, B, C, D, R(56) );
+    P( D, E, A, B, C, R(57) );
+    P( C, D, E, A, B, R(58) );
+    P( B, C, D, E, A, R(59) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+    P( A, B, C, D, E, R(60) );
+    P( E, A, B, C, D, R(61) );
+    P( D, E, A, B, C, R(62) );
+    P( C, D, E, A, B, R(63) );
+    P( B, C, D, E, A, R(64) );
+    P( A, B, C, D, E, R(65) );
+    P( E, A, B, C, D, R(66) );
+    P( D, E, A, B, C, R(67) );
+    P( C, D, E, A, B, R(68) );
+    P( B, C, D, E, A, R(69) );
+    P( A, B, C, D, E, R(70) );
+    P( E, A, B, C, D, R(71) );
+    P( D, E, A, B, C, R(72) );
+    P( C, D, E, A, B, R(73) );
+    P( B, C, D, E, A, R(74) );
+    P( A, B, C, D, E, R(75) );
+    P( E, A, B, C, D, R(76) );
+    P( D, E, A, B, C, R(77) );
+    P( C, D, E, A, B, R(78) );
+    P( B, C, D, E, A, R(79) );
+
+#undef K
+#undef F
+
+    ctx->state[0] += A;
+    ctx->state[1] += B;
+    ctx->state[2] += C;
+    ctx->state[3] += D;
+    ctx->state[4] += E;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+void core_sha1_update(iot_sha1_context *ctx, const unsigned char *input, uint32_t ilen)
+{
+    uint32_t fill;
+    uint32_t left;
+
+    if( ilen == 0 )
+        return;
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if( ctx->total[0] < (uint32_t) ilen )
+        ctx->total[1]++;
+
+    if( left && ilen >= fill )
+    {
+        memcpy( (void *) (ctx->buffer + left), input, fill );
+        core_sha1_process( ctx, ctx->buffer );
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while( ilen >= 64 )
+    {
+        core_sha1_process( ctx, input );
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if( ilen > 0 )
+        memcpy( (void *) (ctx->buffer + left), input, ilen );
+}
+
+static const unsigned char sha1_padding[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * SHA-1 final digest
+ */
+void core_sha1_finish(iot_sha1_context *ctx, unsigned char output[20])
+{
+    uint32_t last, padn;
+    uint32_t high, low;
+    unsigned char msglen[8];
+
+    high = ( ctx->total[0] >> 29 )
+         | ( ctx->total[1] <<  3 );
+    low  = ( ctx->total[0] <<  3 );
+
+    PUT_UINT32_BE( high, msglen, 0 );
+    PUT_UINT32_BE( low,  msglen, 4 );
+
+    last = ctx->total[0] & 0x3F;
+    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+    core_sha1_update( ctx, sha1_padding, padn );
+    core_sha1_update( ctx, msglen, 8 );
+
+    PUT_UINT32_BE( ctx->state[0], output,  0 );
+    PUT_UINT32_BE( ctx->state[1], output,  4 );
+    PUT_UINT32_BE( ctx->state[2], output,  8 );
+    PUT_UINT32_BE( ctx->state[3], output, 12 );
+    PUT_UINT32_BE( ctx->state[4], output, 16 );
+}
+
+
+/*
+ * output = SHA-1( input buffer )
+ */
+void core_sha1(const unsigned char *input, uint32_t ilen, unsigned char output[20])
+{
+    iot_sha1_context ctx;
+
+    core_sha1_init(&ctx);
+    core_sha1_starts(&ctx);
+    core_sha1_update(&ctx, input, ilen);
+    core_sha1_finish(&ctx, output);
+    core_sha1_free(&ctx);
+}
+
+static int8_t core_hb2hex(uint8_t hb)
+{
+    hb = hb & 0xF;
+    return (int8_t)(hb < 10 ? '0' + hb : hb - 10 + 'a');
+}
+
+void core_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len)
+{
+    iot_sha1_context context;
+    unsigned char k_ipad[SHA1_KEY_IOPAD_SIZE];    /* inner padding - key XORd with ipad  */
+    unsigned char k_opad[SHA1_KEY_IOPAD_SIZE];    /* outer padding - key XORd with opad */
+    unsigned char out[SHA1_DIGEST_SIZE];
+    int i;
+
+    if ((NULL == msg) || (NULL == digest) || (NULL == key)) {
+        return;
+    }
+
+    if (key_len > SHA1_KEY_IOPAD_SIZE) {
+        return;
+    }
+
+    /* start out by storing key in pads */
+    memset(k_ipad, 0, sizeof(k_ipad));
+    memset(k_opad, 0, sizeof(k_opad));
+    memcpy(k_ipad, key, key_len);
+    memcpy(k_opad, key, key_len);
+
+    /* XOR key with ipad and opad values */
+    for (i = 0; i < SHA1_KEY_IOPAD_SIZE; i++) {
+        k_ipad[i] ^= 0x36;
+        k_opad[i] ^= 0x5c;
+    }
+
+    /* perform inner SHA */
+    core_sha1_init(&context);                                      /* init context for 1st pass */
+    core_sha1_starts(&context);                                    /* setup context for 1st pass */
+    core_sha1_update(&context, k_ipad, SHA1_KEY_IOPAD_SIZE);            /* start with inner pad */
+    core_sha1_update(&context, (unsigned char *) msg, msg_len);    /* then text of datagram */
+    core_sha1_finish(&context, out);                               /* finish up 1st pass */
+
+    /* perform outer SHA */
+    core_sha1_init(&context);                              /* init context for 2nd pass */
+    core_sha1_starts(&context);                            /* setup context for 2nd pass */
+    core_sha1_update(&context, k_opad, SHA1_KEY_IOPAD_SIZE);    /* start with outer pad */
+    core_sha1_update(&context, out, SHA1_DIGEST_SIZE);     /* then results of 1st hash */
+    core_sha1_finish(&context, out);                       /* finish up 2nd pass */
+
+    for (i = 0; i < SHA1_DIGEST_SIZE; ++i) {
+        digest[i * 2] = core_hb2hex(out[i] >> 4);
+        digest[i * 2 + 1] = core_hb2hex(out[i]);
+    }
+}
+
+void core_hmac_sha1_hex(const char *msg, int msg_len, char *digest, const char *key, int key_len)
+{
+    iot_sha1_context context;
+    unsigned char k_ipad[SHA1_KEY_IOPAD_SIZE];    /* inner padding - key XORd with ipad  */
+    unsigned char k_opad[SHA1_KEY_IOPAD_SIZE];    /* outer padding - key XORd with opad */
+    unsigned char out[SHA1_DIGEST_SIZE];
+    int i;
+
+    if ((NULL == msg) || (NULL == digest) || (NULL == key)) {
+        return;
+    }
+
+    if (key_len > SHA1_KEY_IOPAD_SIZE) {
+        return;
+    }
+
+    /* start out by storing key in pads */
+    memset(k_ipad, 0, sizeof(k_ipad));
+    memset(k_opad, 0, sizeof(k_opad));
+    memcpy(k_ipad, key, key_len);
+    memcpy(k_opad, key, key_len);
+
+    /* XOR key with ipad and opad values */
+    for (i = 0; i < SHA1_KEY_IOPAD_SIZE; i++) {
+        k_ipad[i] ^= 0x36;
+        k_opad[i] ^= 0x5c;
+    }
+
+    /* perform inner SHA */
+    core_sha1_init(&context);                                      /* init context for 1st pass */
+    core_sha1_starts(&context);                                    /* setup context for 1st pass */
+    core_sha1_update(&context, k_ipad, SHA1_KEY_IOPAD_SIZE);            /* start with inner pad */
+    core_sha1_update(&context, (unsigned char *) msg, msg_len);    /* then text of datagram */
+    core_sha1_finish(&context, out);                               /* finish up 1st pass */
+
+    /* perform outer SHA */
+    core_sha1_init(&context);                              /* init context for 2nd pass */
+    core_sha1_starts(&context);                            /* setup context for 2nd pass */
+    core_sha1_update(&context, k_opad, SHA1_KEY_IOPAD_SIZE);    /* start with outer pad */
+    core_sha1_update(&context, out, SHA1_DIGEST_SIZE);     /* then results of 1st hash */
+    core_sha1_finish(&context, out);                       /* finish up 2nd pass */
+    memcpy(digest, out, SHA1_DIGEST_SIZE);
+}
+
+//#endif
diff --git a/mbtk/mbtk_mqtt/MQTTPacket/core_sha1.h b/mbtk/mbtk_mqtt/MQTTPacket/core_sha1.h
new file mode 100644
index 0000000..0260002
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/core_sha1.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2015-2018 Alibaba Group Holding Limited
+ */
+
+
+
+
+#ifndef _CORE_SHA1_H_
+#define _CORE_SHA1_H_
+
+//#include "infra_types.h"
+
+#define SHA1_DIGEST_SIZE    (20)
+
+typedef unsigned int uint32_t;
+typedef unsigned char uint8_t;
+
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+        | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+        | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+        | ( (uint32_t) (b)[(i) + 3]       );            \
+}
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+{                                                       \
+    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+}
+#endif
+
+/**
+ * \brief          SHA-1 context structure
+ */
+typedef struct {
+    uint32_t total[2];          /*!< number of bytes processed  */
+    uint32_t state[5];          /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+} iot_sha1_context;
+
+/**
+ * \brief          Initialize SHA-1 context
+ *
+ * \param ctx      SHA-1 context to be initialized
+ */
+void core_sha1_init(iot_sha1_context *ctx);
+
+/**
+ * \brief          Clear SHA-1 context
+ *
+ * \param ctx      SHA-1 context to be cleared
+ */
+void core_sha1_free(iot_sha1_context *ctx);
+
+/**
+ * \brief          Clone (the state of) a SHA-1 context
+ *
+ * \param dst      The destination context
+ * \param src      The context to be cloned
+ */
+void core_sha1_clone(iot_sha1_context *dst,
+                      const iot_sha1_context *src);
+
+/**
+ * \brief          SHA-1 context setup
+ *
+ * \param ctx      context to be initialized
+ */
+void core_sha1_starts(iot_sha1_context *ctx);
+
+/**
+ * \brief          SHA-1 process buffer
+ *
+ * \param ctx      SHA-1 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void core_sha1_update(iot_sha1_context *ctx, const unsigned char *input, uint32_t ilen);
+
+/**
+ * \brief          SHA-1 final digest
+ *
+ * \param ctx      SHA-1 context
+ * \param output   SHA-1 checksum result
+ */
+void core_sha1_finish(iot_sha1_context *ctx, unsigned char output[20]);
+
+/* Internal use */
+void core_sha1_process(iot_sha1_context *ctx, const unsigned char data[64]);
+
+/**
+ * \brief          Output = SHA-1( input buffer )
+ *
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   SHA-1 checksum result
+ */
+void core_sha1(const unsigned char *input, uint32_t ilen, unsigned char output[20]);
+void core_hmac_sha1(const char *msg, int msg_len, char *digest, const char *key, int key_len);
+void core_hmac_sha1_hex(const char *msg, int msg_len, char *digest, const char *key, int key_len);
+
+#endif
diff --git a/mbtk/mbtk_mqtt/MQTTPacket/core_sha256.c b/mbtk/mbtk_mqtt/MQTTPacket/core_sha256.c
new file mode 100755
index 0000000..d819047
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/core_sha256.c
@@ -0,0 +1,329 @@
+#include "core_sha256.h"
+
+#define MINI_SHA256_SMALLER
+#define SHA256_KEY_IOPAD_SIZE   (64)
+#define SHA256_DIGEST_SIZE      (32)
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_UINT32_BE
+#define GET_UINT32_BE(n,b,i)                            \
+    do {                                                    \
+        (n) = ( (uint32_t) (b)[(i)    ] << 24 )             \
+              | ( (uint32_t) (b)[(i) + 1] << 16 )             \
+              | ( (uint32_t) (b)[(i) + 2] <<  8 )             \
+              | ( (uint32_t) (b)[(i) + 3]       );            \
+    } while( 0 )
+#endif
+
+#ifndef PUT_UINT32_BE
+#define PUT_UINT32_BE(n,b,i)                            \
+    do {                                                    \
+        (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
+        (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
+        (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
+        (b)[(i) + 3] = (unsigned char) ( (n)       );       \
+    } while( 0 )
+#endif
+
+
+static void utils_sha256_zeroize(void *v, uint32_t n)
+{
+    volatile unsigned char *p = v;
+    while (n--) {
+        *p++ = 0;
+    }
+}
+
+void core_sha256_init(core_sha256_context_t *ctx)
+{
+    memset(ctx, 0, sizeof(core_sha256_context_t));
+}
+
+void core_sha256_free(core_sha256_context_t *ctx)
+{
+    if (NULL == ctx) {
+        return;
+    }
+
+    utils_sha256_zeroize(ctx, sizeof(core_sha256_context_t));
+}
+
+void core_sha256_starts(core_sha256_context_t *ctx)
+{
+    uint8_t is224 = 0;
+    ctx->total[0] = 0;
+    ctx->total[1] = 0;
+
+    if (is224 == 0) {
+        /* SHA-256 */
+        ctx->state[0] = 0x6A09E667;
+        ctx->state[1] = 0xBB67AE85;
+        ctx->state[2] = 0x3C6EF372;
+        ctx->state[3] = 0xA54FF53A;
+        ctx->state[4] = 0x510E527F;
+        ctx->state[5] = 0x9B05688C;
+        ctx->state[6] = 0x1F83D9AB;
+        ctx->state[7] = 0x5BE0CD19;
+    }
+
+    ctx->is224 = is224;
+}
+
+static const uint32_t K[] = {
+    0x428A2F98, 0x71374491, 0xB5C0FBCF, 0xE9B5DBA5,
+    0x3956C25B, 0x59F111F1, 0x923F82A4, 0xAB1C5ED5,
+    0xD807AA98, 0x12835B01, 0x243185BE, 0x550C7DC3,
+    0x72BE5D74, 0x80DEB1FE, 0x9BDC06A7, 0xC19BF174,
+    0xE49B69C1, 0xEFBE4786, 0x0FC19DC6, 0x240CA1CC,
+    0x2DE92C6F, 0x4A7484AA, 0x5CB0A9DC, 0x76F988DA,
+    0x983E5152, 0xA831C66D, 0xB00327C8, 0xBF597FC7,
+    0xC6E00BF3, 0xD5A79147, 0x06CA6351, 0x14292967,
+    0x27B70A85, 0x2E1B2138, 0x4D2C6DFC, 0x53380D13,
+    0x650A7354, 0x766A0ABB, 0x81C2C92E, 0x92722C85,
+    0xA2BFE8A1, 0xA81A664B, 0xC24B8B70, 0xC76C51A3,
+    0xD192E819, 0xD6990624, 0xF40E3585, 0x106AA070,
+    0x19A4C116, 0x1E376C08, 0x2748774C, 0x34B0BCB5,
+    0x391C0CB3, 0x4ED8AA4A, 0x5B9CCA4F, 0x682E6FF3,
+    0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208,
+    0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2,
+};
+
+#define  SHR(x,n) ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n) (SHR(x,n) | (x << (32 - n)))
+
+#define S0(x) (ROTR(x, 7) ^ ROTR(x,18) ^  SHR(x, 3))
+#define S1(x) (ROTR(x,17) ^ ROTR(x,19) ^  SHR(x,10))
+
+#define S2(x) (ROTR(x, 2) ^ ROTR(x,13) ^ ROTR(x,22))
+#define S3(x) (ROTR(x, 6) ^ ROTR(x,11) ^ ROTR(x,25))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define R(t)                                    \
+    (                                               \
+            W[t] = S1(W[t -  2]) + W[t -  7] +          \
+                   S0(W[t - 15]) + W[t - 16]            \
+    )
+
+#define P(a,b,c,d,e,f,g,h,x,K)                  \
+    {                                               \
+        temp1 = h + S3(e) + F1(e,f,g) + K + x;      \
+        temp2 = S2(a) + F0(a,b,c);                  \
+        d += temp1; h = temp1 + temp2;              \
+    }
+
+void core_sha256_process(core_sha256_context_t *ctx, const unsigned char data[64])
+{
+    uint32_t temp1, temp2, W[64];
+    uint32_t A[8];
+    unsigned int i;
+
+    for (i = 0; i < 8; i++) {
+        A[i] = ctx->state[i];
+    }
+
+#if defined(MINI_SHA256_SMALLER)
+    for (i = 0; i < 64; i++) {
+        if (i < 16) {
+            GET_UINT32_BE(W[i], data, 4 * i);
+        } else {
+            R(i);
+        }
+
+        P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i], K[i]);
+
+        temp1 = A[7];
+        A[7] = A[6];
+        A[6] = A[5];
+        A[5] = A[4];
+        A[4] = A[3];
+        A[3] = A[2];
+        A[2] = A[1];
+        A[1] = A[0];
+        A[0] = temp1;
+    }
+#else /* MINI_SHA256_SMALLER */
+    for (i = 0; i < 16; i++) {
+        GET_UINT32_BE(W[i], data, 4 * i);
+    }
+
+    for (i = 0; i < 16; i += 8) {
+        P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], W[i + 0], K[i + 0]);
+        P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], W[i + 1], K[i + 1]);
+        P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], W[i + 2], K[i + 2]);
+        P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], W[i + 3], K[i + 3]);
+        P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], W[i + 4], K[i + 4]);
+        P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], W[i + 5], K[i + 5]);
+        P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], W[i + 6], K[i + 6]);
+        P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], W[i + 7], K[i + 7]);
+    }
+
+    for (i = 16; i < 64; i += 8) {
+        P(A[0], A[1], A[2], A[3], A[4], A[5], A[6], A[7], R(i + 0), K[i + 0]);
+        P(A[7], A[0], A[1], A[2], A[3], A[4], A[5], A[6], R(i + 1), K[i + 1]);
+        P(A[6], A[7], A[0], A[1], A[2], A[3], A[4], A[5], R(i + 2), K[i + 2]);
+        P(A[5], A[6], A[7], A[0], A[1], A[2], A[3], A[4], R(i + 3), K[i + 3]);
+        P(A[4], A[5], A[6], A[7], A[0], A[1], A[2], A[3], R(i + 4), K[i + 4]);
+        P(A[3], A[4], A[5], A[6], A[7], A[0], A[1], A[2], R(i + 5), K[i + 5]);
+        P(A[2], A[3], A[4], A[5], A[6], A[7], A[0], A[1], R(i + 6), K[i + 6]);
+        P(A[1], A[2], A[3], A[4], A[5], A[6], A[7], A[0], R(i + 7), K[i + 7]);
+    }
+#endif /* MINI_SHA256_SMALLER */
+
+    for (i = 0; i < 8; i++) {
+        ctx->state[i] += A[i];
+    }
+}
+void core_sha256_update(core_sha256_context_t *ctx, const unsigned char *input, uint32_t ilen)
+{
+    size_t fill;
+    uint32_t left;
+
+    if (ilen == 0) {
+        return;
+    }
+
+    left = ctx->total[0] & 0x3F;
+    fill = 64 - left;
+
+    ctx->total[0] += (uint32_t) ilen;
+    ctx->total[0] &= 0xFFFFFFFF;
+
+    if (ctx->total[0] < (uint32_t) ilen) {
+        ctx->total[1]++;
+    }
+
+    if (left && ilen >= fill) {
+        memcpy((void *)(ctx->buffer + left), input, fill);
+        core_sha256_process(ctx, ctx->buffer);
+        input += fill;
+        ilen  -= fill;
+        left = 0;
+    }
+
+    while (ilen >= 64) {
+        core_sha256_process(ctx, input);
+        input += 64;
+        ilen  -= 64;
+    }
+
+    if (ilen > 0) {
+        memcpy((void *)(ctx->buffer + left), input, ilen);
+    }
+}
+
+static const unsigned char sha256_padding[64] = {
+    0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+void core_sha256_finish(core_sha256_context_t *ctx, uint8_t output[32])
+{
+    uint32_t last, padn;
+    uint32_t high, low;
+    unsigned char msglen[8];
+
+    high = (ctx->total[0] >> 29)
+           | (ctx->total[1] <<  3);
+    low  = (ctx->total[0] <<  3);
+
+    PUT_UINT32_BE(high, msglen, 0);
+    PUT_UINT32_BE(low,  msglen, 4);
+
+    last = ctx->total[0] & 0x3F;
+    padn = (last < 56) ? (56 - last) : (120 - last);
+
+    core_sha256_update(ctx, sha256_padding, padn);
+    core_sha256_update(ctx, msglen, 8);
+
+    PUT_UINT32_BE(ctx->state[0], output,  0);
+    PUT_UINT32_BE(ctx->state[1], output,  4);
+    PUT_UINT32_BE(ctx->state[2], output,  8);
+    PUT_UINT32_BE(ctx->state[3], output, 12);
+    PUT_UINT32_BE(ctx->state[4], output, 16);
+    PUT_UINT32_BE(ctx->state[5], output, 20);
+    PUT_UINT32_BE(ctx->state[6], output, 24);
+
+    if (ctx->is224 == 0) {
+        PUT_UINT32_BE(ctx->state[7], output, 28);
+    }
+}
+
+void core_sha256(const uint8_t *input, uint32_t ilen, uint8_t output[32])
+{
+    core_sha256_context_t ctx;
+
+    core_sha256_init(&ctx);
+    core_sha256_starts(&ctx);
+    core_sha256_update(&ctx, input, ilen);
+    core_sha256_finish(&ctx, output);
+    core_sha256_free(&ctx);
+}
+
+void core_hmac_sha256(const uint8_t *msg, uint32_t msg_len, const uint8_t *key, uint32_t key_len, uint8_t output[32])
+{
+    core_sha256_context_t context;
+    uint8_t k_ipad[SHA256_KEY_IOPAD_SIZE];    /* inner padding - key XORd with ipad  */
+    uint8_t k_opad[SHA256_KEY_IOPAD_SIZE];    /* outer padding - key XORd with opad */
+    int32_t i;
+
+    if ((NULL == msg) || (NULL == key) || (NULL == output)) {
+        return;
+    }
+
+    if (key_len > SHA256_KEY_IOPAD_SIZE) {
+        return;
+    }
+
+    /* start out by storing key in pads */
+    memset(k_ipad, 0, sizeof(k_ipad));
+    memset(k_opad, 0, sizeof(k_opad));
+    memcpy(k_ipad, key, key_len);
+    memcpy(k_opad, key, key_len);
+
+    /* XOR key with ipad and opad values */
+    for (i = 0; i < SHA256_KEY_IOPAD_SIZE; i++) {
+        k_ipad[i] ^= 0x36;
+        k_opad[i] ^= 0x5c;
+    }
+
+    /* perform inner SHA */
+    core_sha256_init(&context);                                      /* init context for 1st pass */
+    core_sha256_starts(&context);                                    /* setup context for 1st pass */
+    core_sha256_update(&context, k_ipad, SHA256_KEY_IOPAD_SIZE);     /* start with inner pad */
+    core_sha256_update(&context, msg, msg_len);                      /* then text of datagram */
+    core_sha256_finish(&context, output);                            /* finish up 1st pass */
+
+    /* perform outer SHA */
+    core_sha256_init(&context);                              /* init context for 2nd pass */
+    core_sha256_starts(&context);                            /* setup context for 2nd pass */
+    core_sha256_update(&context, k_opad, SHA256_KEY_IOPAD_SIZE);    /* start with outer pad */
+    core_sha256_update(&context, output, SHA256_DIGEST_SIZE);     /* then results of 1st hash */
+    core_sha256_finish(&context, output);                       /* finish up 2nd pass */
+}
+
+int32_t core_hex2str(uint8_t *input, uint32_t input_len, char *output, uint8_t lowercase)
+{
+    char *upper = "0123456789ABCDEF";
+    char *lower = "0123456789abcdef";
+    char *encode = upper;
+    int i = 0, j = 0;
+
+    if (lowercase) {
+        encode = lower;
+    }
+
+    for (i = 0; i < input_len; i++) {
+        output[j++] = encode[(input[i] >> 4) & 0xf];
+        output[j++] = encode[(input[i]) & 0xf];
+    }
+
+    return 0;
+}
+
+
diff --git a/mbtk/mbtk_mqtt/MQTTPacket/core_sha256.h b/mbtk/mbtk_mqtt/MQTTPacket/core_sha256.h
new file mode 100755
index 0000000..2141941
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/core_sha256.h
@@ -0,0 +1,86 @@
+#ifndef _CORE_SHA256_H_
+#define _CORE_SHA256_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "core_stdinc.h"
+
+#define CORE_SHA256_DIGEST_LENGTH            (32)
+#define CORE_SHA256_BLOCK_LENGTH             (64)
+#define CORE_SHA256_SHORT_BLOCK_LENGTH       (CORE_SHA256_BLOCK_LENGTH - 8)
+#define CORE_SHA256_DIGEST_STRING_LENGTH     (CORE_SHA256_DIGEST_LENGTH * 2 + 1)
+
+/**
+ * \brief          SHA-256 context structure
+ */
+typedef struct {
+    uint32_t total[2];          /*!< number of bytes processed  */
+    uint32_t state[8];          /*!< intermediate digest state  */
+    unsigned char buffer[64];   /*!< data block being processed */
+    uint8_t is224;                  /*!< 0 => SHA-256, else SHA-224 */
+} core_sha256_context_t;
+
+/**
+ * \brief          Initialize SHA-256 context
+ *
+ * \param ctx      SHA-256 context to be initialized
+ */
+void core_sha256_init(core_sha256_context_t *ctx);
+
+/**
+ * \brief          Clear SHA-256 context
+ *
+ * \param ctx      SHA-256 context to be cleared
+ */
+void core_sha256_free(core_sha256_context_t *ctx);
+
+
+/**
+ * \brief          SHA-256 context setup
+ *
+ * \param ctx      context to be initialized
+ */
+void core_sha256_starts(core_sha256_context_t *ctx);
+
+/**
+ * \brief          SHA-256 process buffer
+ *
+ * \param ctx      SHA-256 context
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ */
+void core_sha256_update(core_sha256_context_t *ctx, const unsigned char *input, uint32_t ilen);
+
+/**
+ * \brief          SHA-256 final digest
+ *
+ * \param ctx      SHA-256 context
+ * \param output   SHA-256 checksum result
+ */
+void core_sha256_finish(core_sha256_context_t *ctx, uint8_t output[32]);
+
+/* Internal use */
+void core_sha256_process(core_sha256_context_t *ctx, const unsigned char data[64]);
+
+/**
+ * \brief          Output = SHA-256( input buffer )
+ *
+ * \param input    buffer holding the  data
+ * \param ilen     length of the input data
+ * \param output   SHA-256 checksum result
+ */
+void core_sha256(const uint8_t *input, uint32_t ilen, uint8_t output[32]);
+
+void core_hmac_sha256(const uint8_t *msg, uint32_t msg_len, const uint8_t *key, uint32_t key_len, uint8_t output[32]);
+
+int core_hex2str(uint8_t *input, uint32_t input_len, char *output, uint8_t lowercase);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/mbtk/mbtk_mqtt/MQTTPacket/core_stdinc.h b/mbtk/mbtk_mqtt/MQTTPacket/core_stdinc.h
new file mode 100755
index 0000000..d58acbc
--- /dev/null
+++ b/mbtk/mbtk_mqtt/MQTTPacket/core_stdinc.h
@@ -0,0 +1,16 @@
+#ifndef _CORE_STDINC_H_
+#define _CORE_STDINC_H_
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <string.h>
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
diff --git a/mbtk/mbtk_mqtt/Makefile b/mbtk/mbtk_mqtt/Makefile
new file mode 100755
index 0000000..9102863
--- /dev/null
+++ b/mbtk/mbtk_mqtt/Makefile
@@ -0,0 +1,44 @@
+ROOT = $(shell pwd)/../..
+include ../Make.defines
+
+LOCAL_PATH=$(BUILD_ROOT)/mbtk_mqtt
+
+INC_DIR += -I. \
+	-I$(LOCAL_PATH)/MQTTPacket
+
+LIB_DIR +=
+
+LIBS += -llog -lmbtk_lib
+
+CFLAGS += -shared -Wl,-shared,-Bsymbolic
+
+DEFINE +=
+
+MY_FILES_PATH:=$(LOCAL_PATH)
+#MY_FILES_PATH += $(LOCAL_PATH)/MQTTPacket
+
+#ifeq ($(CONFIG_MBTK_QL_SUPPORT),y)
+#MY_FILES_PATH += $(LOCAL_PATH)/ql
+#endif
+
+#ifeq ($(CONFIG_MBTK_PLATFORM),linux)
+#MY_FILES_PATH += $(LOCAL_PATH)/platform/linux
+#endif
+
+MY_FILES_SUFFIX:=%.c %.cpp
+My_All_Files := $(foreach src_path,$(MY_FILES_PATH), $(shell find "$(src_path)" -type f))
+MY_SRC_LIST  := $(filter $(MY_FILES_SUFFIX),$(My_All_Files))
+MY_SRC_LIST  := $(MY_SRC_LIST:$(LOCAL_PATH)/%=%)
+LOCAL_SRC_FILES += $(MY_SRC_LIST)
+$(info LOCAL_SRC_FILES = $(LOCAL_SRC_FILES))
+
+dtarget := $(OUT_DIR)/lib/libmbtk_mqtt_lib.so
+
+all: $(dtarget)
+
+$(dtarget):
+	$(CC) $(CFLAGS) $(LOCAL_SRC_FILES) -o $@ $(DEFINE) $(INC_DIR) $(LIB_DIR) $(LIBS)
+
+clean:
+	
+
diff --git a/mbtk/mbtk_mqtt/mbtk_mqtt.c b/mbtk/mbtk_mqtt/mbtk_mqtt.c
new file mode 100755
index 0000000..3af31f2
--- /dev/null
+++ b/mbtk/mbtk_mqtt/mbtk_mqtt.c
@@ -0,0 +1,669 @@
+/*************************************************************************
+	> File Name: main.c
+	> Author: LFJ
+	> Mail: 
+	> Created Time: 2018年09月05日 星期三 13时48分17秒
+ ************************************************************************/
+
+#include <stdio.h>
+
+#include "MQTTClient.h"
+#include "mbtk_mqtt.h"
+#include "pthread.h"
+#include "string.h"
+#include "unistd.h"
+#include "sys/stat.h"
+#include "sys/types.h"
+#include "sys/socket.h"
+#include "netinet/in.h"
+#include "arpa/inet.h"
+#include "fcntl.h"
+#include "mbtk_sock2.h"
+
+#include "mbtk_type.h"
+#include "mbtk_http.h"
+
+/*
+static Cloud_MQTT_t *iot_mqtt;
+
+void set_mqtt_t(Cloud_MQTT_t *piot_mqtt)
+{
+    iot_mqtt = piot_mqtt;
+}
+Cloud_MQTT_t * get_mqtt_t()
+{
+    return iot_mqtt;
+}
+*/
+
+extern regnwl_info_t regnwl_info;
+
+
+#define CORE_AUTH_SDK_VERSION "sdk-c-4.1.0"
+#define CORE_AUTH_TIMESTAMP   "2524608000000"
+#define MBTK_MQTT_HTTP_AUTH_PATH               "/auth/register/device"
+#define MBTK_MQTT_HTTP_SIGN_METHOD_HMACSHA256  "hmacsha256"
+
+
+const char * mqtt_url[7] = {
+                   "iot-as-mqtt.cn-shanghai.aliyuncs.com",        /* Shanghai */
+                   "iot-as-mqtt.ap-southeast-1.aliyuncs.com",    /* Singapore */
+                    "iot-as-mqtt.ap-northeast-1.aliyuncs.com",    /* Japan */
+                    "iot-as-mqtt.us-west-1.aliyuncs.com",         /* America */
+                    "iot-as-mqtt.eu-central-1.aliyuncs.com",      /* Germany */
+                    "118.114.239.159",      /* me */
+                    NULL,                                         /* Custom */
+   };
+
+
+const char    *http_host[6] = {
+    "iot-auth.cn-shanghai.aliyuncs.com",          /* Shanghai */
+    "iot-auth.ap-southeast-1.aliyuncs.com",      /* Singapore */
+    "iot-auth.ap-northeast-1.aliyuncs.com",      /* Japan */
+    "iot-auth.us-west-1.aliyuncs.com",           /* America */
+    "iot-auth.eu-central-1.aliyuncs.com",         /* Germany */
+    NULL,                                         /* Custom */
+ };
+
+mbtk_mqtt_device_session_t mbtk_mqtt_device ={0};
+
+
+char mbtk_mqtt_http_url[255] ={0};
+char mbtk_mqtt_http_content[1024] ={0};
+
+char Device_Secret[255] = {0};
+
+
+int mbtk_imqtt_http_dynreg_sign(char *product_key,char* product_secret,char*device_name,char* random,char* sign)
+{
+    int sign_source_len = 0;
+    uint8_t signnum[32];
+    uint8_t  *sign_source = NULL;
+    const char *dynamic_register_sign_fmt = "deviceName%sproductKey%srandom%s";
+
+    /* Start Dynamic Register */
+    /* Calculate SHA256 Value */
+    sign_source_len = strlen(dynamic_register_sign_fmt) + strlen(device_name) + strlen(product_key) + strlen(random) + 1;
+    sign_source = malloc(sign_source_len);
+    if (sign_source == NULL)
+    {
+        return -1;
+    }
+    memset(sign_source, 0, sign_source_len);
+    snprintf((char *)sign_source, sign_source_len, dynamic_register_sign_fmt, device_name, product_key, random);
+
+    core_hmac_sha256(sign_source, strlen((const char *)sign_source), (uint8_t *)product_secret, strlen(product_secret),
+                      signnum);
+    core_hex2str(signnum, 32, sign,0);
+    free(sign_source);
+    sign_source = NULL;
+
+    return 0;
+
+}
+
+
+int mbtk_imqtt_send_post_request(char *product_key, char *product_secret, char *device_name, int host)
+{
+
+    printf("product_key: %s\n", product_key);
+    printf("product_secret: %s\n", product_secret);
+    printf("device_name: %s\n", device_name);
+
+    int32_t res = 0, content_len = 0;
+    char content[255] = {0};
+    char random[15+1]={0};;
+    char  sign[65] = {0};
+    int dynamic_register_request_len = 0;
+//    char *content_fmt = "productKey=%s&deviceName=%s&random=%s&sign=%s&signMethod=%s";
+    char *signMethod = MBTK_MQTT_HTTP_SIGN_METHOD_HMACSHA256;
+
+
+    memcpy(random, "8Ygb7ULYh53B6OA", strlen("8Ygb7ULYh53B6OA"));
+    char *content_src[] = { product_key, device_name, random,sign,signMethod};
+    mbtk_imqtt_http_dynreg_sign(product_key,product_secret,device_name,random,sign);
+
+    sprintf(content, "productKey=%s&deviceName=%s&random=%s&sign=%s&signMethod=%s",
+                    product_key, device_name, random, sign, MBTK_MQTT_HTTP_SIGN_METHOD_HMACSHA256);
+
+    memset(mbtk_mqtt_http_url, 0, sizeof(mbtk_mqtt_http_url));
+    sprintf(mbtk_mqtt_http_url, "https://%s:443/auth/register/device", http_host[host]);
+
+    memset(mbtk_mqtt_http_content, 0, sizeof(mbtk_mqtt_http_content));
+    memcpy(mbtk_mqtt_http_content, content, strlen(content));
+
+    printf("mbtk_mqtt_http_url:%s\n", mbtk_mqtt_http_url);
+    printf("mbtk_mqtt_http_content:%s\n", mbtk_mqtt_http_content);
+
+    return 0;
+}
+
+void mbtk_mqt_http_device_secret_response(void *data,int data_len)
+{
+    if(data != NULL && data_len != 0)
+    {
+        char* ptr_start = NULL;
+        char* ptr_end = NULL;
+        char fac[64] = {'\0'};
+        ptr_start = strstr(data, "deviceSecret");
+        if(ptr_start != NULL)
+        {
+            ptr_end = strstr(ptr_start, "\",");
+            if(ptr_end != NULL)
+            {
+                strncpy(Device_Secret, ptr_start + 15, ptr_end - ptr_start - 15);
+                printf("device_secret:%s\n", Device_Secret);
+            }
+            printf("ptr_start:%s,\n ptr_end:%s\n", ptr_start, ptr_end);
+        }
+
+    }
+
+	return;
+}
+
+
+static void mbtk_mqtt_http_data_cb_func(
+    int session_id, mbtk_http_data_type_enum type,
+    void *data,int data_len)
+{
+    if(type == MBTK_HTTP_DATA_HEADER) {
+        printf("Header(%d):%s\n",data_len,(char*)data);
+        mbtk_mqt_http_device_secret_response((char*)data, data_len);
+    } else if(type == MBTK_HTTP_DATA_CONTENT) {
+        printf("Data(%d):%s\n",data_len,(char*)data);
+        mbtk_mqt_http_device_secret_response((char*)data, data_len);
+    } else {
+        printf(">>>>>Complete<<<<<\n");
+    }
+}
+
+int mbtk_aliyun_mqtt_one_type_one_secret_regint_get_info(mbtk_mqtt_device_session_t *mbtk_mqtt_device_t)
+{
+    printf("mbtk_mqtt_http_request    1111111");
+    char product_key[255] = {0};
+    char product_secret[255] = {0};
+    char device_name[255] = {0};
+
+    int http_handle = mbtk_http_handle_get(TRUE, mbtk_mqtt_http_data_cb_func);
+    if(http_handle < 0)
+    {
+        printf("mbtk_http_handle_get() fail.");
+        return -1;
+    }
+
+    int http_session = mbtk_http_session_create(http_handle,HTTP_OPTION_POST,HTTP_VERSION_1_1);
+    if(http_handle < 0)
+    {
+        printf("mbtk_http_session_create() fail.");
+        return -1;
+    }
+
+//    mbtk_http_session_option_reset(http_handle, http_session , HTTP_OPTION_HEAD_ONLY);
+//    mbtk_http_session_option_reset(http_handle, http_session , HTTP_OPTION_POST);
+
+    memcpy(product_key, mbtk_mqtt_device_t->product_key, strlen(mbtk_mqtt_device_t->product_key));
+    memcpy(product_secret, mbtk_mqtt_device_t->product_secret, strlen(mbtk_mqtt_device_t->product_secret));
+    memcpy(device_name, mbtk_mqtt_device_t->device_name, strlen(mbtk_mqtt_device_t->device_name));
+
+    mbtk_imqtt_send_post_request(product_key, product_secret,device_name, 0);
+
+    if(mbtk_http_session_url_set(http_handle, http_session, mbtk_mqtt_http_url)) {
+        printf("mbtk_http_session_url_set() fail.\n");
+        return -1;
+    }
+
+    const mbtk_http_session_t* session = mbtk_http_session_get(http_handle, http_session);
+    printf("HTTP:%d,%s,%d,%s\n",session->option,session->host,session->port,session->uri);
+
+    char *header = "Accept: text/xml,text/javascript,text/html,application/json\r\n" \
+                          "Content-Type: application/x-www-form-urlencoded\r\n";
+
+
+    mbtk_http_session_head_add(http_handle, http_session, "Accept", "text/xml,text/javascript,text/html,application/json");
+
+    mbtk_http_session_head_add(http_handle, http_session, "Content-Type", "application/x-www-form-urlencoded");
+
+    mbtk_http_session_content_set(http_handle, http_session, mbtk_mqtt_http_content, strlen(mbtk_mqtt_http_content) );
+
+//    mbtk_http_session_option_reset(http_handle, http_session , HTTP_OPTION_HEAD_ONLY);
+//    mbtk_http_session_option_reset(http_handle, http_session , HTTP_OPTION_POST);
+
+    memset(Device_Secret, 0, sizeof(Device_Secret));
+    if(mbtk_http_session_start(http_handle, http_session)) {
+        printf("mbtk_http_session_start() fail.\n");
+        return -1;
+    }
+
+    if(mbtk_http_handle_free(http_handle))
+    {
+        printf("mbtk_http_handle_free() fail.");
+        return -1;
+    }
+
+    if(strlen(Device_Secret ) > 0)
+    {
+        printf("\nstrlen(Device_Secret :%d\n )", strlen(Device_Secret ));
+        memcpy(mbtk_mqtt_device_t->device_secret,Device_Secret, strlen(Device_Secret) );
+    }else{
+        printf("get Device_Secret fail\n");
+        return -1;
+    }
+
+    printf("MBTK_HTTP exit.");
+    return 0;
+
+}
+
+
+void mbtk_aliyun_mqtt_get_connect_para(char *password,char *cliendid,char *username, mbtk_mqtt_device_session_t *mbtk_mqtt_device_t)
+{
+  /*********password.mqttClientId.user_name *************/
+    char content[MBTK_IMQTT_PASSWORD_LEN] = {0};
+
+    printf("mbtk_mqtt_device_t->device_name: %s\n", mbtk_mqtt_device_t->device_name);
+    printf("mbtk_mqtt_device_t->product_key: %s\n", mbtk_mqtt_device_t->product_key);
+    printf("mbtk_mqtt_device_t->product_secret: %s\n", mbtk_mqtt_device_t->product_secret);
+
+    sprintf(content,"deviceName%sproductKey%srandom123",mbtk_mqtt_device_t->device_name,mbtk_mqtt_device_t->product_key);
+    core_hmac_sha1((const char*)content,strlen((const char*)content),(char *)password,mbtk_mqtt_device_t->product_secret,strlen(mbtk_mqtt_device_t->product_secret));
+
+
+//    snprintf((char *)cliendid,MBTK_IMQTT_CLIENT_ID_LEN,"%s|securemode=-2,authType=regnwl,random=123,signmethod=hmacsha1,instanceId=%s|",mbtk_mqtt_device_t->device_name,"iot-06z00ag5qidat54");
+
+    snprintf((char *)cliendid,MBTK_IMQTT_CLIENT_ID_LEN,"%s|securemode=-2,authType=regnwl,random=123,signmethod=hmacsha1|",mbtk_mqtt_device_t->device_name);
+    snprintf((char *)username,MBTK_IMQTT_USER_NAME_LEN,"%s&%s",mbtk_mqtt_device_t->device_name,mbtk_mqtt_device_t->product_key);
+}
+
+
+void mbtk_imqtt_auth_hostname(char *dest, char *product_key, int host)
+{
+//  char *host = "&product_key.iot-as-mqtt.cn-shanghai.aliyuncs.com";
+    int8_t      public_instance = 1;
+
+    snprintf(dest, 100, "%s.%s", product_key, mqtt_url[host]);
+}
+
+
+void mbtk_imqtt_auth_clientid(char *dest,char *product_key, char *device_name)
+{
+//	char *clientid = "gyj01ZAd7HF.MATT1|securemode=3,signmethod=hmacsha256,timestamp=1647830635443|";
+
+    sprintf(dest, "%s.%s|securemode=3,signmethod=hmacsha256,timestamp=%s|", product_key,device_name,CORE_AUTH_TIMESTAMP);
+}
+
+void mbtk_imqtt_auth_clientid_yixinyimi_unregin(char *dest,char *client_id)
+{
+//	char *clientid = "client_id|securemode=-2,authType=connwl|";
+
+    sprintf(dest, "%s|securemode=-2,authType=connwl|", client_id);
+
+}
+
+
+void mbtk_aliyun_imqtt_auth_clientid(char *dest, char *product_key, char *device_name)
+{
+
+    sprintf(dest, "%s.%s|timestamp=%s,_ss=1,_v=%s,securemode=2,signmethod=hmacsha256,ext=3|", product_key,device_name,CORE_AUTH_TIMESTAMP,CORE_AUTH_SDK_VERSION);
+
+    //instanceId 实例id
+//    sprintf(dest, "%s.%s|timestamp=%s,_ss=1,_v=%s,securemode=2,signmethod=hmacsha256,ext=3,instanceId=%s|", product_key,device_name,CORE_AUTH_TIMESTAMP,CORE_AUTH_SDK_VERSION,"iot-06z00ag5qidat54");
+}
+
+
+void mbtk_imqtt_auth_username(char *dest,char *device_name, char *product_key)
+{
+	//data.username.cstring="$deviceName&$productKey";
+
+    snprintf(dest,128, "%s&%s", device_name, product_key );
+}
+
+void mbtk_imqtt_auth_password(char *dest, char *device_name, char *product_key, char *device_secret)
+{
+//	> data.password.cstring=hmacsha1($deviceSecret,$content);
+//	$content为productKey,deviceName,timestamp,clientId按照手母顺序排序,然后将参数值依次拼接例如
+
+
+    char content[300] = {0};
+    uint8_t source_temp[65]={0};
+    sprintf(content,"clientId%s.%sdeviceName%sproductKey%stimestamp%s",product_key, device_name, device_name, product_key,CORE_AUTH_TIMESTAMP);
+	
+//    sprintf(content,"clientId%sdeviceName%sproductKey%stimestamp%s",client_id, device_name, product_key,CORE_AUTH_TIMESTAMP);
+    core_hmac_sha256((uint8_t *)content, strlen((const char *)content), (uint8_t *)device_secret, strlen(device_secret),
+                      source_temp);
+		  
+    core_hex2str(source_temp, 32, dest,0);
+}
+
+void iot_aliyun_mqtt_init(Cloud_MQTT_t *piot_mqtt,int host,int port ,char *device_name,char *product_key, 
+		char * DeviceSecret,int keepAliveInterval,int version,char *sub_topic,char *pub_topic,pMessageArrived_Fun mqtt_data_rx_cb) 
+{
+    mbtk_imqtt_auth_hostname(piot_mqtt->mqtt_host,product_key,host);
+    mbtk_imqtt_auth_clientid(piot_mqtt->mqtt_client_id,product_key,device_name);
+    mbtk_imqtt_auth_username(piot_mqtt->mqtt_user,device_name,product_key);
+    mbtk_imqtt_auth_password(piot_mqtt->mqtt_pass,device_name,product_key,DeviceSecret);
+    piot_mqtt->mqtt_port = port;
+    piot_mqtt->keepAliveInterval = keepAliveInterval;
+    //    piot_mqtt->mqtt_version = version;
+    piot_mqtt->mqtt_version = 3;
+
+    printf("mqtt_host is %s\nmqtt_port is %d\nmqtt_client_id is %s\nmqtt_user is %s\nmqtt_pass is %s\n",piot_mqtt->mqtt_host,piot_mqtt->mqtt_port,piot_mqtt->mqtt_client_id,piot_mqtt->mqtt_user,piot_mqtt->mqtt_pass);
+    memset(piot_mqtt->sub_topic, '\0', MQTT_TOPIC_SIZE);
+    memset(piot_mqtt->pub_topic, '\0', MQTT_TOPIC_SIZE);
+    
+    sprintf(piot_mqtt->sub_topic, "%s", sub_topic);	//将初始化好的订阅主题填到数组中
+    printf("subscribe:%s\n", piot_mqtt->sub_topic);
+
+    sprintf(piot_mqtt->pub_topic, "%s", pub_topic);	//将初始化好的发布主题填到数组中
+    printf("pub:%s\n", piot_mqtt->pub_topic);
+    
+    piot_mqtt->DataArrived_Cb = mqtt_data_rx_cb;		//设置接收到数据回调函数
+    printf("iot_mqtt_init end\n");
+}
+
+void mbtk_aliyun_mqtt_one_type_one_secret_unregin_set_info_init(Cloud_MQTT_t *piot_mqtt,mbtk_mqtt_device_session_t *device,int keepAliveInterval,int version,pMessageArrived_Fun mqtt_data_rx_cb) 
+{
+
+    mbtk_imqtt_auth_hostname(piot_mqtt->mqtt_host,device->product_key,device->host);
+    mbtk_aliyun_mqtt_get_connect_para(piot_mqtt->mqtt_pass, piot_mqtt->mqtt_client_id, piot_mqtt->mqtt_user, device);
+
+    piot_mqtt->mqtt_port = device->port;
+    piot_mqtt->keepAliveInterval = keepAliveInterval;
+    piot_mqtt->mqtt_version = version;
+
+    printf("mqtt_host is %s\nmqtt_port is %d\nmqtt_client_id is %s\nmqtt_user is %s\nmqtt_pass is %s\n",piot_mqtt->mqtt_host,piot_mqtt->mqtt_port,piot_mqtt->mqtt_client_id,piot_mqtt->mqtt_user,piot_mqtt->mqtt_pass);
+    printf("piot_mqtt->mqtt_version:%d\n", piot_mqtt->mqtt_version);
+    memset(piot_mqtt->sub_topic, '\0', MQTT_TOPIC_SIZE);
+    memset(piot_mqtt->pub_topic, '\0', MQTT_TOPIC_SIZE);
+    
+    piot_mqtt->DataArrived_Cb = mqtt_data_rx_cb;		//设置接收到数据回调函数
+    printf("iot_mqtt_init end\n");
+}
+
+int mbtk_aliyun_mqtt_one_type_one_secret_unregin_get_regin_info(char *clientId, char *deviceToken)
+{
+    int ret = 0;
+    if(strlen(regnwl_info.deviceToken) > 5)
+    {
+        memcpy(clientId, regnwl_info.clientId, strlen(regnwl_info.clientId));
+        memcpy(deviceToken, regnwl_info.deviceToken , strlen(regnwl_info.deviceToken));
+    }else{
+        ret=  -1;
+    }
+
+    printf("regnwl_info.clientId:%s\n", regnwl_info.clientId);
+    printf("regn->deviceToken:%s\n", regnwl_info.deviceToken);
+    return ret;
+}
+
+
+void iot_aliyun_mqtt_one_type_one_secret_unregin_connect_init(Cloud_MQTT_t *piot_mqtt,mbtk_mqtt_device_session_t *device, char *clientId, char *deviceToken,
+         int keepAliveInterval,int version,char *sub_topic,char *pub_topic,pMessageArrived_Fun mqtt_data_rx_cb) 
+{
+    mbtk_imqtt_auth_hostname(piot_mqtt->mqtt_host,device->product_key,device->host);
+    mbtk_imqtt_auth_clientid_yixinyimi_unregin(piot_mqtt->mqtt_client_id, clientId);
+    mbtk_imqtt_auth_username(piot_mqtt->mqtt_user,device->device_name,device->product_key);
+    sprintf(piot_mqtt->mqtt_pass, "%s", deviceToken);
+    piot_mqtt->mqtt_port = device->port;
+    piot_mqtt->keepAliveInterval = keepAliveInterval;
+    //    piot_mqtt->mqtt_version = version;
+    piot_mqtt->mqtt_version = 3;
+
+    printf("mqtt_host is %s\nmqtt_port is %d\nmqtt_client_id is %s\nmqtt_user is %s\nmqtt_pass is %s\n",piot_mqtt->mqtt_host,piot_mqtt->mqtt_port,piot_mqtt->mqtt_client_id,piot_mqtt->mqtt_user,piot_mqtt->mqtt_pass);
+    memset(piot_mqtt->sub_topic, '\0', MQTT_TOPIC_SIZE);
+    memset(piot_mqtt->pub_topic, '\0', MQTT_TOPIC_SIZE);
+    
+    sprintf(piot_mqtt->sub_topic, "%s", sub_topic);	//将初始化好的订阅主题填到数组中
+    printf("subscribe:%s\n", piot_mqtt->sub_topic);
+
+    sprintf(piot_mqtt->pub_topic, "%s", pub_topic);	//将初始化好的发布主题填到数组中
+    printf("pub:%s\n", piot_mqtt->pub_topic);
+    
+    piot_mqtt->DataArrived_Cb = mqtt_data_rx_cb;		//设置接收到数据回调函数
+    printf("iot_mqtt_init end\n");
+}
+
+
+void mbtk_aliyun_mqtt_one_type_one_secret_regint_connect_init(Cloud_MQTT_t *piot_mqtt,int host,int port ,char *device_name,char *product_key, 
+		char * DeviceSecret,int keepAliveInterval,int version,char *sub_topic,char *pub_topic,pMessageArrived_Fun mqtt_data_rx_cb) 
+{
+    mbtk_imqtt_auth_hostname(piot_mqtt->mqtt_host,product_key,host);
+    mbtk_aliyun_imqtt_auth_clientid(piot_mqtt->mqtt_client_id,product_key,device_name);
+    mbtk_imqtt_auth_username(piot_mqtt->mqtt_user,device_name,product_key);
+    mbtk_imqtt_auth_password(piot_mqtt->mqtt_pass,device_name,product_key,DeviceSecret);
+    piot_mqtt->mqtt_port = port;
+    piot_mqtt->keepAliveInterval = keepAliveInterval;
+    //    piot_mqtt->mqtt_version = version;
+    piot_mqtt->mqtt_version = 3;
+
+    printf("mqtt_host is %s\nmqtt_port is %d\nmqtt_client_id is %s\nmqtt_user is %s\nmqtt_pass is %s\n",piot_mqtt->mqtt_host,piot_mqtt->mqtt_port,piot_mqtt->mqtt_client_id,piot_mqtt->mqtt_user,piot_mqtt->mqtt_pass);
+    memset(piot_mqtt->sub_topic, '\0', MQTT_TOPIC_SIZE);
+    memset(piot_mqtt->pub_topic, '\0', MQTT_TOPIC_SIZE);
+    
+    sprintf(piot_mqtt->sub_topic, "%s", sub_topic);	//将初始化好的订阅主题填到数组中
+    printf("subscribe:%s\n", piot_mqtt->sub_topic);
+
+    sprintf(piot_mqtt->pub_topic, "%s", pub_topic);	//将初始化好的发布主题填到数组中
+    printf("pub:%s\n", piot_mqtt->pub_topic);
+    
+    piot_mqtt->DataArrived_Cb = mqtt_data_rx_cb;		//设置接收到数据回调函数
+    printf("iot_mqtt_init end\n");
+}
+
+
+void iot_mqtt_init(Cloud_MQTT_t *piot_mqtt,char *host,int port ,char *clientid,char *user,char *pass,int keepAliveInterval,int version,char *sub_topic,char *pub_topic,pMessageArrived_Fun mqtt_data_rx_cb) 
+{
+
+    memcpy(piot_mqtt->mqtt_host,host,strlen(host));
+    memcpy(piot_mqtt->mqtt_client_id,clientid,strlen(clientid));
+    memcpy(piot_mqtt->mqtt_user,user,strlen(user));
+    memcpy(piot_mqtt->mqtt_pass,pass,strlen(pass));
+    piot_mqtt->mqtt_port = port;
+    piot_mqtt->keepAliveInterval = keepAliveInterval;
+    piot_mqtt->mqtt_version = version;
+
+    
+    printf("mqtt_host is %s\nmqtt_port is %d\nmqtt_client_id is %s\nmqtt_user is %s\nmqtt_pass is %s\n",piot_mqtt->mqtt_host,piot_mqtt->mqtt_port,piot_mqtt->mqtt_client_id,piot_mqtt->mqtt_user,piot_mqtt->mqtt_pass);
+    memset(piot_mqtt->sub_topic, '\0', MQTT_TOPIC_SIZE);
+    memset(piot_mqtt->pub_topic, '\0', MQTT_TOPIC_SIZE);
+    
+    sprintf(piot_mqtt->sub_topic, "%s", sub_topic);	//将初始化好的订阅主题填到数组中
+    printf("subscribe:%s\n", piot_mqtt->sub_topic);
+
+    sprintf(piot_mqtt->pub_topic, "%s", pub_topic);	//将初始化好的发布主题填到数组中
+    printf("pub:%s\n", piot_mqtt->pub_topic);
+    
+    piot_mqtt->DataArrived_Cb = mqtt_data_rx_cb;		//设置接收到数据回调函数
+    printf("iot_mqtt_init end\n");
+}
+/*
+void MQTTMessageArrived_Cb(MessageData* md)
+{
+    MQTTMessage *message = md->message; 
+
+    Cloud_MQTT_t *piot_mqtt = get_mqtt_t();
+
+    if (NULL != piot_mqtt->DataArrived_Cb) {
+        piot_mqtt->DataArrived_Cb((void *)message->payload, message->payloadlen);//异步消息体
+    }
+}
+*/
+
+int mbtk_aliyun_mqtt_one_type_one_secret_unregin_device_connect(Cloud_MQTT_t *piot_mqtt)
+{
+    int rc = 0, ret = 0;
+    Network* network = (Network*)malloc(sizeof(Network));
+    memset(network ,0x0, sizeof(Network));
+    NewNetwork(network);
+    piot_mqtt->network = network;
+
+    printf("topic = %s\n", piot_mqtt->sub_topic);
+//    set_mqtt_t(piot_mqtt);
+    piot_mqtt->network->is_support_ssl = 1;
+    printf("23131mqtt_host is %s\nmqtt_port is %d\nmqtt_client_id is %s\nmqtt_user is %s\nmqtt_pass is %s\n",piot_mqtt->mqtt_host,piot_mqtt->mqtt_port,piot_mqtt->mqtt_client_id,piot_mqtt->mqtt_user,piot_mqtt->mqtt_pass);
+    rc = ConnectNetwork(piot_mqtt->network, piot_mqtt->mqtt_host, piot_mqtt->mqtt_port,piot_mqtt->network->is_support_ssl,piot_mqtt->network->ingnore_cert);
+    if (rc != 0) {
+        ret = -101;
+        goto __END;
+    }
+    MQTTClient(&piot_mqtt->Client, piot_mqtt->network, 1000*30, piot_mqtt->mqtt_buffer, MQTT_BUF_SIZE, piot_mqtt->mqtt_read_buffer, MQTT_BUF_SIZE);
+    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+
+    data.MQTTVersion = piot_mqtt->mqtt_version;
+    data.clientID.cstring = piot_mqtt->mqtt_client_id;
+    data.username.cstring = piot_mqtt->mqtt_user;
+    data.password.cstring = piot_mqtt->mqtt_pass;
+    data.keepAliveInterval = piot_mqtt->keepAliveInterval;
+    data.willFlag = 0;
+    data.will.qos = 0;
+    data.will.retained     =                    0;
+    data.will.topicName.cstring =            NULL;
+    data.will.message.cstring   =            NULL;
+
+    data.cleansession = 1;
+    rc = MQTTConnect(&piot_mqtt->Client, &data);
+    if (rc) {
+        printf("mqtt connect broker fail \n");
+        printf("rc = %d\n", rc);
+        ret = -102;
+        goto __END;
+    }
+__END:
+    return ret;
+}
+
+int mqtt_device_connect(Cloud_MQTT_t *piot_mqtt)
+{
+    int rc = 0, ret = 0;
+    Network* network = (Network*)malloc(sizeof(Network));
+    memset(network ,0x0, sizeof(Network));
+    NewNetwork(network);
+    piot_mqtt->network = network;
+
+    printf("topic = %s\n", piot_mqtt->sub_topic);
+//    set_mqtt_t(piot_mqtt);
+    printf("23131mqtt_host is %s\nmqtt_port is %d\nmqtt_client_id is %s\nmqtt_user is %s\nmqtt_pass is %s\n",piot_mqtt->mqtt_host,piot_mqtt->mqtt_port,piot_mqtt->mqtt_client_id,piot_mqtt->mqtt_user,piot_mqtt->mqtt_pass);
+    rc = ConnectNetwork(piot_mqtt->network, piot_mqtt->mqtt_host, piot_mqtt->mqtt_port,piot_mqtt->network->is_support_ssl,piot_mqtt->network->ingnore_cert);
+    if (rc != 0) {
+        ret = -101;
+        goto __END;
+    }
+    MQTTClient(&piot_mqtt->Client, piot_mqtt->network, 1000, piot_mqtt->mqtt_buffer, MQTT_BUF_SIZE, piot_mqtt->mqtt_read_buffer, MQTT_BUF_SIZE);
+    MQTTPacket_connectData data = MQTTPacket_connectData_initializer;
+
+    if (piot_mqtt->willFlag) {
+        data.willFlag = 1;
+        memcpy(&data.will, &piot_mqtt->will, sizeof(MQTTPacket_willOptions));
+    } else {
+        data.willFlag = 0;
+    }
+    data.MQTTVersion = piot_mqtt->mqtt_version;
+    data.clientID.cstring = piot_mqtt->mqtt_client_id;
+    data.username.cstring = piot_mqtt->mqtt_user;
+    data.password.cstring = piot_mqtt->mqtt_pass;
+    data.keepAliveInterval = piot_mqtt->keepAliveInterval;
+    data.cleansession = 1;
+    rc = MQTTConnect(&piot_mqtt->Client, &data);
+    if (rc) {
+        printf("mqtt connect broker fail \n");
+        printf("rc = %d\n", rc);
+        ret = -102;
+        goto __END;
+    }
+__END:
+    return ret;
+}
+
+int mqtt_device_disconnect(Cloud_MQTT_t *piot_mqtt)//断开mqtt连接
+{
+    int ret = 0;
+
+    ret = MQTTDisconnect(&piot_mqtt->Client,piot_mqtt->network);
+    printf("disconnectNetwork ret = %d\n", ret);
+
+    return ret;
+}
+
+void iot_yield(Cloud_MQTT_t *piot_mqtt,iot_device_info_t *gateway)
+{
+    int ret;
+    switch (gateway->iotstatus) {
+        case IOT_STATUS_LOGIN:
+        ret = mqtt_device_connect(piot_mqtt);
+        if (ret < 0) {
+            printf("iot connect error code %d\n", ret);
+            sleep(1);
+        }
+        break;
+        case IOT_STATUS_CONNECT:
+        ret = MQTTYield(&piot_mqtt->Client, 200);
+        //printf("iot_yield ret %d\n",ret);
+        if (ret != SUCCESS) {
+            printf("why???\n");
+            gateway->iotstatus = IOT_STATUS_DROP;
+        }
+        break;
+        case IOT_STATUS_DROP:
+        mqtt_device_disconnect(piot_mqtt);
+        //gateway.iotstatus = IOT_STATUS_LOGIN;
+        usleep(1000);
+        break;
+        default:
+        break;
+    }
+}
+
+int mqtt_will_msg_set(Cloud_MQTT_t *piot_mqtt, char *pbuf, int len)//设置遗嘱函数
+{
+    memset(piot_mqtt->will_topic, '\0', MQTT_TOPIC_SIZE);
+    MQTTPacket_willOptions mqtt_will = MQTTPacket_willOptions_initializer;
+
+    strcpy(piot_mqtt->will_topic, piot_mqtt->pub_topic);
+    memcpy(&piot_mqtt->will, &mqtt_will, sizeof(MQTTPacket_willOptions));
+
+    piot_mqtt->willFlag = 1;
+    piot_mqtt->will.retained = 0;
+    piot_mqtt->will.topicName.cstring = (char *)piot_mqtt->will_topic;
+    piot_mqtt->will.message.cstring = (char *)pbuf;
+    piot_mqtt->will.qos = QOS2;
+    return 0;
+
+}
+
+int mbtk_MQTTSubscribe(Client* c, const char* topicFilter, enum QoS qos, messageHandler messageHandler)
+{
+    return MQTTSubscribe(c, topicFilter, qos, messageHandler);
+}
+int mbtk_MQTTUnsubscribe(Client* c, const char* topicFilter)
+{
+    return MQTTUnsubscribe(c,topicFilter);
+}
+/*
+int mbtk_MQTTPublish(Client* c, const char* topicName, MQTTMessage* message)
+{
+    return MQTTPublish(c,topicName,message);
+}
+*/
+int mbtk_MQTTPublish(char *pbuf, int len, char retain,Client* c,const char* pub_topic,enum QoS qos,char dup)
+{
+    int ret = 0;
+    MQTTMessage message;
+    char my_topic[128] = {0};
+
+    strcpy(my_topic, pub_topic);
+
+    message.payload = (void *)pbuf;
+    message.payloadlen = len;
+    message.dup = dup;
+    message.qos = qos;
+    if (retain) {
+        message.retained = 1;
+    } else {
+        message.retained = 0;
+    }
+
+    ret = MQTTPublish(c, my_topic, &message);	//发布一个主题
+
+    return ret;
+}
+