mqtt_decoder.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /**
  2. * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. /** @file mqtt_decoder.c
  41. *
  42. * @brief Decoder functions needs for decoding packets received from the broker.
  43. */
  44. #include "mqtt_internal.h"
  45. #if MQTT_CONFIG_LOG_ENABLED
  46. #define NRF_LOG_MODULE_NAME mqtt_dec
  47. #define NRF_LOG_LEVEL MQTT_CONFIG_LOG_LEVEL
  48. #define NRF_LOG_INFO_COLOR MQTT_CONFIG_INFO_COLOR
  49. #define NRF_LOG_DEBUG_COLOR MQTT_CONFIG_DEBUG_COLOR
  50. #include "nrf_log.h"
  51. NRF_LOG_MODULE_REGISTER();
  52. #define MQTT_TRC NRF_LOG_DEBUG /**< Used for getting trace of execution in the module. */
  53. #define MQTT_ERR NRF_LOG_ERROR /**< Used for logging errors in the module. */
  54. #define MQTT_DUMP NRF_LOG_HEXDUMP_DEBUG /**< Used for dumping octet information to get details of bond information etc. */
  55. #define MQTT_ENTRY() MQTT_TRC(">> %s", __func__)
  56. #define MQTT_EXIT() MQTT_TRC("<< %s", __func__)
  57. #else // MQTT_CONFIG_LOG_ENABLED
  58. #define MQTT_TRC(...) /**< Disables traces. */
  59. #define MQTT_DUMP(...) /**< Disables dumping of octet streams. */
  60. #define MQTT_ERR(...) /**< Disables error logs. */
  61. #define MQTT_ENTRY(...)
  62. #define MQTT_EXIT(...)
  63. #endif // MQTT_CONFIG_LOG_ENABLED
  64. #define MQTT_LENGTH_VALUE_MASK 0x7F
  65. #define MQTT_LENGTH_CONTINUATION_BIT 0x80
  66. #define MQTT_LENGTH_MULTIPLIER 0x80
  67. uint32_t unpack_uint8(uint8_t * p_val,
  68. uint32_t buffer_len,
  69. uint8_t * const buffer,
  70. uint32_t * const p_offset)
  71. {
  72. uint32_t err_code = NRF_ERROR_DATA_SIZE;
  73. if (buffer_len > (*p_offset))
  74. {
  75. const uint32_t available_len = buffer_len - (*p_offset);
  76. MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
  77. buffer_len, buffer, (*p_offset), available_len);
  78. if (available_len >= SIZE_OF_UINT8)
  79. {
  80. // Create unit8 value.
  81. (*p_val) = buffer[*p_offset];
  82. // Increment offset.
  83. (*p_offset) += SIZE_OF_UINT8;
  84. // Indicate success.
  85. err_code = NRF_SUCCESS;
  86. }
  87. }
  88. MQTT_TRC("<< %s result:0x%08x val:0x%02x", __func__, err_code, (*p_val));
  89. return err_code;
  90. }
  91. uint32_t unpack_uint16(uint16_t * p_val,
  92. uint32_t buffer_len,
  93. uint8_t * const buffer,
  94. uint32_t * const p_offset)
  95. {
  96. uint32_t err_code = NRF_ERROR_DATA_SIZE;
  97. if (buffer_len > (*p_offset))
  98. {
  99. const uint32_t available_len = buffer_len - (*p_offset);
  100. MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
  101. buffer_len, buffer, (*p_offset), available_len);
  102. if (available_len >= SIZE_OF_UINT16)
  103. {
  104. // Create unit16 value.
  105. (*p_val) = ((buffer[*p_offset] & 0x00FF) << 8); // MSB
  106. (*p_val) |= (buffer[(*p_offset+1)] & 0x00FF); // LSB
  107. // Increment offset.
  108. (*p_offset) += SIZE_OF_UINT16;
  109. // Indicate success.
  110. err_code = NRF_SUCCESS;
  111. }
  112. }
  113. MQTT_TRC("<< %s result:0x%08x val:0x%04x", __func__, err_code, (*p_val));
  114. return err_code;
  115. }
  116. uint32_t unpack_utf8_str(mqtt_utf8_t * const p_str,
  117. uint32_t buffer_len,
  118. uint8_t * const buffer,
  119. uint32_t * const p_offset)
  120. {
  121. uint16_t utf8_strlen;
  122. uint32_t err_code = unpack_uint16(&utf8_strlen, buffer_len, buffer, p_offset);
  123. p_str->p_utf_str = NULL;
  124. p_str->utf_strlen = 0;
  125. if (err_code == NRF_SUCCESS)
  126. {
  127. const uint32_t available_len = buffer_len - (*p_offset);
  128. MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x A:%08x", __func__,
  129. buffer_len, buffer, (*p_offset), available_len);
  130. if (utf8_strlen <= available_len)
  131. {
  132. // Zero length UTF8 strings permitted.
  133. if (utf8_strlen)
  134. {
  135. // Point to right location in buffer.
  136. p_str->p_utf_str = &buffer[(*p_offset)];
  137. }
  138. // Populate length field.
  139. p_str->utf_strlen = utf8_strlen;
  140. // Increment offset.
  141. (*p_offset) += utf8_strlen;
  142. // Indicate success
  143. err_code = NRF_SUCCESS;
  144. }
  145. else
  146. {
  147. // Reset to original value.
  148. (*p_offset) -= SIZE_OF_UINT16;
  149. err_code = NRF_ERROR_DATA_SIZE;
  150. }
  151. }
  152. MQTT_TRC("<< %s result:0x%08x utf8 len:0x%08x", __func__, err_code, p_str->utf_strlen);
  153. return err_code;
  154. }
  155. uint32_t unpack_bin_str(mqtt_binstr_t * const p_str,
  156. uint32_t buffer_len,
  157. uint8_t * const buffer,
  158. uint32_t * const p_offset)
  159. {
  160. uint32_t error_code = NRF_ERROR_DATA_SIZE;
  161. MQTT_TRC(">> %s BL:%08x, B:%p, O:%08x", __func__,
  162. buffer_len, buffer, (*p_offset));
  163. if (buffer_len >= (*p_offset))
  164. {
  165. p_str->p_bin_str = NULL;
  166. p_str->bin_strlen = 0;
  167. // Indicate success zero length binary strings are permitted.
  168. error_code = NRF_SUCCESS;
  169. const uint32_t available_len = buffer_len - (*p_offset);
  170. if (available_len)
  171. {
  172. // Point to start of binary string.
  173. p_str->p_bin_str = &buffer[(*p_offset)];
  174. p_str->bin_strlen = available_len;
  175. // Increment offset.
  176. (*p_offset) += available_len;
  177. }
  178. }
  179. MQTT_TRC("<< %s bin len:0x%08x", __func__, p_str->bin_strlen);
  180. return error_code;
  181. }
  182. uint32_t packet_length_decode(uint8_t * p_buffer,
  183. uint32_t buffer_len,
  184. uint32_t * p_remaining_length,
  185. uint32_t * p_offset)
  186. {
  187. uint32_t index = (*p_offset);
  188. uint32_t remaining_length = 0;
  189. uint32_t multiplier = 1;
  190. do
  191. {
  192. if (index >= buffer_len)
  193. {
  194. return NRF_ERROR_DATA_SIZE;
  195. }
  196. remaining_length += (p_buffer[index] & MQTT_LENGTH_VALUE_MASK) * multiplier;
  197. multiplier *= MQTT_LENGTH_MULTIPLIER;
  198. } while ((p_buffer[index++] & MQTT_LENGTH_CONTINUATION_BIT) != 0);
  199. *p_offset = index;
  200. *p_remaining_length = remaining_length;
  201. MQTT_TRC("%s: RL:0x%08x RLS:0x%08x", __func__, remaining_length, index);
  202. return NRF_SUCCESS;
  203. }