Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

subsys: net: download_client rework #17481

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

eivindj-nordic
Copy link
Contributor

@eivindj-nordic eivindj-nordic commented Sep 25, 2024

Work in progress. No need for thorough review yet.

  • Deprecate current download client
  • Download client restructuring:
    • Move socket features to a separate file.
    • Restructuring of socket functions.
    • Update to download client internal states.
    • Replace is_idle(), is_connecting, is_downloading(), is closed() and is_finished() with is_state(). This reduces the code size a bit.
    • Align download client variable name as dlc.
    • Add interface for transport (http, coap, ...). Goal is to make the library easier to maintain and ease the work to add more transports (mqtt, ...).
  • Use range requests for nRF91 TLS only
  • Use uri instead of separate host and filename as input parameters. This has ripple effects to other libraries.
  • Let application provide client buffer. This allows for multiple download clients with different buffer sizes.
  • Parse HTTP header line for line. This reduces the size requirement for the download client recv buffer.
  • Add new field for requesting new data to dlc.
  • Change TLS range override logic.

TODOs

  • Update libraries and samples.
  • Update tests.
  • Address changes suggested for CoAP
  • Migration guide
  • Fixes to align behavior with new (internal) tests.

@eivindj-nordic eivindj-nordic self-assigned this Sep 25, 2024
@github-actions github-actions bot added doc-required PR must not be merged without tech writer approval. changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. labels Sep 25, 2024
@NordicBuilder
Copy link
Contributor

NordicBuilder commented Sep 25, 2024

CI Information

To view the history of this post, clich the 'edited' button above
Build number: 83

Inputs:

Sources:

sdk-nrf: PR head: 898ce25474b7446472debd4a630b8488f9d5c2b2

more details

sdk-nrf:

PR head: 898ce25474b7446472debd4a630b8488f9d5c2b2
merge base: d839e3cda69a64e0f3de12cea337aef824512bcb
target head (main): 95987240d21a43fcb2711eb81909ceb2e622f916
Diff

Github labels

Enabled Name Description
ci-disabled Disable the ci execution
ci-all-test Run all of ci, no test spec filtering will be done
ci-force-downstream Force execution of downstream even if twister fails
ci-run-twister Force run twister
ci-run-zephyr-twister Force run zephyr twister
List of changed files detected by CI (110)
CODEOWNERS
applications
│  ├── asset_tracker_v2
│  │  ├── boards
│  │  │  │ native_sim.conf
│  │  ├── doc
│  │  │  │ asset_tracker_v2_description.rst
│  │  ├── overlay-carrier.conf
│  │  │ prj.conf
│  ├── serial_lte_modem
│  │  ├── doc
│  │  │  │ slm_description.rst
│  │  ├── overlay-carrier.conf
│  │  ├── prj.conf
│  │  ├── src
│  │  │  │ slm_at_fota.c
doc
│  ├── nrf
│  │  ├── libraries
│  │  │  ├── bin
│  │  │  │  ├── lwm2m_carrier
│  │  │  │  │  ├── app_integration.rst
│  │  │  │  │  │ requirements.rst
│  │  │  ├── networking
│  │  │  │  ├── aws_fota.rst
│  │  │  │  ├── azure_fota.rst
│  │  │  │  ├── downloader.rst
│  │  │  │  ├── fota_download.rst
│  │  │  │  ├── nrf_cloud.rst
│  │  │  │  │ nrf_cloud_pgps.rst
│  │  ├── releases_and_maturity
│  │  │  ├── known_issues.rst
│  │  │  ├── releases
│  │  │  │  │ release-notes-2.4.0.rst
include
│  ├── net
│  │  ├── download_client.h
│  │  ├── downloader.h
│  │  ├── downloader_transport.h
│  │  ├── fota_download.h
│  │  │ nrf_cloud_pgps.h
lib
│  ├── bin
│  │  ├── lwm2m_carrier
│  │  │  ├── Kconfig
│  │  │  ├── include
│  │  │  │  │ lwm2m_os.h
│  │  │  ├── os
│  │  │  │  │ lwm2m_os.c
samples
│  ├── cellular
│  │  ├── http_update
│  │  │  ├── application_update
│  │  │  │  ├── overlay-carrier.conf
│  │  │  │  ├── prj.conf
│  │  │  │  ├── src
│  │  │  │  │  │ main.c
│  │  │  ├── modem_delta_update
│  │  │  │  ├── prj.conf
│  │  │  │  ├── src
│  │  │  │  │  │ main.c
│  │  │  ├── modem_full_update
│  │  │  │  ├── prj.conf
│  │  │  │  ├── src
│  │  │  │  │  │ main.c
│  │  ├── location
│  │  │  │ overlay-pgps.conf
│  │  ├── lwm2m_carrier
│  │  │  │ prj.conf
│  │  ├── lwm2m_client
│  │  │  ├── prj.conf
│  │  │  │ sample_description.rst
│  │  ├── modem_shell
│  │  │  ├── overlay-carrier.conf
│  │  │  ├── overlay-modem_fota_full.conf
│  │  │  ├── prj.conf
│  │  │  ├── src
│  │  │  │  ├── fota
│  │  │  │  │  │ fota_shell.c
│  │  │  │  ├── gnss
│  │  │  │  │  │ gnss.c
│  │  ├── nrf_cloud_multi_service
│  │  │  ├── Kconfig
│  │  │  │ prj.conf
│  │  ├── nrf_cloud_rest_fota
│  │  │  │ prj.conf
│  ├── net
│  │  ├── aws_iot
│  │  │  ├── boards
│  │  │  │  ├── nrf7002dk_nrf5340_cpuapp_ns.conf
│  │  │  │  ├── nrf9151dk_nrf9151_ns.conf
│  │  │  │  ├── nrf9160dk_nrf9160_ns.conf
│  │  │  │  ├── nrf9161dk_nrf9161_ns.conf
│  │  │  │  ├── thingy91_nrf9160_ns.conf
│  │  │  │  │ thingy91x_nrf9151_ns.conf
│  │  ├── azure_iot_hub
│  │  │  ├── README.rst
│  │  │  ├── boards
│  │  │  │  ├── nrf7002dk_nrf5340_cpuapp_ns.conf
│  │  │  │  ├── nrf9151dk_nrf9151_ns.conf
│  │  │  │  ├── nrf9160dk_nrf9160_ns.conf
│  │  │  │  │ nrf9161dk_nrf9161_ns.conf
│  │  ├── download
│  │  │  ├── README.rst
│  │  │  ├── prj.conf
│  │  │  ├── sample.yaml
│  │  │  ├── src
│  │  │  │  │ main.c
scripts
│  │ quarantine_integration.yaml
subsys
│  ├── dfu
│  │  ├── dfu_target
│  │  │  │ Kconfig
│  ├── net
│  │  ├── lib
│  │  │  ├── CMakeLists.txt
│  │  │  ├── Kconfig
│  │  │  ├── aws_fota
│  │  │  │  ├── src
│  │  │  │  │  │ aws_fota.c
│  │  │  ├── azure_fota
│  │  │  │  │ azure_fota.c
│  │  │  ├── downloader
│  │  │  │  ├── CMakeLists.txt
│  │  │  │  ├── Kconfig
│  │  │  │  ├── dl_transports.ld
│  │  │  │  ├── include
│  │  │  │  │  ├── dl_parse.h
│  │  │  │  │  │ dl_socket.h
│  │  │  │  ├── src
│  │  │  │  │  ├── dl_parse.c
│  │  │  │  │  ├── dl_socket.c
│  │  │  │  │  ├── downloader.c
│  │  │  │  │  ├── sanity.c
│  │  │  │  │  ├── shell.c
│  │  │  │  │  ├── transports
│  │  │  │  │  │  ├── coap.c
│  │  │  │  │  │  │ http.c
│  │  │  ├── fota_download
│  │  │  │  ├── CMakeLists.txt
│  │  │  │  ├── Kconfig
│  │  │  │  ├── src
│  │  │  │  │  ├── fota_download.c
│  │  │  │  │  ├── util
│  │  │  │  │  │  ├── fota_download_delta_modem.c
│  │  │  │  │  │  ├── fota_download_full_modem.c
│  │  │  │  │  │  │ fota_download_util.c
│  │  │  ├── mcumgr_smp_client
│  │  │  │  ├── Kconfig
│  │  │  │  ├── src
│  │  │  │  │  │ mcumgr_smp_client_shell.c
│  │  │  ├── nrf_cloud
│  │  │  │  ├── Kconfig.nrf_cloud_fota
│  │  │  │  ├── Kconfig.nrf_cloud_pgps
│  │  │  │  ├── include
│  │  │  │  │  ├── nrf_cloud_download.h
│  │  │  │  │  │ nrf_cloud_pgps_utils.h
│  │  │  │  ├── src
│  │  │  │  │  ├── nrf_cloud_codec_internal.c
│  │  │  │  │  ├── nrf_cloud_download.c
│  │  │  │  │  ├── nrf_cloud_fota.c
│  │  │  │  │  ├── nrf_cloud_fota_poll.c
│  │  │  │  │  ├── nrf_cloud_pgps.c
│  │  │  │  │  │ nrf_cloud_pgps_utils.c
tests
│  ├── subsys
│  │  ├── net
│  │  │  ├── lib
│  │  │  │  ├── aws_fota
│  │  │  │  │  ├── aws_fota_json
│  │  │  │  │  │  │ CMakeLists.txt
│  │  │  │  ├── downloader
│  │  │  │  │  ├── CMakeLists.txt
│  │  │  │  │  ├── boards
│  │  │  │  │  │  ├── native_sim.conf
│  │  │  │  │  │  │ qemu_cortex_m3.conf
│  │  │  │  │  ├── prj.conf
│  │  │  │  │  ├── src
│  │  │  │  │  │  │ main.c
│  │  │  │  │  │ testcase.yaml
│  │  │  │  ├── fota_download
│  │  │  │  │  ├── CMakeLists.txt
│  │  │  │  │  ├── src
│  │  │  │  │  │  │ test_fota_download.c
│  │  │  │  ├── lwm2m_client_utils
│  │  │  │  │  │ CMakeLists.txt
│  │  │  │  ├── lwm2m_fota_utils
│  │  │  │  │  │ CMakeLists.txt
│  │  │  │  ├── mcumgr_smp_client
│  │  │  │  │  │ CMakeLists.txt
│  │  │  │  ├── nrf_cloud
│  │  │  │  │  ├── cloud
│  │  │  │  │  │  │ CMakeLists.txt

Outputs:

Toolchain

Version: f51bdba1d9
Build docker image: docker-dtr.nordicsemi.no/sw-production/ncs-build:f51bdba1d9_912848a074

Test Spec & Results: ✅ Success; ❌ Failure; 🟠 Queued; 🟡 Progress; ◻️ Skipped; ⚠️ Quarantine

  • ◻️ Toolchain - Skipped: existing toolchain is used
  • ❌ Build twister
    • sdk-nrf test count: 618
  • ❌ Integration tests
    • ❌ test-fw-nrfconnect-boot
    • ❌ test-fw-nrfconnect-chip
    • ❌ test-fw-nrfconnect-nrf-iot_cloud
    • ❌ test-fw-nrfconnect-nrf-iot_serial_lte_modem
    • ❌ test-fw-nrfconnect-nrf-iot_zephyr_lwm2m
    • ❌ test-fw-nrfconnect-nrf-iot_samples
    • ❌ test-fw-nrfconnect-nrf-iot_lwm2m
    • ❌ test-fw-nrfconnect-nrf-iot_thingy91
    • ❌ test-fw-nrfconnect-zigbee
    • ❌ test-sdk-find-my
    • ❌ test-fw-nrfconnect-nrf-iot_mosh
    • ❌ test-fw-nrfconnect-nrf-iot_positioning
    • ❌ test-sdk-sidewalk
    • ❌ test-sdk-mcuboot
    • ⚠️ test-fw-nrfconnect-fw-update
Disabled integration tests
    • desktop52_verification
    • doc-internal
    • test_ble_nrf_config
    • test-fw-nrfconnect-ble_mesh
    • test-fw-nrfconnect-ble_samples
    • test-fw-nrfconnect-fem
    • test-fw-nrfconnect-nfc
    • test-fw-nrfconnect-nrf-iot_libmodem-nrf
    • test-fw-nrfconnect-nrf-iot_nrf_provisioning
    • test-fw-nrfconnect-nrf_crypto
    • test-fw-nrfconnect-ps
    • test-fw-nrfconnect-rpc
    • test-fw-nrfconnect-rs
    • test-fw-nrfconnect-tfm
    • test-fw-nrfconnect-thread
    • test-low-level
    • test-sdk-audio
    • test-sdk-dfu
    • test-sdk-pmic-samples
    • test-sdk-wifi

Note: This message is automatically posted and updated by the CI

Comment on lines 133 to 137
struct download_client_host_cfg {
/** Server hosting the file, null-terminated.
* The host name must be kept in scope while download is going on.
*/
const char *hostname;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since you are so heavily refactoring, I would propose that we get rid of this separation of host and path.
Just use URI on the API.
It is actually very rare that any interfaces would give us host and path separately. I only know nRF Cloud to do so on some REST APIs. It is more common that we receive full URI where to fetch the data.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh.. and also now host is provided inside a struct and path is provided as a function parameter. This emphasizes the separation even further.

It feels like cleanest API would just take URI as one parameter, or field inside this struct. Let the HTTP parser to split protocol, host, port and path.

@github-actions github-actions bot removed the changelog-entry-required Update changelog before merge. Remove label if entry is not needed or already added. label Oct 17, 2024
@eivindj-nordic eivindj-nordic force-pushed the 25700_download_client_rework branch 6 times, most recently from 6573c1d to 2666f2d Compare October 24, 2024 13:07
@eivindj-nordic eivindj-nordic force-pushed the 25700_download_client_rework branch 9 times, most recently from 272b2de to c058985 Compare November 1, 2024 09:41
@eivindj-nordic
Copy link
Contributor Author

Marking ready for review to trigger CI.

@eivindj-nordic eivindj-nordic marked this pull request as ready for review November 1, 2024 12:21
@eivindj-nordic eivindj-nordic requested a review from a team as a code owner November 1, 2024 12:21
@eivindj-nordic eivindj-nordic requested review from a team as code owners November 13, 2024 09:26
@eivindj-nordic eivindj-nordic requested review from umapraseeda and divipillai and removed request for a team November 13, 2024 09:26
@eivindj-nordic eivindj-nordic force-pushed the 25700_download_client_rework branch 5 times, most recently from b39dec5 to a25fb0d Compare November 13, 2024 11:49
:local:
:depth: 2

The download client library can be used to download files from a server.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The download client library can be used to download files from a server.
You can use the Download client library to download files from a server.

Overview
********

The download is carried out in a separate thread, and the application receives events such as :c:enumerator:`DOWNLOADER_EVT_FRAGMENT` that contain the data fragments as the download progresses.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The download is carried out in a separate thread, and the application receives events such as :c:enumerator:`DOWNLOADER_EVT_FRAGMENT` that contain the data fragments as the download progresses.
The download is carried out in a separate thread and the application receives events such as :c:enumerator:`DOWNLOADER_EVT_FRAGMENT` that contain the data fragments as the download progresses.

Protocols
=========

The library supports HTTP, HTTPS (TLS 1.2), CoAP, and CoAPS (DTLS 1.2) over IPv4 and IPv6. If other protocols are required they can be added by the application. See :c:file:`downloader_transport.h` for details.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The library supports HTTP, HTTPS (TLS 1.2), CoAP, and CoAPS (DTLS 1.2) over IPv4 and IPv6. If other protocols are required they can be added by the application. See :c:file:`downloader_transport.h` for details.
The library supports HTTP, HTTPS (TLS 1.2), CoAP, and CoAPS (DTLS 1.2) over IPv4 and IPv6.
If other protocols are required they can be added by the application.
See :c:file:`downloader_transport.h` for details.

=========

The library supports HTTP, HTTPS (TLS 1.2), CoAP, and CoAPS (DTLS 1.2) over IPv4 and IPv6. If other protocols are required they can be added by the application. See :c:file:`downloader_transport.h` for details.
The protocol used for the download is specified by the start of the ``uri``. Use ``http://`` for HTTP, ``https://`` for HTTPS, ``coap://`` for COAP and ``coaps://`` for COAPS.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The protocol used for the download is specified by the start of the ``uri``. Use ``http://`` for HTTP, ``https://`` for HTTPS, ``coap://`` for COAP and ``coaps://`` for COAPS.
The protocol used for the download is specified in the beginning of the URI.
Use ``http://`` for HTTP, ``https://`` for HTTPS, ``coap://`` for COAP and ``coaps://`` for COAPS.


The library supports HTTP, HTTPS (TLS 1.2), CoAP, and CoAPS (DTLS 1.2) over IPv4 and IPv6. If other protocols are required they can be added by the application. See :c:file:`downloader_transport.h` for details.
The protocol used for the download is specified by the start of the ``uri``. Use ``http://`` for HTTP, ``https://`` for HTTPS, ``coap://`` for COAP and ``coaps://`` for COAPS.
If no protocol is specified, the download client will default to HTTP or HTTPS, dependent on the server security configuration.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If no protocol is specified, the download client will default to HTTP or HTTPS, dependent on the server security configuration.
If no protocol is specified, the download client defaults to HTTP or HTTPS, depending on the server security configuration.

printk("Download client deinit failed, err %d\n", err);
}

This will free up the resources used by the download client.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
This will free up the resources used by the download client.
This will free up the resources used by the library.


This will free up the resources used by the download client.

The following snippet shouws how to download a file using HTTPS:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The following snippet shouws how to download a file using HTTPS:
The following snippet shows how to download a file using HTTPS:

* @c downloader_host_cfg.downloader_host_cfg is set, the downloader will stay
* connected to the server. If a new download is initiated from a different server, the
* current connection is closed and the downloader will connect to the new server. The
* connection can be closed by deinitilzing the downloader, which will also free the
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* connection can be closed by deinitilzing the downloader, which will also free the
* connection can be closed by deinitializing the downloader, which will also free the

* connection can be closed by deinitilzing the downloader, which will also free the
* downloaders resources.
*
* If the @c downloader_host_cfg.keep_connection flag is not set the downloader
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* If the @c downloader_host_cfg.keep_connection flag is not set the downloader
* If the @c downloader_host_cfg.keep_connection flag is not set, the downloader

* This initiates an asynchronous connect-download-disconnect sequence to the target
* host.
*
* Downloads are handled one at a time. If previous download is not finished
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* Downloads are handled one at a time. If previous download is not finished
* Downloads are handled one at a time. If previous download is not finished,

@eivindj-nordic eivindj-nordic force-pushed the 25700_download_client_rework branch 2 times, most recently from f31e3f6 to bfb7c2a Compare November 13, 2024 12:49
@NordicBuilder
Copy link
Contributor

You can find the documentation preview for this PR at this link. It will be updated about 10 minutes after the documentation build succeeds.

Note: This comment is automatically posted by the Documentation Publishing GitHub Action.

@eivindj-nordic eivindj-nordic force-pushed the 25700_download_client_rework branch 12 times, most recently from 649d1d7 to 73302f2 Compare November 14, 2024 12:48
The new downloader is replacing the download_client library and is
based on that.

Internal restructuring:

* Restructuring of socket functions and files.
* Parse HTTP header line for line. This reduces the size requirement
  for the download client recv buffer.
* Change TLS range override logic.
* Use range requests for nRF91 TLS only, and when specified by app.

API updates:

* Let application provide client buffer. This allows for multiple
  download clients with different buffer sizes.
* Add downloader_deinit()
* Add downloader_stop()
* Remove downloader_disconnect()
* Changed signature of downloader_init(), downloader_start()
  and downloader_get() to take a URI.
* Added downloader_get_with_host_and_path() for downloads where
  host and path are separate arguments to keep backwards compatibility.
* The transports (http, coap) are now separated out of the download
  client with its own API.

Future work:

* Take uri as input param to fota_download library and use URI in
  other relevant libaries and structures.
* Curent download client is deprecated and will be removed later.

Signed-off-by: Eivind Jølsgard <[email protected]>
@NordicBuilder
Copy link
Contributor

You can find the documentation preview for this PR at this link. It will be updated about 10 minutes after the documentation build succeeds.

Note: This comment is automatically posted by the Documentation Publish GitHub Action.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
DNM doc-required PR must not be merged without tech writer approval.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants