MQTTFormat.c 12 KB

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