27
27
28
28
#if defined(CONFIG_APP_POWER )
29
29
#include "power.h"
30
- #define BAT_MSG_SIZE sizeof(struct power_msg)
30
+ #define POWER_MSG_SIZE sizeof(struct power_msg)
31
31
#else
32
- #define BAT_MSG_SIZE 0
32
+ #define POWER_MSG_SIZE 0
33
33
#endif /* CONFIG_APP_POWER */
34
34
35
35
/* Register log module */
36
36
LOG_MODULE_REGISTER (main , CONFIG_APP_LOG_LEVEL );
37
37
38
38
#define MAX_MSG_SIZE (MAX(sizeof(struct configuration), \
39
39
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 ))))))))
41
47
42
48
/* Register subscriber */
43
49
ZBUS_MSG_SUBSCRIBER_DEFINE (main_subscriber );
@@ -87,8 +93,11 @@ static void fota_run(void *o);
87
93
88
94
static void fota_downloading_run (void * o );
89
95
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 );
92
101
93
102
static void fota_applying_image_entry (void * o );
94
103
static void fota_applying_image_run (void * o );
@@ -111,7 +120,11 @@ enum state {
111
120
/* FOTA image is being downloaded */
112
121
STATE_FOTA_DOWNLOADING ,
113
122
/* 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 ,
115
128
/* Applying the image */
116
129
STATE_FOTA_APPLYING_IMAGE ,
117
130
/* Rebooting */
@@ -134,23 +147,8 @@ struct main_state {
134
147
/* Trigger interval */
135
148
uint64_t interval_sec ;
136
149
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 ;
154
152
};
155
153
156
154
/* Construct state table */
@@ -204,9 +202,16 @@ static const struct smf_state states[] = {
204
202
& states [STATE_FOTA ],
205
203
NULL
206
204
),
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 ,
210
215
NULL ,
211
216
& states [STATE_FOTA ],
212
217
NULL
@@ -327,9 +332,7 @@ static void running_entry(void *o)
327
332
328
333
LOG_DBG ("%s" , __func__ );
329
334
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 ) {
333
336
smf_set_state (SMF_CTX (state_object ), & states [STATE_TRIGGERING ]);
334
337
return ;
335
338
}
@@ -341,10 +344,13 @@ static void running_run(void *o)
341
344
{
342
345
const struct main_state * state_object = (const struct main_state * )o ;
343
346
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
+ }
348
354
}
349
355
}
350
356
@@ -382,12 +388,16 @@ static void idle_entry(void *o)
382
388
383
389
static void idle_run (void * o )
384
390
{
385
- const struct main_state * state_object = ( const struct main_state * ) o ;
391
+ struct main_state * state_object = o ;
386
392
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
+ }
391
401
}
392
402
}
393
403
@@ -425,19 +435,30 @@ static void triggering_entry(void *o)
425
435
426
436
static void triggering_run (void * o )
427
437
{
428
- const struct main_state * state_object = ( const struct main_state * ) o ;
438
+ struct main_state * state_object = o ;
429
439
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
+ }
435
449
}
436
450
437
451
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
+ }
441
462
}
442
463
}
443
464
@@ -464,10 +485,14 @@ static void requesting_location_run(void *o)
464
485
{
465
486
const struct main_state * state_object = (const struct main_state * )o ;
466
487
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
+ }
471
496
}
472
497
473
498
if (state_object -> chan == & BUTTON_CHAN ) {
@@ -531,7 +556,9 @@ static void fota_run(void *o)
531
556
const struct main_state * state_object = (const struct main_state * )o ;
532
557
533
558
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 ) {
535
562
case FOTA_DOWNLOAD_CANCELED :
536
563
__fallthrough ;
537
564
case FOTA_DOWNLOAD_TIMED_OUT :
@@ -553,13 +580,16 @@ static void fota_downloading_run(void *o)
553
580
const struct main_state * state_object = (const struct main_state * )o ;
554
581
555
582
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 ) {
557
586
case FOTA_SUCCESS_REBOOT_NEEDED :
558
587
smf_set_state (SMF_CTX (state_object ),
559
- & states [STATE_FOTA_NETWORK_DISCONNECT ]);
588
+ & states [STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT ]);
560
589
return ;
561
590
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 ]);
563
593
return ;
564
594
default :
565
595
/* Don't care */
@@ -568,9 +598,9 @@ static void fota_downloading_run(void *o)
568
598
}
569
599
}
570
600
571
- /* STATE_FOTA_NETWORK_DISCONNECT */
601
+ /* STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT */
572
602
573
- static void fota_network_disconnect_entry (void * o )
603
+ static void fota_waiting_for_network_disconnect_entry (void * o )
574
604
{
575
605
ARG_UNUSED (o );
576
606
@@ -588,20 +618,23 @@ static void fota_network_disconnect_entry(void *o)
588
618
}
589
619
}
590
620
591
- static void fota_network_disconnect_run (void * o )
621
+ static void fota_waiting_for_network_disconnect_run (void * o )
592
622
{
593
623
const struct main_state * state_object = (const struct main_state * )o ;
594
624
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
+ }
599
632
}
600
633
}
601
634
602
- /* STATE_FOTA_APPLYING_IMAGE, */
635
+ /* STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT_TO_APPLY_IMAGE */
603
636
604
- static void fota_applying_image_entry (void * o )
637
+ static void fota_waiting_for_network_disconnect_to_apply_image_entry (void * o )
605
638
{
606
639
ARG_UNUSED (o );
607
640
@@ -619,26 +652,48 @@ static void fota_applying_image_entry(void *o)
619
652
}
620
653
}
621
654
622
- static void fota_applying_image_run (void * o )
655
+ static void fota_waiting_for_network_disconnect_to_apply_image_run (void * o )
623
656
{
624
657
const struct main_state * state_object = (const struct main_state * )o ;
625
658
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 );
631
661
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 ]);
636
664
}
665
+ }
666
+ }
637
667
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
+ }
642
697
}
643
698
}
644
699
@@ -699,32 +754,6 @@ int main(void)
699
754
return err ;
700
755
}
701
756
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 */
728
757
err = smf_run_state (SMF_CTX (& main_state ));
729
758
if (err ) {
730
759
LOG_ERR ("smf_run_state(), error: %d" , err );
0 commit comments