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