MQTTSerializePublish.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  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. * Ian Craggs - fix for https://bugs.eclipse.org/bugs/show_bug.cgi?id=453144
  16. *******************************************************************************/
  17. #include "MQTTPacket.h"
  18. #include "StackTrace.h"
  19. #include <string.h>
  20. /**
  21. * Determines the length of the MQTT publish packet that would be produced using the supplied parameters
  22. * @param qos the MQTT QoS of the publish (packetid is omitted for QoS 0)
  23. * @param topicName the topic name to be used in the publish
  24. * @param payloadlen the length of the payload to be sent
  25. * @return the length of buffer needed to contain the serialized version of the packet
  26. */
  27. int MQTTSerialize_publishLength(int qos, MQTTString topicName, int payloadlen)
  28. {
  29. int len = 0;
  30. len += 2 + MQTTstrlen(topicName) + payloadlen;
  31. if (qos > 0)
  32. len += 2; /* packetid */
  33. return len;
  34. }
  35. /**
  36. * Serializes the supplied publish data into the supplied buffer, ready for sending
  37. * @param buf the buffer into which the packet will be serialized
  38. * @param buflen the length in bytes of the supplied buffer
  39. * @param dup integer - the MQTT dup flag
  40. * @param qos integer - the MQTT QoS value
  41. * @param retained integer - the MQTT retained flag
  42. * @param packetid integer - the MQTT packet identifier
  43. * @param topicName MQTTString - the MQTT topic in the publish
  44. * @param payload byte buffer - the MQTT publish payload
  45. * @param payloadlen integer - the length of the MQTT payload
  46. * @return the length of the serialized data. <= 0 indicates error
  47. */
  48. int MQTTSerialize_publish(unsigned char* buf, int buflen, unsigned char dup, int qos, unsigned char retained, unsigned short packetid,
  49. MQTTString topicName, unsigned char* payload, int payloadlen)
  50. {
  51. unsigned char *ptr = buf;
  52. MQTTHeader header = {0};
  53. int rem_len = 0;
  54. int rc = 0;
  55. FUNC_ENTRY;
  56. if (MQTTPacket_len(rem_len = MQTTSerialize_publishLength(qos, topicName, payloadlen)) > buflen)
  57. {
  58. rc = MQTTPACKET_BUFFER_TOO_SHORT;
  59. goto exit;
  60. }
  61. header.bits.type = PUBLISH;
  62. header.bits.dup = dup;
  63. header.bits.qos = qos;
  64. header.bits.retain = retained;
  65. writeChar(&ptr, header.byte); /* write header */
  66. ptr += MQTTPacket_encode(ptr, rem_len); /* write remaining length */;
  67. writeMQTTString(&ptr, topicName);
  68. if (qos > 0)
  69. writeInt(&ptr, packetid);
  70. memcpy(ptr, payload, payloadlen);
  71. ptr += payloadlen;
  72. rc = ptr - buf;
  73. exit:
  74. FUNC_EXIT_RC(rc);
  75. return rc;
  76. }
  77. /**
  78. * Serializes the ack packet into the supplied buffer.
  79. * @param buf the buffer into which the packet will be serialized
  80. * @param buflen the length in bytes of the supplied buffer
  81. * @param type the MQTT packet type
  82. * @param dup the MQTT dup flag
  83. * @param packetid the MQTT packet identifier
  84. * @return serialized length, or error if 0
  85. */
  86. int MQTTSerialize_ack(unsigned char* buf, int buflen, unsigned char packettype, unsigned char dup, unsigned short packetid)
  87. {
  88. MQTTHeader header = {0};
  89. int rc = 0;
  90. unsigned char *ptr = buf;
  91. FUNC_ENTRY;
  92. if (buflen < 4)
  93. {
  94. rc = MQTTPACKET_BUFFER_TOO_SHORT;
  95. goto exit;
  96. }
  97. header.bits.type = packettype;
  98. header.bits.dup = dup;
  99. header.bits.qos = (packettype == PUBREL) ? 1 : 0;
  100. writeChar(&ptr, header.byte); /* write header */
  101. ptr += MQTTPacket_encode(ptr, 2); /* write remaining length */
  102. writeInt(&ptr, packetid);
  103. rc = ptr - buf;
  104. exit:
  105. FUNC_EXIT_RC(rc);
  106. return rc;
  107. }
  108. /**
  109. * Serializes a puback packet into the supplied buffer.
  110. * @param buf the buffer into which the packet will be serialized
  111. * @param buflen the length in bytes of the supplied buffer
  112. * @param packetid integer - the MQTT packet identifier
  113. * @return serialized length, or error if 0
  114. */
  115. int MQTTSerialize_puback(unsigned char* buf, int buflen, unsigned short packetid)
  116. {
  117. return MQTTSerialize_ack(buf, buflen, PUBACK, 0, packetid);
  118. }
  119. int MQTTSerialize_pubrec(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid)
  120. {
  121. return MQTTSerialize_ack(buf, buflen, PUBREC, dup, packetid);
  122. }
  123. /**
  124. * Serializes a pubrel packet into the supplied buffer.
  125. * @param buf the buffer into which the packet will be serialized
  126. * @param buflen the length in bytes of the supplied buffer
  127. * @param dup integer - the MQTT dup flag
  128. * @param packetid integer - the MQTT packet identifier
  129. * @return serialized length, or error if 0
  130. */
  131. int MQTTSerialize_pubrel(unsigned char* buf, int buflen, unsigned char dup, unsigned short packetid)
  132. {
  133. return MQTTSerialize_ack(buf, buflen, PUBREL, dup, packetid);
  134. }
  135. /**
  136. * Serializes a pubrel packet into the supplied buffer.
  137. * @param buf the buffer into which the packet will be serialized
  138. * @param buflen the length in bytes of the supplied buffer
  139. * @param packetid integer - the MQTT packet identifier
  140. * @return serialized length, or error if 0
  141. */
  142. int MQTTSerialize_pubcomp(unsigned char* buf, int buflen, unsigned short packetid)
  143. {
  144. return MQTTSerialize_ack(buf, buflen, PUBCOMP, 0, packetid);
  145. }