MQTTPacket.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  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 Sergio R. Caprile - non-blocking packet read functions for
  16. *stream transport
  17. *******************************************************************************/
  18. #include "MQTTPacket.h"
  19. #include "StackTrace.h"
  20. #include <string.h>
  21. /**
  22. * Encodes the message length according to the MQTT algorithm
  23. * @param buf the buffer into which the encoded data is written
  24. * @param length the length to be encoded
  25. * @return the number of bytes written to buffer
  26. */
  27. int MQTTPacket_encode(unsigned char* buf, int length) {
  28. int rc = 0;
  29. FUNC_ENTRY;
  30. do {
  31. char d = length % 128;
  32. length /= 128;
  33. /* if there are more digits to encode, set the top bit of this digit */
  34. if (length > 0)
  35. d |= 0x80;
  36. buf[rc++] = d;
  37. } while (length > 0);
  38. FUNC_EXIT_RC(rc);
  39. return rc;
  40. }
  41. /**
  42. * Decodes the message length according to the MQTT algorithm
  43. * @param getcharfn pointer to function to read the next character from the data
  44. * source
  45. * @param value the decoded length returned
  46. * @return the number of bytes read from the socket
  47. */
  48. int MQTTPacket_decode(int (*getcharfn)(unsigned char*, int), int* value) {
  49. unsigned char c;
  50. int multiplier = 1;
  51. int len = 0;
  52. #define MAX_NO_OF_REMAINING_LENGTH_BYTES 4
  53. FUNC_ENTRY;
  54. *value = 0;
  55. do {
  56. int rc = MQTTPACKET_READ_ERROR;
  57. if (++len > MAX_NO_OF_REMAINING_LENGTH_BYTES) {
  58. rc = MQTTPACKET_READ_ERROR; /* bad data */
  59. goto exit;
  60. }
  61. rc = (*getcharfn)(&c, 1);
  62. if (rc != 1)
  63. goto exit;
  64. *value += (c & 127) * multiplier;
  65. multiplier *= 128;
  66. } while ((c & 128) != 0);
  67. exit:
  68. FUNC_EXIT_RC(len);
  69. return len;
  70. }
  71. int MQTTPacket_len(int rem_len) {
  72. rem_len += 1; /* header byte */
  73. /* now remaining_length field */
  74. if (rem_len < 128)
  75. rem_len += 1;
  76. else if (rem_len < 16384)
  77. rem_len += 2;
  78. else if (rem_len < 2097151)
  79. rem_len += 3;
  80. else
  81. rem_len += 4;
  82. return rem_len;
  83. }
  84. static unsigned char* bufptr;
  85. int bufchar(unsigned char* c, int count) {
  86. int i;
  87. for (i = 0; i < count; ++i)
  88. *c = *bufptr++;
  89. return count;
  90. }
  91. int MQTTPacket_decodeBuf(unsigned char* buf, int* value) {
  92. bufptr = buf;
  93. return MQTTPacket_decode(bufchar, value);
  94. }
  95. /**
  96. * Calculates an integer from two bytes read from the input buffer
  97. * @param pptr pointer to the input buffer - incremented by the number of bytes
  98. * used & returned
  99. * @return the integer value calculated
  100. */
  101. int readInt(unsigned char** pptr) {
  102. unsigned char* ptr = *pptr;
  103. int len = 256 * (*ptr) + (*(ptr + 1));
  104. *pptr += 2;
  105. return len;
  106. }
  107. /**
  108. * Reads one character from the input buffer.
  109. * @param pptr pointer to the input buffer - incremented by the number of bytes
  110. * used & returned
  111. * @return the character read
  112. */
  113. char readChar(unsigned char** pptr) {
  114. char c = **pptr;
  115. (*pptr)++;
  116. return c;
  117. }
  118. /**
  119. * Writes one character to an output buffer.
  120. * @param pptr pointer to the output buffer - incremented by the number of bytes
  121. * used & returned
  122. * @param c the character to write
  123. */
  124. void writeChar(unsigned char** pptr, char c) {
  125. **pptr = c;
  126. (*pptr)++;
  127. }
  128. /**
  129. * Writes an integer as 2 bytes to an output buffer.
  130. * @param pptr pointer to the output buffer - incremented by the number of bytes
  131. * used & returned
  132. * @param anInt the integer to write
  133. */
  134. void writeInt(unsigned char** pptr, int anInt) {
  135. **pptr = (unsigned char)(anInt / 256);
  136. (*pptr)++;
  137. **pptr = (unsigned char)(anInt % 256);
  138. (*pptr)++;
  139. }
  140. /**
  141. * Writes a "UTF" string to an output buffer. Converts C string to
  142. * length-delimited.
  143. * @param pptr pointer to the output buffer - incremented by the number of bytes
  144. * used & returned
  145. * @param string the C string to write
  146. */
  147. void writeCString(unsigned char** pptr, const char* string) {
  148. int len = strlen(string);
  149. writeInt(pptr, len);
  150. memcpy(*pptr, string, len);
  151. *pptr += len;
  152. }
  153. int getLenStringLen(char* ptr) {
  154. int len = 256 * ((unsigned char)(*ptr)) + (unsigned char)(*(ptr + 1));
  155. return len;
  156. }
  157. void writeMQTTString(unsigned char** pptr, MQTTString mqttstring) {
  158. if (mqttstring.lenstring.len > 0) {
  159. writeInt(pptr, mqttstring.lenstring.len);
  160. memcpy(*pptr, mqttstring.lenstring.data, mqttstring.lenstring.len);
  161. *pptr += mqttstring.lenstring.len;
  162. } else if (mqttstring.cstring)
  163. writeCString(pptr, mqttstring.cstring);
  164. else
  165. writeInt(pptr, 0);
  166. }
  167. /**
  168. * @param mqttstring the MQTTString structure into which the data is to be read
  169. * @param pptr pointer to the output buffer - incremented by the number of bytes
  170. * used & returned
  171. * @param enddata pointer to the end of the data: do not read beyond
  172. * @return 1 if successful, 0 if not
  173. */
  174. int readMQTTLenString(MQTTString* mqttstring,
  175. unsigned char** pptr,
  176. unsigned char* enddata) {
  177. int rc = 0;
  178. FUNC_ENTRY;
  179. /* the first two bytes are the length of the string */
  180. if (enddata - (*pptr) > 1) /* enough length to read the integer? */
  181. {
  182. mqttstring->lenstring.len =
  183. readInt(pptr); /* increments pptr to point past length */
  184. if (&(*pptr)[mqttstring->lenstring.len] <= enddata) {
  185. mqttstring->lenstring.data = (char*)*pptr;
  186. *pptr += mqttstring->lenstring.len;
  187. rc = 1;
  188. }
  189. }
  190. mqttstring->cstring = NULL;
  191. FUNC_EXIT_RC(rc);
  192. return rc;
  193. }
  194. /**
  195. * Return the length of the MQTTstring - C string if there is one, otherwise the
  196. * length delimited string
  197. * @param mqttstring the string to return the length of
  198. * @return the length of the string
  199. */
  200. int MQTTstrlen(MQTTString mqttstring) {
  201. int rc = 0;
  202. if (mqttstring.cstring)
  203. rc = strlen(mqttstring.cstring);
  204. else
  205. rc = mqttstring.lenstring.len;
  206. return rc;
  207. }
  208. /**
  209. * Compares an MQTTString to a C string
  210. * @param a the MQTTString to compare
  211. * @param bptr the C string to compare
  212. * @return boolean - equal or not
  213. */
  214. int MQTTPacket_equals(MQTTString* a, char* bptr) {
  215. int alen = 0, blen = 0;
  216. char* aptr;
  217. if (a->cstring) {
  218. aptr = a->cstring;
  219. alen = strlen(a->cstring);
  220. } else {
  221. aptr = a->lenstring.data;
  222. alen = a->lenstring.len;
  223. }
  224. blen = strlen(bptr);
  225. return (alen == blen) && (strncmp(aptr, bptr, alen) == 0);
  226. }
  227. /**
  228. * Helper function to read packet data from some source into a buffer
  229. * @param buf the buffer into which the packet will be serialized
  230. * @param buflen the length in bytes of the supplied buffer
  231. * @param getfn pointer to a function which will read any number of bytes from
  232. * the needed source
  233. * @return integer MQTT packet type, or -1 on error
  234. * @note the whole message must fit into the caller's buffer
  235. */
  236. int MQTTPacket_read(unsigned char* buf,
  237. int buflen,
  238. int (*getfn)(unsigned char*, int)) {
  239. int rc = -1;
  240. MQTTHeader header = {0};
  241. int len = 0;
  242. int rem_len = 0;
  243. /* 1. read the header byte. This has the packet type in it */
  244. if ((*getfn)(buf, 1) != 1)
  245. goto exit;
  246. len = 1;
  247. /* 2. read the remaining length. This is variable in itself */
  248. MQTTPacket_decode(getfn, &rem_len);
  249. len += MQTTPacket_encode(
  250. buf + 1,
  251. rem_len); /* put the original remaining length back into the buffer */
  252. /* 3. read the rest of the buffer using a callback to supply the rest of the
  253. * data */
  254. if ((rem_len + len) > buflen)
  255. goto exit;
  256. if (rem_len && ((*getfn)(buf + len, rem_len) != rem_len))
  257. goto exit;
  258. header.byte = buf[0];
  259. rc = header.bits.type;
  260. exit:
  261. return rc;
  262. }
  263. /**
  264. * Decodes the message length according to the MQTT algorithm, non-blocking
  265. * @param trp pointer to a transport structure holding what is needed to solve
  266. * getting data from it
  267. * @param value the decoded length returned
  268. * @return integer the number of bytes read from the socket, 0 for call again,
  269. * or -1 on error
  270. */
  271. static int MQTTPacket_decodenb(MQTTTransport* trp) {
  272. unsigned char c;
  273. int rc = MQTTPACKET_READ_ERROR;
  274. FUNC_ENTRY;
  275. if (trp->len == 0) { /* initialize on first call */
  276. trp->multiplier = 1;
  277. trp->rem_len = 0;
  278. }
  279. do {
  280. int frc;
  281. if (trp->len >= MAX_NO_OF_REMAINING_LENGTH_BYTES)
  282. goto exit;
  283. if ((frc = (*trp->getfn)(trp->sck, &c, 1)) == -1)
  284. goto exit;
  285. if (frc == 0) {
  286. rc = 0;
  287. goto exit;
  288. }
  289. ++(trp->len);
  290. trp->rem_len += (c & 127) * trp->multiplier;
  291. trp->multiplier *= 128;
  292. } while ((c & 128) != 0);
  293. rc = trp->len;
  294. exit:
  295. FUNC_EXIT_RC(rc);
  296. return rc;
  297. }
  298. /**
  299. * Helper function to read packet data from some source into a buffer,
  300. * non-blocking
  301. * @param buf the buffer into which the packet will be serialized
  302. * @param buflen the length in bytes of the supplied buffer
  303. * @param trp pointer to a transport structure holding what is needed to solve
  304. * getting data from it
  305. * @return integer MQTT packet type, 0 for call again, or -1 on error
  306. * @note the whole message must fit into the caller's buffer
  307. */
  308. int MQTTPacket_readnb(unsigned char* buf, int buflen, MQTTTransport* trp) {
  309. int rc = -1, frc;
  310. MQTTHeader header = {0};
  311. switch (trp->state) {
  312. default:
  313. trp->state = 0;
  314. /*FALLTHROUGH*/
  315. case 0:
  316. /* read the header byte. This has the packet type in it */
  317. if ((frc = (*trp->getfn)(trp->sck, buf, 1)) == -1)
  318. goto exit;
  319. if (frc == 0)
  320. return 0;
  321. trp->len = 0;
  322. ++trp->state;
  323. /*FALLTHROUGH*/
  324. /* read the remaining length. This is variable in itself */
  325. case 1:
  326. if ((frc = MQTTPacket_decodenb(trp)) == MQTTPACKET_READ_ERROR)
  327. goto exit;
  328. if (frc == 0)
  329. return 0;
  330. trp->len = 1 + MQTTPacket_encode(
  331. buf + 1,
  332. trp->rem_len); /* put the original remaining
  333. length back into the buffer */
  334. if ((trp->rem_len + trp->len) > buflen)
  335. goto exit;
  336. ++trp->state;
  337. /*FALLTHROUGH*/
  338. case 2:
  339. if (trp->rem_len) {
  340. /* read the rest of the buffer using a callback to supply the
  341. * rest of the data */
  342. if ((frc = (*trp->getfn)(trp->sck, buf + trp->len,
  343. trp->rem_len)) == -1)
  344. goto exit;
  345. if (frc == 0)
  346. return 0;
  347. trp->rem_len -= frc;
  348. trp->len += frc;
  349. if (trp->rem_len)
  350. return 0;
  351. }
  352. header.byte = buf[0];
  353. rc = header.bits.type;
  354. break;
  355. }
  356. exit:
  357. trp->state = 0;
  358. return rc;
  359. }