Basic C library for MQTT packet serialization and deserialization

Dependents:   MQTT MQTT MQTT MQTT ... more

Fork of MQTTPacket by MQTT

This library is part of the EclipseTM Paho project; specifically the embedded client.

A basic MQTT library in C for packet serialization and deserialization

Committer:
Ian Craggs
Date:
Mon Oct 30 12:47:11 2017 +0000
Revision:
25:aedcaf7984d5
Parent:
23:7a52009beba1
Merging mine and Jan's changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jan Jongboom 23:7a52009beba1 1 /*******************************************************************************
Jan Jongboom 23:7a52009beba1 2 * Copyright (c) 2014 IBM Corp.
Jan Jongboom 23:7a52009beba1 3 *
Jan Jongboom 23:7a52009beba1 4 * All rights reserved. This program and the accompanying materials
Jan Jongboom 23:7a52009beba1 5 * are made available under the terms of the Eclipse Public License v1.0
Jan Jongboom 23:7a52009beba1 6 * and Eclipse Distribution License v1.0 which accompany this distribution.
Jan Jongboom 23:7a52009beba1 7 *
Jan Jongboom 23:7a52009beba1 8 * The Eclipse Public License is available at
Jan Jongboom 23:7a52009beba1 9 * http://www.eclipse.org/legal/epl-v10.html
Jan Jongboom 23:7a52009beba1 10 * and the Eclipse Distribution License is available at
Jan Jongboom 23:7a52009beba1 11 * http://www.eclipse.org/org/documents/edl-v10.php.
Jan Jongboom 23:7a52009beba1 12 *
Jan Jongboom 23:7a52009beba1 13 * Contributors:
Jan Jongboom 23:7a52009beba1 14 * Ian Craggs - initial API and implementation and/or initial documentation
Jan Jongboom 23:7a52009beba1 15 *******************************************************************************/
Jan Jongboom 23:7a52009beba1 16
Jan Jongboom 23:7a52009beba1 17 #include "StackTrace.h"
Jan Jongboom 23:7a52009beba1 18 #include "MQTTPacket.h"
Jan Jongboom 23:7a52009beba1 19
Jan Jongboom 23:7a52009beba1 20 #include <string.h>
Jan Jongboom 23:7a52009beba1 21
Jan Jongboom 23:7a52009beba1 22
Jan Jongboom 23:7a52009beba1 23 const char* MQTTPacket_names[] =
Jan Jongboom 23:7a52009beba1 24 {
Jan Jongboom 23:7a52009beba1 25 "RESERVED", "CONNECT", "CONNACK", "PUBLISH", "PUBACK", "PUBREC", "PUBREL",
Jan Jongboom 23:7a52009beba1 26 "PUBCOMP", "SUBSCRIBE", "SUBACK", "UNSUBSCRIBE", "UNSUBACK",
Jan Jongboom 23:7a52009beba1 27 "PINGREQ", "PINGRESP", "DISCONNECT"
Jan Jongboom 23:7a52009beba1 28 };
Jan Jongboom 23:7a52009beba1 29
Jan Jongboom 23:7a52009beba1 30
Jan Jongboom 23:7a52009beba1 31 const char* MQTTPacket_getName(unsigned short packetid)
Jan Jongboom 23:7a52009beba1 32 {
Jan Jongboom 23:7a52009beba1 33 return MQTTPacket_names[packetid];
Jan Jongboom 23:7a52009beba1 34 }
Jan Jongboom 23:7a52009beba1 35
Jan Jongboom 23:7a52009beba1 36
Jan Jongboom 23:7a52009beba1 37 int MQTTStringFormat_connect(char* strbuf, int strbuflen, MQTTPacket_connectData* data)
Jan Jongboom 23:7a52009beba1 38 {
Jan Jongboom 23:7a52009beba1 39 int strindex = 0;
Jan Jongboom 23:7a52009beba1 40
Jan Jongboom 23:7a52009beba1 41 strindex = snprintf(strbuf, strbuflen,
Jan Jongboom 23:7a52009beba1 42 "CONNECT MQTT version %d, client id %.*s, clean session %d, keep alive %d",
Jan Jongboom 23:7a52009beba1 43 (int)data->MQTTVersion, data->clientID.lenstring.len, data->clientID.lenstring.data,
Jan Jongboom 23:7a52009beba1 44 (int)data->cleansession, data->keepAliveInterval);
Jan Jongboom 23:7a52009beba1 45 if (data->willFlag)
Jan Jongboom 23:7a52009beba1 46 strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
Jan Jongboom 23:7a52009beba1 47 ", will QoS %d, will retain %d, will topic %.*s, will message %.*s",
Jan Jongboom 23:7a52009beba1 48 data->will.qos, data->will.retained,
Jan Jongboom 23:7a52009beba1 49 data->will.topicName.lenstring.len, data->will.topicName.lenstring.data,
Jan Jongboom 23:7a52009beba1 50 data->will.message.lenstring.len, data->will.message.lenstring.data);
Jan Jongboom 23:7a52009beba1 51 if (data->username.lenstring.data && data->username.lenstring.len > 0)
Jan Jongboom 23:7a52009beba1 52 strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
Jan Jongboom 23:7a52009beba1 53 ", user name %.*s", data->username.lenstring.len, data->username.lenstring.data);
Jan Jongboom 23:7a52009beba1 54 if (data->password.lenstring.data && data->password.lenstring.len > 0)
Jan Jongboom 23:7a52009beba1 55 strindex += snprintf(&strbuf[strindex], strbuflen - strindex,
Jan Jongboom 23:7a52009beba1 56 ", password %.*s", data->password.lenstring.len, data->password.lenstring.data);
Jan Jongboom 23:7a52009beba1 57 return strindex;
Jan Jongboom 23:7a52009beba1 58 }
Jan Jongboom 23:7a52009beba1 59
Jan Jongboom 23:7a52009beba1 60
Jan Jongboom 23:7a52009beba1 61 int MQTTStringFormat_connack(char* strbuf, int strbuflen, unsigned char connack_rc, unsigned char sessionPresent)
Jan Jongboom 23:7a52009beba1 62 {
Jan Jongboom 23:7a52009beba1 63 int strindex = snprintf(strbuf, strbuflen, "CONNACK session present %d, rc %d", sessionPresent, connack_rc);
Jan Jongboom 23:7a52009beba1 64 return strindex;
Jan Jongboom 23:7a52009beba1 65 }
Jan Jongboom 23:7a52009beba1 66
Jan Jongboom 23:7a52009beba1 67
Jan Jongboom 23:7a52009beba1 68 int MQTTStringFormat_publish(char* strbuf, int strbuflen, unsigned char dup, int qos, unsigned char retained,
Jan Jongboom 23:7a52009beba1 69 unsigned short packetid, MQTTString topicName, unsigned char* payload, int payloadlen)
Jan Jongboom 23:7a52009beba1 70 {
Jan Jongboom 23:7a52009beba1 71 int strindex = snprintf(strbuf, strbuflen,
Jan Jongboom 23:7a52009beba1 72 "PUBLISH dup %d, QoS %d, retained %d, packet id %d, topic %.*s, payload length %d, payload %.*s",
Jan Jongboom 23:7a52009beba1 73 dup, qos, retained, packetid,
Jan Jongboom 23:7a52009beba1 74 (topicName.lenstring.len < 20) ? topicName.lenstring.len : 20, topicName.lenstring.data,
Jan Jongboom 23:7a52009beba1 75 payloadlen, (payloadlen < 20) ? payloadlen : 20, payload);
Jan Jongboom 23:7a52009beba1 76 return strindex;
Jan Jongboom 23:7a52009beba1 77 }
Jan Jongboom 23:7a52009beba1 78
Jan Jongboom 23:7a52009beba1 79
Jan Jongboom 23:7a52009beba1 80 int MQTTStringFormat_ack(char* strbuf, int strbuflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
Jan Jongboom 23:7a52009beba1 81 {
Jan Jongboom 23:7a52009beba1 82 int strindex = snprintf(strbuf, strbuflen, "%s, packet id %d", MQTTPacket_names[packettype], packetid);
Jan Jongboom 23:7a52009beba1 83 if (dup)
Jan Jongboom 23:7a52009beba1 84 strindex += snprintf(strbuf + strindex, strbuflen - strindex, ", dup %d", dup);
Jan Jongboom 23:7a52009beba1 85 return strindex;
Jan Jongboom 23:7a52009beba1 86 }
Jan Jongboom 23:7a52009beba1 87
Jan Jongboom 23:7a52009beba1 88
Jan Jongboom 23:7a52009beba1 89 int MQTTStringFormat_subscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid, int count,
Jan Jongboom 23:7a52009beba1 90 MQTTString topicFilters[], int requestedQoSs[])
Jan Jongboom 23:7a52009beba1 91 {
Jan Jongboom 23:7a52009beba1 92 return snprintf(strbuf, strbuflen,
Jan Jongboom 23:7a52009beba1 93 "SUBSCRIBE dup %d, packet id %d count %d topic %.*s qos %d",
Jan Jongboom 23:7a52009beba1 94 dup, packetid, count,
Jan Jongboom 23:7a52009beba1 95 topicFilters[0].lenstring.len, topicFilters[0].lenstring.data,
Jan Jongboom 23:7a52009beba1 96 requestedQoSs[0]);
Jan Jongboom 23:7a52009beba1 97 }
Jan Jongboom 23:7a52009beba1 98
Jan Jongboom 23:7a52009beba1 99
Jan Jongboom 23:7a52009beba1 100 int MQTTStringFormat_suback(char* strbuf, int strbuflen, unsigned short packetid, int count, int* grantedQoSs)
Jan Jongboom 23:7a52009beba1 101 {
Jan Jongboom 23:7a52009beba1 102 return snprintf(strbuf, strbuflen,
Jan Jongboom 23:7a52009beba1 103 "SUBACK packet id %d count %d granted qos %d", packetid, count, grantedQoSs[0]);
Jan Jongboom 23:7a52009beba1 104 }
Jan Jongboom 23:7a52009beba1 105
Jan Jongboom 23:7a52009beba1 106
Jan Jongboom 23:7a52009beba1 107 int MQTTStringFormat_unsubscribe(char* strbuf, int strbuflen, unsigned char dup, unsigned short packetid,
Jan Jongboom 23:7a52009beba1 108 int count, MQTTString topicFilters[])
Jan Jongboom 23:7a52009beba1 109 {
Jan Jongboom 23:7a52009beba1 110 return snprintf(strbuf, strbuflen,
Jan Jongboom 23:7a52009beba1 111 "UNSUBSCRIBE dup %d, packet id %d count %d topic %.*s",
Jan Jongboom 23:7a52009beba1 112 dup, packetid, count,
Jan Jongboom 23:7a52009beba1 113 topicFilters[0].lenstring.len, topicFilters[0].lenstring.data);
Jan Jongboom 23:7a52009beba1 114 }
Jan Jongboom 23:7a52009beba1 115
Jan Jongboom 23:7a52009beba1 116
Jan Jongboom 23:7a52009beba1 117 #if defined(MQTT_CLIENT)
Jan Jongboom 23:7a52009beba1 118 char* MQTTFormat_toClientString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
Jan Jongboom 23:7a52009beba1 119 {
Jan Jongboom 23:7a52009beba1 120 int index = 0;
Jan Jongboom 23:7a52009beba1 121 int rem_length = 0;
Jan Jongboom 23:7a52009beba1 122 MQTTHeader header = {0};
Jan Jongboom 23:7a52009beba1 123 int strindex = 0;
Jan Jongboom 23:7a52009beba1 124
Jan Jongboom 23:7a52009beba1 125 header.byte = buf[index++];
Jan Jongboom 23:7a52009beba1 126 index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
Jan Jongboom 23:7a52009beba1 127
Jan Jongboom 23:7a52009beba1 128 switch (header.bits.type)
Jan Jongboom 23:7a52009beba1 129 {
Jan Jongboom 23:7a52009beba1 130
Jan Jongboom 23:7a52009beba1 131 case CONNACK:
Jan Jongboom 23:7a52009beba1 132 {
Jan Jongboom 23:7a52009beba1 133 unsigned char sessionPresent, connack_rc;
Jan Jongboom 23:7a52009beba1 134 if (MQTTDeserialize_connack(&sessionPresent, &connack_rc, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 135 strindex = MQTTStringFormat_connack(strbuf, strbuflen, connack_rc, sessionPresent);
Jan Jongboom 23:7a52009beba1 136 }
Jan Jongboom 23:7a52009beba1 137 break;
Jan Jongboom 23:7a52009beba1 138 case PUBLISH:
Jan Jongboom 23:7a52009beba1 139 {
Jan Jongboom 23:7a52009beba1 140 unsigned char dup, retained, *payload;
Jan Jongboom 23:7a52009beba1 141 unsigned short packetid;
Jan Jongboom 23:7a52009beba1 142 int qos, payloadlen;
Jan Jongboom 23:7a52009beba1 143 MQTTString topicName = MQTTString_initializer;
Jan Jongboom 23:7a52009beba1 144 if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
Jan Jongboom 23:7a52009beba1 145 &payload, &payloadlen, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 146 strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
Jan Jongboom 23:7a52009beba1 147 topicName, payload, payloadlen);
Jan Jongboom 23:7a52009beba1 148 }
Jan Jongboom 23:7a52009beba1 149 break;
Jan Jongboom 23:7a52009beba1 150 case PUBACK:
Jan Jongboom 23:7a52009beba1 151 case PUBREC:
Jan Jongboom 23:7a52009beba1 152 case PUBREL:
Jan Jongboom 23:7a52009beba1 153 case PUBCOMP:
Jan Jongboom 23:7a52009beba1 154 {
Jan Jongboom 23:7a52009beba1 155 unsigned char packettype, dup;
Jan Jongboom 23:7a52009beba1 156 unsigned short packetid;
Jan Jongboom 23:7a52009beba1 157 if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 158 strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
Jan Jongboom 23:7a52009beba1 159 }
Jan Jongboom 23:7a52009beba1 160 break;
Jan Jongboom 23:7a52009beba1 161 case SUBACK:
Jan Jongboom 23:7a52009beba1 162 {
Jan Jongboom 23:7a52009beba1 163 unsigned short packetid;
Jan Jongboom 23:7a52009beba1 164 int maxcount = 1, count = 0;
Jan Jongboom 23:7a52009beba1 165 int grantedQoSs[1];
Jan Jongboom 23:7a52009beba1 166 if (MQTTDeserialize_suback(&packetid, maxcount, &count, grantedQoSs, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 167 strindex = MQTTStringFormat_suback(strbuf, strbuflen, packetid, count, grantedQoSs);
Jan Jongboom 23:7a52009beba1 168 }
Jan Jongboom 23:7a52009beba1 169 break;
Jan Jongboom 23:7a52009beba1 170 case UNSUBACK:
Jan Jongboom 23:7a52009beba1 171 {
Jan Jongboom 23:7a52009beba1 172 unsigned short packetid;
Jan Jongboom 23:7a52009beba1 173 if (MQTTDeserialize_unsuback(&packetid, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 174 strindex = MQTTStringFormat_ack(strbuf, strbuflen, UNSUBACK, 0, packetid);
Jan Jongboom 23:7a52009beba1 175 }
Jan Jongboom 23:7a52009beba1 176 break;
Jan Jongboom 23:7a52009beba1 177 case PINGREQ:
Jan Jongboom 23:7a52009beba1 178 case PINGRESP:
Jan Jongboom 23:7a52009beba1 179 case DISCONNECT:
Jan Jongboom 23:7a52009beba1 180 strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
Jan Jongboom 23:7a52009beba1 181 break;
Jan Jongboom 23:7a52009beba1 182 }
Jan Jongboom 23:7a52009beba1 183 return strbuf;
Jan Jongboom 23:7a52009beba1 184 }
Jan Jongboom 23:7a52009beba1 185 #endif
Jan Jongboom 23:7a52009beba1 186
Jan Jongboom 23:7a52009beba1 187 #if defined(MQTT_SERVER)
Jan Jongboom 23:7a52009beba1 188 char* MQTTFormat_toServerString(char* strbuf, int strbuflen, unsigned char* buf, int buflen)
Jan Jongboom 23:7a52009beba1 189 {
Jan Jongboom 23:7a52009beba1 190 int index = 0;
Jan Jongboom 23:7a52009beba1 191 int rem_length = 0;
Jan Jongboom 23:7a52009beba1 192 MQTTHeader header = {0};
Jan Jongboom 23:7a52009beba1 193 int strindex = 0;
Jan Jongboom 23:7a52009beba1 194
Jan Jongboom 23:7a52009beba1 195 header.byte = buf[index++];
Jan Jongboom 23:7a52009beba1 196 index += MQTTPacket_decodeBuf(&buf[index], &rem_length);
Jan Jongboom 23:7a52009beba1 197
Jan Jongboom 23:7a52009beba1 198 switch (header.bits.type)
Jan Jongboom 23:7a52009beba1 199 {
Jan Jongboom 23:7a52009beba1 200 case CONNECT:
Jan Jongboom 23:7a52009beba1 201 {
Jan Jongboom 23:7a52009beba1 202 MQTTPacket_connectData data;
Jan Jongboom 23:7a52009beba1 203 int rc;
Jan Jongboom 23:7a52009beba1 204 if ((rc = MQTTDeserialize_connect(&data, buf, buflen)) == 1)
Jan Jongboom 23:7a52009beba1 205 strindex = MQTTStringFormat_connect(strbuf, strbuflen, &data);
Jan Jongboom 23:7a52009beba1 206 }
Jan Jongboom 23:7a52009beba1 207 break;
Jan Jongboom 23:7a52009beba1 208 case PUBLISH:
Jan Jongboom 23:7a52009beba1 209 {
Jan Jongboom 23:7a52009beba1 210 unsigned char dup, retained, *payload;
Jan Jongboom 23:7a52009beba1 211 unsigned short packetid;
Jan Jongboom 23:7a52009beba1 212 int qos, payloadlen;
Jan Jongboom 23:7a52009beba1 213 MQTTString topicName = MQTTString_initializer;
Jan Jongboom 23:7a52009beba1 214 if (MQTTDeserialize_publish(&dup, &qos, &retained, &packetid, &topicName,
Jan Jongboom 23:7a52009beba1 215 &payload, &payloadlen, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 216 strindex = MQTTStringFormat_publish(strbuf, strbuflen, dup, qos, retained, packetid,
Jan Jongboom 23:7a52009beba1 217 topicName, payload, payloadlen);
Jan Jongboom 23:7a52009beba1 218 }
Jan Jongboom 23:7a52009beba1 219 break;
Jan Jongboom 23:7a52009beba1 220 case PUBACK:
Jan Jongboom 23:7a52009beba1 221 case PUBREC:
Jan Jongboom 23:7a52009beba1 222 case PUBREL:
Jan Jongboom 23:7a52009beba1 223 case PUBCOMP:
Jan Jongboom 23:7a52009beba1 224 {
Jan Jongboom 23:7a52009beba1 225 unsigned char packettype, dup;
Jan Jongboom 23:7a52009beba1 226 unsigned short packetid;
Jan Jongboom 23:7a52009beba1 227 if (MQTTDeserialize_ack(&packettype, &dup, &packetid, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 228 strindex = MQTTStringFormat_ack(strbuf, strbuflen, packettype, dup, packetid);
Jan Jongboom 23:7a52009beba1 229 }
Jan Jongboom 23:7a52009beba1 230 break;
Jan Jongboom 23:7a52009beba1 231 case SUBSCRIBE:
Jan Jongboom 23:7a52009beba1 232 {
Jan Jongboom 23:7a52009beba1 233 unsigned char dup;
Jan Jongboom 23:7a52009beba1 234 unsigned short packetid;
Jan Jongboom 23:7a52009beba1 235 int maxcount = 1, count = 0;
Jan Jongboom 23:7a52009beba1 236 MQTTString topicFilters[1];
Jan Jongboom 23:7a52009beba1 237 int requestedQoSs[1];
Jan Jongboom 23:7a52009beba1 238 if (MQTTDeserialize_subscribe(&dup, &packetid, maxcount, &count,
Jan Jongboom 23:7a52009beba1 239 topicFilters, requestedQoSs, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 240 strindex = MQTTStringFormat_subscribe(strbuf, strbuflen, dup, packetid, count, topicFilters, requestedQoSs);;
Jan Jongboom 23:7a52009beba1 241 }
Jan Jongboom 23:7a52009beba1 242 break;
Jan Jongboom 23:7a52009beba1 243 case UNSUBSCRIBE:
Jan Jongboom 23:7a52009beba1 244 {
Jan Jongboom 23:7a52009beba1 245 unsigned char dup;
Jan Jongboom 23:7a52009beba1 246 unsigned short packetid;
Jan Jongboom 23:7a52009beba1 247 int maxcount = 1, count = 0;
Jan Jongboom 23:7a52009beba1 248 MQTTString topicFilters[1];
Jan Jongboom 23:7a52009beba1 249 if (MQTTDeserialize_unsubscribe(&dup, &packetid, maxcount, &count, topicFilters, buf, buflen) == 1)
Jan Jongboom 23:7a52009beba1 250 strindex = MQTTStringFormat_unsubscribe(strbuf, strbuflen, dup, packetid, count, topicFilters);
Jan Jongboom 23:7a52009beba1 251 }
Jan Jongboom 23:7a52009beba1 252 break;
Jan Jongboom 23:7a52009beba1 253 case PINGREQ:
Jan Jongboom 23:7a52009beba1 254 case PINGRESP:
Jan Jongboom 23:7a52009beba1 255 case DISCONNECT:
Jan Jongboom 23:7a52009beba1 256 strindex = snprintf(strbuf, strbuflen, "%s", MQTTPacket_names[header.bits.type]);
Jan Jongboom 23:7a52009beba1 257 break;
Jan Jongboom 23:7a52009beba1 258 }
Jan Jongboom 23:7a52009beba1 259 strbuf[strbuflen] = '\0';
Jan Jongboom 23:7a52009beba1 260 return strbuf;
Jan Jongboom 23:7a52009beba1 261 }
Jan Jongboom 23:7a52009beba1 262 #endif