@@ -50,7 +50,7 @@ static enum nrf_cloud_fota_status fota_status = NRF_CLOUD_FOTA_QUEUED;
50
50
static char const * fota_status_details = FOTA_STATUS_DETAILS_SUCCESS ;
51
51
52
52
/* Forward-declarations */
53
- static void handle_download_succeeded_and_reboot (struct nrf_cloud_fota_poll_ctx * ctx );
53
+ static int handle_downloaded_image (struct nrf_cloud_fota_poll_ctx * ctx , bool cloud_disconnect );
54
54
static int update_job_status (struct nrf_cloud_fota_poll_ctx * ctx );
55
55
56
56
/****************************************************/
@@ -103,7 +103,7 @@ static int disconnect(struct nrf_cloud_fota_poll_ctx *ctx)
103
103
err = - ENOTSUP ;
104
104
#endif
105
105
#if defined(CONFIG_LTE_LINK_CONTROL )
106
- ( void ) lte_lc_power_off ();
106
+ err = lte_lc_power_off ();
107
107
#endif
108
108
109
109
return err ;
@@ -118,6 +118,21 @@ static void cleanup(void)
118
118
#endif
119
119
}
120
120
121
+ static void fota_status_callback (struct nrf_cloud_fota_poll_ctx * ctx ,
122
+ enum nrf_cloud_fota_status status )
123
+ { if (ctx -> status_fn ) {
124
+ ctx -> status_fn (status , NULL );
125
+ }
126
+ }
127
+
128
+ static void fota_reboot_callback (struct nrf_cloud_fota_poll_ctx * ctx ,
129
+ enum nrf_cloud_fota_reboot_status status )
130
+ {
131
+ if (ctx -> reboot_fn ) {
132
+ ctx -> reboot_fn (status );
133
+ }
134
+ }
135
+
121
136
/****************************************************/
122
137
/* End of transport-specific wrappers. */
123
138
/****************************************************/
@@ -139,10 +154,24 @@ static void http_fota_dl_handler(const struct fota_download_evt *evt)
139
154
140
155
if (ctx_ptr -> is_nonblocking ) {
141
156
k_work_cancel_delayable (& ctx_ptr -> timeout_work );
142
- handle_download_succeeded_and_reboot (ctx_ptr );
157
+ }
158
+
159
+ if (IS_ENABLED (CONFIG_NRF_CLOUD_FOTA_POLL_VALIDATE_UPDATE )) {
160
+ int err = handle_downloaded_image (ctx_ptr , true);
161
+
162
+ if (err ) {
163
+ LOG_ERR ("handle_downloaded_image() failed: %d" , err );
164
+ nrf_cloud_download_cancel ();
165
+ }
166
+
143
167
} else {
168
+ fota_status_callback (ctx_ptr , NRF_CLOUD_FOTA_VALIDATION_NEEDED );
169
+ }
170
+
171
+ if (!ctx_ptr -> is_nonblocking ) {
144
172
k_sem_give (& fota_download_sem );
145
173
}
174
+
146
175
break ;
147
176
case FOTA_DOWNLOAD_EVT_ERASE_PENDING :
148
177
case FOTA_DOWNLOAD_EVT_ERASE_TIMEOUT :
@@ -233,9 +262,7 @@ static void process_pending_job(struct nrf_cloud_fota_poll_ctx *ctx)
233
262
/* Save validate status and reboot */
234
263
(void )nrf_cloud_fota_settings_save (& pending_job );
235
264
236
- if (ctx -> reboot_fn ) {
237
- ctx -> reboot_fn (FOTA_REBOOT_REQUIRED );
238
- }
265
+ fota_reboot_callback (ctx , FOTA_REBOOT_REQUIRED );
239
266
}
240
267
}
241
268
@@ -494,7 +521,7 @@ static int wait_for_download(void)
494
521
return 0 ;
495
522
}
496
523
497
- static void handle_download_succeeded_and_reboot (struct nrf_cloud_fota_poll_ctx * ctx )
524
+ static int handle_downloaded_image (struct nrf_cloud_fota_poll_ctx * ctx , bool cloud_disconnect )
498
525
{
499
526
int err ;
500
527
@@ -506,17 +533,26 @@ static void handle_download_succeeded_and_reboot(struct nrf_cloud_fota_poll_ctx
506
533
507
534
err = nrf_cloud_bootloader_fota_slot_set (& pending_job );
508
535
if (err ) {
509
- LOG_WRN ("Failed to set B1 slot flag, BOOT FOTA validation may be incorrect" );
536
+ LOG_ERR ("Failed to set B1 slot flag, BOOT FOTA validation may be incorrect" );
537
+ return err ;
510
538
}
511
539
512
- disconnect (ctx );
540
+ if (cloud_disconnect ) {
541
+ err = disconnect (ctx );
542
+ if (err ) {
543
+ LOG_ERR ("Failed to disconnect from nRF Cloud, error: %d" , err );
544
+ return err ;
545
+ }
546
+ }
513
547
514
548
#if defined(CONFIG_NRF_CLOUD_FOTA_FULL_MODEM_UPDATE )
515
549
if (job .type == NRF_CLOUD_FOTA_MODEM_FULL ) {
516
550
LOG_INF ("Applying full modem FOTA update..." );
551
+
517
552
err = nrf_cloud_fota_fmfu_apply ();
518
553
if (err ) {
519
554
LOG_ERR ("Failed to apply full modem FOTA update %d" , err );
555
+
520
556
pending_job .validate = NRF_CLOUD_FOTA_VALIDATE_FAIL ;
521
557
} else {
522
558
pending_job .validate = NRF_CLOUD_FOTA_VALIDATE_PASS ;
@@ -529,9 +565,11 @@ static void handle_download_succeeded_and_reboot(struct nrf_cloud_fota_poll_ctx
529
565
bool reboot_required = false;
530
566
531
567
LOG_INF ("Installing SMP FOTA update..." );
568
+
532
569
err = nrf_cloud_pending_fota_job_process (& pending_job , & reboot_required );
533
570
if (err < 0 ) {
534
571
LOG_ERR ("Failed to install SMP FOTA update %d" , err );
572
+
535
573
pending_job .validate = NRF_CLOUD_FOTA_VALIDATE_FAIL ;
536
574
} else {
537
575
pending_job .validate = NRF_CLOUD_FOTA_VALIDATE_PASS ;
@@ -541,18 +579,14 @@ static void handle_download_succeeded_and_reboot(struct nrf_cloud_fota_poll_ctx
541
579
542
580
err = nrf_cloud_fota_settings_save (& pending_job );
543
581
if (err ) {
544
- LOG_WRN ("FOTA job will be marked as successful without validation" );
545
- fota_status_details = FOTA_STATUS_DETAILS_NO_VALIDATE ;
546
- (void )update_job_status (ctx );
582
+ LOG_ERR ("Failed saving pending FOTA job, error: %d" , err );
583
+ return err ;
547
584
}
548
585
549
- if (ctx_ptr -> status_fn ) {
550
- ctx_ptr -> status_fn (NRF_CLOUD_FOTA_SUCCEEDED , NULL );
551
- }
586
+ fota_status_callback (ctx , NRF_CLOUD_FOTA_SUCCEEDED );
587
+ fota_reboot_callback (ctx , FOTA_REBOOT_SUCCESS );
552
588
553
- if (ctx -> reboot_fn ) {
554
- ctx -> reboot_fn (FOTA_REBOOT_SUCCESS );
555
- }
589
+ return 0 ;
556
590
}
557
591
558
592
static void wait_after_job_update (void )
@@ -563,6 +597,18 @@ static void wait_after_job_update(void)
563
597
k_sleep (K_SECONDS (JOB_WAIT_S ));
564
598
}
565
599
600
+ int nrf_cloud_fota_poll_update_apply (struct nrf_cloud_fota_poll_ctx * ctx )
601
+ {
602
+ int err = handle_downloaded_image (ctx , false);
603
+
604
+ if (err ) {
605
+ LOG_ERR ("handle_downloaded_image, error: %d" , err );
606
+ return err ;
607
+ }
608
+
609
+ return 0 ;
610
+ }
611
+
566
612
int nrf_cloud_fota_poll_process (struct nrf_cloud_fota_poll_ctx * ctx )
567
613
{
568
614
int err ;
@@ -592,9 +638,7 @@ int nrf_cloud_fota_poll_process(struct nrf_cloud_fota_poll_ctx *ctx)
592
638
return - EAGAIN ;
593
639
}
594
640
595
- if (ctx_ptr -> status_fn ) {
596
- ctx_ptr -> status_fn (NRF_CLOUD_FOTA_DOWNLOADING , NULL );
597
- }
641
+ fota_status_callback (ctx , NRF_CLOUD_FOTA_DOWNLOADING );
598
642
599
643
/* Start the FOTA download process and wait for completion (or timeout) */
600
644
err = start_download ();
@@ -624,7 +668,7 @@ int nrf_cloud_fota_poll_process(struct nrf_cloud_fota_poll_ctx *ctx)
624
668
* Job status will be sent to nRF Cloud after reboot and validation.
625
669
*/
626
670
if (fota_status == NRF_CLOUD_FOTA_SUCCEEDED ) {
627
- handle_download_succeeded_and_reboot (ctx );
671
+ handle_downloaded_image (ctx , true );
628
672
/* Application was expected to reboot... */
629
673
return - EBUSY ;
630
674
}
0 commit comments