MQTTPacket fixes

Fork of MQTTPacket by MQTT

Committer:
icraggs
Date:
Tue Oct 03 17:02:36 2017 +0000
Revision:
23:0cfb74c5a621
Latest level of Paho code including PUBREL packet (QoS) fix.

Who changed what in which revision?

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