Skip to content

Commit fbec239

Browse files
maxd-nordicrlubos
authored andcommitted
net: use downloader for coap downloads
Integrate the improved downloader library into nRF Cloud. Instead of using a custom downloader backend, use downloader for coap downloads. Also, remove external_download_client support since it isn't used anymore. Signed-off-by: Maximilian Deubel <[email protected]>
1 parent e3313de commit fbec239

File tree

11 files changed

+83
-485
lines changed

11 files changed

+83
-485
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,18 @@ Libraries for networking
543543

544544
* Fixed the warning due to missing ``https`` download protocol.
545545

546+
* :ref:`lib_downloader` library:
547+
548+
* Updated to support Proxy-URI option and an authentication callback after connecting.
549+
550+
* :ref:`lib_fota_download` library:
551+
552+
* Updated to use the :ref:`lib_downloader` library for CoAP downloads.
553+
554+
* :ref:`lib_nrf_cloud` library:
555+
556+
* Updated to use the :ref:`lib_downloader` library for CoAP downloads.
557+
546558
Libraries for NFC
547559
-----------------
548560

include/net/fota_download.h

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,6 @@ enum fota_download_evt_id {
6363

6464
/** FOTA download abandoned due to a cancellation request. */
6565
FOTA_DOWNLOAD_EVT_CANCELLED,
66-
67-
/** Resume the download at offset.
68-
* Only generated if @kconfig{CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL} is enabled.
69-
*/
70-
FOTA_DOWNLOAD_EVT_RESUME_OFFSET,
7166
};
7267

7368
/**
@@ -101,8 +96,6 @@ struct fota_download_evt {
10196
enum fota_download_error_cause cause;
10297
/** Download progress %. */
10398
int progress;
104-
/** Resume at offset @ref FOTA_DOWNLOAD_EVT_RESUME_OFFSET */
105-
size_t resume_offset;
10699
};
107100
};
108101

@@ -152,6 +145,32 @@ int fota_download(const char *host, const char *file, const int *sec_tag_list,
152145
uint8_t sec_tag_count, uint8_t pdn_id, size_t fragment_size,
153146
const enum dfu_target_image_type expected_type);
154147

148+
/**@brief Download the given file with the specified image type from the given host.
149+
*
150+
* Identical to fota_download_start_with_image_type(),
151+
* but with additional host configuration options.
152+
*
153+
* @param host Name of host to start downloading from. Can include scheme
154+
* and port number, for example https://google.com:443
155+
* @param file Path to the file you wish to download. See fota_download_any()
156+
* for details on expected format.
157+
* @param sec_tag Security tag you want to use with COAPS. Pass -1 to disable DTLS.
158+
* @param pdn_id Packet Data Network ID to use for the download, or 0 to use the default.
159+
* @param fragment_size Fragment size to be used for the download. If 0, no fragmentation is used.
160+
* @param expected_type Type of firmware file to be downloaded and installed.
161+
* @param host_cfg Additional host configuration options.
162+
*
163+
* @retval 0 If download has started successfully.
164+
* @retval -EALREADY If download is already ongoing.
165+
* @retval -E2BIG If sec_tag_count is larger than
166+
* @kconfig{CONFIG_FOTA_DOWNLOAD_SEC_TAG_LIST_SIZE_MAX}
167+
* Otherwise, a negative value is returned.
168+
*/
169+
int fota_download_with_host_cfg(const char *host, const char *file,
170+
int sec_tag, uint8_t pdn_id, size_t fragment_size,
171+
const enum dfu_target_image_type expected_type,
172+
const struct downloader_host_cfg *host_cfg);
173+
155174

156175
/**@brief Start downloading the given file of any image type from the given host.
157176
*
@@ -281,31 +300,6 @@ int fota_download_s0_active_get(bool *const s0_active);
281300
*/
282301
int fota_download_b1_file_parse(char *s0_s1_files);
283302

284-
/**@brief Start a FOTA download using an external download client.
285-
* Requires @kconfig{CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL} to be enabled.
286-
*
287-
* @param host Name of host.
288-
* @param file File path of the firmware image.
289-
* @param expected_type Type of firmware image to be installed.
290-
* @param image_size Size of the firmware image.
291-
*
292-
* @retval 0 If successful.
293-
* Otherwise, a (negative) error code is returned.
294-
*/
295-
int fota_download_external_start(const char *host, const char *file,
296-
const enum dfu_target_image_type expected_type,
297-
const size_t image_size);
298-
299-
/**@brief Handle a download event from an external download client.
300-
* Requires @kconfig{CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL} to be enabled.
301-
*
302-
* @param evt Download event.
303-
*
304-
* @retval 0 If successful.
305-
* Otherwise, a (negative) error code is returned.
306-
*/
307-
int fota_download_external_evt_handle(struct downloader_evt const *const evt);
308-
309303
#ifdef __cplusplus
310304
}
311305
#endif

subsys/net/lib/fota_download/Kconfig

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,6 @@ config FOTA_DOWNLOAD_SEC_TAG_LIST_SIZE_MAX
6666
help
6767
Maximum size of the list of security tags used to store TLS credentials.
6868

69-
config FOTA_DOWNLOAD_EXTERNAL_DL
70-
bool "Use external download events to perform FOTA updates"
71-
select EXPERIMENTAL
72-
7369
module=FOTA_DOWNLOAD
7470
module-dep=LOG
7571
module-str=Firmware Over the Air Download

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

Lines changed: 10 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,6 @@
2525

2626
LOG_MODULE_REGISTER(fota_download, CONFIG_FOTA_DOWNLOAD_LOG_LEVEL);
2727

28-
#if defined(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL)
29-
static size_t ext_file_sz;
30-
static size_t ext_rcvd_sz;
31-
#endif
32-
3328
static fota_download_callback_t callback;
3429
static const char *dl_host;
3530
static const char *dl_file;
@@ -105,15 +100,6 @@ static void send_progress(int progress)
105100
#endif
106101
}
107102

108-
static void send_ext_resume(const size_t offset)
109-
{
110-
#if defined(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL)
111-
const struct fota_download_evt evt = { .id = FOTA_DOWNLOAD_EVT_RESUME_OFFSET,
112-
.resume_offset = offset };
113-
callback(&evt);
114-
#endif
115-
}
116-
117103
static void stopped(void)
118104
{
119105
atomic_clear_bit(&flags, FLAG_DOWNLOADING);
@@ -143,27 +129,16 @@ static void dfu_target_callback_handler(enum dfu_target_evt_id evt)
143129

144130
static size_t file_size_get(size_t *size)
145131
{
146-
#if defined(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL)
147-
*size = ext_file_sz;
148-
return 0;
149-
#endif
150132
return downloader_file_size_get(&dl, size);
151133
}
152134

153135
static size_t downloaded_size_get(size_t *size)
154136
{
155-
#if defined(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL)
156-
*size = ext_rcvd_sz;
157-
return 0;
158-
#endif
159137
return downloader_downloaded_size_get(&dl, size);
160138
}
161139

162140
static int dl_cancel(void)
163141
{
164-
#if defined(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL)
165-
return 0;
166-
#endif
167142
return downloader_cancel(&dl);
168143
}
169144

@@ -264,10 +239,6 @@ static int downloader_callback(const struct downloader_evt *event)
264239
}
265240
}
266241

267-
#if defined(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL)
268-
ext_rcvd_sz += event->fragment.len;
269-
#endif
270-
271242
err = dfu_target_write(event->fragment.buf, event->fragment.len);
272243
if (err && err == -EINVAL) {
273244
LOG_INF("Image refused");
@@ -321,7 +292,8 @@ static int downloader_callback(const struct downloader_evt *event)
321292
/* In case of socket errors we can return 0 to retry/continue,
322293
* or non-zero to stop
323294
*/
324-
if ((socket_retries_left) && (event->error == -ECONNRESET)) {
295+
if ((socket_retries_left)
296+
&& ((event->error == -ECONNRESET) || (event->error == -EAGAIN))) {
325297
LOG_WRN("Download socket error. %d retries left...",
326298
socket_retries_left);
327299
socket_retries_left--;
@@ -371,11 +343,6 @@ static int downloader_callback(const struct downloader_evt *event)
371343

372344
static int get_from_offset(const size_t offset)
373345
{
374-
if (IS_ENABLED(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL)) {
375-
send_ext_resume(offset);
376-
return 0;
377-
}
378-
379346
int err = downloader_get_with_host_and_file(&dl, &dl_host_cfg, dl_host, dl_file, offset);
380347

381348
if (err != 0) {
@@ -533,47 +500,21 @@ static void set_host_and_file(char const *const host, char const *const file)
533500
dl_file = file;
534501
}
535502

536-
#if defined(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL)
537-
int fota_download_external_evt_handle(struct downloader_evt const *const evt)
538-
{
539-
return downloader_callback(evt);
540-
}
541-
542-
int fota_download_external_start(const char *host, const char *file,
543-
const enum dfu_target_image_type expected_type,
544-
const size_t image_size)
503+
int fota_download_with_host_cfg(const char *host, const char *file,
504+
int sec_tag, uint8_t pdn_id, size_t fragment_size,
505+
const enum dfu_target_image_type expected_type,
506+
const struct downloader_host_cfg *host_cfg)
545507
{
546-
if (host == NULL || file == NULL || callback == NULL || image_size == 0) {
547-
return -EINVAL;
548-
}
549-
550-
if (atomic_test_and_set_bit(&flags, FLAG_DOWNLOADING)) {
551-
return -EALREADY;
552-
}
553-
554-
atomic_clear_bit(&flags, FLAG_STOPPED);
555-
atomic_clear_bit(&flags, FLAG_RESUME);
556-
set_error_state(FOTA_DOWNLOAD_ERROR_CAUSE_NO_ERROR);
557-
558-
set_host_and_file(host, file);
559-
560-
socket_retries_left = CONFIG_FOTA_SOCKET_RETRIES;
561-
562-
img_type_expected = expected_type;
563-
ext_file_sz = image_size;
564-
ext_rcvd_sz = 0;
565-
566-
atomic_set_bit(&flags, FLAG_FIRST_FRAGMENT);
567-
568-
return 0;
508+
dl_host_cfg = *host_cfg;
509+
LOG_DBG("Downloading %s/%s", host, file);
510+
return fota_download_start_with_image_type(host, file, sec_tag,
511+
pdn_id, fragment_size, expected_type);
569512
}
570-
#endif /* CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL */
571513

572514
int fota_download(const char *host, const char *file,
573515
const int *sec_tag_list, uint8_t sec_tag_count, uint8_t pdn_id, size_t fragment_size,
574516
const enum dfu_target_image_type expected_type)
575517
{
576-
__ASSERT_NO_MSG(!IS_ENABLED(CONFIG_FOTA_DOWNLOAD_EXTERNAL_DL));
577518

578519
if (host == NULL || file == NULL || callback == NULL) {
579520
return -EINVAL;

subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_coap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ endif # WIFI
6868
config NRF_CLOUD_COAP_DOWNLOADS
6969
bool "Download files using CoAP instead of HTTP [EXPERIMENTAL]"
7070
depends on NRF_CLOUD_COAP
71+
select DOWNLOADER_TRANSPORT_COAP
7172
select EXPERIMENTAL
7273
help
7374
Use nRF Cloud CoAP's proxy download resource to download files for FOTA and P-GPS.

subsys/net/lib/nrf_cloud/Kconfig.nrf_cloud_fota

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ config NRF_CLOUD_FOTA_POLL
5050
bool "FOTA job polling helpers (REST/CoAP)"
5151
depends on !NRF_CLOUD_FOTA
5252
depends on FOTA_DOWNLOAD
53-
select FOTA_DOWNLOAD_EXTERNAL_DL if NRF_CLOUD_COAP_DOWNLOADS
5453
help
5554
When enabled, nRF Cloud FOTA job polling helpers will be built. These
5655
functions make it easy to request, download, and handle modem, boot,

subsys/net/lib/nrf_cloud/coap/include/nrf_cloud_coap_transport.h

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,18 +97,17 @@ int nrf_cloud_coap_transport_pause(struct nrf_cloud_coap_client *const client);
9797
*/
9898
int nrf_cloud_coap_transport_resume(struct nrf_cloud_coap_client *const client);
9999

100-
/**@brief Get the CoAP options required to perform a proxy download.
100+
/**@brief Get the URI required to perform a proxy download.
101101
*
102-
* @param opt_accept Option to be populated with COAP_OPTION_ACCEPT details.
103-
* @param opt_proxy_uri Option to be populated with COAP_OPTION_PROXY_URI details.
102+
* @param uri Buffer to store the URI.
103+
* @param uri_len Length of the URI buffer.
104104
* @param host Download host.
105105
* @param path Download file path.
106106
*
107107
* @return 0 if successful, otherwise a negative error code.
108108
*/
109-
int nrf_cloud_coap_transport_proxy_dl_opts_get(struct coap_client_option *const opt_accept,
110-
struct coap_client_option *const opt_proxy_uri,
111-
char const *const host, char const *const path);
109+
int nrf_cloud_coap_transport_proxy_dl_uri_get(char *const uri, size_t uri_len,
110+
char const *const host, char const *const path);
112111

113112
/**@brief Check if device is connected and authorized to use nRF Cloud CoAP.
114113
*

subsys/net/lib/nrf_cloud/coap/src/nrf_cloud_coap_transport.c

Lines changed: 12 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -928,49 +928,33 @@ int nrf_cloud_coap_transport_resume(struct nrf_cloud_coap_client *const client)
928928
#define PROXY_URI_DL_HTTPS_LEN (sizeof(PROXY_URI_DL_HTTPS) - 1)
929929
#define PROXY_URI_DL_SEP "/"
930930
#define PROXY_URI_DL_SEP_LEN (sizeof(PROXY_URI_DL_SEP) - 1)
931-
#define PROXY_URI_ADDED_LEN (PROXY_URI_DL_HTTPS_LEN + PROXY_URI_DL_SEP_LEN)
932931

933-
int nrf_cloud_coap_transport_proxy_dl_opts_get(struct coap_client_option *const opt_accept,
934-
struct coap_client_option *const opt_proxy_uri,
935-
char const *const host, char const *const path)
932+
int nrf_cloud_coap_transport_proxy_dl_uri_get(char *const uri, size_t uri_len,
933+
char const *const host, char const *const path)
936934
{
937-
__ASSERT_NO_MSG(opt_accept != NULL);
938-
__ASSERT_NO_MSG(opt_proxy_uri != NULL);
935+
__ASSERT_NO_MSG(uri != NULL);
939936
__ASSERT_NO_MSG(host != NULL);
940937
__ASSERT_NO_MSG(path != NULL);
941938

942-
size_t uri_idx = 0;
943939
size_t host_len = strlen(host);
944940
size_t path_len = strlen(path);
945941

946-
opt_accept->code = COAP_OPTION_ACCEPT;
947-
opt_accept->len = 1;
948-
opt_accept->value[0] = COAP_CONTENT_FORMAT_TEXT_PLAIN;
942+
const size_t needed_len =
943+
PROXY_URI_DL_HTTPS_LEN + host_len + PROXY_URI_DL_SEP_LEN + path_len;
949944

950-
opt_proxy_uri->code = COAP_OPTION_PROXY_URI;
951-
opt_proxy_uri->len = host_len + path_len + PROXY_URI_ADDED_LEN;
952-
953-
if (opt_proxy_uri->len > CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE) {
945+
if (needed_len > uri_len) {
954946
LOG_ERR("Host and path for CoAP proxy GET is too large: %u bytes",
955-
opt_proxy_uri->len);
956-
LOG_INF("Increase CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE, current value: %d",
957-
CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE);
947+
needed_len);
958948
return -E2BIG;
959949
}
960950

961951
/* We don't want a NULL terminated string, so just copy the data to create the full URI */
962-
memcpy(&opt_proxy_uri->value[uri_idx], PROXY_URI_DL_HTTPS, PROXY_URI_DL_HTTPS_LEN);
963-
uri_idx += PROXY_URI_DL_HTTPS_LEN;
964-
965-
memcpy(&opt_proxy_uri->value[uri_idx], host, host_len);
966-
uri_idx += host_len;
967-
968-
memcpy(&opt_proxy_uri->value[uri_idx], PROXY_URI_DL_SEP, PROXY_URI_DL_SEP_LEN);
969-
uri_idx += PROXY_URI_DL_SEP_LEN;
970-
971-
memcpy(&opt_proxy_uri->value[uri_idx], path, path_len);
952+
memcpy(uri, PROXY_URI_DL_HTTPS, PROXY_URI_DL_HTTPS_LEN);
953+
memcpy(&uri[PROXY_URI_DL_HTTPS_LEN], host, host_len);
954+
memcpy(&uri[PROXY_URI_DL_HTTPS_LEN + host_len], PROXY_URI_DL_SEP, PROXY_URI_DL_SEP_LEN);
955+
memcpy(&uri[PROXY_URI_DL_HTTPS_LEN + host_len + PROXY_URI_DL_SEP_LEN], path, path_len);
972956

973-
LOG_DBG("Proxy URI: %.*s", opt_proxy_uri->len, opt_proxy_uri->value);
957+
LOG_DBG("Proxy URI: %.*s", needed_len, uri);
974958

975959
return 0;
976960
}

subsys/net/lib/nrf_cloud/include/nrf_cloud_download.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,6 @@ struct nrf_cloud_download_data {
5151
/* Downloader data */
5252
struct downloader *dl;
5353
};
54-
55-
#if defined(CONFIG_NRF_CLOUD_COAP_DOWNLOADS)
56-
/* Track the received bytes for CoAP downloads */
57-
size_t coap_rcvd_bytes;
58-
/* Offset used when resuming a download */
59-
size_t resume_offset;
60-
#endif
6154
};
6255

6356
/** @brief Start download. Only one download at a time is allowed. FOTA downloads have priority.
@@ -71,9 +64,6 @@ int nrf_cloud_download_start(struct nrf_cloud_download_data *const cloud_dl);
7164
*/
7265
void nrf_cloud_download_cancel(void);
7366

74-
/** @brief Resume a CoAP download at the provided offset. */
75-
int nrf_cloud_download_coap_offset_resume(const size_t offset);
76-
7767
/** @brief Reset the active download state. Call when download has ended. */
7868
void nrf_cloud_download_end(void);
7969

0 commit comments

Comments
 (0)