diff --git a/subsys/net/lib/nrf_cloud/include/nrf_cloud_download.h b/subsys/net/lib/nrf_cloud/include/nrf_cloud_download.h index 165a7f104ee..5af78b40b18 100644 --- a/subsys/net/lib/nrf_cloud/include/nrf_cloud_download.h +++ b/subsys/net/lib/nrf_cloud/include/nrf_cloud_download.h @@ -64,6 +64,11 @@ struct nrf_cloud_download_data { */ int nrf_cloud_download_start(struct nrf_cloud_download_data *const dl); +/** @brief Cancel the active download. + * Call to stop the current download and reset the download state. + */ +void nrf_cloud_download_cancel(void); + /** @brief Resume a CoAP download at the provided offset. */ int nrf_cloud_download_coap_offset_resume(const size_t offset); diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_download.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_download.c index 63908bc4e55..e5ddd426314 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_download.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_download.c @@ -403,6 +403,30 @@ static void active_dl_reset(void) active_dl.type = NRF_CLOUD_DL_TYPE_NONE; } +void nrf_cloud_download_cancel(void) +{ + int ret = 0; + + k_mutex_lock(&active_dl_mutex, K_FOREVER); + + if (active_dl.type == NRF_CLOUD_DL_TYPE_FOTA) { +#if defined(CONFIG_FOTA_DOWNLOAD) + ret = fota_download_cancel(); +#endif + } else if (active_dl.type == NRF_CLOUD_DL_TYPE_DL_CLIENT) { + ret = dlc_disconnect(&active_dl); + } else { + LOG_WRN("No active download to cancel"); + } + + if (ret) { + LOG_WRN("Error canceling download: %d", ret); + } + + active_dl_reset(); + k_mutex_unlock(&active_dl_mutex); +} + void nrf_cloud_download_end(void) { #if defined(CONFIG_NRF_CLOUD_COAP_DOWNLOADS) diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c index 2a711620bf1..532e0a14d10 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_fota_poll.c @@ -124,6 +124,11 @@ static void http_fota_dl_handler(const struct fota_download_evt *evt) { LOG_DBG("evt: %d", evt->id); + if (fota_status != NRF_CLOUD_FOTA_IN_PROGRESS) { + LOG_DBG("No FOTA job in progress"); + return; + } + switch (evt->id) { case FOTA_DOWNLOAD_EVT_FINISHED: LOG_INF("FOTA download finished"); @@ -244,7 +249,7 @@ static void fota_dl_timeout_work_fn(struct k_work *work) { LOG_ERR("Timeout; FOTA download took longer than %d minutes", CONFIG_FOTA_DL_TIMEOUT_MIN); - (void)fota_download_cancel(); + nrf_cloud_download_cancel(); } int nrf_cloud_fota_poll_init(struct nrf_cloud_fota_poll_ctx *ctx) @@ -446,9 +451,16 @@ static int start_download(void) } }; + /* Clear semaphore before starting download */ + k_sem_reset(&fota_download_sem); + + fota_status = NRF_CLOUD_FOTA_IN_PROGRESS; + fota_status_details = NULL; + ret = nrf_cloud_download_start(&dl); if (ret) { LOG_ERR("Failed to start FOTA download, error: %d", ret); + fota_status = NRF_CLOUD_FOTA_QUEUED; return -ENODEV; } @@ -460,7 +472,9 @@ static int wait_for_download(void) int err = k_sem_take(&fota_download_sem, K_MINUTES(CONFIG_FOTA_DL_TIMEOUT_MIN)); if (err == -EAGAIN) { - fota_download_cancel(); + fota_status = NRF_CLOUD_FOTA_TIMED_OUT; + fota_status_details = FOTA_STATUS_DETAILS_TIMEOUT; + nrf_cloud_download_cancel(); return -ETIMEDOUT; } else if (err != 0) { LOG_ERR("k_sem_take error: %d", err); @@ -571,8 +585,6 @@ int nrf_cloud_fota_poll_process(struct nrf_cloud_fota_poll_ctx *ctx) if (err == -ETIMEDOUT) { LOG_ERR("Timeout; FOTA download took longer than %d minutes", CONFIG_FOTA_DL_TIMEOUT_MIN); - fota_status = NRF_CLOUD_FOTA_TIMED_OUT; - fota_status_details = FOTA_STATUS_DETAILS_TIMEOUT; } /* On download success, save job info and reboot to complete installation.