Skip to content

Commit 107b2ac

Browse files
committed
net: fota_download: Add more error codes to callback
Add error codes for * Unsupported protocol * DFU failure * Invalid configuration or invalid URI This is because Downloader may give us -EPROTONOSUPPORT or -EINVAL and these have no equivalent on FOTA Download callbacks. DFU failures might also be usefull to see as a separate error instead of generic INTERNAL error. Signed-off-by: Seppo Takalo <[email protected]>
1 parent 085e0ac commit 107b2ac

File tree

6 files changed

+140
-25
lines changed

6 files changed

+140
-25
lines changed

doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,7 @@ Libraries for networking
633633

634634
* :ref:`lib_fota_download` library:
635635

636+
* Added error codes related to unsupported protocol, DFU failures, and invalid configuration.
636637
* Updated to use the :ref:`lib_downloader` library for CoAP downloads.
637638

638639
* :ref:`lib_nrf_cloud` library:

include/net/fota_download.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ enum fota_download_error_cause {
8383
FOTA_DOWNLOAD_ERROR_CAUSE_TYPE_MISMATCH,
8484
/** Generic error on device side. */
8585
FOTA_DOWNLOAD_ERROR_CAUSE_INTERNAL,
86+
/** Error on DFU library */
87+
FOTA_DOWNLOAD_ERROR_CAUSE_DFU,
88+
/** Protocol not supported */
89+
FOTA_DOWNLOAD_ERROR_CAUSE_PROTO_NOT_SUPPORTED,
90+
/** Invalid URI or invalid configuration */
91+
FOTA_DOWNLOAD_ERROR_CAUSE_INVALID_CONFIGURATION,
8692
};
8793

8894
/**

subsys/net/lib/fota_download/src/fota_download.c

Lines changed: 41 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ static int downloader_callback(const struct downloader_evt *event)
187187
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_INVALID_UPDATE);
188188
} else if (err < 0) {
189189
LOG_ERR("dfu_target_init error %d", err);
190-
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_INTERNAL);
190+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_DFU);
191191
}
192192
}
193193

@@ -199,7 +199,7 @@ static int downloader_callback(const struct downloader_evt *event)
199199
if (err != 0) {
200200
LOG_DBG("unable to get dfu target offset err: "
201201
"%d", err);
202-
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_DOWNLOAD_FAILED);
202+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_DFU);
203203
goto error_and_close;
204204
}
205205

@@ -213,15 +213,15 @@ static int downloader_callback(const struct downloader_evt *event)
213213
if (err != 0) {
214214
LOG_ERR("Unable to reset DFU target, err: %d", err);
215215
set_error_state(
216-
FOTA_DOWNLOAD_ERROR_CAUSE_DOWNLOAD_FAILED);
216+
FOTA_DOWNLOAD_ERROR_CAUSE_DFU);
217217
goto error_and_close;
218218
}
219219
err = dfu_target_init(img_type, 0, file_size,
220220
dfu_target_callback_handler);
221221
if (err != 0) {
222222
LOG_ERR("Failed to re-initialize target, err: %d",
223223
err);
224-
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_INTERNAL);
224+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_DFU);
225225
goto error_and_close;
226226
}
227227
} else {
@@ -246,7 +246,7 @@ static int downloader_callback(const struct downloader_evt *event)
246246
goto error_and_close;
247247
} else if (err != 0) {
248248
LOG_ERR("dfu_target_write error %d", err);
249-
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_INTERNAL);
249+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_DFU);
250250
goto error_and_close;
251251
}
252252

@@ -278,7 +278,7 @@ static int downloader_callback(const struct downloader_evt *event)
278278

279279
if (err != 0) {
280280
LOG_ERR("dfu_target_done error: %d", err);
281-
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_INTERNAL);
281+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_DFU);
282282
goto error_and_close;
283283
}
284284

@@ -300,26 +300,44 @@ static int downloader_callback(const struct downloader_evt *event)
300300
/* Fall through and return 0 below to tell
301301
* downloader to retry
302302
*/
303-
} else if ((event->error == -ECONNABORTED) ||
304-
(event->error == -ECONNREFUSED) ||
305-
(event->error == -EHOSTUNREACH)) {
306-
LOG_ERR("Download client failed to connect to server");
307-
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_CONNECT_FAILED);
303+
break;
304+
}
305+
LOG_ERR("Downloader error event %d", event->error);
306+
err = dfu_target_done(false);
307+
if (err == -EACCES) {
308+
LOG_DBG("No DFU target was initialized");
309+
} else if (err != 0) {
310+
LOG_ERR("Unable to deinitialize resources "
311+
"used by dfu_target.");
312+
}
313+
switch (event->error) {
308314

309-
goto error_and_close;
310-
} else {
311-
LOG_ERR("Downloader error event %d", event->error);
312-
err = dfu_target_done(false);
313-
if (err == -EACCES) {
314-
LOG_DBG("No DFU target was initialized");
315-
} else if (err != 0) {
316-
LOG_ERR("Unable to deinitialze resources "
317-
"used by dfu_target.");
318-
}
315+
case -ECONNABORTED:
316+
case -ECONNREFUSED:
317+
case -EHOSTUNREACH:
318+
case -ENETDOWN:
319+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_CONNECT_FAILED);
320+
break;
321+
case -ECONNRESET:
322+
case -ETIMEDOUT:
323+
case -EHOSTDOWN:
324+
case -EBADMSG:
325+
case -ERANGE:
326+
case -E2BIG:
319327
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_DOWNLOAD_FAILED);
320-
goto error_and_close;
328+
break;
329+
case -EPROTONOSUPPORT:
330+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_PROTO_NOT_SUPPORTED);
331+
break;
332+
case -EINVAL:
333+
case -EAFNOSUPPORT:
334+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_INVALID_CONFIGURATION);
335+
break;
336+
default:
337+
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_INTERNAL);
338+
break;
321339
}
322-
break;
340+
goto error_and_close;
323341
case DOWNLOADER_EVT_STOPPED:
324342
atomic_set_bit(&flags, FLAG_STOPPED);
325343
/* Only clear flags if we are not going to resume */

subsys/net/lib/fota_download/src/util/fota_download_util.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,24 @@ static void start_fota_download(struct k_work *work)
184184
ret = fota_download_start_with_image_type(fota_host, fota_path, fota_sec_tag, 0, 0,
185185
active_dfu_type);
186186
if (ret) {
187-
struct fota_download_evt evt;
187+
struct fota_download_evt evt = {
188+
.id = FOTA_DOWNLOAD_EVT_ERROR
189+
};
190+
191+
switch (ret) {
192+
case -EINVAL:
193+
case -E2BIG:
194+
evt.cause = FOTA_DOWNLOAD_ERROR_CAUSE_INVALID_CONFIGURATION;
195+
break;
196+
case -EPROTONOSUPPORT:
197+
evt.cause = FOTA_DOWNLOAD_ERROR_CAUSE_PROTO_NOT_SUPPORTED;
198+
break;
199+
default:
200+
evt.cause = FOTA_DOWNLOAD_ERROR_CAUSE_INTERNAL;
201+
break;
202+
}
188203

189204
LOG_ERR("fota_download_start() failed, return code %d", ret);
190-
evt.id = FOTA_DOWNLOAD_EVT_CANCELLED;
191205
fota_download_callback(&evt);
192206
}
193207
}

subsys/net/lib/lwm2m_client_utils/lwm2m/lwm2m_firmware.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,9 @@ static void fota_download_callback(const struct fota_download_evt *evt)
902902
LOG_INF("FOTA download failed, target %d", dfu_image_type);
903903
target_image_type_store(ongoing_obj_id, dfu_image_type);
904904
switch (evt->cause) {
905+
case FOTA_DOWNLOAD_ERROR_CAUSE_PROTO_NOT_SUPPORTED:
906+
set_result(ongoing_obj_id, RESULT_UNSUP_PROTO);
907+
break;
905908
/* Connecting to the FOTA server failed. */
906909
case FOTA_DOWNLOAD_ERROR_CAUSE_CONNECT_FAILED:
907910
/* FALLTHROUGH */

tests/subsys/net/lib/fota_download/src/test_fota_download.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <pm_config.h>
1414
#include <fota_download.h>
1515
#include "test_fota_download_common.h"
16+
#include <fota_download_util.h>
1617

1718
/* fota_download_start may modify the resource locator passed to it, so we cannot directly pass
1819
* test constants. Instead, we copy them to a modifiable buffer first.
@@ -32,6 +33,7 @@ static bool start_with_offset;
3233
static bool fail_on_offset_get;
3334
static bool fail_on_connect;
3435
static bool fail_on_start;
36+
static bool fail_on_proto;
3537
static bool download_with_offset_success;
3638
static downloader_callback_t downloader_event_handler;
3739
K_SEM_DEFINE(stop_sem, 0, 1);
@@ -101,6 +103,9 @@ int downloader_get_with_host_and_file(struct downloader *dl,
101103
const struct downloader_host_cfg *dl_host_cfg,
102104
const char *host, const char *file, size_t from)
103105
{
106+
if (fail_on_proto == true) {
107+
return -EPROTONOSUPPORT;
108+
}
104109
if (fail_on_connect == true) {
105110
return -1;
106111
}
@@ -209,8 +214,14 @@ void set_s0_active(bool s0_active)
209214

210215
void client_callback(const struct fota_download_evt *evt)
211216
{
217+
printk("Event: %d\n", evt->id);
212218
switch (evt->id) {
213219
case FOTA_DOWNLOAD_EVT_ERROR:
220+
if (fail_on_proto) {
221+
zassert_equal(evt->cause, FOTA_DOWNLOAD_ERROR_CAUSE_PROTO_NOT_SUPPORTED);
222+
fail_on_proto = false;
223+
k_sem_give(&download_with_offset_sem);
224+
}
214225
if (fail_on_offset_get == true) {
215226
zassert_equal(evt->cause, FOTA_DOWNLOAD_ERROR_CAUSE_INTERNAL, NULL);
216227
fail_on_offset_get = false;
@@ -253,10 +264,12 @@ static void init(void)
253264
fail_on_offset_get = false;
254265
fail_on_connect = false;
255266
fail_on_start = false;
267+
fail_on_proto = false;
256268
downloader_get_file = NULL;
257269
spm_s0_active_retval = false;
258270

259271
k_sem_reset(&stop_sem);
272+
k_sem_reset(&download_with_offset_sem);
260273

261274
err = fota_download_init(client_callback);
262275
zassert_equal(err, 0, NULL);
@@ -415,3 +428,63 @@ ZTEST(fota_download_tests, test_download_with_offset)
415428
err = fota_download_cancel();
416429
zassert_equal(err, -EAGAIN);
417430
}
431+
432+
433+
ZTEST(fota_download_tests, test_download_invalid_protocol)
434+
{
435+
init();
436+
437+
fail_on_proto = true;
438+
int err = fota_download_any("ftp://" BASE_DOMAIN, buf, NO_TLS, 0, 0, 0);
439+
440+
zassert_equal(err, -EPROTONOSUPPORT, "%d", err);
441+
fota_download_cancel();
442+
443+
}
444+
445+
ZTEST_SUITE(fota_download_util, NULL, NULL, NULL, NULL, NULL);
446+
447+
ZTEST(fota_download_util, test_download_util_invalid_protocol)
448+
{
449+
init();
450+
451+
fail_on_proto = true;
452+
int err = fota_download_util_download_start("ftp://host.com/file.bin",
453+
DFU_TARGET_IMAGE_TYPE_ANY, 0,
454+
client_callback);
455+
456+
zassert_ok(err, NULL);
457+
k_sem_take(&download_with_offset_sem, K_SECONDS(2));
458+
k_sem_take(&stop_sem, K_FOREVER);
459+
}
460+
461+
ZTEST(fota_download_util, test_download_util_start)
462+
{
463+
init();
464+
465+
uint8_t fragment_buf[1] = {0};
466+
size_t fragment_len = 1;
467+
struct downloader_evt evt = {
468+
.id = DOWNLOADER_EVT_FRAGMENT,
469+
.fragment = {
470+
.buf = fragment_buf,
471+
.len = fragment_len,
472+
}
473+
};
474+
475+
start_with_offset = true;
476+
int err = fota_download_util_download_start("http://host.com/file.bin",
477+
DFU_TARGET_IMAGE_TYPE_ANY, 0,
478+
client_callback);
479+
480+
zassert_ok(err);
481+
482+
err = downloader_event_handler(&evt);
483+
zassert_ok(err);
484+
485+
evt.id = DOWNLOADER_EVT_DONE;
486+
err = downloader_event_handler(&evt);
487+
zassert_ok(err);
488+
489+
k_sem_take(&stop_sem, K_FOREVER);
490+
}

0 commit comments

Comments
 (0)