Basic C library for MQTT packet serialization and deserialization

Dependents:   MQTT MQTT MQTT MQTT ... more

Fork of MQTTPacket by MQTT

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MQTTFormat.c Source File

MQTTFormat.c

00001 /*******************************************************************************
00002  * Copyright (c) 2014 IBM Corp.
00003  *
00004  * All rights reserved. This program and the accompanying materials
00005  * are made available under the terms of the Eclipse Public License v1.0
00006  * and Eclipse Distribution License v1.0 which accompany this distribution.
00007  *
00008  * The Eclipse Public License is available at
00009  *    http://www.eclipse.org/legal/epl-v10.html
00010  * and the Eclipse Distribution License is available at
00011  *   http://www.eclipse.org/org/documents/edl-v10.php.
00012  *
00013  * Contributors:
00014  *    Ian Craggs - initial API and implementation and/or initial documentation
00015  *******************************************************************************/
00016 
00017 #include "StackTrace.h"
00018 #include "MQTTPacket.h"
00019 
00020 #include <string.h>
00021 
00022 
00023 const char* MQTTPacket_names[] =
00024 {
00025     "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
00026     "PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
00027     "PINGREQ", "PINGRESP", "DISCONNECT"
00028 };
00029 
00030 
00031 const char* MQTTPacket_getName(unsigned short packetid)
00032 {
00033     return MQTTPacket_names[packetid];
00034 }
00035 
00036 
00037 int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data)
00038 {
00039     int strindex = 0;
00040 
00041     strindex = snprintf(strbuf, strbuflen,
00042             "CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",
00043             (int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,
00044             (int)data->cleansession, data->keepAliveInterval);
00045     if (data->willFlag)
00046         strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
00047                 ", will QoS %d, will retain %d, will topic %.*s, will message %.*s",
00048                 data->will.qos, data->will.retained,
00049                 data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,
00050                 data->will.message.lenstring.len, data->will.message.lenstring.data);
00051     if (data->username.lenstring.data && data->username.lenstring.len > 0)
00052         strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
00053                 ", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);
00054     if (data->password.lenstring.data && data->password.lenstring.len > 0)
00055         strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
00056                 ", password %.*s", data->password.lenstring.len, data->password.lenstring.data);
00057     return strindex;
00058 }
00059 
00060 
00061 int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent)
00062 {
00063     int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);
00064     return strindex;
00065 }
00066 
00067 
00068 int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
00069         unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen)
00070 {
00071     int strindex = snprintf(strbuf, strbuflen,
00072                 "PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",
00073                 dup, qos, retained, packetid,
00074                 (topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,
00075                 payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);
00076     return strindex;
00077 }
00078 
00079 
00080 int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
00081 {
00082     int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);
00083     if (dup)
00084         strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);
00085     return strindex;
00086 }
00087 
00088 
00089 int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
00090         MQTTString topicFilters[], int requestedQoSs[])
00091 {
00092     return snprintf(strbuf, strbuflen,
00093         "SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",
00094         dup, packetid, count,
00095         topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,
00096         requestedQoSs[0]);
00097 }
00098 
00099 
00100 int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs)
00101 {
00102     return snprintf(strbuf, strbuflen,
00103         "SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);
00104 }
00105 
00106 
00107 int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
00108         int count, MQTTString topicFilters[])
00109 {
00110     return snprintf(strbuf, strbuflen,
00111                     "UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",
00112                     dup, packetid, count,
00113                     topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);
00114 }
00115 
00116 
00117 #if defined(MQTT_CLIENT)
00118 char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
00119 {
00120     int index = 0;
00121     int rem_length = 0;
00122     MQTTHeader header = {0};
00123     int strindex = 0;
00124 
00125     header.byte = buf[index++];
00126     index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
00127 
00128     switch (header.bits.type)
00129     {
00130 
00131     case CONNACK:
00132     {
00133         unsigned char sessionPresent, connack_rc;
00134         if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
00135             strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
00136     }
00137     break;
00138     case PUBLISH:
00139     {
00140         unsigned char dup, retained, *payload;
00141         unsigned short packetid;
00142         int qos, payloadlen;
00143         MQTTString topicName = MQTTString_initializer;
00144         if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
00145                 &payload, &payloadlen, buf, buflen) == 1)
00146             strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
00147                     topicName, payload, payloadlen);
00148     }
00149     break;
00150     case PUBACK:
00151     case PUBREC:
00152     case PUBREL:
00153     case PUBCOMP:
00154     {
00155         unsigned char packettype, dup;
00156         unsigned short packetid;
00157         if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
00158             strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
00159     }
00160     break;
00161     case SUBACK:
00162     {
00163         unsigned short packetid;
00164         int maxcount = 1, count = 0;
00165         int grantedQoSs[1];
00166         if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
00167             strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
00168     }
00169     break;
00170     case UNSUBACK:
00171     {
00172         unsigned short packetid;
00173         if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
00174             strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
00175     }
00176     break;
00177     case PINGREQ:
00178     case PINGRESP:
00179     case DISCONNECT:
00180         strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
00181         break;
00182     }
00183     return strbuf;
00184 }
00185 #endif
00186 
00187 #if defined(MQTT_SERVER)
00188 char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
00189 {
00190     int index = 0;
00191     int rem_length = 0;
00192     MQTTHeader header = {0};
00193     int strindex = 0;
00194 
00195     header.byte = buf[index++];
00196     index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
00197 
00198     switch (header.bits.type)
00199     {
00200     case CONNECT:
00201     {
00202         MQTTPacket_connectData data;
00203         int rc;
00204         if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1)
00205             strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data);
00206     }
00207     break;
00208     case PUBLISH:
00209     {
00210         unsigned char dup, retained, *payload;
00211         unsigned short packetid;
00212         int qos, payloadlen;
00213         MQTTString topicName = MQTTString_initializer;
00214         if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
00215                 &payload, &payloadlen, buf, buflen) == 1)
00216             strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
00217                     topicName, payload, payloadlen);
00218     }
00219     break;
00220     case PUBACK:
00221     case PUBREC:
00222     case PUBREL:
00223     case PUBCOMP:
00224     {
00225         unsigned char packettype, dup;
00226         unsigned short packetid;
00227         if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
00228             strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
00229     }
00230     break;
00231     case SUBSCRIBE:
00232     {
00233         unsigned char dup;
00234         unsigned short packetid;
00235         int maxcount = 1, count = 0;
00236         MQTTString topicFilters[1];
00237         int requestedQoSs[1];
00238         if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
00239                 topicFilters, requestedQoSs, buf, buflen) == 1)
00240             strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
00241     }
00242     break;
00243     case UNSUBSCRIBE:
00244     {
00245         unsigned char dup;
00246         unsigned short packetid;
00247         int maxcount = 1, count = 0;
00248         MQTTString topicFilters[1];
00249         if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
00250             strindex =  MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
00251     }
00252     break;
00253     case PINGREQ:
00254     case PINGRESP:
00255     case DISCONNECT:
00256         strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
00257         break;
00258     }
00259     strbuf[strbuflen] = '\0';
00260     return strbuf;
00261 }
00262 #endif