core_mqtt_serializer.c 95 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706
  1. /*
  2. * coreMQTT <DEVELOPMENT BRANCH>
  3. * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  4. *
  5. * SPDX-License-Identifier: MIT
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy of
  8. * this software and associated documentation files (the "Software"), to deal in
  9. * the Software without restriction, including without limitation the rights to
  10. * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  11. * the Software, and to permit persons to whom the Software is furnished to do so,
  12. * subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in all
  15. * copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  19. * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  20. * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  21. * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  22. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. */
  24. /**
  25. * @file core_mqtt_serializer.c
  26. * @brief Implements the user-facing functions in core_mqtt_serializer.h.
  27. */
  28. #include <string.h>
  29. #include <assert.h>
  30. #include "core_mqtt_serializer.h"
  31. /* Include config defaults header to get default values of configs. */
  32. #include "core_mqtt_config_defaults.h"
  33. /**
  34. * @brief MQTT protocol version 3.1.1.
  35. */
  36. #define MQTT_VERSION_3_1_1 ( ( uint8_t ) 4U )
  37. /**
  38. * @brief Size of the fixed and variable header of a CONNECT packet.
  39. */
  40. #define MQTT_PACKET_CONNECT_HEADER_SIZE ( 10UL )
  41. /* MQTT CONNECT flags. */
  42. #define MQTT_CONNECT_FLAG_CLEAN ( 1 ) /**< @brief Clean session. */
  43. #define MQTT_CONNECT_FLAG_WILL ( 2 ) /**< @brief Will present. */
  44. #define MQTT_CONNECT_FLAG_WILL_QOS1 ( 3 ) /**< @brief Will QoS 1. */
  45. #define MQTT_CONNECT_FLAG_WILL_QOS2 ( 4 ) /**< @brief Will QoS 2. */
  46. #define MQTT_CONNECT_FLAG_WILL_RETAIN ( 5 ) /**< @brief Will retain. */
  47. #define MQTT_CONNECT_FLAG_PASSWORD ( 6 ) /**< @brief Password present. */
  48. #define MQTT_CONNECT_FLAG_USERNAME ( 7 ) /**< @brief User name present. */
  49. /*
  50. * Positions of each flag in the first byte of an MQTT PUBLISH packet's
  51. * fixed header.
  52. */
  53. #define MQTT_PUBLISH_FLAG_RETAIN ( 0 ) /**< @brief MQTT PUBLISH retain flag. */
  54. #define MQTT_PUBLISH_FLAG_QOS1 ( 1 ) /**< @brief MQTT PUBLISH QoS1 flag. */
  55. #define MQTT_PUBLISH_FLAG_QOS2 ( 2 ) /**< @brief MQTT PUBLISH QoS2 flag. */
  56. #define MQTT_PUBLISH_FLAG_DUP ( 3 ) /**< @brief MQTT PUBLISH duplicate flag. */
  57. /**
  58. * @brief The size of MQTT DISCONNECT packets, per MQTT spec.
  59. */
  60. #define MQTT_DISCONNECT_PACKET_SIZE ( 2UL )
  61. /**
  62. * @brief A PINGREQ packet is always 2 bytes in size, defined by MQTT 3.1.1 spec.
  63. */
  64. #define MQTT_PACKET_PINGREQ_SIZE ( 2UL )
  65. /**
  66. * @brief The Remaining Length field of MQTT disconnect packets, per MQTT spec.
  67. */
  68. #define MQTT_DISCONNECT_REMAINING_LENGTH ( ( uint8_t ) 0 )
  69. /*
  70. * Constants relating to CONNACK packets, defined by MQTT 3.1.1 spec.
  71. */
  72. #define MQTT_PACKET_CONNACK_REMAINING_LENGTH ( ( uint8_t ) 2U ) /**< @brief A CONNACK packet always has a "Remaining length" of 2. */
  73. #define MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK ( ( uint8_t ) 0x01U ) /**< @brief The "Session Present" bit is always the lowest bit. */
  74. /*
  75. * UNSUBACK, PUBACK, PUBREC, PUBREL, and PUBCOMP always have a remaining length
  76. * of 2.
  77. */
  78. #define MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH ( ( uint8_t ) 2 ) /**< @brief PUBACK, PUBREC, PUBREl, PUBCOMP, UNSUBACK Remaining length. */
  79. #define MQTT_PACKET_PINGRESP_REMAINING_LENGTH ( 0U ) /**< @brief A PINGRESP packet always has a "Remaining length" of 0. */
  80. /**
  81. * @brief Per the MQTT 3.1.1 spec, the largest "Remaining Length" of an MQTT
  82. * packet is this value, 256 MB.
  83. */
  84. #define MQTT_MAX_REMAINING_LENGTH ( 268435455UL )
  85. /**
  86. * @brief Set a bit in an 8-bit unsigned integer.
  87. */
  88. #define UINT8_SET_BIT( x, position ) ( ( x ) = ( uint8_t ) ( ( x ) | ( 0x01U << ( position ) ) ) )
  89. /**
  90. * @brief Clear a bit in an 8-bit unsigned integer.
  91. */
  92. #define UINT8_CLEAR_BIT( x, position ) ( ( x ) = ( uint8_t ) ( ( x ) & ( ~( 0x01U << ( position ) ) ) ) )
  93. /**
  94. * @brief Macro for checking if a bit is set in a 1-byte unsigned int.
  95. *
  96. * @param[in] x The unsigned int to check.
  97. * @param[in] position Which bit to check.
  98. */
  99. #define UINT8_CHECK_BIT( x, position ) ( ( ( x ) & ( 0x01U << ( position ) ) ) == ( 0x01U << ( position ) ) )
  100. /**
  101. * @brief Get the high byte of a 16-bit unsigned integer.
  102. */
  103. #define UINT16_HIGH_BYTE( x ) ( ( uint8_t ) ( ( x ) >> 8 ) )
  104. /**
  105. * @brief Get the low byte of a 16-bit unsigned integer.
  106. */
  107. #define UINT16_LOW_BYTE( x ) ( ( uint8_t ) ( ( x ) & 0x00ffU ) )
  108. /**
  109. * @brief Macro for decoding a 2-byte unsigned int from a sequence of bytes.
  110. *
  111. * @param[in] ptr A uint8_t* that points to the high byte.
  112. */
  113. #define UINT16_DECODE( ptr ) \
  114. ( uint16_t ) ( ( ( ( uint16_t ) ptr[ 0 ] ) << 8 ) | \
  115. ( ( uint16_t ) ptr[ 1 ] ) )
  116. /**
  117. * @brief A value that represents an invalid remaining length.
  118. *
  119. * This value is greater than what is allowed by the MQTT specification.
  120. */
  121. #define MQTT_REMAINING_LENGTH_INVALID ( ( size_t ) 268435456 )
  122. /**
  123. * @brief The minimum remaining length for a QoS 0 PUBLISH.
  124. *
  125. * Includes two bytes for topic name length and one byte for topic name.
  126. */
  127. #define MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0 ( 3U )
  128. /*-----------------------------------------------------------*/
  129. /**
  130. * @brief MQTT Subscription packet types.
  131. */
  132. typedef enum MQTTSubscriptionType
  133. {
  134. MQTT_SUBSCRIBE, /**< @brief The type is a SUBSCRIBE packet. */
  135. MQTT_UNSUBSCRIBE /**< @brief The type is a UNSUBSCRIBE packet. */
  136. } MQTTSubscriptionType_t;
  137. /*-----------------------------------------------------------*/
  138. /**
  139. * @brief Serializes MQTT PUBLISH packet into the buffer provided.
  140. *
  141. * This function serializes MQTT PUBLISH packet into #MQTTFixedBuffer_t.pBuffer.
  142. * Copy of the payload into the buffer is done as part of the serialization
  143. * only if @p serializePayload is true.
  144. *
  145. * @brief param[in] pPublishInfo Publish information.
  146. * @brief param[in] remainingLength Remaining length of the PUBLISH packet.
  147. * @brief param[in] packetIdentifier Packet identifier of PUBLISH packet.
  148. * @brief param[in, out] pFixedBuffer Buffer to which PUBLISH packet will be
  149. * serialized.
  150. * @brief param[in] serializePayload Copy payload to the serialized buffer
  151. * only if true. Only PUBLISH header will be serialized if false.
  152. */
  153. static void serializePublishCommon( const MQTTPublishInfo_t * pPublishInfo,
  154. size_t remainingLength,
  155. uint16_t packetIdentifier,
  156. const MQTTFixedBuffer_t * pFixedBuffer,
  157. bool serializePayload );
  158. /**
  159. * @brief Calculates the packet size and remaining length of an MQTT
  160. * PUBLISH packet.
  161. *
  162. * @param[in] pPublishInfo MQTT PUBLISH packet parameters.
  163. * @param[out] pRemainingLength The Remaining Length of the MQTT PUBLISH packet.
  164. * @param[out] pPacketSize The total size of the MQTT PUBLISH packet.
  165. *
  166. * @return false if the packet would exceed the size allowed by the
  167. * MQTT spec; true otherwise.
  168. */
  169. static bool calculatePublishPacketSize( const MQTTPublishInfo_t * pPublishInfo,
  170. size_t * pRemainingLength,
  171. size_t * pPacketSize );
  172. /**
  173. * @brief Calculates the packet size and remaining length of an MQTT
  174. * SUBSCRIBE or UNSUBSCRIBE packet.
  175. *
  176. * @param[in] pSubscriptionList List of MQTT subscription info.
  177. * @param[in] subscriptionCount The number of elements in pSubscriptionList.
  178. * @param[out] pRemainingLength The Remaining Length of the MQTT SUBSCRIBE or
  179. * UNSUBSCRIBE packet.
  180. * @param[out] pPacketSize The total size of the MQTT MQTT SUBSCRIBE or
  181. * UNSUBSCRIBE packet.
  182. * @param[in] subscriptionType #MQTT_SUBSCRIBE or #MQTT_UNSUBSCRIBE.
  183. *
  184. * #MQTTBadParameter if the packet would exceed the size allowed by the
  185. * MQTT spec or a subscription is empty; #MQTTSuccess otherwise.
  186. */
  187. static MQTTStatus_t calculateSubscriptionPacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  188. size_t subscriptionCount,
  189. size_t * pRemainingLength,
  190. size_t * pPacketSize,
  191. MQTTSubscriptionType_t subscriptionType );
  192. /**
  193. * @brief Validates parameters of #MQTT_SerializeSubscribe or
  194. * #MQTT_SerializeUnsubscribe.
  195. *
  196. * @param[in] pSubscriptionList List of MQTT subscription info.
  197. * @param[in] subscriptionCount The number of elements in pSubscriptionList.
  198. * @param[in] packetId Packet identifier.
  199. * @param[in] remainingLength Remaining length of the packet.
  200. * @param[in] pFixedBuffer Buffer for packet serialization.
  201. *
  202. * @return #MQTTNoMemory if pBuffer is too small to hold the MQTT packet;
  203. * #MQTTBadParameter if invalid parameters are passed;
  204. * #MQTTSuccess otherwise.
  205. */
  206. static MQTTStatus_t validateSubscriptionSerializeParams( const MQTTSubscribeInfo_t * pSubscriptionList,
  207. size_t subscriptionCount,
  208. uint16_t packetId,
  209. size_t remainingLength,
  210. const MQTTFixedBuffer_t * pFixedBuffer );
  211. /**
  212. * @brief Serialize an MQTT CONNECT packet in the given buffer.
  213. *
  214. * @param[in] pConnectInfo MQTT CONNECT packet parameters.
  215. * @param[in] pWillInfo Last Will and Testament. Pass NULL if not used.
  216. * @param[in] remainingLength Remaining Length of MQTT CONNECT packet.
  217. * @param[out] pFixedBuffer Buffer for packet serialization.
  218. */
  219. static void serializeConnectPacket( const MQTTConnectInfo_t * pConnectInfo,
  220. const MQTTPublishInfo_t * pWillInfo,
  221. size_t remainingLength,
  222. const MQTTFixedBuffer_t * pFixedBuffer );
  223. /**
  224. * @brief Prints the appropriate message for the CONNACK response code if logs
  225. * are enabled.
  226. *
  227. * @param[in] responseCode MQTT standard CONNACK response code.
  228. */
  229. static void logConnackResponse( uint8_t responseCode );
  230. /**
  231. * @brief Encodes the remaining length of the packet using the variable length
  232. * encoding scheme provided in the MQTT v3.1.1 specification.
  233. *
  234. * @param[out] pDestination The destination buffer to store the encoded remaining
  235. * length.
  236. * @param[in] length The remaining length to encode.
  237. *
  238. * @return The location of the byte following the encoded value.
  239. */
  240. static uint8_t * encodeRemainingLength( uint8_t * pDestination,
  241. size_t length );
  242. /**
  243. * @brief Retrieve the size of the remaining length if it were to be encoded.
  244. *
  245. * @param[in] length The remaining length to be encoded.
  246. *
  247. * @return The size of the remaining length if it were to be encoded.
  248. */
  249. static size_t remainingLengthEncodedSize( size_t length );
  250. /**
  251. * @brief Encode a string whose size is at maximum 16 bits in length.
  252. *
  253. * @param[out] pDestination Destination buffer for the encoding.
  254. * @param[in] pSource The source string to encode.
  255. * @param[in] sourceLength The length of the source string to encode.
  256. *
  257. * @return A pointer to the end of the encoded string.
  258. */
  259. static uint8_t * encodeString( uint8_t * pDestination,
  260. const char * pSource,
  261. uint16_t sourceLength );
  262. /**
  263. * @brief Retrieves and decodes the Remaining Length from the network interface
  264. * by reading a single byte at a time.
  265. *
  266. * @param[in] recvFunc Network interface receive function.
  267. * @param[in] pNetworkContext Network interface context to the receive function.
  268. *
  269. * @return The Remaining Length of the incoming packet.
  270. */
  271. static size_t getRemainingLength( TransportRecv_t recvFunc,
  272. NetworkContext_t * pNetworkContext );
  273. /**
  274. * @brief Retrieves, decodes and stores the Remaining Length from the network
  275. * interface by reading a single byte at a time.
  276. *
  277. * @param[in] pBuffer The buffer holding the raw data to be processed
  278. * @param[in] pIndex Pointer to the index within the buffer to marking the end of raw data
  279. * available.
  280. * @param[in] pIncomingPacket Structure used to hold the fields of the
  281. * incoming packet.
  282. *
  283. * @return MQTTNeedMoreBytes is returned to show that the incoming
  284. * packet is not yet fully received and decoded. Otherwise, MQTTSuccess
  285. * shows that processing of the packet was successful.
  286. */
  287. static MQTTStatus_t processRemainingLength( const uint8_t * pBuffer,
  288. const size_t * pIndex,
  289. MQTTPacketInfo_t * pIncomingPacket );
  290. /**
  291. * @brief Check if an incoming packet type is valid.
  292. *
  293. * @param[in] packetType The packet type to check.
  294. *
  295. * @return `true` if the packet type is valid; `false` otherwise.
  296. */
  297. static bool incomingPacketValid( uint8_t packetType );
  298. /**
  299. * @brief Check the remaining length of an incoming PUBLISH packet against some
  300. * value for QoS 0, or for QoS 1 and 2.
  301. *
  302. * The remaining length for a QoS 1 and 2 packet will always be two greater than
  303. * for a QoS 0.
  304. *
  305. * @param[in] remainingLength Remaining length of the PUBLISH packet.
  306. * @param[in] qos The QoS of the PUBLISH.
  307. * @param[in] qos0Minimum Minimum possible remaining length for a QoS 0 PUBLISH.
  308. *
  309. * @return #MQTTSuccess or #MQTTBadResponse.
  310. */
  311. static MQTTStatus_t checkPublishRemainingLength( size_t remainingLength,
  312. MQTTQoS_t qos,
  313. size_t qos0Minimum );
  314. /**
  315. * @brief Process the flags of an incoming PUBLISH packet.
  316. *
  317. * @param[in] publishFlags Flags of an incoming PUBLISH.
  318. * @param[in, out] pPublishInfo Pointer to #MQTTPublishInfo_t struct where
  319. * output will be written.
  320. *
  321. * @return #MQTTSuccess or #MQTTBadResponse.
  322. */
  323. static MQTTStatus_t processPublishFlags( uint8_t publishFlags,
  324. MQTTPublishInfo_t * pPublishInfo );
  325. /**
  326. * @brief Deserialize a CONNACK packet.
  327. *
  328. * Converts the packet from a stream of bytes to an #MQTTStatus_t.
  329. *
  330. * @param[in] pConnack Pointer to an MQTT packet struct representing a
  331. * CONNACK.
  332. * @param[out] pSessionPresent Whether a previous session was present.
  333. *
  334. * @return #MQTTSuccess if CONNACK specifies that CONNECT was accepted;
  335. * #MQTTServerRefused if CONNACK specifies that CONNECT was rejected;
  336. * #MQTTBadResponse if the CONNACK packet doesn't follow MQTT spec.
  337. */
  338. static MQTTStatus_t deserializeConnack( const MQTTPacketInfo_t * pConnack,
  339. bool * pSessionPresent );
  340. /**
  341. * @brief Decode the status bytes of a SUBACK packet to a #MQTTStatus_t.
  342. *
  343. * @param[in] statusCount Number of status bytes in the SUBACK.
  344. * @param[in] pStatusStart The first status byte in the SUBACK.
  345. *
  346. * @return #MQTTSuccess, #MQTTServerRefused, or #MQTTBadResponse.
  347. */
  348. static MQTTStatus_t readSubackStatus( size_t statusCount,
  349. const uint8_t * pStatusStart );
  350. /**
  351. * @brief Deserialize a SUBACK packet.
  352. *
  353. * Converts the packet from a stream of bytes to an #MQTTStatus_t and extracts
  354. * the packet identifier.
  355. *
  356. * @param[in] pSuback Pointer to an MQTT packet struct representing a SUBACK.
  357. * @param[out] pPacketIdentifier Packet ID of the SUBACK.
  358. *
  359. * @return #MQTTSuccess if SUBACK is valid; #MQTTBadResponse if SUBACK packet
  360. * doesn't follow the MQTT spec.
  361. */
  362. static MQTTStatus_t deserializeSuback( const MQTTPacketInfo_t * pSuback,
  363. uint16_t * pPacketIdentifier );
  364. /**
  365. * @brief Deserialize a PUBLISH packet received from the server.
  366. *
  367. * Converts the packet from a stream of bytes to an #MQTTPublishInfo_t and
  368. * extracts the packet identifier. Also prints out debug log messages about the
  369. * packet.
  370. *
  371. * @param[in] pIncomingPacket Pointer to an MQTT packet struct representing a
  372. * PUBLISH.
  373. * @param[out] pPacketId Packet identifier of the PUBLISH.
  374. * @param[out] pPublishInfo Pointer to #MQTTPublishInfo_t where output is
  375. * written.
  376. *
  377. * @return #MQTTSuccess if PUBLISH is valid; #MQTTBadResponse
  378. * if the PUBLISH packet doesn't follow MQTT spec.
  379. */
  380. static MQTTStatus_t deserializePublish( const MQTTPacketInfo_t * pIncomingPacket,
  381. uint16_t * pPacketId,
  382. MQTTPublishInfo_t * pPublishInfo );
  383. /**
  384. * @brief Deserialize an UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP packet.
  385. *
  386. * Converts the packet from a stream of bytes to an #MQTTStatus_t and extracts
  387. * the packet identifier.
  388. *
  389. * @param[in] pAck Pointer to the MQTT packet structure representing the packet.
  390. * @param[out] pPacketIdentifier Packet ID of the ack type packet.
  391. *
  392. * @return #MQTTSuccess if UNSUBACK, PUBACK, PUBREC, PUBREL, or PUBCOMP is valid;
  393. * #MQTTBadResponse if the packet doesn't follow the MQTT spec.
  394. */
  395. static MQTTStatus_t deserializeSimpleAck( const MQTTPacketInfo_t * pAck,
  396. uint16_t * pPacketIdentifier );
  397. /**
  398. * @brief Deserialize a PINGRESP packet.
  399. *
  400. * Converts the packet from a stream of bytes to an #MQTTStatus_t.
  401. *
  402. * @param[in] pPingresp Pointer to an MQTT packet struct representing a PINGRESP.
  403. *
  404. * @return #MQTTSuccess if PINGRESP is valid; #MQTTBadResponse if the PINGRESP
  405. * packet doesn't follow MQTT spec.
  406. */
  407. static MQTTStatus_t deserializePingresp( const MQTTPacketInfo_t * pPingresp );
  408. /*-----------------------------------------------------------*/
  409. static size_t remainingLengthEncodedSize( size_t length )
  410. {
  411. size_t encodedSize;
  412. /* Determine how many bytes are needed to encode length.
  413. * The values below are taken from the MQTT 3.1.1 spec. */
  414. /* 1 byte is needed to encode lengths between 0 and 127. */
  415. if( length < 128U )
  416. {
  417. encodedSize = 1U;
  418. }
  419. /* 2 bytes are needed to encode lengths between 128 and 16,383. */
  420. else if( length < 16384U )
  421. {
  422. encodedSize = 2U;
  423. }
  424. /* 3 bytes are needed to encode lengths between 16,384 and 2,097,151. */
  425. else if( length < 2097152U )
  426. {
  427. encodedSize = 3U;
  428. }
  429. /* 4 bytes are needed to encode lengths between 2,097,152 and 268,435,455. */
  430. else
  431. {
  432. encodedSize = 4U;
  433. }
  434. LogDebug( ( "Encoded size for length %lu is %lu bytes.",
  435. ( unsigned long ) length,
  436. ( unsigned long ) encodedSize ) );
  437. return encodedSize;
  438. }
  439. /*-----------------------------------------------------------*/
  440. static uint8_t * encodeRemainingLength( uint8_t * pDestination,
  441. size_t length )
  442. {
  443. uint8_t lengthByte;
  444. uint8_t * pLengthEnd = NULL;
  445. size_t remainingLength = length;
  446. assert( pDestination != NULL );
  447. pLengthEnd = pDestination;
  448. /* This algorithm is copied from the MQTT v3.1.1 spec. */
  449. do
  450. {
  451. lengthByte = ( uint8_t ) ( remainingLength % 128U );
  452. remainingLength = remainingLength / 128U;
  453. /* Set the high bit of this byte, indicating that there's more data. */
  454. if( remainingLength > 0U )
  455. {
  456. UINT8_SET_BIT( lengthByte, 7 );
  457. }
  458. /* Output a single encoded byte. */
  459. *pLengthEnd = lengthByte;
  460. pLengthEnd++;
  461. } while( remainingLength > 0U );
  462. return pLengthEnd;
  463. }
  464. /*-----------------------------------------------------------*/
  465. static uint8_t * encodeString( uint8_t * pDestination,
  466. const char * pSource,
  467. uint16_t sourceLength )
  468. {
  469. uint8_t * pBuffer = NULL;
  470. assert( pDestination != NULL );
  471. pBuffer = pDestination;
  472. /* The first byte of a UTF-8 string is the high byte of the string length. */
  473. *pBuffer = UINT16_HIGH_BYTE( sourceLength );
  474. pBuffer++;
  475. /* The second byte of a UTF-8 string is the low byte of the string length. */
  476. *pBuffer = UINT16_LOW_BYTE( sourceLength );
  477. pBuffer++;
  478. /* Copy the string into pBuffer. */
  479. if( pSource != NULL )
  480. {
  481. ( void ) memcpy( ( void * ) pBuffer, ( const void * ) pSource, sourceLength );
  482. }
  483. /* Return the pointer to the end of the encoded string. */
  484. pBuffer = &pBuffer[ sourceLength ];
  485. return pBuffer;
  486. }
  487. /*-----------------------------------------------------------*/
  488. static bool calculatePublishPacketSize( const MQTTPublishInfo_t * pPublishInfo,
  489. size_t * pRemainingLength,
  490. size_t * pPacketSize )
  491. {
  492. bool status = true;
  493. size_t packetSize = 0, payloadLimit = 0;
  494. assert( pPublishInfo != NULL );
  495. assert( pRemainingLength != NULL );
  496. assert( pPacketSize != NULL );
  497. /* The variable header of a PUBLISH packet always contains the topic name.
  498. * The first 2 bytes of UTF-8 string contains length of the string.
  499. */
  500. packetSize += pPublishInfo->topicNameLength + sizeof( uint16_t );
  501. /* The variable header of a QoS 1 or 2 PUBLISH packet contains a 2-byte
  502. * packet identifier. */
  503. if( pPublishInfo->qos > MQTTQoS0 )
  504. {
  505. packetSize += sizeof( uint16_t );
  506. }
  507. /* Calculate the maximum allowed size of the payload for the given parameters.
  508. * This calculation excludes the "Remaining length" encoding, whose size is not
  509. * yet known. */
  510. payloadLimit = MQTT_MAX_REMAINING_LENGTH - packetSize - 1U;
  511. /* Ensure that the given payload fits within the calculated limit. */
  512. if( pPublishInfo->payloadLength > payloadLimit )
  513. {
  514. LogError( ( "PUBLISH payload length of %lu cannot exceed "
  515. "%lu so as not to exceed the maximum "
  516. "remaining length of MQTT 3.1.1 packet( %lu ).",
  517. ( unsigned long ) pPublishInfo->payloadLength,
  518. ( unsigned long ) payloadLimit,
  519. MQTT_MAX_REMAINING_LENGTH ) );
  520. status = false;
  521. }
  522. else
  523. {
  524. /* Add the length of the PUBLISH payload. At this point, the "Remaining length"
  525. * has been calculated. */
  526. packetSize += pPublishInfo->payloadLength;
  527. /* Now that the "Remaining length" is known, recalculate the payload limit
  528. * based on the size of its encoding. */
  529. payloadLimit -= remainingLengthEncodedSize( packetSize );
  530. /* Check that the given payload fits within the size allowed by MQTT spec. */
  531. if( pPublishInfo->payloadLength > payloadLimit )
  532. {
  533. LogError( ( "PUBLISH payload length of %lu cannot exceed "
  534. "%lu so as not to exceed the maximum "
  535. "remaining length of MQTT 3.1.1 packet( %lu ).",
  536. ( unsigned long ) pPublishInfo->payloadLength,
  537. ( unsigned long ) payloadLimit,
  538. MQTT_MAX_REMAINING_LENGTH ) );
  539. status = false;
  540. }
  541. else
  542. {
  543. /* Set the "Remaining length" output parameter and calculate the full
  544. * size of the PUBLISH packet. */
  545. *pRemainingLength = packetSize;
  546. packetSize += 1U + remainingLengthEncodedSize( packetSize );
  547. *pPacketSize = packetSize;
  548. }
  549. }
  550. LogDebug( ( "PUBLISH packet remaining length=%lu and packet size=%lu.",
  551. ( unsigned long ) *pRemainingLength,
  552. ( unsigned long ) *pPacketSize ) );
  553. return status;
  554. }
  555. /*-----------------------------------------------------------*/
  556. MQTTStatus_t MQTT_SerializePublishHeaderWithoutTopic( const MQTTPublishInfo_t * pPublishInfo,
  557. size_t remainingLength,
  558. uint8_t * pBuffer,
  559. size_t * headerSize )
  560. {
  561. size_t headerLength;
  562. uint8_t * pIndex;
  563. MQTTStatus_t status = MQTTSuccess;
  564. /* The first byte of a PUBLISH packet contains the packet type and flags. */
  565. uint8_t publishFlags = MQTT_PACKET_TYPE_PUBLISH;
  566. /* Get the start address of the buffer. */
  567. pIndex = pBuffer;
  568. /* Length of serialized packet = First byte
  569. * + Length of encoded remaining length
  570. * + Encoded topic length. */
  571. headerLength = 1U + remainingLengthEncodedSize( remainingLength ) + 2U;
  572. if( pPublishInfo->qos == MQTTQoS1 )
  573. {
  574. LogDebug( ( "Adding QoS as QoS1 in PUBLISH flags." ) );
  575. UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 );
  576. }
  577. else if( pPublishInfo->qos == MQTTQoS2 )
  578. {
  579. LogDebug( ( "Adding QoS as QoS2 in PUBLISH flags." ) );
  580. UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 );
  581. }
  582. else
  583. {
  584. /* Empty else MISRA 15.7 */
  585. }
  586. if( pPublishInfo->retain == true )
  587. {
  588. LogDebug( ( "Adding retain bit in PUBLISH flags." ) );
  589. UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN );
  590. }
  591. if( pPublishInfo->dup == true )
  592. {
  593. LogDebug( ( "Adding dup bit in PUBLISH flags." ) );
  594. UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_DUP );
  595. }
  596. *pIndex = publishFlags;
  597. pIndex++;
  598. /* The "Remaining length" is encoded from the second byte. */
  599. pIndex = encodeRemainingLength( pIndex, remainingLength );
  600. /* The first byte of a UTF-8 string is the high byte of the string length. */
  601. *pIndex = UINT16_HIGH_BYTE( pPublishInfo->topicNameLength );
  602. pIndex++;
  603. /* The second byte of a UTF-8 string is the low byte of the string length. */
  604. *pIndex = UINT16_LOW_BYTE( pPublishInfo->topicNameLength );
  605. pIndex++;
  606. *headerSize = headerLength;
  607. return status;
  608. }
  609. /*-----------------------------------------------------------*/
  610. static void serializePublishCommon( const MQTTPublishInfo_t * pPublishInfo,
  611. size_t remainingLength,
  612. uint16_t packetIdentifier,
  613. const MQTTFixedBuffer_t * pFixedBuffer,
  614. bool serializePayload )
  615. {
  616. uint8_t * pIndex = NULL;
  617. /* The first byte of a PUBLISH packet contains the packet type and flags. */
  618. uint8_t publishFlags = MQTT_PACKET_TYPE_PUBLISH;
  619. assert( pPublishInfo != NULL );
  620. assert( pFixedBuffer != NULL );
  621. assert( pFixedBuffer->pBuffer != NULL );
  622. /* Packet Id should be non zero for Qos 1 and Qos 2. */
  623. assert( ( pPublishInfo->qos == MQTTQoS0 ) || ( packetIdentifier != 0U ) );
  624. /* Duplicate flag should be set only for Qos 1 or Qos 2. */
  625. assert( ( pPublishInfo->dup != true ) || ( pPublishInfo->qos != MQTTQoS0 ) );
  626. /* Get the start address of the buffer. */
  627. pIndex = pFixedBuffer->pBuffer;
  628. if( pPublishInfo->qos == MQTTQoS1 )
  629. {
  630. LogDebug( ( "Adding QoS as QoS1 in PUBLISH flags." ) );
  631. UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 );
  632. }
  633. else if( pPublishInfo->qos == MQTTQoS2 )
  634. {
  635. LogDebug( ( "Adding QoS as QoS2 in PUBLISH flags." ) );
  636. UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 );
  637. }
  638. else
  639. {
  640. /* Empty else MISRA 15.7 */
  641. }
  642. if( pPublishInfo->retain == true )
  643. {
  644. LogDebug( ( "Adding retain bit in PUBLISH flags." ) );
  645. UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN );
  646. }
  647. if( pPublishInfo->dup == true )
  648. {
  649. LogDebug( ( "Adding dup bit in PUBLISH flags." ) );
  650. UINT8_SET_BIT( publishFlags, MQTT_PUBLISH_FLAG_DUP );
  651. }
  652. *pIndex = publishFlags;
  653. pIndex++;
  654. /* The "Remaining length" is encoded from the second byte. */
  655. pIndex = encodeRemainingLength( pIndex, remainingLength );
  656. /* The topic name is placed after the "Remaining length". */
  657. pIndex = encodeString( pIndex,
  658. pPublishInfo->pTopicName,
  659. pPublishInfo->topicNameLength );
  660. /* A packet identifier is required for QoS 1 and 2 messages. */
  661. if( pPublishInfo->qos > MQTTQoS0 )
  662. {
  663. LogDebug( ( "Adding packet Id in PUBLISH packet." ) );
  664. /* Place the packet identifier into the PUBLISH packet. */
  665. *pIndex = UINT16_HIGH_BYTE( packetIdentifier );
  666. pIndex[ 1U ] = UINT16_LOW_BYTE( packetIdentifier );
  667. pIndex = &pIndex[ 2U ];
  668. }
  669. /* The payload is placed after the packet identifier.
  670. * Payload is copied over only if required by the flag serializePayload.
  671. * This will help reduce an unnecessary copy of the payload into the buffer.
  672. */
  673. if( ( pPublishInfo->payloadLength > 0U ) &&
  674. ( serializePayload == true ) )
  675. {
  676. LogDebug( ( "Copying PUBLISH payload of length =%lu to buffer",
  677. ( unsigned long ) pPublishInfo->payloadLength ) );
  678. ( void ) memcpy( ( void * ) pIndex, ( const void * ) pPublishInfo->pPayload, pPublishInfo->payloadLength );
  679. /* Move the index to after the payload. */
  680. pIndex = &pIndex[ pPublishInfo->payloadLength ];
  681. }
  682. /* Ensure that the difference between the end and beginning of the buffer
  683. * is less than the buffer size. */
  684. assert( ( ( size_t ) ( pIndex - pFixedBuffer->pBuffer ) ) <= pFixedBuffer->size );
  685. }
  686. static size_t getRemainingLength( TransportRecv_t recvFunc,
  687. NetworkContext_t * pNetworkContext )
  688. {
  689. size_t remainingLength = 0, multiplier = 1, bytesDecoded = 0, expectedSize = 0;
  690. uint8_t encodedByte = 0;
  691. int32_t bytesReceived = 0;
  692. /* This algorithm is copied from the MQTT v3.1.1 spec. */
  693. do
  694. {
  695. if( multiplier > 2097152U ) /* 128 ^ 3 */
  696. {
  697. remainingLength = MQTT_REMAINING_LENGTH_INVALID;
  698. }
  699. else
  700. {
  701. bytesReceived = recvFunc( pNetworkContext, &encodedByte, 1U );
  702. if( bytesReceived == 1 )
  703. {
  704. remainingLength += ( ( size_t ) encodedByte & 0x7FU ) * multiplier;
  705. multiplier *= 128U;
  706. bytesDecoded++;
  707. }
  708. else
  709. {
  710. remainingLength = MQTT_REMAINING_LENGTH_INVALID;
  711. }
  712. }
  713. if( remainingLength == MQTT_REMAINING_LENGTH_INVALID )
  714. {
  715. break;
  716. }
  717. } while( ( encodedByte & 0x80U ) != 0U );
  718. /* Check that the decoded remaining length conforms to the MQTT specification. */
  719. if( remainingLength != MQTT_REMAINING_LENGTH_INVALID )
  720. {
  721. expectedSize = remainingLengthEncodedSize( remainingLength );
  722. if( bytesDecoded != expectedSize )
  723. {
  724. remainingLength = MQTT_REMAINING_LENGTH_INVALID;
  725. }
  726. }
  727. return remainingLength;
  728. }
  729. /*-----------------------------------------------------------*/
  730. static MQTTStatus_t processRemainingLength( const uint8_t * pBuffer,
  731. const size_t * pIndex,
  732. MQTTPacketInfo_t * pIncomingPacket )
  733. {
  734. size_t remainingLength = 0;
  735. size_t multiplier = 1;
  736. size_t bytesDecoded = 0;
  737. size_t expectedSize = 0;
  738. uint8_t encodedByte = 0;
  739. MQTTStatus_t status = MQTTSuccess;
  740. /* This algorithm is copied from the MQTT v3.1.1 spec. */
  741. do
  742. {
  743. if( multiplier > 2097152U ) /* 128 ^ 3 */
  744. {
  745. remainingLength = MQTT_REMAINING_LENGTH_INVALID;
  746. LogError( ( "Invalid remaining length in the packet.\n" ) );
  747. status = MQTTBadResponse;
  748. }
  749. else
  750. {
  751. if( *pIndex > ( bytesDecoded + 1U ) )
  752. {
  753. /* Get the next byte. It is at the next position after the bytes
  754. * decoded till now since the header of one byte was read before. */
  755. encodedByte = pBuffer[ bytesDecoded + 1U ];
  756. remainingLength += ( ( size_t ) encodedByte & 0x7FU ) * multiplier;
  757. multiplier *= 128U;
  758. bytesDecoded++;
  759. }
  760. else
  761. {
  762. status = MQTTNeedMoreBytes;
  763. }
  764. }
  765. /* If the response is incorrect, or no more data is available, then
  766. * break out of the loop. */
  767. if( ( remainingLength == MQTT_REMAINING_LENGTH_INVALID ) ||
  768. ( status != MQTTSuccess ) )
  769. {
  770. break;
  771. }
  772. } while( ( encodedByte & 0x80U ) != 0U );
  773. if( status == MQTTSuccess )
  774. {
  775. /* Check that the decoded remaining length conforms to the MQTT specification. */
  776. expectedSize = remainingLengthEncodedSize( remainingLength );
  777. if( bytesDecoded != expectedSize )
  778. {
  779. LogError( ( "Expected and actual length of decoded bytes do not match.\n" ) );
  780. status = MQTTBadResponse;
  781. }
  782. else
  783. {
  784. pIncomingPacket->remainingLength = remainingLength;
  785. pIncomingPacket->headerLength = bytesDecoded + 1U;
  786. }
  787. }
  788. return status;
  789. }
  790. /*-----------------------------------------------------------*/
  791. static bool incomingPacketValid( uint8_t packetType )
  792. {
  793. bool status = false;
  794. /* Check packet type. Mask out lower bits to ignore flags. */
  795. switch( packetType & 0xF0U )
  796. {
  797. /* Valid incoming packet types. */
  798. case MQTT_PACKET_TYPE_CONNACK:
  799. case MQTT_PACKET_TYPE_PUBLISH:
  800. case MQTT_PACKET_TYPE_PUBACK:
  801. case MQTT_PACKET_TYPE_PUBREC:
  802. case MQTT_PACKET_TYPE_PUBCOMP:
  803. case MQTT_PACKET_TYPE_SUBACK:
  804. case MQTT_PACKET_TYPE_UNSUBACK:
  805. case MQTT_PACKET_TYPE_PINGRESP:
  806. status = true;
  807. break;
  808. case ( MQTT_PACKET_TYPE_PUBREL & 0xF0U ):
  809. /* The second bit of a PUBREL must be set. */
  810. if( ( packetType & 0x02U ) > 0U )
  811. {
  812. status = true;
  813. }
  814. break;
  815. /* Any other packet type is invalid. */
  816. default:
  817. LogWarn( ( "Incoming packet invalid: Packet type=%u.",
  818. ( unsigned int ) packetType ) );
  819. break;
  820. }
  821. return status;
  822. }
  823. /*-----------------------------------------------------------*/
  824. static MQTTStatus_t checkPublishRemainingLength( size_t remainingLength,
  825. MQTTQoS_t qos,
  826. size_t qos0Minimum )
  827. {
  828. MQTTStatus_t status = MQTTSuccess;
  829. /* Sanity checks for "Remaining length". */
  830. if( qos == MQTTQoS0 )
  831. {
  832. /* Check that the "Remaining length" is greater than the minimum. */
  833. if( remainingLength < qos0Minimum )
  834. {
  835. LogError( ( "QoS 0 PUBLISH cannot have a remaining length less than %lu.",
  836. ( unsigned long ) qos0Minimum ) );
  837. status = MQTTBadResponse;
  838. }
  839. }
  840. else
  841. {
  842. /* Check that the "Remaining length" is greater than the minimum. For
  843. * QoS 1 or 2, this will be two bytes greater than for QoS 0 due to the
  844. * packet identifier. */
  845. if( remainingLength < ( qos0Minimum + 2U ) )
  846. {
  847. LogError( ( "QoS 1 or 2 PUBLISH cannot have a remaining length less than %lu.",
  848. ( unsigned long ) ( qos0Minimum + 2U ) ) );
  849. status = MQTTBadResponse;
  850. }
  851. }
  852. return status;
  853. }
  854. /*-----------------------------------------------------------*/
  855. static MQTTStatus_t processPublishFlags( uint8_t publishFlags,
  856. MQTTPublishInfo_t * pPublishInfo )
  857. {
  858. MQTTStatus_t status = MQTTSuccess;
  859. assert( pPublishInfo != NULL );
  860. /* Check for QoS 2. */
  861. if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 ) )
  862. {
  863. /* PUBLISH packet is invalid if both QoS 1 and QoS 2 bits are set. */
  864. if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) )
  865. {
  866. LogError( ( "Bad QoS: 3." ) );
  867. status = MQTTBadResponse;
  868. }
  869. else
  870. {
  871. pPublishInfo->qos = MQTTQoS2;
  872. }
  873. }
  874. /* Check for QoS 1. */
  875. else if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) )
  876. {
  877. pPublishInfo->qos = MQTTQoS1;
  878. }
  879. /* If the PUBLISH isn't QoS 1 or 2, then it's QoS 0. */
  880. else
  881. {
  882. pPublishInfo->qos = MQTTQoS0;
  883. }
  884. if( status == MQTTSuccess )
  885. {
  886. LogDebug( ( "QoS is %d.", ( int ) pPublishInfo->qos ) );
  887. /* Parse the Retain bit. */
  888. pPublishInfo->retain = UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN );
  889. LogDebug( ( "Retain bit is %d.", ( int ) pPublishInfo->retain ) );
  890. /* Parse the DUP bit. */
  891. pPublishInfo->dup = UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_DUP );
  892. LogDebug( ( "DUP bit is %d.", ( int ) pPublishInfo->dup ) );
  893. }
  894. return status;
  895. }
  896. /*-----------------------------------------------------------*/
  897. static void logConnackResponse( uint8_t responseCode )
  898. {
  899. const char * const pConnackResponses[ 6 ] =
  900. {
  901. "Connection accepted.", /* 0 */
  902. "Connection refused: unacceptable protocol version.", /* 1 */
  903. "Connection refused: identifier rejected.", /* 2 */
  904. "Connection refused: server unavailable", /* 3 */
  905. "Connection refused: bad user name or password.", /* 4 */
  906. "Connection refused: not authorized." /* 5 */
  907. };
  908. /* Avoid unused parameter warning when assert and logs are disabled. */
  909. ( void ) responseCode;
  910. ( void ) pConnackResponses;
  911. assert( responseCode <= 5U );
  912. if( responseCode == 0u )
  913. {
  914. /* Log at Debug level for a success CONNACK response. */
  915. LogDebug( ( "%s", pConnackResponses[ 0 ] ) );
  916. }
  917. else
  918. {
  919. /* Log an error based on the CONNACK response code. */
  920. LogError( ( "%s", pConnackResponses[ responseCode ] ) );
  921. }
  922. }
  923. /*-----------------------------------------------------------*/
  924. static MQTTStatus_t deserializeConnack( const MQTTPacketInfo_t * pConnack,
  925. bool * pSessionPresent )
  926. {
  927. MQTTStatus_t status = MQTTSuccess;
  928. const uint8_t * pRemainingData = NULL;
  929. assert( pConnack != NULL );
  930. assert( pSessionPresent != NULL );
  931. pRemainingData = pConnack->pRemainingData;
  932. /* According to MQTT 3.1.1, the second byte of CONNACK must specify a
  933. * "Remaining length" of 2. */
  934. if( pConnack->remainingLength != MQTT_PACKET_CONNACK_REMAINING_LENGTH )
  935. {
  936. LogError( ( "CONNACK does not have remaining length of %u.",
  937. ( unsigned int ) MQTT_PACKET_CONNACK_REMAINING_LENGTH ) );
  938. status = MQTTBadResponse;
  939. }
  940. /* Check the reserved bits in CONNACK. The high 7 bits of the third byte
  941. * in CONNACK must be 0. */
  942. else if( ( pRemainingData[ 0 ] | 0x01U ) != 0x01U )
  943. {
  944. LogError( ( "Reserved bits in CONNACK incorrect." ) );
  945. status = MQTTBadResponse;
  946. }
  947. else
  948. {
  949. /* Determine if the "Session Present" bit is set. This is the lowest bit of
  950. * the third byte in CONNACK. */
  951. if( ( pRemainingData[ 0 ] & MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK )
  952. == MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK )
  953. {
  954. LogDebug( ( "CONNACK session present bit set." ) );
  955. *pSessionPresent = true;
  956. /* MQTT 3.1.1 specifies that the fourth byte in CONNACK must be 0 if the
  957. * "Session Present" bit is set. */
  958. if( pRemainingData[ 1 ] != 0U )
  959. {
  960. LogError( ( "Session Present bit is set, but connect return code in CONNACK is %u (nonzero).",
  961. ( unsigned int ) pRemainingData[ 1 ] ) );
  962. status = MQTTBadResponse;
  963. }
  964. }
  965. else
  966. {
  967. LogDebug( ( "CONNACK session present bit not set." ) );
  968. *pSessionPresent = false;
  969. }
  970. }
  971. if( status == MQTTSuccess )
  972. {
  973. /* In MQTT 3.1.1, only values 0 through 5 are valid CONNACK response codes. */
  974. if( pRemainingData[ 1 ] > 5U )
  975. {
  976. LogError( ( "CONNACK response %u is invalid.",
  977. ( unsigned int ) pRemainingData[ 1 ] ) );
  978. status = MQTTBadResponse;
  979. }
  980. else
  981. {
  982. /* Print the appropriate message for the CONNACK response code if logs are
  983. * enabled. */
  984. logConnackResponse( pRemainingData[ 1 ] );
  985. /* A nonzero CONNACK response code means the connection was refused. */
  986. if( pRemainingData[ 1 ] > 0U )
  987. {
  988. status = MQTTServerRefused;
  989. }
  990. }
  991. }
  992. return status;
  993. }
  994. /*-----------------------------------------------------------*/
  995. static MQTTStatus_t calculateSubscriptionPacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  996. size_t subscriptionCount,
  997. size_t * pRemainingLength,
  998. size_t * pPacketSize,
  999. MQTTSubscriptionType_t subscriptionType )
  1000. {
  1001. MQTTStatus_t status = MQTTSuccess;
  1002. size_t i = 0, packetSize = 0;
  1003. assert( pSubscriptionList != NULL );
  1004. assert( subscriptionCount != 0U );
  1005. assert( pRemainingLength != NULL );
  1006. assert( pPacketSize != NULL );
  1007. /* The variable header of a subscription packet consists of a 2-byte packet
  1008. * identifier. */
  1009. packetSize += sizeof( uint16_t );
  1010. /* Sum the lengths of all subscription topic filters; add 1 byte for each
  1011. * subscription's QoS if type is MQTT_SUBSCRIBE. */
  1012. for( i = 0; i < subscriptionCount; i++ )
  1013. {
  1014. /* Add the length of the topic filter. MQTT strings are prepended
  1015. * with 2 byte string length field. Hence 2 bytes are added to size. */
  1016. packetSize += pSubscriptionList[ i ].topicFilterLength + sizeof( uint16_t );
  1017. /* Only SUBSCRIBE packets include the QoS. */
  1018. if( subscriptionType == MQTT_SUBSCRIBE )
  1019. {
  1020. packetSize += 1U;
  1021. }
  1022. /* Validate each topic filter. */
  1023. if( ( pSubscriptionList[ i ].topicFilterLength == 0U ) ||
  1024. ( pSubscriptionList[ i ].pTopicFilter == NULL ) )
  1025. {
  1026. status = MQTTBadParameter;
  1027. LogError( ( "Subscription #%lu in %sSUBSCRIBE packet cannot be empty.",
  1028. ( unsigned long ) i,
  1029. ( subscriptionType == MQTT_SUBSCRIBE ) ? "" : "UN" ) );
  1030. /* It is not necessary to break as an error status has already been set. */
  1031. }
  1032. }
  1033. /* At this point, the "Remaining length" has been calculated. Return error
  1034. * if the "Remaining length" exceeds what is allowed by MQTT 3.1.1. Otherwise,
  1035. * set the output parameter.*/
  1036. if( packetSize > MQTT_MAX_REMAINING_LENGTH )
  1037. {
  1038. LogError( ( "Subscription packet length of %lu exceeds"
  1039. "the MQTT 3.1.1 maximum packet length of %lu.",
  1040. ( unsigned long ) packetSize,
  1041. MQTT_MAX_REMAINING_LENGTH ) );
  1042. status = MQTTBadParameter;
  1043. }
  1044. if( status == MQTTSuccess )
  1045. {
  1046. *pRemainingLength = packetSize;
  1047. /* Calculate the full size of the subscription packet by adding
  1048. * number of bytes required to encode the "Remaining length" field
  1049. * plus 1 byte for the "Packet type" field. */
  1050. packetSize += 1U + remainingLengthEncodedSize( packetSize );
  1051. /*Set the pPacketSize output parameter. */
  1052. *pPacketSize = packetSize;
  1053. }
  1054. LogDebug( ( "Subscription packet remaining length=%lu and packet size=%lu.",
  1055. ( unsigned long ) *pRemainingLength,
  1056. ( unsigned long ) *pPacketSize ) );
  1057. return status;
  1058. }
  1059. /*-----------------------------------------------------------*/
  1060. static MQTTStatus_t readSubackStatus( size_t statusCount,
  1061. const uint8_t * pStatusStart )
  1062. {
  1063. MQTTStatus_t status = MQTTSuccess;
  1064. uint8_t subscriptionStatus = 0;
  1065. size_t i = 0;
  1066. assert( pStatusStart != NULL );
  1067. /* Iterate through each status byte in the SUBACK packet. */
  1068. for( i = 0; i < statusCount; i++ )
  1069. {
  1070. /* Read a single status byte in SUBACK. */
  1071. subscriptionStatus = pStatusStart[ i ];
  1072. /* MQTT 3.1.1 defines the following values as status codes. */
  1073. switch( subscriptionStatus )
  1074. {
  1075. case 0x00:
  1076. case 0x01:
  1077. case 0x02:
  1078. LogDebug( ( "Topic filter %lu accepted, max QoS %u.",
  1079. ( unsigned long ) i,
  1080. ( unsigned int ) subscriptionStatus ) );
  1081. break;
  1082. case 0x80:
  1083. LogWarn( ( "Topic filter %lu refused.", ( unsigned long ) i ) );
  1084. /* Application should remove subscription from the list */
  1085. status = MQTTServerRefused;
  1086. break;
  1087. default:
  1088. LogError( ( "Bad SUBSCRIBE status %u.",
  1089. ( unsigned int ) subscriptionStatus ) );
  1090. status = MQTTBadResponse;
  1091. break;
  1092. }
  1093. /* Stop parsing the subscription statuses if a bad response was received. */
  1094. if( status == MQTTBadResponse )
  1095. {
  1096. break;
  1097. }
  1098. }
  1099. return status;
  1100. }
  1101. /*-----------------------------------------------------------*/
  1102. static MQTTStatus_t deserializeSuback( const MQTTPacketInfo_t * pSuback,
  1103. uint16_t * pPacketIdentifier )
  1104. {
  1105. MQTTStatus_t status = MQTTSuccess;
  1106. size_t remainingLength;
  1107. const uint8_t * pVariableHeader = NULL;
  1108. assert( pSuback != NULL );
  1109. assert( pPacketIdentifier != NULL );
  1110. remainingLength = pSuback->remainingLength;
  1111. pVariableHeader = pSuback->pRemainingData;
  1112. /* A SUBACK must have a remaining length of at least 3 to accommodate the
  1113. * packet identifier and at least 1 return code. */
  1114. if( remainingLength < 3U )
  1115. {
  1116. LogError( ( "SUBACK cannot have a remaining length less than 3." ) );
  1117. status = MQTTBadResponse;
  1118. }
  1119. else
  1120. {
  1121. /* Extract the packet identifier (first 2 bytes of variable header) from SUBACK. */
  1122. *pPacketIdentifier = UINT16_DECODE( pVariableHeader );
  1123. LogDebug( ( "Packet identifier %hu.",
  1124. ( unsigned short ) *pPacketIdentifier ) );
  1125. if( *pPacketIdentifier == 0U )
  1126. {
  1127. status = MQTTBadResponse;
  1128. }
  1129. else
  1130. {
  1131. status = readSubackStatus( remainingLength - sizeof( uint16_t ),
  1132. &pVariableHeader[ sizeof( uint16_t ) ] );
  1133. }
  1134. }
  1135. return status;
  1136. }
  1137. /*-----------------------------------------------------------*/
  1138. static MQTTStatus_t validateSubscriptionSerializeParams( const MQTTSubscribeInfo_t * pSubscriptionList,
  1139. size_t subscriptionCount,
  1140. uint16_t packetId,
  1141. size_t remainingLength,
  1142. const MQTTFixedBuffer_t * pFixedBuffer )
  1143. {
  1144. MQTTStatus_t status = MQTTSuccess;
  1145. size_t packetSize = 0;
  1146. /* Validate all the parameters. */
  1147. if( ( pFixedBuffer == NULL ) || ( pSubscriptionList == NULL ) )
  1148. {
  1149. LogError( ( "Argument cannot be NULL: pFixedBuffer=%p, "
  1150. "pSubscriptionList=%p.",
  1151. ( void * ) pFixedBuffer,
  1152. ( void * ) pSubscriptionList ) );
  1153. status = MQTTBadParameter;
  1154. }
  1155. /* A buffer must be configured for serialization. */
  1156. else if( pFixedBuffer->pBuffer == NULL )
  1157. {
  1158. LogError( ( "Argument cannot be NULL: pFixedBuffer->pBuffer is NULL." ) );
  1159. status = MQTTBadParameter;
  1160. }
  1161. else if( subscriptionCount == 0U )
  1162. {
  1163. LogError( ( "Subscription count is 0." ) );
  1164. status = MQTTBadParameter;
  1165. }
  1166. else if( packetId == 0U )
  1167. {
  1168. LogError( ( "Packet Id for subscription packet is 0." ) );
  1169. status = MQTTBadParameter;
  1170. }
  1171. else
  1172. {
  1173. /* The serialized packet size = First byte
  1174. * + length of encoded size of remaining length
  1175. * + remaining length. */
  1176. packetSize = 1U + remainingLengthEncodedSize( remainingLength )
  1177. + remainingLength;
  1178. if( packetSize > pFixedBuffer->size )
  1179. {
  1180. LogError( ( "Buffer size of %lu is not sufficient to hold "
  1181. "serialized packet of size of %lu.",
  1182. ( unsigned long ) pFixedBuffer->size,
  1183. ( unsigned long ) packetSize ) );
  1184. status = MQTTNoMemory;
  1185. }
  1186. }
  1187. return status;
  1188. }
  1189. /*-----------------------------------------------------------*/
  1190. static MQTTStatus_t deserializePublish( const MQTTPacketInfo_t * pIncomingPacket,
  1191. uint16_t * pPacketId,
  1192. MQTTPublishInfo_t * pPublishInfo )
  1193. {
  1194. MQTTStatus_t status = MQTTSuccess;
  1195. const uint8_t * pVariableHeader, * pPacketIdentifierHigh = NULL;
  1196. assert( pIncomingPacket != NULL );
  1197. assert( pPacketId != NULL );
  1198. assert( pPublishInfo != NULL );
  1199. assert( pIncomingPacket->pRemainingData != NULL );
  1200. pVariableHeader = pIncomingPacket->pRemainingData;
  1201. /* The flags are the lower 4 bits of the first byte in PUBLISH. */
  1202. status = processPublishFlags( ( pIncomingPacket->type & 0x0FU ), pPublishInfo );
  1203. if( status == MQTTSuccess )
  1204. {
  1205. /* Sanity checks for "Remaining length". A QoS 0 PUBLISH must have a remaining
  1206. * length of at least 3 to accommodate topic name length (2 bytes) and topic
  1207. * name (at least 1 byte). A QoS 1 or 2 PUBLISH must have a remaining length of
  1208. * at least 5 for the packet identifier in addition to the topic name length and
  1209. * topic name. */
  1210. status = checkPublishRemainingLength( pIncomingPacket->remainingLength,
  1211. pPublishInfo->qos,
  1212. MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0 );
  1213. }
  1214. if( status == MQTTSuccess )
  1215. {
  1216. /* Extract the topic name starting from the first byte of the variable header.
  1217. * The topic name string starts at byte 3 in the variable header. */
  1218. pPublishInfo->topicNameLength = UINT16_DECODE( pVariableHeader );
  1219. /* Sanity checks for topic name length and "Remaining length". The remaining
  1220. * length must be at least as large as the variable length header. */
  1221. status = checkPublishRemainingLength( pIncomingPacket->remainingLength,
  1222. pPublishInfo->qos,
  1223. pPublishInfo->topicNameLength + sizeof( uint16_t ) );
  1224. }
  1225. if( status == MQTTSuccess )
  1226. {
  1227. /* Parse the topic. */
  1228. pPublishInfo->pTopicName = ( const char * ) ( &pVariableHeader[ sizeof( uint16_t ) ] );
  1229. LogDebug( ( "Topic name length: %hu.", ( unsigned short ) pPublishInfo->topicNameLength ) );
  1230. /* Extract the packet identifier for QoS 1 or 2 PUBLISH packets. Packet
  1231. * identifier starts immediately after the topic name. */
  1232. /* coverity[tainted_scalar] */
  1233. pPacketIdentifierHigh = ( const uint8_t * ) ( &pPublishInfo->pTopicName[ pPublishInfo->topicNameLength ] );
  1234. if( pPublishInfo->qos > MQTTQoS0 )
  1235. {
  1236. *pPacketId = UINT16_DECODE( pPacketIdentifierHigh );
  1237. LogDebug( ( "Packet identifier %hu.",
  1238. ( unsigned short ) *pPacketId ) );
  1239. /* Advance pointer two bytes to start of payload as in the QoS 0 case. */
  1240. pPacketIdentifierHigh = &pPacketIdentifierHigh[ sizeof( uint16_t ) ];
  1241. /* Packet identifier cannot be 0. */
  1242. if( *pPacketId == 0U )
  1243. {
  1244. LogError( ( "Packet identifier cannot be 0." ) );
  1245. status = MQTTBadResponse;
  1246. }
  1247. }
  1248. }
  1249. if( status == MQTTSuccess )
  1250. {
  1251. /* Calculate the length of the payload. QoS 1 or 2 PUBLISH packets contain
  1252. * a packet identifier, but QoS 0 PUBLISH packets do not. */
  1253. pPublishInfo->payloadLength = pIncomingPacket->remainingLength - pPublishInfo->topicNameLength - sizeof( uint16_t );
  1254. if( pPublishInfo->qos != MQTTQoS0 )
  1255. {
  1256. /* Two more bytes for the packet identifier. */
  1257. pPublishInfo->payloadLength -= sizeof( uint16_t );
  1258. }
  1259. /* Set payload if it exists. */
  1260. pPublishInfo->pPayload = ( pPublishInfo->payloadLength != 0U ) ? pPacketIdentifierHigh : NULL;
  1261. LogDebug( ( "Payload length %lu.",
  1262. ( unsigned long ) pPublishInfo->payloadLength ) );
  1263. }
  1264. return status;
  1265. }
  1266. /*-----------------------------------------------------------*/
  1267. static MQTTStatus_t deserializeSimpleAck( const MQTTPacketInfo_t * pAck,
  1268. uint16_t * pPacketIdentifier )
  1269. {
  1270. MQTTStatus_t status = MQTTSuccess;
  1271. assert( pAck != NULL );
  1272. assert( pPacketIdentifier != NULL );
  1273. /* Check that the "Remaining length" of the received ACK is 2. */
  1274. if( pAck->remainingLength != MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH )
  1275. {
  1276. LogError( ( "ACK does not have remaining length of %u.",
  1277. ( unsigned int ) MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH ) );
  1278. status = MQTTBadResponse;
  1279. }
  1280. else
  1281. {
  1282. /* Extract the packet identifier (third and fourth bytes) from ACK. */
  1283. *pPacketIdentifier = UINT16_DECODE( pAck->pRemainingData );
  1284. LogDebug( ( "Packet identifier %hu.",
  1285. ( unsigned short ) *pPacketIdentifier ) );
  1286. /* Packet identifier cannot be 0. */
  1287. if( *pPacketIdentifier == 0U )
  1288. {
  1289. LogError( ( "Packet identifier cannot be 0." ) );
  1290. status = MQTTBadResponse;
  1291. }
  1292. }
  1293. return status;
  1294. }
  1295. /*-----------------------------------------------------------*/
  1296. static MQTTStatus_t deserializePingresp( const MQTTPacketInfo_t * pPingresp )
  1297. {
  1298. MQTTStatus_t status = MQTTSuccess;
  1299. assert( pPingresp != NULL );
  1300. /* Check the "Remaining length" (second byte) of the received PINGRESP is 0. */
  1301. if( pPingresp->remainingLength != MQTT_PACKET_PINGRESP_REMAINING_LENGTH )
  1302. {
  1303. LogError( ( "PINGRESP does not have remaining length of %u.",
  1304. MQTT_PACKET_PINGRESP_REMAINING_LENGTH ) );
  1305. status = MQTTBadResponse;
  1306. }
  1307. return status;
  1308. }
  1309. uint8_t * MQTT_SerializeConnectFixedHeader( uint8_t * pIndex,
  1310. const MQTTConnectInfo_t * pConnectInfo,
  1311. const MQTTPublishInfo_t * pWillInfo,
  1312. size_t remainingLength )
  1313. {
  1314. uint8_t * pIndexLocal = pIndex;
  1315. uint8_t connectFlags = 0U;
  1316. /* The first byte in the CONNECT packet is the control packet type. */
  1317. *pIndexLocal = MQTT_PACKET_TYPE_CONNECT;
  1318. pIndexLocal++;
  1319. /* The remaining length of the CONNECT packet is encoded starting from the
  1320. * second byte. The remaining length does not include the length of the fixed
  1321. * header or the encoding of the remaining length. */
  1322. pIndexLocal = encodeRemainingLength( pIndexLocal, remainingLength );
  1323. /* The string "MQTT" is placed at the beginning of the CONNECT packet's variable
  1324. * header. This string is 4 bytes long. */
  1325. pIndexLocal = encodeString( pIndexLocal, "MQTT", 4 );
  1326. /* The MQTT protocol version is the second field of the variable header. */
  1327. *pIndexLocal = MQTT_VERSION_3_1_1;
  1328. pIndexLocal++;
  1329. /* Set the clean session flag if needed. */
  1330. if( pConnectInfo->cleanSession == true )
  1331. {
  1332. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_CLEAN );
  1333. }
  1334. /* Set the flags for username and password if provided. */
  1335. if( pConnectInfo->pUserName != NULL )
  1336. {
  1337. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_USERNAME );
  1338. }
  1339. if( pConnectInfo->pPassword != NULL )
  1340. {
  1341. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_PASSWORD );
  1342. }
  1343. /* Set will flag if a Last Will and Testament is provided. */
  1344. if( pWillInfo != NULL )
  1345. {
  1346. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL );
  1347. /* Flags only need to be changed for Will QoS 1 or 2. */
  1348. if( pWillInfo->qos == MQTTQoS1 )
  1349. {
  1350. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS1 );
  1351. }
  1352. else if( pWillInfo->qos == MQTTQoS2 )
  1353. {
  1354. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS2 );
  1355. }
  1356. else
  1357. {
  1358. /* Empty else MISRA 15.7 */
  1359. }
  1360. if( pWillInfo->retain == true )
  1361. {
  1362. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_RETAIN );
  1363. }
  1364. }
  1365. *pIndexLocal = connectFlags;
  1366. pIndexLocal++;
  1367. /* Write the 2 bytes of the keep alive interval into the CONNECT packet. */
  1368. pIndexLocal[ 0 ] = UINT16_HIGH_BYTE( pConnectInfo->keepAliveSeconds );
  1369. pIndexLocal[ 1 ] = UINT16_LOW_BYTE( pConnectInfo->keepAliveSeconds );
  1370. pIndexLocal = &pIndexLocal[ 2 ];
  1371. return pIndexLocal;
  1372. }
  1373. /*-----------------------------------------------------------*/
  1374. static void serializeConnectPacket( const MQTTConnectInfo_t * pConnectInfo,
  1375. const MQTTPublishInfo_t * pWillInfo,
  1376. size_t remainingLength,
  1377. const MQTTFixedBuffer_t * pFixedBuffer )
  1378. {
  1379. uint8_t * pIndex = NULL;
  1380. assert( pConnectInfo != NULL );
  1381. assert( pFixedBuffer != NULL );
  1382. assert( pFixedBuffer->pBuffer != NULL );
  1383. pIndex = pFixedBuffer->pBuffer;
  1384. /* Serialize the header. */
  1385. pIndex = MQTT_SerializeConnectFixedHeader( pIndex,
  1386. pConnectInfo,
  1387. pWillInfo,
  1388. remainingLength );
  1389. /* Write the client identifier into the CONNECT packet. */
  1390. pIndex = encodeString( pIndex,
  1391. pConnectInfo->pClientIdentifier,
  1392. pConnectInfo->clientIdentifierLength );
  1393. /* Write the will topic name and message into the CONNECT packet if provided. */
  1394. if( pWillInfo != NULL )
  1395. {
  1396. pIndex = encodeString( pIndex,
  1397. pWillInfo->pTopicName,
  1398. pWillInfo->topicNameLength );
  1399. pIndex = encodeString( pIndex,
  1400. pWillInfo->pPayload,
  1401. ( uint16_t ) pWillInfo->payloadLength );
  1402. }
  1403. /* Encode the user name if provided. */
  1404. if( pConnectInfo->pUserName != NULL )
  1405. {
  1406. pIndex = encodeString( pIndex, pConnectInfo->pUserName, pConnectInfo->userNameLength );
  1407. }
  1408. /* Encode the password if provided. */
  1409. if( pConnectInfo->pPassword != NULL )
  1410. {
  1411. pIndex = encodeString( pIndex, pConnectInfo->pPassword, pConnectInfo->passwordLength );
  1412. }
  1413. LogDebug( ( "Length of serialized CONNECT packet is %lu.",
  1414. ( ( unsigned long ) ( pIndex - pFixedBuffer->pBuffer ) ) ) );
  1415. /* Ensure that the difference between the end and beginning of the buffer
  1416. * is less than the buffer size. */
  1417. assert( ( ( size_t ) ( pIndex - pFixedBuffer->pBuffer ) ) <= pFixedBuffer->size );
  1418. }
  1419. /*-----------------------------------------------------------*/
  1420. MQTTStatus_t MQTT_GetConnectPacketSize( const MQTTConnectInfo_t * pConnectInfo,
  1421. const MQTTPublishInfo_t * pWillInfo,
  1422. size_t * pRemainingLength,
  1423. size_t * pPacketSize )
  1424. {
  1425. MQTTStatus_t status = MQTTSuccess;
  1426. size_t remainingLength;
  1427. /* The CONNECT packet will always include a 10-byte variable header. */
  1428. size_t connectPacketSize = MQTT_PACKET_CONNECT_HEADER_SIZE;
  1429. /* Validate arguments. */
  1430. if( ( pConnectInfo == NULL ) || ( pRemainingLength == NULL ) ||
  1431. ( pPacketSize == NULL ) )
  1432. {
  1433. LogError( ( "Argument cannot be NULL: pConnectInfo=%p, "
  1434. "pRemainingLength=%p, pPacketSize=%p.",
  1435. ( void * ) pConnectInfo,
  1436. ( void * ) pRemainingLength,
  1437. ( void * ) pPacketSize ) );
  1438. status = MQTTBadParameter;
  1439. }
  1440. else if( ( pConnectInfo->clientIdentifierLength == 0U ) || ( pConnectInfo->pClientIdentifier == NULL ) )
  1441. {
  1442. LogError( ( "Mqtt_GetConnectPacketSize() client identifier must be set." ) );
  1443. status = MQTTBadParameter;
  1444. }
  1445. else if( ( pWillInfo != NULL ) && ( pWillInfo->payloadLength > ( size_t ) UINT16_MAX ) )
  1446. {
  1447. /* The MQTTPublishInfo_t is reused for the will message. The payload
  1448. * length for any other message could be larger than 65,535, but
  1449. * the will message length is required to be represented in 2 bytes.
  1450. * By bounding the payloadLength of the will message, the CONNECT
  1451. * packet will never be larger than 327699 bytes. */
  1452. LogError( ( "The Will Message length must not exceed %d. "
  1453. "pWillInfo->payloadLength=%lu.",
  1454. UINT16_MAX,
  1455. ( unsigned long ) pWillInfo->payloadLength ) );
  1456. status = MQTTBadParameter;
  1457. }
  1458. else
  1459. {
  1460. /* Add the length of the client identifier. */
  1461. connectPacketSize += pConnectInfo->clientIdentifierLength + sizeof( uint16_t );
  1462. /* Add the lengths of the will message and topic name if provided. */
  1463. if( pWillInfo != NULL )
  1464. {
  1465. connectPacketSize += pWillInfo->topicNameLength + sizeof( uint16_t ) +
  1466. pWillInfo->payloadLength + sizeof( uint16_t );
  1467. }
  1468. /* Add the lengths of the user name and password if provided. */
  1469. if( pConnectInfo->pUserName != NULL )
  1470. {
  1471. connectPacketSize += pConnectInfo->userNameLength + sizeof( uint16_t );
  1472. }
  1473. if( pConnectInfo->pPassword != NULL )
  1474. {
  1475. connectPacketSize += pConnectInfo->passwordLength + sizeof( uint16_t );
  1476. }
  1477. /* At this point, the "Remaining Length" field of the MQTT CONNECT packet has
  1478. * been calculated. */
  1479. remainingLength = connectPacketSize;
  1480. /* Calculate the full size of the MQTT CONNECT packet by adding the size of
  1481. * the "Remaining Length" field plus 1 byte for the "Packet Type" field. */
  1482. connectPacketSize += 1U + remainingLengthEncodedSize( connectPacketSize );
  1483. /* The connectPacketSize calculated from this function's parameters is
  1484. * guaranteed to be less than the maximum MQTT CONNECT packet size, which
  1485. * is 327700. If the maximum client identifier length, the maximum will
  1486. * message topic length, the maximum will topic payload length, the
  1487. * maximum username length, and the maximum password length are all present
  1488. * in the MQTT CONNECT packet, the total size will be calculated to be
  1489. * 327699:
  1490. * (variable length header)10 +
  1491. * (maximum client identifier length) 65535 + (encoded length) 2 +
  1492. * (maximum will message topic name length) 65535 + (encoded length)2 +
  1493. * (maximum will message payload length) 65535 + 2 +
  1494. * (maximum username length) 65535 + (encoded length) 2 +
  1495. * (maximum password length) 65535 + (encoded length) 2 +
  1496. * (packet type field length) 1 +
  1497. * (CONNECT packet encoded length) 3 = 327699 */
  1498. *pRemainingLength = remainingLength;
  1499. *pPacketSize = connectPacketSize;
  1500. LogDebug( ( "CONNECT packet remaining length=%lu and packet size=%lu.",
  1501. ( unsigned long ) *pRemainingLength,
  1502. ( unsigned long ) *pPacketSize ) );
  1503. }
  1504. return status;
  1505. }
  1506. /*-----------------------------------------------------------*/
  1507. MQTTStatus_t MQTT_SerializeConnect( const MQTTConnectInfo_t * pConnectInfo,
  1508. const MQTTPublishInfo_t * pWillInfo,
  1509. size_t remainingLength,
  1510. const MQTTFixedBuffer_t * pFixedBuffer )
  1511. {
  1512. MQTTStatus_t status = MQTTSuccess;
  1513. size_t connectPacketSize = 0;
  1514. /* Validate arguments. */
  1515. if( ( pConnectInfo == NULL ) || ( pFixedBuffer == NULL ) )
  1516. {
  1517. LogError( ( "Argument cannot be NULL: pConnectInfo=%p, "
  1518. "pFixedBuffer=%p.",
  1519. ( void * ) pConnectInfo,
  1520. ( void * ) pFixedBuffer ) );
  1521. status = MQTTBadParameter;
  1522. }
  1523. /* A buffer must be configured for serialization. */
  1524. else if( pFixedBuffer->pBuffer == NULL )
  1525. {
  1526. LogError( ( "Argument cannot be NULL: pFixedBuffer->pBuffer is NULL." ) );
  1527. status = MQTTBadParameter;
  1528. }
  1529. else if( ( pWillInfo != NULL ) && ( pWillInfo->pTopicName == NULL ) )
  1530. {
  1531. LogError( ( "pWillInfo->pTopicName cannot be NULL if Will is present." ) );
  1532. status = MQTTBadParameter;
  1533. }
  1534. else
  1535. {
  1536. /* Calculate CONNECT packet size. Overflow in in this addition is not checked
  1537. * because it is part of the API contract to call Mqtt_GetConnectPacketSize()
  1538. * before this function. */
  1539. connectPacketSize = remainingLength + remainingLengthEncodedSize( remainingLength ) + 1U;
  1540. /* Check that the full packet size fits within the given buffer. */
  1541. if( connectPacketSize > pFixedBuffer->size )
  1542. {
  1543. LogError( ( "Buffer size of %lu is not sufficient to hold "
  1544. "serialized CONNECT packet of size of %lu.",
  1545. ( unsigned long ) pFixedBuffer->size,
  1546. ( unsigned long ) connectPacketSize ) );
  1547. status = MQTTNoMemory;
  1548. }
  1549. else
  1550. {
  1551. serializeConnectPacket( pConnectInfo,
  1552. pWillInfo,
  1553. remainingLength,
  1554. pFixedBuffer );
  1555. }
  1556. }
  1557. return status;
  1558. }
  1559. /*-----------------------------------------------------------*/
  1560. MQTTStatus_t MQTT_GetSubscribePacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  1561. size_t subscriptionCount,
  1562. size_t * pRemainingLength,
  1563. size_t * pPacketSize )
  1564. {
  1565. MQTTStatus_t status = MQTTSuccess;
  1566. /* Validate parameters. */
  1567. if( ( pSubscriptionList == NULL ) || ( pRemainingLength == NULL ) ||
  1568. ( pPacketSize == NULL ) )
  1569. {
  1570. LogError( ( "Argument cannot be NULL: pSubscriptionList=%p, "
  1571. "pRemainingLength=%p, pPacketSize=%p.",
  1572. ( void * ) pSubscriptionList,
  1573. ( void * ) pRemainingLength,
  1574. ( void * ) pPacketSize ) );
  1575. status = MQTTBadParameter;
  1576. }
  1577. else if( subscriptionCount == 0U )
  1578. {
  1579. LogError( ( "subscriptionCount is 0." ) );
  1580. status = MQTTBadParameter;
  1581. }
  1582. else
  1583. {
  1584. /* Calculate the MQTT SUBSCRIBE packet size. */
  1585. status = calculateSubscriptionPacketSize( pSubscriptionList,
  1586. subscriptionCount,
  1587. pRemainingLength,
  1588. pPacketSize,
  1589. MQTT_SUBSCRIBE );
  1590. }
  1591. return status;
  1592. }
  1593. /*-----------------------------------------------------------*/
  1594. uint8_t * MQTT_SerializeSubscribeHeader( size_t remainingLength,
  1595. uint8_t * pIndex,
  1596. uint16_t packetId )
  1597. {
  1598. uint8_t * pIterator = pIndex;
  1599. /* The first byte in SUBSCRIBE is the packet type. */
  1600. *pIterator = MQTT_PACKET_TYPE_SUBSCRIBE;
  1601. pIterator++;
  1602. /* Encode the "Remaining length" starting from the second byte. */
  1603. pIterator = encodeRemainingLength( pIterator, remainingLength );
  1604. /* Place the packet identifier into the SUBSCRIBE packet. */
  1605. pIterator[ 0 ] = UINT16_HIGH_BYTE( packetId );
  1606. pIterator[ 1 ] = UINT16_LOW_BYTE( packetId );
  1607. /* Advance the pointer. */
  1608. pIterator = &pIterator[ 2 ];
  1609. return pIterator;
  1610. }
  1611. /*-----------------------------------------------------------*/
  1612. uint8_t * MQTT_SerializeUnsubscribeHeader( size_t remainingLength,
  1613. uint8_t * pIndex,
  1614. uint16_t packetId )
  1615. {
  1616. uint8_t * pIterator = pIndex;
  1617. /* The first byte in UNSUBSCRIBE is the packet type. */
  1618. *pIterator = MQTT_PACKET_TYPE_UNSUBSCRIBE;
  1619. pIterator++;
  1620. /* Encode the "Remaining length" starting from the second byte. */
  1621. pIterator = encodeRemainingLength( pIterator, remainingLength );
  1622. /* Place the packet identifier into the SUBSCRIBE packet. */
  1623. pIterator[ 0 ] = UINT16_HIGH_BYTE( packetId );
  1624. pIterator[ 1 ] = UINT16_LOW_BYTE( packetId );
  1625. /* Increment the pointer. */
  1626. pIterator = &pIterator[ 2 ];
  1627. return pIterator;
  1628. }
  1629. MQTTStatus_t MQTT_SerializeSubscribe( const MQTTSubscribeInfo_t * pSubscriptionList,
  1630. size_t subscriptionCount,
  1631. uint16_t packetId,
  1632. size_t remainingLength,
  1633. const MQTTFixedBuffer_t * pFixedBuffer )
  1634. {
  1635. size_t i = 0;
  1636. uint8_t * pIndex = NULL;
  1637. /* Validate all the parameters. */
  1638. MQTTStatus_t status =
  1639. validateSubscriptionSerializeParams( pSubscriptionList,
  1640. subscriptionCount,
  1641. packetId,
  1642. remainingLength,
  1643. pFixedBuffer );
  1644. if( status == MQTTSuccess )
  1645. {
  1646. pIndex = pFixedBuffer->pBuffer;
  1647. pIndex = MQTT_SerializeSubscribeHeader( remainingLength,
  1648. pIndex,
  1649. packetId );
  1650. /* Serialize each subscription topic filter and QoS. */
  1651. for( i = 0; i < subscriptionCount; i++ )
  1652. {
  1653. pIndex = encodeString( pIndex,
  1654. pSubscriptionList[ i ].pTopicFilter,
  1655. pSubscriptionList[ i ].topicFilterLength );
  1656. /* Place the QoS in the SUBSCRIBE packet. */
  1657. *pIndex = ( uint8_t ) ( pSubscriptionList[ i ].qos );
  1658. pIndex++;
  1659. }
  1660. LogDebug( ( "Length of serialized SUBSCRIBE packet is %lu.",
  1661. ( ( unsigned long ) ( pIndex - pFixedBuffer->pBuffer ) ) ) );
  1662. }
  1663. return status;
  1664. }
  1665. /*-----------------------------------------------------------*/
  1666. MQTTStatus_t MQTT_GetUnsubscribePacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  1667. size_t subscriptionCount,
  1668. size_t * pRemainingLength,
  1669. size_t * pPacketSize )
  1670. {
  1671. MQTTStatus_t status = MQTTSuccess;
  1672. /* Validate parameters. */
  1673. if( ( pSubscriptionList == NULL ) || ( pRemainingLength == NULL ) ||
  1674. ( pPacketSize == NULL ) )
  1675. {
  1676. LogError( ( "Argument cannot be NULL: pSubscriptionList=%p, "
  1677. "pRemainingLength=%p, pPacketSize=%p.",
  1678. ( void * ) pSubscriptionList,
  1679. ( void * ) pRemainingLength,
  1680. ( void * ) pPacketSize ) );
  1681. status = MQTTBadParameter;
  1682. }
  1683. else if( subscriptionCount == 0U )
  1684. {
  1685. LogError( ( "Subscription count is 0." ) );
  1686. status = MQTTBadParameter;
  1687. }
  1688. else
  1689. {
  1690. /* Calculate the MQTT UNSUBSCRIBE packet size. */
  1691. status = calculateSubscriptionPacketSize( pSubscriptionList,
  1692. subscriptionCount,
  1693. pRemainingLength,
  1694. pPacketSize,
  1695. MQTT_UNSUBSCRIBE );
  1696. }
  1697. return status;
  1698. }
  1699. /*-----------------------------------------------------------*/
  1700. MQTTStatus_t MQTT_SerializeUnsubscribe( const MQTTSubscribeInfo_t * pSubscriptionList,
  1701. size_t subscriptionCount,
  1702. uint16_t packetId,
  1703. size_t remainingLength,
  1704. const MQTTFixedBuffer_t * pFixedBuffer )
  1705. {
  1706. MQTTStatus_t status = MQTTSuccess;
  1707. size_t i = 0;
  1708. uint8_t * pIndex = NULL;
  1709. /* Validate all the parameters. */
  1710. status = validateSubscriptionSerializeParams( pSubscriptionList,
  1711. subscriptionCount,
  1712. packetId,
  1713. remainingLength,
  1714. pFixedBuffer );
  1715. if( status == MQTTSuccess )
  1716. {
  1717. /* Get the start of the buffer to the iterator variable. */
  1718. pIndex = pFixedBuffer->pBuffer;
  1719. pIndex = MQTT_SerializeUnsubscribeHeader( remainingLength, pIndex, packetId );
  1720. /* Serialize each subscription topic filter. */
  1721. for( i = 0; i < subscriptionCount; i++ )
  1722. {
  1723. pIndex = encodeString( pIndex,
  1724. pSubscriptionList[ i ].pTopicFilter,
  1725. pSubscriptionList[ i ].topicFilterLength );
  1726. }
  1727. LogDebug( ( "Length of serialized UNSUBSCRIBE packet is %lu.",
  1728. ( ( unsigned long ) ( pIndex - pFixedBuffer->pBuffer ) ) ) );
  1729. }
  1730. return status;
  1731. }
  1732. /*-----------------------------------------------------------*/
  1733. MQTTStatus_t MQTT_GetPublishPacketSize( const MQTTPublishInfo_t * pPublishInfo,
  1734. size_t * pRemainingLength,
  1735. size_t * pPacketSize )
  1736. {
  1737. MQTTStatus_t status = MQTTSuccess;
  1738. if( ( pPublishInfo == NULL ) || ( pRemainingLength == NULL ) || ( pPacketSize == NULL ) )
  1739. {
  1740. LogError( ( "Argument cannot be NULL: pPublishInfo=%p, "
  1741. "pRemainingLength=%p, pPacketSize=%p.",
  1742. ( void * ) pPublishInfo,
  1743. ( void * ) pRemainingLength,
  1744. ( void * ) pPacketSize ) );
  1745. status = MQTTBadParameter;
  1746. }
  1747. else if( ( pPublishInfo->pTopicName == NULL ) || ( pPublishInfo->topicNameLength == 0U ) )
  1748. {
  1749. LogError( ( "Invalid topic name for PUBLISH: pTopicName=%p, "
  1750. "topicNameLength=%hu.",
  1751. ( void * ) pPublishInfo->pTopicName,
  1752. ( unsigned short ) pPublishInfo->topicNameLength ) );
  1753. status = MQTTBadParameter;
  1754. }
  1755. else
  1756. {
  1757. /* Calculate the "Remaining length" field and total packet size. If it exceeds
  1758. * what is allowed in the MQTT standard, return an error. */
  1759. if( calculatePublishPacketSize( pPublishInfo, pRemainingLength, pPacketSize ) == false )
  1760. {
  1761. LogError( ( "PUBLISH packet remaining length exceeds %lu, which is the "
  1762. "maximum size allowed by MQTT 3.1.1.",
  1763. MQTT_MAX_REMAINING_LENGTH ) );
  1764. status = MQTTBadParameter;
  1765. }
  1766. }
  1767. return status;
  1768. }
  1769. /*-----------------------------------------------------------*/
  1770. MQTTStatus_t MQTT_SerializePublish( const MQTTPublishInfo_t * pPublishInfo,
  1771. uint16_t packetId,
  1772. size_t remainingLength,
  1773. const MQTTFixedBuffer_t * pFixedBuffer )
  1774. {
  1775. MQTTStatus_t status = MQTTSuccess;
  1776. size_t packetSize = 0;
  1777. if( ( pFixedBuffer == NULL ) || ( pPublishInfo == NULL ) )
  1778. {
  1779. LogError( ( "Argument cannot be NULL: pFixedBuffer=%p, "
  1780. "pPublishInfo=%p.",
  1781. ( void * ) pFixedBuffer,
  1782. ( void * ) pPublishInfo ) );
  1783. status = MQTTBadParameter;
  1784. }
  1785. /* A buffer must be configured for serialization. */
  1786. else if( pFixedBuffer->pBuffer == NULL )
  1787. {
  1788. LogError( ( "Argument cannot be NULL: pFixedBuffer->pBuffer is NULL." ) );
  1789. status = MQTTBadParameter;
  1790. }
  1791. /* For serializing a publish, if there exists a payload, then the buffer
  1792. * cannot be NULL. */
  1793. else if( ( pPublishInfo->payloadLength > 0U ) && ( pPublishInfo->pPayload == NULL ) )
  1794. {
  1795. LogError( ( "A nonzero payload length requires a non-NULL payload: "
  1796. "payloadLength=%lu, pPayload=%p.",
  1797. ( unsigned long ) pPublishInfo->payloadLength,
  1798. pPublishInfo->pPayload ) );
  1799. status = MQTTBadParameter;
  1800. }
  1801. else if( ( pPublishInfo->pTopicName == NULL ) || ( pPublishInfo->topicNameLength == 0U ) )
  1802. {
  1803. LogError( ( "Invalid topic name for PUBLISH: pTopicName=%p, "
  1804. "topicNameLength=%hu.",
  1805. ( void * ) pPublishInfo->pTopicName,
  1806. ( unsigned short ) pPublishInfo->topicNameLength ) );
  1807. status = MQTTBadParameter;
  1808. }
  1809. else if( ( pPublishInfo->qos != MQTTQoS0 ) && ( packetId == 0U ) )
  1810. {
  1811. LogError( ( "Packet ID is 0 for PUBLISH with QoS=%u.",
  1812. ( unsigned int ) pPublishInfo->qos ) );
  1813. status = MQTTBadParameter;
  1814. }
  1815. else if( ( pPublishInfo->dup == true ) && ( pPublishInfo->qos == MQTTQoS0 ) )
  1816. {
  1817. LogError( ( "Duplicate flag is set for PUBLISH with Qos 0." ) );
  1818. status = MQTTBadParameter;
  1819. }
  1820. else
  1821. {
  1822. /* Length of serialized packet = First byte
  1823. * + Length of encoded remaining length
  1824. * + Remaining length. */
  1825. packetSize = 1U + remainingLengthEncodedSize( remainingLength )
  1826. + remainingLength;
  1827. }
  1828. if( ( status == MQTTSuccess ) && ( packetSize > pFixedBuffer->size ) )
  1829. {
  1830. LogError( ( "Buffer size of %lu is not sufficient to hold "
  1831. "serialized PUBLISH packet of size of %lu.",
  1832. ( unsigned long ) pFixedBuffer->size,
  1833. ( unsigned long ) packetSize ) );
  1834. status = MQTTNoMemory;
  1835. }
  1836. if( status == MQTTSuccess )
  1837. {
  1838. /* Serialize publish with header and payload. */
  1839. serializePublishCommon( pPublishInfo,
  1840. remainingLength,
  1841. packetId,
  1842. pFixedBuffer,
  1843. true );
  1844. }
  1845. return status;
  1846. }
  1847. /*-----------------------------------------------------------*/
  1848. MQTTStatus_t MQTT_SerializePublishHeader( const MQTTPublishInfo_t * pPublishInfo,
  1849. uint16_t packetId,
  1850. size_t remainingLength,
  1851. const MQTTFixedBuffer_t * pFixedBuffer,
  1852. size_t * pHeaderSize )
  1853. {
  1854. MQTTStatus_t status = MQTTSuccess;
  1855. size_t packetSize = 0;
  1856. if( ( pFixedBuffer == NULL ) || ( pPublishInfo == NULL ) ||
  1857. ( pHeaderSize == NULL ) )
  1858. {
  1859. LogError( ( "Argument cannot be NULL: pFixedBuffer=%p, "
  1860. "pPublishInfo=%p, pHeaderSize=%p.",
  1861. ( void * ) pFixedBuffer,
  1862. ( void * ) pPublishInfo,
  1863. ( void * ) pHeaderSize ) );
  1864. status = MQTTBadParameter;
  1865. }
  1866. /* A buffer must be configured for serialization. */
  1867. else if( pFixedBuffer->pBuffer == NULL )
  1868. {
  1869. LogError( ( "Argument cannot be NULL: pFixedBuffer->pBuffer is NULL." ) );
  1870. status = MQTTBadParameter;
  1871. }
  1872. else if( ( pPublishInfo->pTopicName == NULL ) || ( pPublishInfo->topicNameLength == 0U ) )
  1873. {
  1874. LogError( ( "Invalid topic name for publish: pTopicName=%p, "
  1875. "topicNameLength=%hu.",
  1876. ( void * ) pPublishInfo->pTopicName,
  1877. ( unsigned short ) pPublishInfo->topicNameLength ) );
  1878. status = MQTTBadParameter;
  1879. }
  1880. else if( ( pPublishInfo->qos != MQTTQoS0 ) && ( packetId == 0U ) )
  1881. {
  1882. LogError( ( "Packet Id is 0 for publish with QoS=%hu.",
  1883. ( unsigned short ) pPublishInfo->qos ) );
  1884. status = MQTTBadParameter;
  1885. }
  1886. else if( ( pPublishInfo->dup == true ) && ( pPublishInfo->qos == MQTTQoS0 ) )
  1887. {
  1888. LogError( ( "Duplicate flag is set for PUBLISH with Qos 0." ) );
  1889. status = MQTTBadParameter;
  1890. }
  1891. else
  1892. {
  1893. /* Length of serialized packet = First byte
  1894. * + Length of encoded remaining length
  1895. * + Remaining length
  1896. * - Payload Length.
  1897. */
  1898. packetSize = 1U + remainingLengthEncodedSize( remainingLength )
  1899. + remainingLength
  1900. - pPublishInfo->payloadLength;
  1901. }
  1902. if( ( status == MQTTSuccess ) && ( packetSize > pFixedBuffer->size ) )
  1903. {
  1904. LogError( ( "Buffer size of %lu is not sufficient to hold "
  1905. "serialized PUBLISH header packet of size of %lu.",
  1906. ( unsigned long ) pFixedBuffer->size,
  1907. ( unsigned long ) ( packetSize - pPublishInfo->payloadLength ) ) );
  1908. status = MQTTNoMemory;
  1909. }
  1910. if( status == MQTTSuccess )
  1911. {
  1912. /* Serialize publish without copying the payload. */
  1913. serializePublishCommon( pPublishInfo,
  1914. remainingLength,
  1915. packetId,
  1916. pFixedBuffer,
  1917. false );
  1918. /* Header size is the same as calculated packet size. */
  1919. *pHeaderSize = packetSize;
  1920. }
  1921. return status;
  1922. }
  1923. /*-----------------------------------------------------------*/
  1924. MQTTStatus_t MQTT_SerializeAck( const MQTTFixedBuffer_t * pFixedBuffer,
  1925. uint8_t packetType,
  1926. uint16_t packetId )
  1927. {
  1928. MQTTStatus_t status = MQTTSuccess;
  1929. if( pFixedBuffer == NULL )
  1930. {
  1931. LogError( ( "Provided buffer is NULL." ) );
  1932. status = MQTTBadParameter;
  1933. }
  1934. else if( pFixedBuffer->pBuffer == NULL )
  1935. {
  1936. LogError( ( "pFixedBuffer->pBuffer cannot be NULL." ) );
  1937. status = MQTTBadParameter;
  1938. }
  1939. /* The buffer must be able to fit 4 bytes for the packet. */
  1940. else if( pFixedBuffer->size < MQTT_PUBLISH_ACK_PACKET_SIZE )
  1941. {
  1942. LogError( ( "Insufficient memory for packet." ) );
  1943. status = MQTTNoMemory;
  1944. }
  1945. else if( packetId == 0U )
  1946. {
  1947. LogError( ( "Packet ID cannot be 0." ) );
  1948. status = MQTTBadParameter;
  1949. }
  1950. else
  1951. {
  1952. switch( packetType )
  1953. {
  1954. /* Only publish acks are serialized by the client. */
  1955. case MQTT_PACKET_TYPE_PUBACK:
  1956. case MQTT_PACKET_TYPE_PUBREC:
  1957. case MQTT_PACKET_TYPE_PUBREL:
  1958. case MQTT_PACKET_TYPE_PUBCOMP:
  1959. pFixedBuffer->pBuffer[ 0 ] = packetType;
  1960. pFixedBuffer->pBuffer[ 1 ] = MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH;
  1961. pFixedBuffer->pBuffer[ 2 ] = UINT16_HIGH_BYTE( packetId );
  1962. pFixedBuffer->pBuffer[ 3 ] = UINT16_LOW_BYTE( packetId );
  1963. break;
  1964. default:
  1965. LogError( ( "Packet type is not a publish ACK: Packet type=%02x",
  1966. ( unsigned int ) packetType ) );
  1967. status = MQTTBadParameter;
  1968. break;
  1969. }
  1970. }
  1971. return status;
  1972. }
  1973. /*-----------------------------------------------------------*/
  1974. MQTTStatus_t MQTT_GetDisconnectPacketSize( size_t * pPacketSize )
  1975. {
  1976. MQTTStatus_t status = MQTTSuccess;
  1977. if( pPacketSize == NULL )
  1978. {
  1979. LogError( ( "pPacketSize is NULL." ) );
  1980. status = MQTTBadParameter;
  1981. }
  1982. else
  1983. {
  1984. /* MQTT DISCONNECT packets always have the same size. */
  1985. *pPacketSize = MQTT_DISCONNECT_PACKET_SIZE;
  1986. }
  1987. return status;
  1988. }
  1989. /*-----------------------------------------------------------*/
  1990. MQTTStatus_t MQTT_SerializeDisconnect( const MQTTFixedBuffer_t * pFixedBuffer )
  1991. {
  1992. MQTTStatus_t status = MQTTSuccess;
  1993. /* Validate arguments. */
  1994. if( pFixedBuffer == NULL )
  1995. {
  1996. LogError( ( "pFixedBuffer cannot be NULL." ) );
  1997. status = MQTTBadParameter;
  1998. }
  1999. else if( pFixedBuffer->pBuffer == NULL )
  2000. {
  2001. LogError( ( "pFixedBuffer->pBuffer cannot be NULL." ) );
  2002. status = MQTTBadParameter;
  2003. }
  2004. else
  2005. {
  2006. /* Empty else MISRA 15.7 */
  2007. }
  2008. if( status == MQTTSuccess )
  2009. {
  2010. if( pFixedBuffer->size < MQTT_DISCONNECT_PACKET_SIZE )
  2011. {
  2012. LogError( ( "Buffer size of %lu is not sufficient to hold "
  2013. "serialized DISCONNECT packet of size of %lu.",
  2014. ( unsigned long ) pFixedBuffer->size,
  2015. MQTT_DISCONNECT_PACKET_SIZE ) );
  2016. status = MQTTNoMemory;
  2017. }
  2018. }
  2019. if( status == MQTTSuccess )
  2020. {
  2021. pFixedBuffer->pBuffer[ 0 ] = MQTT_PACKET_TYPE_DISCONNECT;
  2022. pFixedBuffer->pBuffer[ 1 ] = MQTT_DISCONNECT_REMAINING_LENGTH;
  2023. }
  2024. return status;
  2025. }
  2026. /*-----------------------------------------------------------*/
  2027. MQTTStatus_t MQTT_GetPingreqPacketSize( size_t * pPacketSize )
  2028. {
  2029. MQTTStatus_t status = MQTTSuccess;
  2030. if( pPacketSize == NULL )
  2031. {
  2032. LogError( ( "pPacketSize is NULL." ) );
  2033. status = MQTTBadParameter;
  2034. }
  2035. else
  2036. {
  2037. /* MQTT PINGREQ packets always have the same size. */
  2038. *pPacketSize = MQTT_PACKET_PINGREQ_SIZE;
  2039. }
  2040. return status;
  2041. }
  2042. /*-----------------------------------------------------------*/
  2043. MQTTStatus_t MQTT_SerializePingreq( const MQTTFixedBuffer_t * pFixedBuffer )
  2044. {
  2045. MQTTStatus_t status = MQTTSuccess;
  2046. if( pFixedBuffer == NULL )
  2047. {
  2048. LogError( ( "pFixedBuffer is NULL." ) );
  2049. status = MQTTBadParameter;
  2050. }
  2051. else if( pFixedBuffer->pBuffer == NULL )
  2052. {
  2053. LogError( ( "pFixedBuffer->pBuffer cannot be NULL." ) );
  2054. status = MQTTBadParameter;
  2055. }
  2056. else
  2057. {
  2058. /* Empty else MISRA 15.7 */
  2059. }
  2060. if( status == MQTTSuccess )
  2061. {
  2062. if( pFixedBuffer->size < MQTT_PACKET_PINGREQ_SIZE )
  2063. {
  2064. LogError( ( "Buffer size of %lu is not sufficient to hold "
  2065. "serialized PINGREQ packet of size of %lu.",
  2066. ( unsigned long ) pFixedBuffer->size,
  2067. MQTT_PACKET_PINGREQ_SIZE ) );
  2068. status = MQTTNoMemory;
  2069. }
  2070. }
  2071. if( status == MQTTSuccess )
  2072. {
  2073. /* Ping request packets are always the same. */
  2074. pFixedBuffer->pBuffer[ 0 ] = MQTT_PACKET_TYPE_PINGREQ;
  2075. pFixedBuffer->pBuffer[ 1 ] = 0x00;
  2076. }
  2077. return status;
  2078. }
  2079. /*-----------------------------------------------------------*/
  2080. MQTTStatus_t MQTT_DeserializePublish( const MQTTPacketInfo_t * pIncomingPacket,
  2081. uint16_t * pPacketId,
  2082. MQTTPublishInfo_t * pPublishInfo )
  2083. {
  2084. MQTTStatus_t status = MQTTSuccess;
  2085. if( ( pIncomingPacket == NULL ) || ( pPacketId == NULL ) || ( pPublishInfo == NULL ) )
  2086. {
  2087. LogError( ( "Argument cannot be NULL: pIncomingPacket=%p, "
  2088. "pPacketId=%p, pPublishInfo=%p",
  2089. ( void * ) pIncomingPacket,
  2090. ( void * ) pPacketId,
  2091. ( void * ) pPublishInfo ) );
  2092. status = MQTTBadParameter;
  2093. }
  2094. else if( ( pIncomingPacket->type & 0xF0U ) != MQTT_PACKET_TYPE_PUBLISH )
  2095. {
  2096. LogError( ( "Packet is not publish. Packet type: %02x.",
  2097. ( unsigned int ) pIncomingPacket->type ) );
  2098. status = MQTTBadParameter;
  2099. }
  2100. else if( pIncomingPacket->pRemainingData == NULL )
  2101. {
  2102. LogError( ( "Argument cannot be NULL: "
  2103. "pIncomingPacket->pRemainingData is NULL." ) );
  2104. status = MQTTBadParameter;
  2105. }
  2106. else
  2107. {
  2108. status = deserializePublish( pIncomingPacket, pPacketId, pPublishInfo );
  2109. }
  2110. return status;
  2111. }
  2112. /*-----------------------------------------------------------*/
  2113. MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
  2114. uint16_t * pPacketId,
  2115. bool * pSessionPresent )
  2116. {
  2117. MQTTStatus_t status = MQTTSuccess;
  2118. if( pIncomingPacket == NULL )
  2119. {
  2120. LogError( ( "pIncomingPacket cannot be NULL." ) );
  2121. status = MQTTBadParameter;
  2122. }
  2123. /* Pointer for packet identifier cannot be NULL for packets other than
  2124. * CONNACK and PINGRESP. */
  2125. else if( ( pPacketId == NULL ) &&
  2126. ( ( pIncomingPacket->type != MQTT_PACKET_TYPE_CONNACK ) &&
  2127. ( pIncomingPacket->type != MQTT_PACKET_TYPE_PINGRESP ) ) )
  2128. {
  2129. LogError( ( "pPacketId cannot be NULL for packet type %02x.",
  2130. ( unsigned int ) pIncomingPacket->type ) );
  2131. status = MQTTBadParameter;
  2132. }
  2133. /* Pointer for session present cannot be NULL for CONNACK. */
  2134. else if( ( pSessionPresent == NULL ) &&
  2135. ( pIncomingPacket->type == MQTT_PACKET_TYPE_CONNACK ) )
  2136. {
  2137. LogError( ( "pSessionPresent cannot be NULL for CONNACK packet." ) );
  2138. status = MQTTBadParameter;
  2139. }
  2140. /* Pointer for remaining data cannot be NULL for packets other
  2141. * than PINGRESP. */
  2142. else if( ( pIncomingPacket->pRemainingData == NULL ) &&
  2143. ( pIncomingPacket->type != MQTT_PACKET_TYPE_PINGRESP ) )
  2144. {
  2145. LogError( ( "Remaining data of incoming packet is NULL." ) );
  2146. status = MQTTBadParameter;
  2147. }
  2148. else
  2149. {
  2150. /* Make sure response packet is a valid ack. */
  2151. switch( pIncomingPacket->type )
  2152. {
  2153. case MQTT_PACKET_TYPE_CONNACK:
  2154. status = deserializeConnack( pIncomingPacket, pSessionPresent );
  2155. break;
  2156. case MQTT_PACKET_TYPE_SUBACK:
  2157. status = deserializeSuback( pIncomingPacket, pPacketId );
  2158. break;
  2159. case MQTT_PACKET_TYPE_PINGRESP:
  2160. status = deserializePingresp( pIncomingPacket );
  2161. break;
  2162. case MQTT_PACKET_TYPE_UNSUBACK:
  2163. case MQTT_PACKET_TYPE_PUBACK:
  2164. case MQTT_PACKET_TYPE_PUBREC:
  2165. case MQTT_PACKET_TYPE_PUBREL:
  2166. case MQTT_PACKET_TYPE_PUBCOMP:
  2167. status = deserializeSimpleAck( pIncomingPacket, pPacketId );
  2168. break;
  2169. /* Any other packet type is invalid. */
  2170. default:
  2171. LogError( ( "IotMqtt_DeserializeResponse() called with unknown packet type:(%02x).",
  2172. ( unsigned int ) pIncomingPacket->type ) );
  2173. status = MQTTBadResponse;
  2174. break;
  2175. }
  2176. }
  2177. return status;
  2178. }
  2179. /*-----------------------------------------------------------*/
  2180. MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength( TransportRecv_t readFunc,
  2181. NetworkContext_t * pNetworkContext,
  2182. MQTTPacketInfo_t * pIncomingPacket )
  2183. {
  2184. MQTTStatus_t status = MQTTSuccess;
  2185. int32_t bytesReceived = 0;
  2186. if( pIncomingPacket == NULL )
  2187. {
  2188. LogError( ( "Invalid parameter: pIncomingPacket is NULL." ) );
  2189. status = MQTTBadParameter;
  2190. }
  2191. else
  2192. {
  2193. /* Read a single byte. */
  2194. bytesReceived = readFunc( pNetworkContext,
  2195. &( pIncomingPacket->type ),
  2196. 1U );
  2197. }
  2198. if( bytesReceived == 1 )
  2199. {
  2200. /* Check validity. */
  2201. if( incomingPacketValid( pIncomingPacket->type ) == true )
  2202. {
  2203. pIncomingPacket->remainingLength = getRemainingLength( readFunc,
  2204. pNetworkContext );
  2205. if( pIncomingPacket->remainingLength == MQTT_REMAINING_LENGTH_INVALID )
  2206. {
  2207. LogError( ( "Incoming packet remaining length invalid." ) );
  2208. status = MQTTBadResponse;
  2209. }
  2210. }
  2211. else
  2212. {
  2213. LogError( ( "Incoming packet invalid: Packet type=%u.",
  2214. ( unsigned int ) pIncomingPacket->type ) );
  2215. status = MQTTBadResponse;
  2216. }
  2217. }
  2218. else if( ( status != MQTTBadParameter ) && ( bytesReceived == 0 ) )
  2219. {
  2220. status = MQTTNoDataAvailable;
  2221. }
  2222. /* If the input packet was valid, then any other number of bytes received is
  2223. * a failure. */
  2224. else if( status != MQTTBadParameter )
  2225. {
  2226. LogError( ( "A single byte was not read from the transport: "
  2227. "transportStatus=%ld.",
  2228. ( long int ) bytesReceived ) );
  2229. status = MQTTRecvFailed;
  2230. }
  2231. else
  2232. {
  2233. /* Empty else MISRA 15.7 */
  2234. }
  2235. return status;
  2236. }
  2237. /*-----------------------------------------------------------*/
  2238. MQTTStatus_t MQTT_UpdateDuplicatePublishFlag( uint8_t * pHeader,
  2239. bool set )
  2240. {
  2241. MQTTStatus_t status = MQTTSuccess;
  2242. if( pHeader == NULL )
  2243. {
  2244. LogError( ( "Header cannot be NULL" ) );
  2245. status = MQTTBadParameter;
  2246. }
  2247. else if( ( ( *pHeader ) & 0xF0U ) != MQTT_PACKET_TYPE_PUBLISH )
  2248. {
  2249. LogError( ( "Header is not publish packet header" ) );
  2250. status = MQTTBadParameter;
  2251. }
  2252. else if( set == true )
  2253. {
  2254. UINT8_SET_BIT( *pHeader, MQTT_PUBLISH_FLAG_DUP );
  2255. }
  2256. else
  2257. {
  2258. UINT8_CLEAR_BIT( *pHeader, MQTT_PUBLISH_FLAG_DUP );
  2259. }
  2260. return status;
  2261. }
  2262. /*-----------------------------------------------------------*/
  2263. MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength( const uint8_t * pBuffer,
  2264. const size_t * pIndex,
  2265. MQTTPacketInfo_t * pIncomingPacket )
  2266. {
  2267. MQTTStatus_t status = MQTTSuccess;
  2268. if( pIncomingPacket == NULL )
  2269. {
  2270. LogError( ( "Invalid parameter: pIncomingPacket is NULL." ) );
  2271. status = MQTTBadParameter;
  2272. }
  2273. else if( pIndex == NULL )
  2274. {
  2275. LogError( ( "Invalid parameter: pIndex is NULL." ) );
  2276. status = MQTTBadParameter;
  2277. }
  2278. else if( pBuffer == NULL )
  2279. {
  2280. LogError( ( "Invalid parameter: pBuffer is NULL." ) );
  2281. status = MQTTBadParameter;
  2282. }
  2283. /* There should be at least one byte in the buffer */
  2284. else if( *pIndex < 1U )
  2285. {
  2286. /* No data is available. There are 0 bytes received from the network
  2287. * receive function. */
  2288. status = MQTTNoDataAvailable;
  2289. }
  2290. else
  2291. {
  2292. /* At least one byte is present which should be deciphered. */
  2293. pIncomingPacket->type = pBuffer[ 0 ];
  2294. }
  2295. if( status == MQTTSuccess )
  2296. {
  2297. /* Check validity. */
  2298. if( incomingPacketValid( pIncomingPacket->type ) == true )
  2299. {
  2300. status = processRemainingLength( pBuffer,
  2301. pIndex,
  2302. pIncomingPacket );
  2303. }
  2304. else
  2305. {
  2306. LogError( ( "Incoming packet invalid: Packet type=%u.",
  2307. ( unsigned int ) pIncomingPacket->type ) );
  2308. status = MQTTBadResponse;
  2309. }
  2310. }
  2311. return status;
  2312. }
  2313. /*-----------------------------------------------------------*/