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,14 @@ 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 ),
493+ & states [STATE_REQUESTING_SENSORS_AND_POLLING ]);
494+ return ;
495+ }
471496 }
472497
473498 if (state_object -> chan == & BUTTON_CHAN ) {
@@ -531,7 +556,9 @@ static void fota_run(void *o)
531556 const struct main_state * state_object = (const struct main_state * )o ;
532557
533558 if (state_object -> chan == & FOTA_CHAN ) {
534- switch (state_object -> fota_status ) {
559+ enum fota_msg_type msg = MSG_TO_FOTA_TYPE (state_object -> msg_buf );
560+
561+ switch (msg ) {
535562 case FOTA_DOWNLOAD_CANCELED :
536563 __fallthrough ;
537564 case FOTA_DOWNLOAD_TIMED_OUT :
@@ -553,13 +580,16 @@ static void fota_downloading_run(void *o)
553580 const struct main_state * state_object = (const struct main_state * )o ;
554581
555582 if (state_object -> chan == & FOTA_CHAN ) {
556- switch (state_object -> fota_status ) {
583+ enum fota_msg_type msg = MSG_TO_FOTA_TYPE (state_object -> msg_buf );
584+
585+ switch (msg ) {
557586 case FOTA_SUCCESS_REBOOT_NEEDED :
558587 smf_set_state (SMF_CTX (state_object ),
559- & states [STATE_FOTA_NETWORK_DISCONNECT ]);
588+ & states [STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT ]);
560589 return ;
561590 case FOTA_IMAGE_APPLY_NEEDED :
562- smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_APPLYING_IMAGE ]);
591+ smf_set_state (SMF_CTX (state_object ),
592+ & states [STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT_TO_APPLY_IMAGE ]);
563593 return ;
564594 default :
565595 /* Don't care */
@@ -568,9 +598,9 @@ static void fota_downloading_run(void *o)
568598 }
569599}
570600
571- /* STATE_FOTA_NETWORK_DISCONNECT */
601+ /* STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT */
572602
573- static void fota_network_disconnect_entry (void * o )
603+ static void fota_waiting_for_network_disconnect_entry (void * o )
574604{
575605 ARG_UNUSED (o );
576606
@@ -588,20 +618,23 @@ static void fota_network_disconnect_entry(void *o)
588618 }
589619}
590620
591- static void fota_network_disconnect_run (void * o )
621+ static void fota_waiting_for_network_disconnect_run (void * o )
592622{
593623 const struct main_state * state_object = (const struct main_state * )o ;
594624
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 ;
625+ if (state_object -> chan == & NETWORK_CHAN ) {
626+ struct network_msg msg = MSG_TO_NETWORK_MSG (state_object -> msg_buf );
627+
628+ if (msg .type == NETWORK_DISCONNECTED ) {
629+ smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_REBOOTING ]);
630+ return ;
631+ }
599632 }
600633}
601634
602- /* STATE_FOTA_APPLYING_IMAGE, */
635+ /* STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT_TO_APPLY_IMAGE */
603636
604- static void fota_applying_image_entry (void * o )
637+ static void fota_waiting_for_network_disconnect_to_apply_image_entry (void * o )
605638{
606639 ARG_UNUSED (o );
607640
@@ -619,26 +652,48 @@ static void fota_applying_image_entry(void *o)
619652 }
620653}
621654
622- static void fota_applying_image_run (void * o )
655+ static void fota_waiting_for_network_disconnect_to_apply_image_run (void * o )
623656{
624657 const struct main_state * state_object = (const struct main_state * )o ;
625658
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 ;
659+ if (state_object -> chan == & NETWORK_CHAN ) {
660+ struct network_msg msg = MSG_TO_NETWORK_MSG (state_object -> msg_buf );
631661
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 ();
662+ if (msg .type == NETWORK_DISCONNECTED ) {
663+ smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_APPLYING_IMAGE ]);
636664 }
665+ }
666+ }
637667
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 ;
668+ /* STATE_FOTA_APPLYING_IMAGE, */
669+
670+ static void fota_applying_image_entry (void * o )
671+ {
672+ ARG_UNUSED (o );
673+
674+ LOG_DBG ("%s" , __func__ );
675+
676+ int err ;
677+ enum fota_msg_type msg = FOTA_IMAGE_APPLY ;
678+
679+ err = zbus_chan_pub (& FOTA_CHAN , & msg , K_SECONDS (1 ));
680+ if (err ) {
681+ LOG_ERR ("zbus_chan_pub, error: %d" , err );
682+ SEND_FATAL_ERROR ();
683+ }
684+ }
685+
686+ static void fota_applying_image_run (void * o )
687+ {
688+ const struct main_state * state_object = (const struct main_state * )o ;
689+
690+ if (state_object -> chan == & FOTA_CHAN ) {
691+ enum fota_msg_type msg = MSG_TO_FOTA_TYPE (state_object -> msg_buf );
692+
693+ if (msg == FOTA_SUCCESS_REBOOT_NEEDED ) {
694+ smf_set_state (SMF_CTX (state_object ), & states [STATE_FOTA_REBOOTING ]);
695+ return ;
696+ }
642697 }
643698}
644699
@@ -699,32 +754,6 @@ int main(void)
699754 return err ;
700755 }
701756
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 */
728757 err = smf_run_state (SMF_CTX (& main_state ));
729758 if (err ) {
730759 LOG_ERR ("smf_run_state(), error: %d" , err );
0 commit comments