]> git.sur5r.net Git - freertos/blob - FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries/c_sdk/standard/mqtt/src/iot_ble_mqtt_serialize.c
Correct an err in queue.c introduced when previously updating behaviour when queue...
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-IoT-Libraries / c_sdk / standard / mqtt / src / iot_ble_mqtt_serialize.c
1 /*\r
2  * Amazon FreeRTOS MQTT V2.0.0\r
3  * Copyright (C) 2018 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software.\r
14  *\r
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
21  *\r
22  * http://aws.amazon.com/freertos\r
23  * http://www.FreeRTOS.org\r
24  */\r
25 \r
26 /**\r
27  * @file aws_mqtt_lib_ble.c\r
28  * @brief MQTT library for BLE.\r
29  */\r
30 /* The config header is always included first. */\r
31 #include "iot_config.h"\r
32 \r
33 /* Standard includes. */\r
34 #include <string.h>\r
35 #include <stdio.h>\r
36 \r
37 /* FreeRTOS includes. */\r
38 #include "FreeRTOS.h"\r
39 \r
40 #include "iot_ble_config.h"\r
41 \r
42 \r
43 /* MQTT internal includes. */\r
44 #include "platform/iot_threads.h"\r
45 #include "iot_serializer.h"\r
46 #include "platform/iot_network_ble.h"\r
47 #include "iot_ble_data_transfer.h"\r
48 #include "iot_ble_mqtt_serialize.h"\r
49 #include "private/iot_mqtt_internal.h"\r
50 \r
51 #define _INVALID_MQTT_PACKET_TYPE        ( 0xF0 )\r
52 \r
53 \r
54 #define _IS_VALID_SERIALIZER_RET( ret, pSerializerBuf )                                \\r
55     (  ( ret == IOT_SERIALIZER_SUCCESS ) ||                                        \\r
56           (  ( !pSerializerBuf ) && ( ret == IOT_SERIALIZER_BUFFER_TOO_SMALL ) ) )\r
57 \r
58 #define _NUM_CONNECT_PARMAS                   ( 4 )\r
59 #define _NUM_DEFAULT_PUBLISH_PARMAS           ( 4 )\r
60 #define _NUM_PUBACK_PARMAS                    ( 2 )\r
61 #define _NUM_SUBACK_PARAMS                    ( 4 )\r
62 #define _NUM_UNSUBACK_PARAMS                  ( 3 )\r
63 #define _NUM_DISCONNECT_PARAMS                ( 1 )\r
64 #define _NUM_PINGREQUEST_PARAMS               ( 1 )\r
65 \r
66 const IotMqttSerializer_t IotBleMqttSerializer = {\r
67     .serialize.connect       = IotBleMqtt_SerializeConnect,\r
68     .serialize.publish       = IotBleMqtt_SerializePublish,\r
69     .serialize.publishSetDup = IotBleMqtt_PublishSetDup,\r
70     .serialize.puback        = IotBleMqtt_SerializePuback,\r
71     .serialize.subscribe     = IotBleMqtt_SerializeSubscribe,\r
72     .serialize.unsubscribe   = IotBleMqtt_SerializeUnsubscribe,\r
73     .serialize.pingreq       = IotBleMqtt_SerializePingreq,\r
74     .serialize.disconnect    = IotBleMqtt_SerializeDisconnect,\r
75     .freePacket              = IotBleMqtt_FreePacket,\r
76     .getPacketType           = IotBleMqtt_GetPacketType,\r
77     .getRemainingLength      = IotBleMqtt_GetRemainingLength,\r
78     .deserialize.connack     = IotBleMqtt_DeserializeConnack,\r
79     .deserialize.publish     = IotBleMqtt_DeserializePublish,\r
80     .deserialize.puback      = IotBleMqtt_DeserializePuback,\r
81     .deserialize.suback      = IotBleMqtt_DeserializeSuback,\r
82     .deserialize.unsuback    = IotBleMqtt_DeserializeUnsuback,\r
83     .deserialize.pingresp    = IotBleMqtt_DeserializePingresp\r
84 };\r
85 \r
86 /**\r
87  * @brief Guards access to the packet identifier counter.\r
88  *\r
89  * Each packet should have a unique packet identifier. This mutex ensures that only\r
90  * one thread at a time may read the global packet identifer.\r
91  */\r
92 \r
93 \r
94 /**\r
95  * @brief Generates a monotonically increasing identifier used in  MQTT message\r
96  *\r
97  * @return Identifier for the MQTT message\r
98  */\r
99 static uint16_t _nextPacketIdentifier( void );\r
100 \r
101 \r
102 static inline uint16_t _getNumPublishParams( const IotMqttPublishInfo_t * const pPublish )\r
103 {\r
104    return ( pPublish->qos > 0 ) ?  ( _NUM_DEFAULT_PUBLISH_PARMAS + 1 ) : _NUM_DEFAULT_PUBLISH_PARMAS;\r
105 }\r
106 \r
107 static IotSerializerError_t _serializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
108                                        uint8_t* const pBuffer,\r
109                                        size_t* const pSize );\r
110 static IotSerializerError_t _serializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
111                                                   uint8_t * pBuffer,\r
112                                                   size_t  * pSize,\r
113                                                   uint16_t packetIdentifier );\r
114 static IotSerializerError_t _serializePubAck( uint16_t packetIdentifier,\r
115                                       uint8_t * pBuffer,\r
116                                       size_t  * pSize );\r
117 \r
118 \r
119 \r
120 static IotSerializerError_t _serializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
121                                                size_t subscriptionCount,\r
122                                                uint8_t * const pBuffer,\r
123                                                size_t * const pSize,\r
124                                                uint16_t packetIdentifier );\r
125 \r
126 static IotSerializerError_t _serializeUnSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
127                                                size_t subscriptionCount,\r
128                                                uint8_t * const pBuffer,\r
129                                                size_t * const pSize,\r
130                                                uint16_t packetIdentifier );\r
131 \r
132 static IotSerializerError_t _serializeDisconnect( uint8_t * const pBuffer,\r
133                                                 size_t * const pSize );\r
134 \r
135 \r
136 static IotSerializerError_t _serializePingRequest( uint8_t * const pBuffer,\r
137                                                 size_t * const pSize );\r
138 \r
139 #if LIBRARY_LOG_LEVEL > AWS_IOT_LOG_NONE\r
140 \r
141 /**\r
142  * @brief If logging is enabled, define a log configuration that only prints the log\r
143  * string. This is used when printing out details of deserialized MQTT packets.\r
144  */\r
145 static const IotLogConfig_t _logHideAll =\r
146 {\r
147     .hideLibraryName = true,\r
148     .hideLogLevel    = true,\r
149     .hideTimestring  = true\r
150 };\r
151 #endif\r
152 \r
153 \r
154 static IotMutex_t _packetIdentifierMutex;\r
155 \r
156 \r
157 /* Declaration of snprintf. The header stdio.h is not included because it\r
158  * includes conflicting symbols on some platforms. */\r
159 extern int snprintf( char * s,\r
160                      size_t n,\r
161                      const char * format,\r
162                      ... );\r
163 \r
164 /*-----------------------------------------------------------*/\r
165 \r
166 static uint16_t _nextPacketIdentifier( void )\r
167 {\r
168     static uint16_t nextPacketIdentifier = 1;\r
169     uint16_t newPacketIdentifier = 0;\r
170 \r
171     /* Lock the packet identifier mutex so that only one thread may read and\r
172          * modify nextPacketIdentifier. */\r
173      IotMutex_Lock( &_packetIdentifierMutex );\r
174 \r
175     /* Read the next packet identifier. */\r
176     newPacketIdentifier = nextPacketIdentifier;\r
177 \r
178     /* The next packet identifier will be greater by 2. This prevents packet\r
179      * identifiers from ever being 0, which is not allowed by MQTT 3.1.1. Packet\r
180      * identifiers will follow the sequence 1,3,5...65535,1,3,5... */\r
181     nextPacketIdentifier = ( uint16_t ) ( nextPacketIdentifier + ( ( uint16_t ) 2 ) );\r
182 \r
183     /* Unlock the packet identifier mutex. */\r
184     IotMutex_Unlock( &_packetIdentifierMutex );\r
185 \r
186     return newPacketIdentifier;\r
187 }\r
188 \r
189 static IotSerializerError_t _serializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
190                                        uint8_t* const pBuffer,\r
191                                        size_t* const pSize )\r
192 {\r
193     IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
194     IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
195     IotSerializerEncoderObject_t connectMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
196     IotSerializerScalarData_t data = { 0 };\r
197 \r
198     error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
199     if( error == IOT_SERIALIZER_SUCCESS )\r
200     {\r
201 \r
202         error = IOT_BLE_MESG_ENCODER.openContainer(\r
203                 &encoderObj,\r
204                 &connectMap,\r
205                 _NUM_CONNECT_PARMAS );\r
206     }\r
207 \r
208     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
209     {\r
210         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
211         data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_CONNECT;\r
212         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
213     }\r
214 \r
215     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
216     {\r
217         data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
218         data.value.u.string.pString = ( uint8_t * ) pConnectInfo->pClientIdentifier;\r
219         data.value.u.string.length = pConnectInfo->clientIdentifierLength;\r
220         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_CLIENT_ID, data );\r
221     }\r
222     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
223     {\r
224         data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
225         data.value.u.string.pString = ( uint8_t * ) clientcredentialMQTT_BROKER_ENDPOINT;\r
226         data.value.u.string.length = strlen( clientcredentialMQTT_BROKER_ENDPOINT );\r
227         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_BROKER_EP, data );\r
228     }\r
229     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
230     {\r
231         data.type = IOT_SERIALIZER_SCALAR_BOOL;\r
232         data.value.u.booleanValue = pConnectInfo->cleanSession;\r
233         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &connectMap, IOT_BLE_MQTT_CLEAN_SESSION, data );\r
234     }\r
235     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
236     {\r
237         error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &connectMap );\r
238     }\r
239 \r
240     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
241     {\r
242         if( pBuffer == NULL )\r
243         {\r
244             *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
245         }\r
246         else\r
247         {\r
248             *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
249         }\r
250 \r
251         IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
252         error = IOT_SERIALIZER_SUCCESS;\r
253 \r
254     }\r
255 \r
256     return error;\r
257 }\r
258 \r
259 static IotSerializerError_t _serializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
260                                                   uint8_t * pBuffer,\r
261                                                   size_t  * pSize,\r
262                                                   uint16_t packetIdentifier )\r
263 {\r
264     IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
265     IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
266     IotSerializerEncoderObject_t publishMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
267     IotSerializerScalarData_t data = { 0 };\r
268     uint16_t numPublishParams = _getNumPublishParams( pPublishInfo );\r
269 \r
270     error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
271 \r
272     if( error == IOT_SERIALIZER_SUCCESS )\r
273     {\r
274 \r
275 \r
276         error = IOT_BLE_MESG_ENCODER.openContainer(\r
277                 &encoderObj,\r
278                 &publishMap,\r
279                 numPublishParams );\r
280     }\r
281 \r
282 \r
283     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
284     {\r
285         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
286         data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PUBLISH;\r
287         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
288     }\r
289 \r
290     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
291     {\r
292         data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
293         data.value.u.string.pString = ( uint8_t * ) pPublishInfo->pTopicName;\r
294         data.value.u.string.length = pPublishInfo->topicNameLength;\r
295         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_TOPIC, data );\r
296     }\r
297 \r
298     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
299     {\r
300 \r
301         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
302         data.value.u.signedInt = pPublishInfo->qos;\r
303         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_QOS, data );\r
304     }\r
305 \r
306     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
307     {\r
308         data.type = IOT_SERIALIZER_SCALAR_BYTE_STRING;\r
309         data.value.u.string.pString = ( uint8_t * ) pPublishInfo->pPayload;\r
310         data.value.u.string.length = pPublishInfo->payloadLength;\r
311         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_PAYLOAD, data );\r
312     }\r
313 \r
314 \r
315     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
316     {\r
317         if( pPublishInfo->qos != 0 )\r
318         {\r
319             data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
320             data.value.u.signedInt = packetIdentifier;\r
321             error = IOT_BLE_MESG_ENCODER.appendKeyValue( &publishMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
322 \r
323         }\r
324     }\r
325 \r
326     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
327     {\r
328 \r
329         error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &publishMap );\r
330     }\r
331 \r
332     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
333     {\r
334         if( pBuffer == NULL )\r
335         {\r
336             *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
337 \r
338         }\r
339         else\r
340         {\r
341             *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
342         }\r
343         IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
344         error = IOT_SERIALIZER_SUCCESS;\r
345     }\r
346 \r
347 \r
348     return error;\r
349 }\r
350 \r
351 static IotSerializerError_t _serializePubAck( uint16_t packetIdentifier,\r
352                                       uint8_t * pBuffer,\r
353                                       size_t  * pSize )\r
354 \r
355 {\r
356     IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
357     IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
358     IotSerializerEncoderObject_t pubAckMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
359     IotSerializerScalarData_t data = { 0 };\r
360 \r
361     error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
362 \r
363     if( error == IOT_SERIALIZER_SUCCESS )\r
364     {\r
365 \r
366         error = IOT_BLE_MESG_ENCODER.openContainer(\r
367                 &encoderObj,\r
368                 &pubAckMap,\r
369                 _NUM_PUBACK_PARMAS );\r
370     }\r
371 \r
372     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
373     {\r
374         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
375         data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PUBACK;\r
376         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pubAckMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
377     }\r
378 \r
379     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
380     {\r
381         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
382         data.value.u.signedInt = packetIdentifier;\r
383         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pubAckMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
384     }\r
385     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
386     {\r
387         error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &pubAckMap );\r
388     }\r
389 \r
390     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
391     {\r
392         if( pBuffer == NULL )\r
393         {\r
394             *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
395         }\r
396         else\r
397         {\r
398             *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
399         }\r
400         IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
401         error = IOT_SERIALIZER_SUCCESS;\r
402     }\r
403 \r
404     return error;\r
405 }\r
406 \r
407 \r
408 static IotSerializerError_t _serializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
409                                                size_t subscriptionCount,\r
410                                                uint8_t * const pBuffer,\r
411                                                size_t * const pSize,\r
412                                                uint16_t packetIdentifier )\r
413 {\r
414     IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
415     IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM ;\r
416     IotSerializerEncoderObject_t subscribeMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
417     IotSerializerEncoderObject_t subscriptionArray = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_ARRAY;\r
418     IotSerializerScalarData_t data = { 0 };\r
419     uint16_t idx;\r
420 \r
421     error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
422 \r
423     if( error == IOT_SERIALIZER_SUCCESS )\r
424     {\r
425         error = IOT_BLE_MESG_ENCODER.openContainer(\r
426                 &encoderObj,\r
427                 &subscribeMap,\r
428                 _NUM_SUBACK_PARAMS );\r
429     }\r
430 \r
431     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
432     {\r
433         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
434         data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_SUBSCRIBE;\r
435         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
436     }\r
437 \r
438     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
439     {\r
440 \r
441         error = IOT_BLE_MESG_ENCODER.openContainerWithKey(\r
442                 &subscribeMap,\r
443                 IOT_BLE_MQTT_TOPIC_LIST,\r
444                 &subscriptionArray,\r
445                 subscriptionCount );\r
446     }\r
447 \r
448     for( idx = 0; idx < subscriptionCount; idx++ )\r
449     {\r
450         if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
451         {\r
452             data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
453             data.value.u.string.pString = ( uint8_t * ) pSubscriptionList[ idx ].pTopicFilter;\r
454             data.value.u.string.length = pSubscriptionList[ idx ].topicFilterLength;\r
455             error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
456         }\r
457         else\r
458         {\r
459             break;\r
460         }\r
461     }\r
462 \r
463     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
464     {\r
465         error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
466     }\r
467 \r
468     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
469     {\r
470 \r
471         error = IOT_BLE_MESG_ENCODER.openContainerWithKey(\r
472                 &subscribeMap,\r
473                 IOT_BLE_MQTT_QOS_LIST,\r
474                 &subscriptionArray,\r
475                 subscriptionCount );\r
476     }\r
477 \r
478 \r
479     for( idx = 0; idx < subscriptionCount; idx++ )\r
480     {\r
481         if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
482         {\r
483 \r
484             data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
485             data.value.u.signedInt = pSubscriptionList[ idx ].qos;\r
486             error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
487         }\r
488         else\r
489         {\r
490             break;\r
491         }\r
492     }\r
493 \r
494     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
495     {\r
496         error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
497     }\r
498 \r
499     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
500     {\r
501 \r
502         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
503         data.value.u.signedInt = packetIdentifier;\r
504         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
505     }\r
506 \r
507     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
508     {\r
509         error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &subscribeMap );\r
510     }\r
511 \r
512     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
513     {\r
514         if( pBuffer == NULL )\r
515         {\r
516             *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
517         }\r
518         else\r
519         {\r
520             *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
521         }\r
522 \r
523         IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
524         error = IOT_SERIALIZER_SUCCESS;\r
525     }\r
526     return error;\r
527 }\r
528 \r
529 static IotSerializerError_t _serializeUnSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
530                                                size_t subscriptionCount,\r
531                                                uint8_t * const pBuffer,\r
532                                                size_t * const pSize,\r
533                                                uint16_t packetIdentifier )\r
534 {\r
535     IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
536     IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
537     IotSerializerEncoderObject_t subscribeMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
538     IotSerializerEncoderObject_t subscriptionArray = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_ARRAY;\r
539     IotSerializerScalarData_t data = { 0 };\r
540     uint16_t idx;\r
541 \r
542     error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
543 \r
544     if( error == IOT_SERIALIZER_SUCCESS )\r
545     {\r
546 \r
547         error = IOT_BLE_MESG_ENCODER.openContainer(\r
548                 &encoderObj,\r
549                 &subscribeMap,\r
550                 _NUM_UNSUBACK_PARAMS );\r
551     }\r
552 \r
553 \r
554     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
555     {\r
556         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
557         data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_UNSUBSCRIBE;\r
558         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
559     }\r
560 \r
561     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
562     {\r
563         error = IOT_BLE_MESG_ENCODER.openContainerWithKey (\r
564                 &subscribeMap,\r
565                 IOT_BLE_MQTT_TOPIC_LIST,\r
566                 &subscriptionArray,\r
567                 subscriptionCount );\r
568     }\r
569 \r
570     for( idx = 0; idx < subscriptionCount; idx++ )\r
571     {\r
572         if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
573         {\r
574             data.type = IOT_SERIALIZER_SCALAR_TEXT_STRING;\r
575             data.value.u.string.pString = ( uint8_t * ) pSubscriptionList[ idx ].pTopicFilter;\r
576             data.value.u.string.length = pSubscriptionList[ idx ].topicFilterLength;\r
577             error = IOT_BLE_MESG_ENCODER.append( &subscriptionArray, data );\r
578         }\r
579         else\r
580         {\r
581             break;\r
582         }\r
583     }\r
584 \r
585     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
586     {\r
587         error = IOT_BLE_MESG_ENCODER.closeContainer( &subscribeMap, &subscriptionArray );\r
588     }\r
589 \r
590     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
591     {\r
592         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
593         data.value.u.signedInt = packetIdentifier;\r
594         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &subscribeMap, IOT_BLE_MQTT_MESSAGE_ID, data );\r
595     }\r
596 \r
597     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
598     {\r
599         error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &subscribeMap );\r
600     }\r
601 \r
602     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
603     {\r
604         if( pBuffer == NULL )\r
605         {\r
606             *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
607 \r
608         }\r
609         else\r
610         {\r
611             *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
612         }\r
613         IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
614         error = IOT_SERIALIZER_SUCCESS;\r
615     }\r
616 \r
617     return error;\r
618 }\r
619 \r
620 static IotSerializerError_t _serializeDisconnect( uint8_t * const pBuffer,\r
621                                                 size_t * const pSize )\r
622 {\r
623     IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
624     IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
625     IotSerializerEncoderObject_t disconnectMap = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
626     IotSerializerScalarData_t data = { 0 };\r
627 \r
628     error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
629 \r
630     if( error == IOT_SERIALIZER_SUCCESS )\r
631     {\r
632         error = IOT_BLE_MESG_ENCODER.openContainer(\r
633                 &encoderObj,\r
634                 &disconnectMap,\r
635                 _NUM_DISCONNECT_PARAMS );\r
636     }\r
637 \r
638     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
639     {\r
640         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
641         data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_DISCONNECT;\r
642         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &disconnectMap, IOT_BLE_MQTT_MSG_TYPE, data );\r
643     }\r
644 \r
645     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
646     {\r
647         error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &disconnectMap );\r
648     }\r
649 \r
650     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
651     {\r
652         if( pBuffer == NULL )\r
653         {\r
654             *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
655         }\r
656         else\r
657         {\r
658             *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
659         }\r
660         IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
661         error = IOT_SERIALIZER_SUCCESS;\r
662     }\r
663 \r
664     return error;\r
665 }\r
666 \r
667 static IotSerializerError_t _serializePingRequest( uint8_t * const pBuffer,\r
668                                                    size_t * const pSize )\r
669 {\r
670     IotSerializerError_t error = IOT_SERIALIZER_SUCCESS;\r
671     IotSerializerEncoderObject_t encoderObj = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_STREAM;\r
672     IotSerializerEncoderObject_t pingRequest = IOT_SERIALIZER_ENCODER_CONTAINER_INITIALIZER_MAP;\r
673     IotSerializerScalarData_t data = { 0 };\r
674 \r
675     error = IOT_BLE_MESG_ENCODER.init( &encoderObj, pBuffer, *pSize );\r
676 \r
677     if( error == IOT_SERIALIZER_SUCCESS )\r
678     {\r
679         error = IOT_BLE_MESG_ENCODER.openContainer(\r
680                 &encoderObj,\r
681                 &pingRequest,\r
682                 _NUM_PINGREQUEST_PARAMS );\r
683     }\r
684 \r
685     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
686     {\r
687         data.type = IOT_SERIALIZER_SCALAR_SIGNED_INT;\r
688          data.value.u.signedInt = IOT_BLE_MQTT_MSG_TYPE_PINGREQ;\r
689         error = IOT_BLE_MESG_ENCODER.appendKeyValue( &pingRequest, IOT_BLE_MQTT_MSG_TYPE, data );\r
690     }\r
691 \r
692     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
693     {\r
694         error = IOT_BLE_MESG_ENCODER.closeContainer( &encoderObj, &pingRequest );\r
695     }\r
696 \r
697     if( _IS_VALID_SERIALIZER_RET( error, pBuffer ) )\r
698     {\r
699         if( pBuffer == NULL )\r
700         {\r
701             *pSize = IOT_BLE_MESG_ENCODER.getExtraBufferSizeNeeded( &encoderObj );\r
702         }\r
703         else\r
704         {\r
705             *pSize = IOT_BLE_MESG_ENCODER.getEncodedSize( &encoderObj, pBuffer );\r
706         }\r
707         IOT_BLE_MESG_ENCODER.destroy( &encoderObj );\r
708         error = IOT_SERIALIZER_SUCCESS;\r
709     }\r
710 \r
711     return error;\r
712 }\r
713 \r
714 \r
715 bool IotBleMqtt_InitSerialize( void )\r
716 {\r
717         /* Create the packet identifier mutex. */\r
718         return IotMutex_Create( &_packetIdentifierMutex, false );\r
719 }\r
720 \r
721 void IotBleMqtt_CleanupSerialize( void )\r
722 {\r
723         /* Destroy the packet identifier mutex */\r
724         IotMutex_Destroy( &_packetIdentifierMutex );\r
725 }\r
726 \r
727 \r
728 IotMqttError_t IotBleMqtt_SerializeConnect( const IotMqttConnectInfo_t * const pConnectInfo,\r
729                                                            uint8_t ** const pConnectPacket,\r
730                                                            size_t * const pPacketSize )\r
731 {\r
732         uint8_t * pBuffer = NULL;\r
733         size_t bufLen = 0;\r
734         IotSerializerError_t error;\r
735         IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
736 \r
737 \r
738         error = _serializeConnect( pConnectInfo, NULL, &bufLen );\r
739         if( error != IOT_SERIALIZER_SUCCESS )\r
740         {\r
741             IotLogError( "Failed to find length of serialized CONNECT message, error = %d", error );\r
742             ret = IOT_MQTT_BAD_PARAMETER;\r
743         }\r
744 \r
745         if( ret == IOT_MQTT_SUCCESS )\r
746         {\r
747 \r
748             pBuffer = IotMqtt_MallocMessage( bufLen );\r
749 \r
750             /* If Memory cannot be allocated log an error and return */\r
751             if( pBuffer == NULL )\r
752             {\r
753                 IotLogError( "Failed to allocate memory for CONNECT packet." );\r
754                 ret =  IOT_MQTT_NO_MEMORY;\r
755             }\r
756         }\r
757 \r
758         if( ret == IOT_MQTT_SUCCESS )\r
759         {\r
760             error = _serializeConnect( pConnectInfo, pBuffer, &bufLen );\r
761             if( error != IOT_SERIALIZER_SUCCESS )\r
762             {\r
763                 IotLogError( "Failed to serialize CONNECT message, error = %d", error );\r
764                 ret = IOT_MQTT_BAD_PARAMETER;\r
765             }\r
766         }\r
767 \r
768         if( ret == IOT_MQTT_SUCCESS )\r
769         {\r
770             *pConnectPacket = pBuffer;\r
771             *pPacketSize = bufLen;\r
772         }\r
773         else\r
774         {\r
775             *pConnectPacket = NULL;\r
776             *pPacketSize = 0;\r
777             if( pBuffer != NULL )\r
778             {\r
779                 IotMqtt_FreeMessage( pBuffer );\r
780             }\r
781         }\r
782 \r
783     return ret;\r
784 }\r
785 \r
786 IotMqttError_t IotBleMqtt_DeserializeConnack( _mqttPacket_t * pConnack )\r
787 {\r
788 \r
789     IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
790     IotSerializerError_t error;\r
791     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
792     int64_t respCode = 0L;\r
793 \r
794     error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pConnack->pRemainingData, pConnack->remainingLength );\r
795     if( ( error != IOT_SERIALIZER_SUCCESS )\r
796             || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
797     {\r
798         IotLogError( "Malformed CONNACK, decoding the packet failed, decoder error = %d, type: %d", error, decoderObj.type );\r
799         ret = IOT_MQTT_BAD_RESPONSE;\r
800     }\r
801 \r
802 \r
803     if( ret == IOT_MQTT_SUCCESS )\r
804     {\r
805 \r
806         error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_STATUS, &decoderValue );\r
807         if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
808                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
809         {\r
810             IotLogError( "Invalid CONNACK, response code decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
811             ret = IOT_MQTT_BAD_RESPONSE;\r
812         }\r
813         else\r
814         {\r
815 \r
816             respCode =  decoderValue.u.value.u.signedInt;\r
817             if( ( respCode != IOT_BLE_MQTT_STATUS_CONNECTING )\r
818                     && ( respCode != IOT_BLE_MQTT_STATUS_CONNECTED ) )\r
819             {\r
820                 ret = IOT_MQTT_SERVER_REFUSED;\r
821             }\r
822         }\r
823     }\r
824 \r
825     IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
826 \r
827     return ret;\r
828 }\r
829 \r
830 IotMqttError_t IotBleMqtt_SerializePublish( const IotMqttPublishInfo_t * const pPublishInfo,\r
831                                                   uint8_t ** const pPublishPacket,\r
832                                                   size_t * const pPacketSize,\r
833                                                   uint16_t * const pPacketIdentifier,\r
834                                                                                                   uint8_t ** pPacketIdentifierHigh )\r
835 {\r
836 \r
837     uint8_t * pBuffer = NULL;\r
838     size_t bufLen = 0;\r
839     uint16_t usPacketIdentifier = 0;\r
840     IotSerializerError_t error;\r
841     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
842 \r
843     (void)pPacketIdentifierHigh;\r
844 \r
845     if( pPublishInfo->qos != 0 )\r
846     {\r
847         usPacketIdentifier = _nextPacketIdentifier();\r
848     }\r
849 \r
850     error = _serializePublish( pPublishInfo, NULL, &bufLen, usPacketIdentifier );\r
851     if( error != IOT_SERIALIZER_SUCCESS  )\r
852     {\r
853         IotLogError( "Failed to find size of serialized PUBLISH message, error = %d", error );\r
854         ret = IOT_MQTT_BAD_PARAMETER;\r
855     }\r
856 \r
857     if( ret == IOT_MQTT_SUCCESS )\r
858     {\r
859 \r
860         pBuffer = IotMqtt_MallocMessage( bufLen );\r
861         /* If Memory cannot be allocated log an error and return */\r
862         if( pBuffer == NULL )\r
863         {\r
864             IotLogError( "Failed to allocate memory for PUBLISH packet." );\r
865             ret =  IOT_MQTT_NO_MEMORY;\r
866         }\r
867     }\r
868 \r
869     if( ret == IOT_MQTT_SUCCESS )\r
870     {\r
871 \r
872         error = _serializePublish( pPublishInfo, pBuffer, &bufLen, usPacketIdentifier );\r
873         if( error != IOT_SERIALIZER_SUCCESS )\r
874         {\r
875             IotLogError( "Failed to serialize PUBLISH message, error = %d", error );\r
876             ret = IOT_MQTT_BAD_PARAMETER;\r
877         }\r
878     }\r
879 \r
880     if( ret == IOT_MQTT_SUCCESS )\r
881     {\r
882         *pPublishPacket = pBuffer;\r
883         *pPacketSize = bufLen;\r
884         *pPacketIdentifier = usPacketIdentifier;\r
885     }\r
886     else\r
887     {\r
888         if( pBuffer != NULL )\r
889         {\r
890             IotMqtt_FreeMessage( pBuffer );\r
891         }\r
892         *pPublishPacket = NULL;\r
893         *pPacketSize = 0;\r
894     }\r
895 \r
896     return ret;\r
897 }\r
898 \r
899 void IotBleMqtt_PublishSetDup( uint8_t * const pPublishPacket, uint8_t * pPacketIdentifierHigh, uint16_t * const pNewPacketIdentifier  )\r
900 {\r
901         /** TODO: Currently DUP flag is not supported by BLE SDKs **/\r
902 }\r
903 \r
904 IotMqttError_t IotBleMqtt_DeserializePublish( _mqttPacket_t * pPublish )\r
905 {\r
906 \r
907     IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
908     IotSerializerError_t xSerializerRet;\r
909     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
910 \r
911     xSerializerRet = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pPublish->pRemainingData, pPublish->remainingLength );\r
912     if ( (xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
913             ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
914     {\r
915 \r
916         IotLogError( "Decoding PUBLISH packet failed, decoder error = %d, object type = %d", xSerializerRet, decoderObj.type );\r
917         ret = IOT_MQTT_BAD_RESPONSE;\r
918     }\r
919 \r
920     if( ret == IOT_MQTT_SUCCESS )\r
921     {\r
922         xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_QOS, &decoderValue );\r
923         if ( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
924                  ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
925         {\r
926             IotLogError( "QOS Value decode failed, error = %d, decoded value type = %d", xSerializerRet, decoderValue.type );\r
927             ret = IOT_MQTT_BAD_RESPONSE;\r
928         }\r
929         else\r
930         {\r
931                 pPublish->u.pIncomingPublish->u.publish.publishInfo.qos = decoderValue.u.value.u.signedInt;\r
932         }\r
933     }\r
934 \r
935     if( ret == IOT_MQTT_SUCCESS )\r
936     {\r
937         decoderValue.u.value.u.string.pString = NULL;\r
938         decoderValue.u.value.u.string.length = 0;\r
939         xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_TOPIC, &decoderValue );\r
940 \r
941         if( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
942                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_TEXT_STRING ) )\r
943         {\r
944             IotLogError( "Topic value decode failed, error = %d", xSerializerRet );\r
945             ret = IOT_MQTT_BAD_RESPONSE;\r
946         }\r
947         else\r
948         {\r
949                 pPublish->u.pIncomingPublish->u.publish.publishInfo.pTopicName = ( const char* ) decoderValue.u.value.u.string.pString;\r
950                 pPublish->u.pIncomingPublish->u.publish.publishInfo.topicNameLength = decoderValue.u.value.u.string.length;\r
951         }\r
952     }\r
953 \r
954     if( ret == IOT_MQTT_SUCCESS )\r
955     {\r
956         decoderValue.u.value.u.string.pString = NULL;\r
957         decoderValue.u.value.u.string.length = 0;\r
958         xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_PAYLOAD, &decoderValue );\r
959 \r
960         if( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
961                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_BYTE_STRING ) )\r
962         {\r
963             IotLogError( "Payload value decode failed, error = %d", xSerializerRet );\r
964             ret = IOT_MQTT_BAD_RESPONSE;\r
965         }\r
966         else\r
967         {\r
968                 pPublish->u.pIncomingPublish->u.publish.publishInfo.pPayload = ( const char* ) decoderValue.u.value.u.string.pString;\r
969                 pPublish->u.pIncomingPublish->u.publish.publishInfo.payloadLength = decoderValue.u.value.u.string.length;\r
970         }\r
971     }\r
972 \r
973     if( ret == IOT_MQTT_SUCCESS )\r
974     {\r
975         if( pPublish->u.pIncomingPublish->u.publish.publishInfo.qos != 0 )\r
976         {\r
977             xSerializerRet = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
978             if ( ( xSerializerRet != IOT_SERIALIZER_SUCCESS ) ||\r
979                     ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
980             {\r
981                 IotLogError( "Message identifier decode failed, error = %d, decoded value type = %d", xSerializerRet, decoderValue.type );\r
982                 ret = IOT_MQTT_BAD_RESPONSE;\r
983             }\r
984             else\r
985             {\r
986                 pPublish->packetIdentifier  = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
987             }\r
988         }\r
989     }\r
990 \r
991     if( ret == IOT_MQTT_SUCCESS  )\r
992     {\r
993         pPublish->u.pIncomingPublish->u.publish.publishInfo.retain = false;\r
994     }\r
995 \r
996     IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
997 \r
998     return ret;\r
999 }\r
1000 \r
1001 IotMqttError_t IotBleMqtt_SerializePuback( uint16_t packetIdentifier,\r
1002                                                       uint8_t ** const pPubackPacket,\r
1003                                                       size_t * const pPacketSize )\r
1004 {\r
1005     uint8_t * pBuffer = NULL;\r
1006     size_t bufLen = 0;\r
1007     IotSerializerError_t error;\r
1008     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
1009 \r
1010     error = _serializePubAck( packetIdentifier, NULL, &bufLen );\r
1011 \r
1012     if( error != IOT_SERIALIZER_SUCCESS )\r
1013     {\r
1014         IotLogError( "Failed to find size of serialized PUBACK message, error = %d", error );\r
1015         ret = IOT_MQTT_BAD_PARAMETER;\r
1016     }\r
1017 \r
1018 \r
1019     if( ret == IOT_MQTT_SUCCESS )\r
1020     {\r
1021         pBuffer = IotMqtt_MallocMessage( bufLen );\r
1022 \r
1023         /* If Memory cannot be allocated log an error and return */\r
1024         if( pBuffer == NULL )\r
1025         {\r
1026             IotLogError( "Failed to allocate memory for PUBACK packet, packet identifier = %d", packetIdentifier );\r
1027             ret = IOT_MQTT_NO_MEMORY;\r
1028         }\r
1029     }\r
1030 \r
1031 \r
1032     if( ret == IOT_MQTT_SUCCESS )\r
1033     {\r
1034         error = _serializePubAck( packetIdentifier, pBuffer, &bufLen );\r
1035 \r
1036         if( error != IOT_SERIALIZER_SUCCESS )\r
1037         {\r
1038             IotLogError( "Failed to find size of serialized PUBACK message, error = %d", error );\r
1039             ret = IOT_MQTT_BAD_PARAMETER;\r
1040         }\r
1041     }\r
1042 \r
1043 \r
1044     if( ret == IOT_MQTT_SUCCESS )\r
1045     {\r
1046         *pPubackPacket = pBuffer;\r
1047         *pPacketSize = bufLen;\r
1048     }\r
1049     else\r
1050     {\r
1051         if( pBuffer != NULL )\r
1052         {\r
1053             IotMqtt_FreeMessage( pBuffer );\r
1054         }\r
1055 \r
1056         *pPubackPacket = NULL;\r
1057         *pPacketSize = 0;\r
1058     }\r
1059 \r
1060         return ret;\r
1061 \r
1062 }\r
1063 \r
1064 IotMqttError_t IotBleMqtt_DeserializePuback( _mqttPacket_t * pPuback )\r
1065 {\r
1066 \r
1067     IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
1068     IotSerializerError_t error;\r
1069     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
1070 \r
1071     error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pPuback->pRemainingData, pPuback->remainingLength );\r
1072 \r
1073     if ( ( error != IOT_SERIALIZER_SUCCESS )\r
1074             || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
1075     {\r
1076         IotLogError( "Malformed PUBACK, decoding the packet failed, decoder error = %d, object type: %d", error, decoderObj.type );\r
1077         ret = IOT_MQTT_BAD_RESPONSE;\r
1078     }\r
1079 \r
1080 \r
1081     if( ret == IOT_MQTT_SUCCESS )\r
1082     {\r
1083 \r
1084         error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
1085 \r
1086         if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
1087                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
1088         {\r
1089             IotLogError( "Message ID decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
1090             ret = IOT_MQTT_BAD_RESPONSE;\r
1091         }\r
1092         else\r
1093         {\r
1094                 pPuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
1095         }\r
1096     }\r
1097 \r
1098     IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
1099 \r
1100     return ret;\r
1101 \r
1102 }\r
1103 \r
1104 IotMqttError_t IotBleMqtt_SerializeSubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
1105                                                          size_t subscriptionCount,\r
1106                                                          uint8_t ** const pSubscribePacket,\r
1107                                                          size_t * const pPacketSize,\r
1108                                                          uint16_t * const pPacketIdentifier )\r
1109 {\r
1110     uint8_t * pBuffer = NULL;\r
1111     size_t bufLen = 0;\r
1112     uint16_t usPacketIdentifier = 0;\r
1113     IotSerializerError_t error;\r
1114     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
1115 \r
1116     usPacketIdentifier = _nextPacketIdentifier();\r
1117 \r
1118     error = _serializeSubscribe( pSubscriptionList, subscriptionCount, NULL, &bufLen, usPacketIdentifier );\r
1119     if( error != IOT_SERIALIZER_SUCCESS )\r
1120     {\r
1121         IotLogError( "Failed to find serialized length of SUBSCRIBE message, error = %d", error );\r
1122         ret = IOT_MQTT_BAD_PARAMETER;\r
1123     }\r
1124 \r
1125     if( ret == IOT_MQTT_SUCCESS )\r
1126     {\r
1127         pBuffer = IotMqtt_MallocMessage( bufLen );\r
1128 \r
1129         /* If Memory cannot be allocated log an error and return */\r
1130         if( pBuffer == NULL )\r
1131         {\r
1132             IotLogError( "Failed to allocate memory for SUBSCRIBE message." );\r
1133             ret = IOT_MQTT_NO_MEMORY;\r
1134         }\r
1135     }\r
1136 \r
1137     if( ret == IOT_MQTT_SUCCESS )\r
1138     {\r
1139         error = _serializeSubscribe( pSubscriptionList, subscriptionCount, pBuffer, &bufLen, usPacketIdentifier );\r
1140         if( error != IOT_SERIALIZER_SUCCESS )\r
1141         {\r
1142             IotLogError( "Failed to serialize SUBSCRIBE message, error = %d", error );\r
1143             ret = IOT_MQTT_BAD_PARAMETER;\r
1144         }\r
1145     }\r
1146 \r
1147     if( ret == IOT_MQTT_SUCCESS )\r
1148     {\r
1149         *pSubscribePacket = pBuffer;\r
1150         *pPacketSize = bufLen;\r
1151         *pPacketIdentifier = usPacketIdentifier;\r
1152     }\r
1153     else\r
1154     {\r
1155         if( pBuffer != NULL )\r
1156         {\r
1157             IotMqtt_FreeMessage( pBuffer );\r
1158         }\r
1159 \r
1160         *pSubscribePacket = NULL;\r
1161         *pPacketSize = 0;\r
1162     }\r
1163 \r
1164     return ret;\r
1165 }\r
1166 \r
1167 IotMqttError_t IotBleMqtt_DeserializeSuback( _mqttPacket_t * pSuback )\r
1168 {\r
1169 \r
1170     IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
1171     IotSerializerError_t error;\r
1172     int64_t subscriptionStatus;\r
1173     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
1174 \r
1175     error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pSuback->pRemainingData, pSuback->remainingLength );\r
1176 \r
1177     if ( ( error != IOT_SERIALIZER_SUCCESS )\r
1178             || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
1179     {\r
1180         IotLogError( "Malformed SUBACK, decoding the packet failed, decoder error = %d, type: %d", error, decoderObj.type );\r
1181         ret = IOT_MQTT_BAD_RESPONSE;\r
1182     }\r
1183 \r
1184     if( ret == IOT_MQTT_SUCCESS )\r
1185     {\r
1186 \r
1187         error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
1188         if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
1189                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
1190         {\r
1191             IotLogError( "Message ID decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
1192             ret = IOT_MQTT_BAD_RESPONSE;\r
1193         }\r
1194         else\r
1195         {\r
1196                 pSuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
1197         }\r
1198     }\r
1199 \r
1200     if( ret == IOT_MQTT_SUCCESS )\r
1201     {\r
1202         error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_STATUS, &decoderValue );\r
1203         if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
1204                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
1205         {\r
1206             IotLogError( "Status code decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
1207             ret = IOT_MQTT_BAD_RESPONSE;\r
1208         }\r
1209         else\r
1210         {\r
1211             subscriptionStatus = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
1212             switch( subscriptionStatus )\r
1213             {\r
1214                 case 0x00:\r
1215                 case 0x01:\r
1216                 case 0x02:\r
1217                     IotLog( IOT_LOG_DEBUG,\r
1218                                &_logHideAll,\r
1219                                "Topic accepted, max QoS %hhu.", subscriptionStatus );\r
1220                     ret = IOT_MQTT_SUCCESS;\r
1221                     break;\r
1222                 case 0x80:\r
1223                     IotLog( IOT_LOG_DEBUG,\r
1224                                &_logHideAll,\r
1225                                "Topic refused." );\r
1226 \r
1227                     /* Remove a rejected subscription from the subscription manager. */\r
1228                     _IotMqtt_RemoveSubscriptionByPacket(\r
1229                                 pSuback->u.pMqttConnection,\r
1230                                                         pSuback->packetIdentifier,\r
1231                             0 );\r
1232                     ret = IOT_MQTT_SERVER_REFUSED;\r
1233                     break;\r
1234                 default:\r
1235                     IotLog( IOT_LOG_DEBUG,\r
1236                                &_logHideAll,\r
1237                                "Bad SUBSCRIBE status %hhu.", subscriptionStatus );\r
1238 \r
1239                     ret = IOT_MQTT_BAD_RESPONSE;\r
1240                     break;\r
1241             }\r
1242         }\r
1243 \r
1244     }\r
1245 \r
1246     IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
1247 \r
1248         return ret;\r
1249 }\r
1250 \r
1251 IotMqttError_t IotBleMqtt_SerializeUnsubscribe( const IotMqttSubscription_t * const pSubscriptionList,\r
1252                 size_t subscriptionCount,\r
1253                 uint8_t ** const pUnsubscribePacket,\r
1254                 size_t * const pPacketSize,\r
1255                 uint16_t * const pPacketIdentifier )\r
1256 {\r
1257 \r
1258         uint8_t * pBuffer = NULL;\r
1259     size_t bufLen = 0;\r
1260     uint16_t usPacketIdentifier = 0;\r
1261     IotSerializerError_t error;\r
1262     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
1263 \r
1264     usPacketIdentifier = _nextPacketIdentifier();\r
1265 \r
1266     error = _serializeUnSubscribe( pSubscriptionList, subscriptionCount, NULL, &bufLen, usPacketIdentifier );\r
1267     if( error != IOT_SERIALIZER_SUCCESS )\r
1268     {\r
1269         IotLogError( "Failed to find serialized length of UNSUBSCRIBE message, error = %d", error );\r
1270         ret = IOT_MQTT_BAD_PARAMETER;\r
1271     }\r
1272 \r
1273     if( ret == IOT_MQTT_SUCCESS )\r
1274     {\r
1275         pBuffer = IotMqtt_MallocMessage( bufLen );\r
1276 \r
1277         /* If Memory cannot be allocated log an error and return */\r
1278         if( pBuffer == NULL )\r
1279         {\r
1280             IotLogError( "Failed to allocate memory for UNSUBSCRIBE message." );\r
1281             ret = IOT_MQTT_NO_MEMORY;\r
1282         }\r
1283     }\r
1284 \r
1285     if( ret == IOT_MQTT_SUCCESS )\r
1286     {\r
1287         error = _serializeUnSubscribe( pSubscriptionList, subscriptionCount, pBuffer, &bufLen, usPacketIdentifier );\r
1288         if( error != IOT_SERIALIZER_SUCCESS )\r
1289         {\r
1290             IotLogError( "Failed to serialize UNSUBSCRIBE message, error = %d", error );\r
1291             ret = IOT_MQTT_BAD_PARAMETER;\r
1292         }\r
1293     }\r
1294 \r
1295     if( ret == IOT_MQTT_SUCCESS )\r
1296     {\r
1297         *pUnsubscribePacket = pBuffer;\r
1298         *pPacketSize = bufLen;\r
1299         *pPacketIdentifier = usPacketIdentifier;\r
1300     }\r
1301     else\r
1302     {\r
1303         if( pBuffer != NULL )\r
1304         {\r
1305             IotMqtt_FreeMessage( pBuffer );\r
1306         }\r
1307 \r
1308         *pUnsubscribePacket = NULL;\r
1309         *pPacketSize = 0;\r
1310     }\r
1311 \r
1312     return ret;\r
1313 }\r
1314 \r
1315 IotMqttError_t IotBleMqtt_DeserializeUnsuback( _mqttPacket_t * pUnsuback )\r
1316 {\r
1317     IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
1318     IotSerializerError_t error;\r
1319     IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
1320 \r
1321     error = IOT_BLE_MESG_DECODER.init( &decoderObj, ( uint8_t * ) pUnsuback->pRemainingData, pUnsuback->remainingLength );\r
1322     if( ( error != IOT_SERIALIZER_SUCCESS )\r
1323             || ( decoderObj.type != IOT_SERIALIZER_CONTAINER_MAP ) )\r
1324     {\r
1325         IotLogError( "Malformed UNSUBACK, decoding the packet failed, decoder error = %d, type:%d ", error, decoderObj.type );\r
1326         ret = IOT_MQTT_BAD_RESPONSE;\r
1327     }\r
1328 \r
1329     if( ret == IOT_MQTT_SUCCESS )\r
1330     {\r
1331         error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MESSAGE_ID, &decoderValue );\r
1332         if ( ( error != IOT_SERIALIZER_SUCCESS ) ||\r
1333                 ( decoderValue.type != IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
1334         {\r
1335             IotLogError( "UNSUBACK Message identifier decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
1336             ret = IOT_MQTT_BAD_RESPONSE;\r
1337 \r
1338         }\r
1339         else\r
1340         {\r
1341                 pUnsuback->packetIdentifier = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
1342         }\r
1343     }\r
1344 \r
1345     IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
1346 \r
1347         return IOT_MQTT_SUCCESS;\r
1348 }\r
1349 \r
1350 IotMqttError_t IotBleMqtt_SerializeDisconnect( uint8_t ** const pDisconnectPacket,\r
1351                                                           size_t * const pPacketSize )\r
1352 {\r
1353         uint8_t *pBuffer = NULL;\r
1354         size_t bufLen = 0;\r
1355         IotSerializerError_t error;\r
1356         IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
1357 \r
1358         error = _serializeDisconnect( NULL, &bufLen);\r
1359         if( error != IOT_SERIALIZER_SUCCESS )\r
1360         {\r
1361             IotLogError( "Failed to find serialized length of DISCONNECT message, error = %d", error );\r
1362             ret = IOT_MQTT_BAD_PARAMETER;\r
1363         }\r
1364 \r
1365         if( ret == IOT_MQTT_SUCCESS )\r
1366         {\r
1367             pBuffer = IotMqtt_MallocMessage( bufLen );\r
1368 \r
1369             /* If Memory cannot be allocated log an error and return */\r
1370             if( pBuffer == NULL )\r
1371             {\r
1372                 IotLogError( "Failed to allocate memory for DISCONNECT message." );\r
1373                 ret = IOT_MQTT_NO_MEMORY;\r
1374             }\r
1375         }\r
1376 \r
1377 \r
1378         if( ret == IOT_MQTT_SUCCESS )\r
1379         {\r
1380             error = _serializeDisconnect( pBuffer, &bufLen );\r
1381             if( error != IOT_SERIALIZER_SUCCESS )\r
1382             {\r
1383                 IotLogError( "Failed to serialize DISCONNECT message, error = %d", error );\r
1384                 ret = IOT_MQTT_BAD_PARAMETER;\r
1385             }\r
1386         }\r
1387 \r
1388         if( ret == IOT_MQTT_SUCCESS )\r
1389         {\r
1390             *pDisconnectPacket = pBuffer;\r
1391             *pPacketSize = bufLen;\r
1392         }\r
1393         else\r
1394         {\r
1395             if( pBuffer != NULL )\r
1396             {\r
1397                 IotMqtt_FreeMessage( pBuffer );\r
1398             }\r
1399 \r
1400             *pDisconnectPacket = NULL;\r
1401             *pPacketSize = 0;\r
1402         }\r
1403 \r
1404         return ret;\r
1405 }\r
1406 \r
1407 size_t IotBleMqtt_GetRemainingLength ( void * pNetworkConnection,\r
1408                                        const IotNetworkInterface_t * pNetworkInterface )\r
1409 {\r
1410     const uint8_t *pBuffer;\r
1411     size_t length;\r
1412 \r
1413     IotBleDataTransfer_PeekReceiveBuffer( *( IotBleDataTransferChannel_t ** ) ( pNetworkConnection ), &pBuffer, &length );\r
1414 \r
1415     return length;\r
1416 }\r
1417 \r
1418 \r
1419 uint8_t IotBleMqtt_GetPacketType( void * pNetworkConnection, const IotNetworkInterface_t * pNetworkInterface )\r
1420 {\r
1421 \r
1422     IotSerializerDecoderObject_t decoderObj = { 0 }, decoderValue = { 0 };\r
1423     IotSerializerError_t error;\r
1424     uint8_t value = 0xFF, packetType = _INVALID_MQTT_PACKET_TYPE;\r
1425     const uint8_t *pBuffer;\r
1426     size_t length;\r
1427 \r
1428     IotBleDataTransfer_PeekReceiveBuffer( *( IotBleDataTransferChannel_t ** ) ( pNetworkConnection ), &pBuffer, &length );\r
1429 \r
1430     error = IOT_BLE_MESG_DECODER.init( &decoderObj, pBuffer, length );\r
1431 \r
1432     if( ( error == IOT_SERIALIZER_SUCCESS )\r
1433             && ( decoderObj.type == IOT_SERIALIZER_CONTAINER_MAP ) )\r
1434     {\r
1435 \r
1436         error = IOT_BLE_MESG_DECODER.find( &decoderObj, IOT_BLE_MQTT_MSG_TYPE, &decoderValue );\r
1437 \r
1438         if ( ( error == IOT_SERIALIZER_SUCCESS ) &&\r
1439                 ( decoderValue.type == IOT_SERIALIZER_SCALAR_SIGNED_INT ) )\r
1440         {\r
1441             value = ( uint16_t ) decoderValue.u.value.u.signedInt;\r
1442 \r
1443             /** Left shift by 4 bits as MQTT library expects packet type to be upper 4 bits **/\r
1444             packetType = value << 4;\r
1445         }\r
1446         else\r
1447         {\r
1448             IotLogError( "Packet type decode failed, error = %d, decoded value type = %d", error, decoderValue.type );\r
1449         }\r
1450     }\r
1451     else\r
1452     {\r
1453         IotLogError( "Decoding the packet failed, decoder error = %d, type = %d", error, decoderObj.type );\r
1454     }\r
1455 \r
1456     IOT_BLE_MESG_DECODER.destroy( &decoderObj );\r
1457 \r
1458     return packetType;\r
1459 }\r
1460 \r
1461 IotMqttError_t IotBleMqtt_SerializePingreq( uint8_t ** const pPingreqPacket,\r
1462                                             size_t * const pPacketSize )\r
1463 {\r
1464     uint8_t *pBuffer = NULL;\r
1465         size_t bufLen = 0;\r
1466         IotSerializerError_t error;\r
1467         IotMqttError_t ret = IOT_MQTT_SUCCESS;\r
1468 \r
1469         error = _serializePingRequest( NULL, &bufLen);\r
1470         if( error != IOT_SERIALIZER_SUCCESS )\r
1471         {\r
1472             IotLogError( "Failed to find serialized length of DISCONNECT message, error = %d", error );\r
1473             ret = IOT_MQTT_BAD_PARAMETER;\r
1474         }\r
1475 \r
1476         if( ret == IOT_MQTT_SUCCESS )\r
1477         {\r
1478             pBuffer = IotMqtt_MallocMessage( bufLen );\r
1479 \r
1480             /* If Memory cannot be allocated log an error and return */\r
1481             if( pBuffer == NULL )\r
1482             {\r
1483                 IotLogError( "Failed to allocate memory for DISCONNECT message." );\r
1484                 ret = IOT_MQTT_NO_MEMORY;\r
1485             }\r
1486         }\r
1487 \r
1488         if( ret == IOT_MQTT_SUCCESS )\r
1489         {\r
1490             error = _serializePingRequest( pBuffer, &bufLen );\r
1491             if( error != IOT_SERIALIZER_SUCCESS )\r
1492             {\r
1493                 IotLogError( "Failed to serialize DISCONNECT message, error = %d", error );\r
1494                 ret = IOT_MQTT_BAD_PARAMETER;\r
1495             }\r
1496         }\r
1497 \r
1498         if( ret == IOT_MQTT_SUCCESS )\r
1499         {\r
1500             *pPingreqPacket = pBuffer;\r
1501             *pPacketSize = bufLen;\r
1502         }\r
1503         else\r
1504         {\r
1505             if( pBuffer != NULL )\r
1506             {\r
1507                 IotMqtt_FreeMessage( pBuffer );\r
1508             }\r
1509 \r
1510             *pPingreqPacket = NULL;\r
1511             *pPacketSize = 0;\r
1512         }\r
1513 \r
1514     return ret;\r
1515 \r
1516 }\r
1517 \r
1518 IotMqttError_t IotBleMqtt_DeserializePingresp( _mqttPacket_t * pPingresp )\r
1519 {\r
1520     /* Ping Response for BLE contains only packet type field in CBOR, which is already decoded\r
1521        in IotBleMqtt_GetPacketType() function. Returning IOT_MQTT_SUCCESS. */\r
1522     return IOT_MQTT_SUCCESS;\r
1523 }\r
1524 \r
1525 void IotBleMqtt_FreePacket( uint8_t * pPacket )\r
1526 {\r
1527     IotMqtt_FreeMessage( pPacket );\r
1528 }\r