2727
2828#if defined(CONFIG_APP_POWER )
2929#include "power.h"
30- #define BAT_MSG_SIZE sizeof(struct power_msg)
30+ #define POWER_MSG_SIZE sizeof(struct power_msg)
3131#else
32- #define BAT_MSG_SIZE 0
32+ #define POWER_MSG_SIZE 0
3333#endif /* CONFIG_APP_POWER */
3434
3535/* Register log module */
3636LOG_MODULE_REGISTER (main , CONFIG_APP_LOG_LEVEL );
3737
3838#define MAX_MSG_SIZE (MAX(sizeof(struct configuration), \
3939 MAX(sizeof(struct cloud_payload), \
40- MAX(sizeof(struct network_msg), BAT_MSG_SIZE))))
40+ /* Button channel payload size */ \
41+ MAX (sizeof (uint8_t ), \
42+ /* Timer channel payload size */ \
43+ MAX (sizeof (int ), \
44+ MAX (sizeof (enum fota_msg_type ), \
45+ MAX (sizeof (enum location_msg_type ), \
46+ MAX (sizeof (struct network_msg ), POWER_MSG_SIZE ))))))))
4147
4248/* Register subscriber */
4349ZBUS_MSG_SUBSCRIBER_DEFINE (main_subscriber );
@@ -87,8 +93,11 @@ static void fota_run(void *o);
8793
8894static void fota_downloading_run (void * o );
8995
90- static void fota_network_disconnect_entry (void * o );
91- static void fota_network_disconnect_run (void * o );
96+ static void fota_waiting_for_network_disconnect_entry (void * o );
97+ static void fota_waiting_for_network_disconnect_run (void * o );
98+
99+ static void fota_waiting_for_network_disconnect_to_apply_image_entry (void * o );
100+ static void fota_waiting_for_network_disconnect_to_apply_image_run (void * o );
92101
93102static void fota_applying_image_entry (void * o );
94103static void fota_applying_image_run (void * o );
@@ -111,7 +120,11 @@ enum state {
111120 /* FOTA image is being downloaded */
112121 STATE_FOTA_DOWNLOADING ,
113122 /* Disconnecting from the network */
114- STATE_FOTA_NETWORK_DISCONNECT ,
123+ STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT ,
124+ /* Waiting for network disconnect to apply the image, state needed for
125+ * Full Modem FOTA. Extra step needed to apply the image before rebooting.
126+ */
127+ STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT_TO_APPLY_IMAGE ,
115128 /* Applying the image */
116129 STATE_FOTA_APPLYING_IMAGE ,
117130 /* Rebooting */
@@ -134,23 +147,8 @@ struct main_state {
134147 /* Trigger interval */
135148 uint64_t interval_sec ;
136149
137- /* Button number */
138- uint8_t button_number ;
139-
140- /* Time available */
141- enum time_status time_status ;
142-
143- /* Cloud status */
144- enum cloud_msg_type status ;
145-
146- /* FOTA status */
147- enum fota_msg_type fota_status ;
148-
149- /* Network status */
150- enum network_msg_type network_status ;
151-
152- /* Location status */
153- enum location_msg_type location_status ;
150+ /* Cloud connection status */
151+ bool connected ;
154152};
155153
156154/* Construct state table */
@@ -204,9 +202,16 @@ static const struct smf_state states[] = {
204202 & states [STATE_FOTA ],
205203 NULL
206204 ),
207- [STATE_FOTA_NETWORK_DISCONNECT ] = SMF_CREATE_STATE (
208- fota_network_disconnect_entry ,
209- fota_network_disconnect_run ,
205+ [STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT ] = SMF_CREATE_STATE (
206+ fota_waiting_for_network_disconnect_entry ,
207+ fota_waiting_for_network_disconnect_run ,
208+ NULL ,
209+ & states [STATE_FOTA ],
210+ NULL
211+ ),
212+ [STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT_TO_APPLY_IMAGE ] = SMF_CREATE_STATE (
213+ fota_waiting_for_network_disconnect_to_apply_image_entry ,
214+ fota_waiting_for_network_disconnect_to_apply_image_run ,
210215 NULL ,
211216 & states [STATE_FOTA ],
212217 NULL
@@ -327,9 +332,7 @@ static void running_entry(void *o)
327332
328333 LOG_DBG ("%s" , __func__ );
329334
330- if (state_object -> status == CLOUD_CONNECTED_READY_TO_SEND ||
331- state_object -> status == CLOUD_PAYLOAD_JSON ||
332- state_object -> status == CLOUD_POLL_SHADOW ) {
335+ if (state_object -> connected ) {
333336 smf_set_state (SMF_CTX (state_object ), & states [STATE_TRIGGERING ]);
334337 return ;
335338 }
@@ -341,10 +344,13 @@ static void running_run(void *o)
341344{
342345 const struct main_state * state_object = (const struct main_state * )o ;
343346
344- if (state_object -> chan == & FOTA_CHAN &&
345- state_object -> fota_status == FOTA_DOWNLOADING_UPDATE ) {
346- smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA ]);
347- return ;
347+ if (state_object -> chan == & FOTA_CHAN ) {
348+ enum fota_msg_type msg = MSG_TO_FOTA_TYPE (state_object -> msg_buf );
349+
350+ if (msg == FOTA_DOWNLOADING_UPDATE ) {
351+ smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA ]);
352+ return ;
353+ }
348354 }
349355}
350356
@@ -382,12 +388,16 @@ static void idle_entry(void *o)
382388
383389static void idle_run (void * o )
384390{
385- const struct main_state * state_object = ( const struct main_state * ) o ;
391+ struct main_state * state_object = o ;
386392
387- if ((state_object -> chan == & CLOUD_CHAN ) &&
388- (state_object -> status == CLOUD_CONNECTED_READY_TO_SEND )) {
389- smf_set_state (SMF_CTX (state_object ), & states [STATE_TRIGGERING ]);
390- return ;
393+ if (state_object -> chan == & CLOUD_CHAN ) {
394+ struct cloud_msg msg = MSG_TO_CLOUD_MSG (state_object -> msg_buf );
395+
396+ if (msg .type == CLOUD_CONNECTED_READY_TO_SEND ) {
397+ state_object -> connected = true;
398+ smf_set_state (SMF_CTX (state_object ), & states [STATE_TRIGGERING ]);
399+ return ;
400+ }
391401 }
392402}
393403
@@ -425,19 +435,30 @@ static void triggering_entry(void *o)
425435
426436static void triggering_run (void * o )
427437{
428- const struct main_state * state_object = ( const struct main_state * ) o ;
438+ struct main_state * state_object = o ;
429439
430- if ((state_object -> chan == & CLOUD_CHAN ) &&
431- ((state_object -> status == CLOUD_CONNECTED_PAUSED ) ||
432- (state_object -> status == CLOUD_DISCONNECTED ))) {
433- smf_set_state (SMF_CTX (state_object ), & states [STATE_IDLE ]);
434- return ;
440+ if ((state_object -> chan == & CLOUD_CHAN )) {
441+ struct cloud_msg msg = MSG_TO_CLOUD_MSG (state_object -> msg_buf );
442+
443+ if ((msg .type == CLOUD_CONNECTED_PAUSED ) ||
444+ (msg .type == CLOUD_DISCONNECTED )) {
445+ state_object -> connected = false;
446+ smf_set_state (SMF_CTX (state_object ), & states [STATE_IDLE ]);
447+ return ;
448+ }
435449 }
436450
437451 if (state_object -> chan == & CONFIG_CHAN ) {
438- LOG_DBG ("Configuration update, new interval: %lld" , state_object -> interval_sec );
439- k_work_reschedule (& trigger_work , K_SECONDS (state_object -> interval_sec ));
440- return ;
452+ struct configuration config = MSG_TO_CONFIGURATION (state_object -> msg_buf );
453+
454+ if (config .config_present ) {
455+ LOG_DBG ("Configuration update, new interval: %lld" , config .update_interval );
456+
457+ state_object -> interval_sec = config .update_interval ;
458+
459+ k_work_reschedule (& trigger_work , K_SECONDS (state_object -> interval_sec ));
460+ return ;
461+ }
441462 }
442463}
443464
@@ -464,10 +485,13 @@ static void requesting_location_run(void *o)
464485{
465486 const struct main_state * state_object = (const struct main_state * )o ;
466487
467- if (state_object -> chan == & LOCATION_CHAN &&
468- (state_object -> location_status == LOCATION_SEARCH_DONE )) {
469- smf_set_state (SMF_CTX (state_object ), & states [STATE_REQUESTING_SENSORS_AND_POLLING ]);
470- return ;
488+ if (state_object -> chan == & LOCATION_CHAN ) {
489+ enum location_msg_type msg = MSG_TO_LOCATION_TYPE (state_object -> msg_buf );
490+
491+ if (msg == LOCATION_SEARCH_DONE ) {
492+ smf_set_state (SMF_CTX (state_object ), & states [STATE_REQUESTING_SENSORS_AND_POLLING ]);
493+ return ;
494+ }
471495 }
472496
473497 if (state_object -> chan == & BUTTON_CHAN ) {
@@ -531,7 +555,9 @@ static void fota_run(void *o)
531555 const struct main_state * state_object = (const struct main_state * )o ;
532556
533557 if (state_object -> chan == & FOTA_CHAN ) {
534- switch (state_object -> fota_status ) {
558+ enum fota_msg_type msg = MSG_TO_FOTA_TYPE (state_object -> msg_buf );
559+
560+ switch (msg ) {
535561 case FOTA_DOWNLOAD_CANCELED :
536562 __fallthrough ;
537563 case FOTA_DOWNLOAD_TIMED_OUT :
@@ -553,13 +579,16 @@ static void fota_downloading_run(void *o)
553579 const struct main_state * state_object = (const struct main_state * )o ;
554580
555581 if (state_object -> chan == & FOTA_CHAN ) {
556- switch (state_object -> fota_status ) {
582+ enum fota_msg_type msg = MSG_TO_FOTA_TYPE (state_object -> msg_buf );
583+
584+ switch (msg ) {
557585 case FOTA_SUCCESS_REBOOT_NEEDED :
558586 smf_set_state (SMF_CTX (state_object ),
559- & states [STATE_FOTA_NETWORK_DISCONNECT ]);
587+ & states [STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT ]);
560588 return ;
561589 case FOTA_IMAGE_APPLY_NEEDED :
562- smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_APPLYING_IMAGE ]);
590+ smf_set_state (SMF_CTX (state_object ),
591+ & states [STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT_TO_APPLY_IMAGE ]);
563592 return ;
564593 default :
565594 /* Don't care */
@@ -568,9 +597,9 @@ static void fota_downloading_run(void *o)
568597 }
569598}
570599
571- /* STATE_FOTA_NETWORK_DISCONNECT */
600+ /* STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT */
572601
573- static void fota_network_disconnect_entry (void * o )
602+ static void fota_waiting_for_network_disconnect_entry (void * o )
574603{
575604 ARG_UNUSED (o );
576605
@@ -588,20 +617,23 @@ static void fota_network_disconnect_entry(void *o)
588617 }
589618}
590619
591- static void fota_network_disconnect_run (void * o )
620+ static void fota_waiting_for_network_disconnect_run (void * o )
592621{
593622 const struct main_state * state_object = (const struct main_state * )o ;
594623
595- if (state_object -> chan == & NETWORK_CHAN &&
596- state_object -> network_status == NETWORK_DISCONNECTED ) {
597- smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_REBOOTING ]);
598- return ;
624+ if (state_object -> chan == & NETWORK_CHAN ) {
625+ struct network_msg msg = MSG_TO_NETWORK_MSG (state_object -> msg_buf );
626+
627+ if (msg .type == NETWORK_DISCONNECTED ) {
628+ smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_REBOOTING ]);
629+ return ;
630+ }
599631 }
600632}
601633
602- /* STATE_FOTA_APPLYING_IMAGE, */
634+ /* STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT_TO_APPLY_IMAGE */
603635
604- static void fota_applying_image_entry (void * o )
636+ static void fota_waiting_for_network_disconnect_to_apply_image_entry (void * o )
605637{
606638 ARG_UNUSED (o );
607639
@@ -619,26 +651,48 @@ static void fota_applying_image_entry(void *o)
619651 }
620652}
621653
622- static void fota_applying_image_run (void * o )
654+ static void fota_waiting_for_network_disconnect_to_apply_image_run (void * o )
623655{
624656 const struct main_state * state_object = (const struct main_state * )o ;
625657
626- if (state_object -> chan == & NETWORK_CHAN &&
627- state_object -> network_status == NETWORK_DISCONNECTED ) {
628-
629- int err ;
630- enum fota_msg_type msg = FOTA_IMAGE_APPLY ;
658+ if (state_object -> chan == & NETWORK_CHAN ) {
659+ struct network_msg msg = MSG_TO_NETWORK_MSG (state_object -> msg_buf );
631660
632- err = zbus_chan_pub (& FOTA_CHAN , & msg , K_SECONDS (1 ));
633- if (err ) {
634- LOG_ERR ("zbus_chan_pub, error: %d" , err );
635- SEND_FATAL_ERROR ();
661+ if (msg .type == NETWORK_DISCONNECTED ) {
662+ smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_APPLYING_IMAGE ]);
636663 }
664+ }
665+ }
637666
638- } else if (state_object -> chan == & FOTA_CHAN &&
639- state_object -> fota_status == FOTA_SUCCESS_REBOOT_NEEDED ) {
640- smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_REBOOTING ]);
641- return ;
667+ /* STATE_FOTA_APPLYING_IMAGE, */
668+
669+ static void fota_applying_image_entry (void * o )
670+ {
671+ ARG_UNUSED (o );
672+
673+ LOG_DBG ("%s" , __func__ );
674+
675+ int err ;
676+ enum fota_msg_type msg = FOTA_IMAGE_APPLY ;
677+
678+ err = zbus_chan_pub (& FOTA_CHAN , & msg , K_SECONDS (1 ));
679+ if (err ) {
680+ LOG_ERR ("zbus_chan_pub, error: %d" , err );
681+ SEND_FATAL_ERROR ();
682+ }
683+ }
684+
685+ static void fota_applying_image_run (void * o )
686+ {
687+ const struct main_state * state_object = (const struct main_state * )o ;
688+
689+ if (state_object -> chan == & FOTA_CHAN ) {
690+ enum fota_msg_type msg = MSG_TO_FOTA_TYPE (state_object -> msg_buf );
691+
692+ if (msg == FOTA_SUCCESS_REBOOT_NEEDED ) {
693+ smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_REBOOTING ]);
694+ return ;
695+ }
642696 }
643697}
644698
@@ -669,7 +723,7 @@ int main(void)
669723 const uint32_t execution_time_ms =
670724 (CONFIG_APP_MSG_PROCESSING_TIMEOUT_SECONDS * MSEC_PER_SEC );
671725 const k_timeout_t zbus_wait_ms = K_MSEC (wdt_timeout_ms - execution_time_ms );
672- struct main_state main_state ;
726+ struct main_state main_state = { 0 } ;
673727
674728 main_state .interval_sec = CONFIG_APP_MODULE_TRIGGER_TIMEOUT_SECONDS ;
675729
@@ -699,32 +753,6 @@ int main(void)
699753 return err ;
700754 }
701755
702- /* Copy corresponding data to the state object depending on the incoming channel */
703- if (& CONFIG_CHAN == main_state .chan ) {
704- const struct configuration * config = zbus_chan_const_msg (main_state .chan );
705-
706- if (config -> update_interval_present ) {
707- main_state .interval_sec = config -> update_interval ;
708- }
709- } else if (& CLOUD_CHAN == main_state .chan ) {
710- const struct cloud_msg * cloud_msg = zbus_chan_const_msg (main_state .chan );
711-
712- main_state .status = cloud_msg -> type ;
713- } else if (& FOTA_CHAN == main_state .chan ) {
714- const enum fota_msg_type * status = zbus_chan_const_msg (main_state .chan );
715-
716- main_state .fota_status = * status ;
717- } else if (& NETWORK_CHAN == main_state .chan ) {
718- const struct network_msg * msg = zbus_chan_const_msg (main_state .chan );
719-
720- main_state .network_status = msg -> type ;
721- } else if (& LOCATION_CHAN == main_state .chan ) {
722- const enum location_msg_type * msg = zbus_chan_const_msg (main_state .chan );
723-
724- main_state .location_status = * msg ;
725- }
726-
727- /* State object updated, run SMF */
728756 err = smf_run_state (SMF_CTX (& main_state ));
729757 if (err ) {
730758 LOG_ERR ("smf_run_state(), error: %d" , err );
0 commit comments