@@ -643,6 +643,128 @@ static void mqtt_sn_do_ping(struct mqtt_sn_client *client)
643
643
}
644
644
}
645
645
646
+ static void mqtt_sn_do_will_topic_update (struct mqtt_sn_client * client )
647
+ {
648
+ struct mqtt_sn_param p = {.type = MQTT_SN_MSG_TYPE_WILLTOPICUPD };
649
+
650
+ if (client == NULL ) {
651
+ return ;
652
+ }
653
+
654
+ if (client -> state != MQTT_SN_CLIENT_ACTIVE ) {
655
+ LOG_ERR ("Cannot update will topic: not connected" );
656
+ return ;
657
+ }
658
+
659
+ LOG_INF ("Updating will topic" );
660
+
661
+ p .params .willtopicupd .topic .data = client -> will_topic .data ;
662
+ p .params .willtopicupd .topic .size = client -> will_topic .size ;
663
+ p .params .willtopicupd .retain = client -> will_retain ;
664
+ p .params .willtopicupd .qos = client -> will_qos ;
665
+
666
+ encode_and_send (client , & p , 0 );
667
+ }
668
+
669
+ static void mqtt_sn_do_will_message_update (struct mqtt_sn_client * client )
670
+ {
671
+ struct mqtt_sn_param p = {.type = MQTT_SN_MSG_TYPE_WILLMSGUPD };
672
+
673
+ if (client == NULL ) {
674
+ return ;
675
+ }
676
+
677
+ if (client -> state != MQTT_SN_CLIENT_ACTIVE ) {
678
+ LOG_ERR ("Cannot update will message: not connected" );
679
+ return ;
680
+ }
681
+
682
+ LOG_INF ("Updating will message" );
683
+
684
+ p .params .willmsgupd .msg .data = client -> will_msg .data ;
685
+ p .params .willmsgupd .msg .size = client -> will_msg .size ;
686
+
687
+ encode_and_send (client , & p , 0 );
688
+ }
689
+
690
+ static int process_will_topic_update (struct mqtt_sn_client * client , int64_t * next_cycle )
691
+ {
692
+ const int64_t now = k_uptime_get ();
693
+ int64_t next_attempt ;
694
+
695
+ if (!client -> will_topic_update .in_progress ) {
696
+ return 0 ;
697
+ }
698
+
699
+ if (now == 0 ) {
700
+ next_attempt = 1 ;
701
+ } else if (client -> will_topic_update .last_attempt == 0 ) {
702
+ next_attempt = 0 ;
703
+ } else {
704
+ next_attempt = client -> will_topic_update .last_attempt + T_RETRY_MSEC ;
705
+ }
706
+
707
+ if (next_attempt <= now ) {
708
+ if (client -> will_topic_update .retries -- == 0 ) {
709
+ LOG_WRN ("Will topic update ran out of retries" );
710
+ client -> will_topic_update .in_progress = false;
711
+ mqtt_sn_disconnect_internal (client );
712
+ return - ETIMEDOUT ;
713
+ }
714
+
715
+ LOG_DBG ("Sending WILLTOPICUPD" );
716
+ mqtt_sn_do_will_topic_update (client );
717
+ client -> will_topic_update .last_attempt = now ;
718
+ next_attempt = now + T_RETRY_MSEC ;
719
+ }
720
+
721
+ if (* next_cycle == 0 || next_attempt < * next_cycle ) {
722
+ * next_cycle = next_attempt ;
723
+ }
724
+ LOG_DBG ("next_cycle: %lld" , * next_cycle );
725
+
726
+ return 0 ;
727
+ }
728
+
729
+ static int process_will_message_update (struct mqtt_sn_client * client , int64_t * next_cycle )
730
+ {
731
+ const int64_t now = k_uptime_get ();
732
+ int64_t next_attempt ;
733
+
734
+ if (!client -> will_message_update .in_progress ) {
735
+ return 0 ;
736
+ }
737
+
738
+ if (now == 0 ) {
739
+ next_attempt = 1 ;
740
+ } else if (client -> will_message_update .last_attempt == 0 ) {
741
+ next_attempt = 0 ;
742
+ } else {
743
+ next_attempt = client -> will_message_update .last_attempt + T_RETRY_MSEC ;
744
+ }
745
+
746
+ if (next_attempt <= now ) {
747
+ if (client -> will_message_update .retries -- == 0 ) {
748
+ LOG_WRN ("Will message update ran out of retries" );
749
+ client -> will_message_update .in_progress = false;
750
+ mqtt_sn_disconnect_internal (client );
751
+ return - ETIMEDOUT ;
752
+ }
753
+
754
+ LOG_DBG ("Sending WILLMSGUPD" );
755
+ mqtt_sn_do_will_message_update (client );
756
+ client -> will_message_update .last_attempt = now ;
757
+ next_attempt = now + T_RETRY_MSEC ;
758
+ }
759
+
760
+ if (* next_cycle == 0 || next_attempt < * next_cycle ) {
761
+ * next_cycle = next_attempt ;
762
+ }
763
+ LOG_DBG ("next_cycle: %lld" , * next_cycle );
764
+
765
+ return 0 ;
766
+ }
767
+
646
768
/**
647
769
* @brief Process all publish tasks in the queue.
648
770
*
@@ -997,6 +1119,16 @@ static void process_work(struct k_work *wrk)
997
1119
}
998
1120
999
1121
if (client -> state == MQTT_SN_CLIENT_ACTIVE ) {
1122
+ err = process_will_topic_update (client , & next_cycle );
1123
+ if (err ) {
1124
+ return ;
1125
+ }
1126
+
1127
+ err = process_will_message_update (client , & next_cycle );
1128
+ if (err ) {
1129
+ return ;
1130
+ }
1131
+
1000
1132
err = process_topics (client , & next_cycle );
1001
1133
if (err ) {
1002
1134
return ;
@@ -1599,6 +1731,35 @@ static void handle_disconnect(struct mqtt_sn_client *client, struct mqtt_sn_para
1599
1731
mqtt_sn_disconnect_internal (client );
1600
1732
}
1601
1733
1734
+ static void handle_willtopicresp (struct mqtt_sn_client * client ,
1735
+ struct mqtt_sn_param_willtopicresp * p )
1736
+ {
1737
+ if (!client -> will_topic_update .in_progress ) {
1738
+ LOG_ERR ("There's no will topic update in progress" );
1739
+ return ;
1740
+ }
1741
+
1742
+ if (p -> ret_code == MQTT_SN_CODE_ACCEPTED ) {
1743
+ client -> will_topic_update .in_progress = false;
1744
+ } else {
1745
+ LOG_WRN ("WILLTOPICRESP with ret code %d" , p -> ret_code );
1746
+ }
1747
+ }
1748
+
1749
+ static void handle_willmsgresp (struct mqtt_sn_client * client , struct mqtt_sn_param_willmsgresp * p )
1750
+ {
1751
+ if (!client -> will_message_update .in_progress ) {
1752
+ LOG_ERR ("There's no will message update in progress" );
1753
+ return ;
1754
+ }
1755
+
1756
+ if (p -> ret_code == MQTT_SN_CODE_ACCEPTED ) {
1757
+ client -> will_message_update .in_progress = false;
1758
+ } else {
1759
+ LOG_WRN ("WILLMSGRESP with ret code %d" , p -> ret_code );
1760
+ }
1761
+ }
1762
+
1602
1763
static int handle_msg (struct mqtt_sn_client * client , struct mqtt_sn_data rx_addr )
1603
1764
{
1604
1765
int err ;
@@ -1667,8 +1828,10 @@ static int handle_msg(struct mqtt_sn_client *client, struct mqtt_sn_data rx_addr
1667
1828
handle_disconnect (client , & p .params .disconnect );
1668
1829
break ;
1669
1830
case MQTT_SN_MSG_TYPE_WILLTOPICRESP :
1831
+ handle_willtopicresp (client , & p .params .willtopicresp );
1670
1832
break ;
1671
1833
case MQTT_SN_MSG_TYPE_WILLMSGRESP :
1834
+ handle_willmsgresp (client , & p .params .willmsgresp );
1672
1835
break ;
1673
1836
default :
1674
1837
LOG_ERR ("Unexpected message type %d" , p .type );
@@ -1775,3 +1938,37 @@ int mqtt_sn_predefine_topic(struct mqtt_sn_client *client, uint16_t topic_id,
1775
1938
return 0 ;
1776
1939
1777
1940
}
1941
+
1942
+ static int attempt_will_update (struct mqtt_sn_client * client , struct mqtt_sn_will_update * state )
1943
+ {
1944
+ int err ;
1945
+
1946
+ if (client -> state != MQTT_SN_CLIENT_ACTIVE ) {
1947
+ return - ENOTCONN ;
1948
+ }
1949
+
1950
+ if (state -> in_progress ) {
1951
+ return - EALREADY ;
1952
+ }
1953
+
1954
+ state -> retries = N_RETRY ;
1955
+ state -> last_attempt = 0 ;
1956
+ state -> in_progress = true;
1957
+
1958
+ err = k_work_reschedule (& client -> process_work , K_NO_WAIT );
1959
+ if (err < 0 ) {
1960
+ return err ;
1961
+ }
1962
+
1963
+ return 0 ;
1964
+ }
1965
+
1966
+ int mqtt_sn_update_will_topic (struct mqtt_sn_client * client )
1967
+ {
1968
+ return attempt_will_update (client , & client -> will_topic_update );
1969
+ }
1970
+
1971
+ int mqtt_sn_update_will_message (struct mqtt_sn_client * client )
1972
+ {
1973
+ return attempt_will_update (client , & client -> will_message_update );
1974
+ }
0 commit comments