mqtt_sn_client_message.c
Go to the documentation of this file.
1 /**
2  * @file mqtt_sn_client_message.c
3  * @brief MQTT-SN message parsing and formatting
4  *
5  * @section License
6  *
7  * Copyright (C) 2010-2018 Oryx Embedded SARL. All rights reserved.
8  *
9  * This file is part of CycloneTCP Open.
10  *
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24  *
25  * @author Oryx Embedded SARL (www.oryx-embedded.com)
26  * @version 1.9.0
27  **/
28 
29 //Switch to the appropriate trace level
30 #define TRACE_LEVEL MQTT_SN_TRACE_LEVEL
31 
32 //Dependencies
33 #include "core/net.h"
34 #include "mqtt_sn/mqtt_sn_client.h"
39 #include "mqtt_sn/mqtt_sn_debug.h"
40 #include "debug.h"
41 
42 //Check TCP/IP stack configuration
43 #if (MQTT_SN_CLIENT_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Process incoming MQTT-SN message
48  * @param[in] context Pointer to the MQTT-SN client context
49  * @param[in] message Pointer to the received MQTT-SN message
50  * @param[in] ipAddr Source IP address
51  * @param[in] port Source port
52  * @return Error code
53  **/
54 
56  MqttSnMessage *message, const IpAddr *ipAddr, uint16_t port)
57 {
58  error_t error;
60 
61  //Parse MQTT-SN message header
62  error = mqttSnParseHeader(message, &type);
63 
64  //Check status code
65  if(!error)
66  {
67  //Debug message
68  TRACE_INFO("%s message received (%" PRIuSIZE " bytes)...\r\n",
70 
71  //Dump the contents of the message for debugging purpose
72  mqttSnDumpMessage(message->buffer, message->length);
73 
74  //Check message type
75  switch(type)
76  {
77  //GWINFO message received?
79  //Process incoming GWINFO message
80  error = mqttSnClientProcessGwInfo(context, message, ipAddr, port);
81  break;
82  //CONNACK message received?
84  //Process incoming CONNACK message
85  error = mqttSnClientProcessConnAck(context, message);
86  break;
87  //WILLTOPICREQ message received?
89  //Process incoming WILLTOPICREQ message
90  error = mqttSnClientProcessWillTopicReq(context, message);
91  break;
92  //WILLMSGREQ message received?
94  //Process incoming WILLMSGREQ message
95  error = mqttSnClientProcessWillMsgReq(context, message);
96  break;
97  //REGISTER message received?
99  //Process incoming REGISTER message
100  error = mqttSnClientProcessRegister(context, message);
101  break;
102  //REGACK message received?
104  //Process incoming REGACK message
105  error = mqttSnClientProcessRegAck(context, message);
106  break;
107  //PUBLISH message received?
109  //Process incoming PUBLISH message
110  error = mqttSnClientProcessPublish(context, message);
111  break;
112  //PUBACK message received?
114  //Process incoming PUBACK message
115  error = mqttSnClientProcessPubAck(context, message);
116  break;
117  //PUBREC message received?
119  //Process incoming PUBREC message
120  error = mqttSnClientProcessPubRec(context, message);
121  break;
122  //PUBREL message received?
124  //Process incoming PUBREL message
125  error = mqttSnClientProcessPubRel(context, message);
126  break;
127  //PUBCOMP message received?
129  //Process incoming PUBCOMP message
130  error = mqttSnClientProcessPubComp(context, message);
131  break;
132  //SUBACK message received?
134  //Process incoming SUBACK message
135  error = mqttSnClientProcessSubAck(context, message);
136  break;
137  //UNSUBACK message received?
139  //Process incoming UNSUBACK message
140  error = mqttSnClientProcessUnsubAck(context, message);
141  break;
142  //PINGREQ message received?
144  //Process incoming PINGREQ message
145  error = mqttSnClientProcessPingReq(context, message);
146  break;
147  //PINGRESP message received?
149  //Process incoming PINGRESP message
150  error = mqttSnClientProcessPingResp(context, message);
151  break;
152  //DISCONNECT message received?
154  //Process incoming DISCONNECT message
155  error = mqttSnClientProcessDisconnect(context, message);
156  break;
157  //WILLTOPICRESP message received?
159  //Process incoming DISCONNECT message
160  error = mqttSnClientProcessWillTopicResp(context, message);
161  break;
162  //WILLMSGRESP message received?
164  //Process incoming DISCONNECT message
165  error = mqttSnClientProcessWillMsgResp(context, message);
166  break;
167  //Unknown message received?
168  default:
169  //Report an error
170  error = ERROR_INVALID_TYPE;
171  break;
172  }
173  }
174  else
175  {
176  //Debug message
177  TRACE_WARNING("Invalid message received (%" PRIuSIZE " bytes)...\r\n",
178  message->length);
179 
180  //Dump the contents of the message
181  TRACE_DEBUG_ARRAY(" ", message->buffer, message->length);
182  }
183 
184  //Return status code
185  return error;
186 }
187 
188 
189 /**
190  * @brief Process incoming GWINFO message
191  * @param[in] context Pointer to the MQTT-SN client context
192  * @param[in] message Pointer to the received MQTT-SN message
193  * @param[in] ipAddr Source IP address
194  * @param[in] port Source port
195  * @return Error code
196  **/
197 
199  const MqttSnMessage *message, const IpAddr *ipAddr, uint16_t port)
200 {
201  error_t error;
202  uint8_t gwId;
203  const uint8_t *gwAdd;
204  size_t gwAddLen;
205 
206  //Parse GWINFO message
207  error = mqttSnParseGwInfo(message, &gwId, &gwAdd, &gwAddLen);
208 
209  //Valid message received?
210  if(!error)
211  {
212  //Check current state
213  if(context->state == MQTT_SN_CLIENT_STATE_SEARCHING)
214  {
215  //Notify the application that a GWINFO message has been received
216  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
217  context->msgType = MQTT_SN_MSG_TYPE_GWINFO;
218  context->gwIpAddr = *ipAddr;
219  context->gwPort = port;
220  }
221  }
222 
223  //Return status code
224  return error;
225 }
226 
227 
228 /**
229  * @brief Process incoming CONNACK message
230  * @param[in] context Pointer to the MQTT-SN client context
231  * @param[in] message Pointer to the received MQTT-SN message
232  * @return Error code
233  **/
234 
236  const MqttSnMessage *message)
237 {
238  error_t error;
240 
241  //Parse CONNACK message
243 
244  //Valid message received?
245  if(!error)
246  {
247  //Check current state
248  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
249  context->msgType == MQTT_SN_MSG_TYPE_CONNECT)
250  {
251  //Notify the application that a CONNACK message has been received
252  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
253  context->msgType = MQTT_SN_MSG_TYPE_CONNACK;
254  context->returnCode = returnCode;
255 
256  //The MQTT-SN gateway is alive
257  context->keepAliveCounter = 0;
258  }
259  }
260 
261  //Return status code
262  return error;
263 }
264 
265 
266 /**
267  * @brief Process incoming WILLTOPICREQ message
268  * @param[in] context Pointer to the MQTT-SN client context
269  * @param[in] message Pointer to the received MQTT-SN message
270  * @return Error code
271  **/
272 
274  const MqttSnMessage *message)
275 {
276  error_t error;
277 
278  //Parse WILLTOPICREQ message
280 
281  //Valid message received?
282  if(!error)
283  {
284  //The WILLTOPIC message is sent by a client as response to the WILLTOPICREQ
285  //message for transferring its Will topic name to the GW
286  error = mqttSnClientSendWillTopic(context);
287  }
288 
289  //Return status code
290  return error;
291 }
292 
293 
294 /**
295  * @brief Process incoming WILLMSGREQ message
296  * @param[in] context Pointer to the MQTT-SN client context
297  * @param[in] message Pointer to the received MQTT-SN message
298  * @return Error code
299  **/
300 
302  const MqttSnMessage *message)
303 {
304  error_t error;
305 
306  //Parse WILLMSGREQ message
308 
309  //Valid message received?
310  if(!error)
311  {
312  //The WILLMSG message is sent by a client as response to a WILLMSGREQ
313  //for transferring its Will message to the GW
314  error = mqttSnClientSendWillMsg(context);
315  }
316 
317  //Return status code
318  return error;
319 }
320 
321 
322 /**
323  * @brief Process incoming REGISTER message
324  * @param[in] context Pointer to the MQTT-SN client context
325  * @param[in] message Pointer to the received MQTT-SN message
326  * @return Error code
327  **/
328 
330  const MqttSnMessage *message)
331 {
332  error_t error;
333  uint16_t msgId;
334  uint16_t topicId;
335  const char_t *topicName;
337 
338  //Parse REGISTER message
340 
341  //Valid message received?
342  if(!error)
343  {
344  //Save the topic ID assigned by the gateway
345  error = mqttSnClientAddTopic(context, topicName, topicId);
346 
347  //Check status code
348  if(!error)
350  else
352 
353  //The client sends a REGACK message to acknowledge the receipt and
354  //processing of a REGISTER message
355  error = mqttSnClientSendRegAck(context, msgId, topicId, returnCode);
356  }
357 
358  //Return status code
359  return error;
360 }
361 
362 
363 /**
364  * @brief Process incoming REGACK message
365  * @param[in] context Pointer to the MQTT-SN client context
366  * @param[in] message Pointer to the received MQTT-SN message
367  * @return Error code
368  **/
369 
371  const MqttSnMessage *message)
372 {
373  error_t error;
374  uint16_t msgId;
375  uint16_t topicId;
377 
378  //Parse REGACK message
380 
381  //Valid message received?
382  if(!error)
383  {
384  //Check current state
385  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
386  context->msgType == MQTT_SN_MSG_TYPE_REGISTER &&
387  context->msgId == msgId)
388  {
389  //Notify the application that a REGACK message has been received
390  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
391  context->msgType = MQTT_SN_MSG_TYPE_REGACK;
392  context->topicId = topicId;
393  context->returnCode = returnCode;
394 
395  //The MQTT-SN gateway is alive
396  context->keepAliveCounter = 0;
397  }
398  }
399 
400  //Return status code
401  return error;
402 }
403 
404 
405 /**
406  * @brief Process incoming PUBLISH message
407  * @param[in] context Pointer to the MQTT-SN client context
408  * @param[in] message Pointer to the received MQTT-SN message
409  * @return Error code
410  **/
411 
413  const MqttSnMessage *message)
414 {
415  error_t error;
416  bool_t duplicate;
417  uint16_t msgId;
418  uint16_t topicId;
419  const uint8_t *data;
420  size_t dataLen;
423 
424  //Parse PUBLISH message
426  &data, &dataLen);
427 
428  //Valid message received?
429  if(!error)
430  {
431  //Check QoS level
432  if(flags.qos == MQTT_SN_QOS_LEVEL_1)
433  {
434  //Deliver the message to the application
436  data, dataLen);
437 
438  //A PUBACK packet is the response to a PUBLISH packet with QoS level 1
439  error = mqttSnClientSendPubAck(context, msgId, topicId, returnCode);
440  }
441  else if(flags.qos == MQTT_SN_QOS_LEVEL_2)
442  {
443  //Check whether the ownership of the QoS 2 message has already been
444  //transferred to the client
445  duplicate = mqttSnClientIsDuplicateMessageId(context, msgId);
446 
447  //Duplicate message?
448  if(duplicate)
449  {
450  //In QoS 2, the receiver must not cause duplicate messages to be
451  //delivered to any onward recipients
452  error = mqttSnClientSendPubRec(context, msgId);
453  }
454  else
455  {
456  //Accept the ownership of the QoS 2 message
457  error = mqttSnClientStoreMessageId(context, msgId);
458 
459  //Check status code
460  if(!error)
461  {
462  //Initiate onward delivery of the application message
464  data, dataLen);
465  }
466  else
467  {
468  //The message identifier cannot be saved
470  }
471 
472  //Check whether the PUBLISH message has been accepted
474  {
475  //A PUBREC packet is the response to a PUBLISH packet with QoS 2.
476  //It is the second packet of the QoS 2 protocol exchange
477  error = mqttSnClientSendPubRec(context, msgId);
478  }
479  else
480  {
481  //Discard message identifier
483 
484  //Reject the PUBLISH message
485  error = mqttSnClientSendPubAck(context, msgId, topicId,
486  returnCode);
487  }
488  }
489  }
490  else
491  {
492  //Deliver the message to the application
494  data, dataLen);
495 
496  //In QoS 0, the receiver always accepts the message
497  error = NO_ERROR;
498  }
499  }
500 
501  //Return status code
502  return error;
503 }
504 
505 
506 /**
507  * @brief Process incoming PUBACK message
508  * @param[in] context Pointer to the MQTT-SN client context
509  * @param[in] message Pointer to the received MQTT-SN message
510  * @return Error code
511  **/
512 
514  const MqttSnMessage *message)
515 {
516  error_t error;
517  uint16_t msgId;
518  uint16_t topicId;
520 
521  //Parse PUBACK message
523 
524  //Valid message received?
525  if(!error)
526  {
527  //Check current state
528  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
529  context->msgType == MQTT_SN_MSG_TYPE_PUBLISH &&
530  context->msgId == msgId)
531  {
532  //Notify the application that a PUBACK message has been received
533  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
534  context->msgType = MQTT_SN_MSG_TYPE_PUBACK;
535  context->returnCode = returnCode;
536 
537  //The MQTT-SN gateway is alive
538  context->keepAliveCounter = 0;
539  }
540  }
541 
542  //Return status code
543  return error;
544 }
545 
546 
547 /**
548  * @brief Process incoming PUBREC message
549  * @param[in] context Pointer to the MQTT-SN client context
550  * @param[in] message Pointer to the received MQTT-SN message
551  * @return Error code
552  **/
553 
555  const MqttSnMessage *message)
556 {
557  error_t error;
558  uint16_t msgId;
559 
560  //Parse PUBREC message
561  error = mqttSnParsePubRec(message, &msgId);
562 
563  //Valid message received?
564  if(!error)
565  {
566  //Check current state
567  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
568  context->msgType == MQTT_SN_MSG_TYPE_PUBLISH &&
569  context->msgId == msgId)
570  {
571  //Notify the application that a PUBREC message has been received
572  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
573  context->msgType = MQTT_SN_MSG_TYPE_PUBREC;
574 
575  //The MQTT-SN gateway is alive
576  context->keepAliveCounter = 0;
577  }
578  }
579 
580  //Return status code
581  return error;
582 }
583 
584 
585 /**
586  * @brief Process incoming PUBREL message
587  * @param[in] context Pointer to the MQTT-SN client context
588  * @param[in] message Pointer to the received MQTT-SN message
589  * @return Error code
590  **/
591 
593  const MqttSnMessage *message)
594 {
595  error_t error;
596  uint16_t msgId;
597 
598  //Parse PUBREL message
599  error = mqttSnParsePubRel(message, &msgId);
600 
601  //Valid message received?
602  if(!error)
603  {
604  //Discard message identifier
606 
607  //A PUBCOMP message is the response to a PUBREL packet. It is the fourth
608  //and final message of the QoS 2 protocol exchange
609  error = mqttSnClientSendPubComp(context, msgId);
610  }
611 
612  //Return status code
613  return error;
614 }
615 
616 
617 /**
618  * @brief Process incoming PUBCOMP message
619  * @param[in] context Pointer to the MQTT-SN client context
620  * @param[in] message Pointer to the received MQTT-SN message
621  * @return Error code
622  **/
623 
625  const MqttSnMessage *message)
626 {
627  error_t error;
628  uint16_t msgId;
629 
630  //Parse PUBCOMP message
631  error = mqttSnParsePubComp(message, &msgId);
632 
633  //Valid message received?
634  if(!error)
635  {
636  //Check current state
637  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
638  context->msgType == MQTT_SN_MSG_TYPE_PUBREL &&
639  context->msgId == msgId)
640  {
641  //Notify the application that a PUBCOMP message has been received
642  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
643  context->msgType = MQTT_SN_MSG_TYPE_PUBCOMP;
644 
645  //The MQTT-SN gateway is alive
646  context->keepAliveCounter = 0;
647  }
648  }
649 
650  //Return status code
651  return error;
652 }
653 
654 
655 /**
656  * @brief Process incoming SUBACK message
657  * @param[in] context Pointer to the MQTT-SN client context
658  * @param[in] message Pointer to the received MQTT-SN message
659  * @return Error code
660  **/
661 
663  const MqttSnMessage *message)
664 {
665  error_t error;
666  uint16_t msgId;
667  uint16_t topicId;
670 
671  //Parse SUBACK message
673 
674  //Valid message received?
675  if(!error)
676  {
677  //Check current state
678  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
679  context->msgType == MQTT_SN_MSG_TYPE_SUBSCRIBE &&
680  context->msgId == msgId)
681  {
682  //Notify the application that a SUBACK message has been received
683  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
684  context->msgType = MQTT_SN_MSG_TYPE_SUBACK;
685  context->topicId = topicId;
686  context->returnCode = returnCode;
687 
688  //The MQTT-SN gateway is alive
689  context->keepAliveCounter = 0;
690  }
691  }
692 
693  //Return status code
694  return error;
695 }
696 
697 
698 /**
699  * @brief Process incoming UNSUBACK message
700  * @param[in] context Pointer to the MQTT-SN client context
701  * @param[in] message Pointer to the received MQTT-SN message
702  * @return Error code
703  **/
704 
706  const MqttSnMessage *message)
707 {
708  error_t error;
709  uint16_t msgId;
710 
711  //Parse UNSUBACK message
712  error = mqttSnParseUnsubAck(message, &msgId);
713 
714  //Valid message received?
715  if(!error)
716  {
717  //Check current state
718  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
719  context->msgType == MQTT_SN_MSG_TYPE_UNSUBSCRIBE &&
720  context->msgId == msgId)
721  {
722  //Notify the application that a UNSUBACK message has been received
723  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
724  context->msgType = MQTT_SN_MSG_TYPE_UNSUBACK;
725 
726  //The MQTT-SN gateway is alive
727  context->keepAliveCounter = 0;
728  }
729  }
730 
731  //Return status code
732  return error;
733 }
734 
735 
736 /**
737  * @brief Process incoming PINGREQ message
738  * @param[in] context Pointer to the MQTT-SN client context
739  * @param[in] message Pointer to the received MQTT-SN message
740  * @return Error code
741  **/
742 
744  const MqttSnMessage *message)
745 {
746  error_t error;
747  const char_t *clientId;
748 
749  //Parse PINGREQ message
751 
752  //Valid message received?
753  if(!error)
754  {
755  //A client shall answer with a PINGRESP message when it receives a
756  //PINGREQ message from the GW to which it is connected
757  error = mqttSnClientSendPingResp(context);
758  }
759 
760  //Return status code
761  return error;
762 }
763 
764 
765 /**
766  * @brief Process incoming PINGRESP message
767  * @param[in] context Pointer to the MQTT-SN client context
768  * @param[in] message Pointer to the received MQTT-SN message
769  * @return Error code
770  **/
771 
773  const MqttSnMessage *message)
774 {
775  error_t error;
776 
777  //Parse PINGRESP message
778  error = mqttSnParsePingResp(message);
779 
780  //Valid message received?
781  if(!error)
782  {
783  //Check current state
784  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
785  context->msgType == MQTT_SN_MSG_TYPE_PINGREQ)
786  {
787  //Notify the application that a PINGRESP message has been received
788  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
789  context->msgType = MQTT_SN_MSG_TYPE_PINGRESP;
790  }
791 
792  //The MQTT-SN gateway is alive
793  context->keepAliveCounter = 0;
794  }
795 
796  //Return status code
797  return error;
798 }
799 
800 
801 /**
802  * @brief Process incoming DISCONNECT message
803  * @param[in] context Pointer to the MQTT-SN client context
804  * @param[in] message Pointer to the received MQTT-SN message
805  * @return Error code
806  **/
807 
809  const MqttSnMessage *message)
810 {
811  error_t error;
812  uint16_t duration;
813 
814  //Parse DISCONNECT message
816 
817  //Valid message received?
818  if(!error)
819  {
820  //The gateway indicates that it wants to close the connection
821  context->state = MQTT_SN_CLIENT_STATE_DISCONNECTING;
822  }
823 
824  //Return status code
825  return error;
826 }
827 
828 
829 /**
830  * @brief Process incoming WILLTOPICRESP message
831  * @param[in] context Pointer to the MQTT-SN client context
832  * @param[in] message Pointer to the received MQTT-SN message
833  * @return Error code
834  **/
835 
837  const MqttSnMessage *message)
838 {
839  error_t error;
841 
842  //Parse WILLTOPICRESP message
844 
845  //Valid message received?
846  if(!error)
847  {
848  //Check current state
849  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
850  context->msgType == MQTT_SN_MSG_TYPE_WILLTOPICUPD)
851  {
852  //Notify the application that a WILLTOPICRESP message has been received
853  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
854  context->msgType = MQTT_SN_MSG_TYPE_WILLTOPICRESP;
855  context->returnCode = returnCode;
856 
857  //The MQTT-SN gateway is alive
858  context->keepAliveCounter = 0;
859  }
860  }
861 
862  //Return status code
863  return error;
864 }
865 
866 
867 /**
868  * @brief Process incoming WILLMSGRESP message
869  * @param[in] context Pointer to the MQTT-SN client context
870  * @param[in] message Pointer to the received MQTT-SN message
871  * @return Error code
872  **/
873 
875  const MqttSnMessage *message)
876 {
877  error_t error;
879 
880  //Parse WILLMSGRESP message
882 
883  //Valid message received?
884  if(!error)
885  {
886  //Check current state
887  if(context->state == MQTT_SN_CLIENT_STATE_SENDING_REQ &&
888  context->msgType == MQTT_SN_MSG_TYPE_WILLMSGUPD)
889  {
890  //Notify the application that a WILLMSGRESP message has been received
891  context->state = MQTT_SN_CLIENT_STATE_RESP_RECEIVED;
892  context->msgType = MQTT_SN_MSG_TYPE_WILLMSGRESP;
893  context->returnCode = returnCode;
894 
895  //The MQTT-SN gateway is alive
896  context->keepAliveCounter = 0;
897  }
898  }
899 
900  //Return status code
901  return error;
902 }
903 
904 
905 /**
906  * @brief Send SEARCHGW message
907  * @param[in] context Pointer to the MQTT-SN client context
908  * @param[in] radius Broadcast radius of SEARCHGW message
909  * @param[in] destIpAddr Destination IP address
910  * @param[in] destPort Destination port number
911  * @return Error code
912  **/
913 
915  const IpAddr *destIpAddr, uint16_t destPort)
916 {
917  error_t error;
918 
919  //Format SEARCHGW message
920  error = mqttSnFormatSearchGw(&context->message, radius);
921 
922  //Check status code
923  if(!error)
924  {
925  //Debug message
926  TRACE_INFO("Sending SEARCHGW message (%" PRIuSIZE " bytes)...\r\n",
927  context->message.length);
928 
929  //Dump the contents of the message for debugging purpose
930  mqttSnDumpMessage(context->message.buffer, context->message.length);
931 
932  //Send MQTT-SN message
934  context->message.buffer, context->message.length);
935 
936  //Save the time at which the message was sent
937  context->retransmitStartTime = osGetSystemTime();
938  }
939 
940  //Return status code
941  return error;
942 }
943 
944 
945 /**
946  * @brief Send CONNECT message
947  * @param[in] context Pointer to the MQTT-SN client context
948  * @param[in] cleanSession If this flag is set, then the client and server
949  * must discard any previous session and start a new one
950  * @return Error code
951  **/
952 
955 {
956  error_t error;
957  systime_t time;
959 
960  //The flags contains a number of parameters specifying the behavior of
961  //the MQTT-SN connection
962  flags.all = 0;
963 
964  //If CleanSession is set to 1, the client and server must discard any
965  //previous session and start a new one
966  if(cleanSession)
967  flags.cleanSession = TRUE;
968 
969  //If the client supplies a zero-byte Client Identifier, the client must
970  //also set CleanSession to 1
971  if(context->clientId[0] == '\0')
972  flags.cleanSession = TRUE;
973 
974  //Check whether a valid Will message has been specified
975  if(context->willMessage.topic[0] != '\0')
976  flags.will = TRUE;
977 
978  //Format CONNECT message
979  error = mqttSnFormatConnect(&context->message, flags,
980  context->keepAlive / 1000, context->clientId);
981 
982  //Check status code
983  if(!error)
984  {
985  //Debug message
986  TRACE_INFO("Sending CONNECT message (%" PRIuSIZE " bytes)...\r\n",
987  context->message.length);
988 
989  //Dump the contents of the message for debugging purpose
990  mqttSnDumpMessage(context->message.buffer, context->message.length);
991 
992  //Send MQTT-SN message
993  error = mqttSnClientSendDatagram(context, context->message.buffer,
994  context->message.length);
995 
996  //Get current time
997  time = osGetSystemTime();
998 
999  //Save the time at which the message was sent
1000  context->retransmitStartTime = time;
1001  context->keepAliveTimestamp = time;
1002 
1003  //Update MQTT-SN client state
1004  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1005  context->msgType = MQTT_SN_MSG_TYPE_CONNECT;
1006  }
1007 
1008  //Return status code
1009  return error;
1010 }
1011 
1012 
1013 /**
1014  * @brief Send WILLTOPIC message
1015  * @param[in] context Pointer to the MQTT-SN client context
1016  * @return Error code
1017  **/
1018 
1020 {
1021  error_t error;
1022 
1023  //Format WILLTOPIC message
1024  error = mqttSnFormatWillTopic(&context->message,
1025  context->willMessage.flags, context->willMessage.topic);
1026 
1027  //Check status code
1028  if(!error)
1029  {
1030  //Debug message
1031  TRACE_INFO("Sending WILLTOPIC message (%" PRIuSIZE " bytes)...\r\n",
1032  context->message.length);
1033 
1034  //Dump the contents of the message for debugging purpose
1035  mqttSnDumpMessage(context->message.buffer, context->message.length);
1036 
1037  //Send MQTT-SN message
1038  error = mqttSnClientSendDatagram(context, context->message.buffer,
1039  context->message.length);
1040  }
1041 
1042  //Return status code
1043  return error;
1044 }
1045 
1046 
1047 /**
1048  * @brief Send WILLMSG message
1049  * @param[in] context Pointer to the MQTT-SN client context
1050  * @return Error code
1051  **/
1052 
1054 {
1055  error_t error;
1056 
1057  //Format WILLMSG message
1058  error = mqttSnFormatWillMsg(&context->message,
1059  context->willMessage.payload, context->willMessage.length);
1060 
1061  //Check status code
1062  if(!error)
1063  {
1064  //Debug message
1065  TRACE_INFO("Sending WILLMSG message (%" PRIuSIZE " bytes)...\r\n",
1066  context->message.length);
1067 
1068  //Dump the contents of the message for debugging purpose
1069  mqttSnDumpMessage(context->message.buffer, context->message.length);
1070 
1071  //Send MQTT-SN message
1072  error = mqttSnClientSendDatagram(context, context->message.buffer,
1073  context->message.length);
1074  }
1075 
1076  //Return status code
1077  return error;
1078 }
1079 
1080 
1081 /**
1082  * @brief Send REGISTER message
1083  * @param[in] context Pointer to the MQTT-SN client context
1084  * @param[in] topicName Topic name
1085  * @return Error code
1086  **/
1087 
1089  const char_t *topicName)
1090 {
1091  error_t error;
1092  systime_t time;
1093 
1094  //Format REGISTER message
1095  error = mqttSnFormatRegister(&context->message, context->msgId, 0,
1096  topicName);
1097 
1098  //Check status code
1099  if(!error)
1100  {
1101  //Debug message
1102  TRACE_INFO("Sending REGISTER message (%" PRIuSIZE " bytes)...\r\n",
1103  context->message.length);
1104 
1105  //Dump the contents of the message for debugging purpose
1106  mqttSnDumpMessage(context->message.buffer, context->message.length);
1107 
1108  //Send MQTT-SN message
1109  error = mqttSnClientSendDatagram(context, context->message.buffer,
1110  context->message.length);
1111 
1112  //Get current time
1113  time = osGetSystemTime();
1114 
1115  //Save the time at which the message was sent
1116  context->retransmitStartTime = time;
1117  context->keepAliveTimestamp = time;
1118 
1119  //Update MQTT-SN client state
1120  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1121  context->msgType = MQTT_SN_MSG_TYPE_REGISTER;
1122  }
1123 
1124  //Return status code
1125  return error;
1126 }
1127 
1128 
1129 /**
1130  * @brief Send REGACK message
1131  * @param[in] context Pointer to the MQTT-SN client context
1132  * @param[in] msgId Message identifier
1133  * @param[in] topicId Topic identifier
1134  * @param[in] returnCode Return code
1135  * @return Error code
1136  **/
1137 
1140 {
1141  error_t error;
1142 
1143  //Format REGACK message
1144  error = mqttSnFormatRegAck(&context->message, msgId, topicId, returnCode);
1145 
1146  //Check status code
1147  if(!error)
1148  {
1149  //Debug message
1150  TRACE_INFO("Sending REGACK message (%" PRIuSIZE " bytes)...\r\n",
1151  context->message.length);
1152 
1153  //Dump the contents of the message for debugging purpose
1154  mqttSnDumpMessage(context->message.buffer, context->message.length);
1155 
1156  //Send MQTT-SN message
1157  error = mqttSnClientSendDatagram(context, context->message.buffer,
1158  context->message.length);
1159  }
1160 
1161  //Return status code
1162  return error;
1163 }
1164 
1165 
1166 /**
1167  * @brief Send PUBLISH message
1168  * @param[in] context Pointer to the MQTT-SN client context
1169  * @param[in] msgId Message identifier
1170  * @param[in] topicName Short topic name
1171  * @param[in] data Message payload
1172  * @param[in] length Length of the message payload
1173  * @param[in] qos QoS level to be used when publishing the message
1174  * @param[in] retain This flag specifies if the message is to be retained
1175  * @param[in] dup This flag specifies if the message is sent for the first
1176  * time or if the message is retransmitted
1177  * @return Error code
1178  **/
1179 
1181  uint16_t msgId, const char_t *topicName, const uint8_t *data,
1183 {
1184  error_t error;
1185  systime_t time;
1186  uint16_t topicId;
1188 
1189  //Initialize status code
1190  error = NO_ERROR;
1191 
1192  //Reset unused flags
1193  flags.all = 0;
1194  //Set QoS level
1195  flags.qos = qos;
1196  //Set RETAIN flag
1197  flags.retain = retain;
1198  //set DUP flag
1199  flags.dup = dup;
1200 
1201  //Short topic name?
1203  {
1204  //The PUBLISH message contains a short topic name
1205  flags.topicIdType = MQTT_SN_SHORT_TOPIC_NAME;
1206  //The value of the topic ID is not relevant
1207  topicId = 0;
1208  }
1209  else
1210  {
1211  //Check whether a predefined topic ID has been registered
1213 
1214  //Predefined topic ID found?
1216  {
1217  //The PUBLISH message contains a predefined topic ID
1218  flags.topicIdType = MQTT_SN_PREDEFINED_TOPIC_ID;
1219  }
1220  else
1221  {
1222  //Check whether the topic name has been registered
1224 
1225  //Topic ID found?
1227  {
1228  //The PUBLISH message contains a normal topic ID
1229  flags.topicIdType = MQTT_SN_NORMAL_TOPIC_ID;
1230  }
1231  else
1232  {
1233  //The topic name has not been registered
1234  error = ERROR_NOT_FOUND;
1235  }
1236  }
1237  }
1238 
1239  //Check status code
1240  if(!error)
1241  {
1242  //Format PUBLISH message
1243  error = mqttSnFormatPublish(&context->message, flags, msgId,
1245  }
1246 
1247  //Check status code
1248  if(!error)
1249  {
1250  //Debug message
1251  TRACE_INFO("Sending PUBLISH message (%" PRIuSIZE " bytes)...\r\n",
1252  context->message.length);
1253 
1254  //Dump the contents of the message for debugging purpose
1255  mqttSnDumpMessage(context->message.buffer, context->message.length);
1256 
1257  //Send MQTT-SN message
1258  error = mqttSnClientSendDatagram(context, context->message.buffer,
1259  context->message.length);
1260 
1261  //Get current time
1262  time = osGetSystemTime();
1263 
1264  //Check QoS level
1266  {
1267  //Save the time at which the message was sent
1268  context->retransmitStartTime = time;
1269  context->keepAliveTimestamp = time;
1270 
1271  //Update MQTT-SN client state
1272  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1273  context->msgType = MQTT_SN_MSG_TYPE_PUBLISH;
1274  }
1275  else
1276  {
1277  //In the QoS 0, no response is sent by the receiver and no retry
1278  //is performed by the sender
1279  context->state = MQTT_SN_CLIENT_STATE_ACTIVE;
1280  }
1281  }
1282 
1283  //Return status code
1284  return error;
1285 }
1286 
1287 
1288 /**
1289  * @brief Send PUBACK message
1290  * @param[in] context Pointer to the MQTT-SN client context
1291  * @param[in] msgId Message identifier of the corresponding PUBLISH message
1292  * @param[in] topicId Topic identifier
1293  * @param[in] returnCode Return code
1294  * @return Error code
1295  **/
1296 
1299 {
1300  error_t error;
1301 
1302  //Format PUBACK message
1303  error = mqttSnFormatPubAck(&context->message, msgId, topicId, returnCode);
1304 
1305  //Check status code
1306  if(!error)
1307  {
1308  //Debug message
1309  TRACE_INFO("Sending PUBACK message (%" PRIuSIZE " bytes)...\r\n",
1310  context->message.length);
1311 
1312  //Dump the contents of the message for debugging purpose
1313  mqttSnDumpMessage(context->message.buffer, context->message.length);
1314 
1315  //Send MQTT-SN message
1316  error = mqttSnClientSendDatagram(context, context->message.buffer,
1317  context->message.length);
1318  }
1319 
1320  //Return status code
1321  return error;
1322 }
1323 
1324 
1325 /**
1326  * @brief Send PUBREC message
1327  * @param[in] context Pointer to the MQTT-SN client context
1328  * @param[in] msgId Message identifier of the corresponding PUBLISH message
1329  * @return Error code
1330  **/
1331 
1333 {
1334  error_t error;
1335 
1336  //Format PUBREC message
1337  error = mqttSnFormatPubRec(&context->message, msgId);
1338 
1339  //Check status code
1340  if(!error)
1341  {
1342  //Debug message
1343  TRACE_INFO("Sending PUBREC message (%" PRIuSIZE " bytes)...\r\n",
1344  context->message.length);
1345 
1346  //Dump the contents of the message for debugging purpose
1347  mqttSnDumpMessage(context->message.buffer, context->message.length);
1348 
1349  //Send MQTT-SN message
1350  error = mqttSnClientSendDatagram(context, context->message.buffer,
1351  context->message.length);
1352  }
1353 
1354  //Return status code
1355  return error;
1356 }
1357 
1358 
1359 /**
1360  * @brief Send PUBREL message
1361  * @param[in] context Pointer to the MQTT-SN client context
1362  * @param[in] msgId Message identifier of the corresponding PUBLISH message
1363  * @return Error code
1364  **/
1365 
1367 {
1368  error_t error;
1369  systime_t time;
1370 
1371  //Format PUBREL message
1372  error = mqttSnFormatPubRel(&context->message, msgId);
1373 
1374  //Check status code
1375  if(!error)
1376  {
1377  //Debug message
1378  TRACE_INFO("Sending PUBREL message (%" PRIuSIZE " bytes)...\r\n",
1379  context->message.length);
1380 
1381  //Dump the contents of the message for debugging purpose
1382  mqttSnDumpMessage(context->message.buffer, context->message.length);
1383 
1384  //Send MQTT-SN message
1385  error = mqttSnClientSendDatagram(context, context->message.buffer,
1386  context->message.length);
1387 
1388  //Get current time
1389  time = osGetSystemTime();
1390 
1391  //Save the time at which the message was sent
1392  context->retransmitStartTime = time;
1393  context->keepAliveTimestamp = time;
1394 
1395  //Update MQTT-SN client state
1396  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1397  context->msgType = MQTT_SN_MSG_TYPE_PUBREL;
1398  }
1399 
1400  //Return status code
1401  return error;
1402 }
1403 
1404 
1405 /**
1406  * @brief Send PUBCOMP message
1407  * @param[in] context Pointer to the MQTT-SN client context
1408  * @param[in] msgId Message identifier of the corresponding PUBLISH message
1409  * @return Error code
1410  **/
1411 
1413 {
1414  error_t error;
1415 
1416  //Format PUBCOMP message
1417  error = mqttSnFormatPubComp(&context->message, msgId);
1418 
1419  //Check status code
1420  if(!error)
1421  {
1422  //Debug message
1423  TRACE_INFO("Sending PUBCOMP message (%" PRIuSIZE " bytes)...\r\n",
1424  context->message.length);
1425 
1426  //Dump the contents of the message for debugging purpose
1427  mqttSnDumpMessage(context->message.buffer, context->message.length);
1428 
1429  //Send MQTT-SN message
1430  error = mqttSnClientSendDatagram(context, context->message.buffer,
1431  context->message.length);
1432  }
1433 
1434  //Return status code
1435  return error;
1436 }
1437 
1438 
1439 /**
1440  * @brief Send SUBSCRIBE message
1441  * @param[in] context Pointer to the MQTT-SN client context
1442  * @param[in] topicName Topic filter
1443  * @param[in] qos Maximum QoS level at which the server can send application
1444  * messages to the client
1445  * @return Error code
1446  **/
1447 
1450 {
1451  error_t error;
1452  systime_t time;
1453  uint16_t topicId;
1455 
1456  //Initialize status code
1457  error = NO_ERROR;
1458 
1459  //Reset unused flags
1460  flags.all = 0;
1461  //Set QoS level
1462  flags.qos = qos;
1463 
1464  //Check whether a predefined topic ID has been registered
1466 
1467  //Predefined topic ID found?
1469  {
1470  //The SUBSCRIBE message contains a predefined topic ID
1471  flags.topicIdType = MQTT_SN_PREDEFINED_TOPIC_ID;
1472  }
1473  else
1474  {
1475  //Short topic name?
1477  {
1478  //The SUBSCRIBE message contains a short topic name
1479  flags.topicIdType = MQTT_SN_SHORT_TOPIC_NAME;
1480  }
1481  else
1482  {
1483  //The SUBSCRIBE message contains a normal topic name
1484  flags.topicIdType = MQTT_SN_NORMAL_TOPIC_NAME;
1485  }
1486 
1487  //Format SUBSCRIBE message
1488  error = mqttSnFormatSubscribe(&context->message, flags,
1489  context->msgId, topicId, topicName);
1490  }
1491 
1492  //Check status code
1493  if(!error)
1494  {
1495  //Debug message
1496  TRACE_INFO("Sending SUBSCRIBE message (%" PRIuSIZE " bytes)...\r\n",
1497  context->message.length);
1498 
1499  //Dump the contents of the message for debugging purpose
1500  mqttSnDumpMessage(context->message.buffer, context->message.length);
1501 
1502  //Send MQTT-SN message
1503  error = mqttSnClientSendDatagram(context, context->message.buffer,
1504  context->message.length);
1505 
1506  //Get current time
1507  time = osGetSystemTime();
1508 
1509  //Save the time at which the message was sent
1510  context->retransmitStartTime = time;
1511  context->keepAliveTimestamp = time;
1512 
1513  //Update MQTT-SN client state
1514  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1515  context->msgType = MQTT_SN_MSG_TYPE_SUBSCRIBE;
1516  }
1517 
1518  //Return status code
1519  return error;
1520 }
1521 
1522 
1523 /**
1524  * @brief Send UNSUBSCRIBE message
1525  * @param[in] context Pointer to the MQTT-SN client context
1526  * @param[in] topicName Topic filter
1527  * @return Error code
1528  **/
1529 
1531  const char_t *topicName)
1532 {
1533  error_t error;
1534  systime_t time;
1535  uint16_t topicId;
1537 
1538  //Initialize status code
1539  error = NO_ERROR;
1540 
1541  //Reset unused flags
1542  flags.all = 0;
1543 
1544  //Check whether a predefined topic ID has been registered
1546 
1547  //Predefined topic ID found?
1549  {
1550  //The UNSUBSCRIBE message contains a predefined topic ID
1551  flags.topicIdType = MQTT_SN_PREDEFINED_TOPIC_ID;
1552  }
1553  else
1554  {
1555  //Short topic name?
1556  if(strlen(topicName) == 2 && strchr(topicName, '#') == NULL &&
1557  strchr(topicName, '+') == NULL)
1558  {
1559  //The UNSUBSCRIBE message contains a short topic name
1560  flags.topicIdType = MQTT_SN_SHORT_TOPIC_NAME;
1561  }
1562  else
1563  {
1564  //The UNSUBSCRIBE message contains a normal topic name
1565  flags.topicIdType = MQTT_SN_NORMAL_TOPIC_NAME;
1566  }
1567 
1568  //Format UNSUBSCRIBE message
1569  error = mqttSnFormatUnsubscribe(&context->message, flags,
1570  context->msgId, topicId, topicName);
1571  }
1572 
1573  //Check status code
1574  if(!error)
1575  {
1576  //Debug message
1577  TRACE_INFO("Sending UNSUBSCRIBE message (%" PRIuSIZE " bytes)...\r\n",
1578  context->message.length);
1579 
1580  //Dump the contents of the message for debugging purpose
1581  mqttSnDumpMessage(context->message.buffer, context->message.length);
1582 
1583  //Send MQTT-SN message
1584  error = mqttSnClientSendDatagram(context, context->message.buffer,
1585  context->message.length);
1586 
1587  //Get current time
1588  time = osGetSystemTime();
1589 
1590  //Save the time at which the message was sent
1591  context->retransmitStartTime = time;
1592  context->keepAliveTimestamp = time;
1593 
1594  //Update MQTT-SN client state
1595  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1596  context->msgType = MQTT_SN_MSG_TYPE_UNSUBSCRIBE;
1597  }
1598 
1599  //Return status code
1600  return error;
1601 }
1602 
1603 
1604 /**
1605  * @brief Send PINGREQ message
1606  * @param[in] context Pointer to the MQTT-SN client context
1607  * @return Error code
1608  **/
1609 
1611 {
1612  error_t error;
1613 
1614  //Format PINGREQ message
1615  error = mqttSnFormatPingReq(&context->message, context->clientId);
1616 
1617  //Check status code
1618  if(!error)
1619  {
1620  //Debug message
1621  TRACE_INFO("Sending PINGREQ message (%" PRIuSIZE " bytes)...\r\n",
1622  context->message.length);
1623 
1624  //Dump the contents of the message for debugging purpose
1625  mqttSnDumpMessage(context->message.buffer, context->message.length);
1626 
1627  //Send MQTT-SN message
1628  error = mqttSnClientSendDatagram(context, context->message.buffer,
1629  context->message.length);
1630 
1631  //Save the time at which the message was sent
1632  context->keepAliveTimestamp = osGetSystemTime();
1633  }
1634 
1635  //Return status code
1636  return error;
1637 }
1638 
1639 
1640 /**
1641  * @brief Send PINGRESP message
1642  * @param[in] context Pointer to the MQTT-SN client context
1643  * @return Error code
1644  **/
1645 
1647 {
1648  error_t error;
1649 
1650  //Format PINGRESP message
1651  error = mqttSnFormatPingResp(&context->message);
1652 
1653  //Check status code
1654  if(!error)
1655  {
1656  //Debug message
1657  TRACE_INFO("Sending PINGRESP message (%" PRIuSIZE " bytes)...\r\n",
1658  context->message.length);
1659 
1660  //Dump the contents of the message for debugging purpose
1661  mqttSnDumpMessage(context->message.buffer, context->message.length);
1662 
1663  //Send MQTT-SN message
1664  error = mqttSnClientSendDatagram(context, context->message.buffer,
1665  context->message.length);
1666  }
1667 
1668  //Return status code
1669  return error;
1670 }
1671 
1672 
1673 /**
1674  * @brief Send DISCONNECT message
1675  * @param[in] context Pointer to the MQTT-SN client context
1676  * @param[in] duration Value of the sleep timer
1677  * @return Error code
1678  **/
1679 
1681  uint16_t duration)
1682 {
1683  error_t error;
1684 
1685  //Format DISCONNECT message
1686  error = mqttSnFormatDisconnect(&context->message, duration);
1687 
1688  //Check status code
1689  if(!error)
1690  {
1691  //Debug message
1692  TRACE_INFO("Sending DISCONNECT message (%" PRIuSIZE " bytes)...\r\n",
1693  context->message.length);
1694 
1695  //Dump the contents of the message for debugging purpose
1696  mqttSnDumpMessage(context->message.buffer, context->message.length);
1697 
1698  //Send MQTT-SN message
1699  error = mqttSnClientSendDatagram(context, context->message.buffer,
1700  context->message.length);
1701 
1702  //Save the time at which the message was sent
1703  context->retransmitStartTime = osGetSystemTime();
1704 
1705  //Update MQTT-SN client state
1706  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1707  context->msgType = MQTT_SN_MSG_TYPE_DISCONNECT;
1708  }
1709 
1710  //Return status code
1711  return error;
1712 }
1713 
1714 
1715 /**
1716  * @brief Send WILLTOPICUPD message
1717  * @param[in] context Pointer to the MQTT-SN client context
1718  * @return Error code
1719  **/
1720 
1722 {
1723  error_t error;
1724  systime_t time;
1725 
1726  //Format WILLTOPICUPD message
1727  error = mqttSnFormatWillTopicUpd(&context->message,
1728  context->willMessage.flags, context->willMessage.topic);
1729 
1730  //Check status code
1731  if(!error)
1732  {
1733  //Debug message
1734  TRACE_INFO("Sending WILLTOPICUPD message (%" PRIuSIZE " bytes)...\r\n",
1735  context->message.length);
1736 
1737  //Dump the contents of the message for debugging purpose
1738  mqttSnDumpMessage(context->message.buffer, context->message.length);
1739 
1740  //Send MQTT-SN message
1741  error = mqttSnClientSendDatagram(context, context->message.buffer,
1742  context->message.length);
1743 
1744  //Get current time
1745  time = osGetSystemTime();
1746 
1747  //Save the time at which the message was sent
1748  context->retransmitStartTime = time;
1749  context->keepAliveTimestamp = time;
1750 
1751  //Update MQTT-SN client state
1752  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1753  context->msgType = MQTT_SN_MSG_TYPE_WILLTOPICUPD;
1754  }
1755 
1756  //Return status code
1757  return error;
1758 }
1759 
1760 
1761 /**
1762  * @brief Send WILLMSGUPD message
1763  * @param[in] context Pointer to the MQTT-SN client context
1764  * @return Error code
1765  **/
1766 
1768 {
1769  error_t error;
1770  systime_t time;
1771 
1772  //Format WILLMSGUPD message
1773  error = mqttSnFormatWillMsgUpd(&context->message,
1774  context->willMessage.payload, context->willMessage.length);
1775 
1776  //Check status code
1777  if(!error)
1778  {
1779  //Debug message
1780  TRACE_INFO("Sending WILLMSGUPD message (%" PRIuSIZE " bytes)...\r\n",
1781  context->message.length);
1782 
1783  //Dump the contents of the message for debugging purpose
1784  mqttSnDumpMessage(context->message.buffer, context->message.length);
1785 
1786  //Send MQTT-SN message
1787  error = mqttSnClientSendDatagram(context, context->message.buffer,
1788  context->message.length);
1789 
1790  //Get current time
1791  time = osGetSystemTime();
1792 
1793  //Save the time at which the message was sent
1794  context->retransmitStartTime = time;
1795  context->keepAliveTimestamp = time;
1796 
1797  //Update MQTT-SN client state
1798  context->state = MQTT_SN_CLIENT_STATE_SENDING_REQ;
1799  context->msgType = MQTT_SN_MSG_TYPE_WILLMSGUPD;
1800  }
1801 
1802  //Return status code
1803  return error;
1804 }
1805 
1806 #endif
uint8_t returnCode
MQTT-SN message formatting and parsing.
error_t mqttSnClientSendWillTopic(MqttSnClientContext *context)
Send WILLTOPIC message.
error_t mqttSnClientSendRegAck(MqttSnClientContext *context, uint16_t msgId, uint16_t topicId, MqttSnReturnCode returnCode)
Send REGACK message.
error_t mqttSnFormatSearchGw(MqttSnMessage *message, uint8_t radius)
Format SEARCHGW message.
uint32_t systime_t
Definition: compiler_port.h:44
error_t mqttSnParseConnAck(const MqttSnMessage *message, MqttSnReturnCode *returnCode)
Parse CONNACK message.
error_t mqttSnFormatUnsubscribe(MqttSnMessage *message, MqttSnFlags flags, uint16_t msgId, uint16_t topicId, const char_t *topicName)
Format UNSUBSCRIBE message.
error_t mqttSnParseWillTopicResp(const MqttSnMessage *message, MqttSnReturnCode *returnCode)
Parse WILLTOPICRESP message.
uint16_t destPort
Definition: tcp.h:301
char char_t
Definition: compiler_port.h:41
uint8_t flags
Definition: tcp.h:312
error_t mqttSnParsePingReq(const MqttSnMessage *message, const char_t **clientId)
Parse PINGREQ message.
error_t mqttSnFormatPingResp(MqttSnMessage *message)
Format PINGRESP message.
Exactly once delivery.
error_t mqttSnParsePubRec(const MqttSnMessage *message, uint16_t *msgId)
Parse PUBREC message.
At least once delivery.
systime_t osGetSystemTime(void)
Retrieve system time.
uint32_t time
error_t mqttSnClientProcessDisconnect(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming DISCONNECT message.
TCP/IP stack core.
uint8_t radius
error_t mqttSnFormatWillMsg(MqttSnMessage *message, const void *data, size_t dataLen)
Format WILLMSG message.
Short topic name.
error_t mqttSnParseWillMsgResp(const MqttSnMessage *message, MqttSnReturnCode *returnCode)
Parse WILLMSGRESP message.
Predefined topic ID.
Debugging facilities.
error_t mqttSnParseWillMsgReq(const MqttSnMessage *message)
Parse WILLMSGREQ message.
error_t mqttSnClientProcessPublish(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming PUBLISH message.
error_t mqttSnClientSendPubComp(MqttSnClientContext *context, uint16_t msgId)
Send PUBCOMP message.
error_t mqttSnClientProcessMessage(MqttSnClientContext *context, MqttSnMessage *message, const IpAddr *ipAddr, uint16_t port)
Process incoming MQTT-SN message.
uint8_t message[]
Definition: chap.h:150
error_t mqttSnClientProcessWillMsgResp(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming WILLMSGRESP message.
error_t mqttSnClientProcessUnsubAck(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming UNSUBACK message.
error_t mqttSnFormatRegister(MqttSnMessage *message, uint16_t msgId, uint16_t topicId, const char_t *topicName)
Format REGISTER message.
Transport protocol abstraction layer.
uint8_t gwId
error_t mqttSnClientProcessRegAck(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming REGACK message.
error_t mqttSnClientSendDatagram(MqttSnClientContext *context, const void *data, size_t length)
Send a datagram.
MQTT-SN message.
error_t mqttSnParseRegAck(const MqttSnMessage *message, uint16_t *msgId, uint16_t *topicId, MqttSnReturnCode *returnCode)
Parse REGACK message.
IP network address.
Definition: ip.h:57
error_t mqttSnClientAddTopic(MqttSnClientContext *context, const char_t *topicName, uint16_t topicId)
Add a new entry to the topic table.
Normal topic name.
error_t mqttSnFormatPubRel(MqttSnMessage *message, uint16_t msgId)
Format PUBREL message.
MqttSnQosLevel
Quality of service level.
MQTT-SN message parsing and formatting.
error_t mqttSnClientStoreMessageId(MqttSnClientContext *context, uint16_t msgId)
Store message ID (QoS 2 message processing)
char_t type
error_t mqttSnParseRegister(const MqttSnMessage *message, uint16_t *msgId, uint16_t *topicId, const char_t **topicName)
Parse REGISTER message.
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:99
uint16_t msgId
error_t mqttSnFormatPubRec(MqttSnMessage *message, uint16_t msgId)
Format PUBREC message.
error_t mqttSnClientSendPingResp(MqttSnClientContext *context)
Send PINGRESP message.
error_t mqttSnClientProcessRegister(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming REGISTER message.
error_t mqttSnClientSendWillMsgUpd(MqttSnClientContext *context)
Send WILLMSGUPD message.
MqttSnMsgType
MQTT-SN message types.
uint16_t duration
error_t mqttSnClientProcessPubComp(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming PUBCOMP message.
error_t mqttSnFormatSubscribe(MqttSnMessage *message, MqttSnFlags flags, uint16_t msgId, uint16_t topicId, const char_t *topicName)
Format SUBSCRIBE message.
uint8_t qos
Definition: mqtt_common.h:177
#define TRUE
Definition: os_port.h:48
error_t mqttSnClientSendPubAck(MqttSnClientContext *context, uint16_t msgId, uint16_t topicId, MqttSnReturnCode returnCode)
Send PUBACK message.
error_t mqttSnClientSendRegister(MqttSnClientContext *context, const char_t *topicName)
Send REGISTER message.
uint8_t ipAddr[4]
Definition: mib_common.h:185
error_t mqttSnClientSendPingReq(MqttSnClientContext *context)
Send PINGREQ message.
Normal topic ID.
error_t mqttSnClientSendWillTopicUpd(MqttSnClientContext *context)
Send WILLTOPICUPD message.
bool_t mqttSnClientIsDuplicateMessageId(MqttSnClientContext *context, uint16_t msgId)
Check whether the message ID is a duplicate (QoS 2 message processing)
#define MqttSnClientContext
error_t mqttSnParseUnsubAck(const MqttSnMessage *message, uint16_t *msgId)
Parse UNSUBACK message.
error_t mqttSnParsePubAck(const MqttSnMessage *message, uint16_t *msgId, uint16_t *topicId, MqttSnReturnCode *returnCode)
Parse PUBACK message.
uint16_t mqttSnClientFindPredefTopicName(MqttSnClientContext *context, const char_t *topicName)
Retrieve the topic ID associated with a predefined topic name.
error_t mqttSnClientSendPubRec(MqttSnClientContext *context, uint16_t msgId)
Send PUBREC message.
error_t mqttSnClientSendDisconnect(MqttSnClientContext *context, uint16_t duration)
Send DISCONNECT message.
error_t mqttSnClientSendPublish(MqttSnClientContext *context, uint16_t msgId, const char_t *topicName, const uint8_t *data, size_t length, MqttSnQosLevel qos, bool_t retain, bool_t dup)
Send PUBLISH message.
uint8_t cleanSession
error_t mqttSnParsePubRel(const MqttSnMessage *message, uint16_t *msgId)
Parse PUBREL message.
error_t mqttSnClientSendConnect(MqttSnClientContext *context, bool_t cleanSession)
Send CONNECT message.
error_t mqttSnFormatWillTopicUpd(MqttSnMessage *message, MqttSnFlags flags, const char_t *topicName)
Format WILLTOPICUPD message.
char_t clientId[]
error_t mqttSnClientProcessWillMsgReq(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming WILLMSGREQ message.
error_t mqttSnClientProcessPubRec(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming PUBREC message.
error_t mqttSnClientProcessConnAck(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming CONNACK message.
char_t topicName[]
error_t mqttSnFormatPublish(MqttSnMessage *message, MqttSnFlags flags, uint16_t msgId, uint16_t topicId, const char_t *topicName, const uint8_t *data, size_t dataLen)
Format PUBLISH message.
error_t mqttSnParseHeader(MqttSnMessage *message, MqttSnMsgType *type)
Format MQTT-SN message header.
#define MQTT_SN_INVALID_TOPIC_ID
error_t mqttSnClientProcessSubAck(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming SUBACK message.
MqttSnReturnCode mqttSnDeliverPublishMessage(MqttSnClientContext *context, MqttSnFlags flags, uint16_t topicId, const uint8_t *data, size_t dataLen)
Deliver a PUBLISH message to the application.
error_t mqttSnFormatWillTopic(MqttSnMessage *message, MqttSnFlags flags, const char_t *topicName)
Format WILLTOPIC message.
error_t mqttSnClientProcessPubAck(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming PUBACK message.
error_t mqttSnParseDisconnect(const MqttSnMessage *message, uint16_t *duration)
Parse DISCONNECT message.
error_t mqttSnClientProcessWillTopicReq(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming WILLTOPICREQ message.
uint16_t topicId
error_t mqttSnClientSendWillMsg(MqttSnClientContext *context)
Send WILLMSG message.
error_t mqttSnClientSendUnsubscribe(MqttSnClientContext *context, const char_t *topicName)
Send UNSUBSCRIBE message.
#define TRACE_INFO(...)
Definition: debug.h:86
Success.
Definition: error.h:42
error_t mqttSnFormatWillMsgUpd(MqttSnMessage *message, const void *data, size_t dataLen)
Format WILLMSGUPD message.
error_t mqttSnFormatRegAck(MqttSnMessage *message, uint16_t msgId, uint16_t topicId, MqttSnReturnCode returnCode)
Format REGACK message.
__start_packed struct @235 MqttSnFlags
MQTT-SN flags.
error_t
Error codes.
Definition: error.h:40
uint8_t retain
Definition: mqtt_common.h:176
#define TRACE_WARNING(...)
Definition: debug.h:78
error_t mqttSnClientSendSubscribe(MqttSnClientContext *context, const char_t *topicName, MqttSnQosLevel qos)
Send SUBSCRIBE message.
Ipv4Addr destIpAddr
Definition: ipcp.h:76
error_t mqttSnFormatPingReq(MqttSnMessage *message, const char_t *clientId)
Format PINGREQ message.
uint16_t mqttSnClientFindTopicName(MqttSnClientContext *context, const char_t *topicName)
Retrieve the topic ID associated with a given topic name.
error_t mqttSnDumpMessage(const uint8_t *message, size_t length)
Dump MQTT-SN message for debugging purpose.
Definition: mqtt_sn_debug.c:93
uint8_t data[]
Definition: dtls_misc.h:167
#define PRIuSIZE
Definition: compiler_port.h:72
error_t mqttSnFormatConnect(MqttSnMessage *message, MqttSnFlags flags, uint16_t duration, const char_t *clientId)
Format CONNECT message.
MqttSnReturnCode
MQTT-SN return codes.
error_t mqttSnClientProcessWillTopicResp(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming WILLTOPICRESP message.
error_t mqttSnParseGwInfo(const MqttSnMessage *message, uint8_t *gwId, const uint8_t **gwAdd, size_t *gwAddLen)
Parse GWINFO message.
error_t mqttSnClientDiscardMessageId(MqttSnClientContext *context, uint16_t msgId)
Discard message ID (QoS 2 message processing)
uint16_t port
Definition: dns_common.h:221
error_t mqttSnParseSubAck(const MqttSnMessage *message, MqttSnFlags *flags, uint16_t *msgId, uint16_t *topicId, MqttSnReturnCode *returnCode)
Parse SUBACK message.
Data logging functions for debugging purpose (MQTT-SN)
uint8_t dup
Definition: mqtt_common.h:178
error_t mqttSnClientProcessPingResp(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming PINGRESP message.
error_t mqttSnFormatDisconnect(MqttSnMessage *message, uint16_t duration)
Format DISCONNECT message.
error_t mqttSnParseWillTopicReq(const MqttSnMessage *message)
Parse WILLTOPICREQ message.
error_t mqttSnClientProcessPubRel(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming PUBREL message.
error_t mqttSnFormatPubAck(MqttSnMessage *message, uint16_t msgId, uint16_t topicId, MqttSnReturnCode returnCode)
Format PUBACK message.
bool_t mqttSnClientIsShortTopicName(const char_t *topicName)
Check whether a topic name is a short topic name.
error_t mqttSnClientProcessPingReq(MqttSnClientContext *context, const MqttSnMessage *message)
Process incoming PINGREQ message.
MQTT-SN client.
const char_t * mqttSnGetMessageName(uint16_t msgType)
Get the name of the specified MQTT-SN message.
error_t mqttSnClientBroadcastDatagram(MqttSnClientContext *context, const IpAddr *destIpAddr, uint16_t destPort, const void *data, size_t length)
Broadcast a datagram.
error_t mqttSnClientProcessGwInfo(MqttSnClientContext *context, const MqttSnMessage *message, const IpAddr *ipAddr, uint16_t port)
Process incoming GWINFO message.
uint8_t length
Definition: dtls_misc.h:140
error_t mqttSnFormatPubComp(MqttSnMessage *message, uint16_t msgId)
Format PUBCOMP message.
Helper functions for MQTT-SN client.
error_t mqttSnParsePubComp(const MqttSnMessage *message, uint16_t *msgId)
Parse PUBCOMP message.
error_t mqttSnParsePublish(const MqttSnMessage *message, MqttSnFlags *flags, uint16_t *msgId, uint16_t *topicId, const uint8_t **data, size_t *dataLen)
Parse PUBLISH message.
int bool_t
Definition: compiler_port.h:47
error_t mqttSnClientSendSearchGw(MqttSnClientContext *context, uint8_t radius, const IpAddr *destIpAddr, uint16_t destPort)
Send SEARCHGW message.
uint8_t gwAdd[]
error_t mqttSnClientSendPubRel(MqttSnClientContext *context, uint16_t msgId)
Send PUBREL message.
error_t mqttSnParsePingResp(const MqttSnMessage *message)
Parse PINGRESP message.