core_mqtt_serializer.c 98 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715
  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 ) RyanMqttMemcpy( ( 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 ) RyanMqttMemcpy( ( 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_PUBACK:
  800. case MQTT_PACKET_TYPE_PUBREC:
  801. case MQTT_PACKET_TYPE_PUBCOMP:
  802. case MQTT_PACKET_TYPE_SUBACK:
  803. case MQTT_PACKET_TYPE_UNSUBACK:
  804. case MQTT_PACKET_TYPE_PINGRESP:
  805. if( ( packetType & 0x0FU ) == 0U )
  806. {
  807. status = true;
  808. }
  809. break;
  810. case MQTT_PACKET_TYPE_PUBLISH:
  811. if( ( packetType & 0x06U ) != 0x06U )
  812. {
  813. status = true;
  814. }
  815. break;
  816. case ( MQTT_PACKET_TYPE_PUBREL & 0xF0U ):
  817. /* The second bit of a PUBREL must be set. */
  818. if( ( packetType & 0x02U ) > 0U )
  819. {
  820. status = true;
  821. }
  822. break;
  823. /* Any other packet type is invalid. */
  824. default:
  825. LogWarn( ( "Incoming packet invalid: Packet type=%u.",
  826. ( unsigned int ) packetType ) );
  827. break;
  828. }
  829. return status;
  830. }
  831. /*-----------------------------------------------------------*/
  832. static MQTTStatus_t checkPublishRemainingLength( size_t remainingLength,
  833. MQTTQoS_t qos,
  834. size_t qos0Minimum )
  835. {
  836. MQTTStatus_t status = MQTTSuccess;
  837. /* Sanity checks for "Remaining length". */
  838. if( qos == MQTTQoS0 )
  839. {
  840. /* Check that the "Remaining length" is greater than the minimum. */
  841. if( remainingLength < qos0Minimum )
  842. {
  843. LogError( ( "QoS 0 PUBLISH cannot have a remaining length less than %lu.",
  844. ( unsigned long ) qos0Minimum ) );
  845. status = MQTTBadResponse;
  846. }
  847. }
  848. else
  849. {
  850. /* Check that the "Remaining length" is greater than the minimum. For
  851. * QoS 1 or 2, this will be two bytes greater than for QoS 0 due to the
  852. * packet identifier. */
  853. if( remainingLength < ( qos0Minimum + 2U ) )
  854. {
  855. LogError( ( "QoS 1 or 2 PUBLISH cannot have a remaining length less than %lu.",
  856. ( unsigned long ) ( qos0Minimum + 2U ) ) );
  857. status = MQTTBadResponse;
  858. }
  859. }
  860. return status;
  861. }
  862. /*-----------------------------------------------------------*/
  863. static MQTTStatus_t processPublishFlags( uint8_t publishFlags,
  864. MQTTPublishInfo_t * pPublishInfo )
  865. {
  866. MQTTStatus_t status = MQTTSuccess;
  867. assert( pPublishInfo != NULL );
  868. /* Check for QoS 2. */
  869. if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS2 ) )
  870. {
  871. /* PUBLISH packet is invalid if both QoS 1 and QoS 2 bits are set. */
  872. if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) )
  873. {
  874. LogError( ( "Bad QoS: 3." ) );
  875. status = MQTTBadResponse;
  876. }
  877. else
  878. {
  879. pPublishInfo->qos = MQTTQoS2;
  880. }
  881. }
  882. /* Check for QoS 1. */
  883. else if( UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_QOS1 ) )
  884. {
  885. pPublishInfo->qos = MQTTQoS1;
  886. }
  887. /* If the PUBLISH isn't QoS 1 or 2, then it's QoS 0. */
  888. else
  889. {
  890. pPublishInfo->qos = MQTTQoS0;
  891. }
  892. if( status == MQTTSuccess )
  893. {
  894. LogDebug( ( "QoS is %d.", ( int ) pPublishInfo->qos ) );
  895. /* Parse the Retain bit. */
  896. pPublishInfo->retain = UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_RETAIN );
  897. LogDebug( ( "Retain bit is %d.", ( int ) pPublishInfo->retain ) );
  898. /* Parse the DUP bit. */
  899. pPublishInfo->dup = UINT8_CHECK_BIT( publishFlags, MQTT_PUBLISH_FLAG_DUP );
  900. LogDebug( ( "DUP bit is %d.", ( int ) pPublishInfo->dup ) );
  901. }
  902. return status;
  903. }
  904. /*-----------------------------------------------------------*/
  905. // static void logConnackResponse( uint8_t responseCode )
  906. // {
  907. // const char * const pConnackResponses[ 6 ] =
  908. // {
  909. // "Connection accepted.", /* 0 */
  910. // "Connection refused: unacceptable protocol version.", /* 1 */
  911. // "Connection refused: identifier rejected.", /* 2 */
  912. // "Connection refused: server unavailable", /* 3 */
  913. // "Connection refused: bad user name or password.", /* 4 */
  914. // "Connection refused: not authorized." /* 5 */
  915. // };
  916. // /* Avoid unused parameter warning when assert and logs are disabled. */
  917. // ( void ) responseCode;
  918. // ( void ) pConnackResponses;
  919. // assert( responseCode <= 5U );
  920. // if( responseCode == 0u )
  921. // {
  922. // /* Log at Debug level for a success CONNACK response. */
  923. // LogDebug( ( "%s", pConnackResponses[ 0 ] ) );
  924. // }
  925. // else
  926. // {
  927. // /* Log an error based on the CONNACK response code. */
  928. // LogError( ( "%s", pConnackResponses[ responseCode ] ) );
  929. // }
  930. // }
  931. /*-----------------------------------------------------------*/
  932. static MQTTStatus_t deserializeConnack( const MQTTPacketInfo_t * pConnack,
  933. bool * pSessionPresent )
  934. {
  935. MQTTStatus_t status = MQTTSuccess;
  936. const uint8_t * pRemainingData = NULL;
  937. assert( pConnack != NULL );
  938. assert( pSessionPresent != NULL );
  939. pRemainingData = pConnack->pRemainingData;
  940. /* According to MQTT 3.1.1, the second byte of CONNACK must specify a
  941. * "Remaining length" of 2. */
  942. if( pConnack->remainingLength != MQTT_PACKET_CONNACK_REMAINING_LENGTH )
  943. {
  944. LogError( ( "CONNACK does not have remaining length of %u.",
  945. ( unsigned int ) MQTT_PACKET_CONNACK_REMAINING_LENGTH ) );
  946. status = MQTTBadResponse;
  947. }
  948. /* Check the reserved bits in CONNACK. The high 7 bits of the third byte
  949. * in CONNACK must be 0. */
  950. else if( ( pRemainingData[ 0 ] | 0x01U ) != 0x01U )
  951. {
  952. LogError( ( "Reserved bits in CONNACK incorrect." ) );
  953. status = MQTTBadResponse;
  954. }
  955. else
  956. {
  957. /* Determine if the "Session Present" bit is set. This is the lowest bit of
  958. * the third byte in CONNACK. */
  959. if( ( pRemainingData[ 0 ] & MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK )
  960. == MQTT_PACKET_CONNACK_SESSION_PRESENT_MASK )
  961. {
  962. LogDebug( ( "CONNACK session present bit set." ) );
  963. *pSessionPresent = true;
  964. /* MQTT 3.1.1 specifies that the fourth byte in CONNACK must be 0 if the
  965. * "Session Present" bit is set. */
  966. if( pRemainingData[ 1 ] != 0U )
  967. {
  968. LogError( ( "Session Present bit is set, but connect return code in CONNACK is %u (nonzero).",
  969. ( unsigned int ) pRemainingData[ 1 ] ) );
  970. status = MQTTBadResponse;
  971. }
  972. }
  973. else
  974. {
  975. LogDebug( ( "CONNACK session present bit not set." ) );
  976. *pSessionPresent = false;
  977. }
  978. }
  979. if( status == MQTTSuccess )
  980. {
  981. /* In MQTT 3.1.1, only values 0 through 5 are valid CONNACK response codes. */
  982. if( pRemainingData[ 1 ] > 5U )
  983. {
  984. LogError( ( "CONNACK response %u is invalid.",
  985. ( unsigned int ) pRemainingData[ 1 ] ) );
  986. status = MQTTBadResponse;
  987. }
  988. else
  989. {
  990. /* Print the appropriate message for the CONNACK response code if logs are
  991. * enabled. */
  992. // logConnackResponse( pRemainingData[ 1 ] );
  993. /* A nonzero CONNACK response code means the connection was refused. */
  994. if( pRemainingData[ 1 ] > 0U )
  995. {
  996. status = MQTTServerRefused;
  997. }
  998. }
  999. }
  1000. return status;
  1001. }
  1002. /*-----------------------------------------------------------*/
  1003. static MQTTStatus_t calculateSubscriptionPacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  1004. size_t subscriptionCount,
  1005. size_t * pRemainingLength,
  1006. size_t * pPacketSize,
  1007. MQTTSubscriptionType_t subscriptionType )
  1008. {
  1009. MQTTStatus_t status = MQTTSuccess;
  1010. size_t i = 0, packetSize = 0;
  1011. assert( pSubscriptionList != NULL );
  1012. assert( subscriptionCount != 0U );
  1013. assert( pRemainingLength != NULL );
  1014. assert( pPacketSize != NULL );
  1015. /* The variable header of a subscription packet consists of a 2-byte packet
  1016. * identifier. */
  1017. packetSize += sizeof( uint16_t );
  1018. /* Sum the lengths of all subscription topic filters; add 1 byte for each
  1019. * subscription's QoS if type is MQTT_SUBSCRIBE. */
  1020. for( i = 0; i < subscriptionCount; i++ )
  1021. {
  1022. /* Add the length of the topic filter. MQTT strings are prepended
  1023. * with 2 byte string length field. Hence 2 bytes are added to size. */
  1024. packetSize += pSubscriptionList[ i ].topicFilterLength + sizeof( uint16_t );
  1025. /* Only SUBSCRIBE packets include the QoS. */
  1026. if( subscriptionType == MQTT_SUBSCRIBE )
  1027. {
  1028. packetSize += 1U;
  1029. }
  1030. /* Validate each topic filter. */
  1031. if( ( pSubscriptionList[ i ].topicFilterLength == 0U ) ||
  1032. ( pSubscriptionList[ i ].pTopicFilter == NULL ) )
  1033. {
  1034. status = MQTTBadParameter;
  1035. LogError( ( "Subscription #%lu in %sSUBSCRIBE packet cannot be empty.",
  1036. ( unsigned long ) i,
  1037. ( subscriptionType == MQTT_SUBSCRIBE ) ? "" : "UN" ) );
  1038. /* It is not necessary to break as an error status has already been set. */
  1039. }
  1040. }
  1041. /* At this point, the "Remaining length" has been calculated. Return error
  1042. * if the "Remaining length" exceeds what is allowed by MQTT 3.1.1. Otherwise,
  1043. * set the output parameter.*/
  1044. if( packetSize > MQTT_MAX_REMAINING_LENGTH )
  1045. {
  1046. LogError( ( "Subscription packet length of %lu exceeds"
  1047. "the MQTT 3.1.1 maximum packet length of %lu.",
  1048. ( unsigned long ) packetSize,
  1049. MQTT_MAX_REMAINING_LENGTH ) );
  1050. status = MQTTBadParameter;
  1051. }
  1052. if( status == MQTTSuccess )
  1053. {
  1054. *pRemainingLength = packetSize;
  1055. /* Calculate the full size of the subscription packet by adding
  1056. * number of bytes required to encode the "Remaining length" field
  1057. * plus 1 byte for the "Packet type" field. */
  1058. packetSize += 1U + remainingLengthEncodedSize( packetSize );
  1059. /*Set the pPacketSize output parameter. */
  1060. *pPacketSize = packetSize;
  1061. }
  1062. LogDebug( ( "Subscription packet remaining length=%lu and packet size=%lu.",
  1063. ( unsigned long ) *pRemainingLength,
  1064. ( unsigned long ) *pPacketSize ) );
  1065. return status;
  1066. }
  1067. /*-----------------------------------------------------------*/
  1068. static MQTTStatus_t readSubackStatus( size_t statusCount,
  1069. const uint8_t * pStatusStart )
  1070. {
  1071. MQTTStatus_t status = MQTTSuccess;
  1072. uint8_t subscriptionStatus = 0;
  1073. size_t i = 0;
  1074. assert( pStatusStart != NULL );
  1075. /* Iterate through each status byte in the SUBACK packet. */
  1076. for( i = 0; i < statusCount; i++ )
  1077. {
  1078. /* Read a single status byte in SUBACK. */
  1079. subscriptionStatus = pStatusStart[ i ];
  1080. /* MQTT 3.1.1 defines the following values as status codes. */
  1081. switch( subscriptionStatus )
  1082. {
  1083. case 0x00:
  1084. case 0x01:
  1085. case 0x02:
  1086. LogDebug( ( "Topic filter %lu accepted, max QoS %u.",
  1087. ( unsigned long ) i,
  1088. ( unsigned int ) subscriptionStatus ) );
  1089. break;
  1090. case 0x80:
  1091. LogWarn( ( "Topic filter %lu refused.", ( unsigned long ) i ) );
  1092. /* Application should remove subscription from the list */
  1093. status = MQTTServerRefused;
  1094. break;
  1095. default:
  1096. LogError( ( "Bad SUBSCRIBE status %u.",
  1097. ( unsigned int ) subscriptionStatus ) );
  1098. status = MQTTBadResponse;
  1099. break;
  1100. }
  1101. /* Stop parsing the subscription statuses if a bad response was received. */
  1102. if( status == MQTTBadResponse )
  1103. {
  1104. break;
  1105. }
  1106. }
  1107. return status;
  1108. }
  1109. /*-----------------------------------------------------------*/
  1110. static MQTTStatus_t deserializeSuback( const MQTTPacketInfo_t * pSuback,
  1111. uint16_t * pPacketIdentifier )
  1112. {
  1113. MQTTStatus_t status = MQTTSuccess;
  1114. size_t remainingLength;
  1115. const uint8_t * pVariableHeader = NULL;
  1116. assert( pSuback != NULL );
  1117. assert( pPacketIdentifier != NULL );
  1118. remainingLength = pSuback->remainingLength;
  1119. pVariableHeader = pSuback->pRemainingData;
  1120. /* A SUBACK must have a remaining length of at least 3 to accommodate the
  1121. * packet identifier and at least 1 return code. */
  1122. if( remainingLength < 3U )
  1123. {
  1124. LogError( ( "SUBACK cannot have a remaining length less than 3." ) );
  1125. status = MQTTBadResponse;
  1126. }
  1127. else
  1128. {
  1129. /* Extract the packet identifier (first 2 bytes of variable header) from SUBACK. */
  1130. *pPacketIdentifier = UINT16_DECODE( pVariableHeader );
  1131. LogDebug( ( "Packet identifier %hu.",
  1132. ( unsigned short ) *pPacketIdentifier ) );
  1133. if( *pPacketIdentifier == 0U )
  1134. {
  1135. status = MQTTBadResponse;
  1136. }
  1137. else
  1138. {
  1139. status = readSubackStatus( remainingLength - sizeof( uint16_t ),
  1140. &pVariableHeader[ sizeof( uint16_t ) ] );
  1141. }
  1142. }
  1143. return status;
  1144. }
  1145. /*-----------------------------------------------------------*/
  1146. static MQTTStatus_t validateSubscriptionSerializeParams( const MQTTSubscribeInfo_t * pSubscriptionList,
  1147. size_t subscriptionCount,
  1148. uint16_t packetId,
  1149. size_t remainingLength,
  1150. const MQTTFixedBuffer_t * pFixedBuffer )
  1151. {
  1152. MQTTStatus_t status = MQTTSuccess;
  1153. size_t packetSize = 0;
  1154. /* Validate all the parameters. */
  1155. if( ( pFixedBuffer == NULL ) || ( pSubscriptionList == NULL ) )
  1156. {
  1157. LogError( ( "Argument cannot be NULL: pFixedBuffer=%p, "
  1158. "pSubscriptionList=%p.",
  1159. ( void * ) pFixedBuffer,
  1160. ( void * ) pSubscriptionList ) );
  1161. status = MQTTBadParameter;
  1162. }
  1163. /* A buffer must be configured for serialization. */
  1164. else if( pFixedBuffer->pBuffer == NULL )
  1165. {
  1166. LogError( ( "Argument cannot be NULL: pFixedBuffer->pBuffer is NULL." ) );
  1167. status = MQTTBadParameter;
  1168. }
  1169. else if( subscriptionCount == 0U )
  1170. {
  1171. LogError( ( "Subscription count is 0." ) );
  1172. status = MQTTBadParameter;
  1173. }
  1174. else if( packetId == 0U )
  1175. {
  1176. LogError( ( "Packet Id for subscription packet is 0." ) );
  1177. status = MQTTBadParameter;
  1178. }
  1179. else
  1180. {
  1181. /* The serialized packet size = First byte
  1182. * + length of encoded size of remaining length
  1183. * + remaining length. */
  1184. packetSize = 1U + remainingLengthEncodedSize( remainingLength )
  1185. + remainingLength;
  1186. if( packetSize > pFixedBuffer->size )
  1187. {
  1188. LogError( ( "Buffer size of %lu is not sufficient to hold "
  1189. "serialized packet of size of %lu.",
  1190. ( unsigned long ) pFixedBuffer->size,
  1191. ( unsigned long ) packetSize ) );
  1192. status = MQTTNoMemory;
  1193. }
  1194. }
  1195. return status;
  1196. }
  1197. /*-----------------------------------------------------------*/
  1198. static MQTTStatus_t deserializePublish( const MQTTPacketInfo_t * pIncomingPacket,
  1199. uint16_t * pPacketId,
  1200. MQTTPublishInfo_t * pPublishInfo )
  1201. {
  1202. MQTTStatus_t status = MQTTSuccess;
  1203. const uint8_t * pVariableHeader, * pPacketIdentifierHigh = NULL;
  1204. assert( pIncomingPacket != NULL );
  1205. assert( pPacketId != NULL );
  1206. assert( pPublishInfo != NULL );
  1207. assert( pIncomingPacket->pRemainingData != NULL );
  1208. pVariableHeader = pIncomingPacket->pRemainingData;
  1209. /* The flags are the lower 4 bits of the first byte in PUBLISH. */
  1210. status = processPublishFlags( ( pIncomingPacket->type & 0x0FU ), pPublishInfo );
  1211. if( status == MQTTSuccess )
  1212. {
  1213. /* Sanity checks for "Remaining length". A QoS 0 PUBLISH must have a remaining
  1214. * length of at least 3 to accommodate topic name length (2 bytes) and topic
  1215. * name (at least 1 byte). A QoS 1 or 2 PUBLISH must have a remaining length of
  1216. * at least 5 for the packet identifier in addition to the topic name length and
  1217. * topic name. */
  1218. status = checkPublishRemainingLength( pIncomingPacket->remainingLength,
  1219. pPublishInfo->qos,
  1220. MQTT_MIN_PUBLISH_REMAINING_LENGTH_QOS0 );
  1221. }
  1222. if( status == MQTTSuccess )
  1223. {
  1224. /* Extract the topic name starting from the first byte of the variable header.
  1225. * The topic name string starts at byte 3 in the variable header. */
  1226. pPublishInfo->topicNameLength = UINT16_DECODE( pVariableHeader );
  1227. /* Sanity checks for topic name length and "Remaining length". The remaining
  1228. * length must be at least as large as the variable length header. */
  1229. status = checkPublishRemainingLength( pIncomingPacket->remainingLength,
  1230. pPublishInfo->qos,
  1231. pPublishInfo->topicNameLength + sizeof( uint16_t ) );
  1232. }
  1233. if( status == MQTTSuccess )
  1234. {
  1235. /* Parse the topic. */
  1236. pPublishInfo->pTopicName = ( const char * ) ( &pVariableHeader[ sizeof( uint16_t ) ] );
  1237. LogDebug( ( "Topic name length: %hu.", ( unsigned short ) pPublishInfo->topicNameLength ) );
  1238. /* Extract the packet identifier for QoS 1 or 2 PUBLISH packets. Packet
  1239. * identifier starts immediately after the topic name. */
  1240. /* coverity[tainted_scalar] */
  1241. pPacketIdentifierHigh = ( const uint8_t * ) ( &pPublishInfo->pTopicName[ pPublishInfo->topicNameLength ] );
  1242. if( pPublishInfo->qos > MQTTQoS0 )
  1243. {
  1244. *pPacketId = UINT16_DECODE( pPacketIdentifierHigh );
  1245. LogDebug( ( "Packet identifier %hu.",
  1246. ( unsigned short ) *pPacketId ) );
  1247. /* Advance pointer two bytes to start of payload as in the QoS 0 case. */
  1248. pPacketIdentifierHigh = &pPacketIdentifierHigh[ sizeof( uint16_t ) ];
  1249. /* Packet identifier cannot be 0. */
  1250. if( *pPacketId == 0U )
  1251. {
  1252. LogError( ( "Packet identifier cannot be 0." ) );
  1253. status = MQTTBadResponse;
  1254. }
  1255. }
  1256. }
  1257. if( status == MQTTSuccess )
  1258. {
  1259. /* Calculate the length of the payload. QoS 1 or 2 PUBLISH packets contain
  1260. * a packet identifier, but QoS 0 PUBLISH packets do not. */
  1261. pPublishInfo->payloadLength = pIncomingPacket->remainingLength - pPublishInfo->topicNameLength - sizeof( uint16_t );
  1262. if( pPublishInfo->qos != MQTTQoS0 )
  1263. {
  1264. /* Two more bytes for the packet identifier. */
  1265. pPublishInfo->payloadLength -= sizeof( uint16_t );
  1266. }
  1267. /* Set payload if it exists. */
  1268. pPublishInfo->pPayload = ( pPublishInfo->payloadLength != 0U ) ? pPacketIdentifierHigh : NULL;
  1269. LogDebug( ( "Payload length %lu.",
  1270. ( unsigned long ) pPublishInfo->payloadLength ) );
  1271. }
  1272. return status;
  1273. }
  1274. /*-----------------------------------------------------------*/
  1275. static MQTTStatus_t deserializeSimpleAck( const MQTTPacketInfo_t * pAck,
  1276. uint16_t * pPacketIdentifier )
  1277. {
  1278. MQTTStatus_t status = MQTTSuccess;
  1279. assert( pAck != NULL );
  1280. assert( pPacketIdentifier != NULL );
  1281. /* Check that the "Remaining length" of the received ACK is 2. */
  1282. if( pAck->remainingLength != MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH )
  1283. {
  1284. LogError( ( "ACK does not have remaining length of %u.",
  1285. ( unsigned int ) MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH ) );
  1286. status = MQTTBadResponse;
  1287. }
  1288. else
  1289. {
  1290. /* Extract the packet identifier (third and fourth bytes) from ACK. */
  1291. *pPacketIdentifier = UINT16_DECODE( pAck->pRemainingData );
  1292. LogDebug( ( "Packet identifier %hu.",
  1293. ( unsigned short ) *pPacketIdentifier ) );
  1294. /* Packet identifier cannot be 0. */
  1295. if( *pPacketIdentifier == 0U )
  1296. {
  1297. LogError( ( "Packet identifier cannot be 0." ) );
  1298. status = MQTTBadResponse;
  1299. }
  1300. }
  1301. return status;
  1302. }
  1303. /*-----------------------------------------------------------*/
  1304. static MQTTStatus_t deserializePingresp( const MQTTPacketInfo_t * pPingresp )
  1305. {
  1306. MQTTStatus_t status = MQTTSuccess;
  1307. assert( pPingresp != NULL );
  1308. /* Check the "Remaining length" (second byte) of the received PINGRESP is 0. */
  1309. if( pPingresp->remainingLength != MQTT_PACKET_PINGRESP_REMAINING_LENGTH )
  1310. {
  1311. LogError( ( "PINGRESP does not have remaining length of %u.",
  1312. MQTT_PACKET_PINGRESP_REMAINING_LENGTH ) );
  1313. status = MQTTBadResponse;
  1314. }
  1315. return status;
  1316. }
  1317. uint8_t * MQTT_SerializeConnectFixedHeader( uint8_t * pIndex,
  1318. const MQTTConnectInfo_t * pConnectInfo,
  1319. const MQTTPublishInfo_t * pWillInfo,
  1320. size_t remainingLength )
  1321. {
  1322. uint8_t * pIndexLocal = pIndex;
  1323. uint8_t connectFlags = 0U;
  1324. /* The first byte in the CONNECT packet is the control packet type. */
  1325. *pIndexLocal = MQTT_PACKET_TYPE_CONNECT;
  1326. pIndexLocal++;
  1327. /* The remaining length of the CONNECT packet is encoded starting from the
  1328. * second byte. The remaining length does not include the length of the fixed
  1329. * header or the encoding of the remaining length. */
  1330. pIndexLocal = encodeRemainingLength( pIndexLocal, remainingLength );
  1331. /* The string "MQTT" is placed at the beginning of the CONNECT packet's variable
  1332. * header. This string is 4 bytes long. */
  1333. pIndexLocal = encodeString( pIndexLocal, "MQTT", 4 );
  1334. /* The MQTT protocol version is the second field of the variable header. */
  1335. *pIndexLocal = MQTT_VERSION_3_1_1;
  1336. pIndexLocal++;
  1337. /* Set the clean session flag if needed. */
  1338. if( pConnectInfo->cleanSession == true )
  1339. {
  1340. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_CLEAN );
  1341. }
  1342. /* Set the flags for username and password if provided. */
  1343. if( pConnectInfo->pUserName != NULL )
  1344. {
  1345. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_USERNAME );
  1346. }
  1347. if( pConnectInfo->pPassword != NULL )
  1348. {
  1349. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_PASSWORD );
  1350. }
  1351. /* Set will flag if a Last Will and Testament is provided. */
  1352. if( pWillInfo != NULL )
  1353. {
  1354. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL );
  1355. /* Flags only need to be changed for Will QoS 1 or 2. */
  1356. if( pWillInfo->qos == MQTTQoS1 )
  1357. {
  1358. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS1 );
  1359. }
  1360. else if( pWillInfo->qos == MQTTQoS2 )
  1361. {
  1362. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_QOS2 );
  1363. }
  1364. else
  1365. {
  1366. /* Empty else MISRA 15.7 */
  1367. }
  1368. if( pWillInfo->retain == true )
  1369. {
  1370. UINT8_SET_BIT( connectFlags, MQTT_CONNECT_FLAG_WILL_RETAIN );
  1371. }
  1372. }
  1373. *pIndexLocal = connectFlags;
  1374. pIndexLocal++;
  1375. /* Write the 2 bytes of the keep alive interval into the CONNECT packet. */
  1376. pIndexLocal[ 0 ] = UINT16_HIGH_BYTE( pConnectInfo->keepAliveSeconds );
  1377. pIndexLocal[ 1 ] = UINT16_LOW_BYTE( pConnectInfo->keepAliveSeconds );
  1378. pIndexLocal = &pIndexLocal[ 2 ];
  1379. return pIndexLocal;
  1380. }
  1381. /*-----------------------------------------------------------*/
  1382. static void serializeConnectPacket( const MQTTConnectInfo_t * pConnectInfo,
  1383. const MQTTPublishInfo_t * pWillInfo,
  1384. size_t remainingLength,
  1385. const MQTTFixedBuffer_t * pFixedBuffer )
  1386. {
  1387. uint8_t * pIndex = NULL;
  1388. assert( pConnectInfo != NULL );
  1389. assert( pFixedBuffer != NULL );
  1390. assert( pFixedBuffer->pBuffer != NULL );
  1391. pIndex = pFixedBuffer->pBuffer;
  1392. /* Serialize the header. */
  1393. pIndex = MQTT_SerializeConnectFixedHeader( pIndex,
  1394. pConnectInfo,
  1395. pWillInfo,
  1396. remainingLength );
  1397. /* Write the client identifier into the CONNECT packet. */
  1398. pIndex = encodeString( pIndex,
  1399. pConnectInfo->pClientIdentifier,
  1400. pConnectInfo->clientIdentifierLength );
  1401. /* Write the will topic name and message into the CONNECT packet if provided. */
  1402. if( pWillInfo != NULL )
  1403. {
  1404. pIndex = encodeString( pIndex,
  1405. pWillInfo->pTopicName,
  1406. pWillInfo->topicNameLength );
  1407. pIndex = encodeString( pIndex,
  1408. pWillInfo->pPayload,
  1409. ( uint16_t ) pWillInfo->payloadLength );
  1410. }
  1411. /* Encode the user name if provided. */
  1412. if( pConnectInfo->pUserName != NULL )
  1413. {
  1414. pIndex = encodeString( pIndex, pConnectInfo->pUserName, pConnectInfo->userNameLength );
  1415. }
  1416. /* Encode the password if provided. */
  1417. if( pConnectInfo->pPassword != NULL )
  1418. {
  1419. pIndex = encodeString( pIndex, pConnectInfo->pPassword, pConnectInfo->passwordLength );
  1420. }
  1421. LogDebug( ( "Length of serialized CONNECT packet is %lu.",
  1422. ( ( unsigned long ) ( pIndex - pFixedBuffer->pBuffer ) ) ) );
  1423. /* Ensure that the difference between the end and beginning of the buffer
  1424. * is less than the buffer size. */
  1425. assert( ( ( size_t ) ( pIndex - pFixedBuffer->pBuffer ) ) <= pFixedBuffer->size );
  1426. }
  1427. /*-----------------------------------------------------------*/
  1428. MQTTStatus_t MQTT_GetConnectPacketSize( const MQTTConnectInfo_t * pConnectInfo,
  1429. const MQTTPublishInfo_t * pWillInfo,
  1430. size_t * pRemainingLength,
  1431. size_t * pPacketSize )
  1432. {
  1433. MQTTStatus_t status = MQTTSuccess;
  1434. size_t remainingLength;
  1435. /* The CONNECT packet will always include a 10-byte variable header. */
  1436. size_t connectPacketSize = MQTT_PACKET_CONNECT_HEADER_SIZE;
  1437. /* Validate arguments. */
  1438. if( ( pConnectInfo == NULL ) || ( pRemainingLength == NULL ) ||
  1439. ( pPacketSize == NULL ) )
  1440. {
  1441. LogError( ( "Argument cannot be NULL: pConnectInfo=%p, "
  1442. "pRemainingLength=%p, pPacketSize=%p.",
  1443. ( void * ) pConnectInfo,
  1444. ( void * ) pRemainingLength,
  1445. ( void * ) pPacketSize ) );
  1446. status = MQTTBadParameter;
  1447. }
  1448. // else if( ( pConnectInfo->clientIdentifierLength == 0U ) || ( pConnectInfo->pClientIdentifier == NULL ) )
  1449. // {
  1450. // LogError( ( "Mqtt_GetConnectPacketSize() client identifier must be set." ) );
  1451. // status = MQTTBadParameter;
  1452. // }
  1453. else if( ( pWillInfo != NULL ) && ( pWillInfo->payloadLength > ( size_t ) UINT16_MAX ) )
  1454. {
  1455. /* The MQTTPublishInfo_t is reused for the will message. The payload
  1456. * length for any other message could be larger than 65,535, but
  1457. * the will message length is required to be represented in 2 bytes.
  1458. * By bounding the payloadLength of the will message, the CONNECT
  1459. * packet will never be larger than 327699 bytes. */
  1460. LogError( ( "The Will Message length must not exceed %d. "
  1461. "pWillInfo->payloadLength=%lu.",
  1462. UINT16_MAX,
  1463. ( unsigned long ) pWillInfo->payloadLength ) );
  1464. status = MQTTBadParameter;
  1465. }
  1466. else
  1467. {
  1468. /* Add the length of the client identifier. */
  1469. connectPacketSize += pConnectInfo->clientIdentifierLength + sizeof( uint16_t );
  1470. /* Add the lengths of the will message and topic name if provided. */
  1471. if( pWillInfo != NULL )
  1472. {
  1473. connectPacketSize += pWillInfo->topicNameLength + sizeof( uint16_t ) +
  1474. pWillInfo->payloadLength + sizeof( uint16_t );
  1475. }
  1476. /* Add the lengths of the user name and password if provided. */
  1477. if( pConnectInfo->pUserName != NULL )
  1478. {
  1479. connectPacketSize += pConnectInfo->userNameLength + sizeof( uint16_t );
  1480. }
  1481. if( pConnectInfo->pPassword != NULL )
  1482. {
  1483. connectPacketSize += pConnectInfo->passwordLength + sizeof( uint16_t );
  1484. }
  1485. /* At this point, the "Remaining Length" field of the MQTT CONNECT packet has
  1486. * been calculated. */
  1487. remainingLength = connectPacketSize;
  1488. /* Calculate the full size of the MQTT CONNECT packet by adding the size of
  1489. * the "Remaining Length" field plus 1 byte for the "Packet Type" field. */
  1490. connectPacketSize += 1U + remainingLengthEncodedSize( connectPacketSize );
  1491. /* The connectPacketSize calculated from this function's parameters is
  1492. * guaranteed to be less than the maximum MQTT CONNECT packet size, which
  1493. * is 327700. If the maximum client identifier length, the maximum will
  1494. * message topic length, the maximum will topic payload length, the
  1495. * maximum username length, and the maximum password length are all present
  1496. * in the MQTT CONNECT packet, the total size will be calculated to be
  1497. * 327699:
  1498. * (variable length header)10 +
  1499. * (maximum client identifier length) 65535 + (encoded length) 2 +
  1500. * (maximum will message topic name length) 65535 + (encoded length)2 +
  1501. * (maximum will message payload length) 65535 + 2 +
  1502. * (maximum username length) 65535 + (encoded length) 2 +
  1503. * (maximum password length) 65535 + (encoded length) 2 +
  1504. * (packet type field length) 1 +
  1505. * (CONNECT packet encoded length) 3 = 327699 */
  1506. *pRemainingLength = remainingLength;
  1507. *pPacketSize = connectPacketSize;
  1508. LogDebug( ( "CONNECT packet remaining length=%lu and packet size=%lu.",
  1509. ( unsigned long ) *pRemainingLength,
  1510. ( unsigned long ) *pPacketSize ) );
  1511. }
  1512. return status;
  1513. }
  1514. /*-----------------------------------------------------------*/
  1515. MQTTStatus_t MQTT_SerializeConnect( const MQTTConnectInfo_t * pConnectInfo,
  1516. const MQTTPublishInfo_t * pWillInfo,
  1517. size_t remainingLength,
  1518. const MQTTFixedBuffer_t * pFixedBuffer )
  1519. {
  1520. MQTTStatus_t status = MQTTSuccess;
  1521. size_t connectPacketSize = 0;
  1522. /* Validate arguments. */
  1523. if( ( pConnectInfo == NULL ) || ( pFixedBuffer == NULL ) )
  1524. {
  1525. LogError( ( "Argument cannot be NULL: pConnectInfo=%p, "
  1526. "pFixedBuffer=%p.",
  1527. ( void * ) pConnectInfo,
  1528. ( void * ) pFixedBuffer ) );
  1529. status = MQTTBadParameter;
  1530. }
  1531. /* A buffer must be configured for serialization. */
  1532. else if( pFixedBuffer->pBuffer == NULL )
  1533. {
  1534. LogError( ( "Argument cannot be NULL: pFixedBuffer->pBuffer is NULL." ) );
  1535. status = MQTTBadParameter;
  1536. }
  1537. else if( ( pWillInfo != NULL ) && ( pWillInfo->pTopicName == NULL ) )
  1538. {
  1539. LogError( ( "pWillInfo->pTopicName cannot be NULL if Will is present." ) );
  1540. status = MQTTBadParameter;
  1541. }
  1542. else
  1543. {
  1544. /* Calculate CONNECT packet size. Overflow in in this addition is not checked
  1545. * because it is part of the API contract to call Mqtt_GetConnectPacketSize()
  1546. * before this function. */
  1547. connectPacketSize = remainingLength + remainingLengthEncodedSize( remainingLength ) + 1U;
  1548. /* Check that the full packet size fits within the given buffer. */
  1549. if( connectPacketSize > pFixedBuffer->size )
  1550. {
  1551. LogError( ( "Buffer size of %lu is not sufficient to hold "
  1552. "serialized CONNECT packet of size of %lu.",
  1553. ( unsigned long ) pFixedBuffer->size,
  1554. ( unsigned long ) connectPacketSize ) );
  1555. status = MQTTNoMemory;
  1556. }
  1557. else
  1558. {
  1559. serializeConnectPacket( pConnectInfo,
  1560. pWillInfo,
  1561. remainingLength,
  1562. pFixedBuffer );
  1563. }
  1564. }
  1565. return status;
  1566. }
  1567. /*-----------------------------------------------------------*/
  1568. MQTTStatus_t MQTT_GetSubscribePacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  1569. size_t subscriptionCount,
  1570. size_t * pRemainingLength,
  1571. size_t * pPacketSize )
  1572. {
  1573. MQTTStatus_t status = MQTTSuccess;
  1574. /* Validate parameters. */
  1575. if( ( pSubscriptionList == NULL ) || ( pRemainingLength == NULL ) ||
  1576. ( pPacketSize == NULL ) )
  1577. {
  1578. LogError( ( "Argument cannot be NULL: pSubscriptionList=%p, "
  1579. "pRemainingLength=%p, pPacketSize=%p.",
  1580. ( void * ) pSubscriptionList,
  1581. ( void * ) pRemainingLength,
  1582. ( void * ) pPacketSize ) );
  1583. status = MQTTBadParameter;
  1584. }
  1585. else if( subscriptionCount == 0U )
  1586. {
  1587. LogError( ( "subscriptionCount is 0." ) );
  1588. status = MQTTBadParameter;
  1589. }
  1590. else
  1591. {
  1592. /* Calculate the MQTT SUBSCRIBE packet size. */
  1593. status = calculateSubscriptionPacketSize( pSubscriptionList,
  1594. subscriptionCount,
  1595. pRemainingLength,
  1596. pPacketSize,
  1597. MQTT_SUBSCRIBE );
  1598. }
  1599. return status;
  1600. }
  1601. /*-----------------------------------------------------------*/
  1602. uint8_t * MQTT_SerializeSubscribeHeader( size_t remainingLength,
  1603. uint8_t * pIndex,
  1604. uint16_t packetId )
  1605. {
  1606. uint8_t * pIterator = pIndex;
  1607. /* The first byte in SUBSCRIBE is the packet type. */
  1608. *pIterator = MQTT_PACKET_TYPE_SUBSCRIBE;
  1609. pIterator++;
  1610. /* Encode the "Remaining length" starting from the second byte. */
  1611. pIterator = encodeRemainingLength( pIterator, remainingLength );
  1612. /* Place the packet identifier into the SUBSCRIBE packet. */
  1613. pIterator[ 0 ] = UINT16_HIGH_BYTE( packetId );
  1614. pIterator[ 1 ] = UINT16_LOW_BYTE( packetId );
  1615. /* Advance the pointer. */
  1616. pIterator = &pIterator[ 2 ];
  1617. return pIterator;
  1618. }
  1619. /*-----------------------------------------------------------*/
  1620. uint8_t * MQTT_SerializeUnsubscribeHeader( size_t remainingLength,
  1621. uint8_t * pIndex,
  1622. uint16_t packetId )
  1623. {
  1624. uint8_t * pIterator = pIndex;
  1625. /* The first byte in UNSUBSCRIBE is the packet type. */
  1626. *pIterator = MQTT_PACKET_TYPE_UNSUBSCRIBE;
  1627. pIterator++;
  1628. /* Encode the "Remaining length" starting from the second byte. */
  1629. pIterator = encodeRemainingLength( pIterator, remainingLength );
  1630. /* Place the packet identifier into the SUBSCRIBE packet. */
  1631. pIterator[ 0 ] = UINT16_HIGH_BYTE( packetId );
  1632. pIterator[ 1 ] = UINT16_LOW_BYTE( packetId );
  1633. /* Increment the pointer. */
  1634. pIterator = &pIterator[ 2 ];
  1635. return pIterator;
  1636. }
  1637. MQTTStatus_t MQTT_SerializeSubscribe( const MQTTSubscribeInfo_t * pSubscriptionList,
  1638. size_t subscriptionCount,
  1639. uint16_t packetId,
  1640. size_t remainingLength,
  1641. const MQTTFixedBuffer_t * pFixedBuffer )
  1642. {
  1643. size_t i = 0;
  1644. uint8_t * pIndex = NULL;
  1645. /* Validate all the parameters. */
  1646. MQTTStatus_t status =
  1647. validateSubscriptionSerializeParams( pSubscriptionList,
  1648. subscriptionCount,
  1649. packetId,
  1650. remainingLength,
  1651. pFixedBuffer );
  1652. if( status == MQTTSuccess )
  1653. {
  1654. pIndex = pFixedBuffer->pBuffer;
  1655. pIndex = MQTT_SerializeSubscribeHeader( remainingLength,
  1656. pIndex,
  1657. packetId );
  1658. /* Serialize each subscription topic filter and QoS. */
  1659. for( i = 0; i < subscriptionCount; i++ )
  1660. {
  1661. pIndex = encodeString( pIndex,
  1662. pSubscriptionList[ i ].pTopicFilter,
  1663. pSubscriptionList[ i ].topicFilterLength );
  1664. /* Place the QoS in the SUBSCRIBE packet. */
  1665. *pIndex = ( uint8_t ) ( pSubscriptionList[ i ].qos );
  1666. pIndex++;
  1667. }
  1668. LogDebug( ( "Length of serialized SUBSCRIBE packet is %lu.",
  1669. ( ( unsigned long ) ( pIndex - pFixedBuffer->pBuffer ) ) ) );
  1670. }
  1671. return status;
  1672. }
  1673. /*-----------------------------------------------------------*/
  1674. MQTTStatus_t MQTT_GetUnsubscribePacketSize( const MQTTSubscribeInfo_t * pSubscriptionList,
  1675. size_t subscriptionCount,
  1676. size_t * pRemainingLength,
  1677. size_t * pPacketSize )
  1678. {
  1679. MQTTStatus_t status = MQTTSuccess;
  1680. /* Validate parameters. */
  1681. if( ( pSubscriptionList == NULL ) || ( pRemainingLength == NULL ) ||
  1682. ( pPacketSize == NULL ) )
  1683. {
  1684. LogError( ( "Argument cannot be NULL: pSubscriptionList=%p, "
  1685. "pRemainingLength=%p, pPacketSize=%p.",
  1686. ( void * ) pSubscriptionList,
  1687. ( void * ) pRemainingLength,
  1688. ( void * ) pPacketSize ) );
  1689. status = MQTTBadParameter;
  1690. }
  1691. else if( subscriptionCount == 0U )
  1692. {
  1693. LogError( ( "Subscription count is 0." ) );
  1694. status = MQTTBadParameter;
  1695. }
  1696. else
  1697. {
  1698. /* Calculate the MQTT UNSUBSCRIBE packet size. */
  1699. status = calculateSubscriptionPacketSize( pSubscriptionList,
  1700. subscriptionCount,
  1701. pRemainingLength,
  1702. pPacketSize,
  1703. MQTT_UNSUBSCRIBE );
  1704. }
  1705. return status;
  1706. }
  1707. /*-----------------------------------------------------------*/
  1708. MQTTStatus_t MQTT_SerializeUnsubscribe( const MQTTSubscribeInfo_t * pSubscriptionList,
  1709. size_t subscriptionCount,
  1710. uint16_t packetId,
  1711. size_t remainingLength,
  1712. const MQTTFixedBuffer_t * pFixedBuffer )
  1713. {
  1714. MQTTStatus_t status = MQTTSuccess;
  1715. size_t i = 0;
  1716. uint8_t * pIndex = NULL;
  1717. /* Validate all the parameters. */
  1718. status = validateSubscriptionSerializeParams( pSubscriptionList,
  1719. subscriptionCount,
  1720. packetId,
  1721. remainingLength,
  1722. pFixedBuffer );
  1723. if( status == MQTTSuccess )
  1724. {
  1725. /* Get the start of the buffer to the iterator variable. */
  1726. pIndex = pFixedBuffer->pBuffer;
  1727. pIndex = MQTT_SerializeUnsubscribeHeader( remainingLength, pIndex, packetId );
  1728. /* Serialize each subscription topic filter. */
  1729. for( i = 0; i < subscriptionCount; i++ )
  1730. {
  1731. pIndex = encodeString( pIndex,
  1732. pSubscriptionList[ i ].pTopicFilter,
  1733. pSubscriptionList[ i ].topicFilterLength );
  1734. }
  1735. LogDebug( ( "Length of serialized UNSUBSCRIBE packet is %lu.",
  1736. ( ( unsigned long ) ( pIndex - pFixedBuffer->pBuffer ) ) ) );
  1737. }
  1738. return status;
  1739. }
  1740. /*-----------------------------------------------------------*/
  1741. MQTTStatus_t MQTT_GetPublishPacketSize( const MQTTPublishInfo_t * pPublishInfo,
  1742. size_t * pRemainingLength,
  1743. size_t * pPacketSize )
  1744. {
  1745. MQTTStatus_t status = MQTTSuccess;
  1746. if( ( pPublishInfo == NULL ) || ( pRemainingLength == NULL ) || ( pPacketSize == NULL ) )
  1747. {
  1748. LogError( ( "Argument cannot be NULL: pPublishInfo=%p, "
  1749. "pRemainingLength=%p, pPacketSize=%p.",
  1750. ( void * ) pPublishInfo,
  1751. ( void * ) pRemainingLength,
  1752. ( void * ) pPacketSize ) );
  1753. status = MQTTBadParameter;
  1754. }
  1755. else if( ( pPublishInfo->pTopicName == NULL ) || ( pPublishInfo->topicNameLength == 0U ) )
  1756. {
  1757. LogError( ( "Invalid topic name for PUBLISH: pTopicName=%p, "
  1758. "topicNameLength=%hu.",
  1759. ( void * ) pPublishInfo->pTopicName,
  1760. ( unsigned short ) pPublishInfo->topicNameLength ) );
  1761. status = MQTTBadParameter;
  1762. }
  1763. else
  1764. {
  1765. /* Calculate the "Remaining length" field and total packet size. If it exceeds
  1766. * what is allowed in the MQTT standard, return an error. */
  1767. if( calculatePublishPacketSize( pPublishInfo, pRemainingLength, pPacketSize ) == false )
  1768. {
  1769. LogError( ( "PUBLISH packet remaining length exceeds %lu, which is the "
  1770. "maximum size allowed by MQTT 3.1.1.",
  1771. MQTT_MAX_REMAINING_LENGTH ) );
  1772. status = MQTTBadParameter;
  1773. }
  1774. }
  1775. return status;
  1776. }
  1777. /*-----------------------------------------------------------*/
  1778. MQTTStatus_t MQTT_SerializePublish( const MQTTPublishInfo_t * pPublishInfo,
  1779. uint16_t packetId,
  1780. size_t remainingLength,
  1781. const MQTTFixedBuffer_t * pFixedBuffer )
  1782. {
  1783. MQTTStatus_t status = MQTTSuccess;
  1784. size_t packetSize = 0;
  1785. if( ( pFixedBuffer == NULL ) || ( pPublishInfo == NULL ) )
  1786. {
  1787. LogError( ( "Argument cannot be NULL: pFixedBuffer=%p, "
  1788. "pPublishInfo=%p.",
  1789. ( void * ) pFixedBuffer,
  1790. ( void * ) pPublishInfo ) );
  1791. status = MQTTBadParameter;
  1792. }
  1793. /* A buffer must be configured for serialization. */
  1794. else if( pFixedBuffer->pBuffer == NULL )
  1795. {
  1796. LogError( ( "Argument cannot be NULL: pFixedBuffer->pBuffer is NULL." ) );
  1797. status = MQTTBadParameter;
  1798. }
  1799. /* For serializing a publish, if there exists a payload, then the buffer
  1800. * cannot be NULL. */
  1801. else if( ( pPublishInfo->payloadLength > 0U ) && ( pPublishInfo->pPayload == NULL ) )
  1802. {
  1803. LogError( ( "A nonzero payload length requires a non-NULL payload: "
  1804. "payloadLength=%lu, pPayload=%p.",
  1805. ( unsigned long ) pPublishInfo->payloadLength,
  1806. pPublishInfo->pPayload ) );
  1807. status = MQTTBadParameter;
  1808. }
  1809. else if( ( pPublishInfo->pTopicName == NULL ) || ( pPublishInfo->topicNameLength == 0U ) )
  1810. {
  1811. LogError( ( "Invalid topic name for PUBLISH: pTopicName=%p, "
  1812. "topicNameLength=%hu.",
  1813. ( void * ) pPublishInfo->pTopicName,
  1814. ( unsigned short ) pPublishInfo->topicNameLength ) );
  1815. status = MQTTBadParameter;
  1816. }
  1817. else if( ( pPublishInfo->qos != MQTTQoS0 ) && ( packetId == 0U ) )
  1818. {
  1819. LogError( ( "Packet ID is 0 for PUBLISH with QoS=%u.",
  1820. ( unsigned int ) pPublishInfo->qos ) );
  1821. status = MQTTBadParameter;
  1822. }
  1823. else if( ( pPublishInfo->dup == true ) && ( pPublishInfo->qos == MQTTQoS0 ) )
  1824. {
  1825. LogError( ( "Duplicate flag is set for PUBLISH with Qos 0." ) );
  1826. status = MQTTBadParameter;
  1827. }
  1828. else
  1829. {
  1830. /* Length of serialized packet = First byte
  1831. * + Length of encoded remaining length
  1832. * + Remaining length. */
  1833. packetSize = 1U + remainingLengthEncodedSize( remainingLength )
  1834. + remainingLength;
  1835. }
  1836. if( ( status == MQTTSuccess ) && ( packetSize > pFixedBuffer->size ) )
  1837. {
  1838. LogError( ( "Buffer size of %lu is not sufficient to hold "
  1839. "serialized PUBLISH packet of size of %lu.",
  1840. ( unsigned long ) pFixedBuffer->size,
  1841. ( unsigned long ) packetSize ) );
  1842. status = MQTTNoMemory;
  1843. }
  1844. if( status == MQTTSuccess )
  1845. {
  1846. /* Serialize publish with header and payload. */
  1847. serializePublishCommon( pPublishInfo,
  1848. remainingLength,
  1849. packetId,
  1850. pFixedBuffer,
  1851. true );
  1852. }
  1853. return status;
  1854. }
  1855. /*-----------------------------------------------------------*/
  1856. MQTTStatus_t MQTT_SerializePublishHeader( const MQTTPublishInfo_t * pPublishInfo,
  1857. uint16_t packetId,
  1858. size_t remainingLength,
  1859. const MQTTFixedBuffer_t * pFixedBuffer,
  1860. size_t * pHeaderSize )
  1861. {
  1862. MQTTStatus_t status = MQTTSuccess;
  1863. size_t packetSize = 0;
  1864. if( ( pFixedBuffer == NULL ) || ( pPublishInfo == NULL ) ||
  1865. ( pHeaderSize == NULL ) )
  1866. {
  1867. LogError( ( "Argument cannot be NULL: pFixedBuffer=%p, "
  1868. "pPublishInfo=%p, pHeaderSize=%p.",
  1869. ( void * ) pFixedBuffer,
  1870. ( void * ) pPublishInfo,
  1871. ( void * ) pHeaderSize ) );
  1872. status = MQTTBadParameter;
  1873. }
  1874. /* A buffer must be configured for serialization. */
  1875. else if( pFixedBuffer->pBuffer == NULL )
  1876. {
  1877. LogError( ( "Argument cannot be NULL: pFixedBuffer->pBuffer is NULL." ) );
  1878. status = MQTTBadParameter;
  1879. }
  1880. else if( ( pPublishInfo->pTopicName == NULL ) || ( pPublishInfo->topicNameLength == 0U ) )
  1881. {
  1882. LogError( ( "Invalid topic name for publish: pTopicName=%p, "
  1883. "topicNameLength=%hu.",
  1884. ( void * ) pPublishInfo->pTopicName,
  1885. ( unsigned short ) pPublishInfo->topicNameLength ) );
  1886. status = MQTTBadParameter;
  1887. }
  1888. else if( ( pPublishInfo->qos != MQTTQoS0 ) && ( packetId == 0U ) )
  1889. {
  1890. LogError( ( "Packet Id is 0 for publish with QoS=%hu.",
  1891. ( unsigned short ) pPublishInfo->qos ) );
  1892. status = MQTTBadParameter;
  1893. }
  1894. else if( ( pPublishInfo->dup == true ) && ( pPublishInfo->qos == MQTTQoS0 ) )
  1895. {
  1896. LogError( ( "Duplicate flag is set for PUBLISH with Qos 0." ) );
  1897. status = MQTTBadParameter;
  1898. }
  1899. else
  1900. {
  1901. /* Length of serialized packet = First byte
  1902. * + Length of encoded remaining length
  1903. * + Remaining length
  1904. * - Payload Length.
  1905. */
  1906. packetSize = 1U + remainingLengthEncodedSize( remainingLength )
  1907. + remainingLength
  1908. - pPublishInfo->payloadLength;
  1909. }
  1910. if( ( status == MQTTSuccess ) && ( packetSize > pFixedBuffer->size ) )
  1911. {
  1912. LogError( ( "Buffer size of %lu is not sufficient to hold "
  1913. "serialized PUBLISH header packet of size of %lu.",
  1914. ( unsigned long ) pFixedBuffer->size,
  1915. ( unsigned long ) ( packetSize - pPublishInfo->payloadLength ) ) );
  1916. status = MQTTNoMemory;
  1917. }
  1918. if( status == MQTTSuccess )
  1919. {
  1920. /* Serialize publish without copying the payload. */
  1921. serializePublishCommon( pPublishInfo,
  1922. remainingLength,
  1923. packetId,
  1924. pFixedBuffer,
  1925. false );
  1926. /* Header size is the same as calculated packet size. */
  1927. *pHeaderSize = packetSize;
  1928. }
  1929. return status;
  1930. }
  1931. /*-----------------------------------------------------------*/
  1932. MQTTStatus_t MQTT_SerializeAck( const MQTTFixedBuffer_t * pFixedBuffer,
  1933. uint8_t packetType,
  1934. uint16_t packetId )
  1935. {
  1936. MQTTStatus_t status = MQTTSuccess;
  1937. if( pFixedBuffer == NULL )
  1938. {
  1939. LogError( ( "Provided buffer is NULL." ) );
  1940. status = MQTTBadParameter;
  1941. }
  1942. else if( pFixedBuffer->pBuffer == NULL )
  1943. {
  1944. LogError( ( "pFixedBuffer->pBuffer cannot be NULL." ) );
  1945. status = MQTTBadParameter;
  1946. }
  1947. /* The buffer must be able to fit 4 bytes for the packet. */
  1948. else if( pFixedBuffer->size < MQTT_PUBLISH_ACK_PACKET_SIZE )
  1949. {
  1950. LogError( ( "Insufficient memory for packet." ) );
  1951. status = MQTTNoMemory;
  1952. }
  1953. else if( packetId == 0U )
  1954. {
  1955. LogError( ( "Packet ID cannot be 0." ) );
  1956. status = MQTTBadParameter;
  1957. }
  1958. else
  1959. {
  1960. switch( packetType )
  1961. {
  1962. /* Only publish acks are serialized by the client. */
  1963. case MQTT_PACKET_TYPE_PUBACK:
  1964. case MQTT_PACKET_TYPE_PUBREC:
  1965. case MQTT_PACKET_TYPE_PUBREL:
  1966. case MQTT_PACKET_TYPE_PUBCOMP:
  1967. pFixedBuffer->pBuffer[ 0 ] = packetType;
  1968. pFixedBuffer->pBuffer[ 1 ] = MQTT_PACKET_SIMPLE_ACK_REMAINING_LENGTH;
  1969. pFixedBuffer->pBuffer[ 2 ] = UINT16_HIGH_BYTE( packetId );
  1970. pFixedBuffer->pBuffer[ 3 ] = UINT16_LOW_BYTE( packetId );
  1971. break;
  1972. default:
  1973. LogError( ( "Packet type is not a publish ACK: Packet type=%02x",
  1974. ( unsigned int ) packetType ) );
  1975. status = MQTTBadParameter;
  1976. break;
  1977. }
  1978. }
  1979. return status;
  1980. }
  1981. /*-----------------------------------------------------------*/
  1982. MQTTStatus_t MQTT_GetDisconnectPacketSize( size_t * pPacketSize )
  1983. {
  1984. MQTTStatus_t status = MQTTSuccess;
  1985. if( pPacketSize == NULL )
  1986. {
  1987. LogError( ( "pPacketSize is NULL." ) );
  1988. status = MQTTBadParameter;
  1989. }
  1990. else
  1991. {
  1992. /* MQTT DISCONNECT packets always have the same size. */
  1993. *pPacketSize = MQTT_DISCONNECT_PACKET_SIZE;
  1994. }
  1995. return status;
  1996. }
  1997. /*-----------------------------------------------------------*/
  1998. MQTTStatus_t MQTT_SerializeDisconnect( const MQTTFixedBuffer_t * pFixedBuffer )
  1999. {
  2000. MQTTStatus_t status = MQTTSuccess;
  2001. /* Validate arguments. */
  2002. if( pFixedBuffer == NULL )
  2003. {
  2004. LogError( ( "pFixedBuffer cannot be NULL." ) );
  2005. status = MQTTBadParameter;
  2006. }
  2007. else if( pFixedBuffer->pBuffer == NULL )
  2008. {
  2009. LogError( ( "pFixedBuffer->pBuffer cannot be NULL." ) );
  2010. status = MQTTBadParameter;
  2011. }
  2012. else
  2013. {
  2014. /* Empty else MISRA 15.7 */
  2015. }
  2016. if( status == MQTTSuccess )
  2017. {
  2018. if( pFixedBuffer->size < MQTT_DISCONNECT_PACKET_SIZE )
  2019. {
  2020. LogError( ( "Buffer size of %lu is not sufficient to hold "
  2021. "serialized DISCONNECT packet of size of %lu.",
  2022. ( unsigned long ) pFixedBuffer->size,
  2023. MQTT_DISCONNECT_PACKET_SIZE ) );
  2024. status = MQTTNoMemory;
  2025. }
  2026. }
  2027. if( status == MQTTSuccess )
  2028. {
  2029. pFixedBuffer->pBuffer[ 0 ] = MQTT_PACKET_TYPE_DISCONNECT;
  2030. pFixedBuffer->pBuffer[ 1 ] = MQTT_DISCONNECT_REMAINING_LENGTH;
  2031. }
  2032. return status;
  2033. }
  2034. /*-----------------------------------------------------------*/
  2035. MQTTStatus_t MQTT_GetPingreqPacketSize( size_t * pPacketSize )
  2036. {
  2037. MQTTStatus_t status = MQTTSuccess;
  2038. if( pPacketSize == NULL )
  2039. {
  2040. LogError( ( "pPacketSize is NULL." ) );
  2041. status = MQTTBadParameter;
  2042. }
  2043. else
  2044. {
  2045. /* MQTT PINGREQ packets always have the same size. */
  2046. *pPacketSize = MQTT_PACKET_PINGREQ_SIZE;
  2047. }
  2048. return status;
  2049. }
  2050. /*-----------------------------------------------------------*/
  2051. MQTTStatus_t MQTT_SerializePingreq( const MQTTFixedBuffer_t * pFixedBuffer )
  2052. {
  2053. MQTTStatus_t status = MQTTSuccess;
  2054. if( pFixedBuffer == NULL )
  2055. {
  2056. LogError( ( "pFixedBuffer is NULL." ) );
  2057. status = MQTTBadParameter;
  2058. }
  2059. else if( pFixedBuffer->pBuffer == NULL )
  2060. {
  2061. LogError( ( "pFixedBuffer->pBuffer cannot be NULL." ) );
  2062. status = MQTTBadParameter;
  2063. }
  2064. else
  2065. {
  2066. /* Empty else MISRA 15.7 */
  2067. }
  2068. if( status == MQTTSuccess )
  2069. {
  2070. if( pFixedBuffer->size < MQTT_PACKET_PINGREQ_SIZE )
  2071. {
  2072. LogError( ( "Buffer size of %lu is not sufficient to hold "
  2073. "serialized PINGREQ packet of size of %lu.",
  2074. ( unsigned long ) pFixedBuffer->size,
  2075. MQTT_PACKET_PINGREQ_SIZE ) );
  2076. status = MQTTNoMemory;
  2077. }
  2078. }
  2079. if( status == MQTTSuccess )
  2080. {
  2081. /* Ping request packets are always the same. */
  2082. pFixedBuffer->pBuffer[ 0 ] = MQTT_PACKET_TYPE_PINGREQ;
  2083. pFixedBuffer->pBuffer[ 1 ] = 0x00;
  2084. }
  2085. return status;
  2086. }
  2087. /*-----------------------------------------------------------*/
  2088. MQTTStatus_t MQTT_DeserializePublish( const MQTTPacketInfo_t * pIncomingPacket,
  2089. uint16_t * pPacketId,
  2090. MQTTPublishInfo_t * pPublishInfo )
  2091. {
  2092. MQTTStatus_t status = MQTTSuccess;
  2093. if( ( pIncomingPacket == NULL ) || ( pPacketId == NULL ) || ( pPublishInfo == NULL ) )
  2094. {
  2095. LogError( ( "Argument cannot be NULL: pIncomingPacket=%p, "
  2096. "pPacketId=%p, pPublishInfo=%p",
  2097. ( void * ) pIncomingPacket,
  2098. ( void * ) pPacketId,
  2099. ( void * ) pPublishInfo ) );
  2100. status = MQTTBadParameter;
  2101. }
  2102. else if( ( pIncomingPacket->type & 0xF0U ) != MQTT_PACKET_TYPE_PUBLISH )
  2103. {
  2104. LogError( ( "Packet is not publish. Packet type: %02x.",
  2105. ( unsigned int ) pIncomingPacket->type ) );
  2106. status = MQTTBadParameter;
  2107. }
  2108. else if( pIncomingPacket->pRemainingData == NULL )
  2109. {
  2110. LogError( ( "Argument cannot be NULL: "
  2111. "pIncomingPacket->pRemainingData is NULL." ) );
  2112. status = MQTTBadParameter;
  2113. }
  2114. else
  2115. {
  2116. status = deserializePublish( pIncomingPacket, pPacketId, pPublishInfo );
  2117. }
  2118. return status;
  2119. }
  2120. /*-----------------------------------------------------------*/
  2121. MQTTStatus_t MQTT_DeserializeAck( const MQTTPacketInfo_t * pIncomingPacket,
  2122. uint16_t * pPacketId,
  2123. bool * pSessionPresent )
  2124. {
  2125. MQTTStatus_t status = MQTTSuccess;
  2126. if( pIncomingPacket == NULL )
  2127. {
  2128. LogError( ( "pIncomingPacket cannot be NULL." ) );
  2129. status = MQTTBadParameter;
  2130. }
  2131. /* Pointer for packet identifier cannot be NULL for packets other than
  2132. * CONNACK and PINGRESP. */
  2133. else if( ( pPacketId == NULL ) &&
  2134. ( ( pIncomingPacket->type != MQTT_PACKET_TYPE_CONNACK ) &&
  2135. ( pIncomingPacket->type != MQTT_PACKET_TYPE_PINGRESP ) ) )
  2136. {
  2137. LogError( ( "pPacketId cannot be NULL for packet type %02x.",
  2138. ( unsigned int ) pIncomingPacket->type ) );
  2139. status = MQTTBadParameter;
  2140. }
  2141. /* Pointer for session present cannot be NULL for CONNACK. */
  2142. else if( ( pSessionPresent == NULL ) &&
  2143. ( pIncomingPacket->type == MQTT_PACKET_TYPE_CONNACK ) )
  2144. {
  2145. LogError( ( "pSessionPresent cannot be NULL for CONNACK packet." ) );
  2146. status = MQTTBadParameter;
  2147. }
  2148. /* Pointer for remaining data cannot be NULL for packets other
  2149. * than PINGRESP. */
  2150. else if( ( pIncomingPacket->pRemainingData == NULL ) &&
  2151. ( pIncomingPacket->type != MQTT_PACKET_TYPE_PINGRESP ) )
  2152. {
  2153. LogError( ( "Remaining data of incoming packet is NULL." ) );
  2154. status = MQTTBadParameter;
  2155. }
  2156. else
  2157. {
  2158. /* Make sure response packet is a valid ack. */
  2159. switch( pIncomingPacket->type )
  2160. {
  2161. case MQTT_PACKET_TYPE_CONNACK:
  2162. status = deserializeConnack( pIncomingPacket, pSessionPresent );
  2163. break;
  2164. case MQTT_PACKET_TYPE_SUBACK:
  2165. status = deserializeSuback( pIncomingPacket, pPacketId );
  2166. break;
  2167. case MQTT_PACKET_TYPE_PINGRESP:
  2168. status = deserializePingresp( pIncomingPacket );
  2169. break;
  2170. case MQTT_PACKET_TYPE_UNSUBACK:
  2171. case MQTT_PACKET_TYPE_PUBACK:
  2172. case MQTT_PACKET_TYPE_PUBREC:
  2173. case MQTT_PACKET_TYPE_PUBREL:
  2174. case MQTT_PACKET_TYPE_PUBCOMP:
  2175. status = deserializeSimpleAck( pIncomingPacket, pPacketId );
  2176. break;
  2177. /* Any other packet type is invalid. */
  2178. default:
  2179. LogError( ( "IotMqtt_DeserializeResponse() called with unknown packet type:(%02x).",
  2180. ( unsigned int ) pIncomingPacket->type ) );
  2181. status = MQTTBadResponse;
  2182. break;
  2183. }
  2184. }
  2185. return status;
  2186. }
  2187. /*-----------------------------------------------------------*/
  2188. MQTTStatus_t MQTT_GetIncomingPacketTypeAndLength( TransportRecv_t readFunc,
  2189. NetworkContext_t * pNetworkContext,
  2190. MQTTPacketInfo_t * pIncomingPacket )
  2191. {
  2192. MQTTStatus_t status = MQTTSuccess;
  2193. int32_t bytesReceived = 0;
  2194. if( pIncomingPacket == NULL )
  2195. {
  2196. LogError( ( "Invalid parameter: pIncomingPacket is NULL." ) );
  2197. status = MQTTBadParameter;
  2198. }
  2199. else
  2200. {
  2201. /* Read a single byte. */
  2202. bytesReceived = readFunc( pNetworkContext,
  2203. &( pIncomingPacket->type ),
  2204. 1U );
  2205. }
  2206. if( bytesReceived == 1 )
  2207. {
  2208. /* Check validity. */
  2209. if( incomingPacketValid( pIncomingPacket->type ) == true )
  2210. {
  2211. pIncomingPacket->remainingLength = getRemainingLength( readFunc,
  2212. pNetworkContext );
  2213. if( pIncomingPacket->remainingLength == MQTT_REMAINING_LENGTH_INVALID )
  2214. {
  2215. LogError( ( "Incoming packet remaining length invalid." ) );
  2216. status = MQTTBadResponse;
  2217. }
  2218. }
  2219. else
  2220. {
  2221. LogError( ( "Incoming packet invalid: Packet type=%u.",
  2222. ( unsigned int ) pIncomingPacket->type ) );
  2223. status = MQTTBadResponse;
  2224. }
  2225. }
  2226. else if( ( status != MQTTBadParameter ) && ( bytesReceived == 0 ) )
  2227. {
  2228. status = MQTTNoDataAvailable;
  2229. }
  2230. /* If the input packet was valid, then any other number of bytes received is
  2231. * a failure. */
  2232. else if( status != MQTTBadParameter )
  2233. {
  2234. LogError( ( "A single byte was not read from the transport: "
  2235. "transportStatus=%ld.",
  2236. ( long int ) bytesReceived ) );
  2237. status = MQTTRecvFailed;
  2238. }
  2239. else
  2240. {
  2241. /* Empty else MISRA 15.7 */
  2242. }
  2243. return status;
  2244. }
  2245. /*-----------------------------------------------------------*/
  2246. MQTTStatus_t MQTT_UpdateDuplicatePublishFlag( uint8_t * pHeader,
  2247. bool set )
  2248. {
  2249. MQTTStatus_t status = MQTTSuccess;
  2250. if( pHeader == NULL )
  2251. {
  2252. LogError( ( "Header cannot be NULL" ) );
  2253. status = MQTTBadParameter;
  2254. }
  2255. else if( ( ( *pHeader ) & 0xF0U ) != MQTT_PACKET_TYPE_PUBLISH )
  2256. {
  2257. LogError( ( "Header is not publish packet header" ) );
  2258. status = MQTTBadParameter;
  2259. }
  2260. else if( set == true )
  2261. {
  2262. UINT8_SET_BIT( *pHeader, MQTT_PUBLISH_FLAG_DUP );
  2263. }
  2264. else
  2265. {
  2266. UINT8_CLEAR_BIT( *pHeader, MQTT_PUBLISH_FLAG_DUP );
  2267. }
  2268. return status;
  2269. }
  2270. /*-----------------------------------------------------------*/
  2271. MQTTStatus_t MQTT_ProcessIncomingPacketTypeAndLength( const uint8_t * pBuffer,
  2272. const size_t * pIndex,
  2273. MQTTPacketInfo_t * pIncomingPacket )
  2274. {
  2275. MQTTStatus_t status = MQTTSuccess;
  2276. if( pIncomingPacket == NULL )
  2277. {
  2278. LogError( ( "Invalid parameter: pIncomingPacket is NULL." ) );
  2279. status = MQTTBadParameter;
  2280. }
  2281. else if( pIndex == NULL )
  2282. {
  2283. LogError( ( "Invalid parameter: pIndex is NULL." ) );
  2284. status = MQTTBadParameter;
  2285. }
  2286. else if( pBuffer == NULL )
  2287. {
  2288. LogError( ( "Invalid parameter: pBuffer is NULL." ) );
  2289. status = MQTTBadParameter;
  2290. }
  2291. /* There should be at least one byte in the buffer */
  2292. else if( *pIndex < 1U )
  2293. {
  2294. /* No data is available. There are 0 bytes received from the network
  2295. * receive function. */
  2296. status = MQTTNoDataAvailable;
  2297. }
  2298. else
  2299. {
  2300. /* At least one byte is present which should be deciphered. */
  2301. pIncomingPacket->type = pBuffer[ 0 ];
  2302. }
  2303. if( status == MQTTSuccess )
  2304. {
  2305. /* Check validity. */
  2306. if( incomingPacketValid( pIncomingPacket->type ) == true )
  2307. {
  2308. status = processRemainingLength( pBuffer,
  2309. pIndex,
  2310. pIncomingPacket );
  2311. }
  2312. else
  2313. {
  2314. LogError( ( "Incoming packet invalid: Packet type=%u.",
  2315. ( unsigned int ) pIncomingPacket->type ) );
  2316. status = MQTTBadResponse;
  2317. }
  2318. }
  2319. return status;
  2320. }
  2321. /*-----------------------------------------------------------*/