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,13 @@ 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 ), & states [STATE_REQUESTING_SENSORS_AND_POLLING ]);
493
+ return ;
494
+ }
471
495
}
472
496
473
497
if (state_object -> chan == & BUTTON_CHAN ) {
@@ -531,7 +555,9 @@ static void fota_run(void *o)
531
555
const struct main_state * state_object = (const struct main_state * )o ;
532
556
533
557
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 ) {
535
561
case FOTA_DOWNLOAD_CANCELED :
536
562
__fallthrough ;
537
563
case FOTA_DOWNLOAD_TIMED_OUT :
@@ -553,13 +579,16 @@ static void fota_downloading_run(void *o)
553
579
const struct main_state * state_object = (const struct main_state * )o ;
554
580
555
581
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 ) {
557
585
case FOTA_SUCCESS_REBOOT_NEEDED :
558
586
smf_set_state (SMF_CTX (state_object ),
559
- & states [STATE_FOTA_NETWORK_DISCONNECT ]);
587
+ & states [STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT ]);
560
588
return ;
561
589
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 ]);
563
592
return ;
564
593
default :
565
594
/* Don't care */
@@ -568,9 +597,9 @@ static void fota_downloading_run(void *o)
568
597
}
569
598
}
570
599
571
- /* STATE_FOTA_NETWORK_DISCONNECT */
600
+ /* STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT */
572
601
573
- static void fota_network_disconnect_entry (void * o )
602
+ static void fota_waiting_for_network_disconnect_entry (void * o )
574
603
{
575
604
ARG_UNUSED (o );
576
605
@@ -588,20 +617,23 @@ static void fota_network_disconnect_entry(void *o)
588
617
}
589
618
}
590
619
591
- static void fota_network_disconnect_run (void * o )
620
+ static void fota_waiting_for_network_disconnect_run (void * o )
592
621
{
593
622
const struct main_state * state_object = (const struct main_state * )o ;
594
623
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
+ }
599
631
}
600
632
}
601
633
602
- /* STATE_FOTA_APPLYING_IMAGE, */
634
+ /* STATE_FOTA_WAITING_FOR_NETWORK_DISCONNECT_TO_APPLY_IMAGE */
603
635
604
- static void fota_applying_image_entry (void * o )
636
+ static void fota_waiting_for_network_disconnect_to_apply_image_entry (void * o )
605
637
{
606
638
ARG_UNUSED (o );
607
639
@@ -619,26 +651,48 @@ static void fota_applying_image_entry(void *o)
619
651
}
620
652
}
621
653
622
- static void fota_applying_image_run (void * o )
654
+ static void fota_waiting_for_network_disconnect_to_apply_image_run (void * o )
623
655
{
624
656
const struct main_state * state_object = (const struct main_state * )o ;
625
657
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 );
631
660
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 ]);
636
663
}
664
+ }
665
+ }
637
666
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
+ }
642
696
}
643
697
}
644
698
@@ -699,32 +753,6 @@ int main(void)
699
753
return err ;
700
754
}
701
755
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
756
err = smf_run_state (SMF_CTX (& main_state ));
729
757
if (err ) {
730
758
LOG_ERR ("smf_run_state(), error: %d" , err );
0 commit comments