From 67e3d5e54b697a309b6095425d2fcb6971778dee Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Tue, 26 Jan 2021 15:43:08 +0100 Subject: [PATCH 001/528] [nrf noup] ci: set `ZEPHYR__KCONFIG` for NCS modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit sets `ZEPHYR__KCONFIG` variable for each Kconfig file discovered in `nrf/modules//Kconfig`. This is not meant as a permanent solution; we should do more careful consideration on the optimal approach forward that will allow compliance_check.py to be used downstream with custom module_ext_roots, and at the same time keep current flexibility for module glue code handling intact. Signed-off-by: Torsten Rasmussen Signed-off-by: Martí Bolívar (cherry picked from commit c78a6eaec795464633b7fa68a8bc3a1ef4bf35c4) --- scripts/ci/check_compliance.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/scripts/ci/check_compliance.py b/scripts/ci/check_compliance.py index bc65892c85a7..caef0d40757d 100755 --- a/scripts/ci/check_compliance.py +++ b/scripts/ci/check_compliance.py @@ -303,6 +303,13 @@ def get_modules(self, modules_file): modules = [name for name in os.listdir(modules_dir) if os.path.exists(os.path.join(modules_dir, name, 'Kconfig'))] + nrf_modules_dir = ZEPHYR_BASE + '/../nrf/modules' + nrf_modules = [] + if os.path.exists(nrf_modules_dir): + nrf_modules = [name for name in os.listdir(nrf_modules_dir) if + os.path.exists(os.path.join(nrf_modules_dir, name, + 'Kconfig'))] + with open(modules_file, 'r') as fp_module_file: content = fp_module_file.read() @@ -312,6 +319,15 @@ def get_modules(self, modules_file): re.sub('[^a-zA-Z0-9]', '_', module).upper(), modules_dir + '/' + module + '/Kconfig' )) + for module in nrf_modules: + fp_module_file.write("ZEPHYR_{}_KCONFIG = {}\n".format( + re.sub('[^a-zA-Z0-9]', '_', module).upper(), + nrf_modules_dir + '/' + module + '/Kconfig' + )) + fp_module_file.write("NCS_{}_KCONFIG = {}\n".format( + re.sub('[^a-zA-Z0-9]', '_', module).upper(), + modules_dir + '/' + module + '/Kconfig' + )) fp_module_file.write(content) def get_kconfig_dts(self, kconfig_dts_file): From f9eac37be8ef89db5b2cbb06e38aef09e13fc448 Mon Sep 17 00:00:00 2001 From: Sebastian Wezel Date: Tue, 15 Mar 2022 13:12:25 +0100 Subject: [PATCH 002/528] [nrf noup] ci: add .github/test-spec.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This file is used for NCS-specific testing configuration based on modifications to files in this repository. Signed-off-by: Alperen Sener Signed-off-by: Dominik Ermel Signed-off-by: Elisabeth Solheim Klakken Signed-off-by: Mariusz Poslinski Signed-off-by: Markus Swarowsky Signed-off-by: Robert Lubos Signed-off-by: Sebastian Wezel Signed-off-by: Tomasz Tyzenhauz Signed-off-by: Fredrik Ås Signed-off-by: Michał Szablowski Signed-off-by: Tony Le Signed-off-by: Krishna T (cherry picked from commit 2a59fbdf425895a357fc6bff919d3108b6e35469) (cherry picked from commit acb96b140c95e933546acc41cc6df22b609342db) (cherry picked from commit e102ad15b3804c9d71447dda2bf4e321ec4185fb) --- .github/test-spec.yml | 143 ++++++++++++++++++++++++++++++++++++++++++ CODEOWNERS | 1 + 2 files changed, 144 insertions(+) create mode 100644 .github/test-spec.yml diff --git a/.github/test-spec.yml b/.github/test-spec.yml new file mode 100644 index 000000000000..c252335495ac --- /dev/null +++ b/.github/test-spec.yml @@ -0,0 +1,143 @@ +# This is the Jenkins ci variant of the .github/labler.yaml +"CI-iot-zephyr-lwm2m-test": + - "drivers/console/**/*" + - "drivers/flash/**/*" + - "subsys/dfu/boot/**/*" + - "subsys/net/ip/**/*" + - "subsys/net/lib/http/**/*" + - "subsys/net/lib/lwm2m//**/*" + - "subsys/net/**/*" + +"CI-iot-samples-test": + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "dts/arm/nordic/nrf9160*" + - "include/net/**/*" + - "subsys/net/lib/**/*" + +"CI-iot-libraries-test": + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "dts/arm/nordic/nrf9160*" + - "include/net/socket_ncs.h" + - "subsys/testsuite/ztest/**/*" + +"CI-lwm2m-test": + - "**/*" + +"CI-boot-dfu-test": + - "subsys/mgmt/mcumgr/**/*" + - "subsys/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "include/dfu/**/*" + - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" + +"CI-tfm-test": + - "**/*" + +"CI-ble-test": + - "**/*" + +"CI-mesh-test": + - "subsys/bluetooth/mesh/**/*" + - "include/bluetooth/mesh/**/*" + - "samples/bluetooth/mesh/**/*" + - "samples/bluetooth/mesh_demo/**/*" + - "samples/bluetooth/mesh_provisioner/**/*" + - "tests/bluetooth/mesh/**/*" + - "tests/bluetooth/mesh_shell/**/*" + +"CI-zigbee-test": + - "subsys/mgmt/mcumgr/**/*" + - "subsys/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "include/dfu/**/*" + +"CI-thingy91-test": + - "**/*" + +"CI-desktop-test": + - "**/*" + +"CI-crypto-test": + - "**/*" + +"CI-rs-test": + - "**/*" + +"CI-homekit-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/net/lib/openthread/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "samples/hci_rpmsg/**/*" + - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + +"CI-thread-test": + - "**/*" + +"CI-nfc-test": + - "**/*" + +"CI-matter-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/net/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "drivers/net/**/*" + - "samples/hci_rpmsg/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" + +"CI-find-my-test": + - "**/*" + +"CI-gazell-test": + - "**/*" + +"CI-rpc-test": + - "**/*" + +"CI-modemshell-test": + - "include/net/**/*" + - "include/posix/**/*" + - "include/shell/**/*" + - "drivers/net/**/*" + - "drivers/serial/**/*" + - "drivers/wifi/**/*" + - "subsys/shell/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-positioning-test": + - "include/net/**/*" + - "include/posix/**/*" + - "drivers/net/**/*" + - "drivers/wifi/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" + +"CI-cloud-test": + - "include/zephyr/dfu/**/*" + - "include/zephyr/net/**/*" + - "include/zephyr/posix/**/*" + - "include/zephyr/settings/**/*" + - "drivers/led/**/*" + - "drivers/net/**/*" + - "drivers/sensor/**/*" + - "drivers/serial/**/*" + - "drivers/wifi/**/*" + - "lib/posix/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/net/**/*" + - "subsys/settings/**/*" diff --git a/CODEOWNERS b/CODEOWNERS index bc22b561ea68..d0cff8e135c7 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -14,6 +14,7 @@ # * @galak @nashif /.github/ @nashif @stephanosio +/.github/test-spec.yml @nrfconnect/ncs-test-leads /.github/workflows/ @galak @nashif /MAINTAINERS.yml @MaureenHelm /arch/arc/ @abrodkin @ruuddw @evgeniy-paltsev From 5e2f4ecc0bd4171ff60bfbc9f60271d0a30142cc Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Fri, 28 Jan 2022 12:02:58 +0100 Subject: [PATCH 003/528] [nrf noup] ci: clang: parallel execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring back parallel execution to the clang action. In the upstream they went to use a single dedicated powerful agent to run this. We need to keep this as we have to base on agents available in github's cloud. zephyr_runner is upstream's proprietary agent inaccessible outside of upstream's CI. Use ubuntu-latest instead. Signed-off-by: Maciej Perkowski Signed-off-by: Gerard Marull-Paretas Signed-off-by: Dominik Ermel Signed-off-by: Torsten Rasmussen Signed-off-by: Tomasz Moń Signed-off-by: Stephanos Ioannidis Signed-off-by: Vinayak Kariappa Chettimada (cherry picked from commit 5b3d0ff9ab29e66d52fd7c3ffbd50e9e97b1d7d5) --- .github/workflows/clang.yaml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index b30ccbd9516e..f2f67c4923a2 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -8,8 +8,7 @@ concurrency: jobs: clang-build: - if: github.repository_owner == 'zephyrproject-rtos' - runs-on: zephyr-runner-linux-x64-4xlarge + runs-on: ubuntu-latest container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.1 options: '--entrypoint /bin/bash' @@ -19,11 +18,13 @@ jobs: fail-fast: false matrix: platform: ["native_posix"] + subset: [1, 2, 3, 4, 5] env: ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.0 LLVM_TOOLCHAIN_PATH: /usr/lib/llvm-16 COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} BASE_REF: ${{ github.base_ref }} + MATRIX_SIZE: 5 outputs: report_needed: ${{ steps.twister.outputs.report_needed }} steps: @@ -85,7 +86,7 @@ jobs: id: cache-ccache uses: zephyrproject-rtos/action-s3-cache@v1.2.0 with: - key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.platform }}-ccache + key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.subset }}-ccache path: /github/home/.ccache aws-s3-bucket: ccache.zephyrproject.org aws-access-key-id: ${{ secrets.CCACHE_S3_ACCESS_KEY_ID }} @@ -97,6 +98,16 @@ jobs: test -d github/home/.ccache && rm -rf /github/home/.ccache && mv github/home/.ccache /github/home/.ccache ccache -M 10G -s + - name: Build test plan with Twister + id: twister_test_plan + run: | + export ZEPHYR_BASE=${PWD} + export ZEPHYR_TOOLCHAIN_VARIANT=llvm + + # check if we need to run a full twister or not based on files changed + python3 ./scripts/ci/test_plan.py -p native_posix -c origin/${BASE_REF}.. + + - name: Run Tests with Twister id: twister run: | @@ -110,7 +121,7 @@ jobs: if [ -s testplan.json ]; then echo "report_needed=1" >> $GITHUB_OUTPUT # Full twister but with options based on changes - ./scripts/twister --force-color --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 + ./scripts/twister --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 --subset ${{matrix.subset}}/${MATRIX_SIZE} else # if nothing is run, skip reporting step echo "report_needed=0" >> $GITHUB_OUTPUT @@ -124,7 +135,7 @@ jobs: if: always() && steps.twister.outputs.report_needed != 0 uses: actions/upload-artifact@v3 with: - name: Unit Test Results (Subset ${{ matrix.platform }}) + name: Unit Test Results (Subset ${{ matrix.subset }}) path: twister-out/twister.xml clang-build-results: From 4a6d5fc57fe7589b2585ee5e44341f50821cc653 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 30 Nov 2018 14:07:56 +0100 Subject: [PATCH 004/528] [nrf noup] ci: NCS-specific CI tweaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Necessary changes for NCS CI. - Add a Jenkinsfile - compliance.yml: Disable check for merge commits, since we have upmerges downstream. Add an additional check for sauce tags (details in scripts/gitlint) Also, since in the code we refer to Kconfig symbols that are defined in the sdk-nrf repository, the Kconfig checks (Kconfig and KconfigBasic) will not pass so exclude them. - Extend the max commit line lengths for Gitlint to account for sauce tags - scripts/gitlint: Add support for sauce tags checks. In order to not interfere with CI in other repos (namely sdk-nrf) this is run as an independent gitlint invocation and not as part of check_compliance.py. This invocation enables the ncs-sauce-tags rule and, since it runs before rebasing and thus will run on merge commits, disables the title-starts-with-subsystem rule by setting a catch-all regex. Signed-off-by: Carles Cufi Signed-off-by: Dominik Ermel Signed-off-by: Martí Bolívar Signed-off-by: Vinayak Kariappa Chettimada Signed-off-by: Krishna T (cherry picked from commit d34b035bcc569431b7008c72edc55db1b29bccf3) --- .github/workflows/compliance.yml | 12 +++++-- .gitlint | 4 +-- Jenkinsfile | 5 +++ scripts/gitlint/ncs.py | 55 ++++++++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 5 deletions(-) create mode 100644 Jenkinsfile create mode 100644 scripts/gitlint/ncs.py diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index f84faff3e4af..a41ab9a47199 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -38,8 +38,14 @@ jobs: git config --global user.name "Your Name" git remote -v # Ensure there's no merge commits in the PR - [[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ - (echo "::error ::Merge commits not allowed, rebase instead";false) + #[[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ + #(echo "::error ::Merge commits not allowed, rebase instead";false) + # Sauce tag checks before rebasing + # Handle single commit separately + if [[ "$(git rev-list --first-parent --count origin/${BASE_REF}..HEAD)" == "1" ]]; then COMMITS="--commit"; else COMMITS="--commits"; fi + git rev-list --first-parent origin/${BASE_REF}..HEAD | paste -sd, | \ + xargs gitlint -c ncs-sauce-tags.enable=true \ + -c title-starts-with-subsystem.regex=".*" $COMMITS git rebase origin/${BASE_REF} # debug git log --pretty=oneline | head -n 10 @@ -56,7 +62,7 @@ jobs: # debug ls -la git log --pretty=oneline | head -n 10 - ./scripts/ci/check_compliance.py --annotate -e KconfigBasic \ + ./scripts/ci/check_compliance.py --annotate -e KconfigBasic -e Kconfig \ -c origin/${BASE_REF}.. - name: upload-results diff --git a/.gitlint b/.gitlint index b8d25ce49b92..8a33f140b2ab 100644 --- a/.gitlint +++ b/.gitlint @@ -16,7 +16,7 @@ debug = false extra-path=scripts/gitlint [title-max-length-no-revert] -line-length=75 +line-length=120 [body-min-line-count] min-line-count=1 @@ -42,7 +42,7 @@ words=wip [max-line-length-with-exceptions] # B1 = body-max-line-length -line-length=75 +line-length=120 [body-min-length] min-length=3 diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000000..3b9cf0022399 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,5 @@ +@Library("CI_LIB") _ + +def pipeline = new ncs.sdk_zephyr.Main() + +pipeline.run(JOB_NAME) diff --git a/scripts/gitlint/ncs.py b/scripts/gitlint/ncs.py new file mode 100644 index 000000000000..a70ce4c900c2 --- /dev/null +++ b/scripts/gitlint/ncs.py @@ -0,0 +1,55 @@ +# Copyright (c) 2022 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +from gitlint.rules import BoolOption, CommitRule, RuleViolation +import re + +class NCSSauceTags(CommitRule): + """This rule enforces the NCS sauce tag specification. + https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/dm_code_base.html#oss-repositories-downstream-project-history + """ + + # A rule MUST have a human friendly name + name = "ncs-sauce-tags" + + # A rule MUST have a *unique* id, we recommend starting with UC (for User-defined Commit-rule). + id = "UC100" + + options_spec = [BoolOption('enable', False, 'Enable the Sauce Tags Rule')] + + def validate(self, commit): + self.log.debug(f'NCSSauceTags: enable:{self.options["enable"].value} ' \ + f'sha:{commit.sha}') + + if not self.options['enable'].value: + self.log.debug(f'Disabled, skipping') + return + + m = re.match(r'^(Revert\s+\")?\[nrf (mergeup|fromtree|fromlist|noup)\]\s+', + commit.message.title) + if not m: + return [RuleViolation(self.id, 'Title does not contain a sauce tag', + line_nr=1)] + + tag = m.group(1) + self.log.debug(f'Matched sauce tag {tag}') + + if tag == 'mergeup': + if not commit.is_merge_commit: + return [RuleViolation(self.id, + 'mergeup used in a non-merge commit')] + if not re.match(r'^\[nrf mergeup\] Merge upstream up to commit \b([a-f0-9]{40})\b', + commit.message.title): + return [RuleViolation(self.id, 'Invalid mergeup commit title')] + elif tag == 'fromlist': + regex = r'^Upstream PR: https://github\.com/.*/pull/\d+' + matches = re.findall(regex, '\n'.join(commit.message.body), re.MULTILINE) + if len(matches) == 0: + return [RuleViolation(self.id, + 'Missing Upstream PR reference in fromlist commit')] + elif tag == 'fromtree': + regex = r'^\(cherry picked from commit \b([a-f0-9]{40})\b\)' + matches = re.findall(regex, '\n'.join(commit.message.body), re.MULTILINE) + if len(matches) == 0: + return [RuleViolation(self.id, + 'Missing cherry-pick reference in fromtree commit')] From 1667b8f0abd8095b2593420e14ba3f4b68c33e59 Mon Sep 17 00:00:00 2001 From: Piotr Golyzniak Date: Mon, 1 Aug 2022 13:06:01 +0200 Subject: [PATCH 005/528] [nrf noup] ci: scripts: add quarantine file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add scripts/quarantine.yaml file, which will be used in CI. Signed-off-by: Piotr Golyzniak Signed-off-by: Andrzej Głąbek Signed-off-by: Maciej Perkowski Signed-off-by: Robert Lubos (cherry picked from commit d08f81fe56931040f77ce9a2f703bf445b0c0bdc) (cherry picked from commit 9a7ce33cfd8cfcbbf0ab2cedd8c94f09b9c4e9d2) (cherry picked from commit b1766970c8cf3309ef93597a52c6999a864883eb) --- scripts/quarantine.yaml | 80 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 scripts/quarantine.yaml diff --git a/scripts/quarantine.yaml b/scripts/quarantine.yaml new file mode 100644 index 000000000000..ca85bcb8cfa4 --- /dev/null +++ b/scripts/quarantine.yaml @@ -0,0 +1,80 @@ +# The configurations resulting as a product of scenarios and platforms +# will be skipped if quarantine is used. More details here: +# https://docs.zephyrproject.org/latest/guides/test/twister.html#quarantine + +- scenarios: + - testing.ztest.busy_sim + - testing.ztest.busy_sim_nrf52840dk_pin + platforms: + - nrf52840dk_nrf52840 + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.unary_f64 + platforms: + - nrf5340dk_nrf5340_cpunet + - qemu_cortex_m3 + comment: "Flash overflows" + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.binary_f16 + - libraries.cmsis_dsp.matrix.binary_f16.fpu + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Flash overflows" + +# Already reported, but will not be fixed (look at the discussion): +# https://github.com/zephyrproject-rtos/zephyr/issues/44947 +- scenarios: + - libraries.cmsis_dsp.matrix.binary_q15 + - libraries.cmsis_dsp.matrix.binary_q15.fpu + - libraries.cmsis_dsp.matrix.unary_f32 + - libraries.cmsis_dsp.matrix.unary_f32.fpu + - libraries.cmsis_dsp.matrix.unary_f64 + - libraries.cmsis_dsp.matrix.unary_f64.fpu + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + - nrf9160dk_nrf9160_ns + comment: "Flash overflows" + +# libsdl2-dev package should be added into docker image +- scenarios: + - sample.boards.nrf.nrf_led_matrix + - sample.display.lvgl.gui + platforms: + - native_posix + comment: "libsdl2-dev package not available" + +- scenarios: + - sample.net.sockets.echo_server.usbnet + - sample.net.sockets.echo_server.usbnet_composite + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - sample.net.zperf.netusb_ecm + - sample.net.zperf.netusb_eem + - sample.net.zperf.netusb_rndis + platforms: + - nrf52833dk_nrf52833 + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - net.mqtt.tls + platforms: + - nrf5340dk_nrf5340_cpuapp_ns + comment: "Ram/flash overflows, also in the upstream" + +- scenarios: + - kernel.common.picolibc + - libraries.picolibc + - libraries.libc.picolibc.mem_alloc + - libraries.picolibc.sprintf_new + platforms: + - nrf52dk_nrf52832 + comment: "Ram overflows, also in the upstream" From aa9e63340ee7824e1d9294eea4629e8dabd9ffd9 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 3 Mar 2022 15:28:16 +0100 Subject: [PATCH 006/528] [nrf noup] doc: remove Kconfig search Kconfig search is handled in a separate docset in NCS, so remove the page. This is a long-term noup patch. Signed-off-by: Gerard Marull-Paretas Signed-off-by: Krishna T (cherry picked from commit 89babe6a30bb3e5c4fa411168cd4135dbb99e70f) (cherry picked from commit fdbdd8017796455cba30971c153289aa17236b9b) --- MAINTAINERS.yml | 1 - doc/build/kconfig/setting.rst | 6 ++---- doc/develop/application/index.rst | 5 ++--- doc/kconfig.rst | 8 -------- 4 files changed, 4 insertions(+), 16 deletions(-) delete mode 100644 doc/kconfig.rst diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index 9b9e51cd1bf0..a09a689391cd 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -573,7 +573,6 @@ Documentation: - doc/images/Zephyr-Kite-in-tree.png - doc/index-tex.rst - doc/index.rst - - doc/kconfig.rst - doc/known-warnings.txt - doc/templates/sample.tmpl - doc/templates/board.tmpl diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index f01ef8914725..048aea25fa1b 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -7,8 +7,7 @@ The :ref:`menuconfig and guiconfig interfaces ` can be used to test out configurations during application development. This page explains how to make settings permanent. -All Kconfig options can be searched in the :ref:`Kconfig search page -`. +All Kconfig options can be searched in the Kconfig search page. .. note:: @@ -115,8 +114,7 @@ Assignments in configuration files are only respected if the dependencies for the symbol are satisfied. A warning is printed otherwise. To figure out what the dependencies of a symbol are, use one of the :ref:`interactive configuration interfaces ` (you can jump directly to a symbol with -:kbd:`/`), or look up the symbol in the :ref:`Kconfig search page -`. +:kbd:`/`), or look up the symbol in the Kconfig search page. .. _initial-conf: diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index ede89cb66064..bf934cf3532e 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -621,9 +621,8 @@ started. See :ref:`setting_configuration_values` for detailed documentation on setting Kconfig configuration values. The :ref:`initial-conf` section on the same page -explains how the initial configuration is derived. See :ref:`kconfig-search` -for a complete list of configuration options. -See :ref:`hardening` for security information related with Kconfig options. +explains how the initial configuration is derived. See :ref:`hardening` for +security information related with Kconfig options. The other pages in the :ref:`Kconfig section of the manual ` are also worth going through, especially if you planning to add new configuration diff --git a/doc/kconfig.rst b/doc/kconfig.rst deleted file mode 100644 index 1123de2adbd9..000000000000 --- a/doc/kconfig.rst +++ /dev/null @@ -1,8 +0,0 @@ -:orphan: - -.. _kconfig-search: - -Kconfig Search -============== - -.. kconfig:search:: From 68110ee5a75167e8e2c65746211571315618a3e1 Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Fri, 3 May 2019 14:21:52 +0200 Subject: [PATCH 007/528] [nrf noup] tree-wide: support NCS Partition Manager (PM) definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partition Manager (PM) is a component of the nRF Connect SDK (NCS) which uses yaml files to resolve flash partition placement with a holistic view of the entire device, including each firmware image present on the flash device, and various subsystems, such as settings and NFFS. When this NCS extension is used, various source files which would use partition information from devicetree in "vanilla" zephyr instead use defines generated by PM instead. This commit removes support for HEX_FILES_TO_MERGE, as it conflicts with PM. The settings subsystem pm.yml defines a partition 'settings_storage'. The nffs subsystem pm.yml defines 'nffs_storage'. Leverage label translation to avoid patching partition names. Refer to the NCS documentation page for this feature for more details. This is a long-running out of tree patch which has been worked on by several people. The following sign-offs are in alphabetical order by first name. Signed-off-by: Andrzej Głąbek Signed-off-by: Andrzej Puzdrowski Signed-off-by: Dominik Ermel Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Joakim Andersson Signed-off-by: Johann Fischer Signed-off-by: Martí Bolívar Signed-off-by: Ole Sæther Signed-off-by: Robert Lubos Signed-off-by: Sebastian Bøe Signed-off-by: Sigvart Hovland Signed-off-by: Thomas Stenersen Signed-off-by: Torsten Rasmussen Signed-off-by: Øyvind Rønningstad Signed-off-by: Trond Einar Snekvik Signed-off-by: Gerard Marull-Paretas Signed-off-by: Tomasz Moń (cherry picked from commit ba54fe88dcfe3b25aca4c02f01e47f232b0f8bf7) --- cmake/modules/kernel.cmake | 4 ++ drivers/flash/soc_flash_nrf.c | 11 +++++ .../arm/aarch32/cortex_m/scripts/linker.ld | 46 +++++++++++++++++++ include/zephyr/storage/flash_map.h | 6 +++ soc/arm/common/cortex_m/arm_mpu_regions.c | 13 ++++++ subsys/fs/littlefs_fs.c | 7 ++- subsys/ipc/rpmsg_service/rpmsg_backend.h | 27 +++++++++++ 7 files changed, 113 insertions(+), 1 deletion(-) diff --git a/cmake/modules/kernel.cmake b/cmake/modules/kernel.cmake index 7e65c9cd186d..28ee922d40b0 100644 --- a/cmake/modules/kernel.cmake +++ b/cmake/modules/kernel.cmake @@ -242,3 +242,7 @@ if("${CMAKE_EXTRA_GENERATOR}" STREQUAL "Eclipse CDT4") include(${ZEPHYR_BASE}/cmake/ide/eclipse_cdt4_generator_amendment.cmake) eclipse_cdt4_generator_amendment(1) endif() + +if(ZEPHYR_NRF_MODULE_DIR) + include(${ZEPHYR_NRF_MODULE_DIR}/cmake/partition_manager.cmake) +endif() diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index e7f5fb27bafc..e170b507c7a7 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -37,6 +37,11 @@ LOG_MODULE_REGISTER(flash_nrf); #define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) +#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER +#include +#include +#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER */ + #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE #define FLASH_SLOT_WRITE 7500 #if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE) @@ -137,6 +142,12 @@ static int flash_nrf_read(const struct device *dev, off_t addr, return 0; } +#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER && PM_APP_ADDRESS + if (addr < PM_APP_ADDRESS) { + return soc_secure_mem_read(data, (void *)addr, len); + } +#endif + memcpy(data, (void *)addr, len); return 0; diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld index 567e213fe6d1..56c5271462f1 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld @@ -26,6 +26,35 @@ #endif #define RAMABLE_REGION RAM +#if USE_PARTITION_MANAGER + +#include + +#if CONFIG_NCS_IS_VARIANT_IMAGE && defined(PM_S0_ID) +/* We are linking against S1, create symbol containing the flash ID of S0. + * This is used when writing code operating on the "other" slot. + */ +_image_1_primary_slot_id = PM_S0_ID; + +#else /* ! CONFIG_NCS_IS_VARIANT_IMAGE */ + +#ifdef PM_S1_ID +/* We are linking against S0, create symbol containing the flash ID of S1. + * This is used when writing code operating on the "other" slot. + */ +_image_1_primary_slot_id = PM_S1_ID; +#endif /* PM_S1_ID */ + +#endif /* CONFIG_NCS_IS_VARIANT_IMAGE */ + +#define ROM_ADDR PM_ADDRESS +#define ROM_SIZE PM_SIZE + +#define RAM_SIZE PM_SRAM_SIZE +#define RAM_ADDR PM_SRAM_ADDRESS + +#else /* ! USE_PARTITION_MANAGER */ + #if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0) #define ROM_ADDR RAM_ADDR #else @@ -52,6 +81,23 @@ #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS #endif +#endif /* USE_PARTITION_MANAGER */ + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ccm), okay) +#define CCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ccm)) +#define CCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ccm)) +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) +#define ITCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_itcm)) +#define ITCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_itcm)) +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) +#define DTCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm)) +#define DTCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm)) +#endif + #if defined(CONFIG_CUSTOM_SECTION_ALIGN) _region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE; #else diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index e07305cddaa6..2bda4a8d980d 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -255,6 +255,10 @@ const struct device *flash_area_get_device(const struct flash_area *fa); */ uint8_t flash_area_erased_val(const struct flash_area *fa); +#if USE_PARTITION_MANAGER +#include +#else + #define FLASH_AREA_LABEL_EXISTS(label) __DEPRECATED_MACRO \ DT_HAS_FIXED_PARTITION_LABEL(label) @@ -327,6 +331,8 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #define FIXED_PARTITION_DEVICE(label) \ DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))) +#endif /* USE_PARTITION_MANAGER */ + #ifdef __cplusplus } #endif diff --git a/soc/arm/common/cortex_m/arm_mpu_regions.c b/soc/arm/common/cortex_m/arm_mpu_regions.c index 477dc30566c7..d44c2ee05b3d 100644 --- a/soc/arm/common/cortex_m/arm_mpu_regions.c +++ b/soc/arm/common/cortex_m/arm_mpu_regions.c @@ -9,6 +9,9 @@ #include #include "arm_mpu_mem_cfg.h" +#if USE_PARTITION_MANAGER +#include +#endif static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ @@ -22,6 +25,14 @@ static const struct arm_mpu_region mpu_regions[] = { #endif /* Region 1 */ MPU_REGION_ENTRY("SRAM_0", +#if USE_PARTITION_MANAGER + PM_SRAM_ADDRESS, +#if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) + REGION_RAM_ATTR(PM_SRAM_ADDRESS, PM_SRAM_SIZE)), +#else + REGION_RAM_ATTR(REGION_SRAM_SIZE)), +#endif +#else CONFIG_SRAM_BASE_ADDRESS, #if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) REGION_RAM_ATTR(CONFIG_SRAM_BASE_ADDRESS, \ @@ -30,6 +41,8 @@ static const struct arm_mpu_region mpu_regions[] = { REGION_RAM_ATTR(REGION_SRAM_SIZE)), #endif +#endif /* USE_PARTITION_MANAGER */ + /* DT-defined regions */ LINKER_DT_REGION_MPU(ARM_MPU_REGION_INIT) }; diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c index 2a4915b4d1cb..ff190c74edb8 100644 --- a/subsys/fs/littlefs_fs.c +++ b/subsys/fs/littlefs_fs.c @@ -1009,7 +1009,12 @@ struct fs_mount_t FS_FSTAB_ENTRY(DT_DRV_INST(inst)) = { \ .type = FS_LITTLEFS, \ .mnt_point = DT_INST_PROP(inst, mount_point), \ .fs_data = &fs_data_##inst, \ - .storage_dev = (void *)DT_FIXED_PARTITION_ID(FS_PARTITION(inst)), \ + .storage_dev = (void *) \ + COND_CODE_1(USE_PARTITION_MANAGER, \ + (COND_CODE_1(FIXED_PARTITION_EXISTS(littlefs_storage), \ + (FIXED_PARTITION_ID(littlefs_storage)), \ + (FIXED_PARTITION_ID(storage)))), \ + (DT_FIXED_PARTITION_ID(FS_PARTITION(inst)))), \ .flags = FSTAB_ENTRY_DT_MOUNT_FLAGS(DT_DRV_INST(inst)), \ }; diff --git a/subsys/ipc/rpmsg_service/rpmsg_backend.h b/subsys/ipc/rpmsg_service/rpmsg_backend.h index a74e46b85207..9996e1d74d9b 100644 --- a/subsys/ipc/rpmsg_service/rpmsg_backend.h +++ b/subsys/ipc/rpmsg_service/rpmsg_backend.h @@ -13,8 +13,35 @@ extern "C" { #endif +#if CONFIG_PARTITION_MANAGER_ENABLED + +#include "pm_config.h" + +#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) + +#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) +#define VDEV_START_ADDR PM_RPMSG_NRF53_SRAM_ADDRESS +#define VDEV_SIZE PM_RPMSG_NRF53_SRAM_SIZE +#else +/* The current image is a child image in a different domain than the image + * which defined the required values. To reach the values of the parent domain + * we use the 'PM__' variant of the define. + */ +#define VDEV_START_ADDR PM__RPMSG_NRF53_SRAM_ADDRESS +#define VDEV_SIZE PM__RPMSG_NRF53_SRAM_SIZE +#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) */ + +#else #define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) #define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) +#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) */ + +#else + +#define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) +#define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) + +#endif /* CONFIG_PARTITION_MANAGER_ENABLED */ #define VDEV_STATUS_ADDR VDEV_START_ADDR #define VDEV_STATUS_SIZE 0x400 From 3819c4ae701f0b4265bbd3409e37e5bba5c4abcb Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Mon, 16 Jan 2023 14:15:22 +0100 Subject: [PATCH 008/528] [nrf noup] dts: choose cryptocell for entropy when available This is a long-term noup patch because driver support is NCS-only. Set HAS_HW_NRF_CC3XX to be defined in NS build when cryptocell is accessed through the PSA API. We need to know which CC3XX features are available. Signed-off-by: Georgios Vasilakis Signed-off-by: Joakim Andersson (cherry picked from commit c76cf8776d7bcbb7eef8023191a941f8e9410cb4) (cherry picked from commit 214533fa69601f52933977a39fff855d955c886f) --- dts/arm/nordic/nrf52840.dtsi | 2 +- dts/arm/nordic/nrf5340_cpuapp.dtsi | 2 +- dts/arm/nordic/nrf91.dtsi | 1 + soc/arm/nordic_nrf/Kconfig.peripherals | 6 ++++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/dts/arm/nordic/nrf52840.dtsi b/dts/arm/nordic/nrf52840.dtsi index 0fb5fb753cd4..a35ad5901456 100644 --- a/dts/arm/nordic/nrf52840.dtsi +++ b/dts/arm/nordic/nrf52840.dtsi @@ -5,7 +5,7 @@ / { chosen { - zephyr,entropy = &rng; + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; diff --git a/dts/arm/nordic/nrf5340_cpuapp.dtsi b/dts/arm/nordic/nrf5340_cpuapp.dtsi index 7a32c5398db4..1294203f00ac 100644 --- a/dts/arm/nordic/nrf5340_cpuapp.dtsi +++ b/dts/arm/nordic/nrf5340_cpuapp.dtsi @@ -33,7 +33,7 @@ }; chosen { - zephyr,entropy = &rng_hci; + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; diff --git a/dts/arm/nordic/nrf91.dtsi b/dts/arm/nordic/nrf91.dtsi index d872680fb20e..a2a490ab0b15 100644 --- a/dts/arm/nordic/nrf91.dtsi +++ b/dts/arm/nordic/nrf91.dtsi @@ -28,6 +28,7 @@ }; chosen { + zephyr,entropy = &cryptocell; zephyr,flash-controller = &flash_controller; }; diff --git a/soc/arm/nordic_nrf/Kconfig.peripherals b/soc/arm/nordic_nrf/Kconfig.peripherals index de3da1f9b7d4..f883fc54578c 100644 --- a/soc/arm/nordic_nrf/Kconfig.peripherals +++ b/soc/arm/nordic_nrf/Kconfig.peripherals @@ -13,10 +13,12 @@ config HAS_HW_NRF_BPROT def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_BPROT)) config HAS_HW_NRF_CC310 - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC310)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC310)) || \ + ($(dt_nodelabel_enabled,psa_rng) && SOC_SERIES_NRF91X) config HAS_HW_NRF_CC312 - def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC312)) + def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CC312)) || \ + ($(dt_nodelabel_enabled,psa_rng) && SOC_NRF5340_CPUAPP) config HAS_HW_NRF_CCM def_bool $(dt_compat_enabled,$(DT_COMPAT_NORDIC_NRF_CCM)) From a7d1b3ddd1b740db3e04e967e12bfdf6e76e4d48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Audun=20Kvamtr=C3=B8?= Date: Tue, 30 Nov 2021 09:41:05 +0100 Subject: [PATCH 009/528] [nrf noup] modules: mbedtls: add PSA configurations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Adds Kconfig.psa -Add standardized algorithms, curve types etc as Kconfig variables -Add configurations for internal logic to see if a feature is enabled by PSA_WANTS_XXX ref: NCSDK-11689 ref: NCSDK-17840 ref: NCSDK-17840 Signed-off-by: Frank Audun Kvamtrø Signed-off-by: Joakim Andersson (cherry picked from commit c913e3aaa7c59737c9f25a7c58cfbb20503f791c) (cherry picked from commit 6ae8ab054126778fcc0054d5243580e72197359c) --- modules/mbedtls/Kconfig | 4 +- modules/mbedtls/Kconfig.psa | 427 ++++++++++++++++++++++++++++++++++++ 2 files changed, 430 insertions(+), 1 deletion(-) create mode 100644 modules/mbedtls/Kconfig.psa diff --git a/modules/mbedtls/Kconfig b/modules/mbedtls/Kconfig index 81edf4ab5742..10b23fa4979b 100644 --- a/modules/mbedtls/Kconfig +++ b/modules/mbedtls/Kconfig @@ -13,7 +13,6 @@ config MBEDTLS_PROMPTLESS mbed TLS menu prompt and instead handle the selection of MBEDTLS from dependent sub-configurations and thus prevent stuck symbol behavior. - menuconfig MBEDTLS bool "mbed TLS Support" if !MBEDTLS_PROMPTLESS help @@ -225,4 +224,7 @@ config APP_LINK_WITH_MBEDTLS disabled if the include paths for MBEDTLS are causing aliasing issues for 'app'. +# Add PSA configurations +rsource "Kconfig.psa" + endif # MBEDTLS diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa new file mode 100644 index 000000000000..e60da36d48a2 --- /dev/null +++ b/modules/mbedtls/Kconfig.psa @@ -0,0 +1,427 @@ +# +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# +menu "PSA RNG support" + +config PSA_WANT_GENERATE_RANDOM + bool + prompt "PSA RNG support" + default y + +config PSA_WANT_ALG_CTR_DRBG + bool + prompt "PSA RNG using CTR_DRBG" + help + Provide CTR_DRBG as the random number generator. + Note: This configuration is currently not described and has no effect. + +config PSA_WANT_ALG_HMAC_DRBG + bool + prompt "PSA RNG using HMAC_DRBG" + help + Provide HMAC_DRBG as the random number generator. + Note: This configuration is currently not described and has no effect. + +endmenu # RNG support + +config PSA_HAS_KEY_SUPPORT + bool + default y + depends on PSA_WANT_KEY_TYPE_DERIVE || \ + PSA_WANT_KEY_TYPE_HMAC || \ + PSA_WANT_KEY_TYPE_AES || \ + PSA_WANT_KEY_TYPE_CHACHA20 || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY || \ + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + +config PSA_WANT_KEY_TYPE_DERIVE + bool + default y + depends on PSA_HAS_KEY_DERIVATION + help + Prompt-less configuration that states that the derived key type is used. + +config PSA_WANT_KEY_TYPE_HMAC + bool + default y + depends on PSA_HAS_MAC_SUPPORT + help + Prompt-less configuration that states that the HMAC key type is used. + +config PSA_WANT_KEY_TYPE_AES + bool + default y + depends on PSA_HAS_CIPHER_SUPPORT || PSA_HAS_AEAD_SUPPORT + help + Prompt-less configuration that states that AES key type is used. + +config PSA_WANT_KEY_TYPE_CHACHA20 + bool + default y + depends on PSA_WANT_ALG_CHACHA20_POLY1305 + help + Prompt-less configuration that states that CHACHA20 key type is used. + +config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR + bool + default y + depends on PSA_HAS_ECC_SUPPORT + help + Prompt-less configuration that states that ECC key pair type is used. + +config PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY + bool + default y + depends on PSA_HAS_ECC_SUPPORT + help + Prompt-less configuration that states that ECC public key type is used. + +config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR + bool + default y + depends on PSA_HAS_RSA_SUPPORT + help + Prompt-less configuration that states that RSA key pair type is used. + +config PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + bool + default y + depends on PSA_HAS_RSA_SUPPORT + help + Prompt-less configuration that states that RSA public key type is used. + +menu "PSA AEAD support" + +config PSA_HAS_AEAD_SUPPORT + bool + default y + depends on PSA_WANT_ALG_CCM || \ + PSA_WANT_ALG_GCM || \ + PSA_WANT_ALG_CHACHA20_POLY1305 + help + Prompt-less configuration that states that AEAD is supported. + +config PSA_WANT_ALG_CCM + bool + prompt "PSA AES CCM support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_GCM + bool + prompt "PSA AES GCM support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_CHACHA20_POLY1305 + bool + prompt "PSA ChaCha20/Poly1305 support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +endmenu # PSA AEAD support + + +menu "PSA MAC support" + +config PSA_HAS_MAC_SUPPORT + bool + default y + depends on PSA_WANT_ALG_CBC_MAC || \ + PSA_WANT_ALG_CMAC || \ + PSA_WANT_ALG_HMAC + help + Prompt-less configuration that states that MAC is supported. + +config PSA_WANT_ALG_CBC_MAC + bool + help + CBC-MAC is not yet supported via the PSA API in Mbed TLS. + +config PSA_WANT_ALG_CMAC + bool + prompt "PSA AES CMAC support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_HMAC + bool + prompt "PSA HMAC support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +endmenu # PSA MAC support + + +menu "PSA Hash support" + +config PSA_HAS_HASH_SUPPORT + bool + default y + depends on PSA_WANT_ALG_SHA_1 || \ + PSA_WANT_ALG_SHA_224 || \ + PSA_WANT_ALG_SHA_256 || \ + PSA_WANT_ALG_SHA_384 || \ + PSA_WANT_ALG_SHA_512 || \ + PSA_WANT_ALG_RIPEMD160 || \ + PSA_WANT_ALG_MD5 + help + Prompt-less configuration that states that hash is supported. + +config PSA_WANT_ALG_SHA_1 + bool + prompt "PSA SHA1 support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_SHA_224 + bool + prompt "PSA SHA-224 support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_SHA_256 + bool + prompt "PSA SSH-256 support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_SHA_384 + bool + prompt "PSA SHA-384 support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_SHA_512 + bool + prompt "PSA SHA-512 support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_RIPEMD160 + bool + prompt "PSA RIPEMD160 support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_MD5 + bool + prompt "PSA MD5 support" if !PSA_PROMPTLESS + +endmenu # PSA Hash support + +menu "PSA Cipher support" + +config PSA_HAS_CIPHER_SUPPORT + bool + default y + depends on PSA_WANT_ALG_ECB_NO_PADDING || \ + PSA_WANT_ALG_CBC_NO_PADDING || \ + PSA_WANT_ALG_CBC_PKCS7 || \ + PSA_WANT_ALG_CFB || \ + PSA_WANT_ALG_CTR || \ + PSA_WANT_ALG_OFB || \ + PSA_WANT_ALG_CTR || \ + PSA_WANT_ALG_XTS + help + Prompt-less configuration that states that cipher is supported. + +config PSA_WANT_ALG_ECB_NO_PADDING + bool + prompt "PSA AES ECB (no padding)" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_CBC_NO_PADDING + bool + prompt "PSA CBC support (without padding)" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_CBC_PKCS7 + bool + prompt "PSA CBC support (padded with PKCS#7)" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_CFB + bool + prompt "PSA AES CFB support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_CTR + bool + prompt "PSA AES CTR mode support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_OFB + bool + prompt "PSA AES OFB mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_XTS + bool + help + AES XTS is currently not supported + +endmenu # PSA Cipher Support + + +menu "PSA Key derivation support" + +config PSA_HAS_KEY_DERIVATION + bool + default y + depends on PSA_WANT_ALG_HKDF || \ + PSA_WANT_ALG_PBKDF2_HMAC || \ + PSA_WANT_ALG_TLS12_PRF || \ + PSA_WANT_ALG_TLS12_PSK_TO_MS + help + Prompt-less configuration that states that key derivation is supported. + +config PSA_WANT_ALG_HKDF + bool + prompt "PSA HKFD support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + depends on PSA_WANT_ALG_HMAC + +config PSA_WANT_ALG_PBKDF2_HMAC + bool + depends on PSA_WANT_ALG_HMAC + help + PBKDF2-HMAC is not yet supported via the PSA APIs in Mbed TLS. + +config PSA_WANT_ALG_TLS12_PRF + bool + prompt "PSA PRF support (TLS1.2)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_TLS12_PSK_TO_MS + bool + prompt "PSA TLS 1.2 PSK to MS support" if !PSA_PROMPTLESS + +endmenu # PSA Key derivation support + + +menu "PSA Asymmetric support" + +config PSA_HAS_ASYM_ENCRYPT_SUPPORT + bool + default y + depends on PSA_WANT_ALG_RSA_OAEP || \ + PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + help + Prompt-less configuration that states that asymmetric encryption + is supported. + + +config PSA_HAS_ASYM_SIGN_SUPPORT + bool + default y + depends on PSA_WANT_ALG_DETERMINISTIC_ECDSA || \ + PSA_WANT_ALG_ECDSA || \ + PSA_WANT_ALG_RSA_PKCS1V15_SIGN || \ + PSA_WANT_ALG_RSA_PSS + + help + Prompt-less configuration that states that asymmetric signing + is supported. + +config PSA_HAS_ECC_SUPPORT + bool + depends on PSA_WANT_ALG_ECDH || PSA_WANT_ALG_ECDSA || PSA_WANT_ALG_DETERMINISTIC_ECDSA + default y + help + Prompt-less configuration that states that ECC is supported. + +config PSA_WANT_ALG_ECDH + bool + prompt "PSA ECDH support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_ECDSA + bool + prompt "PSA ECDSA support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_DETERMINISTIC_ECDSA + bool + prompt "PSA ECDSA support (deterministic mode)" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +menu "Elliptic Curve type support" + depends on PSA_HAS_ECC_SUPPORT + +config PSA_WANT_ECC_BRAINPOOL_P_R1_256 + bool + prompt "PSA ECC Brainpool256r1 support" + +config PSA_WANT_ECC_BRAINPOOL_P_R1_384 + bool "PSA ECC Brainpool384r1 support" + +config PSA_WANT_ECC_BRAINPOOL_P_R1_512 + bool "PSA ECC Brainpool512r1 support" + +config PSA_WANT_ECC_MONTGOMERY_255 + bool "PSA ECC Curve X25519 support" + +config PSA_WANT_ECC_MONTGOMERY_448 + bool "PSA ECC Curve X448 support" + +config PSA_WANT_ECC_TWISTED_EDWARDS_255 + bool "PSA ECC Curve Ed25519 support" + +config PSA_WANT_ECC_SECP_K1_192 + bool "PSA ECC secp192k1 support" + +config PSA_WANT_ECC_SECP_K1_224 + bool + help + SECP224K1 is buggy via the PSA API in Mbed TLS + See https://github.com/ARMmbed/mbedtls/issues/3541 + +config PSA_WANT_ECC_SECP_K1_256 + bool + prompt "PSA ECC secp256k1 support" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_192 + bool + prompt "PSA ECC secp192r1" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_224 + bool + prompt "PSA ECC secp224r1" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_256 + bool + prompt "PSA ECC secp256r1" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ECC_SECP_R1_384 + bool + prompt "PSA ECC secp384r1" if !PSA_PROMPTLESS + +config PSA_WANT_ECC_SECP_R1_521 + bool + prompt "PSA ECC secp521r1" if !PSA_PROMPTLESS + +endmenu # Elliptic Curve type support + +config PSA_HAS_RSA_SUPPORT + bool + depends on PSA_WANT_ALG_RSA_OAEP || \ + PSA_WANT_ALG_RSA_PKCS1V15_CRYPT || \ + PSA_WANT_ALG_RSA_PKCS1V15_SIGN || \ + PSA_WANT_ALG_RSA_PSS + default y + help + Prompt-less configuration that states that RSA is supported. + +config PSA_WANT_ALG_RSA_OAEP + bool + prompt "PSA RSA OAEP support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + bool + prompt "PSA RSA crypt support (PKCS1V15 mode)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PKCS1V15_SIGN + bool + prompt "PSA RSA signature support (PKCS1V15 mode)" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_RSA_PSS + bool + prompt "PSA RSA (PSS mode)" if !PSA_PROMPTLESS + +endmenu # PSA Asymmetric support + +config PSA_WANT_ALG_STREAM_CIPHER + bool + prompt "PSA stream cipher support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF From 1a12d6cd21e3dc31472694881a027e19b3283db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Sat, 29 Jan 2022 13:03:08 +0100 Subject: [PATCH 010/528] [nrf noup] modules: mbedtls: Allow MBEDTLS_BUILTIN to be deselected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Out-of-tree crypto subsystems need to deselect MBEDTLS_BUILTIN, but deselection is not supported. It is however supported to select a dependency in a ! expression. Signed-off-by: Sebastian Bøe (cherry picked from commit d2eb105082a6df51584e6cd49838cce7ac39d20c) --- modules/mbedtls/Kconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/mbedtls/Kconfig b/modules/mbedtls/Kconfig index 10b23fa4979b..7ee4888400b1 100644 --- a/modules/mbedtls/Kconfig +++ b/modules/mbedtls/Kconfig @@ -26,6 +26,7 @@ choice MBEDTLS_IMPLEMENTATION config MBEDTLS_BUILTIN bool "Use Zephyr in-tree mbedTLS version" + depends on ! DISABLE_MBEDTLS_BUILTIN help Link with mbedTLS sources included with Zephyr distribution. Included mbedTLS version is well integrated with and supported @@ -39,6 +40,11 @@ config MBEDTLS_LIBRARY endchoice +# subsystems cannot deselect MBEDTLS_BUILTIN, but they can select +# DISABLE_MBEDTLS_BUILTIN. +config DISABLE_MBEDTLS_BUILTIN + bool + config CUSTOM_MBEDTLS_CFG_FILE bool "Custom mbed TLS configuration file" help From 4ab6d30e95770e5dabc601d5a491733a097a763b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Audun=20Kvamtr=C3=B8?= Date: Thu, 13 Jan 2022 11:37:18 +0100 Subject: [PATCH 011/528] [nrf noup] modules: tf-m: use of PSA_HAS_XXXX_SUPPORT MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -This allows configurations enabled by PSA_WANTS_ALG_XXXX to be used to control which TF-M module is enabled -If the TF-M image doesn't support e.g. the MAC APIs, then the MAC interface is not enabled Note: This functionality requires that nrf_security is enabled ref: NCSDK-11689 Signed-off-by: Frank Audun Kvamtrø (cherry picked from commit 55015d61ea589ab77987c3e74d9d2c8ed73d1590) --- modules/trusted-firmware-m/Kconfig.tfm.crypto_modules | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules b/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules index 1b4f7e1b17a4..eb33b9101bd0 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules +++ b/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules @@ -17,6 +17,7 @@ config TFM_CRYPTO_RNG_MODULE_ENABLED config TFM_CRYPTO_KEY_MODULE_ENABLED bool "KEY crypto module" default y + depends on PSA_HAS_KEY_SUPPORT && NRF_SECURITY help Enables the KEY crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_key.c' @@ -25,6 +26,7 @@ config TFM_CRYPTO_KEY_MODULE_ENABLED config TFM_CRYPTO_AEAD_MODULE_ENABLED bool "AEAD crypto module" default y + depends on PSA_HAS_AEAD_SUPPORT && NRF_SECURITY help Enables the AEAD crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_aead.c' @@ -33,6 +35,7 @@ config TFM_CRYPTO_AEAD_MODULE_ENABLED config TFM_CRYPTO_MAC_MODULE_ENABLED bool "MAC crypto module" default y + depends on PSA_HAS_MAC_SUPPORT && NRF_SECURITY help Enables the MAC crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_mac.c' @@ -41,6 +44,7 @@ config TFM_CRYPTO_MAC_MODULE_ENABLED config TFM_CRYPTO_HASH_MODULE_ENABLED bool "HASH crypto module" default y + depends on PSA_HAS_HASH_SUPPORT && NRF_SECURITY help Enables the HASH crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_hash.c' @@ -49,6 +53,7 @@ config TFM_CRYPTO_HASH_MODULE_ENABLED config TFM_CRYPTO_CIPHER_MODULE_ENABLED bool "CIPHER crypto module" default y + depends on PSA_HAS_CIPHER_SUPPORT && NRF_SECURITY help Enables the CIPHER crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_cipher.c' @@ -57,6 +62,7 @@ config TFM_CRYPTO_CIPHER_MODULE_ENABLED config TFM_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED bool "ASYM ENCRYPT crypto module" default y + depends on PSA_HAS_ASYM_ENCRYPT_SUPPORT && NRF_SECURITY help Enables the ASYM ENCRYPT crypto module within the crypto partition. Unset this option if the encrypt functionality provided by 'crypto_asymmetric.c' @@ -65,6 +71,7 @@ config TFM_CRYPTO_ASYM_ENCRYPT_MODULE_ENABLED config TFM_CRYPTO_ASYM_SIGN_MODULE_ENABLED bool "ASYM SIGN crypto module" default y + depends on PSA_HAS_ASYM_SIGN_SUPPORT && NRF_SECURITY help Enables the ASYM SIGN crypto module within the crypto partition. Unset this option if the sign functionality provided by 'crypto_asymmetric.c' @@ -73,6 +80,7 @@ config TFM_CRYPTO_ASYM_SIGN_MODULE_ENABLED config TFM_CRYPTO_KEY_DERIVATION_MODULE_ENABLED bool "KEY DERIVATION crypto module" default y + depends on PSA_HAS_KEY_DERIVATION && NRF_SECURITY help Enables the KEY_DERIVATION crypto module within the crypto partition. Unset this option if the functionality provided by 'crypto_key_derivation.c' From ea5314da140b632aad85d39ea2dad02929ac83a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Frank=20Audun=20Kvamtr=C3=B8?= Date: Mon, 31 Jan 2022 03:48:11 +0100 Subject: [PATCH 012/528] [nrf noup] modules: mbedtls: Disable configurations in Kconfig.tls-generic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -This commit prevents legacy mbed TLS configurations from being in conflict with PSA Configurations while using nrf_security -Removing use of unsupported TLS protocols (TLS 1.0, 1.1) -Required configurations are duplicated inside nrf_security Kconfig -Ensured that mbedtls_platform_zeroize is not duplicated when CONFIG_NRF_CC3XX_PLATFORM is set ref: NCSDK-13503 Signed-off-by: Frank Audun Kvamtrø Signed-off-by: Andrzej Głąbek (cherry picked from commit 84ee8c8015d1362b7888aeb7e0991e3f7092b35a) --- modules/mbedtls/Kconfig.tls-generic | 31 ++++++++++++++++++++ modules/mbedtls/configs/config-tls-generic.h | 4 +++ 2 files changed, 35 insertions(+) diff --git a/modules/mbedtls/Kconfig.tls-generic b/modules/mbedtls/Kconfig.tls-generic index 6275c6570f75..d8432dc176f1 100644 --- a/modules/mbedtls/Kconfig.tls-generic +++ b/modules/mbedtls/Kconfig.tls-generic @@ -9,6 +9,8 @@ menu "TLS configuration" menu "Supported TLS version" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_TLS_VERSION_1_0 bool "Support for TLS 1.0" select MBEDTLS_CIPHER @@ -33,6 +35,8 @@ config MBEDTLS_DTLS bool "Support for DTLS" depends on MBEDTLS_TLS_VERSION_1_1 || MBEDTLS_TLS_VERSION_1_2 +endif + config MBEDTLS_SSL_EXPORT_KEYS bool "Support for exporting SSL key block and master secret" depends on MBEDTLS_TLS_VERSION_1_0 || MBEDTLS_TLS_VERSION_1_1 || MBEDTLS_TLS_VERSION_1_2 @@ -47,6 +51,8 @@ menu "Ciphersuite configuration" comment "Supported key exchange modes" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_KEY_EXCHANGE_ALL_ENABLED bool "All available ciphersuite modes" select MBEDTLS_KEY_EXCHANGE_PSK_ENABLED @@ -81,6 +87,8 @@ config MBEDTLS_KEY_EXCHANGE_SOME_PSK_ENABLED MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED || \ MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED +endif + config MBEDTLS_PSK_MAX_LEN int "Max size of TLS pre-shared keys" default 32 @@ -88,6 +96,8 @@ config MBEDTLS_PSK_MAX_LEN help Max size of TLS pre-shared keys, in bytes. +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_KEY_EXCHANGE_RSA_ENABLED bool "RSA-only based ciphersuite modes" default y if !NET_L2_OPENTHREAD @@ -202,6 +212,7 @@ config MBEDTLS_ECP_NIST_OPTIM bool "NSIT curves optimization" endif +endif # !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) comment "Supported hash" @@ -226,6 +237,8 @@ config MBEDTLS_HASH_SHA512_ENABLED comment "Supported cipher modes" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_CIPHER_ALL_ENABLED bool "All available ciphers" select MBEDTLS_CIPHER_AES_ENABLED @@ -290,8 +303,12 @@ config MBEDTLS_CHACHAPOLY_AEAD_ENABLED bool "ChaCha20-Poly1305 AEAD algorithm" depends on MBEDTLS_CIPHER_CHACHA20_ENABLED || MBEDTLS_MAC_POLY1305_ENABLED +endif + comment "Supported message authentication methods" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_MAC_ALL_ENABLED bool "All available MAC methods" select MBEDTLS_MAC_MD4_ENABLED @@ -340,10 +357,14 @@ config MBEDTLS_MAC_CMAC_ENABLED bool "CMAC (Cipher-based Message Authentication Code) mode for block ciphers." depends on MBEDTLS_CIPHER_AES_ENABLED || MBEDTLS_CIPHER_DES_ENABLED +endif + endmenu comment "Random number generators" +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_CTR_DRBG_ENABLED bool "CTR_DRBG AES-256-based random generator" depends on MBEDTLS_CIPHER_AES_ENABLED @@ -353,14 +374,20 @@ config MBEDTLS_HMAC_DRBG_ENABLED bool "HMAC_DRBG random generator" select MBEDTLS_MD +endif + comment "Other configurations" config MBEDTLS_CIPHER bool "generic cipher layer." +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_MD bool "generic message digest layer." +endif + config MBEDTLS_GENPRIME_ENABLED bool "prime-number generation code." @@ -378,11 +405,15 @@ config MBEDTLS_HAVE_ASM of asymmetric cryptography, however this might have an impact on the code size. +if !(NRF_SECURITY || NORDIC_SECURITY_BACKEND) + config MBEDTLS_ENTROPY_ENABLED bool "MbedTLS generic entropy pool" depends on MBEDTLS_MAC_SHA256_ENABLED || MBEDTLS_MAC_SHA384_ENABLED || MBEDTLS_MAC_SHA512_ENABLED default y if MBEDTLS_ZEPHYR_ENTROPY +endif + config MBEDTLS_OPENTHREAD_OPTIMIZATIONS_ENABLED bool "MbedTLS optimizations for OpenThread" depends on NET_L2_OPENTHREAD diff --git a/modules/mbedtls/configs/config-tls-generic.h b/modules/mbedtls/configs/config-tls-generic.h index b95d0f1f0f13..39e250cffb33 100644 --- a/modules/mbedtls/configs/config-tls-generic.h +++ b/modules/mbedtls/configs/config-tls-generic.h @@ -470,6 +470,10 @@ #include CONFIG_MBEDTLS_USER_CONFIG_FILE #endif +#if defined(CONFIG_NRF_CC3XX_PLATFORM) +#define MBEDTLS_PLATFORM_ZEROIZE_ALT +#endif + #include "mbedtls/check_config.h" #endif /* MBEDTLS_CONFIG_H */ From cf7645feef8bb6dac4b37a689146d0bab3741a4c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 1 Oct 2018 10:27:32 +0200 Subject: [PATCH 013/528] [nrf noup] include: net: add NCS extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add some socket options and address family extensions to Zephyr headers, which will be useful for nRF Connect SDK. Add secure socket options: * Add CID socket options to NCS specific options. * Add TLS/DTLS tls ciphersuite chosen socket option to NCS specific options. * Add TLS/DTLS connection save/load socket options to NCS specific options. * Add TLS/DTLS handshake status socket option to NCS specific options. The "author" of this commit is a contact person; various people with s-o-b lines following here have contributed to the maintenance of this patch. Signed-off-by: Andreas Moltumyr Signed-off-by: Andrzej Głąbek Signed-off-by: Christopher Métrailler Signed-off-by: Dominik Ermel Signed-off-by: Emanuele Di Santo Signed-off-by: Glenn Ruben Bakke Signed-off-by: Håkon Alseth Signed-off-by: Ioannis Glaropoulos Signed-off-by: Jan Tore Guggedal Signed-off-by: Joakim Andersson Signed-off-by: Martí Bolívar Signed-off-by: Mirko Covizzi Signed-off-by: Petri Honkala Signed-off-by: Robert Lubos Signed-off-by: Tommi Mammela Signed-off-by: Trond Einar Snekvik Signed-off-by: Torsten Rasmussen Signed-off-by: Eivind Jølsgard Signed-off-by: Emanuele Di Santo (cherry picked from commit 11a73e1d2d9ce98d8610281c9b00da688dc31802) (cherry picked from commit 1fbee9f184e0047bc98fe96629dcafe45de5ab09) --- include/zephyr/net/socket.h | 2 + include/zephyr/net/socket_ncs.h | 144 ++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 include/zephyr/net/socket_ncs.h diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index 1209bc0cc736..2d82039a47ab 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -27,6 +27,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -138,6 +139,7 @@ struct zsock_pollfd { */ #define TLS_DTLS_HANDSHAKE_TIMEOUT_MIN 8 #define TLS_DTLS_HANDSHAKE_TIMEOUT_MAX 9 + /** Socket option for preventing certificates from being copied to the mbedTLS * heap if possible. The option is only effective for DER certificates and is * ignored for PEM certificates. diff --git a/include/zephyr/net/socket_ncs.h b/include/zephyr/net/socket_ncs.h new file mode 100644 index 000000000000..20502ffa550c --- /dev/null +++ b/include/zephyr/net/socket_ncs.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ +#define ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ + +/** + * @file + * @brief NCS specific additions to the BSD sockets API definitions + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* When CONFIG_NET_SOCKETS_OFFLOAD is enabled, offloaded sockets take precedence + * when creating a new socket. Combine this flag with a socket type when + * creating a socket, to enforce native socket creation (e. g. SOCK_STREAM | SOCK_NATIVE). + * If it's desired to create a native TLS socket, but still offload the + * underlying TCP/UDP socket, use e. g. SOCK_STREAM | SOCK_NATIVE_TLS. + */ +#define SOCK_NATIVE 0x80000000 +#define SOCK_NATIVE_TLS 0x40000000 + +/* NCS specific TLS options */ + +/** Socket option to set DTLS handshake timeout, specifically for nRF sockets. + * The option accepts an integer, indicating the total handshake timeout, + * including retransmissions, in seconds. + * Accepted values for the option are: 1, 3, 7, 15, 31, 63, 123. + */ +#define TLS_DTLS_HANDSHAKE_TIMEO 14 + +/** Socket option to set and get DTLS CID setting, specifically for nRF sockets. + * The option accepts an integer, indicating the setting. + * Accepted vaules for the option are: 0, 1 and 2. + */ +#define TLS_DTLS_CID 17 + +/** Socket option to get DTLS CID status, specifically for nRF sockets. + * The option accepts an integer, indicating the setting. + * Accepted vaules for the option are: 0, 1, 2 and 3. + */ +#define TLS_DTLS_CID_STATUS 18 + +/** Socket option to save DTLS connection, specifically for nRF sockets. + */ +#define TLS_DTLS_CONN_SAVE 19 + +/** Socket option to load DTLS connection, specifically for nRF sockets. + */ +#define TLS_DTLS_CONN_LOAD 20 + +/** Socket option to get result of latest TLS/DTLS completed handshakes end status, + * specifically for nRF sockets. + * The option accepts an integer, indicating the setting. + * Accepted vaules for the option are: 0 and 1. + */ +#define TLS_DTLS_HANDSHAKE_STATUS 21 + +/* Valid values for TLS_SESSION_CACHE option */ +#define TLS_SESSION_CACHE_DISABLED 0 /**< Disable TLS session caching. */ +#define TLS_SESSION_CACHE_ENABLED 1 /**< Enable TLS session caching. */ + +/* Valid values for TLS_DTLS_HANDSHAKE_TIMEO option */ +#define TLS_DTLS_HANDSHAKE_TIMEO_NONE 0 /**< No timeout */ +#define TLS_DTLS_HANDSHAKE_TIMEO_1S 1 /**< 1 second */ +#define TLS_DTLS_HANDSHAKE_TIMEO_3S 3 /**< 1s + 2s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_7S 7 /**< 1s + 2s + 4s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_15S 15 /**< 1s + 2s + 4s + 8s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_31S 31 /**< 1s + 2s + 4s + 8s + 16s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_63S 63 /**< 1s + 2s + 4s + 8s + 16s + 32s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_123S 123 /**< 1s + 2s + 4s + 8s + 16s + 32s + 60s */ + +/* Valid values for TLS_DTLS_CID option */ +#define TLS_DTLS_CID_DISABLED 0 +#define TLS_DTLS_CID_SUPPORTED 1 +#define TLS_DTLS_CID_ENABLED 2 + +/* Valid values for TLS_DTLS_CID_STATUS option */ +#define TLS_DTLS_CID_STATUS_DISABLED 0 +#define TLS_DTLS_CID_STATUS_DOWNLINK 1 +#define TLS_DTLS_CID_STATUS_UPLINK 2 +#define TLS_DTLS_CID_STATUS_BIDIRECTIONAL 3 + +/* Valid values for TLS_DTLS_HANDSHAKE_STATUS option */ +#define TLS_DTLS_HANDSHAKE_STATUS_FULL 0 +#define TLS_DTLS_HANDSHAKE_STATUS_CACHED 1 + +/* NCS specific socket options */ + +/** sockopt: disable all replies to unexpected traffics */ +#define SO_SILENCE_ALL 30 +/** sockopt: disable IPv4 ICMP replies */ +#define SO_IP_ECHO_REPLY 31 +/** sockopt: disable IPv6 ICMP replies */ +#define SO_IPV6_ECHO_REPLY 32 +/** sockopt: Release Assistance Indication feature: This will indicate that the + * application will not send any more data. + */ +#define SO_RAI_NO_DATA 50 +/** sockopt: Release Assistance Indication feature: This will indicate that the + * next call to send/sendto will be the last one for some time. + */ +#define SO_RAI_LAST 51 +/** sockopt: Release Assistance Indication feature: This will indicate that + * after the next call to send/sendto, the application is expecting to receive + * one more data packet before this socket will not be used again for some time. + */ +#define SO_RAI_ONE_RESP 52 +/** sockopt: Release Assistance Indication feature: If a client application + * expects to use the socket more it can indicate that by setting this socket + * option before the next send call which will keep the network up longer. + */ +#define SO_RAI_ONGOING 53 +/** sockopt: Release Assistance Indication feature: If a server application + * expects to use the socket more it can indicate that by setting this socket + * option before the next send call. + */ +#define SO_RAI_WAIT_MORE 54 +/** sockopt: Configurable TCP server session timeout in minutes. + * Range is 0 to 135. 0 is no timeout and 135 is 2 h 15 min. Default is 0 (no timeout). + */ +#define SO_TCP_SRV_SESSTIMEO 55 + +/* NCS specific gettaddrinfo() flags */ + +/** Assume `service` contains a Packet Data Network (PDN) ID. + * When specified together with the AI_NUMERICSERV flag, + * `service` shall be formatted as follows: "port:pdn_id" + * where "port" is the port number and "pdn_id" is the PDN ID. + * Example: "8080:1", port 8080 PDN ID 1. + * Example: "42:0", port 42 PDN ID 0. + */ +#define AI_PDNSERV 0x1000 + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ */ From 60fed8dbcb765eea06cd02fc2e080fa77a3c7310 Mon Sep 17 00:00:00 2001 From: Jan Tore Guggedal Date: Mon, 18 May 2020 20:50:13 +0200 Subject: [PATCH 014/528] [nrf noup] net: mqtt: Provide option to enable TLS session caching Provides an option to enable TLS session caching for an MQTT client's secure socket. Signed-off-by: Jan Tore Guggedal Signed-off-by: Robert Lubos Signed-off-by: Dominik Ermel Signed-off-by: Johann Fischer (cherry picked from commit 97e75e91a3ffaa585c69052c14134f13ea9c54fc) --- include/zephyr/net/mqtt.h | 3 +++ subsys/net/lib/mqtt/mqtt_transport_socket_tls.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/include/zephyr/net/mqtt.h b/include/zephyr/net/mqtt.h index aaba49a60e56..401de60628a8 100644 --- a/include/zephyr/net/mqtt.h +++ b/include/zephyr/net/mqtt.h @@ -350,6 +350,9 @@ struct mqtt_sec_config { /** Indicates the list of security tags to be used for the session. */ sec_tag_t *sec_tag_list; + /** Indicates the preference for enabling TLS session caching. */ + int session_cache; + /** Peer hostname for ceritificate verification. * May be NULL to skip hostname verification. */ diff --git a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c index c835656b6cf8..363ff51afeff 100644 --- a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c +++ b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c @@ -78,6 +78,16 @@ int mqtt_client_tls_connect(struct mqtt_client *client) } } + if (tls_config->session_cache == TLS_SESSION_CACHE_ENABLED) { + ret = zsock_setsockopt(client->transport.tls.sock, SOL_TLS, + TLS_SESSION_CACHE, + &tls_config->session_cache, + sizeof(tls_config->session_cache)); + if (ret < 0) { + goto error; + } + } + if (tls_config->cert_nocopy != TLS_CERT_NOCOPY_NONE) { ret = zsock_setsockopt(client->transport.tls.sock, SOL_TLS, TLS_CERT_NOCOPY, &tls_config->cert_nocopy, From 30140d610d67a52e7ed830b81f042be696fe74b6 Mon Sep 17 00:00:00 2001 From: Mirko Covizzi Date: Thu, 10 Mar 2022 00:25:50 -0800 Subject: [PATCH 015/528] [nrf noup] net: mqtt: add native TLS support This commit adds an extra parameter in the configuration structure to configure native TLS support at runtime. Signed-off-by: Mirko Covizzi (cherry picked from commit a719cd235202700bf2a874abce66a41fe715954e) --- doc/connectivity/networking/api/mqtt.rst | 3 +++ include/zephyr/net/mqtt.h | 3 +++ subsys/net/lib/mqtt/mqtt_transport_socket_tls.c | 7 ++++++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/doc/connectivity/networking/api/mqtt.rst b/doc/connectivity/networking/api/mqtt.rst index b1090c8d3947..dcc71e3320b8 100644 --- a/doc/connectivity/networking/api/mqtt.rst +++ b/doc/connectivity/networking/api/mqtt.rst @@ -149,6 +149,7 @@ additional configuration information: tls_config->sec_tag_list = m_sec_tags; tls_config->sec_tag_count = ARRAY_SIZE(m_sec_tags); tls_config->hostname = MQTT_BROKER_HOSTNAME; + tls_config->set_native_tls = true; In this sample code, the ``m_sec_tags`` array holds a list of tags, referencing TLS credentials that the MQTT library should use for authentication. We do not specify @@ -161,6 +162,8 @@ Note, that TLS credentials referenced by the ``m_sec_tags`` array must be registered in the system first. For more information on how to do that, refer to :ref:`secure sockets documentation `. +Finally, ``set_native_tls`` can be optionally set to enable native TLS support instead of offloading TLS operations to the modem. + An example of how to use TLS with MQTT is also present in :ref:`mqtt-publisher-sample`. diff --git a/include/zephyr/net/mqtt.h b/include/zephyr/net/mqtt.h index 401de60628a8..3cd628e5c2b0 100644 --- a/include/zephyr/net/mqtt.h +++ b/include/zephyr/net/mqtt.h @@ -360,6 +360,9 @@ struct mqtt_sec_config { /** Indicates the preference for copying certificates to the heap. */ int cert_nocopy; + + /** Set socket to native TLS */ + bool set_native_tls; }; /** @brief MQTT transport type. */ diff --git a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c index 363ff51afeff..8e9cc87239af 100644 --- a/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c +++ b/subsys/net/lib/mqtt/mqtt_transport_socket_tls.c @@ -22,10 +22,15 @@ int mqtt_client_tls_connect(struct mqtt_client *client) { const struct sockaddr *broker = client->broker; struct mqtt_sec_config *tls_config = &client->transport.tls.config; + int type = SOCK_STREAM; int ret; + if (tls_config->set_native_tls) { + type |= SOCK_NATIVE_TLS; + } + client->transport.tls.sock = zsock_socket(broker->sa_family, - SOCK_STREAM, IPPROTO_TLS_1_2); + type, IPPROTO_TLS_1_2); if (client->transport.tls.sock < 0) { return -errno; } From 22a279bf1d28f83ae9ea6bc4a5e0bf7e04e7589f Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Fri, 18 Mar 2022 14:46:42 +0100 Subject: [PATCH 016/528] [nrf noup] ipc: backends: rpmsg: initialize shared memory to zero Added a code for initializing shared memory to zero. This operation normalizes the memory state so that the IPC service is no longer prone to reading status bits from the previous reset session. Signed-off-by: Kamil Piszczek Signed-off-by: Dominik Ermel (cherry picked from commit 5e850cf31fc07d3e9f8042bb45845c4ad17d949a) --- .../backends/ipc_rpmsg_static_vrings.c | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c index 35f989fcd598..96016bb0a956 100644 --- a/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c +++ b/subsys/ipc/ipc_service/backends/ipc_rpmsg_static_vrings.c @@ -742,8 +742,8 @@ static int backend_init(const struct device *instance) return 0; } -#define DEFINE_BACKEND_DEVICE(i) \ - static struct backend_config_t backend_config_##i = { \ +#define BACKEND_CONFIG_POPULATE(i) \ + { \ .role = DT_ENUM_IDX_OR(DT_DRV_INST(i), role, ROLE_HOST), \ .shm_size = DT_REG_SIZE(DT_INST_PHANDLE(i, memory_region)), \ .shm_addr = DT_REG_ADDR(DT_INST_PHANDLE(i, memory_region)), \ @@ -758,8 +758,10 @@ static int backend_init(const struct device *instance) .buffer_size = DT_INST_PROP_OR(i, zephyr_buffer_size, \ RPMSG_BUFFER_SIZE), \ .id = i, \ - }; \ - \ + } + +#define BACKEND_DEVICE_DEFINE(i) \ + static struct backend_config_t backend_config_##i = BACKEND_CONFIG_POPULATE(i); \ static struct backend_data_t backend_data_##i; \ \ DEVICE_DT_INST_DEFINE(i, \ @@ -771,20 +773,23 @@ static int backend_init(const struct device *instance) CONFIG_IPC_SERVICE_REG_BACKEND_PRIORITY, \ &backend_ops); -DT_INST_FOREACH_STATUS_OKAY(DEFINE_BACKEND_DEVICE) +DT_INST_FOREACH_STATUS_OKAY(BACKEND_DEVICE_DEFINE) -#define BACKEND_CONFIG_INIT(n) &backend_config_##n, +#define BACKEND_CONFIG_DEFINE(i) BACKEND_CONFIG_POPULATE(i), #if defined(CONFIG_IPC_SERVICE_BACKEND_RPMSG_SHMEM_RESET) static int shared_memory_prepare(void) { - static const struct backend_config_t *config[] = { - DT_INST_FOREACH_STATUS_OKAY(BACKEND_CONFIG_INIT) + const struct backend_config_t *backend_config; + const struct backend_config_t backend_configs[] = { + DT_INST_FOREACH_STATUS_OKAY(BACKEND_CONFIG_DEFINE) }; - for (int i = 0; i < DT_NUM_INST_STATUS_OKAY(DT_DRV_COMPAT); i++) { - if (config[i]->role == ROLE_HOST) { - memset((void *) config[i]->shm_addr, 0, VDEV_STATUS_SIZE); + for (backend_config = backend_configs; + backend_config < backend_configs + ARRAY_SIZE(backend_configs); + backend_config++) { + if (backend_config->role == ROLE_HOST) { + memset((void *) backend_config->shm_addr, 0, VDEV_STATUS_SIZE); } } From cda81c03ba45ec242fac84666759ec360968aa29 Mon Sep 17 00:00:00 2001 From: Azizah Ibrahim Date: Wed, 7 Apr 2021 13:03:19 +0100 Subject: [PATCH 017/528] [nrf noup] samples: bluetooth: hci_pwr_ctrl: add dynamic control Enable dynamic power control in hci_pwr_ctrl sample for platforms using hci_rpmsg as controller Signed-off-by: Azizah Ibrahim Signed-off-by: Trond Einar Snekvik (cherry picked from commit 14f6d9c0682df75df177253797bb5c904860e632) --- samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf | 1 + 1 file changed, 1 insertion(+) create mode 100644 samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf diff --git a/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf b/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf new file mode 100644 index 000000000000..e6749ae63990 --- /dev/null +++ b/samples/bluetooth/hci_pwr_ctrl/child_image/hci_rpmsg.conf @@ -0,0 +1 @@ +CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y From 5689592f52a43cd26d1d5ae3fb6e662a5cf98780 Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Mon, 20 Jun 2022 10:14:39 +0200 Subject: [PATCH 018/528] [nrf noup] samples: mgmt: mcumgr: add hci_rpmsg child image config Added a configuration file for the HCI RPMsg child image that is necessary for multi-core targets. Signed-off-by: Kamil Piszczek (cherry picked from commit 761f5fd8491635bb3a72006d83a2071c7c379b1f) --- .../mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf b/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf new file mode 100644 index 000000000000..98260877332f --- /dev/null +++ b/samples/subsys/mgmt/mcumgr/smp_svr/child_image/hci_rpmsg.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2022 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_BT_MAX_CONN=2 +CONFIG_BT_BUF_ACL_RX_SIZE=502 +CONFIG_BT_BUF_ACL_TX_SIZE=502 +CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 From 4edd3681905057c345eb622ffe144fac958593e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Thu, 1 Dec 2022 14:41:13 +0100 Subject: [PATCH 019/528] [nrf noup] samples&tests: Restore a few CONFIG_NEWLIB_LIBC_NANO=n MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a follow-up to commit 9dd570f8a2207a02c886480b0065cd5a0e3a2e94. Since in NCS, unlike in vanilla Zephyr, the nano variant of newlib is the default one, restore entries that disable the nano variant in one sample and one test that require the full newlib variant. This patch is supposed to be removed when picolibc becomes the default. Signed-off-by: Andrzej Głąbek (cherry picked from commit 56204202e86fb7fa89f7ae74c916f73a00a22044) --- samples/posix/eventfd/prj.conf | 1 + tests/lib/newlib/heap_listener/prj.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/samples/posix/eventfd/prj.conf b/samples/posix/eventfd/prj.conf index af6bfd12d863..ab7c7475befd 100644 --- a/samples/posix/eventfd/prj.conf +++ b/samples/posix/eventfd/prj.conf @@ -1,5 +1,6 @@ # General config CONFIG_NEWLIB_LIBC=y +CONFIG_NEWLIB_LIBC_NANO=n CONFIG_POSIX_API=y CONFIG_EVENTFD=y diff --git a/tests/lib/newlib/heap_listener/prj.conf b/tests/lib/newlib/heap_listener/prj.conf index 31bc1ca7e765..8d8ebf99baf2 100644 --- a/tests/lib/newlib/heap_listener/prj.conf +++ b/tests/lib/newlib/heap_listener/prj.conf @@ -1,4 +1,5 @@ CONFIG_ZTEST=y CONFIG_NEWLIB_LIBC=y +CONFIG_NEWLIB_LIBC_NANO=n CONFIG_NEWLIB_LIBC_HEAP_LISTENER=y CONFIG_ZTEST_NEW_API=y From a722c66f997db0f1a74004c3f5c424808938abac Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Mon, 14 Nov 2022 11:22:06 +0100 Subject: [PATCH 020/528] [nrf noup] boards: thingy53_nrf5340: Add common partition map Change introduces common static Partition Manager configuration. The tfm_nonsecure partition must be SPU region aligned. Ref: NCSDK-18033 Ref: NCSDK-19515 Signed-off-by: Marek Pieta Signed-off-by: Markus Swarowsky (cherry picked from commit 6a9eba74bdc36576bdc6f562380912ee44f38bf8) --- .../pm_static_thingy53_nrf5340_cpuapp.yml | 55 ++++++++++++++ .../pm_static_thingy53_nrf5340_cpuapp_ns.yml | 73 +++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml create mode 100644 boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml diff --git a/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml new file mode 100644 index 000000000000..7a48d51ec334 --- /dev/null +++ b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp.yml @@ -0,0 +1,55 @@ +app: + address: 0x10200 + region: flash_primary + size: 0xdfe00 +mcuboot: + address: 0x0 + region: flash_primary + size: 0x10000 +mcuboot_pad: + address: 0x10000 + region: flash_primary + size: 0x200 +mcuboot_primary: + address: 0x10000 + orig_span: &id001 + - mcuboot_pad + - app + region: flash_primary + size: 0xe0000 + span: *id001 +mcuboot_primary_app: + address: 0x10200 + orig_span: &id002 + - app + region: flash_primary + size: 0xdfe00 + span: *id002 +settings_storage: + address: 0xf0000 + region: flash_primary + size: 0x10000 +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x00000 + size: 0xe0000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xe0000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x120000 + size: 0x6e0000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary diff --git a/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml new file mode 100644 index 000000000000..70ffe6d9c124 --- /dev/null +++ b/boards/arm/thingy53_nrf5340/pm_static_thingy53_nrf5340_cpuapp_ns.yml @@ -0,0 +1,73 @@ +mcuboot: + address: 0x0 + region: flash_primary + size: 0x10000 +mcuboot_pad: + address: 0x10000 + region: flash_primary + size: 0x200 +tfm_secure: + address: 0x10000 + size: 0xc000 + span: [mcuboot_pad, tfm] +tfm_nonsecure: + address: 0x1c000 + size: 0xd4000 + span: [app] +tfm: + address: 0x10200 + region: flash_primary + size: 0xbe00 +app: + address: 0x1c000 + region: flash_primary + size: 0xd4000 +mcuboot_primary: + address: 0x10000 + orig_span: &id001 + - mcuboot_pad + - tfm + - app + region: flash_primary + size: 0xe0000 + span: *id001 +mcuboot_primary_app: + address: 0x10200 + orig_span: &id002 + - tfm + - app + region: flash_primary + size: 0xdfe00 + span: *id002 +nonsecure_storage: + address: 0xf0000 + size: 0x10000 + span: [settings_storage] +settings_storage: + address: 0xf0000 + region: flash_primary + size: 0x10000 +mcuboot_primary_1: + address: 0x0 + size: 0x40000 + device: flash_ctrl + region: ram_flash +mcuboot_secondary: + address: 0x00000 + size: 0xe0000 + device: MX25R64 + region: external_flash +mcuboot_secondary_1: + address: 0xe0000 + size: 0x40000 + device: MX25R64 + region: external_flash +external_flash: + address: 0x120000 + size: 0x6e0000 + device: MX25R64 + region: external_flash +pcd_sram: + address: 0x20000000 + size: 0x2000 + region: sram_primary From a5ab323470201713ded500729f8cd34fc13c96f0 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Tue, 7 Feb 2023 12:39:12 +0100 Subject: [PATCH 021/528] [nrf noup] Bluetooth: Mesh: zero randomization for friend's adv Friend's replies on LPN's polls do not assume randomization in advertiser. Zero randomization will help to optimize time when LPN keeps receiving window open and save power. Signed-off-by: Aleksandr Khromykh (cherry picked from commit 88d5ef9efab511212a171fe67faf82468bcd0531) --- subsys/bluetooth/mesh/Kconfig | 2 +- subsys/bluetooth/mesh/adv_ext.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 3f2657a0fdfa..2c1ffb241c6e 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -839,7 +839,7 @@ config BT_MESH_LPN_INIT_POLL_TIMEOUT config BT_MESH_LPN_SCAN_LATENCY int "Latency for enabling scanning" range 0 50 - default 15 + default 2 help Latency in milliseconds that it takes to enable scanning. This is in practice how much time in advance before the Receive Window diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index 38bb4313f6fd..bb9f9730ce7a 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -13,6 +13,9 @@ #include #include #include +#if defined(CONFIG_BT_LL_SOFTDEVICE) +#include +#endif #include "common/bt_str.h" @@ -135,6 +138,28 @@ static inline struct bt_mesh_ext_adv *gatt_adv_get(void) #endif /* CONFIG_BT_MESH_ADV_EXT_GATT_SEPARATE */ } +static int set_adv_randomness(uint8_t handle, int rand_us) +{ +#if defined(CONFIG_BT_LL_SOFTDEVICE) + struct net_buf *buf; + sdc_hci_cmd_vs_set_adv_randomness_t *cmd_params; + + buf = bt_hci_cmd_create(SDC_HCI_OPCODE_CMD_VS_SET_ADV_RANDOMNESS, sizeof(*cmd_params)); + if (!buf) { + LOG_ERR("Could not allocate command buffer"); + return -ENOMEM; + } + + cmd_params = net_buf_add(buf, sizeof(*cmd_params)); + cmd_params->adv_handle = handle; + cmd_params->rand_us = rand_us; + + return bt_hci_cmd_send_sync(SDC_HCI_OPCODE_CMD_VS_SET_ADV_RANDOMNESS, buf, NULL); +#else + return 0; +#endif /* defined(CONFIG_BT_LL_SOFTDEVICE) */ +} + static int adv_start(struct bt_mesh_ext_adv *adv, const struct bt_le_adv_param *param, struct bt_le_ext_adv_start_param *start, @@ -466,6 +491,13 @@ int bt_mesh_adv_enable(void) if (err) { return err; } + + if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && adv->tag & BT_MESH_FRIEND_ADV) { + err = set_adv_randomness(adv->instance->handle, 0); + if (err) { + LOG_ERR("Failed to set zero randomness: %d", err); + } + } } return 0; From b182da7fcd6efed1fb177f87328f597cb14662e4 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 20 Nov 2020 14:44:03 +0100 Subject: [PATCH 022/528] [nrf noup] Bluetooth: update experimental for qualification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update Kconfig options for qualification: - Remove experimental on qualified feature. - Add experimental on unqualified feature. - BT_L2CAP_ECRED is not marked as experimental upstream and we qualify it downstream. Signed-off-by: Joakim Andersson Signed-off-by: Trond Einar Snekvik Signed-off-by: Martí Bolívar Signed-off-by: Robert Lubos Signed-off-by: Dominik Ermel Signed-off-by: Ingar Kulbrandstad Signed-off-by: Torsten Rasmussen Signed-off-by: Herman Berget Signed-off-by: Tomasz Moń (cherry picked from commit a6c2e3bbc24b7f565e3a8c0cc3d2d83b6d442487) --- subsys/bluetooth/controller/Kconfig | 3 ++- subsys/bluetooth/host/Kconfig.l2cap | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 9d42871093f6..1154d4ac3a6f 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -106,7 +106,8 @@ choice BT_LL_CHOICE Select the Bluetooth Link Layer to compile. config BT_LL_SW_SPLIT - bool "Software-based BLE Link Layer" + bool "Software-based BLE Link Layer [EXPERIMENTAL]" + select EXPERIMENTAL select ENTROPY_GENERATOR help Use Zephyr software BLE Link Layer ULL LLL split implementation. diff --git a/subsys/bluetooth/host/Kconfig.l2cap b/subsys/bluetooth/host/Kconfig.l2cap index 2d172595ad97..2364c6cb6261 100644 --- a/subsys/bluetooth/host/Kconfig.l2cap +++ b/subsys/bluetooth/host/Kconfig.l2cap @@ -52,7 +52,7 @@ config BT_L2CAP_DYNAMIC_CHANNEL allowing the creation of dynamic L2CAP Channels. config BT_L2CAP_ECRED - bool "L2CAP Enhanced Credit Based Flow Control support" + bool "L2CAP Enhanced Credit Based Flow Control support [EXPERIMENTAL]" depends on BT_L2CAP_DYNAMIC_CHANNEL help This option enables support for LE Connection oriented Channels with From 996037de254a91a9b2da4a288f48c09e90427501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20Storr=C3=B8?= Date: Wed, 8 Mar 2023 12:17:09 +0100 Subject: [PATCH 023/528] [nrf noup] Bluetooth: Mesh: Fix adv randomness bug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes issue where randomness can be removed for advertising sets that have to handle other adv types than the BT_MESH_FRIEND_ADV tag type. Signed-off-by: Anders Storrø (cherry picked from commit f8f113382356934cb6d1ef4cdad95a843f922085) --- subsys/bluetooth/mesh/adv_ext.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/mesh/adv_ext.c b/subsys/bluetooth/mesh/adv_ext.c index bb9f9730ce7a..4f61431f3690 100644 --- a/subsys/bluetooth/mesh/adv_ext.c +++ b/subsys/bluetooth/mesh/adv_ext.c @@ -492,7 +492,9 @@ int bt_mesh_adv_enable(void) return err; } - if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && adv->tag & BT_MESH_FRIEND_ADV) { + if (IS_ENABLED(CONFIG_BT_LL_SOFTDEVICE) && + IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && + adv->tag == BT_MESH_FRIEND_ADV) { err = set_adv_randomness(adv->instance->handle, 0); if (err) { LOG_ERR("Failed to set zero randomness: %d", err); From 7f45aa42295533c14994fe1c449da643fa7d6399 Mon Sep 17 00:00:00 2001 From: Mateusz Kapala Date: Thu, 2 Feb 2023 11:04:23 +0100 Subject: [PATCH 024/528] [nrf noup] boards: arm: thingy53: Disable USB CDC added by MCUBoot Enabling USB CDC by default in Thingy:53 board configuration caused that there were two instances of USB CDC in MCUBoot. Change disables one instance which was added automatically by NCS if MCUBoot bootloader was built as a child image. Jira: NCSDK-18596 Signed-off-by: Mateusz Kapala Signed-off-by: Johann Fischer (cherry picked from commit 5193278031897be51edfac12ac8cb250f9b8ff93) --- boards/arm/thingy53_nrf5340/Kconfig.defconfig | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/boards/arm/thingy53_nrf5340/Kconfig.defconfig b/boards/arm/thingy53_nrf5340/Kconfig.defconfig index e4d9e63b7f17..b34d118e59cb 100644 --- a/boards/arm/thingy53_nrf5340/Kconfig.defconfig +++ b/boards/arm/thingy53_nrf5340/Kconfig.defconfig @@ -135,6 +135,12 @@ endif # LOG endif # BOARD_SERIAL_BACKEND_CDC_ACM +# By default, a USB CDC ACM instance is already enabled in the board's DTS. +# It is not necessary for nRF Connect SDK to add another instance if MCUBoot +# bootloader is built as a child image. +config MCUBOOT_USB_SUPPORT + default n + endif # BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS if BOARD_THINGY53_NRF5340_CPUNET From 79993350d8494c3cba1e9947925890249aaedde2 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 5 May 2022 12:04:26 +0200 Subject: [PATCH 025/528] [nrf noup] boards: Enable TF-M by default for nordic SoC NS boards Enable TF-M by default for nordic nRF5340 and nrf9160 SoC boards. NCSDK-14811 Signed-off-by: Joakim Andersson Signed-off-by: Jamie McCrae Signed-off-by: Alex Tsamakos Signed-off-by: Johann Fischer (cherry picked from commit 1f9e520d7518322c0cfd40d91f299cfa28ad07fb) --- boards/arm/actinius_icarus/Kconfig.defconfig | 15 +++++++++++++++ boards/arm/actinius_icarus_bee/Kconfig.defconfig | 15 +++++++++++++++ boards/arm/actinius_icarus_som/Kconfig.defconfig | 15 +++++++++++++++ .../circuitdojo_feather_nrf9160/Kconfig.defconfig | 15 +++++++++++++++ .../sparkfun_thing_plus_nrf9160/Kconfig.defconfig | 15 +++++++++++++++ boards/arm/thingy53_nrf5340/Kconfig.defconfig | 15 +++++++++++++++ 6 files changed, 90 insertions(+) diff --git a/boards/arm/actinius_icarus/Kconfig.defconfig b/boards/arm/actinius_icarus/Kconfig.defconfig index 6994aac280d6..3b8093275da3 100644 --- a/boards/arm/actinius_icarus/Kconfig.defconfig +++ b/boards/arm/actinius_icarus/Kconfig.defconfig @@ -8,6 +8,21 @@ if BOARD_ACTINIUS_ICARUS || BOARD_ACTINIUS_ICARUS_NS config BOARD default "actinius_icarus" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_ACTINIUS_ICARUS_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + source "boards/common/actinius/Kconfig" # For the secure version of the board the firmware is linked at the beginning diff --git a/boards/arm/actinius_icarus_bee/Kconfig.defconfig b/boards/arm/actinius_icarus_bee/Kconfig.defconfig index 309a45a61d42..7b733d910d9f 100644 --- a/boards/arm/actinius_icarus_bee/Kconfig.defconfig +++ b/boards/arm/actinius_icarus_bee/Kconfig.defconfig @@ -8,6 +8,21 @@ if BOARD_ACTINIUS_ICARUS_BEE || BOARD_ACTINIUS_ICARUS_BEE_NS config BOARD default "actinius_icarus_bee" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_ACTINIUS_ICARUS_BEE_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + source "boards/common/actinius/Kconfig" # For the secure version of the board the firmware is linked at the beginning diff --git a/boards/arm/actinius_icarus_som/Kconfig.defconfig b/boards/arm/actinius_icarus_som/Kconfig.defconfig index 473acfea29fe..cc92427d24c8 100644 --- a/boards/arm/actinius_icarus_som/Kconfig.defconfig +++ b/boards/arm/actinius_icarus_som/Kconfig.defconfig @@ -8,6 +8,21 @@ if BOARD_ACTINIUS_ICARUS_SOM || BOARD_ACTINIUS_ICARUS_SOM_NS config BOARD default "actinius_icarus_som" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_ACTINIUS_ICARUS_SOM_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + source "boards/common/actinius/Kconfig" # For the secure version of the board the firmware is linked at the beginning diff --git a/boards/arm/circuitdojo_feather_nrf9160/Kconfig.defconfig b/boards/arm/circuitdojo_feather_nrf9160/Kconfig.defconfig index 73648be3ef17..f37bfbf84fb4 100644 --- a/boards/arm/circuitdojo_feather_nrf9160/Kconfig.defconfig +++ b/boards/arm/circuitdojo_feather_nrf9160/Kconfig.defconfig @@ -9,6 +9,21 @@ if BOARD_CIRCUITDOJO_FEATHER_NRF9160 || BOARD_CIRCUITDOJO_FEATHER_NRF9160_NS config BOARD default "circuitdojo_feather_nrf9160" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_CIRCUITDOJO_FEATHER_NRF9160_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/boards/arm/sparkfun_thing_plus_nrf9160/Kconfig.defconfig b/boards/arm/sparkfun_thing_plus_nrf9160/Kconfig.defconfig index 8ae5b832d895..3d98b1b4cb4b 100644 --- a/boards/arm/sparkfun_thing_plus_nrf9160/Kconfig.defconfig +++ b/boards/arm/sparkfun_thing_plus_nrf9160/Kconfig.defconfig @@ -9,6 +9,21 @@ if BOARD_SPARKFUN_THING_PLUS_NRF9160 || BOARD_SPARKFUN_THING_PLUS_NRF9160_NS config BOARD default "sparkfun_thing_plus_nrf9160" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_SPARKFUN_THING_PLUS_NRF9160_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/boards/arm/thingy53_nrf5340/Kconfig.defconfig b/boards/arm/thingy53_nrf5340/Kconfig.defconfig index b34d118e59cb..0afe06dacb9e 100644 --- a/boards/arm/thingy53_nrf5340/Kconfig.defconfig +++ b/boards/arm/thingy53_nrf5340/Kconfig.defconfig @@ -8,6 +8,21 @@ if BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS config BOARD default "thingy53_nrf5340_cpuapp" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_THINGY53_NRF5340_CPUAPP_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # Code Partition: # # For the secure version of the board the firmware is linked at the beginning From ff1db43269579e2a0bdc28c55f2c83d3ad58ebb7 Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Mon, 28 Nov 2022 15:31:33 +0100 Subject: [PATCH 026/528] [nrf noup] boards: thingy53_nrf5340: Enable MCUboot by default Change enables MCUboot bootloader by default to allow programming samples and applications without external programmer (using MCUboot serial recovery). Change also enables network core to prevent build failures when building MCUboot with nRF53 multi image DFU. Jira: NCSDK-18263 Signed-off-by: Marek Pieta Signed-off-by: Vinayak Kariappa Chettimada Signed-off-by: Johann Fischer (cherry picked from commit 46895493bf1b0988e44ea344f4420b543e307eae) --- boards/arm/thingy53_nrf5340/Kconfig.defconfig | 6 ++++++ boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts | 1 + 2 files changed, 7 insertions(+) diff --git a/boards/arm/thingy53_nrf5340/Kconfig.defconfig b/boards/arm/thingy53_nrf5340/Kconfig.defconfig index 0afe06dacb9e..c79eb908c215 100644 --- a/boards/arm/thingy53_nrf5340/Kconfig.defconfig +++ b/boards/arm/thingy53_nrf5340/Kconfig.defconfig @@ -8,6 +8,12 @@ if BOARD_THINGY53_NRF5340_CPUAPP || BOARD_THINGY53_NRF5340_CPUAPP_NS config BOARD default "thingy53_nrf5340_cpuapp" +config BOOTLOADER_MCUBOOT + default y if !MCUBOOT + +config BOARD_ENABLE_CPUNET + default y if !MCUBOOT + # By default, if we build for a Non-Secure version of the board, # enable building with TF-M as the Secure Execution Environment. config BUILD_WITH_TFM diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts index 62403423b9c5..3ce47a68f628 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts @@ -15,6 +15,7 @@ zephyr,bt-hci-rpmsg-ipc = &ipc0; nordic,802154-spinel-ipc = &ipc0; zephyr,ieee802154 = &ieee802154; + nordic,pm-ext-flash = &mx25r64; }; buttons { From 298d8037d2b60b4ca4dd8b2a7727196e33054dd8 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 23 Jun 2022 14:10:01 +0000 Subject: [PATCH 027/528] [nrf noup] mgmt/mcumgr: Bootutil hooks to handle image-1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The commit adds bootutil hook, for nrf5340, to allow it handling the non-accessible image-1/primary slot. Signed-off-by: Dominik Ermel Signed-off-by: Andrzej Głąbek Signed-off-by: Vinayak Kariappa Chettimada Signed-off-by: Johann Fischer (cherry picked from commit 840b8fa1dba3ddda02fa1652a9408b08b7c310de) (cherry picked from commit 9af7d7ad2f70cee26ccc98b4daadd2260662ff78) --- subsys/mgmt/mcumgr/CMakeLists.txt | 8 ++++++ subsys/mgmt/mcumgr/Kconfig | 1 + .../mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c | 27 +++++++++++++++++++ 3 files changed, 36 insertions(+) create mode 100644 subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c diff --git a/subsys/mgmt/mcumgr/CMakeLists.txt b/subsys/mgmt/mcumgr/CMakeLists.txt index c977160f05b0..d0f0c55e19cd 100644 --- a/subsys/mgmt/mcumgr/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/CMakeLists.txt @@ -15,3 +15,11 @@ add_subdirectory(grp) add_subdirectory(transport) zephyr_library_link_libraries(mgmt_mcumgr) + +if (CONFIG_BOOT_IMAGE_ACCESS_HOOKS) + zephyr_include_directories( + ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/bootutil/include + ${ZEPHYR_MCUBOOT_MODULE_DIR}/boot/zephyr/include + ) + zephyr_library_sources(bootutil_hooks/nrf53_hooks.c) +endif() diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig index cdf292bcaefe..075ad0511161 100644 --- a/subsys/mgmt/mcumgr/Kconfig +++ b/subsys/mgmt/mcumgr/Kconfig @@ -7,6 +7,7 @@ menuconfig MCUMGR depends on NET_BUF depends on ZCBOR depends on CRC + imply BOOT_IMAGE_ACCESS_HOOKS if (SOC_NRF5340_CPUAPP_QKAA && MCUMGR_GRP_IMG) help This option enables the mcumgr management library. diff --git a/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c b/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c new file mode 100644 index 000000000000..9971a4e08431 --- /dev/null +++ b/subsys/mgmt/mcumgr/bootutil_hooks/nrf53_hooks.c @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "bootutil/bootutil_public.h" + +int boot_read_swap_state_primary_slot_hook(int image_index, + struct boot_swap_state *state) +{ + if (image_index == 1) { + /* Pretend that primary slot of image 1 unpopulated */ + state->magic = BOOT_MAGIC_UNSET; + state->swap_type = BOOT_SWAP_TYPE_NONE; + state->image_num = image_index; + state->copy_done = BOOT_FLAG_UNSET; + state->image_ok = BOOT_FLAG_UNSET; + + /* Prevent bootutil from trying to obtain true info */ + return 0; + } + + return BOOT_HOOK_REGULAR; +} From 6f270fa5a6b68e485184bd551ac4b18033333d6a Mon Sep 17 00:00:00 2001 From: Krishna T Date: Mon, 15 Aug 2022 02:45:06 +0530 Subject: [PATCH 028/528] [nrf noup] net: wifi: Add support for WPA supplicant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If WPA supplicant is enabled at build time, then use the WPA supplicant APIs, else use offload driver APIs. Use z_wpa_supplicant as the name space. Signed-off-by: Krishna T Signed-off-by: Tomasz Moń Signed-off-by: Johann Fischer (cherry picked from commit 1f61ba55173d87a239b27f5f698ee5472933e996) --- subsys/net/l2/wifi/wifi_mgmt.c | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 7f92410f9175..3a0f41f63d26 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -12,6 +12,9 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include +#ifdef CONFIG_WPA_SUPP +#include "supp_api.h" +#endif static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) @@ -19,12 +22,15 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, struct wifi_connect_req_params *params = (struct wifi_connect_req_params *)data; const struct device *dev = net_if_get_device(iface); +#ifndef CONFIG_WPA_SUPP struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + if (off_api == NULL || off_api->connect == NULL) { return -ENOTSUP; } +#endif /* CONFIG_WPA_SUPP */ LOG_HEXDUMP_DBG(params->ssid, params->ssid_length, "ssid"); LOG_HEXDUMP_DBG(params->psk, params->psk_length, "psk"); @@ -48,8 +54,11 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, !params->ssid) { return -EINVAL; } - +#ifdef CONFIG_WPA_SUPP + return z_wpa_supplicant_connect(dev, params); +#else return off_api->connect(dev, params); +#endif /* CONFIG_WPA_SUPP */ } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT, wifi_connect); @@ -97,6 +106,10 @@ static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); + +#ifdef CONFIG_WPA_SUPP + return z_wpa_supplicant_disconnect(dev); +#else struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; @@ -105,6 +118,7 @@ static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface, } return off_api->disconnect(dev); +#endif /* CONFIG_WPA_SUPP */ } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT, wifi_disconnect); @@ -169,19 +183,24 @@ static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); + struct wifi_iface_status *status = data; + + if (!data || len != sizeof(*status)) { + return -EINVAL; + } + +#ifdef CONFIG_WPA_SUPP + return z_wpa_supplicant_status(dev, status); +#else struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; - struct wifi_iface_status *status = data; if (off_api == NULL || off_api->iface_status == NULL) { return -ENOTSUP; } - if (!data || len != sizeof(*status)) { - return -EINVAL; - } - return off_api->iface_status(dev, status); +#endif /* CONFIG_WPA_SUPP */ } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_IFACE_STATUS, wifi_iface_status); From b1b412685610a94fc236d1100b1c4f437add7ecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 18 Apr 2023 05:12:44 -0700 Subject: [PATCH 029/528] [nrf fromtree] apps: misc void main -> int main fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix some additional cases in in-tree applications (samples and tests). Signed-off-by: Martí Bolívar (cherry picked from commit 1d214e7c2d83f9a67c8abbf34e63576bee91057f) --- samples/bluetooth/encrypted_advertising/central/src/main.c | 6 ++++-- .../bluetooth/encrypted_advertising/peripheral/src/main.c | 5 +++-- samples/shields/npm1300_ek/src/main.c | 4 ++-- .../bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c | 3 ++- tests/drivers/build_all/i2c/src/main.c | 3 ++- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/samples/bluetooth/encrypted_advertising/central/src/main.c b/samples/bluetooth/encrypted_advertising/central/src/main.c index ecff673e9f64..888940af780b 100644 --- a/samples/bluetooth/encrypted_advertising/central/src/main.c +++ b/samples/bluetooth/encrypted_advertising/central/src/main.c @@ -103,16 +103,18 @@ static int setup_btn(void) return 0; } -void main(void) +int main(void) { int err; err = setup_btn(); if (err) { - return; + return 0; } LOG_DBG("Starting central sample..."); (void)run_central_sample(get_passkey_confirmation, NULL, 0, NULL); + + return 0; } diff --git a/samples/bluetooth/encrypted_advertising/peripheral/src/main.c b/samples/bluetooth/encrypted_advertising/peripheral/src/main.c index 86ca785accc8..6b269d30513b 100644 --- a/samples/bluetooth/encrypted_advertising/peripheral/src/main.c +++ b/samples/bluetooth/encrypted_advertising/peripheral/src/main.c @@ -97,16 +97,17 @@ static int setup_btn(void) return 0; } -void main(void) +int main(void) { int err; err = setup_btn(); if (err) { - return; + return 0; } LOG_DBG("Starting peripheral sample..."); (void)run_peripheral_sample(get_passkey_confirmation); + return 0; } diff --git a/samples/shields/npm1300_ek/src/main.c b/samples/shields/npm1300_ek/src/main.c index b133a26aed77..af7e6b92decc 100644 --- a/samples/shields/npm1300_ek/src/main.c +++ b/samples/shields/npm1300_ek/src/main.c @@ -37,13 +37,13 @@ void configure_ui(void) printk("Set up button at %s pin %d\n", button1.port->name, button1.pin); } -void main(void) +int main(void) { configure_ui(); if (!device_is_ready(regulators)) { printk("Error: Regulator device is not ready\n"); - return; + return 0; } while (1) { diff --git a/tests/bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c b/tests/bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c index 445d1e8b3b41..9abc66fcb5f9 100644 --- a/tests/bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c +++ b/tests/bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c @@ -149,7 +149,8 @@ struct bst_test_list *test_ead_sample_install(struct bst_test_list *tests) bst_test_install_t test_installers[] = {test_ead_sample_install, NULL}; -void main(void) +int main(void) { bst_main(); + return 0; } diff --git a/tests/drivers/build_all/i2c/src/main.c b/tests/drivers/build_all/i2c/src/main.c index 9620d82627e8..d0d8b7b2b502 100644 --- a/tests/drivers/build_all/i2c/src/main.c +++ b/tests/drivers/build_all/i2c/src/main.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -void main(void) +int main(void) { + return 0; } From 40010edf12eb94038090e7f3072b91f4beefd0c1 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Tue, 18 Apr 2023 16:11:33 +0200 Subject: [PATCH 030/528] [nrf fromtree] modules: openthread: align received frame timestamp to SFD OpenThread requires that the `mTimestamp` parameter from the `mRxInfo` struct points to the end of SFD, i.e. beggining of PHR. Signed-off-by: Eduardo Montoya (cherry picked from commit 760d8fc9703615fde89bf51b343eb4194628424f) --- include/zephyr/net/net_pkt.h | 5 ++++- modules/openthread/platform/radio.c | 13 ++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 893689523487..5725aefbeb8f 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -95,7 +95,10 @@ struct net_pkt { #endif #if defined(CONFIG_NET_PKT_TIMESTAMP) - /** Timestamp if available. */ + /** + * Timestamp if available. + * For IEEE 802.15.4 packets this refers to the first symbol of the MAC Header. + */ struct net_ptp_time timestamp; #endif diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 1c8b2896e8c5..69a4e1f73211 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -38,7 +38,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_OPENTHREAD_L2_LOG_LEVEL); #define SHORT_ADDRESS_SIZE 2 -#define FCS_SIZE 2 +#define FCS_SIZE 2 +#define PHR_DURATION 32 #if defined(CONFIG_IEEE802154_2015) #define ACK_PKT_LENGTH 127 #else @@ -185,8 +186,9 @@ enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface, #if defined(CONFIG_NET_PKT_TIMESTAMP) struct net_ptp_time *pkt_time = net_pkt_timestamp(pkt); - ack_frame.mInfo.mRxInfo.mTimestamp = - pkt_time->second * USEC_PER_SEC + pkt_time->nanosecond / NSEC_PER_USEC; + /* OpenThread expects the timestamp to point to the end of SFD */ + ack_frame.mInfo.mRxInfo.mTimestamp = pkt_time->second * USEC_PER_SEC + + pkt_time->nanosecond / NSEC_PER_USEC - PHR_DURATION; #endif return NET_OK; @@ -394,8 +396,9 @@ static void openthread_handle_received_frame(otInstance *instance, #if defined(CONFIG_NET_PKT_TIMESTAMP) struct net_ptp_time *pkt_time = net_pkt_timestamp(pkt); - recv_frame.mInfo.mRxInfo.mTimestamp = - pkt_time->second * USEC_PER_SEC + pkt_time->nanosecond / NSEC_PER_USEC; + /* OpenThread expects the timestamp to point to the end of SFD */ + recv_frame.mInfo.mRxInfo.mTimestamp = pkt_time->second * USEC_PER_SEC + + pkt_time->nanosecond / NSEC_PER_USEC - PHR_DURATION; #endif #if defined(CONFIG_IEEE802154_2015) From 0fed1a68a04ac2212b9a4b925f3fc22e7e6f7901 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Tue, 18 Apr 2023 10:20:14 +0200 Subject: [PATCH 031/528] [nrf fromtree] modules: openthread: fix handling tx done when sleep to tx is supported After `otPlatRadioSleep` was fixed to properly set radio state to sleep, radios supporting `IEEE802154_HW_SLEEP_TO_TX` capability would not be able to handle `PENDING_EVENT_TX_DONE` while in sleep state. This commit fixes such case. Signed-off-by: Eduardo Montoya (cherry picked from commit 2c4cf2583685781d30f3d9f7c5090a0b56d440a7) --- modules/openthread/platform/radio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 69a4e1f73211..df3266b1274b 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -529,7 +529,8 @@ void platformRadioProcess(otInstance *aInstance) if (is_pending_event_set(PENDING_EVENT_TX_DONE)) { reset_pending_event(PENDING_EVENT_TX_DONE); - if (sState == OT_RADIO_STATE_TRANSMIT) { + if (sState == OT_RADIO_STATE_TRANSMIT || + radio_api->get_capabilities(radio_dev) & IEEE802154_HW_SLEEP_TO_TX) { sState = OT_RADIO_STATE_RECEIVE; handle_tx_done(aInstance); } From 3370d8abe426c03b539b6a290accd2d8eb2acb7c Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 20 Apr 2023 14:04:55 +0200 Subject: [PATCH 032/528] [nrf fromlist] Bluetooth: BAP: Fix missing guards of sent and recv in uni cli The unicast client did not properly guard the sent and recv callbacks. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57079 Signed-off-by: Emil Gydesen (cherry picked from commit aec4315c917fd05fa4d8286a990300164c8516a2) --- subsys/bluetooth/audio/bap_unicast_client.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 3c5530fea6b9..5897afc5628e 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -207,6 +207,7 @@ static struct bt_bap_stream *audio_stream_by_ep_id(const struct bt_conn *conn, return NULL; } +#if defined(CONFIG_BT_AUDIO_RX) static void unicast_client_ep_iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info, struct net_buf *buf) { @@ -256,7 +257,9 @@ static void unicast_client_ep_iso_recv(struct bt_iso_chan *chan, LOG_WRN("No callback for recv set"); } } +#endif /* CONFIG_BT_AUDIO_RX */ +#if defined(CONFIG_BT_AUDIO_TX) static void unicast_client_ep_iso_sent(struct bt_iso_chan *chan) { struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan); @@ -282,6 +285,7 @@ static void unicast_client_ep_iso_sent(struct bt_iso_chan *chan) stream->ops->sent(stream); } } +#endif /* CONFIG_BT_AUDIO_TX */ static void unicast_client_ep_iso_connected(struct bt_bap_ep *ep) { @@ -392,8 +396,12 @@ static void unicast_client_iso_disconnected(struct bt_iso_chan *chan, uint8_t re } static struct bt_iso_chan_ops unicast_client_iso_ops = { +#if defined(CONFIG_BT_AUDIO_RX) .recv = unicast_client_ep_iso_recv, +#endif /* CONFIG_BT_AUDIO_RX */ +#if defined(CONFIG_BT_AUDIO_TX) .sent = unicast_client_ep_iso_sent, +#endif /* CONFIG_BT_AUDIO_TX */ .connected = unicast_client_iso_connected, .disconnected = unicast_client_iso_disconnected, }; From b5e62e59ac1cab9ee2854347479fb985f3856672 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 20 Apr 2023 14:05:52 +0200 Subject: [PATCH 033/528] [nrf fromlist] Bluetooth: BAP: Guard bt_bap_stream_send with CONFIG_BT_AUDIO_TX Modify the guard of bt_bap_stream_send to use the CONFIG_BT_AUDIO_TX. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57079 Signed-off-by: Emil Gydesen (cherry picked from commit 53683a2d2e7557b5063224546fabb074aa77eaa3) --- subsys/bluetooth/audio/bap_stream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 1f037bb6655c..bdb8b3bff090 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -134,7 +134,7 @@ int bt_bap_ep_get_info(const struct bt_bap_ep *ep, struct bt_bap_ep_info *info) return 0; } -#if defined(CONFIG_BT_BAP_UNICAST) || defined(CONFIG_BT_BAP_BROADCAST_SOURCE) +#if defined(CONFIG_BT_AUDIO_TX) enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos) { if (qos->interval < BT_ISO_SDU_INTERVAL_MIN || @@ -192,7 +192,7 @@ int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, return bt_iso_chan_send(bt_bap_stream_iso_chan_get(stream), buf, seq_num, ts); } -#endif /* CONFIG_BT_BAP_UNICAST || CONFIG_BT_BAP_BROADCAST_SOURCE */ +#endif /* CONFIG_BT_AUDIO_TX */ #if defined(CONFIG_BT_BAP_UNICAST) static bool bt_bap_stream_is_broadcast(const struct bt_bap_stream *stream) From 9a894b9b04faa373d01ec6d743071a09909611b7 Mon Sep 17 00:00:00 2001 From: Magdalena Kasenberg Date: Wed, 19 Apr 2023 18:09:44 +0200 Subject: [PATCH 034/528] [nrf fromtree] bluetooth: tester: Restore removed nrf5340_hci_rpmsg.conf This overlay is still needed for non-leaudio tests. Signed-off-by: Magdalena Kasenberg (cherry picked from commit 0b5f976073cdf70bd12b037cd2207fe79ab77c2b) (cherry picked from commit 7312f5e2071fe7ecc4459a8584f7e2e3cecac3ed) --- tests/bluetooth/tester/nrf5340_hci_rpmsg.conf | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 tests/bluetooth/tester/nrf5340_hci_rpmsg.conf diff --git a/tests/bluetooth/tester/nrf5340_hci_rpmsg.conf b/tests/bluetooth/tester/nrf5340_hci_rpmsg.conf new file mode 100644 index 000000000000..16d6d2ab402c --- /dev/null +++ b/tests/bluetooth/tester/nrf5340_hci_rpmsg.conf @@ -0,0 +1,13 @@ +# Those have to be the same as in the controller (hci_rpmsg) +CONFIG_BT_MAX_CONN=2 +CONFIG_BT_BUF_EVT_RX_COUNT=16 +CONFIG_BT_BUF_EVT_RX_SIZE=255 +CONFIG_BT_BUF_CMD_TX_SIZE=255 +CONFIG_BT_BUF_ACL_TX_SIZE=251 + +# L2CAP SDU/PDU TX MTU +CONFIG_BT_L2CAP_TX_MTU=247 + +# The minimum value for this is +# L2AP MPS + L2CAP header (4) +CONFIG_BT_BUF_ACL_RX_SIZE=255 From 045dc290b0116df9dcb7e715bf08075eb487e83c Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 21 Mar 2023 11:17:43 +0000 Subject: [PATCH 035/528] [nrf fromlist] mgmt/mcumgr: Add img_mgmt_active_slot() and img_mgmt_active_image() The commit adds img_mgmt_active_slot() which allows to get active (running) slot for given application image. Added img_mgmt_active_image() allows to get number of image running on current MCU core. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56725 Signed-off-by: Dominik Ermel (cherry picked from commit dc2a6b5d07e19cbdac2b3c58ae6e99a3c2f87954) --- .../mgmt/mcumgr/grp/img_mgmt/img_mgmt.h | 20 +++++- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 61 +++++++++++++++++-- .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 28 ++++----- 3 files changed, 89 insertions(+), 20 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h index a5acf784fb47..c3ab8bf6104b 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022 Nordic Semiconductor ASA + * Copyright (c) 2022-2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -143,6 +143,24 @@ int img_mgmt_my_version(struct image_version *ver); */ int img_mgmt_ver_str(const struct image_version *ver, char *dst); +/** + * @brief Get active, running application slot number for an image + * + * @param image image number to get active slot for. + * + * @return Non-negative slot number + */ +int img_mgmt_active_slot(int image); + +/** + * @brief Get active image number + * + * Gets 0 based number for running application. + * + * @return Non-negative image number. + */ +int img_mgmt_active_image(void); + /** * @brief Check if the image slot is in use. * diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 526a03a80d3b..292d275ce958 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022 Nordic Semiconductor ASA + * Copyright (c) 2022-2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -35,6 +34,16 @@ #include #endif +#define FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(label) \ + DT_SAME_NODE(DT_NODELABEL(label), DT_CHOSEN(zephyr_code_partition)) + +#if !(FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_partition) || \ + FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_ns_partition) || \ + FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot1_partition) || \ + FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot2_partition)) +#error "Unsupported chosen zephyr,code-partition for boot application." +#endif + LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); struct img_mgmt_state g_img_mgmt_state; @@ -78,6 +87,31 @@ img_mgmt_find_tlvs(int slot, size_t *start_off, size_t *end_off, return 0; } +int img_mgmt_active_slot(int image) +{ +#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 + if (image == 1) { + return 2; + } +#endif + /* Image 0 */ + if (FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot1_partition)) { + return 1; + } + return 0; +} + +int img_mgmt_active_image(void) +{ +#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 + if (!(FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_partition) || + FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_ns_partition) || + FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot1_partition))) { + return 1; + } +#endif + return 0; +} /* * Reads the version and build hash from the specified image slot. */ @@ -258,6 +292,24 @@ void img_mgmt_reset_upload(void) g_img_mgmt_state.area_id = -1; } +static int +img_mgmt_get_other_slot(void) +{ + int slot = img_mgmt_active_slot(img_mgmt_active_image()); + + switch (slot) { + case 1: + return 0; +#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER + case 2: + return 3; + case 3: + return 2; + } +#endif + return 1; +} + /** * Command handler: image erase */ @@ -269,7 +321,7 @@ img_mgmt_erase(struct smp_streamer *ctxt) zcbor_state_t *zsd = ctxt->reader->zs; zcbor_state_t *zse = ctxt->writer->zs; bool ok; - uint32_t slot = 1; + uint32_t slot = img_mgmt_get_other_slot(); size_t decoded = 0; struct zcbor_map_decode_key_val image_erase_decode[] = { @@ -620,7 +672,8 @@ img_mgmt_upload(struct smp_streamer *ctxt) int img_mgmt_my_version(struct image_version *ver) { - return img_mgmt_read_info(IMG_MGMT_BOOT_CURR_SLOT, ver, NULL, NULL); + return img_mgmt_read_info(img_mgmt_active_slot(img_mgmt_active_image()), + ver, NULL, NULL); } static const struct mgmt_handler img_mgmt_handlers[] = { diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index a5ef02196df1..6f7750c68a09 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022 Nordic Semiconductor ASA + * Copyright (c) 2022-2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -56,6 +55,8 @@ img_mgmt_state_flags(int query_slot) { uint8_t flags; int swap_type; + int image = query_slot / 2; /* We support max 2 images for now */ + int active_slot = img_mgmt_active_slot(image); flags = 0; @@ -65,14 +66,13 @@ img_mgmt_state_flags(int query_slot) swap_type = img_mgmt_swap_type(query_slot); switch (swap_type) { case IMG_MGMT_SWAP_TYPE_NONE: - if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { + if (query_slot == active_slot) { flags |= IMG_MGMT_STATE_F_CONFIRMED; - flags |= IMG_MGMT_STATE_F_ACTIVE; } break; case IMG_MGMT_SWAP_TYPE_TEST: - if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { + if (query_slot == active_slot) { flags |= IMG_MGMT_STATE_F_CONFIRMED; } else { flags |= IMG_MGMT_STATE_F_PENDING; @@ -80,7 +80,7 @@ img_mgmt_state_flags(int query_slot) break; case IMG_MGMT_SWAP_TYPE_PERM: - if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { + if (query_slot == active_slot) { flags |= IMG_MGMT_STATE_F_CONFIRMED; } else { flags |= IMG_MGMT_STATE_F_PENDING | IMG_MGMT_STATE_F_PERMANENT; @@ -88,17 +88,14 @@ img_mgmt_state_flags(int query_slot) break; case IMG_MGMT_SWAP_TYPE_REVERT: - if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { - flags |= IMG_MGMT_STATE_F_ACTIVE; - } else { + if (query_slot != active_slot) { flags |= IMG_MGMT_STATE_F_CONFIRMED; } break; } - /* Slot 0 is always active. */ - /* XXX: The slot 0 assumption only holds when running from flash. */ - if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { + /* Only running application is active */ + if (image == img_mgmt_active_image() && query_slot == active_slot) { flags |= IMG_MGMT_STATE_F_ACTIVE; } @@ -124,9 +121,10 @@ int img_mgmt_slot_in_use(int slot) { uint8_t state_flags; + int active_slot = img_mgmt_active_slot(img_mgmt_active_image()); state_flags = img_mgmt_state_flags(slot); - return state_flags & IMG_MGMT_STATE_F_ACTIVE || + return slot == active_slot || state_flags & IMG_MGMT_STATE_F_CONFIRMED || state_flags & IMG_MGMT_STATE_F_PENDING; } @@ -297,7 +295,7 @@ img_mgmt_state_write(struct smp_streamer *ctxt) /* Determine which slot is being operated on. */ if (zhash.len == 0) { if (confirm) { - slot = IMG_MGMT_BOOT_CURR_SLOT; + slot = img_mgmt_active_slot(img_mgmt_active_image()); } else { /* A 'test' without a hash is invalid. */ return MGMT_ERR_EINVAL; @@ -318,7 +316,7 @@ img_mgmt_state_write(struct smp_streamer *ctxt) } } - if (slot == IMG_MGMT_BOOT_CURR_SLOT && confirm) { + if (slot == img_mgmt_active_slot() && confirm) { /* Confirm current setup. */ rc = img_mgmt_state_confirm(); } else { From 982d29e522c69d3eda21143a72ec25fcf8893d18 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 6 Apr 2023 13:38:03 +0000 Subject: [PATCH 036/528] [nrf fromlist] mgmt/mcumgr: Use boot_set_next to set image for test or confirm The commit adds img_mgmt_set_boot_next function which uses boot_set_next MCUboot/bootutil function to set application slot for next boot. The img_mgmt_set_boot_next is intended to replace img_mgmt_state_confirm and img_mgmt_state_set_pending. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56725 Signed-off-by: Dominik Ermel (cherry picked from commit 4810c10ff05dd1cdfc2b44c2024cc6af5d8d755b) --- .../mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h | 3 +- .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 60 ++++++++++++++++--- .../mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 2 +- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h b/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h index 2aac063eae32..57ed3854f0be 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022 Nordic Semiconductor ASA + * Copyright (c) 2022-2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -141,6 +141,7 @@ int img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver); int img_mgmt_find_by_ver(struct image_version *find, uint8_t *hash); int img_mgmt_state_read(struct smp_streamer *ctxt); int img_mgmt_state_write(struct smp_streamer *njb); +int img_mgmt_flash_area_id(int slot); #ifdef __cplusplus } diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 6f7750c68a09..a006e2899750 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -7,13 +7,15 @@ #include #include -#include #include +#include #include #include #include +#include + #include #include #include @@ -27,6 +29,8 @@ #include #endif +LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); + /* The value here sets how many "characteristics" that describe image is * encoded into a map per each image (like bootable flags, and so on). * This value is only used for zcbor to predict map size and map encoding @@ -265,6 +269,53 @@ img_mgmt_state_read(struct smp_streamer *ctxt) return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; } +int img_mgmt_set_boot_next(int slot, bool confirm) +{ + const struct flash_area *fa; + int area_id = img_mgmt_flash_area_id(slot); + int rc = 0; + bool active = (slot == img_mgmt_active_slot(img_mgmt_active_image())); + + if (active) { + confirm = true; + } else { + if (slot != 1 && + !(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 && slot == 3)) { + return MGMT_ERR_EINVAL; + } + } + + /* Confirm disallowed if a test is pending. */ + if (active && img_mgmt_state_any_pending()) { + return MGMT_ERR_EBADSTATE; + } + + if (flash_area_open(area_id, &fa) != 0) { + return MGMT_ERR_EUNKNOWN; + } + + rc = boot_set_next(fa, active, confirm); + if (rc != 0) { + /* Failed to set next slot for boot as desired */ + if (active) { + LOG_ERR("Failed to write confirmed flag: %d", rc); + } else { + LOG_ERR("Failed to write pending flag for slot %d: %d", slot, rc); + } + rc = MGMT_ERR_EUNKNOWN; + } + flash_area_close(fa); + +#if CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS + if (active) { + /* Confirm event is only sent for active slot */ + (void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED, NULL, 0); + } +#endif + + return rc; +} + /** * Command handler: image state write */ @@ -316,12 +367,7 @@ img_mgmt_state_write(struct smp_streamer *ctxt) } } - if (slot == img_mgmt_active_slot() && confirm) { - /* Confirm current setup. */ - rc = img_mgmt_state_confirm(); - } else { - rc = img_mgmt_state_set_pending(slot, confirm); - } + rc = img_mgmt_set_boot_next(slot, confirm); if (rc != 0) { return rc; } diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index c62ee53b4378..81bdf56dc9e8 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -152,7 +152,7 @@ static int img_mgmt_flash_check_empty(uint8_t fa_id) * image_2 and so on. The function treats slot numbers as absolute * slot number starting at 0. */ -static int +int img_mgmt_flash_area_id(int slot) { uint8_t fa_id; From fac25b2b5d404ddc863daebd963af0a07cd85319 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 25 Apr 2023 16:34:48 +0000 Subject: [PATCH 037/528] [nrf fromtree] mgmt/mcumgr: Fix image erase returning MGMT_ERR_EMSGSIZE In case when CONFIG_MCUMGR_SMP_LEGACY_RC_BEHAVIOUR=n then the image erase command would incorrectly return MGMT_ERR_EMSGSIZE, even though no such error occurred. (cherry picked from commit 00f1639e389e56f561e5c30d17c7567a3ab15f8b) Signed-off-by: Dominik Ermel (cherry picked from commit 70e3114517ab0a4253ac39503b0fffbd7bbd20eb) --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 292d275ce958..73f96eaf8b58 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -319,7 +319,6 @@ img_mgmt_erase(struct smp_streamer *ctxt) struct image_version ver; int rc; zcbor_state_t *zsd = ctxt->reader->zs; - zcbor_state_t *zse = ctxt->writer->zs; bool ok; uint32_t slot = img_mgmt_get_other_slot(); size_t decoded = 0; @@ -359,12 +358,15 @@ img_mgmt_erase(struct smp_streamer *ctxt) return rc; } - if (IS_ENABLED(CONFIG_MCUMGR_SMP_LEGACY_RC_BEHAVIOUR) && zcbor_tstr_put_lit(zse, "rc") && - zcbor_int32_put(zse, 0)) { - return MGMT_ERR_EOK; + if (IS_ENABLED(CONFIG_MCUMGR_SMP_LEGACY_RC_BEHAVIOUR)) { + zcbor_state_t *zse = ctxt->writer->zs; + + if (!zcbor_tstr_put_lit(zse, "rc") || !zcbor_int32_put(zse, 0)) { + return MGMT_ERR_EMSGSIZE; + } } - return MGMT_ERR_EMSGSIZE; + return MGMT_ERR_EOK; } static int From 420241edec7a2e1314ed04f636fd62f1e16fd9dc Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Wed, 26 Apr 2023 09:38:49 +0200 Subject: [PATCH 038/528] [nrf fromtree] manifest: openthread: Regular openthread upmerge to `2594291` Bumping version of openthread and rename of `OT_MTD_NETDIAG` to `OT_NETDIAG_CLIENT` Signed-off-by: Przemyslaw Bida (cherry picked from commit de20ba88698dbd20d09e805e4b9fd9674ff4d639) (cherry picked from commit ebd08e6aef0d51db9ca4863d466d9b641cc86577) --- modules/openthread/CMakeLists.txt | 12 ++++++------ modules/openthread/Kconfig.features | 6 +++--- west.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 3c428b999a57..a263e2256082 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -316,12 +316,6 @@ else() set(OT_MLR OFF CACHE BOOL "Enable Multicast Listener Registration feature for Thread 1.2" FORCE) endif() -if(CONFIG_OPENTHREAD_MTD_NETDIAG) - set(OT_MTD_NETDIAG ON CACHE BOOL "Enable TMF network diagnostics on MTDs" FORCE) -else() - set(OT_MTD_NETDIAG OFF CACHE BOOL "Enable TMF network diagnostics on MTDs" FORCE) -endif() - if(CONFIG_OPENTHREAD_MULTIPLE_INSTANCE) set(OT_MULTIPLE_INSTANCE ON CACHE BOOL "Enable multiple instances" FORCE) else() @@ -346,6 +340,12 @@ else() set(OT_NEIGHBOR_DISCOVERY_AGENT OFF CACHE BOOL "Enable neighbor discovery agent support" FORCE) endif() +if(CONFIG_OPENTHREAD_NETDIAG_CLIENT) + set(OT_NETDIAG_CLIENT ON CACHE BOOL "Enable TMF network diagnostics on clients" FORCE) +else() + set(OT_NETDIAG_CLIENT OFF CACHE BOOL "Enable TMF network diagnostics on clients" FORCE) +endif() + if(CONFIG_OPENTHREAD_NETDATA_PUBLISHER) set(OT_NETDATA_PUBLISHER ON CACHE BOOL "Enable Thread Network Data publisher" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index ce531ad2abe9..a57de4b31c16 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -193,9 +193,6 @@ config OPENTHREAD_MLR help Enable Multicast Listener Registration support for Thread 1.2 -config OPENTHREAD_MTD_NETDIAG - bool "TMF network diagnostics on MTDs" - config OPENTHREAD_MULTIPLE_INSTANCE bool "OpenThread multiple instances" @@ -205,6 +202,9 @@ config OPENTHREAD_NAT64_BORDER_ROUTING config OPENTHREAD_NAT64_TRANSLATOR bool "NAT64 translator support" +config OPENTHREAD_NETDIAG_CLIENT + bool "TMF network diagnostics on client" + config OPENTHREAD_NEIGHBOR_DISCOVERY_AGENT bool "Neighbor discovery agent support" diff --git a/west.yml b/west.yml index f228a5db7984..a984ab9acfc5 100644 --- a/west.yml +++ b/west.yml @@ -203,7 +203,7 @@ manifest: revision: aedcc262f93bbb1b0c2f58026911575729b7465c path: modules/lib/open-amp - name: openthread - revision: 7bdcf8a5d49838ce6e3e227e2780e4f12c461330 + revision: 25942910ab57b32f73d9c56d8c6cf07c7cf98c49 path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From 2cdb33462b5c0169d18d5c32b44a053cbb918669 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 17 Apr 2023 18:03:56 +0200 Subject: [PATCH 039/528] [nrf fromtree] Bluetooth: BAP: Add guard of BIS specific CC data The data can only be used if CONFIG_BT_CODEC_MAX_DATA_COUNT is non-0. Signed-off-by: Emil Gydesen (cherry picked from commit da9096c10308957958714755eed4a80c30585d57) (cherry picked from commit 2a5335ef6238fa409e1e94e501593f85acb7b32f) --- include/zephyr/bluetooth/audio/bap.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 7badeb955e9f..7379275266a7 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -1327,6 +1327,7 @@ struct bt_bap_broadcast_source_stream_param { /** Audio stream */ struct bt_bap_stream *stream; +#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 /** * @brief The number of elements in the @p data array. * @@ -1336,6 +1337,7 @@ struct bt_bap_broadcast_source_stream_param { /** BIS Codec Specific Configuration */ struct bt_codec_data *data; +#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */ }; /** Broadcast Source subgroup parameters*/ From 99facf30f40d3d864ede649a60e8916da786d5c9 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Wed, 12 Apr 2023 16:29:29 +0200 Subject: [PATCH 040/528] [nrf fromtree] Bluetooth: BAP: Add missing Broadcast source param checks Several input parameter checks were missing in the BAP broadcast source API. Signed-off-by: Emil Gydesen (cherry picked from commit fa95a7add2004f7277b7e061a62095aa64fb9d52) (cherry picked from commit 3413947ff0f6921b2f559f8d9d9e923139a29f5f) --- subsys/bluetooth/audio/bap_broadcast_source.c | 88 ++++++++++++++++++- subsys/bluetooth/audio/bap_stream.c | 56 ++++++++++++ subsys/bluetooth/audio/bap_stream.h | 2 + 3 files changed, 142 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index 21f2d41248b9..248b5d979ec0 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -545,18 +545,40 @@ static bool valid_create_param(const struct bt_bap_broadcast_source_create_param return false; } + CHECKIF(param->qos->rtn > BT_ISO_BROADCAST_RTN_MAX) { + LOG_DBG("param->qos->rtn %u invalid", param->qos->rtn); + return false; + } + + CHECKIF(param->params == NULL) { + LOG_DBG("param->params is NULL"); + return false; + } + + CHECKIF(param->params_count == 0) { + LOG_DBG("param->params_count is 0"); + return false; + } + for (size_t i = 0U; i < param->params_count; i++) { const struct bt_bap_broadcast_source_subgroup_param *subgroup_param; subgroup_param = ¶m->params[i]; - CHECKIF(subgroup_param->params_count == 0U) { - LOG_DBG("subgroup_params[%zu].count is 0", i); + CHECKIF(subgroup_param->params == NULL) { + LOG_DBG("subgroup_params[%zu].params is NULL", i); return false; } - CHECKIF(subgroup_param->codec == NULL) { - LOG_DBG("subgroup_params[%zu].codec is NULL", i); + CHECKIF(!IN_RANGE(subgroup_param->params_count, 1U, + CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT)) { + LOG_DBG("subgroup_params[%zu].count (%zu) is invalid", i, + subgroup_param->params_count); + return false; + } + + CHECKIF(!bt_audio_valid_codec(subgroup_param->codec)) { + LOG_DBG("subgroup_params[%zu].codec is invalid", i); return false; } @@ -577,7 +599,34 @@ static bool valid_create_param(const struct bt_bap_broadcast_source_create_param i, j, stream_param->stream->group); return false; } + + CHECKIF(stream_param->data == NULL && stream_param->data_count != 0) { + LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data is " + "NULL with count %zu", + i, j, stream_param->data_count); + return false; + } + +#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 + CHECKIF(stream_param->data_count > CONFIG_BT_CODEC_MAX_DATA_COUNT) { + LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data_count too " + "large: %zu/%d", + i, j, stream_param->data_count, + CONFIG_BT_CODEC_MAX_DATA_COUNT); + return false; + } + + for (size_t k = 0U; k < stream_param->data_count; k++) { + CHECKIF(!(bt_audio_valid_codec_data(&stream_param->data[k]))) { + LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data[%zu]" + " invalid", + i, j, k); + + return false; + } + } } +#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */ } return true; @@ -631,6 +680,7 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param * LOG_DBG("out_source is NULL"); return -EINVAL; } + /* Set out_source to NULL until the source has actually been created */ *out_source = NULL; @@ -755,6 +805,26 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, str return -EINVAL; } + CHECKIF(!bt_audio_valid_codec(codec)) { + LOG_DBG("codec is invalid"); + return -EINVAL; + } + + CHECKIF(qos == NULL) { + LOG_DBG("qos is NULL"); + return -EINVAL; + } + + CHECKIF(bt_audio_verify_qos(qos) != BT_BAP_ASCS_REASON_NONE) { + LOG_DBG("qos is invalid"); + return -EINVAL; + } + + CHECKIF(qos->rtn > BT_ISO_BROADCAST_RTN_MAX) { + LOG_DBG("qos->rtn %u invalid", qos->rtn); + return -EINVAL; + } + broadcast_state = broadcast_source_get_state(source); if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_QOS_CONFIGURED) { LOG_DBG("Broadcast source invalid state: %u", broadcast_state); @@ -987,6 +1057,16 @@ int bt_bap_broadcast_source_get_id(const struct bt_bap_broadcast_source *source, int bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source *source, struct net_buf_simple *base_buf) { + CHECKIF(source == NULL) { + LOG_DBG("source is NULL"); + return -EINVAL; + } + + CHECKIF(base_buf == NULL) { + LOG_DBG("base_buf is NULL"); + return -EINVAL; + } + if (!encode_base(source, base_buf)) { LOG_DBG("base_buf %p with size %u not large enough", base_buf, base_buf->size); diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index bdb8b3bff090..2be984607384 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -167,9 +167,65 @@ enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos) return BT_BAP_ASCS_REASON_LATENCY; } + if (qos->pd > BT_AUDIO_PD_MAX) { + LOG_DBG("Invalid presentation delay %u", qos->pd); + return BT_BAP_ASCS_REASON_PD; + } + return BT_BAP_ASCS_REASON_NONE; } +#if CONFIG_BT_CODEC_MAX_DATA_LEN > 0 +bool bt_audio_valid_codec_data(const struct bt_codec_data *data) +{ + if (data->data.data_len > ARRAY_SIZE(data->value)) { + LOG_DBG("data invalid length: %zu/%zu", data->data.data_len, + ARRAY_SIZE(data->value)); + return false; + } + + return true; +} +#endif /* CONFIG_BT_CODEC_MAX_DATA_LEN > 0 */ + +bool bt_audio_valid_codec(const struct bt_codec *codec) +{ + if (codec == NULL) { + LOG_DBG("codec is NULL"); + return false; + } + +#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 + if (codec->data_count > CONFIG_BT_CODEC_MAX_DATA_COUNT) { + LOG_DBG("codec->data_count (%zu) is invalid", codec->data_count); + return false; + } + + for (size_t i = 0U; i < codec->data_count; i++) { + if (!bt_audio_valid_codec_data(&codec->data[i])) { + LOG_DBG("codec->data[%zu] invalid", i); + return false; + } + } +#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */ + +#if CONFIG_BT_CODEC_MAX_METADATA_COUNT > 0 + if (codec->meta_count > CONFIG_BT_CODEC_MAX_METADATA_COUNT) { + LOG_DBG("codec->meta_count (%zu) is invalid", codec->meta_count); + return false; + } + + for (size_t i = 0U; i < codec->meta_count; i++) { + if (!bt_audio_valid_codec_data(&codec->meta[i])) { + LOG_DBG("codec->meta[%zu] invalid", i); + return false; + } + } +#endif /* CONFIG_BT_CODEC_MAX_METADATA_COUNT > 0 */ + + return true; +} + int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, uint16_t seq_num, uint32_t ts) { diff --git a/subsys/bluetooth/audio/bap_stream.h b/subsys/bluetooth/audio/bap_stream.h index 378b8dbcc88f..f2074932f162 100644 --- a/subsys/bluetooth/audio/bap_stream.h +++ b/subsys/bluetooth/audio/bap_stream.h @@ -25,6 +25,8 @@ void bt_audio_codec_qos_to_iso_qos(struct bt_iso_chan_io_qos *io, void bt_bap_stream_detach(struct bt_bap_stream *stream); enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos); +bool bt_audio_valid_codec_data(const struct bt_codec_data *data); +bool bt_audio_valid_codec(const struct bt_codec *codec); enum bt_bap_ascs_reason bt_bap_stream_verify_qos(const struct bt_bap_stream *stream, const struct bt_codec_qos *qos); From 9a1e63d3004d7ca2e76e5289c6a5d19f6d23853e Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 24 Apr 2023 09:55:58 +0200 Subject: [PATCH 041/528] [nrf fromtree] Bluetooth: BAP: Move TX guard to not cover verify funcs Move the BT_AUDIO_TX guard so that it does not cover the verification functions for valid_codec and qos, as they are also relevant for receivers to verify what remote devices send. Signed-off-by: Emil Gydesen (cherry picked from commit 32e8392400ce46dcea60300fefe562fb5fc3af85) (cherry picked from commit cdf9c232761662e26e138b28373438704fa72e9f) --- subsys/bluetooth/audio/bap_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 2be984607384..b2de44830334 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -134,7 +134,6 @@ int bt_bap_ep_get_info(const struct bt_bap_ep *ep, struct bt_bap_ep_info *info) return 0; } -#if defined(CONFIG_BT_AUDIO_TX) enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos) { if (qos->interval < BT_ISO_SDU_INTERVAL_MIN || @@ -226,6 +225,7 @@ bool bt_audio_valid_codec(const struct bt_codec *codec) return true; } +#if defined(CONFIG_BT_AUDIO_TX) int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, uint16_t seq_num, uint32_t ts) { From 99f0de8ca2d681b5c6e11080ba45e867f4d7a634 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 24 Apr 2023 10:13:01 +0200 Subject: [PATCH 042/528] [nrf fromtree] Bluetooth: BAP: Add guard before accessing qos->latency The qos->latency is not available for broadcast sink-only builds. Signed-off-by: Emil Gydesen (cherry picked from commit 2c5a249fdd4252f8a4e869da3f5605f8e3841385) (cherry picked from commit 0b3a45379733891451a02a2977f7320f1ca51abd) --- subsys/bluetooth/audio/bap_stream.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index b2de44830334..9dd32a8dc76a 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -160,11 +160,13 @@ enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos) return BT_BAP_ASCS_REASON_SDU; } +#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_UNICAST) if (qos->latency < BT_ISO_LATENCY_MIN || qos->latency > BT_ISO_LATENCY_MAX) { LOG_DBG("Invalid Latency %u", qos->latency); return BT_BAP_ASCS_REASON_LATENCY; } +#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_UNICAST */ if (qos->pd > BT_AUDIO_PD_MAX) { LOG_DBG("Invalid presentation delay %u", qos->pd); From 62c50cbf56b1b802cb2f6f14c9e7adcdcfcf1939 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 24 Apr 2023 10:17:12 +0200 Subject: [PATCH 043/528] [nrf fromtree] Bluetooth: Shell: Add testcases for AUDIO_RX and TX disabled Add configurations where CONFIG_BT_AUDIO_TX and CONFIG_BT_AUDIO_RX are disabled. Fixes issues found in the BT shell implemented caused by these configurations. Signed-off-by: Emil Gydesen (cherry picked from commit 303bcfdcb70f99b7bc1d62eafdbd046d37004780) (cherry picked from commit 8276e946b8714e167ea88bb0248a30f50b01e19f) --- subsys/bluetooth/audio/shell/bap.c | 22 +++++++++++++++------- tests/bluetooth/shell/testcase.yaml | 16 ++++++++++++++++ 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index e895ecfda0c7..d7676a3ec9bf 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -61,10 +61,7 @@ static struct bt_codec_qos broadcast_source_qos; static struct bt_bap_stream broadcast_sink_streams[BROADCAST_SNK_STREAM_CNT]; static struct bt_bap_broadcast_sink *default_sink; #endif /* CONFIG_BT_BAP_BROADCAST_SINK */ -static struct bt_bap_stream *txing_stream; static struct bt_bap_stream *default_stream; -static uint16_t seq_num; -static size_t rx_cnt; static const struct named_lc3_preset lc3_unicast_presets[] = { {"8_1_1", BT_BAP_LC3_UNICAST_PRESET_8_1_1(LOCATION, CONTEXT)}, @@ -144,6 +141,10 @@ const struct named_lc3_preset *default_source_preset = &lc3_unicast_presets[3]; static const struct named_lc3_preset *default_broadcast_source_preset = &lc3_broadcast_presets[3]; static bool initialized; +#if defined(CONFIG_BT_AUDIO_TX) +static struct bt_bap_stream *txing_stream; +static uint16_t seq_num; + static uint16_t get_next_seq_num(uint32_t interval_us) { static int64_t last_ticks; @@ -165,8 +166,9 @@ static uint16_t get_next_seq_num(uint32_t interval_us) return (uint16_t)next_seq_num; } +#endif /* CONFIG_BT_AUDIO_TX */ -#if defined(CONFIG_LIBLC3) +#if defined(CONFIG_LIBLC3) && defined(CONFIG_BT_AUDIO_TX) NET_BUF_POOL_FIXED_DEFINE(sine_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, CONFIG_BT_ISO_TX_MTU + BT_ISO_CHAN_SEND_RESERVE, 8, NULL); @@ -363,7 +365,7 @@ static void lc3_audio_timer_timeout(struct k_work *work) } static K_WORK_DELAYABLE_DEFINE(audio_send_work, lc3_audio_timer_timeout); -#endif /* CONFIG_LIBLC3 */ +#endif /* CONFIG_LIBLC3 && CONFIG_BT_AUDIO_TX */ static void print_codec(const struct bt_codec *codec) { @@ -534,7 +536,9 @@ static int lc3_start(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp) { shell_print(ctx_shell, "Start: stream %p", stream); +#if defined(CONFIG_BT_AUDIO_TX) seq_num = 0; +#endif /* CONFIG_BT_AUDIO_TX */ return 0; } @@ -1725,6 +1729,7 @@ static void audio_recv(struct bt_bap_stream *stream, struct net_buf *buf) { static struct bt_iso_recv_info last_info; + static size_t rx_cnt; /* TODO: Make it possible to only print every X packets, and make X settable by the shell */ if ((rx_cnt % 100) == 0) { @@ -2380,6 +2385,7 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[]) return 0; } +#if defined(CONFIG_BT_AUDIO_TX) #define DATA_MTU CONFIG_BT_ISO_TX_MTU NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, DATA_MTU, 8, NULL); @@ -2486,6 +2492,7 @@ static int cmd_stop_sine(const struct shell *sh, size_t argc, char *argv[]) return 0; } #endif /* CONFIG_LIBLC3 */ +#endif /* CONFIG_BT_AUDIO_TX */ #if defined(CONFIG_BT_BAP_UNICAST_SERVER) static void print_ase_info(struct bt_bap_ep *ep, void *user_data) @@ -2550,16 +2557,17 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(start, NULL, NULL, cmd_start, 1, 0), SHELL_CMD_ARG(disable, NULL, NULL, cmd_disable, 1, 0), SHELL_CMD_ARG(release, NULL, NULL, cmd_release, 1, 0), - SHELL_CMD_ARG(select_unicast, NULL, "", - cmd_select_unicast, 2, 0), + SHELL_CMD_ARG(select_unicast, NULL, "", cmd_select_unicast, 2, 0), #endif /* CONFIG_BT_BAP_UNICAST */ SHELL_CMD_ARG(preset, NULL, " [preset]", cmd_preset, 2, 1), +#if defined(CONFIG_BT_AUDIO_TX) SHELL_CMD_ARG(send, NULL, "Send to Audio Stream [data]", cmd_send, 1, 1), #if defined(CONFIG_LIBLC3) SHELL_CMD_ARG(start_sine, NULL, "Start sending a LC3 encoded sine wave", cmd_start_sine, 1, 0), SHELL_CMD_ARG(stop_sine, NULL, "Stop sending a LC3 encoded sine wave", cmd_stop_sine, 1, 0), #endif /* CONFIG_LIBLC3 */ +#endif /* CONFIG_BT_AUDIO_TX */ SHELL_COND_CMD_ARG(CONFIG_BT_PACS, set_location, NULL, " ", cmd_set_loc, 3, 0), SHELL_COND_CMD_ARG(CONFIG_BT_PACS, set_context, NULL, diff --git a/tests/bluetooth/shell/testcase.yaml b/tests/bluetooth/shell/testcase.yaml index 7f8419700b91..642e3388f621 100644 --- a/tests/bluetooth/shell/testcase.yaml +++ b/tests/bluetooth/shell/testcase.yaml @@ -237,6 +237,22 @@ tests: platform_allow: native_posix extra_configs: - CONFIG_BT_BAP_BROADCAST_SINK=n + bluetooth.audio_shell.no_audio_tx: + extra_args: CONF_FILE="audio.conf" + build_only: true + platform_allow: native_posix + extra_configs: + - CONFIG_BT_BAP_BROADCAST_SOURCE=n + - CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=0 + - CONFIG_BT_ASCS_ASE_SRC_COUNT=0 + bluetooth.audio_shell.no_audio_rx: + extra_args: CONF_FILE="audio.conf" + build_only: true + platform_allow: native_posix + extra_configs: + - CONFIG_BT_BAP_BROADCAST_SINK=n + - CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=0 + - CONFIG_BT_ASCS_ASE_SNK_COUNT=0 bluetooth.audio_shell.no_has: extra_args: CONF_FILE="audio.conf" build_only: true From cfe7e71c632a1d41ca0b97d9def36590d2003aed Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Thu, 27 Apr 2023 09:54:36 +0200 Subject: [PATCH 044/528] [nrf fromtree] Bluetooth: BAP: Fix missing remove of streams from slist In the broadcast sink when the streams disconnected (without the PA disconnecting), the streams were not properly removed from the sink's list of streams. This allowed the same stream to be added to the list twice, which would cause a infinite loop as the stream would point to itself as the next. Signed-off-by: Emil Gydesen (cherry picked from commit 5076476cf52b315502f7c046df8fe109a795b631) (cherry picked from commit 9600b80f8390e70ad9975c0b3acfa9180b9ac06f) --- subsys/bluetooth/audio/bap_broadcast_sink.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 6c9fb4c815d4..65b9a0b2fab0 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -347,7 +347,6 @@ static void broadcast_sink_iso_disconnected(struct bt_iso_chan *chan, struct bt_bap_stream *stream; struct bt_bap_ep *ep = iso->rx.ep; struct bt_bap_broadcast_sink *sink; - bool all_disconnected; if (ep == NULL) { LOG_ERR("iso %p not bound with ep", chan); @@ -378,17 +377,12 @@ static void broadcast_sink_iso_disconnected(struct bt_iso_chan *chan, return; } - all_disconnected = true; - SYS_SLIST_FOR_EACH_CONTAINER(&sink->streams, stream, _node) { - /* stream->ep is cleared when the steam disconnects */ - if (stream->ep != NULL) { - all_disconnected = false; - break; - } + if (!sys_slist_find_and_remove(&sink->streams, &stream->_node)) { + LOG_DBG("Could not find and remove stream %p from sink %p", stream, sink); } /* Clear sink->big if not already cleared */ - if (all_disconnected && sink->big) { + if (sys_slist_is_empty(&sink->streams) && sink->big) { broadcast_sink_clear_big(sink, reason); } } From f51a134c9a66c6082c14fccead2fb03413f022ce Mon Sep 17 00:00:00 2001 From: Krishna T Date: Thu, 20 Apr 2023 16:26:26 +0530 Subject: [PATCH 045/528] [nrf fromtree] net: wifi: Fix backward compatibility Changing this enumeration breaks backward compatibility with Wi-Fi shell as we rely on these values to decide the Wi-Fi security. Add them at the end to fix backward compatibility. Signed-off-by: Krishna T (cherry picked from commit f7dbc59e04d37f5c40337656a21afaa65f26103b) (cherry picked from commit b54c8baeeafb3d6e9eef6092c5d88a6771548460) --- include/zephyr/net/wifi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 0ec71c56b5e8..eb9270042c22 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -19,13 +19,13 @@ */ enum wifi_security_type { WIFI_SECURITY_TYPE_NONE = 0, - WIFI_SECURITY_TYPE_WEP, - WIFI_SECURITY_TYPE_WPA_PSK, WIFI_SECURITY_TYPE_PSK, WIFI_SECURITY_TYPE_PSK_SHA256, WIFI_SECURITY_TYPE_SAE, WIFI_SECURITY_TYPE_WAPI, WIFI_SECURITY_TYPE_EAP, + WIFI_SECURITY_TYPE_WEP, + WIFI_SECURITY_TYPE_WPA_PSK, __WIFI_SECURITY_TYPE_AFTER_LAST, WIFI_SECURITY_TYPE_MAX = __WIFI_SECURITY_TYPE_AFTER_LAST - 1, From 885b316642588ffe6fa9ef9aeae7a13090bde4c4 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Wed, 26 Apr 2023 11:28:45 +0000 Subject: [PATCH 046/528] [nrf fromtree] west.yaml: MCUboot synchronization from upstream Update Zephyr fork of MCUboot to revision: 1558e7ab0aadb4eac11f03befb5ccd3fa3f0aafe Brings following Zephyr relevant fixes: - 1558e7ab boot: zephyr: remove stm32 watchdog defines - 4420bb66 boot: zephyr: setup watchdog - 393af79e boot_serial: Update zcbor files from zcbor 0.7.0 - a95a41b3 boot: bootutil: loader: Let image version comparison use build number - f7d8660e boot_serial: Fix include paths for zephyr builds - c7835371 bootutil: Add FIH for ED25519 sig verification - 186ac885 bootutil: Fix FIH return type for EC256 - 5397c13d zephyr: serial_recovery: Fix broken CDC device selection - 918da26a bootutil: Provide boot_set_next function (cherry picked from commit af2576a127c27e3a715605be53339c3cadca5243) Signed-off-by: Dominik Ermel (cherry picked from commit efb5295ab8e2897bcd3a8feb3e1ee8a2fee98ba5) --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a984ab9acfc5..efeb1f8bd159 100644 --- a/west.yml +++ b/west.yml @@ -181,7 +181,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 6902abba270c0fbcbe8ee3bb56fe39bc9acc2774 + revision: 1558e7ab0aadb4eac11f03befb5ccd3fa3f0aafe path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From c07ed8f4501e565e5b6b4ab3e61d2ba556c9b78f Mon Sep 17 00:00:00 2001 From: Piotr Kosycarz Date: Fri, 21 Apr 2023 14:09:10 +0200 Subject: [PATCH 047/528] [nrf fromtree] twister: add options to shuffle tests across subsets Add option to shuffle tests (randomly) before they are split into subsets. This allow to fairly distribute tests across subsets, so that long tests are not crowded in a single group. This also allows to detect unwanted dependencies in test execution order. Also, added option to provide custom seed to random generator used to shuffle tests. This will allow to reproduce certain test order if needed. Used seed is printed at console. Signed-off-by: Piotr Kosycarz (cherry picked from 7892f40a528028503f5b8f08d0a8dac9255b7c27) (cherry picked from commit 4b5d5aa9ca8c414338f91f0c27f0e8426d2a6da0) --- .../pylib/twister/twisterlib/environment.py | 19 +++++++++++++++++++ scripts/pylib/twister/twisterlib/testplan.py | 12 ++++++++++++ 2 files changed, 31 insertions(+) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 028c42b5f57d..318a0449f1c4 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -247,6 +247,17 @@ def add_parse_arguments(parser = None): "This option is useful when running a large number of tests on " "different hosts to speed up execution time.") + parser.add_argument( + "--shuffle-tests", action="store_true", default=None, + help="""Shuffle test execution order to get randomly distributed tests across subsets. + Used only when --subset is provided.""") + + parser.add_argument( + "--shuffle-tests-seed", action="store", default=None, + help="""Seed value for random generator used to shuffle tests. + If not provided, seed in generated by system. + Used only when --shuffle-tests is provided.""") + parser.add_argument("-C", "--coverage", action="store_true", help="Generate coverage reports. Implies " "--enable-coverage.") @@ -698,6 +709,14 @@ def parse_arguments(parser, args, options = None): logger.error("--device-flash-with-test requires --device-testing") sys.exit(1) + if options.shuffle_tests and options.subset is None: + logger.error("--shuffle-tests requires --subset") + sys.exit(1) + + if options.shuffle_tests_seed and options.shuffle_tests is None: + logger.error("--shuffle-tests-seed requires --shuffle-tests") + sys.exit(1) + if options.coverage_formats and (options.coverage_tool != "gcovr"): logger.error("""--coverage-formats can only be used when coverage tool is set to gcovr""") diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index ad2486e4b0db..3dffbc21213d 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -15,6 +15,7 @@ import logging import copy import shutil +import random logger = logging.getLogger('twister') logger.setLevel(logging.DEBUG) @@ -251,6 +252,17 @@ def generate_subset(self, subset, sets): else: self.instances = OrderedDict(sorted(self.instances.items())) + if self.options.shuffle_tests: + seed_value = int.from_bytes(os.urandom(8), byteorder="big") + if self.options.shuffle_tests_seed is not None: + seed_value = self.options.shuffle_tests_seed + + logger.info(f"Shuffle tests with seed: {seed_value}") + random.seed(seed_value) + temp_list = list(self.instances.items()) + random.shuffle(temp_list) + self.instances = OrderedDict(temp_list) + # Do calculation based on what is actually going to be run and evaluated # at runtime, ignore the cases we already know going to be skipped. # This fixes an issue where some sets would get majority of skips and From 6e436e015ca26840add95eac4df926f2492cf97c Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Fri, 5 May 2023 13:34:05 +0200 Subject: [PATCH 048/528] [nrf fromtree] twister: Bring back scope selection rule using platform_allow A change to the scope selection rules was introduced by #52715 but it doesn't comply with the description in the code. What's more, the change introduces major issues i.e. non deterministic scope selection, especially in a CI environment. More context at #57595 (cherry picked from commit 3bf7f83f213f96daa9a17cd3ddd4cff0a200bb9d) Signed-off-by: Maciej Perkowski (cherry picked from commit f405f78fea3e474468176ba4923382895ab20ac0) --- scripts/pylib/twister/twisterlib/testplan.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 3dffbc21213d..3b56f2da00c2 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -685,10 +685,8 @@ def apply_filters(self, **kwargs): b = set(filter(lambda item: item.name in ts.platform_allow, self.platforms)) c = a.intersection(b) if not c: - _platform_scope = list(filter(lambda item: item.name in ts.platform_allow, \ + platform_scope = list(filter(lambda item: item.name in ts.platform_allow, \ self.platforms)) - if len(_platform_scope) > 0: - platform_scope = _platform_scope[:1] # list of instances per testsuite, aka configurations. From 35460d14d9f39ec81aedac076a2c7315a64e0b49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Jasi=C5=84ski?= Date: Thu, 4 May 2023 12:29:02 +0200 Subject: [PATCH 049/528] [nrf fromtree] net: update tfm dependency for psa MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TFM is not the only provider for PSA API, which means the PSA config shouldn't depend only on it. Signed-off-by: Piotr Jasiński (cherry picked from commit e010dcee5d7c582dbfd1e197f53c777ac640f362) (cherry picked from commit 66a1410a8f8dcc1684774d7ea3a6778097638da8) --- subsys/net/l2/openthread/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/openthread/Kconfig b/subsys/net/l2/openthread/Kconfig index 51cb0c2cceb3..f8803b316de1 100644 --- a/subsys/net/l2/openthread/Kconfig +++ b/subsys/net/l2/openthread/Kconfig @@ -316,7 +316,7 @@ config OPENTHREAD_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE config OPENTHREAD_CRYPTO_PSA bool "ARM PSA crypto API" - depends on BUILD_WITH_TFM + depends on MBEDTLS_PSA_CRYPTO_C || BUILD_WITH_TFM select OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE select OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE help From 946db8886691802b8700c332334d3e47ec504b91 Mon Sep 17 00:00:00 2001 From: Krishna T Date: Fri, 28 Apr 2023 01:46:16 +0530 Subject: [PATCH 050/528] [nrf fromtree] net: Make net_mgmt queue timeout configurable This helps us work with low queue depth of network management queue in case the we have high rate events. Fixes https://github.com/zephyrproject-rtos/zephyr/issues/56595 . Signed-off-by: Krishna T (cherry picked from commit 30efd04060579e97b6b9967a1d06cd971e72cd5b) (cherry picked from commit 4c765eaad4953cf08c7bf2b1fc3cbff7383d05ff) --- subsys/net/ip/Kconfig.mgmt | 8 ++++++++ subsys/net/ip/net_mgmt.c | 6 ++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/subsys/net/ip/Kconfig.mgmt b/subsys/net/ip/Kconfig.mgmt index 8166f4315ae1..281d38c7a488 100644 --- a/subsys/net/ip/Kconfig.mgmt +++ b/subsys/net/ip/Kconfig.mgmt @@ -38,6 +38,14 @@ config NET_MGMT_EVENT_QUEUE_SIZE notification. Thus the size of this queue has to be tweaked depending on the load of the system, planned for the usage. +config NET_MGMT_EVENT_QUEUE_TIMEOUT + int "Timeout for event queue" + default 10 + range 1 10000 + help + Timeout in milliseconds for the event queue. This timeout is used to + wait for the queue to be available. + config NET_MGMT_EVENT_INFO bool "Passing information along with an event" help diff --git a/subsys/net/ip/net_mgmt.c b/subsys/net/ip/net_mgmt.c index 4fc0ea1c7274..94dac5ef6efe 100644 --- a/subsys/net/ip/net_mgmt.c +++ b/subsys/net/ip/net_mgmt.c @@ -79,9 +79,11 @@ static inline void mgmt_push_event(uint32_t mgmt_event, struct net_if *iface, new_event.event = mgmt_event; new_event.iface = iface; - if (k_msgq_put(&event_msgq, &new_event, K_MSEC(10)) != 0) { + if (k_msgq_put(&event_msgq, &new_event, + K_MSEC(CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT)) != 0) { NET_WARN("Failure to push event (%u), " - "try increasing the 'CONFIG_NET_MGMT_EVENT_QUEUE_SIZE'", + "try increasing the 'CONFIG_NET_MGMT_EVENT_QUEUE_SIZE' " + "or 'CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT' options.", mgmt_event); } From 77991d31c48e4fba925fd3c853dd19fdc8ee0bd5 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Thu, 30 Mar 2023 13:12:49 +0200 Subject: [PATCH 051/528] [nrf fromtree] Bluetooth: Host: Add support for PAwR Advertiser Adds API for Periodic Advertising with Responses - Advertiser: - Configure parameters - Receive subevent data requests - Set subevent data - Receive response reports The support is enabled by CONFIG_BT_PER_ADV_RSP, and requires a controller that selects CONFIG_BT_CTLR_ADV_PERIODIC_RSP_SUPPORT. Signed-off-by: Herman Berget (cherry picked from commit 9021e2f438c64fc9d6daaedcfd06d9280c288d75) (cherry picked from commit 2a5646939847ff69e67e284f8b777591b540afbe) --- include/zephyr/bluetooth/bluetooth.h | 128 +++++++++++++++++++ include/zephyr/bluetooth/hci.h | 68 ++++++++++ subsys/bluetooth/Kconfig.adv | 8 ++ subsys/bluetooth/controller/Kconfig | 13 ++ subsys/bluetooth/host/adv.c | 178 ++++++++++++++++++++++++++- subsys/bluetooth/host/hci_core.c | 12 ++ subsys/bluetooth/host/hci_core.h | 3 + 7 files changed, 405 insertions(+), 5 deletions(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index fd0c638bb966..8b5be28dfce3 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -74,6 +74,39 @@ struct bt_le_ext_adv_scanned_info { bt_addr_le_t *addr; }; +struct bt_le_per_adv_data_request { + /** The first subevent data can be set for */ + uint8_t start; + + /** The number of subevents data can be set for */ + uint8_t count; +}; + +struct bt_le_per_adv_response_info { + /** The subevent the response was received in */ + uint8_t subevent; + + /** @brief Status of the subevent indication. + * + * 0 if subevent indication was transmitted. + * 1 if subevent indication was not transmitted. + * All other values RFU. + */ + uint8_t tx_status; + + /** The TX power of the response in dBm */ + int8_t tx_power; + + /** The RSSI of the response in dBm */ + int8_t rssi; + + /** The Constant Tone Extension (CTE) of the advertisement (@ref bt_df_cte_type) */ + uint8_t cte_type; + + /** The slot the response was received in */ + uint8_t response_slot; +}; + struct bt_le_ext_adv_cb { /** * @brief The advertising set has finished sending adv data. @@ -129,6 +162,32 @@ struct bt_le_ext_adv_cb { */ bool (*rpa_expired)(struct bt_le_ext_adv *adv); #endif /* defined(CONFIG_BT_PRIVACY) */ + +#if defined(CONFIG_BT_PER_ADV_RSP) + /** + * @brief The Controller indicates it is ready to transmit one or more subevent. + * + * This callback notifies the application that the controller has requested + * data for upcoming subevents. + * + * @param adv The advertising set object. + * @param request Information about the upcoming subevents. + */ + void (*pawr_data_request)(struct bt_le_ext_adv *adv, + const struct bt_le_per_adv_data_request *request); + /** + * @brief The Controller indicates that one or more synced devices have + * responded to a periodic advertising subevent indication. + * + * @param adv The advertising set object. + * @param info Information about the responses received. + * @param buf The received data. NULL if the controller reported + * that it did not receive any response. + */ + void (*pawr_response)(struct bt_le_ext_adv *adv, struct bt_le_per_adv_response_info *info, + struct net_buf_simple *buf); + +#endif /* defined(CONFIG_BT_PER_ADV_RSP) */ }; /** @@ -731,6 +790,43 @@ struct bt_le_per_adv_param { /** Bit-field of periodic advertising options */ uint32_t options; + +#if defined(CONFIG_BT_PER_ADV_RSP) + /** + * @brief Number of subevents + * + * If zero, the periodic advertiser will be a broadcaster, without responses. + */ + uint8_t num_subevents; + + /** + * @brief Interval between subevents (N * 1.25 ms) + * + * Shall be between 7.5ms and 318.75 ms. + */ + uint8_t subevent_interval; + + /** + * @brief Time between the advertising packet in a subevent and the + * first response slot (N * 1.25 ms) + * + */ + uint8_t response_slot_delay; + + /** + * @brief Time between response slots (N * 0.125 ms) + * + * Shall be between 0.25 and 31.875 ms. + */ + uint8_t response_slot_spacing; + + /** + * @brief Number of subevent response slots + * + * If zero, response_slot_delay and response_slot_spacing are ignored. + */ + uint8_t num_response_slots; +#endif /* CONFIG_BT_PER_ADV_RSP */ }; /** @@ -1198,6 +1294,38 @@ int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv, int bt_le_per_adv_set_data(const struct bt_le_ext_adv *adv, const struct bt_data *ad, size_t ad_len); +struct bt_le_per_adv_subevent_data_params { + /** The subevent to set data for */ + uint8_t subevent; + + /** The first response slot to listen to */ + uint8_t response_slot_start; + + /** The number of response slots to listen to */ + uint8_t response_slot_count; + + /** The data to send */ + const struct net_buf_simple *data; +}; + +/** + * @brief Set the periodic advertising with response subevent data. + * + * Set the data for one or more subevents of a Periodic Advertising with + * Responses Advertiser in reply data request. + * + * @pre There are @p num_subevents elements in @p params. + * @pre The controller has requested data for the subevents in @p params. + * + * @param adv The extended advertiser the PAwR train belongs to. + * @param num_subevents The number of subevents to set data for. + * @param params Subevent parameters. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_le_per_adv_set_subevent_data(const struct bt_le_ext_adv *adv, uint8_t num_subevents, + const struct bt_le_per_adv_subevent_data_params *params); + /** * @brief Starts periodic advertising. * diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index f0625de39711..456d06d8dc6e 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -35,6 +35,10 @@ extern "C" { #define BT_ENC_KEY_SIZE_MIN 0x07 #define BT_ENC_KEY_SIZE_MAX 0x10 +#define BT_HCI_ADV_HANDLE_INVALID 0xff +#define BT_HCI_SYNC_HANDLE_INVALID 0xffff +#define BT_HCI_PAWR_SUBEVENT_MAX 128 + struct bt_hci_evt_hdr { uint8_t evt; uint8_t len; @@ -173,6 +177,8 @@ struct bt_hci_cmd_hdr { #define BT_LE_FEAT_BIT_CONN_SUBRATING_HOST_SUPP 38 #define BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION 39 +#define BT_LE_FEAT_BIT_PAWR_ADVERTISER 43 + #define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \ BIT((n) & 7)) @@ -236,6 +242,8 @@ struct bt_hci_cmd_hdr { BT_LE_FEAT_BIT_CONN_SUBRATING_HOST_SUPP) #define BT_FEAT_LE_CHANNEL_CLASSIFICATION(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION) +#define BT_FEAT_LE_PAWR_ADVERTISER(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_PAWR_ADVERTISER) #define BT_FEAT_LE_CIS(feat) (BT_FEAT_LE_CIS_CENTRAL(feat) | \ BT_FEAT_LE_CIS_PERIPHERAL(feat)) @@ -1488,6 +1496,35 @@ struct bt_hci_cp_le_ext_create_conn { struct bt_hci_ext_conn_phy p[0]; } __packed; +#define BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA BT_OP(BT_OGF_LE, 0x0082) +struct bt_hci_cp_le_set_pawr_subevent_data_element { + uint8_t subevent; + uint8_t response_slot_start; + uint8_t response_slot_count; + uint8_t subevent_data_length; + uint8_t subevent_data[0]; +} __packed; + +struct bt_hci_cp_le_set_pawr_subevent_data { + uint8_t adv_handle; + uint8_t num_subevents; + struct bt_hci_cp_le_set_pawr_subevent_data_element subevents[0]; +} __packed; + +#define BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2 BT_OP(BT_OGF_LE, 0x0086) +struct bt_hci_cp_le_set_per_adv_param_v2 { + uint8_t handle; + uint16_t min_interval; + uint16_t max_interval; + uint16_t props; + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; + uint8_t num_response_slots; +} __packed; + + #define BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_USE_LIST BIT(0) #define BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_REPORTS_DISABLED BIT(1) #define BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_FILTER_DUPLICATE BIT(2) @@ -2293,6 +2330,33 @@ struct bt_hci_evt_remote_ext_features { uint8_t features[8]; } __packed; +#define BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST 0x27 +struct bt_hci_evt_le_per_adv_subevent_data_request { + uint8_t adv_handle; + uint8_t subevent_start; + uint8_t subevent_data_count; +} __packed; + +#define BT_HCI_EVT_LE_PER_ADV_RESPONSE_REPORT 0x28 + +struct bt_hci_evt_le_per_adv_response { + int8_t tx_power; + int8_t rssi; + uint8_t cte_type; + uint8_t response_slot; + uint8_t data_status; + uint8_t data_length; + uint8_t data[0]; +} __packed; + +struct bt_hci_evt_le_per_adv_response_report { + uint8_t adv_handle; + uint8_t subevent; + uint8_t tx_status; + uint8_t num_responses; + struct bt_hci_evt_le_per_adv_response responses[0]; +} __packed; + #define BT_HCI_EVT_SYNC_CONN_COMPLETE 0x2c struct bt_hci_evt_sync_conn_complete { uint8_t status; @@ -2498,6 +2562,7 @@ struct bt_hci_evt_le_phy_update_complete { #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE 0 #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL 1 #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE 2 +#define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED 0xFF struct bt_hci_evt_le_ext_advertising_info { uint16_t evt_type; @@ -2816,6 +2881,9 @@ struct bt_hci_evt_le_biginfo_adv_report { #define BT_EVT_MASK_LE_TRANSMIT_POWER_REPORTING BT_EVT_BIT(32) #define BT_EVT_MASK_LE_BIGINFO_ADV_REPORT BT_EVT_BIT(33) +#define BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ BT_EVT_BIT(38) +#define BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT BT_EVT_BIT(39) + /** Allocate a HCI command buffer. * * This function allocates a new buffer for a HCI command. It is given diff --git a/subsys/bluetooth/Kconfig.adv b/subsys/bluetooth/Kconfig.adv index 1633e48bd0c7..d978d8d7e34e 100644 --- a/subsys/bluetooth/Kconfig.adv +++ b/subsys/bluetooth/Kconfig.adv @@ -43,6 +43,14 @@ config BT_PER_ADV intervals. Scanners can synchronize to the periodic advertisements to periodically get the data. +config BT_PER_ADV_RSP + bool "Periodic Advertising with Responses support [EXPERIMENTAL]" + select EXPERIMENTAL + depends on BT_PER_ADV + help + Select this to enable Periodic Advertising with Responses + API support. + config BT_PER_ADV_SYNC bool "Periodic advertising sync support" depends on BT_OBSERVER diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index 1154d4ac3a6f..d2490a426b4f 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -43,6 +43,10 @@ config BT_CTLR_ADV_PERIODIC_SUPPORT depends on BT_CTLR_ADV_EXT_SUPPORT bool +config BT_CTLR_ADV_PERIODIC_RSP_SUPPORT + depends on BT_CTLR_ADV_PERIODIC_SUPPORT + bool + config BT_CTLR_SYNC_PERIODIC_SUPPORT depends on BT_CTLR_ADV_EXT_SUPPORT bool @@ -608,6 +612,15 @@ config BT_CTLR_ADV_PERIODIC Enable support for Bluetooth 5.0 LE Periodic Advertising in the Controller. +config BT_CTLR_ADV_PERIODIC_RSP + bool "LE Periodic Advertising with Responses in Advertising State" + depends on BT_BROADCASTER && BT_CTLR_ADV_PERIODIC_RSP_SUPPORT + select BT_CTLR_CHAN_SEL_2 + default y if BT_PER_ADV_RSP + help + Enable support for Bluetooth 5.4 LE Periodic Advertising with + Responses in the Controller. + if BT_CTLR_ADV_PERIODIC config BT_CTLR_ADV_PERIODIC_ADI_SUPPORT diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 2a7b0cab419d..7963b39f99b9 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -1779,12 +1779,29 @@ static void adv_timeout(struct k_work *work) int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv, const struct bt_le_per_adv_param *param) { +#if defined(CONFIG_BT_PER_ADV_RSP) + /* The v2 struct can be used even if we end up sending a v1 command + * because they have the same layout for the common fields. + * V2 simply adds fields at the end of the v1 command. + */ + struct bt_hci_cp_le_set_per_adv_param_v2 *cp; +#else struct bt_hci_cp_le_set_per_adv_param *cp; +#endif /* CONFIG_BT_PER_ADV_RSP */ + + uint16_t opcode; + uint16_t size; struct net_buf *buf; int err; uint16_t props = 0; - if (!BT_FEAT_LE_EXT_PER_ADV(bt_dev.le.features)) { + if (IS_ENABLED(CONFIG_BT_PER_ADV_RSP) && BT_FEAT_LE_PAWR_ADVERTISER(bt_dev.le.features)) { + opcode = BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2; + size = sizeof(struct bt_hci_cp_le_set_per_adv_param_v2); + } else if (BT_FEAT_LE_EXT_PER_ADV(bt_dev.le.features)) { + opcode = BT_HCI_OP_LE_SET_PER_ADV_PARAM; + size = sizeof(struct bt_hci_cp_le_set_per_adv_param); + } else { return -ENOTSUP; } @@ -1807,13 +1824,13 @@ int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv, return -ENOTSUP; } - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_PARAM, sizeof(*cp)); + buf = bt_hci_cmd_create(opcode, size); if (!buf) { return -ENOBUFS; } - cp = net_buf_add(buf, sizeof(*cp)); - (void)memset(cp, 0, sizeof(*cp)); + cp = net_buf_add(buf, size); + (void)memset(cp, 0, size); cp->handle = adv->handle; cp->min_interval = sys_cpu_to_le16(param->interval_min); @@ -1824,7 +1841,18 @@ int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv, } cp->props = sys_cpu_to_le16(props); - err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_PARAM, buf, NULL); + +#if defined(CONFIG_BT_PER_ADV_RSP) + if (opcode == BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2) { + cp->num_subevents = param->num_subevents; + cp->subevent_interval = param->subevent_interval; + cp->response_slot_delay = param->response_slot_delay; + cp->response_slot_spacing = param->response_slot_spacing; + cp->num_response_slots = param->num_response_slots; + } +#endif /* CONFIG_BT_PER_ADV_RSP */ + + err = bt_hci_cmd_send_sync(opcode, buf, NULL); if (err) { return err; } @@ -1872,6 +1900,48 @@ int bt_le_per_adv_set_data(const struct bt_le_ext_adv *adv, return hci_set_per_adv_data(adv, ad, ad_len); } +int bt_le_per_adv_set_subevent_data(const struct bt_le_ext_adv *adv, uint8_t num_subevents, + const struct bt_le_per_adv_subevent_data_params *params) +{ + struct bt_hci_cp_le_set_pawr_subevent_data *cp; + struct bt_hci_cp_le_set_pawr_subevent_data_element *element; + struct net_buf *buf; + size_t cmd_length = sizeof(*cp); + + if (!BT_FEAT_LE_PAWR_ADVERTISER(bt_dev.le.features)) { + return -ENOTSUP; + } + + for (size_t i = 0; i < num_subevents; i++) { + cmd_length += sizeof(struct bt_hci_cp_le_set_pawr_subevent_data_element); + cmd_length += params[i].data->len; + } + + if (cmd_length > 0xFF) { + return -EINVAL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA, (uint8_t)cmd_length); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + cp->adv_handle = adv->handle; + cp->num_subevents = num_subevents; + + for (size_t i = 0; i < num_subevents; i++) { + element = net_buf_add(buf, sizeof(*element)); + element->subevent = params[i].subevent; + element->response_slot_start = params[i].response_slot_start; + element->response_slot_count = params[i].response_slot_count; + element->subevent_data_length = params[i].data->len; + net_buf_add_mem(buf, params[i].data->data, params[i].data->len); + } + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA, buf, NULL); +} + static int bt_le_per_adv_enable(struct bt_le_ext_adv *adv, bool enable) { struct bt_hci_cp_le_set_per_adv_enable *cp; @@ -1933,6 +2003,104 @@ int bt_le_per_adv_stop(struct bt_le_ext_adv *adv) return bt_le_per_adv_enable(adv, false); } +#if defined(CONFIG_BT_PER_ADV_RSP) +void bt_hci_le_per_adv_subevent_data_request(struct net_buf *buf) +{ + struct bt_hci_evt_le_per_adv_subevent_data_request *evt; + struct bt_le_per_adv_data_request request; + struct bt_le_ext_adv *adv; + + if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request)) { + LOG_ERR("Invalid data request"); + + return; + } + + evt = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request)); + adv = bt_adv_lookup_handle(evt->adv_handle); + if (!adv) { + LOG_ERR("Unknown advertising handle %d", evt->adv_handle); + + return; + } + + request.start = evt->subevent_start; + request.count = evt->subevent_data_count; + + if (adv->cb && adv->cb->pawr_data_request) { + adv->cb->pawr_data_request(adv, &request); + } +} + +void bt_hci_le_per_adv_response_report(struct net_buf *buf) +{ + struct bt_hci_evt_le_per_adv_response_report *evt; + struct bt_hci_evt_le_per_adv_response *response; + struct bt_le_ext_adv *adv; + struct bt_le_per_adv_response_info info; + struct net_buf_simple data; + + if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_response_report)) { + LOG_ERR("Invalid response report"); + + return; + } + + evt = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_response_report)); + adv = bt_adv_lookup_handle(evt->adv_handle); + if (!adv) { + LOG_ERR("Unknown advertising handle %d", evt->adv_handle); + + return; + } + + info.subevent = evt->subevent; + info.tx_status = evt->tx_status; + + for (uint8_t i = 0; i < evt->num_responses; i++) { + if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_response)) { + LOG_ERR("Invalid response report"); + + return; + } + + response = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_response)); + info.tx_power = response->tx_power; + info.rssi = response->rssi; + info.cte_type = BIT(response->cte_type); + info.response_slot = response->response_slot; + + if (buf->len < response->data_length) { + LOG_ERR("Invalid response report"); + + return; + } + + if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL) { + LOG_WRN("Incomplete response report received, discarding"); + (void)net_buf_pull_mem(buf, response->data_length); + } else if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED) { + (void)net_buf_pull_mem(buf, response->data_length); + + if (adv->cb && adv->cb->pawr_response) { + adv->cb->pawr_response(adv, &info, NULL); + } + } else if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE) { + net_buf_simple_init_with_data(&data, + net_buf_pull_mem(buf, response->data_length), + response->data_length); + + if (adv->cb && adv->cb->pawr_response) { + adv->cb->pawr_response(adv, &info, &data); + } + } else { + LOG_ERR("Invalid data status %d", response->data_status); + (void)net_buf_pull_mem(buf, response->data_length); + } + } +} +#endif /* CONFIG_BT_PER_ADV_RSP */ + #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER) int bt_le_per_adv_set_info_transfer(const struct bt_le_ext_adv *adv, const struct bt_conn *conn, diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index cab4c10e5a39..3e9488ffdffe 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -2325,6 +2325,13 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_CTE_REQUEST_FAILED, bt_hci_le_df_cte_req_failed, sizeof(struct bt_hci_evt_le_cte_req_failed)), #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */ +#if defined(CONFIG_BT_PER_ADV_RSP) + EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST, + bt_hci_le_per_adv_subevent_data_request, + sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request)), + EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_RESPONSE_REPORT, bt_hci_le_per_adv_response_report, + sizeof(struct bt_hci_evt_le_per_adv_response_report)), +#endif /* CONFIG_BT_PER_ADV_RSP */ }; @@ -2899,6 +2906,11 @@ static int le_set_event_mask(void) mask |= BT_EVT_MASK_LE_CTE_REQUEST_FAILED; } + if (IS_ENABLED(CONFIG_BT_PER_ADV_RSP)) { + mask |= BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ; + mask |= BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT; + } + sys_put_le64(mask, cp_mask->events); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL); } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index c0e4dddaffa7..3f41073f9682 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -488,3 +488,6 @@ void bt_hci_synchronous_conn_complete(struct net_buf *buf); void bt_hci_le_df_connection_iq_report(struct net_buf *buf); void bt_hci_le_vs_df_connection_iq_report(struct net_buf *buf); void bt_hci_le_df_cte_req_failed(struct net_buf *buf); + +void bt_hci_le_per_adv_subevent_data_request(struct net_buf *buf); +void bt_hci_le_per_adv_response_report(struct net_buf *buf); From 7660f3da7bb8047d1f31b120b0ec3135409b8597 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Thu, 30 Mar 2023 13:48:33 +0200 Subject: [PATCH 052/528] [nrf fromtree] Bluetooth: Host: Add support for PAwR Sync Adds API for Periodic Advertising with Responses - Scanner: - Synchronize to a PAwR train - Choose which subevents to synchronize to - Receive advertising reports from subevents - Send responses The support is enabled by CONFIG_BT_PER_ADV_SYNC_RSP, and requires a controller that selects CONFIG_BT_CTLR_SYNC_PERIODIC_RSP_SUPPORT. Signed-off-by: Herman Berget (cherry picked from commit 95bc5cf8e5e208315cdaf69a9b0d25d3d78f40ca) (cherry picked from commit cc544c75e73bfe2e2cfea000a64c07a4c9b88d29) --- include/zephyr/bluetooth/bluetooth.h | 97 ++++++++++++++ include/zephyr/bluetooth/hci.h | 72 ++++++++++ subsys/bluetooth/Kconfig.adv | 8 ++ subsys/bluetooth/controller/Kconfig | 13 ++ subsys/bluetooth/host/hci_core.c | 15 +++ subsys/bluetooth/host/hci_core.h | 17 +++ subsys/bluetooth/host/scan.c | 192 ++++++++++++++++++++++++++- 7 files changed, 411 insertions(+), 3 deletions(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 8b5be28dfce3..42ab174abc68 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -1388,6 +1388,20 @@ struct bt_le_per_adv_sync_synced_info { * */ struct bt_conn *conn; +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + /** Number of subevents */ + uint8_t num_subevents; + + /** Subevent interval (N * 1.25 ms) */ + uint8_t subevent_interval; + + /** Response slot delay (N * 1.25 ms) */ + uint8_t response_slot_delay; + + /** Response slot spacing (N * 1.25 ms) */ + uint8_t response_slot_spacing; + +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ }; struct bt_le_per_adv_sync_term_info { @@ -1416,6 +1430,13 @@ struct bt_le_per_adv_sync_recv_info { /** The Constant Tone Extension (CTE) of the advertisement (@ref bt_df_cte_type) */ uint8_t cte_type; +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + /** The value of the event counter where the subevent indication was received. */ + uint16_t periodic_event_counter; + + /** The subevent where the subevend indication was received. */ + uint8_t subevent; +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ }; @@ -1459,6 +1480,9 @@ struct bt_le_per_adv_sync_cb { * @param sync The advertising set object. * @param info Information about the periodic advertising event. * @param buf Buffer containing the periodic advertising data. + * NULL if the controller failed to receive a subevent + * indication. Only happens if + * @kconfig{CONFIG_BT_PER_ADV_SYNC_RSP} is enabled. */ void (*recv)(struct bt_le_per_adv_sync *sync, const struct bt_le_per_adv_sync_recv_info *info, @@ -2511,6 +2535,79 @@ void bt_foreach_bond(uint8_t id, void (*func)(const struct bt_bond_info *info, int bt_configure_data_path(uint8_t dir, uint8_t id, uint8_t vs_config_len, const uint8_t *vs_config); +struct bt_le_per_adv_sync_subevent_params { + /** @brief Periodic Advertising Properties. + * + * Bit 6 is include TxPower, all others RFU. + * + */ + uint16_t properties; + + /** Number of subevents to sync to */ + uint8_t num_subevents; + + /** @brief The subevent(s) to synchronize with + * + * The array must have @ref num_subevents elements. + * + */ + uint8_t *subevents; +}; + +/** @brief Synchronize with a subset of subevents + * + * Until this command is issued, the subevent(s) the controller is synchronized + * to is unspecified. + * + * @param per_adv_sync The periodic advertising sync object. + * @param params Parameters. + * + * @return 0 in case of success or negative value in case of error. + */ +int bt_le_per_adv_sync_subevent(struct bt_le_per_adv_sync *per_adv_sync, + struct bt_le_per_adv_sync_subevent_params *params); + +struct bt_le_per_adv_response_params { + /** @brief The periodic event counter of the request the response is sent to. + * + * @ref bt_le_per_adv_sync_recv_info + * + * @note The response can be sent up to one periodic interval after + * the request was received. + * + */ + uint16_t request_event; + + /** @brief The subevent counter of the request the response is sent to. + * + * @ref bt_le_per_adv_sync_recv_info + * + */ + uint8_t request_subevent; + + /** The subevent the response shall be sent in */ + uint8_t response_subevent; + + /** The response slot the response shall be sent in */ + uint8_t response_slot; +}; + +/** + * @brief Set the data for a response slot in a specific subevent of the PAwR. + * + * This function is called by the Host to set the response dat. + * The data for a repsonse slot shall be transmitted only once. + * + * @param per_adv_sync The periodic advertising sync object. + * @param params Parameters. + * @param data The response data to send. + * + * @return Zero on success or (negative) error code otherwise. + */ +int bt_le_per_adv_set_response_data(struct bt_le_per_adv_sync *per_adv_sync, + const struct bt_le_per_adv_response_params *params, + const struct net_buf_simple *data); + /** * @} */ diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index 456d06d8dc6e..375e10a81572 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -178,6 +178,7 @@ struct bt_hci_cmd_hdr { #define BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION 39 #define BT_LE_FEAT_BIT_PAWR_ADVERTISER 43 +#define BT_LE_FEAT_BIT_PAWR_SCANNER 44 #define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \ BIT((n) & 7)) @@ -244,6 +245,8 @@ struct bt_hci_cmd_hdr { BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION) #define BT_FEAT_LE_PAWR_ADVERTISER(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_PAWR_ADVERTISER) +#define BT_FEAT_LE_PAWR_SCANNER(feat) BT_LE_FEAT_TEST(feat, \ + BT_LE_FEAT_BIT_PAWR_SCANNER) #define BT_FEAT_LE_CIS(feat) (BT_FEAT_LE_CIS_CENTRAL(feat) | \ BT_FEAT_LE_CIS_PERIPHERAL(feat)) @@ -1511,6 +1514,27 @@ struct bt_hci_cp_le_set_pawr_subevent_data { struct bt_hci_cp_le_set_pawr_subevent_data_element subevents[0]; } __packed; + +#define BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA BT_OP(BT_OGF_LE, 0x0083) +struct bt_hci_cp_le_set_pawr_response_data { + uint16_t sync_handle; + uint16_t request_event; + uint8_t request_subevent; + uint8_t response_subevent; + uint8_t response_slot; + uint8_t response_data_length; + uint8_t response_data[0]; +} __packed; + +#define BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT BT_OP(BT_OGF_LE, 0x0084) +struct bt_hci_cp_le_set_pawr_sync_subevent { + uint16_t sync_handle; + uint16_t periodic_adv_properties; + uint8_t num_subevents; + uint8_t subevents[0]; +} __packed; + + #define BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2 BT_OP(BT_OGF_LE, 0x0086) struct bt_hci_cp_le_set_per_adv_param_v2 { uint8_t handle; @@ -2330,6 +2354,51 @@ struct bt_hci_evt_remote_ext_features { uint8_t features[8]; } __packed; +#define BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED_V2 0x24 +struct bt_hci_evt_le_per_adv_sync_established_v2 { + uint8_t status; + uint16_t handle; + uint8_t sid; + bt_addr_le_t adv_addr; + uint8_t phy; + uint16_t interval; + uint8_t clock_accuracy; + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; +} __packed; + +#define BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2 0x25 +struct bt_hci_evt_le_per_advertising_report_v2 { + uint16_t handle; + int8_t tx_power; + int8_t rssi; + uint8_t cte_type; + uint16_t periodic_event_counter; + uint8_t subevent; + uint8_t data_status; + uint8_t length; + uint8_t data[0]; +} __packed; + +#define BT_HCI_EVT_LE_PAST_RECEIVED_V2 0x26 +struct bt_hci_evt_le_past_received_v2 { + uint8_t status; + uint16_t conn_handle; + uint16_t service_data; + uint16_t sync_handle; + uint8_t adv_sid; + bt_addr_le_t addr; + uint8_t phy; + uint16_t interval; + uint8_t clock_accuracy; + uint8_t num_subevents; + uint8_t subevent_interval; + uint8_t response_slot_delay; + uint8_t response_slot_spacing; +} __packed; + #define BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST 0x27 struct bt_hci_evt_le_per_adv_subevent_data_request { uint8_t adv_handle; @@ -2881,6 +2950,9 @@ struct bt_hci_evt_le_biginfo_adv_report { #define BT_EVT_MASK_LE_TRANSMIT_POWER_REPORTING BT_EVT_BIT(32) #define BT_EVT_MASK_LE_BIGINFO_ADV_REPORT BT_EVT_BIT(33) +#define BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED_V2 BT_EVT_BIT(35) +#define BT_EVT_MASK_LE_PER_ADVERTISING_REPORT_V2 BT_EVT_BIT(36) +#define BT_EVT_MASK_LE_PAST_RECEIVED_V2 BT_EVT_BIT(37) #define BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ BT_EVT_BIT(38) #define BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT BT_EVT_BIT(39) diff --git a/subsys/bluetooth/Kconfig.adv b/subsys/bluetooth/Kconfig.adv index d978d8d7e34e..233ee20d4cbd 100644 --- a/subsys/bluetooth/Kconfig.adv +++ b/subsys/bluetooth/Kconfig.adv @@ -60,6 +60,14 @@ config BT_PER_ADV_SYNC and deterministic receive data from that device in a connectionless manner. +config BT_PER_ADV_SYNC_RSP + bool "Periodic Advertising with Responses sync support [EXPERIMENTAL]" + select EXPERIMENTAL + depends on BT_OBSERVER + help + Select this to enable Periodic Advertising with Responses Sync + API support. + if BT_PER_ADV_SYNC config BT_PER_ADV_SYNC_MAX diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index d2490a426b4f..f5c5ad66b5af 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -51,6 +51,10 @@ config BT_CTLR_SYNC_PERIODIC_SUPPORT depends on BT_CTLR_ADV_EXT_SUPPORT bool +config BT_CTLR_SYNC_PERIODIC_RSP_SUPPORT + depends on BT_CTLR_SYNC_PERIODIC_SUPPORT + bool + config BT_CTLR_SYNC_TRANSFER_SENDER_SUPPORT depends on BT_CTLR_SYNC_PERIODIC_SUPPORT || BT_CTLR_ADV_PERIODIC_SUPPORT bool @@ -651,6 +655,15 @@ config BT_CTLR_SYNC_PERIODIC Enable support for Bluetooth 5.0 LE Periodic Advertising in Synchronization state in the Controller. +config BT_CTLR_SYNC_PERIODIC_RSP + bool "LE Periodic Advertising with Responses in Synchronization State" + depends on BT_OBSERVER && BT_CTLR_SYNC_PERIODIC_RSP_SUPPORT + select BT_CTLR_CHAN_SEL_2 + default y if BT_PER_ADV_SYNC_RSP + help + Enable support for Bluetooth 5.4 LE Periodic Advertising with + Responses in Synchronization state in the Controller. + if BT_CTLR_SYNC_PERIODIC config BT_CTLR_SYNC_PERIODIC_ADV_LIST diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 3e9488ffdffe..9457c52ce21a 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -2325,6 +2325,15 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_CTE_REQUEST_FAILED, bt_hci_le_df_cte_req_failed, sizeof(struct bt_hci_evt_le_cte_req_failed)), #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */ +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2, bt_hci_le_per_adv_report_v2, + sizeof(struct bt_hci_evt_le_per_advertising_report_v2)), + EVENT_HANDLER(BT_HCI_EVT_LE_PAST_RECEIVED_V2, bt_hci_le_past_received_v2, + sizeof(struct bt_hci_evt_le_past_received_v2)), + EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED_V2, + bt_hci_le_per_adv_sync_established_v2, + sizeof(struct bt_hci_evt_le_per_adv_sync_established_v2)), +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ #if defined(CONFIG_BT_PER_ADV_RSP) EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST, bt_hci_le_per_adv_subevent_data_request, @@ -2911,6 +2920,12 @@ static int le_set_event_mask(void) mask |= BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT; } + if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) { + mask |= BT_EVT_MASK_LE_PER_ADVERTISING_REPORT_V2; + mask |= BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED_V2; + mask |= BT_EVT_MASK_LE_PAST_RECEIVED_V2; + } + sys_put_le64(mask, cp_mask->events); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL); } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 3f41073f9682..18fd0e35b2a8 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -227,6 +227,20 @@ struct bt_le_per_adv_sync { /** Flags */ ATOMIC_DEFINE(flags, BT_PER_ADV_SYNC_NUM_FLAGS); + +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + /** Number of subevents */ + uint8_t num_subevents; + + /** Subevent interval (N * 1.25ms) */ + uint8_t subevent_interval; + + /** Response slot delay (N * 1.25ms) */ + uint8_t response_slot_delay; + + /** Response slot spacing (N * 1.25ms) */ + uint8_t response_slot_spacing; +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ }; struct bt_dev_le { @@ -459,12 +473,15 @@ void bt_hci_le_adv_report(struct net_buf *buf); void bt_hci_le_scan_timeout(struct net_buf *buf); void bt_hci_le_adv_ext_report(struct net_buf *buf); void bt_hci_le_per_adv_sync_established(struct net_buf *buf); +void bt_hci_le_per_adv_sync_established_v2(struct net_buf *buf); void bt_hci_le_per_adv_report(struct net_buf *buf); +void bt_hci_le_per_adv_report_v2(struct net_buf *buf); void bt_hci_le_per_adv_sync_lost(struct net_buf *buf); void bt_hci_le_biginfo_adv_report(struct net_buf *buf); void bt_hci_le_df_connectionless_iq_report(struct net_buf *buf); void bt_hci_le_vs_df_connectionless_iq_report(struct net_buf *buf); void bt_hci_le_past_received(struct net_buf *buf); +void bt_hci_le_past_received_v2(struct net_buf *buf); /* Adv HCI event handlers */ void bt_hci_le_adv_set_terminated(struct net_buf *buf); diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 70955ce78288..3b2fdb543237 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -768,9 +768,28 @@ void bt_hci_le_per_adv_report_recv(struct bt_le_per_adv_sync *per_adv_sync, } } -void bt_hci_le_per_adv_report(struct net_buf *buf) +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) && (CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0) +static void bt_hci_le_per_adv_report_recv_failure(struct bt_le_per_adv_sync *per_adv_sync, + const struct bt_le_per_adv_sync_recv_info *info) +{ + struct bt_le_per_adv_sync_cb *listener; + + SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { + if (listener->recv) { + listener->recv(per_adv_sync, info, NULL); + } + } +} +#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) && (CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0) */ + +static void bt_hci_le_per_adv_report_common(struct net_buf *buf) { +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + struct bt_hci_evt_le_per_advertising_report_v2 *evt; +#else struct bt_hci_evt_le_per_advertising_report *evt; +#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ + struct bt_le_per_adv_sync *per_adv_sync; struct bt_le_per_adv_sync_recv_info info; @@ -801,6 +820,11 @@ void bt_hci_le_per_adv_report(struct net_buf *buf) info.addr = &per_adv_sync->addr; info.sid = per_adv_sync->sid; +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + info.periodic_event_counter = sys_le16_to_cpu(evt->periodic_event_counter); + info.subevent = evt->subevent; +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ + if (!per_adv_sync->report_truncated) { #if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 if (net_buf_simple_tailroom(&per_adv_sync->reassembly) < evt->length) { @@ -835,6 +859,11 @@ void bt_hci_le_per_adv_report(struct net_buf *buf) } else if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL) { net_buf_simple_add_mem(&per_adv_sync->reassembly, buf->data, evt->length); +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + } else if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED && + per_adv_sync->num_subevents) { + bt_hci_le_per_adv_report_recv_failure(per_adv_sync, &info); +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ } else { __ASSERT(false, "Invalid data status 0x%02X", evt->data_status); } @@ -850,6 +879,17 @@ void bt_hci_le_per_adv_report(struct net_buf *buf) } } +void bt_hci_le_per_adv_report(struct net_buf *buf) +{ + if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) { + LOG_ERR("The controller shall raise the latest unmasked version of the event"); + + return; + } + + bt_hci_le_per_adv_report_common(buf); +} + static int per_adv_sync_terminate(uint16_t handle) { struct bt_hci_cp_le_per_adv_terminate_sync *cp; @@ -893,10 +933,16 @@ static void per_adv_sync_terminated(struct bt_le_per_adv_sync *per_adv_sync, } } -void bt_hci_le_per_adv_sync_established(struct net_buf *buf) +static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) { +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + struct bt_hci_evt_le_per_adv_sync_established_v2 *evt = + (struct bt_hci_evt_le_per_adv_sync_established_v2 *)buf->data; +#else struct bt_hci_evt_le_per_adv_sync_established *evt = (struct bt_hci_evt_le_per_adv_sync_established *)buf->data; +#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ + struct bt_le_per_adv_sync_synced_info sync_info; struct bt_le_per_adv_sync *pending_per_adv_sync; struct bt_le_per_adv_sync_cb *listener; @@ -1004,6 +1050,17 @@ void bt_hci_le_per_adv_sync_established(struct net_buf *buf) sync_info.addr = &pending_per_adv_sync->addr; sync_info.sid = pending_per_adv_sync->sid; +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + sync_info.num_subevents = evt->num_subevents; + sync_info.subevent_interval = evt->subevent_interval; + sync_info.response_slot_delay = evt->response_slot_delay; + sync_info.response_slot_spacing = evt->response_slot_spacing; + + pending_per_adv_sync->num_subevents = evt->num_subevents; + pending_per_adv_sync->subevent_interval = evt->subevent_interval; + pending_per_adv_sync->response_slot_delay = evt->response_slot_delay; + pending_per_adv_sync->response_slot_spacing = evt->response_slot_spacing; +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ sync_info.recv_enabled = !atomic_test_bit(pending_per_adv_sync->flags, @@ -1016,6 +1073,85 @@ void bt_hci_le_per_adv_sync_established(struct net_buf *buf) } } +void bt_hci_le_per_adv_sync_established(struct net_buf *buf) +{ + if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) { + LOG_ERR("The controller shall raise the latest unmasked version of the event"); + + return; + } + + bt_hci_le_per_adv_sync_established_common(buf); +} + +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) +int bt_le_per_adv_sync_subevent(struct bt_le_per_adv_sync *per_adv_sync, + struct bt_le_per_adv_sync_subevent_params *params) +{ + struct bt_hci_cp_le_set_pawr_sync_subevent *cp; + struct net_buf *buf; + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, sizeof(*cp)); + + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + (void)memset(cp, 0, sizeof(*cp)); + cp->sync_handle = sys_cpu_to_le16(per_adv_sync->handle); + cp->periodic_adv_properties = sys_cpu_to_le16(params->properties); + cp->num_subevents = params->num_subevents; + net_buf_add_mem(buf, params->subevents, cp->num_subevents); + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, buf, NULL); +} + +int bt_le_per_adv_set_response_data(struct bt_le_per_adv_sync *per_adv_sync, + const struct bt_le_per_adv_response_params *param, + const struct net_buf_simple *data) +{ + struct bt_hci_cp_le_set_pawr_response_data *cp; + struct net_buf *buf; + + if (per_adv_sync->num_subevents == 0) { + return -EINVAL; + } + + if (param->request_subevent >= per_adv_sync->num_subevents) { + return -EINVAL; + } + + if (param->response_subevent >= per_adv_sync->num_subevents) { + return -EINVAL; + } + + if (data->len > 247) { + return -EINVAL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA, + sizeof(*cp) + data->len); + + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + (void)memset(cp, 0, sizeof(*cp)); + cp->sync_handle = sys_cpu_to_le16(per_adv_sync->handle); + cp->request_event = sys_cpu_to_le16(param->request_event); + cp->request_subevent = param->request_subevent; + cp->response_subevent = param->response_subevent; + cp->response_slot = param->response_slot; + cp->response_data_length = data->len; + + net_buf_add_mem(buf, data->data, cp->response_data_length); + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA, buf, NULL); +} +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ + void bt_hci_le_per_adv_sync_lost(struct net_buf *buf) { struct bt_hci_evt_le_per_adv_sync_lost *evt = @@ -1035,10 +1171,16 @@ void bt_hci_le_per_adv_sync_lost(struct net_buf *buf) } #if defined(CONFIG_BT_CONN) -void bt_hci_le_past_received(struct net_buf *buf) +static void bt_hci_le_past_received_common(struct net_buf *buf) { +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + struct bt_hci_evt_le_past_received_v2 *evt = + (struct bt_hci_evt_le_past_received_v2 *)buf->data; +#else struct bt_hci_evt_le_past_received *evt = (struct bt_hci_evt_le_past_received *)buf->data; +#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ + struct bt_le_per_adv_sync_synced_info sync_info; struct bt_le_per_adv_sync_cb *listener; struct bt_le_per_adv_sync *per_adv_sync; @@ -1083,12 +1225,26 @@ void bt_hci_le_past_received(struct net_buf *buf) bt_addr_le_copy(&per_adv_sync->addr, &id_addr); per_adv_sync->sid = evt->adv_sid; +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + per_adv_sync->num_subevents = evt->num_subevents; + per_adv_sync->subevent_interval = evt->subevent_interval; + per_adv_sync->response_slot_delay = evt->response_slot_delay; + per_adv_sync->response_slot_spacing = evt->response_slot_spacing; +#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ + sync_info.interval = per_adv_sync->interval; sync_info.phy = bt_get_phy(per_adv_sync->phy); sync_info.addr = &per_adv_sync->addr; sync_info.sid = per_adv_sync->sid; sync_info.service_data = sys_le16_to_cpu(evt->service_data); +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + sync_info.num_subevents = per_adv_sync->num_subevents; + sync_info.subevent_interval = per_adv_sync->subevent_interval; + sync_info.response_slot_delay = per_adv_sync->response_slot_delay; + sync_info.response_slot_spacing = per_adv_sync->response_slot_spacing; +#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ + SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { if (listener->synced) { listener->synced(per_adv_sync, &sync_info); @@ -1097,8 +1253,38 @@ void bt_hci_le_past_received(struct net_buf *buf) bt_conn_unref(sync_info.conn); } + +void bt_hci_le_past_received(struct net_buf *buf) +{ + if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) { + LOG_ERR("The controller shall raise the latest unmasked version of the event"); + + return; + } + + bt_hci_le_past_received_common(buf); +} + +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) +void bt_hci_le_past_received_v2(struct net_buf *buf) +{ + bt_hci_le_past_received_common(buf); +} +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ #endif /* CONFIG_BT_CONN */ +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) +void bt_hci_le_per_adv_sync_established_v2(struct net_buf *buf) +{ + bt_hci_le_per_adv_sync_established_common(buf); +} + +void bt_hci_le_per_adv_report_v2(struct net_buf *buf) +{ + bt_hci_le_per_adv_report_common(buf); +} +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ + #if defined(CONFIG_BT_ISO_BROADCAST) void bt_hci_le_biginfo_adv_report(struct net_buf *buf) { From 6b53826a1dfa964e7b9d6dc6d727dc4f0893ba39 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Thu, 30 Mar 2023 13:04:55 +0200 Subject: [PATCH 053/528] [nrf fromtree] Samples: Bluetooth: Add samples for PAwR Adds samples for both advertiser and sync. Signed-off-by: Herman Berget (cherry picked from commit 627b340780da2c44b8b795b5eb29f02b008a7abc) (cherry picked from commit 2b05d87d09a1bae58e892fab526a56db2381f245) --- .../bluetooth/periodic_adv_rsp/CMakeLists.txt | 7 + samples/bluetooth/periodic_adv_rsp/README.rst | 38 ++ samples/bluetooth/periodic_adv_rsp/prj.conf | 16 + .../bluetooth/periodic_adv_rsp/sample.yaml | 12 + samples/bluetooth/periodic_adv_rsp/src/main.c | 382 ++++++++++++++++++ .../periodic_sync_rsp/CMakeLists.txt | 7 + .../bluetooth/periodic_sync_rsp/README.rst | 40 ++ samples/bluetooth/periodic_sync_rsp/prj.conf | 16 + .../bluetooth/periodic_sync_rsp/sample.yaml | 12 + .../bluetooth/periodic_sync_rsp/src/main.c | 256 ++++++++++++ 10 files changed, 786 insertions(+) create mode 100644 samples/bluetooth/periodic_adv_rsp/CMakeLists.txt create mode 100644 samples/bluetooth/periodic_adv_rsp/README.rst create mode 100644 samples/bluetooth/periodic_adv_rsp/prj.conf create mode 100644 samples/bluetooth/periodic_adv_rsp/sample.yaml create mode 100644 samples/bluetooth/periodic_adv_rsp/src/main.c create mode 100644 samples/bluetooth/periodic_sync_rsp/CMakeLists.txt create mode 100644 samples/bluetooth/periodic_sync_rsp/README.rst create mode 100644 samples/bluetooth/periodic_sync_rsp/prj.conf create mode 100644 samples/bluetooth/periodic_sync_rsp/sample.yaml create mode 100644 samples/bluetooth/periodic_sync_rsp/src/main.c diff --git a/samples/bluetooth/periodic_adv_rsp/CMakeLists.txt b/samples/bluetooth/periodic_adv_rsp/CMakeLists.txt new file mode 100644 index 000000000000..796bd5e5d8ed --- /dev/null +++ b/samples/bluetooth/periodic_adv_rsp/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(periodic_adv) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/periodic_adv_rsp/README.rst b/samples/bluetooth/periodic_adv_rsp/README.rst new file mode 100644 index 000000000000..4446313997d2 --- /dev/null +++ b/samples/bluetooth/periodic_adv_rsp/README.rst @@ -0,0 +1,38 @@ +.. _bluetooth-periodic-advertising-rsp-sample: + +Bluetooth: Periodic Advertising with Responses (PAwR) Advertiser +################################################################ + +Overview +******** + +A simple application demonstrating the BLE Periodic Advertising with +Responses Advertiser functionality. + +This sample will scan for the corresponding sync sample and send the required +synchronization info to it. The advertising data is a counter that increases +for each subevent. + +Multiple devices can synchronize and respond to one advertiser. + +Which subevent to listen to and in which response slot to respond is +application specific. In this sample it is decided by the PAwR advertiser. +Upon connection it will write to a GATT characteristic +the assigned subevent and response slot. + +Requirements +************ + +* A board with BLE support +* A controller that supports the Periodic Advertising with Responses (PAwR) - Advertiser feature + +Building and Running +******************** + +This sample can be found under :zephyr_file:`samples/bluetooth/periodic_adv_rsp` in +the Zephyr tree. + +Use the sample found under :zephyr_file:`samples/bluetooth/periodic_sync_rsp` in the +Zephyr tree that will synchronize and respond to this sample. + +See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/periodic_adv_rsp/prj.conf b/samples/bluetooth/periodic_adv_rsp/prj.conf new file mode 100644 index 000000000000..5b7aba46a49c --- /dev/null +++ b/samples/bluetooth/periodic_adv_rsp/prj.conf @@ -0,0 +1,16 @@ +CONFIG_BT=y +CONFIG_BT_BROADCASTER=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PER_ADV=y +CONFIG_BT_DEVICE_NAME="PAwR adv sample" + +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CENTRAL=y +CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y + +CONFIG_BT_PER_ADV_RSP=y + +CONFIG_BT_REMOTE_INFO=y +CONFIG_BT_GATT_CLIENT=y + +CONFIG_LOG=y diff --git a/samples/bluetooth/periodic_adv_rsp/sample.yaml b/samples/bluetooth/periodic_adv_rsp/sample.yaml new file mode 100644 index 000000000000..ff64f1d1208e --- /dev/null +++ b/samples/bluetooth/periodic_adv_rsp/sample.yaml @@ -0,0 +1,12 @@ +sample: + name: Bluetooth Periodic Advertising with Responses Advertiser +tests: + sample.bluetooth.periodic_adv: + harness: bluetooth + platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840 + tags: bluetooth + integration_platforms: + - nrf52840dk_nrf52840 + extra_configs: + - CONFIG_BT_CTLR=n + - CONFIG_BT_NO_DRIVER=y diff --git a/samples/bluetooth/periodic_adv_rsp/src/main.c b/samples/bluetooth/periodic_adv_rsp/src/main.c new file mode 100644 index 000000000000..463ecedf10a9 --- /dev/null +++ b/samples/bluetooth/periodic_adv_rsp/src/main.c @@ -0,0 +1,382 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define NUM_RSP_SLOTS 5 +#define NUM_SUBEVENTS 5 +#define PACKET_SIZE 5 +#define NAME_LEN 30 + +static K_SEM_DEFINE(sem_connected, 0, 1); +static K_SEM_DEFINE(sem_discovered, 0, 1); +static K_SEM_DEFINE(sem_written, 0, 1); +static K_SEM_DEFINE(sem_disconnected, 0, 1); + +static struct bt_uuid_128 pawr_char_uuid = + BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1)); +static uint16_t pawr_attr_handle; +static const struct bt_le_per_adv_param per_adv_params = { + .interval_min = 0xFF, + .interval_max = 0xFF, + .options = 0, + .num_subevents = NUM_SUBEVENTS, + .subevent_interval = 0x30, + .response_slot_delay = 0x5, + .response_slot_spacing = 0x50, + .num_response_slots = NUM_RSP_SLOTS, +}; + +static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS]; +static struct net_buf_simple bufs[NUM_SUBEVENTS]; +static uint8_t backing_store[PACKET_SIZE][NUM_SUBEVENTS]; + +BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params)); +BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params)); + +static uint8_t counter; + +static void request_cb(struct bt_le_ext_adv *adv, const struct bt_le_per_adv_data_request *request) +{ + int err; + uint8_t to_send; + struct net_buf_simple *buf; + + to_send = MIN(request->count, ARRAY_SIZE(subevent_data_params)); + + for (size_t i = 0; i < to_send; i++) { + buf = &bufs[i]; + buf->data[buf->len - 1] = counter++; + + subevent_data_params[i].subevent = + (request->start + i) % per_adv_params.num_subevents; + subevent_data_params[i].response_slot_start = 0; + subevent_data_params[i].response_slot_count = NUM_RSP_SLOTS; + subevent_data_params[i].data = buf; + } + + err = bt_le_per_adv_set_subevent_data(adv, to_send, subevent_data_params); + if (err) { + printk("Failed to set subevent data (err %d)\n", err); + } else { + printk("Subevent data set %d\n", counter); + } +} + +static bool print_ad_field(struct bt_data *data, void *user_data) +{ + ARG_UNUSED(user_data); + + printk(" 0x%02X: ", data->type); + for (size_t i = 0; i < data->data_len; i++) { + printk("%02X", data->data[i]); + } + + printk("\n"); + + return true; +} + +static struct bt_conn *default_conn; + +static void response_cb(struct bt_le_ext_adv *adv, struct bt_le_per_adv_response_info *info, + struct net_buf_simple *buf) +{ + if (buf) { + printk("Response: subevent %d, slot %d\n", info->subevent, info->response_slot); + bt_data_parse(buf, print_ad_field, NULL); + } else { + printk("Failed to receive response: subevent %d, slot %d\n", info->subevent, + info->response_slot); + } +} + +static const struct bt_le_ext_adv_cb adv_cb = { + .pawr_data_request = request_cb, + .pawr_response = response_cb, +}; + +void connected_cb(struct bt_conn *conn, uint8_t err) +{ + printk("Connected (err 0x%02X)\n", err); + + __ASSERT(conn == default_conn, "Unexpected connected callback"); + + if (err) { + bt_conn_unref(default_conn); + default_conn = NULL; + } +} + +void disconnected_cb(struct bt_conn *conn, uint8_t reason) +{ + printk("Disconnected (reason 0x%02X)\n", reason); + + bt_conn_unref(default_conn); + default_conn = NULL; + + k_sem_give(&sem_disconnected); +} + +void remote_info_available_cb(struct bt_conn *conn, struct bt_conn_remote_info *remote_info) +{ + /* Need to wait for remote info before initiating PAST */ + k_sem_give(&sem_connected); +} + +BT_CONN_CB_DEFINE(conn_cb) = { + .connected = connected_cb, + .disconnected = disconnected_cb, + .remote_info_available = remote_info_available_cb, +}; + +static bool data_cb(struct bt_data *data, void *user_data) +{ + char *name = user_data; + uint8_t len; + + switch (data->type) { + case BT_DATA_NAME_SHORTENED: + case BT_DATA_NAME_COMPLETE: + len = MIN(data->data_len, NAME_LEN - 1); + memcpy(name, data->data, len); + name[len] = '\0'; + return false; + default: + return true; + } +} + +static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, + struct net_buf_simple *ad) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + char name[NAME_LEN]; + int err; + + if (default_conn) { + return; + } + + /* We're only interested in connectable events */ + if (type != BT_GAP_ADV_TYPE_ADV_IND && type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) { + return; + } + + (void)memset(name, 0, sizeof(name)); + bt_data_parse(ad, data_cb, name); + + if (strcmp(name, "PAwR sync sample")) { + return; + } + + if (bt_le_scan_stop()) { + return; + } + + err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, + &default_conn); + if (err) { + printk("Create conn to %s failed (%u)\n", addr_str, err); + } +} + +static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr, + struct bt_gatt_discover_params *params) +{ + struct bt_gatt_chrc *chrc; + char str[BT_UUID_STR_LEN]; + + printk("Discovery: attr %p\n", attr); + + if (!attr) { + return BT_GATT_ITER_STOP; + } + + chrc = (struct bt_gatt_chrc *)attr->user_data; + + bt_uuid_to_str(chrc->uuid, str, sizeof(str)); + printk("UUID %s\n", str); + + if (!bt_uuid_cmp(chrc->uuid, &pawr_char_uuid.uuid)) { + pawr_attr_handle = chrc->value_handle; + + printk("Characteristic handle: %d\n", pawr_attr_handle); + + k_sem_give(&sem_discovered); + } + + return BT_GATT_ITER_STOP; +} + +static void write_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params) +{ + if (err) { + printk("Write failed (err %d)\n", err); + + return; + } + + k_sem_give(&sem_written); +} + +void init_bufs(void) +{ + for (size_t i = 0; i < ARRAY_SIZE(backing_store); i++) { + backing_store[i][0] = ARRAY_SIZE(backing_store[i]) - 1; + backing_store[i][1] = BT_DATA_MANUFACTURER_DATA; + backing_store[i][2] = 0x59; /* Nordic */ + backing_store[i][3] = 0x00; + + net_buf_simple_init_with_data(&bufs[i], &backing_store[i], + ARRAY_SIZE(backing_store[i])); + } +} + +#define MAX_SYNCS (NUM_SUBEVENTS * NUM_RSP_SLOTS) +struct pawr_timing { + uint8_t subevent; + uint8_t response_slot; +} __packed; + +static uint8_t num_synced; + +void main(void) +{ + int err; + struct bt_le_ext_adv *pawr_adv; + struct bt_gatt_discover_params discover_params; + struct bt_gatt_write_params write_params; + struct pawr_timing sync_config; + + init_bufs(); + + printk("Starting Periodic Advertising Demo\n"); + + /* Initialize the Bluetooth Subsystem */ + err = bt_enable(NULL); + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + return; + } + + /* Create a non-connectable non-scannable advertising set */ + err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, &adv_cb, &pawr_adv); + if (err) { + printk("Failed to create advertising set (err %d)\n", err); + return; + } + + /* Set periodic advertising parameters */ + err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params); + if (err) { + printk("Failed to set periodic advertising parameters (err %d)\n", err); + return; + } + + /* Enable Periodic Advertising */ + err = bt_le_per_adv_start(pawr_adv); + if (err) { + printk("Failed to enable periodic advertising (err %d)\n", err); + return; + } + + printk("Start Periodic Advertising\n"); + err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err) { + printk("Failed to start extended advertising (err %d)\n", err); + return; + } + + while (num_synced < MAX_SYNCS) { + err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); + if (err) { + printk("Scanning failed to start (err %d)\n", err); + return; + } + + printk("Scanning successfully started\n"); + + k_sem_take(&sem_connected, K_FOREVER); + + err = bt_le_per_adv_set_info_transfer(pawr_adv, default_conn, 0); + if (err) { + printk("Failed to send PAST (err %d)\n", err); + + goto disconnect; + } + + printk("PAST sent\n"); + + discover_params.uuid = &pawr_char_uuid.uuid; + discover_params.func = discover_func; + discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; + discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; + discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; + err = bt_gatt_discover(default_conn, &discover_params); + if (err) { + printk("Discovery failed (err %d)\n", err); + + goto disconnect; + } + + printk("Discovery started\n"); + + err = k_sem_take(&sem_discovered, K_SECONDS(10)); + if (err) { + printk("Timed out during GATT discovery\n"); + + goto disconnect; + } + + sync_config.subevent = num_synced % NUM_SUBEVENTS; + sync_config.response_slot = num_synced / NUM_RSP_SLOTS; + num_synced++; + + write_params.func = write_func; + write_params.handle = pawr_attr_handle; + write_params.offset = 0; + write_params.data = &sync_config; + write_params.length = sizeof(sync_config); + + err = bt_gatt_write(default_conn, &write_params); + if (err) { + printk("Write failed (err %d)\n", err); + num_synced--; + + goto disconnect; + } + + printk("Write started\n"); + + err = k_sem_take(&sem_written, K_SECONDS(10)); + if (err) { + printk("Timed out during GATT write\n"); + num_synced--; + + goto disconnect; + } + + printk("PAwR config written to sync %d, disconnecting\n", num_synced - 1); + +disconnect: + err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + if (err) { + return; + } + + k_sem_take(&sem_disconnected, K_FOREVER); + } + + printk("Maximum numnber of syncs onboarded\n"); + + while (true) { + k_sleep(K_SECONDS(1)); + } +} diff --git a/samples/bluetooth/periodic_sync_rsp/CMakeLists.txt b/samples/bluetooth/periodic_sync_rsp/CMakeLists.txt new file mode 100644 index 000000000000..ab801447a2b9 --- /dev/null +++ b/samples/bluetooth/periodic_sync_rsp/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(periodic_sync) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/periodic_sync_rsp/README.rst b/samples/bluetooth/periodic_sync_rsp/README.rst new file mode 100644 index 000000000000..787061f2e3ae --- /dev/null +++ b/samples/bluetooth/periodic_sync_rsp/README.rst @@ -0,0 +1,40 @@ +.. _bluetooth-periodic-advertising-sync-rsp-sample: + +Bluetooth: Periodic Advertising with Responses (PAwR) Synchronization +##################################################################### + +Overview +******** + +A simple application demonstrating the BLE Periodic Advertising with +Responses Synchronization functionality. + +This sample will echo the data received in subevent indications back to the +advertiser. + +Which subevent to listen to and in which response slot to respond is +application specific. In this sample it is decided by the PAwR advertiser. +Upon connection it will write to a GATT characteristic +the assigned subevent and response slot. + +Flash this sample to multiple devices and they will be given different +subevents and response slots, to that they can communicate with the +advertiser concurrently. + +Requirements +************ + +* A board with BLE support +* A controller that supports the Periodic Advertising with Responses (PAwR) - Scanner feature + +Building and Running +******************** + +This sample can be found under :zephyr_file:`samples/bluetooth/periodic_sync_rsp` in +the Zephyr tree. + +Use the sample found under :zephyr_file:`samples/bluetooth/periodic_adv_rsp` on +another board that will start periodic advertising, which will connect to this +sample and transfer the synchronization info. + +See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/periodic_sync_rsp/prj.conf b/samples/bluetooth/periodic_sync_rsp/prj.conf new file mode 100644 index 000000000000..bd4f97e60d94 --- /dev/null +++ b/samples/bluetooth/periodic_sync_rsp/prj.conf @@ -0,0 +1,16 @@ +CONFIG_BT=y +CONFIG_BT_OBSERVER=y +CONFIG_BT_BROADCASTER=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PER_ADV_SYNC=y +CONFIG_BT_DEVICE_NAME="PAwR sync sample" + +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y +CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER=y + +CONFIG_BT_PER_ADV_SYNC_RSP=y +CONFIG_BT_PER_ADV_SYNC_BUF_SIZE=247 + +CONFIG_LOG=y diff --git a/samples/bluetooth/periodic_sync_rsp/sample.yaml b/samples/bluetooth/periodic_sync_rsp/sample.yaml new file mode 100644 index 000000000000..8146eeecdbf2 --- /dev/null +++ b/samples/bluetooth/periodic_sync_rsp/sample.yaml @@ -0,0 +1,12 @@ +sample: + name: Bluetooth Periodic Advertising with Responses Synchronization +tests: + sample.bluetooth.periodic_sync: + harness: bluetooth + platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840 + tags: bluetooth + integration_platforms: + - nrf52840dk_nrf52840 + extra_configs: + - CONFIG_BT_CTLR=n + - CONFIG_BT_NO_DRIVER=y diff --git a/samples/bluetooth/periodic_sync_rsp/src/main.c b/samples/bluetooth/periodic_sync_rsp/src/main.c new file mode 100644 index 000000000000..a4a8a1cb852e --- /dev/null +++ b/samples/bluetooth/periodic_sync_rsp/src/main.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#define NAME_LEN 30 + +static K_SEM_DEFINE(sem_per_adv, 0, 1); +static K_SEM_DEFINE(sem_per_sync, 0, 1); +static K_SEM_DEFINE(sem_per_sync_lost, 0, 1); + +static struct bt_conn *default_conn; +static struct bt_le_per_adv_sync *default_sync; +static struct __packed { + uint8_t subevent; + uint8_t response_slot; + +} pawr_timing; + +static void sync_cb(struct bt_le_per_adv_sync *sync, struct bt_le_per_adv_sync_synced_info *info) +{ + struct bt_le_per_adv_sync_subevent_params params; + uint8_t subevents[1]; + char le_addr[BT_ADDR_LE_STR_LEN]; + int err; + + bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); + printk("Synced to %s with %d subevents\n", le_addr, info->num_subevents); + + default_sync = sync; + + params.properties = 0; + params.num_subevents = 1; + params.subevents = subevents; + subevents[0] = pawr_timing.subevent; + + err = bt_le_per_adv_sync_subevent(sync, ¶ms); + if (err) { + printk("Failed to set subevents to sync to (err %d)\n", err); + } + + k_sem_give(&sem_per_sync); +} + +static void term_cb(struct bt_le_per_adv_sync *sync, + const struct bt_le_per_adv_sync_term_info *info) +{ + char le_addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); + + printk("Sync terminated (reason %d)\n", info->reason); + + default_sync = NULL; + + k_sem_give(&sem_per_sync_lost); +} + +static bool print_ad_field(struct bt_data *data, void *user_data) +{ + ARG_UNUSED(user_data); + + printk(" 0x%02X: ", data->type); + for (size_t i = 0; i < data->data_len; i++) { + printk("%02X", data->data[i]); + } + + printk("\n"); + + return true; +} + +int bt_le_per_adv_set_response_data(struct bt_le_per_adv_sync *per_adv_sync, + const struct bt_le_per_adv_response_params *params, + const struct net_buf_simple *data); + +static struct bt_le_per_adv_response_params rsp_params; + +NET_BUF_SIMPLE_DEFINE_STATIC(rsp_buf, 247); + +static void recv_cb(struct bt_le_per_adv_sync *sync, + const struct bt_le_per_adv_sync_recv_info *info, struct net_buf_simple *buf) +{ + int err; + + if (buf && buf->len) { + /* Echo the data back to the advertiser */ + net_buf_simple_reset(&rsp_buf); + net_buf_simple_add_mem(&rsp_buf, buf->data, buf->len); + + rsp_params.request_event = info->periodic_event_counter; + rsp_params.request_subevent = info->subevent; + /* Respond in current subevent and assigned response slot */ + rsp_params.response_subevent = info->subevent; + rsp_params.response_slot = pawr_timing.response_slot; + + printk("Indication: subevent %d, responding in slot %d\n", info->subevent, + pawr_timing.response_slot); + bt_data_parse(buf, print_ad_field, NULL); + + err = bt_le_per_adv_set_response_data(sync, &rsp_params, &rsp_buf); + if (err) { + printk("Failed to send response (err %d)\n", err); + } + } else if (buf) { + printk("Received empty indication: subevent %d\n", info->subevent); + } else { + printk("Failed to receive indication: subevent %d\n", info->subevent); + } +} + +static struct bt_le_per_adv_sync_cb sync_callbacks = { + .synced = sync_cb, + .term = term_cb, + .recv = recv_cb, +}; + +static struct bt_uuid_128 pawr_svc_uuid = + BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0)); +static struct bt_uuid_128 pawr_char_uuid = + BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1)); + +static ssize_t write_timing(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, + uint16_t len, uint16_t offset, uint8_t flags) +{ + if (offset) { + return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + } + + if (len != sizeof(pawr_timing)) { + return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + } + + memcpy(&pawr_timing, buf, len); + + printk("New timing: subevent %d, response slot %d\n", pawr_timing.subevent, + pawr_timing.response_slot); + + struct bt_le_per_adv_sync_subevent_params params; + uint8_t subevents[1]; + int err; + + params.properties = 0; + params.num_subevents = 1; + params.subevents = subevents; + subevents[0] = pawr_timing.subevent; + + if (default_sync) { + err = bt_le_per_adv_sync_subevent(default_sync, ¶ms); + if (err) { + printk("Failed to set subevents to sync to (err %d)\n", err); + } + } else { + printk("Not synced yet\n"); + } + + return len; +} + +BT_GATT_SERVICE_DEFINE(pawr_svc, BT_GATT_PRIMARY_SERVICE(&pawr_svc_uuid.uuid), + BT_GATT_CHARACTERISTIC(&pawr_char_uuid.uuid, BT_GATT_CHRC_WRITE, + BT_GATT_PERM_WRITE, NULL, write_timing, + &pawr_timing)); + +void connected(struct bt_conn *conn, uint8_t err) +{ + printk("Connected (err 0x%02X)\n", err); + + if (err) { + default_conn = NULL; + + return; + } + + default_conn = bt_conn_ref(conn); +} + +void disconnected(struct bt_conn *conn, uint8_t reason) +{ + bt_conn_unref(default_conn); + default_conn = NULL; + + printk("Disconnected (reason 0x%02X)\n", reason); +} + +BT_CONN_CB_DEFINE(conn_cb) = { + .connected = connected, + .disconnected = disconnected, +}; + +void main(void) +{ + struct bt_le_per_adv_sync_transfer_param past_param; + int err; + + printk("Starting Periodic Advertising with Responses Synchronization Demo\n"); + + err = bt_enable(NULL); + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + + return; + } + + bt_le_per_adv_sync_cb_register(&sync_callbacks); + + past_param.skip = 1; + past_param.timeout = 1000; /* 10 seconds */ + past_param.options = BT_LE_PER_ADV_SYNC_TRANSFER_OPT_NONE; + err = bt_le_per_adv_sync_transfer_subscribe(NULL, &past_param); + if (err) { + printk("PAST subscribe failed (err %d)\n", err); + + return; + } + + do { + err = bt_le_adv_start( + BT_LE_ADV_PARAM(BT_LE_ADV_OPT_ONE_TIME | BT_LE_ADV_OPT_CONNECTABLE | + BT_LE_ADV_OPT_USE_NAME | + BT_LE_ADV_OPT_FORCE_NAME_IN_AD, + BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, NULL), + NULL, 0, NULL, 0); + if (err && err != -EALREADY) { + printk("Advertising failed to start (err %d)\n", err); + + return; + } + + printk("Waiting for periodic sync...\n"); + err = k_sem_take(&sem_per_sync, K_SECONDS(10)); + if (err) { + printk("Timed out while synchronizing\n"); + + continue; + } + + printk("Periodic sync established.\n"); + + err = k_sem_take(&sem_per_sync_lost, K_FOREVER); + if (err) { + printk("failed (err %d)\n", err); + + return; + } + + printk("Periodic sync lost.\n"); + } while (true); +} From 39cd3a2a915556fe170e709d63da1bb815f0043a Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Thu, 20 Apr 2023 16:58:03 +0200 Subject: [PATCH 054/528] [nrf fromtree] Bluetooth: Host: Fix periodic sync reassembly The reassembly buffer for periodic sync was not initialized if the sync was established via PAST. Move the initialization of the reassembly buffer to a common place. Signed-off-by: Herman Berget (cherry picked from commit e745439c40734009986bb31b3789a536174bb50c) (cherry picked from commit 4c9facbc4c715b5139265d492a16dc56def053c9) --- subsys/bluetooth/host/scan.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 3b2fdb543237..00f0147a35af 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -717,6 +717,13 @@ static struct bt_le_per_adv_sync *per_adv_sync_new(void) (void)memset(per_adv_sync, 0, sizeof(*per_adv_sync)); atomic_set_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CREATED); +#if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 + net_buf_simple_init_with_data(&per_adv_sync->reassembly, + per_adv_sync->reassembly_data, + CONFIG_BT_PER_ADV_SYNC_BUF_SIZE); + net_buf_simple_reset(&per_adv_sync->reassembly); +#endif /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */ + return per_adv_sync; } @@ -1016,12 +1023,6 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) } pending_per_adv_sync->report_truncated = false; -#if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 - net_buf_simple_init_with_data(&pending_per_adv_sync->reassembly, - pending_per_adv_sync->reassembly_data, - CONFIG_BT_PER_ADV_SYNC_BUF_SIZE); - net_buf_simple_reset(&pending_per_adv_sync->reassembly); -#endif /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */ atomic_set_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCED); From 1bf676d9c1d4e2a32087aa7a74baa4b397e74575 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Thu, 30 Mar 2023 14:06:14 +0200 Subject: [PATCH 055/528] [nrf fromtree] Bluetooth: Host: Add support for initiating connections from PAwR This is known as the Periodic Advertising Connection Procedure. The PAwR advertiser can initiate a connection to a synced device and become the central. Signed-off-by: Herman Berget (cherry picked from commit c961e2c2129b4f0c1e5ff2db9df55c8366773984) (cherry picked from commit a0dee1dbb8c034cc1f2d1b807dcd806af6c0b590) --- include/zephyr/bluetooth/conn.h | 34 +++++++ include/zephyr/bluetooth/hci.h | 28 ++++++ subsys/bluetooth/host/adv.c | 2 + subsys/bluetooth/host/conn.c | 101 ++++++++++++++++--- subsys/bluetooth/host/hci_core.c | 160 +++++++++++++++++++++++++------ subsys/bluetooth/host/hci_core.h | 7 ++ 6 files changed, 289 insertions(+), 43 deletions(-) diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index dd0c1f8f182c..1ee7cda5f176 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -709,6 +709,40 @@ int bt_conn_le_create(const bt_addr_le_t *peer, const struct bt_le_conn_param *conn_param, struct bt_conn **conn); +struct bt_conn_le_create_synced_param { + + /** @brief Remote address + * + * The peer must be synchronized to the PAwR train. + * + */ + const bt_addr_le_t *peer; + + /** The subevent where the connection will be initiated. */ + uint8_t subevent; +}; + +/** @brief Create a connection to a synced device + * + * Initiate a connection to a synced device from a Periodic Advertising + * with Responses (PAwR) train. + * + * The caller gets a new reference to the connection object which must be + * released with bt_conn_unref() once done using the object. + * + * This uses the Periodic Advertising Connection Procedure. + * + * @param[in] adv The adverting set the PAwR advertiser belongs to. + * @param[in] synced_param Create connection parameters. + * @param[in] conn_param Initial connection parameters. + * @param[out] conn Valid connection object on success. + * + * @return Zero on success or (negative) error code on failure. + */ +int bt_conn_le_create_synced(const struct bt_le_ext_adv *adv, + const struct bt_conn_le_create_synced_param *synced_param, + const struct bt_le_conn_param *conn_param, struct bt_conn **conn); + /** @brief Automatically connect to remote devices in the filter accept list.. * * This uses the Auto Connection Establishment procedure. diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index 375e10a81572..70fa845027a9 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -1480,6 +1480,7 @@ struct bt_hci_cp_le_set_ext_scan_enable { } __packed; #define BT_HCI_OP_LE_EXT_CREATE_CONN BT_OP(BT_OGF_LE, 0x0043) +#define BT_HCI_OP_LE_EXT_CREATE_CONN_V2 BT_OP(BT_OGF_LE, 0x0085) struct bt_hci_ext_conn_phy { uint16_t scan_interval; uint16_t scan_window; @@ -1499,6 +1500,16 @@ struct bt_hci_cp_le_ext_create_conn { struct bt_hci_ext_conn_phy p[0]; } __packed; +struct bt_hci_cp_le_ext_create_conn_v2 { + uint8_t adv_handle; + uint8_t subevent; + uint8_t filter_policy; + uint8_t own_addr_type; + bt_addr_le_t peer_addr; + uint8_t phys; + struct bt_hci_ext_conn_phy p[0]; +} __packed; + #define BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA BT_OP(BT_OGF_LE, 0x0082) struct bt_hci_cp_le_set_pawr_subevent_data_element { uint8_t subevent; @@ -2426,6 +2437,22 @@ struct bt_hci_evt_le_per_adv_response_report { struct bt_hci_evt_le_per_adv_response responses[0]; } __packed; +#define BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2 0x29 +struct bt_hci_evt_le_enh_conn_complete_v2 { + uint8_t status; + uint16_t handle; + uint8_t role; + bt_addr_le_t peer_addr; + bt_addr_t local_rpa; + bt_addr_t peer_rpa; + uint16_t interval; + uint16_t latency; + uint16_t supv_timeout; + uint8_t clock_accuracy; + uint8_t adv_handle; + uint16_t sync_handle; +} __packed; + #define BT_HCI_EVT_SYNC_CONN_COMPLETE 0x2c struct bt_hci_evt_sync_conn_complete { uint8_t status; @@ -2955,6 +2982,7 @@ struct bt_hci_evt_le_biginfo_adv_report { #define BT_EVT_MASK_LE_PAST_RECEIVED_V2 BT_EVT_BIT(37) #define BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ BT_EVT_BIT(38) #define BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT BT_EVT_BIT(39) +#define BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2 BT_EVT_BIT(40) /** Allocate a HCI command buffer. * diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 7963b39f99b9..619a9170fd96 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -1153,6 +1153,8 @@ static int le_ext_adv_param_set(struct bt_le_ext_adv *adv, cp->filter_policy = get_filter_policy(param->options); cp->tx_power = BT_HCI_LE_ADV_TX_POWER_NO_PREF; + adv->options = param->options; + cp->prim_adv_phy = BT_HCI_LE_PHY_1M; if (param->options & BT_LE_ADV_OPT_EXT_ADV) { if (param->options & BT_LE_ADV_OPT_NO_2M) { diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 54b05cbdb460..10d894a4444b 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1135,7 +1135,8 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) * will handle connection timeout. */ if (IS_ENABLED(CONFIG_BT_CENTRAL) && - conn->type == BT_CONN_TYPE_LE) { + conn->type == BT_CONN_TYPE_LE && + bt_dev.create_param.timeout != 0) { k_work_schedule(&conn->deferred_work, K_MSEC(10 * bt_dev.create_param.timeout)); } @@ -2812,14 +2813,9 @@ int bt_conn_create_auto_stop(void) } #endif /* defined(CONFIG_BT_FILTER_ACCEPT_LIST) */ -int bt_conn_le_create(const bt_addr_le_t *peer, - const struct bt_conn_le_create_param *create_param, - const struct bt_le_conn_param *conn_param, - struct bt_conn **ret_conn) +static int conn_le_create_common_checks(const bt_addr_le_t *peer, + const struct bt_le_conn_param *conn_param) { - struct bt_conn *conn; - bt_addr_le_t dst; - int err; if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) { return -EAGAIN; @@ -2829,10 +2825,6 @@ int bt_conn_le_create(const bt_addr_le_t *peer, return -EINVAL; } - if (!create_param_validate(create_param)) { - return -EINVAL; - } - if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { return -EAGAIN; } @@ -2849,6 +2841,15 @@ int bt_conn_le_create(const bt_addr_le_t *peer, return -EINVAL; } + return 0; +} + +static struct bt_conn *conn_le_create_helper(const bt_addr_le_t *peer, + const struct bt_le_conn_param *conn_param) +{ + bt_addr_le_t dst; + struct bt_conn *conn; + if (bt_addr_le_is_resolved(peer)) { bt_addr_le_copy_resolved(&dst, peer); } else { @@ -2858,10 +2859,34 @@ int bt_conn_le_create(const bt_addr_le_t *peer, /* Only default identity supported for now */ conn = bt_conn_add_le(BT_ID_DEFAULT, &dst); if (!conn) { - return -ENOMEM; + return NULL; } bt_conn_set_param_le(conn, conn_param); + + return conn; +} + +int bt_conn_le_create(const bt_addr_le_t *peer, const struct bt_conn_le_create_param *create_param, + const struct bt_le_conn_param *conn_param, struct bt_conn **ret_conn) +{ + struct bt_conn *conn; + int err; + + err = conn_le_create_common_checks(peer, conn_param); + if (err) { + return err; + } + + if (!create_param_validate(create_param)) { + return -EINVAL; + } + + conn = conn_le_create_helper(peer, conn_param); + if (!conn) { + return -ENOMEM; + } + create_param_setup(create_param); #if defined(CONFIG_BT_SMP) @@ -2898,6 +2923,56 @@ int bt_conn_le_create(const bt_addr_le_t *peer, return 0; } +int bt_conn_le_create_synced(const struct bt_le_ext_adv *adv, + const struct bt_conn_le_create_synced_param *synced_param, + const struct bt_le_conn_param *conn_param, struct bt_conn **ret_conn) +{ + struct bt_conn *conn; + int err; + + err = conn_le_create_common_checks(synced_param->peer, conn_param); + if (err) { + return err; + } + + if (!atomic_test_bit(adv->flags, BT_PER_ADV_ENABLED)) { + return -EINVAL; + } + + if (!BT_FEAT_LE_PAWR_ADVERTISER(bt_dev.le.features)) { + return -ENOTSUP; + } + + if (synced_param->subevent >= BT_HCI_PAWR_SUBEVENT_MAX) { + return -EINVAL; + } + + conn = conn_le_create_helper(synced_param->peer, conn_param); + if (!conn) { + return -ENOMEM; + } + + /* The connection creation timeout is not really useful for PAwR. + * The controller will give a result for the connection attempt + * within a periodic interval. We do not know the periodic interval + * used, so disable the timeout. + */ + bt_dev.create_param.timeout = 0; + bt_conn_set_state(conn, BT_CONN_CONNECTING); + + err = bt_le_create_conn_synced(conn, adv, synced_param->subevent); + if (err) { + conn->err = 0; + bt_conn_set_state(conn, BT_CONN_DISCONNECTED); + bt_conn_unref(conn); + + return err; + } + + *ret_conn = conn; + return 0; +} + #if !defined(CONFIG_BT_FILTER_ACCEPT_LIST) int bt_le_set_auto_conn(const bt_addr_le_t *addr, const struct bt_le_conn_param *param) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 9457c52ce21a..024720547b3d 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -630,6 +630,52 @@ int bt_le_create_conn_ext(const struct bt_conn *conn) return bt_hci_cmd_send_sync(BT_HCI_OP_LE_EXT_CREATE_CONN, buf, NULL); } +int bt_le_create_conn_synced(const struct bt_conn *conn, const struct bt_le_ext_adv *adv, + uint8_t subevent) +{ + struct bt_hci_cp_le_ext_create_conn_v2 *cp; + struct bt_hci_ext_conn_phy *phy; + struct bt_hci_cmd_state_set state; + struct net_buf *buf; + uint8_t own_addr_type; + int err; + + err = bt_id_set_create_conn_own_addr(false, &own_addr_type); + if (err) { + return err; + } + + /* There shall only be one Initiating_PHYs */ + buf = bt_hci_cmd_create(BT_HCI_OP_LE_EXT_CREATE_CONN_V2, sizeof(*cp) + sizeof(*phy)); + if (!buf) { + return -ENOBUFS; + } + + cp = net_buf_add(buf, sizeof(*cp)); + (void)memset(cp, 0, sizeof(*cp)); + + bt_addr_le_copy(&cp->peer_addr, &conn->le.dst); + cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_NO_FILTER; + cp->own_addr_type = own_addr_type; + + /* The Initiating_PHY is the secondary phy of the corresponding ext adv set */ + if (adv->options & BT_LE_ADV_OPT_CODED) { + cp->phys = BT_HCI_LE_EXT_SCAN_PHY_CODED; + } else if (adv->options & BT_LE_ADV_OPT_NO_2M) { + cp->phys = BT_HCI_LE_EXT_SCAN_PHY_1M; + } else { + cp->phys = BT_HCI_LE_EXT_SCAN_PHY_2M; + } + + phy = net_buf_add(buf, sizeof(*phy)); + (void)memset(phy, 0, sizeof(*phy)); + set_phy_conn_param(conn, phy); + + bt_hci_cmd_state_set_init(buf, &state, bt_dev.flags, BT_DEV_INITIATING, true); + + return bt_hci_cmd_send_sync(BT_HCI_OP_LE_EXT_CREATE_CONN_V2, buf, NULL); +} + static int bt_le_create_conn_legacy(const struct bt_conn *conn) { struct bt_hci_cp_le_create_conn *cp; @@ -1070,7 +1116,7 @@ static void conn_auto_initiate(struct bt_conn *conn) } } -static void le_conn_complete_cancel(void) +static void le_conn_complete_cancel(uint8_t err) { struct bt_conn *conn; @@ -1085,7 +1131,7 @@ static void le_conn_complete_cancel(void) return; } - conn->err = BT_HCI_ERR_UNKNOWN_CONN_ID; + conn->err = err; /* Handle cancellation of outgoing connection attempt. */ if (!IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST)) { @@ -1180,12 +1226,46 @@ static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) bt_hci_le_enh_conn_complete(evt); } +static void translate_addrs(bt_addr_le_t *peer_addr, bt_addr_le_t *id_addr, + const struct bt_hci_evt_le_enh_conn_complete *evt, uint8_t id) +{ + if (bt_addr_le_is_resolved(&evt->peer_addr)) { + bt_addr_le_copy_resolved(id_addr, &evt->peer_addr); + + bt_addr_copy(&peer_addr->a, &evt->peer_rpa); + peer_addr->type = BT_ADDR_LE_RANDOM; + } else { + bt_addr_le_copy(id_addr, bt_lookup_id_addr(id, &evt->peer_addr)); + bt_addr_le_copy(peer_addr, &evt->peer_addr); + } +} + +static void update_conn(struct bt_conn *conn, const bt_addr_le_t *id_addr, + const struct bt_hci_evt_le_enh_conn_complete *evt) +{ + conn->handle = sys_le16_to_cpu(evt->handle); + bt_addr_le_copy(&conn->le.dst, id_addr); + conn->le.interval = sys_le16_to_cpu(evt->interval); + conn->le.latency = sys_le16_to_cpu(evt->latency); + conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout); + conn->role = evt->role; + conn->err = 0U; + +#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE) + conn->le.data_len.tx_max_len = BT_GAP_DATA_LEN_DEFAULT; + conn->le.data_len.tx_max_time = BT_GAP_DATA_TIME_DEFAULT; + conn->le.data_len.rx_max_len = BT_GAP_DATA_LEN_DEFAULT; + conn->le.data_len.rx_max_time = BT_GAP_DATA_TIME_DEFAULT; +#endif +} + void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) { uint16_t handle = sys_le16_to_cpu(evt->handle); bool is_disconnected = conn_handle_is_disconnected(handle); bt_addr_le_t peer_addr, id_addr; struct bt_conn *conn; + uint8_t id; LOG_DBG("status 0x%02x handle %u role %u peer %s peer RPA %s", evt->status, handle, evt->role, bt_addr_le_str(&evt->peer_addr), bt_addr_str(&evt->peer_rpa)); @@ -1204,30 +1284,28 @@ void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) if (IS_ENABLED(CONFIG_BT_CENTRAL) && evt->status == BT_HCI_ERR_UNKNOWN_CONN_ID) { - le_conn_complete_cancel(); + le_conn_complete_cancel(evt->status); bt_le_scan_update(false); return; } - LOG_WRN("Unexpected status 0x%02x", evt->status); + if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PER_ADV_RSP) && + evt->status == BT_HCI_ERR_CONN_FAIL_TO_ESTAB) { + le_conn_complete_cancel(evt->status); - return; - } + atomic_clear_bit(bt_dev.flags, BT_DEV_INITIATING); - if (bt_addr_le_is_resolved(&evt->peer_addr)) { - bt_addr_le_copy_resolved(&id_addr, &evt->peer_addr); + return; + } - bt_addr_copy(&peer_addr.a, &evt->peer_rpa); - peer_addr.type = BT_ADDR_LE_RANDOM; - } else { - uint8_t id = evt->role == BT_HCI_ROLE_PERIPHERAL ? bt_dev.adv_conn_id : - BT_ID_DEFAULT; + LOG_WRN("Unexpected status 0x%02x", evt->status); - bt_addr_le_copy(&id_addr, - bt_lookup_id_addr(id, &evt->peer_addr)); - bt_addr_le_copy(&peer_addr, &evt->peer_addr); + return; } + id = evt->role == BT_HCI_ROLE_PERIPHERAL ? bt_dev.adv_conn_id : BT_ID_DEFAULT; + translate_addrs(&peer_addr, &id_addr, evt, id); + conn = find_pending_connect(evt->role, &id_addr); if (IS_ENABLED(CONFIG_BT_PERIPHERAL) && @@ -1256,20 +1334,7 @@ void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) return; } - conn->handle = handle; - bt_addr_le_copy(&conn->le.dst, &id_addr); - conn->le.interval = sys_le16_to_cpu(evt->interval); - conn->le.latency = sys_le16_to_cpu(evt->latency); - conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout); - conn->role = evt->role; - conn->err = 0U; - -#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE) - conn->le.data_len.tx_max_len = BT_GAP_DATA_LEN_DEFAULT; - conn->le.data_len.tx_max_time = BT_GAP_DATA_TIME_DEFAULT; - conn->le.data_len.rx_max_len = BT_GAP_DATA_LEN_DEFAULT; - conn->le.data_len.rx_max_time = BT_GAP_DATA_TIME_DEFAULT; -#endif + update_conn(conn, &id_addr, evt); #if defined(CONFIG_BT_USER_PHY_UPDATE) conn->le.phy.tx_phy = BT_GAP_LE_PHY_1M; @@ -1390,6 +1455,30 @@ static void le_enh_conn_complete(struct net_buf *buf) enh_conn_complete((void *)buf->data); } +#if defined(CONFIG_BT_PER_ADV_RSP) +static void le_enh_conn_complete_v2(struct net_buf *buf) +{ + struct bt_hci_evt_le_enh_conn_complete_v2 *evt = + (struct bt_hci_evt_le_enh_conn_complete_v2 *)buf->data; + + if (evt->adv_handle == BT_HCI_ADV_HANDLE_INVALID && + evt->sync_handle == BT_HCI_SYNC_HANDLE_INVALID) { + /* The connection was not created via PAwR, handle the event like v1 */ + enh_conn_complete((struct bt_hci_evt_le_enh_conn_complete *)evt); + } +#if defined(CONFIG_BT_PER_ADV_RSP) + else if (evt->adv_handle != BT_HCI_ADV_HANDLE_INVALID && + evt->sync_handle == BT_HCI_SYNC_HANDLE_INVALID) { + /* The connection was created via PAwR advertiser, it can be handled like v1 */ + enh_conn_complete((struct bt_hci_evt_le_enh_conn_complete *)evt); + } +#endif /* CONFIG_BT_PER_ADV_RSP */ + else { + LOG_ERR("Invalid connection complete event"); + } +} +#endif /* CONFIG_BT_PER_ADV_RSP */ + static void le_legacy_conn_complete(struct net_buf *buf) { struct bt_hci_evt_le_conn_complete *evt = (void *)buf->data; @@ -2341,6 +2430,12 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_RESPONSE_REPORT, bt_hci_le_per_adv_response_report, sizeof(struct bt_hci_evt_le_per_adv_response_report)), #endif /* CONFIG_BT_PER_ADV_RSP */ +#if defined(CONFIG_BT_CONN) +#if defined(CONFIG_BT_PER_ADV_RSP) + EVENT_HANDLER(BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2, le_enh_conn_complete_v2, + sizeof(struct bt_hci_evt_le_enh_conn_complete_v2)), +#endif /* CONFIG_BT_PER_ADV_RSP */ +#endif /* CONFIG_BT_CONN */ }; @@ -2926,6 +3021,11 @@ static int le_set_event_mask(void) mask |= BT_EVT_MASK_LE_PAST_RECEIVED_V2; } + if (IS_ENABLED(CONFIG_BT_CONN) && + IS_ENABLED(CONFIG_BT_PER_ADV_RSP)) { + mask |= BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2; + } + sys_put_le64(mask, cp_mask->events); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL); } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 18fd0e35b2a8..0859c342ddf4 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -156,6 +156,11 @@ struct bt_le_ext_adv { #endif /* defined(CONFIG_BT_EXT_ADV) */ struct k_work_delayable lim_adv_timeout_work; + + /** The options used to set the parameters for this advertising set + * @ref bt_le_adv_param + */ + uint32_t options; }; enum { @@ -429,6 +434,8 @@ int bt_le_scan_update(bool fast_scan); int bt_le_create_conn(const struct bt_conn *conn); int bt_le_create_conn_cancel(void); +int bt_le_create_conn_synced(const struct bt_conn *conn, const struct bt_le_ext_adv *adv, + uint8_t subevent); bool bt_addr_le_is_bonded(uint8_t id, const bt_addr_le_t *addr); const bt_addr_le_t *bt_lookup_id_addr(uint8_t id, const bt_addr_le_t *addr); From 0e9435e8031fa89f3f1c9d86a86deeb3f33ad824 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Thu, 30 Mar 2023 14:15:47 +0200 Subject: [PATCH 056/528] [nrf fromtree] Bluetooth: Host: Add support for receiving connections while synced The PAwR sync can receive a connection request from the PAwR advertiser and become peripheral. Signed-off-by: Herman Berget (cherry picked from commit d7218fe35926f29058bfbfb916831a44957584b5) (cherry picked from commit be2d6a38d57fb7e7750e2d7c4d63a9e0b6d83d57) --- subsys/bluetooth/host/hci_core.c | 109 +++++++++++++++++++++++++++++-- 1 file changed, 104 insertions(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 024720547b3d..1b9d97e2e1b9 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1450,12 +1450,95 @@ void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) } } +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) +void bt_hci_le_enh_conn_complete_sync(struct bt_hci_evt_le_enh_conn_complete_v2 *evt, + struct bt_le_per_adv_sync *sync) +{ + uint16_t handle = sys_le16_to_cpu(evt->handle); + bool is_disconnected = conn_handle_is_disconnected(handle); + bt_addr_le_t peer_addr, id_addr; + struct bt_conn *conn; + + if (!sync->num_subevents) { + LOG_ERR("Unexpected connection complete event"); + + return; + } + + conn = bt_conn_add_le(BT_ID_DEFAULT, BT_ADDR_LE_ANY); + if (!conn) { + LOG_ERR("Unable to allocate connection"); + /* Tell the controller to disconnect to keep it in sync with + * the host state and avoid a "rogue" connection. + */ + bt_hci_disconnect(handle, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + + return; + } + + LOG_DBG("status 0x%02x handle %u role %u peer %s peer RPA %s", evt->status, handle, + evt->role, bt_addr_le_str(&evt->peer_addr), bt_addr_str(&evt->peer_rpa)); + LOG_DBG("local RPA %s", bt_addr_str(&evt->local_rpa)); + + if (evt->role != BT_HCI_ROLE_PERIPHERAL) { + LOG_ERR("PAwR sync always becomes peripheral"); + + return; + } + +#if defined(CONFIG_BT_SMP) + bt_id_pending_keys_update(); +#endif + + if (evt->status) { + LOG_ERR("Unexpected status 0x%02x", evt->status); + + return; + } + + translate_addrs(&peer_addr, &id_addr, (const struct bt_hci_evt_le_enh_conn_complete *)evt, + BT_ID_DEFAULT); + update_conn(conn, &id_addr, (const struct bt_hci_evt_le_enh_conn_complete *)evt); + +#if defined(CONFIG_BT_USER_PHY_UPDATE) + /* The connection is always initated on the same phy as the PAwR advertiser */ + conn->le.phy.tx_phy = sync->phy; + conn->le.phy.rx_phy = sync->phy; +#endif + + bt_addr_le_copy(&conn->le.init_addr, &peer_addr); + + /* There is no random addr to get, set responder addr to local identity addr. */ + bt_addr_le_copy(&conn->le.resp_addr, &bt_dev.id_addr[conn->id]); + + bt_conn_set_state(conn, BT_CONN_CONNECTED); + + if (is_disconnected) { + /* Mark the connection as already disconnected before calling + * the connected callback, so that the application cannot + * start sending packets + */ + bt_conn_set_state(conn, BT_CONN_DISCONNECT_COMPLETE); + } + + bt_conn_connected(conn); + + /* Since we don't give the application a reference to manage + * for peripheral connections, we need to release this reference here. + */ + bt_conn_unref(conn); + + /* Start auto-initiated procedures */ + conn_auto_initiate(conn); +} +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ + static void le_enh_conn_complete(struct net_buf *buf) { enh_conn_complete((void *)buf->data); } -#if defined(CONFIG_BT_PER_ADV_RSP) +#if defined(CONFIG_BT_PER_ADV_RSP) || defined(CONFIG_BT_PER_ADV_SYNC_RSP) static void le_enh_conn_complete_v2(struct net_buf *buf) { struct bt_hci_evt_le_enh_conn_complete_v2 *evt = @@ -1473,11 +1556,27 @@ static void le_enh_conn_complete_v2(struct net_buf *buf) enh_conn_complete((struct bt_hci_evt_le_enh_conn_complete *)evt); } #endif /* CONFIG_BT_PER_ADV_RSP */ +#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) + else if (evt->adv_handle == BT_HCI_ADV_HANDLE_INVALID && + evt->sync_handle != BT_HCI_SYNC_HANDLE_INVALID) { + /* Created via PAwR sync, no adv set terminated event, needs separate handling */ + struct bt_le_per_adv_sync *sync; + + sync = bt_hci_get_per_adv_sync(evt->sync_handle); + if (!sync) { + LOG_ERR("Unknown sync handle %d", evt->sync_handle); + + return; + } + + bt_hci_le_enh_conn_complete_sync(evt, sync); + } +#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ else { LOG_ERR("Invalid connection complete event"); } } -#endif /* CONFIG_BT_PER_ADV_RSP */ +#endif /* CONFIG_BT_PER_ADV_RSP || CONFIG_BT_PER_ADV_SYNC_RSP */ static void le_legacy_conn_complete(struct net_buf *buf) { @@ -2431,10 +2530,10 @@ static const struct event_handler meta_events[] = { sizeof(struct bt_hci_evt_le_per_adv_response_report)), #endif /* CONFIG_BT_PER_ADV_RSP */ #if defined(CONFIG_BT_CONN) -#if defined(CONFIG_BT_PER_ADV_RSP) +#if defined(CONFIG_BT_PER_ADV_RSP) || defined(CONFIG_BT_PER_ADV_SYNC_RSP) EVENT_HANDLER(BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2, le_enh_conn_complete_v2, sizeof(struct bt_hci_evt_le_enh_conn_complete_v2)), -#endif /* CONFIG_BT_PER_ADV_RSP */ +#endif /* CONFIG_BT_PER_ADV_RSP || CONFIG_BT_PER_ADV_SYNC_RSP */ #endif /* CONFIG_BT_CONN */ }; @@ -3022,7 +3121,7 @@ static int le_set_event_mask(void) } if (IS_ENABLED(CONFIG_BT_CONN) && - IS_ENABLED(CONFIG_BT_PER_ADV_RSP)) { + (IS_ENABLED(CONFIG_BT_PER_ADV_RSP) || IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP))) { mask |= BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2; } From 50570ca2c19bd7029713db78222a7687b584b57a Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Fri, 21 Apr 2023 17:50:02 +0200 Subject: [PATCH 057/528] [nrf fromtree] Samples: Bluetooth: Add samples for PADV Connection Procedure Samples demonstrating initiating connections from PAwR. Signed-off-by: Herman Berget (cherry picked from commit 3c7b3e5648f9fd7dedc058b356bb598e1e247d66) (cherry picked from commit 01cb90f8f9aea2fdddcf1638f174187af97ccea0) --- .../periodic_adv_conn/CMakeLists.txt | 7 + .../bluetooth/periodic_adv_conn/README.rst | 32 +++ samples/bluetooth/periodic_adv_conn/prj.conf | 14 + .../bluetooth/periodic_adv_conn/sample.yaml | 12 + .../bluetooth/periodic_adv_conn/src/main.c | 210 ++++++++++++++ .../periodic_sync_conn/CMakeLists.txt | 7 + .../bluetooth/periodic_sync_conn/README.rst | 32 +++ samples/bluetooth/periodic_sync_conn/prj.conf | 15 + .../bluetooth/periodic_sync_conn/sample.yaml | 12 + .../bluetooth/periodic_sync_conn/src/main.c | 267 ++++++++++++++++++ 10 files changed, 608 insertions(+) create mode 100644 samples/bluetooth/periodic_adv_conn/CMakeLists.txt create mode 100644 samples/bluetooth/periodic_adv_conn/README.rst create mode 100644 samples/bluetooth/periodic_adv_conn/prj.conf create mode 100644 samples/bluetooth/periodic_adv_conn/sample.yaml create mode 100644 samples/bluetooth/periodic_adv_conn/src/main.c create mode 100644 samples/bluetooth/periodic_sync_conn/CMakeLists.txt create mode 100644 samples/bluetooth/periodic_sync_conn/README.rst create mode 100644 samples/bluetooth/periodic_sync_conn/prj.conf create mode 100644 samples/bluetooth/periodic_sync_conn/sample.yaml create mode 100644 samples/bluetooth/periodic_sync_conn/src/main.c diff --git a/samples/bluetooth/periodic_adv_conn/CMakeLists.txt b/samples/bluetooth/periodic_adv_conn/CMakeLists.txt new file mode 100644 index 000000000000..796bd5e5d8ed --- /dev/null +++ b/samples/bluetooth/periodic_adv_conn/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(periodic_adv) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/periodic_adv_conn/README.rst b/samples/bluetooth/periodic_adv_conn/README.rst new file mode 100644 index 000000000000..149e81439902 --- /dev/null +++ b/samples/bluetooth/periodic_adv_conn/README.rst @@ -0,0 +1,32 @@ +.. _bluetooth-periodic-advertising-conn-sample: + +Bluetooth: Periodic Advertising Connection Procedure - Initiator +################################################################ + +Overview +******** + +A simple application demonstrating the initiator side of the BLE +Periodic Advertising Connection Procedure. + +How the initiator decides the address of the synced device to connect to +is application specific. This sample will connect to any synced device +responding with its address. Once the connection is established, it will +wait for disconnect before connecting to another synced device. + +Requirements +************ + +* A board with BLE support +* A controller that supports the Periodic Advertising with Responses (PAwR) - Advertiser feature + +Building and Running +******************** + +This sample can be found under :zephyr_file:`samples/bluetooth/periodic_adv_conn` in +the Zephyr tree. + +Use the sample found under :zephyr_file:`samples/bluetooth/periodic_sync_conn` in the +Zephyr tree that will synchronize and respond to this sample. + +See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/periodic_adv_conn/prj.conf b/samples/bluetooth/periodic_adv_conn/prj.conf new file mode 100644 index 000000000000..2f5aed3551cf --- /dev/null +++ b/samples/bluetooth/periodic_adv_conn/prj.conf @@ -0,0 +1,14 @@ +CONFIG_BT=y +CONFIG_BT_BROADCASTER=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PER_ADV=y +CONFIG_BT_DEVICE_NAME="PAwR conn sample" +CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y +CONFIG_BT_PER_ADV_RSP=y + +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_CENTRAL=y +CONFIG_BT_PRIVACY=y +CONFIG_BT_SMP=y + +CONFIG_LOG=y diff --git a/samples/bluetooth/periodic_adv_conn/sample.yaml b/samples/bluetooth/periodic_adv_conn/sample.yaml new file mode 100644 index 000000000000..ff64f1d1208e --- /dev/null +++ b/samples/bluetooth/periodic_adv_conn/sample.yaml @@ -0,0 +1,12 @@ +sample: + name: Bluetooth Periodic Advertising with Responses Advertiser +tests: + sample.bluetooth.periodic_adv: + harness: bluetooth + platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840 + tags: bluetooth + integration_platforms: + - nrf52840dk_nrf52840 + extra_configs: + - CONFIG_BT_CTLR=n + - CONFIG_BT_NO_DRIVER=y diff --git a/samples/bluetooth/periodic_adv_conn/src/main.c b/samples/bluetooth/periodic_adv_conn/src/main.c new file mode 100644 index 000000000000..65b119062719 --- /dev/null +++ b/samples/bluetooth/periodic_adv_conn/src/main.c @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#define NUM_RSP_SLOTS 5 +#define NUM_SUBEVENTS 5 +#define PACKET_SIZE 5 +#define SUBEVENT_INTERVAL 0x30 + +static const struct bt_le_per_adv_param per_adv_params = { + .interval_min = 0xFF, + .interval_max = 0xFF, + .options = 0, + .num_subevents = NUM_SUBEVENTS, + .subevent_interval = SUBEVENT_INTERVAL, + .response_slot_delay = 0x5, + .response_slot_spacing = 0x50, + .num_response_slots = NUM_RSP_SLOTS, +}; + +static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS]; +static struct net_buf_simple bufs[NUM_SUBEVENTS]; +static uint8_t backing_store[PACKET_SIZE][NUM_SUBEVENTS]; + +BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params)); +BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params)); + +static void request_cb(struct bt_le_ext_adv *adv, const struct bt_le_per_adv_data_request *request) +{ + int err; + uint8_t to_send; + + /* Continuously send the same dummy data and listen to all response slots */ + + to_send = MIN(request->count, ARRAY_SIZE(subevent_data_params)); + for (size_t i = 0; i < to_send; i++) { + subevent_data_params[i].subevent = + (request->start + i) % per_adv_params.num_subevents; + subevent_data_params[i].response_slot_start = 0; + subevent_data_params[i].response_slot_count = NUM_RSP_SLOTS; + subevent_data_params[i].data = &bufs[i]; + } + + err = bt_le_per_adv_set_subevent_data(adv, to_send, subevent_data_params); + if (err) { + printk("Failed to set subevent data (err %d)\n", err); + } +} + +static bool get_address(struct bt_data *data, void *user_data) +{ + bt_addr_le_t *addr = user_data; + + if (data->type == BT_DATA_LE_BT_DEVICE_ADDRESS) { + memcpy(addr->a.val, data->data, sizeof(addr->a.val)); + addr->type = data->data[sizeof(addr->a)]; + + return false; + } + + return true; +} + +static struct bt_conn *default_conn; + +static void response_cb(struct bt_le_ext_adv *adv, struct bt_le_per_adv_response_info *info, + struct net_buf_simple *buf) +{ + int err; + bt_addr_le_t peer; + char addr_str[BT_ADDR_LE_STR_LEN]; + struct bt_conn_le_create_synced_param synced_param; + struct bt_le_conn_param conn_param; + + if (!buf) { + return; + } + + if (default_conn) { + /* Do not initiate new connections while already connected */ + return; + } + + bt_addr_le_copy(&peer, &bt_addr_le_none); + bt_data_parse(buf, get_address, &peer); + if (bt_addr_le_eq(&peer, &bt_addr_le_none)) { + /* No address found */ + return; + } + + bt_addr_le_to_str(&peer, addr_str, sizeof(addr_str)); + printk("Connecting to %s in subevent %d\n", addr_str, info->subevent); + + synced_param.peer = &peer; + synced_param.subevent = info->subevent; + + /* Choose same interval as PAwR advertiser to avoid scheduling conflicts */ + conn_param.interval_min = SUBEVENT_INTERVAL; + conn_param.interval_max = SUBEVENT_INTERVAL; + + /* Default values */ + conn_param.latency = 0; + conn_param.timeout = 400; + + err = bt_conn_le_create_synced(adv, &synced_param, &conn_param, &default_conn); + if (err) { + printk("Failed to initiate connection (err %d)", err); + } +} + +static const struct bt_le_ext_adv_cb adv_cb = { + .pawr_data_request = request_cb, + .pawr_response = response_cb, +}; + +static void connected_cb(struct bt_conn *conn, uint8_t err) +{ + printk("Connected (err 0x%02X)\n", err); + + __ASSERT(conn == default_conn, "Unexpected connected callback"); + + if (err) { + bt_conn_unref(default_conn); + default_conn = NULL; + } +} + +static void disconnected_cb(struct bt_conn *conn, uint8_t reason) +{ + printk("Disconnected (reason 0x%02X)\n", reason); + + __ASSERT(conn == default_conn, "Unexpected disconnected callback"); + + bt_conn_unref(default_conn); + default_conn = NULL; +} + +BT_CONN_CB_DEFINE(conn_cb) = { + .connected = connected_cb, + .disconnected = disconnected_cb, +}; + +static void init_bufs(void) +{ + /* Set up some dummy data to send */ + for (size_t i = 0; i < ARRAY_SIZE(backing_store); i++) { + backing_store[i][0] = ARRAY_SIZE(backing_store[i]) - 1; + backing_store[i][1] = BT_DATA_MANUFACTURER_DATA; + backing_store[i][2] = 0x59; /* Nordic */ + backing_store[i][3] = 0x00; + + net_buf_simple_init_with_data(&bufs[i], &backing_store[i], + ARRAY_SIZE(backing_store[i])); + } +} + +void main(void) +{ + int err; + struct bt_le_ext_adv *pawr_adv; + + init_bufs(); + + printk("Starting Periodic Advertising Demo\n"); + + /* Initialize the Bluetooth Subsystem */ + err = bt_enable(NULL); + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + return; + } + + /* Create a non-connectable non-scannable advertising set */ + err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, &adv_cb, &pawr_adv); + if (err) { + printk("Failed to create advertising set (err %d)\n", err); + return; + } + + /* Set periodic advertising parameters */ + err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params); + if (err) { + printk("Failed to set periodic advertising parameters (err %d)\n", err); + return; + } + + /* Enable Periodic Advertising */ + err = bt_le_per_adv_start(pawr_adv); + if (err) { + printk("Failed to enable periodic advertising (err %d)\n", err); + return; + } + + printk("Start Periodic Advertising\n"); + err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err) { + printk("Failed to start extended advertising (err %d)\n", err); + return; + } + + while (true) { + k_sleep(K_SECONDS(1)); + } +} diff --git a/samples/bluetooth/periodic_sync_conn/CMakeLists.txt b/samples/bluetooth/periodic_sync_conn/CMakeLists.txt new file mode 100644 index 000000000000..ab801447a2b9 --- /dev/null +++ b/samples/bluetooth/periodic_sync_conn/CMakeLists.txt @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(periodic_sync) + +target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/periodic_sync_conn/README.rst b/samples/bluetooth/periodic_sync_conn/README.rst new file mode 100644 index 000000000000..9f050ac38fb2 --- /dev/null +++ b/samples/bluetooth/periodic_sync_conn/README.rst @@ -0,0 +1,32 @@ +.. _bluetooth-periodic-advertising-sync-conn-sample: + +Bluetooth: Periodic Advertising Connection Procedure - Responder +##################################################################### + +Overview +******** + +A simple application demonstrating the responder side of the BLE +Periodic Advertising Connection Procedure. + +This sample will send its address in response to the advertiser when receiving +subevent data. Once the connection is established, it will disconnect and wait +for a new connection to be established. + +Requirements +************ + +* A board with BLE support +* A controller that supports the Periodic Advertising with Responses (PAwR) - Scanner feature + +Building and Running +******************** + +This sample can be found under :zephyr_file:`samples/bluetooth/periodic_sync_conn` in +the Zephyr tree. + +Use the sample found under :zephyr_file:`samples/bluetooth/periodic_adv_conn` on +another board that will start periodic advertising and connect to this sample +once synced. + +See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/periodic_sync_conn/prj.conf b/samples/bluetooth/periodic_sync_conn/prj.conf new file mode 100644 index 000000000000..16f52f609830 --- /dev/null +++ b/samples/bluetooth/periodic_sync_conn/prj.conf @@ -0,0 +1,15 @@ +CONFIG_BT=y +CONFIG_BT_OBSERVER=y +CONFIG_BT_EXT_ADV=y +CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y +CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER=y +CONFIG_BT_PER_ADV_SYNC=y +CONFIG_BT_PER_ADV_SYNC_RSP=y +CONFIG_BT_PER_ADV_SYNC_BUF_SIZE=247 + +CONFIG_BT_MAX_CONN=1 +CONFIG_BT_PERIPHERAL=y +CONFIG_BT_PRIVACY=y +CONFIG_BT_SMP=y + +CONFIG_LOG=y diff --git a/samples/bluetooth/periodic_sync_conn/sample.yaml b/samples/bluetooth/periodic_sync_conn/sample.yaml new file mode 100644 index 000000000000..8146eeecdbf2 --- /dev/null +++ b/samples/bluetooth/periodic_sync_conn/sample.yaml @@ -0,0 +1,12 @@ +sample: + name: Bluetooth Periodic Advertising with Responses Synchronization +tests: + sample.bluetooth.periodic_sync: + harness: bluetooth + platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840 + tags: bluetooth + integration_platforms: + - nrf52840dk_nrf52840 + extra_configs: + - CONFIG_BT_CTLR=n + - CONFIG_BT_NO_DRIVER=y diff --git a/samples/bluetooth/periodic_sync_conn/src/main.c b/samples/bluetooth/periodic_sync_conn/src/main.c new file mode 100644 index 000000000000..c5b964b1c957 --- /dev/null +++ b/samples/bluetooth/periodic_sync_conn/src/main.c @@ -0,0 +1,267 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +#define NAME_LEN 30 + +static K_SEM_DEFINE(sem_per_adv, 0, 1); +static K_SEM_DEFINE(sem_per_sync, 0, 1); +static K_SEM_DEFINE(sem_connected, 0, 1); +static K_SEM_DEFINE(sem_disconnected, 0, 1); + +static struct bt_conn *default_conn; +static bool per_adv_found; +static bt_addr_le_t per_addr; +static uint8_t per_sid; + +static void sync_cb(struct bt_le_per_adv_sync *sync, struct bt_le_per_adv_sync_synced_info *info) +{ + struct bt_le_per_adv_sync_subevent_params params; + uint8_t subevents[1]; + char le_addr[BT_ADDR_LE_STR_LEN]; + int err; + + bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); + printk("Synced to %s with %d subevents\n", le_addr, info->num_subevents); + + params.properties = 0; + params.num_subevents = 1; + params.subevents = subevents; + subevents[0] = 0; + err = bt_le_per_adv_sync_subevent(sync, ¶ms); + if (err) { + printk("Failed to set subevents to sync to (err %d)\n", err); + } + + k_sem_give(&sem_per_sync); +} + +static void term_cb(struct bt_le_per_adv_sync *sync, + const struct bt_le_per_adv_sync_term_info *info) +{ + char le_addr[BT_ADDR_LE_STR_LEN]; + + bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); + + printk("Sync terminated (reason %d)\n", info->reason); +} + +static struct bt_le_per_adv_response_params rsp_params; + +NET_BUF_SIMPLE_DEFINE_STATIC(rsp_buf, sizeof(bt_addr_le_t) + 2 * sizeof(uint8_t)); + +static void recv_cb(struct bt_le_per_adv_sync *sync, + const struct bt_le_per_adv_sync_recv_info *info, struct net_buf_simple *buf) +{ + int err; + struct bt_le_oob oob; + char addr_str[BT_ADDR_LE_STR_LEN]; + + if (default_conn) { + /* Only respond with address if not already connected */ + return; + } + + if (buf && buf->len) { + /* Respond with own address for the advertiser to connect to */ + net_buf_simple_reset(&rsp_buf); + + rsp_params.request_event = info->periodic_event_counter; + rsp_params.request_subevent = info->subevent; + rsp_params.response_subevent = info->subevent; + rsp_params.response_slot = 0; + + err = bt_le_oob_get_local(BT_ID_DEFAULT, &oob); + if (err) { + printk("Failed to get OOB data (err %d)\n", err); + + return; + } + + bt_addr_le_to_str(&oob.addr, addr_str, sizeof(addr_str)); + printk("Responding with own addr: %s\n", addr_str); + + net_buf_simple_add_u8(&rsp_buf, sizeof(bt_addr_le_t)); + net_buf_simple_add_u8(&rsp_buf, BT_DATA_LE_BT_DEVICE_ADDRESS); + net_buf_simple_add_mem(&rsp_buf, &oob.addr.a, sizeof(oob.addr.a)); + net_buf_simple_add_u8(&rsp_buf, oob.addr.type); + + err = bt_le_per_adv_set_response_data(sync, &rsp_params, &rsp_buf); + if (err) { + printk("Failed to send response (err %d)\n", err); + } + } else if (buf) { + printk("Received empty indication: subevent %d\n", info->subevent); + } else { + printk("Failed to receive indication: subevent %d\n", info->subevent); + } +} + +static struct bt_le_per_adv_sync_cb sync_callbacks = { + .synced = sync_cb, + .term = term_cb, + .recv = recv_cb, +}; + +static void connected_cb(struct bt_conn *conn, uint8_t err) +{ + printk("Connected (err 0x%02X)\n", err); + + if (err) { + return; + } + + default_conn = bt_conn_ref(conn); + k_sem_give(&sem_connected); +} + +static void disconnected_cb(struct bt_conn *conn, uint8_t reason) +{ + bt_conn_unref(default_conn); + default_conn = NULL; + + printk("Disconnected (reason 0x%02X)\n", reason); + + k_sem_give(&sem_disconnected); +} + +BT_CONN_CB_DEFINE(conn_cb) = { + .connected = connected_cb, + .disconnected = disconnected_cb, +}; + +static bool data_cb(struct bt_data *data, void *user_data) +{ + char *name = user_data; + uint8_t len; + + switch (data->type) { + case BT_DATA_NAME_SHORTENED: + case BT_DATA_NAME_COMPLETE: + len = MIN(data->data_len, NAME_LEN - 1); + memcpy(name, data->data, len); + name[len] = '\0'; + return false; + default: + return true; + } +} + +static void scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf) +{ + char name[NAME_LEN]; + + (void)memset(name, 0, sizeof(name)); + bt_data_parse(buf, data_cb, name); + + if (strcmp(name, "PAwR conn sample")) { + return; + } + + if (!per_adv_found && info->interval) { + per_adv_found = true; + + per_sid = info->sid; + bt_addr_le_copy(&per_addr, info->addr); + + k_sem_give(&sem_per_adv); + } +} + +static struct bt_le_scan_cb scan_callbacks = { + .recv = scan_recv, +}; + +int main(void) +{ + struct bt_le_per_adv_sync_param sync_create_param; + struct bt_le_per_adv_sync *sync; + int err; + + printk("Starting Periodic Advertising with Responses Synchronization Demo\n"); + + err = bt_enable(NULL); + if (err) { + printk("Bluetooth init failed (err %d)\n", err); + + return 0; + } + + bt_le_scan_cb_register(&scan_callbacks); + bt_le_per_adv_sync_cb_register(&sync_callbacks); + + err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL); + if (err) { + printk("failed (err %d)\n", err); + + return 0; + } + + err = k_sem_take(&sem_per_adv, K_FOREVER); + if (err) { + printk("failed (err %d)\n", err); + + return 0; + } + printk("Found periodic advertising.\n"); + + printk("Creating Periodic Advertising Sync"); + bt_addr_le_copy(&sync_create_param.addr, &per_addr); + sync_create_param.options = 0; + sync_create_param.sid = per_sid; + sync_create_param.skip = 0; + sync_create_param.timeout = 0xaa; + err = bt_le_per_adv_sync_create(&sync_create_param, &sync); + if (err) { + printk("Failed to create sync (err %d)\n", err); + + return 0; + } + + printk("Waiting for periodic sync\n"); + err = k_sem_take(&sem_per_sync, K_FOREVER); + if (err) { + printk("Failed (err %d)\n", err); + + return 0; + } + + printk("Periodic sync established.\n"); + + err = bt_le_scan_stop(); + if (err) { + printk("Failed to stop scanning (err %d)\n", err); + } + + printk("Stopped scanning\n"); + + do { + err = k_sem_take(&sem_connected, K_FOREVER); + if (err) { + printk("failed (err %d)\n", err); + + return 0; + } + + printk("Disconnecting\n"); + + err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); + if (err) { + return 0; + } + + err = k_sem_take(&sem_disconnected, K_FOREVER); + if (err) { + printk("failed (err %d)\n", err); + + return 0; + } + } while (true); +} From 435907725065d9da43c460d2550ed2edf4fdb97f Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Thu, 27 Apr 2023 09:03:05 +0200 Subject: [PATCH 058/528] [nrf fromtree] Bluetooth: Host: Fix typos and inaccuracies for PAwR Fixes some typos and inaccuracies in the PAwR docstrings. Signed-off-by: Herman Berget (cherry picked from commit 14406cc664a15419ee6591297ba7c7a6cc6f06c3) (cherry picked from commit 2637dac83acf3054d46e02464727a811d7a22f3f) --- include/zephyr/bluetooth/bluetooth.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 42ab174abc68..f93eb3d210cf 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -2595,8 +2595,8 @@ struct bt_le_per_adv_response_params { /** * @brief Set the data for a response slot in a specific subevent of the PAwR. * - * This function is called by the Host to set the response dat. - * The data for a repsonse slot shall be transmitted only once. + * This function is called by the application to set the response data. + * The data for a response slot shall be transmitted only once. * * @param per_adv_sync The periodic advertising sync object. * @param params Parameters. From 3dee54c3ca1b7eebde47d42d91a10d6f00fc742b Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Tue, 2 May 2023 12:52:59 +0200 Subject: [PATCH 059/528] [nrf fromtree] Bluetooth: Host: Fix sync subevent cmd length The subevents were not considered in the length of the command. Signed-off-by: Herman Berget (cherry picked from commit bf4e3fe2a485a9a55580d04e47e49bdc117d3b86) (cherry picked from commit 0833ad9900ff5b0ce3a118284eb2f2b52ee46557) --- subsys/bluetooth/host/scan.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 00f0147a35af..6630951ba8ed 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1092,7 +1092,12 @@ int bt_le_per_adv_sync_subevent(struct bt_le_per_adv_sync *per_adv_sync, struct bt_hci_cp_le_set_pawr_sync_subevent *cp; struct net_buf *buf; - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, sizeof(*cp)); + if (params->num_subevents > BT_HCI_PAWR_SUBEVENT_MAX) { + return -EINVAL; + } + + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, + sizeof(*cp) + params->num_subevents); if (!buf) { return -ENOBUFS; From d4c8639105054b2b562520e921ff3cef0d6a6808 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Wed, 3 May 2023 12:45:33 +0200 Subject: [PATCH 060/528] [nrf noup] samples: cleanup void main usage. Some samples got missed in the switch from void main() to int main(). Cleanup those samples to use int main(). Parts of upstream commit 340ed20c12198e6bdefbb483ca8880698a51e898, to be removed in next upmerge. Signed-off-by: Herman Berget (cherry picked from commit 4c11b1ac632c2b0e4bbf59d37b2bb2af4a90c3a1) --- samples/bluetooth/periodic_adv_conn/src/main.c | 14 ++++++++------ samples/bluetooth/periodic_adv_rsp/src/main.c | 18 ++++++++++-------- samples/bluetooth/periodic_sync_rsp/src/main.c | 12 +++++++----- 3 files changed, 25 insertions(+), 19 deletions(-) diff --git a/samples/bluetooth/periodic_adv_conn/src/main.c b/samples/bluetooth/periodic_adv_conn/src/main.c index 65b119062719..c1070009b2c2 100644 --- a/samples/bluetooth/periodic_adv_conn/src/main.c +++ b/samples/bluetooth/periodic_adv_conn/src/main.c @@ -160,7 +160,7 @@ static void init_bufs(void) } } -void main(void) +int main(void) { int err; struct bt_le_ext_adv *pawr_adv; @@ -173,38 +173,40 @@ void main(void) err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); - return; + return 0; } /* Create a non-connectable non-scannable advertising set */ err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, &adv_cb, &pawr_adv); if (err) { printk("Failed to create advertising set (err %d)\n", err); - return; + return 0; } /* Set periodic advertising parameters */ err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params); if (err) { printk("Failed to set periodic advertising parameters (err %d)\n", err); - return; + return 0; } /* Enable Periodic Advertising */ err = bt_le_per_adv_start(pawr_adv); if (err) { printk("Failed to enable periodic advertising (err %d)\n", err); - return; + return 0; } printk("Start Periodic Advertising\n"); err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT); if (err) { printk("Failed to start extended advertising (err %d)\n", err); - return; + return 0; } while (true) { k_sleep(K_SECONDS(1)); } + + return 0; } diff --git a/samples/bluetooth/periodic_adv_rsp/src/main.c b/samples/bluetooth/periodic_adv_rsp/src/main.c index 463ecedf10a9..a7e180edecff 100644 --- a/samples/bluetooth/periodic_adv_rsp/src/main.c +++ b/samples/bluetooth/periodic_adv_rsp/src/main.c @@ -247,7 +247,7 @@ struct pawr_timing { static uint8_t num_synced; -void main(void) +int main(void) { int err; struct bt_le_ext_adv *pawr_adv; @@ -263,42 +263,42 @@ void main(void) err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); - return; + return 0; } /* Create a non-connectable non-scannable advertising set */ err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, &adv_cb, &pawr_adv); if (err) { printk("Failed to create advertising set (err %d)\n", err); - return; + return 0; } /* Set periodic advertising parameters */ err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params); if (err) { printk("Failed to set periodic advertising parameters (err %d)\n", err); - return; + return 0; } /* Enable Periodic Advertising */ err = bt_le_per_adv_start(pawr_adv); if (err) { printk("Failed to enable periodic advertising (err %d)\n", err); - return; + return 0; } printk("Start Periodic Advertising\n"); err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT); if (err) { printk("Failed to start extended advertising (err %d)\n", err); - return; + return 0; } while (num_synced < MAX_SYNCS) { err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err) { printk("Scanning failed to start (err %d)\n", err); - return; + return 0; } printk("Scanning successfully started\n"); @@ -368,7 +368,7 @@ void main(void) disconnect: err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); if (err) { - return; + return 0; } k_sem_take(&sem_disconnected, K_FOREVER); @@ -379,4 +379,6 @@ void main(void) while (true) { k_sleep(K_SECONDS(1)); } + + return 0; } diff --git a/samples/bluetooth/periodic_sync_rsp/src/main.c b/samples/bluetooth/periodic_sync_rsp/src/main.c index a4a8a1cb852e..d39a7814943f 100644 --- a/samples/bluetooth/periodic_sync_rsp/src/main.c +++ b/samples/bluetooth/periodic_sync_rsp/src/main.c @@ -195,7 +195,7 @@ BT_CONN_CB_DEFINE(conn_cb) = { .disconnected = disconnected, }; -void main(void) +int main(void) { struct bt_le_per_adv_sync_transfer_param past_param; int err; @@ -206,7 +206,7 @@ void main(void) if (err) { printk("Bluetooth init failed (err %d)\n", err); - return; + return 0; } bt_le_per_adv_sync_cb_register(&sync_callbacks); @@ -218,7 +218,7 @@ void main(void) if (err) { printk("PAST subscribe failed (err %d)\n", err); - return; + return 0; } do { @@ -231,7 +231,7 @@ void main(void) if (err && err != -EALREADY) { printk("Advertising failed to start (err %d)\n", err); - return; + return 0; } printk("Waiting for periodic sync...\n"); @@ -248,9 +248,11 @@ void main(void) if (err) { printk("failed (err %d)\n", err); - return; + return 0; } printk("Periodic sync lost.\n"); } while (true); + + return 0; } From 2080584f6dcfcc0c5c6cdc9c72e397a01892fbd8 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Thu, 4 May 2023 14:32:22 +0200 Subject: [PATCH 061/528] [nrf fromtree] Bluetooth: Host: Fix PHY translation from HCI HCI events use different values for the PHYs than the GAP macros. Signed-off-by: Herman Berget (cherry picked from commit a947af8ac37b901973f004745c09303eeadcd019) (cherry picked from commit 1e9ba1ded4cf2f8328490719ee74a6348b7d6207) --- subsys/bluetooth/host/scan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 6630951ba8ed..c48f40502a59 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1030,7 +1030,7 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) pending_per_adv_sync->interval = sys_le16_to_cpu(evt->interval); pending_per_adv_sync->clock_accuracy = sys_le16_to_cpu(evt->clock_accuracy); - pending_per_adv_sync->phy = evt->phy; + pending_per_adv_sync->phy = bt_get_phy(evt->phy); memset(&sync_info, 0, sizeof(sync_info)); sync_info.interval = pending_per_adv_sync->interval; @@ -1227,7 +1227,7 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) per_adv_sync->handle = sys_le16_to_cpu(evt->sync_handle); per_adv_sync->interval = sys_le16_to_cpu(evt->interval); per_adv_sync->clock_accuracy = sys_le16_to_cpu(evt->clock_accuracy); - per_adv_sync->phy = evt->phy; + per_adv_sync->phy = bt_get_phy(evt->phy); bt_addr_le_copy(&per_adv_sync->addr, &id_addr); per_adv_sync->sid = evt->adv_sid; @@ -1239,7 +1239,7 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) #endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ sync_info.interval = per_adv_sync->interval; - sync_info.phy = bt_get_phy(per_adv_sync->phy); + sync_info.phy = per_adv_sync->phy; sync_info.addr = &per_adv_sync->addr; sync_info.sid = per_adv_sync->sid; sync_info.service_data = sys_le16_to_cpu(evt->service_data); @@ -1320,7 +1320,7 @@ void bt_hci_le_biginfo_adv_report(struct net_buf *buf) biginfo.max_pdu = sys_le16_to_cpu(evt->max_pdu); biginfo.sdu_interval = sys_get_le24(evt->sdu_interval); biginfo.max_sdu = sys_le16_to_cpu(evt->max_sdu); - biginfo.phy = evt->phy; + biginfo.phy = bt_get_phy(evt->phy); biginfo.framing = evt->framing; biginfo.encryption = evt->encryption ? true : false; From 41e70dde6455d3cbc76db6368b93d3122d8f4de3 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Fri, 5 May 2023 15:28:25 +0200 Subject: [PATCH 062/528] [nrf fromtree] Bluetooth: Host: Fix setting missing params in create connection v2. The adv_handle and subevent were always set to 0. Signed-off-by: Herman Berget (cherry picked from commit 1f43e126a841a231eb8da455a865f1a38a238315) (cherry picked from commit a4c0187373b34ff242fbcee759fbd4617f639725) --- subsys/bluetooth/host/hci_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 1b9d97e2e1b9..c3d2afef8a09 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -654,6 +654,8 @@ int bt_le_create_conn_synced(const struct bt_conn *conn, const struct bt_le_ext_ cp = net_buf_add(buf, sizeof(*cp)); (void)memset(cp, 0, sizeof(*cp)); + cp->subevent = subevent; + cp->adv_handle = adv->handle; bt_addr_le_copy(&cp->peer_addr, &conn->le.dst); cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_NO_FILTER; cp->own_addr_type = own_addr_type; From 9ff8fc26ec0560b26744c96944ae620b884f9a5f Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Fri, 5 May 2023 12:50:04 +0200 Subject: [PATCH 063/528] [nrf fromtree] Samples: Bluetooth: Fix PAwR sample backing store array The array sizes were in the wrong order. Signed-off-by: Herman Berget (cherry picked from commit e28f90f7d2c9acc5ed24610064c531923a7cf339) (cherry picked from commit 90af9e20fe9b37031dd8d13b0d58f7955237dcaf) --- samples/bluetooth/periodic_adv_conn/src/main.c | 2 +- samples/bluetooth/periodic_adv_rsp/src/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/bluetooth/periodic_adv_conn/src/main.c b/samples/bluetooth/periodic_adv_conn/src/main.c index c1070009b2c2..00464b43ead2 100644 --- a/samples/bluetooth/periodic_adv_conn/src/main.c +++ b/samples/bluetooth/periodic_adv_conn/src/main.c @@ -26,7 +26,7 @@ static const struct bt_le_per_adv_param per_adv_params = { static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS]; static struct net_buf_simple bufs[NUM_SUBEVENTS]; -static uint8_t backing_store[PACKET_SIZE][NUM_SUBEVENTS]; +static uint8_t backing_store[NUM_SUBEVENTS][PACKET_SIZE]; BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params)); BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params)); diff --git a/samples/bluetooth/periodic_adv_rsp/src/main.c b/samples/bluetooth/periodic_adv_rsp/src/main.c index a7e180edecff..0b0db7766928 100644 --- a/samples/bluetooth/periodic_adv_rsp/src/main.c +++ b/samples/bluetooth/periodic_adv_rsp/src/main.c @@ -35,7 +35,7 @@ static const struct bt_le_per_adv_param per_adv_params = { static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS]; static struct net_buf_simple bufs[NUM_SUBEVENTS]; -static uint8_t backing_store[PACKET_SIZE][NUM_SUBEVENTS]; +static uint8_t backing_store[NUM_SUBEVENTS][PACKET_SIZE]; BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params)); BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params)); From 2336257f3b8d7646eddac1bc5f291e8c292b07d5 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Sun, 7 May 2023 12:40:30 +0530 Subject: [PATCH 064/528] [nrf fromtree] net: shell: Display TWT response details [SHEL-1390] Show TWT response parameters details. Signed-off-by: Ajay Parida (cherry picked from commit bdec0338899365e34a4f34bb7f417536504ac087) (cherry picked from commit 93c74865ae1f581beb7de68932bfa1f845cc260d) --- subsys/net/l2/wifi/wifi_shell.c | 77 ++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 30 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 7ccf57b8fc2a..67137a5c6427 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -148,23 +148,50 @@ static void handle_wifi_disconnect_result(struct net_mgmt_event_callback *cb) } } +static void print_twt_params(uint8_t dialog_token, uint8_t flow_id, + enum wifi_twt_negotiation_type negotiation_type, + bool responder, bool implicit, bool announce, + bool trigger, uint32_t twt_wake_interval, + uint64_t twt_interval) +{ + shell_fprintf(context.sh, SHELL_NORMAL, "TWT Dialog token: %d\n", + dialog_token); + shell_fprintf(context.sh, SHELL_NORMAL, "TWT flow ID: %d\n", + flow_id); + shell_fprintf(context.sh, SHELL_NORMAL, "TWT negotiation type: %s\n", + wifi_twt_negotiation_type2str[negotiation_type]); + shell_fprintf(context.sh, SHELL_NORMAL, "TWT responder: %s\n", + responder ? "true" : "false"); + shell_fprintf(context.sh, SHELL_NORMAL, "TWT implicit: %s\n", + implicit ? "true" : "false"); + shell_fprintf(context.sh, SHELL_NORMAL, "TWT announce: %s\n", + announce ? "true" : "false"); + shell_fprintf(context.sh, SHELL_NORMAL, "TWT trigger: %s\n", + trigger ? "true" : "false"); + shell_fprintf(context.sh, SHELL_NORMAL, "TWT wake interval: %d us\n", + twt_wake_interval); + shell_fprintf(context.sh, SHELL_NORMAL, "TWT interval: %lld us\n", + twt_interval); + shell_fprintf(context.sh, SHELL_NORMAL, "========================\n"); +} + static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) { const struct wifi_twt_params *resp = (const struct wifi_twt_params *)cb->info; if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { - print(context.sh, SHELL_NORMAL, "TWT response: %s for dialog: %d and flow: %d\n", - wifi_twt_setup_cmd2str[resp->setup_cmd], resp->dialog_token, resp->flow_id); - - /* If accepted, then no need to print TWT params */ - if (resp->setup_cmd != WIFI_TWT_SETUP_CMD_ACCEPT) { - print(context.sh, SHELL_NORMAL, - "TWT parameters: trigger: %s wake_interval: %d us, interval: %lld us\n", - resp->setup.trigger ? "trigger" : "no_trigger", - resp->setup.twt_wake_interval, - resp->setup.twt_interval); - } + print(context.sh, SHELL_NORMAL, "TWT response: %s\n", + wifi_twt_setup_cmd2str[resp->setup_cmd]); + print_twt_params(resp->dialog_token, + resp->flow_id, + resp->negotiation_type, + resp->setup.responder, + resp->setup.implicit, + resp->setup.announce, + resp->setup.trigger, + resp->setup.twt_wake_interval, + resp->setup.twt_interval); } else { print(context.sh, SHELL_NORMAL, "TWT response timed out\n"); } @@ -463,26 +490,16 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); } else { for (int i = 0; i < config.num_twt_flows; i++) { - shell_fprintf(sh, SHELL_NORMAL, "TWT Dialog token: %d\n", - config.twt_flows[i].dialog_token); - shell_fprintf(sh, SHELL_NORMAL, "TWT flow ID: %d\n", - config.twt_flows[i].flow_id); - shell_fprintf(sh, SHELL_NORMAL, "TWT negotiation type: %s\n", - wifi_twt_negotiation_type2str[ - config.twt_flows[i].negotiation_type]); - shell_fprintf(sh, SHELL_NORMAL, "TWT responder: %s\n", - config.twt_flows[i].responder ? "true" : "false"); - shell_fprintf(sh, SHELL_NORMAL, "TWT implicit: %s\n", - config.twt_flows[i].implicit ? "true" : "false"); - shell_fprintf(sh, SHELL_NORMAL, "TWT trigger: %s\n", - config.twt_flows[i].trigger ? "true" : "false"); - shell_fprintf(sh, SHELL_NORMAL, "TWT announce: %s\n", - config.twt_flows[i].announce ? "true" : "false"); - shell_fprintf(sh, SHELL_NORMAL, "TWT wake interval: %d us\n", - config.twt_flows[i].twt_wake_interval); - shell_fprintf(sh, SHELL_NORMAL, "TWT interval: %lld us\n", + print_twt_params( + config.twt_flows[i].dialog_token, + config.twt_flows[i].flow_id, + config.twt_flows[i].negotiation_type, + config.twt_flows[i].responder, + config.twt_flows[i].implicit, + config.twt_flows[i].announce, + config.twt_flows[i].trigger, + config.twt_flows[i].twt_wake_interval, config.twt_flows[i].twt_interval); - shell_fprintf(sh, SHELL_NORMAL, "========================\n"); } } return 0; From 10dd35561631401f40c9f8f49ea47e46e4d0419f Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 17 Jan 2023 10:42:27 -0800 Subject: [PATCH 065/528] [nrf fromtree] net: conn_mgr: connectivity API Allows L2s to declare generic association/connection routines that can be bound by name to ifaces. Allows L2-agnostic control over connectivity/association for iface that support it. Signed-off-by: Georges Oates_Larsen (cherry picked from commit 7c4397ae797fff00fab86ee0d317b8b5705a4862) (cherry picked from commit f2211c9c5e417953d905a9c4d320d5e7bb353d27) --- include/zephyr/net/conn_mgr_connectivity.h | 415 ++++++++++++++++++ subsys/net/lib/conn_mgr/CMakeLists.txt | 4 + subsys/net/lib/conn_mgr/conn_mgr.c | 3 + subsys/net/lib/conn_mgr/conn_mgr.ld | 7 + .../net/lib/conn_mgr/conn_mgr_connectivity.c | 277 ++++++++++++ 5 files changed, 706 insertions(+) create mode 100644 include/zephyr/net/conn_mgr_connectivity.h create mode 100644 subsys/net/lib/conn_mgr/conn_mgr.ld create mode 100644 subsys/net/lib/conn_mgr/conn_mgr_connectivity.c diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h new file mode 100644 index 000000000000..023b043a249a --- /dev/null +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -0,0 +1,415 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief API for defining generic interfaces for configuring and firing network association + * routines on network devices that support it. + */ + +#ifndef ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_ +#define ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Connection Manager Connectivity API + * @defgroup conn_mgr_connectivity Connection Manager Connectivity API + * @ingroup networking + * @{ + */ + + +/** @cond INTERNAL_HIDDEN */ + +/* Connectivity Events */ +#define _NET_MGMT_CONN_LAYER NET_MGMT_LAYER(NET_MGMT_LAYER_L2) +#define _NET_MGMT_CONN_CODE NET_MGMT_LAYER_CODE(0x207) +#define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE) +#define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_EVENT) + +enum net_event_ethernet_cmd { + NET_EVENT_CONN_CMD_IF_TIMEOUT = 1, + NET_EVENT_CONN_CMD_IF_FATAL_ERROR, +}; + +#define NET_EVENT_CONN_IF_TIMEOUT \ + (_NET_MGMT_CONN_IF_EVENT | NET_EVENT_CONN_CMD_IF_TIMEOUT) + +#define NET_EVENT_CONN_IF_FATAL_ERROR \ + (_NET_MGMT_CONN_IF_EVENT | NET_EVENT_CONN_CMD_IF_FATAL_ERROR) + +/** @endcond */ + +/** + * @brief Connectivity Manager Connectivity API structure + * + * Used to provide generic access to network association parameters and procedures + */ +struct conn_mgr_conn_binding; +struct conn_mgr_conn_api { + /** + * @brief When called, the connectivity implementation should start attempting to + * establish connectivity for (associate with a network) the bound iface pointed + * to by if_conn->iface. + * + * Must be non-blocking. + * + * Called by conn_mgr_if_connect. + */ + int (*connect)(struct conn_mgr_conn_binding *const binding); + + /** + * @brief When called, the connectivity implementation should disconnect (dissasociate), or + * stop any in-progress attempts to associate to a network, the bound iface pointed to by + * if_conn->iface. + * + * Must be non-blocking. + * + * Called by conn_mgr_if_disconnect. + */ + int (*disconnect)(struct conn_mgr_conn_binding *const binding); + + /** + * @brief Called once for each iface that has been bound to a connectivity implementation + * using this API. + * + * Connectivity implementations should use this callback to perform any required + * per-bound-iface initialization. + * + * Implementations may choose to gracefully handle invalid buffer lengths with partial + * writes, rather than raise errors, if deemed appropriate. + */ + void (*init)(struct conn_mgr_conn_binding *const binding); + + /** + * @brief Implementation callback for conn_mgr_if_set_opt. + * + * Used to set implementation-specific connectivity settings. + * + * Calls to conn_mgr_if_set_opt on an iface will result in calls to this callback with + * the conn_mgr_conn_binding struct bound to that iface. + * + * It is up to the connectivity implementation to interpret optname. Options can be + * specific to the bound iface (pointed to by if_conn->iface), or can apply to the whole + * connectivity implementation. + * + * See the description of conn_mgr_if_set_opt for more details. + * set_opt implementations should conform to that description. + * + * Implementations may choose to gracefully handle invalid buffer lengths with partial + * reads, rather than raise errors, if deemed appropriate. + */ + int (*set_opt)(struct conn_mgr_conn_binding *const binding, + int optname, const void *optval, size_t optlen); + + /** + * @brief Implementation callback for conn_mgr_if_get_opt. + * + * Used to retrieve implementation-specific connectivity settings. + * + * Calls to conn_mgr_if_get_opt on an iface will result in calls to this callback with + * the conn_mgr_conn_binding struct bound to that iface. + * + * It is up to the connectivity implementation to interpret optname. Options can be + * specific to the bound iface (pointed to by if_conn->iface), or can apply to the whole + * connectivity implementation. + * + * See the description of conn_mgr_if_get_opt for more details. + * get_opt implementations should conform to that description. + */ + int (*get_opt)(struct conn_mgr_conn_binding *const binding, + int optname, void *optval, size_t *optlen); +}; + +/** @cond INTERNAL_HIDDEN */ +#define CONN_MGR_CONN_IMPL_GET_NAME(conn_id) __conn_mgr_conn_##conn_id +#define CONN_MGR_CONN_IMPL_GET_CTX_TYPE(conn_id) conn_id##_CTX_TYPE +/** @endcond */ + +/** + * @brief conn_mgr Connectivity Implementation struct + * Declares a conn_mgr connectivity layer implementation with the provided API + */ +struct conn_mgr_conn_impl { + /* The connectivity API used by the implementation */ + struct conn_mgr_conn_api *api; +}; + +/** + * @brief Define a conn_mgr connectivity implementation that can be bound to network devices. + * + * @param conn_id The name of the new connectivity implementation + * @param conn_api A pointer to a conn_mgr_conn_api struct + */ +#define CONN_MGR_CONN_DEFINE(conn_id, conn_api) \ + const struct conn_mgr_conn_impl CONN_MGR_CONN_IMPL_GET_NAME(conn_id) = { \ + .api = conn_api, \ + }; + +/** + * @brief Helper macro to make a conn_mgr connectivity implementation publicly available. + */ +#define CONN_MGR_CONN_DECLARE_PUBLIC(conn_id) \ + extern const struct conn_mgr_conn_impl CONN_MGR_CONN_IMPL_GET_NAME(conn_id) + +/** @cond INTERNAL_HIDDEN */ +#define CONN_MGR_CONN_BINDING_GET_NAME(dev_id, sfx) __conn_mgr_bndg_##dev_id##_##sfx +#define CONN_MGR_CONN_BINDING_GET_DATA(dev_id, sfx) __conn_mgr_bndg_data_##dev_id##_##sfx +#define CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, sfx) __conn_mgr_bndg_mutex_##dev_id##_##sfx +/** @endcond */ + +/** + * @brief Per-iface connectivity flags + */ +enum conn_mgr_if_flag { + /* Persistent + * When set, indicates that the connectivity implementation bound to this iface should + * attempt to persist connectivity by automatically reconnecting after connection loss. + */ + CONN_MGR_IF_PERSISTENT, + +/** @cond INTERNAL_HIDDEN */ + /* Total number of flags - must be at the end of the enum */ + CONN_MGR_NUM_IF_FLAGS, +/** @endcond */ +}; + +/* Value to use with conn_mgr_conn_binding->timeout to indicate no timeout */ +#define CONN_MGR_IF_NO_TIMEOUT 0 + +/** + * @brief Connectivity Manager network interface binding structure + * + * Binds a conn_mgr connectivity implementation to an iface / network device. + * Stores per-iface state for the connectivity implementation. + */ +struct conn_mgr_conn_binding { + /* The network interface the connectivity implementation is bound to */ + struct net_if *iface; + + /* The connectivity implementation the network device is bound to */ + const struct conn_mgr_conn_impl *impl; + + /* Pointer to private, per-iface connectivity context */ + void *ctx; + + /* Generic connectivity state - Flags + * Public boolean state and configuration values supported by all bindings. + * See conn_mgr_if_flag for options. + */ + uint32_t flags; + + /* Generic connectivity state - Timeout (seconds) + * Indicates to the connectivity implementation how long it should attempt to + * establish connectivity for during a connection attempt before giving up. + * + * The connectivity implementation should give up on establishing connectivity after this + * timeout, even if persistence is enabled. + * + * Set to CONN_MGR_IF_NO_TIMEOUT to indicate that no timeout should be used. + */ + int timeout; + +/** @cond INTERNAL_HIDDEN */ + /* Internal-use mutex for protecting access to the binding and API functions. */ + struct k_mutex *mutex; +/** @endcond */ +}; + +/** + * @brief Associate a connectivity implementation with an existing network device instance + * + * @param dev_id Network device id. + * @param inst Network device instance. + * @param conn_id Name of the connectivity implementation to associate. + */ +#define CONN_MGR_BIND_CONN_INST(dev_id, inst, conn_id) \ + K_MUTEX_DEFINE(CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, inst)); \ + static CONN_MGR_CONN_IMPL_GET_CTX_TYPE(conn_id) \ + CONN_MGR_CONN_BINDING_GET_DATA(dev_id, inst); \ + static STRUCT_SECTION_ITERABLE(conn_mgr_conn_binding, \ + CONN_MGR_CONN_BINDING_GET_NAME(dev_id, inst)) = { \ + .iface = NET_IF_GET(dev_id, inst), \ + .impl = &(CONN_MGR_CONN_IMPL_GET_NAME(conn_id)), \ + .ctx = &(CONN_MGR_CONN_BINDING_GET_DATA(dev_id, inst)), \ + .mutex = &(CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, inst)) \ + }; + +/** + * @brief Associate a connectivity implementation with an existing network device + * + * @param dev_id Network device id. + * @param conn_id Name of the connectivity implementation to associate. + */ +#define CONN_MGR_BIND_CONN(dev_id, conn_id) \ + CONN_MGR_BIND_CONN_INST(dev_id, 0, conn_id) + +/** + * @brief Connect interface + * + * If the provided iface has been bound to a connectivity implementation, initiate + * network connect/association. + * + * Non-Blocking. + * + * @param iface Pointer to network interface + * @retval 0 on success. + * @retval -ESHUTDOWN if the iface is not admin-up. + * @retval -ENOTSUP if the iface does not have a connectivity implementation. + * @retval implementation-specific status code otherwise. + */ +int conn_mgr_if_connect(struct net_if *iface); + +/** + * @brief Disconnect interface + * + * If the provided iface has been bound to a connectivity implementation, disconnect/dissassociate + * it from the network, and cancel any pending attempts to connect/associate. + * + * @param iface Pointer to network interface + * + * @retval 0 on success. + * @retval -ENOTSUP if the iface does not have a connectivity implementation. + * @retval implementation-specific status code otherwise. + */ +int conn_mgr_if_disconnect(struct net_if *iface); + +/** + * @brief Check whether the provided network interface supports connectivity / has been bound + * to a connectivity implementation. + * + * @param iface Pointer to the iface to check. + * @retval true if connectivity is supported (a connectivity implementation has been bound). + * @retval false otherwise. + */ +bool conn_mgr_if_is_bound(struct net_if *iface); + +/** + * @brief Set implementation-specific connectivity options. + * + * If the provided iface has been bound to a connectivity implementation that supports it, + * implementation-specific connectivity options related to the iface. + * + * @param iface Pointer to the network interface. + * @param optname Integer value representing the option to set. + * The meaning of values is up to the conn_mgr_conn_api implementation. + * Some settings may affect multiple ifaces. + * @param optval Pointer to the value to be assigned to the option. + * @param optlen Length (in bytes) of the value to be assigned to the option. + * @retval 0 if successful. + * @retval -ENOTSUP if conn_mgr_if_set_opt not implemented by the iface. + * @retval -ENOBUFS if optlen is too long. + * @retval -EINVAL if NULL optval pointer provided. + * @retval -ENOPROTOOPT if the optname is not recognized. + * @retval implementation-specific error code otherwise. + */ +int conn_mgr_if_set_opt(struct net_if *iface, int optname, const void *optval, size_t optlen); + +/** + * @brief Get implementation-specific connectivity options. + * + * If the provided iface has been bound to a connectivity implementation that supports it, + * retrieves implementation-specific connectivity options related to the iface. + * + * @param iface Pointer to the network interface. + * @param optname Integer value representing the option to set. + * The meaning of values is up to the conn_mgr_conn_api implementation. + * Some settings may be shared by multiple ifaces. + * @param optval Pointer to where the retrieved value should be stored. + * @param optlen Pointer to length (in bytes) of the destination buffer available for storing the + * retrieved value. If the available space is less than what is needed, -ENOBUFS + * is returned. If the available space is invalid, -EINVAL is returned. + * + * optlen will always be set to the total number of bytes written, regardless of + * whether an error is returned, even if zero bytes were written. + * + * @retval 0 if successful. + * @retval -ENOTSUP if conn_mgr_if_get_opt is not implemented by the iface. + * @retval -ENOBUFS if retrieval buffer is too small. + * @retval -EINVAL if invalid retrieval buffer length is provided, or if NULL optval or + * optlen pointer provided. + * @retval -ENOPROTOOPT if the optname is not recognized. + * @retval implementation-specific error code otherwise. + */ +int conn_mgr_if_get_opt(struct net_if *iface, int optname, void *optval, size_t *optlen); + +/** + * @brief Check the value of connectivity flags + * + * If the provided iface is bound to a connectivity implementation, retrieves the value of the + * specified connectivity flag associated with that iface. + * + * @param iface - Pointer to the network interface to check. + * @param flag - The flag to check. + * @return True if the flag is set, otherwise False. + * Also returns False if the provided iface is not bound to a connectivity implementation, + * or the requested flag doesn't exist. + */ +bool conn_mgr_if_get_flag(struct net_if *iface, enum conn_mgr_if_flag flag); + +/** + * @brief Set the value of a connectivity flags + * + * If the provided iface is bound to a connectivity implementation, sets the value of the + * specified connectivity flag associated with that iface. + * + * @param iface - Pointer to the network interface to modify. + * @param flag - The flag to set. + * @param value - Whether the flag should be enabled or disabled. + * @retval 0 on success. + * @retval -EINVAL if the flag does not exist. + * @retval -ENOTSUP if the provided iface is not bound to a connectivity implementation. + */ +int conn_mgr_if_set_flag(struct net_if *iface, enum conn_mgr_if_flag flag, bool value); + +/** + * @brief Get the connectivity timeout for an iface + * + * If the provided iface is bound to a connectivity implementation, retrieves the timeout setting + * in seconds for it. + * + * @param iface - Pointer to the iface to check. + * @return int - The connectivity timeout value (in seconds) if it could be retrieved, otherwise + * CONN_MGR_IF_NO_TIMEOUT. + */ +int conn_mgr_if_get_timeout(struct net_if *iface); + +/** + * @brief Set the connectivity timeout for an iface. + * + * If the provided iface is bound to a connectivity implementation, sets the timeout setting in + * seconds for it. + * + * @param iface - Pointer to the network interface to modify. + * @param timeout - The timeout value to set (in seconds). + * Pass CONN_MGR_IF_NO_TIMEOUT to disable the timeout. + * @retval 0 on success. + * @retval -ENOTSUP if the provided iface is not bound to a connectivity implementation. + */ +int conn_mgr_if_set_timeout(struct net_if *iface, int timeout); + +/** + * @brief Initialize all connectivity implementation bindings + * + * + */ +void conn_mgr_conn_init(void); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_ */ diff --git a/subsys/net/lib/conn_mgr/CMakeLists.txt b/subsys/net/lib/conn_mgr/CMakeLists.txt index 7bb98d963c78..2f2d233196f0 100644 --- a/subsys/net/lib/conn_mgr/CMakeLists.txt +++ b/subsys/net/lib/conn_mgr/CMakeLists.txt @@ -6,4 +6,8 @@ zephyr_library() zephyr_library_sources( conn_mgr.c events_handler.c + conn_mgr_connectivity.c ) + +zephyr_linker_sources(DATA_SECTIONS conn_mgr.ld) +zephyr_iterable_section(NAME conn_mgr_conn_binding GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) diff --git a/subsys/net/lib/conn_mgr/conn_mgr.c b/subsys/net/lib/conn_mgr/conn_mgr.c index 345e5a5736e2..c81033ec30d8 100644 --- a/subsys/net/lib/conn_mgr/conn_mgr.c +++ b/subsys/net/lib/conn_mgr/conn_mgr.c @@ -14,6 +14,7 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include +#include #include #if defined(CONFIG_NET_TC_THREAD_COOPERATIVE) @@ -174,6 +175,8 @@ static void conn_mgr_init_cb(struct net_if *iface, void *user_data) static void conn_mgr_handler(void) { + conn_mgr_conn_init(); + conn_mgr_init_events_handler(); net_if_foreach(conn_mgr_init_cb, NULL); diff --git a/subsys/net/lib/conn_mgr/conn_mgr.ld b/subsys/net/lib/conn_mgr/conn_mgr.ld new file mode 100644 index 000000000000..352dde5c6472 --- /dev/null +++ b/subsys/net/lib/conn_mgr/conn_mgr.ld @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +ITERABLE_SECTION_RAM(conn_mgr_conn_binding, 4) diff --git a/subsys/net/lib/conn_mgr/conn_mgr_connectivity.c b/subsys/net/lib/conn_mgr/conn_mgr_connectivity.c new file mode 100644 index 000000000000..c0812dac1727 --- /dev/null +++ b/subsys/net/lib/conn_mgr/conn_mgr_connectivity.c @@ -0,0 +1,277 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(conn_mgr_conn, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); + +#include +#include + +/** + * @brief Retrieves the conn_mgr binding struct for a provided iface if it exists. + * + * Bindings for connectivity implementations with missing API structs are ignored. + * + * @param iface - bound network interface to obtain the binding struct for. + * @return struct conn_mgr_conn_binding* Pointer to the retrieved binding struct if it exists, + * NULL otherwise. + */ +static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) +{ + STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { + if (iface == binding->iface) { + if (binding->impl->api) { + return binding; + } + return NULL; + } + } + return NULL; +} + +int conn_mgr_if_connect(struct net_if *iface) +{ + struct conn_mgr_conn_binding *binding; + struct conn_mgr_conn_api *api; + int status; + + LOG_DBG("iface %p connect", iface); + + binding = conn_mgr_if_get_binding(iface); + if (!binding) { + return -ENOTSUP; + } + + api = binding->impl->api; + if (!api->connect) { + return -ENOTSUP; + } + + k_mutex_lock(binding->mutex, K_FOREVER); + + if (!net_if_flag_is_set(iface, NET_IF_UP)) { + status = -ESHUTDOWN; + goto out; + } + + status = api->connect(binding); + +out: + k_mutex_unlock(binding->mutex); + + return status; +} + +int conn_mgr_if_disconnect(struct net_if *iface) +{ + struct conn_mgr_conn_binding *binding; + struct conn_mgr_conn_api *api; + int status; + + LOG_DBG("iface %p disconnect", iface); + + binding = conn_mgr_if_get_binding(iface); + if (!binding) { + return -ENOTSUP; + } + + api = binding->impl->api; + if (!api->disconnect) { + return -ENOTSUP; + } + + + k_mutex_lock(binding->mutex, K_FOREVER); + + if (!net_if_flag_is_set(iface, NET_IF_UP)) { + status = -EALREADY; + goto out; + } + + status = api->disconnect(binding); + +out: + k_mutex_unlock(binding->mutex); + + return status; +} + +bool conn_mgr_if_is_bound(struct net_if *iface) +{ + struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); + + return binding != NULL; +} + +int conn_mgr_if_get_opt(struct net_if *iface, int optname, void *optval, size_t *optlen) +{ + struct conn_mgr_conn_binding *binding; + struct conn_mgr_conn_api *api; + int status; + + if (!optlen) { + return -EINVAL; + } + + if (!optval) { + *optlen = 0; + return -EINVAL; + } + + binding = conn_mgr_if_get_binding(iface); + if (!binding) { + *optlen = 0; + return -ENOTSUP; + } + + api = binding->impl->api; + if (!api->get_opt) { + *optlen = 0; + return -ENOTSUP; + } + + k_mutex_lock(binding->mutex, K_FOREVER); + + status = api->get_opt(binding, optname, optval, optlen); + + k_mutex_unlock(binding->mutex); + + return status; +} + +int conn_mgr_if_set_opt(struct net_if *iface, int optname, const void *optval, size_t optlen) +{ + struct conn_mgr_conn_binding *binding; + struct conn_mgr_conn_api *api; + int status; + + if (!optval) { + return -EINVAL; + } + + binding = conn_mgr_if_get_binding(iface); + if (!binding) { + return -ENOTSUP; + } + + api = binding->impl->api; + if (!api->set_opt) { + return -ENOTSUP; + } + + k_mutex_lock(binding->mutex, K_FOREVER); + + status = api->set_opt(binding, optname, optval, optlen); + + k_mutex_unlock(binding->mutex); + + return status; +} + +int conn_mgr_if_set_flag(struct net_if *iface, enum conn_mgr_if_flag flag, bool value) +{ + struct conn_mgr_conn_binding *binding; + + if (flag >= CONN_MGR_NUM_IF_FLAGS) { + return -EINVAL; + } + + binding = conn_mgr_if_get_binding(iface); + if (!binding) { + return -ENOTSUP; + } + + k_mutex_lock(binding->mutex, K_FOREVER); + + binding->flags &= ~BIT(flag); + if (value) { + binding->flags |= BIT(flag); + } + + k_mutex_unlock(binding->mutex); + + return 0; +} + +bool conn_mgr_if_get_flag(struct net_if *iface, enum conn_mgr_if_flag flag) +{ + struct conn_mgr_conn_binding *binding; + bool value; + + if (flag >= CONN_MGR_NUM_IF_FLAGS) { + return false; + } + + binding = conn_mgr_if_get_binding(iface); + if (!binding) { + return false; + } + + k_mutex_lock(binding->mutex, K_FOREVER); + + value = !!(binding->flags & BIT(flag)); + + k_mutex_unlock(binding->mutex); + + return value; +} + +int conn_mgr_if_get_timeout(struct net_if *iface) +{ + struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); + int value; + + if (!binding) { + return false; + } + + k_mutex_lock(binding->mutex, K_FOREVER); + + value = binding->timeout; + + k_mutex_unlock(binding->mutex); + + return value; +} + +int conn_mgr_if_set_timeout(struct net_if *iface, int timeout) +{ + struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); + + if (!binding) { + return -ENOTSUP; + } + + k_mutex_lock(binding->mutex, K_FOREVER); + + binding->timeout = timeout; + + k_mutex_unlock(binding->mutex); + + return 0; +} + +void conn_mgr_conn_init(void) +{ + STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { + if (!(binding->impl->api)) { + LOG_ERR("Connectivity implementation has NULL API, and will be treated as " + "non-existent."); + } else if (binding->impl->api->init) { + k_mutex_lock(binding->mutex, K_FOREVER); + + /* Set initial default values for binding state */ + + binding->timeout = CONN_MGR_IF_NO_TIMEOUT; + + /* Call binding initializer */ + + binding->impl->api->init(binding); + + k_mutex_unlock(binding->mutex); + } + } +} From 031eb6e1b954e01aee3e4f259880667f8d00711d Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Fri, 27 Jan 2023 12:27:30 -0800 Subject: [PATCH 066/528] [nrf fromtree] tests: net: Add tests for conn_mgr_conn Adds integration tests for conn_mgr connectivity API Signed-off-by: Georges Oates_Larsen (cherry picked from commit 129291f1e4136a142cff98ca9e8559833d0e1a01) (cherry picked from commit 67036554f215d486429b378681f6a5c039762648) --- tests/net/conn_mgr_conn/CMakeLists.txt | 9 + tests/net/conn_mgr_conn/prj.conf | 26 + tests/net/conn_mgr_conn/src/main.c | 702 +++++++++++++++++++ tests/net/conn_mgr_conn/src/test_conn_impl.c | 187 +++++ tests/net/conn_mgr_conn/src/test_conn_impl.h | 76 ++ tests/net/conn_mgr_conn/src/test_ifaces.c | 125 ++++ tests/net/conn_mgr_conn/src/test_ifaces.h | 29 + tests/net/conn_mgr_conn/testcase.yaml | 6 + 8 files changed, 1160 insertions(+) create mode 100644 tests/net/conn_mgr_conn/CMakeLists.txt create mode 100644 tests/net/conn_mgr_conn/prj.conf create mode 100644 tests/net/conn_mgr_conn/src/main.c create mode 100644 tests/net/conn_mgr_conn/src/test_conn_impl.c create mode 100644 tests/net/conn_mgr_conn/src/test_conn_impl.h create mode 100644 tests/net/conn_mgr_conn/src/test_ifaces.c create mode 100644 tests/net/conn_mgr_conn/src/test_ifaces.h create mode 100644 tests/net/conn_mgr_conn/testcase.yaml diff --git a/tests/net/conn_mgr_conn/CMakeLists.txt b/tests/net/conn_mgr_conn/CMakeLists.txt new file mode 100644 index 000000000000..c1807456006c --- /dev/null +++ b/tests/net/conn_mgr_conn/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(test_conn_mgr_conn) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/conn_mgr_conn/prj.conf b/tests/net/conn_mgr_conn/prj.conf new file mode 100644 index 000000000000..5ffa0ba9d9fc --- /dev/null +++ b/tests/net/conn_mgr_conn/prj.conf @@ -0,0 +1,26 @@ +CONFIG_NETWORKING=y +CONFIG_NET_TEST=y +CONFIG_NET_IPV6=y +CONFIG_NET_IPV4=y +CONFIG_NET_MAX_CONTEXTS=4 +CONFIG_NET_L2_DUMMY=y +CONFIG_NET_LOG=y +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NET_IPV6_DAD=n +CONFIG_NET_IPV6_MLD=n +CONFIG_NET_PKT_TX_COUNT=10 +CONFIG_NET_PKT_RX_COUNT=5 +CONFIG_NET_BUF_RX_COUNT=10 +CONFIG_NET_BUF_TX_COUNT=10 +CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 +CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2 +CONFIG_NET_MAX_NEXTHOPS=8 +CONFIG_NET_IPV6_MAX_NEIGHBORS=8 +CONFIG_NET_IPV6_ND=n +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_NET_IF_MAX_IPV4_COUNT=6 +CONFIG_NET_IF_MAX_IPV6_COUNT=6 +CONFIG_TEST_USERSPACE=y diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c new file mode 100644 index 000000000000..e8da4e9d7d58 --- /dev/null +++ b/tests/net/conn_mgr_conn/src/main.c @@ -0,0 +1,702 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "test_conn_impl.h" +#include "test_ifaces.h" + + +/* This is a duplicate of conn_mgr_if_get_binding in net_if.c, + * which is currently not exposed. + */ +static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) +{ + STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { + if (iface == binding->iface) { + if (binding->impl->api) { + return binding; + } + return NULL; + } + } + return NULL; +} + +static inline struct test_conn_data *conn_mgr_if_get_data(struct net_if *iface) +{ + struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); + + if (!binding) { + return NULL; + } + return binding->ctx; +} + +static void reset_test_iface(struct net_if *iface) +{ + if (net_if_is_admin_up(iface)) { + (void)net_if_down(iface); + } + + /* Some tests can leave the iface in a bad state where it is admin-down but not dormant */ + net_if_dormant_on(iface); + + struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface); + struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); + + if (iface_binding) { + iface_binding->flags = 0; + iface_binding->timeout = CONN_MGR_IF_NO_TIMEOUT; + } + + if (iface_data) { + iface_data->call_cnt_a = 0; + iface_data->call_cnt_b = 0; + iface_data->conn_bal = 0; + iface_data->api_err = 0; + memset(iface_data->data_x, 0, sizeof(iface_data->data_x)); + memset(iface_data->data_y, 0, sizeof(iface_data->data_y)); + } +} + +static void conn_mgr_conn_before(void *data) +{ + ARG_UNUSED(data); + reset_test_iface(ifa1); + reset_test_iface(ifa2); + reset_test_iface(ifb); + reset_test_iface(ifni); + reset_test_iface(ifnone); + reset_test_iface(ifnull); +} + +/* This suite uses k_sleep(K_MSEC(1)) to allow Zephyr to perform event propagation. + * This is not guaranteed to execute in the fastest possible time, nor is it technically guaranteed + * that Zephyr will finish its operations in less than a millisecond, but for this test suite, + * event propagation times longer than a millisecond would be a sign of a problem, + * a few milliseconds of delay are miniscule compared to the time it takes to build the suite, + * and using k_sleep has the advantage of being completely agnostic to the underlying operation + * of the events. + */ + +/* Verify that the correct init APIs were called. */ +ZTEST(conn_mgr_conn, test_inspect_init) +{ + /* This isn't a proper test in that it only verifies the result of an exterior operation, + * but it increases coverage and costs next to nothing to add. + */ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + struct test_conn_data *ifa2_data = conn_mgr_if_get_data(ifa2); + struct test_conn_data *ifb_data = conn_mgr_if_get_data(ifb); + struct test_conn_data *ifni_data = conn_mgr_if_get_data(ifni); + + + zassert_equal(ifa1_data->init_calls_a, 1, "ifa1->init should be called exactly once."); + zassert_equal(ifa1_data->init_calls_b, 0, "ifa1 should use implementation A"); + + zassert_equal(ifa2_data->init_calls_a, 1, "ifa2->init should be called exactly once."); + zassert_equal(ifa2_data->init_calls_b, 0, "ifa2 should use implementation A"); + + zassert_equal(ifb_data->init_calls_b, 1, "ifb->init should be called exactly once."); + zassert_equal(ifb_data->init_calls_a, 0, "ifb should use implementation B"); + + zassert_equal(ifni_data->init_calls_a, 0, "ifni->init should not be called."); + zassert_equal(ifni_data->init_calls_b, 0, "ifni->init should not be called."); +} + +/* Verify that conn_mgr_if_connect and conn_mgr_if_disconnect perform the + * correct API calls to the correct interfaces and connectivity implementations + */ +ZTEST(conn_mgr_conn, test_connect_disconnect) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + struct test_conn_data *ifa2_data = conn_mgr_if_get_data(ifa2); + struct test_conn_data *ifb_data = conn_mgr_if_get_data(ifb); + + /* Take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should not fail"); + zassert_equal(net_if_up(ifb), 0, "net_if_up should not fail"); + + /* Verify ifaces are still disconnected */ + zassert_false(net_if_is_up(ifa1), "Ifaces must be disconnected before test"); + zassert_false(net_if_is_up(ifa2), "Ifaces must be disconnected before test"); + zassert_false(net_if_is_up(ifb), "Ifaces must be disconnected before test"); + + /* Connect one of the A ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success, and that only the target iface/conn impl were affected/invoked */ + zassert_true(net_if_is_up(ifa1), "ifa1 should be oper-up after conn_mgr_if_connect"); + zassert_false(net_if_is_up(ifa2), "ifa2 should not be affected by ifa1"); + zassert_false(net_if_is_up(ifb), "ifb should not be affected by ifa1"); + + /* Verify that all ifaces have the expected call counts and types */ + zassert_equal(ifa1_data->conn_bal, 1, "ifa1->connect should be called once"); + zassert_equal(ifa1_data->call_cnt_a, 1, "Implementation A should be used for ifa1"); + zassert_equal(ifa1_data->call_cnt_b, 0, "Implementation A should be used for ifa1"); + + zassert_equal(ifa2_data->conn_bal, 0, "ifa2 should not be affected by ifa1"); + zassert_equal(ifa2_data->call_cnt_a, 0, "ifa2 should not be affected by ifa1"); + zassert_equal(ifa2_data->call_cnt_b, 0, "ifa2 should not be affected by ifa1"); + + zassert_equal(ifb_data->conn_bal, 0, "ifb should not be affected by ifa1"); + zassert_equal(ifb_data->call_cnt_a, 0, "ifb should not be affected by ifa1"); + zassert_equal(ifb_data->call_cnt_b, 0, "ifb should not be affected by ifa1"); + + /* Now connect the B iface */ + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success, and that only the target iface/conn impl were affected/invoked */ + zassert_true(net_if_is_up(ifa1), "ifa1 should still be connected"); + zassert_false(net_if_is_up(ifa2), "ifa2 should not be affected by ifb"); + zassert_true(net_if_is_up(ifb), "ifb should be oper-up after conn_mgr_if_connect"); + + /* Verify that all ifaces have the expected call counts and types */ + zassert_equal(ifa1_data->conn_bal, 1, "ifa1 should not be affected by ifb"); + zassert_equal(ifa1_data->call_cnt_a, 1, "ifa1 should not be affected by ifb"); + zassert_equal(ifa1_data->call_cnt_b, 0, "ifa1 should not be affected by ifb"); + + zassert_equal(ifa2_data->conn_bal, 0, "ifa2 should not be affected by ifb"); + zassert_equal(ifa2_data->call_cnt_a, 0, "ifa2 should not be affected by ifb"); + zassert_equal(ifa2_data->call_cnt_b, 0, "ifa2 should not be affected by ifb"); + + zassert_equal(ifb_data->conn_bal, 1, "ifb->connect should be called once"); + zassert_equal(ifb_data->call_cnt_a, 0, "Implementation B should be used for ifb"); + zassert_equal(ifb_data->call_cnt_b, 1, "Implementation B should be used for ifb"); + + /* Now connect the other A iface */ + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success, and that only the target iface/conn impl were affected/invoked */ + zassert_true(net_if_is_up(ifa1), "ifa1 should still be connected"); + zassert_true(net_if_is_up(ifa2), "ifa2 should be oper-up after conn_mgr_if_connect"); + zassert_true(net_if_is_up(ifb), "ifb should still be connected"); + + /* Verify that all ifaces have the expected call counts and types */ + zassert_equal(ifa1_data->conn_bal, 1, "ifa1 should not be affected by ifa2"); + zassert_equal(ifa1_data->call_cnt_a, 1, "ifa1 should not be affected by ifa2"); + zassert_equal(ifa1_data->call_cnt_b, 0, "ifa1 should not be affected by ifa2"); + + zassert_equal(ifa2_data->conn_bal, 1, "ifa2->connect should be called once"); + zassert_equal(ifa2_data->call_cnt_a, 1, "Implementation A should be used for ifa2"); + zassert_equal(ifa2_data->call_cnt_b, 0, "Implementation A should be used for ifa2"); + + zassert_equal(ifb_data->conn_bal, 1, "ifb should not be affected by ifa2"); + zassert_equal(ifb_data->call_cnt_a, 0, "ifb should not be affected by ifa2"); + zassert_equal(ifb_data->call_cnt_b, 1, "ifb should not be affected by ifa2"); + + /* Now disconnect the original A iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); + k_sleep(K_MSEC(1)); + + + /* Verify success, and that only the target iface/conn impl were affected/invoked */ + zassert_false(net_if_is_up(ifa1), "ifa1 should be oper-down after conn_mgr_if_disconnect"); + zassert_true(net_if_is_up(ifa2), "ifa2 should not be affected by ifa1"); + zassert_true(net_if_is_up(ifb), "ifb should not be affected by ifa1"); + + /* Verify that all ifaces have the expected call counts and types */ + zassert_equal(ifa1_data->conn_bal, 0, "ifa1->disconnect should be called once"); + zassert_equal(ifa1_data->call_cnt_a, 2, "Implementation A should be used for ifa1"); + zassert_equal(ifa1_data->call_cnt_b, 0, "Implementation A should be used for ifa1"); + + zassert_equal(ifa2_data->conn_bal, 1, "ifa2 should not be affected by ifa1"); + zassert_equal(ifa2_data->call_cnt_a, 1, "ifa2 should not be affected by ifa1"); + zassert_equal(ifa2_data->call_cnt_b, 0, "ifa2 should not be affected by ifa1"); + + zassert_equal(ifb_data->conn_bal, 1, "ifb should not be affected by ifa1"); + zassert_equal(ifb_data->call_cnt_a, 0, "ifb should not be affected by ifa1"); + zassert_equal(ifb_data->call_cnt_b, 1, "ifb should not be affected by ifa1"); + + /* Now disconnect the B iface */ + zassert_equal(conn_mgr_if_disconnect(ifb), 0, "conn_mgr_if_disconnect should not fail"); + k_sleep(K_MSEC(1)); + + + /* Verify success, and that only the target iface/conn impl were affected/invoked */ + zassert_false(net_if_is_up(ifa1), "ifa1 should still be disconnected"); + zassert_true(net_if_is_up(ifa2), "ifa2 should not be affected by ifb"); + zassert_false(net_if_is_up(ifb), "ifb should be oper-down after conn_mgr_if_disconnect"); + + /* Verify that all ifaces have the expected call counts and types */ + zassert_equal(ifa1_data->conn_bal, 0, "ifa1 should not be affected by ifb"); + zassert_equal(ifa1_data->call_cnt_a, 2, "ifa1 should not be affected by ifb"); + zassert_equal(ifa1_data->call_cnt_b, 0, "ifa1 should not be affected by ifb"); + + zassert_equal(ifa2_data->conn_bal, 1, "ifa1 should not be affected by ifb"); + zassert_equal(ifa2_data->call_cnt_a, 1, "ifa1 should not be affected by ifb"); + zassert_equal(ifa2_data->call_cnt_b, 0, "ifa1 should not be affected by ifb"); + + zassert_equal(ifb_data->conn_bal, 0, "ifa1->disconnect should be called once"); + zassert_equal(ifb_data->call_cnt_a, 0, "Implementation B should be used for ifb"); + zassert_equal(ifb_data->call_cnt_b, 2, "Implementation B should be used for ifb"); + + /* Finally, disconnect the last A iface */ + zassert_equal(conn_mgr_if_disconnect(ifa2), 0, "conn_mgr_if_disconnect should not fail"); + k_sleep(K_MSEC(1)); + + + /* Verify success, and that only the target iface/conn impl were affected/invoked */ + zassert_false(net_if_is_up(ifa1), "ifa1 should still be disconnected"); + zassert_false(net_if_is_up(ifa2), "ifa2 should be oper-down after conn_mgr_if_disconnect"); + zassert_false(net_if_is_up(ifb), "ifb should still be disconnected"); + + /* Verify that all ifaces have the expected call counts and types */ + zassert_equal(ifa1_data->conn_bal, 0, "ifa1 should not be affected by ifa2"); + zassert_equal(ifa1_data->call_cnt_a, 2, "ifa1 should not be affected by ifa2"); + zassert_equal(ifa1_data->call_cnt_b, 0, "ifa1 should not be affected by ifa2"); + + zassert_equal(ifa2_data->conn_bal, 0, "ifa2->disconnect should be called once"); + zassert_equal(ifa2_data->call_cnt_a, 2, "Implementation A should be used for ifa2"); + zassert_equal(ifa2_data->call_cnt_b, 0, "Implementation A should be used for ifa2"); + + zassert_equal(ifb_data->conn_bal, 0, "ifb should not be affected by ifa2"); + zassert_equal(ifb_data->call_cnt_a, 0, "ifb should not be affected by ifa2"); + zassert_equal(ifb_data->call_cnt_b, 2, "ifb should not be affected by ifa2"); +} + +/* Verify that double calls to conn_mgr_if_connect and conn_mgr_if_disconnect cause no problems */ +ZTEST(conn_mgr_conn, test_connect_disconnect_double_delayed) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); + + /* Connect iface */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success */ + zassert_true(net_if_is_up(ifa1), "ifa1 should be oper-up after conn_mgr_if_connect"); + zassert_equal(ifa1_data->conn_bal, 1, "ifa1->connect should have been called once."); + zassert_equal(ifa1_data->call_cnt_a, 1, "ifa1->connect should have been called once."); + + /* Connect iface again */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success + * To be clear: Yes, ifa1->connect should be called twice. It is up to the L2 + * connectivity implementation to either handle idempotence + */ + zassert_true(net_if_is_up(ifa1), "ifa1 should still be connected"); + zassert_equal(ifa1_data->conn_bal, 2, "ifa1->connect should have been called again."); + zassert_equal(ifa1_data->call_cnt_a, 2, "ifa1->connect should have been called again."); + + /* Now disconnect the iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success */ + zassert_false(net_if_is_up(ifa1), "ifa1 should be oper-down after conn_mgr_if_disconnect"); + zassert_equal(ifa1_data->conn_bal, 1, "ifa1->disconnect should have been called once."); + zassert_equal(ifa1_data->call_cnt_a, 3, "ifa1->disconnect should have been called once."); + + /* Disconnect again! */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success */ + zassert_false(net_if_is_up(ifa1), "ifa1 should be oper-down after conn_mgr_if_disconnect"); + zassert_equal(ifa1_data->conn_bal, 0, "ifa1->disconnect should have been called again."); + zassert_equal(ifa1_data->call_cnt_a, 4, "ifa1->disconnect should have been called again."); +} + +/* Verify that fast double calls to conn_mgr_if_connect and conn_mgr_if_disconnect + * do not fail + */ +ZTEST(conn_mgr_conn, test_connect_disconnect_double_instant) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); + + /* Connect twice */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success */ + zassert_true(net_if_is_up(ifa1), "ifa1 should be oper-up after conn_mgr_if_connect"); + zassert_equal(ifa1_data->conn_bal, 2, "ifa1->connect should have been called once."); + zassert_equal(ifa1_data->call_cnt_a, 2, "ifa1->connect should have been called once."); + + /* Now disconnect twice */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify success */ + zassert_false(net_if_is_up(ifa1), "ifa1 should be oper-down after conn_mgr_if_disconnect"); + zassert_equal(ifa1_data->conn_bal, 0, "ifa1->disconnect should have been called once."); + zassert_equal(ifa1_data->call_cnt_a, 4, "ifa1->disconnect should have been called once."); +} + +/* Verify that connecting an iface that isn't up, missing an API, + * or isn't connectivity-bound raises an error. + */ +ZTEST(conn_mgr_conn, test_connect_invalid) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Bring ifnull and ifnone up */ + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for ifnull"); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for ifnone"); + + /* Attempts to connect ifa1 without bringing it up should fail */ + zassert_equal(conn_mgr_if_connect(ifa1), -ESHUTDOWN, + "conn_mgr_if_connect should give -ENOTSUP for down iface"); + zassert_equal(ifa1_data->conn_bal, 0, + "conn_mgr_if_connect should not affect down iface"); + zassert_equal(ifa1_data->call_cnt_a, 0, + "conn_mgr_if_connect should not affect down iface"); + + /* Attempts to connect ifnull should fail, even if it is up */ + zassert_equal(conn_mgr_if_connect(ifnull), -ENOTSUP, + "conn_mgr_if_connect should give -ENOTSUP for ifnull"); + + /* Attempts to connect ifnone should fail, even if it is up */ + zassert_equal(conn_mgr_if_connect(ifnone), -ENOTSUP, + "conn_mgr_if_connect should give -ENOTSUP for ifnone"); +} + +/* Verify that disconnecting an iface that isn't up, missing an API, + * or isn't connectivity-bound raises an error. + */ +ZTEST(conn_mgr_conn, test_disconnect_invalid) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Bring ifnull and ifnone up */ + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for ifnull"); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for ifnone"); + + /* Attempts to disconnect ifa1 without bringing it up should fail */ + zassert_equal(conn_mgr_if_disconnect(ifa1), -EALREADY, + "conn_mgr_if_disconnect should give -ENOTSUP for down iface"); + zassert_equal(ifa1_data->conn_bal, 0, + "conn_mgr_if_disconnect should not affect down iface"); + zassert_equal(ifa1_data->call_cnt_a, 0, + "conn_mgr_if_disconnect should not affect down iface"); + + /* Attempts to disconnect ifnull should fail, even if it is up */ + zassert_equal(conn_mgr_if_disconnect(ifnull), -ENOTSUP, + "conn_mgr_if_disconnect should give -ENOTSUP for ifnull"); + + /* Attempts to disconnect ifnone should fail, even if it is up */ + zassert_equal(conn_mgr_if_disconnect(ifnone), -ENOTSUP, + "conn_mgr_if_disconnect should give -ENOTSUP for ifnone"); +} + +/* Verify that conn_mgr_if_connect forwards error codes from API */ +ZTEST(conn_mgr_conn, test_connect_fail) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Instruct ifa1 to fail on connect attempt */ + ifa1_data->api_err = -ECHILD; + + /* Take ifa1 up before attempting to connect */ + zassert_equal(net_if_up(ifa1), 0, + "conn_mgr_if_connect should succeed"); + + /* Attempts to connect ifa1 should return the expected error*/ + zassert_equal(conn_mgr_if_connect(ifa1), -ECHILD, + "conn_mgr_if_connect should give -ECHILD"); +} + +/* Verify that conn_mgr_if_disconnect forwards error codes from API */ +ZTEST(conn_mgr_conn, test_disconnect_fail) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Take up and connect iface first */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed"); + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed"); + + /* Instruct ifa1 to fail on disconnect attempt */ + ifa1_data->api_err = -EDOM; + + /* Attempts to disconnect ifa1 should return the expected error*/ + zassert_equal(conn_mgr_if_disconnect(ifa1), -EDOM, + "conn_mgr_if_disconnect should give -EDOM"); +} + +/* Verify that conn_mgr_if_is_bound gives correct results */ +ZTEST(conn_mgr_conn, test_supports_connectivity) +{ + zassert_true(conn_mgr_if_is_bound(ifa1)); + zassert_true(conn_mgr_if_is_bound(ifa2)); + zassert_true(conn_mgr_if_is_bound(ifb)); + zassert_false(conn_mgr_if_is_bound(ifnull)); + zassert_false(conn_mgr_if_is_bound(ifnone)); +} + +/* 60 characters long */ +#define TEST_STR_LONG "AAAAAaaaaaBBBBBbbbbbCCCCCcccccDDDDDdddddEEEEEeeeeeFFFFFfffff" + +/* Verify that conn_opt get/set functions operate correctly and affect only the target iface */ +ZTEST(conn_mgr_conn, test_conn_opt) +{ + char buf[100]; + size_t buf_len = 0; + + /* Set ifa1->X to "A" */ + strcpy(buf, "A"); + zassert_equal(conn_mgr_if_set_opt(ifa1, TEST_CONN_OPT_X, &buf, strlen(buf) + 1), 0, + "conn_mgr_if_set_opt should succeed for valid parameters"); + + /* Verify success */ + memset(buf, 0, sizeof(buf)); + buf_len = sizeof(buf); + zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, &buf, &buf_len), + 0, "conn_mgr_if_get_opt should succeed for valid parameters"); + printk("%d, %d", buf_len, strlen(buf) + 1); + zassert_equal(buf_len, strlen(buf) + 1, "conn_mgr_if_get_opt should return valid optlen"); + zassert_equal(strcmp(buf, "A"), 0, "conn_mgr_if_get_opt should retrieve \"A\""); + + /* Verify that ifa1->Y was not affected */ + memset(buf, 0, sizeof(buf)); + buf_len = sizeof(buf); + zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_Y, &buf, &buf_len), + 0, "conn_mgr_if_get_opt should succeed for valid parameters"); + zassert_equal(buf_len, 1, "conn_mgr_if_get_opt should yield nothing for ifa1->Y"); + zassert_equal(buf[0], 0, "conn_mgr_if_get_opt should yield nothing for ifa1->Y"); + + /* Verify that ifa2->X was not affected */ + memset(buf, 0, sizeof(buf)); + buf_len = sizeof(buf); + zassert_equal(conn_mgr_if_get_opt(ifa2, TEST_CONN_OPT_X, &buf, &buf_len), + 0, "conn_mgr_if_get_opt should succeed for valid parameters"); + zassert_equal(buf_len, 1, "conn_mgr_if_get_opt should yield nothing for ifa2->X"); + zassert_equal(buf[0], 0, "conn_mgr_if_get_opt should yield nothing for ifa2->X"); + + /* Now, set ifa->Y to "ABC" */ + strcpy(buf, "ABC"); + zassert_equal(conn_mgr_if_set_opt(ifa1, TEST_CONN_OPT_Y, &buf, strlen(buf) + 1), 0, + "conn_mgr_if_set_opt should succeed for valid parameters"); + + /* Verify success */ + memset(buf, 0, sizeof(buf)); + buf_len = sizeof(buf); + zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_Y, &buf, &buf_len), + 0, "conn_mgr_if_get_opt should succeed for valid parameters"); + zassert_equal(buf_len, strlen(buf) + 1, "conn_mgr_if_get_opt should return valid optlen"); + zassert_equal(strcmp(buf, "ABC"), 0, "conn_mgr_if_get_opt should retrieve \"ABC\""); + + /* Verify that ifa1->X was not affected */ + memset(buf, 0, sizeof(buf)); + buf_len = sizeof(buf); + zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, &buf, &buf_len), + 0, "conn_mgr_if_get_opt should succeed for valid parameters"); + zassert_equal(buf_len, strlen(buf) + 1, "conn_mgr_if_get_opt should return valid optlen"); + zassert_equal(strcmp(buf, "A"), 0, "conn_mgr_if_get_opt should retrieve \"A\""); + + /* Next, we pass some buffers that are too large or too small. + * This is an indirect way of verifying that buf_len is passed correctly. + */ + + /* Try writing a string that is too large to ifa1->X */ + strcpy(buf, TEST_STR_LONG); + zassert_equal(conn_mgr_if_set_opt(ifa1, TEST_CONN_OPT_X, &buf, strlen(buf) + 1), 0, + "conn_mgr_if_set_opt should succeed for valid parameters"); + + /* Verify partial success */ + memset(buf, 0, sizeof(buf)); + buf_len = sizeof(buf); + zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, &buf, &buf_len), 0, + "conn_mgr_if_get_opt should succeed for valid parameters"); + zassert_equal(buf_len, strlen(buf) + 1, + "conn_mgr_if_get_opt should return valid optlen"); + + /* This does, technically, test the test harness, but this test will fail if + * the unit under test (conn_mgr_if_set_opt) fails to pass along the optlen + */ + zassert_true(strlen(buf) < strlen(TEST_STR_LONG), + "test_set_opt_a should truncate long values"); + + /* For the same reason, verify that get_opt truncates given a small destination buffer */ + memset(buf, 0, sizeof(buf)); + buf_len = 10; + zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, &buf, &buf_len), 0, + "conn_mgr_if_get_opt should succeed for valid parameters"); + zassert_equal(buf_len, strlen(buf) + 1, + "conn_mgr_if_get_opt should return valid optlen"); + zassert_equal(buf_len, 10, + "test_get_opt_a should truncate if dest. buffer is too small."); +} + +/* Verify that conn_mgr_if_get_opt and conn_mgr_if_set_opt behave as expected when given invalid + * arguments. + */ +ZTEST(conn_mgr_conn, test_conn_opt_invalid) +{ + char buf[100]; + size_t buf_len; + + /* Verify that getting/setting non-existent option on ifa1 fails */ + zassert_equal(conn_mgr_if_set_opt(ifa1, -1, "A", strlen("A")), -ENOPROTOOPT, + "conn_mgr_if_set_opt should fail with invalid optname"); + buf_len = sizeof(buf_len); + zassert_equal(conn_mgr_if_get_opt(ifa1, -1, buf, &buf_len), -ENOPROTOOPT, + "conn_mgr_if_get_opt should fail with invalid optname"); + zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); + + /* Verify that getting/setting with NULL buffer on ifa1 fails */ + zassert_equal(conn_mgr_if_set_opt(ifa1, TEST_CONN_OPT_X, NULL, 100), -EINVAL, + "conn_mgr_if_set_opt should fail with invalid buffer"); + buf_len = sizeof(buf_len); + zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, NULL, &buf_len), -EINVAL, + "conn_mgr_if_get_opt should fail with invalid buffer"); + zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); + + /* Verify that getting with NULL buffer length on ifa1 fails */ + zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, buf, NULL), -EINVAL, + "conn_mgr_if_get_opt should fail with invalid buffer length"); + + /* Verify that getting/setting with ifnull fails */ + zassert_equal(conn_mgr_if_set_opt(ifnull, TEST_CONN_OPT_X, "A", strlen("A")), -ENOTSUP, + "conn_mgr_if_set_opt should fail for ifnull"); + buf_len = sizeof(buf_len); + zassert_equal(conn_mgr_if_get_opt(ifnull, TEST_CONN_OPT_X, buf, &buf_len), -ENOTSUP, + "conn_mgr_if_get_opt should fail for ifnull"); + zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); + + /* Verify that getting/setting with ifnone fails */ + zassert_equal(conn_mgr_if_set_opt(ifnone, TEST_CONN_OPT_X, "A", strlen("A")), -ENOTSUP, + "conn_mgr_if_set_opt should fail for ifnull"); + buf_len = sizeof(buf_len); + zassert_equal(conn_mgr_if_get_opt(ifnone, TEST_CONN_OPT_X, buf, &buf_len), -ENOTSUP, + "conn_mgr_if_get_opt should fail for ifnull"); + zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); + + /* Verify that getting/setting with ifb fails (since implementation B doesn't support it) */ + zassert_equal(conn_mgr_if_set_opt(ifb, TEST_CONN_OPT_X, "A", strlen("A")), -ENOTSUP, + "conn_mgr_if_set_opt should fail for ifb"); + buf_len = sizeof(buf_len); + zassert_equal(conn_mgr_if_get_opt(ifb, TEST_CONN_OPT_X, buf, &buf_len), -ENOTSUP, + "conn_mgr_if_get_opt should fail for ifb"); + zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); +} + +/* Verify that flag get/set functions operate correctly */ +ZTEST(conn_mgr_conn, test_flags) +{ + struct conn_mgr_conn_binding *ifa1_binding = conn_mgr_if_get_binding(ifa1); + + /* Try setting persistence flag */ + zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true), 0, + "Setting persistence flag should succeed for ifa1"); + + /* Verify success */ + zassert_true(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_PERSISTENT), + "Persistence should be set for ifa1"); + + /* Verify that the conn struct agrees, since this is what implementations may use */ + zassert_equal(ifa1_binding->flags, BIT(CONN_MGR_IF_PERSISTENT), + "Persistence flag set should affect conn struct"); + + /* Try unsetting persistence flag */ + zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false), 0, + "Unsetting persistence flag should succeed for ifa1"); + + /* Verify success */ + zassert_false(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_PERSISTENT), + "Persistence should be unset for ifa1"); + + /* Verify that the conn struct agrees, since this is what implementations may use */ + zassert_equal(ifa1_binding->flags, 0, + "Persistence flag unset should affect conn struct"); +} + +/* Verify that flag get/set fail and behave as expected respectively for invalid ifaces and + * invalid flags. + */ +ZTEST(conn_mgr_conn, test_flags_invalid) +{ + int invalid_flag = CONN_MGR_NUM_IF_FLAGS; + + /* Verify set failure for invalid ifaces / flags */ + zassert_equal(conn_mgr_if_set_flag(ifnull, CONN_MGR_IF_PERSISTENT, true), -ENOTSUP, + "Setting persistence flag should fail for ifnull"); + zassert_equal(conn_mgr_if_set_flag(ifnone, CONN_MGR_IF_PERSISTENT, true), -ENOTSUP, + "Setting persistence flag should fail for ifnone"); + zassert_equal(conn_mgr_if_set_flag(ifa1, invalid_flag, true), -EINVAL, + "Setting invalid flag should fail for ifa1"); + + /* Verify get graceful behavior for invalid ifaces / flags */ + zassert_false(conn_mgr_if_get_flag(ifnull, CONN_MGR_IF_PERSISTENT), + "Getting persistence flag should yield false for ifnull"); + zassert_false(conn_mgr_if_get_flag(ifnone, CONN_MGR_IF_PERSISTENT), + "Getting persistence flag should yield false for ifnone"); + zassert_false(conn_mgr_if_get_flag(ifa1, invalid_flag), + "Getting invalid flag should yield false for ifa1"); +} + + +/* Verify that timeout get/set functions operate correctly (A/B) */ +ZTEST(conn_mgr_conn, test_timeout) +{ + struct conn_mgr_conn_binding *ifa1_binding = conn_mgr_if_get_binding(ifa1); + + /* Try setting timeout */ + zassert_equal(conn_mgr_if_set_timeout(ifa1, 99), 0, + "Setting timeout should succeed for ifa1"); + + /* Verify success */ + zassert_equal(conn_mgr_if_get_timeout(ifa1), 99, + "Timeout should be set to 99 for ifa1"); + + /* Verify that the conn struct agrees, since this is what implementations may use */ + zassert_equal(ifa1_binding->timeout, 99, + "Timeout set should affect conn struct"); + + /* Try unsetting timeout */ + zassert_equal(conn_mgr_if_set_timeout(ifa1, CONN_MGR_IF_NO_TIMEOUT), 0, + "Unsetting timeout should succeed for ifa1"); + + /* Verify success */ + zassert_equal(conn_mgr_if_get_timeout(ifa1), CONN_MGR_IF_NO_TIMEOUT, + "Timeout should be unset for ifa1"); + + /* Verify that the conn struct agrees, since this is what implementations may use */ + zassert_equal(ifa1_binding->timeout, CONN_MGR_IF_NO_TIMEOUT, + "Timeout unset should affect conn struct"); +} + +/* Verify that timeout get/set fail and behave as expected respectively for invalid ifaces */ +ZTEST(conn_mgr_conn, test_timeout_invalid) +{ + /* Verify set failure */ + zassert_equal(conn_mgr_if_set_timeout(ifnull, 99), -ENOTSUP, + "Setting timeout should fail for ifnull"); + zassert_equal(conn_mgr_if_set_timeout(ifnone, 99), -ENOTSUP, + "Setting timeout should fail for ifnone"); + + /* Verify get graceful behavior */ + zassert_equal(conn_mgr_if_get_timeout(ifnull), CONN_MGR_IF_NO_TIMEOUT, + "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnull"); + zassert_equal(conn_mgr_if_get_timeout(ifnone), CONN_MGR_IF_NO_TIMEOUT, + "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnone"); +} + +ZTEST_SUITE(conn_mgr_conn, NULL, NULL, conn_mgr_conn_before, NULL, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c new file mode 100644 index 000000000000..6004fe34974b --- /dev/null +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "test_conn_impl.h" + +static void inc_call_count(struct test_conn_data *data, bool a) +{ + if (a) { + data->call_cnt_a += 1; + } else { + data->call_cnt_b += 1; + } +} + +static int test_connect(struct conn_mgr_conn_binding *const binding, bool a) +{ + struct test_conn_data *data = binding->ctx; + + inc_call_count(data, a); + + if (data->api_err != 0) { + return data->api_err; + } + + data->conn_bal += 1; + /* Mark iface as connected */ + net_if_dormant_off(binding->iface); + return 0; +} + +static int test_disconnect(struct conn_mgr_conn_binding *const binding, bool a) +{ + struct test_conn_data *data = binding->ctx; + + inc_call_count(data, a); + + if (data->api_err != 0) { + return data->api_err; + } + + data->conn_bal -= 1; + + /* Mark iface as dormant (disconnected) */ + net_if_dormant_on(binding->iface); + return 0; +} + +char *opt_pointer(struct test_conn_data *data, int optname) +{ + switch (optname) { + case TEST_CONN_OPT_X: + return data->data_x; + case TEST_CONN_OPT_Y: + return data->data_y; + } + return NULL; +} + +int test_set_opt_a(struct conn_mgr_conn_binding *const binding, int optname, + const void *optval, size_t optlen) +{ + struct test_conn_data *data = binding->ctx; + char *target = opt_pointer(data, optname); + int len = MIN(optlen, TEST_CONN_DATA_LEN); + + /* get/set opt are only implemented for implementation A */ + inc_call_count(data, true); + + if (target == NULL) { + return -ENOPROTOOPT; + } + + if (data->api_err) { + return data->api_err; + } + + (void)memset(target, 0, TEST_CONN_DATA_LEN); + (void)memcpy(target, optval, len); + + return 0; +} + +int test_get_opt_a(struct conn_mgr_conn_binding *const binding, int optname, + void *optval, size_t *optlen) +{ + struct test_conn_data *data = binding->ctx; + char *target = opt_pointer(data, optname); + int len; + + /* get/set opt are only implemented for implementation A */ + inc_call_count(data, true); + + if (target == NULL) { + *optlen = 0; + return -ENOPROTOOPT; + } + + len = MIN(strlen(target) + 1, *optlen); + + if (data->api_err) { + *optlen = 0; + return data->api_err; + } + *optlen = len; + (void)memset(optval, 0, len); + (void)memcpy(optval, target, len-1); + + return 0; +} + +static void test_init(struct conn_mgr_conn_binding *const binding, bool a) +{ + struct test_conn_data *data = binding->ctx; + + if (a) { + data->init_calls_a += 1; + } else { + data->init_calls_b += 1; + } + + /* Mark the iface dormant (disconnected) on initialization */ + net_if_dormant_on(binding->iface); +} + +static void test_init_a(struct conn_mgr_conn_binding *const binding) +{ + test_init(binding, true); +} + +static void test_init_b(struct conn_mgr_conn_binding *const binding) +{ + test_init(binding, false); +} + +static int test_connect_a(struct conn_mgr_conn_binding *const binding) +{ + return test_connect(binding, true); +} + +static int test_connect_b(struct conn_mgr_conn_binding *const binding) +{ + return test_connect(binding, false); +} + +static int test_disconnect_a(struct conn_mgr_conn_binding *const binding) +{ + return test_disconnect(binding, true); +} + +static int test_disconnect_b(struct conn_mgr_conn_binding *const binding) +{ + return test_disconnect(binding, false); +} + +static struct conn_mgr_conn_api test_conn_api_a = { + .connect = test_connect_a, + .disconnect = test_disconnect_a, + .init = test_init_a, + .get_opt = test_get_opt_a, + .set_opt = test_set_opt_a +}; + +static struct conn_mgr_conn_api test_conn_api_b = { + .connect = test_connect_b, + .disconnect = test_disconnect_b, + .init = test_init_b, +}; + +static struct conn_mgr_conn_api test_conn_api_ni = { + .connect = test_connect_a, + .disconnect = test_disconnect_a, +}; + +/* Equivalent but distinct implementations */ +CONN_MGR_CONN_DEFINE(TEST_L2_CONN_IMPL_A, &test_conn_api_a); +CONN_MGR_CONN_DEFINE(TEST_L2_CONN_IMPL_B, &test_conn_api_b); + +/* Implementation without init */ +CONN_MGR_CONN_DEFINE(TEST_L2_CONN_IMPL_NI, &test_conn_api_ni); + +/* Bad implementation, should be handled gracefully */ +CONN_MGR_CONN_DEFINE(TEST_L2_CONN_IMPL_N, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h new file mode 100644 index 000000000000..170ffc436bf4 --- /dev/null +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + + + +/* test_conn_impl is separated into its own file specifically in order to test that + * CONN_MGR_CONN_DECLARE_PUBLIC functions as expected. + */ + + +#ifndef ZEPHYR_INCLUDE_TEST_CONN_IMPL_H_ +#define ZEPHYR_INCLUDE_TEST_CONN_IMPL_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEST_CONN_OPT_X 0 +#define TEST_CONN_OPT_Y 1 +#define TEST_CONN_DATA_LEN 50 + +struct test_conn_data { + /* The number of times an A-implementation API func has been called (other than init) */ + int call_cnt_a; + + /* The number of times a B-implementation API func has been called (other than init) */ + int call_cnt_b; + + /* Increases on each connect call, decreases on each disconnect call */ + int conn_bal; + + /* The number of times A-implementation init was called (should always be 1) */ + int init_calls_a; + + /* The number of times B-implementation init was called (should always be 1) */ + int init_calls_b; + + /* If nonzero, an error code the APIs should return. */ + int api_err; + + /* Places to store data from set_opt calls */ + char data_x[TEST_CONN_DATA_LEN + 1]; + char data_y[TEST_CONN_DATA_LEN + 1]; +}; + +/* Create test L2 connectivity implementations A and B + * + * A and B share generic connect/disconnect implementations that differ only in which call counter + * they increment. + * + * Additionally, A has conn_opt callbacks, whereas B does not. + */ +#define TEST_L2_CONN_IMPL_A_CTX_TYPE struct test_conn_data +CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_A); + +#define TEST_L2_CONN_IMPL_B_CTX_TYPE struct test_conn_data +CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_B); + +/* Create an invalid L2 connectivity implementation with NULL API */ +#define TEST_L2_CONN_IMPL_N_CTX_TYPE struct test_conn_data +CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_N); + +/* Create an L2 connectivity implementation without the optional init */ +#define TEST_L2_CONN_IMPL_NI_CTX_TYPE struct test_conn_data +CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_TEST_CONN_IMPL_H_ */ diff --git a/tests/net/conn_mgr_conn/src/test_ifaces.c b/tests/net/conn_mgr_conn/src/test_ifaces.c new file mode 100644 index 000000000000..23accdd1e803 --- /dev/null +++ b/tests/net/conn_mgr_conn/src/test_ifaces.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "test_conn_impl.h" +#include "test_ifaces.h" + +/* Create test ifaces */ + +/* Generic iface initializer, shared by all three ifaces */ +static void test_iface_init(struct net_if *iface) +{ + /* Fake link layer address is needed to silence assertions inside the net core */ + static uint8_t fake_lladdr[] = { 0x01 }; + + net_if_set_link_addr(iface, fake_lladdr, sizeof(fake_lladdr), NET_LINK_DUMMY); + + /* Do not automatically start the iface */ + net_if_flag_set(iface, NET_IF_NO_AUTO_START); +} + +/* Mandatory stub for NET_DEVICE_INIT */ +static int test_iface_netdev_init(const struct device *dev) +{ + return 0; +} + +static struct dummy_api test_iface_api = { + .iface_api.init = test_iface_init, +}; + +/* Create three ifaces, a1, a2, b such that: + * iface a1 and a2 share L2 connectivity implementation a + * iface b uses connectivity implementation b + */ +NET_DEVICE_INIT(test_iface_a1, + "test_iface_a1", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); +NET_DEVICE_INIT(test_iface_a2, + "test_iface_a2", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); +NET_DEVICE_INIT(test_iface_b, + "test_iface_b", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); + +/* Create an ifaces with NULL implementation, NULL init, and no connectivity at all */ +NET_DEVICE_INIT(test_iface_null, + "test_iface_null", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); +NET_DEVICE_INIT(test_iface_ni, + "test_iface_ni", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); +NET_DEVICE_INIT(test_iface_none, + "test_iface_none", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); + +/* Bind L2 connectivity implementations to ifaces */ +CONN_MGR_BIND_CONN(test_iface_a1, TEST_L2_CONN_IMPL_A); +CONN_MGR_BIND_CONN(test_iface_a2, TEST_L2_CONN_IMPL_A); +CONN_MGR_BIND_CONN(test_iface_b, TEST_L2_CONN_IMPL_B); + +/* Bind edge-case L2 connectivity implementations to ifaces */ +CONN_MGR_BIND_CONN(test_iface_null, TEST_L2_CONN_IMPL_N); +CONN_MGR_BIND_CONN(test_iface_ni, TEST_L2_CONN_IMPL_NI); + +/* Public accessors for static iface structs */ +struct net_if *ifa1 = NET_IF_GET(test_iface_a1, 0); +struct net_if *ifa2 = NET_IF_GET(test_iface_a2, 0); +struct net_if *ifb = NET_IF_GET(test_iface_b, 0); +struct net_if *ifni = NET_IF_GET(test_iface_ni, 0); +struct net_if *ifnull = NET_IF_GET(test_iface_null, 0); +struct net_if *ifnone = NET_IF_GET(test_iface_none, 0); diff --git a/tests/net/conn_mgr_conn/src/test_ifaces.h b/tests/net/conn_mgr_conn/src/test_ifaces.h new file mode 100644 index 000000000000..acae7cf78bf3 --- /dev/null +++ b/tests/net/conn_mgr_conn/src/test_ifaces.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_TEST_IFACES_H_ +#define ZEPHYR_INCLUDE_TEST_IFACES_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Public accessors for static iface structs */ + +extern struct net_if *ifa1; +extern struct net_if *ifa2; +extern struct net_if *ifb; +extern struct net_if *ifni; +extern struct net_if *ifnull; +extern struct net_if *ifnone; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_TEST_IFACES_H_ */ diff --git a/tests/net/conn_mgr_conn/testcase.yaml b/tests/net/conn_mgr_conn/testcase.yaml new file mode 100644 index 000000000000..77cf06a13095 --- /dev/null +++ b/tests/net/conn_mgr_conn/testcase.yaml @@ -0,0 +1,6 @@ +common: + min_ram: 16 + depends_on: netif +tests: + net.conn_mgr_conn: + tags: net iface From 62ed73d1c9af8b3ad6767f02470556a205052fe5 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Wed, 19 Apr 2023 12:42:59 -0700 Subject: [PATCH 067/528] [nrf fromtree] net: conn_mgr: Fix event definitions conn_mgr events cannot be used due to mistake in event definitions. Fix these definitions so that events can be used. Also patch hole in test coverage that allowed this in the first place. Signed-off-by: Georges Oates_Larsen (cherry picked from commit fdaeabfdb644fa86ff959fca6cb1c84338f9789f) (cherry picked from commit 5a47016a6f44f9d6accb914f6b4ad1393a453b1a) --- include/zephyr/net/conn_mgr_connectivity.h | 2 +- tests/net/conn_mgr_conn/src/main.c | 126 ++++++++++++++++++- tests/net/conn_mgr_conn/src/test_conn_impl.c | 81 ++++++++++++ tests/net/conn_mgr_conn/src/test_conn_impl.h | 9 ++ 4 files changed, 216 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 023b043a249a..7f035a277b51 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -34,7 +34,7 @@ extern "C" { #define _NET_MGMT_CONN_LAYER NET_MGMT_LAYER(NET_MGMT_LAYER_L2) #define _NET_MGMT_CONN_CODE NET_MGMT_LAYER_CODE(0x207) #define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE) -#define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_EVENT) +#define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_BASE) enum net_event_ethernet_cmd { NET_EVENT_CONN_CMD_IF_TIMEOUT = 1, diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index e8da4e9d7d58..3906d9729e66 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -67,11 +67,50 @@ static void reset_test_iface(struct net_if *iface) iface_data->call_cnt_b = 0; iface_data->conn_bal = 0; iface_data->api_err = 0; + iface_data->fatal_error = 0; + iface_data->timeout = false; memset(iface_data->data_x, 0, sizeof(iface_data->data_x)); memset(iface_data->data_y, 0, sizeof(iface_data->data_y)); } } + +/* NET_MGMT event tracking */ + +static K_MUTEX_DEFINE(event_mutex); +static struct event_stats { + int timeout_count; + int fatal_error_count; + int event_count; + int event_info; + struct net_if *event_iface; +} test_event_stats; + +struct net_mgmt_event_callback conn_mgr_conn_callback; + +static void conn_mgr_conn_handler(struct net_mgmt_event_callback *cb, + uint32_t event, struct net_if *iface) +{ + k_mutex_lock(&event_mutex, K_FOREVER); + + if (event == NET_EVENT_CONN_IF_TIMEOUT) { + test_event_stats.timeout_count += 1; + } else if (event == NET_EVENT_CONN_IF_FATAL_ERROR) { + test_event_stats.fatal_error_count += 1; + } + + test_event_stats.event_count += 1; + test_event_stats.event_iface = iface; + + if (cb->info) { + test_event_stats.event_info = *((int *)cb->info); + } else { + test_event_stats.event_info = 0; + } + + k_mutex_unlock(&event_mutex); +} + static void conn_mgr_conn_before(void *data) { ARG_UNUSED(data); @@ -81,6 +120,24 @@ static void conn_mgr_conn_before(void *data) reset_test_iface(ifni); reset_test_iface(ifnone); reset_test_iface(ifnull); + + k_mutex_lock(&event_mutex, K_FOREVER); + + test_event_stats.event_count = 0; + test_event_stats.timeout_count = 0; + test_event_stats.fatal_error_count = 0; + test_event_stats.event_iface = NULL; + test_event_stats.event_info = 0; + + k_mutex_unlock(&event_mutex); +} + +static void *conn_mgr_conn_setup(void) +{ + net_mgmt_init_event_callback(&conn_mgr_conn_callback, conn_mgr_conn_handler, + NET_EVENT_CONN_IF_TIMEOUT | NET_EVENT_CONN_IF_FATAL_ERROR); + net_mgmt_add_event_callback(&conn_mgr_conn_callback); + return NULL; } /* This suite uses k_sleep(K_MSEC(1)) to allow Zephyr to perform event propagation. @@ -441,6 +498,73 @@ ZTEST(conn_mgr_conn, test_disconnect_fail) "conn_mgr_if_disconnect should give -EDOM"); } +/* Verify that the NET_EVENT_CONN_IF_TIMEOUT event works as expected. */ +ZTEST(conn_mgr_conn, test_connect_timeout) +{ + struct event_stats stats; + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* instruct ifa1 to timeout on connect */ + ifa1_data->timeout = true; + + /* Take up and attempt to connect iface */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed"); + + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed"); + + /* Confirm iface is not immediately connected */ + zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); + + /* Ensure timeout event is fired */ + k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); + + k_mutex_lock(&event_mutex, K_FOREVER); + stats = test_event_stats; + k_mutex_unlock(&event_mutex); + + zassert_equal(stats.timeout_count, 1, + "NET_EVENT_CONN_IF_TIMEOUT should have been fired"); + zassert_equal(stats.event_count, 1, + "only NET_EVENT_CONN_IF_TIMEOUT should have been fired"); + zassert_equal(stats.event_iface, ifa1, + "Timeout event should be raised on ifa1"); +} + +/* Verify that the NET_EVENT_CONN_IF_FATAL_ERROR event works as expected. */ +ZTEST(conn_mgr_conn, test_connect_fatal_error) +{ + struct event_stats stats; + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* instruct ifa1 to have fatal error on connect. */ + ifa1_data->fatal_error = -EADDRINUSE; + + /* Take up and attempt to connect iface */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed"); + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed"); + + /* Confirm iface is not immediately connected */ + zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); + + /* Ensure fatal_error event is fired */ + k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); + + k_mutex_lock(&event_mutex, K_FOREVER); + stats = test_event_stats; + k_mutex_unlock(&event_mutex); + + zassert_equal(stats.fatal_error_count, 1, + "NET_EVENT_CONN_IF_FATAL_ERROR should have been fired"); + zassert_equal(stats.event_count, 1, + "only NET_EVENT_CONN_IF_FATAL_ERROR should have been fired"); + zassert_equal(stats.event_iface, ifa1, + "Fatal error event should be raised on ifa1"); + zassert_equal(stats.event_info, -EADDRINUSE, + "Fatal error info should be -EADDRINUSE"); +} + + + /* Verify that conn_mgr_if_is_bound gives correct results */ ZTEST(conn_mgr_conn, test_supports_connectivity) { @@ -699,4 +823,4 @@ ZTEST(conn_mgr_conn, test_timeout_invalid) "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnone"); } -ZTEST_SUITE(conn_mgr_conn, NULL, NULL, conn_mgr_conn_before, NULL, NULL); +ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c index 6004fe34974b..8d2395160590 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -8,6 +8,72 @@ #include #include "test_conn_impl.h" +/* Event simulation */ +static int simulated_event; +static struct net_if *simulated_event_iface; +static K_MUTEX_DEFINE(simulated_event_mutex); + +/* Static storage for fatal error info */ +static int fatal_error; + +void simulate_event_handler(struct k_work *work) +{ + ARG_UNUSED(*work); + + k_mutex_lock(&simulated_event_mutex, K_FOREVER); + + if (simulated_event == 0) { + net_mgmt_event_notify( + NET_EVENT_CONN_IF_TIMEOUT, + simulated_event_iface + ); + } else { + fatal_error = simulated_event; + net_mgmt_event_notify_with_info( + NET_EVENT_CONN_IF_FATAL_ERROR, + simulated_event_iface, &fatal_error, sizeof(fatal_error) + ); + } + + k_mutex_unlock(&simulated_event_mutex); +} + +static K_WORK_DELAYABLE_DEFINE(simulate_event_work, simulate_event_handler); + +/** + * @brief Simulates an event on the target iface. + * + * Do not attempt to simulate multiple events simultaneously -- only the last event requested + * will be fired. + * + * @param target - iface to simulate the event on. + * @param event - Event to simulate. + * If 0, simulate a timeout. + * Otherwise, simulate a fatal error with this value as the reason/info. + */ +static void simulate_event(struct net_if *target, int event) +{ + k_mutex_lock(&simulated_event_mutex, K_FOREVER); + + simulated_event = event; + simulated_event_iface = target; + k_work_reschedule(&simulate_event_work, K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS)); + + k_mutex_unlock(&simulated_event_mutex); +} + +static void simulate_timeout(struct net_if *target) +{ + simulate_event(target, 0); +} + +static void simulate_fatal_error(struct net_if *target, int reason) +{ + simulate_event(target, reason); +} + +/* Connectivity implementations */ + static void inc_call_count(struct test_conn_data *data, bool a) { if (a) { @@ -23,11 +89,26 @@ static int test_connect(struct conn_mgr_conn_binding *const binding, bool a) inc_call_count(data, a); + /* Fail immediately if requested */ if (data->api_err != 0) { return data->api_err; } + /* Fail after a delay if requested */ + if (data->fatal_error) { + simulate_fatal_error(binding->iface, data->fatal_error); + return 0; + } + + if (data->timeout) { + simulate_timeout(binding->iface); + return 0; + } + + /* Succeed otherwise */ + data->conn_bal += 1; + /* Mark iface as connected */ net_if_dormant_off(binding->iface); return 0; diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h index 170ffc436bf4..6408bb802cfc 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -15,6 +15,7 @@ #define ZEPHYR_INCLUDE_TEST_CONN_IMPL_H_ #include +#include #ifdef __cplusplus extern "C" { @@ -43,6 +44,12 @@ struct test_conn_data { /* If nonzero, an error code the APIs should return. */ int api_err; + /* If true, the implementation should time out on connect. */ + bool timeout; + + /* If nonzero, the implementation should fail to connect and raise this fatal error. */ + int fatal_error; + /* Places to store data from set_opt calls */ char data_x[TEST_CONN_DATA_LEN + 1]; char data_y[TEST_CONN_DATA_LEN + 1]; @@ -69,6 +76,8 @@ CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_N); #define TEST_L2_CONN_IMPL_NI_CTX_TYPE struct test_conn_data CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); +#define SIMULATED_EVENT_DELAY_SECONDS 5 + #ifdef __cplusplus } #endif From dc47180586120e29d2f80b5372565fc433356d36 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 28 Mar 2023 13:12:35 -0700 Subject: [PATCH 068/528] [nrf fromlist] net: conn_mgr: Reorganize files Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 Since conn_mgr is a subsystem rather than a library, relocate it directly into subsys/net rather than subsys/net/lib/ Rename header files to better match their function. Remove net_ prefix from conn_mgr types, API, and files, since it is unnecessary. Signed-off-by: Georges Oates_Larsen (cherry picked from commit 7278bee3f59e56b89b2f662dd01584d52d000790) --- .../zephyr/net/{net_conn_mgr.h => conn_mgr.h} | 10 ++--- include/zephyr/shell/shell_mqtt.h | 2 +- samples/net/gsm_modem/src/main.c | 2 +- samples/net/mqtt_sn_publisher/src/main.c | 4 +- samples/net/mqtt_sn_publisher/src/udp.c | 2 +- .../sockets/dumb_http_server_mt/src/main.c | 4 +- .../net/sockets/echo_client/src/echo-client.c | 4 +- .../net/sockets/echo_server/src/echo-server.c | 6 +-- samples/net/sockets/txtime/src/main.c | 6 +-- samples/subsys/mgmt/updatehub/src/main.c | 4 +- subsys/mgmt/mcumgr/transport/src/smp_udp.c | 4 +- subsys/net/CMakeLists.txt | 1 + subsys/net/Kconfig | 2 + subsys/net/{lib => }/conn_mgr/CMakeLists.txt | 0 subsys/net/{lib => }/conn_mgr/Kconfig | 0 subsys/net/{lib => }/conn_mgr/conn_mgr.c | 37 +++++++++---------- subsys/net/{lib => }/conn_mgr/conn_mgr.ld | 0 .../conn_mgr/conn_mgr_connectivity.c | 0 .../conn_mgr_private.h} | 12 +++--- .../net/{lib => }/conn_mgr/events_handler.c | 2 +- subsys/net/lib/CMakeLists.txt | 1 - subsys/net/lib/Kconfig | 2 - subsys/shell/backends/shell_mqtt.c | 2 +- 23 files changed, 53 insertions(+), 54 deletions(-) rename include/zephyr/net/{net_conn_mgr.h => conn_mgr.h} (56%) rename subsys/net/{lib => }/conn_mgr/CMakeLists.txt (100%) rename subsys/net/{lib => }/conn_mgr/Kconfig (100%) rename subsys/net/{lib => }/conn_mgr/conn_mgr.c (82%) rename subsys/net/{lib => }/conn_mgr/conn_mgr.ld (100%) rename subsys/net/{lib => }/conn_mgr/conn_mgr_connectivity.c (100%) rename subsys/net/{lib/conn_mgr/conn_mgr.h => conn_mgr/conn_mgr_private.h} (87%) rename subsys/net/{lib => }/conn_mgr/events_handler.c (99%) diff --git a/include/zephyr/net/net_conn_mgr.h b/include/zephyr/net/conn_mgr.h similarity index 56% rename from include/zephyr/net/net_conn_mgr.h rename to include/zephyr/net/conn_mgr.h index 1d85a23a5cdf..bd6b4e5d3fc5 100644 --- a/include/zephyr/net/net_conn_mgr.h +++ b/include/zephyr/net/conn_mgr.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_NET_CONN_MGR_H_ -#define ZEPHYR_INCLUDE_NET_CONN_MGR_H_ +#ifndef ZEPHYR_INCLUDE_CONN_MGR_H_ +#define ZEPHYR_INCLUDE_CONN_MGR_H_ #ifdef __cplusplus extern "C" { @@ -13,11 +13,11 @@ extern "C" { #if defined(CONFIG_NET_CONNECTION_MANAGER) -void net_conn_mgr_resend_status(void); +void conn_mgr_resend_status(void); #else -#define net_conn_mgr_resend_status(...) +#define conn_mgr_resend_status(...) #endif /* CONFIG_NET_CONNECTION_MANAGER */ @@ -25,4 +25,4 @@ void net_conn_mgr_resend_status(void); } #endif -#endif /* ZEPHYR_INCLUDE_NET_CONN_MGR_H_ */ +#endif /* ZEPHYR_INCLUDE_CONN_MGR_H_ */ diff --git a/include/zephyr/shell/shell_mqtt.h b/include/zephyr/shell/shell_mqtt.h index f709ffd1ed0e..c1120527f5d0 100644 --- a/include/zephyr/shell/shell_mqtt.h +++ b/include/zephyr/shell/shell_mqtt.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/samples/net/gsm_modem/src/main.c b/samples/net/gsm_modem/src/main.c index 3ee50df53e09..8e9d0a7521a8 100644 --- a/samples/net/gsm_modem/src/main.c +++ b/samples/net/gsm_modem/src/main.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/samples/net/mqtt_sn_publisher/src/main.c b/samples/net/mqtt_sn_publisher/src/main.c index ebeda9f455a2..efacb696dd08 100644 --- a/samples/net/mqtt_sn_publisher/src/main.c +++ b/samples/net/mqtt_sn_publisher/src/main.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -79,7 +79,7 @@ static void init_app(void) net_mgmt_init_event_callback(&mgmt_cb, net_event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); } } diff --git a/samples/net/mqtt_sn_publisher/src/udp.c b/samples/net/mqtt_sn_publisher/src/udp.c index fb96e71ae79f..a47bc6932216 100644 --- a/samples/net/mqtt_sn_publisher/src/udp.c +++ b/samples/net/mqtt_sn_publisher/src/udp.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/samples/net/sockets/dumb_http_server_mt/src/main.c b/samples/net/sockets/dumb_http_server_mt/src/main.c index a4f3d1365f5f..77b7a836f756 100644 --- a/samples/net/sockets/dumb_http_server_mt/src/main.c +++ b/samples/net/sockets/dumb_http_server_mt/src/main.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(net_dumb_http_srv_mt_sample); #include #include -#include +#include #define MY_PORT 8080 @@ -426,7 +426,7 @@ int main(void) event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); } if (!IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) { diff --git a/samples/net/sockets/echo_client/src/echo-client.c b/samples/net/sockets/echo_client/src/echo-client.c index 351131edbf70..c211de8f3c93 100644 --- a/samples/net/sockets/echo_client/src/echo-client.c +++ b/samples/net/sockets/echo_client/src/echo-client.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(net_echo_client_sample, LOG_LEVEL_DBG); #include #include -#include +#include #if defined(CONFIG_USERSPACE) #include @@ -271,7 +271,7 @@ static void init_app(void) event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); } init_vlan(); diff --git a/samples/net/sockets/echo_server/src/echo-server.c b/samples/net/sockets/echo_server/src/echo-server.c index 2b9cd2785148..c5a1ae0e0a6f 100644 --- a/samples/net/sockets/echo_server/src/echo-server.c +++ b/samples/net/sockets/echo_server/src/echo-server.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(net_echo_server_sample, LOG_LEVEL_DBG); #include #include -#include +#include #include "common.h" #include "certificate.h" @@ -196,7 +196,7 @@ static void init_app(void) event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); } init_vlan(); @@ -210,7 +210,7 @@ static int cmd_sample_quit(const struct shell *sh, { want_to_quit = true; - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); quit(); diff --git a/samples/net/sockets/txtime/src/main.c b/samples/net/sockets/txtime/src/main.c index 674fd83e54eb..38ed702797b3 100644 --- a/samples/net/sockets/txtime/src/main.c +++ b/samples/net/sockets/txtime/src/main.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(net_txtime_sample, LOG_LEVEL_DBG); #include #include -#include +#include #include #include @@ -497,7 +497,7 @@ static int cmd_sample_quit(const struct shell *sh, quit(); - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); return 0; } @@ -535,7 +535,7 @@ int main(void) net_mgmt_add_event_callback(&dhcpv4_cb); } - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); } /* The VLAN in this example is created for demonstration purposes. diff --git a/samples/subsys/mgmt/updatehub/src/main.c b/samples/subsys/mgmt/updatehub/src/main.c index efb941d7f536..9e51c7e7b2dc 100644 --- a/samples/subsys/mgmt/updatehub/src/main.c +++ b/samples/subsys/mgmt/updatehub/src/main.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #if defined(CONFIG_UPDATEHUB_DTLS) @@ -150,6 +150,6 @@ int main(void) net_mgmt_init_event_callback(&mgmt_cb, event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); return 0; } diff --git a/subsys/mgmt/mcumgr/transport/src/smp_udp.c b/subsys/mgmt/mcumgr/transport/src/smp_udp.c index aab40d4e2119..ef01ac8515b0 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_udp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_udp.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #endif #define LOG_LEVEL CONFIG_MCUMGR_LOG_LEVEL @@ -316,7 +316,7 @@ static void smp_udp_start(void) net_mgmt_init_event_callback(&smp_udp_mgmt_cb, smp_udp_net_event_handler, (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)); net_mgmt_add_event_callback(&smp_udp_mgmt_cb); - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); } MCUMGR_HANDLER_DEFINE(smp_udp, smp_udp_start); diff --git a/subsys/net/CMakeLists.txt b/subsys/net/CMakeLists.txt index 35fab9994e4f..f9cf4940a438 100644 --- a/subsys/net/CMakeLists.txt +++ b/subsys/net/CMakeLists.txt @@ -20,3 +20,4 @@ if(CONFIG_NETWORKING) endif() add_subdirectory(lib) +add_subdirectory_ifdef(CONFIG_NET_CONNECTION_MANAGER conn_mgr) diff --git a/subsys/net/Kconfig b/subsys/net/Kconfig index a8b8f94c44b2..fad47cfe8816 100644 --- a/subsys/net/Kconfig +++ b/subsys/net/Kconfig @@ -80,6 +80,8 @@ source "subsys/net/pkt_filter/Kconfig" source "subsys/net/lib/Kconfig" +source "subsys/net/conn_mgr/Kconfig" + endif endmenu diff --git a/subsys/net/lib/conn_mgr/CMakeLists.txt b/subsys/net/conn_mgr/CMakeLists.txt similarity index 100% rename from subsys/net/lib/conn_mgr/CMakeLists.txt rename to subsys/net/conn_mgr/CMakeLists.txt diff --git a/subsys/net/lib/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig similarity index 100% rename from subsys/net/lib/conn_mgr/Kconfig rename to subsys/net/conn_mgr/Kconfig diff --git a/subsys/net/lib/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c similarity index 82% rename from subsys/net/lib/conn_mgr/conn_mgr.c rename to subsys/net/conn_mgr/conn_mgr.c index c81033ec30d8..ebae5e1df750 100644 --- a/subsys/net/lib/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -15,7 +15,7 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include -#include +#include "conn_mgr_private.h" #if defined(CONFIG_NET_TC_THREAD_COOPERATIVE) #define THREAD_PRIORITY K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1) @@ -27,43 +27,43 @@ uint16_t iface_states[CONN_MGR_IFACE_MAX]; K_SEM_DEFINE(conn_mgr_lock, 1, K_SEM_MAX_LIMIT); -static enum net_conn_mgr_state conn_mgr_iface_status(int index) +static enum conn_mgr_state conn_mgr_iface_status(int index) { if (iface_states[index] & NET_STATE_IFACE_UP) { - return NET_CONN_MGR_STATE_CONNECTED; + return CONN_MGR_STATE_CONNECTED; } - return NET_CONN_MGR_STATE_DISCONNECTED; + return CONN_MGR_STATE_DISCONNECTED; } #if defined(CONFIG_NET_IPV6) -static enum net_conn_mgr_state conn_mgr_ipv6_status(int index) +static enum conn_mgr_state conn_mgr_ipv6_status(int index) { if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == CONN_MGR_IPV6_STATUS_MASK) { NET_DBG("IPv6 connected on iface index %u", index + 1); - return NET_CONN_MGR_STATE_CONNECTED; + return CONN_MGR_STATE_CONNECTED; } - return NET_CONN_MGR_STATE_DISCONNECTED; + return CONN_MGR_STATE_DISCONNECTED; } #else -#define conn_mgr_ipv6_status(...) NET_CONN_MGR_STATE_CONNECTED +#define conn_mgr_ipv6_status(...) CONN_MGR_STATE_CONNECTED #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) -static enum net_conn_mgr_state conn_mgr_ipv4_status(int index) +static enum conn_mgr_state conn_mgr_ipv4_status(int index) { if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == CONN_MGR_IPV4_STATUS_MASK) { NET_DBG("IPv4 connected on iface index %u", index + 1); - return NET_CONN_MGR_STATE_CONNECTED; + return CONN_MGR_STATE_CONNECTED; } - return NET_CONN_MGR_STATE_DISCONNECTED; + return CONN_MGR_STATE_DISCONNECTED; } #else -#define conn_mgr_ipv4_status(...) NET_CONN_MGR_STATE_CONNECTED +#define conn_mgr_ipv4_status(...) CONN_MGR_STATE_CONNECTED #endif /* CONFIG_NET_IPV4 */ static void conn_mgr_notify_status(int index) @@ -90,7 +90,7 @@ static void conn_mgr_act_on_changes(void) int idx; for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { - enum net_conn_mgr_state state; + enum conn_mgr_state state; if (iface_states[idx] == 0) { /* This interface is not used */ @@ -101,12 +101,11 @@ static void conn_mgr_act_on_changes(void) continue; } - state = NET_CONN_MGR_STATE_CONNECTED; + state = CONN_MGR_STATE_CONNECTED; state &= conn_mgr_iface_status(idx); if (state) { - enum net_conn_mgr_state ip_state = - NET_CONN_MGR_STATE_DISCONNECTED; + enum conn_mgr_state ip_state = CONN_MGR_STATE_DISCONNECTED; if (IS_ENABLED(CONFIG_NET_IPV6)) { ip_state |= conn_mgr_ipv6_status(idx); @@ -121,12 +120,12 @@ static void conn_mgr_act_on_changes(void) iface_states[idx] &= ~NET_STATE_CHANGED; - if (state == NET_CONN_MGR_STATE_CONNECTED && + if (state == CONN_MGR_STATE_CONNECTED && !(iface_states[idx] & NET_STATE_CONNECTED)) { iface_states[idx] |= NET_STATE_CONNECTED; conn_mgr_notify_status(idx); - } else if (state != NET_CONN_MGR_STATE_CONNECTED && + } else if (state != CONN_MGR_STATE_CONNECTED && (iface_states[idx] & NET_STATE_CONNECTED)) { iface_states[idx] &= ~NET_STATE_CONNECTED; @@ -194,7 +193,7 @@ K_THREAD_DEFINE(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE, (k_thread_entry_t)conn_mgr_handler, NULL, NULL, NULL, THREAD_PRIORITY, 0, 0); -void net_conn_mgr_resend_status(void) +void conn_mgr_resend_status(void) { int idx; diff --git a/subsys/net/lib/conn_mgr/conn_mgr.ld b/subsys/net/conn_mgr/conn_mgr.ld similarity index 100% rename from subsys/net/lib/conn_mgr/conn_mgr.ld rename to subsys/net/conn_mgr/conn_mgr.ld diff --git a/subsys/net/lib/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c similarity index 100% rename from subsys/net/lib/conn_mgr/conn_mgr_connectivity.c rename to subsys/net/conn_mgr/conn_mgr_connectivity.c diff --git a/subsys/net/lib/conn_mgr/conn_mgr.h b/subsys/net/conn_mgr/conn_mgr_private.h similarity index 87% rename from subsys/net/lib/conn_mgr/conn_mgr.h rename to subsys/net/conn_mgr/conn_mgr_private.h index 0f1c8ecd24b5..821780aeda4b 100644 --- a/subsys/net/lib/conn_mgr/conn_mgr.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __CONN_MGR_H__ -#define __CONN_MGR_H__ +#ifndef __CONN_MGR_PRV_H__ +#define __CONN_MGR_PRV_H__ #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV4) #define CONN_MGR_IFACE_MAX MAX(CONFIG_NET_IF_MAX_IPV6_COUNT, \ @@ -42,11 +42,11 @@ extern struct k_sem conn_mgr_lock; -enum net_conn_mgr_state { - NET_CONN_MGR_STATE_DISCONNECTED = 0, - NET_CONN_MGR_STATE_CONNECTED = 1, +enum conn_mgr_state { + CONN_MGR_STATE_DISCONNECTED = 0, + CONN_MGR_STATE_CONNECTED = 1, }; void conn_mgr_init_events_handler(void); -#endif /* __CONN_MGR_H__ */ +#endif /* __CONN_MGR_PRV_H__ */ diff --git a/subsys/net/lib/conn_mgr/events_handler.c b/subsys/net/conn_mgr/events_handler.c similarity index 99% rename from subsys/net/lib/conn_mgr/events_handler.c rename to subsys/net/conn_mgr/events_handler.c index 551420df49f2..fa227048e238 100644 --- a/subsys/net/lib/conn_mgr/events_handler.c +++ b/subsys/net/conn_mgr/events_handler.c @@ -11,7 +11,7 @@ LOG_MODULE_DECLARE(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include -#include +#include "conn_mgr_private.h" extern uint16_t iface_states[CONN_MGR_IFACE_MAX]; diff --git a/subsys/net/lib/CMakeLists.txt b/subsys/net/lib/CMakeLists.txt index 9161026d910a..6c045b586928 100644 --- a/subsys/net/lib/CMakeLists.txt +++ b/subsys/net/lib/CMakeLists.txt @@ -11,7 +11,6 @@ add_subdirectory_ifdef(CONFIG_TFTP_LIB tftp) add_subdirectory_ifdef(CONFIG_NET_CONFIG_SETTINGS config) add_subdirectory_ifdef(CONFIG_NET_SOCKETS sockets) add_subdirectory_ifdef(CONFIG_TLS_CREDENTIALS tls_credentials) -add_subdirectory_ifdef(CONFIG_NET_CONNECTION_MANAGER conn_mgr) add_subdirectory_ifdef(CONFIG_NET_CAPTURE capture) add_subdirectory_ifdef(CONFIG_NET_ZPERF zperf) diff --git a/subsys/net/lib/Kconfig b/subsys/net/lib/Kconfig index ca59d89a66b6..5df4a445885a 100644 --- a/subsys/net/lib/Kconfig +++ b/subsys/net/lib/Kconfig @@ -37,8 +37,6 @@ endmenu menu "Network additional services" -source "subsys/net/lib/conn_mgr/Kconfig" - source "subsys/net/lib/capture/Kconfig" source "subsys/net/lib/zperf/Kconfig" diff --git a/subsys/shell/backends/shell_mqtt.c b/subsys/shell/backends/shell_mqtt.c index 8b535a960153..58654dcf4000 100644 --- a/subsys/shell/backends/shell_mqtt.c +++ b/subsys/shell/backends/shell_mqtt.c @@ -716,7 +716,7 @@ static int enable(const struct shell_transport *transport, bool blocking) /* Listen for network connection status */ net_mgmt_add_event_callback(&sh_mqtt->mgmt_cb); - net_conn_mgr_resend_status(); + conn_mgr_resend_status(); return 0; } From af4070afb9dc09ebcf0881d6055d8e421bb02c0c Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Fri, 14 Apr 2023 16:20:43 -0700 Subject: [PATCH 069/528] [nrf fromlist] net: conn_mgr: relocate if_get_binding Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 Relocate conn_mgr_if_get_binding to conn_mgr_private.h so that it can be used by test suites. Signed-off-by: Georges Oates_Larsen (cherry picked from commit affa23f4b0bd9fa01bd6cc3f0a3667516abedb69) --- subsys/net/conn_mgr/conn_mgr_connectivity.c | 23 +--------------- subsys/net/conn_mgr/conn_mgr_private.h | 24 +++++++++++++++++ tests/net/conn_mgr_conn/src/main.c | 29 +++++++++------------ 3 files changed, 37 insertions(+), 39 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index c0812dac1727..ac33ce68bce7 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -9,28 +9,7 @@ LOG_MODULE_REGISTER(conn_mgr_conn, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include - -/** - * @brief Retrieves the conn_mgr binding struct for a provided iface if it exists. - * - * Bindings for connectivity implementations with missing API structs are ignored. - * - * @param iface - bound network interface to obtain the binding struct for. - * @return struct conn_mgr_conn_binding* Pointer to the retrieved binding struct if it exists, - * NULL otherwise. - */ -static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) -{ - STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { - if (iface == binding->iface) { - if (binding->impl->api) { - return binding; - } - return NULL; - } - } - return NULL; -} +#include "conn_mgr_private.h" int conn_mgr_if_connect(struct net_if *iface) { diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 821780aeda4b..d92318e629d7 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -7,6 +7,8 @@ #ifndef __CONN_MGR_PRV_H__ #define __CONN_MGR_PRV_H__ +#include + #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV4) #define CONN_MGR_IFACE_MAX MAX(CONFIG_NET_IF_MAX_IPV6_COUNT, \ CONFIG_NET_IF_MAX_IPV4_COUNT) @@ -49,4 +51,26 @@ enum conn_mgr_state { void conn_mgr_init_events_handler(void); +/** + * @brief Retrieves the conn_mgr binding struct for a provided iface if it exists. + * + * Bindings for connectivity implementations with missing API structs are ignored. + * + * @param iface - bound network interface to obtain the binding struct for. + * @return struct conn_mgr_conn_binding* Pointer to the retrieved binding struct if it exists, + * NULL otherwise. + */ +static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) +{ + STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { + if (iface == binding->iface) { + if (binding->impl->api) { + return binding; + } + return NULL; + } + } + return NULL; +} + #endif /* __CONN_MGR_PRV_H__ */ diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index 3906d9729e66..9111aa89b510 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -15,26 +15,10 @@ #include #include #include +#include "conn_mgr_private.h" #include "test_conn_impl.h" #include "test_ifaces.h" - -/* This is a duplicate of conn_mgr_if_get_binding in net_if.c, - * which is currently not exposed. - */ -static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) -{ - STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { - if (iface == binding->iface) { - if (binding->impl->api) { - return binding; - } - return NULL; - } - } - return NULL; -} - static inline struct test_conn_data *conn_mgr_if_get_data(struct net_if *iface) { struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); @@ -408,6 +392,17 @@ ZTEST(conn_mgr_conn, test_connect_disconnect_double_instant) zassert_equal(ifa1_data->call_cnt_a, 4, "ifa1->disconnect should have been called once."); } +/** + * Verify that invalid bound ifaces are treated as though they are not bound at all. + */ +ZTEST(conn_mgr_conn, test_invalid_ignored) +{ + zassert_is_null(conn_mgr_if_get_binding(ifnull)); + zassert_is_null(conn_mgr_if_get_binding(ifnone)); + zassert_false(conn_mgr_if_is_bound(ifnull)); + zassert_false(conn_mgr_if_is_bound(ifnone)); +} + /* Verify that connecting an iface that isn't up, missing an API, * or isn't connectivity-bound raises an error. */ From 56a84417b6607ad93dbfaa179524e096611a4ee0 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Mon, 3 Apr 2023 14:02:49 -0700 Subject: [PATCH 070/528] [nrf fromlist] net: conn_mgr: Rename flags Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 Rename internal flags for clarity Signed-off-by: Georges Oates_Larsen (cherry picked from commit b265c2b4212ef76dbc14625b66d22dc44f1fa74a) --- subsys/net/conn_mgr/conn_mgr.c | 27 ++++++++++---------- subsys/net/conn_mgr/conn_mgr_private.h | 34 +++++++++++++++----------- subsys/net/conn_mgr/events_handler.c | 22 ++++++++--------- 3 files changed, 44 insertions(+), 39 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index ebae5e1df750..e8f336ac28a7 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -29,7 +29,7 @@ K_SEM_DEFINE(conn_mgr_lock, 1, K_SEM_MAX_LIMIT); static enum conn_mgr_state conn_mgr_iface_status(int index) { - if (iface_states[index] & NET_STATE_IFACE_UP) { + if (iface_states[index] & CONN_MGR_IF_UP) { return CONN_MGR_STATE_CONNECTED; } @@ -74,7 +74,7 @@ static void conn_mgr_notify_status(int index) return; } - if (iface_states[index] & NET_STATE_CONNECTED) { + if (iface_states[index] & CONN_MGR_IF_READY) { NET_DBG("Iface %d (%p) connected", net_if_get_by_iface(iface), iface); net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, iface); @@ -97,7 +97,7 @@ static void conn_mgr_act_on_changes(void) continue; } - if (!(iface_states[idx] & NET_STATE_CHANGED)) { + if (!(iface_states[idx] & CONN_MGR_IF_CHANGED)) { continue; } @@ -118,16 +118,16 @@ static void conn_mgr_act_on_changes(void) state &= ip_state; } - iface_states[idx] &= ~NET_STATE_CHANGED; + iface_states[idx] &= ~CONN_MGR_IF_CHANGED; if (state == CONN_MGR_STATE_CONNECTED && - !(iface_states[idx] & NET_STATE_CONNECTED)) { - iface_states[idx] |= NET_STATE_CONNECTED; + !(iface_states[idx] & CONN_MGR_IF_READY)) { + iface_states[idx] |= CONN_MGR_IF_READY; conn_mgr_notify_status(idx); } else if (state != CONN_MGR_STATE_CONNECTED && - (iface_states[idx] & NET_STATE_CONNECTED)) { - iface_states[idx] &= ~NET_STATE_CONNECTED; + (iface_states[idx] & CONN_MGR_IF_READY)) { + iface_states[idx] &= ~CONN_MGR_IF_READY; conn_mgr_notify_status(idx); } @@ -140,29 +140,28 @@ static void conn_mgr_initial_state(struct net_if *iface) if (net_if_is_up(iface)) { NET_DBG("Iface %p UP", iface); - iface_states[idx] = NET_STATE_IFACE_UP; + iface_states[idx] = CONN_MGR_IF_UP; } if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6)) { if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { NET_DBG("IPv6 addr set"); - iface_states[idx] |= NET_STATE_IPV6_ADDR_SET | - NET_STATE_IPV6_DAD_OK; + iface_states[idx] |= CONN_MGR_IF_IPV6_SET | CONN_MGR_IF_IPV6_DAD_OK; } else if (net_if_ipv6_get_global_addr(NET_ADDR_TENTATIVE, &iface)) { - iface_states[idx] |= NET_STATE_IPV6_ADDR_SET; + iface_states[idx] |= CONN_MGR_IF_IPV6_SET; } } if (IS_ENABLED(CONFIG_NET_NATIVE_IPV4)) { if (net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) { NET_DBG("IPv4 addr set"); - iface_states[idx] |= NET_STATE_IPV4_ADDR_SET; + iface_states[idx] |= CONN_MGR_IF_IPV4_SET; } } - iface_states[idx] |= NET_STATE_CHANGED; + iface_states[idx] |= CONN_MGR_IF_CHANGED; } static void conn_mgr_init_cb(struct net_if *iface, void *user_data) diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index d92318e629d7..ecdf4523f545 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -18,29 +18,35 @@ #define CONN_MGR_IFACE_MAX CONFIG_NET_IF_MAX_IPV4_COUNT #endif -#define NET_STATE_IFACE_UP BIT(0) -#define NET_STATE_IPV6_ADDR_SET BIT(1) -#define NET_STATE_IPV6_DAD_OK BIT(2) -#define NET_STATE_IPV4_ADDR_SET BIT(3) +/* External state flags */ +#define CONN_MGR_IF_UP BIT(0) +#define CONN_MGR_IF_IPV6_SET BIT(1) +#define CONN_MGR_IF_IPV6_DAD_OK BIT(2) +#define CONN_MGR_IF_IPV4_SET BIT(3) -#define NET_STATE_CONNECTED BIT(14) -#define NET_STATE_CHANGED BIT(15) +/* Internal state flags */ +#define CONN_MGR_IF_READY BIT(14) -#define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ +/* Event flags */ +#define CONN_MGR_IF_CHANGED BIT(15) + +/* NET_MGMT event masks */ +#define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ NET_EVENT_IF_UP) -#define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ - NET_EVENT_IPV6_ADDR_DEL | \ - NET_EVENT_IPV6_DAD_SUCCEED | \ +#define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ + NET_EVENT_IPV6_ADDR_DEL | \ + NET_EVENT_IPV6_DAD_SUCCEED | \ NET_EVENT_IPV6_DAD_FAILED) -#define CONN_MGR_IPV4_EVENTS_MASK (NET_EVENT_IPV4_ADDR_ADD | \ +#define CONN_MGR_IPV4_EVENTS_MASK (NET_EVENT_IPV4_ADDR_ADD | \ NET_EVENT_IPV4_ADDR_DEL) -#define CONN_MGR_IPV6_STATUS_MASK (NET_STATE_IPV6_ADDR_SET | \ - NET_STATE_IPV6_DAD_OK) +/* Internal event masks */ +#define CONN_MGR_IPV6_STATUS_MASK (CONN_MGR_IF_IPV6_SET | \ + CONN_MGR_IF_IPV6_DAD_OK) -#define CONN_MGR_IPV4_STATUS_MASK (NET_STATE_IPV4_ADDR_SET) +#define CONN_MGR_IPV4_STATUS_MASK (CONN_MGR_IF_IPV4_SET) extern struct k_sem conn_mgr_lock; diff --git a/subsys/net/conn_mgr/events_handler.c b/subsys/net/conn_mgr/events_handler.c index fa227048e238..b5b4dfab9689 100644 --- a/subsys/net/conn_mgr/events_handler.c +++ b/subsys/net/conn_mgr/events_handler.c @@ -38,16 +38,16 @@ static void conn_mgr_iface_events_handler(struct net_mgmt_event_callback *cb, switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IF_CMD_DOWN: - iface_states[idx] &= ~NET_STATE_IFACE_UP; + iface_states[idx] &= ~CONN_MGR_IF_UP; break; case NET_EVENT_IF_CMD_UP: - iface_states[idx] |= NET_STATE_IFACE_UP; + iface_states[idx] |= CONN_MGR_IF_UP; break; default: return; } - iface_states[idx] |= NET_STATE_CHANGED; + iface_states[idx] |= CONN_MGR_IF_CHANGED; k_sem_give(&conn_mgr_lock); } @@ -71,30 +71,30 @@ static void conn_mgr_ipv6_events_handler(struct net_mgmt_event_callback *cb, switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IPV6_CMD_ADDR_ADD: - iface_states[idx] |= NET_STATE_IPV6_ADDR_SET; + iface_states[idx] |= CONN_MGR_IF_IPV6_SET; break; case NET_EVENT_IPV6_CMD_ADDR_DEL: if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { break; } - iface_states[idx] &= ~NET_STATE_IPV6_ADDR_SET; + iface_states[idx] &= ~CONN_MGR_IF_IPV6_SET; break; case NET_EVENT_IPV6_CMD_DAD_SUCCEED: - iface_states[idx] |= NET_STATE_IPV6_DAD_OK; + iface_states[idx] |= CONN_MGR_IF_IPV6_DAD_OK; break; case NET_EVENT_IPV6_CMD_DAD_FAILED: if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { break; } - iface_states[idx] &= ~NET_STATE_IPV6_DAD_OK; + iface_states[idx] &= ~CONN_MGR_IF_IPV6_DAD_OK; break; default: return; } - iface_states[idx] |= NET_STATE_CHANGED; + iface_states[idx] |= CONN_MGR_IF_CHANGED; k_sem_give(&conn_mgr_lock); } #else @@ -129,20 +129,20 @@ static void conn_mgr_ipv4_events_handler(struct net_mgmt_event_callback *cb, switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IPV4_CMD_ADDR_ADD: - iface_states[idx] |= NET_STATE_IPV4_ADDR_SET; + iface_states[idx] |= CONN_MGR_IF_IPV4_SET; break; case NET_EVENT_IPV4_CMD_ADDR_DEL: if (net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) { break; } - iface_states[idx] &= ~NET_STATE_IPV4_ADDR_SET; + iface_states[idx] &= ~CONN_MGR_IF_IPV4_SET; break; default: return; } - iface_states[idx] |= NET_STATE_CHANGED; + iface_states[idx] |= CONN_MGR_IF_CHANGED; k_sem_give(&conn_mgr_lock); } #else From 606e61fc2ef24bb758ec0c50dd0d249fea8f0f84 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Mon, 13 Feb 2023 13:02:04 -0800 Subject: [PATCH 071/528] [nrf fromlist] net: conn_mgr: Add thread-safety Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 Current implementation does not prevent the net_mgmt thread from preempting during state change handling and generating more state changes. Add a mutex to protect internal state of conn_mgr Signed-off-by: Georges Oates_Larsen (cherry picked from commit 095fbfadd73f6e8eb4be5b5eb594ae8dccb2d615) --- subsys/net/conn_mgr/conn_mgr.c | 26 +++++++++++++++++++++++-- subsys/net/conn_mgr/conn_mgr_private.h | 3 ++- subsys/net/conn_mgr/events_handler.c | 27 ++++++++++++++++++++------ 3 files changed, 47 insertions(+), 9 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index e8f336ac28a7..4a800dfe5204 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -25,7 +25,11 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); uint16_t iface_states[CONN_MGR_IFACE_MAX]; -K_SEM_DEFINE(conn_mgr_lock, 1, K_SEM_MAX_LIMIT); +/* Used to signal when modifications have been made that need to be responded to */ +K_SEM_DEFINE(conn_mgr_event_signal, 1, 1); + +/* Used to protect conn_mgr state */ +K_MUTEX_DEFINE(conn_mgr_lock); static enum conn_mgr_state conn_mgr_iface_status(int index) { @@ -89,6 +93,8 @@ static void conn_mgr_act_on_changes(void) { int idx; + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { enum conn_mgr_state state; @@ -132,12 +138,16 @@ static void conn_mgr_act_on_changes(void) conn_mgr_notify_status(idx); } } + + k_mutex_unlock(&conn_mgr_lock); } static void conn_mgr_initial_state(struct net_if *iface) { int idx = net_if_get_by_iface(iface) - 1; + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + if (net_if_is_up(iface)) { NET_DBG("Iface %p UP", iface); iface_states[idx] = CONN_MGR_IF_UP; @@ -162,6 +172,8 @@ static void conn_mgr_initial_state(struct net_if *iface) } iface_states[idx] |= CONN_MGR_IF_CHANGED; + + k_mutex_unlock(&conn_mgr_lock); } static void conn_mgr_init_cb(struct net_if *iface, void *user_data) @@ -173,17 +185,23 @@ static void conn_mgr_init_cb(struct net_if *iface, void *user_data) static void conn_mgr_handler(void) { + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + conn_mgr_conn_init(); conn_mgr_init_events_handler(); net_if_foreach(conn_mgr_init_cb, NULL); + k_mutex_unlock(&conn_mgr_lock); + NET_DBG("Connection Manager started"); while (true) { - k_sem_take(&conn_mgr_lock, K_FOREVER); + /* Wait for changes */ + k_sem_take(&conn_mgr_event_signal, K_FOREVER); + /* Respond to changes */ conn_mgr_act_on_changes(); } } @@ -196,9 +214,13 @@ void conn_mgr_resend_status(void) { int idx; + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { conn_mgr_notify_status(idx); } + + k_mutex_unlock(&conn_mgr_lock); } static int conn_mgr_init(void) diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index ecdf4523f545..04c5898c9ef0 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -48,7 +48,8 @@ #define CONN_MGR_IPV4_STATUS_MASK (CONN_MGR_IF_IPV4_SET) -extern struct k_sem conn_mgr_lock; +extern struct k_sem conn_mgr_event_signal; +extern struct k_mutex conn_mgr_lock; enum conn_mgr_state { CONN_MGR_STATE_DISCONNECTED = 0, diff --git a/subsys/net/conn_mgr/events_handler.c b/subsys/net/conn_mgr/events_handler.c index b5b4dfab9689..81a4ea6f7e40 100644 --- a/subsys/net/conn_mgr/events_handler.c +++ b/subsys/net/conn_mgr/events_handler.c @@ -36,6 +36,8 @@ static void conn_mgr_iface_events_handler(struct net_mgmt_event_callback *cb, NET_DBG("Iface index %u", idx); + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IF_CMD_DOWN: iface_states[idx] &= ~CONN_MGR_IF_UP; @@ -44,11 +46,14 @@ static void conn_mgr_iface_events_handler(struct net_mgmt_event_callback *cb, iface_states[idx] |= CONN_MGR_IF_UP; break; default: - return; + goto done; } iface_states[idx] |= CONN_MGR_IF_CHANGED; - k_sem_give(&conn_mgr_lock); + k_sem_give(&conn_mgr_event_signal); + +done: + k_mutex_unlock(&conn_mgr_lock); } #if defined(CONFIG_NET_IPV6) @@ -69,6 +74,8 @@ static void conn_mgr_ipv6_events_handler(struct net_mgmt_event_callback *cb, NET_DBG("Iface index %u", idx); + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IPV6_CMD_ADDR_ADD: iface_states[idx] |= CONN_MGR_IF_IPV6_SET; @@ -91,11 +98,14 @@ static void conn_mgr_ipv6_events_handler(struct net_mgmt_event_callback *cb, iface_states[idx] &= ~CONN_MGR_IF_IPV6_DAD_OK; break; default: - return; + goto done; } iface_states[idx] |= CONN_MGR_IF_CHANGED; - k_sem_give(&conn_mgr_lock); + k_sem_give(&conn_mgr_event_signal); + +done: + k_mutex_unlock(&conn_mgr_lock); } #else static inline @@ -127,6 +137,8 @@ static void conn_mgr_ipv4_events_handler(struct net_mgmt_event_callback *cb, NET_DBG("Iface index %u", idx); + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IPV4_CMD_ADDR_ADD: iface_states[idx] |= CONN_MGR_IF_IPV4_SET; @@ -139,11 +151,14 @@ static void conn_mgr_ipv4_events_handler(struct net_mgmt_event_callback *cb, iface_states[idx] &= ~CONN_MGR_IF_IPV4_SET; break; default: - return; + goto done; } iface_states[idx] |= CONN_MGR_IF_CHANGED; - k_sem_give(&conn_mgr_lock); + k_sem_give(&conn_mgr_event_signal); + +done: + k_mutex_unlock(&conn_mgr_lock); } #else static inline From 160fd21baacd4a0b17a829f9b86ce890f99b14b7 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Fri, 31 Mar 2023 16:01:48 -0700 Subject: [PATCH 072/528] [nrf fromlist] net: conn_mgr: refactor event logic Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 In preparation for altering the conditions under which conn_mgr fires NET_EVENT_L4_CONNECTED and NET_EVENT_L4_DISCONNECTED, refactor the event logic without changing its behavior. These changes do not alter the behavior of conn_mgr. They merely change how that behavior is expressed so that it is easier to understand, and so that upcoming changes are easier to implement. Signed-off-by: Georges Oates_Larsen (cherry picked from commit f17249f4c1e967125f5b4b4503c835ea49eb5c90) --- subsys/net/conn_mgr/conn_mgr.c | 127 +++++++++++++------------ subsys/net/conn_mgr/conn_mgr_private.h | 5 - 2 files changed, 68 insertions(+), 64 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index 4a800dfe5204..5dd28eb28f20 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -31,72 +31,89 @@ K_SEM_DEFINE(conn_mgr_event_signal, 1, 1); /* Used to protect conn_mgr state */ K_MUTEX_DEFINE(conn_mgr_lock); -static enum conn_mgr_state conn_mgr_iface_status(int index) -{ - if (iface_states[index] & CONN_MGR_IF_UP) { - return CONN_MGR_STATE_CONNECTED; - } - - return CONN_MGR_STATE_DISCONNECTED; -} - #if defined(CONFIG_NET_IPV6) -static enum conn_mgr_state conn_mgr_ipv6_status(int index) +static bool conn_mgr_is_if_ipv6_ready(int index) { - if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == - CONN_MGR_IPV6_STATUS_MASK) { + if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == CONN_MGR_IPV6_STATUS_MASK) { NET_DBG("IPv6 connected on iface index %u", index + 1); - return CONN_MGR_STATE_CONNECTED; + return true; } - return CONN_MGR_STATE_DISCONNECTED; + return false; } #else -#define conn_mgr_ipv6_status(...) CONN_MGR_STATE_CONNECTED +#define conn_mgr_is_if_ipv6_ready(...) false #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) -static enum conn_mgr_state conn_mgr_ipv4_status(int index) +static bool conn_mgr_is_if_ipv4_ready(int index) { - if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == - CONN_MGR_IPV4_STATUS_MASK) { + if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == CONN_MGR_IPV4_STATUS_MASK) { NET_DBG("IPv4 connected on iface index %u", index + 1); - return CONN_MGR_STATE_CONNECTED; + return true; } - return CONN_MGR_STATE_DISCONNECTED; + return false; } #else -#define conn_mgr_ipv4_status(...) CONN_MGR_STATE_CONNECTED +#define conn_mgr_is_if_ipv4_ready(...) false #endif /* CONFIG_NET_IPV4 */ -static void conn_mgr_notify_status(int index) +/** + * @brief Retrieves pointer to an iface by the index that corresponds to it in iface_states + * + * @param index - The index in iface_states to find the corresponding iface for. + * @return net_if* - The corresponding iface. + */ +static struct net_if *conn_mgr_get_if_by_index(int index) { - struct net_if *iface = net_if_get_by_index(index + 1); + return net_if_get_by_index(index + 1); +} + +/** + * @brief Notifies listeners of the current readiness state of the iface at the given index + * + * @param index - Index of the iface (in iface_states) + */ +static void conn_mgr_notify_if_readiness(int index) +{ + struct net_if *iface = conn_mgr_get_if_by_index(index); + bool readiness = iface_states[index] & CONN_MGR_IF_READY; if (iface == NULL) { return; } - if (iface_states[index] & CONN_MGR_IF_READY) { - NET_DBG("Iface %d (%p) connected", - net_if_get_by_iface(iface), iface); - net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, iface); - } else { - NET_DBG("Iface %d (%p) disconnected", - net_if_get_by_iface(iface), iface); - net_mgmt_event_notify(NET_EVENT_L4_DISCONNECTED, iface); + NET_DBG("Iface %d (%p) %s", net_if_get_by_iface(iface), + iface, readiness ? "ready" : "unready"); + + net_mgmt_event_notify( + readiness ? NET_EVENT_L4_CONNECTED : NET_EVENT_L4_DISCONNECTED, + iface + ); + +} + +static void conn_mgr_set_ready(int idx, bool readiness) +{ + /* Clear and then update the L4-readiness bit */ + iface_states[idx] &= ~CONN_MGR_IF_READY; + if (readiness) { + iface_states[idx] |= CONN_MGR_IF_READY; } } static void conn_mgr_act_on_changes(void) { int idx; + bool is_ip_ready; + bool is_l4_ready; + bool is_oper_up; + bool was_l4_ready; k_mutex_lock(&conn_mgr_lock, K_FOREVER); for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { - enum conn_mgr_state state; if (iface_states[idx] == 0) { /* This interface is not used */ @@ -104,44 +121,36 @@ static void conn_mgr_act_on_changes(void) } if (!(iface_states[idx] & CONN_MGR_IF_CHANGED)) { + /* No changes on this iface */ continue; } - state = CONN_MGR_STATE_CONNECTED; - - state &= conn_mgr_iface_status(idx); - if (state) { - enum conn_mgr_state ip_state = CONN_MGR_STATE_DISCONNECTED; - - if (IS_ENABLED(CONFIG_NET_IPV6)) { - ip_state |= conn_mgr_ipv6_status(idx); - } - - if (IS_ENABLED(CONFIG_NET_IPV4)) { - ip_state |= conn_mgr_ipv4_status(idx); - } - - state &= ip_state; - } - + /* Clear the state-change flag */ iface_states[idx] &= ~CONN_MGR_IF_CHANGED; - if (state == CONN_MGR_STATE_CONNECTED && - !(iface_states[idx] & CONN_MGR_IF_READY)) { - iface_states[idx] |= CONN_MGR_IF_READY; + /* Detect whether the iface is currently or was L4 ready */ + is_ip_ready = conn_mgr_is_if_ipv6_ready(idx) || conn_mgr_is_if_ipv4_ready(idx); + is_oper_up = iface_states[idx] & CONN_MGR_IF_UP; + was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY; + is_l4_ready = is_oper_up && is_ip_ready; - conn_mgr_notify_status(idx); - } else if (state != CONN_MGR_STATE_CONNECTED && - (iface_states[idx] & CONN_MGR_IF_READY)) { - iface_states[idx] &= ~CONN_MGR_IF_READY; + /* Respond to changes to iface readiness */ + if (was_l4_ready != is_l4_ready) { + /* Track the iface readiness change */ + conn_mgr_set_ready(idx, is_l4_ready); - conn_mgr_notify_status(idx); + /* Notify listeners of the readiness change */ + conn_mgr_notify_if_readiness(idx); } } - k_mutex_unlock(&conn_mgr_lock); } +/** + * @brief Initialize the internal state flags for the given iface using its current status + * + * @param iface - iface to initialize from. + */ static void conn_mgr_initial_state(struct net_if *iface) { int idx = net_if_get_by_iface(iface) - 1; @@ -217,7 +226,7 @@ void conn_mgr_resend_status(void) k_mutex_lock(&conn_mgr_lock, K_FOREVER); for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { - conn_mgr_notify_status(idx); + conn_mgr_notify_if_readiness(idx); } k_mutex_unlock(&conn_mgr_lock); diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 04c5898c9ef0..097b501d682f 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -51,11 +51,6 @@ extern struct k_sem conn_mgr_event_signal; extern struct k_mutex conn_mgr_lock; -enum conn_mgr_state { - CONN_MGR_STATE_DISCONNECTED = 0, - CONN_MGR_STATE_CONNECTED = 1, -}; - void conn_mgr_init_events_handler(void); /** From 734675e0e6d1c92aeef38a53653a81a4cfe105b1 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 4 Apr 2023 11:03:13 -0700 Subject: [PATCH 073/528] [nrf fromlist] net: conn_mgr: Ignore ifaces and L2s Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 Adds a flag to allow ifaces and L2s to be ignored. This is so that applictions have better control over what ifaces they want connectivity management for. Enabling the flag forces conn_mgr to consider the iface unready. Also increase NET_CONNECTION_MANAGER_PRIORITY default value from 0 to 1 so that applications can register SYS_INIT callbacks that fire just before conn_mgr initializes. This allows ignored ifaces to be configured before conn_mgr starts, if needed. Signed-off-by: Georges Oates_Larsen (cherry picked from commit 6759d9f65f5539bbf803e38cb6a59559138adf91) --- include/zephyr/net/conn_mgr.h | 64 ++++++++++++++ subsys/net/conn_mgr/Kconfig | 3 +- subsys/net/conn_mgr/conn_mgr.c | 111 ++++++++++++++++++++++++- subsys/net/conn_mgr/conn_mgr_private.h | 5 +- 4 files changed, 178 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/conn_mgr.h b/include/zephyr/net/conn_mgr.h index bd6b4e5d3fc5..55a57135a593 100644 --- a/include/zephyr/net/conn_mgr.h +++ b/include/zephyr/net/conn_mgr.h @@ -13,11 +13,75 @@ extern "C" { #if defined(CONFIG_NET_CONNECTION_MANAGER) +struct net_if; +struct net_l2; + +/** + * @brief Resend either NET_L4_CONNECTED or NET_L4_DISCONNECTED depending on whether connectivity + * is currently available. + */ void conn_mgr_resend_status(void); +/** + * @brief Mark an iface to be ignored by conn_mgr. + * + * Ignoring an iface forces conn_mgr to consider it unready/disconnected. + * + * This means that events related to the iface connecting/disconnecting will not be fired, + * and if the iface was connected before being ignored, events will be fired as though it + * disconnected at that moment. + * + * @param iface - iface to be ignored. + */ +void conn_mgr_ignore_iface(struct net_if *iface); + +/** + * @brief Stop ignoring an iface. + * + * conn_mgr will no longer be forced to consider the iface unreadly/disconnected. + * + * Events related to the iface connecting/disconnecting will no longer be blocked, + * and if the iface was connected before being unignored, events will be fired as though + * it connected in that moment. + * + * @param iface - iface to no longer ignore. + */ +void conn_mgr_unignore_iface(struct net_if *iface); + +/** + * @brief Check whether the provided iface is currently ignored. + * + * @param iface - The iface to check. + * @retval true if the iface is being ignored by conn_mgr. + * @retval false otherwise. + */ +bool conn_mgr_is_iface_ignored(struct net_if *iface); + +/** + * @brief Mark an L2 to be ignored by conn_mgr. + * + * This is a wrapper for conn_mgr_ignore_iface that ignores all ifaces that use the L2. + * + * @param l2 - L2 to be ignored. + */ +void conn_mgr_ignore_l2(const struct net_l2 *l2); + +/** + * @brief Stop ignoring an L2. + * + * This is a wrapper for conn_mgr_ignore_iface that unignores all ifaces that use the L2. + * + * @param l2 - L2 to no longer ignore. + */ +void conn_mgr_unignore_l2(const struct net_l2 *l2); + #else #define conn_mgr_resend_status(...) +#define conn_mgr_ignore_iface(...) +#define conn_mgr_unignore_iface(...) +#define conn_mgr_ignore_l2(...) +#define conn_mgr_unignore_l2(...) #endif /* CONFIG_NET_CONNECTION_MANAGER */ diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig index 93efffd7e6b1..5c742fb852f5 100644 --- a/subsys/net/conn_mgr/Kconfig +++ b/subsys/net/conn_mgr/Kconfig @@ -31,7 +31,8 @@ config NET_CONNECTION_MANAGER_STACK_SIZE config NET_CONNECTION_MANAGER_PRIORITY int "Thread starting priority" - default 0 + default 1 + range 1 99 help This sets the starting priority of the connection manager thread. diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index 5dd28eb28f20..628bd2ba4d65 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -70,6 +70,17 @@ static struct net_if *conn_mgr_get_if_by_index(int index) return net_if_get_by_index(index + 1); } +/** + * @brief Gets the index in iface_states for the state corresponding to a provided iface. + * + * @param iface - iface to find the index of. + * @return int - The index found. + */ +static int conn_mgr_get_index_for_if(struct net_if *iface) +{ + return net_if_get_by_iface(iface) - 1; +} + /** * @brief Notifies listeners of the current readiness state of the iface at the given index * @@ -110,11 +121,11 @@ static void conn_mgr_act_on_changes(void) bool is_l4_ready; bool is_oper_up; bool was_l4_ready; + bool is_ignored; k_mutex_lock(&conn_mgr_lock, K_FOREVER); for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { - if (iface_states[idx] == 0) { /* This interface is not used */ continue; @@ -132,7 +143,8 @@ static void conn_mgr_act_on_changes(void) is_ip_ready = conn_mgr_is_if_ipv6_ready(idx) || conn_mgr_is_if_ipv4_ready(idx); is_oper_up = iface_states[idx] & CONN_MGR_IF_UP; was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY; - is_l4_ready = is_oper_up && is_ip_ready; + is_ignored = iface_states[idx] & CONN_MGR_IF_IGNORED; + is_l4_ready = is_oper_up && is_ip_ready && !is_ignored; /* Respond to changes to iface readiness */ if (was_l4_ready != is_l4_ready) { @@ -159,7 +171,7 @@ static void conn_mgr_initial_state(struct net_if *iface) if (net_if_is_up(iface)) { NET_DBG("Iface %p UP", iface); - iface_states[idx] = CONN_MGR_IF_UP; + iface_states[idx] |= CONN_MGR_IF_UP; } if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6)) { @@ -232,6 +244,99 @@ void conn_mgr_resend_status(void) k_mutex_unlock(&conn_mgr_lock); } +void conn_mgr_ignore_iface(struct net_if *iface) +{ + int idx = conn_mgr_get_index_for_if(iface); + + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + + if (!(iface_states[idx] & CONN_MGR_IF_IGNORED)) { + /* Set ignored flag and mark state as changed */ + iface_states[idx] |= CONN_MGR_IF_IGNORED; + iface_states[idx] |= CONN_MGR_IF_CHANGED; + k_sem_give(&conn_mgr_event_signal); + } + + k_mutex_unlock(&conn_mgr_lock); +} + +void conn_mgr_unignore_iface(struct net_if *iface) +{ + int idx = conn_mgr_get_index_for_if(iface); + + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + + if (iface_states[idx] & CONN_MGR_IF_IGNORED) { + /* Clear ignored flag and mark state as changed */ + iface_states[idx] &= ~CONN_MGR_IF_IGNORED; + iface_states[idx] |= CONN_MGR_IF_CHANGED; + k_sem_give(&conn_mgr_event_signal); + } + + k_mutex_unlock(&conn_mgr_lock); +} + +bool conn_mgr_is_iface_ignored(struct net_if *iface) +{ + int idx = conn_mgr_get_index_for_if(iface); + + bool ret = false; + + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + + ret = iface_states[idx] & CONN_MGR_IF_IGNORED; + + k_mutex_unlock(&conn_mgr_lock); + + return ret; +} + +/** + * @brief Check whether a provided iface uses the provided L2. + * + * @param iface - iface to check. + * @param l2 - L2 to check. NULL will match offloaded ifaces. + * @retval true if the iface uses the provided L2. + * @retval false otherwise. + */ +static bool iface_uses_l2(struct net_if *iface, const struct net_l2 *l2) +{ + return (!l2 && net_if_offload(iface)) || + (net_if_l2(iface) == l2); +} + +void conn_mgr_ignore_l2(const struct net_l2 *l2) +{ + /* conn_mgr_ignore_iface already locks the mutex, but we lock it here too + * so that all matching ifaces are updated simultaneously. + */ + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + + STRUCT_SECTION_FOREACH(net_if, iface) { + if (iface_uses_l2(iface, l2)) { + conn_mgr_ignore_iface(iface); + } + } + + k_mutex_unlock(&conn_mgr_lock); +} + +void conn_mgr_unignore_l2(const struct net_l2 *l2) +{ + /* conn_mgr_unignore_iface already locks the mutex, but we lock it here too + * so that all matching ifaces are updated simultaneously. + */ + k_mutex_lock(&conn_mgr_lock, K_FOREVER); + + STRUCT_SECTION_FOREACH(net_if, iface) { + if (iface_uses_l2(iface, l2)) { + conn_mgr_unignore_iface(iface); + } + } + + k_mutex_unlock(&conn_mgr_lock); +} + static int conn_mgr_init(void) { int i; diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 097b501d682f..42c41e318f10 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -24,7 +24,10 @@ #define CONN_MGR_IF_IPV6_DAD_OK BIT(2) #define CONN_MGR_IF_IPV4_SET BIT(3) -/* Internal state flags */ +/* Configuration flags */ +#define CONN_MGR_IF_IGNORED BIT(7) + +/* Internal state flags*/ #define CONN_MGR_IF_READY BIT(14) /* Event flags */ From 2eee4cbf787218c8acf88d2359623d96801fd38a Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Fri, 21 Apr 2023 15:55:42 -0700 Subject: [PATCH 074/528] [nrf fromlist] samples: net: sockets: echo_server: Use conn_mgr ignore_iface Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 conn_mgr now allows applications to request that ifaces be ignored. This commit changes the echo_server sample to use this feature to filter out the tunnel iface, instead of manually filtering events generated by it. This will allow the echo_server sample to remain compatible with planned changes to conn_mgr, namely a switch from events being fired for every individual iface that goes up or down, to only being fired when connectivity is gained or completely lost. Signed-off-by: Georges Oates_Larsen (cherry picked from commit 602cf19903f408c42b49eb01b792f2934a632fda) --- samples/net/sockets/echo_server/src/echo-server.c | 8 +++----- samples/net/sockets/echo_server/src/tunnel.c | 3 +++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/samples/net/sockets/echo_server/src/echo-server.c b/samples/net/sockets/echo_server/src/echo-server.c index c5a1ae0e0a6f..fbf189f898ad 100644 --- a/samples/net/sockets/echo_server/src/echo-server.c +++ b/samples/net/sockets/echo_server/src/echo-server.c @@ -84,6 +84,9 @@ static void stop_udp_and_tcp(void) static void event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) { + ARG_UNUSED(iface); + ARG_UNUSED(cb); + if ((mgmt_event & EVENT_MASK) != mgmt_event) { return; } @@ -93,11 +96,6 @@ static void event_handler(struct net_mgmt_event_callback *cb, want_to_quit = false; } - if (is_tunnel(iface)) { - /* Tunneling is handled separately, so ignore it here */ - return; - } - if (mgmt_event == NET_EVENT_L4_CONNECTED) { LOG_INF("Network connected"); diff --git a/samples/net/sockets/echo_server/src/tunnel.c b/samples/net/sockets/echo_server/src/tunnel.c index e1cb98fb9cec..91d1aa7108d1 100644 --- a/samples/net/sockets/echo_server/src/tunnel.c +++ b/samples/net/sockets/echo_server/src/tunnel.c @@ -42,6 +42,9 @@ static int setup_iface(struct net_if *iface, const char *ipaddr) struct net_if_addr *ifaddr; struct sockaddr addr; + /* Before setting up tunnel, make sure it will be ignored by conn_mgr */ + conn_mgr_ignore_iface(iface); + if (!net_ipaddr_parse(ipaddr, strlen(ipaddr), &addr)) { LOG_ERR("Tunnel peer address \"%s\" invalid.", ipaddr); return -EINVAL; From 3b0ca1e118685b033bccbb6d308842fe20ea4eb1 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Mon, 3 Apr 2023 16:56:52 -0700 Subject: [PATCH 075/528] [nrf fromlist] net: conn_mgr: Fire events only on connectivity gain/loss Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 Currently, conn_mgr fires L4_CONNECTED and L4_DISCONNECTED events for every individual iface that gains or loses connectivity. After this commit, these events are only fired when the first iface gains connectivity, and the last iface loses connectivity, respectively. This is so that applications can rely on conn_mgr as a simple way to track whether connectivity is available. Signed-off-by: Georges Oates_Larsen (cherry picked from commit 971f89337d0ff6a444a9e2a537e669b4b43a824f) --- subsys/net/conn_mgr/conn_mgr.c | 67 +++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index 628bd2ba4d65..9f9c791c1956 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -23,8 +23,16 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #define THREAD_PRIORITY K_PRIO_PREEMPT(7) #endif +/* Tracks per-iface state and event flags */ uint16_t iface_states[CONN_MGR_IFACE_MAX]; +/* Tracks the total number of L4-ready ifaces */ +static uint16_t ready_count; + +/* Tracks the last ifaces to change state in each respective direction */ +static int last_iface_down; +static int last_iface_up; + /* Used to signal when modifications have been made that need to be responded to */ K_SEM_DEFINE(conn_mgr_event_signal, 1, 1); @@ -81,50 +89,36 @@ static int conn_mgr_get_index_for_if(struct net_if *iface) return net_if_get_by_iface(iface) - 1; } -/** - * @brief Notifies listeners of the current readiness state of the iface at the given index - * - * @param index - Index of the iface (in iface_states) - */ -static void conn_mgr_notify_if_readiness(int index) -{ - struct net_if *iface = conn_mgr_get_if_by_index(index); - bool readiness = iface_states[index] & CONN_MGR_IF_READY; - - if (iface == NULL) { - return; - } - - NET_DBG("Iface %d (%p) %s", net_if_get_by_iface(iface), - iface, readiness ? "ready" : "unready"); - - net_mgmt_event_notify( - readiness ? NET_EVENT_L4_CONNECTED : NET_EVENT_L4_DISCONNECTED, - iface - ); - -} - static void conn_mgr_set_ready(int idx, bool readiness) { /* Clear and then update the L4-readiness bit */ iface_states[idx] &= ~CONN_MGR_IF_READY; + if (readiness) { iface_states[idx] |= CONN_MGR_IF_READY; + + ready_count += 1; + last_iface_up = idx; + } else { + ready_count -= 1; + last_iface_down = idx; } } static void conn_mgr_act_on_changes(void) { int idx; + int original_ready_count; bool is_ip_ready; bool is_l4_ready; bool is_oper_up; bool was_l4_ready; bool is_ignored; + struct net_if *last_iface; k_mutex_lock(&conn_mgr_lock, K_FOREVER); + original_ready_count = ready_count; for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { if (iface_states[idx] == 0) { /* This interface is not used */ @@ -150,11 +144,22 @@ static void conn_mgr_act_on_changes(void) if (was_l4_ready != is_l4_ready) { /* Track the iface readiness change */ conn_mgr_set_ready(idx, is_l4_ready); + } + } - /* Notify listeners of the readiness change */ - conn_mgr_notify_if_readiness(idx); + /* If the total number of ready ifaces changed, possibly send an event */ + if (ready_count != original_ready_count) { + if (ready_count == 0) { + /* We just lost connectivity */ + last_iface = conn_mgr_get_if_by_index(last_iface_down); + net_mgmt_event_notify(NET_EVENT_L4_DISCONNECTED, last_iface); + } else if (original_ready_count == 0) { + /* We just gained connectivity */ + last_iface = conn_mgr_get_if_by_index(last_iface_up); + net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, last_iface); } } + k_mutex_unlock(&conn_mgr_lock); } @@ -233,12 +238,16 @@ K_THREAD_DEFINE(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE, void conn_mgr_resend_status(void) { - int idx; + struct net_if *last_iface; k_mutex_lock(&conn_mgr_lock, K_FOREVER); - for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { - conn_mgr_notify_if_readiness(idx); + if (ready_count == 0) { + last_iface = conn_mgr_get_if_by_index(last_iface_down); + net_mgmt_event_notify(NET_EVENT_L4_DISCONNECTED, last_iface); + } else { + last_iface = conn_mgr_get_if_by_index(last_iface_up); + net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, last_iface); } k_mutex_unlock(&conn_mgr_lock); From bf31d7373dbe8fbfb6d3c1cfbbe3bd7f4ab72058 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 18 Apr 2023 13:36:40 -0700 Subject: [PATCH 076/528] [nrf fromlist] net: conn_mgr: Simplify DAD handling Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 The current method for handling DAD directly tracks a DAD state for each iface. This does not reflect the fact that each individual IP has a separate DAD state. This also does not align with the logic in conn_mgr_initial_state, which instead uses net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, ...). Thus, the current approach falsely reports IPv6 ready when DAD adds the link_addr, and also fails to report IPv6 ready if DAD is disabled. This commit removes DAD tracking completely, and relies solely on net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, ...), fixing both problems, and simplifying the event tracking. For consistency, slight modifications to IPv4 handling as well. Signed-off-by: Georges Oates_Larsen (cherry picked from commit e7a2c675e60514d86ee16454528ec35adb1f1f05) --- subsys/net/conn_mgr/conn_mgr.c | 45 ++++++-------------------- subsys/net/conn_mgr/conn_mgr_private.h | 9 +----- subsys/net/conn_mgr/events_handler.c | 19 ++++------- 3 files changed, 17 insertions(+), 56 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index 9f9c791c1956..faf14a6d3802 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -39,34 +39,6 @@ K_SEM_DEFINE(conn_mgr_event_signal, 1, 1); /* Used to protect conn_mgr state */ K_MUTEX_DEFINE(conn_mgr_lock); -#if defined(CONFIG_NET_IPV6) -static bool conn_mgr_is_if_ipv6_ready(int index) -{ - if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == CONN_MGR_IPV6_STATUS_MASK) { - NET_DBG("IPv6 connected on iface index %u", index + 1); - return true; - } - - return false; -} -#else -#define conn_mgr_is_if_ipv6_ready(...) false -#endif /* CONFIG_NET_IPV6 */ - -#if defined(CONFIG_NET_IPV4) -static bool conn_mgr_is_if_ipv4_ready(int index) -{ - if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == CONN_MGR_IPV4_STATUS_MASK) { - NET_DBG("IPv4 connected on iface index %u", index + 1); - return true; - } - - return false; -} -#else -#define conn_mgr_is_if_ipv4_ready(...) false -#endif /* CONFIG_NET_IPV4 */ - /** * @brief Retrieves pointer to an iface by the index that corresponds to it in iface_states * @@ -110,6 +82,8 @@ static void conn_mgr_act_on_changes(void) int idx; int original_ready_count; bool is_ip_ready; + bool is_ipv6_ready; + bool is_ipv4_ready; bool is_l4_ready; bool is_oper_up; bool was_l4_ready; @@ -134,11 +108,13 @@ static void conn_mgr_act_on_changes(void) iface_states[idx] &= ~CONN_MGR_IF_CHANGED; /* Detect whether the iface is currently or was L4 ready */ - is_ip_ready = conn_mgr_is_if_ipv6_ready(idx) || conn_mgr_is_if_ipv4_ready(idx); - is_oper_up = iface_states[idx] & CONN_MGR_IF_UP; - was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY; - is_ignored = iface_states[idx] & CONN_MGR_IF_IGNORED; - is_l4_ready = is_oper_up && is_ip_ready && !is_ignored; + was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY; + is_ipv6_ready = iface_states[idx] & CONN_MGR_IF_IPV6_SET; + is_ipv4_ready = iface_states[idx] & CONN_MGR_IF_IPV4_SET; + is_oper_up = iface_states[idx] & CONN_MGR_IF_UP; + is_ignored = iface_states[idx] & CONN_MGR_IF_IGNORED; + is_ip_ready = is_ipv6_ready || is_ipv4_ready; + is_l4_ready = is_oper_up && is_ip_ready && !is_ignored; /* Respond to changes to iface readiness */ if (was_l4_ready != is_l4_ready) { @@ -182,9 +158,6 @@ static void conn_mgr_initial_state(struct net_if *iface) if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6)) { if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { NET_DBG("IPv6 addr set"); - iface_states[idx] |= CONN_MGR_IF_IPV6_SET | CONN_MGR_IF_IPV6_DAD_OK; - } else if (net_if_ipv6_get_global_addr(NET_ADDR_TENTATIVE, - &iface)) { iface_states[idx] |= CONN_MGR_IF_IPV6_SET; } } diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 42c41e318f10..b21e61bf0aa6 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -21,8 +21,7 @@ /* External state flags */ #define CONN_MGR_IF_UP BIT(0) #define CONN_MGR_IF_IPV6_SET BIT(1) -#define CONN_MGR_IF_IPV6_DAD_OK BIT(2) -#define CONN_MGR_IF_IPV4_SET BIT(3) +#define CONN_MGR_IF_IPV4_SET BIT(2) /* Configuration flags */ #define CONN_MGR_IF_IGNORED BIT(7) @@ -45,12 +44,6 @@ #define CONN_MGR_IPV4_EVENTS_MASK (NET_EVENT_IPV4_ADDR_ADD | \ NET_EVENT_IPV4_ADDR_DEL) -/* Internal event masks */ -#define CONN_MGR_IPV6_STATUS_MASK (CONN_MGR_IF_IPV6_SET | \ - CONN_MGR_IF_IPV6_DAD_OK) - -#define CONN_MGR_IPV4_STATUS_MASK (CONN_MGR_IF_IPV4_SET) - extern struct k_sem conn_mgr_event_signal; extern struct k_mutex conn_mgr_lock; diff --git a/subsys/net/conn_mgr/events_handler.c b/subsys/net/conn_mgr/events_handler.c index 81a4ea6f7e40..a3cdc903c6c8 100644 --- a/subsys/net/conn_mgr/events_handler.c +++ b/subsys/net/conn_mgr/events_handler.c @@ -77,25 +77,20 @@ static void conn_mgr_ipv6_events_handler(struct net_mgmt_event_callback *cb, k_mutex_lock(&conn_mgr_lock, K_FOREVER); switch (NET_MGMT_GET_COMMAND(mgmt_event)) { + case NET_EVENT_IPV6_CMD_DAD_SUCCEED: + __fallthrough; case NET_EVENT_IPV6_CMD_ADDR_ADD: - iface_states[idx] |= CONN_MGR_IF_IPV6_SET; - break; - case NET_EVENT_IPV6_CMD_ADDR_DEL: if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { - break; + iface_states[idx] |= CONN_MGR_IF_IPV6_SET; } - - iface_states[idx] &= ~CONN_MGR_IF_IPV6_SET; - break; - case NET_EVENT_IPV6_CMD_DAD_SUCCEED: - iface_states[idx] |= CONN_MGR_IF_IPV6_DAD_OK; break; case NET_EVENT_IPV6_CMD_DAD_FAILED: - if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { - break; + __fallthrough; + case NET_EVENT_IPV6_CMD_ADDR_DEL: + if (!net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { + iface_states[idx] &= ~CONN_MGR_IF_IPV6_SET; } - iface_states[idx] &= ~CONN_MGR_IF_IPV6_DAD_OK; break; default: goto done; From e50f48465a09ca70250bfd5428ee5d0104433717 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 2 May 2023 17:29:31 -0700 Subject: [PATCH 077/528] [nrf fromlist] net: conn_mgr: connect/disconnect adjustments Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 Rather than raise error on connect if iface is down, just take the iface up. Rather than raise error on disconnect if iface is down, just ignore the disconnection request. Adjust tests and documentation accordingly. This should make the API easier to use for applications and is more in line with the original L2 agnostic connectivity RFC. Also replace some instances of net_if_flag_is_set with net_if_is_admin_up, which is cleaner and identical in function. Signed-off-by: Georges Oates_Larsen (cherry picked from commit 46d2b62e02a650d0f658a3f1a616754ef20c3282) --- include/zephyr/net/conn_mgr_connectivity.h | 4 ++ subsys/net/conn_mgr/conn_mgr_connectivity.c | 14 +++--- tests/net/conn_mgr_conn/src/main.c | 55 +++++++++++++-------- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 7f035a277b51..cad0bdfb4d56 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -259,6 +259,8 @@ struct conn_mgr_conn_binding { * If the provided iface has been bound to a connectivity implementation, initiate * network connect/association. * + * Automatically takes the iface admin-up (by calling net_if_up) if it isn't already. + * * Non-Blocking. * * @param iface Pointer to network interface @@ -275,6 +277,8 @@ int conn_mgr_if_connect(struct net_if *iface); * If the provided iface has been bound to a connectivity implementation, disconnect/dissassociate * it from the network, and cancel any pending attempts to connect/associate. * + * Does nothing if the iface is currently admin-down. + * * @param iface Pointer to network interface * * @retval 0 on success. diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index ac33ce68bce7..2cc075074fbd 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -31,9 +31,11 @@ int conn_mgr_if_connect(struct net_if *iface) k_mutex_lock(binding->mutex, K_FOREVER); - if (!net_if_flag_is_set(iface, NET_IF_UP)) { - status = -ESHUTDOWN; - goto out; + if (!net_if_is_admin_up(iface)) { + status = net_if_up(iface); + if (status) { + goto out; + } } status = api->connect(binding); @@ -48,7 +50,7 @@ int conn_mgr_if_disconnect(struct net_if *iface) { struct conn_mgr_conn_binding *binding; struct conn_mgr_conn_api *api; - int status; + int status = 0; LOG_DBG("iface %p disconnect", iface); @@ -62,11 +64,9 @@ int conn_mgr_if_disconnect(struct net_if *iface) return -ENOTSUP; } - k_mutex_lock(binding->mutex, K_FOREVER); - if (!net_if_flag_is_set(iface, NET_IF_UP)) { - status = -EALREADY; + if (!net_if_is_admin_up(iface)) { goto out; } diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index 9111aa89b510..dbe1d4cb3374 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -392,6 +392,41 @@ ZTEST(conn_mgr_conn, test_connect_disconnect_double_instant) zassert_equal(ifa1_data->call_cnt_a, 4, "ifa1->disconnect should have been called once."); } +/* Verify that calling connect on a down iface automatically takes the iface up. */ +ZTEST(conn_mgr_conn, test_connect_autoup) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Connect iface */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); + k_sleep(K_MSEC(1)); + + /* Verify net_if_up was called */ + zassert_true(net_if_is_admin_up(ifa1), "ifa1 should be admin-up after conn_mgr_if_connect"); + + /* Verify that connection succeeds */ + zassert_true(net_if_is_up(ifa1), "ifa1 should be oper-up after conn_mgr_if_connect"); + zassert_equal(ifa1_data->conn_bal, 1, "ifa1->connect should have been called once."); + zassert_equal(ifa1_data->call_cnt_a, 1, "ifa1->connect should have been called once."); +} + +/* Verify that calling disconnect on a down iface has no effect and raises no error. */ +ZTEST(conn_mgr_conn, test_disconnect_down) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Disconnect iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail."); + k_sleep(K_MSEC(1)); + + /* Verify iface is still down */ + zassert_false(net_if_is_admin_up(ifa1), "ifa1 should be still be admin-down."); + + /* Verify that no callbacks were fired */ + zassert_equal(ifa1_data->conn_bal, 0, "No callbacks should have been fired."); + zassert_equal(ifa1_data->call_cnt_a, 0, "No callbacks should have been fired."); +} + /** * Verify that invalid bound ifaces are treated as though they are not bound at all. */ @@ -408,20 +443,10 @@ ZTEST(conn_mgr_conn, test_invalid_ignored) */ ZTEST(conn_mgr_conn, test_connect_invalid) { - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - /* Bring ifnull and ifnone up */ zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for ifnull"); zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for ifnone"); - /* Attempts to connect ifa1 without bringing it up should fail */ - zassert_equal(conn_mgr_if_connect(ifa1), -ESHUTDOWN, - "conn_mgr_if_connect should give -ENOTSUP for down iface"); - zassert_equal(ifa1_data->conn_bal, 0, - "conn_mgr_if_connect should not affect down iface"); - zassert_equal(ifa1_data->call_cnt_a, 0, - "conn_mgr_if_connect should not affect down iface"); - /* Attempts to connect ifnull should fail, even if it is up */ zassert_equal(conn_mgr_if_connect(ifnull), -ENOTSUP, "conn_mgr_if_connect should give -ENOTSUP for ifnull"); @@ -436,20 +461,10 @@ ZTEST(conn_mgr_conn, test_connect_invalid) */ ZTEST(conn_mgr_conn, test_disconnect_invalid) { - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - /* Bring ifnull and ifnone up */ zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for ifnull"); zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for ifnone"); - /* Attempts to disconnect ifa1 without bringing it up should fail */ - zassert_equal(conn_mgr_if_disconnect(ifa1), -EALREADY, - "conn_mgr_if_disconnect should give -ENOTSUP for down iface"); - zassert_equal(ifa1_data->conn_bal, 0, - "conn_mgr_if_disconnect should not affect down iface"); - zassert_equal(ifa1_data->call_cnt_a, 0, - "conn_mgr_if_disconnect should not affect down iface"); - /* Attempts to disconnect ifnull should fail, even if it is up */ zassert_equal(conn_mgr_if_disconnect(ifnull), -ENOTSUP, "conn_mgr_if_disconnect should give -ENOTSUP for ifnull"); From 30e2e33a84913c834725c550c0b87c541da2eb44 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Mon, 10 Apr 2023 12:57:49 -0700 Subject: [PATCH 078/528] [nrf fromlist] net: conn_mgr: Add test suite Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56549 Create test suite covering all major features of conn_mgr Signed-off-by: Georges Oates_Larsen (cherry picked from commit 77109dd6b6a4a34ae103a9ad922627e1ea6bad2e) --- tests/net/conn_mgr/CMakeLists.txt | 9 + tests/net/conn_mgr/prj.conf | 30 + tests/net/conn_mgr/src/main.c | 939 +++++++++++++++++++++++++++ tests/net/conn_mgr/src/test_ifaces.c | 155 +++++ tests/net/conn_mgr/src/test_ifaces.h | 27 + tests/net/conn_mgr/testcase.yaml | 11 + 6 files changed, 1171 insertions(+) create mode 100644 tests/net/conn_mgr/CMakeLists.txt create mode 100644 tests/net/conn_mgr/prj.conf create mode 100644 tests/net/conn_mgr/src/main.c create mode 100644 tests/net/conn_mgr/src/test_ifaces.c create mode 100644 tests/net/conn_mgr/src/test_ifaces.h create mode 100644 tests/net/conn_mgr/testcase.yaml diff --git a/tests/net/conn_mgr/CMakeLists.txt b/tests/net/conn_mgr/CMakeLists.txt new file mode 100644 index 000000000000..dba2a43f052e --- /dev/null +++ b/tests/net/conn_mgr/CMakeLists.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(iface) + +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/conn_mgr/prj.conf b/tests/net/conn_mgr/prj.conf new file mode 100644 index 000000000000..1e60d8327ed2 --- /dev/null +++ b/tests/net/conn_mgr/prj.conf @@ -0,0 +1,30 @@ +CONFIG_NETWORKING=y +CONFIG_NET_TEST=y +CONFIG_NET_IPV6=y +CONFIG_NET_IPV4=y +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_MAX_CONTEXTS=4 +CONFIG_NET_L2_DUMMY=y +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_NET_IPV6_MLD=n +CONFIG_NET_PKT_TX_COUNT=10 +CONFIG_NET_PKT_RX_COUNT=5 +CONFIG_NET_BUF_RX_COUNT=10 +CONFIG_NET_BUF_TX_COUNT=10 +CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 +CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2 +CONFIG_NET_MAX_NEXTHOPS=8 +CONFIG_NET_IPV6_MAX_NEIGHBORS=8 +CONFIG_NET_IPV6_ND=n +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_NET_IF_MAX_IPV4_COUNT=6 +CONFIG_NET_IF_MAX_IPV6_COUNT=6 +CONFIG_TEST_USERSPACE=y + +# Enable for help debugging this test suite: +# CONFIG_NET_LOG=y +# CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL_DBG=y +# CONFIG_NET_IF_LOG_LEVEL_DBG=y diff --git a/tests/net/conn_mgr/src/main.c b/tests/net/conn_mgr/src/main.c new file mode 100644 index 000000000000..f5399b92e743 --- /dev/null +++ b/tests/net/conn_mgr/src/main.c @@ -0,0 +1,939 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include "conn_mgr_private.h" +#include "test_ifaces.h" +#include + +#include + +/* Time to wait for NET_MGMT events to finish firing */ +#define EVENT_WAIT_TIME K_MSEC(1) + +/* Time to wait for IPv6 DAD to finish */ +#define DAD_WAIT_TIME K_MSEC(110) + +/* IP addresses -- Two of each are needed because address sharing will cause address removal to + * fail silently (Address is only removed from one iface). + */ +static struct in_addr test_ipv4_a = { { { 10, 0, 0, 1 } } }; +static struct in_addr test_ipv4_b = { { { 10, 0, 0, 2 } } }; +static struct in6_addr test_ipv6_a = { { { + 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 +} } }; + +/* Helpers */ +static void reset_test_iface(struct net_if *iface) +{ + struct in6_addr *ll_ipv6; + + if (net_if_is_admin_up(iface)) { + if (conn_mgr_if_is_bound(iface)) { + (void)conn_mgr_if_disconnect(iface); + } + (void)net_if_down(iface); + } + + net_if_ipv4_addr_rm(iface, &test_ipv4_a); + net_if_ipv4_addr_rm(iface, &test_ipv4_b); + net_if_ipv6_addr_rm(iface, &test_ipv6_a); + + /* DAD adds the link-local address automatically. Check for it, and remove it if present. */ + ll_ipv6 = net_if_ipv6_get_ll(iface, NET_ADDR_ANY_STATE); + if (ll_ipv6) { + net_if_ipv6_addr_rm(iface, ll_ipv6); + } + + conn_mgr_unignore_iface(iface); +} + +/* Thread-safe test statistics */ +K_MUTEX_DEFINE(stats_mutex); +static struct test_stats { + /** The number of times conn_mgr has raised a connect event */ + int conn_count; + + /** The number of times conn_mgr has raised a disconnect event */ + int dconn_count; + + /** The total number of connectivity events fired by conn_mgr */ + int event_count; + + /** The iface blamed for the last disconnect event */ + struct net_if *dconn_iface; + + /** The iface blamed for the last connect event */ + struct net_if *conn_iface; +} global_stats; + +static void reset_stats(void) +{ + k_mutex_lock(&stats_mutex, K_FOREVER); + + global_stats.conn_count = 0; + global_stats.dconn_count = 0; + global_stats.event_count = 0; + global_stats.dconn_iface = NULL; + global_stats.conn_iface = NULL; + + k_mutex_unlock(&stats_mutex); +} + +/** + * @brief Copy and then reset global test stats. + * + * @return struct test_stats -- The copy of the global test stats struct before it was reset + */ +static struct test_stats get_reset_stats(void) +{ + struct test_stats copy; + + k_mutex_lock(&stats_mutex, K_FOREVER); + copy = global_stats; + reset_stats(); + k_mutex_unlock(&stats_mutex); + return copy; +} + +/* Callback hooks */ +struct net_mgmt_event_callback l4_callback; + +void l4_handler(struct net_mgmt_event_callback *cb, uint32_t event, struct net_if *iface) +{ + if (event == NET_EVENT_L4_CONNECTED) { + k_mutex_lock(&stats_mutex, K_FOREVER); + global_stats.conn_count += 1; + global_stats.event_count += 1; + global_stats.conn_iface = iface; + k_mutex_unlock(&stats_mutex); + } else if (event == NET_EVENT_L4_DISCONNECTED) { + k_mutex_lock(&stats_mutex, K_FOREVER); + global_stats.dconn_count += 1; + global_stats.event_count += 1; + global_stats.dconn_iface = iface; + k_mutex_unlock(&stats_mutex); + } +} + + +/* Test suite shared functions & routines */ + +static void *conn_mgr_setup(void) +{ + net_mgmt_init_event_callback( + &l4_callback, l4_handler, NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED + ); + net_mgmt_add_event_callback(&l4_callback); + return NULL; +} + + +static void conn_mgr_before(void *data) +{ + ARG_UNUSED(data); + + reset_test_iface(if_simp_a); + reset_test_iface(if_simp_b); + reset_test_iface(if_conn_a); + reset_test_iface(if_conn_b); + + /* Allow any triggered events to shake out */ + k_sleep(EVENT_WAIT_TIME); + + reset_stats(); +} + +/** + * @brief Cycles two ifaces through several transitions from readiness to unreadiness. + * + * Ifaces are assigned a single IPv4 address at the start, and cycled through oper-states, since + * the other manners in which an iface can become L4-ready are covered by cycle_iface_pre_ready + * + * It is not necessary to cover all possible state transitions, only half of them, since + * this will be called twice by the test suites for each combination of iface type (except + * combinations where both ifaces are of the same type). + */ + +static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) +{ + struct test_stats stats; + + /* Add IPv4 addresses */ + net_if_ipv4_addr_add(ifa, &test_ipv4_a, NET_ADDR_MANUAL, 0); + net_if_ipv4_addr_add(ifb, &test_ipv4_b, NET_ADDR_MANUAL, 0); + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take A up */ + zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_connect(ifa), 0, + "conn_mgr_if_connect should succeed for ifa."); + } + + /* Expect connectivity gained */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.conn_count, 1, + "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); + + /* Take B up */ + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take A down */ + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_disconnect(ifa), 0, + "conn_mgr_if_disconnect should succeed for ifa."); + } + zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifb."); + } + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); + + /* Expect connectivity loss */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.dconn_count, 1, + "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.dconn_iface, ifb, "ifb should be blamed."); +} + +/** + * @brief Ignores and then toggles ifb's readiness several times, ensuring no events are fired. + * + * At several points, change the readiness state of ifa and ensure events are fired. + * + * @param ifa + * @param ifb + */ +static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) +{ + struct test_stats stats; + + /* Ignore B */ + conn_mgr_ignore_iface(ifb); + + /* Add IPv4 addresses */ + net_if_ipv4_addr_add(ifa, &test_ipv4_a, NET_ADDR_MANUAL, 0); + net_if_ipv4_addr_add(ifb, &test_ipv4_b, NET_ADDR_MANUAL, 0); + + /* Set one: Change A state between B state toggles */ + + /* Take B up */ + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifb."); + } + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take A up */ + zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_connect(ifa), 0, + "conn_mgr_if_connect should succeed for ifa."); + } + + /* Expect connectivity gained */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.conn_count, 1, + "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); + + /* Take B up */ + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifba."); + } + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take A down */ + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_disconnect(ifa), 0, + "conn_mgr_if_disconnect should succeed for ifa."); + } + zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); + + /* Expect connectivity lost */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.dconn_count, 1, + "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.dconn_iface, ifa, "ifa should be blamed."); + + + /* Set two: Change A state during B state toggles */ + + /* Take B up */ + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take A up */ + zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_connect(ifa), 0, + "conn_mgr_if_connect should succeed for ifa."); + } + + /* Expect connectivity gained */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.conn_count, 1, + "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); + + /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifb."); + } + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + + /* Take B up */ + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Take A down */ + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_disconnect(ifa), 0, + "conn_mgr_if_disconnect should succeed for ifa."); + } + zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); + + /* Expect connectivity lost */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.dconn_count, 1, + "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.dconn_iface, ifa, "ifa should be blamed."); + + /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifb."); + } + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); + + /* Expect no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); +} + +enum ip_order { + IPV4_FIRST, + IPV6_FIRST +}; + +/** + * @brief Cycles a single iface through all possible ready and pre-ready states, + * ensuring the correct events are observed and generated by conn_mgr. + * + * Ifaces can be in one of four states that are relevant to L4 readiness: + * 00: oper-down, no IPs associated (unready state) + * 01: Has IP, is oper-down (semi-ready state) + * 10: Is oper-up, has no IP (semi-ready state) + * 11: Has IP and is oper-up (ready state) + * + * In total there are eight possible state transitions: + * + * (00 -> 10): Gain oper-up from unready state + * (10 -> 11): Gain IP from semi-ready state + * (11 -> 10): Lose IP from ready state + * (10 -> 00): Lose oper-up from semi-ready state + * (00 -> 01): Gain IP from unready state + * (01 -> 11): Gain Oper-up from semi-ready state + * (11 -> 01): Lose oper-up from ready state + * (01 -> 00): Lose IP from semi-ready state + * + * We test these state transitions in that order. + * + * This is slightly complicated by the fact that ifaces can be assigned multiple IPs, and multiple + * types of IPs. Whenever IPs are assigned or removed, two of them, an IPv6 and IPv4 address is + * added or removed. + * + * @param iface + * @param ifa_ipm + */ +static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) +{ + struct test_stats stats; + + /* (00 -> 10): Gain oper-up from unready state */ + + /* Take iface up */ + zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); + + if (conn_mgr_if_is_bound(iface)) { + zassert_equal(conn_mgr_if_connect(iface), 0, + "conn_mgr_if_connect should succeed."); + } + + /* Verify that no events have been fired yet */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* (10 -> 11): Gain IP from semi-ready state */ + switch (ifa_ipm) { + case IPV4_FIRST: + /* Add IPv4 */ + net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0); + + /* Verify correct events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.conn_count, 1, + "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.conn_iface, iface, "The test iface should be blamed."); + + + /* Add IPv6 */ + net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0); + k_sleep(DAD_WAIT_TIME); + + /* Verify no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + break; + case IPV6_FIRST: + /* Add IPv6 */ + net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0); + k_sleep(DAD_WAIT_TIME); + + /* Verify correct events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.conn_count, 1, + "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.conn_iface, iface, "The test iface should be blamed."); + + /* Add IPv4 */ + net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0); + + /* Verify no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + break; + } + + /* (11 -> 10): Lose IP from ready state */ + switch (ifa_ipm) { + case IPV4_FIRST: + /* Remove IPv4 */ + zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a), + "IPv4 removal should succeed."); + + /* Verify no events (because IPv6 addr is still active) */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Remove IPv6 */ + zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a), + "IPv6 removal should succeed."); + + /* Verify correct events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.dconn_count, 1, + "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity " + "is lost."); + zassert_equal(stats.dconn_iface, iface, "The test iface should be blamed."); + + break; + case IPV6_FIRST: + /* Remove IPv6 */ + zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a), + "IPv6 removal should succeed."); + + /* Verify no events (because IPv4 addr is still active) */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* Remove IPv4 */ + zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a), + "IPv4 removal should succeed."); + + /* Verify correct events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.dconn_count, 1, + "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity " + "is lost."); + zassert_equal(stats.dconn_iface, iface, "The test iface should be blamed."); + + break; + } + + /* (10 -> 00): Lose oper-up from semi-ready state */ + + /* Take iface down */ + if (conn_mgr_if_is_bound(iface)) { + zassert_equal(conn_mgr_if_disconnect(iface), 0, + "conn_mgr_if_disconnect should succeed."); + } + zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); + + /* Verify there are no events fired */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* (00 -> 01): Gain IP from unready state */ + + /* Add IP addresses to iface */ + switch (ifa_ipm) { + case IPV4_FIRST: + /* Add IPv4 and IPv6 */ + net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0); + net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0); + k_sleep(DAD_WAIT_TIME); + break; + case IPV6_FIRST: + /* Add IPv6 then IPv4 */ + net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0); + k_sleep(DAD_WAIT_TIME); + net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0); + break; + } + + /* Verify that no events are fired */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); + + /* (01 -> 11): Gain Oper-up from semi-ready state */ + + /* Take iface up */ + zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); + if (conn_mgr_if_is_bound(iface)) { + zassert_equal(conn_mgr_if_connect(iface), 0, + "conn_mgr_if_connect should succeed."); + } + + /* Verify events are fired */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.conn_count, 1, + "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); + zassert_equal(stats.conn_iface, iface, "The test iface should be blamed."); + + /* (11 -> 01): Lose oper-up from ready state */ + + /* Take iface down */ + if (conn_mgr_if_is_bound(iface)) { + zassert_equal(conn_mgr_if_disconnect(iface), 0, + "conn_mgr_if_disconnect should succeed."); + } + zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); + + /* Verify events are fired */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.dconn_count, 1, + "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); + zassert_equal(stats.dconn_iface, iface, "The test iface should be blamed."); + + /* (01 -> 00): Lose IP from semi-ready state */ + + /* Remove IPs */ + switch (ifa_ipm) { + case IPV4_FIRST: + /* Remove IPv4 then IPv6 */ + zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a), + "IPv4 removal should succeed."); + zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a), + "IPv6 removal should succeed."); + break; + case IPV6_FIRST: + /* Remove IPv6 then IPv4 */ + zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a), + "IPv6 removal should succeed."); + zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a), + "IPv4 removal should succeed."); + break; + } + + /* Verify no events fired */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connectivity availability did not change."); +} + +/* Cases */ + +/* Make sure all readiness transitions of a pair of connectivity-enabled ifaces results in all + * expected events. + */ +ZTEST(conn_mgr, test_cycle_ready_CC) +{ + cycle_ready_ifaces(if_conn_a, if_conn_b); +} + +/* Make sure half of all readiness transitions of a connectivity-enabled iface and a simple + * iface results in all expected events. + */ +ZTEST(conn_mgr, test_cycle_ready_CNC) +{ + cycle_ready_ifaces(if_conn_a, if_simp_a); +} + +/* Make sure the other half of all readiness transitions of a connectivity-enabled iface and a + * simple iface results in all expected events. + */ +ZTEST(conn_mgr, test_cycle_ready_NCC) +{ + cycle_ready_ifaces(if_simp_a, if_conn_a); +} + +/* Make sure all readiness transitions of a pair of simple ifaces results in all expected events. + */ +ZTEST(conn_mgr, test_cycle_ready_NCNC) +{ + cycle_ready_ifaces(if_simp_a, if_simp_b); +} + +/* Make sure that a simple iface can be successfully ignored without interfering with the events + * fired by another simple iface + */ +ZTEST(conn_mgr, test_cycle_ready_NCINC) +{ + cycle_ignored_iface(if_simp_a, if_simp_b); +} + +/* Make sure that a connectivity-enabled iface can be successfully ignored without interfering + * with the events fired by another connectivity-enabled iface + */ +ZTEST(conn_mgr, test_cycle_ready_CIC) +{ + cycle_ignored_iface(if_conn_a, if_conn_b); +} + +/* Make sure that a connectivity-enabled iface can be successfully ignored without interfering + * with the events fired by a simple iface + */ +ZTEST(conn_mgr, test_cycle_ready_CINC) +{ + cycle_ignored_iface(if_conn_a, if_simp_a); +} + +/* Make sure that a simple iface can be successfully ignored without interfering + * with the events fired by a connectivity-enabled iface + */ +ZTEST(conn_mgr, test_cycle_ready_NCIC) +{ + cycle_ignored_iface(if_simp_a, if_conn_a); +} + +/* Make sure that DAD readiness is actually verified by conn_mgr */ +ZTEST(conn_mgr, test_DAD) +{ + struct test_stats stats; + + /* This test specifically requires DAD to function */ + Z_TEST_SKIP_IFNDEF(CONFIG_NET_IPV6_DAD); + + /* Take iface up */ + zassert_equal(net_if_up(if_simp_a), 0, "net_if_up should succeed."); + + /* Add IPv6 */ + net_if_ipv6_addr_add(if_simp_a, &test_ipv6_a, NET_ADDR_MANUAL, 0); + + /* After a delay too short for DAD, ensure no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired before DAD success."); + + /* After a delay long enough for DAD, ensure connectivity acquired */ + k_sleep(DAD_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.conn_count, 1, + "NET_EVENT_L4_CONNECTED should be fired after DAD success."); +} + +/* Test whether ignoring and un-ignoring a ready iface fires the appropriate events */ +ZTEST(conn_mgr, test_ignore_while_ready) +{ + struct test_stats stats; + + /* Ignore iface */ + conn_mgr_ignore_iface(if_simp_a); + + /* Add IP and take iface up */ + net_if_ipv4_addr_add(if_simp_a, &test_ipv4_a, NET_ADDR_MANUAL, 0); + zassert_equal(net_if_up(if_simp_a), 0, "net_if_up should succeed for if_simp_a."); + + /* Ensure no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if connecting iface is ignored."); + + /* Un-ignore iface */ + conn_mgr_unignore_iface(if_simp_a); + + /* Ensure connectivity gained */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.conn_count, 1, + "NET_EVENT_L4_CONNECTED should be fired when online iface is unignored."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_CONNECTED should be fired."); + zassert_equal(stats.conn_iface, if_simp_a, "if_simp_a should be blamed."); + + /* Ignore iface */ + conn_mgr_ignore_iface(if_simp_a); + + /* Ensure connectivity lost */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.dconn_count, 1, + "NET_EVENT_L4_DISCONNECTED should be fired when online iface is ignored."); + zassert_equal(stats.event_count, 1, + "Only NET_EVENT_L4_DISCONNECTED should be fired."); + zassert_equal(stats.dconn_iface, if_simp_a, "if_simp_a should be blamed"); + + /* Take iface down*/ + zassert_equal(net_if_down(if_simp_a), 0, "net_if_down should succeed for if_simp_a."); + + /* Ensure no events */ + k_sleep(EVENT_WAIT_TIME); + stats = get_reset_stats(); + zassert_equal(stats.event_count, 0, + "No events should be fired if disconnecting iface is ignored."); +} + +/* Test L2 and iface ignore API */ +ZTEST(conn_mgr, test_ignores) +{ + /* Ignore if_simp_a, ensuring if_simp_b is unaffected */ + conn_mgr_ignore_iface(if_simp_a); + zassert_true(conn_mgr_is_iface_ignored(if_simp_a), + "if_simp_a should be ignored."); + zassert_false(conn_mgr_is_iface_ignored(if_simp_b), + "if_simp_b should not be affected."); + + /* Ignore if_simp_b, ensuring if_simp_a is unaffected */ + conn_mgr_ignore_iface(if_simp_b); + zassert_true(conn_mgr_is_iface_ignored(if_simp_b), + "if_simp_b should be ignored."); + zassert_true(conn_mgr_is_iface_ignored(if_simp_a), + "if_simp_a should not be affected."); + + /* Unignore if_simp_a, ensuring if_simp_b is unaffected */ + conn_mgr_unignore_iface(if_simp_a); + zassert_false(conn_mgr_is_iface_ignored(if_simp_a), + "if_simp_a should be unignored."); + zassert_true(conn_mgr_is_iface_ignored(if_simp_b), + "if_simp_b should not be affected."); + + /* Unignore if_simp_b, ensuring if_simp_a is unaffected */ + conn_mgr_unignore_iface(if_simp_b); + zassert_false(conn_mgr_is_iface_ignored(if_simp_b), + "if_simp_b should be unignored."); + zassert_false(conn_mgr_is_iface_ignored(if_simp_a), + "if_simp_a should not be affected."); + + /* Ignore the entire DUMMY_L2, ensuring all ifaces except if_dummy_eth are affected */ + conn_mgr_ignore_l2(&NET_L2_GET_NAME(DUMMY)); + zassert_true(conn_mgr_is_iface_ignored(if_simp_a), + "All DUMMY_L2 ifaces should be ignored."); + zassert_true(conn_mgr_is_iface_ignored(if_simp_b), + "All DUMMY_L2 ifaces should be ignored."); + zassert_true(conn_mgr_is_iface_ignored(if_conn_a), + "All DUMMY_L2 ifaces should be ignored."); + zassert_true(conn_mgr_is_iface_ignored(if_conn_b), + "All DUMMY_L2 ifaces should be ignored."); + zassert_false(conn_mgr_is_iface_ignored(if_dummy_eth), + "if_dummy_eth should not be affected."); + + /* Unignore the entire DUMMY_L2, ensuring all ifaces except if_dummy_eth are affected */ + conn_mgr_unignore_l2(&NET_L2_GET_NAME(DUMMY)); + zassert_false(conn_mgr_is_iface_ignored(if_simp_a), + "All DUMMY_L2 ifaces should be unignored."); + zassert_false(conn_mgr_is_iface_ignored(if_simp_b), + "All DUMMY_L2 ifaces should be unignored."); + zassert_false(conn_mgr_is_iface_ignored(if_conn_a), + "All DUMMY_L2 ifaces should be unignored."); + zassert_false(conn_mgr_is_iface_ignored(if_conn_b), + "All DUMMY_L2 ifaces should be unignored."); + zassert_false(conn_mgr_is_iface_ignored(if_dummy_eth), + "if_dummy_eth should not be affected."); +} + +/* Make sure all state transitions of a single connectivity-enabled iface result in all expected + * events. Perform IPv4 changes before IPv6 changes. + */ +ZTEST(conn_mgr, test_cycle_states_connected_ipv46) +{ + cycle_iface_states(if_conn_a, IPV4_FIRST); +} + +/* Make sure all state transitions of a single connectivity-enabled iface result in all expected + * events. Perform IPv6 changes before IPv4 changes. + */ +ZTEST(conn_mgr, test_cycle_states_connected_ipv64) +{ + cycle_iface_states(if_conn_a, IPV6_FIRST); +} + +/* Make sure all state transitions of a single simple iface result in all expected events. + * Perform IPv4 changes before IPv6 changes. + */ +ZTEST(conn_mgr, test_cycle_states_simple_ipv46) +{ + cycle_iface_states(if_simp_a, IPV4_FIRST); +} + +/* Make sure all state transitions of a single simple iface result in all expected events. + * Perform IPv6 changes before IPv4 changes. + */ +ZTEST(conn_mgr, test_cycle_states_simple_ipv64) +{ + cycle_iface_states(if_simp_a, IPV6_FIRST); +} + +ZTEST_SUITE(conn_mgr, NULL, conn_mgr_setup, conn_mgr_before, NULL, NULL); diff --git a/tests/net/conn_mgr/src/test_ifaces.c b/tests/net/conn_mgr/src/test_ifaces.c new file mode 100644 index 000000000000..6dd0ab4ded9f --- /dev/null +++ b/tests/net/conn_mgr/src/test_ifaces.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include +#include "test_ifaces.h" + +/* Create test ifaces */ + +/* Generic iface initializer, shared by all test ifaces */ +static void test_iface_init(struct net_if *iface) +{ + /* Fake link layer address is needed to silence assertions inside the net core */ + static uint8_t fake_lladdr[] = { 0x01 }; + + net_if_set_link_addr(iface, fake_lladdr, sizeof(fake_lladdr), NET_LINK_DUMMY); + + /* Do not automatically start the iface */ + net_if_flag_set(iface, NET_IF_NO_AUTO_START); +} + +/* Mandatory stub for NET_DEVICE_INIT */ +static int test_iface_netdev_init(const struct device *dev) +{ + return 0; +} + +/* This is needed specifically for IPv6 DAD. + * DAD tries to send a packet, and the test will hang if send is not implemented. + */ +static int test_iface_send(const struct device *dev, struct net_pkt *pkt) +{ + return 0; +} + +static struct dummy_api test_iface_api = { + .iface_api.init = test_iface_init, + .send = test_iface_send, +}; + +static struct ethernet_api dummy_eth_api = { + .iface_api.init = test_iface_init, +}; + +NET_DEVICE_INIT(test_if_simple_a, + "test_if_simple_a", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); + +NET_DEVICE_INIT(test_if_simple_b, + "test_if_simple_b", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); + +NET_DEVICE_INIT(test_if_connected_a, + "test_if_connected_a", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); + +NET_DEVICE_INIT(test_if_connected_b, + "test_if_connected_b", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, + &test_iface_api, + DUMMY_L2, + NET_L2_GET_CTX_TYPE(DUMMY_L2), + 127); + +/* A dummy ETHERNET_L2 iface so that we can test L2 ignore. + * This iface is not properly defined, do not attempt to use it. + */ +NET_DEVICE_INIT(test_if_dummy_eth, + "test_if_dummy_eth", + test_iface_netdev_init, + NULL, + NULL, + NULL, + CONFIG_ETH_INIT_PRIORITY, + &dummy_eth_api, + ETHERNET_L2, + NET_L2_GET_CTX_TYPE(ETHERNET_L2), + 127); + + +static void test_conn_api_init(struct conn_mgr_conn_binding *const binding) +{ + /* Mark the iface dormant (disconnected) on initialization */ + net_if_dormant_on(binding->iface); +} + +static int test_conn_api_connect(struct conn_mgr_conn_binding *const binding) +{ + /* Mark iface as connected */ + net_if_dormant_off(binding->iface); + return 0; +} + +static int test_conn_api_disconnect(struct conn_mgr_conn_binding *const binding) +{ + /* Mark iface as dormant (disconnected) */ + net_if_dormant_on(binding->iface); + return 0; +} + +static struct conn_mgr_conn_api test_conn_api = { + .init = test_conn_api_init, + .connect = test_conn_api_connect, + .disconnect = test_conn_api_disconnect, +}; + +/* Dummy struct */ +struct test_conn_data { +}; + +#define TEST_CONN_IMPL_CTX_TYPE struct test_conn_data +CONN_MGR_CONN_DEFINE(TEST_CONN_IMPL, &test_conn_api); + +/* Bind connectivity implementation to ifaces */ +CONN_MGR_BIND_CONN(test_if_connected_a, TEST_CONN_IMPL); +CONN_MGR_BIND_CONN(test_if_connected_b, TEST_CONN_IMPL); + + +struct net_if *if_simp_a = NET_IF_GET(test_if_simple_a, 0); +struct net_if *if_simp_b = NET_IF_GET(test_if_simple_b, 0); +struct net_if *if_conn_a = NET_IF_GET(test_if_connected_a, 0); +struct net_if *if_conn_b = NET_IF_GET(test_if_connected_b, 0); +struct net_if *if_dummy_eth = NET_IF_GET(test_if_dummy_eth, 0); diff --git a/tests/net/conn_mgr/src/test_ifaces.h b/tests/net/conn_mgr/src/test_ifaces.h new file mode 100644 index 000000000000..a7aabaa95e9a --- /dev/null +++ b/tests/net/conn_mgr/src/test_ifaces.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_TEST_IFACES_H_ +#define ZEPHYR_INCLUDE_TEST_IFACES_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Public accessors for static iface structs */ +extern struct net_if *if_simp_a; +extern struct net_if *if_simp_b; +extern struct net_if *if_conn_a; +extern struct net_if *if_conn_b; +extern struct net_if *if_dummy_eth; + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_TEST_IFACES_H_ */ diff --git a/tests/net/conn_mgr/testcase.yaml b/tests/net/conn_mgr/testcase.yaml new file mode 100644 index 000000000000..64ce1efacec0 --- /dev/null +++ b/tests/net/conn_mgr/testcase.yaml @@ -0,0 +1,11 @@ +common: + min_ram: 16 + depends_on: netif + tags: net iface +tests: + net.conn_mgr_nodad: + extra_configs: + - CONFIG_NET_IPV6_DAD=n + net.conn_mgr_dad: + extra_configs: + - CONFIG_NET_IPV6_DAD=y From d19310968bf7c435fc12b52b1db84117f009e5d2 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Fri, 28 Apr 2023 14:38:23 -0700 Subject: [PATCH 079/528] [nrf fromlist] net: conn_mgr: Minor fixes Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57399 - Add missing event sleep after taking all ifaces up in test_connect_disconnect. - Add missing event sleep after resetting ifaces in conn_mgr_conn_before - Fix typo in comment for internal state flags. - Add missing NET_MGMT_EVENT_BIT to conn_mgr_connectivity event definitions. - Missing net_mgmt.h include in conn_mgr_connectivity.h - Split conn_mgr_conn iface reset into network and state resets, before and after event sleep, so that triggered events do not corrupt the state reset. - Reduce SIMULATED_EVENT_DELAY to 100ms to avoid timeouts on real-time targets. - Use macro for simulated event wait times. Signed-off-by: Georges Oates_Larsen (cherry picked from commit 0042591ba99cd6afbd7618262772673d80940e36) --- include/zephyr/net/conn_mgr_connectivity.h | 4 +- subsys/net/conn_mgr/conn_mgr_private.h | 2 +- tests/net/conn_mgr_conn/src/main.c | 42 +++++++++++++++----- tests/net/conn_mgr_conn/src/test_conn_impl.c | 2 +- tests/net/conn_mgr_conn/src/test_conn_impl.h | 4 +- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index cad0bdfb4d56..0b54224c448e 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -15,6 +15,7 @@ #include #include +#include #ifdef __cplusplus extern "C" { @@ -33,7 +34,8 @@ extern "C" { /* Connectivity Events */ #define _NET_MGMT_CONN_LAYER NET_MGMT_LAYER(NET_MGMT_LAYER_L2) #define _NET_MGMT_CONN_CODE NET_MGMT_LAYER_CODE(0x207) -#define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE) +#define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE | \ + NET_MGMT_EVENT_BIT) #define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_BASE) enum net_event_ethernet_cmd { diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index b21e61bf0aa6..76dcd0c7f639 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -26,7 +26,7 @@ /* Configuration flags */ #define CONN_MGR_IF_IGNORED BIT(7) -/* Internal state flags*/ +/* Internal state flags */ #define CONN_MGR_IF_READY BIT(14) /* Event flags */ diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index dbe1d4cb3374..373dcdd04265 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -29,7 +29,12 @@ static inline struct test_conn_data *conn_mgr_if_get_data(struct net_if *iface) return binding->ctx; } -static void reset_test_iface(struct net_if *iface) +/** + * @brief Reset the network state of the provided iface. + * + * @param iface - iface to reset. + */ +static void reset_test_iface_networking(struct net_if *iface) { if (net_if_is_admin_up(iface)) { (void)net_if_down(iface); @@ -37,7 +42,15 @@ static void reset_test_iface(struct net_if *iface) /* Some tests can leave the iface in a bad state where it is admin-down but not dormant */ net_if_dormant_on(iface); +} +/** + * @brief Reset testing state for the provided iface. + * + * @param iface - iface to reset. + */ +static void reset_test_iface_state(struct net_if *iface) +{ struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface); struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); @@ -98,12 +111,22 @@ static void conn_mgr_conn_handler(struct net_mgmt_event_callback *cb, static void conn_mgr_conn_before(void *data) { ARG_UNUSED(data); - reset_test_iface(ifa1); - reset_test_iface(ifa2); - reset_test_iface(ifb); - reset_test_iface(ifni); - reset_test_iface(ifnone); - reset_test_iface(ifnull); + reset_test_iface_networking(ifa1); + reset_test_iface_networking(ifa2); + reset_test_iface_networking(ifb); + reset_test_iface_networking(ifni); + reset_test_iface_networking(ifnone); + reset_test_iface_networking(ifnull); + + /* Allow any triggered events to shake out */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + + reset_test_iface_state(ifa1); + reset_test_iface_state(ifa2); + reset_test_iface_state(ifb); + reset_test_iface_state(ifni); + reset_test_iface_state(ifnone); + reset_test_iface_state(ifnull); k_mutex_lock(&event_mutex, K_FOREVER); @@ -171,6 +194,7 @@ ZTEST(conn_mgr_conn, test_connect_disconnect) zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); zassert_equal(net_if_up(ifa2), 0, "net_if_up should not fail"); zassert_equal(net_if_up(ifb), 0, "net_if_up should not fail"); + k_sleep(K_MSEC(1)); /* Verify ifaces are still disconnected */ zassert_false(net_if_is_up(ifa1), "Ifaces must be disconnected before test"); @@ -526,7 +550,7 @@ ZTEST(conn_mgr_conn, test_connect_timeout) zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); /* Ensure timeout event is fired */ - k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); + k_sleep(SIMULATED_EVENT_WAIT_TIME); k_mutex_lock(&event_mutex, K_FOREVER); stats = test_event_stats; @@ -557,7 +581,7 @@ ZTEST(conn_mgr_conn, test_connect_fatal_error) zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); /* Ensure fatal_error event is fired */ - k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); + k_sleep(SIMULATED_EVENT_WAIT_TIME); k_mutex_lock(&event_mutex, K_FOREVER); stats = test_event_stats; diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c index 8d2395160590..c6e4cff6a2d0 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -57,7 +57,7 @@ static void simulate_event(struct net_if *target, int event) simulated_event = event; simulated_event_iface = target; - k_work_reschedule(&simulate_event_work, K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS)); + k_work_reschedule(&simulate_event_work, SIMULATED_EVENT_DELAY_TIME); k_mutex_unlock(&simulated_event_mutex); } diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h index 6408bb802cfc..1df7e6d02011 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -76,7 +76,9 @@ CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_N); #define TEST_L2_CONN_IMPL_NI_CTX_TYPE struct test_conn_data CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); -#define SIMULATED_EVENT_DELAY_SECONDS 5 +#define SIMULATED_EVENT_DELAY_MS 100 +#define SIMULATED_EVENT_DELAY_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS) +#define SIMULATED_EVENT_WAIT_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS + 10) #ifdef __cplusplus } From 4e087cc2e96ed230ab4f0442757097b6b69e0d7f Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Wed, 26 Apr 2023 13:58:47 -0700 Subject: [PATCH 080/528] [nrf fromlist] net: conn_mgr: Support Auto-Connect Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57399 To reduce the need for boilerplate in application code, conn_mgr now supports an auto-connect feature on all ifaces with connectivity bindings. conn_mgr will automatically call conn_mgr_if_connect on any iface with a connectivity binding that enters the admin-up state, unless the newly added CONN_MGR_IF_NO_AUTO_CONNECT flag has been set for that iface. Also adjust automated tests to account for and take advantage of this behavior. Signed-off-by: Georges Oates_Larsen (cherry picked from commit b6552ec1f947591e6761bc0adba1963fc4c30f2f) --- include/zephyr/net/conn_mgr_connectivity.h | 6 ++ subsys/net/conn_mgr/conn_mgr_connectivity.c | 62 ++++++++++++++++++++ subsys/net/conn_mgr/conn_mgr_private.h | 2 + tests/net/conn_mgr/src/main.c | 41 ------------- tests/net/conn_mgr_conn/src/main.c | 64 ++++++++++++++++++++- 5 files changed, 133 insertions(+), 42 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 0b54224c448e..52e116d38572 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -179,6 +179,12 @@ enum conn_mgr_if_flag { */ CONN_MGR_IF_PERSISTENT, + /* No auto-connect + * When set, conn_mgr will not automatically attempt to connect this iface when it reaches + * admin-up. + */ + CONN_MGR_IF_NO_AUTO_CONNECT, + /** @cond INTERNAL_HIDDEN */ /* Total number of flags - must be at the end of the enum */ CONN_MGR_NUM_IF_FLAGS, diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index 2cc075074fbd..fc4f628a8f76 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -233,8 +233,52 @@ int conn_mgr_if_set_timeout(struct net_if *iface, int timeout) return 0; } +/* Automated behavior handling */ + +/** + * @brief Perform automated behaviors in response to ifaces going admin-up. + * + * @param iface - The iface which became admin-up. + */ +static void conn_mgr_conn_handle_iface_admin_up(struct net_if *iface) +{ + int err; + + /* Ignore ifaces that don't have connectivity implementations */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + /* Ignore ifaces for which auto-connect is disabled */ + if (conn_mgr_if_get_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT)) { + return; + } + + /* Otherwise, automatically instruct the iface to connect */ + err = conn_mgr_if_connect(iface); + if (err < 0) { + NET_ERR("iface auto-connect failed: %d", err); + } +} + +static struct net_mgmt_event_callback conn_mgr_conn_iface_cb; +static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, + struct net_if *iface) +{ + if ((mgmt_event & CONN_MGR_CONN_IFACE_EVENTS_MASK) != mgmt_event) { + return; + } + + switch (NET_MGMT_GET_COMMAND(mgmt_event)) { + case NET_EVENT_IF_CMD_ADMIN_UP: + conn_mgr_conn_handle_iface_admin_up(iface); + break; + } +} + void conn_mgr_conn_init(void) { + /* Initialize connectivity bindings. */ STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { if (!(binding->impl->api)) { LOG_ERR("Connectivity implementation has NULL API, and will be treated as " @@ -253,4 +297,22 @@ void conn_mgr_conn_init(void) k_mutex_unlock(binding->mutex); } } + + /* Set up event listeners for automated behaviors */ + net_mgmt_init_event_callback(&conn_mgr_conn_iface_cb, conn_mgr_conn_iface_handler, + CONN_MGR_CONN_IFACE_EVENTS_MASK); + net_mgmt_add_event_callback(&conn_mgr_conn_iface_cb); + + /* Trigger any initial automated behaviors for ifaces */ + STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { + if (binding->impl->api) { + /* We need to fire conn_mgr_conn_handle_iface_admin_up for any + * (connectivity-enabled) ifaces that went admin-up before we registerred + * the event callback that typically handles this. + */ + if (net_if_is_admin_up(binding->iface)) { + conn_mgr_conn_handle_iface_admin_up(binding->iface); + } + } + } } diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 76dcd0c7f639..18f5c7da73fa 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -36,6 +36,8 @@ #define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ NET_EVENT_IF_UP) +#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP) + #define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ NET_EVENT_IPV6_ADDR_DEL | \ NET_EVENT_IPV6_DAD_SUCCEED | \ diff --git a/tests/net/conn_mgr/src/main.c b/tests/net/conn_mgr/src/main.c index f5399b92e743..5b7584ab4173 100644 --- a/tests/net/conn_mgr/src/main.c +++ b/tests/net/conn_mgr/src/main.c @@ -186,10 +186,6 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -202,10 +198,6 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -266,10 +258,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -292,10 +280,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -308,10 +292,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -353,10 +333,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -366,10 +342,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -408,10 +380,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect connectivity lost */ @@ -481,11 +449,6 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* Take iface up */ zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_connect(iface), 0, - "conn_mgr_if_connect should succeed."); - } - /* Verify that no events have been fired yet */ k_sleep(EVENT_WAIT_TIME); stats = get_reset_stats(); @@ -643,10 +606,6 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* Take iface up */ zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_connect(iface), 0, - "conn_mgr_if_connect should succeed."); - } /* Verify events are fired */ k_sleep(EVENT_WAIT_TIME); diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index 373dcdd04265..fbb88d7732d1 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -55,8 +55,12 @@ static void reset_test_iface_state(struct net_if *iface) struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); if (iface_binding) { + /* Reset all flags and settings for the binding */ iface_binding->flags = 0; iface_binding->timeout = CONN_MGR_IF_NO_TIMEOUT; + + /* Disable auto-connect */ + conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT, true); } if (iface_data) { @@ -761,6 +765,9 @@ ZTEST(conn_mgr_conn, test_flags) { struct conn_mgr_conn_binding *ifa1_binding = conn_mgr_if_get_binding(ifa1); + /* Firstly, clear all flags (some are automatically enabled before each test) */ + ifa1_binding->flags = 0; + /* Try setting persistence flag */ zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true), 0, "Setting persistence flag should succeed for ifa1"); @@ -773,6 +780,19 @@ ZTEST(conn_mgr_conn, test_flags) zassert_equal(ifa1_binding->flags, BIT(CONN_MGR_IF_PERSISTENT), "Persistence flag set should affect conn struct"); + /* Try setting no-autoconnect flag */ + zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, true), 0, + "Setting no-autoconnect flag should succeed for ifa1"); + + /* Verify success */ + zassert_true(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT), + "No-autoconnect should be set for ifa1"); + + /* Verify that the conn struct agrees, since this is what implementations may use */ + zassert_equal(ifa1_binding->flags, + BIT(CONN_MGR_IF_PERSISTENT) | BIT(CONN_MGR_IF_NO_AUTO_CONNECT), + "Persistence flag set should affect conn struct"); + /* Try unsetting persistence flag */ zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false), 0, "Unsetting persistence flag should succeed for ifa1"); @@ -782,8 +802,20 @@ ZTEST(conn_mgr_conn, test_flags) "Persistence should be unset for ifa1"); /* Verify that the conn struct agrees, since this is what implementations may use */ - zassert_equal(ifa1_binding->flags, 0, + zassert_equal(ifa1_binding->flags, BIT(CONN_MGR_IF_NO_AUTO_CONNECT), "Persistence flag unset should affect conn struct"); + + /* Try unsetting no-autoconnect flag */ + zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false), 0, + "Clearing no-autoconnect flag should succeed for ifa1"); + + /* Verify success */ + zassert_false(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT), + "No-autoconnect should be set for ifa1"); + + /* Verify that the conn struct agrees, since this is what implementations may use */ + zassert_equal(ifa1_binding->flags, 0, + "No-autoconnect flag set should affect conn struct"); } /* Verify that flag get/set fail and behave as expected respectively for invalid ifaces and @@ -857,4 +889,34 @@ ZTEST(conn_mgr_conn, test_timeout_invalid) "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnone"); } +/* Verify that auto-connect works as expected. */ +ZTEST(conn_mgr_conn, test_auto_connect) +{ + /* Disable auto-connect. + * Not strictly necessary, since this is the default for this suite, but do it anyways + * since this test case specifically focuses on auto-connect. + */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, true); + + /* Take the iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail."); + + /* Verify no connection */ + k_sleep(K_MSEC(1)); + zassert_false(net_if_is_up(ifa1), "Auto-connect should not trigger if disabled."); + + /* Take the iface down */ + zassert_equal(net_if_down(ifa1), 0, "net_if_down should not fail."); + + /* Enable auto-connect */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Take the iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail."); + + /* Verify connection */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Auto-connect should succeed if enabled."); +} + ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); From 91b6eaa73b67b3cc0bcdd86e4870513202f04aef Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Wed, 26 Apr 2023 16:30:23 -0700 Subject: [PATCH 081/528] [nrf fromlist] net: conn_mgr: Support Auto-Down Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57399 To reduce the amount of boiler-plate needed in applications, this commit grants conn_mgr the ability to automatically take ifaces that have given up on connecting into the admin-down state. Tests adjusted as appropriate. This behavior can be disabled globally by disabling NET_CONNECTION_MANAGER_AUTO_IF_DOWN, or disabled per-iface using the CONN_MGR_IF_NO_AUTO_DOWN flag. Signed-off-by: Georges Oates_Larsen (cherry picked from commit 9ec9dc75580674460f8fbe4f92e2108965c469c2) --- include/zephyr/net/conn_mgr_connectivity.h | 8 + subsys/net/conn_mgr/Kconfig | 4 + subsys/net/conn_mgr/conn_mgr_connectivity.c | 94 ++++++++ subsys/net/conn_mgr/conn_mgr_private.h | 6 +- tests/net/conn_mgr/src/main.c | 43 ---- tests/net/conn_mgr_conn/src/main.c | 223 ++++++++++++++++++- tests/net/conn_mgr_conn/src/test_conn_impl.c | 7 +- tests/net/conn_mgr_conn/src/test_conn_impl.h | 19 ++ 8 files changed, 358 insertions(+), 46 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 52e116d38572..a48b84473ce5 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -185,6 +185,12 @@ enum conn_mgr_if_flag { */ CONN_MGR_IF_NO_AUTO_CONNECT, + /* No auto-down + * When set, conn_mgr will not automatically take the iface admin-down when it stops + * trying to connect, even if NET_CONNECTION_MANAGER_AUTO_IF_DOWN is enabled. + */ + CONN_MGR_IF_NO_AUTO_DOWN, + /** @cond INTERNAL_HIDDEN */ /* Total number of flags - must be at the end of the enum */ CONN_MGR_NUM_IF_FLAGS, @@ -271,6 +277,8 @@ struct conn_mgr_conn_binding { * * Non-Blocking. * + * TODO: Talk about persistence and timeouts in this PR for docs. + * * @param iface Pointer to network interface * @retval 0 on success. * @retval -ESHUTDOWN if the iface is not admin-up. diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig index 5c742fb852f5..1c9a09104e9c 100644 --- a/subsys/net/conn_mgr/Kconfig +++ b/subsys/net/conn_mgr/Kconfig @@ -36,4 +36,8 @@ config NET_CONNECTION_MANAGER_PRIORITY help This sets the starting priority of the connection manager thread. +config NET_CONNECTION_MANAGER_AUTO_IF_DOWN + bool "Automatically take ifaces admin-down if they have stopped trying to connect" + default y + endif # NET_CONNECTION_MANAGER diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index fc4f628a8f76..7e8629de9752 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -46,6 +46,8 @@ int conn_mgr_if_connect(struct net_if *iface) return status; } +static void conn_mgr_conn_handle_iface_hard_down(struct net_if *iface); + int conn_mgr_if_disconnect(struct net_if *iface) { struct conn_mgr_conn_binding *binding; @@ -75,6 +77,11 @@ int conn_mgr_if_disconnect(struct net_if *iface) out: k_mutex_unlock(binding->mutex); + /* Inform conn_mgr that this is a hard-down scenario, since it won't know from the + * if_down event alone. + */ + conn_mgr_conn_handle_iface_hard_down(iface); + return status; } @@ -261,6 +268,59 @@ static void conn_mgr_conn_handle_iface_admin_up(struct net_if *iface) } } +/** + * @brief Perform automated behaviors in response to any iface that loses + * connection and does not expect to regain it (referred to, here, as hard-down). + * + * This is how conn_mgr_conn automatically takes such ifaces admin-down. + * + * @param iface - The iface which experienced hard-down. + */ +static void conn_mgr_conn_handle_iface_hard_down(struct net_if *iface) +{ + /* NOTE: This will be double-fired for ifaces that are both non-persistent + * and are being directly requested to disconnect, since both of these conditions + * separately trigger conn_mgr_conn_handle_iface_hard_down. + * + * This is fine, because net_if_down is idempotent, but if you are adding other + * behaviors to this function, bear it in mind. + */ + + /* Ignore ifaces that don't have connectivity implementations */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + /* Take the iface admin-down if AUTO_DOWN is enabled */ + if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN) && + !conn_mgr_if_get_flag(iface, CONN_MGR_IF_NO_AUTO_DOWN)) { + net_if_down(iface); + } +} + +/** + * @brief Perform automated behaviors in response to any iface that loses oper-up state. + * + * This is how conn_mgr_conn automatically takes such ifaces admin-down if they are not persistent. + * + * @param iface - The iface which lost oper-up state. + */ +static void conn_mgr_conn_handle_iface_down(struct net_if *iface) +{ + /* Ignore ifaces that don't have connectivity implementations */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + /* If the iface is persistent, do not treat any disconnect as hard-down */ + if (conn_mgr_if_get_flag(iface, CONN_MGR_IF_PERSISTENT)) { + return; + } + + /* Otherwise, treat as a hard-down */ + conn_mgr_conn_handle_iface_hard_down(iface); +} + static struct net_mgmt_event_callback conn_mgr_conn_iface_cb; static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) @@ -270,12 +330,42 @@ static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint } switch (NET_MGMT_GET_COMMAND(mgmt_event)) { + case NET_EVENT_IF_CMD_DOWN: + conn_mgr_conn_handle_iface_down(iface); + break; case NET_EVENT_IF_CMD_ADMIN_UP: conn_mgr_conn_handle_iface_admin_up(iface); break; } } +static struct net_mgmt_event_callback conn_mgr_conn_self_cb; +static void conn_mgr_conn_self_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, + struct net_if *iface) +{ + if ((mgmt_event & CONN_MGR_CONN_SELF_EVENTS_MASK) != mgmt_event) { + return; + } + + switch (NET_MGMT_GET_COMMAND(mgmt_event)) { + case NET_EVENT_CONN_CMD_IF_FATAL_ERROR: + if (cb->info) { + NET_ERR("Fatal connectivity error on iface %d (%p). Reason: %d.", + net_if_get_by_iface(iface), iface, *((int *)cb->info) + ); + } else { + NET_ERR("Unknown fatal connectivity error on iface %d (%p).", + net_if_get_by_iface(iface), iface + ); + } + __fallthrough; + case NET_EVENT_CONN_CMD_IF_TIMEOUT: + conn_mgr_conn_handle_iface_hard_down(iface); + break; + } + +} + void conn_mgr_conn_init(void) { /* Initialize connectivity bindings. */ @@ -303,6 +393,10 @@ void conn_mgr_conn_init(void) CONN_MGR_CONN_IFACE_EVENTS_MASK); net_mgmt_add_event_callback(&conn_mgr_conn_iface_cb); + net_mgmt_init_event_callback(&conn_mgr_conn_self_cb, conn_mgr_conn_self_handler, + CONN_MGR_CONN_SELF_EVENTS_MASK); + net_mgmt_add_event_callback(&conn_mgr_conn_self_cb); + /* Trigger any initial automated behaviors for ifaces */ STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { if (binding->impl->api) { diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 18f5c7da73fa..0290f3d2b5a2 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -36,7 +36,11 @@ #define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ NET_EVENT_IF_UP) -#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP) +#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP |\ + NET_EVENT_IF_DOWN) + +#define CONN_MGR_CONN_SELF_EVENTS_MASK (NET_EVENT_CONN_IF_TIMEOUT | \ + NET_EVENT_CONN_IF_FATAL_ERROR) #define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ NET_EVENT_IPV6_ADDR_DEL | \ diff --git a/tests/net/conn_mgr/src/main.c b/tests/net/conn_mgr/src/main.c index 5b7584ab4173..a7680ff05878 100644 --- a/tests/net/conn_mgr/src/main.c +++ b/tests/net/conn_mgr/src/main.c @@ -44,9 +44,6 @@ static void reset_test_iface(struct net_if *iface) struct in6_addr *ll_ipv6; if (net_if_is_admin_up(iface)) { - if (conn_mgr_if_is_bound(iface)) { - (void)conn_mgr_if_disconnect(iface); - } (void)net_if_down(iface); } @@ -206,10 +203,6 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect no events */ @@ -219,10 +212,6 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect connectivity loss */ @@ -266,10 +255,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -300,10 +285,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifba."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -313,10 +294,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect connectivity lost */ @@ -353,10 +330,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -368,10 +341,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -392,10 +361,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) zassert_equal(stats.dconn_iface, ifa, "ifa should be blamed."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -566,10 +531,6 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* (10 -> 00): Lose oper-up from semi-ready state */ /* Take iface down */ - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_disconnect(iface), 0, - "conn_mgr_if_disconnect should succeed."); - } zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); /* Verify there are no events fired */ @@ -619,10 +580,6 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* (11 -> 01): Lose oper-up from ready state */ /* Take iface down */ - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_disconnect(iface), 0, - "conn_mgr_if_disconnect should succeed."); - } zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); /* Verify events are fired */ diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index fbb88d7732d1..e7154329d5a8 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -59,8 +59,9 @@ static void reset_test_iface_state(struct net_if *iface) iface_binding->flags = 0; iface_binding->timeout = CONN_MGR_IF_NO_TIMEOUT; - /* Disable auto-connect */ + /* Disable auto-connect and auto-down */ conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT, true); + conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_DOWN, true); } if (iface_data) { @@ -919,4 +920,224 @@ ZTEST(conn_mgr_conn, test_auto_connect) zassert_true(net_if_is_up(ifa1), "Auto-connect should succeed if enabled."); } +/* Verify that if auto-down is enabled, disconnecting an iface also takes it down, + * regardless of whether persistence is enabled, but only if auto-down is disabled. + */ +ZTEST(conn_mgr_conn, test_auto_down_disconnect) +{ + /* For convenience, use auto-connect for this test. */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Enable auto-down, disable persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Disconnect iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, + "conn_mgr_if_disconnect should succeed."); + + /* Verify down */ + k_sleep(K_MSEC(1)); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on direct disconnect."); + + + + /* Enable persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Disconnect iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, + "conn_mgr_if_disconnect should succeed."); + + /* Verify down */ + k_sleep(K_MSEC(1)); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on direct disconnect, even if persistence is enabled."); + + + + /* Disable auto-down */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Disconnect iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, + "conn_mgr_if_disconnect should succeed."); + + /* Verify up */ + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger if it is disabled."); +} + +/* Verify that auto-down takes an iface down if connection is lost, but only if persistence is not + * enabled, and only if auto-down is enabled. + */ +ZTEST(conn_mgr_conn, test_auto_down_conn_loss) +{ + /* For convenience, use auto-connect for this test. */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Enable auto-down, disable persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Simulate connection loss */ + simulate_connection_loss(ifa1); + + /* Verify down */ + k_sleep(K_MSEC(1)); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on connection loss if persistence is disabled."); + + /* Enable persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Simulate connection loss */ + simulate_connection_loss(ifa1); + + /* Verify up */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger on connection loss if persistence is enabled."); + + /* Disable persistence and disable auto-down*/ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); + + /* Reconnect iface */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Simulate connection loss */ + simulate_connection_loss(ifa1); + + /* Verify up */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger on connection loss if it is disabled."); +} + +/* Verify that timeout takes the iface down, even if + * persistence is enabled, but only if auto-down is enabled. + */ +ZTEST(conn_mgr_conn, test_auto_down_timeout) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* For convenience, use auto-connect for this test. */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Enable auto-down and persistence*/ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); + + /* Schedule timeout */ + ifa1_data->timeout = true; + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify iface down after timeout */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on connection timeout, even if persistence is enabled."); + + /* Disable auto-down */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); + + /* Take iface up (timing out again) */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify iface up after timeout */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger on connection timeout if it is disabled."); +} + + +/* Verify that fatal error takes the iface down, even if + * persistence is enabled, but only if auto-down is enabled. + */ +ZTEST(conn_mgr_conn, test_auto_down_fatal) +{ + /* For convenience, use auto-connect for this test. */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Enable auto-down and persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Raise fatal error */ + simulate_fatal_error(ifa1, -EAGAIN); + + /* Verify iface down after fatal error */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on fatal error, even if persistence is enabled."); + + /* Disable auto-down */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Raise fatal error */ + simulate_fatal_error(ifa1, -EAGAIN); + + /* Verify iface still up after fatal error */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger on fatal error if it is disabled."); +} + + ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c index c6e4cff6a2d0..a0f2de45c545 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -67,11 +67,16 @@ static void simulate_timeout(struct net_if *target) simulate_event(target, 0); } -static void simulate_fatal_error(struct net_if *target, int reason) +void simulate_fatal_error(struct net_if *target, int reason) { simulate_event(target, reason); } +void simulate_connection_loss(struct net_if *target) +{ + net_if_dormant_on(target); +} + /* Connectivity implementations */ static void inc_call_count(struct test_conn_data *data, bool a) diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h index 1df7e6d02011..bab0c9b3aa9a 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -80,6 +80,25 @@ CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); #define SIMULATED_EVENT_DELAY_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS) #define SIMULATED_EVENT_WAIT_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS + 10) +/* Helper API for controlling implementations from tests */ + +/** + * @brief Simulate a connection loss on the target iface. + * + * @param target - iface to simulate connection loss on. + */ +void simulate_connection_loss(struct net_if *target); + +/** + * @brief Simulate a fatal error on the target iface + * + * Please do not simulate events on more than one iface at a time. + * + * @param target - iface to simulate fatal error on. + * @param reason - Reason to be given for the fatal error. + */ +void simulate_fatal_error(struct net_if *target, int reason); + #ifdef __cplusplus } #endif From 518e45afefd835f88bc6e5137ddf82e136a9fc01 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 2 May 2023 16:46:30 -0700 Subject: [PATCH 082/528] [nrf fromlist] net: conn_mgr: Bulk convenience functions Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57399 To further reduce the need for networking boilerplate in applications, provide bulk versions of net_if_up, net_if_down, conn_mgr_if_connect, and conn_mgr_if_disconnect that affect all available / eligible ifaces at once. Since it is not intuitive whether these functions should affect ifaces which conn_mgr is ignoring, these functions take an argument that allows this to be specified by the application. Signed-off-by: Georges Oates_Larsen (cherry picked from commit f90241c7660f821181404b9adcdf2fab3c6b5760) --- include/zephyr/net/conn_mgr_connectivity.h | 51 +++ subsys/net/conn_mgr/conn_mgr_connectivity.c | 142 +++++++ tests/net/conn_mgr_conn/prj.conf | 4 + tests/net/conn_mgr_conn/src/main.c | 439 ++++++++++++++++++++ 4 files changed, 636 insertions(+) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index a48b84473ce5..f39a47b0f785 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -424,6 +424,57 @@ int conn_mgr_if_set_timeout(struct net_if *iface, int timeout); */ void conn_mgr_conn_init(void); +/** + * @brief Convenience function that takes all available ifaces into the admin-up state. + * + * Essentially a wrapper for net_if_up. + * + * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. + * Otherwise, affect all ifaces. + * @return 0 if all net_if_up calls returned 0, otherwise the first nonzero value + * returned by a net_if_up call. + */ +int conn_mgr_all_if_up(bool skip_ignored); + + +/** + * @brief Convenience function that takes all available ifaces into the admin-down state. + * + * Essentially a wrapper for net_if_down. + * + * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. + * Otherwise, affect all ifaces. + * @return 0 if all net_if_down calls returned 0, otherwise the first nonzero value + * returned by a net_if_down call. + */ +int conn_mgr_all_if_down(bool skip_ignored); + +/** + * @brief Convenience function that takes all available ifaces into the admin-up state, and + * connects those that support connectivity. + * + * Essentially a wrapper for net_if_up and conn_mgr_if_connect. + * + * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. + * Otherwise, affect all ifaces. + * @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero + * value returned by either net_if_up or conn_mgr_if_connect. + */ +int conn_mgr_all_if_connect(bool skip_ignored); + +/** + * @brief Convenience function that disconnects all available ifaces that support connectivity + * without putting them into admin-down state (unless auto-down is enabled for the iface). + * + * Essentially a wrapper for net_if_down. + * + * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. + * Otherwise, affect all ifaces. + * @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero + * value returned by either net_if_up or conn_mgr_if_connect. + */ +int conn_mgr_all_if_disconnect(bool skip_ignored); + /** * @} */ diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index 7e8629de9752..f20bb9fcd5df 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -9,6 +9,7 @@ LOG_MODULE_REGISTER(conn_mgr_conn, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include +#include #include "conn_mgr_private.h" int conn_mgr_if_connect(struct net_if *iface) @@ -410,3 +411,144 @@ void conn_mgr_conn_init(void) } } } + +enum conn_mgr_conn_all_if_oper { + ALL_IF_UP, + ALL_IF_DOWN, + ALL_IF_CONNECT, + ALL_IF_DISCONNECT +}; + +struct conn_mgr_conn_all_if_ctx { + bool skip_ignored; + enum conn_mgr_conn_all_if_oper operation; + int status; +}; + +/* Per-iface callback for conn_mgr_conn_all_if_up */ +static void conn_mgr_conn_all_if_cb(struct net_if *iface, void *user_data) +{ + int status = 0; + struct conn_mgr_conn_all_if_ctx *context = (struct conn_mgr_conn_all_if_ctx *)user_data; + + /* Skip ignored ifaces if so desired */ + if (context->skip_ignored && conn_mgr_is_iface_ignored(iface)) { + return; + } + + /* Perform the requested operation */ + switch (context->operation) { + case ALL_IF_UP: + /* Do not take iface admin up if it already is. */ + if (net_if_is_admin_up(iface)) { + return; + } + + status = net_if_up(iface); + break; + case ALL_IF_DOWN: + /* Do not take iface admin down if it already is. */ + if (!net_if_is_admin_up(iface)) { + return; + } + + status = net_if_down(iface); + break; + case ALL_IF_CONNECT: + /* Connect operation only supported if iface is bound */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + status = conn_mgr_if_connect(iface); + break; + case ALL_IF_DISCONNECT: + /* Disconnect operation only supported if iface is bound */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + status = conn_mgr_if_disconnect(iface); + break; + } + + if (status == 0) { + return; + } + + if (context->status == 0) { + context->status = status; + } + + NET_ERR("%s failed for iface %d (%p). Error: %d", + context->operation == ALL_IF_UP ? "net_if_up" : + context->operation == ALL_IF_DOWN ? "net_if_down" : + context->operation == ALL_IF_CONNECT ? "conn_mgr_if_connect" : + context->operation == ALL_IF_DISCONNECT ? "conn_mgr_if_disconnect" : + "invalid", + net_if_get_by_iface(iface), iface, status + ); +} + +int conn_mgr_all_if_up(bool skip_ignored) +{ + struct conn_mgr_conn_all_if_ctx context = { + .operation = ALL_IF_UP, + .skip_ignored = skip_ignored, + .status = 0 + }; + + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + return context.status; +} + +int conn_mgr_all_if_down(bool skip_ignored) +{ + struct conn_mgr_conn_all_if_ctx context = { + .operation = ALL_IF_DOWN, + .skip_ignored = skip_ignored, + .status = 0 + }; + + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + return context.status; +} + +int conn_mgr_all_if_connect(bool skip_ignored) +{ + /* First, take all ifaces up. + * All bound ifaces will do this automatically when connect is called, but non-bound ifaces + * won't, so we must request it explicitly. + */ + struct conn_mgr_conn_all_if_ctx context = { + .operation = ALL_IF_UP, + .skip_ignored = skip_ignored, + .status = 0 + }; + + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + /* Now connect all ifaces. + * We are delibarately not resetting context.status between these two calls so that + * the first nonzero status code encountered between the two of them is what is returned. + */ + context.operation = ALL_IF_CONNECT; + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + return context.status; +} + +int conn_mgr_all_if_disconnect(bool skip_ignored) +{ + struct conn_mgr_conn_all_if_ctx context = { + .operation = ALL_IF_DISCONNECT, + .skip_ignored = skip_ignored, + .status = 0 + }; + + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + return context.status; +} diff --git a/tests/net/conn_mgr_conn/prj.conf b/tests/net/conn_mgr_conn/prj.conf index 5ffa0ba9d9fc..ec6b62f6be3f 100644 --- a/tests/net/conn_mgr_conn/prj.conf +++ b/tests/net/conn_mgr_conn/prj.conf @@ -24,3 +24,7 @@ CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=6 CONFIG_NET_IF_MAX_IPV6_COUNT=6 CONFIG_TEST_USERSPACE=y + +# Increased net event queue size needed since this test performs simultaneous events on a +# large number of ifaces. +CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=16 diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index e7154329d5a8..9942ba576659 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "conn_mgr_private.h" #include "test_conn_impl.h" #include "test_ifaces.h" @@ -54,6 +55,9 @@ static void reset_test_iface_state(struct net_if *iface) struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface); struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); + /* Some tests mark ifaces as ignored, this must be reset between each test. */ + conn_mgr_unignore_iface(iface); + if (iface_binding) { /* Reset all flags and settings for the binding */ iface_binding->flags = 0; @@ -1139,5 +1143,440 @@ ZTEST(conn_mgr_conn, test_auto_down_fatal) "Auto-down should not trigger on fatal error if it is disabled."); } +/* Verify that all_if_up brings all ifaces up, but only if they are not ignored or + * skip_ignored is false + */ +ZTEST(conn_mgr_conn, test_all_if_up) +{ + /* Ignore an iface */ + conn_mgr_ignore_iface(ifa1); + + /* Take all ifaces up (do not skip ignored) */ + zassert_equal(conn_mgr_all_if_up(false), 0, "conn_mgr_all_if_up should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + + /* Manually take all ifaces down */ + zassert_equal(net_if_down(ifa1), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifa2), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifni), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifnull), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifnone), 0, "net_if_down should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Take all ifaces up (skip ignored) */ + zassert_equal(conn_mgr_all_if_up(true), 0, "conn_mgr_all_if_up should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all except ignored are up */ + zassert_true(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All non-ignored ifaces should be admin-up."); + + zassert_false(net_if_is_admin_up(ifa1), "Ignored iface should not be admin-up."); +} + +/* Verify that all_if_connect brings all ifaces up, and connects all bound ifaces, but only those + * that are not ignored, or all of them if skip_ignored is false + */ +ZTEST(conn_mgr_conn, test_all_if_connect) +{ + /* Ignore a bound and an unbound iface */ + conn_mgr_ignore_iface(ifa1); + conn_mgr_ignore_iface(ifnone); + + /* Connect all ifaces (do not skip ignored) */ + zassert_equal(conn_mgr_all_if_connect(false), 0, "conn_mgr_all_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Verify bound ifaces are connected */ + zassert_true(net_if_is_up(ifa1), "All bound ifaces should be connected."); + zassert_true(net_if_is_up(ifa2), "All bound ifaces should be connected."); + zassert_true(net_if_is_up(ifb), "All bound ifaces should be connected."); + zassert_true(net_if_is_up(ifni), "All bound ifaces should be connected."); + + /* Manually take all ifaces down */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "net_if_disconnect should succeed."); + zassert_equal(conn_mgr_if_disconnect(ifa2), 0, "net_if_disconnect should succeed."); + zassert_equal(conn_mgr_if_disconnect(ifb), 0, "net_if_disconnect should succeed."); + zassert_equal(conn_mgr_if_disconnect(ifni), 0, "net_if_disconnect should succeed."); + + zassert_equal(net_if_down(ifa1), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifa2), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifni), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifnull), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifnone), 0, "net_if_down should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Connect all ifaces (skip ignored) */ + zassert_equal(conn_mgr_all_if_connect(true), 0, "conn_mgr_all_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all except ignored are up */ + zassert_true(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-up."); + + zassert_false(net_if_is_admin_up(ifa1), "All ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnone), "All ignored ifaces should be admin-down."); + + /* Verify bound ifaces are connected, except for ignored */ + zassert_true(net_if_is_up(ifa2), "All non-ignored bound ifaces should be connected."); + zassert_true(net_if_is_up(ifb), "All non-ignored bound ifaces should be connected."); + zassert_true(net_if_is_up(ifni), "All non-ignored bound ifaces should be connected."); + + zassert_false(net_if_is_up(ifa1), "Ignored iface should not be connected."); +} + +/* Verify that all_if_down takes all ifaces down, but only if they are not ignored, + * or skip_ignored is false + */ +ZTEST(conn_mgr_conn, test_all_if_down) +{ + /* Ignore an iface */ + conn_mgr_ignore_iface(ifa1); + + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Take all ifaces down (do not skip ignored) */ + zassert_equal(conn_mgr_all_if_down(false), 0, "conn_mgr_all_if_down should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are down */ + zassert_false(net_if_is_admin_up(ifa1), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifa2), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifb), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifni), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnull), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnone), "All ifaces should be admin-down."); + + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Take all ifaces down (skip ignored) */ + zassert_equal(conn_mgr_all_if_down(true), 0, "conn_mgr_all_if_down should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify that all except the ignored iface is down */ + zassert_false(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnone), "All non-ignored ifaces should be admin-down."); + + zassert_true(net_if_is_admin_up(ifa1), "Ignored iface should be admin-up."); +} + +/* Verify that all_if_disconnect disconnects all bound ifaces, but only if they are not ignored, + * or skip_ignored is false + */ +ZTEST(conn_mgr_conn, test_all_if_disconnect) +{ + /* Ignore a bound iface */ + conn_mgr_ignore_iface(ifa1); + + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Manually connect all bound ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Disconnect all ifaces (do not skip ignored) */ + zassert_equal(conn_mgr_all_if_disconnect(false), 0, + "conn_mgr_all_if_disconnect should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify that all bound ifaces are disconnected */ + zassert_false(net_if_is_up(ifa1), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifa2), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifb), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifni), "All bound ifaces should be disconnected."); + + /* Verify that all ifaces are still up, even if disconnected */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Manually reconnect bound ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Disconnect all ifaces (skip ignored) */ + zassert_equal(conn_mgr_all_if_disconnect(true), 0, + "conn_mgr_all_if_disconnect should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify that all bound ifaces are disconnected, except the ignored iface */ + zassert_false(net_if_is_up(ifa2), "All non-ignored bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifb), "All non-ignored bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifni), "All non-ignored bound ifaces should be disconnected."); + + zassert_true(net_if_is_up(ifa1), "Ignored iface should still be connected"); +} + + +/* Verify that double calls to all_if_up do not raise errors */ +ZTEST(conn_mgr_conn, test_all_if_up_double) +{ + /* Take all ifaces up twice in a row */ + zassert_equal(conn_mgr_all_if_up(false), 0, + "conn_mgr_all_if_up should succeed."); + zassert_equal(conn_mgr_all_if_up(false), 0, + "conn_mgr_all_if_up should succeed twice in a row."); + + /* One more time, after a delay, to be sure */ + k_sleep(K_MSEC(1)); + zassert_equal(conn_mgr_all_if_up(false), 0, + "conn_mgr_all_if_up should succeed twice in a row."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); +} + +/* Verify that double calls to all_if_down do not raise errors */ +ZTEST(conn_mgr_conn, test_all_if_down_double) +{ + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Take all ifaces down twice in a row */ + zassert_equal(conn_mgr_all_if_down(false), 0, + "conn_mgr_all_if_down should succeed."); + zassert_equal(conn_mgr_all_if_down(false), 0, + "conn_mgr_all_if_down should succeed twice in a row."); + + /* One more time, after a delay, to be sure */ + k_sleep(K_MSEC(1)); + zassert_equal(conn_mgr_all_if_down(false), 0, + "conn_mgr_all_if_down should succeed twice in a row."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are down */ + zassert_false(net_if_is_admin_up(ifa1), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifa2), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifb), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifni), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnull), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnone), "All ifaces should be admin-down."); +} + +/* Verify that double calls to all_if_connect do not raise errors */ +ZTEST(conn_mgr_conn, test_all_if_connect_double) +{ + /* Connect all ifaces twice in a row */ + zassert_equal(conn_mgr_all_if_connect(false), 0, + "conn_mgr_all_if_connect should succeed."); + zassert_equal(conn_mgr_all_if_connect(false), 0, + "conn_mgr_all_if_connect should succeed twice in a row."); + + /* One more time, after a delay, to be sure */ + k_sleep(K_MSEC(1)); + zassert_equal(conn_mgr_all_if_connect(false), 0, + "conn_mgr_all_if_connect should succeed twice in a row."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Verify all bound ifaces are connected */ +} + +/* Verify that double calls to all_if_disconnect do not raise errors */ +ZTEST(conn_mgr_conn, test_all_if_disconnect_double) +{ + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Manually connect all bound ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Connect all ifaces twice in a row */ + zassert_equal(conn_mgr_all_if_disconnect(false), 0, + "conn_mgr_all_if_disconnect should succeed."); + zassert_equal(conn_mgr_all_if_disconnect(false), 0, + "conn_mgr_all_if_disconnect should succeed twice in a row."); + + /* One more time, after a delay, to be sure */ + k_sleep(K_MSEC(1)); + zassert_equal(conn_mgr_all_if_disconnect(false), 0, + "conn_mgr_all_if_disconnect should succeed twice in a row."); + k_sleep(K_MSEC(1)); + + /* Verify all bound ifaces are disconnected */ + zassert_false(net_if_is_up(ifa1), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifa2), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifb), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifni), "All bound ifaces should be disconnected."); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); +} + + + +/* Testing error passing for all_if_up/all_if_down is not possible without using an L2 other than + * Dummy, since the dummy L2 is not capable of erroring in response to either of these. + * + * However, since all bulk convenience functions share a single implementation, testing + * connect and disconnect is sufficient to gain acceptable coverage of this behavior for all of + * them. + */ + +/* Verify that all_if_connect successfully forwards errors encountered on individual ifaces */ +ZTEST(conn_mgr_conn, test_all_if_connect_err) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Schedule a connect error on one of the ifaces */ + ifa1_data->api_err = -ECHILD; + + /* Verify that this error is passed to all_if_connect */ + zassert_equal(conn_mgr_all_if_connect(false), -ECHILD, + "conn_mgr_all_if_connect should fail with the requested error."); + k_sleep(K_MSEC(1)); + + /* Verify that all ifaces went admin-up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Verify that all the non-error ifaces are connected */ + zassert_true(net_if_is_up(ifa2), "All non-failing ifaces should be connected."); + zassert_true(net_if_is_up(ifb), "All non-failing ifaces should be connected."); + zassert_true(net_if_is_up(ifni), "All non-failing ifaces should be connected."); + + /* Verify that the error iface is not connected */ + zassert_false(net_if_is_up(ifa1), "The failing iface should not be connected."); +} + +/* Verify that all_if_disconnect successfully forwards errors encountered on individual ifaces */ +ZTEST(conn_mgr_conn, test_all_if_disconnect_err) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Manually connect all bound ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Schedule a disconnect error on one of the ifaces */ + ifa1_data->api_err = -ECHILD; + + /* Verify that this error is passed to all_if_disconnect */ + zassert_equal(conn_mgr_all_if_disconnect(false), -ECHILD, + "conn_mgr_all_if_disconnect should fail with the requested error."); + + /* Verify that all ifaces are still admin-up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Verify that all the non-error ifaces are disconnected */ + zassert_false(net_if_is_up(ifa2), "All non-failing ifaces should be disconnected."); + zassert_false(net_if_is_up(ifb), "All non-failing ifaces should be disconnected."); + zassert_false(net_if_is_up(ifni), "All non-failing ifaces should be disconnected."); + + /* Verify that the error iface is not connected */ + zassert_true(net_if_is_up(ifa1), "The failing iface should not be disconnected."); +} ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); From 977d57d98719280c1b27857d6f50aeb9b9fa8b09 Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Fri, 5 May 2023 14:36:09 +0200 Subject: [PATCH 083/528] [nrf fromtree] mcumgr: img_mgmt: Fix check for upgrade-only Change fixes check for upgrade-only to ensure that the the new image version is greater than version of the currently running image. Signed-off-by: Marek Pieta (cherry picked from ce18ed05d1a444de64c132d850a6caeac7108226) (cherry picked from commit c33111ae17d381bbd185827fbf082bb3a40ac3f1) --- subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index 81bdf56dc9e8..e4ea3b568f77 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -646,7 +646,7 @@ img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req, if (req->upgrade) { - /* User specified upgrade-only. Make sure new image version is + /* User specified upgrade-only. Make sure new image version is * greater than that of the currently running image. */ rc = img_mgmt_my_version(&cur_ver); @@ -654,7 +654,7 @@ img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req, return MGMT_ERR_EUNKNOWN; } - if (img_mgmt_vercmp(&cur_ver, &hdr->ih_ver) > 0) { + if (img_mgmt_vercmp(&cur_ver, &hdr->ih_ver) >= 0) { IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_downgrade); return MGMT_ERR_EBADSTATE; From 63516e45a77ada31e13aa961540f127a6fdf7d7d Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Fri, 5 May 2023 13:32:00 +0200 Subject: [PATCH 084/528] [nrf fromtree] mcumgr: img_mgmt: Let image version comparison use build number Change allows using build number in image version comparison. Signed-off-by: Marek Pieta (cherry picked from 8df81737e01ee5c519905d206c82699fd494e7ff) (cherry picked from commit 0e7cde7dd1f2ecf14393107aacd253834e31f843) --- subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig | 7 +++++++ subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 8 +++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig index 106a29006f41..ec7d17f43d17 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig @@ -94,6 +94,13 @@ config MCUMGR_GRP_IMG_FRUGAL_LIST a device but requires support in client software, which has to default omitted values. Works correctly with mcumgr-cli. +config MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER + bool "Use build number while comparing image version" + help + By default, the image version comparison relies only on version major, + minor and revision. Enable this option to take into account the build + number as well. + config MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK bool "Upload check hook" depends on MCUMGR_MGMT_NOTIFICATION_HOOKS diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index e4ea3b568f77..ccf02564d487 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -278,7 +278,13 @@ img_mgmt_vercmp(const struct image_version *a, const struct image_version *b) return 1; } - /* Note: For semver compatibility, don't compare the 32-bit build num. */ +#if defined(CONFIG_MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER) + if (a->iv_build_num < b->iv_build_num) { + return -1; + } else if (a->iv_build_num > b->iv_build_num) { + return 1; + } +#endif return 0; } From 36961d6b72f53b9ff0eef1e398f08da84dae5032 Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Fri, 5 May 2023 11:12:26 +0200 Subject: [PATCH 085/528] [nrf noup] mcumgr: img_mgmt: Fix check for chosen code partition The "zephyr-code-partition" chosen DTS node cannot be used when build uses Partition Manager. In that case, mcumgr must rely on the definitions provided by the Partition Manager. Jira: NCSDK-21381 Signed-off-by: Marek Pieta (cherry picked from commit 394faafd215eaa2405f58f6aa7793afcc62b6e99) --- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 73f96eaf8b58..c490b0ea5314 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -34,14 +34,34 @@ #include #endif +#if USE_PARTITION_MANAGER +#include + +#ifdef PM_MCUBOOT_SECONDARY_PAD_SIZE +BUILD_ASSERT(PM_MCUBOOT_PAD_SIZE == PM_MCUBOOT_SECONDARY_PAD_SIZE); +#endif + +#if CONFIG_BUILD_WITH_TFM + #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE + PM_TFM_SIZE) +#else + #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE) +#endif + +#define FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(label) \ + (FIXED_PARTITION_OFFSET(label) == (PM_ADDRESS - PM_ADDRESS_OFFSET)) + +#else /* ! USE_PARTITION_MANAGER */ + #define FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(label) \ DT_SAME_NODE(DT_NODELABEL(label), DT_CHOSEN(zephyr_code_partition)) +#endif /* USE_PARTITION_MANAGER */ + #if !(FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_partition) || \ FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_ns_partition) || \ FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot1_partition) || \ FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot2_partition)) -#error "Unsupported chosen zephyr,code-partition for boot application." +#error "Unsupported chosen code partition for boot application." #endif LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); From 59f4a55ce4279c95db0b67326ec4a82938095ac4 Mon Sep 17 00:00:00 2001 From: Lukasz Duda Date: Tue, 9 May 2023 22:36:56 +0200 Subject: [PATCH 086/528] [nrf fromlist] net: openthread: configure OPENTHREAD_CSL_TIMEOUT Added the possibility to set the default OpenThread CSL timeout using Kconfig. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57716 Signed-off-by: Lukasz Duda (cherry picked from commit c2859f736bfc959b91cca472ba32563afccea0bc) --- modules/openthread/Kconfig.thread | 6 ++++++ .../platform/openthread-core-zephyr-config.h | 10 ++++++++++ 2 files changed, 16 insertions(+) diff --git a/modules/openthread/Kconfig.thread b/modules/openthread/Kconfig.thread index a77f699448c7..3a84dc87ad55 100644 --- a/modules/openthread/Kconfig.thread +++ b/modules/openthread/Kconfig.thread @@ -100,6 +100,12 @@ config OPENTHREAD_PLATFORM_CSL_UNCERT help The fixed uncertainty of the Device for scheduling CSL Transmissions in units of 10 microseconds. +config OPENTHREAD_CSL_TIMEOUT + int "CSL timeout in seconds" + default 100 + help + The default CSL timeout in seconds. + config OPENTHREAD_MAC_SOFTWARE_TX_SECURITY_ENABLE bool "Software transmission security logic" default y if !OPENTHREAD_THREAD_VERSION_1_1 diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 54bc73fd869b..3cb1be96c439 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -294,6 +294,16 @@ #define OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON #endif /* CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON */ +/** + * @def OPENTHREAD_CONFIG_CSL_TIMEOUT + * + * The default CSL timeout in seconds. + * + */ +#ifdef CONFIG_OPENTHREAD_CSL_TIMEOUT +#define OPENTHREAD_CONFIG_CSL_TIMEOUT CONFIG_OPENTHREAD_CSL_TIMEOUT +#endif /* CONFIG_OPENTHREAD_CSL_TIMEOUT */ + /** * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE * From 7e63dfc689ff90e9818d245383d878b0d152c364 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 22 Mar 2023 12:19:57 +0100 Subject: [PATCH 087/528] [nrf fromtree] Bluetooth: Mesh: Use BT_MESH_MSG_CTX_INIT_DEV macro in LCD Client Use BT_MESH_MSG_CTX_INIT_DEV macro in LCD Client. Signed-off-by: Pavel Vasilyev (cherry picked from commit 60e874472ca7faca252578ddab63e46de1e09b5f) (cherry picked from commit 93f13b7e27119e4b41969885f2f76166e3d9a0ba) --- subsys/bluetooth/mesh/large_comp_data_cli.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/subsys/bluetooth/mesh/large_comp_data_cli.c b/subsys/bluetooth/mesh/large_comp_data_cli.c index 5ec45239bc82..e8d5f5cbba51 100644 --- a/subsys/bluetooth/mesh/large_comp_data_cli.c +++ b/subsys/bluetooth/mesh/large_comp_data_cli.c @@ -124,12 +124,7 @@ int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, size_t offset, struct net_buf_simple *comp) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_LARGE_COMP_DATA_GET, 3); - struct bt_mesh_msg_ctx ctx = { - .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV_REMOTE, - .addr = addr, - .send_ttl = BT_MESH_TTL_DEFAULT, - }; + struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); int err; err = cli_prepare(comp, OP_LARGE_COMP_DATA_STATUS, addr); @@ -155,12 +150,7 @@ int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, size_t offset, struct net_buf_simple *metadata) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_MODELS_METADATA_STATUS, 3); - struct bt_mesh_msg_ctx ctx = { - .net_idx = net_idx, - .app_idx = BT_MESH_KEY_DEV_REMOTE, - .addr = addr, - .send_ttl = BT_MESH_TTL_DEFAULT, - }; + struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); int err; err = cli_prepare(metadata, OP_MODELS_METADATA_STATUS, addr); From 0074273db330d765ac090f9959fee1344f572a44 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 22 Mar 2023 12:24:30 +0100 Subject: [PATCH 088/528] [nrf fromtree] Bluetooth: Mesh: Use bt_mesh_msg_ackd_send API in LCD Client Use bt_mesh_msg_ackd_send API in LCD Client. Signed-off-by: Pavel Vasilyev (cherry picked from commit b99d4dbce227cb068bd142a0248537987748d3cb) (cherry picked from commit f375b48326a0204426a97957f9aa188fce7a4b39) --- subsys/bluetooth/mesh/large_comp_data_cli.c | 49 +++++++-------------- 1 file changed, 16 insertions(+), 33 deletions(-) diff --git a/subsys/bluetooth/mesh/large_comp_data_cli.c b/subsys/bluetooth/mesh/large_comp_data_cli.c index e8d5f5cbba51..47c8db5b1f52 100644 --- a/subsys/bluetooth/mesh/large_comp_data_cli.c +++ b/subsys/bluetooth/mesh/large_comp_data_cli.c @@ -18,6 +18,8 @@ #include #include +#include "msg.h" + #include #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL @@ -115,35 +117,23 @@ const struct bt_mesh_model_cb _bt_mesh_large_comp_data_cli_cb = { .init = large_comp_data_cli_init, }; -static int cli_prepare(void *param, uint32_t op, uint16_t addr) -{ - return bt_mesh_msg_ack_ctx_prepare(&cli.ack_ctx, op, addr, param); -} - int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, size_t offset, struct net_buf_simple *comp) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_LARGE_COMP_DATA_GET, 3); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); - int err; - - err = cli_prepare(comp, OP_LARGE_COMP_DATA_STATUS, addr); - if (err) { - return err; - } + const struct bt_mesh_msg_rsp_ctx rsp = { + .ack = &cli.ack_ctx, + .op = OP_LARGE_COMP_DATA_STATUS, + .user_data = comp, + .timeout = msg_timeout, + }; bt_mesh_model_msg_init(&msg, OP_LARGE_COMP_DATA_GET); net_buf_simple_add_u8(&msg, page); net_buf_simple_add_le16(&msg, offset); - err = bt_mesh_model_send(cli.model, &ctx, &msg, NULL, NULL); - if (err) { - LOG_ERR("model_send() failed (err %d)", err); - bt_mesh_msg_ack_ctx_clear(&cli.ack_ctx); - return err; - } - - return bt_mesh_msg_ack_ctx_wait(&cli.ack_ctx, K_MSEC(msg_timeout)); + return bt_mesh_msg_ackd_send(cli.model, &ctx, &msg, comp ? &rsp : NULL); } int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, @@ -151,23 +141,16 @@ int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, { BT_MESH_MODEL_BUF_DEFINE(msg, OP_MODELS_METADATA_STATUS, 3); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); - int err; - - err = cli_prepare(metadata, OP_MODELS_METADATA_STATUS, addr); - if (err) { - return err; - } + const struct bt_mesh_msg_rsp_ctx rsp = { + .ack = &cli.ack_ctx, + .op = OP_MODELS_METADATA_STATUS, + .user_data = metadata, + .timeout = msg_timeout, + }; bt_mesh_model_msg_init(&msg, OP_MODELS_METADATA_GET); net_buf_simple_add_u8(&msg, page); net_buf_simple_add_le16(&msg, offset); - err = bt_mesh_model_send(cli.model, &ctx, &msg, NULL, NULL); - if (err) { - LOG_ERR("model_send() failed (err %d)", err); - bt_mesh_msg_ack_ctx_clear(&cli.ack_ctx); - return err; - } - - return bt_mesh_msg_ack_ctx_wait(&cli.ack_ctx, K_MSEC(msg_timeout)); + return bt_mesh_msg_ackd_send(cli.model, &ctx, &msg, metadata ? &rsp : NULL); } From 57d4f110f34acec2be279453a08c40a7e9d75412 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 22 Mar 2023 13:49:21 +0100 Subject: [PATCH 089/528] [nrf fromtree] Bluetooth: Mesh: Add async API for Large Comp Data Client Add asynchronous API for Large Composition Data Client. Signed-off-by: Pavel Vasilyev (cherry picked from commit c4fa085ec4e1bab787ccd68fe83ed6f20e42354d) (cherry picked from commit 3be8d2b735b2728db1f303789973c17ece6668f2) --- .../bluetooth/mesh/large_comp_data_cli.h | 103 ++++++++++++-- subsys/bluetooth/mesh/large_comp_data_cli.c | 133 +++++++++--------- subsys/bluetooth/mesh/shell/large_comp_data.c | 46 +++--- tests/bluetooth/mesh_shell/src/main.c | 6 +- tests/bsim/bluetooth/mesh/src/test_lcd.c | 82 ++++++----- 5 files changed, 241 insertions(+), 129 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/large_comp_data_cli.h b/include/zephyr/bluetooth/mesh/large_comp_data_cli.h index ae23cda468f7..40ee0316637e 100644 --- a/include/zephyr/bluetooth/mesh/large_comp_data_cli.h +++ b/include/zephyr/bluetooth/mesh/large_comp_data_cli.h @@ -19,44 +19,123 @@ extern "C" { #endif +struct bt_mesh_large_comp_data_cli; + +/** Large Composition Data response. */ +struct bt_mesh_large_comp_data_rsp { + /** Page number. */ + uint8_t page; + /** Offset within the page. */ + uint16_t offset; + /** Total size of the page. */ + uint16_t total_size; + /** Pointer to allocated buffer for storing received data. */ + struct net_buf_simple *data; +}; + +/** Large Composition Data Status messages callbacks */ +struct bt_mesh_large_comp_data_cli_cb { + /** @brief Optional callback for Large Composition Data Status message. + * + * Handles received Large Composition Data Status messages from a Large Composition Data + * Server. + * + * If the content of @c rsp is needed after exiting this callback, a user should + * deep copy it. + * + * @param cli Large Composition Data Client context. + * @param addr Address of the sender. + * @param rsp Response received from the server. + */ + void (*large_comp_data_status)(struct bt_mesh_large_comp_data_cli *cli, uint16_t addr, + struct bt_mesh_large_comp_data_rsp *rsp); + + /** @brief Optional callback for Models Metadata Status message. + * + * Handles received Models Metadata Status messages from a Large Composition Data + * Server. + * + * If the content of @c rsp is needed after exiting this callback, a user should + * deep copy it. + * + * @param cli Large Composition Data Client context. + * @param addr Address of the sender. + * @param rsp Response received from the server. + */ + void (*models_metadata_status)(struct bt_mesh_large_comp_data_cli *cli, uint16_t addr, + struct bt_mesh_large_comp_data_rsp *rsp); +}; + +/** Large Composition Data Client model context */ +struct bt_mesh_large_comp_data_cli { + /** Model entry pointer. */ + struct bt_mesh_model *model; + + /** Internal parameters for tracking message responses. */ + struct bt_mesh_msg_ack_ctx ack_ctx; + + /** Optional callback for Large Composition Data Status messages. */ + const struct bt_mesh_large_comp_data_cli_cb *cb; +}; + /** * - * @brief Large Composition Data Client model composition data entry. + * @brief Large Composition Data Client model Composition Data entry. + * + * @param cli_data Pointer to a @ref bt_mesh_large_comp_data_cli instance. */ -#define BT_MESH_MODEL_LARGE_COMP_DATA_CLI \ - BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_LARGE_COMP_DATA_CLI, \ - _bt_mesh_large_comp_data_cli_op, NULL, NULL, \ +#define BT_MESH_MODEL_LARGE_COMP_DATA_CLI(cli_data) \ + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_LARGE_COMP_DATA_CLI, \ + _bt_mesh_large_comp_data_cli_op, NULL, cli_data, \ &_bt_mesh_large_comp_data_cli_cb) /** @brief Send Large Composition Data Get message. * - * This API is used to read a portion of a page of the Composition Data. + * This API is used to read a portion of a Composition Data Page. + * + * This API can be used asynchronously by setting @p rsp as NULL. This way, the + * method will not wait for a response and will return immediately after sending + * the command. + * + * When @c rsp is set, the user is responsible for providing a buffer for the + * Composition Data in @ref bt_mesh_large_comp_data_rsp::data. If a buffer is + * not provided, the metadata won't be copied. * * @param net_idx Network index to encrypt with. * @param addr Target node element address. - * @param page Composition Data page to read. + * @param page Composition Data Page to read. * @param offset Offset within the Composition Data Page. - * @param comp Output buffer for storing received Composition data. + * @param rsp Pointer to a struct storing the received response from + * the server, or NULL to not wait for a response. * * @return 0 on success, or (negative) error code on failure. */ int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, - size_t offset, struct net_buf_simple *comp); + size_t offset, struct bt_mesh_large_comp_data_rsp *rsp); /** @brief Send Models Metadata Get message. * - * This API is used to read a portion of a page of the Models Metadata state. + * This API is used to read a portion of a Models Metadata Page. + * + * This API can be used asynchronously by setting @p rsp as NULL. This way, the + * method will not wait for a response and will return immediately after sending + * the command. + * + * When @c rsp is set, a user is responsible for providing a buffer for + * metadata in @ref bt_mesh_large_comp_data_rsp::data. If a buffer is not + * provided, the metadata won't be copied. * * @param net_idx Network index to encrypt with. * @param addr Target node element address. - * @param page Models Metadata page to read. + * @param page Models Metadata Page to read. * @param offset Offset within the Models Metadata Page. - * @param metadata Output buffer for storing received Models Metadata. + * @param rsp Pointer to a struct storing the received response from + * the server, or NULL to not wait for a response. * * @return 0 on success, or (negative) error code on failure. */ int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, - size_t offset, struct net_buf_simple *metadata); + size_t offset, struct bt_mesh_large_comp_data_rsp *rsp); /** @cond INTERNAL_HIDDEN */ extern const struct bt_mesh_model_op _bt_mesh_large_comp_data_cli_op[]; diff --git a/subsys/bluetooth/mesh/large_comp_data_cli.c b/subsys/bluetooth/mesh/large_comp_data_cli.c index 47c8db5b1f52..614569d54ae6 100644 --- a/subsys/bluetooth/mesh/large_comp_data_cli.c +++ b/subsys/bluetooth/mesh/large_comp_data_cli.c @@ -30,63 +30,68 @@ LOG_MODULE_REGISTER(bt_mesh_large_comp_data_cli); #include "access.h" #include "foundation.h" -/** Mesh Large Composition Data Client Model Context */ -static struct bt_mesh_large_comp_data_cli { - /** Composition data model entry pointer. */ - struct bt_mesh_model *model; - - /* Internal parameters for tracking message responses. */ - struct bt_mesh_msg_ack_ctx ack_ctx; -} cli; - +static struct bt_mesh_large_comp_data_cli *cli; static int32_t msg_timeout; -static int large_comp_data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, uint32_t op, + void (*cb)(struct bt_mesh_large_comp_data_cli *cli, uint16_t addr, + struct bt_mesh_large_comp_data_rsp *rsp)) { - struct net_buf_simple *comp; - size_t to_copy; + struct bt_mesh_large_comp_data_rsp *rsp; + uint8_t page; + uint16_t offset; + uint16_t total_size; LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, bt_hex(buf->data, buf->len)); - if (!bt_mesh_msg_ack_ctx_match(&cli.ack_ctx, OP_LARGE_COMP_DATA_STATUS, - ctx->addr, (void **)&comp)) { - return 0; + page = net_buf_simple_pull_u8(buf); + offset = net_buf_simple_pull_le16(buf); + total_size = net_buf_simple_pull_le16(buf); + + if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, op, ctx->addr, (void **)&rsp)) { + rsp->page = page; + rsp->offset = offset; + rsp->total_size = total_size; + + if (rsp->data) { + net_buf_simple_add_mem(rsp->data, buf->data, + MIN(net_buf_simple_tailroom(rsp->data), buf->len)); + } + + bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } - to_copy = MIN(net_buf_simple_tailroom(comp), buf->len); - net_buf_simple_add_mem(comp, buf->data, to_copy); + if (cb) { + struct bt_mesh_large_comp_data_rsp status_rsp = { + .page = page, + .offset = offset, + .total_size = total_size, + .data = buf, + }; - bt_mesh_msg_ack_ctx_rx(&cli.ack_ctx); + cb(cli, ctx->addr, &status_rsp); + } return 0; } -static int models_metadata_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int large_comp_data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - struct net_buf_simple *metadata; - size_t to_copy; - - LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", - ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, - bt_hex(buf->data, buf->len)); - - if (!bt_mesh_msg_ack_ctx_match(&cli.ack_ctx, OP_MODELS_METADATA_STATUS, - ctx->addr, (void **)&metadata)) { - return 0; - } - - metadata = (struct net_buf_simple *)cli.ack_ctx.user_data; - - to_copy = MIN(net_buf_simple_tailroom(metadata), buf->len); - net_buf_simple_add_mem(metadata, buf->data, to_copy); - - bt_mesh_msg_ack_ctx_rx(&cli.ack_ctx); + return data_status(model, ctx, buf, OP_LARGE_COMP_DATA_STATUS, + (cli->cb && cli->cb->large_comp_data_status ? + cli->cb->large_comp_data_status : NULL)); +} - return 0; +static int models_metadata_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) +{ + return data_status(model, ctx, buf, OP_MODELS_METADATA_STATUS, + (cli->cb && cli->cb->models_metadata_status ? + cli->cb->models_metadata_status : NULL)); } const struct bt_mesh_model_op _bt_mesh_large_comp_data_cli_op[] = { @@ -98,17 +103,18 @@ const struct bt_mesh_model_op _bt_mesh_large_comp_data_cli_op[] = { static int large_comp_data_cli_init(struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { - LOG_ERR("Configuration Client only allowed in primary element"); + LOG_ERR("Large Comp Data Client only allowed in primary element"); return -EINVAL; } model->keys[0] = BT_MESH_KEY_DEV_ANY; model->flags |= BT_MESH_MOD_DEVKEY_ONLY; - cli.model = model; + cli = model->user_data; + cli->model = model; msg_timeout = 5000; - bt_mesh_msg_ack_ctx_init(&cli.ack_ctx); + bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); return 0; } @@ -117,40 +123,35 @@ const struct bt_mesh_model_cb _bt_mesh_large_comp_data_cli_cb = { .init = large_comp_data_cli_init, }; -int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, - size_t offset, struct net_buf_simple *comp) +static int data_get(uint16_t net_idx, uint16_t addr, uint32_t op, uint32_t status_op, uint8_t page, + size_t offset, struct bt_mesh_large_comp_data_rsp *rsp) { - BT_MESH_MODEL_BUF_DEFINE(msg, OP_LARGE_COMP_DATA_GET, 3); + BT_MESH_MODEL_BUF_DEFINE(msg, op, 3); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); - const struct bt_mesh_msg_rsp_ctx rsp = { - .ack = &cli.ack_ctx, - .op = OP_LARGE_COMP_DATA_STATUS, - .user_data = comp, + const struct bt_mesh_msg_rsp_ctx rsp_ctx = { + .ack = &cli->ack_ctx, + .op = status_op, + .user_data = rsp, .timeout = msg_timeout, }; - bt_mesh_model_msg_init(&msg, OP_LARGE_COMP_DATA_GET); + bt_mesh_model_msg_init(&msg, op); net_buf_simple_add_u8(&msg, page); net_buf_simple_add_le16(&msg, offset); - return bt_mesh_msg_ackd_send(cli.model, &ctx, &msg, comp ? &rsp : NULL); + return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, rsp ? &rsp_ctx : NULL); } -int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, - size_t offset, struct net_buf_simple *metadata) +int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, + size_t offset, struct bt_mesh_large_comp_data_rsp *rsp) { - BT_MESH_MODEL_BUF_DEFINE(msg, OP_MODELS_METADATA_STATUS, 3); - struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); - const struct bt_mesh_msg_rsp_ctx rsp = { - .ack = &cli.ack_ctx, - .op = OP_MODELS_METADATA_STATUS, - .user_data = metadata, - .timeout = msg_timeout, - }; - - bt_mesh_model_msg_init(&msg, OP_MODELS_METADATA_GET); - net_buf_simple_add_u8(&msg, page); - net_buf_simple_add_le16(&msg, offset); + return data_get(net_idx, addr, OP_LARGE_COMP_DATA_GET, OP_LARGE_COMP_DATA_STATUS, + page, offset, rsp); +} - return bt_mesh_msg_ackd_send(cli.model, &ctx, &msg, metadata ? &rsp : NULL); +int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, + size_t offset, struct bt_mesh_large_comp_data_rsp *rsp) +{ + return data_get(net_idx, addr, OP_MODELS_METADATA_GET, OP_MODELS_METADATA_STATUS, + page, offset, rsp); } diff --git a/subsys/bluetooth/mesh/shell/large_comp_data.c b/subsys/bluetooth/mesh/shell/large_comp_data.c index d278bbfc936c..750f7b318fd7 100644 --- a/subsys/bluetooth/mesh/shell/large_comp_data.c +++ b/subsys/bluetooth/mesh/shell/large_comp_data.c @@ -11,9 +11,28 @@ #include "utils.h" +extern const struct shell *bt_mesh_shell_ctx_shell; + +static void status_print(int err, char *msg, uint16_t addr, struct bt_mesh_large_comp_data_rsp *rsp) +{ + if (err) { + shell_error(bt_mesh_shell_ctx_shell, + "Failed to send %s Get message (err %d)", msg, err); + return; + } + + shell_print(bt_mesh_shell_ctx_shell, + "%s [0x%04x]: page: %u offset: %u total size: %u", msg, addr, rsp->page, + rsp->offset, rsp->total_size); + shell_hexdump(bt_mesh_shell_ctx_shell, rsp->data->data, rsp->data->len); +} + static int cmd_large_comp_data_get(const struct shell *sh, size_t argc, char *argv[]) { NET_BUF_SIMPLE_DEFINE(comp, 64); + struct bt_mesh_large_comp_data_rsp rsp = { + .data = &comp, + }; uint8_t page; uint16_t offset; int err = 0; @@ -29,21 +48,18 @@ static int cmd_large_comp_data_get(const struct shell *sh, size_t argc, char *ar } err = bt_mesh_large_comp_data_get(bt_mesh_shell_target_ctx.net_idx, - bt_mesh_shell_target_ctx.dst, page, offset, - &comp); - if (err) { - shell_print(sh, "Failed to send Large Composition Data Get (err=%d)", err); - return err; - } + bt_mesh_shell_target_ctx.dst, page, offset, &rsp); + status_print(err, "Composition Data", bt_mesh_shell_target_ctx.dst, &rsp); - shell_print(sh, "Large Composition Data Get len=%d", comp.len); - - return 0; + return err; } static int cmd_models_metadata_get(const struct shell *sh, size_t argc, char *argv[]) { NET_BUF_SIMPLE_DEFINE(metadata, 64); + struct bt_mesh_large_comp_data_rsp rsp = { + .data = &metadata, + }; uint8_t page; uint16_t offset; int err = 0; @@ -59,16 +75,10 @@ static int cmd_models_metadata_get(const struct shell *sh, size_t argc, char *ar } err = bt_mesh_models_metadata_get(bt_mesh_shell_target_ctx.net_idx, - bt_mesh_shell_target_ctx.dst, page, offset, - &metadata); - if (err) { - shell_print(sh, "Failed to send Models Metadata Get (err=%d)", err); - return err; - } - - shell_print(sh, "Models Metadata Get len=%d", metadata.len); + bt_mesh_shell_target_ctx.dst, page, offset, &rsp); + status_print(err, "Models Metadata", bt_mesh_shell_target_ctx.dst, &rsp); - return 0; + return err; } SHELL_STATIC_SUBCMD_SET_CREATE( diff --git a/tests/bluetooth/mesh_shell/src/main.c b/tests/bluetooth/mesh_shell/src/main.c index e2b2a5ad60d3..4e0394c234d0 100644 --- a/tests/bluetooth/mesh_shell/src/main.c +++ b/tests/bluetooth/mesh_shell/src/main.c @@ -37,6 +37,10 @@ static struct bt_mesh_sol_pdu_rpl_cli srpl_cli; static struct bt_mesh_od_priv_proxy_cli od_priv_proxy_cli; #endif +#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) +struct bt_mesh_large_comp_data_cli large_comp_data_cli; +#endif + BT_MESH_SHELL_HEALTH_PUB_DEFINE(health_pub); static struct bt_mesh_model root_models[] = { @@ -83,7 +87,7 @@ static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_LARGE_COMP_DATA_SRV, #endif #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) - BT_MESH_MODEL_LARGE_COMP_DATA_CLI, + BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&large_comp_data_cli), #endif #if defined(CONFIG_BT_MESH_PRIV_BEACON_SRV) diff --git a/tests/bsim/bluetooth/mesh/src/test_lcd.c b/tests/bsim/bluetooth/mesh/src/test_lcd.c index 7797a1854745..1dc5fc70054f 100644 --- a/tests/bsim/bluetooth/mesh/src/test_lcd.c +++ b/tests/bsim/bluetooth/mesh/src/test_lcd.c @@ -27,6 +27,7 @@ LOG_MODULE_REGISTER(test_lcd, LOG_LEVEL_INF); #define DUMMY_2_BYTE_OP BT_MESH_MODEL_OP_2(0xff, 0xff) #define BT_MESH_LCD_PAYLOAD_MAX \ (BT_MESH_TX_SDU_MAX - BT_MESH_MODEL_OP_LEN(DUMMY_2_BYTE_OP) - \ + LCD_STATUS_FIELDS_LEN - \ BT_MESH_MIC_SHORT) /* 378 bytes */ #define TEST_MODEL_CNT_CB(_dummy_op, _metadata) \ @@ -67,13 +68,14 @@ static const struct bt_mesh_test_cfg srv_cfg = { static struct bt_mesh_prov prov; static struct bt_mesh_cfg_cli cfg_cli; +static struct bt_mesh_large_comp_data_cli lcd_cli; /* Creates enough composition data to send a max SDU comp status message + 1 byte */ static struct bt_mesh_elem elements_1[] = { BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), - BT_MESH_MODEL_LARGE_COMP_DATA_CLI, + BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), BT_MESH_MODEL_LARGE_COMP_DATA_SRV), BT_MESH_MODEL_NONE), LISTIFY(88, DUMMY_ELEM, (,)), @@ -84,7 +86,7 @@ static struct bt_mesh_elem elements_2[] = { BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), - BT_MESH_MODEL_LARGE_COMP_DATA_CLI, + BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), BT_MESH_MODEL_LARGE_COMP_DATA_SRV), BT_MESH_MODEL_NONE), LISTIFY(186, DUMMY_ELEM, (,)), @@ -140,16 +142,12 @@ static void merge_and_compare_assert(struct net_buf_simple *sample1, struct net_ /* Assert that the received status fields are equal to local values. Buffer state is saved. */ -static void verify_status_fields(struct net_buf_simple *srv_rsp, uint8_t page_local, +static void verify_status_fields(struct bt_mesh_large_comp_data_rsp *srv_rsp, uint8_t page_local, uint16_t offset_local, uint16_t total_size_local) { - uint8_t byte_value[LCD_STATUS_FIELDS_LEN]; - - byte_value[0] = page_local; - memcpy(&byte_value[1], &offset_local, 2); - memcpy(&byte_value[3], &total_size_local, 2); - - ASSERT_TRUE(memcmp(srv_rsp->data, byte_value, LCD_STATUS_FIELDS_LEN) == 0); + ASSERT_EQUAL(page_local, srv_rsp->page); + ASSERT_EQUAL(offset_local, srv_rsp->offset); + ASSERT_EQUAL(total_size_local, srv_rsp->total_size); } /* Compare response data with local data. @@ -158,7 +156,7 @@ static void verify_status_fields(struct net_buf_simple *srv_rsp, uint8_t page_lo * * local_data: state is preserved. * * prev_len: Set to NULL if irrelevant. Used for split and merge testing. */ -static void rsp_equals_local_data_assert(uint16_t addr, struct net_buf_simple *srv_rsp, +static void rsp_equals_local_data_assert(uint16_t addr, struct bt_mesh_large_comp_data_rsp *srv_rsp, struct net_buf_simple *local_data, uint8_t page, uint16_t offset, uint16_t total_size, uint16_t *prev_len) { @@ -166,8 +164,6 @@ static void rsp_equals_local_data_assert(uint16_t addr, struct net_buf_simple *s /* Check that status field data matches local values. */ verify_status_fields(srv_rsp, page, offset, total_size); - /* Remove field data bytes before comparing comp data */ - net_buf_simple_pull_mem(srv_rsp, LCD_STATUS_FIELDS_LEN); net_buf_simple_save(local_data, &local_state); @@ -178,7 +174,7 @@ static void rsp_equals_local_data_assert(uint16_t addr, struct net_buf_simple *s } /* Check that local and rsp data are equal */ - ASSERT_TRUE(memcmp(srv_rsp->data, local_data->data, srv_rsp->len) == 0); + ASSERT_TRUE(memcmp(srv_rsp->data->data, local_data->data, srv_rsp->data->len) == 0); net_buf_simple_restore(local_data, &local_state); } @@ -200,9 +196,13 @@ static void test_cli_max_sdu_comp_data_request(void) uint16_t offset, total_size; NET_BUF_SIMPLE_DEFINE(local_comp, 500); - NET_BUF_SIMPLE_DEFINE(srv_rsp, 500); + NET_BUF_SIMPLE_DEFINE(srv_rsp_comp, 500); net_buf_simple_init(&local_comp, 0); - net_buf_simple_init(&srv_rsp, 0); + net_buf_simple_init(&srv_rsp_comp, 0); + + struct bt_mesh_large_comp_data_rsp srv_rsp = { + .data = &srv_rsp_comp, + }; bt_mesh_device_setup(&prov, &comp_1); prov_and_conf(cli_cfg); @@ -223,7 +223,7 @@ static void test_cli_max_sdu_comp_data_request(void) /* Get server composition data and check integrity */ ASSERT_OK(bt_mesh_large_comp_data_get(0, SRV_ADDR, page, offset, &srv_rsp)); - ASSERT_EQUAL(srv_rsp.len, BT_MESH_LCD_PAYLOAD_MAX); + ASSERT_EQUAL(srv_rsp_comp.len, BT_MESH_LCD_PAYLOAD_MAX); rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp, &local_comp, page, offset, total_size, NULL); @@ -237,11 +237,18 @@ static void test_cli_split_comp_data_request(void) uint16_t offset, total_size, prev_len = 0; NET_BUF_SIMPLE_DEFINE(local_comp, 200); - NET_BUF_SIMPLE_DEFINE(srv_rsp_1, 64); - NET_BUF_SIMPLE_DEFINE(srv_rsp_2, 64); + NET_BUF_SIMPLE_DEFINE(srv_rsp_comp_1, 64); + NET_BUF_SIMPLE_DEFINE(srv_rsp_comp_2, 64); net_buf_simple_init(&local_comp, 0); - net_buf_simple_init(&srv_rsp_1, 0); - net_buf_simple_init(&srv_rsp_2, 0); + net_buf_simple_init(&srv_rsp_comp_1, 0); + net_buf_simple_init(&srv_rsp_comp_2, 0); + + struct bt_mesh_large_comp_data_rsp srv_rsp_1 = { + .data = &srv_rsp_comp_1, + }; + struct bt_mesh_large_comp_data_rsp srv_rsp_2 = { + .data = &srv_rsp_comp_2, + }; bt_mesh_device_setup(&prov, &comp_1); prov_and_conf(cli_cfg); @@ -262,7 +269,7 @@ static void test_cli_split_comp_data_request(void) rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp_1, &local_comp, page, offset, total_size, &prev_len); - prev_len = srv_rsp_1.len; + prev_len = srv_rsp_comp_1.len; offset += prev_len; /* Get next server composition data sample */ @@ -271,7 +278,7 @@ static void test_cli_split_comp_data_request(void) &prev_len); /* Check data integrity of merged sample data */ - merge_and_compare_assert(&srv_rsp_1, &srv_rsp_2, &local_comp); + merge_and_compare_assert(&srv_rsp_comp_1, &srv_rsp_comp_2, &local_comp); PASS(); } @@ -283,9 +290,13 @@ static void test_cli_max_sdu_metadata_request(void) uint16_t offset, total_size; NET_BUF_SIMPLE_DEFINE(local_metadata, 500); - NET_BUF_SIMPLE_DEFINE(srv_rsp, 500); + NET_BUF_SIMPLE_DEFINE(srv_rsp_metadata, 500); net_buf_simple_init(&local_metadata, 0); - net_buf_simple_init(&srv_rsp, 0); + net_buf_simple_init(&srv_rsp_metadata, 0); + + struct bt_mesh_large_comp_data_rsp srv_rsp = { + .data = &srv_rsp_metadata, + }; bt_mesh_device_setup(&prov, &comp_2); prov_and_conf(cli_cfg); @@ -306,7 +317,7 @@ static void test_cli_max_sdu_metadata_request(void) /* Get server metadata and check integrity */ ASSERT_OK(bt_mesh_models_metadata_get(0, SRV_ADDR, page, offset, &srv_rsp)); - ASSERT_EQUAL(srv_rsp.len, BT_MESH_LCD_PAYLOAD_MAX); + ASSERT_EQUAL(srv_rsp_metadata.len, BT_MESH_LCD_PAYLOAD_MAX); rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp, &local_metadata, page, offset, total_size, NULL); @@ -319,11 +330,18 @@ static void test_cli_split_metadata_request(void) uint16_t offset, total_size, prev_len = 0; NET_BUF_SIMPLE_DEFINE(local_metadata, 500); - NET_BUF_SIMPLE_DEFINE(srv_rsp_1, 64); - NET_BUF_SIMPLE_DEFINE(srv_rsp_2, 64); + NET_BUF_SIMPLE_DEFINE(srv_rsp_metadata_1, 64); + NET_BUF_SIMPLE_DEFINE(srv_rsp_metadata_2, 64); net_buf_simple_init(&local_metadata, 0); - net_buf_simple_init(&srv_rsp_1, 0); - net_buf_simple_init(&srv_rsp_2, 0); + net_buf_simple_init(&srv_rsp_metadata_1, 0); + net_buf_simple_init(&srv_rsp_metadata_2, 0); + + struct bt_mesh_large_comp_data_rsp srv_rsp_1 = { + .data = &srv_rsp_metadata_1, + }; + struct bt_mesh_large_comp_data_rsp srv_rsp_2 = { + .data = &srv_rsp_metadata_2, + }; bt_mesh_device_setup(&prov, &comp_2); prov_and_conf(cli_cfg); @@ -344,7 +362,7 @@ static void test_cli_split_metadata_request(void) rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp_1, &local_metadata, page, offset, total_size, &prev_len); - prev_len = srv_rsp_1.len; + prev_len = srv_rsp_metadata_1.len; offset += prev_len; /* Get next server composition data sample and check integrity */ @@ -353,7 +371,7 @@ static void test_cli_split_metadata_request(void) total_size, &prev_len); /* Check data integrity of merged sample data */ - merge_and_compare_assert(&srv_rsp_1, &srv_rsp_2, &local_metadata); + merge_and_compare_assert(&srv_rsp_metadata_1, &srv_rsp_metadata_2, &local_metadata); PASS(); } From 134a065cff348e851c083911edf4b6d79e765145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Tue, 18 Apr 2023 14:13:06 +0200 Subject: [PATCH 090/528] [nrf fromtree] Bluetooth: Mesh: Add callback for received beacons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This adds callbacks for Secure and Private Network Beacons. SNB callbacks are called after `secure_beacon_authenticate` ends with success, and Private Beacon callback after Private Beacon payload is decrypted succsessfully. Signed-off-by: Krzysztof Kopyściński (cherry picked from commit 0a55ec8d52f781ccd50795feba7e9fb2ed03258e) (cherry picked from commit 0678898f8608a710d6ec8e4df595a6d59e04c9f8) --- include/zephyr/bluetooth/mesh/main.h | 67 +++++++++++++++++++ .../zephyr/linker/common-rom/common-rom-bt.ld | 4 ++ subsys/bluetooth/mesh/beacon.c | 30 +++++++++ 3 files changed, 101 insertions(+) diff --git a/include/zephyr/bluetooth/mesh/main.h b/include/zephyr/bluetooth/mesh/main.h index 5ac5447acea5..00309b352f8c 100644 --- a/include/zephyr/bluetooth/mesh/main.h +++ b/include/zephyr/bluetooth/mesh/main.h @@ -762,6 +762,73 @@ struct bt_mesh_friend_cb { static const STRUCT_SECTION_ITERABLE(bt_mesh_friend_cb, \ _CONCAT(bt_mesh_friend_cb_, \ _name)) +#if defined(CONFIG_BT_TESTING) +struct bt_mesh_snb { + /** Flags */ + uint8_t flags; + + /** Network ID */ + uint64_t net_id; + + /** IV Index */ + uint32_t iv_idx; + + /** Authentication Value */ + uint64_t auth_val; +}; + +#if defined(CONFIG_BT_MESH_V1d1) +struct bt_mesh_prb { + /** Random */ + uint8_t random[13]; + + /** Flags */ + uint8_t flags; + + /** IV Index */ + uint32_t iv_idx; + + /** Authentication tag */ + uint64_t auth_tag; +}; +#endif + +/** Beacon callback functions. */ +struct bt_mesh_beacon_cb { + /** @brief Secure Network Beacon received. + * + * This callback notifies the application that Secure Network Beacon + * was received. + * + * @param snb Structure describing received Secure Network Beacon + */ + void (*snb_received)(const struct bt_mesh_snb *snb); + +#if defined(CONFIG_BT_MESH_V1d1) + /** @brief Private Beacon received. + * + * This callback notifies the application that Private Beacon + * was received and successfully decrypted. + * + * @param prb Structure describing received Private Beacon + */ + void (*priv_received)(const struct bt_mesh_prb *prb); +#endif +}; + +/** + * @brief Register a callback structure for beacon events. + * + * Registers a callback structure that will be called whenever beacon advertisement + * is received. + * + * @param _name Name of callback structure. + */ +#define BT_MESH_BEACON_CB_DEFINE(_name) \ + static const STRUCT_SECTION_ITERABLE(bt_mesh_beacon_cb, \ + _CONCAT(bt_mesh_beacon_cb_, \ + _name)) +#endif /** @brief Terminate Friendship. * diff --git a/include/zephyr/linker/common-rom/common-rom-bt.ld b/include/zephyr/linker/common-rom/common-rom-bt.ld index 1d6c55c0afe0..ecd9ae05e3d2 100644 --- a/include/zephyr/linker/common-rom/common-rom-bt.ld +++ b/include/zephyr/linker/common-rom/common-rom-bt.ld @@ -17,6 +17,10 @@ ITERABLE_SECTION_ROM(bt_mesh_app_key_cb, 4) ITERABLE_SECTION_ROM(bt_mesh_hb_cb, 4) + +#if defined(CONFIG_BT_TESTING) + ITERABLE_SECTION_ROM(bt_mesh_beacon_cb, 4) +#endif #endif #if defined(CONFIG_BT_MESH_FRIEND) diff --git a/subsys/bluetooth/mesh/beacon.c b/subsys/bluetooth/mesh/beacon.c index bdcb18f1a27c..fc4f6e491bcd 100644 --- a/subsys/bluetooth/mesh/beacon.c +++ b/subsys/bluetooth/mesh/beacon.c @@ -501,6 +501,21 @@ static bool secure_beacon_authenticate(struct bt_mesh_subnet *sub, void *cb_data for (int i = 0; i < ARRAY_SIZE(sub->keys); i++) { if (sub->keys[i].valid && auth_match(&sub->keys[i], params)) { params->new_key = (i > 0); +#if defined(CONFIG_BT_TESTING) + struct bt_mesh_snb beacon_info; + + beacon_info.flags = params->flags; + memcpy(&beacon_info.net_id, params->net_id, 8); + beacon_info.iv_idx = params->iv_index; + memcpy(&beacon_info.auth_val, params->auth, 8); + + STRUCT_SECTION_FOREACH(bt_mesh_beacon_cb, cb) { + if (cb->snb_received) { + cb->snb_received(&beacon_info); + } + } +#endif + return true; } } @@ -526,6 +541,21 @@ static bool priv_beacon_decrypt(struct bt_mesh_subnet *sub, void *cb_data) params->new_key = (i > 0); params->flags = out[0]; params->iv_index = sys_get_be32(&out[1]); + +#if defined(CONFIG_BT_TESTING) + struct bt_mesh_prb beacon_info; + + memcpy(beacon_info.random, params->random, 13); + beacon_info.flags = params->flags; + beacon_info.iv_idx = params->iv_index; + memcpy(&beacon_info.auth_tag, params->auth, 8); + + STRUCT_SECTION_FOREACH(bt_mesh_beacon_cb, cb) { + if (cb->priv_received) { + cb->priv_received(&beacon_info); + } + } +#endif return true; } } From 428fefd2e794190560dc526d44d8f6173f2ccdb6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stine=20=C3=85kredalen?= Date: Tue, 25 Apr 2023 01:00:36 +0200 Subject: [PATCH 091/528] [nrf fromtree] doc: Bluetooth: Mesh: update proxy solicitation docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated related docs. Small fix in mesh/Kconfig and shell.rst. Signed-off-by: Stine Åkredalen (cherry picked from commit 80158c14286ee5e4002a576b5bf3289ed53e8bba) (cherry picked from commit 6d5a9d9647266567282bea1ac1645f3ff9cfe692) --- .../bluetooth/api/mesh/models.rst | 6 ++- doc/connectivity/bluetooth/api/mesh/od.rst | 14 ------ .../bluetooth/api/mesh/od_cli.rst | 18 +++++++- .../bluetooth/api/mesh/od_srv.rst | 17 ++++++- doc/connectivity/bluetooth/api/mesh/proxy.rst | 46 +++++++++++++++++++ doc/connectivity/bluetooth/api/mesh/shell.rst | 4 +- doc/connectivity/bluetooth/api/mesh/srpl.rst | 16 ------- .../bluetooth/api/mesh/srpl_cli.rst | 20 +++++++- .../bluetooth/api/mesh/srpl_srv.rst | 19 +++++++- subsys/bluetooth/mesh/Kconfig | 4 +- 10 files changed, 124 insertions(+), 40 deletions(-) delete mode 100644 doc/connectivity/bluetooth/api/mesh/od.rst delete mode 100644 doc/connectivity/bluetooth/api/mesh/srpl.rst diff --git a/doc/connectivity/bluetooth/api/mesh/models.rst b/doc/connectivity/bluetooth/api/mesh/models.rst index 85453a788082..5269790944cd 100644 --- a/doc/connectivity/bluetooth/api/mesh/models.rst +++ b/doc/connectivity/bluetooth/api/mesh/models.rst @@ -22,8 +22,10 @@ used by network administrators to configure and diagnose mesh nodes. op_agg_srv rpr_cli rpr_srv - srpl - od + od_cli + od_srv + srpl_cli + srpl_srv Model specification models ************************** diff --git a/doc/connectivity/bluetooth/api/mesh/od.rst b/doc/connectivity/bluetooth/api/mesh/od.rst deleted file mode 100644 index bece6d9a1a92..000000000000 --- a/doc/connectivity/bluetooth/api/mesh/od.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. _bluetooth_mesh_od: - -On-Demand Private GATT Proxy models -################################### - -On-Demand Private GATT Proxy state defines how long a node will advertise Mesh Proxy Service with Private Network Identity type after it receives Solicitation PDU. - -On-Demand Private GATT Proxy models are: - -.. toctree:: - :maxdepth: 1 - - od_srv - od_cli diff --git a/doc/connectivity/bluetooth/api/mesh/od_cli.rst b/doc/connectivity/bluetooth/api/mesh/od_cli.rst index dfdb6df234ef..ea2deae79b9f 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_cli.rst @@ -3,7 +3,23 @@ On-Demand Private Proxy Client ############################## -On-Demand Private Proxy Client model is used to set and retrieve the On-Demand Private GATT Proxy state, and to adjust message transmission timeout. +The On-Demand Private Proxy Client model is a foundation model defined by the Bluetooth +mesh specification. The model is optional, and is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` option. + +The On-Demand Private Proxy Client model was introduced in the Bluetooth Mesh Protocol +Specification version 1.1, and is used to set and retrieve the On-Demand Private GATT Proxy state. The state defines +how long a node will advertise Mesh Proxy Service with Private Network Identity type after it receives a Solicitation PDU. + +The On-Demand Private Proxy Client model communicates with an On-Demand Private Proxy Server model +using the device key of the node containing the target On-Demand Private Proxy Server model instance. + +Configurations +************** + +The On-Demand Private Proxy Client model behavior can be configured with the transmission timeout option :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT`. +The :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT`controls how long the Client waits for a state response message to arrive +in milliseconds. This value can be changed at runtime using :c:func:`bt_mesh_od_priv_proxy_cli_timeout_set`. + API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/od_srv.rst b/doc/connectivity/bluetooth/api/mesh/od_srv.rst index 969100ed8118..241ce5f155cf 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_srv.rst @@ -3,7 +3,22 @@ On-Demand Private Proxy Server ############################## -On-Demand Private Proxy Server manages the On-Demand Private GATT Proxy state of the node that is a recipient of Solicitation PDUs. +The On-Demand Private Proxy Server model is a foundation model defined by the Bluetooth +mesh specification. It is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_SRV` option. + +The On-Demand Private Proxy Server model was introduced in the Bluetooth Mesh Protocol +Specification version 1.1, and supports the configuration of advertising with Private Network Identity type of a node +that is a recipient of Solicitation PDUs by managing its On-Demand Private GATT Proxy state. + +When enabled, the :ref:`bluetooth_mesh_srpl_srv` is also enabled. The On-Demand Private Proxy Server is dependent on the +:ref:`bluetooth_mesh_models_priv_beacon_srv` to be present on the node. + +The On-Demand Private Proxy Server does not have an API of its own, and relies on a +:ref:`bluetooth_mesh_od_cli` to control it. The On-Demand Private Proxy Server +model only accepts messages encrypted with the node's device key. + +If present, the On-Demand Private Proxy Server model must be instantiated on the primary +element. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/proxy.rst b/doc/connectivity/bluetooth/api/mesh/proxy.rst index 9c004909eb5b..87ee3b07f1d7 100644 --- a/doc/connectivity/bluetooth/api/mesh/proxy.rst +++ b/doc/connectivity/bluetooth/api/mesh/proxy.rst @@ -9,6 +9,52 @@ mesh network through GATT. The Proxy feature is only compiled in if the controlled by the :ref:`bluetooth_mesh_models_cfg_srv`, and the initial value can be set with :c:member:`bt_mesh_cfg_srv.gatt_proxy`. +Nodes with the Proxy feature enabled can advertise with Network Identity and Node Identity, +which is controlled by the :ref:`bluetooth_mesh_models_cfg_cli`. + +The GATT Proxy state indicates if the Proxy feature is supported. + +Private Proxy +************* + +A node supporting the Proxy feature and the :ref:`bluetooth_mesh_models_priv_beacon_srv` model can advertise with +Private Network Identity and Private Node Identity types, which is controlled by the +:ref:`bluetooth_mesh_models_priv_beacon_cli`. By advertising with this set of identification types, +the node allows the legacy device to connect to the network over GATT while maintaining the +privacy of the network. + +The Private GATT Proxy state indicates whether the Private Proxy functionality is supported. + +Proxy Solicitation +****************** + +In the case where both GATT Proxy and Private GATT Proxy states are disabled on a node, a legacy device cannot +connect to it. A node supporting the :ref:`bluetooth_mesh_od_srv` may however be +solicited to advertise connectable advertising events without enabling the Private GATT Proxy state. +To solicit the node, the legacy device can send a Solicitation PDU by calling the :func:`bt_mesh_proxy_solicit` function. +To enable this feature, the client must to be compiled with the :kconfig:option:`CONFIG_BT_MESH_PROXY_SOLICITATION` +option set. + +Solicitation PDUs are non-mesh, non-connectable, undirected advertising messages +containing Proxy Solicitation UUID, encrypted with the network key of the subnet that the legacy device +wants to connect to. The PDU contains the source address of the legacy device and a sequence number. The +sequence number is maintained by the legacy device and is incremented for every new Solicitation PDU sent. + +Each node supporting the Solicitation PDU reception holds its own Solicitation Replay Protection List (SRPL). +The SRPL protects the solicitation mechanism from replay attacks by storing solicitation sequence number (SSEQ) +and solicitation source (SSRC) pairs of valid Solicitation PDUs processed by the node. The delay between updating the +SRPL and storing the change to the persistent storage is defined by :kconfig:option:`CONFIG_BT_MESH_RPL_STORE_TIMEOUT`. + +The Solicitation PDU RPL Configuration models, :ref:`bluetooth_mesh_srpl_cli` and +:ref:`bluetooth_mesh_srpl_srv`, provide the functionality of saving and clearing SRPL entries. +A node that supports the Solicitation PDU RPL Configuration Client model can clear a section of the SRPL on the target by calling the :func:`bt_mesh_sol_pdu_rpl_clear` function. +Communication between the Solicitation PDU RPL Configuration Client and Server is encrypted using the application key, therefore, +the Solicitation PDU RPL Configuration Client can be instantiated on any device in the network. + +When the node receives the Solicitation PDU and successfully authenticates it, it will start +advertising connectable advertisements with the Private Network Identity type. The duration of the +advertisement can be configured by the On-Demand Private Proxy Client model. + API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index e1d1ec0f31d1..7a3f2e1b291e 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -1669,7 +1669,7 @@ The On-Demand Private GATT Proxy Client model is an optional mesh subsystem that ``mesh models od_priv_proxy od-priv-gatt-proxy [Dur(s)]`` --------------------------------------------------------- - Set the On-Demand Private GATT Proxy state on active target, or fetch the value of this state from it. This feature can be enabled through the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` configuration option. + Set the On-Demand Private GATT Proxy state on active target, or fetch the value of this state from it. * ``Dur``: If given, set the state of On-Demand Private GATT Proxy to this value in seconds. Fetch this value otherwise. @@ -1682,7 +1682,7 @@ The Solicitation PDU RPL Client model is an optional mesh subsystem that can be ``mesh models sol_pdu_rpl sol-pdu-rpl-clear [RngLen]`` ------------------------------------------------------------------------ - Clear active target's solicitation replay protection list (SRPL) in given range of solicitation source (SSRC) addresses. This feature can be enabled through the :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI` configuration option. + Clear active target's solicitation replay protection list (SRPL) in given range of solicitation source (SSRC) addresses. * ``RngStart``: Start address of the SSRC range. * ``Ackd``: This argument decides on whether an acknowledged or unacknowledged message will be sent. diff --git a/doc/connectivity/bluetooth/api/mesh/srpl.rst b/doc/connectivity/bluetooth/api/mesh/srpl.rst deleted file mode 100644 index 6d4a12aea77e..000000000000 --- a/doc/connectivity/bluetooth/api/mesh/srpl.rst +++ /dev/null @@ -1,16 +0,0 @@ -.. _bluetooth_mesh_srpl: - -Solicitation PDU RPL Configuration models -######################################### - -Solicitation PDU RPL Configuration models provide functionality for saving and clearing the solicitation replay protection list (SRPL). - -Solicitation RPL secures the solicitation mechanism from replay attacks by storing solicitation sequence number (SSEQ) and solicitation source (SSRC) pairs of valid Solicitation PDUs processed by a node. - -Solicitation PDU RPL Configuration models are: - -.. toctree:: - :maxdepth: 1 - - srpl_srv - srpl_cli diff --git a/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst b/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst index bed85d381ce3..e940158dd2ef 100644 --- a/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst @@ -3,7 +3,25 @@ Solicitation PDU RPL Configuration Client ######################################### -Solicitation PDU RPL Configuration Client model is used for clearing the solicitation replay protection list (SRPL) of a node that supports the Solicitation PDU RPL Configuration Server model. +The Solicitation PDU RPL Configuration Client model is a foundation model defined by the Bluetooth +mesh specification. The model is optional, and is enabled through the :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI` option. + +The Solicitation PDU RPL Configuration Client model was introduced in the Bluetooth Mesh Protocol +Specification version 1.1, and supports the functionality of removing addresses from the solicitation +replay protection list (SRPL) of a node that supports the :ref:`bluetooth_mesh_srpl_srv` model. + +The Solicitation PDU RPL Configuration Client model communicates with a Solicitation PDU RPL Configuration Server model +using the application keys configured by the Configuration Client. + +If present, the Solicitation PDU RPL Configuration Client model must be instantiated on the primary +element. + +Configurations +************** + +The Solicitation PDU RPL Configuration Client model behavior can be configured with the transmission timeout option :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT`. +The :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT` controls how long the Solicitation PDU RPL Configuration Client waits +for a response message to arrive in milliseconds. This value can be changed at runtime using :c:func:`bt_mesh_sol_pdu_rpl_cli_timeout_set`. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst b/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst index 4d87f754fa92..a8c5379e3052 100644 --- a/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst @@ -3,7 +3,24 @@ Solicitation PDU RPL Configuration Server ######################################### -Solicitation PDU RPL Configuration Server model manages the solicitation RPL saved on the device. +The Solicitation PDU RPL Configuration Server model is a foundation model defined by the Bluetooth +mesh specification. The model is enabled if the node has the :ref:`bluetooth_mesh_od_srv` enabled. + +The Solicitation PDU RPL Configuration Server model was introduced in the Bluetooth Mesh Protocol +Specification version 1.1, and manages the Solicitation Replay Protection List (SRPL) saved on the device. +The SRPL is used to reject Solicitation PDUs that are already processed by a node. When a valid Solicitation PDU message is +successfully processed by a node, the SSRC field and SSEQ field of the message are stored in the node's SRPL. + +The Solicitation PDU RPL Configuration Server does not have an API of its own, and relies on a :ref:`bluetooth_mesh_srpl_cli` to control it. +The model only accepts messages encrypted with an application key as configured by the Configuration Client. + +If present, the Solicitation PDU RPL Configuration Server model must be instantiated on the primary +element. + +Configurations +************** + +For the Solicitation PDU RPL Configuration Server model, the :kconfig:option:`CONFIG_BT_MESH_PROXY_SRPL_SIZE` option can be configured to set the size of the SRPL. API reference ************* diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 2c1ffb241c6e..9ac042f464c7 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1354,9 +1354,9 @@ config BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT default 5000 depends on BT_MESH_OD_PRIV_PROXY_CLI help - This timeout controls how long the Solicitation PDU RPL Configuration Client waits + This timeout controls how long the On-Demand Private Proxy Client waits for a response message to arrive. This value can be changed at runtime - using @ref bt_mesh_sol_pdu_rpl_cli_timeout_set. + using @ref bt_mesh_od_priv_proxy_cli_timeout_set. config BT_MESH_OD_PRIV_PROXY_SRV bool "Support for On-Demand Private Proxy Server model" From 341b076ee35b1320726e8e3d67cec0a2171c5c1e Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 27 Apr 2023 09:47:34 +0200 Subject: [PATCH 092/528] [nrf fromtree] Bluetooth: Mesh: Move storing of new prov data to settings work item This allows to move flash operations from the context that triggered bt_mesh_provision or bt_mesh_reprovision to the mesh settings work item that runs on the system workqueue. This is required to for a case where the mesh settings work item is running on a separate thread instead of the system workqueue to unblock the system workqueue eventually. Signed-off-by: Pavel Vasilyev (cherry picked from commit f3085ab95dda6dadbbdd23318f316ac64de5ee0a) (cherry picked from commit 80410b1cf4ee602b2806aa306054cdc74dbf1b2d) --- subsys/bluetooth/mesh/access.c | 15 +++++++++++++-- subsys/bluetooth/mesh/access.h | 5 +++-- subsys/bluetooth/mesh/main.c | 9 ++++----- subsys/bluetooth/mesh/net.c | 12 +++++++++--- subsys/bluetooth/mesh/net.h | 2 ++ subsys/bluetooth/mesh/settings.c | 8 +++++++- subsys/bluetooth/mesh/settings.h | 1 + 7 files changed, 39 insertions(+), 13 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index 30f1b9547671..d009837c167c 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -1905,7 +1905,7 @@ int bt_mesh_comp_change_prepare(void) return bt_mesh_comp_store(); } -void bt_mesh_comp_clear(void) +static void comp_data_clear(void) { int err; @@ -2073,7 +2073,7 @@ int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset) } #endif -void bt_mesh_models_metadata_clear(void) +static void models_metadata_clear(void) { int err; @@ -2087,6 +2087,17 @@ void bt_mesh_models_metadata_clear(void) atomic_clear_bit(bt_mesh.flags, BT_MESH_METADATA_DIRTY); } +void bt_mesh_comp_data_pending_clear(void) +{ + comp_data_clear(); + models_metadata_clear(); +} + +void bt_mesh_comp_data_clear(void) +{ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_COMP_PENDING); +} + int bt_mesh_models_metadata_change_prepare(void) { #if !IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 7c86de4282c4..86d7a2123440 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -62,13 +62,14 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); int bt_mesh_comp_register(const struct bt_mesh_comp *comp); int bt_mesh_comp_store(void); -void bt_mesh_comp_clear(void); int bt_mesh_comp_read(struct net_buf_simple *buf); int bt_mesh_models_metadata_store(void); -void bt_mesh_models_metadata_clear(void); int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset); +void bt_mesh_comp_data_pending_clear(void); +void bt_mesh_comp_data_clear(void); + void bt_mesh_model_pending_store(void); void bt_mesh_model_bind_store(struct bt_mesh_model *mod); void bt_mesh_model_sub_store(struct bt_mesh_model *mod); diff --git a/subsys/bluetooth/mesh/main.c b/subsys/bluetooth/mesh/main.c index 25de16bf1047..099ed2891123 100644 --- a/subsys/bluetooth/mesh/main.c +++ b/subsys/bluetooth/mesh/main.c @@ -130,7 +130,7 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_net_pending_net_store(); + bt_mesh_net_store(); } bt_mesh_start(); @@ -159,10 +159,9 @@ void bt_mesh_reprovision(uint16_t addr) if (IS_ENABLED(CONFIG_BT_SETTINGS)) { LOG_DBG("Storing network information persistently"); - bt_mesh_net_pending_net_store(); - bt_mesh_net_pending_seq_store(); - bt_mesh_comp_clear(); - bt_mesh_models_metadata_clear(); + bt_mesh_net_store(); + bt_mesh_net_seq_store(true); + bt_mesh_comp_data_clear(); } } diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index 88f91a1ac835..c60e1df758c0 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -189,9 +189,10 @@ static void store_iv(bool only_duration) } } -static void store_seq(void) +void bt_mesh_net_seq_store(bool force) { - if (CONFIG_BT_MESH_SEQ_STORE_RATE > 1 && + if (!force && + CONFIG_BT_MESH_SEQ_STORE_RATE > 1 && (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)) { return; } @@ -379,7 +380,7 @@ uint32_t bt_mesh_next_seq(void) uint32_t seq = bt_mesh.seq++; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - store_seq(); + bt_mesh_net_seq_store(false); } if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) && @@ -1185,6 +1186,11 @@ void bt_mesh_net_pending_seq_store(void) } } +void bt_mesh_net_store(void) +{ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING); +} + void bt_mesh_net_clear(void) { bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING); diff --git a/subsys/bluetooth/mesh/net.h b/subsys/bluetooth/mesh/net.h index 2d9309a0ff7d..02286b1ae403 100644 --- a/subsys/bluetooth/mesh/net.h +++ b/subsys/bluetooth/mesh/net.h @@ -303,6 +303,7 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi, void bt_mesh_net_loopback_clear(uint16_t net_idx); uint32_t bt_mesh_next_seq(void); +void bt_mesh_net_seq_store(bool force); void bt_mesh_net_init(void); void bt_mesh_net_header_parse(struct net_buf_simple *buf, @@ -312,6 +313,7 @@ void bt_mesh_net_pending_iv_store(void); void bt_mesh_net_pending_seq_store(void); void bt_mesh_net_dev_key_cand_store(void); +void bt_mesh_net_store(void); void bt_mesh_net_clear(void); void bt_mesh_net_settings_commit(void); diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 7413407681e3..89082264ea7a 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -115,7 +115,8 @@ SETTINGS_STATIC_HANDLER_DEFINE(bt_mesh, "bt/mesh", NULL, NULL, mesh_commit, BIT(BT_MESH_SETTINGS_CFG_PENDING) | \ BIT(BT_MESH_SETTINGS_MOD_PENDING) | \ BIT(BT_MESH_SETTINGS_VA_PENDING) | \ - BIT(BT_MESH_SETTINGS_SSEQ_PENDING)) + BIT(BT_MESH_SETTINGS_SSEQ_PENDING) | \ + BIT(BT_MESH_SETTINGS_COMP_PENDING)) void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) { @@ -197,6 +198,11 @@ static void store_pending(struct k_work *work) bt_mesh_cfg_pending_store(); } + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_COMP_PENDING)) { + bt_mesh_comp_data_pending_clear(); + } + if (atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_MOD_PENDING)) { bt_mesh_model_pending_store(); diff --git a/subsys/bluetooth/mesh/settings.h b/subsys/bluetooth/mesh/settings.h index ac019e2e60e8..10ce23d1106f 100644 --- a/subsys/bluetooth/mesh/settings.h +++ b/subsys/bluetooth/mesh/settings.h @@ -19,6 +19,7 @@ enum bt_mesh_settings_flag { BT_MESH_SETTINGS_CDB_PENDING, BT_MESH_SETTINGS_SRPL_PENDING, BT_MESH_SETTINGS_SSEQ_PENDING, + BT_MESH_SETTINGS_COMP_PENDING, BT_MESH_SETTINGS_FLAG_COUNT, }; From 585a48b38c1276522ac91628e819daf6faf332d5 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 27 Apr 2023 10:34:31 +0200 Subject: [PATCH 093/528] [nrf fromtree] Bluetooth: Mesh: Store device key candidate asynchronously This allows to move flash operations from the context that triggered storing device key candidate to the mesh settings work item that runs on the system workqueue. This is required to for a case where the mesh settings work item is running on a separate thread instead of the system workqueue to unblock the system workqueue eventually. Signed-off-by: Pavel Vasilyev (cherry picked from commit 1113c2efd47e4c9ccb2ac5193731aee62f39f022) (cherry picked from commit 80662a83e19275fad6aa17bc4d05dccd99e0b091) --- subsys/bluetooth/mesh/net.c | 11 +++++++++-- subsys/bluetooth/mesh/net.h | 2 ++ subsys/bluetooth/mesh/settings.c | 8 +++++++- subsys/bluetooth/mesh/settings.h | 1 + 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index c60e1df758c0..11412112ea43 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -1066,9 +1066,11 @@ static int dev_key_cand_set(const char *name, size_t len_rd, settings_read_cb re } BT_MESH_SETTINGS_DEFINE(dev_key, "DevKeyC", dev_key_cand_set); +#endif -void bt_mesh_net_dev_key_cand_store(void) +void bt_mesh_net_pending_dev_key_cand_store(void) { +#if defined(CONFIG_BT_MESH_RPR_SRV) int err; if (atomic_test_bit(bt_mesh.flags, BT_MESH_DEVKEY_CAND)) { @@ -1082,8 +1084,13 @@ void bt_mesh_net_dev_key_cand_store(void) } else { LOG_DBG("Stored DevKey candidate value"); } -} #endif +} + +void bt_mesh_net_dev_key_cand_store(void) +{ + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING); +} static void clear_iv(void) { diff --git a/subsys/bluetooth/mesh/net.h b/subsys/bluetooth/mesh/net.h index 02286b1ae403..84f5c8998e91 100644 --- a/subsys/bluetooth/mesh/net.h +++ b/subsys/bluetooth/mesh/net.h @@ -311,6 +311,8 @@ void bt_mesh_net_header_parse(struct net_buf_simple *buf, void bt_mesh_net_pending_net_store(void); void bt_mesh_net_pending_iv_store(void); void bt_mesh_net_pending_seq_store(void); + +void bt_mesh_net_pending_dev_key_cand_store(void); void bt_mesh_net_dev_key_cand_store(void); void bt_mesh_net_store(void); diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 89082264ea7a..56149cf70257 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -116,7 +116,8 @@ SETTINGS_STATIC_HANDLER_DEFINE(bt_mesh, "bt/mesh", NULL, NULL, mesh_commit, BIT(BT_MESH_SETTINGS_MOD_PENDING) | \ BIT(BT_MESH_SETTINGS_VA_PENDING) | \ BIT(BT_MESH_SETTINGS_SSEQ_PENDING) | \ - BIT(BT_MESH_SETTINGS_COMP_PENDING)) + BIT(BT_MESH_SETTINGS_COMP_PENDING) | \ + BIT(BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING)) void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) { @@ -188,6 +189,11 @@ static void store_pending(struct k_work *work) bt_mesh_net_pending_seq_store(); } + if (atomic_test_and_clear_bit(pending_flags, + BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING)) { + bt_mesh_net_pending_dev_key_cand_store(); + } + if (atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_HB_PUB_PENDING)) { bt_mesh_hb_pub_pending_store(); diff --git a/subsys/bluetooth/mesh/settings.h b/subsys/bluetooth/mesh/settings.h index 10ce23d1106f..bd6db9c3cdc2 100644 --- a/subsys/bluetooth/mesh/settings.h +++ b/subsys/bluetooth/mesh/settings.h @@ -20,6 +20,7 @@ enum bt_mesh_settings_flag { BT_MESH_SETTINGS_SRPL_PENDING, BT_MESH_SETTINGS_SSEQ_PENDING, BT_MESH_SETTINGS_COMP_PENDING, + BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING, BT_MESH_SETTINGS_FLAG_COUNT, }; From d764834a58c487d26975b26353de6b176675fe00 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 20 Apr 2023 17:35:44 +0200 Subject: [PATCH 094/528] [nrf fromtree] Bluetooth: Mesh: Use separate workq for storing mesh settings Currently mesh settings are stored in the system workqueue context. Most of other stack functionality, such that advertisements (incl relay), loopback, transport sar, beacons transmission, etc. is also processed in the system workqueue context. When a massive amount of data needs to be stored and in particularly when page erase needs to be triggered by GC of NVS subsystem to allocate flash pages, the execution of the stack (and other functionality that uses the system workqueue) will be blocked until storing is finished. For example, right after the provisioning of a erased device, a node may not be responsive for up to 400ms before it can continue sending messages. The waiting time may increase if there is a GATT connection in the mean time. When write or erase operation is triggered, the flash driver waits for Bluetooth controller to allocate a time needed to perform the operation. During the whole operation, the context from which the operation was triggered is put to sleep. This allows other threads to run until Bluetooth controller finds the time for the flash driver. In other words, every settings_save_one or settings_delete should be considered as rescheduling points. Considering this, Bluetooth mesh can use another thread to store its settings, thus releasing the system workqueue for other tasks including the operation of the stack itself. The consistency of the data to be stored is guaranteed by the current implementation where the data is copied to another struct before calling settings_save_one. The pending flag of a particular module is dropped in settings.c before starting to store the corresponding data. Thus, if during the sleep the node receives a message that triggers a change in a module which data is currently being stored, the pending flag will be restored and the new change will be stored eventually. Having this option enabled including with the partial erase, will make the node more responsive in the described situations. Signed-off-by: Pavel Vasilyev (cherry picked from commit e33a4ace0fcb4535256de1c91d2b9485b46e85d2) (cherry picked from commit 699623cc2bb936ecab0581eb54d993f99b12af3e) --- doc/connectivity/bluetooth/api/mesh/core.rst | 40 ++++++++++++++++++++ subsys/bluetooth/mesh/Kconfig | 28 ++++++++++++++ subsys/bluetooth/mesh/settings.c | 36 +++++++++++++++++- 3 files changed, 102 insertions(+), 2 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/core.rst b/doc/connectivity/bluetooth/api/mesh/core.rst index c06ce3771e2d..e27f29a31350 100644 --- a/doc/connectivity/bluetooth/api/mesh/core.rst +++ b/doc/connectivity/bluetooth/api/mesh/core.rst @@ -67,6 +67,46 @@ vulnerability and flash wear out. the RPL between reboots, will make the device vulnerable to replay attacks and not perform the replay protection required by the spec. +Persistent storage +****************** + +The mesh stack uses the :ref:`Settings Subsystem ` for storing the +device configuration persistently. When the stack configuration changes and +the change needs to be stored persistently, the stack schedules a work item. +The delay between scheduling the work item and submitting it to the workqueue +is defined by the :kconfig:option:`CONFIG_BT_MESH_STORE_TIMEOUT` option. Once +storing of data is scheduled, it can not be rescheduled until the work item is +processed. Exceptions are made in certain cases as described below. + +When IV index, Sequence Number or CDB configuration have to be stored, the work +item is submitted to the workqueue without the delay. If the work item was +previously scheduled, it will be rescheduled without the delay. + +The Replay Protection List uses the same work item to store RPL entries. If +storing of RPL entries is requested and no other configuration is pending to be +stored, the delay is set to :kconfig:option:`CONFIG_BT_MESH_RPL_STORE_TIMEOUT`. +If other stack configuration has to be stored, the delay defined by +the :kconfig:option:`CONFIG_BT_MESH_STORE_TIMEOUT` option is less than +:kconfig:option:`CONFIG_BT_MESH_RPL_STORE_TIMEOUT`, and the work item was +scheduled by the Replay Protection List, the work item will be rescheduled. + +When the work item is running, the stack will store all pending configuration, +including the RPL entries. + +Work item execution context +=========================== + +The :kconfig:option:`CONFIG_BT_MESH_SETTINGS_WORKQ` option configures the +context from which the work item is executed. This option is enabled by +default, and results in stack using a dedicated cooperative thread to +process the work item. This allows the stack to process other incoming and +outgoing messages, as well as other work items submitted to the system +workqueue, while the stack configuration is being stored. + +When this option is disabled, the work item is submitted to the system workqueue. +This means that the system workqueue is blocked for the time it takes to store +the stack's configuration. It is not recommended to disable this option as this +will make the device non-responsive for a noticeable amount of time. API reference ************** diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 9ac042f464c7..3957fd4e1f16 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1584,6 +1584,34 @@ config BT_MESH_SEQ_STORE_RATE off with a value that's guaranteed to be larger than the last one used before power off. +config BT_MESH_SETTINGS_WORKQ + bool "Store the Bluetooth mesh settings in a separate work queue" + default y + help + This option enables a separate cooperative thread which is used to + store Bluetooth mesh configuration. When this option is disabled, + the stack's configuration is stored in the system workqueue. This + means that the system workqueue will be blocked for the time needed + to store the pending data. This time may significantly increase if + the flash driver does the erase operation. Enabling this option + allows Bluetooth mesh not to block the system workqueue, and thus + process the incoming and outgoing messages while the flash driver + waits for the controller to allocate the time needed to write the + data and/or erase the required flash pages. + +if BT_MESH_SETTINGS_WORKQ + +config BT_MESH_SETTINGS_WORKQ_PRIO + int + default 1 + +config BT_MESH_SETTINGS_WORKQ_STACK_SIZE + int "Stack size of the settings workq" + default 880 + help + Size of the settings workqueue stack. + +endif # BT_MESH_SETTINGS_WORKQ endif # BT_SETTINGS if BT_MESH_LOG_LEVEL_DBG diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 56149cf70257..2c3ef3bc9022 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -40,6 +40,21 @@ LOG_MODULE_REGISTER(bt_mesh_settings); #define RPL_STORE_TIMEOUT (-1) #endif +#ifdef CONFIG_BT_MESH_SETTINGS_WORKQ_PRIO +#define SETTINGS_WORKQ_PRIO CONFIG_BT_MESH_SETTINGS_WORKQ_PRIO +#else +#define SETTINGS_WORKQ_PRIO 1 +#endif + +#ifdef CONFIG_BT_MESH_SETTINGS_WORKQ_STACK_SIZE +#define SETTINGS_WORKQ_STACK_SIZE CONFIG_BT_MESH_SETTINGS_WORKQ_STACK_SIZE +#else +#define SETTINGS_WORKQ_STACK_SIZE 0 +#endif + +static struct k_work_q settings_work_q; +static K_THREAD_STACK_DEFINE(settings_work_stack, SETTINGS_WORKQ_STACK_SIZE); + static struct k_work_delayable pending_store; static ATOMIC_DEFINE(pending_flags, BT_MESH_SETTINGS_FLAG_COUNT); @@ -144,9 +159,19 @@ void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) * deadline. */ if (timeout_ms < remaining_ms) { - k_work_reschedule(&pending_store, K_MSEC(timeout_ms)); + if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) { + k_work_reschedule_for_queue(&settings_work_q, &pending_store, + K_MSEC(timeout_ms)); + } else { + k_work_reschedule(&pending_store, K_MSEC(timeout_ms)); + } } else { - k_work_schedule(&pending_store, K_MSEC(timeout_ms)); + if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) { + k_work_schedule_for_queue(&settings_work_q, &pending_store, + K_MSEC(timeout_ms)); + } else { + k_work_schedule(&pending_store, K_MSEC(timeout_ms)); + } } } @@ -240,6 +265,13 @@ static void store_pending(struct k_work *work) void bt_mesh_settings_init(void) { + if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) { + k_work_queue_start(&settings_work_q, settings_work_stack, + K_THREAD_STACK_SIZEOF(settings_work_stack), + K_PRIO_COOP(SETTINGS_WORKQ_PRIO), NULL); + k_thread_name_set(&settings_work_q.thread, "BT Mesh settings workq"); + } + k_work_init_delayable(&pending_store, store_pending); } From dd149c1d2f95eff1f881c753f03947dded8680a5 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Thu, 20 Apr 2023 18:09:02 +0200 Subject: [PATCH 095/528] [nrf fromtree] Bluetooth: Mesh: Add API to store model's user data in settings work Mesh models may have a data that needs to be stored persistently. Currently, the models should call bt_mesh_model_data_store and the store will happen in the calling context. Most likely that it will be called in BT RX thread as this is the context from which model's opcodes handlers are called. Thus, the thread will be blocked until the store is finished. Another issues is that some models may have states that changes frequently. Triggering the store on every state change may wear out flash. Therefore, the models need to implement some postpone mechanism to reduce the flash wear out. The mesh stack has already implemented the mechanism of deferred store with its own settings. The models could use it instead of implementing their own mechanism. In combination with the mesh settings workqueue, the models can store their data without blocking the stack work. Signed-off-by: Pavel Vasilyev (cherry picked from commit 177e9b93bf0595b70f04100ea6a19d2d05da0914) (cherry picked from commit 08068d0db9f2d81064d0c0023753352cd937ba8a) --- .../bluetooth/api/mesh/access.rst | 16 +++++++++++++ include/zephyr/bluetooth/mesh/access.h | 23 +++++++++++++++++++ subsys/bluetooth/mesh/access.c | 11 +++++++++ subsys/bluetooth/mesh/access.h | 1 + 4 files changed, 51 insertions(+) diff --git a/doc/connectivity/bluetooth/api/mesh/access.rst b/doc/connectivity/bluetooth/api/mesh/access.rst index 06236f98cb67..37d5d6fddef8 100644 --- a/doc/connectivity/bluetooth/api/mesh/access.rst +++ b/doc/connectivity/bluetooth/api/mesh/access.rst @@ -149,6 +149,22 @@ storage. The model can retrieve the data by calling the ``read_cb`` passed as a parameter to the callback. See the :ref:`settings_api` module documentation for details. +When model data changes frequently, storing it on every change may lead to +increased wear of flash. To reduce the wear, the model can postpone storing of +data by calling :c:func:`bt_mesh_model_data_store_schedule`. The stack will +schedule a work item with delay defined by the +:kconfig:option:`CONFIG_BT_MESH_STORE_TIMEOUT` option. When the work item is +running, the stack will call the :c:member:`bt_mesh_model_cb.pending_store` +callback for every model that has requested storing of data. The model can +then call :c:func:`bt_mesh_model_data_store` to store the data. + +If :kconfig:option:`CONFIG_BT_MESH_SETTINGS_WORKQ` is enabled, the +:c:member:`bt_mesh_model_cb.pending_store` callback is called from a dedicated +thread. This allows the stack to process other incoming and outgoing messages +while model data is being stored. It is recommended to use this option and the +:c:func:`bt_mesh_model_data_store_schedule` function when large amount of data +needs to be stored. + API reference ************* diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 80e3948f1eb4..75fa81c90893 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -662,6 +662,16 @@ struct bt_mesh_model_cb { * @param model Model this callback belongs to. */ void (*const reset)(struct bt_mesh_model *model); + + /** @brief Callback used to store pending model's user data. + * + * Triggered by @ref bt_mesh_model_data_store_schedule. + * + * To store the user data, call @ref bt_mesh_model_data_store. + * + * @param model Model this callback belongs to. + */ + void (*const pending_store)(struct bt_mesh_model *model); }; /** Vendor model ID */ @@ -842,6 +852,19 @@ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, const char *name, const void *data, size_t data_len); +/** @brief Schedule the model's user data store in persistent storage. + * + * This function triggers the @ref bt_mesh_model_cb.pending_store callback + * for the corresponding model after delay defined by + * @kconfig{CONFIG_BT_MESH_STORE_TIMEOUT}. + * + * The delay is global for all models. Once scheduled, the callback can + * not be re-scheduled until previous schedule completes. + * + * @param mod Mesh model. + */ +void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod); + /** @brief Let a model extend another. * * Mesh models may be extended to reuse their functionality, forming a more diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index d009837c167c..d8ba60cbb46f 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -1850,6 +1850,11 @@ static void store_pending_mod(struct bt_mesh_model *mod, mod->flags &= ~BT_MESH_MOD_PUB_PENDING; store_pending_mod_pub(mod, vnd); } + + if (mod->flags & BT_MESH_MOD_DATA_PENDING) { + mod->flags &= ~BT_MESH_MOD_DATA_PENDING; + mod->cb->pending_store(mod); + } } void bt_mesh_model_pending_store(void) @@ -2134,3 +2139,9 @@ void bt_mesh_model_settings_commit(void) { bt_mesh_model_foreach(commit_mod, NULL); } + +void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod) +{ + mod->flags |= BT_MESH_MOD_DATA_PENDING; + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); +} diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 86d7a2123440..43ec18391600 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -17,6 +17,7 @@ enum { BT_MESH_MOD_PUB_PENDING = BIT(2), BT_MESH_MOD_EXTENDED = BIT(3), BT_MESH_MOD_DEVKEY_ONLY = BIT(4), + BT_MESH_MOD_DATA_PENDING = BIT(5), }; void bt_mesh_elem_register(struct bt_mesh_elem *elem, uint8_t count); From dab6fbfc28872a36326b9d83f6af032b4a8444d9 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 26 Apr 2023 19:28:00 +0200 Subject: [PATCH 096/528] [nrf fromtree] Bluetooth: Mesh: Remove outdated RPL entries in settings work item This allows to move flash operations from the context that triggered IVI update to the mesh settings work item that runs on the system workqueue. After this change, the outdated RPL entries will be removed in the setting work item triggered by store_pending function in mesh/settings.c. This is required to for a case where the mesh settings work item is running on a separate thread instead of the system workqueue to unblock the system workqueue eventually. Signed-off-by: Pavel Vasilyev (cherry picked from commit 1fdf2835312aa02cf227ca21f1f7d3fee880f84e) (cherry picked from commit d80d5a5866cf09fd534ad2bc18979c0656c88597) --- subsys/bluetooth/mesh/rpl.c | 156 +++++++++++++++++++++++++----------- 1 file changed, 107 insertions(+), 49 deletions(-) diff --git a/subsys/bluetooth/mesh/rpl.c b/subsys/bluetooth/mesh/rpl.c index d055f278e4fc..717bd11242f1 100644 --- a/subsys/bluetooth/mesh/rpl.c +++ b/subsys/bluetooth/mesh/rpl.c @@ -37,7 +37,12 @@ struct rpl_val { static struct bt_mesh_rpl replay_list[CONFIG_BT_MESH_CRPL]; static ATOMIC_DEFINE(store, CONFIG_BT_MESH_CRPL); -static atomic_t clear; + +enum { + PENDING_CLEAR, + PENDING_RESET, +}; +static atomic_t rpl_flags; static inline int rpl_idx(const struct bt_mesh_rpl *rpl) { @@ -53,6 +58,8 @@ static void clear_rpl(struct bt_mesh_rpl *rpl) return; } + atomic_clear_bit(store, rpl_idx(rpl)); + snprintk(path, sizeof(path), "bt/mesh/RPL/%x", rpl->src); err = settings_delete(path); if (err) { @@ -60,9 +67,6 @@ static void clear_rpl(struct bt_mesh_rpl *rpl) } else { LOG_DBG("Cleared RPL"); } - - (void)memset(rpl, 0, sizeof(*rpl)); - atomic_clear_bit(store, rpl_idx(rpl)); } static void schedule_rpl_store(struct bt_mesh_rpl *entry, bool force) @@ -105,6 +109,7 @@ void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match) { + struct bt_mesh_rpl *rpl; int i; /* Don't bother checking messages from ourselves */ @@ -118,34 +123,33 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, } for (i = 0; i < ARRAY_SIZE(replay_list); i++) { - struct bt_mesh_rpl *rpl = &replay_list[i]; + rpl = &replay_list[i]; /* Empty slot */ if (!rpl->src) { - if (match) { - *match = rpl; - } else { - bt_mesh_rpl_update(rpl, rx); - } - - return false; + goto match; } /* Existing slot for given address */ if (rpl->src == rx->ctx.addr) { + if (!rpl->old_iv && + atomic_test_bit(&rpl_flags, PENDING_RESET) && + !atomic_test_bit(store, i)) { + /* Until rpl reset is finished, entry with old_iv == false and + * without "store" bit set will be removed, therefore it can be + * reused. If such entry is reused, "store" bit will be set and + * the entry won't be removed. + */ + goto match; + } + if (rx->old_iv && !rpl->old_iv) { return true; } if ((!rx->old_iv && rpl->old_iv) || rpl->seq < rx->seq) { - if (match) { - *match = rpl; - } else { - bt_mesh_rpl_update(rpl, rx); - } - - return false; + goto match; } else { return true; } @@ -154,6 +158,15 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, LOG_ERR("RPL is full!"); return true; + +match: + if (match) { + *match = rpl; + } else { + bt_mesh_rpl_update(rpl, rx); + } + + return false; } void bt_mesh_rpl_clear(void) @@ -165,7 +178,7 @@ void bt_mesh_rpl_clear(void) return; } - (void)atomic_cas(&clear, 0, 1); + atomic_set_bit(&rpl_flags, PENDING_CLEAR); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); } @@ -199,41 +212,56 @@ static struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src) void bt_mesh_rpl_reset(void) { - int shift = 0; - int last = 0; - /* Discard "old old" IV Index entries from RPL and flag * any other ones (which are valid) as old. */ - for (int i = 0; i < ARRAY_SIZE(replay_list); i++) { - struct bt_mesh_rpl *rpl = &replay_list[i]; + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + int i; - if (rpl->src) { - if (rpl->old_iv) { - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - clear_rpl(rpl); - } else { + for (i = 0; i < ARRAY_SIZE(replay_list); i++) { + struct bt_mesh_rpl *rpl = &replay_list[i]; + + if (!rpl->src) { + continue; + } + + /* Entries with "store" bit set will be stored, other entries will be + * removed. + */ + atomic_set_bit_to(store, i, !rpl->old_iv); + rpl->old_iv = !rpl->old_iv; + } + + if (i != 0) { + atomic_set_bit(&rpl_flags, PENDING_RESET); + bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); + } + } else { + int shift = 0; + int last = 0; + + for (int i = 0; i < ARRAY_SIZE(replay_list); i++) { + struct bt_mesh_rpl *rpl = &replay_list[i]; + + if (rpl->src) { + if (rpl->old_iv) { (void)memset(rpl, 0, sizeof(*rpl)); - } - shift++; - } else { - rpl->old_iv = true; + shift++; + } else { + rpl->old_iv = true; - if (shift > 0) { - replay_list[i - shift] = *rpl; + if (shift > 0) { + replay_list[i - shift] = *rpl; + } } - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - schedule_rpl_store(&replay_list[i - shift], true); - } + last = i; } - - last = i; } - } - (void) memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift); + (void)memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift); + } } static int rpl_set(const char *name, size_t len_rd, @@ -315,7 +343,10 @@ static void store_rpl(struct bt_mesh_rpl *entry) void bt_mesh_rpl_pending_store(uint16_t addr) { + int shift = 0; + int last = 0; bool clr; + bool rst; if (!IS_ENABLED(CONFIG_BT_SETTINGS) || (!BT_MESH_ADDR_IS_UNICAST(addr) && @@ -327,22 +358,49 @@ void bt_mesh_rpl_pending_store(uint16_t addr) bt_mesh_settings_store_cancel(BT_MESH_SETTINGS_RPL_PENDING); } - clr = atomic_cas(&clear, 1, 0); + clr = atomic_test_and_clear_bit(&rpl_flags, PENDING_CLEAR); + rst = atomic_test_bit(&rpl_flags, PENDING_RESET); for (int i = 0; i < ARRAY_SIZE(replay_list); i++) { - if (addr != BT_MESH_ADDR_ALL_NODES && - addr != replay_list[i].src) { + struct bt_mesh_rpl *rpl = &replay_list[i]; + + if (addr != BT_MESH_ADDR_ALL_NODES && addr != rpl->src) { continue; } if (clr) { - clear_rpl(&replay_list[i]); - } else if (atomic_test_and_clear_bit(store, rpl_idx(&replay_list[i]))) { - store_rpl(&replay_list[i]); + clear_rpl(rpl); + shift++; + } else if (atomic_test_and_clear_bit(store, i)) { + if (shift > 0) { + replay_list[i - shift] = *rpl; + } + + store_rpl(&replay_list[i - shift]); + } else if (rst) { + clear_rpl(rpl); + + /* Check if this entry was re-used during removal. If so, shift it as well. + * Otherwise, increment shift counter. + */ + if (atomic_test_and_clear_bit(store, i)) { + replay_list[i - shift] = *rpl; + atomic_set_bit(store, i - shift); + } else { + shift++; + } } + last = i; + if (addr != BT_MESH_ADDR_ALL_NODES) { break; } } + + atomic_test_and_clear_bit(&rpl_flags, PENDING_RESET); + + if (addr == BT_MESH_ADDR_ALL_NODES) { + (void)memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift); + } } From d121698904a177644f7bbeec5f7460f2b42b0f3d Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Fri, 31 Mar 2023 14:40:39 +0100 Subject: [PATCH 097/528] [nrf fromtree] drivers: sensor: npm1300_charger: NPM1300 charger driver Initial sensor driver for NPM1300 PMIC charger. Includes basic configuration of charger voltage and current. Signed-off-by: Andy Sinclair (cherry picked from commit d700ab5a889bb486ed1c0f0141f84124f28b5cc9) (cherry picked from commit 4130ca093cf926121db111e8a6271c818736e2d0) --- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 2 + drivers/sensor/npm1300_charger/CMakeLists.txt | 7 + drivers/sensor/npm1300_charger/Kconfig | 12 + .../sensor/npm1300_charger/npm1300_charger.c | 421 ++++++++++++++++++ .../sensor/nordic,npm1300-charger.yaml | 68 +++ .../zephyr/drivers/sensor/npm1300_charger.h | 17 + 7 files changed, 528 insertions(+) create mode 100644 drivers/sensor/npm1300_charger/CMakeLists.txt create mode 100644 drivers/sensor/npm1300_charger/Kconfig create mode 100644 drivers/sensor/npm1300_charger/npm1300_charger.c create mode 100644 dts/bindings/sensor/nordic,npm1300-charger.yaml create mode 100644 include/zephyr/drivers/sensor/npm1300_charger.h diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index d895d3190beb..d9bb2b5fc89e 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -83,6 +83,7 @@ add_subdirectory_ifdef(CONFIG_MPU6050 mpu6050) add_subdirectory_ifdef(CONFIG_MPU9250 mpu9250) add_subdirectory_ifdef(CONFIG_MS5607 ms5607) add_subdirectory_ifdef(CONFIG_MS5837 ms5837) +add_subdirectory_ifdef(CONFIG_NPM1300_CHARGER npm1300_charger) add_subdirectory_ifdef(CONFIG_OPT3001 opt3001) add_subdirectory_ifdef(CONFIG_PMS7003 pms7003) add_subdirectory_ifdef(CONFIG_QDEC_MCUX qdec_mcux) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 449de52c82ec..a00e01e47965 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -209,6 +209,8 @@ source "drivers/sensor/ms5837/Kconfig" source "drivers/sensor/ms5607/Kconfig" +source "drivers/sensor/npm1300_charger/Kconfig" + source "drivers/sensor/nrf5/Kconfig" source "drivers/sensor/opt3001/Kconfig" diff --git a/drivers/sensor/npm1300_charger/CMakeLists.txt b/drivers/sensor/npm1300_charger/CMakeLists.txt new file mode 100644 index 000000000000..51083775eff7 --- /dev/null +++ b/drivers/sensor/npm1300_charger/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library() + +zephyr_library_sources(npm1300_charger.c) diff --git a/drivers/sensor/npm1300_charger/Kconfig b/drivers/sensor/npm1300_charger/Kconfig new file mode 100644 index 000000000000..12a3e6937cf5 --- /dev/null +++ b/drivers/sensor/npm1300_charger/Kconfig @@ -0,0 +1,12 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + +config NPM1300_CHARGER + bool "NPM1300 Charger" + default y + depends on DT_HAS_NORDIC_NPM1300_CHARGER_ENABLED + select I2C + select REQUIRES_FULL_LIBC + help + Enable NPM1300 charger driver. diff --git a/drivers/sensor/npm1300_charger/npm1300_charger.c b/drivers/sensor/npm1300_charger/npm1300_charger.c new file mode 100644 index 000000000000..8a5ff935777d --- /dev/null +++ b/drivers/sensor/npm1300_charger/npm1300_charger.c @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nordic_npm1300_charger + +#include +#include +#include +#include +#include +#include + +struct npm1300_charger_config { + struct i2c_dt_spec i2c; + int32_t term_microvolt; + int32_t term_warm_microvolt; + int32_t current_microamp; + int32_t dischg_limit_microamp; + int32_t vbus_limit_microamp; + uint8_t thermistor_idx; + uint16_t thermistor_beta; + bool charging_enable; +}; + +struct npm1300_charger_data { + uint16_t voltage; + uint16_t current; + uint16_t temp; + uint8_t status; + uint8_t error; + uint8_t ibat_stat; + uint8_t vbus_stat; +}; + +/* nPM1300 base addresses */ +#define CHGR_BASE 0x03U +#define ADC_BASE 0x05U +#define VBUS_BASE 0x02U + +/* nPM1300 charger register offsets */ +#define CHGR_OFFSET_EN_SET 0x04U +#define CHGR_OFFSET_EN_CLR 0x05U +#define CHGR_OFFSET_ISET 0x08U +#define CHGR_OFFSET_ISET_DISCHG 0x0AU +#define CHGR_OFFSET_VTERM 0x0CU +#define CHGR_OFFSET_VTERM_R 0x0DU +#define CHGR_OFFSET_CHG_STAT 0x34U +#define CHGR_OFFSET_ERR_REASON 0x36U + +/* nPM1300 ADC register offsets */ +#define ADC_OFFSET_TASK_VBAT 0x00U +#define ADC_OFFSET_TASK_TEMP 0x01U +#define ADC_OFFSET_CONFIG 0x09U +#define ADC_OFFSET_NTCR_SEL 0x0AU +#define ADC_OFFSET_RESULTS 0x10U +#define ADC_OFFSET_IBAT_EN 0x24U + +/* nPM1300 VBUS register offsets */ +#define VBUS_OFFSET_TASK_UPDATE 0x00U +#define VBUS_OFFSET_ILIM 0x01U +#define VBUS_OFFSET_STATUS 0x07U + +/* Ibat status */ +#define IBAT_STAT_DISCHARGE 0x04U +#define IBAT_STAT_CHARGE_TRICKLE 0x0CU +#define IBAT_STAT_CHARGE_COOL 0x0DU +#define IBAT_STAT_CHARGE_NORMAL 0x0FU + +struct adc_results_t { + uint8_t ibat_stat; + uint8_t msb_vbat; + uint8_t msb_ntc; + uint8_t msb_die; + uint8_t msb_vsys; + uint8_t lsb_a; + uint8_t reserved1; + uint8_t reserved2; + uint8_t msb_ibat; + uint8_t msb_vbus; + uint8_t lsb_b; +} __packed; + +/* ADC result masks */ +#define ADC_MSB_SHIFT 2U +#define ADC_LSB_MASK 0x03U +#define ADC_LSB_VBAT_SHIFT 0U +#define ADC_LSB_NTC_SHIFT 2U +#define ADC_LSB_IBAT_SHIFT 4U + +/* Linear range for charger terminal voltage */ +static const struct linear_range charger_volt_ranges[] = { + LINEAR_RANGE_INIT(3500000, 50000, 0U, 3U), LINEAR_RANGE_INIT(4000000, 50000, 4U, 13U)}; + +/* Linear range for charger current */ +static const struct linear_range charger_current_range = LINEAR_RANGE_INIT(32000, 2000, 16U, 400U); + +/* Linear range for Discharge limit */ +static const struct linear_range discharge_limit_range = LINEAR_RANGE_INIT(268090, 3230, 83U, 415U); + +/* Linear range for vbusin current limit */ +static const struct linear_range vbus_current_ranges[] = { + LINEAR_RANGE_INIT(100000, 0, 1U, 1U), LINEAR_RANGE_INIT(500000, 100000, 5U, 15U)}; + +/* Read multiple registers from specified address */ +static int reg_read_burst(const struct device *dev, uint8_t base, uint8_t offset, void *data, + size_t len) +{ + const struct npm1300_charger_config *const config = dev->config; + uint8_t buff[] = {base, offset}; + + return i2c_write_read_dt(&config->i2c, buff, sizeof(buff), data, len); +} + +static int reg_read(const struct device *dev, uint8_t base, uint8_t offset, uint8_t *data) +{ + return reg_read_burst(dev, base, offset, data, 1U); +} + +/* Write single register to specified address */ +static int reg_write(const struct device *dev, uint8_t base, uint8_t offset, uint8_t data) +{ + const struct npm1300_charger_config *const config = dev->config; + uint8_t buff[] = {base, offset, data}; + + return i2c_write_dt(&config->i2c, buff, sizeof(buff)); +} + +static int reg_write2(const struct device *dev, uint8_t base, uint8_t offset, uint8_t data1, + uint8_t data2) +{ + const struct npm1300_charger_config *const config = dev->config; + uint8_t buff[] = {base, offset, data1, data2}; + + return i2c_write_dt(&config->i2c, buff, sizeof(buff)); +} + +static void calc_temp(const struct npm1300_charger_config *const config, uint16_t code, + struct sensor_value *valp) +{ + /* Ref: Datasheet Figure 42: Battery temperature (Kelvin) */ + float log_result = log((1024.f / (float)code) - 1); + float inv_temp_k = (1.f / 298.15f) - (log_result / (float)config->thermistor_beta); + + float temp = (1.f / inv_temp_k) - 273.15f; + + valp->val1 = (int32_t)temp; + valp->val2 = (int32_t)(fmodf(temp, 1.f) * 1000000.f); +} + +static uint16_t adc_get_res(uint8_t msb, uint8_t lsb, uint16_t lsb_shift) +{ + return ((uint16_t)msb << ADC_MSB_SHIFT) | ((lsb >> lsb_shift) & ADC_LSB_MASK); +} + +static void calc_current(const struct npm1300_charger_config *const config, + struct npm1300_charger_data *const data, struct sensor_value *valp) +{ + int32_t full_scale_ma; + int32_t current; + + switch (data->ibat_stat) { + case IBAT_STAT_DISCHARGE: + full_scale_ma = config->dischg_limit_microamp / 1000; + break; + case IBAT_STAT_CHARGE_TRICKLE: + full_scale_ma = -config->current_microamp / 10000; + break; + case IBAT_STAT_CHARGE_COOL: + full_scale_ma = -config->current_microamp / 2000; + break; + case IBAT_STAT_CHARGE_NORMAL: + full_scale_ma = -config->current_microamp / 1000; + break; + default: + full_scale_ma = 0; + break; + } + + current = (data->current * full_scale_ma) / 1024; + + valp->val1 = current / 1000; + valp->val2 = (current % 1000) * 1000; +} + +int npm1300_charger_channel_get(const struct device *dev, enum sensor_channel chan, + struct sensor_value *valp) +{ + const struct npm1300_charger_config *const config = dev->config; + struct npm1300_charger_data *const data = dev->data; + int32_t tmp; + + switch ((uint32_t)chan) { + case SENSOR_CHAN_GAUGE_VOLTAGE: + tmp = data->voltage * 5000 / 1024; + valp->val1 = tmp / 1000; + valp->val2 = (tmp % 1000) * 1000; + break; + case SENSOR_CHAN_GAUGE_TEMP: + calc_temp(config, data->temp, valp); + break; + case SENSOR_CHAN_GAUGE_AVG_CURRENT: + calc_current(config, data, valp); + break; + case SENSOR_CHAN_NPM1300_CHARGER_STATUS: + valp->val1 = data->status; + valp->val2 = 0; + break; + case SENSOR_CHAN_NPM1300_CHARGER_ERROR: + valp->val1 = data->error; + valp->val2 = 0; + break; + case SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT: + valp->val1 = config->current_microamp / 1000000; + valp->val2 = config->current_microamp % 1000000; + break; + case SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT: + valp->val1 = config->dischg_limit_microamp / 1000000; + valp->val2 = config->dischg_limit_microamp % 1000000; + break; + default: + return -ENOTSUP; + } + + return 0; +} + +int npm1300_charger_sample_fetch(const struct device *dev, enum sensor_channel chan) +{ + struct npm1300_charger_data *data = dev->data; + struct adc_results_t results; + bool last_vbus; + int ret; + + /* Read charge status and error reason */ + ret = reg_read(dev, CHGR_BASE, CHGR_OFFSET_CHG_STAT, &data->status); + if (ret != 0) { + return ret; + } + + ret = reg_read(dev, CHGR_BASE, CHGR_OFFSET_ERR_REASON, &data->error); + if (ret != 0) { + return ret; + } + + /* Read adc results */ + ret = reg_read_burst(dev, ADC_BASE, ADC_OFFSET_RESULTS, &results, sizeof(results)); + if (ret != 0) { + return ret; + } + + data->voltage = adc_get_res(results.msb_vbat, results.lsb_a, ADC_LSB_VBAT_SHIFT); + data->temp = adc_get_res(results.msb_ntc, results.lsb_a, ADC_LSB_NTC_SHIFT); + data->current = adc_get_res(results.msb_ibat, results.lsb_b, ADC_LSB_IBAT_SHIFT); + data->ibat_stat = results.ibat_stat; + + /* Trigger temperature measurement */ + ret = reg_write(dev, ADC_BASE, ADC_OFFSET_TASK_TEMP, 1U); + if (ret != 0) { + return ret; + } + + /* Trigger current and voltage measurement */ + ret = reg_write(dev, ADC_BASE, ADC_OFFSET_TASK_VBAT, 1U); + if (ret != 0) { + return ret; + } + + /* Read vbus status, and set SW current limit on new vbus detection */ + last_vbus = (data->vbus_stat & 1U) != 0U; + ret = reg_read(dev, VBUS_BASE, VBUS_OFFSET_STATUS, &data->vbus_stat); + if (ret != 0) { + return ret; + } + + if (!last_vbus && ((data->vbus_stat & 1U) != 0U)) { + ret = reg_write(dev, VBUS_BASE, VBUS_OFFSET_TASK_UPDATE, 1U); + + if (ret != 0) { + return ret; + } + } + + return ret; +} + +int npm1300_charger_init(const struct device *dev) +{ + const struct npm1300_charger_config *const config = dev->config; + uint16_t idx; + int ret; + + if (!i2c_is_ready_dt(&config->i2c)) { + return -ENODEV; + } + + /* Configure thermistor */ + ret = reg_write(dev, ADC_BASE, ADC_OFFSET_NTCR_SEL, config->thermistor_idx + 1U); + if (ret != 0) { + return ret; + } + + /* Configure termination voltages */ + ret = linear_range_group_get_win_index(charger_volt_ranges, ARRAY_SIZE(charger_volt_ranges), + config->term_microvolt, config->term_microvolt, + &idx); + if (ret == -EINVAL) { + return ret; + } + ret = reg_write(dev, CHGR_BASE, CHGR_OFFSET_VTERM, idx); + if (ret != 0) { + return ret; + } + + ret = linear_range_group_get_win_index(charger_volt_ranges, ARRAY_SIZE(charger_volt_ranges), + config->term_warm_microvolt, + config->term_warm_microvolt, &idx); + if (ret == -EINVAL) { + return ret; + } + + ret = reg_write(dev, CHGR_BASE, CHGR_OFFSET_VTERM_R, idx); + if (ret != 0) { + return ret; + } + + /* Set current, allow rounding down to closest value */ + ret = linear_range_get_win_index(&charger_current_range, + config->current_microamp - charger_current_range.step, + config->current_microamp, &idx); + if (ret == -EINVAL) { + return ret; + } + + ret = reg_write2(dev, CHGR_BASE, CHGR_OFFSET_ISET, idx / 2U, idx & 1U); + if (ret != 0) { + return ret; + } + + /* Set discharge limit, allow rounding down to closest value */ + ret = linear_range_get_win_index(&discharge_limit_range, + config->dischg_limit_microamp - discharge_limit_range.step, + config->dischg_limit_microamp, &idx); + if (ret == -EINVAL) { + return ret; + } + + ret = reg_write2(dev, CHGR_BASE, CHGR_OFFSET_ISET_DISCHG, idx / 2U, idx & 1U); + if (ret != 0) { + return ret; + } + + /* Configure vbus current limit */ + ret = linear_range_group_get_win_index(vbus_current_ranges, ARRAY_SIZE(vbus_current_ranges), + config->vbus_limit_microamp, + config->vbus_limit_microamp, &idx); + if (ret == -EINVAL) { + return ret; + } + ret = reg_write(dev, VBUS_BASE, VBUS_OFFSET_ILIM, idx); + if (ret != 0) { + return ret; + } + + /* Enable current measurement */ + ret = reg_write(dev, ADC_BASE, ADC_OFFSET_IBAT_EN, 1U); + if (ret != 0) { + return ret; + } + + /* Trigger current and voltage measurement */ + ret = reg_write(dev, ADC_BASE, ADC_OFFSET_TASK_VBAT, 1U); + if (ret != 0) { + return ret; + } + + /* Trigger temperature measurement */ + ret = reg_write(dev, ADC_BASE, ADC_OFFSET_TASK_TEMP, 1U); + if (ret != 0) { + return ret; + } + + /* Enable charging if configured */ + if (config->charging_enable) { + ret = reg_write(dev, CHGR_BASE, CHGR_OFFSET_EN_SET, 1U); + if (ret != 0) { + return ret; + } + } + + return 0; +} + +static const struct sensor_driver_api npm1300_charger_battery_driver_api = { + .sample_fetch = npm1300_charger_sample_fetch, + .channel_get = npm1300_charger_channel_get, +}; + +#define NPM1300_CHARGER_INIT(n) \ + static struct npm1300_charger_data npm1300_charger_data_##n; \ + \ + static const struct npm1300_charger_config npm1300_charger_config_##n = { \ + .i2c = I2C_DT_SPEC_GET(DT_INST_PARENT(n)), \ + .term_microvolt = DT_INST_PROP(n, term_microvolt), \ + .term_warm_microvolt = \ + DT_INST_PROP_OR(n, term_warm_microvolt, DT_INST_PROP(n, term_microvolt)), \ + .current_microamp = DT_INST_PROP(n, current_microamp), \ + .dischg_limit_microamp = DT_INST_PROP(n, dischg_limit_microamp), \ + .vbus_limit_microamp = DT_INST_PROP(n, vbus_limit_microamp), \ + .thermistor_idx = DT_INST_ENUM_IDX(n, thermistor_ohms), \ + .thermistor_beta = DT_INST_PROP(n, thermistor_beta), \ + .charging_enable = DT_INST_PROP(n, charging_enable), \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(n, &npm1300_charger_init, NULL, &npm1300_charger_data_##n, \ + &npm1300_charger_config_##n, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, \ + &npm1300_charger_battery_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(NPM1300_CHARGER_INIT) diff --git a/dts/bindings/sensor/nordic,npm1300-charger.yaml b/dts/bindings/sensor/nordic,npm1300-charger.yaml new file mode 100644 index 000000000000..86a22b7a3b5d --- /dev/null +++ b/dts/bindings/sensor/nordic,npm1300-charger.yaml @@ -0,0 +1,68 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +description: NPM1300 PMIC Charger + +compatible: "nordic,npm1300-charger" + +include: [sensor-device.yaml] + +properties: + term-microvolt: + type: int + required: true + description: | + Charge termination voltage in uV. + Available range is 3.5 V to 3.65 V and 4.0 V to 4.45 V in 50 mV steps. + + term-warm-microvolt: + type: int + description: | + Charge termination voltage when warm in uV. + Available range is 3.5 V to 3.65 V and 4.0 V to 4.45 V in 50 mV steps. + If omitted, the term-microvolt value will be used. + + current-microamp: + type: int + required: true + description: | + Charge current in uA. + Available range is 32 mA to 800 mA in 2mA steps. + The value specified will be rounded down to the closest implemented value. + + dischg-limit-microamp: + type: int + required: true + description: | + Discharge current limit in uA. + Available range is 270 mA to 1340 mA in 3.23 mA steps. + The value specified will be rounded down to the closest implemented value. + + vbus-limit-microamp: + type: int + description: | + Vbus current limit in uA. + Available values are 100 mA, or between 500 mA and 1500 mA in 100 mA steps. + If omitted, the default value of 100 mA will be used. + + thermistor-ohms: + type: int + required: true + enum: + - 10000 + - 47000 + - 100000 + description: Thermistor nominal resistance type in ohms. + + thermistor-beta: + type: int + required: true + description: Beta value of selected thermistor. + + charging-enable: + type: boolean + description: | + Enable charging. diff --git a/include/zephyr/drivers/sensor/npm1300_charger.h b/include/zephyr/drivers/sensor/npm1300_charger.h new file mode 100644 index 000000000000..eb13f959a466 --- /dev/null +++ b/include/zephyr/drivers/sensor/npm1300_charger.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_NPM1300_CHARGER_H_ +#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_NPM1300_CHARGER_H_ + +#include + +/* NPM1300 charger specific channels */ +enum sensor_channel_npm1300_charger { + SENSOR_CHAN_NPM1300_CHARGER_STATUS = SENSOR_CHAN_PRIV_START, + SENSOR_CHAN_NPM1300_CHARGER_ERROR, +}; + +#endif From 39cfa75a48c3659a4d7f1fa574570274f885f69c Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Fri, 31 Mar 2023 14:43:15 +0100 Subject: [PATCH 098/528] [nrf fromtree] boards: shields: npm1300_ek: Added initial charger sensor Charger sensor support added to NPM1300_EK shield Signed-off-by: Andy Sinclair (cherry picked from commit 1b4f6527075befe8d150aa2d3d2fb5930a6b908a) (cherry picked from commit 52f904147774169dda5203757900e6c0dda87243) --- boards/shields/npm1300_ek/Kconfig.defconfig | 3 +++ boards/shields/npm1300_ek/npm1300_ek.overlay | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/boards/shields/npm1300_ek/Kconfig.defconfig b/boards/shields/npm1300_ek/Kconfig.defconfig index 9c9b0573e2bd..72b27a4f2906 100644 --- a/boards/shields/npm1300_ek/Kconfig.defconfig +++ b/boards/shields/npm1300_ek/Kconfig.defconfig @@ -9,4 +9,7 @@ config REGULATOR config GPIO default y +config SENSOR + default y + endif # SHIELD_NPM1300_EK diff --git a/boards/shields/npm1300_ek/npm1300_ek.overlay b/boards/shields/npm1300_ek/npm1300_ek.overlay index 455a4b925ab1..3c9d8d707c76 100644 --- a/boards/shields/npm1300_ek/npm1300_ek.overlay +++ b/boards/shields/npm1300_ek/npm1300_ek.overlay @@ -46,5 +46,17 @@ enable-gpios = <&npm1300_ek_gpio 2 GPIO_ACTIVE_LOW>; }; }; + + npm1300_ek_charger: charger { + compatible = "nordic,npm1300-charger"; + term-microvolt = <4150000>; + term-warm-microvolt = <4000000>; + current-microamp = <150000>; + dischg-limit-microamp = <1000000>; + vbus-limit-microamp = <500000>; + thermistor-ohms = <10000>; + thermistor-beta = <3380>; + charging-enable; + }; }; }; From 9aa6e9baa3777c7361da5e1eafdd6511a89c4d10 Mon Sep 17 00:00:00 2001 From: Andy Sinclair Date: Fri, 31 Mar 2023 14:46:24 +0100 Subject: [PATCH 099/528] [nrf fromtree] samples: shields: npm1300_ek: Added initial charger sensor Charger sensor support added to NPM1300_EK sample Signed-off-by: Andy Sinclair (cherry-picked from commit 7d2fb0fb787ece27880ee7d58c68ab68ebee91b3) (cherry picked from commit c219c1cc46e85155eb4552da1eaede5f1e26636a) --- samples/shields/npm1300_ek/src/main.c | 45 ++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/samples/shields/npm1300_ek/src/main.c b/samples/shields/npm1300_ek/src/main.c index af7e6b92decc..896604249ae6 100644 --- a/samples/shields/npm1300_ek/src/main.c +++ b/samples/shields/npm1300_ek/src/main.c @@ -8,16 +8,21 @@ #include #include #include +#include +#include #include #include #include -#define SLEEP_TIME_MS 100 +#define SLEEP_TIME_MS 100 +#define UPDATE_TIME_MS 2000 static const struct gpio_dt_spec button1 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios); static const struct device *regulators = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_regulators)); +static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_charger)); + void configure_ui(void) { int ret; @@ -37,6 +42,31 @@ void configure_ui(void) printk("Set up button at %s pin %d\n", button1.port->name, button1.pin); } +void read_sensors(void) +{ + struct sensor_value volt; + struct sensor_value current; + struct sensor_value temp; + struct sensor_value error; + struct sensor_value status; + + sensor_sample_fetch(charger); + sensor_channel_get(charger, SENSOR_CHAN_GAUGE_VOLTAGE, &volt); + sensor_channel_get(charger, SENSOR_CHAN_GAUGE_AVG_CURRENT, ¤t); + sensor_channel_get(charger, SENSOR_CHAN_GAUGE_TEMP, &temp); + sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_STATUS, &status); + sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_ERROR, &error); + + printk("V: %d.%03d ", volt.val1, volt.val2 / 1000); + + printk("I: %s%d.%04d ", ((current.val1 < 0) || (current.val2 < 0)) ? "-" : "", + abs(current.val1), abs(current.val2) / 100); + + printk("T: %d.%02d\n", temp.val1, temp.val2 / 10000); + + printk("Charger Status: %d, Error: %d\n", status.val1, error.val1); +} + int main(void) { configure_ui(); @@ -46,6 +76,11 @@ int main(void) return 0; } + if (!device_is_ready(charger)) { + printk("Charger device not ready.\n"); + return 0; + } + while (1) { /* Cycle regulator control GPIOs when first button pressed */ static bool last_button; @@ -57,6 +92,14 @@ int main(void) regulator_parent_dvs_state_set(regulators, dvs_state); } + /* Read and display charger status */ + static int count; + + if (++count > (UPDATE_TIME_MS / SLEEP_TIME_MS)) { + read_sensors(); + count = 0; + } + last_button = button_state; k_msleep(SLEEP_TIME_MS); } From ab6dc44191d88437776df3884588b93831112bd9 Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Tue, 9 May 2023 13:52:41 +0200 Subject: [PATCH 100/528] [nrf fromtree] net: openthread: Remove not needed `OPENTHREAD_EXCLUDE_TCPLP_LIB` Remove not needed `OPENTHREAD_EXCLUDE_TCPLP_LIB`. Signed-off-by: Przemyslaw Bida (cherry picked form commit 56425425a4f48087e9cca7170f4d6d70612aff1b) (cherry picked from commit 60bdd8a839dcdfe741efd8d0aab12967ab76861e) --- modules/openthread/CMakeLists.txt | 6 ------ modules/openthread/Kconfig.features | 3 --- 2 files changed, 9 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index a263e2256082..508c888e0f3c 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -214,12 +214,6 @@ else() set(OT_SERVICE OFF CACHE BOOL "Enable Service entries in Thread Network Data" FORCE) endif() -if(CONFIG_OPENTHREAD_EXCLUDE_TCPLP_LIB) - set(OT_EXCLUDE_TCPLP_LIB ON CACHE BOOL "Exclude TCPlp library from build" FORCE) -else() - set(OT_EXCLUDE_TCPLP_LIB OFF CACHE BOOL "Exclude TCPlp library from build" FORCE) -endif() - if(CONFIG_OPENTHREAD_EXTERNAL_HEAP) set(OT_EXTERNAL_HEAP ON CACHE BOOL "Enable external heap support" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index a57de4b31c16..2a84e3e9a534 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -133,9 +133,6 @@ config OPENTHREAD_ENABLE_SERVICE help Enable Thread Services capability in OpenThread stack -config OPENTHREAD_EXCLUDE_TCPLP_LIB - bool "Exclude TCPlp library from build" - config OPENTHREAD_EXTERNAL_HEAP bool "External heap support" From 148596ee59989b4df059b8f038d61d0f50be7600 Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Wed, 10 May 2023 14:06:11 +0200 Subject: [PATCH 101/528] [nrf fromtree] net: openthread: Add implementation of crypto api. This commit adds implementation of following new api functions from openthread: - otPlatCryptoEcdsaGenerateAndImportKey - otPlatCryptoEcdsaExportPublicKey - otPlatCryptoEcdsaVerifyUsingKeyRef - otPlatCryptoEcdsaSignUsingKeyRef Signed-off-by: Przemyslaw Bida (cherry picked form commit f93613a245124d195c49241432e93d2e7f90a73e) (cherry picked from commit 64e726ae52c841812f08fec6c4eb2b09ef26e036) --- modules/openthread/platform/crypto_psa.c | 79 ++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/modules/openthread/platform/crypto_psa.c b/modules/openthread/platform/crypto_psa.c index 8132e6013a96..d9deb114f369 100644 --- a/modules/openthread/platform/crypto_psa.c +++ b/modules/openthread/platform/crypto_psa.c @@ -563,4 +563,83 @@ otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey, return psaToOtError(status); } +otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef, + const otPlatCryptoSha256Hash *aHash, + otPlatCryptoEcdsaSignature *aSignature) +{ + psa_status_t status; + size_t signature_length; + + status = psa_sign_hash(aKeyRef, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8, + OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8, + OT_CRYPTO_ECDSA_SIGNATURE_SIZE, &signature_length); + if (status != PSA_SUCCESS) { + goto out; + } + + __ASSERT_NO_MSG(signature_length == OT_CRYPTO_ECDSA_SIGNATURE_SIZE); +out: + return psaToOtError(status); +} + +otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef, + const otPlatCryptoSha256Hash *aHash, + const otPlatCryptoEcdsaSignature *aSignature) +{ + psa_status_t status; + + status = psa_verify_hash(aKeyRef, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8, + OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8, + OT_CRYPTO_ECDSA_SIGNATURE_SIZE); + if (status != PSA_SUCCESS) { + goto out; + } + +out: + return psaToOtError(status); +} + +otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, + otPlatCryptoEcdsaPublicKey *aPublicKey) +{ + psa_status_t status; + size_t exported_length; + uint8_t buffer[1 + OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE]; + + status = psa_export_public_key(aKeyRef, buffer, sizeof(buffer), &exported_length); + if (status != PSA_SUCCESS) { + goto out; + } + + __ASSERT_NO_MSG(exported_length == sizeof(buffer)); + memcpy(aPublicKey->m8, buffer + 1, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE); + +out: + return psaToOtError(status); +} + +otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef) +{ + psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; + psa_status_t status; + psa_key_id_t key_id = (psa_key_id_t)aKeyRef; + + psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_HASH); + psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); + psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); + psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT); + psa_set_key_id(&attributes, key_id); + psa_set_key_bits(&attributes, 256); + + status = psa_generate_key(&attributes, &key_id); + if (status != PSA_SUCCESS) { + goto out; + } + +out: + psa_reset_key_attributes(&attributes); + + return psaToOtError(status); +} + #endif /* #if CONFIG_OPENTHREAD_ECDSA */ From f587bf11821e068b24fa472545daeca3668aa6df Mon Sep 17 00:00:00 2001 From: Mariusz Poslinski Date: Wed, 8 Mar 2023 09:04:15 +0100 Subject: [PATCH 102/528] [nrf fromtree] manifest: openthread upmerge up to commit 1f1a826 Regular OpenThread upmerge. Added new configs: CONFIG_OPENTHREAD_TCP -> OT_TCP CONFIG_OPENTHREAD_DNS_QUERY_UPSTREAM -> OT_DNS_QUERY_UPSTREAM CONFIG_OPENTHREAD_MESH_DIAG -> OT_MESH_DIAG Signed-off-by: Mariusz Poslinski (cherry picked form commit 5027f55a1215aee80a5f31b17de22f5d61c1827b) (cherry picked from commit ea9202cca4dc5036e18d7823a1da5c9f39a6e9e4) --- modules/openthread/CMakeLists.txt | 6 +++--- modules/openthread/Kconfig.features | 2 +- west.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 508c888e0f3c..78d9f835ff6e 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -184,10 +184,10 @@ else() set(OT_DNS_DSO OFF CACHE BOOL "Enable DNS Stateful Operations (DSO) support" FORCE) endif() -if(CONFIG_OPENTHREAD_DNS_UPSTREAM_QUERY) - set(OT_DNS_UPSTREAM_QUERY ON CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) +if(CONFIG_OPENTHREAD_DNS_QUERY_UPSTREAM) + set(OT_DNS_QUERY_UPSTREAM ON CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) else() - set(OT_DNS_UPSTREAM_QUERY OFF CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) + set(OT_DNS_QUERY_UPSTREAM OFF CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) endif() if(CONFIG_OPENTHREAD_DNSSD_SERVER) diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 2a84e3e9a534..4766032cd79a 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -112,7 +112,7 @@ config OPENTHREAD_DNS_CLIENT_OVER_TCP config OPENTHREAD_DNS_DSO bool "DNS Stateful Operations (DSO) support" -config OPENTHREAD_DNS_UPSTREAM_QUERY +config OPENTHREAD_DNS_QUERY_UPSTREAM bool "Forwarding DNS queries to upstream" help Enable forwarding DNS queries to platform DNS upstream API diff --git a/west.yml b/west.yml index efeb1f8bd159..746542a8bc72 100644 --- a/west.yml +++ b/west.yml @@ -203,7 +203,7 @@ manifest: revision: aedcc262f93bbb1b0c2f58026911575729b7465c path: modules/lib/open-amp - name: openthread - revision: 25942910ab57b32f73d9c56d8c6cf07c7cf98c49 + revision: 1f1a826d1891fc99d14822abc0a1de257e9c6e9b path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From 7edf308c6d26915fa2d13f132b623484852e3c15 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 11 May 2023 11:47:21 +0000 Subject: [PATCH 103/528] [nrf fromtree] kconfig: Separate MCUboot options to Kconfig.mcuboot Move Kconfig options related to MCUboot to Kconfig.mcuboot Signed-off-by: Dominik Ermel (cherry picked form commit 865f8014701e9b13ffbfd1998cf9d5ec1bca0911) (cherry picked from commit 240d17c584f2590d85f2d1c16c17e6d02a038fcd) --- Kconfig.mcuboot | 130 ++++++++++++++++++++++++++++++++++++++++++++++++ Kconfig.zephyr | 125 +--------------------------------------------- 2 files changed, 132 insertions(+), 123 deletions(-) create mode 100644 Kconfig.mcuboot diff --git a/Kconfig.mcuboot b/Kconfig.mcuboot new file mode 100644 index 000000000000..ef1cae5f021f --- /dev/null +++ b/Kconfig.mcuboot @@ -0,0 +1,130 @@ +# General configuration options + +# Copyright (c) 2014-2015 Wind River Systems, Inc. +# Copyright (c) 2016 Intel Corporation +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config MCUBOOT + bool + help + Hidden option used to indicate that the current image is MCUBoot + +config BOOTLOADER_MCUBOOT + bool "MCUboot bootloader support" + select USE_DT_CODE_PARTITION + imply INIT_ARCH_HW_AT_BOOT if ARCH_SUPPORTS_ARCH_HW_INIT + depends on !MCUBOOT + help + This option signifies that the target uses MCUboot as a bootloader, + or in other words that the image is to be chain-loaded by MCUboot. + This sets several required build system and Device Tree options in + order for the image generated to be bootable using the MCUboot open + source bootloader. Currently this includes: + + * Setting ROM_START_OFFSET to a default value that allows space + for the MCUboot image header + * Activating SW_VECTOR_RELAY_CLIENT on Cortex-M0 + (or Armv8-M baseline) targets with no built-in vector relocation + mechanisms + + By default, this option instructs Zephyr to initialize the core + architecture HW registers during boot, when this is supported by + the application. This removes the need by MCUboot to reset + the core registers' state itself. + +if BOOTLOADER_MCUBOOT + +config MCUBOOT_CMAKE_WEST_SIGN_PARAMS + string "Extra parameters to west sign" + default "--quiet" + help + Parameters that are passed by cmake to west sign, just after + the command, before all other parameters needed for image + signing. + By default this is set to "--quiet" to prevent extra, non-error, + diagnostic messages from west sign. This does not affect signing + tool for which extra parameters are passed with + MCUBOOT_EXTRA_IMGTOOL_ARGS. + +config MCUBOOT_SIGNATURE_KEY_FILE + string "Path to the mcuboot signing key file" + default "" + depends on !MCUBOOT_GENERATE_UNSIGNED_IMAGE + help + The file contains a key pair whose public half is verified + by your target's MCUboot image. The file is in PEM format. + + If set to a non-empty value, the build system tries to + sign the final binaries using a 'west sign -t imgtool' command. + The signed binaries are placed in the build directory + at zephyr/zephyr.signed.bin and zephyr/zephyr.signed.hex. + + The file names can be customized with CONFIG_KERNEL_BIN_NAME. + The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN + and CONFIG_BUILD_OUTPUT_HEX. + + This option should contain a path to the same file as the + BOOT_SIGNATURE_KEY_FILE option in your MCUboot .config. The path + may be absolute or relative to the west workspace topdir. (The MCUboot + config option is used for the MCUboot bootloader image; this option is + for your application which is to be loaded by MCUboot. The MCUboot + config option can be a relative path from the MCUboot repository + root.) + + If left empty, you must sign the Zephyr binaries manually. + +config MCUBOOT_ENCRYPTION_KEY_FILE + string "Path to the mcuboot encryption key file" + default "" + depends on MCUBOOT_SIGNATURE_KEY_FILE != "" + help + The file contains the public key that is used to encrypt the + ephemeral key that encrypts the image. The corresponding + private key is hard coded in the MCUboot source code and is + used to decrypt the ephemeral key that is embedded in the + image. The file is in PEM format. + + If set to a non-empty value, the build system tries to + sign and encrypt the final binaries using a 'west sign -t imgtool' + command. The binaries are placed in the build directory at + zephyr/zephyr.signed.encrypted.bin and + zephyr/zephyr.signed.encrypted.hex. + + The file names can be customized with CONFIG_KERNEL_BIN_NAME. + The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN + and CONFIG_BUILD_OUTPUT_HEX. + + This option should either be an absolute path or a path relative to + the west workspace topdir. + Example: './bootloader/mcuboot/enc-rsa2048-pub.pem' + + If left empty, you must encrypt the Zephyr binaries manually. + +config MCUBOOT_EXTRA_IMGTOOL_ARGS + string "Extra arguments to pass to imgtool when signing" + default "" + help + When signing (CONFIG_MCUBOOT_SIGNATURE_KEY_FILE is a non-empty + string) you can use this option to pass extra options to + imgtool. For example, you could set this to "--version 1.2". + +config MCUBOOT_GENERATE_UNSIGNED_IMAGE + bool "Generate unsigned binary image bootable with MCUboot" + help + Enabling this configuration allows automatic unsigned binary image + generation when MCUboot signing key is not provided, + i.e., MCUBOOT_SIGNATURE_KEY_FILE is left empty. + +config MCUBOOT_GENERATE_CONFIRMED_IMAGE + bool "Also generate a padded, confirmed image" + help + The signed, padded, and confirmed binaries are placed in the build + directory at zephyr/zephyr.signed.confirmed.bin and + zephyr/zephyr.signed.confirmed.hex. + + The file names can be customized with CONFIG_KERNEL_BIN_NAME. + The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN + and CONFIG_BUILD_OUTPUT_HEX. + +endif # BOOTLOADER_MCUBOOT diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 827b19a6ce4d..2b94489a16b6 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -2,6 +2,7 @@ # Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2016 Intel Corporation +# Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 @@ -783,129 +784,7 @@ config BOOTLOADER_SRAM_SIZE - Zephyr is a !XIP image, which implicitly assumes existence of a bootloader that loads the Zephyr !XIP image onto SRAM. -config MCUBOOT - bool - help - Hidden option used to indicate that the current image is MCUBoot - -config BOOTLOADER_MCUBOOT - bool "MCUboot bootloader support" - select USE_DT_CODE_PARTITION - imply INIT_ARCH_HW_AT_BOOT if ARCH_SUPPORTS_ARCH_HW_INIT - depends on !MCUBOOT - help - This option signifies that the target uses MCUboot as a bootloader, - or in other words that the image is to be chain-loaded by MCUboot. - This sets several required build system and Device Tree options in - order for the image generated to be bootable using the MCUboot open - source bootloader. Currently this includes: - - * Setting ROM_START_OFFSET to a default value that allows space - for the MCUboot image header - * Activating SW_VECTOR_RELAY_CLIENT on Cortex-M0 - (or Armv8-M baseline) targets with no built-in vector relocation - mechanisms - - By default, this option instructs Zephyr to initialize the core - architecture HW registers during boot, when this is supported by - the application. This removes the need by MCUboot to reset - the core registers' state itself. - -if BOOTLOADER_MCUBOOT - -config MCUBOOT_CMAKE_WEST_SIGN_PARAMS - string "Extra parameters to west sign" - default "--quiet" - help - Parameters that are passed by cmake to west sign, just after - the command, before all other parameters needed for image - signing. - By default this is set to "--quiet" to prevent extra, non-error, - diagnostic messages from west sign. This does not affect signing - tool for which extra parameters are passed with - MCUBOOT_EXTRA_IMGTOOL_ARGS. - -config MCUBOOT_SIGNATURE_KEY_FILE - string "Path to the mcuboot signing key file" - default "" - depends on !MCUBOOT_GENERATE_UNSIGNED_IMAGE - help - The file contains a key pair whose public half is verified - by your target's MCUboot image. The file is in PEM format. - - If set to a non-empty value, the build system tries to - sign the final binaries using a 'west sign -t imgtool' command. - The signed binaries are placed in the build directory - at zephyr/zephyr.signed.bin and zephyr/zephyr.signed.hex. - - The file names can be customized with CONFIG_KERNEL_BIN_NAME. - The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN - and CONFIG_BUILD_OUTPUT_HEX. - - This option should contain a path to the same file as the - BOOT_SIGNATURE_KEY_FILE option in your MCUboot .config. The path - may be absolute or relative to the west workspace topdir. (The MCUboot - config option is used for the MCUboot bootloader image; this option is - for your application which is to be loaded by MCUboot. The MCUboot - config option can be a relative path from the MCUboot repository - root.) - - If left empty, you must sign the Zephyr binaries manually. - -config MCUBOOT_ENCRYPTION_KEY_FILE - string "Path to the mcuboot encryption key file" - default "" - depends on MCUBOOT_SIGNATURE_KEY_FILE != "" - help - The file contains the public key that is used to encrypt the - ephemeral key that encrypts the image. The corresponding - private key is hard coded in the MCUboot source code and is - used to decrypt the ephemeral key that is embedded in the - image. The file is in PEM format. - - If set to a non-empty value, the build system tries to - sign and encrypt the final binaries using a 'west sign -t imgtool' - command. The binaries are placed in the build directory at - zephyr/zephyr.signed.encrypted.bin and - zephyr/zephyr.signed.encrypted.hex. - - The file names can be customized with CONFIG_KERNEL_BIN_NAME. - The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN - and CONFIG_BUILD_OUTPUT_HEX. - - This option should either be an absolute path or a path relative to - the west workspace topdir. - Example: './bootloader/mcuboot/enc-rsa2048-pub.pem' - - If left empty, you must encrypt the Zephyr binaries manually. - -config MCUBOOT_EXTRA_IMGTOOL_ARGS - string "Extra arguments to pass to imgtool when signing" - default "" - help - When signing (CONFIG_MCUBOOT_SIGNATURE_KEY_FILE is a non-empty - string) you can use this option to pass extra options to - imgtool. For example, you could set this to "--version 1.2". - -config MCUBOOT_GENERATE_UNSIGNED_IMAGE - bool "Generate unsigned binary image bootable with MCUboot" - help - Enabling this configuration allows automatic unsigned binary image - generation when MCUboot signing key is not provided, - i.e., MCUBOOT_SIGNATURE_KEY_FILE is left empty. - -config MCUBOOT_GENERATE_CONFIRMED_IMAGE - bool "Also generate a padded, confirmed image" - help - The signed, padded, and confirmed binaries are placed in the build - directory at zephyr/zephyr.signed.confirmed.bin and - zephyr/zephyr.signed.confirmed.hex. - - The file names can be customized with CONFIG_KERNEL_BIN_NAME. - The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN - and CONFIG_BUILD_OUTPUT_HEX. - -endif # BOOTLOADER_MCUBOOT +source "Kconfig.mcuboot" config BOOTLOADER_ESP_IDF bool "ESP-IDF bootloader support" From 76c56af9b7ce93228ca7f7afa762ef33be85b48b Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 9 May 2023 15:34:42 +0000 Subject: [PATCH 104/528] [nrf fromtree] mcuboot: Kconfig options allowing to inform on MCUboot config The commit adds Kconfig options that allow to inform application what algorithm is used with MCUboot that will be booting applications on board. Kconfig options added: - CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH - CONFIG_MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH - CONFIG_MCUBOOT_BOOTLOADER_MODE_SINGLE_APP - CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP Signed-off-by: Dominik Ermel (cherry picked from commit 6f6135e6f95f9d244118b42fa455b08d7aad6a26) (cherry picked from commit bf67cecbbbb9bec59dab27673d94892c25103126) --- Kconfig.mcuboot | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/Kconfig.mcuboot b/Kconfig.mcuboot index ef1cae5f021f..7057331a572f 100644 --- a/Kconfig.mcuboot +++ b/Kconfig.mcuboot @@ -127,4 +127,46 @@ config MCUBOOT_GENERATE_CONFIRMED_IMAGE The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN and CONFIG_BUILD_OUTPUT_HEX. +choice MCUBOOT_BOOTLOADER_MODE + prompt "Application assumed MCUboot mode of operation" + default MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH # MCUBOOT_BOOTLOADER_MODE + help + Informs application build on assumed MCUboot mode of operation. + This is important for validataing application against DT configuration, + which is done by west sign. + +config MCUBOOT_BOOTLOADER_MODE_SINGLE_APP + bool "MCUboot has been configured for single slot execution" + help + MCUboot will only boot slot0_partition placed application and does + not care about other slots. In this mode application is not able + to DFU its own update to secondary slot and all updates need to + be performed using MCUboot serial recovery. + +config MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH + bool "MCUboot has been configured for swap without scratch operation" + help + MCUboot expects slot0_partition and slot1_partition to be present + in DT and application will boot from slot0_partition. + +config MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH + bool "MCUboot has been configured for swap using scratch operation" + help + MCUboot expects slot0_partition, slot1_partition and scratch_partition + to be present in DT, and application will boot from slot0_partition. + In this mode scratch_partition is used as temporary storage when + MCUboot swaps application from the secondary slot to the primary + slot. + +config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP + bool "MCUboot has been configured for DirectXIP operation" + help + MCUboot expects slot0_partition and slot1_partition to exist in DT. + In this mode MCUboot can boot from either partition and will + select one with higher application image version, which usually + means major.minor.patch triple, unless BOOT_VERSION_CMP_USE_BUILD_NUMBER + is also selected that enables comparison of build number. + +endchoice # MCUBOOT_BOOTLOADER_MODE + endif # BOOTLOADER_MCUBOOT From 4e68c2a7f451d228c4b51e44a11ccba581549ee6 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 9 May 2023 15:51:41 +0000 Subject: [PATCH 105/528] [nrf fromtree] mgmt/mcumgr/grp/img: No upload for MCUboot in single app mode Image management is now disabled by default if MCUboot is configured for single application mode. Signed-off-by: Dominik Ermel (cherry picked form commit 0a5c4aba52b9904be9b4e5c01773388d98a458ed) (cherry picked from commit ffe9c3df770cebe6680fc802d081ef84716b26e5) --- subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig index ec7d17f43d17..7f0c714d370f 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig @@ -16,6 +16,7 @@ menuconfig MCUMGR_GRP_IMG bool "Mcumgr handlers for image management" depends on FLASH depends on IMG_MANAGER + depends on !MCUBOOT_BOOTLOADER_MODE_SINGLE_APP select MPU_ALLOW_FLASH_WRITE if ARM_MPU select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 help From 397cb90fd5304c6d6516196050c2987885c618fe Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Tue, 9 May 2023 15:54:05 +0000 Subject: [PATCH 106/528] [nrf fromtree] mgmt/mcumgr/grp/img: No MCUboot flags setting in DirectXIP It is no longer possible to select image for test or confirm when MCUboot has been configured for DirectXIP. MCUboot flags, in image trailer, are now ignored in DirectXIP mode allowing to use entire slot for image upload. Signed-off-by: Dominik Ermel (cherry picked from commit a763454c0bc41c13001b672b62f22dc4ec21c877) (cherry picked from commit 7aa848966734576c940f79a8e864a69fc126d40b) --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 4 ++++ .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 15 ++++++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index c490b0ea5314..b4aa59ae7389 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -701,7 +701,11 @@ img_mgmt_my_version(struct image_version *ver) static const struct mgmt_handler img_mgmt_handlers[] = { [IMG_MGMT_ID_STATE] = { .mh_read = img_mgmt_state_read, +#ifdef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP + .mh_write = NULL +#else .mh_write = img_mgmt_state_write, +#endif }, [IMG_MGMT_ID_UPLOAD] = { .mh_read = NULL, diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index a006e2899750..6cdb6e4b8d08 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -124,13 +124,18 @@ img_mgmt_state_any_pending(void) int img_mgmt_slot_in_use(int slot) { - uint8_t state_flags; int active_slot = img_mgmt_active_slot(img_mgmt_active_image()); - state_flags = img_mgmt_state_flags(slot); - return slot == active_slot || - state_flags & IMG_MGMT_STATE_F_CONFIRMED || - state_flags & IMG_MGMT_STATE_F_PENDING; +#ifndef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP + uint8_t state_flags = img_mgmt_state_flags(slot); + + if (state_flags & IMG_MGMT_STATE_F_CONFIRMED || + state_flags & IMG_MGMT_STATE_F_PENDING) { + return 1; + } +#endif + + return (active_slot == slot); } /** From 5dc97da98200519c7cd340d4bc772035c3528a27 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 11 May 2023 14:11:27 +0000 Subject: [PATCH 107/528] [nrf fromlist] mgmt/MCUmgr/grp/img: Rework image list to support DirectXIP Image list will only report active flag for active image and pending flag for other slot, but only if image in that slot has higher version than currently running image. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57794 Signed-off-by: Dominik Ermel (cherry picked from commit 6e1f7d29f0f7f3e8f5d0fc860bcc382b33d58766) --- .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 6cdb6e4b8d08..559a15e139e1 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -54,6 +54,7 @@ LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); /** * Collects information about the specified image slot. */ +#ifndef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP uint8_t img_mgmt_state_flags(int query_slot) { @@ -105,6 +106,34 @@ img_mgmt_state_flags(int query_slot) return flags; } +#else +uint8_t +img_mgmt_state_flags(int query_slot) +{ + uint8_t flags = 0; + int image = query_slot / 2; /* We support max 2 images for now */ + int active_slot = img_mgmt_active_slot(image); + + /* In case when MCUboot is configured for DirectXIP slot may only be + * active or pending. Slot is marked pending only when version in that slot + * is higher than version of active slot. + */ + if (image == img_mgmt_active_image() && query_slot == active_slot) { + flags = IMG_MGMT_STATE_F_ACTIVE; + } else { + struct image_version sver; + struct image_version aver; + int rcs = img_mgmt_read_info(query_slot, &sver, NULL, NULL); + int rca = img_mgmt_read_info(active_slot, &aver, NULL, NULL); + + if (rcs == 0 && rca == 0 && img_mgmt_vercmp(&aver, &sver) < 0) { + flags = IMG_MGMT_STATE_F_PENDING; + } + } + + return flags; +} +#endif /** * Indicates whether any image slot is pending (i.e., whether a test swap will From 5c4420d4541aecca51d012f9375df2ceb255e997 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristoffer=20Rist=20Sk=C3=B8ien?= Date: Thu, 4 May 2023 12:27:31 +0200 Subject: [PATCH 108/528] [nrf fromtree] lib: getopt: Fix compiler warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit current_dash may be used uninitialized Signed-off-by: Kristoffer Rist Skøien (cherry picked from commit 5974617db84bfb3db654c2209ecf3c73cfd83948) (cherry picked from commit 2fdf88bc2915e8e7c07022b34adc0856628ce7d6) --- lib/posix/getopt/getopt_long.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/posix/getopt/getopt_long.c b/lib/posix/getopt/getopt_long.c index a13ebaf18f46..d38cd8258a80 100644 --- a/lib/posix/getopt/getopt_long.c +++ b/lib/posix/getopt/getopt_long.c @@ -172,7 +172,7 @@ parse_long_options(struct getopt_state *state, char * const *nargv, { char *current_argv, *has_equal; #ifdef GNU_COMPATIBLE - char *current_dash; + char *current_dash = ""; #endif size_t current_argv_len; int i, match, exact_match, second_partial_match; @@ -191,7 +191,6 @@ parse_long_options(struct getopt_state *state, char * const *nargv, current_dash = "-W "; break; default: - current_dash = ""; break; } } From 67c774827758444101e1808981f6a5f4af858dda Mon Sep 17 00:00:00 2001 From: Jakub Rzeszutko Date: Mon, 8 May 2023 12:44:40 +0200 Subject: [PATCH 109/528] [nrf fromtree] getopt: extend ztests scope Adding a test to detect problems in the cooperation of the getopt and logger modules. It would detect issue: #57520 Signed-off-by: Jakub Rzeszutko (cherry picked from commit 25a397770931db1a85ede6565ef50254bd18ae10) (cherry picked from commit b1b05885f057a70b6fc381264ee96560d97e9596) --- tests/posix/getopt/testcase.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/posix/getopt/testcase.yaml b/tests/posix/getopt/testcase.yaml index 158297f49d07..31e808fbc446 100644 --- a/tests/posix/getopt/testcase.yaml +++ b/tests/posix/getopt/testcase.yaml @@ -16,3 +16,9 @@ tests: filter: CONFIG_PICOLIBC_SUPPORTED extra_configs: - CONFIG_PICOLIBC=y + portability.posix.getopt.logger: + integration_platforms: + - qemu_x86 + extra_configs: + - CONFIG_LOG=y + build_only: true From 417f8466d90dbf547e09d3b65c92c75a1c0072f1 Mon Sep 17 00:00:00 2001 From: Herman Berget Date: Fri, 12 May 2023 09:46:40 +0200 Subject: [PATCH 110/528] [nrf fromtree] Bluetooth: Host: Fix double conversion of phy The phy was converted both when reading from the event and when reading from the sync, leading to incorrect value in the synced callback. Signed-off-by: Herman Berget (cherry picked from commit 93f36d4bff16b30e4c163dddc25fda18074a8af9) (cherry picked from commit e5cc3323feb7023b79b9d81b20dbba5759c61f9c) --- subsys/bluetooth/host/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index c48f40502a59..187a91fa566c 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1034,7 +1034,7 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) memset(&sync_info, 0, sizeof(sync_info)); sync_info.interval = pending_per_adv_sync->interval; - sync_info.phy = bt_get_phy(pending_per_adv_sync->phy); + sync_info.phy = pending_per_adv_sync->phy; if (atomic_test_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCING_USE_LIST)) { From 625fc579ec6cbc4a5378887470a27e976177b640 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 27 Apr 2023 22:37:17 +0200 Subject: [PATCH 111/528] [nrf fromtree] boards: nrf9161dk_nrf9161_ns: Add TF-M support to nrf9161 DK Add TF-M support for nrf9161 DK and enable it by default for the non-secure board variant. Disable UART1 since TF-M use this for output and it is configured as a secure peripheral. Enabling this will trigger a BusFault in TF-M. Signed-off-by: Joakim Andersson (cherry picked from commit 52d0c8ade2303dc7934bd1a2a2afc17520221d5b) (cherry picked from commit 715e277bd43b2491df5506be93d607cf98101f94) --- boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig | 15 +++++++++++++++ boards/arm/nrf9161dk_nrf9161/board.cmake | 2 +- .../nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts | 5 +++++ modules/trusted-firmware-m/Kconfig.tfm | 1 + 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig b/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig index ea7150ede5fe..2674e87cad49 100644 --- a/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig +++ b/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig @@ -8,6 +8,21 @@ if BOARD_NRF9161DK_NRF9161 || BOARD_NRF9161DK_NRF9161_NS config BOARD default "nrf9161dk_nrf9161" +# By default, if we build for a Non-Secure version of the board, +# enable building with TF-M as the Secure Execution Environment. +config BUILD_WITH_TFM + default y if BOARD_NRF9161DK_NRF9161_NS + +if BUILD_WITH_TFM + +# By default, if we build with TF-M, instruct build system to +# flash the combined TF-M (Secure) & Zephyr (Non Secure) image +config TFM_FLASH_MERGED_BINARY + bool + default y + +endif # BUILD_WITH_TFM + # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/boards/arm/nrf9161dk_nrf9161/board.cmake b/boards/arm/nrf9161dk_nrf9161/board.cmake index 73fe4dee8000..883208b78326 100644 --- a/boards/arm/nrf9161dk_nrf9161/board.cmake +++ b/boards/arm/nrf9161dk_nrf9161/board.cmake @@ -5,7 +5,7 @@ if(CONFIG_BOARD_NRF9161DK_NRF9161_NS) endif() if(CONFIG_TFM_FLASH_MERGED_BINARY) - set_property(TARGET runners_yaml_props_target PROPERTY hex_file "${CMAKE_BINARY_DIR}/tfm_merged.hex") + set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) endif() # TODO: change to nRF9161_xxAA when such device is available in JLink diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts index 623410dc8027..15648e11f419 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts @@ -15,3 +15,8 @@ zephyr,code-partition = &slot0_ns_partition; }; }; + +/* Disable UART1, because it is used by default in TF-M */ +&uart1 { + status = "disabled"; +}; diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index b1dad87c62f9..2a22e0b30dbb 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -10,6 +10,7 @@ config ZEPHYR_TRUSTED_FIRMWARE_M_MODULE config TFM_BOARD string default "nordic_nrf/nrf9160dk_nrf9160" if BOARD_NRF9160DK_NRF9160_NS + default "nordic_nrf/nrf9161dk_nrf9161" if BOARD_NRF9161DK_NRF9161_NS default "nordic_nrf/nrf5340dk_nrf5340_cpuapp" if BOARD_NRF5340DK_NRF5340_CPUAPP_NS default "nxp/lpcxpresso55s69" if BOARD_LPCXPRESSO55S69_CPU0 default "arm/mps2/an521" if BOARD_MPS2_AN521_CPU0_NS From 21084ce1d7b91d1b700fa1ede4be6cb8b12946a7 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 2 May 2023 15:59:13 +0200 Subject: [PATCH 112/528] [nrf fromtree] boards: nrf9161dk_nrf9161: Remove TF-M not supported note Remove note nrf9161dk_nrf9161 board stating that TF-M is not supported for this board. Signed-off-by: Joakim Andersson (cherry picked from commit 0e95846f59434a18e1e2b1d30e46686113c4a484) (cherry picked from commit 115ceea079d2f4b75e669163c6545cfdf23e3688) --- boards/arm/nrf9161dk_nrf9161/doc/index.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/boards/arm/nrf9161dk_nrf9161/doc/index.rst b/boards/arm/nrf9161dk_nrf9161/doc/index.rst index 32fc047d24dd..835ba29c1de4 100644 --- a/boards/arm/nrf9161dk_nrf9161/doc/index.rst +++ b/boards/arm/nrf9161dk_nrf9161/doc/index.rst @@ -138,9 +138,6 @@ have to set the IDAU (SPU) configuration to allow Non-Secure access to all CPU resources utilized by the Non-Secure application firmware. SPU configuration shall take place before jumping to the Non-Secure application. -.. note:: - Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. - Building a Secure only application ================================== From 4a67d5d325d7c7080148311bee8ab08c64c09208 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 2 May 2023 16:08:39 +0200 Subject: [PATCH 113/528] [nrf fromtree] samples: tfm_integration: Add nrf9161dk_nrf9161_ns to TF-M test samples Add nrf9161dk_nrf9161_ns board to the TF-M integration samples for testing. Signed-off-by: Joakim Andersson (cherry picked from commit 76d3fa42433b9f8e7a895e83acc56bd97d6c5d4b) (cherry picked from commit 647ac994a8d1b112e192ae8c18142d1ea3888a5d) --- samples/tfm_integration/tfm_psa_test/sample.yaml | 2 +- samples/tfm_integration/tfm_regression_test/sample.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/tfm_integration/tfm_psa_test/sample.yaml b/samples/tfm_integration/tfm_psa_test/sample.yaml index e1779a139dfa..606df91cf966 100644 --- a/samples/tfm_integration/tfm_psa_test/sample.yaml +++ b/samples/tfm_integration/tfm_psa_test/sample.yaml @@ -2,7 +2,7 @@ common: tags: tfm platform_allow: mps2_an521_ns nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160_ns - v2m_musca_s1_ns + nrf9161dk_nrf9161_ns v2m_musca_s1_ns integration_platforms: - mps2_an521_ns harness: console diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index a6a4f3fbd3d6..e64a84aa7259 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -1,7 +1,7 @@ common: tags: tfm platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160_ns - v2m_musca_s1_ns + nrf9161dk_nrf9161_ns v2m_musca_s1_ns integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns From 9a4611834feff85874e6914993d291bae670a259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20J=C3=B8lsgard?= Date: Mon, 8 May 2023 12:31:22 +0200 Subject: [PATCH 114/528] [nrf fromtree] boards: arm: nrf9161dk_nrf9161: disable external flash by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable external flash by default. When enabled, it will require the SPI driver to be enabled, which in turn require multithreading support. This adds a lot of overhead to applications not needing the external flash. Signed-off-by: Eivind Jølsgard Signed-off-by: Joakim Andersson (cherry picked from commit f328cbc92151fb2cdfdab1af4a98e58f947c130e) (cherry picked from commit bf26d75c70b405d391cdf197244780fff59a7fab) --- boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi index 9bcd6753f6e4..52543f0be9bd 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi @@ -192,6 +192,7 @@ arduino_spi: &spi3 { gd25lb256: gd25lb256e3ir@1 { compatible = "jedec,spi-nor"; + status = "disabled"; reg = <1>; spi-max-frequency = <60000000>; jedec-id = [c8 67 19]; From 20290957bca33d798cd1211c627a1fa0f999b8c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20J=C3=B8lsgard?= Date: Mon, 8 May 2023 12:33:34 +0200 Subject: [PATCH 115/528] [nrf fromtree] boards: arm: nrf9160dk_nrf9160: disable external flash by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Disable external flash by default. When enabled, it will require the SPI driver to be enabled, which in turn require multithreading support. This adds a lot of overhead to applications not needing the external flash. Signed-off-by: Eivind Jølsgard Signed-off-by: Joakim Andersson (cherry picked from commit bd1ab491a8c4df35bfb2a9a6bf253e2574c269c7) (cherry picked from commit a190997328d0f388e74c5d38071ed8e7d88c36fa) --- .../arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi | 1 + 1 file changed, 1 insertion(+) diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi index e5b62be419f7..5589f9ac9f23 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi @@ -42,6 +42,7 @@ <&gpio0 25 GPIO_ACTIVE_LOW>; mx25r64: mx25r6435f@1 { compatible = "jedec,spi-nor"; + status = "disabled"; reg = <1>; spi-max-frequency = <8000000>; label = "MX25R64"; From 271e795ac88d3e5c8a3aae96d26f76391a72306b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20J=C3=B8lsgard?= Date: Mon, 8 May 2023 12:33:54 +0200 Subject: [PATCH 116/528] [nrf fromtree] drivers: spi: nrfx: add multithreading Kconfig dependency MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The nrfx SPI driver depends on semaphores, which require multithreading support to be enabled. Signed-off-by: Eivind Jølsgard Signed-off-by: Joakim Andersson (cherry picked from commit 704e15d7f30758bd487299f9b95abde1a54ec2ff) (cherry picked from commit 8182ebc2d257c309b9c50fc0d895a4b88a672a1b) --- drivers/spi/Kconfig.nrfx | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/spi/Kconfig.nrfx b/drivers/spi/Kconfig.nrfx index 044e3ae09c28..56df44355d3c 100644 --- a/drivers/spi/Kconfig.nrfx +++ b/drivers/spi/Kconfig.nrfx @@ -5,6 +5,7 @@ menuconfig SPI_NRFX bool "nRF SPI nrfx drivers" default y depends on SOC_FAMILY_NRF + depends on MULTITHREADING help Enable support for nrfx SPI drivers for nRF MCU series. From e5835470c5af70b52538164ec5f2ef621a978af8 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Mon, 17 Apr 2023 13:21:23 +0530 Subject: [PATCH 117/528] [nrf fromtree] net: wifi_shell: Updated TWT flow id range TWT flow id is of 3 bit value(maximum mnumber of flows supported is 8). Flow id range limited to 0 to 7. Signed-off-by: Ajay Parida (cherry picked from commit 5c023fbbb9361edd16e2980cd7ec5ba9b3453d12) (cherry picked from commit 89e976f08e3c2f2309b280d40deb47eb706e5dc2) --- subsys/net/l2/wifi/wifi_shell.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 67137a5c6427..067c3f99cbd9 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -610,7 +610,7 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, params.negotiation_type = WIFI_TWT_INDIVIDUAL; params.setup_cmd = WIFI_TWT_SETUP_CMD_REQUEST; params.dialog_token = 1; - params.flow_id = 1; + params.flow_id = 0; params.setup.responder = 0; params.setup.implicit = 1; params.setup.trigger = 1; @@ -661,7 +661,8 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, !parse_number(sh, &setup_cmd, argv[idx++], WIFI_TWT_SETUP_CMD_REQUEST, WIFI_TWT_SETUP_CMD_DEMAND) || !parse_number(sh, (long *)¶ms.dialog_token, argv[idx++], 1, 255) || - !parse_number(sh, (long *)¶ms.flow_id, argv[idx++], 1, WIFI_MAX_TWT_FLOWS) || + !parse_number(sh, (long *)¶ms.flow_id, argv[idx++], 0, + (WIFI_MAX_TWT_FLOWS - 1)) || !parse_number(sh, (long *)¶ms.setup.responder, argv[idx++], 0, 1) || !parse_number(sh, (long *)¶ms.setup.trigger, argv[idx++], 0, 1) || !parse_number(sh, (long *)¶ms.setup.implicit, argv[idx++], 0, 1) || @@ -715,7 +716,8 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, !parse_number(sh, &setup_cmd, argv[idx++], WIFI_TWT_SETUP_CMD_REQUEST, WIFI_TWT_SETUP_CMD_DEMAND) || !parse_number(sh, (long *)¶ms.dialog_token, argv[idx++], 1, 255) || - !parse_number(sh, (long *)¶ms.flow_id, argv[idx++], 1, WIFI_MAX_TWT_FLOWS)) + !parse_number(sh, (long *)¶ms.flow_id, argv[idx++], 0, + (WIFI_MAX_TWT_FLOWS - 1))) return -EINVAL; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { @@ -876,13 +878,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, SHELL_CMD(setup, NULL, " Start a TWT flow:\n" "\n" "\n" - " " + " " " \n", cmd_wifi_twt_setup), SHELL_CMD(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n" - " \n", + " \n", cmd_wifi_twt_teardown), SHELL_CMD(teardown_all, NULL, " Teardown all TWT flows\n", cmd_wifi_twt_teardown_all), From 07f9d80e9c395de29b71bce27a679fcbe48ef10c Mon Sep 17 00:00:00 2001 From: Krishna T Date: Thu, 4 May 2023 20:13:35 +0530 Subject: [PATCH 118/528] [nrf fromtree] net: wifi: Fix TWT interval As we are using a generic validation function for limits, due to data type mismatch the check for TWT interval overflow and fails. Fix the data type and accordingly the maximum value in the help. Signed-off-by: Krishna T (cherry picked from commit 2b48c927420be9465861aab58ae59c543c1caa7b) (cherry picked from commit 92c8ef929565ed7c4723ddeefdcb1f6832bf6d34) --- include/zephyr/net/wifi_mgmt.h | 2 +- subsys/net/l2/wifi/wifi_shell.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 302c395da54b..f6b5e38f1c79 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -230,7 +230,7 @@ struct wifi_twt_params { /* Flow ID is only 3 bits */ #define WIFI_MAX_TWT_FLOWS 8 -#define WIFI_MAX_TWT_INTERVAL_US (ULONG_MAX - 1) +#define WIFI_MAX_TWT_INTERVAL_US (LONG_MAX - 1) /* 256 (u8) * 1TU */ #define WIFI_MAX_TWT_WAKE_INTERVAL_US 262144 struct wifi_twt_flow_info { diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 067c3f99cbd9..1fbbf54fd3c9 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -59,7 +59,7 @@ static struct net_mgmt_event_callback wifi_shell_mgmt_cb; } \ } while (false) -static bool parse_number(const struct shell *sh, long *param, char *str, int min, int max) +static bool parse_number(const struct shell *sh, long *param, char *str, long min, long max) { char *endptr; char *str_tmp = str; @@ -70,7 +70,7 @@ static bool parse_number(const struct shell *sh, long *param, char *str, int min return false; } if ((num) < (min) || (num) > (max)) { - print(sh, SHELL_WARNING, "Value out of range: %s, (%d-%d)", str_tmp, min, max); + print(sh, SHELL_WARNING, "Value out of range: %s, (%ld-%ld)", str_tmp, min, max); return false; } *param = num; @@ -873,13 +873,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, SHELL_CMD(quick_setup, NULL, " Start a TWT flow with defaults:\n" - " \n", + " \n", cmd_wifi_twt_setup_quick), SHELL_CMD(setup, NULL, " Start a TWT flow:\n" "\n" "\n" " " - " \n", + " \n", cmd_wifi_twt_setup), SHELL_CMD(teardown, NULL, " Teardown a TWT flow:\n" "\n" From c9c548d6f01611aabe7d72aa4137dbb492ed5ca5 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Fri, 28 Apr 2023 12:02:58 +0530 Subject: [PATCH 119/528] [nrf fromtree] net: wifi_mgmt: Support to provide raw scan data Support to provide raw beacon and probe response data to registered application. Signed-off-by: Ajay Parida (cherry picked from commit d2e503da8d553063df066919779652a9ce65cd3e) (cherry picked from commit 54c235860a71cb4fe35f66e2fa4e76a644c42431) --- include/zephyr/net/wifi_mgmt.h | 20 ++++++++ subsys/net/ip/net_private.h | 3 ++ subsys/net/l2/Kconfig | 1 + subsys/net/l2/wifi/Kconfig | 29 +++++++++++ subsys/net/l2/wifi/wifi_mgmt.c | 19 +++++++ subsys/net/l2/wifi/wifi_shell.c | 91 ++++++++++++++++++++++++++++++++- 6 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 subsys/net/l2/wifi/Kconfig diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index f6b5e38f1c79..d136c0b69526 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -113,6 +113,7 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_IFACE_STATUS, NET_EVENT_WIFI_CMD_TWT, NET_EVENT_WIFI_CMD_TWT_SLEEP_STATE, + NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -135,6 +136,9 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_TWT_SLEEP_STATE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_TWT_SLEEP_STATE) + +#define NET_EVENT_WIFI_RAW_SCAN_RESULT \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT) /* Each result is provided to the net_mgmt_event_callback * via its info attribute (see net_mgmt.h) */ @@ -274,11 +278,23 @@ enum wifi_twt_sleep_state { WIFI_TWT_STATE_AWAKE = 1, }; +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS +struct wifi_raw_scan_result { + int8_t rssi; + int frame_length; + unsigned short frequency; + uint8_t data[CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH]; +}; +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ #include typedef void (*scan_result_cb_t)(struct net_if *iface, int status, struct wifi_scan_result *entry); +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS +typedef void (*raw_scan_result_cb_t)(struct net_if *iface, int status, + struct wifi_raw_scan_result *entry); +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ struct net_wifi_mgmt_offload { /** * Mandatory to get in first position. @@ -328,6 +344,10 @@ void wifi_mgmt_raise_iface_status_event(struct net_if *iface, void wifi_mgmt_raise_twt_event(struct net_if *iface, struct wifi_twt_params *twt_params); void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, int twt_sleep_state); +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS +void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, + struct wifi_raw_scan_result *raw_scan_info); +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ #ifdef __cplusplus } #endif diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 918fa070f99c..351c87c61466 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -30,6 +30,9 @@ union net_mgmt_events { #endif /* CONFIG_NET_DHCPV4 */ #if defined(CONFIG_NET_L2_WIFI_MGMT) struct wifi_scan_result wifi_scan_result; +#if defined(CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS) + struct wifi_raw_scan_result raw_scan_result; +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ #endif /* CONFIG_NET_L2_WIFI_MGMT */ #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV6_MLD) struct net_event_ipv6_route ipv6_route; diff --git a/subsys/net/l2/Kconfig b/subsys/net/l2/Kconfig index 3bdc0810af39..468e1729dd78 100644 --- a/subsys/net/l2/Kconfig +++ b/subsys/net/l2/Kconfig @@ -110,6 +110,7 @@ module-dep = NET_LOG module-str = Log level for Wi-Fi management layer module-help = Enables Wi-Fi management interface to output debug messages. source "subsys/net/Kconfig.template.log_config.net" +source "subsys/net/l2/wifi/Kconfig" endif # NET_L2_WIFI_MGMT config NET_L2_WIFI_SHELL diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig new file mode 100644 index 000000000000..ecd1d002bc3d --- /dev/null +++ b/subsys/net/l2/wifi/Kconfig @@ -0,0 +1,29 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +config WIFI_MGMT_RAW_SCAN_RESULTS + bool "Raw scan results" + help + This option enables raw scan results. When enabled, the raw scan + results (beacons or probe responses) are provided to the application. + Enabling this config will increase the net_mgmt event size + considerably. + +if WIFI_MGMT_RAW_SCAN_RESULTS + +config WIFI_MGMT_RAW_SCAN_RESULT_LENGTH + int "Maximum length of raw scan results" + default 512 + help + This option defines the maximum length of raw scan results. + +config WIFI_MGMT_RAW_SCAN_RESULTS_ONLY + bool "Only raw scan results" + help + This option enables only raw scan results. When enabled, the raw scan + results (beacons or probe responses) are provided to the application. + The scan results are not parsed and the application is responsible + for parsing the scan results. Normal scan results are not provided + to the application. + +endif # WIFI_MGMT_RAW_SCAN_RESULTS diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 3a0f41f63d26..77d0e8322adc 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -81,8 +81,10 @@ static void scan_result_cb(struct net_if *iface, int status, return; } +#ifndef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_RESULT, iface, entry, sizeof(struct wifi_scan_result)); +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */ } static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, @@ -362,3 +364,20 @@ void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, iface, INT_TO_POINTER(twt_sleep_state), sizeof(twt_sleep_state)); } + +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS +void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, + struct wifi_raw_scan_result *raw_scan_result) +{ + if (raw_scan_result->frame_length > CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH) { + LOG_INF("raw scan result frame length = %d too big," + "saving upto max raw scan length = %d", + raw_scan_result->frame_length, + CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH); + } + + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_RAW_SCAN_RESULT, + iface, raw_scan_result, + sizeof(*raw_scan_result)); +} +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 1fbbf54fd3c9..3502fe551af0 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -26,11 +26,20 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #define WIFI_SHELL_MODULE "wifi" +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY +#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_RAW_SCAN_RESULT | \ + NET_EVENT_WIFI_SCAN_DONE | \ + NET_EVENT_WIFI_CONNECT_RESULT | \ + NET_EVENT_WIFI_DISCONNECT_RESULT | \ + NET_EVENT_WIFI_TWT) +#else #define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_SCAN_RESULT | \ NET_EVENT_WIFI_SCAN_DONE | \ NET_EVENT_WIFI_CONNECT_RESULT | \ NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_TWT) + NET_EVENT_WIFI_TWT | \ + NET_EVENT_WIFI_RAW_SCAN_RESULT) +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */ static struct { const struct shell *sh; @@ -101,6 +110,81 @@ static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) sizeof(mac_string_buf)) : "")); } +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS +static int wifi_freq_to_channel(int frequency) +{ + int channel = 0; + + if (frequency == 2484) { /* channel 14 */ + channel = 14; + } else if ((frequency <= 2472) && (frequency >= 2412)) { + channel = ((frequency - 2412) / 5) + 1; + } else if ((frequency <= 5320) && (frequency >= 5180)) { + channel = ((frequency - 5180) / 5) + 36; + } else if ((frequency <= 5720) && (frequency >= 5500)) { + channel = ((frequency - 5500) / 5) + 100; + } else if ((frequency <= 5895) && (frequency >= 5745)) { + channel = ((frequency - 5745) / 5) + 149; + } else { + channel = frequency; + } + + return channel; +} + +static enum wifi_frequency_bands wifi_freq_to_band(int frequency) +{ + enum wifi_frequency_bands band = WIFI_FREQ_BAND_2_4_GHZ; + + if ((frequency >= 2401) && (frequency <= 2495)) { + band = WIFI_FREQ_BAND_2_4_GHZ; + } else if ((frequency >= 5170) && (frequency <= 5895)) { + band = WIFI_FREQ_BAND_5_GHZ; + } else { + band = WIFI_FREQ_BAND_6_GHZ; + } + + return band; +} + +static void handle_wifi_raw_scan_result(struct net_mgmt_event_callback *cb) +{ + struct wifi_raw_scan_result *raw = + (struct wifi_raw_scan_result *)cb->info; + int channel; + int band; + int rssi; + int i = 0; + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + + scan_result++; + + if (scan_result == 1U) { + print(context.sh, SHELL_NORMAL, + "\n%-4s | %-13s | %-4s | %-15s | %-15s | %-32s\n", + "Num", "Channel (Band)", "RSSI", "BSSID", "Frame length", "Frame Body"); + } + + rssi = raw->rssi; + channel = wifi_freq_to_channel(raw->frequency); + band = wifi_freq_to_band(raw->frequency); + + print(context.sh, SHELL_NORMAL, "%-4d | %-4u (%-6s) | %-4d | %s | %-4d ", + scan_result, + channel, + wifi_band_txt(band), + rssi, + net_sprint_ll_addr_buf(raw->data + 10, WIFI_MAC_ADDR_LEN, mac_string_buf, + sizeof(mac_string_buf)), raw->frame_length); + + for (i = 0; i < 32; i++) { + print(context.sh, SHELL_NORMAL, "%02X ", *(raw->data + i)); + } + + print(context.sh, SHELL_NORMAL, "\n"); +} +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ + static void handle_wifi_scan_done(struct net_mgmt_event_callback *cb) { const struct wifi_status *status = @@ -216,6 +300,11 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, case NET_EVENT_WIFI_TWT: handle_wifi_twt_event(cb); break; +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS + case NET_EVENT_WIFI_RAW_SCAN_RESULT: + handle_wifi_raw_scan_result(cb); + break; +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ default: break; } From 47179329c92210fb71baad46ad5aa7b20cd506ba Mon Sep 17 00:00:00 2001 From: Bansidhar Mangalwedhekar Date: Sun, 7 May 2023 22:48:14 +0530 Subject: [PATCH 120/528] [nrf fromlist] wifi: thingy53: Update dts and dtsi files to support nrf7002 eval board - Add SPI4 pin definitions to the dtsi files - Add edge connector node for nrf7002 eval board Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57636 Signed-off-by: Bansidhar Mangalwedhekar (cherry picked from commit ed5f87293cfa907650db2d69a865414cd9ec1e1e) --- .../thingy53_nrf5340_common-pinctrl.dtsi | 18 ++++++++++++ .../thingy53_nrf5340_common.dts | 23 +++++++++++++++ .../gpio/nordic,thingy53-edge-connector.yaml | 29 +++++++++++++++++++ 3 files changed, 70 insertions(+) create mode 100644 dts/bindings/gpio/nordic,thingy53-edge-connector.yaml diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common-pinctrl.dtsi b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common-pinctrl.dtsi index 6f3e5631de9c..2a9fa480bab9 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common-pinctrl.dtsi +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common-pinctrl.dtsi @@ -108,4 +108,22 @@ }; }; + spi4_default: spi4_default { + group1 { + psels = , + , + ; + nordic,drive-mode = ; + }; + }; + + spi4_sleep: spi4_sleep { + group1 { + psels = , + , + ; + low-power-enable; + }; + }; + }; diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts index 3ce47a68f628..01d8590e2756 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts @@ -64,6 +64,20 @@ }; }; + edge_connector: connector { + compatible = "nordic,thingy53-edge-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <8 0 &gpio0 5 0>, /* P8, P0.05/AIN1 */ + <9 0 &gpio0 4 0>, /* P9, P0.04/AIN0 */ + <15 0 &gpio0 8 0>, /* P15, P0.08/TRACEDATA3 */ + <16 0 &gpio0 9 0>, /* P16, P0.09/TRACEDATA2 */ + <17 0 &gpio0 10 0>, /* P17, P0.10/TRACEDATA1 */ + <18 0 &gpio0 11 0>, /* P18, P0.11/TRACEDATA0 */ + <19 0 &gpio0 12 0>; /* P19, P0.12/TRACECLK */ + }; + npm1100_force_pwm_mode: npm1100_force_pwm_mode { compatible = "regulator-fixed"; regulator-name = "npm1100_force_pwm_mode"; @@ -250,6 +264,15 @@ }; }; +edge_connector_spi: &spi4 { + compatible = "nordic,nrf-spim"; + status = "okay"; + cs-gpios = <&edge_connector 18 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&spi4_default>; + pinctrl-1 = <&spi4_sleep>; + pinctrl-names = "default", "sleep"; +}; + &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/dts/bindings/gpio/nordic,thingy53-edge-connector.yaml b/dts/bindings/gpio/nordic,thingy53-edge-connector.yaml new file mode 100644 index 000000000000..32a7641c2a8c --- /dev/null +++ b/dts/bindings/gpio/nordic,thingy53-edge-connector.yaml @@ -0,0 +1,29 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: | + This binding provides a nexus mapping for 20 pins (HW rev 1.1.0) as depicted below + P1 VLi-Ion + P2 VBat + P3 VOUTB + P4 VDD_nRF53 + P5 P1.01/GRANT + P6 P1.00/REQ + P7 RESET + P8 P0.05/AIN1 + P9 P0.04/AIN0 + P10 LOAD_SW_DISABLE + P11 VOUTB_2 + P12 VDD_nRF21540 + P13 VDD_EXP_BRD + P14 3V3 + P15 P0.08/TRACEDATA3 + P16 P0.09/TRACEDATA2 + P17 P0.10/TRACEDATA1 + P18 P0.11/TRACEDATA0 + P19 P0.12/TRACECLK + P20 GND + +compatible: "nordic,thingy53-edge-connector" + +include: [gpio-nexus.yaml, base.yaml] From 4d2abca02509dbac1d22afcae7a35b295a2574ec Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Wed, 8 Mar 2023 11:58:28 +0530 Subject: [PATCH 121/528] [nrf fromtree] net: shell: Check connection & capabilities in any TWT operation Connection status & AP capabilities checked before any TWT operation is initiated. Signed-off-by: Ajay Parida (cherry picked from commit 95dbf187fb9aaa3edb78e980bcf99b6796eda7a1) (cherry picked from commit 971b65314a74ab3f0a532d53401c12799dead488) --- include/zephyr/net/wifi.h | 37 +++++++++++++++++++++++++++++++++ include/zephyr/net/wifi_mgmt.h | 2 ++ subsys/net/l2/wifi/wifi_mgmt.c | 31 +++++++++++++++++++++++++++ subsys/net/l2/wifi/wifi_shell.c | 26 ++++++++++++++++------- 4 files changed, 88 insertions(+), 8 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index eb9270042c22..3088deed9bcc 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -336,4 +336,41 @@ enum wifi_twt_setup_resp_status { WIFI_TWT_RESP_NOT_RECEIVED, }; +enum wifi_twt_fail_reason { + WIFI_TWT_FAIL_UNSPECIFIED, + WIFI_TWT_FAIL_CMD_EXEC_FAIL, + WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED, + WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS, + WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED, + WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB, + WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB, + WIFI_TWT_FAIL_OPERATION_IN_PROGRESS, + WIFI_TWT_FAIL_INVALID_FLOW_ID, +}; + +static const char * const twt_err_code_tbl[] = { + [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecfied", + [WIFI_TWT_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", + [WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED] = + "Operation not supported", + [WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS] = + "Unable to get iface status", + [WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED] = + "Device not connected", + [WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB] = "Peer not HE capable", + [WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB] = "Peer not TWT capable", + [WIFI_TWT_FAIL_OPERATION_IN_PROGRESS] = + "Operation already in progress", + [WIFI_TWT_FAIL_INVALID_FLOW_ID] = + "Invalid negotiated flow id", +}; + +static inline const char *get_twt_err_code_str(int16_t err_no) +{ + if ((err_no) < ARRAY_SIZE(twt_err_code_tbl)) { + return twt_err_code_tbl[err_no]; + } + + return ""; +} #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index d136c0b69526..0034f1589b62 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -191,6 +191,7 @@ struct wifi_iface_status { int rssi; unsigned char dtim_period; unsigned short beacon_interval; + bool twt_capable; }; struct wifi_ps_params { @@ -230,6 +231,7 @@ struct wifi_twt_params { bool teardown_all; } teardown; }; + enum wifi_twt_fail_reason fail_reason; }; /* Flow ID is only 3 bits */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 77d0e8322adc..c74ba278183f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -298,12 +298,43 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; struct wifi_twt_params *twt_params = data; + struct wifi_iface_status info = { 0 }; if (off_api == NULL || off_api->set_twt == NULL) { + twt_params->fail_reason = + WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED; return -ENOTSUP; } + if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, + sizeof(struct wifi_iface_status))) { + twt_params->fail_reason = + WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS; + goto fail; + } + + if (info.state != WIFI_STATE_COMPLETED) { + twt_params->fail_reason = + WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED; + goto fail; + } + + if (info.link_mode < WIFI_6) { + twt_params->fail_reason = + WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB; + goto fail; + } + + if (!info.twt_capable) { + twt_params->fail_reason = + WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB; + goto fail; + } + return off_api->set_twt(dev, twt_params); +fail: + return -ENOEXEC; + } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT, wifi_set_twt); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 3502fe551af0..9a71324b2429 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -492,6 +492,8 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "RSSI: %d\n", status.rssi); shell_fprintf(sh, SHELL_NORMAL, "Beacon Interval: %d\n", status.beacon_interval); shell_fprintf(sh, SHELL_NORMAL, "DTIM: %d\n", status.dtim_period); + shell_fprintf(sh, SHELL_NORMAL, "TWT: %s\n", + status.twt_capable ? "Supported" : "Not supported"); } return 0; @@ -712,9 +714,11 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, return -EINVAL; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s with %s failed\n", + shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type]); + wifi_twt_negotiation_type2str[params.negotiation_type], + get_twt_err_code_str(params.fail_reason)); + return -ENOEXEC; } @@ -766,9 +770,11 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, params.setup_cmd = setup_cmd; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s with %s failed\n", + shell_fprintf(sh, SHELL_WARNING, "%s with %s failed. reason : %s\n", wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type]); + wifi_twt_negotiation_type2str[params.negotiation_type], + get_twt_err_code_str(params.fail_reason)); + return -ENOEXEC; } @@ -810,9 +816,11 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, return -EINVAL; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s with %s failed\n", + shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type]); + wifi_twt_negotiation_type2str[params.negotiation_type], + get_twt_err_code_str(params.fail_reason)); + return -ENOEXEC; } @@ -835,9 +843,11 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, params.teardown.teardown_all = 1; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s with %s failed\n", + shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type]); + wifi_twt_negotiation_type2str[params.negotiation_type], + get_twt_err_code_str(params.fail_reason)); + return -ENOEXEC; } From 5e46751f2fd5f9138b10852f0dda8c36470b933c Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Thu, 11 May 2023 13:32:57 +0530 Subject: [PATCH 122/528] [nrf fromtree] net: shell: Fix CI warning implicit declaration Fixes "implicit declaration of function ARRAY_SIZE" observed during CI. Signed-off-by: Ajay Parida (cherry picked from commit f519b4d6f24ed5c8333f9dafccadbd7780487967) (cherry picked from commit b0323d30d0eef312400c35bcaa61a8e9aefd3e40) --- include/zephyr/net/wifi.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 3088deed9bcc..00b7a827743f 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -12,6 +12,8 @@ #ifndef ZEPHYR_INCLUDE_NET_WIFI_H_ #define ZEPHYR_INCLUDE_NET_WIFI_H_ +#include /* for ARRAY_SIZE */ + #define WIFI_COUNTRY_CODE_LEN 2 /* Not having support for legacy types is deliberate to enforce From 9c36cddb8834d94411c84e49a2696657a2e7655e Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Tue, 16 May 2023 02:19:42 +0530 Subject: [PATCH 123/528] [nrf noup] net: Increase connection manager stack size Connection manager L2 Wi-Fi calls internally invoke WPA supplicant calls which requires higher stack size. Update the default stack size for such cases. Marking this "nrf noup" since supplicant is not upstream yet. Signed-off-by: Ravi Dondaputi (cherry picked from commit 1d11b7423aff13dc3afcac00e78ce73b07707a09) --- subsys/net/conn_mgr/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig index 1c9a09104e9c..e74a243b4a0a 100644 --- a/subsys/net/conn_mgr/Kconfig +++ b/subsys/net/conn_mgr/Kconfig @@ -24,6 +24,7 @@ source "subsys/net/Kconfig.template.log_config.net" config NET_CONNECTION_MANAGER_STACK_SIZE int "Size of the stack allocated for the connection manager" + default 8192 if WPA_SUPP default 512 help Sets the stack size which will be used by the connection manager From 35c20d02eaa33eaac278b0cfa576d937b9c1feab Mon Sep 17 00:00:00 2001 From: Krishna T Date: Mon, 15 May 2023 20:30:09 +0530 Subject: [PATCH 124/528] [nrf noup] ci: Add Wi-Fi CI to the Wi-Fi modules fixup! [nrf noup] ci: add .github/test-spec.yml Signed-off-by: Krishna T (cherry picked from commit acb96b140c95e933546acc41cc6df22b609342db) --- .github/test-spec.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index c252335495ac..3fe9ba5fbecf 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -141,3 +141,7 @@ - "subsys/dfu/**/*" - "subsys/net/**/*" - "subsys/settings/**/*" + +"CI-wifi": + - "subsys/net/l2/wifi/**/*" + - "subsys/net/l2/ethernet/**/*" From 2bbd5535b02c355e55b3d58a12f0dae59497ad39 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Mon, 27 Mar 2023 19:02:21 +0530 Subject: [PATCH 125/528] [nrf fromtree] net: wifi_mgmt: Configure listen interval listen interval is the time periods the STAs may be in idle without listening beacons. By default STA wakes up for every DTIM period. If listen interval based power save is used STA uses configured listen interval period(default 10 beacon intervals) to wake up. Signed-off-by: Ajay Parida (cherry picked from commit 68403669c668f730a5ea0cf8a60c3e70c415debc) (cherry picked from commit 6be1c19c4442f2b62ce2fb34e5cbd5708030dd3b) --- include/zephyr/net/wifi.h | 8 +++++++ include/zephyr/net/wifi_mgmt.h | 4 +++- subsys/net/l2/wifi/wifi_mgmt.c | 16 +++++++++++++ subsys/net/l2/wifi/wifi_shell.c | 42 ++++++++++++++++++++++++++++++++- 4 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 00b7a827743f..f5d09880c600 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -16,6 +16,9 @@ #define WIFI_COUNTRY_CODE_LEN 2 +#define WIFI_LISTEN_INTERVAL_MIN 0 +#define WIFI_LISTEN_INTERVAL_MAX 65535 + /* Not having support for legacy types is deliberate to enforce * higher security. */ @@ -375,4 +378,9 @@ static inline const char *get_twt_err_code_str(int16_t err_no) return ""; } + +enum ps_param_type { + WIFI_PS_PARAM_STATE, + WIFI_PS_PARAM_LISTEN_INTERVAL, +}; #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 0034f1589b62..c8144db1afd6 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -196,6 +196,8 @@ struct wifi_iface_status { struct wifi_ps_params { enum wifi_ps enabled; + unsigned short listen_interval; + enum ps_param_type type; }; struct wifi_ps_mode_params { @@ -257,9 +259,9 @@ struct wifi_twt_flow_info { struct wifi_ps_config { struct wifi_twt_flow_info twt_flows[WIFI_MAX_TWT_FLOWS]; - bool enabled; enum wifi_ps_mode mode; char num_twt_flows; + struct wifi_ps_params ps_params; }; /* Generic get/set operation for any command*/ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index c74ba278183f..68281c0fd9e1 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -243,11 +243,27 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; struct wifi_ps_params *ps_params = data; + struct wifi_iface_status info = { 0 }; if (off_api == NULL || off_api->set_power_save == NULL) { return -ENOTSUP; } + switch (ps_params->type) { + case WIFI_PS_PARAM_LISTEN_INTERVAL: + if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, + sizeof(struct wifi_iface_status))) { + return -EIO; + } + + if (info.state == WIFI_STATE_COMPLETED) { + return -ENOTSUP; + } + break; + case WIFI_PS_PARAM_STATE: + default: + break; + } return off_api->set_power_save(dev, ps_params); } diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 9a71324b2429..163bb4b24d7f 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -571,12 +571,15 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) } shell_fprintf(sh, SHELL_NORMAL, "PS status: %s\n", - wifi_ps2str[config.enabled]); + wifi_ps2str[config.ps_params.enabled]); if (config.enabled) { shell_fprintf(sh, SHELL_NORMAL, "PS mode: %s\n", wifi_ps_mode2str[config.mode]); } + shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", + config.ps_params.listen_interval); + if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); } else { @@ -605,6 +608,8 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } + params.type = WIFI_PS_PARAM_STATE; + if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "Power save %s failed\n", params.enabled ? "enable" : "disable"); @@ -961,6 +966,35 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, return 0; } +static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = net_if_get_default(); + struct wifi_ps_params params = { 0 }; + long interval = 0; + + context.sh = sh; + + if (!parse_number(sh, &interval, argv[1], + WIFI_LISTEN_INTERVAL_MIN, + WIFI_LISTEN_INTERVAL_MAX)) { + return -EINVAL; + } + + params.listen_interval = interval; + params.type = WIFI_PS_PARAM_LISTEN_INTERVAL; + + if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { + shell_fprintf(sh, SHELL_WARNING, "Setting listen interval failed\n"); + return -ENOEXEC; + } + + shell_fprintf(sh, SHELL_NORMAL, + "Listen interval %hu\n", params.listen_interval); + + return 0; +} + + SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_CMD(disable, NULL, "Disable Access Point mode", @@ -1021,6 +1055,12 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(ps_timeout, NULL, "Configure Wi-Fi power save inactivity timer(in ms)", cmd_wifi_ps_timeout), + SHELL_CMD_ARG(ps_listen_interval, + NULL, + " - Listen interval in the range of <0-65535>", + cmd_wifi_listen_interval, + 2, + 0), SHELL_SUBCMD_SET_END ); From a4a7cf2106c9b9dc8f6799e8d2d939f0519e9bb7 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Tue, 28 Mar 2023 12:25:05 +0530 Subject: [PATCH 126/528] [nrf fromtree] net: wifi_mgmt: Configure ps wakeup mode 'ps_wakeup_mode' is used to set the wake up interval to either 'dtim or 'listen_interval'. By default the sta wakes up every dtim interval. With 'ps_wakeup_mode' set to 'listen_interval' sta will wake up for every listen interval period configured. Signed-off-by: Ajay Parida (cherry picked from commit bdef1bad786df9cafd9dd208d73a07056e4ce08f) (cherry picked from commit fae28e26e4f54b60bfb58b9d6eef63dadf70dcf7) --- include/zephyr/net/wifi.h | 11 +++++++++ include/zephyr/net/wifi_mgmt.h | 1 + subsys/net/l2/wifi/wifi_mgmt.c | 1 + subsys/net/l2/wifi/wifi_shell.c | 41 +++++++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index f5d09880c600..f3f9452cbab3 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -382,5 +382,16 @@ static inline const char *get_twt_err_code_str(int16_t err_no) enum ps_param_type { WIFI_PS_PARAM_STATE, WIFI_PS_PARAM_LISTEN_INTERVAL, + WIFI_PS_PARAM_WAKEUP_MODE, +}; + +enum wifi_ps_wakeup_mode { + WIFI_PS_WAKEUP_MODE_DTIM = 0, + WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL, +}; + +static const char * const wifi_ps_wakeup_mode2str[] = { + [WIFI_PS_WAKEUP_MODE_DTIM] = "PS wakeup mode DTIM", + [WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL] = "PS wakeup mode listen interval", }; #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index c8144db1afd6..7faf29cac513 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -197,6 +197,7 @@ struct wifi_iface_status { struct wifi_ps_params { enum wifi_ps enabled; unsigned short listen_interval; + enum wifi_ps_wakeup_mode wakeup_mode; enum ps_param_type type; }; diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 68281c0fd9e1..54950bded98f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -261,6 +261,7 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, } break; case WIFI_PS_PARAM_STATE: + case WIFI_PS_PARAM_WAKEUP_MODE: default: break; } diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 163bb4b24d7f..b7806296a482 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -580,6 +580,9 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", config.ps_params.listen_interval); + shell_fprintf(sh, SHELL_NORMAL, "PS wake up mode: %s\n", + config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); + if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); } else { @@ -994,6 +997,37 @@ static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *a return 0; } +static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *argv[]) +{ + struct net_if *iface = net_if_get_default(); + struct wifi_ps_params params = { 0 }; + + context.sh = sh; + + if (!strncmp(argv[1], "dtim", 4)) { + params.wakeup_mode = WIFI_PS_WAKEUP_MODE_DTIM; + } else if (!strncmp(argv[1], "listen_interval", 15)) { + params.wakeup_mode = WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL; + } else { + shell_fprintf(sh, SHELL_WARNING, "Invalid argument\n"); + shell_fprintf(sh, SHELL_INFO, + "Valid argument : / \n"); + return -ENOEXEC; + } + + params.type = WIFI_PS_PARAM_WAKEUP_MODE; + + if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { + shell_fprintf(sh, SHELL_WARNING, "Setting PS wake up mode to %s failed\n", + params.wakeup_mode ? "Listen interval" : "DTIM interval"); + return -ENOEXEC; + } + + shell_fprintf(sh, SHELL_NORMAL, "%s\n", + wifi_ps_wakeup_mode2str[params.wakeup_mode]); + + return 0; +} SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_CMD(disable, NULL, @@ -1061,6 +1095,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, cmd_wifi_listen_interval, 2, 0), + SHELL_CMD_ARG(ps_wakeup_mode, + NULL, + " : Set PS wake up mode to DTIM interval\n" + " : Set PS wake up mode to listen interval", + cmd_wifi_ps_wakeup_mode, + 2, + 0), SHELL_SUBCMD_SET_END ); From f9aa02a461c8dc10769112c2000ee0f47975c12d Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Fri, 21 Apr 2023 15:21:03 +0530 Subject: [PATCH 127/528] [nrf fromtree] net: shell: Code cleanup for ps related commands Setting ps_mode and ps_timeout related changes handled in single power save op. Signed-off-by: Ajay Parida (cherry picked from commit 49e6b0c25684c017e00ff775f54d64eb321dbe1f) (cherry picked from commit 2ff4e288f977ee015c1068bab916efe40eb583a2) --- include/zephyr/net/wifi.h | 2 ++ include/zephyr/net/wifi_mgmt.h | 14 ++------- subsys/net/l2/wifi/wifi_mgmt.c | 56 +++++++-------------------------- subsys/net/l2/wifi/wifi_shell.c | 53 +++++++++++++++++-------------- 4 files changed, 44 insertions(+), 81 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index f3f9452cbab3..d324ca57beb3 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -383,6 +383,8 @@ enum ps_param_type { WIFI_PS_PARAM_STATE, WIFI_PS_PARAM_LISTEN_INTERVAL, WIFI_PS_PARAM_WAKEUP_MODE, + WIFI_PS_PARAM_MODE, + WIFI_PS_PARAM_TIMEOUT, }; enum wifi_ps_wakeup_mode { diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 7faf29cac513..b0e306c94360 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -198,15 +198,9 @@ struct wifi_ps_params { enum wifi_ps enabled; unsigned short listen_interval; enum wifi_ps_wakeup_mode wakeup_mode; - enum ps_param_type type; -}; - -struct wifi_ps_mode_params { enum wifi_ps_mode mode; -}; - -struct wifi_ps_timeout_params { int timeout_ms; + enum ps_param_type type; }; struct wifi_twt_params { @@ -259,9 +253,8 @@ struct wifi_twt_flow_info { }; struct wifi_ps_config { - struct wifi_twt_flow_info twt_flows[WIFI_MAX_TWT_FLOWS]; - enum wifi_ps_mode mode; char num_twt_flows; + struct wifi_twt_flow_info twt_flows[WIFI_MAX_TWT_FLOWS]; struct wifi_ps_params ps_params; }; @@ -329,12 +322,9 @@ struct net_wifi_mgmt_offload { int (*get_stats)(const struct device *dev, struct net_stats_wifi *stats); #endif /* CONFIG_NET_STATISTICS_WIFI */ int (*set_power_save)(const struct device *dev, struct wifi_ps_params *params); - int (*set_power_save_mode)(const struct device *dev, struct wifi_ps_mode_params *params); int (*set_twt)(const struct device *dev, struct wifi_twt_params *params); int (*get_power_save_config)(const struct device *dev, struct wifi_ps_config *config); int (*reg_domain)(const struct device *dev, struct wifi_reg_domain *reg_domain); - int (*set_power_save_timeout)(const struct device *dev, - struct wifi_ps_timeout_params *ps_timeout); }; /* Make sure that the network interface API is properly setup inside diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 54950bded98f..38e993914512 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -250,7 +250,8 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, } switch (ps_params->type) { - case WIFI_PS_PARAM_LISTEN_INTERVAL: + case WIFI_PS_PARAM_LISTEN_INTERVAL: + case WIFI_PS_PARAM_MODE: if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, sizeof(struct wifi_iface_status))) { return -EIO; @@ -259,12 +260,15 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, if (info.state == WIFI_STATE_COMPLETED) { return -ENOTSUP; } - break; - case WIFI_PS_PARAM_STATE: - case WIFI_PS_PARAM_WAKEUP_MODE: - default: - break; - } + break; + case WIFI_PS_PARAM_STATE: + case WIFI_PS_PARAM_WAKEUP_MODE: + case WIFI_PS_PARAM_TIMEOUT: + break; + default: + return -ENOTSUP; + } + return off_api->set_power_save(dev, ps_params); } @@ -291,23 +295,6 @@ static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *ifac NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_CONFIG, wifi_get_power_save_config); -static int wifi_set_power_save_mode(uint32_t mgmt_request, struct net_if *iface, - void *data, size_t len) -{ - const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - struct wifi_ps_mode_params *ps_mode_params = data; - - if (off_api == NULL || off_api->set_power_save_mode == NULL) { - return -ENOTSUP; - } - - return off_api->set_power_save_mode(dev, ps_mode_params); -} - -NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_MODE, wifi_set_power_save_mode); - static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { @@ -384,27 +371,6 @@ static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN, wifi_reg_domain); -static int wifi_set_power_save_timeout(uint32_t mgmt_request, struct net_if *iface, - void *data, size_t len) -{ - const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - struct wifi_ps_timeout_params *ps_timeout = data; - - if (off_api == NULL || off_api->set_power_save_timeout == NULL) { - return -ENOTSUP; - } - - if (!data || len != sizeof(*ps_timeout)) { - return -EINVAL; - } - - return off_api->set_power_save_timeout(dev, ps_timeout); -} - -NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_TIMEOUT, wifi_set_power_save_timeout); - void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, int twt_sleep_state) { diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index b7806296a482..ba89ca0cbdee 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -572,9 +572,9 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS status: %s\n", wifi_ps2str[config.ps_params.enabled]); - if (config.enabled) { + if (config.ps_params.enabled) { shell_fprintf(sh, SHELL_NORMAL, "PS mode: %s\n", - wifi_ps_mode2str[config.mode]); + wifi_ps_mode2str[config.ps_params.mode]); } shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", @@ -583,6 +583,9 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS wake up mode: %s\n", config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", + config.ps_params.timeout_ms); + if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); } else { @@ -627,25 +630,22 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_default(); - struct wifi_ps_mode_params params = { 0 }; + struct wifi_ps_params params = { 0 }; context.sh = sh; - if (argc != 2) { - shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); - return -ENOEXEC; - } - if (!strncmp(argv[1], "legacy", 6)) { params.mode = WIFI_PS_MODE_LEGACY; } else if (!strncmp(argv[1], "wmm", 3)) { params.mode = WIFI_PS_MODE_WMM; } else { - shell_fprintf(sh, SHELL_WARNING, "Invalid power save mode\n"); + shell_fprintf(sh, SHELL_WARNING, "Invalid PS mode\n"); return -ENOEXEC; } - if (net_mgmt(NET_REQUEST_WIFI_PS_MODE, iface, ¶ms, sizeof(params))) { + params.type = WIFI_PS_PARAM_MODE; + + if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s failed\n", wifi_ps_mode2str[params.mode]); return -ENOEXEC; } @@ -658,17 +658,12 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_default(); - struct wifi_ps_timeout_params params = { 0 }; + struct wifi_ps_params params = { 0 }; long timeout_ms = 0; int err = 0; context.sh = sh; - if (argc != 2) { - shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); - return -ENOEXEC; - } - timeout_ms = shell_strtol(argv[1], 10, &err); if (err) { @@ -677,14 +672,15 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] } params.timeout_ms = timeout_ms; + params.type = WIFI_PS_PARAM_MODE; - if (net_mgmt(NET_REQUEST_WIFI_PS_TIMEOUT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Setting power save timeout failed\n"); + if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { + shell_fprintf(sh, SHELL_WARNING, "Setting PS timeout failed\n"); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, - "Power save timeout %d ms\n", params.timeout_ms); + "PS timeout %d ms\n", params.timeout_ms); return 0; } @@ -1072,9 +1068,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, cmd_wifi_connect), SHELL_CMD(disconnect, NULL, "Disconnect from the Wi-Fi AP", cmd_wifi_disconnect), - SHELL_CMD(ps, NULL, "Configure Wi-Fi power save on/off, no arguments will dump config", + SHELL_CMD(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", cmd_wifi_ps), - SHELL_CMD(ps_mode, NULL, "Configure Wi-Fi power save mode legacy/wmm", cmd_wifi_ps_mode), + SHELL_CMD_ARG(ps_mode, + NULL, + "\n" + "", + cmd_wifi_ps_mode, + 2, + 0), SHELL_CMD(scan, NULL, "Scan for Wi-Fi APs", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), @@ -1086,9 +1088,12 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "-f: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain), - SHELL_CMD(ps_timeout, NULL, - "Configure Wi-Fi power save inactivity timer(in ms)", - cmd_wifi_ps_timeout), + SHELL_CMD_ARG(ps_timeout, + NULL, + " - PS inactivity timer(in ms)", + cmd_wifi_ps_timeout, + 2, + 0), SHELL_CMD_ARG(ps_listen_interval, NULL, " - Listen interval in the range of <0-65535>", From 942eed74909e99601bada4e1ff38bf7e5a5abdf3 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Wed, 3 May 2023 14:52:09 +0530 Subject: [PATCH 128/528] [nrf fromtree] net: wifi_mgmt: Handle ps command error Failure of setting ps param is handled with error string at user/ app level. Signed-off-by: Ajay Parida (cherry picked from commit 7f9ba751e9cad55ce5abbd24ce155fada535371b) (cherry picked from commit 8282ac7d39e8214ea3e56b60ea3a11e98e592f2a) --- include/zephyr/net/wifi.h | 36 ++++++++++++++++++++++++++++++++- include/zephyr/net/wifi_mgmt.h | 1 + subsys/net/l2/wifi/wifi_mgmt.c | 6 ++++++ subsys/net/l2/wifi/wifi_shell.c | 33 +++++++++++++++++++++++------- 4 files changed, 68 insertions(+), 8 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index d324ca57beb3..d8aa28aa4aad 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -380,7 +380,7 @@ static inline const char *get_twt_err_code_str(int16_t err_no) } enum ps_param_type { - WIFI_PS_PARAM_STATE, + WIFI_PS_PARAM_STATE, WIFI_PS_PARAM_LISTEN_INTERVAL, WIFI_PS_PARAM_WAKEUP_MODE, WIFI_PS_PARAM_MODE, @@ -396,4 +396,38 @@ static const char * const wifi_ps_wakeup_mode2str[] = { [WIFI_PS_WAKEUP_MODE_DTIM] = "PS wakeup mode DTIM", [WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL] = "PS wakeup mode listen interval", }; + +enum wifi_config_ps_param_fail_reason { + WIFI_PS_PARAM_FAIL_UNSPECIFIED, + WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL, + WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED, + WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS, + WIFI_PS_PARAM_FAIL_DEVICE_NOT_CONNECTED, + WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED, + WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID, +}; + +static const char * const ps_param_config_err_code_tbl[] = { + [WIFI_PS_PARAM_FAIL_UNSPECIFIED] = "Unspecfied", + [WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", + [WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED] = + "Operation not supported", + [WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS] = + "Unable to get iface status", + [WIFI_PS_PARAM_FAIL_DEVICE_NOT_CONNECTED] = + "Can not set while device not connected", + [WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED] = + "Can not set while device already connected", + [WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID] = + "Can not set due to invalid range", +}; + +static inline const char *get_ps_config_err_code_str(int16_t err_no) +{ + if ((err_no) < ARRAY_SIZE(ps_param_config_err_code_tbl)) { + return ps_param_config_err_code_tbl[err_no]; + } + + return ""; +} #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index b0e306c94360..07f37ca8ed2f 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -201,6 +201,7 @@ struct wifi_ps_params { enum wifi_ps_mode mode; int timeout_ms; enum ps_param_type type; + enum wifi_config_ps_param_fail_reason fail_reason; }; struct wifi_twt_params { diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 38e993914512..6cbdea061692 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -254,10 +254,14 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, case WIFI_PS_PARAM_MODE: if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, sizeof(struct wifi_iface_status))) { + ps_params->fail_reason = + WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS; return -EIO; } if (info.state == WIFI_STATE_COMPLETED) { + ps_params->fail_reason = + WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED; return -ENOTSUP; } break; @@ -266,6 +270,8 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, case WIFI_PS_PARAM_TIMEOUT: break; default: + ps_params->fail_reason = + WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED; return -ENOTSUP; } diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index ba89ca0cbdee..71f879027791 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -617,8 +617,10 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) params.type = WIFI_PS_PARAM_STATE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Power save %s failed\n", - params.enabled ? "enable" : "disable"); + shell_fprintf(sh, SHELL_WARNING, + "PS %s failed. Reason: %s\n", + params.enabled ? "enable" : "disable", + get_ps_config_err_code_str(params.fail_reason)); return -ENOEXEC; } @@ -646,7 +648,9 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) params.type = WIFI_PS_PARAM_MODE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s failed\n", wifi_ps_mode2str[params.mode]); + shell_fprintf(sh, SHELL_WARNING, "%s failed Reason : %s\n", + wifi_ps_mode2str[params.mode], + get_ps_config_err_code_str(params.fail_reason)); return -ENOEXEC; } @@ -675,7 +679,9 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] params.type = WIFI_PS_PARAM_MODE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Setting PS timeout failed\n"); + shell_fprintf(sh, SHELL_WARNING, + "Setting PS timeout failed. Reason : %s\n", + get_ps_config_err_code_str(params.fail_reason)); return -ENOEXEC; } @@ -983,7 +989,18 @@ static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *a params.type = WIFI_PS_PARAM_LISTEN_INTERVAL; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Setting listen interval failed\n"); + if (params.fail_reason == + WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID) { + shell_fprintf(sh, SHELL_WARNING, + "Setting listen interval failed. Reason :%s\n", + get_ps_config_err_code_str(params.fail_reason)); + shell_fprintf(sh, SHELL_WARNING, + "Hardware support valid range : 3 - 65535\n"); + } else { + shell_fprintf(sh, SHELL_WARNING, + "Setting listen interval failed. Reason :%s\n", + get_ps_config_err_code_str(params.fail_reason)); + } return -ENOEXEC; } @@ -1014,8 +1031,10 @@ static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *ar params.type = WIFI_PS_PARAM_WAKEUP_MODE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Setting PS wake up mode to %s failed\n", - params.wakeup_mode ? "Listen interval" : "DTIM interval"); + shell_fprintf(sh, SHELL_WARNING, + "Setting PS wake up mode to %s failed..Reason :%s\n", + params.wakeup_mode ? "Listen interval" : "DTIM interval", + get_ps_config_err_code_str(params.fail_reason)); return -ENOEXEC; } From 8a7a845140d5f39be185962a05a651fcd784d394 Mon Sep 17 00:00:00 2001 From: Krishna T Date: Mon, 27 Mar 2023 22:34:56 +0530 Subject: [PATCH 129/528] [nrf fromlist] net: context: Set priority based on DSCP If a socket has DSCP set then the packets from the socket should also be marked with appropriate priority in case traffic classes are used in networking stack. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/56259 Signed-off-by: Krishna T (cherry picked from commit 6065f400b3183ce127a2ffc536e3a6c8241f92ea) --- subsys/net/ip/ipv4.h | 10 ++++++++++ subsys/net/ip/ipv6.h | 10 ++++++++++ subsys/net/ip/net_context.c | 10 ++++++++++ 3 files changed, 30 insertions(+) diff --git a/subsys/net/ip/ipv4.h b/subsys/net/ip/ipv4.h index da1e227cf5f7..1359d04bc032 100644 --- a/subsys/net/ip/ipv4.h +++ b/subsys/net/ip/ipv4.h @@ -231,6 +231,16 @@ static inline void net_ipv4_set_dscp(uint8_t *tos, uint8_t dscp) *tos |= (dscp << NET_IPV4_DSCP_OFFSET) & NET_IPV4_DSCP_MASK; } +/** + * @brief Convert DSCP value to priority. + * + * @param dscp DSCP value. + */ +static inline uint8_t net_ipv4_dscp_to_priority(uint8_t dscp) +{ + return dscp >> 3; +} + /** * @brief Decode ECN value from ToS field. * diff --git a/subsys/net/ip/ipv6.h b/subsys/net/ip/ipv6.h index 80543084744a..be97731577ab 100644 --- a/subsys/net/ip/ipv6.h +++ b/subsys/net/ip/ipv6.h @@ -523,6 +523,16 @@ static inline void net_ipv6_set_dscp(uint8_t *tc, uint8_t dscp) *tc |= (dscp << NET_IPV6_DSCP_OFFSET) & NET_IPV6_DSCP_MASK; } +/** + * @brief Convert DSCP value to priority. + * + * @param dscp DSCP value. + */ +static inline uint8_t net_ipv6_dscp_to_priority(uint8_t dscp) +{ + return dscp >> 3; +} + /** * @brief Decode ECN value from TC field. * diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 10787be335fd..d4aa188573d2 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -895,6 +895,11 @@ int net_context_create_ipv4_new(struct net_context *context, #if defined(CONFIG_NET_CONTEXT_DSCP_ECN) net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(context->options.dscp_ecn)); net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(context->options.dscp_ecn)); + /* Direct priority takes precedence over DSCP */ + if (!IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) { + net_pkt_set_priority(pkt, net_ipv4_dscp_to_priority( + net_ipv4_get_dscp(context->options.dscp_ecn))); + } #endif return net_ipv4_create(pkt, src, dst); @@ -925,6 +930,11 @@ int net_context_create_ipv6_new(struct net_context *context, #if defined(CONFIG_NET_CONTEXT_DSCP_ECN) net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(context->options.dscp_ecn)); net_pkt_set_ip_ecn(pkt, net_ipv6_get_ecn(context->options.dscp_ecn)); + /* Direct priority takes precedence over DSCP */ + if (!IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) { + net_pkt_set_priority(pkt, net_ipv6_dscp_to_priority( + net_ipv6_get_dscp(context->options.dscp_ecn))); + } #endif return net_ipv6_create(pkt, src, dst); From b1b22e2fd889c21ee9b2356dcc54edcb3a7e851f Mon Sep 17 00:00:00 2001 From: Krishna T Date: Mon, 15 May 2023 18:58:02 +0530 Subject: [PATCH 130/528] [nrf fromtree] net: wifi: Add an event for disconnect complete This is needed for applications that rely on WPA supplicant being in disconnected state before issue subsequent commands (e.g., issue scan immediately after disconnect fails, until disconnect is completed). Signed-off-by: Krishna T (cherry picked from commit 10f3ca2e1d386949ffa85d33d9fc7dddd5782502) (cherry picked from commit c6c34d7651a4c6416e38e81a662ec04aa5c290d2) --- include/zephyr/net/wifi_mgmt.h | 5 +++++ subsys/net/l2/wifi/wifi_mgmt.c | 12 ++++++++++++ 2 files changed, 17 insertions(+) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 07f37ca8ed2f..8740d6b4bd45 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -114,6 +114,7 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_TWT, NET_EVENT_WIFI_CMD_TWT_SLEEP_STATE, NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT, + NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -139,6 +140,9 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_RAW_SCAN_RESULT \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT) + +#define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ + (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) /* Each result is provided to the net_mgmt_event_callback * via its info attribute (see net_mgmt.h) */ @@ -344,6 +348,7 @@ void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, int twt_sleep_state); void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, struct wifi_raw_scan_result *raw_scan_info); #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ +void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, int status); #ifdef __cplusplus } #endif diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 6cbdea061692..a1939af6e869 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -401,3 +401,15 @@ void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, sizeof(*raw_scan_result)); } #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ + +void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, + int status) +{ + struct wifi_status cnx_status = { + .status = status, + }; + + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, + iface, &cnx_status, + sizeof(struct wifi_status)); +} From 523394d8ce07f2a9b0fb5cfb7824f2e6fef57247 Mon Sep 17 00:00:00 2001 From: Krishna T Date: Tue, 16 May 2023 17:51:31 +0530 Subject: [PATCH 131/528] [nrf fromtree] net: wifi: Fix typo in event Wrong macro was copied, this causes the event to fail. Signed-off-by: Krishna T (cherry picked from commit b7cabb72fab9344c11a43284b014db71e6fc3471) (cherry picked from commit 72190c87d49c1039fe2159ab355504ea3e7261a5) --- subsys/net/l2/wifi/wifi_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index a1939af6e869..4548864fe7c7 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -409,7 +409,7 @@ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, .status = status, }; - net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_COMPLETE, iface, &cnx_status, sizeof(struct wifi_status)); } From 2999c4216d49820f1ff7e11c2fa15e27497ce9af Mon Sep 17 00:00:00 2001 From: Mateusz Kapala Date: Tue, 16 May 2023 14:00:11 +0200 Subject: [PATCH 132/528] [nrf fromtree] bluetooth: host: Fix NULL pointer dereference in bt_conn_auth_cb_overlay There is a check in bt_conn_auth_cb_overlay function which validates if content of the callback structure is correct, but there is no NULL-check on the structure pointer itself, which could result in NULL pointer dereference. It should be possible to set the callback structure pointer to `NULL` using bt_conn_auth_cb_overlay function if the application requires ex. Just Works pairing for one Bluetooth identity and global callbacks are configured for advanced pairing scheme (like Passkey Display) for other Bluetooth identity. Signed-off-by: Mateusz Kapala (cherry picked from commit 15bd8b256f933d322d29dce0505049be1331a5d7) (cherry picked from commit 10d1197916f81fd8017c2962a88476aba671c773) --- subsys/bluetooth/host/conn.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 10d894a4444b..671229682a3a 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -3108,10 +3108,14 @@ int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb) #if defined(CONFIG_BT_SMP) int bt_conn_auth_cb_overlay(struct bt_conn *conn, const struct bt_conn_auth_cb *cb) { + CHECKIF(conn == NULL) { + return -EINVAL; + } + /* The cancel callback must always be provided if the app provides * interactive callbacks. */ - if (!cb->cancel && + if (cb && !cb->cancel && (cb->passkey_display || cb->passkey_entry || cb->passkey_confirm || cb->pairing_confirm)) { return -EINVAL; From 830bdd033429a7ea2fc926ff9714575e5d6b4fed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20Jasi=C5=84ski?= Date: Thu, 18 May 2023 12:59:53 +0200 Subject: [PATCH 133/528] [nrf fromtree] manifest: openthread upmerge to `d9abe30` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit openthread upmerge to `d9abe30` Signed-off-by: Piotr Jasiński (cherry picked from commit 9efd52fb90e21b8c6f3a0d671c003801c22ead76) (cherry picked from commit 1648ab1124ac3d653a2afb1f983c0aa4e654d842) --- modules/openthread/Kconfig.thread | 14 +++++++++---- .../platform/openthread-core-zephyr-config.h | 20 ++++++++++++++----- west.yml | 2 +- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/modules/openthread/Kconfig.thread b/modules/openthread/Kconfig.thread index 3a84dc87ad55..0a7a399e9032 100644 --- a/modules/openthread/Kconfig.thread +++ b/modules/openthread/Kconfig.thread @@ -87,11 +87,17 @@ config OPENTHREAD_CSL_RECEIVE_TIME_AHEAD int "CSL receiver wake up margin in microseconds" default 5000 -config OPENTHREAD_CSL_MIN_RECEIVE_ON - int "Minimum CSL receive window" - default 5696 +config OPENTHREAD_MIN_RECEIVE_ON_AHEAD + int "Minimum receiving time before start of MHR" + default 192 help - The minimum CSL receive window (in microseconds) required to receive a full IEEE 802.15.4 frame + The minimum time (microseconds) that radio has to be in receive mode before the start of the MHR. + +config OPENTHREAD_MIN_RECEIVE_ON_AFTER + int "Minimum receiving time after start of MHR" + default 5504 + help + The minimum time (microseconds) that radio should be in receive mode after the start of the MHR. config OPENTHREAD_PLATFORM_CSL_UNCERT int "CSL uncertainty" diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 3cb1be96c439..7eaccf7948df 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -285,14 +285,24 @@ #endif /* CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD */ /** - * @def OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON + * @def OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD * - * The minimum CSL receive window (in microseconds) required to receive an IEEE 802.15.4 frame. + * The minimum time (microseconds) that radio has to be in receive mode before the start of the MHR. * */ -#ifdef CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON -#define OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON -#endif /* CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON */ +#ifdef CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD +#define OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD +#endif /* CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD */ + +/** + * @def OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER + * + * The minimum time (microseconds) that radio has to be in receive mode after the start of the MHR . + * + */ +#ifdef CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER +#define OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER +#endif /* CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER */ /** * @def OPENTHREAD_CONFIG_CSL_TIMEOUT diff --git a/west.yml b/west.yml index 746542a8bc72..b4c5274e885a 100644 --- a/west.yml +++ b/west.yml @@ -203,7 +203,7 @@ manifest: revision: aedcc262f93bbb1b0c2f58026911575729b7465c path: modules/lib/open-amp - name: openthread - revision: 1f1a826d1891fc99d14822abc0a1de257e9c6e9b + revision: d9abe3071c0131a4adb5d7e7451319b735e6d855 path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From 9e533ba14c65755c5d1e25ccaab836a765d22d9f Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Thu, 18 May 2023 15:37:33 +0530 Subject: [PATCH 134/528] [nrf fromtree] net: shell: Fix for PS timeout param type. Param type is set to correct type for power save timeout. Signed-off-by: Ajay Parida (cherry picked from commit d47021b2f9cdb925e36e947ea23eaced1fa654c1) (cherry picked from commit 5acaefeafa7a96bd8199a94f520dbdacc7d14160) --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 71f879027791..4de52f95926c 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -676,7 +676,7 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] } params.timeout_ms = timeout_ms; - params.type = WIFI_PS_PARAM_MODE; + params.type = WIFI_PS_PARAM_TIMEOUT; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, From 7de382d54a3b70851a4faedcf990b0926c69f56a Mon Sep 17 00:00:00 2001 From: Ravi Dondaputi Date: Wed, 10 May 2023 20:59:19 +0530 Subject: [PATCH 135/528] [nrf fromtree] net: wifi: Display MFP info in scan results Display MFP info in scan results. Signed-off-by: Ravi Dondaputi (cherry picked from commit 0889ceaa4e63feed4ed4a223f986c34be26f3830) (cherry picked from commit 1b36aa5754cfb699e3599b66ba21c4192fc35227) --- subsys/net/l2/wifi/wifi_shell.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 4de52f95926c..47e47830c8e8 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -96,18 +96,21 @@ static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) if (scan_result == 1U) { print(context.sh, SHELL_NORMAL, - "\n%-4s | %-32s %-5s | %-13s | %-4s | %-15s | %s\n", - "Num", "SSID", "(len)", "Chan (Band)", "RSSI", "Security", "BSSID"); + "\n%-4s | %-32s %-5s | %-13s | %-4s | %-15s | %-17s | %-8s\n", + "Num", "SSID", "(len)", "Chan (Band)", "RSSI", "Security", "BSSID", "MFP"); } - print(context.sh, SHELL_NORMAL, "%-4d | %-32s %-5u | %-4u (%-6s) | %-4d | %-15s | %s\n", + print(context.sh, SHELL_NORMAL, + "%-4d | %-32s %-5u | %-4u (%-6s) | %-4d | %-15s | %-17s | %-8s\n", scan_result, entry->ssid, entry->ssid_length, entry->channel, wifi_band_txt(entry->band), entry->rssi, wifi_security_txt(entry->security), ((entry->mac_length) ? - net_sprint_ll_addr_buf(entry->mac, WIFI_MAC_ADDR_LEN, mac_string_buf, - sizeof(mac_string_buf)) : "")); + net_sprint_ll_addr_buf(entry->mac, WIFI_MAC_ADDR_LEN, + mac_string_buf, + sizeof(mac_string_buf)) : ""), + wifi_mfp_txt(entry->mfp)); } #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS From c59f84dfae3602aaa90a3e4fe5a3e23d861e9236 Mon Sep 17 00:00:00 2001 From: Wojciech Slenska Date: Mon, 22 May 2023 13:53:41 +0200 Subject: [PATCH 136/528] [nrf fromtree] net: wifi: Fix cpp compatibility Fixed comparison between signed(int16_t) and unsigned(size_t) variables. Signed-off-by: Wojciech Slenska (cherry picked from commit 330a2f84c7425a3b6b9356b8d148ff44df171d99) (cherry picked from commit 162ab2710d551ce20685565cbed4ac3a535eed64) --- include/zephyr/net/wifi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index d8aa28aa4aad..cace143c93d6 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -372,7 +372,7 @@ static const char * const twt_err_code_tbl[] = { static inline const char *get_twt_err_code_str(int16_t err_no) { - if ((err_no) < ARRAY_SIZE(twt_err_code_tbl)) { + if ((err_no) < (int16_t)ARRAY_SIZE(twt_err_code_tbl)) { return twt_err_code_tbl[err_no]; } @@ -424,7 +424,7 @@ static const char * const ps_param_config_err_code_tbl[] = { static inline const char *get_ps_config_err_code_str(int16_t err_no) { - if ((err_no) < ARRAY_SIZE(ps_param_config_err_code_tbl)) { + if ((err_no) < (int16_t)ARRAY_SIZE(ps_param_config_err_code_tbl)) { return ps_param_config_err_code_tbl[err_no]; } From 002bc5202c53ceb27c3c30d16bb97f4fbd1d4aab Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Thu, 13 Apr 2023 10:48:30 +0100 Subject: [PATCH 137/528] [nrf fromtree] sysbuild: Fix issue with *_ROOT values not propagating Fixes an issue where variables like BOARD_ROOT would be provided to sysbuild but would then be lost on target images. Signed-off-by: Jamie McCrae (cherry picked from commit cd9465ac940ca9fdc66a1d95c158a31a06e471cb) (cherry picked from commit 9d641184f9d55df015d32d6e5c0631b187c8cc8c) --- cmake/modules/extensions.cmake | 65 +++++++++++++++++++++++++++------- cmake/modules/root.cmake | 7 ++++ 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 33951317c1e1..e7e8e12612b6 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2467,10 +2467,10 @@ function(zephyr_list transform list_var action) endfunction() # Usage: -# zephyr_get() -# zephyr_get( SYSBUILD [LOCAL|GLOBAL]) +# zephyr_get( [MERGE] [SYSBUILD [LOCAL|GLOBAL]]) # -# Return the value of as local scoped variable of same name. +# Return the value of as local scoped variable of same name. If MERGE +# is supplied, will return a list of found items. # # zephyr_get() is a common function to provide a uniform way of supporting # build settings that can be set from sysbuild, CMakeLists.txt, CMake cache, or @@ -2484,6 +2484,8 @@ endfunction() # - blinky_BOARD is considered a local sysbuild cache variable only for the # blinky image. # If no sysbuild scope is specified, GLOBAL is assumed. +# If using MERGE then SYSBUILD GLOBAL will get both the local and global +# sysbuild scope variables (in that order, if both exist). # - CMake cache, set by `-D=` or `set( CACHE ...) # - Environment # - Locally in CMakeLists.txt before 'find_package(Zephyr)' @@ -2493,7 +2495,7 @@ endfunction() # using `-DZEPHYR_TOOLCHAIN_VARIANT=`, then the value from the cache is # returned. function(zephyr_get variable) - cmake_parse_arguments(GET_VAR "" "SYSBUILD" "" ${ARGN}) + cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "" ${ARGN}) if(DEFINED GET_VAR_SYSBUILD) if(NOT (${GET_VAR_SYSBUILD} STREQUAL "GLOBAL" OR @@ -2505,6 +2507,13 @@ function(zephyr_get variable) set(GET_VAR_SYSBUILD "GLOBAL") endif() + if(GET_VAR_MERGE) + # Clear variable before appending items in MERGE mode + set(${variable}) + endif() + + set(used_global false) + if(SYSBUILD) get_property(sysbuild_name TARGET sysbuild_cache PROPERTY SYSBUILD_NAME) get_property(sysbuild_main_app TARGET sysbuild_cache PROPERTY SYSBUILD_MAIN_APP) @@ -2513,19 +2522,40 @@ function(zephyr_get variable) (${GET_VAR_SYSBUILD} STREQUAL "GLOBAL" OR sysbuild_main_app) ) get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) + set(used_global true) endif() endif() if(DEFINED sysbuild_${variable}) - set(${variable} ${sysbuild_${variable}} PARENT_SCOPE) - elseif(DEFINED CACHE{${variable}}) - set(${variable} $CACHE{${variable}} PARENT_SCOPE) - elseif(DEFINED ENV{${variable}}) - set(${variable} $ENV{${variable}} PARENT_SCOPE) - # Set the environment variable in CMake cache, so that a build invocation - # triggering a CMake rerun doesn't rely on the environment variable still - # being available / have identical value. - set(${variable} $ENV{${variable}} CACHE INTERNAL "") + if(GET_VAR_MERGE) + list(APPEND ${variable} ${sysbuild_${variable}}) + else() + set(${variable} ${sysbuild_${variable}} PARENT_SCOPE) + return() + endif() + endif() + if(SYSBUILD AND GET_VAR_MERGE AND NOT used_global AND ${GET_VAR_SYSBUILD} STREQUAL "GLOBAL") + get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) + list(APPEND ${variable} ${sysbuild_${variable}}) + endif() + if(DEFINED CACHE{${variable}}) + if(GET_VAR_MERGE) + list(APPEND ${variable} $CACHE{${variable}}) + else() + set(${variable} $CACHE{${variable}} PARENT_SCOPE) + return() + endif() + endif() + if(DEFINED ENV{${variable}}) + if(GET_VAR_MERGE) + list(APPEND ${variable} $ENV{${variable}}}) + else() + set(${variable} $ENV{${variable}} PARENT_SCOPE) + # Set the environment variable in CMake cache, so that a build invocation + # triggering a CMake rerun doesn't rely on the environment variable still + # being available / have identical value. + set(${variable} $ENV{${variable}} CACHE INTERNAL "") + endif() if(DEFINED ${variable} AND NOT "${${variable}}" STREQUAL "$ENV{${variable}}") # Variable exists as a local scoped variable, defined in a CMakeLists.txt @@ -2537,6 +2567,15 @@ function(zephyr_get variable) "Local scope value (hidden): ${${variable}}\n" ) endif() + + if(NOT GET_VAR_MERGE) + return() + endif() + endif() + + if(GET_VAR_MERGE) + list(REMOVE_DUPLICATES ${variable}) + set(${variable} ${${variable}} PARENT_SCOPE) endif() endfunction(zephyr_get variable) diff --git a/cmake/modules/root.cmake b/cmake/modules/root.cmake index 4c6ab0ac5e41..603b3b59cc99 100644 --- a/cmake/modules/root.cmake +++ b/cmake/modules/root.cmake @@ -36,6 +36,13 @@ zephyr_file(APPLICATION_ROOT ARCH_ROOT) # Convert paths to absolute, relative from APPLICATION_SOURCE_DIR zephyr_file(APPLICATION_ROOT SCA_ROOT) +# Merge in variables from other sources (e.g. sysbuild) +zephyr_get(MODULE_EXT_ROOT MERGE SYSBUILD GLOBAL) +zephyr_get(BOARD_ROOT MERGE SYSBUILD GLOBAL) +zephyr_get(SOC_ROOT MERGE SYSBUILD GLOBAL) +zephyr_get(ARCH_ROOT MERGE SYSBUILD GLOBAL) +zephyr_get(SCA_ROOT MERGE SYSBUILD GLOBAL) + if(unittest IN_LIST Zephyr_FIND_COMPONENTS) # Zephyr used in unittest mode, use dedicated unittest root. set(BOARD_ROOT ${ZEPHYR_BASE}/subsys/testsuite) From a1279afd6b21ad0a4d7212ddb1dbe80a4ef7405d Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 5 May 2023 08:57:57 +0100 Subject: [PATCH 138/528] [nrf fromtree] cmake: extensions: Do not clear variable in zephyr_get MERGE mode Fixes a regression whereby the variable would be cleared prior to being used in MERGE mode. Signed-off-by: Jamie McCrae (cherry picked from commit 87f50bb72b6baff7b73fda132304d46338dda5cc) (cherry picked from commit bb8f70a04ed7f52d0e1ca1ca9c437f4b10db6f6d) --- cmake/modules/extensions.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index e7e8e12612b6..7505dea3c52a 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2508,7 +2508,9 @@ function(zephyr_get variable) endif() if(GET_VAR_MERGE) - # Clear variable before appending items in MERGE mode + # Clear variable before appending items in MERGE mode but keep a backup for + # local appending later + set(local_var_backup ${${variable}}) set(${variable}) endif() @@ -2574,6 +2576,7 @@ function(zephyr_get variable) endif() if(GET_VAR_MERGE) + list(APPEND ${variable} ${local_var_backup}) list(REMOVE_DUPLICATES ${variable}) set(${variable} ${${variable}} PARENT_SCOPE) endif() From 5ca6b80c9d29a2cf668e6e8b3599d9ea69625152 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 12 May 2023 07:43:04 +0100 Subject: [PATCH 139/528] [nrf fromtree] cmake: extensions: Fix missing quotes for zephyr_get function Fixes a string comparison which is missing quotes, this works on the first invocation but fails on the second if quotes are not present. Signed-off-by: Jamie McCrae (cherry picked from commit a41f44b8db1da0641f6f84ecbd46d0fe31e01169) (cherry picked from commit 7ee2fa85024d14719eb04d5881e3144b218f805d) --- cmake/modules/extensions.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 7505dea3c52a..82285918e64f 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2498,8 +2498,8 @@ function(zephyr_get variable) cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "" ${ARGN}) if(DEFINED GET_VAR_SYSBUILD) - if(NOT (${GET_VAR_SYSBUILD} STREQUAL "GLOBAL" OR - ${GET_VAR_SYSBUILD} STREQUAL "LOCAL") + if(NOT ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR + "${GET_VAR_SYSBUILD}" STREQUAL "LOCAL") ) message(FATAL_ERROR "zephyr_get(... SYSBUILD) requires GLOBAL or LOCAL.") endif() @@ -2521,7 +2521,7 @@ function(zephyr_get variable) get_property(sysbuild_main_app TARGET sysbuild_cache PROPERTY SYSBUILD_MAIN_APP) get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${sysbuild_name}_${variable}) if(NOT DEFINED sysbuild_${variable} AND - (${GET_VAR_SYSBUILD} STREQUAL "GLOBAL" OR sysbuild_main_app) + ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR sysbuild_main_app) ) get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) set(used_global true) @@ -2536,7 +2536,7 @@ function(zephyr_get variable) return() endif() endif() - if(SYSBUILD AND GET_VAR_MERGE AND NOT used_global AND ${GET_VAR_SYSBUILD} STREQUAL "GLOBAL") + if(SYSBUILD AND GET_VAR_MERGE AND NOT used_global AND "${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL") get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) list(APPEND ${variable} ${sysbuild_${variable}}) endif() From 446648238224bee3349f47c378d1f697425ddb7a Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 12:31:11 +0200 Subject: [PATCH 140/528] [nrf fromtree] cmake: extend zephyr_get() to support fetching of multiple variables This commit extends zephyr_get() to support multiple variable names to be fetched into a single variable. Example: zephyr_get(FOO VAR FOO_A FOO_B FOO_C) will lookup each FOO_A, FOO_B, FOO_C for supported scopes and return the value in FOO of the first scope encountered having one of the variables defined. If MERGE is specified, then all scopes for all vars are looped and the variable values are merged into FOO and returned. This functionality will allow to deprecate user-facing settings while ensuring that both the new and deprecated variables are considered in zephyr_get() and also taking into consideration the scope with highest precedence. This allows Zephyr CMake to do: zephyr_get(FOO VAR FOO DEPRECATED_FOO) zephyr_get(BAR MERGE VAR BAR DEPRECATED_BAR) This allows support of old and new setting for a given number of releases. Signed-off-by: Torsten Rasmussen (cherry picked from commit 8460d91e323cfa7d0017ee027e300f34d4d01a49) (cherry picked from commit b7aa2212d29692fdfea341a951b0c54c5501f1a8) --- cmake/modules/extensions.cmake | 150 +++++++++++++++++++-------------- 1 file changed, 87 insertions(+), 63 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 82285918e64f..4f75b41282b5 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2467,11 +2467,42 @@ function(zephyr_list transform list_var action) endfunction() # Usage: -# zephyr_get( [MERGE] [SYSBUILD [LOCAL|GLOBAL]]) +# zephyr_var_name( ) +# +# Internal function for construction of scoped variable name expansion string. +# Examples: +# reading a current scope FOO variable is identical to expand ${FOO}. +# reading a cache scope FOO variable is identical to expand $CACHE{FOO}. +# +# this functions will return the var name in out var for the scope if it is +# defined, else it will set the outvar to undefined. +function(zephyr_var_name variable scope out) + if(scope STREQUAL "ENV" OR scope STREQUAL "CACHE") + if(DEFINED ${scope}{${variable}}) + set(${out} "$${scope}{${variable}}" PARENT_SCOPE) + else() + set(${out} PARENT_SCOPE) + endif() + else() + if(DEFINED ${scope}_${variable}) + set(${out} "${${scope}_${variable}}" PARENT_SCOPE) + else() + set(${out} PARENT_SCOPE) + endif() + endif() +endfunction() + +# Usage: +# zephyr_get( [MERGE] [SYSBUILD [LOCAL|GLOBAL]] [VAR ...]) # # Return the value of as local scoped variable of same name. If MERGE # is supplied, will return a list of found items. # +# VAR can be used either to store the result in a variable with a different +# name, or to look for values from multiple variables. +# zephyr_get(FOO VAR FOO_A FOO_B) +# zephyr_get(FOO MERGE VAR FOO_A FOO_B) +# # zephyr_get() is a common function to provide a uniform way of supporting # build settings that can be set from sysbuild, CMakeLists.txt, CMake cache, or # in environment. @@ -2495,7 +2526,7 @@ endfunction() # using `-DZEPHYR_TOOLCHAIN_VARIANT=`, then the value from the cache is # returned. function(zephyr_get variable) - cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "" ${ARGN}) + cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "VAR" ${ARGN}) if(DEFINED GET_VAR_SYSBUILD) if(NOT ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR @@ -2507,76 +2538,69 @@ function(zephyr_get variable) set(GET_VAR_SYSBUILD "GLOBAL") endif() - if(GET_VAR_MERGE) - # Clear variable before appending items in MERGE mode but keep a backup for - # local appending later - set(local_var_backup ${${variable}}) - set(${variable}) + if(NOT DEFINED GET_VAR_VAR) + set(GET_VAR_VAR ${variable}) endif() - set(used_global false) - - if(SYSBUILD) - get_property(sysbuild_name TARGET sysbuild_cache PROPERTY SYSBUILD_NAME) - get_property(sysbuild_main_app TARGET sysbuild_cache PROPERTY SYSBUILD_MAIN_APP) - get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${sysbuild_name}_${variable}) - if(NOT DEFINED sysbuild_${variable} AND - ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR sysbuild_main_app) - ) - get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) - set(used_global true) - endif() - endif() + # Keep current scope variables in internal variables. + # This is needed to properly handle cases where we want to check value against + # environment value or when appending with the MERGE operation. + foreach(var ${GET_VAR_VAR}) + set(current_${var} ${${var}}) + set(${var}) - if(DEFINED sysbuild_${variable}) - if(GET_VAR_MERGE) - list(APPEND ${variable} ${sysbuild_${variable}}) - else() - set(${variable} ${sysbuild_${variable}} PARENT_SCOPE) - return() - endif() - endif() - if(SYSBUILD AND GET_VAR_MERGE AND NOT used_global AND "${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL") - get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) - list(APPEND ${variable} ${sysbuild_${variable}}) - endif() - if(DEFINED CACHE{${variable}}) - if(GET_VAR_MERGE) - list(APPEND ${variable} $CACHE{${variable}}) - else() - set(${variable} $CACHE{${variable}} PARENT_SCOPE) - return() - endif() - endif() - if(DEFINED ENV{${variable}}) - if(GET_VAR_MERGE) - list(APPEND ${variable} $ENV{${variable}}}) + if(SYSBUILD) + get_property(sysbuild_name TARGET sysbuild_cache PROPERTY SYSBUILD_NAME) + get_property(sysbuild_main_app TARGET sysbuild_cache PROPERTY SYSBUILD_MAIN_APP) + get_property(sysbuild_${var} TARGET sysbuild_cache PROPERTY ${sysbuild_name}_${var}) + if(NOT DEFINED sysbuild_${var} AND + ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR sysbuild_main_app) + ) + get_property(sysbuild_${var} TARGET sysbuild_cache PROPERTY ${var}) + endif() else() - set(${variable} $ENV{${variable}} PARENT_SCOPE) - # Set the environment variable in CMake cache, so that a build invocation - # triggering a CMake rerun doesn't rely on the environment variable still - # being available / have identical value. - set(${variable} $ENV{${variable}} CACHE INTERNAL "") + set(sysbuild_${var}) endif() + endforeach() - if(DEFINED ${variable} AND NOT "${${variable}}" STREQUAL "$ENV{${variable}}") - # Variable exists as a local scoped variable, defined in a CMakeLists.txt - # file, however it is also set in environment. - # This might be a surprise to the user, so warn about it. - message(WARNING "environment variable '${variable}' is hiding local " - "variable of same name.\n" - "Environment value (in use): $ENV{${variable}}\n" - "Local scope value (hidden): ${${variable}}\n" - ) - endif() + set(scopes "sysbuild;CACHE;ENV;current") + foreach(scope IN LISTS scopes) + foreach(var ${GET_VAR_VAR}) + zephyr_var_name("${var}" "${scope}" expansion_var) + if(DEFINED expansion_var) + string(CONFIGURE "${expansion_var}" scope_value) + if(GET_VAR_MERGE) + list(APPEND ${variable} ${scope_value}) + else() + set(${variable} ${scope_value} PARENT_SCOPE) + + if("${scope}" STREQUAL "ENV") + # Set the environment variable in CMake cache, so that a build + # invocation triggering a CMake rerun doesn't rely on the + # environment variable still being available / have identical value. + set(${var} $ENV{${var}} CACHE INTERNAL "Cached environment variable ${var}") + endif() - if(NOT GET_VAR_MERGE) - return() - endif() - endif() + if("${scope}" STREQUAL "ENV" AND DEFINED current_${var} + AND NOT "${current_${var}}" STREQUAL "$ENV{${var}}" + ) + # Variable exists as current scoped variable, defined in a CMakeLists.txt + # file, however it is also set in environment. + # This might be a surprise to the user, so warn about it. + message(WARNING "environment variable '${var}' is hiding local " + "variable of same name.\n" + "Environment value (in use): $ENV{${var}}\n" + "Current scope value (hidden): ${current_${var}}\n" + ) + endif() + + return() + endif() + endif() + endforeach() + endforeach() if(GET_VAR_MERGE) - list(APPEND ${variable} ${local_var_backup}) list(REMOVE_DUPLICATES ${variable}) set(${variable} ${${variable}} PARENT_SCOPE) endif() From 591023d1b10b6a11cbd2041ad14590f794f7bcde Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 12:46:24 +0200 Subject: [PATCH 141/528] [nrf fromtree] cmake: introduce EXTRA_CONF_FILE and deprecate OVERLAY_CONFIG This commit introduces EXTRA_CONF_FILE and deprecates OVERLAY_CONFIG. It has often caused confusion that OVERLAY_CONFIG adds extra configuration fragments to the value of CONF_FILE (default: prj.conf), but the similar named variable DTC_OVERLAY_FILE replaces the default dtc overlay file used by the build system. To remove such confusion, this commit introduces the EXTRA_ prefix in front of CONF_FILE to clearly indicate it's purpose. Signed-off-by: Torsten Rasmussen (cherry picked from commit 3a345682ba812ceeba5b5c42cb8af74bf4b3e1a1) (cherry picked from commit c1745083096fc72f558fc4b7972f379eb666f1e8) --- cmake/modules/configuration_files.cmake | 3 +++ cmake/modules/kconfig.cmake | 22 ++++++++++++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/cmake/modules/configuration_files.cmake b/cmake/modules/configuration_files.cmake index e5db53fd0880..5ff3ba991b68 100644 --- a/cmake/modules/configuration_files.cmake +++ b/cmake/modules/configuration_files.cmake @@ -11,6 +11,7 @@ # The following variables will be defined when this CMake module completes: # # - CONF_FILE: List of Kconfig fragments +# - EXTRA_CONF_FILE: List of additional Kconfig fragments # - DTC_OVERLAY_FILE: List of devicetree overlay files # - APPLICATION_CONFIG_DIR: Root folder for application configuration # @@ -114,3 +115,5 @@ DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"") # The DTC_OVERLAY_FILE variable is now set to its final value. zephyr_boilerplate_watch(DTC_OVERLAY_FILE) + +zephyr_get(EXTRA_CONF_FILE SYSBUILD LOCAL VAR EXTRA_CONF_FILE OVERLAY_CONFIG) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 3c37e3bce273..97e6aadcf563 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -55,6 +55,9 @@ foreach(root ${kconfig_board_root}) endforeach() if(KCONFIG_ROOT) + # Perform any variable substitutions if they are present + string(CONFIGURE "${KCONFIG_ROOT}" KCONFIG_ROOT) + zephyr_file(APPLICATION_ROOT KCONFIG_ROOT) # KCONFIG_ROOT has either been specified as a CMake variable or is # already in the CMakeCache.txt. This has precedence. @@ -76,10 +79,9 @@ if(CONF_FILE) string(REPLACE " " ";" CONF_FILE_AS_LIST "${CONF_FILE_EXPANDED}") endif() -zephyr_get(OVERLAY_CONFIG SYSBUILD LOCAL) -if(OVERLAY_CONFIG) - string(CONFIGURE "${OVERLAY_CONFIG}" OVERLAY_CONFIG_EXPANDED) - string(REPLACE " " ";" OVERLAY_CONFIG_AS_LIST "${OVERLAY_CONFIG_EXPANDED}") +if(EXTRA_CONF_FILE) + string(CONFIGURE "${EXTRA_CONF_FILE}" EXTRA_CONF_FILE_EXPANDED) + string(REPLACE " " ";" EXTRA_CONF_FILE_AS_LIST "${EXTRA_CONF_FILE_EXPANDED}") endif() @@ -113,10 +115,17 @@ string(REPLACE ";" "\\\;" SHIELD_AS_LIST_ESCAPED "${SHIELD_AS_LIST}") # cmake commands are escaped differently string(REPLACE ";" "\\;" SHIELD_AS_LIST_ESCAPED_COMMAND "${SHIELD_AS_LIST}") +if(TOOLCHAIN_HAS_NEWLIB) + set(_local_TOOLCHAIN_HAS_NEWLIB y) +else() + set(_local_TOOLCHAIN_HAS_NEWLIB n) +endif() + set(COMMON_KCONFIG_ENV_SETTINGS PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} srctree=${ZEPHYR_BASE} KERNELVERSION=${KERNELVERSION} + APPVERSION=${APP_VERSION_STRING} CONFIG_=${KCONFIG_NAMESPACE}_ KCONFIG_CONFIG=${DOTCONFIG} # Set environment variables so that Kconfig can prune Kconfig source @@ -126,9 +135,10 @@ set(COMMON_KCONFIG_ENV_SETTINGS BOARD_DIR=${BOARD_DIR} BOARD_REVISION=${BOARD_REVISION} KCONFIG_BINARY_DIR=${KCONFIG_BINARY_DIR} + APPLICATION_SOURCE_DIR=${APPLICATION_SOURCE_DIR} ZEPHYR_TOOLCHAIN_VARIANT=${ZEPHYR_TOOLCHAIN_VARIANT} TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR} - TOOLCHAIN_HAS_NEWLIB=$,y,n> + TOOLCHAIN_HAS_NEWLIB=${_local_TOOLCHAIN_HAS_NEWLIB} EDT_PICKLE=${EDT_PICKLE} # Export all Zephyr modules to Kconfig ${ZEPHYR_KCONFIG_MODULES_DIR} @@ -241,7 +251,7 @@ set( ${BOARD_REVISION_CONFIG} ${CONF_FILE_AS_LIST} ${shield_conf_files} - ${OVERLAY_CONFIG_AS_LIST} + ${EXTRA_CONF_FILE_AS_LIST} ${EXTRA_KCONFIG_OPTIONS_FILE} ${config_files} ) From 91994930143dbcf3d8d3843935122b19f9519524 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 12:52:45 +0200 Subject: [PATCH 142/528] [nrf fromtree] cmake: introduce EXTRA_DTC_OVERLAY_FILE for devicetree This commit introduces EXTRA_DTC_OVERLAY_FILE. This allows users to specify additional devicetree overlays in addition to a sample / board specific default devicetree overlay files. It also allows snippets to provide extra devicetree overlays on addition to sample / board specific overlays. The name EXTRA_DTC_OVERLAY_FILE clearly indicates the purpose and follows the naming scheme of EXTRA_ in front of variable name. Signed-off-by: Torsten Rasmussen (cherry picked from commit 384fb1e4788a801da21bb845bafd44ca3c72f58d) (cherry picked from commit 0fe5a56b2e2c1f58e017d316829bd93b34709f7a) --- cmake/modules/configuration_files.cmake | 1 + cmake/modules/dts.cmake | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/cmake/modules/configuration_files.cmake b/cmake/modules/configuration_files.cmake index 5ff3ba991b68..24d5e9feedd3 100644 --- a/cmake/modules/configuration_files.cmake +++ b/cmake/modules/configuration_files.cmake @@ -117,3 +117,4 @@ DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"") zephyr_boilerplate_watch(DTC_OVERLAY_FILE) zephyr_get(EXTRA_CONF_FILE SYSBUILD LOCAL VAR EXTRA_CONF_FILE OVERLAY_CONFIG) +zephyr_get(EXTRA_DTC_OVERLAY_FILE SYSBUILD LOCAL) diff --git a/cmake/modules/dts.cmake b/cmake/modules/dts.cmake index 42413ceca73d..e21d9ead887e 100644 --- a/cmake/modules/dts.cmake +++ b/cmake/modules/dts.cmake @@ -75,6 +75,12 @@ find_package(Dtc 1.4.6) # - BOARD_DIR: board directory to use when looking for DTS_SOURCE # - BOARD_REVISION_STRING: used when looking for a board revision's # devicetree overlay file in BOARD_DIR +# - DTC_OVERLAY_FILE: list of devicetree overlay files which will be +# used to modify or extend the base devicetree. +# - EXTRA_DTC_OVERLAY_FILE: list of extra devicetree overlay files. +# This variable is is similar to DTC_OVERLAY_FILE but the files in +# EXTRA_DTC_OVERLAY_FILE will be applied after DTC_OVERLAY_FILE and +# thus files specified by EXTRA_DTC_OVERLAY_FILE have higher precedence. # - EXTRA_DTC_FLAGS: list of extra command line options to pass to # dtc when using it to check for additional errors and warnings; # invalid flags are automatically filtered out of the list @@ -82,7 +88,7 @@ find_package(Dtc 1.4.6) # C preprocessor when generating the devicetree from DTS_SOURCE # - DTS_SOURCE: the devicetree source file to use may be pre-set # with this variable; otherwise, it defaults to -# ${BOARD_DIR}/${BOARD.dts} +# ${BOARD_DIR}/${BOARD}.dts # # Variables set by this module and not mentioned above are for internal # use only, and may be removed, renamed, or re-purposed without prior notice. @@ -158,6 +164,15 @@ if(DTC_OVERLAY_FILE) ) endif() +if(EXTRA_DTC_OVERLAY_FILE) + zephyr_list(TRANSFORM EXTRA_DTC_OVERLAY_FILE NORMALIZE_PATHS + OUTPUT_VARIABLE EXTRA_DTC_OVERLAY_FILE_AS_LIST) + list(APPEND + dts_files + ${EXTRA_DTC_OVERLAY_FILE_AS_LIST} + ) +endif() + set(i 0) foreach(dts_file ${dts_files}) if(i EQUAL 0) From 48ec774711f1f9b64f1facef394ce5737edc59e4 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 13:07:27 +0200 Subject: [PATCH 143/528] [nrf fromtree] cmake: update package helper description to use EXTRA_CONF_FILE var Update package_helper.cmake to use EXTRA_CONF_FILE instead of deprecated OVERLAY_CONFIG variable. Signed-off-by: Torsten Rasmussen (cherry picked from commit ca76349d246dda9ac10affae32cbc948f571aa61) (cherry picked from commit 47d794191b35732a8aa8426a490c2b757caf1b17) --- cmake/package_helper.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/package_helper.cmake b/cmake/package_helper.cmake index 5f48185a57b5..d33b1cf6ddf0 100644 --- a/cmake/package_helper.cmake +++ b/cmake/package_helper.cmake @@ -29,18 +29,18 @@ # It is also possible to pass additional build settings. # If you invoke CMake for 'hello_world' as: # -# $ cmake -DBOARD= -B build -S samples/hello_world -DOVERLAY_CONFIG=foo.overlay +# $ cmake -DBOARD= -B build -S samples/hello_world -DEXTRA_CONF_FILE=foo.conf # # you just add the same argument to the helper like: -# $ cmake -DBOARD= -B build -S samples/hello_world -DOVERLAY_CONFIG=foo.overlay \ +# $ cmake -DBOARD= -B build -S samples/hello_world -DEXTRA_CONF_FILE=foo.conf \ # -DMODULES=dts -P /cmake/package_helper.cmake # # Note: the samples CMakeLists.txt file is not processed by package helper, so # any 'set( )' specified before 'find_package(Zephyr)' must be # manually applied, for example if the CMakeLists.txt contains: -# set(OVERLAY_CONFIG foo.overlay) +# set(EXTRA_CONF_FILE foo.conf) # find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -# the 'foo.overlay' must be specified using '-DOVERLAY_CONFIG=foo.overlay' +# the 'foo.conf' must be specified using '-DEXTRA_CONF_FILE=foo.conf' cmake_minimum_required(VERSION 3.20.5) From 4f3e84a1360db20e32255db513496061ff07876c Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 13:09:50 +0200 Subject: [PATCH 144/528] [nrf fromtree] sysbuild: update sysbuild to use EXTRA_CONF_FILE variable Align sysbuild with Zephyr CMake so that sysbuild supports SB_EXTRA_CONF_FILE. Keep support for the old SB_OVERLAY_CONFIG. This ensures that sysbuild is consistent with Zephyr CMake configuration file handling. Signed-off-by: Torsten Rasmussen (cherry picked from commit 5c4060743d86e6c256d51c03de363713033690b5) (cherry picked from commit 49e95c2765bf9df6b946d925de846003112b24f5) --- .../cmake/modules/sysbuild_extensions.cmake | 8 +++++--- .../sysbuild/cmake/modules/sysbuild_kconfig.cmake | 15 ++++++++++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index d7eb004a17df..76554c7d840f 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -148,13 +148,15 @@ function(ExternalZephyrProject_Add) # The contents of these are appended to the image existing configuration # when user is not specifying custom fragments. if(NOT "${CONF_FILE_BUILD_TYPE}" STREQUAL "") - set(sysbuil_image_conf_fragment ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}_${CONF_FILE_BUILD_TYPE}.conf) + set(sysbuild_image_conf_fragment ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}_${CONF_FILE_BUILD_TYPE}.conf) else() set(sysbuild_image_conf_fragment ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}.conf) endif() - if (NOT ${ZBUILD_APPLICATION}_OVERLAY_CONFIG AND EXISTS ${sysbuild_image_conf_fragment}) - set(${ZBUILD_APPLICATION}_OVERLAY_CONFIG ${sysbuild_image_conf_fragment} + if (NOT (${ZBUILD_APPLICATION}_OVERLAY_CONFIG OR ${ZBUILD_APPLICATION}_EXTRA_CONF_FILE) + AND EXISTS ${sysbuild_image_conf_fragment} + ) + set(${ZBUILD_APPLICATION}_EXTRA_CONF_FILE ${sysbuild_image_conf_fragment} CACHE INTERNAL "Kconfig fragment defined by main application" ) endif() diff --git a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake index 5dbf82728a5e..830ad326fd2a 100644 --- a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake @@ -25,7 +25,19 @@ else() endif() if(DEFINED SB_CONF_FILE AND NOT IS_ABSOLUTE SB_CONF_FILE) - cmake_path(ABSOLUTE_PATH SB_CONF_FILE BASE_DIRECTORY ${APP_DIR} OUTPUT_VARIABLE SB_CONF_FILE) + cmake_path(ABSOLUTE_PATH SB_CONF_FILE BASE_DIRECTORY ${APP_DIR}) +endif() + +if(DEFINED SB_OVERLAY_CONFIG AND NOT IS_ABSOLUTE SB_OVERLAY_CONFIG) + cmake_path(ABSOLUTE_PATH SB_OVERLAY_CONFIG BASE_DIRECTORY ${APP_DIR}) +endif() + +if(DEFINED SB_EXTRA_CONF_FILE AND NOT IS_ABSOLUTE SB_EXTRA_CONF_FILE) + cmake_path(ABSOLUTE_PATH SB_EXTRA_CONF_FILE BASE_DIRECTORY ${APP_DIR}) +endif() + +if(NOT DEFINED SB_EXTRA_CONF_FILE AND DEFINED SB_OVERLAY_CONFIG) + set(SB_EXTRA_CONF_FILE ${SB_OVERLAY_CONFIG}) endif() if(DEFINED SB_CONF_FILE AND NOT DEFINED CACHE{SB_CONF_FILE}) @@ -48,6 +60,7 @@ file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/empty.conf) set(APPLICATION_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(AUTOCONF_H ${CMAKE_CURRENT_BINARY_DIR}/autoconf.h) set(CONF_FILE ${SB_CONF_FILE}) +set(EXTRA_CONF_FILE "${SB_EXTRA_CONF_FILE}") set(BOARD_DEFCONFIG "${CMAKE_CURRENT_BINARY_DIR}/empty.conf") if(DEFINED BOARD_REVISION) set(BOARD_REVISION_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/empty.conf") From 788882adb1489cf4e07d8997b4b1e5988d744950 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 13:11:47 +0200 Subject: [PATCH 145/528] [nrf fromtree] samples: update nrf53_sync_rtc sample to EXTRA_CONF_FILE Update nrf53_sync_rtc to use EXTRA_CONF_FILE instead of the old OVERLAY_CONFIG. Signed-off-by: Torsten Rasmussen (cherry picked from commit 391f4c9b0f186c99e1adcfc9bdc69a3e40ec18b7) (cherry picked from commit 9edf62aee4f088210020c8f59688e0c38f5c63d6) --- samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt b/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt index 32aee7dc0a61..da1ce866e878 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt +++ b/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt @@ -30,7 +30,7 @@ ExternalProject_Add( INSTALL_COMMAND "" # This particular build system has no install command CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} CMAKE_CACHE_ARGS -DDTC_OVERLAY_FILE:STRING=${NET_DTC_OVERLAY_FILE} - CMAKE_CACHE_ARGS -DOVERLAY_CONFIG:STRING=${NET_OVERLAY_CONF} + CMAKE_CACHE_ARGS -DEXTRA_CONF_FILE:STRING=${NET_OVERLAY_CONF} BUILD_BYPRODUCTS "${NET_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" # NB: Do we need to pass on more CMake variables? BUILD_ALWAYS True From 614c4dbe92af512ccee170e3ea38cb1ad85f6e19 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 13:24:35 +0200 Subject: [PATCH 146/528] [nrf fromtree] doc: introduce EXTRA_CONF_FILE and EXTRA_DTC_OVERLAY_FILE Introduce EXTRA_CONF_FILE and EXTRA_DTC_OVERLAY_FILE and remove old references to OVERLAY_CONFIG. Signed-off-by: Torsten Rasmussen (cherry picked from commit 754eca92a2f5e2c5818a38c6ab007752bf71d279) (cherry picked from commit 7c5db3468ee7602dd95b5b9ad3c8adc1a272eafb) --- doc/build/dts/howtos.rst | 11 ++++++++++- doc/build/kconfig/setting.rst | 3 ++- doc/connectivity/bluetooth/autopts/autopts-linux.rst | 2 +- .../networking/networking_with_multiple_instances.rst | 4 ++-- doc/connectivity/networking/qemu_802154_setup.rst | 6 +++--- doc/connectivity/networking/qemu_eth_setup.rst | 2 +- doc/develop/application/index.rst | 6 +++--- doc/develop/west/build-flash-debug.rst | 2 +- 8 files changed, 23 insertions(+), 13 deletions(-) diff --git a/doc/build/dts/howtos.rst b/doc/build/dts/howtos.rst index 35bcf8ae8137..f1a003f2f94f 100644 --- a/doc/build/dts/howtos.rst +++ b/doc/build/dts/howtos.rst @@ -246,9 +246,18 @@ use as devicetree overlays: system will stop looking for more files. #. Otherwise, if :file:`app.overlay` exists, it will be used. +Extra devicetree overlays may be provided using ``EXTRA_DTC_OVERLAY_FILE`` which +will still allow the build system to automatically use devicetree overlays +described in the above steps. + +The build system appends overlays specified in ``EXTRA_DTC_OVERLAY_FILE`` +to the overlays in ``DTC_OVERLAY_FILE`` when processing devicetree overlays. +This means that changes made via ``EXTRA_DTC_OVERLAY_FILE`` have higher +precedence than those made via ``DTC_OVERLAY_FILE``. + All configuration files will be taken from the application's configuration directory except for files with an absolute path that are given with the -``DTC_OVERLAY_FILE`` argument. +``DTC_OVERLAY_FILE`` or ``EXTRA_DTC_OVERLAY_FILE`` argument. See :ref:`Application Configuration Directory ` on how the application configuration directory is defined. diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 048aea25fa1b..5f37e831e9e0 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -170,7 +170,8 @@ used. All configuration files will be taken from the application's configuration directory except for files with an absolute path that are given with the -``CONF_FILE``, ``OVERLAY_CONFIG``, and ``DTC_OVERLAY_FILE`` arguments. For these, +``CONF_FILE``, ``EXTRA_CONF_FILE``, ``DTC_OVERLAY_FILE``, and +``EXTRA_DTC_OVERLAY_FILE`` arguments. For these, a file in a Zephyr module can be referred by escaping the Zephyr module dir variable like this ``\${ZEPHYR__MODULE_DIR}//`` when setting any of said variables in the application's :file:`CMakeLists.txt`. diff --git a/doc/connectivity/bluetooth/autopts/autopts-linux.rst b/doc/connectivity/bluetooth/autopts/autopts-linux.rst index fe300ad9db92..51ef1eab1fa5 100644 --- a/doc/connectivity/bluetooth/autopts/autopts-linux.rst +++ b/doc/connectivity/bluetooth/autopts/autopts-linux.rst @@ -300,7 +300,7 @@ Testing Zephyr Host Stack on native posix: # A Bluetooth controller needs to be mounted. # For running with HCI UART, please visit: https://docs.zephyrproject.org/latest/samples/bluetooth/hci_uart/README.html#bluetooth-hci-uart - west build -b native_posix zephyr/tests/bluetooth/tester/ -DOVERLAY_CONFIG=overlay-native.conf + west build -b native_posix zephyr/tests/bluetooth/tester/ -DEXTRA_CONF_FILE=overlay-native.conf sudo python ./autoptsclient-zephyr.py "C:\Users\USER_NAME\Documents\Profile Tuning Suite\PTS_PROJECT\PTS_PROJECT.pqw6" \ ~/zephyrproject/build/zephyr/zephyr.exe -i SERVER_IP -l LOCAL_IP --hci 0 diff --git a/doc/connectivity/networking/networking_with_multiple_instances.rst b/doc/connectivity/networking/networking_with_multiple_instances.rst index 783e37addf40..6bd4531c8295 100644 --- a/doc/connectivity/networking/networking_with_multiple_instances.rst +++ b/doc/connectivity/networking/networking_with_multiple_instances.rst @@ -132,7 +132,7 @@ In terminal #4, if you are using QEMU, type this: west build -d build/server -b qemu_x86 -t run \ samples/net/sockets/echo_server -- \ - -DOVERLAY_CONFIG=overlay-e1000.conf \ + -DEXTRA_CONF_FILE=overlay-e1000.conf \ -DCONFIG_NET_CONFIG_MY_IPV4_ADDR=\"198.51.100.1\" \ -DCONFIG_NET_CONFIG_PEER_IPV4_ADDR=\"203.0.113.1\" \ -DCONFIG_NET_CONFIG_MY_IPV6_ADDR=\"2001:db8:100::1\" \ @@ -163,7 +163,7 @@ In terminal #5, if you are using QEMU, type this: west build -d build/client -b qemu_x86 -t run \ samples/net/sockets/echo_client -- \ - -DOVERLAY_CONFIG=overlay-e1000.conf \ + -DEXTRA_CONF_FILE=overlay-e1000.conf \ -DCONFIG_NET_CONFIG_MY_IPV4_ADDR=\"203.0.113.1\" \ -DCONFIG_NET_CONFIG_PEER_IPV4_ADDR=\"198.51.100.1\" \ -DCONFIG_NET_CONFIG_MY_IPV6_ADDR=\"2001:db8:200::1\" \ diff --git a/doc/connectivity/networking/qemu_802154_setup.rst b/doc/connectivity/networking/qemu_802154_setup.rst index 0e6f0af6aa8a..12b0ef74de9c 100644 --- a/doc/connectivity/networking/qemu_802154_setup.rst +++ b/doc/connectivity/networking/qemu_802154_setup.rst @@ -40,7 +40,7 @@ In terminal #1, type: :host-os: unix :board: qemu_x86 :build-dir: server - :gen-args: -DOVERLAY_CONFIG=overlay-qemu_802154.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-qemu_802154.conf :goals: server :compact: @@ -51,7 +51,7 @@ If you want to capture the network traffic between the two QEMUs, type: :host-os: unix :board: qemu_x86 :build-dir: server - :gen-args: -G'Unix Makefiles' -DOVERLAY_CONFIG=overlay-qemu_802154.conf -DPCAP=capture.pcap + :gen-args: -G'Unix Makefiles' -DEXTRA_CONF_FILE=overlay-qemu_802154.conf -DPCAP=capture.pcap :goals: server :compact: @@ -69,7 +69,7 @@ In terminal #2, type: :host-os: unix :board: qemu_x86 :build-dir: client - :gen-args: -DOVERLAY_CONFIG=overlay-qemu_802154.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-qemu_802154.conf :goals: client :compact: diff --git a/doc/connectivity/networking/qemu_eth_setup.rst b/doc/connectivity/networking/qemu_eth_setup.rst index f558bae7f4ab..33a99599527f 100644 --- a/doc/connectivity/networking/qemu_eth_setup.rst +++ b/doc/connectivity/networking/qemu_eth_setup.rst @@ -78,7 +78,7 @@ In terminal #2, type: :zephyr-app: samples/net/sockets/echo_server :host-os: unix :board: qemu_x86 - :gen-args: -DOVERLAY_CONFIG=overlay-e1000.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-e1000.conf :goals: run :compact: diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index bf934cf3532e..ca9591bf44c7 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -404,7 +404,7 @@ should know about. See :ref:`initial-conf` for more information. -* :makevar:`OVERLAY_CONFIG`: Additional Kconfig configuration fragment files. +* :makevar:`EXTRA_CONF_FILE`: Additional Kconfig configuration fragment files. Multiple filenames can be separated with either spaces or semicolons. This can be useful in order to leave :makevar:`CONF_FILE` at its default value, but "mix in" some additional configuration options. @@ -587,8 +587,8 @@ Application Configuration Directory Zephyr will use configuration files from the application's configuration directory except for files with an absolute path provided by the arguments -described earlier, for example ``CONF_FILE``, ``OVERLAY_CONFIG``, and -``DTC_OVERLAY_FILE``. +described earlier, for example ``CONF_FILE``, ``EXTRA_CONF_FILE``, +``DTC_OVERLAY_FILE``, and ``EXTRA_DTC_OVERLAY_FILE``. The application configuration directory is defined by the ``APPLICATION_CONFIG_DIR`` variable. diff --git a/doc/develop/west/build-flash-debug.rst b/doc/develop/west/build-flash-debug.rst index 44aa0bb500d8..b6809094f857 100644 --- a/doc/develop/west/build-flash-debug.rst +++ b/doc/develop/west/build-flash-debug.rst @@ -242,7 +242,7 @@ To set :ref:`DTC_OVERLAY_FILE ` to To merge the :file:`file.conf` Kconfig fragment into your build's :file:`.config`:: - west build -- -DOVERLAY_CONFIG=file.conf + west build -- -DEXTRA_CONF_FILE=file.conf .. _west-building-cmake-config: From 05e299fbbf498c5adcb8618b5daa25b8a2da0126 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 15:57:24 +0200 Subject: [PATCH 147/528] [nrf fromtree] doc: samples: update OVERLAY_CONFIG to EXTRA_CONF_FILE Update rst files to use EXTRA_CONF_FILE instead of OVERLAY_CONFIG. Signed-off-by: Torsten Rasmussen (cherry picked from commit 11209348741cdec088b68fc302a2d226488f03f2) (cherry picked from commit 75b5e45b9f83151155e35baae3760a91033f0751) --- samples/bluetooth/broadcast_audio_sink/README.rst | 2 +- .../bluetooth/broadcast_audio_source/README.rst | 2 +- .../bluetooth/direction_finding_central/README.rst | 2 +- .../direction_finding_connectionless_rx/README.rst | 2 +- .../direction_finding_connectionless_tx/README.rst | 2 +- .../direction_finding_peripheral/README.rst | 2 +- samples/bluetooth/hci_uart/README.rst | 2 +- samples/bluetooth/iso_broadcast/README.rst | 2 +- samples/bluetooth/iso_receive/README.rst | 2 +- samples/drivers/spi_flash_at45/README.rst | 6 +++--- samples/net/cloud/tagoio_http_post/README.rst | 8 ++++---- samples/net/mqtt_publisher/README.rst | 6 +++--- samples/net/openthread/coprocessor/README.rst | 2 +- samples/net/sockets/big_http_download/README.rst | 2 +- samples/net/sockets/echo_client/README.rst | 6 +++--- samples/net/sockets/echo_server/README.rst | 4 ++-- samples/net/sockets/http_client/README.rst | 2 +- samples/net/sockets/http_get/README.rst | 2 +- samples/net/sockets/tcp/README.rst | 2 +- samples/net/sockets/websocket_client/README.rst | 2 +- samples/net/wpanusb/README.rst | 2 +- samples/subsys/fs/fat_fs/README.rst | 2 +- samples/subsys/lorawan/class_a/README.rst | 2 +- samples/subsys/mgmt/mcumgr/smp_svr/README.rst | 10 +++++----- samples/subsys/mgmt/updatehub/README.rst | 14 +++++++------- samples/subsys/modbus/rtu_server/README.rst | 2 +- samples/subsys/usb/dfu/README.rst | 2 +- samples/subsys/usb/shell/README.rst | 2 +- 28 files changed, 48 insertions(+), 48 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_sink/README.rst b/samples/bluetooth/broadcast_audio_sink/README.rst index f733dc201cf9..cb0aabc970d6 100644 --- a/samples/bluetooth/broadcast_audio_sink/README.rst +++ b/samples/bluetooth/broadcast_audio_sink/README.rst @@ -20,7 +20,7 @@ Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/broadcast_audio_sink` in the Zephyr tree. -Use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable required ISO +Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/broadcast_audio_source/README.rst b/samples/bluetooth/broadcast_audio_source/README.rst index 223fa27443d4..12fb6c0ca1a6 100644 --- a/samples/bluetooth/broadcast_audio_source/README.rst +++ b/samples/bluetooth/broadcast_audio_source/README.rst @@ -23,7 +23,7 @@ Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/broadcast_audio_source` in the Zephyr tree. -Use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable required ISO +Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/direction_finding_central/README.rst b/samples/bluetooth/direction_finding_central/README.rst index 0f3e4c0cc542..17cbc599f6bd 100644 --- a/samples/bluetooth/direction_finding_central/README.rst +++ b/samples/bluetooth/direction_finding_central/README.rst @@ -32,7 +32,7 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :zephyr-app: samples/bluetooth/direction_finding_central :host-os: unix :board: nrf52833dk_nrf52833 - :gen-args: -DOVERLAY_CONFIG=overlay-aod.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-aod.conf :goals: build flash :compact: diff --git a/samples/bluetooth/direction_finding_connectionless_rx/README.rst b/samples/bluetooth/direction_finding_connectionless_rx/README.rst index 7fb187bc929f..b7a970acbc4f 100644 --- a/samples/bluetooth/direction_finding_connectionless_rx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_rx/README.rst @@ -32,7 +32,7 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :zephyr-app: samples/bluetooth/direction_finding_connectionless_rx :host-os: unix :board: nrf52833dk_nrf52833 - :gen-args: -DOVERLAY_CONFIG=overlay-aod.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-aod.conf :goals: build flash :compact: diff --git a/samples/bluetooth/direction_finding_connectionless_tx/README.rst b/samples/bluetooth/direction_finding_connectionless_tx/README.rst index 6fffb9198b59..ca27319cbc7e 100644 --- a/samples/bluetooth/direction_finding_connectionless_tx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_tx/README.rst @@ -32,7 +32,7 @@ To use Angle of Arrival mode only, build this application as follows, changing :zephyr-app: samples/bluetooth/direction_finding_connectionless_tx :host-os: unix :board: nrf52833dk_nrf52833 - :gen-args: -DOVERLAY_CONFIG=overlay-aoa.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-aoa.conf :goals: build flash :compact: diff --git a/samples/bluetooth/direction_finding_peripheral/README.rst b/samples/bluetooth/direction_finding_peripheral/README.rst index 0a8e7791c3aa..36846c84d6f2 100644 --- a/samples/bluetooth/direction_finding_peripheral/README.rst +++ b/samples/bluetooth/direction_finding_peripheral/README.rst @@ -31,7 +31,7 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :zephyr-app: samples/bluetooth/direction_finding_peripheral :host-os: unix :board: nrf52833dk_nrf52833 - :gen-args: -DOVERLAY_CONFIG=overlay-aoa.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-aoa.conf :goals: build flash :compact: diff --git a/samples/bluetooth/hci_uart/README.rst b/samples/bluetooth/hci_uart/README.rst index 1bd915de2117..21e46970eb6b 100644 --- a/samples/bluetooth/hci_uart/README.rst +++ b/samples/bluetooth/hci_uart/README.rst @@ -122,7 +122,7 @@ application. To enable debug over RTT the debug configuration file can be used. .. code-block:: console - west build samples/bluetooth/hci_uart -- -DOVERLAY_CONFIG='debug.conf' + west build samples/bluetooth/hci_uart -- -DEXTRA_CONF_FILE='debug.conf' Then attach RTT as described here: :ref:`Using Segger J-Link ` diff --git a/samples/bluetooth/iso_broadcast/README.rst b/samples/bluetooth/iso_broadcast/README.rst index 0caec4201579..6b4bb276ab16 100644 --- a/samples/bluetooth/iso_broadcast/README.rst +++ b/samples/bluetooth/iso_broadcast/README.rst @@ -21,7 +21,7 @@ Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/iso_broadcast` in -the Zephyr tree. Use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable +the Zephyr tree. Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. Use the sample found under :zephyr_file:`samples/bluetooth/iso_receive` in the diff --git a/samples/bluetooth/iso_receive/README.rst b/samples/bluetooth/iso_receive/README.rst index 6e5d871bb618..d4bb1a4951ba 100644 --- a/samples/bluetooth/iso_receive/README.rst +++ b/samples/bluetooth/iso_receive/README.rst @@ -21,7 +21,7 @@ Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/iso_receive` in -the Zephyr tree. Use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable +the Zephyr tree. Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. Use the sample found under :zephyr_file:`samples/bluetooth/iso_broadcast` on diff --git a/samples/drivers/spi_flash_at45/README.rst b/samples/drivers/spi_flash_at45/README.rst index a53a84bc9bf3..c8d5b60c91ef 100644 --- a/samples/drivers/spi_flash_at45/README.rst +++ b/samples/drivers/spi_flash_at45/README.rst @@ -51,7 +51,7 @@ To build and flash with device power management enabled: .. zephyr-app-commands:: :zephyr-app: samples/drivers/spi_flash_at45 :board: nrf9160dk_nrf9160 - :gen-args: -DOVERLAY_CONFIG=overlay-pm.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-pm.conf :goals: build flash :compact: @@ -60,7 +60,7 @@ To build and flash with flash page layout enabled: .. zephyr-app-commands:: :zephyr-app: samples/drivers/spi_flash_at45 :board: nrf9160dk_nrf9160 - :gen-args: -DOVERLAY_CONFIG=overlay-page_layout.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-page_layout.conf :goals: build flash :compact: @@ -70,7 +70,7 @@ layout enabled: .. zephyr-app-commands:: :zephyr-app: samples/drivers/spi_flash_at45 :board: nrf9160dk_nrf9160 - :gen-args: -DOVERLAY_CONFIG="overlay-pm.conf overlay-page_layout.conf" + :gen-args: -DEXTRA_CONF_FILE="overlay-pm.conf overlay-page_layout.conf" :goals: build flash :compact: diff --git a/samples/net/cloud/tagoio_http_post/README.rst b/samples/net/cloud/tagoio_http_post/README.rst index 62a8491b6187..235a35265e4b 100644 --- a/samples/net/cloud/tagoio_http_post/README.rst +++ b/samples/net/cloud/tagoio_http_post/README.rst @@ -68,7 +68,7 @@ need fill ``CONFIG_TAGOIO_HTTP_WIFI_SSID`` with your wifi network SSID and .. zephyr-app-commands:: :zephyr-app: samples/net/cloud/tagoio_http_post :board: disco_l475_iot1 - :gen-args: -DOVERLAY_CONFIG=overlay-wifi.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-wifi.conf :goals: build flash :compact: @@ -76,7 +76,7 @@ need fill ``CONFIG_TAGOIO_HTTP_WIFI_SSID`` with your wifi network SSID and :zephyr-app: samples/net/cloud/tagoio_http_post :board: [sam_v71_xult | frdm_k64f | nucleo_f767zi] :shield: [esp_8266_arduino | inventek_eswifi_arduino_uart] - :gen-args: -DOVERLAY_CONFIG=overlay-wifi.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-wifi.conf :goals: build flash :compact: @@ -97,14 +97,14 @@ a special designator like defined at ``arduino.overlay``. .. zephyr-app-commands:: :zephyr-app: samples/net/cloud/tagoio_http_post :board: sam4e_xpro - :gen-args: -DOVERLAY_CONFIG=overlay-modem.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-modem.conf :goals: build flash :compact: .. zephyr-app-commands:: :zephyr-app: samples/net/cloud/tagoio_http_post :board: frdm_k64f - :gen-args: -DOVERLAY_CONFIG=overlay-modem.conf -DDTC_OVERLAY_FILE=arduino.overlay + :gen-args: -DEXTRA_CONF_FILE=overlay-modem.conf -DDTC_OVERLAY_FILE=arduino.overlay :goals: build flash :compact: diff --git a/samples/net/mqtt_publisher/README.rst b/samples/net/mqtt_publisher/README.rst index 05f0541d65d5..04ff4c47bfd2 100644 --- a/samples/net/mqtt_publisher/README.rst +++ b/samples/net/mqtt_publisher/README.rst @@ -129,7 +129,7 @@ try this sample with TLS enabled, by following these steps: i.e., the IP address of test.mosquitto.org ``"37.187.106.16"`` - In :file:`src/main.c`, set TLS_SNI_HOSTNAME to ``"test.mosquitto.org"`` to match the Common Name (CN) in the downloaded certificate. -- Build the sample by specifying ``-DOVERLAY_CONFIG=overlay-tls.conf`` +- Build the sample by specifying ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when running ``west build`` or ``cmake`` (or refer to the TLS offloading section below if your platform uses the offloading feature). - Flash the binary onto the device to run the sample: @@ -142,7 +142,7 @@ TLS offloading ============== For boards that support this feature, TLS offloading is used by -specifying ``-DOVERLAY_CONFIG=overlay-tls-offload.conf`` when running ``west +specifying ``-DEXTRA_CONF_FILE=overlay-tls-offload.conf`` when running ``west build`` or ``cmake``. Using this overlay enables TLS without bringing in mbedtls. @@ -151,7 +151,7 @@ SOCKS5 proxy support ==================== It is also possible to connect to the MQTT broker through a SOCKS5 proxy. -To enable it, use ``-DOVERLAY_CONFIG=overlay-socks5.conf`` when running ``west +To enable it, use ``-DEXTRA_CONF_FILE=overlay-socks5.conf`` when running ``west build`` or ``cmake``. By default, to make the testing easier, the proxy is expected to run on the diff --git a/samples/net/openthread/coprocessor/README.rst b/samples/net/openthread/coprocessor/README.rst index 1c315d4f4d75..ee76942c3fcd 100644 --- a/samples/net/openthread/coprocessor/README.rst +++ b/samples/net/openthread/coprocessor/README.rst @@ -38,7 +38,7 @@ Build the OpenThread NCP sample application which uses CDC ACM UART device: :zephyr-app: samples/net/openthread/coprocessor :board: nrf52840dk_nrf52840 :goals: build flash - :gen-args: -DDTC_OVERLAY_FILE=usb.overlay -DOVERLAY_CONFIG=overlay-usb-nrf-br.conf + :gen-args: -DDTC_OVERLAY_FILE=usb.overlay -DEXTRA_CONF_FILE=overlay-usb-nrf-br.conf :compact: Example building for the nrf52840dk_nrf52840 for RCP: diff --git a/samples/net/sockets/big_http_download/README.rst b/samples/net/sockets/big_http_download/README.rst index 3eaa9a19bab9..0cefa7320637 100644 --- a/samples/net/sockets/big_http_download/README.rst +++ b/samples/net/sockets/big_http_download/README.rst @@ -74,7 +74,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when +An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when running ``west build`` or ``cmake``. The TLS version of this sample downloads a file from diff --git a/samples/net/sockets/echo_client/README.rst b/samples/net/sockets/echo_client/README.rst index bcde370d8ae8..31d03d18202e 100644 --- a/samples/net/sockets/echo_client/README.rst +++ b/samples/net/sockets/echo_client/README.rst @@ -75,7 +75,7 @@ Example building for the IEEE 802.15.4 RF2XX transceiver: :zephyr-app: samples/net/sockets/echo_client :host-os: unix :board: [atsamr21_xpro | sam4s_xplained | sam_v71_xult] - :gen-args: -DOVERLAY_CONFIG=overlay-802154.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-802154.conf :goals: build flash :compact: @@ -100,7 +100,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when +An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when running ``west build`` or ``cmake``. The certificate and private key used by the sample can be found in the sample's @@ -112,7 +112,7 @@ SOCKS5 proxy support ==================== It is also possible to connect to the echo-server through a SOCKS5 proxy. -To enable it, use ``-DOVERLAY_CONFIG=overlay-socks5.conf`` when running ``west +To enable it, use ``-DEXTRA_CONF_FILE=overlay-socks5.conf`` when running ``west build`` or ``cmake``. By default, to make the testing easier, the proxy is expected to run on the diff --git a/samples/net/sockets/echo_server/README.rst b/samples/net/sockets/echo_server/README.rst index 3be89983a962..98260d798730 100644 --- a/samples/net/sockets/echo_server/README.rst +++ b/samples/net/sockets/echo_server/README.rst @@ -82,7 +82,7 @@ Example building for the atsamr21_xpro with RF2XX driver support: :zephyr-app: samples/net/sockets/echo_server :host-os: unix :board: [atsamr21_xpro | sam4e_xpro | sam_v71_xult] - :gen-args: -DOVERLAY_CONFIG=overlay-802154.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-802154.conf :goals: build flash :compact: @@ -105,7 +105,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when +An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when running ``west build`` or ``cmake``. The certificate used by the sample can be found in the sample's ``src`` diff --git a/samples/net/sockets/http_client/README.rst b/samples/net/sockets/http_client/README.rst index 4d1459f8a8fc..1d37121ad568 100644 --- a/samples/net/sockets/http_client/README.rst +++ b/samples/net/sockets/http_client/README.rst @@ -45,7 +45,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when +An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when running ``west build`` or ``cmake``. The certificate and private key used by the sample can be found in the sample's diff --git a/samples/net/sockets/http_get/README.rst b/samples/net/sockets/http_get/README.rst index 07c03fa1fae1..bd4a6824d7f3 100644 --- a/samples/net/sockets/http_get/README.rst +++ b/samples/net/sockets/http_get/README.rst @@ -53,7 +53,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when +An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when running ``west build`` or ``cmake``. For boards that support TLS offloading (e.g. TI's cc3220sf_launchxl), use diff --git a/samples/net/sockets/tcp/README.rst b/samples/net/sockets/tcp/README.rst index d574fdfcf94e..5f43d02d41ff 100644 --- a/samples/net/sockets/tcp/README.rst +++ b/samples/net/sockets/tcp/README.rst @@ -26,7 +26,7 @@ Build the TCP sample app: cd samples/net/sockets/tcp mkdir build && cd build - cmake -DBOARD=qemu_x86 -DOVERLAY_CONFIG="overlay-slip.conf" .. + cmake -DBOARD=qemu_x86 -DEXTRA_CONF_FILE="overlay-slip.conf" .. make run Compile and run the TCP sanity check `net-test-suites`_: diff --git a/samples/net/sockets/websocket_client/README.rst b/samples/net/sockets/websocket_client/README.rst index ee115fbe8f02..d6ae83b568ff 100644 --- a/samples/net/sockets/websocket_client/README.rst +++ b/samples/net/sockets/websocket_client/README.rst @@ -46,7 +46,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when +An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when running ``west build`` or ``cmake``. The certificate and private key used by the sample can be found in the sample's diff --git a/samples/net/wpanusb/README.rst b/samples/net/wpanusb/README.rst index bc53cfa3cd15..e6e87502a661 100644 --- a/samples/net/wpanusb/README.rst +++ b/samples/net/wpanusb/README.rst @@ -39,7 +39,7 @@ Build the wpanusb sample for a board: .. zephyr-app-commands:: :zephyr-app: samples/net/wpanusb :board: - :gen-args: -DOVERLAY_CONFIG= + :gen-args: -DEXTRA_CONF_FILE= :goals: build :compact: diff --git a/samples/subsys/fs/fat_fs/README.rst b/samples/subsys/fs/fat_fs/README.rst index 935c93aed60d..2f7ecb4952d7 100644 --- a/samples/subsys/fs/fat_fs/README.rst +++ b/samples/subsys/fs/fat_fs/README.rst @@ -59,7 +59,7 @@ and DTS overlays need to be also selected. The command would look like this: .. zephyr-app-commands:: :zephyr-app: samples/subsys/fs/fat_fs :board: nrf52840dk_nrf52840 - :gen-args: -DOVERLAY_CONFIG=nrf52840dk_nrf52840_qspi.conf -DDTC_OVERLAY_FILE=nrf52840dk_nrf52840_qspi.overlay + :gen-args: -DEXTRA_CONF_FILE=nrf52840dk_nrf52840_qspi.conf -DDTC_OVERLAY_FILE=nrf52840dk_nrf52840_qspi.overlay :goals: build :compact: diff --git a/samples/subsys/lorawan/class_a/README.rst b/samples/subsys/lorawan/class_a/README.rst index 4d923903fdf2..ba72fe1d4dac 100644 --- a/samples/subsys/lorawan/class_a/README.rst +++ b/samples/subsys/lorawan/class_a/README.rst @@ -38,5 +38,5 @@ enabled. :zephyr-app: samples/subsys/lorawan/class_a :board: nucleo_wl55jc :goals: build flash - :gen-args: -DOVERLAY_CONFIG=overlay-clock-sync.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-clock-sync.conf :compact: diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst index 1559d4123c69..c988e4145648 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst +++ b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst @@ -93,7 +93,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b nrf52dk_nrf52832 \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DOVERLAY_CONFIG=overlay-bt.conf + -DEXTRA_CONF_FILE=overlay-bt.conf .. group-tab:: Serial @@ -105,7 +105,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DOVERLAY_CONFIG='overlay-serial.conf;overlay-fs.conf;overlay-shell-mgmt.conf' + -DEXTRA_CONF_FILE='overlay-serial.conf;overlay-fs.conf;overlay-shell-mgmt.conf' .. group-tab:: USB CDC_ACM @@ -117,7 +117,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b nrf52840dk_nrf52840 \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DOVERLAY_CONFIG=overlay-cdc.conf \ + -DEXTRA_CONF_FILE=overlay-cdc.conf \ -DDTC_OVERLAY_FILE=usb.overlay .. group-tab:: Shell @@ -130,7 +130,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DOVERLAY_CONFIG='overlay-shell.conf' + -DEXTRA_CONF_FILE='overlay-shell.conf' .. group-tab:: UDP @@ -146,7 +146,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DOVERLAY_CONFIG=overlay-udp.conf + -DEXTRA_CONF_FILE=overlay-udp.conf .. _smp_svr_sample_sign: diff --git a/samples/subsys/mgmt/updatehub/README.rst b/samples/subsys/mgmt/updatehub/README.rst index db16237a0a91..0324ab970254 100644 --- a/samples/subsys/mgmt/updatehub/README.rst +++ b/samples/subsys/mgmt/updatehub/README.rst @@ -174,7 +174,7 @@ The ethernet depends only from base configuration. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: [ frdm_k64f | nucleo_f767zi ] :build-dir: app - :gen-args: -DOVERLAY_CONFIG=overlay-prj.conf + :gen-args: -DEXTRA_CONF_FILE=overlay-prj.conf :goals: build :compact: @@ -189,7 +189,7 @@ for details. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: [ frdm_k64f | nrf52840dk_nrf52840 | nucleo_f767zi ] :build-dir: app - :gen-args: -DOVERLAY_CONFIG="overlay-wifi.conf;overlay-prj.conf" + :gen-args: -DEXTRA_CONF_FILE="overlay-wifi.conf;overlay-prj.conf" :shield: esp_8266_arduino :goals: build :compact: @@ -209,7 +209,7 @@ uses PPP over GSM modem, see :ref:`gsm-modem-sample`. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: [ frdm_k64f | nrf52840dk_nrf52840 | nucleo_f767zi ] :build-dir: app - :gen-args: -DOVERLAY_CONFIG="overlay-modem.conf;overlay-prj.conf" \ + :gen-args: -DEXTRA_CONF_FILE="overlay-modem.conf;overlay-prj.conf" \ -DDTC_OVERLAY_FILE=arduino.overlay :goals: build :compact: @@ -228,7 +228,7 @@ tested with both native linux driver and ``atusb`` and with ``wpanusb`` sample. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: nrf52840dk_nrf52840 :build-dir: app - :gen-args: -DOVERLAY_CONFIG="overlay-802154.conf;overlay-prj.conf" + :gen-args: -DEXTRA_CONF_FILE="overlay-802154.conf;overlay-prj.conf" :goals: build :compact: @@ -236,7 +236,7 @@ tested with both native linux driver and ``atusb`` and with ``wpanusb`` sample. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: [ frdm_k64f | nucleo_f767zi ] :build-dir: app - :gen-args: -DOVERLAY_CONFIG="overlay-802154.conf;overlay-prj.conf" + :gen-args: -DEXTRA_CONF_FILE="overlay-802154.conf;overlay-prj.conf" :shield: atmel_rf2xx_arduino :goals: build :compact: @@ -256,7 +256,7 @@ tested with native linux driver and an USB dongle. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: nrf52840dk_nrf52840 :build-dir: app - :gen-args: -DOVERLAY_CONFIG="overlay-ipsp.conf;overlay-prj.conf" + :gen-args: -DEXTRA_CONF_FILE="overlay-ipsp.conf;overlay-prj.conf" :goals: build :compact: @@ -274,7 +274,7 @@ gateway was tested using two boards with OpenThread 1.1.1 on NCP mode. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: nrf52840dk_nrf52840 :build-dir: app - :gen-args: -DOVERLAY_CONFIG="overlay-ot.conf;overlay-prj.conf" + :gen-args: -DEXTRA_CONF_FILE="overlay-ot.conf;overlay-prj.conf" :goals: build :compact: diff --git a/samples/subsys/modbus/rtu_server/README.rst b/samples/subsys/modbus/rtu_server/README.rst index bb29946f7d9c..973339e1cb78 100644 --- a/samples/subsys/modbus/rtu_server/README.rst +++ b/samples/subsys/modbus/rtu_server/README.rst @@ -67,7 +67,7 @@ The following commands build and flash RTU server sample using CDC ACM UART. :zephyr-app: samples/subsys/modbus/rtu_server :board: nrf52840dk_nrf52840 :goals: build flash - :gen-args: -DDTC_OVERLAY_FILE=cdc-acm.overlay -DOVERLAY_CONFIG=overlay-cdc-acm.conf + :gen-args: -DDTC_OVERLAY_FILE=cdc-acm.overlay -DEXTRA_CONF_FILE=overlay-cdc-acm.conf :compact: On the client side, PC or laptop, the following command connects PyModbus diff --git a/samples/subsys/usb/dfu/README.rst b/samples/subsys/usb/dfu/README.rst index dccb53db10fa..0ed2d7e6991e 100644 --- a/samples/subsys/usb/dfu/README.rst +++ b/samples/subsys/usb/dfu/README.rst @@ -129,7 +129,7 @@ Both symbols can be enabled with the :file:`overlay-permanent-download.conf` ove west build -b nrf52840dk_nrf52840 zephyr/samples/subsys/usb/dfu -d build-dfu -- \ -DCONFIG_BOOTLOADER_MCUBOOT=y '-DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/root-rsa-2048.pem"' \ - -DOVERLAY_CONFIG=overlay-permanent-download.conf + -DEXTRA_CONF_FILE=overlay-permanent-download.conf The listing below shows the output to the console when downloading via dfu-util. diff --git a/samples/subsys/usb/shell/README.rst b/samples/subsys/usb/shell/README.rst index 09a57d252069..12f7c0ae1939 100644 --- a/samples/subsys/usb/shell/README.rst +++ b/samples/subsys/usb/shell/README.rst @@ -40,7 +40,7 @@ the platform has already defined or not `zephyr_uhc0` or `zephyr_udc0` nodelabel .. zephyr-app-commands:: :zephyr-app: samples/subsys/usb/shell :board: nrf52840dk_nrf52840 - :gen-args: -DOVERLAY_CONFIG=virtual.conf -DDTC_OVERLAY_FILE=virtual.overlay + :gen-args: -DEXTRA_CONF_FILE=virtual.conf -DDTC_OVERLAY_FILE=virtual.overlay :goals: flash :compact: From 6a780ae402663cc2ca615aae40ae36e849b2b767 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 13:59:28 +0200 Subject: [PATCH 148/528] [nrf fromtree] cmake: align Zephyr module variable to EXTRA_ZEPHYR_MODULES Align Zephyr modules with other user facing variables where settings can be defined or extended, meaning Zephyr modules now supports: ZEPHYR_MODULES and EXTRA_ZEPHYR_MODULES. Support for ZEPHYR_EXTRA_MODULES is kept foir backward compatibility. Signed-off-by: Torsten Rasmussen (cherry picked from commit a88502783b2cebb70d060f84889cfb861d5c45b2) (cherry picked from commit 0b4be63559179c654f43631768ae02b34e03d8a9) --- CMakeLists.txt | 2 +- cmake/modules/zephyr_module.cmake | 8 ++++---- .../out_of_tree_driver/CMakeLists.txt | 2 +- tests/cmake/overlays/var_expansions/CMakeLists.txt | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 41e104494673..cda9062d0b7d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1585,7 +1585,7 @@ if(CONFIG_BUILD_OUTPUT_META) COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/zephyr_module.py ${WEST_ARG} ${ZEPHYR_MODULES_ARG} - ${ZEPHYR_EXTRA_MODULES_ARG} + ${EXTRA_ZEPHYR_MODULES_ARG} --meta-out ${KERNEL_META_NAME} $<$:--meta-state-propagate> ) diff --git a/cmake/modules/zephyr_module.cmake b/cmake/modules/zephyr_module.cmake index 05d13cf5f246..90afc1f02e5b 100644 --- a/cmake/modules/zephyr_module.cmake +++ b/cmake/modules/zephyr_module.cmake @@ -36,9 +36,9 @@ if(ZEPHYR_MODULES) set(ZEPHYR_MODULES_ARG "--modules" ${ZEPHYR_MODULES}) endif() -zephyr_get(ZEPHYR_EXTRA_MODULES) -if(ZEPHYR_EXTRA_MODULES) - set(ZEPHYR_EXTRA_MODULES_ARG "--extra-modules" ${ZEPHYR_EXTRA_MODULES}) +zephyr_get(EXTRA_ZEPHYR_MODULES VAR EXTRA_ZEPHYR_MODULES ZEPHYR_EXTRA_MODULES) +if(EXTRA_ZEPHYR_MODULES) + set(EXTRA_ZEPHYR_MODULES_ARG "--extra-modules" ${EXTRA_ZEPHYR_MODULES}) endif() file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}) @@ -60,7 +60,7 @@ if(WEST OR ZEPHYR_MODULES) ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/zephyr_module.py ${west_arg} ${ZEPHYR_MODULES_ARG} - ${ZEPHYR_EXTRA_MODULES_ARG} + ${EXTRA_ZEPHYR_MODULES_ARG} --kconfig-out ${kconfig_modules_file} --cmake-out ${cmake_modules_file} --sysbuild-kconfig-out ${kconfig_sysbuild_file} diff --git a/samples/application_development/out_of_tree_driver/CMakeLists.txt b/samples/application_development/out_of_tree_driver/CMakeLists.txt index 3f3932363d08..a234427218f3 100644 --- a/samples/application_development/out_of_tree_driver/CMakeLists.txt +++ b/samples/application_development/out_of_tree_driver/CMakeLists.txt @@ -2,7 +2,7 @@ # For the sake of demonstration, we add the driver directory as a zephyr module # by hand. If your driver is a project that's managed by west, you can remove this line. -list(APPEND ZEPHYR_EXTRA_MODULES +list(APPEND EXTRA_ZEPHYR_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/hello_world_module ) diff --git a/tests/cmake/overlays/var_expansions/CMakeLists.txt b/tests/cmake/overlays/var_expansions/CMakeLists.txt index db382a53e966..a36cc87bf8e2 100644 --- a/tests/cmake/overlays/var_expansions/CMakeLists.txt +++ b/tests/cmake/overlays/var_expansions/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.20.0) set(ZEPHYR_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/my_module") -set(ZEPHYR_EXTRA_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/my_extra_module") +set(EXTRA_ZEPHYR_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/my_extra_module") find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(overlay_var_expansions) From 66d000aaf64e341f1e79fd9c1383ffcc484eba1a Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 17 May 2023 14:03:54 +0200 Subject: [PATCH 149/528] [nrf fromtree] doc: update Zephyr modules to use EXTRA_ZEPHYR_MODULES Update Zephyr modules documentation to use EXTRA_ZEPHYR_MODULES. This gives a more consistent naming scheme in Zephyr CMake build system. Signed-off-by: Torsten Rasmussen (cherry picked from commit 6c8e52ba426b72a97497c0f4c3181dffa5bf1266) (cherry picked from commit a85057ce9197929a0206fce510b611f6c1b4c208) --- doc/develop/application/index.rst | 2 +- doc/develop/env_vars.rst | 2 +- doc/develop/modules.rst | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index ca9591bf44c7..e1400b62b55c 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -422,7 +422,7 @@ should know about. variable, it must be a complete list of all modules to use, as the build system will not automatically pick up any modules from west. -* :makevar:`ZEPHYR_EXTRA_MODULES`: Like :makevar:`ZEPHYR_MODULES`, except these +* :makevar:`EXTRA_ZEPHYR_MODULES`: Like :makevar:`ZEPHYR_MODULES`, except these will be added to the list of modules found via west, instead of replacing it. .. note:: diff --git a/doc/develop/env_vars.rst b/doc/develop/env_vars.rst index e5f7269fba5f..459c62b580ae 100644 --- a/doc/develop/env_vars.rst +++ b/doc/develop/env_vars.rst @@ -185,7 +185,7 @@ a comprehensive list. See :ref:`important-build-vars`. -.. envvar:: ZEPHYR_EXTRA_MODULES +.. envvar:: EXTRA_ZEPHYR_MODULES See :ref:`important-build-vars`. diff --git a/doc/develop/modules.rst b/doc/develop/modules.rst index 88467223481d..ab827e911d1c 100644 --- a/doc/develop/modules.rst +++ b/doc/develop/modules.rst @@ -396,16 +396,16 @@ added to the build using CMake's `add_subdirectory()`_ command, and the If you have :ref:`west ` installed, you don't need to worry about how this variable is defined unless you are adding a new module. The build system knows how to use west to set :makevar:`ZEPHYR_MODULES`. You can add additional -modules to this list by setting the :makevar:`ZEPHYR_EXTRA_MODULES` CMake -variable or by adding a :makevar:`ZEPHYR_EXTRA_MODULES` line to ``.zephyrrc`` +modules to this list by setting the :makevar:`EXTRA_ZEPHYR_MODULES` CMake +variable or by adding a :makevar:`EXTRA_ZEPHYR_MODULES` line to ``.zephyrrc`` (See the section on :ref:`env_vars` for more details). This can be useful if you want to keep the list of modules found with west and also add your own. .. note:: If the module ``FOO`` is provided by :ref:`west ` but also given with - ``-DZEPHYR_EXTRA_MODULES=//foo`` then the module given by the command - line variable :makevar:`ZEPHYR_EXTRA_MODULES` will take precedence. + ``-DEXTRA_ZEPHYR_MODULES=//foo`` then the module given by the command + line variable :makevar:`EXTRA_ZEPHYR_MODULES` will take precedence. This allows you to use a custom version of ``FOO`` when building and still use other Zephyr modules provided by :ref:`west `. This can for example be useful for special test purposes. From d94f71aa34cb16216312e4d13e4fe60e730f6470 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 8 May 2023 13:50:03 +0200 Subject: [PATCH 150/528] [nrf fromtree] cmake: add reverse option to `zephyr_get(... MERGE)` Adding the possibility to have the list returned in reversed order when using `zephyr_get(... MERGE). `zephyr_get(... MERGE)` creates a list which populates the content based on variable settings in the following scopes, in this order: sysbuild, cache, environment, local. This works well for lists where content first in list has highest precedence, such as ROOTs settings. However, for settings where the value last in the list will overwrite values earlier in the list, we want the list to be reversed, examples of such can be CONF_FILE, OVERLAY_CONFIG, DTC_OVERLAY_FILE, where the content of the file last in the list will overrule the content from an earlier file. So to ensure that a DTC_OVERLAY_FILE defined as cache takes precedence over an env or local scope variable the possibility of reversing the list must be available. Signed-off-by: Torsten Rasmussen (cherry picked from commit fd526cc4b23258fb69a7fb6fa3bd630828633e09) (cherry picked from commit e56afd2bd93b877215676a16d838158caccdd7a5) --- cmake/modules/extensions.cmake | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 4f75b41282b5..a18b9b0efeee 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2493,10 +2493,13 @@ function(zephyr_var_name variable scope out) endfunction() # Usage: -# zephyr_get( [MERGE] [SYSBUILD [LOCAL|GLOBAL]] [VAR ...]) +# zephyr_get( [MERGE [REVERSE]] [SYSBUILD [LOCAL|GLOBAL]] [VAR ...]) # # Return the value of as local scoped variable of same name. If MERGE -# is supplied, will return a list of found items. +# is supplied, will return a list of found items. If REVERSE is supplied +# together with MERGE, the order of the list will be reversed before being +# returned. Reverse will happen before the list is returned and hence it will +# not change the order of precedence in which the list itself is constructed. # # VAR can be used either to store the result in a variable with a different # name, or to look for values from multiple variables. @@ -2526,7 +2529,7 @@ endfunction() # using `-DZEPHYR_TOOLCHAIN_VARIANT=`, then the value from the cache is # returned. function(zephyr_get variable) - cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "VAR" ${ARGN}) + cmake_parse_arguments(GET_VAR "MERGE;REVERSE" "SYSBUILD" "VAR" ${ARGN}) if(DEFINED GET_VAR_SYSBUILD) if(NOT ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR @@ -2538,6 +2541,10 @@ function(zephyr_get variable) set(GET_VAR_SYSBUILD "GLOBAL") endif() + if(GET_VAR_REVERSE AND NOT GET_VAR_MERGE) + message(FATAL_ERROR "zephyr_get(... REVERSE) missing a required argument: MERGE") + endif() + if(NOT DEFINED GET_VAR_VAR) set(GET_VAR_VAR ${variable}) endif() @@ -2564,6 +2571,9 @@ function(zephyr_get variable) endforeach() set(scopes "sysbuild;CACHE;ENV;current") + if(GET_VAR_REVERSE) + list(REVERSE scopes) + endif() foreach(scope IN LISTS scopes) foreach(var ${GET_VAR_VAR}) zephyr_var_name("${var}" "${scope}" expansion_var) @@ -2601,7 +2611,13 @@ function(zephyr_get variable) endforeach() if(GET_VAR_MERGE) - list(REMOVE_DUPLICATES ${variable}) + if(GET_VAR_REVERSE) + list(REVERSE ${variable}) + list(REMOVE_DUPLICATES ${variable}) + list(REVERSE ${variable}) + else() + list(REMOVE_DUPLICATES ${variable}) + endif() set(${variable} ${${variable}} PARENT_SCOPE) endif() endfunction(zephyr_get variable) From b02e3ccafb1d8596b5974e357362c7341cc3ec63 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 24 May 2023 12:34:34 +0200 Subject: [PATCH 151/528] [nrf fromtree] snippets: support for EXTRA_DTC_OVERLAY_FILE and EXTRA_CONF_FILE This commit adds change snippets to use the new EXTRA_DTC_OVERLAY_FILE and EXTRA_CONF_FILE Zephyr build system variables instead of DTC_OVERLAY_FILE and OVERLAY_CONFIG. Signed-off-by: Torsten Rasmussen (cherry picked from commit 1561a0705f767c4afbede9086bdb2485d16303d7) (cherry picked from commit d683f25ad38786363a9cc0afe5794c735e7d26b6) --- doc/build/snippets/writing.rst | 14 +++++++------- scripts/schemas/snippet-schema.yml | 4 ++-- scripts/snippets.py | 2 +- snippets/cdc-acm-console/snippet.yml | 4 ++-- .../extra_snippet_root/snippets/bar/snippet.yml | 2 +- tests/cmake/snippets/snippets/foo/snippet.yml | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/build/snippets/writing.rst b/doc/build/snippets/writing.rst index 66101e8e2b63..5a60a7e73836 100644 --- a/doc/build/snippets/writing.rst +++ b/doc/build/snippets/writing.rst @@ -28,8 +28,8 @@ this: name: foo append: - DTC_OVERLAY_FILE: foo.overlay - OVERLAY_CONFIG: foo.conf + EXTRA_DTC_OVERLAY_FILE: foo.overlay + EXTRA_CONF_FILE: foo.conf Namespacing *********** @@ -113,7 +113,7 @@ This :file:`snippet.yml` adds :file:`foo.overlay` to the build: name: foo append: - DTC_OVERLAY_FILE: foo.overlay + EXTRA_DTC_OVERLAY_FILE: foo.overlay The path to :file:`foo.overlay` is relative to the directory containing :file:`snippet.yml`. @@ -129,7 +129,7 @@ This :file:`snippet.yml` adds :file:`foo.conf` to the build: name: foo append: - OVERLAY_CONFIG: foo.conf + EXTRA_CONF_FILE: foo.conf The path to :file:`foo.conf` is relative to the directory containing :file:`snippet.yml`. @@ -154,10 +154,10 @@ By name boards: bar: # settings for board "bar" go here append: - DTC_OVERLAY_FILE: bar.overlay + EXTRA_DTC_OVERLAY_FILE: bar.overlay baz: # settings for board "baz" go here append: - DTC_OVERLAY_FILE: baz.overlay + EXTRA_DTC_OVERLAY_FILE: baz.overlay The above example uses :file:`bar.overlay` when building for board ``bar``, and :file:`baz.overlay` when building for ``baz``. @@ -180,7 +180,7 @@ For example: boards: /my_vendor_.*/: append: - DTC_OVERLAY_FILE: my_vendor.overlay + EXTRA_DTC_OVERLAY_FILE: my_vendor.overlay The above example uses devicetree overlay :file:`my_vendor.overlay` when building for either board ``my_vendor_board1`` or ``my_vendor_board2``. It diff --git a/scripts/schemas/snippet-schema.yml b/scripts/schemas/snippet-schema.yml index d6c46d543238..64cebaedc7c2 100644 --- a/scripts/schemas/snippet-schema.yml +++ b/scripts/schemas/snippet-schema.yml @@ -9,9 +9,9 @@ schema;append-schema: # See uses under 'append:' keys below. type: map mapping: - DTC_OVERLAY_FILE: + EXTRA_DTC_OVERLAY_FILE: type: str - OVERLAY_CONFIG: + EXTRA_CONF_FILE: type: str type: map diff --git a/scripts/snippets.py b/scripts/snippets.py index 2158613a1490..74e7ebbbfcea 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -52,7 +52,7 @@ def process_data(self, pathobj: Path, snippet_data: dict): '''Process the data in a snippet.yml file, after it is loaded into a python object and validated by pykwalify.''' def append_value(variable, value): - if variable in ('DTC_OVERLAY_FILE', 'OVERLAY_CONFIG'): + if variable in ('EXTRA_DTC_OVERLAY_FILE', 'EXTRA_CONF_FILE'): path = pathobj.parent / value if not path.is_file(): _err(f'snippet file {pathobj}: {variable}: file not found: {path}') diff --git a/snippets/cdc-acm-console/snippet.yml b/snippets/cdc-acm-console/snippet.yml index eab58a30a40e..98ff05bc14a7 100644 --- a/snippets/cdc-acm-console/snippet.yml +++ b/snippets/cdc-acm-console/snippet.yml @@ -1,4 +1,4 @@ name: cdc-acm-console append: - OVERLAY_CONFIG: cdc-acm-console.conf - DTC_OVERLAY_FILE: cdc-acm-console.overlay + EXTRA_CONF_FILE: cdc-acm-console.conf + EXTRA_DTC_OVERLAY_FILE: cdc-acm-console.overlay diff --git a/tests/cmake/snippets/extra_snippet_root/snippets/bar/snippet.yml b/tests/cmake/snippets/extra_snippet_root/snippets/bar/snippet.yml index 914371337791..607ad57a2c0b 100644 --- a/tests/cmake/snippets/extra_snippet_root/snippets/bar/snippet.yml +++ b/tests/cmake/snippets/extra_snippet_root/snippets/bar/snippet.yml @@ -1,3 +1,3 @@ name: bar append: - DTC_OVERLAY_FILE: bar.overlay + EXTRA_DTC_OVERLAY_FILE: bar.overlay diff --git a/tests/cmake/snippets/snippets/foo/snippet.yml b/tests/cmake/snippets/snippets/foo/snippet.yml index 22817d7ebf1b..ba39e7db108c 100644 --- a/tests/cmake/snippets/snippets/foo/snippet.yml +++ b/tests/cmake/snippets/snippets/foo/snippet.yml @@ -1,3 +1,3 @@ name: foo append: - OVERLAY_CONFIG: foo.conf + EXTRA_CONF_FILE: foo.conf From 1a2b27689bb2d658675b820bdd5b2d6148743c5a Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 24 May 2023 09:56:00 +0200 Subject: [PATCH 152/528] [nrf fromtree] cmake: create Zephyr scope functions for variables zephyr_get() supports multiple scopes when returning variables. Variables are returned based on the scope's priority. To facilitate creation of more scopes in Zephyr for variable handling additional functions are introduced. - zephyr_create_scope() creates a new scope - zephyr_set( ... SCOPE ) set the value of a variable in the specified scope. Signed-off-by: Torsten Rasmussen (cherry picked from commit a6d9105d51de2277ab64457c60c1d23005743790) (cherry picked from commit b8f7f3a457f9c2f783674560eafd20a3c78c8964) --- cmake/modules/extensions.cmake | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index a18b9b0efeee..b0d742703eae 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2622,6 +2622,52 @@ function(zephyr_get variable) endif() endfunction(zephyr_get variable) +# Usage: +# zephyr_create_scope() +# +# Create a new scope for creation of scoped variables. +# +# : Name of new scope. +# +function(zephyr_create_scope scope) + if(TARGET ${scope}_scope) + message(FATAL_ERROR "zephyr_create_scope(${scope}) already exists.") + endif() + + add_custom_target(${scope}_scope) +endfunction() + +# Usage: +# zephyr_set( SCOPE [APPEND]) +# +# Zephyr extension of CMake set which allows a variable to be set in a specific +# scope. The scope is used on later zephyr_get() invocation for precedence +# handling when a variable it set in multiple scopes. +# +# : Name of variable +# : Value of variable, multiple values will create a list. +# The SCOPE argument identifies the end of value list. +# SCOPE : Name of scope for the variable +# APPEND : Append values to the already existing variable in +# +function(zephyr_set variable) + cmake_parse_arguments(SET_VAR "APPEND" "SCOPE" "" ${ARGN}) + + zephyr_check_arguments_required_all(zephyr_set SET_VAR SCOPE) + + if(NOT TARGET ${SET_VAR_SCOPE}_scope) + message(FATAL_ERROR "zephyr_set(... SCOPE ${SET_VAR_SCOPE}) doesn't exists.") + endif() + + if(SET_VAR_APPEND) + set(property_args APPEND) + endif() + + set_property(TARGET ${SET_VAR_SCOPE}_scope ${property_args} + PROPERTY ${variable} ${SET_VAR_UNPARSED_ARGUMENTS} + ) +endfunction() + # Usage: # zephyr_check_cache( [REQUIRED]) # From 0933a4b2949889ca924b10aff05b1093dabe7ba0 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 8 May 2023 14:01:34 +0200 Subject: [PATCH 153/528] [nrf fromtree] cmake: support snippets scope for `zephyr_get()` Fixes: #57139 Snippets provides the possibility of defining EXTRA_DTC_OVERLAY_FILE and EXTRA_CONF_FILE in snippets. Snippets must co-exist with existing infrastructure of EXTRA_DTC_OVERLAY_FILE and EXTRA_CONF_FILE, and a user specifying a snippet must be able to specify extra files for adjusting the snippet. This means that if the following is specified: `-DSNIPPET=some_snippet -DEXTRA_CONF_FILE=extra.conf` then `extra.conf` may contain adjustments to the snippet. Similar to sysbuild. Imagine a sysbuild controlled image uses a default snippet for building, by ensuring that any extra `-D_EXTRA_CONF_FILE=extra.conf` arguments takes precedence over the snippet we allow users to make adjustments if they need. This commit introduces a snippets scope where snippet scoped variables can be set with `zephyr_set()` and then `zephyr_get()` will take the snippet scoped variables into consideration before returning. Adjust calls to `zephyr_get(EXTRA_DTC_OVERLAY_FILE)` and `zephyr_get(EXTRA_CONF_FILE)` to use `MERGE` to ensure all scopes are considered. Signed-off-by: Torsten Rasmussen (cherry picked from commit ba48dd876349832840009462ed03f77c9d3653aa) (cherry picked from commit b9d092ea9eb3bbe7dce434ed4b9d11860d3002c7) --- cmake/modules/configuration_files.cmake | 4 ++-- cmake/modules/extensions.cmake | 6 +++++- cmake/modules/snippets.cmake | 4 ---- scripts/snippets.py | 5 ++++- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/cmake/modules/configuration_files.cmake b/cmake/modules/configuration_files.cmake index 24d5e9feedd3..06ad074f0cef 100644 --- a/cmake/modules/configuration_files.cmake +++ b/cmake/modules/configuration_files.cmake @@ -116,5 +116,5 @@ DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"") # The DTC_OVERLAY_FILE variable is now set to its final value. zephyr_boilerplate_watch(DTC_OVERLAY_FILE) -zephyr_get(EXTRA_CONF_FILE SYSBUILD LOCAL VAR EXTRA_CONF_FILE OVERLAY_CONFIG) -zephyr_get(EXTRA_DTC_OVERLAY_FILE SYSBUILD LOCAL) +zephyr_get(EXTRA_CONF_FILE SYSBUILD LOCAL VAR EXTRA_CONF_FILE OVERLAY_CONFIG MERGE REVERSE) +zephyr_get(EXTRA_DTC_OVERLAY_FILE SYSBUILD LOCAL MERGE REVERSE) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index b0d742703eae..172b707aaff3 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2568,9 +2568,13 @@ function(zephyr_get variable) else() set(sysbuild_${var}) endif() + + if(TARGET snippets_scope) + get_property(snippets_${var} TARGET snippets_scope PROPERTY ${var}) + endif() endforeach() - set(scopes "sysbuild;CACHE;ENV;current") + set(scopes "sysbuild;CACHE;snippets;ENV;current") if(GET_VAR_REVERSE) list(REVERSE scopes) endif() diff --git a/cmake/modules/snippets.cmake b/cmake/modules/snippets.cmake index c3929c86b430..550d236a2f4a 100644 --- a/cmake/modules/snippets.cmake +++ b/cmake/modules/snippets.cmake @@ -93,10 +93,6 @@ function(zephyr_process_snippets) endif() include(${snippets_generated}) - # Propagate include()d build system settings to the caller. - set(DTC_OVERLAY_FILE ${DTC_OVERLAY_FILE} PARENT_SCOPE) - set(OVERLAY_CONFIG ${OVERLAY_CONFIG} PARENT_SCOPE) - # Create the 'snippets' target. Each snippet is printed in a # separate command because build system files are not fond of # newlines. diff --git a/scripts/snippets.py b/scripts/snippets.py index 74e7ebbbfcea..a79f12584ebe 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -133,6 +133,9 @@ def print_cmake(self): # The paths to all the snippet.yml files. One snippet # can have multiple snippet.yml files. set(SNIPPET_PATHS {snippet_path_list}) + +# Create variable scope for snippets build variables +zephyr_create_scope(snippets) ''') for snippet_name in snippet_names: @@ -168,7 +171,7 @@ def print_appends(self, appends: Appends, indent: int): space = ' ' * indent for name, values in appends.items(): for value in values: - self.print(f'{space}list(APPEND {name} {value})') + self.print(f'{space}zephyr_set({name} {value} SCOPE snippets APPEND)') def print(self, *args, **kwargs): kwargs['file'] = self.out_file From a0af43dc4747107348884d7947cab2c413d671f4 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 23 May 2023 10:36:13 +0200 Subject: [PATCH 154/528] [nrf fromtree] tests: drivers: build_all: regulator: add test Add a new _test_ that is used to build all regulator drivers. SoC regulators, such as Raspberry Pi Pico core supply are excluded as they are typically built as part of the platform. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 52aec02e96b598fc0879cd3fa7ccec4a939cb386) --- MAINTAINERS.yml | 1 + .../build_all/regulator/CMakeLists.txt | 8 ++++ tests/drivers/build_all/regulator/app.overlay | 32 +++++++++++++ tests/drivers/build_all/regulator/i2c.dtsi | 48 +++++++++++++++++++ tests/drivers/build_all/regulator/misc.dtsi | 16 +++++++ tests/drivers/build_all/regulator/prj.conf | 1 + tests/drivers/build_all/regulator/src/main.c | 9 ++++ .../drivers/build_all/regulator/testcase.yaml | 10 ++++ 8 files changed, 125 insertions(+) create mode 100644 tests/drivers/build_all/regulator/CMakeLists.txt create mode 100644 tests/drivers/build_all/regulator/app.overlay create mode 100644 tests/drivers/build_all/regulator/i2c.dtsi create mode 100644 tests/drivers/build_all/regulator/misc.dtsi create mode 100644 tests/drivers/build_all/regulator/prj.conf create mode 100644 tests/drivers/build_all/regulator/src/main.c create mode 100644 tests/drivers/build_all/regulator/testcase.yaml diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index a09a689391cd..ed15c0944900 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1109,6 +1109,7 @@ Release Notes: - include/zephyr/drivers/regulator.h - include/zephyr/dt-bindings/regulator/ - tests/drivers/regulator/ + - tests/drivers/build_all/regulator/ - doc/hardware/peripherals/regulators.rst labels: - "area: Regulators" diff --git a/tests/drivers/build_all/regulator/CMakeLists.txt b/tests/drivers/build_all/regulator/CMakeLists.txt new file mode 100644 index 000000000000..534287220b59 --- /dev/null +++ b/tests/drivers/build_all/regulator/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(build_all) + +target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/build_all/regulator/app.overlay b/tests/drivers/build_all/regulator/app.overlay new file mode 100644 index 000000000000..b6871b7bfd5d --- /dev/null +++ b/tests/drivers/build_all/regulator/app.overlay @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + test { + #address-cells = <1>; + #size-cells = <1>; + + test_i2c: i2c@11112222 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "vnd,i2c"; + reg = <0x11112222 0x1000>; + status = "okay"; + clock-frequency = <100000>; + + #include "i2c.dtsi" + }; + + test_gpio: gpio@deadbeef { + compatible = "vnd,gpio"; + gpio-controller; + reg = <0xdeadbeef 0x1000>; + #gpio-cells = <0x2>; + status = "okay"; + }; + + #include "misc.dtsi" + }; +}; diff --git a/tests/drivers/build_all/regulator/i2c.dtsi b/tests/drivers/build_all/regulator/i2c.dtsi new file mode 100644 index 000000000000..2597ab4781f9 --- /dev/null +++ b/tests/drivers/build_all/regulator/i2c.dtsi @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +/**************************************** + * PLEASE KEEP REG ADDRESSES SEQUENTIAL * + ***************************************/ + +pca9420@0 { + compatible = "nxp,pca9420"; + reg = <0x0>; + + BUCK1 {}; + BUCK2 {}; + LDO1 {}; + LDO2 {}; +}; + +npm6001@1 { + compatible = "nordic,npm6001"; + reg = <0x1>; + + regulators { + compatible = "nordic,npm6001-regulator"; + + BUCK0 {}; + BUCK1 {}; + BUCK2 {}; + BUCK3 {}; + LDO0 {}; + LDO1 {}; + }; +}; + +npm1300@2 { + compatible = "nordic,npm1300"; + reg = <0x2>; + + regulators { + compatible = "nordic,npm1300-regulator"; + + BUCK1 {}; + BUCK2 {}; + LDO1 {}; + LDO2 {}; + }; +}; diff --git a/tests/drivers/build_all/regulator/misc.dtsi b/tests/drivers/build_all/regulator/misc.dtsi new file mode 100644 index 000000000000..dcfa2c285d95 --- /dev/null +++ b/tests/drivers/build_all/regulator/misc.dtsi @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +regulator-fixed { + compatible = "regulator-fixed"; + regulator-name = "test"; + enable-gpios = <&test_gpio 0 GPIO_ACTIVE_HIGH>; +}; + +npm1100 { + compatible = "nordic,npm1100"; + + BUCK {}; +}; diff --git a/tests/drivers/build_all/regulator/prj.conf b/tests/drivers/build_all/regulator/prj.conf new file mode 100644 index 000000000000..5b7c35c8f7bc --- /dev/null +++ b/tests/drivers/build_all/regulator/prj.conf @@ -0,0 +1 @@ +CONFIG_REGULATOR=y diff --git a/tests/drivers/build_all/regulator/src/main.c b/tests/drivers/build_all/regulator/src/main.c new file mode 100644 index 000000000000..62180b5fc3e2 --- /dev/null +++ b/tests/drivers/build_all/regulator/src/main.c @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +int main(void) +{ + return 0; +} diff --git a/tests/drivers/build_all/regulator/testcase.yaml b/tests/drivers/build_all/regulator/testcase.yaml new file mode 100644 index 000000000000..9b9c25511c4e --- /dev/null +++ b/tests/drivers/build_all/regulator/testcase.yaml @@ -0,0 +1,10 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +tests: + drivers.regulator.build: + tags: + - drivers + - regulator + build_only: true + platform_allow: native_posix From 5eb4ec7a46f7636300f58f59008003fe63f67bc1 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 22 May 2023 19:07:23 +0200 Subject: [PATCH 155/528] [nrf fromtree] drivers: regulator: adp5360: initial version Add a new regulator driver for Analog Devices ADP5360. While it is a MFD device, only support for BUCK/BUCKBOOST regulators is added in this patch. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit e05df8faf1e4c474014261d849ba41830416b61b) --- drivers/regulator/CMakeLists.txt | 1 + drivers/regulator/Kconfig | 1 + drivers/regulator/Kconfig.adp5360 | 28 ++ drivers/regulator/regulator_adp5360.c | 308 ++++++++++++++++++ dts/bindings/mfd/adi,adp5360.yaml | 12 + .../regulator/adi,adp5360-regulator.yaml | 85 +++++ .../zephyr/dt-bindings/regulator/adp5360.h | 28 ++ tests/drivers/build_all/regulator/i2c.dtsi | 12 + 8 files changed, 475 insertions(+) create mode 100644 drivers/regulator/Kconfig.adp5360 create mode 100644 drivers/regulator/regulator_adp5360.c create mode 100644 dts/bindings/mfd/adi,adp5360.yaml create mode 100644 dts/bindings/regulator/adi,adp5360-regulator.yaml create mode 100644 include/zephyr/dt-bindings/regulator/adp5360.h diff --git a/drivers/regulator/CMakeLists.txt b/drivers/regulator/CMakeLists.txt index 8368d9f37acc..1f5f9f8b3454 100644 --- a/drivers/regulator/CMakeLists.txt +++ b/drivers/regulator/CMakeLists.txt @@ -4,6 +4,7 @@ zephyr_library() zephyr_library_sources(regulator_common.c) +zephyr_library_sources_ifdef(CONFIG_REGULATOR_ADP5360 regulator_adp5360.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_FAKE regulator_fake.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_FIXED regulator_fixed.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM1100 regulator_npm1100.c) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 25b1c711d62c..e8deab647bf1 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -20,6 +20,7 @@ module = REGULATOR module-str = regulator source "subsys/logging/Kconfig.template.log_config" +source "drivers/regulator/Kconfig.adp5360" source "drivers/regulator/Kconfig.fake" source "drivers/regulator/Kconfig.fixed" source "drivers/regulator/Kconfig.npm1100" diff --git a/drivers/regulator/Kconfig.adp5360 b/drivers/regulator/Kconfig.adp5360 new file mode 100644 index 000000000000..30f4d566254b --- /dev/null +++ b/drivers/regulator/Kconfig.adp5360 @@ -0,0 +1,28 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX -License-Identifier: Apache-2.0 + +config REGULATOR_ADP5360 + bool "ADP5360 PMIC regulator driver" + default y + depends on DT_HAS_ADI_ADP5360_REGULATOR_ENABLED + select I2C + help + Enable the Analog Devices ADP5360 PMIC regulator driver + +if REGULATOR_ADP5360 + +config REGULATOR_ADP5360_COMMON_INIT_PRIORITY + int "ADP5360 regulator driver init priority (common part)" + default 75 + help + Init priority for the Analog Devices ADP5360 regulator driver (common + part). It must be greater than I2C init priority. + +config REGULATOR_ADP5360_INIT_PRIORITY + int "ADP5360 regulator driver init priority" + default 76 + help + Init priority for the Analog Devices ADP5360 regulator driver. It must + be greater than REGULATOR_ADP5360_COMMON_INIT_PRIORITY. + +endif diff --git a/drivers/regulator/regulator_adp5360.c b/drivers/regulator/regulator_adp5360.c new file mode 100644 index 000000000000..c417b6e59858 --- /dev/null +++ b/drivers/regulator/regulator_adp5360.c @@ -0,0 +1,308 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT adi_adp5360_regulator + +#include + +#include +#include +#include +#include +#include + +/* ADP5360 regulator related registers */ +#define ADP5360_BUCK_CFG 0x29U +#define ADP5360_BUCK_OUTPUT 0x2AU +#define ADP5360_BUCKBST_CFG 0x2BU +#define ADP5360_BUCKBST_OUTPUT 0x2CU + +/* Buck/boost configure register. */ +#define ADP5360_BUCK_CFG_SS_MSK GENMASK(7, 6) +#define ADP5360_BUCK_CFG_SS_POS 6U +#define ADP5360_BUCK_CFG_BST_ILIM_MSK GENMASK(5, 3) +#define ADP5360_BUCK_CFG_BST_ILIM_POS 3U +#define ADP5360_BUCK_CFG_BUCK_ILIM_MSK GENMASK(5, 3) +#define ADP5360_BUCK_CFG_BUCK_ILIM_POS 3U +#define ADP5360_BUCK_CFG_BUCK_MODE_MSK BIT(3) +#define ADP5360_BUCK_CFG_BUCK_MODE_POS 3U +#define ADP5360_BUCK_CFG_STP_MSK BIT(2) +#define ADP5360_BUCK_CFG_DISCHG_MSK BIT(1) +#define ADP5360_BUCK_CFG_EN_MSK BIT(0) + +/* Buck/boost output voltage setting register. */ +#define ADP5360_BUCK_OUTPUT_VOUT_MSK GENMASK(5, 0) +#define ADP5360_BUCK_OUTPUT_VOUT_POS 0U +#define ADP5360_BUCK_OUTPUT_DLY_MSK GENMASK(7, 6) +#define ADP5360_BUCK_OUTPUT_DLY_POS 6U + +struct regulator_adp5360_desc { + uint8_t cfg_reg; + uint8_t out_reg; + bool has_modes; + const struct linear_range *ranges; + uint8_t nranges; +}; + +static const struct linear_range buck_ranges[] = { + LINEAR_RANGE_INIT(600000, 50000U, 0x0U, 0x3FU), +}; + +static const struct regulator_adp5360_desc buck_desc = { + .cfg_reg = ADP5360_BUCK_CFG, + .out_reg = ADP5360_BUCK_OUTPUT, + .has_modes = true, + .ranges = buck_ranges, + .nranges = ARRAY_SIZE(buck_ranges), +}; + +static const struct linear_range buckboost_ranges[] = { + LINEAR_RANGE_INIT(1800000, 100000U, 0x0U, 0x0BU), + LINEAR_RANGE_INIT(2950000, 50000U, 0xCU, 0x3FU), +}; + +static const struct regulator_adp5360_desc buckboost_desc = { + .cfg_reg = ADP5360_BUCKBST_CFG, + .out_reg = ADP5360_BUCKBST_OUTPUT, + .has_modes = false, + .ranges = buckboost_ranges, + .nranges = ARRAY_SIZE(buckboost_ranges), +}; + +struct regulator_adp5360_config { + struct regulator_common_config common; + struct i2c_dt_spec i2c; + const struct regulator_adp5360_desc *desc; + int8_t dly_idx; + int8_t ss_idx; + int8_t ilim_idx; + bool stp_en; + bool dis_en; +}; + +struct regulator_adp5360_data { + struct regulator_common_data data; +}; + +static unsigned int regulator_adp5360_count_voltages(const struct device *dev) +{ + const struct regulator_adp5360_config *config = dev->config; + + return linear_range_group_values_count(config->desc->ranges, config->desc->nranges); +} + +static int regulator_adp5360_list_voltage(const struct device *dev, unsigned int idx, + int32_t *volt_uv) +{ + const struct regulator_adp5360_config *config = dev->config; + + return linear_range_group_get_value(config->desc->ranges, config->desc->nranges, idx, + volt_uv); +} + +static int regulator_adp5360_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv) +{ + const struct regulator_adp5360_config *config = dev->config; + uint16_t idx; + int ret; + + ret = linear_range_group_get_win_index(config->desc->ranges, config->desc->nranges, min_uv, + max_uv, &idx); + if (ret == -EINVAL) { + return ret; + } + + return i2c_reg_update_byte_dt(&config->i2c, config->desc->out_reg, + ADP5360_BUCK_OUTPUT_VOUT_MSK, + (uint8_t)idx << ADP5360_BUCK_OUTPUT_VOUT_POS); +} + +static int regulator_adp5360_get_voltage(const struct device *dev, int32_t *volt_uv) +{ + const struct regulator_adp5360_config *config = dev->config; + int ret; + uint8_t raw_reg; + + ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->out_reg, &raw_reg); + if (ret < 0) { + return ret; + } + + raw_reg = (raw_reg & ADP5360_BUCK_OUTPUT_VOUT_MSK) >> ADP5360_BUCK_OUTPUT_VOUT_POS; + + return linear_range_group_get_value(config->desc->ranges, config->desc->nranges, raw_reg, + volt_uv); +} + +static int regulator_adp5360_set_mode(const struct device *dev, regulator_mode_t mode) +{ + const struct regulator_adp5360_config *config = dev->config; + + if (!config->desc->has_modes || (mode > ADP5360_MODE_PWM)) { + return -ENOTSUP; + } + + return i2c_reg_update_byte_dt(&config->i2c, config->desc->cfg_reg, + ADP5360_BUCK_CFG_BUCK_MODE_MSK, + mode << ADP5360_BUCK_CFG_BUCK_MODE_POS); +} + +static int regulator_adp5360_get_mode(const struct device *dev, regulator_mode_t *mode) +{ + const struct regulator_adp5360_config *config = dev->config; + uint8_t val; + int ret; + + if (!config->desc->has_modes) { + return -ENOTSUP; + } + + ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->cfg_reg, &val); + if (ret < 0) { + return ret; + } + + *mode = (val & ADP5360_BUCK_CFG_BUCK_MODE_MSK) >> ADP5360_BUCK_CFG_BUCK_MODE_POS; + + return 0; +} + +static int regulator_adp5360_enable(const struct device *dev) +{ + const struct regulator_adp5360_config *config = dev->config; + + return i2c_reg_update_byte_dt(&config->i2c, config->desc->cfg_reg, ADP5360_BUCK_CFG_EN_MSK, + 1U); +} + +static int regulator_adp5360_disable(const struct device *dev) +{ + const struct regulator_adp5360_config *config = dev->config; + + return i2c_reg_update_byte_dt(&config->i2c, config->desc->cfg_reg, ADP5360_BUCK_CFG_EN_MSK, + 0U); +} + +static int regulator_adp5360_init(const struct device *dev) +{ + const struct regulator_adp5360_config *config = dev->config; + int ret; + uint8_t val, nval, msk; + + regulator_common_data_init(dev); + + if (!i2c_is_ready_dt(&config->i2c)) { + return -ENODEV; + } + + /* apply optional delay */ + msk = 0U; + nval = 0U; + + ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->out_reg, &val); + if (ret < 0) { + return ret; + } + + if (config->dly_idx >= 0) { + msk |= ADP5360_BUCK_OUTPUT_DLY_MSK; + nval |= ((uint8_t)config->dly_idx << ADP5360_BUCK_OUTPUT_DLY_POS) & + ADP5360_BUCK_OUTPUT_DLY_MSK; + } + + if (msk != 0U) { + ret = i2c_reg_write_byte_dt(&config->i2c, config->desc->out_reg, + (val & ~msk) | nval); + if (ret < 0) { + return ret; + } + } + + /* apply optional initial configuration */ + msk = 0U; + nval = 0U; + + ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->cfg_reg, &val); + if (ret < 0) { + return ret; + } + + if (config->ss_idx >= 0) { + msk |= ADP5360_BUCK_CFG_SS_MSK; + nval |= ((uint8_t)config->ss_idx << ADP5360_BUCK_CFG_SS_POS) & + ADP5360_BUCK_CFG_SS_MSK; + } + + if (config->ilim_idx >= 0) { + if (config->desc->has_modes) { + msk |= ADP5360_BUCK_CFG_BUCK_ILIM_MSK; + nval |= ((uint8_t)config->ilim_idx << ADP5360_BUCK_CFG_BUCK_ILIM_POS) & + ADP5360_BUCK_CFG_BUCK_ILIM_MSK; + } else { + msk |= ADP5360_BUCK_CFG_BST_ILIM_MSK; + nval |= ((uint8_t)config->ilim_idx << ADP5360_BUCK_CFG_BST_ILIM_POS) & + ADP5360_BUCK_CFG_BST_ILIM_MSK; + } + } + + if (config->stp_en) { + msk |= ADP5360_BUCK_CFG_STP_MSK; + nval |= ADP5360_BUCK_CFG_STP_MSK; + } + + if (config->dis_en) { + msk |= ADP5360_BUCK_CFG_DISCHG_MSK; + nval |= ADP5360_BUCK_CFG_DISCHG_MSK; + } + + if (msk != 0U) { + ret = i2c_reg_write_byte_dt(&config->i2c, config->desc->cfg_reg, + (val & ~msk) | nval); + if (ret < 0) { + return ret; + } + } + + return regulator_common_init(dev, (val & ADP5360_BUCK_CFG_EN_MSK) != 0U); +} + +static const struct regulator_driver_api api = { + .enable = regulator_adp5360_enable, + .disable = regulator_adp5360_disable, + .count_voltages = regulator_adp5360_count_voltages, + .list_voltage = regulator_adp5360_list_voltage, + .set_voltage = regulator_adp5360_set_voltage, + .get_voltage = regulator_adp5360_get_voltage, + .set_mode = regulator_adp5360_set_mode, + .get_mode = regulator_adp5360_get_mode, +}; + +#define REGULATOR_ADP5360_DEFINE(node_id, id, name) \ + static struct regulator_adp5360_data data_##id; \ + \ + static const struct regulator_adp5360_config config_##id = { \ + .common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id), \ + .i2c = I2C_DT_SPEC_GET(DT_GPARENT(node_id)), \ + .desc = &name##_desc, \ + .dly_idx = DT_ENUM_IDX_OR(node_id, adi_switch_delay_us, -1), \ + .ss_idx = DT_ENUM_IDX_OR(node_id, adi_soft_start_ms, -1), \ + .ilim_idx = DT_ENUM_IDX_OR(node_id, adi_ilim_milliamp, -1), \ + .stp_en = DT_PROP(node_id, adi_enable_stop_pulse), \ + .dis_en = DT_PROP(node_id, adi_enable_output_discharge), \ + }; \ + \ + DEVICE_DT_DEFINE(node_id, regulator_adp5360_init, NULL, &data_##id, &config_##id, \ + POST_KERNEL, CONFIG_REGULATOR_ADP5360_INIT_PRIORITY, &api); + +#define REGULATOR_ADP5360_DEFINE_COND(inst, child) \ + COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(inst, child)), \ + (REGULATOR_ADP5360_DEFINE(DT_INST_CHILD(inst, child), child##inst, child)), \ + ()) + +#define REGULATOR_ADP5360_DEFINE_ALL(inst) \ + REGULATOR_ADP5360_DEFINE_COND(inst, buck) \ + REGULATOR_ADP5360_DEFINE_COND(inst, buckboost) + +DT_INST_FOREACH_STATUS_OKAY(REGULATOR_ADP5360_DEFINE_ALL) diff --git a/dts/bindings/mfd/adi,adp5360.yaml b/dts/bindings/mfd/adi,adp5360.yaml new file mode 100644 index 000000000000..982acf66949f --- /dev/null +++ b/dts/bindings/mfd/adi,adp5360.yaml @@ -0,0 +1,12 @@ +# Copyright (c) 2023, Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +description: Analog Devices ADP5360 + +compatible: "adi,adp5360" + +include: i2c-device.yaml + +properties: + reg: + required: true diff --git a/dts/bindings/regulator/adi,adp5360-regulator.yaml b/dts/bindings/regulator/adi,adp5360-regulator.yaml new file mode 100644 index 000000000000..d683bd694ef7 --- /dev/null +++ b/dts/bindings/regulator/adi,adp5360-regulator.yaml @@ -0,0 +1,85 @@ +# Copyright (c), 2023 Nordic Semiconductor ASA +# SPDX -License-Identifier: Apache-2.0 + +description: | + Analog Devices ADP3560 PMIC + + The PMIC has one buck converter and one buck-boost converter. Both need to be + defined as children nodes, strictly following the BUCK and BUCKBOOST node + names. For example: + + pmic@46 { + compatible = "adi,adp5360"; + reg = <0x46>; + ... + regulators { + compatible = "adi,adp5360-regulator"; + + BUCK { + /* all properties for BUCK */ + }; + BUCKBOOST { + /* all properties for BUCKBOOST */ + }; + }; + }; + +compatible: "adi,adp5360-regulator" + +include: base.yaml + +child-binding: + include: + - name: regulator.yaml + property-allowlist: + - regulator-always-on + - regulator-boot-on + - regulator-init-microvolt + - regulator-min-microvolt + - regulator-max-microvolt + - regulator-allowed-modes + - regulator-initial-mode + + properties: + adi,switch-delay-us: + type: int + enum: + - 0 + - 5 + - 10 + - 20 + description: Switch delay time in hysteresis. + + adi,soft-start-ms: + type: int + enum: + - 1 + - 8 + - 64 + - 512 + description: Soft start time in milliseconds + + adi,ilim-milliamp: + type: int + enum: + - 100 + - 200 + - 300 + - 400 + - 500 + - 600 + - 700 + - 800 + description: | + Peak current limit, in milliamperes. Values above 400mA are only + applicable to buck boost. + + adi,enable-stop-pulse: + type: boolean + description: | + With this option selected and the buck/boost enabled, the buck/boost + regulator can be stopped using the STP pin. + + adi,enable-output-discharge: + type: boolean + description: Enable output discharge functionality diff --git a/include/zephyr/dt-bindings/regulator/adp5360.h b/include/zephyr/dt-bindings/regulator/adp5360.h new file mode 100644 index 000000000000..d3aecacaa72f --- /dev/null +++ b/include/zephyr/dt-bindings/regulator/adp5360.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_ADP5360_H_ +#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_ADP5360_H_ + +/** + * @defgroup regulator_adp5360 ADP5360 Devicetree helpers. + * @ingroup regulator_interface + * @{ + */ + +/** + * @name ADP5360 Regulator modes + * @{ + */ +/** Hysteresis mode */ +#define ADP5360_MODE_HYS 0 +/** PWM mode */ +#define ADP5360_MODE_PWM 1 +/** @} */ + +/** @} */ + +#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_ADP5360_H_*/ diff --git a/tests/drivers/build_all/regulator/i2c.dtsi b/tests/drivers/build_all/regulator/i2c.dtsi index 2597ab4781f9..36818b03e8fd 100644 --- a/tests/drivers/build_all/regulator/i2c.dtsi +++ b/tests/drivers/build_all/regulator/i2c.dtsi @@ -46,3 +46,15 @@ npm1300@2 { LDO2 {}; }; }; + +apd356x@3 { + compatible = "adi,adp5360"; + reg = <0x3>; + + regulators { + compatible = "adi,adp5360-regulator"; + + BUCK {}; + BUCKBOOST {}; + }; +}; From ecdb1b279f07bd2eba03d3a30630a793e28d9342 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 24 May 2023 14:23:13 +0200 Subject: [PATCH 156/528] [nrf fromtree] drivers: regulator: adp5360: remove unused init priority The common init priority is a leftover from a previous implementation. Remove it as it's not used. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit d99afcd0da37eb1a8d176f3f091196bb6f9513e9) --- drivers/regulator/Kconfig.adp5360 | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/regulator/Kconfig.adp5360 b/drivers/regulator/Kconfig.adp5360 index 30f4d566254b..0785ba54abf0 100644 --- a/drivers/regulator/Kconfig.adp5360 +++ b/drivers/regulator/Kconfig.adp5360 @@ -9,20 +9,9 @@ config REGULATOR_ADP5360 help Enable the Analog Devices ADP5360 PMIC regulator driver -if REGULATOR_ADP5360 - -config REGULATOR_ADP5360_COMMON_INIT_PRIORITY - int "ADP5360 regulator driver init priority (common part)" - default 75 - help - Init priority for the Analog Devices ADP5360 regulator driver (common - part). It must be greater than I2C init priority. - config REGULATOR_ADP5360_INIT_PRIORITY int "ADP5360 regulator driver init priority" default 76 + depends on REGULATOR_ADP5360 help - Init priority for the Analog Devices ADP5360 regulator driver. It must - be greater than REGULATOR_ADP5360_COMMON_INIT_PRIORITY. - -endif + Init priority for the Analog Devices ADP5360 regulator driver. From 4618cfe53df3154a6ee4101c2e68e98531fdda98 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 1 Jun 2023 15:58:56 +0200 Subject: [PATCH 157/528] [nrf noup] tests: drivers: build_all: regulator: use old schema New Twister schema is not supported yet in sdk-zephyr, drop this patch once Twister is updated. Signed-off-by: Gerard Marull-Paretas --- tests/drivers/build_all/regulator/testcase.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/drivers/build_all/regulator/testcase.yaml b/tests/drivers/build_all/regulator/testcase.yaml index 9b9c25511c4e..c5dbda1913f3 100644 --- a/tests/drivers/build_all/regulator/testcase.yaml +++ b/tests/drivers/build_all/regulator/testcase.yaml @@ -3,8 +3,6 @@ tests: drivers.regulator.build: - tags: - - drivers - - regulator + tags: drivers regulator build_only: true platform_allow: native_posix From 6c3100f4fd366a3c280f614bd2154b22be023662 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 27 Apr 2023 16:43:30 +0200 Subject: [PATCH 158/528] [nrf fromtree] manifest: nrf hw models: Use latest w flash Update to the latest NRF HW models which include models of the NVMC and UICR peripherals, as well as some other (very) minor fixes. Signed-off-by: Alberto Escolar Piedras (cherry picked from commit e7d658c91d19790f03d944b5f6a4581c1ea50522) --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b4c5274e885a..b40fa8488d0a 100644 --- a/west.yml +++ b/west.yml @@ -197,7 +197,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: bad9877e997b2c2a78dd74eec8978181f4655d14 + revision: c8d2ecd25d6976d2d77eccf66878420fdb8ef5a1 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: aedcc262f93bbb1b0c2f58026911575729b7465c From 9b2ecc048c1a4194ff6bb1e5ae883f979496383e Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 1 Jun 2023 13:54:26 +0200 Subject: [PATCH 159/528] [nrf fromlist] manifest: Update nRF HW models to latest The nRF HW models have been updated to include the following fixes and improvements. * PPI: add support for nrf_ppi_group_enable * BLECrypt: Widen search for crypto library * Makefile: Switch to gnu11 from c11 due to HAL * NVMC: Minor fixes in command line options descriptions Which enable more 15.4 functionality with the nrf driver Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/58745 Signed-off-by: Alberto Escolar Piedras --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b40fa8488d0a..141368580cfd 100644 --- a/west.yml +++ b/west.yml @@ -197,7 +197,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: c8d2ecd25d6976d2d77eccf66878420fdb8ef5a1 + revision: 37c571ef7c4a86dad852566fc43eb36f42534e9f path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: aedcc262f93bbb1b0c2f58026911575729b7465c From 70d3f6dc1d46eada29478ea29374923658991759 Mon Sep 17 00:00:00 2001 From: Piotr Pryga Date: Fri, 19 May 2023 19:12:13 +0200 Subject: [PATCH 160/528] [nrf fromtree] Bluetooth: controller: Move DF feat selection to LL_SW_SPLIT KConfig The BT_CTLR_DF_SUPPORTED KConfig was a wrapper for DF related features set that are supported by Zephyr's BLE Controller. At the same time the KConfig is used by Host in compound build to enable BT_DF. That makes the whole thing a bit coupled with Zephyr's controller. External implementations of controller must provide same feature set as Zephyr's Controller or there will be an error during build. The PR moves the Zephyr's Controller DF supported features set to Kconfig.ll_sw_split, where it is included only when BT_LL_SW_SPLIT is selected. BT_CTLR_DF_SUPPORTED is now a top DF_SUPPORTED KConfig option that enables possibility to select actual DF features. That allows to select individual set of DF features by any controller implementation and makes possible to enable BT_DF and build selected DF Host features. Signed-off-by: Piotr Pryga (cherry picked from commit 622299b1c5d34c9681b77099a90c5019250ad52b) Signed-off-by: Piotr Pryga --- subsys/bluetooth/controller/Kconfig.df | 17 ++++++++--------- subsys/bluetooth/controller/Kconfig.ll_sw_split | 10 ++++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.df b/subsys/bluetooth/controller/Kconfig.df index e3f460c7f51a..981d1b8f1fc3 100644 --- a/subsys/bluetooth/controller/Kconfig.df +++ b/subsys/bluetooth/controller/Kconfig.df @@ -3,17 +3,14 @@ # Copyright (c) 2020 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -# BT_CTLR_DF_SUPPORT is a wrapper for all DF features. -# If only certain DF features are supported, those should be selected -# individually. +# BT_CTLR_DF_SUPPORT is a wrapper for all DF features. It is referenced by Host +# to enable its DF related Kconfigs when build together with the Controller. +# It is required to enable it when Controller supports any DF related feature +# but particular features are selected individually. config BT_CTLR_DF_SUPPORT bool - depends on BT_LL_SW_SPLIT && !BT_CTLR_TIFS_HW - select BT_CTLR_DF_CTE_TX_SUPPORT - select BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT - select BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT - select BT_CTLR_DF_CTE_RX_SUPPORT - select BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT + +if BT_CTLR_DF_SUPPORT config BT_CTLR_DF_CTE_TX_SUPPORT bool @@ -33,6 +30,8 @@ config BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT config BT_CTLR_CTEINLINE_SUPPORT bool +endif # BT_CTLR_DF_SUPPORT + menuconfig BT_CTLR_DF bool "LE Direction Finding" depends on BT_CTLR_DF_CTE_TX_SUPPORT || BT_CTLR_DF_CTE_RX_SUPPORT diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index fa4483d7a305..78ef97a65c6c 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -76,6 +76,16 @@ config BT_LLL_VENDOR_OPENISA help Use OpenISA Lower Link Layer implementation. +# BT_CTLR_DF_SUPPORT is a wrapper for all DF features. Here we select features that are supported by +# Zephyr's BLE Controller. +config BT_CTLR_DF_SUPPORT + depends on BT_LL_SW_SPLIT && !BT_CTLR_TIFS_HW + select BT_CTLR_DF_CTE_TX_SUPPORT + select BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT + select BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT + select BT_CTLR_DF_CTE_RX_SUPPORT + select BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT + config BT_CTLR_XTAL_ADVANCED_SUPPORT bool From 6fb229ca3c88b3c7c1ec9b0a2995703032eae4a8 Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Mon, 29 May 2023 19:06:30 +0200 Subject: [PATCH 161/528] [nrf fromtree] net: openthread: Fix `OPENTHREAD_FTD` dependency. Thic commit fixes `OPENTHREAD_FTD` dependency to `OPENTHREAD_UPTIME`. Signed-off-by: Przemyslaw Bida (cherry picked from commit b020c5d88948df0a61421e52e5d309245fb26996) --- modules/openthread/Kconfig.features | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 4766032cd79a..823b77a77a7b 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -286,3 +286,4 @@ config OPENTHREAD_UDP_FORWARD config OPENTHREAD_UPTIME bool "Openthread uptime counter" + default y if OPENTHREAD_FTD From c6f38ecdee5e42f4812c2f33053638a1f8cb2cb8 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Fri, 19 May 2023 07:00:58 +0200 Subject: [PATCH 162/528] [nrf fromtree] boards: nrf5340: use nrf_reset_network_force_off The function nrf_reset_network_force_off contains workaround for errata 161 for nRF5340 SoC. This function should be used instead of manual writing to NRF_RESET->NETWORK.FORCEOFF register. Signed-off-by: Andrzej Kuros (cherry picked from commit 679fa28574812431f79c87308a924db97dc2877e) --- boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c | 3 ++- .../nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c | 3 ++- boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c | 3 ++- boards/arm/thingy53_nrf5340/board.c | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c index 7cf2b399985f..49c0e5a1c730 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c @@ -10,6 +10,7 @@ #include #include +#include LOG_MODULE_REGISTER(bl5340_dvk_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); @@ -49,7 +50,7 @@ static int remoteproc_mgr_boot(void) */ /* Release the Network MCU, 'Release force off signal' */ - NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; + nrf_reset_network_force_off(NRF_RESET, false); LOG_DBG("Network MCU released."); #endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c index 5f30e0d9a66f..4368ca303fc1 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c @@ -9,6 +9,7 @@ #include #include +#include #include @@ -71,7 +72,7 @@ static int remoteproc_mgr_boot(void) */ /* Release the Network MCU, 'Release force off signal' */ - NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; + nrf_reset_network_force_off(NRF_RESET, false); LOG_DBG("Network MCU released."); #endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c index 68700225f4ed..dadba8c0f54a 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c @@ -9,6 +9,7 @@ #include #include +#include LOG_MODULE_REGISTER(nrf5340dk_nrf5340_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); @@ -48,7 +49,7 @@ static int remoteproc_mgr_boot(void) */ /* Release the Network MCU, 'Release force off signal' */ - NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; + nrf_reset_network_force_off(NRF_RESET, false); LOG_DBG("Network MCU released."); #endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ diff --git a/boards/arm/thingy53_nrf5340/board.c b/boards/arm/thingy53_nrf5340/board.c index 509ec04bdab5..88d7e365d824 100644 --- a/boards/arm/thingy53_nrf5340/board.c +++ b/boards/arm/thingy53_nrf5340/board.c @@ -8,6 +8,7 @@ #include #include #include +#include LOG_MODULE_REGISTER(thingy53_board_init); @@ -51,7 +52,7 @@ static void enable_cpunet(void) */ /* Release the Network MCU, 'Release force off signal' */ - NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; + nrf_reset_network_force_off(NRF_RESET, false); LOG_DBG("Network MCU released."); #endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ From e726728e24b87740162890f39a13030ed08bacc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarno=20L=C3=A4ms=C3=A4?= Date: Thu, 23 Feb 2023 12:26:33 +0200 Subject: [PATCH 163/528] [nrf fromtree] net: lib: coap: Add an asynchronous coap client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The coap client takes requests and provides responses asynchronously to callback given in a request. Currently supports only 1 request at a time. Signed-off-by: Jarno Lämsä (cherry picked from commit 05e0b31fa875aaf4dd397267054eee1d572d5155) --- include/zephyr/net/coap_client.h | 139 ++++++ subsys/net/lib/coap/CMakeLists.txt | 4 + subsys/net/lib/coap/Kconfig | 41 ++ subsys/net/lib/coap/coap_client.c | 742 +++++++++++++++++++++++++++++ 4 files changed, 926 insertions(+) create mode 100644 include/zephyr/net/coap_client.h create mode 100644 subsys/net/lib/coap/coap_client.c diff --git a/include/zephyr/net/coap_client.h b/include/zephyr/net/coap_client.h new file mode 100644 index 000000000000..dc5d008c1b74 --- /dev/null +++ b/include/zephyr/net/coap_client.h @@ -0,0 +1,139 @@ +/** @file + * @brief CoAP client API + * + * An API for applications to do CoAP requests + */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_ +#define ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_ + +/** + * @brief CoAP client API + * @defgroup coap_client CoAP client API + * @ingroup networking + * @{ + */ + +#include + + +#define MAX_COAP_MSG_LEN (CONFIG_COAP_CLIENT_MESSAGE_HEADER_SIZE + \ + CONFIG_COAP_CLIENT_MESSAGE_SIZE) + +/** + * @typedef coap_client_response_cb_t + * @brief Callback for CoAP request. + * + * This callback is called for responses to CoAP client requests. + * It is used to indicate errors, response codes from server or to deliver payload. + * Blockwise transfers cause this callback to be called sequentially with increasing payload offset + * and only partial content in buffer pointed by payload parameter. + * + * @param result_code Result code of the response. Negative if there was a failure in send. + * @ref coap_response_code for positive. + * @param offset Payload offset from the beginning of a blockwise transfer. + * @param payload Buffer containing the payload from the response. NULL for empty payload. + * @param len Size of the payload. + * @param last_block Indicates the last block of the response. + * @param user_data User provided context. + */ +typedef void (*coap_client_response_cb_t)(int16_t result_code, + size_t offset, const uint8_t *payload, size_t len, + bool last_block, void *user_data); + +/** + * @brief Representation of a CoAP client request. + */ +struct coap_client_request { + enum coap_method method; /**< Method of the request */ + bool confirmable; /**< CoAP Confirmable/Non-confirmable message */ + const char *path; /**< Path of the requested resource */ + enum coap_content_format fmt; /**< Content format to be used */ + uint8_t *payload; /**< User allocated buffer for send request */ + size_t len; /**< Length of the payload */ + coap_client_response_cb_t cb; /**< Callback when response received */ + struct coap_client_option *options; /**< Extra options to be added to request */ + uint8_t num_options; /**< Number of extra options */ + void *user_data; /**< User provided context */ +}; + +/** + * @brief Representation of extra options for the CoAP client request + */ +struct coap_client_option { + uint16_t code; +#if defined(CONFIG_COAP_EXTENDED_OPTIONS_LEN) + uint16_t len; + uint8_t value[CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE]; +#else + uint8_t len; + uint8_t value[12]; +#endif +}; + +/** @cond INTERNAL_HIDDEN */ +struct coap_client { + int fd; + struct sockaddr address; + socklen_t socklen; + uint8_t send_buf[MAX_COAP_MSG_LEN]; + uint8_t recv_buf[MAX_COAP_MSG_LEN]; + uint8_t request_token[COAP_TOKEN_MAX_LEN]; + int request_tkl; + int offset; + int retry_count; + struct coap_block_context recv_blk_ctx; + struct coap_block_context send_blk_ctx; + struct coap_pending pending; + struct coap_client_request *coap_request; + struct coap_packet request; + k_tid_t tid; + struct k_thread thread; + struct k_sem coap_client_recv_sem; + atomic_t coap_client_recv_active; + + K_THREAD_STACK_MEMBER(coap_thread_stack, CONFIG_COAP_CLIENT_STACK_SIZE); +}; +/** @endcond */ + +/** + * @brief Initialize the CoAP client. + * + * @param[in] client Client instance. + * @param[in] info Name for the receiving thread of the client. Setting this NULL will result as + * default name of "coap_client". + * + * @return int Zero on success, otherwise a negative error code. + */ +int coap_client_init(struct coap_client *client, const char *info); + +/** + * @brief Send CoAP request + * + * Operation is handled asynchronously using a background thread. + * If the socket isn't connected to a destination address, user must provide a destination address, + * otherwise the address should be set as NULL. + * Once the callback is called with last block set as true, socket can be closed or + * used for another query. + * + * @param client Client instance. + * @param sock Open socket file descriptor. + * @param addr the destination address of the request. + * @param req CoAP request structure + * @param retries How many times to retry or -1 to use default. + * @return zero when operation started successfully or negative error code otherwise. + */ + +int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr, + struct coap_client_request *req, int retries); + +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_ */ diff --git a/subsys/net/lib/coap/CMakeLists.txt b/subsys/net/lib/coap/CMakeLists.txt index d97d0e30da3e..39ef8196fbba 100644 --- a/subsys/net/lib/coap/CMakeLists.txt +++ b/subsys/net/lib/coap/CMakeLists.txt @@ -6,3 +6,7 @@ zephyr_sources_ifdef(CONFIG_COAP coap.c coap_link_format.c ) + +zephyr_sources_ifdef(CONFIG_COAP_CLIENT + coap_client.c +) diff --git a/subsys/net/lib/coap/Kconfig b/subsys/net/lib/coap/Kconfig index 06f7ea2e7e7c..12a7c0c9b006 100644 --- a/subsys/net/lib/coap/Kconfig +++ b/subsys/net/lib/coap/Kconfig @@ -94,6 +94,47 @@ config COAP_KEEP_USER_DATA help This option enables keeping application-specific user data +config COAP_CLIENT + bool "CoAP client support [EXPERIMENTAL]" + select EXPERIMENTAL + help + This option enables the API for CoAP-client for sending CoAP requests + +if COAP_CLIENT + +config COAP_CLIENT_THREAD_PRIORITY + int "Coap client thread priority" + default NUM_PREEMPT_PRIORITIES + help + Priority of receive thread of the CoAP client. + +config COAP_CLIENT_BLOCK_SIZE + int "LWM2M CoAP block-wise transfer size" + default 256 + range 64 1024 + help + CoAP block size used by CoAP client when performing block-wise + transfers. Possible values: 64, 128, 256, 512 and 1024. + +config COAP_CLIENT_MESSAGE_SIZE + int "Message payload size" + default COAP_CLIENT_BLOCK_SIZE + help + CoAP client message payload size. Can't be smaller than COAP_CLIENT_BLOCK_SIZE. + +config COAP_CLIENT_MESSAGE_HEADER_SIZE + int "Room for CoAP header data" + default 48 + range 24 128 + help + Extra room allocated to handle CoAP header data + +config COAP_CLIENT_STACK_SIZE + int "Stack size of the CoAP client thread" + default 1024 + +endif # COAP_CLIENT + module = COAP module-dep = NET_LOG module-str = Log level for CoAP diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c new file mode 100644 index 000000000000..ce20cd3bd855 --- /dev/null +++ b/subsys/net/lib/coap/coap_client.c @@ -0,0 +1,742 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL); + +#include + +#include +#include + +#define COAP_VERSION 1 +#define COAP_PATH_ELEM_DELIM '/' +#define COAP_PATH_ELEM_QUERY '?' +#define COAP_PATH_ELEM_AMP '&' +#define COAP_SEPARATE_TIMEOUT 6000 +#define DEFAULT_RETRY_AMOUNT 5 +#define BLOCK1_OPTION_SIZE 4 +#define PAYLOAD_MARKER_SIZE 1 + +static int coap_client_schedule_poll(struct coap_client *client, int sock, + struct coap_client_request *req) +{ + client->fd = sock; + client->coap_request = req; + + k_sem_give(&client->coap_client_recv_sem); + atomic_set(&client->coap_client_recv_active, 1); + + return 0; +} + +static int send_request(int sock, const void *buf, size_t len, int flags, + const struct sockaddr *dest_addr, socklen_t addrlen) +{ + if (addrlen == 0) { + return sendto(sock, buf, len, flags, NULL, 0); + } else { + return sendto(sock, buf, len, flags, dest_addr, addrlen); + } +} + +static int receive(int sock, void *buf, size_t max_len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + if (*addrlen == 0) { + return recvfrom(sock, buf, max_len, flags, NULL, NULL); + } else { + return recvfrom(sock, buf, max_len, flags, src_addr, addrlen); + } +} + +static void reset_block_contexts(struct coap_client *client) +{ + client->recv_blk_ctx.block_size = 0; + client->recv_blk_ctx.total_size = 0; + client->recv_blk_ctx.current = 0; + + client->send_blk_ctx.block_size = 0; + client->send_blk_ctx.total_size = 0; + client->send_blk_ctx.current = 0; +} + +static int coap_client_init_path_options(struct coap_packet *pckt, const char *path) +{ + int ret = 0; + int path_start, path_end; + int path_length; + bool contains_query = false; + int i; + + path_start = 0; + path_end = 0; + path_length = strlen(path); + for (i = 0; i < path_length; i++) { + path_end = i; + if (path[i] == COAP_PATH_ELEM_DELIM) { + /* Guard for preceding delimiters */ + if (path_start < path_end) { + ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH, + path + path_start, + path_end - path_start); + if (ret < 0) { + LOG_ERR("Failed to append path to CoAP message"); + goto out; + } + } + /* Check if there is a new path after delimiter, + * if not, point to the end of string to not add + * new option after this + */ + if (path_length > i + 1) { + path_start = i + 1; + } else { + path_start = path_length; + } + } else if (path[i] == COAP_PATH_ELEM_QUERY) { + /* Guard for preceding delimiters */ + if (path_start < path_end) { + ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH, + path + path_start, + path_end - path_start); + if (ret < 0) { + LOG_ERR("Failed to append path to CoAP message"); + goto out; + } + } + /* Rest of the path is query */ + contains_query = true; + if (path_length > i + 1) { + path_start = i + 1; + } else { + path_start = path_length; + } + break; + } + } + + if (contains_query) { + for (i = path_start; i < path_length; i++) { + path_end = i; + if (path[i] == COAP_PATH_ELEM_AMP || path[i] == COAP_PATH_ELEM_QUERY) { + /* Guard for preceding delimiters */ + if (path_start < path_end) { + ret = coap_packet_append_option(pckt, COAP_OPTION_URI_QUERY, + path + path_start, + path_end - path_start); + if (ret < 0) { + LOG_ERR("Failed to append path to CoAP message"); + goto out; + } + } + /* Check if there is a new query option after delimiter, + * if not, point to the end of string to not add + * new option after this + */ + if (path_length > i + 1) { + path_start = i + 1; + } else { + path_start = path_length; + } + } + } + } + + if (path_start < path_end) { + if (contains_query) { + ret = coap_packet_append_option(pckt, COAP_OPTION_URI_QUERY, + path + path_start, + path_end - path_start + 1); + } else { + ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH, + path + path_start, + path_end - path_start + 1); + } + if (ret < 0) { + LOG_ERR("Failed to append path to CoAP message"); + goto out; + } + } + +out: + return ret; +} + +static enum coap_block_size coap_client_default_block_size(void) +{ + switch (CONFIG_COAP_CLIENT_BLOCK_SIZE) { + case 16: + return COAP_BLOCK_16; + case 32: + return COAP_BLOCK_32; + case 64: + return COAP_BLOCK_64; + case 128: + return COAP_BLOCK_128; + case 256: + return COAP_BLOCK_256; + case 512: + return COAP_BLOCK_512; + case 1024: + return COAP_BLOCK_1024; + } + + return COAP_BLOCK_256; +} + +static int coap_client_init_request(struct coap_client *client, + struct coap_client_request *req) +{ + int ret = 0; + int i; + + memset(client->send_buf, 0, sizeof(client->send_buf)); + ret = coap_packet_init(&client->request, client->send_buf, MAX_COAP_MSG_LEN, 1, + req->confirmable ? COAP_TYPE_CON : COAP_TYPE_NON_CON, + COAP_TOKEN_MAX_LEN, coap_next_token(), req->method, + coap_next_id()); + + if (ret < 0) { + LOG_ERR("Failed to init CoAP message %d", ret); + goto out; + } + + ret = coap_client_init_path_options(&client->request, req->path); + + if (ret < 0) { + LOG_ERR("Failed to parse path to options %d", ret); + goto out; + } + + ret = coap_append_option_int(&client->request, COAP_OPTION_CONTENT_FORMAT, req->fmt); + + if (ret < 0) { + LOG_ERR("Failed to append content format option"); + goto out; + } + + /* Blockwise receive ongoing, request next block. */ + if (client->recv_blk_ctx.current > 0) { + ret = coap_append_block2_option(&client->request, &client->recv_blk_ctx); + + if (ret < 0) { + LOG_ERR("Failed to append block 2 option"); + goto out; + } + } + + /* Add extra options if any */ + for (i = 0; i < req->num_options; i++) { + ret = coap_packet_append_option(&client->request, req->options[i].code, + req->options[i].value, req->options[i].len); + + if (ret < 0) { + LOG_ERR("Failed to append %d option", req->options[i].code); + goto out; + } + } + + if (req->payload) { + uint16_t payload_len; + uint16_t offset; + + /* Blockwise send ongoing, add block1 */ + if (client->send_blk_ctx.total_size > 0 || + (req->len > CONFIG_COAP_CLIENT_MESSAGE_SIZE)) { + + if (client->send_blk_ctx.total_size == 0) { + coap_block_transfer_init(&client->send_blk_ctx, + coap_client_default_block_size(), + req->len); + } + ret = coap_append_block1_option(&client->request, &client->send_blk_ctx); + + if (ret < 0) { + LOG_ERR("Failed to append block1 option"); + goto out; + } + } + + ret = coap_packet_append_payload_marker(&client->request); + + if (ret < 0) { + LOG_ERR("Failed to append payload marker to CoAP message"); + goto out; + } + + if (client->send_blk_ctx.total_size > 0) { + uint16_t block_in_bytes = + coap_block_size_to_bytes(client->send_blk_ctx.block_size); + + payload_len = client->send_blk_ctx.total_size - + client->send_blk_ctx.current; + if (payload_len > block_in_bytes) { + payload_len = block_in_bytes; + } + offset = client->send_blk_ctx.current; + } else { + payload_len = req->len; + offset = 0; + } + + ret = coap_packet_append_payload(&client->request, req->payload + offset, + payload_len); + + if (ret < 0) { + LOG_ERR("Failed to append payload to CoAP message"); + goto out; + } + + if (client->send_blk_ctx.total_size > 0) { + coap_next_block(&client->request, &client->send_blk_ctx); + } + } + client->request_tkl = coap_header_get_token(&client->request, client->request_token); +out: + return ret; +} + + +int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr, + struct coap_client_request *req, int retries) +{ + int ret; + + if (client->coap_client_recv_active) { + return -EAGAIN; + } + + if (sock < 0 || req == NULL || req->path == NULL) { + return -EINVAL; + } + + if (addr != NULL) { + memcpy(&client->address, addr, sizeof(*addr)); + client->socklen = sizeof(client->address); + } else { + memset(&client->address, 0, sizeof(client->address)); + client->socklen = 0; + } + + if (retries == -1) { + client->retry_count = DEFAULT_RETRY_AMOUNT; + } else { + client->retry_count = retries; + } + + ret = coap_client_init_request(client, req); + if (ret < 0) { + LOG_ERR("Failed to initialize coap request"); + return ret; + } + + ret = coap_client_schedule_poll(client, sock, req); + if (ret < 0) { + LOG_ERR("Failed to schedule polling"); + goto out; + } + + ret = coap_pending_init(&client->pending, &client->request, &client->address, + client->retry_count); + + if (ret < 0) { + LOG_ERR("Failed to initialize pending struct"); + goto out; + } + + coap_pending_cycle(&client->pending); + + ret = send_request(sock, client->request.data, client->request.offset, 0, &client->address, + client->socklen); + + if (ret < 0) { + LOG_ERR("Transmission failed: %d", errno); + } else { + /* Do not return the number of bytes sent */ + ret = 0; + } +out: + return ret; +} + +static int handle_poll(struct coap_client *client) +{ + int ret = 0; + + while (1) { + struct pollfd fds; + + fds.fd = client->fd; + fds.events = POLLIN; + fds.revents = 0; + /* rfc7252#section-5.2.2, use separate timeout value for a separate response */ + if (client->pending.timeout != 0) { + ret = poll(&fds, 1, client->pending.timeout); + } else { + ret = poll(&fds, 1, COAP_SEPARATE_TIMEOUT); + } + + if (ret < 0) { + LOG_ERR("Error in poll:%d", errno); + errno = 0; + return ret; + } else if (ret == 0) { + if (client->pending.timeout != 0 && coap_pending_cycle(&client->pending)) { + LOG_ERR("Timeout in poll, retrying send"); + send_request(client->fd, client->request.data, + client->request.offset, 0, &client->address, + client->socklen); + } else { + /* No more retries left, don't retry */ + LOG_ERR("Timeout in poll, no more retries"); + ret = -EFAULT; + break; + } + } else { + if (fds.revents & POLLERR) { + LOG_ERR("Error in poll"); + ret = -EIO; + break; + } + + if (fds.revents & POLLHUP) { + LOG_ERR("Error in poll: POLLHUP"); + ret = -ECONNRESET; + break; + } + + if (fds.revents & POLLNVAL) { + LOG_ERR("Error in poll: POLLNVAL - fd not open"); + ret = -EINVAL; + break; + } + + if (!(fds.revents & POLLIN)) { + LOG_ERR("Unknown poll error"); + ret = -EINVAL; + break; + } + + ret = 0; + break; + } + } + + return ret; +} + +static bool token_compare(struct coap_client *client, const struct coap_packet *resp) +{ + uint8_t response_token[COAP_TOKEN_MAX_LEN]; + uint8_t response_tkl; + + response_tkl = coap_header_get_token(resp, response_token); + + if (client->request_tkl != response_tkl) { + return false; + } + + return memcmp(&client->request_token, &response_token, response_tkl) == 0; +} + +static int recv_response(struct coap_client *client, struct coap_packet *response) +{ + int len; + int ret; + + memset(client->recv_buf, 0, sizeof(client->recv_buf)); + len = receive(client->fd, client->recv_buf, sizeof(client->recv_buf), MSG_DONTWAIT, + &client->address, &client->socklen); + + if (len < 0) { + LOG_ERR("Error reading response: %d", errno); + return -EINVAL; + } else if (len == 0) { + LOG_ERR("Zero length recv"); + return -EINVAL; + } + + LOG_DBG("Received %d bytes", len); + + ret = coap_packet_parse(response, client->recv_buf, len, NULL, 0); + if (ret < 0) { + LOG_ERR("Invalid data received"); + return ret; + } + + return ret; +} + +static void report_callback_error(struct coap_client *client, int error_code) +{ + if (client->coap_request->cb) { + client->coap_request->cb(error_code, 0, NULL, 0, true, + client->coap_request->user_data); + } +} + +static int send_ack(struct coap_client *client, const struct coap_packet *req, + uint8_t response_code) +{ + int ret; + + ret = coap_ack_init(&client->request, req, client->send_buf, MAX_COAP_MSG_LEN, + response_code); + if (ret < 0) { + LOG_ERR("Failed to initialize CoAP ACK-message"); + return ret; + } + + ret = send_request(client->fd, client->request.data, client->request.offset, 0, + &client->address, client->socklen); + if (ret < 0) { + LOG_ERR("Error sending a CoAP ACK-message"); + return ret; + } + + return 0; +} + +static int send_reset(struct coap_client *client, const struct coap_packet *req, + uint8_t response_code) +{ + int ret; + uint16_t id; + uint8_t token[COAP_TOKEN_MAX_LEN]; + uint8_t tkl; + + id = coap_header_get_id(req); + tkl = response_code ? coap_header_get_token(req, token) : 0; + ret = coap_packet_init(&client->request, client->send_buf, MAX_COAP_MSG_LEN, COAP_VERSION, + COAP_TYPE_RESET, tkl, token, response_code, id); + + if (ret < 0) { + LOG_ERR("Error creating CoAP reset message"); + return ret; + } + + ret = send_request(client->fd, client->request.data, client->request.offset, 0, + &client->address, client->socklen); + if (ret < 0) { + LOG_ERR("Error sending CoAP reset message"); + return ret; + } + + return 0; +} + +static int handle_response(struct coap_client *client, const struct coap_packet *response) +{ + int ret = 0; + int response_type; + int block_option; + int block_num; + bool blockwise_transfer = false; + bool last_block = false; + + /* Handle different types, ACK might be separate or piggybacked + * CON and NCON contains a separate response, CON needs an empty response + * CON request results as ACK and possibly separate CON or NCON response + * NCON request results only as a separate CON or NCON message as there is no ACK + * With RESET, just drop gloves and call the callback. + */ + response_type = coap_header_get_type(response); + + /* Reset and Ack need to match the message ID with request */ + if ((response_type == COAP_TYPE_ACK || response_type == COAP_TYPE_RESET) && + coap_header_get_id(response) != client->pending.id) { + LOG_ERR("Unexpected ACK or Reset"); + return -EFAULT; + } else if (response_type == COAP_TYPE_RESET) { + coap_pending_clear(&client->pending); + } + + /* CON, NON_CON and piggybacked ACK need to match the token with original request */ + uint16_t payload_len; + uint8_t response_code = coap_header_get_code(response); + const uint8_t *payload = coap_packet_get_payload(response, &payload_len); + + /* Separate response */ + if (payload_len == 0 && response_type == COAP_TYPE_ACK && + response_code == COAP_CODE_EMPTY) { + /* Clear the pending, poll uses now the separate timeout for the response. */ + coap_pending_clear(&client->pending); + return 1; + } + + /* Check for tokens */ + if (!token_compare(client, response)) { + LOG_ERR("Not matching tokens, respond with reset"); + ret = send_reset(client, response, COAP_RESPONSE_CODE_NOT_FOUND); + return 1; + } + + /* Send ack for CON */ + if (response_type == COAP_TYPE_CON) { + /* CON response is always a separate response, respond with empty ACK. */ + ret = send_ack(client, response, COAP_CODE_EMPTY); + if (ret < 0) { + goto fail; + } + } + + if (client->pending.timeout != 0) { + coap_pending_clear(&client->pending); + } + + /* Check if block2 exists */ + block_option = coap_get_option_int(response, COAP_OPTION_BLOCK2); + if (block_option > 0) { + blockwise_transfer = true; + last_block = !GET_MORE(block_option); + block_num = GET_BLOCK_NUM(block_option); + + if (block_num == 0) { + coap_block_transfer_init(&client->recv_blk_ctx, + coap_client_default_block_size(), + 0); + client->offset = 0; + } + + ret = coap_update_from_block(response, &client->recv_blk_ctx); + if (ret < 0) { + LOG_ERR("Error updating block context"); + } + coap_next_block(response, &client->recv_blk_ctx); + } else { + client->offset = 0; + last_block = true; + } + + /* Check if this was a response to last blockwise send */ + if (client->send_blk_ctx.total_size > 0) { + blockwise_transfer = true; + if (client->send_blk_ctx.total_size == client->send_blk_ctx.current) { + last_block = true; + } else { + last_block = false; + } + } + + /* Call user callback */ + if (client->coap_request->cb) { + client->coap_request->cb(response_code, client->offset, payload, payload_len, + last_block, client->coap_request->user_data); + + /* Update the offset for next callback in a blockwise transfer */ + if (blockwise_transfer) { + client->offset += payload_len; + } + } + + /* If this wasn't last block, send the next request */ + if (blockwise_transfer && !last_block) { + ret = coap_client_init_request(client, client->coap_request); + + if (ret < 0) { + LOG_ERR("Error creating a CoAP request"); + goto fail; + } + + if (client->pending.timeout != 0) { + LOG_ERR("Previous pending hasn't arrived"); + goto fail; + } + + ret = coap_pending_init(&client->pending, &client->request, &client->address, + client->retry_count); + if (ret < 0) { + LOG_ERR("Error creating pending"); + goto fail; + } + coap_pending_cycle(&client->pending); + + ret = send_request(client->fd, client->request.data, client->request.offset, 0, + &client->address, client->socklen); + if (ret < 0) { + LOG_ERR("Error sending a CoAP request"); + goto fail; + } else { + return 1; + } + } +fail: + return ret; +} + +void coap_client_recv(void *coap_cl, void *a, void *b) +{ + int ret; + struct coap_client *const client = coap_cl; + + reset_block_contexts(client); + k_sem_take(&client->coap_client_recv_sem, K_FOREVER); + while (true) { + struct coap_packet response; + + atomic_set(&client->coap_client_recv_active, 1); + ret = handle_poll(client); + if (ret < 0) { + /* Error in polling, clear pending. */ + LOG_ERR("Error in poll"); + coap_pending_clear(&client->pending); + report_callback_error(client, ret); + goto idle; + } + + ret = recv_response(client, &response); + if (ret < 0) { + LOG_ERR("Error receiving response"); + report_callback_error(client, ret); + goto idle; + } + + ret = handle_response(client, &response); + if (ret < 0) { + LOG_ERR("Error handling respnse"); + report_callback_error(client, ret); + goto idle; + } + + /* There are more messages coming for the original request */ + if (ret > 0) { + continue; + } else { +idle: + reset_block_contexts(client); + atomic_set(&client->coap_client_recv_active, 0); + k_sem_take(&client->coap_client_recv_sem, K_FOREVER); + } + } +} + +int coap_client_init(struct coap_client *client, const char *info) +{ + if (client == NULL) { + return -EINVAL; + } + + client->fd = -1; + k_sem_init(&client->coap_client_recv_sem, 0, 1); + + client->tid = + k_thread_create(&client->thread, client->coap_thread_stack, + K_THREAD_STACK_SIZEOF(client->coap_thread_stack), + coap_client_recv, client, NULL, NULL, + CONFIG_COAP_CLIENT_THREAD_PRIORITY, 0, K_NO_WAIT); + + if (IS_ENABLED(CONFIG_THREAD_NAME)) { + if (info != NULL) { + k_thread_name_set(client->tid, info); + } else { + k_thread_name_set(client->tid, "coap_client"); + } + } + + return 0; +} From 5c8d51e3592753c0772a8d04ab329b6578f1a36d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarno=20L=C3=A4ms=C3=A4?= Date: Tue, 18 Apr 2023 12:22:45 +0300 Subject: [PATCH 164/528] [nrf fromtree] tests: Add ztest tests for coap client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add tests for coap client and stubs for isolating the tests. Signed-off-by: Jarno Lämsä (cherry picked from commit 2d06f8061b0d9188e68e129c850e6b1460262736) --- tests/net/lib/coap_client/CMakeLists.txt | 28 ++ tests/net/lib/coap_client/prj.conf | 4 + tests/net/lib/coap_client/src/main.c | 354 +++++++++++++++++++++++ tests/net/lib/coap_client/src/stubs.c | 52 ++++ tests/net/lib/coap_client/src/stubs.h | 39 +++ tests/net/lib/coap_client/testcase.yaml | 6 + 6 files changed, 483 insertions(+) create mode 100644 tests/net/lib/coap_client/CMakeLists.txt create mode 100644 tests/net/lib/coap_client/prj.conf create mode 100644 tests/net/lib/coap_client/src/main.c create mode 100644 tests/net/lib/coap_client/src/stubs.c create mode 100644 tests/net/lib/coap_client/src/stubs.h create mode 100644 tests/net/lib/coap_client/testcase.yaml diff --git a/tests/net/lib/coap_client/CMakeLists.txt b/tests/net/lib/coap_client/CMakeLists.txt new file mode 100644 index 000000000000..60506c23c2d3 --- /dev/null +++ b/tests/net/lib/coap_client/CMakeLists.txt @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(coap_client_test) + +set(APP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) + +# Add test sources +target_sources(app PRIVATE ${APP_SRC_DIR}/main.c) +target_sources(app PRIVATE ${APP_SRC_DIR}/stubs.c) +target_sources(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/coap/coap_client.c) +target_sources(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/coap/coap.c) + +# Add includes directories +target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/include/) + +add_compile_definitions(CONFIG_NET_SOCKETS_POLL_MAX=3) +add_compile_definitions(CONFIG_COAP_CLIENT=y) +add_compile_definitions(CONFIG_COAP_CLIENT_BLOCK_SIZE=256) +add_compile_definitions(CONFIG_COAP_CLIENT_MESSAGE_SIZE=256) +add_compile_definitions(CONFIG_COAP_CLIENT_MESSAGE_HEADER_SIZE=48) +add_compile_definitions(CONFIG_COAP_CLIENT_STACK_SIZE=1024) +add_compile_definitions(CONFIG_COAP_CLIENT_THREAD_PRIORITY=10) +add_compile_definitions(CONFIG_COAP_LOG_LEVEL=4) +add_compile_definitions(CONFIG_NET_SOCKETS_POSIX_NAMES=y) +add_compile_definitions(CONFIG_COAP_INIT_ACK_TIMEOUT_MS=2000) diff --git a/tests/net/lib/coap_client/prj.conf b/tests/net/lib/coap_client/prj.conf new file mode 100644 index 000000000000..d185b3e493cf --- /dev/null +++ b/tests/net/lib/coap_client/prj.conf @@ -0,0 +1,4 @@ +#Testing +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c new file mode 100644 index 000000000000..8cfc70a93dc3 --- /dev/null +++ b/tests/net/lib/coap_client/src/main.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#include "stubs.h" + +LOG_MODULE_REGISTER(coap_client_test); + +DEFINE_FFF_GLOBALS; +#define FFF_FAKES_LIST(FAKE) + +static uint8_t last_response_code; +static const char *test_path = "test"; +static uint16_t last_message_id; + +static struct coap_client client; + +static char *short_payload = "testing"; +static char *long_payload = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " + "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut " + "enim ad minim veniam, quis nostrud exercitation ullamco laboris " + "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor " + "in reprehenderit in voluptate velit esse cillum dolore eu fugiat" + " nulla pariatur. Excepteur sint occaecat cupidatat non proident," + " sunt in culpa qui officia deserunt mollit anim id est laborum."; + +static ssize_t z_impl_zsock_recvfrom_custom_fake(int sock, void *buf, size_t max_len, int flags, + struct sockaddr *src_addr, socklen_t *addrlen) +{ + LOG_INF("Recvfrom"); + static uint8_t ack_data[] = { + 0x68, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + ack_data[2] = (uint8_t) last_message_id >> 8; + ack_data[3] = (uint8_t) last_message_id; + + memcpy(buf, ack_data, sizeof(ack_data)); + + return sizeof(ack_data); +} + +static ssize_t z_impl_zsock_sendto_custom_fake(int sock, void *buf, size_t len, + int flags, const struct sockaddr *dest_addr, + socklen_t addrlen) +{ + LOG_INF("Sendto"); + last_message_id = 0; + last_message_id |= ((uint8_t *) buf)[2] << 8; + last_message_id |= ((uint8_t *) buf)[3]; + + last_response_code = ((uint8_t *) buf)[1]; + + LOG_INF("Latest message ID: %d", last_message_id); + return 1; +} + +static ssize_t z_impl_zsock_recvfrom_custom_fake_response(int sock, void *buf, size_t max_len, + int flags, struct sockaddr *src_addr, + socklen_t *addrlen) +{ + static uint8_t ack_data[] = { + 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + ack_data[2] = (uint8_t) last_message_id >> 8; + ack_data[3] = (uint8_t) last_message_id; + + memcpy(buf, ack_data, sizeof(ack_data)); + + return sizeof(ack_data); +} + +static ssize_t z_impl_zsock_recvfrom_custom_fake_empty_ack(int sock, void *buf, size_t max_len, + int flags, struct sockaddr *src_addr, + socklen_t *addrlen) +{ + static uint8_t ack_data[] = { + 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + }; + + ack_data[2] = (uint8_t) last_message_id >> 8; + ack_data[3] = (uint8_t) last_message_id; + + memcpy(buf, ack_data, sizeof(ack_data)); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_response; + + return sizeof(ack_data); +} + +static ssize_t z_impl_zsock_recvfrom_custom_fake_unmatching(int sock, void *buf, size_t max_len, + int flags, struct sockaddr *src_addr, + socklen_t *addrlen) +{ + static uint8_t ack_data[] = { + 0x68, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + }; + + ack_data[2] = (uint8_t) last_message_id >> 8; + ack_data[3] = (uint8_t) last_message_id; + + memcpy(buf, ack_data, sizeof(ack_data)); + + return sizeof(ack_data); +} + +static void *suite_setup(void) +{ + coap_client_init(&client, NULL); + + return NULL; +} + +static void test_setup(void *data) +{ + /* Register resets */ + DO_FOREACH_FAKE(RESET_FAKE); + /* reset common FFF internal structures */ + FFF_RESET_HISTORY(); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake; + z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake; +} + +void coap_callback(int16_t code, size_t offset, const uint8_t *payload, size_t len, bool last_block, + void *user_data) +{ + LOG_INF("CoAP response callback, %d", code); + last_response_code = code; +} + +ZTEST_SUITE(coap_client, NULL, suite_setup, test_setup, NULL, NULL); + +ZTEST(coap_client, test_get_request) +{ + int ret = 0; + struct sockaddr address; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + k_sleep(K_MSEC(1)); + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + set_socket_events(ZSOCK_POLLIN); + + k_sleep(K_MSEC(5)); + k_sleep(K_MSEC(1000)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); +} + +ZTEST(coap_client, test_get_no_path) +{ + int ret = 0; + struct sockaddr address; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = NULL, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + k_sleep(K_MSEC(1)); + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + + zassert_equal(ret, -EINVAL, "Get request without path"); +} + +ZTEST(coap_client, test_send_large_data) +{ + int ret = 0; + struct sockaddr address; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = long_payload; + client_request.len = strlen(long_payload); + + k_sleep(K_MSEC(1)); + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + set_socket_events(ZSOCK_POLLIN); + + k_sleep(K_MSEC(5)); + k_sleep(K_MSEC(1000)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); +} + +ZTEST(coap_client, test_no_response) +{ + int ret = 0; + struct sockaddr address; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + k_sleep(K_MSEC(1)); + + LOG_INF("Send request"); + clear_socket_events(); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + + zassert_true(ret >= 0, "Sending request failed, %d", ret); + k_sleep(K_MSEC(1000)); +} + +ZTEST(coap_client, test_separate_response) +{ + int ret = 0; + struct sockaddr address; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_empty_ack; + + k_sleep(K_MSEC(1)); + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + set_socket_events(ZSOCK_POLLIN); + + k_sleep(K_MSEC(5)); + k_sleep(K_MSEC(1000)); + + k_sleep(K_MSEC(1000)); + + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); +} + +ZTEST(coap_client, test_multiple_requests) +{ + int ret = 0; + struct sockaddr address; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + k_sleep(K_MSEC(1)); + set_socket_events(ZSOCK_POLLIN); + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_equal(ret, -EAGAIN, "Shouldn't be able to send 2 requests at same time"); + + k_sleep(K_MSEC(5)); + k_sleep(K_MSEC(1000)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); + + ret = coap_client_req(&client, 0, &address, &client_request, -1); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + + k_sleep(K_MSEC(5)); + k_sleep(K_MSEC(1000)); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); +} + +ZTEST(coap_client, test_unmatching_tokens) +{ + int ret = 0; + struct sockaddr address; + struct coap_client_request client_request = { + .method = COAP_METHOD_GET, + .confirmable = true, + .path = test_path, + .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, + .cb = coap_callback, + .payload = NULL, + .len = 0 + }; + + client_request.payload = short_payload; + client_request.len = strlen(short_payload); + + z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_unmatching; + + LOG_INF("Send request"); + ret = coap_client_req(&client, 0, &address, &client_request, 0); + zassert_true(ret >= 0, "Sending request failed, %d", ret); + set_socket_events(ZSOCK_POLLIN); + + k_sleep(K_MSEC(1)); + k_sleep(K_MSEC(1)); + clear_socket_events(); + zassert_equal(last_response_code, COAP_RESPONSE_CODE_NOT_FOUND, "Unexpected response %d", + last_response_code); + k_sleep(K_MSEC(1)); +} diff --git a/tests/net/lib/coap_client/src/stubs.c b/tests/net/lib/coap_client/src/stubs.c new file mode 100644 index 000000000000..13effd8f91b9 --- /dev/null +++ b/tests/net/lib/coap_client/src/stubs.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +LOG_MODULE_DECLARE(coap_client_test); + +DEFINE_FAKE_VALUE_FUNC(uint32_t, z_impl_sys_rand32_get); +DEFINE_FAKE_VOID_FUNC(z_impl_sys_rand_get, void *, size_t); +DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_recvfrom, int, void *, size_t, int, struct sockaddr *, + socklen_t *); +DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void*, size_t, int, + const struct sockaddr *, socklen_t); + +struct zsock_pollfd { + int fd; + short events; + short revents; +}; + +static short my_events; + +void set_socket_events(short events) +{ + my_events |= events; +} + +void clear_socket_events(void) +{ + my_events = 0; +} + +int z_impl_zsock_socket(int family, int type, int proto) +{ + return 0; +} + +int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) +{ + LOG_INF("Polling, events %d", my_events); + k_sleep(K_MSEC(10)); + fds->revents = my_events; + if (my_events) { + return 1; + } else { + return 0; + } +} diff --git a/tests/net/lib/coap_client/src/stubs.h b/tests/net/lib/coap_client/src/stubs.h new file mode 100644 index 000000000000..eb340d914eb9 --- /dev/null +++ b/tests/net/lib/coap_client/src/stubs.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef STUBS_H +#define STUBS_H + +#include +#include + +#include +#include + +#include + +#define ZSOCK_POLLIN 1 +#define ZSOCK_POLLOUT 4 + +void set_socket_events(short events); +void clear_socket_events(void); + +DECLARE_FAKE_VALUE_FUNC(uint32_t, z_impl_sys_rand32_get); +DECLARE_FAKE_VOID_FUNC(z_impl_sys_rand_get, void *, size_t); +DECLARE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_recvfrom, int, void *, size_t, int, struct sockaddr *, + socklen_t *); +DECLARE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void*, size_t, int, + const struct sockaddr *, socklen_t); + +#define DO_FOREACH_FAKE(FUNC) \ + do { \ + FUNC(z_impl_sys_rand32_get) \ + FUNC(z_impl_sys_rand_get) \ + FUNC(z_impl_zsock_recvfrom) \ + FUNC(z_impl_zsock_sendto) \ + } while (0) + +#endif /* STUBS_H */ diff --git a/tests/net/lib/coap_client/testcase.yaml b/tests/net/lib/coap_client/testcase.yaml new file mode 100644 index 000000000000..923e1380f010 --- /dev/null +++ b/tests/net/lib/coap_client/testcase.yaml @@ -0,0 +1,6 @@ +common: + depends_on: netif +tests: + net.coap.client: + platform_allow: native_posix + tags: coap net From 2f5e820792d145c7a460f6c192c83e81d5348ddc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarno=20L=C3=A4ms=C3=A4?= Date: Wed, 24 May 2023 15:37:12 +0300 Subject: [PATCH 165/528] [nrf fromtree] doc: CoAP client documentation and sample MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sample usage and documentation of the CoAP client. Signed-off-by: Jarno Lämsä (cherry picked from commit 3f8c129ae98e43b84e0ff0e3f63bb93c960512cf) --- .../networking/api/coap_client.rst | 84 +++++++++++++++++++ doc/connectivity/networking/api/protocols.rst | 1 + 2 files changed, 85 insertions(+) create mode 100644 doc/connectivity/networking/api/coap_client.rst diff --git a/doc/connectivity/networking/api/coap_client.rst b/doc/connectivity/networking/api/coap_client.rst new file mode 100644 index 000000000000..2251bb3d0da6 --- /dev/null +++ b/doc/connectivity/networking/api/coap_client.rst @@ -0,0 +1,84 @@ +.. _coap_client_interface: + +CoAP client +########### + +.. contents:: + :local: + :depth: 2 + +Overview +******** + +The CoAP client library allows application to send CoAP requests and parse CoAP responses. +The application is notified about the response via a callback that is provided to the API +in the request. The CoAP client handles the communication over sockets. +As the CoAP client doesn't create socket it is using, the application is responsible for creating +the socket. Plain UDP or DTLS sockets are supported. + +Sample Usage +************ + +The following is an example of a CoAP client initialization and request sending: + +.. code-block:: c + + static struct coap_client; + struct coap_client_request req = { 0 }; + + coap_client_init(&client, NULL); + + req.method = COAP_METHOD_GET; + req.confirmable = true; + req.path = "test"; + req.fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN; + req.cb = response_cb; + req.payload = NULL; + req.len = 0; + + /* Sock is a file descriptor referencing a socket, address is the sockaddr struct for the + * destination address of the request or NULL if the socket is already connected. + */ + ret = coap_client_req(&client, sock, &address, &req, -1); + +Before any requests can be sent, the CoAP client needs to be initialized. +After initialization, the application can send a CoAP request and wait for the response. +Currently only one request can be sent for a single CoAP client at a time. There can be multiple +CoAP clients. + +The callback provided in the callback will be called in following cases: + +- There is a response for the request +- The request failed for some reason + +The callback contains a flag `last_block`, which indicates if there is more data to come in the +response and means that the current response is part of a blockwise transfer. When the `last_block` +is set to true, the response is finished and the client is ready for the next request after +returning from the callback. + +If the server responds to the request, the library provides the response to the +application through the response callback registered in the request structure. +As the response can be a blockwise transfer and the client calls the callback once per each +block, the application should be to process all of the blocks to be able to process the response. + +The following is an example of a very simple response handling function: + +.. code-block:: c + + void response_cb(int16_t code, size_t offset, const uint8_t *payload, size_t len, + bool last_block, void *user_data) + { + if (code >= 0) { + LOG_INF("CoAP response from server %d", code); + if (last_block) { + LOG_INF("Last packet received"); + } + } else { + LOG_ERR("Error in sending request %d", code); + } + } + +API Reference +************* + +.. doxygengroup:: coap_client diff --git a/doc/connectivity/networking/api/protocols.rst b/doc/connectivity/networking/api/protocols.rst index f9d3d775e92f..6ed46130fa56 100644 --- a/doc/connectivity/networking/api/protocols.rst +++ b/doc/connectivity/networking/api/protocols.rst @@ -8,6 +8,7 @@ Protocols :maxdepth: 1 coap + coap_client http lwm2m mqtt From b4672df6bb9bb2e3ea44eae8f39051c083f3f124 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eivind=20J=C3=B8lsgard?= Date: Tue, 9 May 2023 12:10:13 +0200 Subject: [PATCH 166/528] [nrf noup] cmake: modules: Add ZEPHYR_NRF_MODULE_DIR to snippets root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add nRF directory to snippets root to allow placing snippets in the sdk-nrf/snippets directory. CmakeLists.txt in nRF directory is handled after the snippets so that adding the directory in sdk-nrf will not work. Signed-off-by: Eivind Jølsgard --- cmake/modules/snippets.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/modules/snippets.cmake b/cmake/modules/snippets.cmake index 550d236a2f4a..6f8950c5f64a 100644 --- a/cmake/modules/snippets.cmake +++ b/cmake/modules/snippets.cmake @@ -59,6 +59,7 @@ function(zephyr_process_snippets) # Set SNIPPET_ROOT. list(APPEND SNIPPET_ROOT ${APPLICATION_SOURCE_DIR}) list(APPEND SNIPPET_ROOT ${ZEPHYR_BASE}) + list(APPEND SNIPPET_ROOT ${ZEPHYR_NRF_MODULE_DIR}) unset(real_snippet_root) foreach(snippet_dir ${SNIPPET_ROOT}) # The user might have put a symbolic link in here, for example. From 1210ab0a4d243aefc06f1664a2be24fd6ac10e74 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 9 Jun 2023 21:08:43 +0530 Subject: [PATCH 167/528] [nrf fromtree] net: l2: ethernet: Fix IPv6 Kconfig Function net_if_ipv6_addr_rm is only defined for NATIVE_IPV6. Signed-off-by: Chaitanya Tata (cherry picked from commit 1b7ef97c31f4b734cae9cfb2b251c1b86b40d109) --- subsys/net/l2/ethernet/ethernet_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/ethernet/ethernet_mgmt.c b/subsys/net/l2/ethernet/ethernet_mgmt.c index 26eea7369f52..e7fcae8ac99a 100644 --- a/subsys/net/l2/ethernet/ethernet_mgmt.c +++ b/subsys/net/l2/ethernet/ethernet_mgmt.c @@ -98,7 +98,7 @@ static int ethernet_set_config(uint32_t mgmt_request, * generated from old MAC address, from network interface if * needed. */ - if (IS_ENABLED(CONFIG_NET_IPV6)) { + if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6)) { struct in6_addr iid; net_ipv6_addr_create_iid(&iid, From 5385c25be98b6812b765d9ce90e3b2f8a03c5bf1 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Mon, 15 May 2023 11:59:52 +0200 Subject: [PATCH 168/528] [nrf fromtree] scripts: adjust WEST_PYTHON to posix path Adjust WEST_PYTHON to posix path to be consistent with other Python scripts which passes paths to the Zephyr CMake build system. Signed-off-by: Torsten Rasmussen (cherry picked from commit c03e1900ae7faf2d64b9275735f59c585a028937) --- scripts/west_commands/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index 6797ff1c48d0..18b656a50008 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -497,7 +497,7 @@ def _run_cmake(self, board, origin, cmake_opts): # to Just Work: # # west build -- -DOVERLAY_CONFIG=relative-path.conf - final_cmake_args = ['-DWEST_PYTHON={}'.format(sys.executable), + final_cmake_args = ['-DWEST_PYTHON={}'.format(pathlib.Path(sys.executable).as_posix()), '-B{}'.format(self.build_dir), '-G{}'.format(config_get('generator', DEFAULT_CMAKE_GENERATOR))] From 31d103f80f634ac98df9cf0a9cc13abaa2686c00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vidar=20Lilleb=C3=B8?= Date: Tue, 9 May 2023 16:21:35 +0200 Subject: [PATCH 169/528] [nrf noup] modules: mbedtls: Add symbols for PAKE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds symbols for J-PAKE, SPAKE2+ and SRP and TLS1.2 EC J-PAKE to PMS. noup reason: We're adding support for Nordic only experimental algorithms. The changed file contains the Nordic's configuration scheme that is also a noup. ref: NCSDK-21261 Signed-off-by: Vidar Lillebø --- modules/mbedtls/Kconfig.psa | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index e60da36d48a2..b91d767285aa 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -262,13 +262,14 @@ config PSA_HAS_KEY_DERIVATION depends on PSA_WANT_ALG_HKDF || \ PSA_WANT_ALG_PBKDF2_HMAC || \ PSA_WANT_ALG_TLS12_PRF || \ - PSA_WANT_ALG_TLS12_PSK_TO_MS + PSA_WANT_ALG_TLS12_PSK_TO_MS || \ + PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS help Prompt-less configuration that states that key derivation is supported. config PSA_WANT_ALG_HKDF bool - prompt "PSA HKFD support" if !PSA_PROMPTLESS + prompt "PSA HKDF support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF depends on PSA_WANT_ALG_HMAC @@ -286,6 +287,10 @@ config PSA_WANT_ALG_TLS12_PSK_TO_MS bool prompt "PSA TLS 1.2 PSK to MS support" if !PSA_PROMPTLESS +config PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS + bool + prompt "PSA TLS 1.2 EC J-PAKE to PMS support" if !PSA_PROMPTLESS + endmenu # PSA Key derivation support @@ -425,3 +430,19 @@ config PSA_WANT_ALG_STREAM_CIPHER bool prompt "PSA stream cipher support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF + +config PSA_WANT_ALG_JPAKE + bool + prompt "PSA EC J-PAKE support" if !PSA_PROMPTLESS + select EXPERIMENTAL + +config PSA_WANT_ALG_SPAKE2P + bool + prompt "PSA SPAKE2+ support" if !PSA_PROMPTLESS + select EXPERIMENTAL + +config PSA_WANT_ALG_SRP + bool + prompt "PSA SRP support" if !PSA_PROMPTLESS + default n + select EXPERIMENTAL From b92f3123358eea8774715b42b4f3741e2eb96d46 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Tue, 13 Jun 2023 12:43:04 +0200 Subject: [PATCH 170/528] [nrf fromlist] drivers: timer: add z_nrf_rtc_timer_exact_set The function `z_nrf_rtc_timer_exact_set` is added to allow setting compare channel without possible creeping of cc val. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/59297 Signed-off-by: Andrzej Kuros --- drivers/timer/nrf_rtc_timer.c | 59 +++++++++++++++----- include/zephyr/drivers/timer/nrf_rtc_timer.h | 31 ++++++++++ 2 files changed, 77 insertions(+), 13 deletions(-) diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c index ef7b2aab574b..c024a82b2061 100644 --- a/drivers/timer/nrf_rtc_timer.c +++ b/drivers/timer/nrf_rtc_timer.c @@ -231,9 +231,20 @@ uint64_t z_nrf_rtc_timer_get_ticks(k_timeout_t t) * @param[in] chan A channel for which a new CC value is to be set. * * @param[in] req_cc Requested CC register value to be set. + * + * @param[in] exact Use @c false to allow CC adjustment if @c req_cc value is + * close to the current value of the timer. + * Use @c true to disallow CC adjustment. The function can + * fail with -EINVAL result if @p req_cc is too close to the + * current value. + * + * @retval 0 The requested CC has been set successfully. + * @retval -EINVAL The requested CC value could not be reliably set. */ -static void set_alarm(int32_t chan, uint32_t req_cc) +static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) { + int ret = 0; + /* Ensure that the value exposed in this driver API is consistent with * assumptions of this function. */ @@ -300,9 +311,16 @@ static void set_alarm(int32_t chan, uint32_t req_cc) now = counter(); if (counter_sub(now, req_cc) > COUNTER_HALF_SPAN) { event_clear(chan); + if (exact) { + ret = -EINVAL; + break; + } } else { break; } + } else if (exact) { + ret = -EINVAL; + break; } cc_val = now + cc_inc; @@ -311,11 +329,13 @@ static void set_alarm(int32_t chan, uint32_t req_cc) break; } } + + return ret; } static int compare_set_nolocks(int32_t chan, uint64_t target_time, z_nrf_rtc_timer_compare_handler_t handler, - void *user_data) + void *user_data, bool exact) { int ret = 0; uint32_t cc_value = absolute_time_to_cc(target_time); @@ -331,29 +351,33 @@ static int compare_set_nolocks(int32_t chan, uint64_t target_time, /* Target time is valid and is different than currently set. * Set CC value. */ - set_alarm(chan, cc_value); + ret = set_alarm(chan, cc_value, exact); } - } else { + } else if (!exact) { /* Force ISR handling when exiting from critical section. */ atomic_or(&force_isr_mask, BIT(chan)); + } else { + ret = -EINVAL; } - cc_data[chan].target_time = target_time; - cc_data[chan].callback = handler; - cc_data[chan].user_context = user_data; + if (ret == 0) { + cc_data[chan].target_time = target_time; + cc_data[chan].callback = handler; + cc_data[chan].user_context = user_data; + } return ret; } static int compare_set(int32_t chan, uint64_t target_time, z_nrf_rtc_timer_compare_handler_t handler, - void *user_data) + void *user_data, bool exact) { bool key; key = compare_int_lock(chan); - int ret = compare_set_nolocks(chan, target_time, handler, user_data); + int ret = compare_set_nolocks(chan, target_time, handler, user_data, exact); compare_int_unlock(chan, key); @@ -366,7 +390,16 @@ int z_nrf_rtc_timer_set(int32_t chan, uint64_t target_time, { __ASSERT_NO_MSG(chan > 0 && chan < CHAN_COUNT); - return compare_set(chan, target_time, handler, user_data); + return compare_set(chan, target_time, handler, user_data, false); +} + +int z_nrf_rtc_timer_exact_set(int32_t chan, uint64_t target_time, + z_nrf_rtc_timer_compare_handler_t handler, + void *user_data) +{ + __ASSERT_NO_MSG(chan > 0 && chan < CHAN_COUNT); + + return compare_set(chan, target_time, handler, user_data, true); } void z_nrf_rtc_timer_abort(int32_t chan) @@ -447,7 +480,7 @@ static void sys_clock_timeout_handler(int32_t chan, * so it won't get preempted by the interrupt. */ compare_set(chan, last_count + CYC_PER_TICK, - sys_clock_timeout_handler, NULL); + sys_clock_timeout_handler, NULL, false); } sys_clock_announce(dticks); @@ -643,7 +676,7 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) uint64_t target_time = cyc + last_count; - compare_set(0, target_time, sys_clock_timeout_handler, NULL); + compare_set(0, target_time, sys_clock_timeout_handler, NULL, false); } uint32_t sys_clock_elapsed(void) @@ -721,7 +754,7 @@ static int sys_clock_driver_init(void) uint32_t initial_timeout = IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? MAX_CYCLES : CYC_PER_TICK; - compare_set(0, initial_timeout, sys_clock_timeout_handler, NULL); + compare_set(0, initial_timeout, sys_clock_timeout_handler, NULL, false); z_nrf_clock_control_lf_on(mode); diff --git a/include/zephyr/drivers/timer/nrf_rtc_timer.h b/include/zephyr/drivers/timer/nrf_rtc_timer.h index b11f201386e6..c5992bee4bdd 100644 --- a/include/zephyr/drivers/timer/nrf_rtc_timer.h +++ b/include/zephyr/drivers/timer/nrf_rtc_timer.h @@ -127,11 +127,42 @@ uint32_t z_nrf_rtc_timer_compare_read(int32_t chan); * @retval 0 if the compare channel was set successfully. * @retval -EINVAL if provided target time was further than * @c NRF_RTC_TIMER_MAX_SCHEDULE_SPAN ticks in the future. + * + * @sa @ref z_nrf_rtc_timer_exact_set */ int z_nrf_rtc_timer_set(int32_t chan, uint64_t target_time, z_nrf_rtc_timer_compare_handler_t handler, void *user_data); +/** @brief Try to set compare channel exactly to given value. + * + * @note This function is similar to @ref z_nrf_rtc_timer_set, but the compare + * channel will be set to expected value only when it can be guaranteed that + * the hardware event will be generated exactly at expected @c target_time in + * the future. If the @c target_time is in the past or so close in the future + * that the reliable generation of event would require adjustment of compare + * value (as would @ref z_nrf_rtc_timer_set function do), neither the hardware + * event nor interrupt will be generated and the function fails. + * + * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. + * + * @param target_time Absolute target time in ticks. + * + * @param handler User function called in the context of the RTC interrupt. + * + * @param user_data Data passed to the handler. + * + * @retval 0 if the compare channel was set successfully. + * @retval -EINVAL if provided target time was further than + * @c NRF_RTC_TIMER_MAX_SCHEDULE_SPAN ticks in the future + * or the target time is in the past or is so close in the future that + * event generation could not be guaranteed without adjusting + * compare value of that channel. + */ +int z_nrf_rtc_timer_exact_set(int32_t chan, uint64_t target_time, + z_nrf_rtc_timer_compare_handler_t handler, + void *user_data); + /** @brief Abort a timer requested with @ref z_nrf_rtc_timer_set. * * If an abort operation is performed too late it is still possible for an event From 890edab701c076b8f8ded3cf2197179a75679ad2 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 20 Jun 2023 17:54:39 +0530 Subject: [PATCH 171/528] [nrf fromlist] boards: thingy53: Fix missing entry for CPUNET CPUNET uses a diffetent DTS file and the edge connector entry was missed, this causes build issue for CPUNET. Fixes 017ff78466("boards: thingy53: Update DTS files to support expansion boards"). Upstream-Pr: https://github.com/zephyrproject-rtos/zephyr/pull/59439 Signed-off-by: Chaitanya Tata --- .../thingy53_nrf5340/thingy53_nrf5340_cpunet.dts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.dts b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.dts index 25eefde08ab6..9d96c23ef76c 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.dts +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_cpunet.dts @@ -63,6 +63,20 @@ supply-voltage-mv = <3000>; }; + edge_connector: connector { + compatible = "nordic-thingy53-edge-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + gpio-map = <8 0 &gpio0 5 0>, /* P8, P0.05/AIN1 */ + <9 0 &gpio0 4 0>, /* P9, P0.04/AIN0 */ + <15 0 &gpio0 8 0>, /* P15, P0.08/TRACEDATA3 */ + <16 0 &gpio0 9 0>, /* P16, P0.09/TRACEDATA2 */ + <17 0 &gpio0 10 0>, /* P17, P0.10/TRACEDATA1 */ + <18 0 &gpio0 11 0>, /* P18, P0.11/TRACEDATA0 */ + <19 0 &gpio0 12 0>; /* P19, P0.12/TRACECLK */ + }; + aliases { sw0 = &button0; sw1 = &button1; From 1b800d818c7d7fa235879f3d3b47240a00d7a92e Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Thu, 1 Jun 2023 14:43:43 +0530 Subject: [PATCH 172/528] [nrf fromtree] net: wifi_mgmt: Reject TWT setup till IP address is configured If a user tries to enable TWT too early in the connection, then we might enter TWT sleep even before DHCP is completed, this can result in packet loss as when we wakeup we cannot receive traffic and completing DHCP itself can take multiple intervals. Though static ip address can be assigned too. Reject TWT till Wi-Fi interface has a valid IP address. Signed-off-by: Ajay Parida (cherry picked from commit 041201b0d19e0ca2e5b530b67a7bde0fb1814b26) (cherry picked from commit 9fbb6be8599fba83be5cf55e1b2d6e6f9ba6147d) --- include/zephyr/net/wifi.h | 3 +++ subsys/net/l2/wifi/Kconfig | 11 +++++++++++ subsys/net/l2/wifi/wifi_mgmt.c | 12 ++++++++++++ 3 files changed, 26 insertions(+) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index cace143c93d6..75139ae36c48 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -351,6 +351,7 @@ enum wifi_twt_fail_reason { WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB, WIFI_TWT_FAIL_OPERATION_IN_PROGRESS, WIFI_TWT_FAIL_INVALID_FLOW_ID, + WIFI_TWT_FAIL_IP_NOT_ASSIGNED, }; static const char * const twt_err_code_tbl[] = { @@ -368,6 +369,8 @@ static const char * const twt_err_code_tbl[] = { "Operation already in progress", [WIFI_TWT_FAIL_INVALID_FLOW_ID] = "Invalid negotiated flow id", + [WIFI_TWT_FAIL_IP_NOT_ASSIGNED] = + "IP address not assigned", }; static inline const char *get_twt_err_code_str(int16_t err_no) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index ecd1d002bc3d..48bcff3943e6 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -27,3 +27,14 @@ config WIFI_MGMT_RAW_SCAN_RESULTS_ONLY to the application. endif # WIFI_MGMT_RAW_SCAN_RESULTS + +config WIFI_MGMT_TWT_CHECK_IP + bool "Check IP Assignment for TWT" + default y + help + This option enables check for valid IP address before TWT setup. + If TWT setup is triggered early in the connection, then device might + enter deep sleep without having a valid IP, this can result in device + being unreachable (IP Level) or unable to receive down link traffic + even when it is awake intervals. Rejecting TWT setup till Wi-Fi + interface has a valid IP address might be desirable in most scenarios. diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 4548864fe7c7..2e123f6dd6c5 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -329,6 +329,18 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, goto fail; } +#ifdef CONFIG_WIFI_MGMT_TWT_CHECK_IP + if ((!net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) && + (!net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface))) { + twt_params->fail_reason = + WIFI_TWT_FAIL_IP_NOT_ASSIGNED; + goto fail; + } +#else + NET_WARN("Check for valid IP address been disabled. " + "Device might be unreachable or might not receive traffic.\n"); +#endif /* CONFIG_WIFI_MGMT_TWT_CHECK_IP */ + if (info.link_mode < WIFI_6) { twt_params->fail_reason = WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB; From c114a91105d4f4036f037283969446bfa83e9522 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 23 Jun 2023 01:53:52 +0530 Subject: [PATCH 173/528] [nrf fromtree] net: wifi: Fix a typo Typo in TWT error strings. Signed-off-by: Chaitanya Tata (cherry picked from commit e4167632df7eab91a2dd15e9def9a87b26cb4ab3) --- include/zephyr/net/wifi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 75139ae36c48..806424475f09 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -355,7 +355,7 @@ enum wifi_twt_fail_reason { }; static const char * const twt_err_code_tbl[] = { - [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecfied", + [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecified", [WIFI_TWT_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", [WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED] = "Operation not supported", From 88b6c53c713faf340c72ac86047afc347c22e614 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 23 Jun 2023 02:06:18 +0530 Subject: [PATCH 174/528] [nrf fromtree] net: wifi: Do TWT checks only for setup For tear down the checks doesn't make any sense, as TWT flow is already established. Signed-off-by: Chaitanya Tata (cherry picked from commit 456859a65dd4ca7bc64bb2aa4c68013eecf499e7) --- subsys/net/l2/wifi/wifi_mgmt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 2e123f6dd6c5..3e2e4c234914 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -316,6 +316,10 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, return -ENOTSUP; } + if (twt_params->operation == WIFI_TWT_TEARDOWN) { + return off_api->set_twt(dev, twt_params); + } + if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, sizeof(struct wifi_iface_status))) { twt_params->fail_reason = From 99c41e2cef058675a13561e812b5ff92d4c8302c Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 23 Jun 2023 14:15:26 +0530 Subject: [PATCH 175/528] [nrf fromtree] net: wifi: Disable trigger in TWT quick setup Most AP's are not sending proper HE triggers or stopping triggers after sometime, so, change the default to non-triggered based TWT. Signed-off-by: Chaitanya Tata (cherry picked from commit 97bd70fa05336b2441237fd6f7b8567a11701a05) --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 47e47830c8e8..5d833c25f750 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -717,7 +717,7 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, params.flow_id = 0; params.setup.responder = 0; params.setup.implicit = 1; - params.setup.trigger = 1; + params.setup.trigger = 0; params.setup.announce = 0; if (!parse_number(sh, (long *)¶ms.setup.twt_wake_interval, argv[idx++], From 917d571c71f56d165f6330a6a276d3bc4eb09fae Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 25 Jun 2023 21:18:19 +0530 Subject: [PATCH 176/528] [nrf fromtree] net: wifi: Add an error code for TWT duplicate flow request This is to handle duplicate TWT setup request. Signed-off-by: Chaitanya Tata (cherry picked from commit 15476aa3985fc5c9f2886dac6d382622136e85e2) --- include/zephyr/net/wifi.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 806424475f09..ae9f8cfa6db4 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -352,6 +352,7 @@ enum wifi_twt_fail_reason { WIFI_TWT_FAIL_OPERATION_IN_PROGRESS, WIFI_TWT_FAIL_INVALID_FLOW_ID, WIFI_TWT_FAIL_IP_NOT_ASSIGNED, + WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS, }; static const char * const twt_err_code_tbl[] = { @@ -371,6 +372,8 @@ static const char * const twt_err_code_tbl[] = { "Invalid negotiated flow id", [WIFI_TWT_FAIL_IP_NOT_ASSIGNED] = "IP address not assigned", + [WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS] = + "Flow already exists", }; static inline const char *get_twt_err_code_str(int16_t err_no) From baaf2e5412a2349c193eececc5706c437c0498a9 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 25 Jun 2023 21:37:16 +0530 Subject: [PATCH 177/528] [nrf fromtree] net: wifi: Fix tear down messages TWT tear down is a synchronous call, so, once it returns the operation is done. Signed-off-by: Chaitanya Tata (cherry picked from commit 3be72657378673e2a055d28927c1a13d6e4c4497) --- subsys/net/l2/wifi/wifi_shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 5d833c25f750..3500743b1148 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -837,7 +837,7 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d requested\n", + shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d success\n", wifi_twt_operation2str[params.operation], params.dialog_token, params.flow_id); @@ -864,7 +864,7 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s all flows\n", + shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s all flows success\n", wifi_twt_operation2str[params.operation]); return 0; From 6e912903d99c09f575b76e9c343676adcc12d3ca Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 25 Jun 2023 22:07:18 +0530 Subject: [PATCH 178/528] [nrf fromtree] net: wifi: Add a demarcation print This helps see the response status and details separately. Signed-off-by: Chaitanya Tata (cherry picked from commit a3ab624f5deb22b1617c67ee1bd5514550c05dde) --- subsys/net/l2/wifi/wifi_shell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 3500743b1148..31e722e21229 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -270,6 +270,7 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { print(context.sh, SHELL_NORMAL, "TWT response: %s\n", wifi_twt_setup_cmd2str[resp->setup_cmd]); + print(context.sh, SHELL_NORMAL, "== TWT negotiated parameters ==\n"); print_twt_params(resp->dialog_token, resp->flow_id, resp->negotiation_type, From e405279d21343b0845242416cc306ad580bb3ba5 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 25 Jun 2023 22:40:22 +0530 Subject: [PATCH 179/528] [nrf fromtree] net: wifi: Add a message for unsolicited TWT tear down This is for TWT tear down by AP. Signed-off-by: Chaitanya Tata (cherry picked from commit 8042218948f671673fd2104fa9eb6f94c745f89a) --- subsys/net/l2/wifi/wifi_shell.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 31e722e21229..503b009707d4 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -267,6 +267,12 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) const struct wifi_twt_params *resp = (const struct wifi_twt_params *)cb->info; + if (resp->operation == WIFI_TWT_TEARDOWN) { + print(context.sh, SHELL_NORMAL, "TWT teardown received for flow ID %d\n", + resp->flow_id); + return; + } + if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { print(context.sh, SHELL_NORMAL, "TWT response: %s\n", wifi_twt_setup_cmd2str[resp->setup_cmd]); From 8f601c9e1b4eecee1ae76b9b897e8d85a0fa0b18 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 23 Jun 2023 00:49:04 +0530 Subject: [PATCH 180/528] [nrf fromtree] net: wifi: Fix power save timeout data type This should be an unsigned integer. Also, add a comment to explain this feature. Signed-off-by: Chaitanya Tata (cherry picked from commit a71bff7f49f78aa3d8526ab71e4c9709e9bc51aa) --- include/zephyr/net/wifi_mgmt.h | 8 +++++++- subsys/net/l2/wifi/wifi_shell.c | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 8740d6b4bd45..7f9cb68c5e99 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -203,7 +203,13 @@ struct wifi_ps_params { unsigned short listen_interval; enum wifi_ps_wakeup_mode wakeup_mode; enum wifi_ps_mode mode; - int timeout_ms; + /* This is the time out to wait after sending a TX packet + * before going back to power save (in ms) to receive any replies + * from the AP. Zero means this feature is disabled. + * + * It's a tradeoff between power consumption and latency. + */ + unsigned int timeout_ms; enum ps_param_type type; enum wifi_config_ps_param_fail_reason fail_reason; }; diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 503b009707d4..36ac32e67224 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -593,8 +593,13 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS wake up mode: %s\n", config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", - config.ps_params.timeout_ms); + if (config.ps_params.timeout_ms) { + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", + config.ps_params.timeout_ms); + } else { + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: disabled\n"); + } + if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); @@ -695,8 +700,11 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, - "PS timeout %d ms\n", params.timeout_ms); + if (params.timeout_ms) { + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", params.timeout_ms); + } else { + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: disabled\n"); + } return 0; } From 6102ccb6f7079d193c5d8ad120d84832322b7f9a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:16 +0200 Subject: [PATCH 181/528] Revert "[nrf fromtree] net: wifi: Fix power save timeout data type" This reverts commit 8f601c9e1b4eecee1ae76b9b897e8d85a0fa0b18. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi_mgmt.h | 8 +------- subsys/net/l2/wifi/wifi_shell.c | 16 ++++------------ 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 7f9cb68c5e99..8740d6b4bd45 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -203,13 +203,7 @@ struct wifi_ps_params { unsigned short listen_interval; enum wifi_ps_wakeup_mode wakeup_mode; enum wifi_ps_mode mode; - /* This is the time out to wait after sending a TX packet - * before going back to power save (in ms) to receive any replies - * from the AP. Zero means this feature is disabled. - * - * It's a tradeoff between power consumption and latency. - */ - unsigned int timeout_ms; + int timeout_ms; enum ps_param_type type; enum wifi_config_ps_param_fail_reason fail_reason; }; diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 36ac32e67224..503b009707d4 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -593,13 +593,8 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS wake up mode: %s\n", config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); - if (config.ps_params.timeout_ms) { - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", - config.ps_params.timeout_ms); - } else { - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: disabled\n"); - } - + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", + config.ps_params.timeout_ms); if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); @@ -700,11 +695,8 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] return -ENOEXEC; } - if (params.timeout_ms) { - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", params.timeout_ms); - } else { - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: disabled\n"); - } + shell_fprintf(sh, SHELL_NORMAL, + "PS timeout %d ms\n", params.timeout_ms); return 0; } From bae6da90c8e003cec90e3b75b4cd169fca81a6f3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:16 +0200 Subject: [PATCH 182/528] Revert "[nrf fromtree] net: wifi: Add a message for unsolicited TWT tear down" This reverts commit e405279d21343b0845242416cc306ad580bb3ba5. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_shell.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 503b009707d4..31e722e21229 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -267,12 +267,6 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) const struct wifi_twt_params *resp = (const struct wifi_twt_params *)cb->info; - if (resp->operation == WIFI_TWT_TEARDOWN) { - print(context.sh, SHELL_NORMAL, "TWT teardown received for flow ID %d\n", - resp->flow_id); - return; - } - if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { print(context.sh, SHELL_NORMAL, "TWT response: %s\n", wifi_twt_setup_cmd2str[resp->setup_cmd]); From 1f725464af5559b381f12d0515bfe13b73040c84 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:16 +0200 Subject: [PATCH 183/528] Revert "[nrf fromtree] net: wifi: Add a demarcation print" This reverts commit 6e912903d99c09f575b76e9c343676adcc12d3ca. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_shell.c | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 31e722e21229..3500743b1148 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -270,7 +270,6 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { print(context.sh, SHELL_NORMAL, "TWT response: %s\n", wifi_twt_setup_cmd2str[resp->setup_cmd]); - print(context.sh, SHELL_NORMAL, "== TWT negotiated parameters ==\n"); print_twt_params(resp->dialog_token, resp->flow_id, resp->negotiation_type, From 78f4ea373ab0ebd0e58efd8156bc28a847e8c199 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:16 +0200 Subject: [PATCH 184/528] Revert "[nrf fromtree] net: wifi: Fix tear down messages" This reverts commit baaf2e5412a2349c193eececc5706c437c0498a9. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 3500743b1148..5d833c25f750 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -837,7 +837,7 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d success\n", + shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d requested\n", wifi_twt_operation2str[params.operation], params.dialog_token, params.flow_id); @@ -864,7 +864,7 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s all flows success\n", + shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s all flows\n", wifi_twt_operation2str[params.operation]); return 0; From d95cbec12f485e6331e4700dc84acc15b65c4cf4 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:16 +0200 Subject: [PATCH 185/528] Revert "[nrf fromtree] net: wifi: Add an error code for TWT duplicate flow request" This reverts commit 917d571c71f56d165f6330a6a276d3bc4eb09fae. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index ae9f8cfa6db4..806424475f09 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -352,7 +352,6 @@ enum wifi_twt_fail_reason { WIFI_TWT_FAIL_OPERATION_IN_PROGRESS, WIFI_TWT_FAIL_INVALID_FLOW_ID, WIFI_TWT_FAIL_IP_NOT_ASSIGNED, - WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS, }; static const char * const twt_err_code_tbl[] = { @@ -372,8 +371,6 @@ static const char * const twt_err_code_tbl[] = { "Invalid negotiated flow id", [WIFI_TWT_FAIL_IP_NOT_ASSIGNED] = "IP address not assigned", - [WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS] = - "Flow already exists", }; static inline const char *get_twt_err_code_str(int16_t err_no) From 3e92e41456e583a880ef6786fe9342676b9963b1 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:17 +0200 Subject: [PATCH 186/528] Revert "[nrf fromtree] net: wifi: Disable trigger in TWT quick setup" This reverts commit 99c41e2cef058675a13561e812b5ff92d4c8302c. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 5d833c25f750..47e47830c8e8 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -717,7 +717,7 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, params.flow_id = 0; params.setup.responder = 0; params.setup.implicit = 1; - params.setup.trigger = 0; + params.setup.trigger = 1; params.setup.announce = 0; if (!parse_number(sh, (long *)¶ms.setup.twt_wake_interval, argv[idx++], From 3446afb91c8edda35b9f021650d99f97c3ff0556 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:17 +0200 Subject: [PATCH 187/528] Revert "[nrf fromtree] net: wifi: Do TWT checks only for setup" This reverts commit 88b6c53c713faf340c72ac86047afc347c22e614. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_mgmt.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 3e2e4c234914..2e123f6dd6c5 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -316,10 +316,6 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, return -ENOTSUP; } - if (twt_params->operation == WIFI_TWT_TEARDOWN) { - return off_api->set_twt(dev, twt_params); - } - if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, sizeof(struct wifi_iface_status))) { twt_params->fail_reason = From 1b0cfe979868fcbe1cb38a5db9da917f11d039f9 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:17 +0200 Subject: [PATCH 188/528] Revert "[nrf fromtree] net: wifi: Fix a typo" This reverts commit c114a91105d4f4036f037283969446bfa83e9522. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 806424475f09..75139ae36c48 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -355,7 +355,7 @@ enum wifi_twt_fail_reason { }; static const char * const twt_err_code_tbl[] = { - [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecified", + [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecfied", [WIFI_TWT_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", [WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED] = "Operation not supported", From 53db4a8c78e45e5c8492a788a3fc7aea7a5a606c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:17 +0200 Subject: [PATCH 189/528] Revert "[nrf fromtree] net: wifi_mgmt: Reject TWT setup till IP address is configured" This reverts commit 1b800d818c7d7fa235879f3d3b47240a00d7a92e. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 3 --- subsys/net/l2/wifi/Kconfig | 11 ----------- subsys/net/l2/wifi/wifi_mgmt.c | 12 ------------ 3 files changed, 26 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 75139ae36c48..cace143c93d6 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -351,7 +351,6 @@ enum wifi_twt_fail_reason { WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB, WIFI_TWT_FAIL_OPERATION_IN_PROGRESS, WIFI_TWT_FAIL_INVALID_FLOW_ID, - WIFI_TWT_FAIL_IP_NOT_ASSIGNED, }; static const char * const twt_err_code_tbl[] = { @@ -369,8 +368,6 @@ static const char * const twt_err_code_tbl[] = { "Operation already in progress", [WIFI_TWT_FAIL_INVALID_FLOW_ID] = "Invalid negotiated flow id", - [WIFI_TWT_FAIL_IP_NOT_ASSIGNED] = - "IP address not assigned", }; static inline const char *get_twt_err_code_str(int16_t err_no) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 48bcff3943e6..ecd1d002bc3d 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -27,14 +27,3 @@ config WIFI_MGMT_RAW_SCAN_RESULTS_ONLY to the application. endif # WIFI_MGMT_RAW_SCAN_RESULTS - -config WIFI_MGMT_TWT_CHECK_IP - bool "Check IP Assignment for TWT" - default y - help - This option enables check for valid IP address before TWT setup. - If TWT setup is triggered early in the connection, then device might - enter deep sleep without having a valid IP, this can result in device - being unreachable (IP Level) or unable to receive down link traffic - even when it is awake intervals. Rejecting TWT setup till Wi-Fi - interface has a valid IP address might be desirable in most scenarios. diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 2e123f6dd6c5..4548864fe7c7 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -329,18 +329,6 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, goto fail; } -#ifdef CONFIG_WIFI_MGMT_TWT_CHECK_IP - if ((!net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) && - (!net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface))) { - twt_params->fail_reason = - WIFI_TWT_FAIL_IP_NOT_ASSIGNED; - goto fail; - } -#else - NET_WARN("Check for valid IP address been disabled. " - "Device might be unreachable or might not receive traffic.\n"); -#endif /* CONFIG_WIFI_MGMT_TWT_CHECK_IP */ - if (info.link_mode < WIFI_6) { twt_params->fail_reason = WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB; From e0de05156570cdefa2ab893f8cd2f289ca3cd2f6 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:17 +0200 Subject: [PATCH 190/528] Revert "[nrf fromlist] drivers: timer: add z_nrf_rtc_timer_exact_set" This reverts commit b92f3123358eea8774715b42b4f3741e2eb96d46. Signed-off-by: Robert Lubos --- drivers/timer/nrf_rtc_timer.c | 59 +++++--------------- include/zephyr/drivers/timer/nrf_rtc_timer.h | 31 ---------- 2 files changed, 13 insertions(+), 77 deletions(-) diff --git a/drivers/timer/nrf_rtc_timer.c b/drivers/timer/nrf_rtc_timer.c index c024a82b2061..ef7b2aab574b 100644 --- a/drivers/timer/nrf_rtc_timer.c +++ b/drivers/timer/nrf_rtc_timer.c @@ -231,20 +231,9 @@ uint64_t z_nrf_rtc_timer_get_ticks(k_timeout_t t) * @param[in] chan A channel for which a new CC value is to be set. * * @param[in] req_cc Requested CC register value to be set. - * - * @param[in] exact Use @c false to allow CC adjustment if @c req_cc value is - * close to the current value of the timer. - * Use @c true to disallow CC adjustment. The function can - * fail with -EINVAL result if @p req_cc is too close to the - * current value. - * - * @retval 0 The requested CC has been set successfully. - * @retval -EINVAL The requested CC value could not be reliably set. */ -static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) +static void set_alarm(int32_t chan, uint32_t req_cc) { - int ret = 0; - /* Ensure that the value exposed in this driver API is consistent with * assumptions of this function. */ @@ -311,16 +300,9 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) now = counter(); if (counter_sub(now, req_cc) > COUNTER_HALF_SPAN) { event_clear(chan); - if (exact) { - ret = -EINVAL; - break; - } } else { break; } - } else if (exact) { - ret = -EINVAL; - break; } cc_val = now + cc_inc; @@ -329,13 +311,11 @@ static int set_alarm(int32_t chan, uint32_t req_cc, bool exact) break; } } - - return ret; } static int compare_set_nolocks(int32_t chan, uint64_t target_time, z_nrf_rtc_timer_compare_handler_t handler, - void *user_data, bool exact) + void *user_data) { int ret = 0; uint32_t cc_value = absolute_time_to_cc(target_time); @@ -351,33 +331,29 @@ static int compare_set_nolocks(int32_t chan, uint64_t target_time, /* Target time is valid and is different than currently set. * Set CC value. */ - ret = set_alarm(chan, cc_value, exact); + set_alarm(chan, cc_value); } - } else if (!exact) { + } else { /* Force ISR handling when exiting from critical section. */ atomic_or(&force_isr_mask, BIT(chan)); - } else { - ret = -EINVAL; } - if (ret == 0) { - cc_data[chan].target_time = target_time; - cc_data[chan].callback = handler; - cc_data[chan].user_context = user_data; - } + cc_data[chan].target_time = target_time; + cc_data[chan].callback = handler; + cc_data[chan].user_context = user_data; return ret; } static int compare_set(int32_t chan, uint64_t target_time, z_nrf_rtc_timer_compare_handler_t handler, - void *user_data, bool exact) + void *user_data) { bool key; key = compare_int_lock(chan); - int ret = compare_set_nolocks(chan, target_time, handler, user_data, exact); + int ret = compare_set_nolocks(chan, target_time, handler, user_data); compare_int_unlock(chan, key); @@ -390,16 +366,7 @@ int z_nrf_rtc_timer_set(int32_t chan, uint64_t target_time, { __ASSERT_NO_MSG(chan > 0 && chan < CHAN_COUNT); - return compare_set(chan, target_time, handler, user_data, false); -} - -int z_nrf_rtc_timer_exact_set(int32_t chan, uint64_t target_time, - z_nrf_rtc_timer_compare_handler_t handler, - void *user_data) -{ - __ASSERT_NO_MSG(chan > 0 && chan < CHAN_COUNT); - - return compare_set(chan, target_time, handler, user_data, true); + return compare_set(chan, target_time, handler, user_data); } void z_nrf_rtc_timer_abort(int32_t chan) @@ -480,7 +447,7 @@ static void sys_clock_timeout_handler(int32_t chan, * so it won't get preempted by the interrupt. */ compare_set(chan, last_count + CYC_PER_TICK, - sys_clock_timeout_handler, NULL, false); + sys_clock_timeout_handler, NULL); } sys_clock_announce(dticks); @@ -676,7 +643,7 @@ void sys_clock_set_timeout(int32_t ticks, bool idle) uint64_t target_time = cyc + last_count; - compare_set(0, target_time, sys_clock_timeout_handler, NULL, false); + compare_set(0, target_time, sys_clock_timeout_handler, NULL); } uint32_t sys_clock_elapsed(void) @@ -754,7 +721,7 @@ static int sys_clock_driver_init(void) uint32_t initial_timeout = IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? MAX_CYCLES : CYC_PER_TICK; - compare_set(0, initial_timeout, sys_clock_timeout_handler, NULL, false); + compare_set(0, initial_timeout, sys_clock_timeout_handler, NULL); z_nrf_clock_control_lf_on(mode); diff --git a/include/zephyr/drivers/timer/nrf_rtc_timer.h b/include/zephyr/drivers/timer/nrf_rtc_timer.h index c5992bee4bdd..b11f201386e6 100644 --- a/include/zephyr/drivers/timer/nrf_rtc_timer.h +++ b/include/zephyr/drivers/timer/nrf_rtc_timer.h @@ -127,42 +127,11 @@ uint32_t z_nrf_rtc_timer_compare_read(int32_t chan); * @retval 0 if the compare channel was set successfully. * @retval -EINVAL if provided target time was further than * @c NRF_RTC_TIMER_MAX_SCHEDULE_SPAN ticks in the future. - * - * @sa @ref z_nrf_rtc_timer_exact_set */ int z_nrf_rtc_timer_set(int32_t chan, uint64_t target_time, z_nrf_rtc_timer_compare_handler_t handler, void *user_data); -/** @brief Try to set compare channel exactly to given value. - * - * @note This function is similar to @ref z_nrf_rtc_timer_set, but the compare - * channel will be set to expected value only when it can be guaranteed that - * the hardware event will be generated exactly at expected @c target_time in - * the future. If the @c target_time is in the past or so close in the future - * that the reliable generation of event would require adjustment of compare - * value (as would @ref z_nrf_rtc_timer_set function do), neither the hardware - * event nor interrupt will be generated and the function fails. - * - * @param chan Channel ID between 1 and CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT. - * - * @param target_time Absolute target time in ticks. - * - * @param handler User function called in the context of the RTC interrupt. - * - * @param user_data Data passed to the handler. - * - * @retval 0 if the compare channel was set successfully. - * @retval -EINVAL if provided target time was further than - * @c NRF_RTC_TIMER_MAX_SCHEDULE_SPAN ticks in the future - * or the target time is in the past or is so close in the future that - * event generation could not be guaranteed without adjusting - * compare value of that channel. - */ -int z_nrf_rtc_timer_exact_set(int32_t chan, uint64_t target_time, - z_nrf_rtc_timer_compare_handler_t handler, - void *user_data); - /** @brief Abort a timer requested with @ref z_nrf_rtc_timer_set. * * If an abort operation is performed too late it is still possible for an event From fd644aaaee1fe81e4e7c4b5a5d1aef7437008065 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:18 +0200 Subject: [PATCH 191/528] Revert "[nrf fromlist] net: openthread: configure OPENTHREAD_CSL_TIMEOUT" This reverts commit 59f4a55ce4279c95db0b67326ec4a82938095ac4. Signed-off-by: Robert Lubos --- modules/openthread/Kconfig.thread | 6 ------ .../platform/openthread-core-zephyr-config.h | 10 ---------- 2 files changed, 16 deletions(-) diff --git a/modules/openthread/Kconfig.thread b/modules/openthread/Kconfig.thread index 0a7a399e9032..d2480c8ca122 100644 --- a/modules/openthread/Kconfig.thread +++ b/modules/openthread/Kconfig.thread @@ -106,12 +106,6 @@ config OPENTHREAD_PLATFORM_CSL_UNCERT help The fixed uncertainty of the Device for scheduling CSL Transmissions in units of 10 microseconds. -config OPENTHREAD_CSL_TIMEOUT - int "CSL timeout in seconds" - default 100 - help - The default CSL timeout in seconds. - config OPENTHREAD_MAC_SOFTWARE_TX_SECURITY_ENABLE bool "Software transmission security logic" default y if !OPENTHREAD_THREAD_VERSION_1_1 diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 7eaccf7948df..256e433a81b5 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -304,16 +304,6 @@ #define OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER #endif /* CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER */ -/** - * @def OPENTHREAD_CONFIG_CSL_TIMEOUT - * - * The default CSL timeout in seconds. - * - */ -#ifdef CONFIG_OPENTHREAD_CSL_TIMEOUT -#define OPENTHREAD_CONFIG_CSL_TIMEOUT CONFIG_OPENTHREAD_CSL_TIMEOUT -#endif /* CONFIG_OPENTHREAD_CSL_TIMEOUT */ - /** * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE * From e1c76a91670596b6123e9f9c6b27b81debd8df62 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:18 +0200 Subject: [PATCH 192/528] Revert "[nrf fromtree] net: l2: ethernet: Fix IPv6 Kconfig" This reverts commit 1210ab0a4d243aefc06f1664a2be24fd6ac10e74. Signed-off-by: Robert Lubos --- subsys/net/l2/ethernet/ethernet_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/ethernet/ethernet_mgmt.c b/subsys/net/l2/ethernet/ethernet_mgmt.c index e7fcae8ac99a..26eea7369f52 100644 --- a/subsys/net/l2/ethernet/ethernet_mgmt.c +++ b/subsys/net/l2/ethernet/ethernet_mgmt.c @@ -98,7 +98,7 @@ static int ethernet_set_config(uint32_t mgmt_request, * generated from old MAC address, from network interface if * needed. */ - if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6)) { + if (IS_ENABLED(CONFIG_NET_IPV6)) { struct in6_addr iid; net_ipv6_addr_create_iid(&iid, From 608c8ae05a2a3ba751b4ef573ca335167cfd3872 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:18 +0200 Subject: [PATCH 193/528] Revert "[nrf fromtree] scripts: adjust WEST_PYTHON to posix path" This reverts commit 5385c25be98b6812b765d9ce90e3b2f8a03c5bf1. Signed-off-by: Robert Lubos --- scripts/west_commands/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/west_commands/build.py b/scripts/west_commands/build.py index 18b656a50008..6797ff1c48d0 100644 --- a/scripts/west_commands/build.py +++ b/scripts/west_commands/build.py @@ -497,7 +497,7 @@ def _run_cmake(self, board, origin, cmake_opts): # to Just Work: # # west build -- -DOVERLAY_CONFIG=relative-path.conf - final_cmake_args = ['-DWEST_PYTHON={}'.format(pathlib.Path(sys.executable).as_posix()), + final_cmake_args = ['-DWEST_PYTHON={}'.format(sys.executable), '-B{}'.format(self.build_dir), '-G{}'.format(config_get('generator', DEFAULT_CMAKE_GENERATOR))] From 2c1cc141e6df1a6cbc532177402ad8b87a2e563d Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:18 +0200 Subject: [PATCH 194/528] Revert "[nrf fromtree] doc: CoAP client documentation and sample" This reverts commit 2f5e820792d145c7a460f6c192c83e81d5348ddc. Signed-off-by: Robert Lubos --- .../networking/api/coap_client.rst | 84 ------------------- doc/connectivity/networking/api/protocols.rst | 1 - 2 files changed, 85 deletions(-) delete mode 100644 doc/connectivity/networking/api/coap_client.rst diff --git a/doc/connectivity/networking/api/coap_client.rst b/doc/connectivity/networking/api/coap_client.rst deleted file mode 100644 index 2251bb3d0da6..000000000000 --- a/doc/connectivity/networking/api/coap_client.rst +++ /dev/null @@ -1,84 +0,0 @@ -.. _coap_client_interface: - -CoAP client -########### - -.. contents:: - :local: - :depth: 2 - -Overview -******** - -The CoAP client library allows application to send CoAP requests and parse CoAP responses. -The application is notified about the response via a callback that is provided to the API -in the request. The CoAP client handles the communication over sockets. -As the CoAP client doesn't create socket it is using, the application is responsible for creating -the socket. Plain UDP or DTLS sockets are supported. - -Sample Usage -************ - -The following is an example of a CoAP client initialization and request sending: - -.. code-block:: c - - static struct coap_client; - struct coap_client_request req = { 0 }; - - coap_client_init(&client, NULL); - - req.method = COAP_METHOD_GET; - req.confirmable = true; - req.path = "test"; - req.fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN; - req.cb = response_cb; - req.payload = NULL; - req.len = 0; - - /* Sock is a file descriptor referencing a socket, address is the sockaddr struct for the - * destination address of the request or NULL if the socket is already connected. - */ - ret = coap_client_req(&client, sock, &address, &req, -1); - -Before any requests can be sent, the CoAP client needs to be initialized. -After initialization, the application can send a CoAP request and wait for the response. -Currently only one request can be sent for a single CoAP client at a time. There can be multiple -CoAP clients. - -The callback provided in the callback will be called in following cases: - -- There is a response for the request -- The request failed for some reason - -The callback contains a flag `last_block`, which indicates if there is more data to come in the -response and means that the current response is part of a blockwise transfer. When the `last_block` -is set to true, the response is finished and the client is ready for the next request after -returning from the callback. - -If the server responds to the request, the library provides the response to the -application through the response callback registered in the request structure. -As the response can be a blockwise transfer and the client calls the callback once per each -block, the application should be to process all of the blocks to be able to process the response. - -The following is an example of a very simple response handling function: - -.. code-block:: c - - void response_cb(int16_t code, size_t offset, const uint8_t *payload, size_t len, - bool last_block, void *user_data) - { - if (code >= 0) { - LOG_INF("CoAP response from server %d", code); - if (last_block) { - LOG_INF("Last packet received"); - } - } else { - LOG_ERR("Error in sending request %d", code); - } - } - -API Reference -************* - -.. doxygengroup:: coap_client diff --git a/doc/connectivity/networking/api/protocols.rst b/doc/connectivity/networking/api/protocols.rst index 6ed46130fa56..f9d3d775e92f 100644 --- a/doc/connectivity/networking/api/protocols.rst +++ b/doc/connectivity/networking/api/protocols.rst @@ -8,7 +8,6 @@ Protocols :maxdepth: 1 coap - coap_client http lwm2m mqtt From 9c890502a9e366864af36b3b9324ed77eb49fd6e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:18 +0200 Subject: [PATCH 195/528] Revert "[nrf fromtree] tests: Add ztest tests for coap client" This reverts commit 5c8d51e3592753c0772a8d04ab329b6578f1a36d. Signed-off-by: Robert Lubos --- tests/net/lib/coap_client/CMakeLists.txt | 28 -- tests/net/lib/coap_client/prj.conf | 4 - tests/net/lib/coap_client/src/main.c | 354 ----------------------- tests/net/lib/coap_client/src/stubs.c | 52 ---- tests/net/lib/coap_client/src/stubs.h | 39 --- tests/net/lib/coap_client/testcase.yaml | 6 - 6 files changed, 483 deletions(-) delete mode 100644 tests/net/lib/coap_client/CMakeLists.txt delete mode 100644 tests/net/lib/coap_client/prj.conf delete mode 100644 tests/net/lib/coap_client/src/main.c delete mode 100644 tests/net/lib/coap_client/src/stubs.c delete mode 100644 tests/net/lib/coap_client/src/stubs.h delete mode 100644 tests/net/lib/coap_client/testcase.yaml diff --git a/tests/net/lib/coap_client/CMakeLists.txt b/tests/net/lib/coap_client/CMakeLists.txt deleted file mode 100644 index 60506c23c2d3..000000000000 --- a/tests/net/lib/coap_client/CMakeLists.txt +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(coap_client_test) - -set(APP_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) - -# Add test sources -target_sources(app PRIVATE ${APP_SRC_DIR}/main.c) -target_sources(app PRIVATE ${APP_SRC_DIR}/stubs.c) -target_sources(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/coap/coap_client.c) -target_sources(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/coap/coap.c) - -# Add includes directories -target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) -target_include_directories(app PRIVATE ${ZEPHYR_BASE}/include/) - -add_compile_definitions(CONFIG_NET_SOCKETS_POLL_MAX=3) -add_compile_definitions(CONFIG_COAP_CLIENT=y) -add_compile_definitions(CONFIG_COAP_CLIENT_BLOCK_SIZE=256) -add_compile_definitions(CONFIG_COAP_CLIENT_MESSAGE_SIZE=256) -add_compile_definitions(CONFIG_COAP_CLIENT_MESSAGE_HEADER_SIZE=48) -add_compile_definitions(CONFIG_COAP_CLIENT_STACK_SIZE=1024) -add_compile_definitions(CONFIG_COAP_CLIENT_THREAD_PRIORITY=10) -add_compile_definitions(CONFIG_COAP_LOG_LEVEL=4) -add_compile_definitions(CONFIG_NET_SOCKETS_POSIX_NAMES=y) -add_compile_definitions(CONFIG_COAP_INIT_ACK_TIMEOUT_MS=2000) diff --git a/tests/net/lib/coap_client/prj.conf b/tests/net/lib/coap_client/prj.conf deleted file mode 100644 index d185b3e493cf..000000000000 --- a/tests/net/lib/coap_client/prj.conf +++ /dev/null @@ -1,4 +0,0 @@ -#Testing -CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y -CONFIG_ZTEST_STACK_SIZE=4096 diff --git a/tests/net/lib/coap_client/src/main.c b/tests/net/lib/coap_client/src/main.c deleted file mode 100644 index 8cfc70a93dc3..000000000000 --- a/tests/net/lib/coap_client/src/main.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#include "stubs.h" - -LOG_MODULE_REGISTER(coap_client_test); - -DEFINE_FFF_GLOBALS; -#define FFF_FAKES_LIST(FAKE) - -static uint8_t last_response_code; -static const char *test_path = "test"; -static uint16_t last_message_id; - -static struct coap_client client; - -static char *short_payload = "testing"; -static char *long_payload = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " - "eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut " - "enim ad minim veniam, quis nostrud exercitation ullamco laboris " - "nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor " - "in reprehenderit in voluptate velit esse cillum dolore eu fugiat" - " nulla pariatur. Excepteur sint occaecat cupidatat non proident," - " sunt in culpa qui officia deserunt mollit anim id est laborum."; - -static ssize_t z_impl_zsock_recvfrom_custom_fake(int sock, void *buf, size_t max_len, int flags, - struct sockaddr *src_addr, socklen_t *addrlen) -{ - LOG_INF("Recvfrom"); - static uint8_t ack_data[] = { - 0x68, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - ack_data[2] = (uint8_t) last_message_id >> 8; - ack_data[3] = (uint8_t) last_message_id; - - memcpy(buf, ack_data, sizeof(ack_data)); - - return sizeof(ack_data); -} - -static ssize_t z_impl_zsock_sendto_custom_fake(int sock, void *buf, size_t len, - int flags, const struct sockaddr *dest_addr, - socklen_t addrlen) -{ - LOG_INF("Sendto"); - last_message_id = 0; - last_message_id |= ((uint8_t *) buf)[2] << 8; - last_message_id |= ((uint8_t *) buf)[3]; - - last_response_code = ((uint8_t *) buf)[1]; - - LOG_INF("Latest message ID: %d", last_message_id); - return 1; -} - -static ssize_t z_impl_zsock_recvfrom_custom_fake_response(int sock, void *buf, size_t max_len, - int flags, struct sockaddr *src_addr, - socklen_t *addrlen) -{ - static uint8_t ack_data[] = { - 0x48, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - ack_data[2] = (uint8_t) last_message_id >> 8; - ack_data[3] = (uint8_t) last_message_id; - - memcpy(buf, ack_data, sizeof(ack_data)); - - return sizeof(ack_data); -} - -static ssize_t z_impl_zsock_recvfrom_custom_fake_empty_ack(int sock, void *buf, size_t max_len, - int flags, struct sockaddr *src_addr, - socklen_t *addrlen) -{ - static uint8_t ack_data[] = { - 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }; - - ack_data[2] = (uint8_t) last_message_id >> 8; - ack_data[3] = (uint8_t) last_message_id; - - memcpy(buf, ack_data, sizeof(ack_data)); - - z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_response; - - return sizeof(ack_data); -} - -static ssize_t z_impl_zsock_recvfrom_custom_fake_unmatching(int sock, void *buf, size_t max_len, - int flags, struct sockaddr *src_addr, - socklen_t *addrlen) -{ - static uint8_t ack_data[] = { - 0x68, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 - }; - - ack_data[2] = (uint8_t) last_message_id >> 8; - ack_data[3] = (uint8_t) last_message_id; - - memcpy(buf, ack_data, sizeof(ack_data)); - - return sizeof(ack_data); -} - -static void *suite_setup(void) -{ - coap_client_init(&client, NULL); - - return NULL; -} - -static void test_setup(void *data) -{ - /* Register resets */ - DO_FOREACH_FAKE(RESET_FAKE); - /* reset common FFF internal structures */ - FFF_RESET_HISTORY(); - - z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake; - z_impl_zsock_sendto_fake.custom_fake = z_impl_zsock_sendto_custom_fake; -} - -void coap_callback(int16_t code, size_t offset, const uint8_t *payload, size_t len, bool last_block, - void *user_data) -{ - LOG_INF("CoAP response callback, %d", code); - last_response_code = code; -} - -ZTEST_SUITE(coap_client, NULL, suite_setup, test_setup, NULL, NULL); - -ZTEST(coap_client, test_get_request) -{ - int ret = 0; - struct sockaddr address; - struct coap_client_request client_request = { - .method = COAP_METHOD_GET, - .confirmable = true, - .path = test_path, - .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, - .cb = coap_callback, - .payload = NULL, - .len = 0 - }; - - client_request.payload = short_payload; - client_request.len = strlen(short_payload); - - k_sleep(K_MSEC(1)); - - LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); - zassert_true(ret >= 0, "Sending request failed, %d", ret); - set_socket_events(ZSOCK_POLLIN); - - k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); - zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); -} - -ZTEST(coap_client, test_get_no_path) -{ - int ret = 0; - struct sockaddr address; - struct coap_client_request client_request = { - .method = COAP_METHOD_GET, - .confirmable = true, - .path = NULL, - .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, - .cb = coap_callback, - .payload = NULL, - .len = 0 - }; - - client_request.payload = short_payload; - client_request.len = strlen(short_payload); - - k_sleep(K_MSEC(1)); - - LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); - - zassert_equal(ret, -EINVAL, "Get request without path"); -} - -ZTEST(coap_client, test_send_large_data) -{ - int ret = 0; - struct sockaddr address; - struct coap_client_request client_request = { - .method = COAP_METHOD_GET, - .confirmable = true, - .path = test_path, - .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, - .cb = coap_callback, - .payload = NULL, - .len = 0 - }; - - client_request.payload = long_payload; - client_request.len = strlen(long_payload); - - k_sleep(K_MSEC(1)); - - LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); - zassert_true(ret >= 0, "Sending request failed, %d", ret); - set_socket_events(ZSOCK_POLLIN); - - k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); - zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); -} - -ZTEST(coap_client, test_no_response) -{ - int ret = 0; - struct sockaddr address; - struct coap_client_request client_request = { - .method = COAP_METHOD_GET, - .confirmable = true, - .path = test_path, - .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, - .cb = coap_callback, - .payload = NULL, - .len = 0 - }; - - client_request.payload = short_payload; - client_request.len = strlen(short_payload); - - k_sleep(K_MSEC(1)); - - LOG_INF("Send request"); - clear_socket_events(); - ret = coap_client_req(&client, 0, &address, &client_request, -1); - - zassert_true(ret >= 0, "Sending request failed, %d", ret); - k_sleep(K_MSEC(1000)); -} - -ZTEST(coap_client, test_separate_response) -{ - int ret = 0; - struct sockaddr address; - struct coap_client_request client_request = { - .method = COAP_METHOD_GET, - .confirmable = true, - .path = test_path, - .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, - .cb = coap_callback, - .payload = NULL, - .len = 0 - }; - - client_request.payload = short_payload; - client_request.len = strlen(short_payload); - - z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_empty_ack; - - k_sleep(K_MSEC(1)); - - LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); - zassert_true(ret >= 0, "Sending request failed, %d", ret); - set_socket_events(ZSOCK_POLLIN); - - k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); - - k_sleep(K_MSEC(1000)); - - zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); -} - -ZTEST(coap_client, test_multiple_requests) -{ - int ret = 0; - struct sockaddr address; - struct coap_client_request client_request = { - .method = COAP_METHOD_GET, - .confirmable = true, - .path = test_path, - .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, - .cb = coap_callback, - .payload = NULL, - .len = 0 - }; - - client_request.payload = short_payload; - client_request.len = strlen(short_payload); - - k_sleep(K_MSEC(1)); - set_socket_events(ZSOCK_POLLIN); - - LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, -1); - zassert_true(ret >= 0, "Sending request failed, %d", ret); - - ret = coap_client_req(&client, 0, &address, &client_request, -1); - zassert_equal(ret, -EAGAIN, "Shouldn't be able to send 2 requests at same time"); - - k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); - zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); - - ret = coap_client_req(&client, 0, &address, &client_request, -1); - zassert_true(ret >= 0, "Sending request failed, %d", ret); - - k_sleep(K_MSEC(5)); - k_sleep(K_MSEC(1000)); - zassert_equal(last_response_code, COAP_RESPONSE_CODE_OK, "Unexpected response"); -} - -ZTEST(coap_client, test_unmatching_tokens) -{ - int ret = 0; - struct sockaddr address; - struct coap_client_request client_request = { - .method = COAP_METHOD_GET, - .confirmable = true, - .path = test_path, - .fmt = COAP_CONTENT_FORMAT_TEXT_PLAIN, - .cb = coap_callback, - .payload = NULL, - .len = 0 - }; - - client_request.payload = short_payload; - client_request.len = strlen(short_payload); - - z_impl_zsock_recvfrom_fake.custom_fake = z_impl_zsock_recvfrom_custom_fake_unmatching; - - LOG_INF("Send request"); - ret = coap_client_req(&client, 0, &address, &client_request, 0); - zassert_true(ret >= 0, "Sending request failed, %d", ret); - set_socket_events(ZSOCK_POLLIN); - - k_sleep(K_MSEC(1)); - k_sleep(K_MSEC(1)); - clear_socket_events(); - zassert_equal(last_response_code, COAP_RESPONSE_CODE_NOT_FOUND, "Unexpected response %d", - last_response_code); - k_sleep(K_MSEC(1)); -} diff --git a/tests/net/lib/coap_client/src/stubs.c b/tests/net/lib/coap_client/src/stubs.c deleted file mode 100644 index 13effd8f91b9..000000000000 --- a/tests/net/lib/coap_client/src/stubs.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include - -LOG_MODULE_DECLARE(coap_client_test); - -DEFINE_FAKE_VALUE_FUNC(uint32_t, z_impl_sys_rand32_get); -DEFINE_FAKE_VOID_FUNC(z_impl_sys_rand_get, void *, size_t); -DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_recvfrom, int, void *, size_t, int, struct sockaddr *, - socklen_t *); -DEFINE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void*, size_t, int, - const struct sockaddr *, socklen_t); - -struct zsock_pollfd { - int fd; - short events; - short revents; -}; - -static short my_events; - -void set_socket_events(short events) -{ - my_events |= events; -} - -void clear_socket_events(void) -{ - my_events = 0; -} - -int z_impl_zsock_socket(int family, int type, int proto) -{ - return 0; -} - -int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) -{ - LOG_INF("Polling, events %d", my_events); - k_sleep(K_MSEC(10)); - fds->revents = my_events; - if (my_events) { - return 1; - } else { - return 0; - } -} diff --git a/tests/net/lib/coap_client/src/stubs.h b/tests/net/lib/coap_client/src/stubs.h deleted file mode 100644 index eb340d914eb9..000000000000 --- a/tests/net/lib/coap_client/src/stubs.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef STUBS_H -#define STUBS_H - -#include -#include - -#include -#include - -#include - -#define ZSOCK_POLLIN 1 -#define ZSOCK_POLLOUT 4 - -void set_socket_events(short events); -void clear_socket_events(void); - -DECLARE_FAKE_VALUE_FUNC(uint32_t, z_impl_sys_rand32_get); -DECLARE_FAKE_VOID_FUNC(z_impl_sys_rand_get, void *, size_t); -DECLARE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_recvfrom, int, void *, size_t, int, struct sockaddr *, - socklen_t *); -DECLARE_FAKE_VALUE_FUNC(ssize_t, z_impl_zsock_sendto, int, void*, size_t, int, - const struct sockaddr *, socklen_t); - -#define DO_FOREACH_FAKE(FUNC) \ - do { \ - FUNC(z_impl_sys_rand32_get) \ - FUNC(z_impl_sys_rand_get) \ - FUNC(z_impl_zsock_recvfrom) \ - FUNC(z_impl_zsock_sendto) \ - } while (0) - -#endif /* STUBS_H */ diff --git a/tests/net/lib/coap_client/testcase.yaml b/tests/net/lib/coap_client/testcase.yaml deleted file mode 100644 index 923e1380f010..000000000000 --- a/tests/net/lib/coap_client/testcase.yaml +++ /dev/null @@ -1,6 +0,0 @@ -common: - depends_on: netif -tests: - net.coap.client: - platform_allow: native_posix - tags: coap net From 5aa7fea028dd6eecf33361a2c99dfda7cd04f23f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:18 +0200 Subject: [PATCH 196/528] Revert "[nrf fromtree] net: lib: coap: Add an asynchronous coap client" This reverts commit e726728e24b87740162890f39a13030ed08bacc7. Signed-off-by: Robert Lubos --- include/zephyr/net/coap_client.h | 139 ------ subsys/net/lib/coap/CMakeLists.txt | 4 - subsys/net/lib/coap/Kconfig | 41 -- subsys/net/lib/coap/coap_client.c | 742 ----------------------------- 4 files changed, 926 deletions(-) delete mode 100644 include/zephyr/net/coap_client.h delete mode 100644 subsys/net/lib/coap/coap_client.c diff --git a/include/zephyr/net/coap_client.h b/include/zephyr/net/coap_client.h deleted file mode 100644 index dc5d008c1b74..000000000000 --- a/include/zephyr/net/coap_client.h +++ /dev/null @@ -1,139 +0,0 @@ -/** @file - * @brief CoAP client API - * - * An API for applications to do CoAP requests - */ - -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ -#ifndef ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_ -#define ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_ - -/** - * @brief CoAP client API - * @defgroup coap_client CoAP client API - * @ingroup networking - * @{ - */ - -#include - - -#define MAX_COAP_MSG_LEN (CONFIG_COAP_CLIENT_MESSAGE_HEADER_SIZE + \ - CONFIG_COAP_CLIENT_MESSAGE_SIZE) - -/** - * @typedef coap_client_response_cb_t - * @brief Callback for CoAP request. - * - * This callback is called for responses to CoAP client requests. - * It is used to indicate errors, response codes from server or to deliver payload. - * Blockwise transfers cause this callback to be called sequentially with increasing payload offset - * and only partial content in buffer pointed by payload parameter. - * - * @param result_code Result code of the response. Negative if there was a failure in send. - * @ref coap_response_code for positive. - * @param offset Payload offset from the beginning of a blockwise transfer. - * @param payload Buffer containing the payload from the response. NULL for empty payload. - * @param len Size of the payload. - * @param last_block Indicates the last block of the response. - * @param user_data User provided context. - */ -typedef void (*coap_client_response_cb_t)(int16_t result_code, - size_t offset, const uint8_t *payload, size_t len, - bool last_block, void *user_data); - -/** - * @brief Representation of a CoAP client request. - */ -struct coap_client_request { - enum coap_method method; /**< Method of the request */ - bool confirmable; /**< CoAP Confirmable/Non-confirmable message */ - const char *path; /**< Path of the requested resource */ - enum coap_content_format fmt; /**< Content format to be used */ - uint8_t *payload; /**< User allocated buffer for send request */ - size_t len; /**< Length of the payload */ - coap_client_response_cb_t cb; /**< Callback when response received */ - struct coap_client_option *options; /**< Extra options to be added to request */ - uint8_t num_options; /**< Number of extra options */ - void *user_data; /**< User provided context */ -}; - -/** - * @brief Representation of extra options for the CoAP client request - */ -struct coap_client_option { - uint16_t code; -#if defined(CONFIG_COAP_EXTENDED_OPTIONS_LEN) - uint16_t len; - uint8_t value[CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE]; -#else - uint8_t len; - uint8_t value[12]; -#endif -}; - -/** @cond INTERNAL_HIDDEN */ -struct coap_client { - int fd; - struct sockaddr address; - socklen_t socklen; - uint8_t send_buf[MAX_COAP_MSG_LEN]; - uint8_t recv_buf[MAX_COAP_MSG_LEN]; - uint8_t request_token[COAP_TOKEN_MAX_LEN]; - int request_tkl; - int offset; - int retry_count; - struct coap_block_context recv_blk_ctx; - struct coap_block_context send_blk_ctx; - struct coap_pending pending; - struct coap_client_request *coap_request; - struct coap_packet request; - k_tid_t tid; - struct k_thread thread; - struct k_sem coap_client_recv_sem; - atomic_t coap_client_recv_active; - - K_THREAD_STACK_MEMBER(coap_thread_stack, CONFIG_COAP_CLIENT_STACK_SIZE); -}; -/** @endcond */ - -/** - * @brief Initialize the CoAP client. - * - * @param[in] client Client instance. - * @param[in] info Name for the receiving thread of the client. Setting this NULL will result as - * default name of "coap_client". - * - * @return int Zero on success, otherwise a negative error code. - */ -int coap_client_init(struct coap_client *client, const char *info); - -/** - * @brief Send CoAP request - * - * Operation is handled asynchronously using a background thread. - * If the socket isn't connected to a destination address, user must provide a destination address, - * otherwise the address should be set as NULL. - * Once the callback is called with last block set as true, socket can be closed or - * used for another query. - * - * @param client Client instance. - * @param sock Open socket file descriptor. - * @param addr the destination address of the request. - * @param req CoAP request structure - * @param retries How many times to retry or -1 to use default. - * @return zero when operation started successfully or negative error code otherwise. - */ - -int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr, - struct coap_client_request *req, int retries); - -/** - * @} - */ - -#endif /* ZEPHYR_INCLUDE_NET_COAP_CLIENT_H_ */ diff --git a/subsys/net/lib/coap/CMakeLists.txt b/subsys/net/lib/coap/CMakeLists.txt index 39ef8196fbba..d97d0e30da3e 100644 --- a/subsys/net/lib/coap/CMakeLists.txt +++ b/subsys/net/lib/coap/CMakeLists.txt @@ -6,7 +6,3 @@ zephyr_sources_ifdef(CONFIG_COAP coap.c coap_link_format.c ) - -zephyr_sources_ifdef(CONFIG_COAP_CLIENT - coap_client.c -) diff --git a/subsys/net/lib/coap/Kconfig b/subsys/net/lib/coap/Kconfig index 12a7c0c9b006..06f7ea2e7e7c 100644 --- a/subsys/net/lib/coap/Kconfig +++ b/subsys/net/lib/coap/Kconfig @@ -94,47 +94,6 @@ config COAP_KEEP_USER_DATA help This option enables keeping application-specific user data -config COAP_CLIENT - bool "CoAP client support [EXPERIMENTAL]" - select EXPERIMENTAL - help - This option enables the API for CoAP-client for sending CoAP requests - -if COAP_CLIENT - -config COAP_CLIENT_THREAD_PRIORITY - int "Coap client thread priority" - default NUM_PREEMPT_PRIORITIES - help - Priority of receive thread of the CoAP client. - -config COAP_CLIENT_BLOCK_SIZE - int "LWM2M CoAP block-wise transfer size" - default 256 - range 64 1024 - help - CoAP block size used by CoAP client when performing block-wise - transfers. Possible values: 64, 128, 256, 512 and 1024. - -config COAP_CLIENT_MESSAGE_SIZE - int "Message payload size" - default COAP_CLIENT_BLOCK_SIZE - help - CoAP client message payload size. Can't be smaller than COAP_CLIENT_BLOCK_SIZE. - -config COAP_CLIENT_MESSAGE_HEADER_SIZE - int "Room for CoAP header data" - default 48 - range 24 128 - help - Extra room allocated to handle CoAP header data - -config COAP_CLIENT_STACK_SIZE - int "Stack size of the CoAP client thread" - default 1024 - -endif # COAP_CLIENT - module = COAP module-dep = NET_LOG module-str = Log level for CoAP diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c deleted file mode 100644 index ce20cd3bd855..000000000000 --- a/subsys/net/lib/coap/coap_client.c +++ /dev/null @@ -1,742 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -LOG_MODULE_DECLARE(net_coap, CONFIG_COAP_LOG_LEVEL); - -#include - -#include -#include - -#define COAP_VERSION 1 -#define COAP_PATH_ELEM_DELIM '/' -#define COAP_PATH_ELEM_QUERY '?' -#define COAP_PATH_ELEM_AMP '&' -#define COAP_SEPARATE_TIMEOUT 6000 -#define DEFAULT_RETRY_AMOUNT 5 -#define BLOCK1_OPTION_SIZE 4 -#define PAYLOAD_MARKER_SIZE 1 - -static int coap_client_schedule_poll(struct coap_client *client, int sock, - struct coap_client_request *req) -{ - client->fd = sock; - client->coap_request = req; - - k_sem_give(&client->coap_client_recv_sem); - atomic_set(&client->coap_client_recv_active, 1); - - return 0; -} - -static int send_request(int sock, const void *buf, size_t len, int flags, - const struct sockaddr *dest_addr, socklen_t addrlen) -{ - if (addrlen == 0) { - return sendto(sock, buf, len, flags, NULL, 0); - } else { - return sendto(sock, buf, len, flags, dest_addr, addrlen); - } -} - -static int receive(int sock, void *buf, size_t max_len, int flags, - struct sockaddr *src_addr, socklen_t *addrlen) -{ - if (*addrlen == 0) { - return recvfrom(sock, buf, max_len, flags, NULL, NULL); - } else { - return recvfrom(sock, buf, max_len, flags, src_addr, addrlen); - } -} - -static void reset_block_contexts(struct coap_client *client) -{ - client->recv_blk_ctx.block_size = 0; - client->recv_blk_ctx.total_size = 0; - client->recv_blk_ctx.current = 0; - - client->send_blk_ctx.block_size = 0; - client->send_blk_ctx.total_size = 0; - client->send_blk_ctx.current = 0; -} - -static int coap_client_init_path_options(struct coap_packet *pckt, const char *path) -{ - int ret = 0; - int path_start, path_end; - int path_length; - bool contains_query = false; - int i; - - path_start = 0; - path_end = 0; - path_length = strlen(path); - for (i = 0; i < path_length; i++) { - path_end = i; - if (path[i] == COAP_PATH_ELEM_DELIM) { - /* Guard for preceding delimiters */ - if (path_start < path_end) { - ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH, - path + path_start, - path_end - path_start); - if (ret < 0) { - LOG_ERR("Failed to append path to CoAP message"); - goto out; - } - } - /* Check if there is a new path after delimiter, - * if not, point to the end of string to not add - * new option after this - */ - if (path_length > i + 1) { - path_start = i + 1; - } else { - path_start = path_length; - } - } else if (path[i] == COAP_PATH_ELEM_QUERY) { - /* Guard for preceding delimiters */ - if (path_start < path_end) { - ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH, - path + path_start, - path_end - path_start); - if (ret < 0) { - LOG_ERR("Failed to append path to CoAP message"); - goto out; - } - } - /* Rest of the path is query */ - contains_query = true; - if (path_length > i + 1) { - path_start = i + 1; - } else { - path_start = path_length; - } - break; - } - } - - if (contains_query) { - for (i = path_start; i < path_length; i++) { - path_end = i; - if (path[i] == COAP_PATH_ELEM_AMP || path[i] == COAP_PATH_ELEM_QUERY) { - /* Guard for preceding delimiters */ - if (path_start < path_end) { - ret = coap_packet_append_option(pckt, COAP_OPTION_URI_QUERY, - path + path_start, - path_end - path_start); - if (ret < 0) { - LOG_ERR("Failed to append path to CoAP message"); - goto out; - } - } - /* Check if there is a new query option after delimiter, - * if not, point to the end of string to not add - * new option after this - */ - if (path_length > i + 1) { - path_start = i + 1; - } else { - path_start = path_length; - } - } - } - } - - if (path_start < path_end) { - if (contains_query) { - ret = coap_packet_append_option(pckt, COAP_OPTION_URI_QUERY, - path + path_start, - path_end - path_start + 1); - } else { - ret = coap_packet_append_option(pckt, COAP_OPTION_URI_PATH, - path + path_start, - path_end - path_start + 1); - } - if (ret < 0) { - LOG_ERR("Failed to append path to CoAP message"); - goto out; - } - } - -out: - return ret; -} - -static enum coap_block_size coap_client_default_block_size(void) -{ - switch (CONFIG_COAP_CLIENT_BLOCK_SIZE) { - case 16: - return COAP_BLOCK_16; - case 32: - return COAP_BLOCK_32; - case 64: - return COAP_BLOCK_64; - case 128: - return COAP_BLOCK_128; - case 256: - return COAP_BLOCK_256; - case 512: - return COAP_BLOCK_512; - case 1024: - return COAP_BLOCK_1024; - } - - return COAP_BLOCK_256; -} - -static int coap_client_init_request(struct coap_client *client, - struct coap_client_request *req) -{ - int ret = 0; - int i; - - memset(client->send_buf, 0, sizeof(client->send_buf)); - ret = coap_packet_init(&client->request, client->send_buf, MAX_COAP_MSG_LEN, 1, - req->confirmable ? COAP_TYPE_CON : COAP_TYPE_NON_CON, - COAP_TOKEN_MAX_LEN, coap_next_token(), req->method, - coap_next_id()); - - if (ret < 0) { - LOG_ERR("Failed to init CoAP message %d", ret); - goto out; - } - - ret = coap_client_init_path_options(&client->request, req->path); - - if (ret < 0) { - LOG_ERR("Failed to parse path to options %d", ret); - goto out; - } - - ret = coap_append_option_int(&client->request, COAP_OPTION_CONTENT_FORMAT, req->fmt); - - if (ret < 0) { - LOG_ERR("Failed to append content format option"); - goto out; - } - - /* Blockwise receive ongoing, request next block. */ - if (client->recv_blk_ctx.current > 0) { - ret = coap_append_block2_option(&client->request, &client->recv_blk_ctx); - - if (ret < 0) { - LOG_ERR("Failed to append block 2 option"); - goto out; - } - } - - /* Add extra options if any */ - for (i = 0; i < req->num_options; i++) { - ret = coap_packet_append_option(&client->request, req->options[i].code, - req->options[i].value, req->options[i].len); - - if (ret < 0) { - LOG_ERR("Failed to append %d option", req->options[i].code); - goto out; - } - } - - if (req->payload) { - uint16_t payload_len; - uint16_t offset; - - /* Blockwise send ongoing, add block1 */ - if (client->send_blk_ctx.total_size > 0 || - (req->len > CONFIG_COAP_CLIENT_MESSAGE_SIZE)) { - - if (client->send_blk_ctx.total_size == 0) { - coap_block_transfer_init(&client->send_blk_ctx, - coap_client_default_block_size(), - req->len); - } - ret = coap_append_block1_option(&client->request, &client->send_blk_ctx); - - if (ret < 0) { - LOG_ERR("Failed to append block1 option"); - goto out; - } - } - - ret = coap_packet_append_payload_marker(&client->request); - - if (ret < 0) { - LOG_ERR("Failed to append payload marker to CoAP message"); - goto out; - } - - if (client->send_blk_ctx.total_size > 0) { - uint16_t block_in_bytes = - coap_block_size_to_bytes(client->send_blk_ctx.block_size); - - payload_len = client->send_blk_ctx.total_size - - client->send_blk_ctx.current; - if (payload_len > block_in_bytes) { - payload_len = block_in_bytes; - } - offset = client->send_blk_ctx.current; - } else { - payload_len = req->len; - offset = 0; - } - - ret = coap_packet_append_payload(&client->request, req->payload + offset, - payload_len); - - if (ret < 0) { - LOG_ERR("Failed to append payload to CoAP message"); - goto out; - } - - if (client->send_blk_ctx.total_size > 0) { - coap_next_block(&client->request, &client->send_blk_ctx); - } - } - client->request_tkl = coap_header_get_token(&client->request, client->request_token); -out: - return ret; -} - - -int coap_client_req(struct coap_client *client, int sock, const struct sockaddr *addr, - struct coap_client_request *req, int retries) -{ - int ret; - - if (client->coap_client_recv_active) { - return -EAGAIN; - } - - if (sock < 0 || req == NULL || req->path == NULL) { - return -EINVAL; - } - - if (addr != NULL) { - memcpy(&client->address, addr, sizeof(*addr)); - client->socklen = sizeof(client->address); - } else { - memset(&client->address, 0, sizeof(client->address)); - client->socklen = 0; - } - - if (retries == -1) { - client->retry_count = DEFAULT_RETRY_AMOUNT; - } else { - client->retry_count = retries; - } - - ret = coap_client_init_request(client, req); - if (ret < 0) { - LOG_ERR("Failed to initialize coap request"); - return ret; - } - - ret = coap_client_schedule_poll(client, sock, req); - if (ret < 0) { - LOG_ERR("Failed to schedule polling"); - goto out; - } - - ret = coap_pending_init(&client->pending, &client->request, &client->address, - client->retry_count); - - if (ret < 0) { - LOG_ERR("Failed to initialize pending struct"); - goto out; - } - - coap_pending_cycle(&client->pending); - - ret = send_request(sock, client->request.data, client->request.offset, 0, &client->address, - client->socklen); - - if (ret < 0) { - LOG_ERR("Transmission failed: %d", errno); - } else { - /* Do not return the number of bytes sent */ - ret = 0; - } -out: - return ret; -} - -static int handle_poll(struct coap_client *client) -{ - int ret = 0; - - while (1) { - struct pollfd fds; - - fds.fd = client->fd; - fds.events = POLLIN; - fds.revents = 0; - /* rfc7252#section-5.2.2, use separate timeout value for a separate response */ - if (client->pending.timeout != 0) { - ret = poll(&fds, 1, client->pending.timeout); - } else { - ret = poll(&fds, 1, COAP_SEPARATE_TIMEOUT); - } - - if (ret < 0) { - LOG_ERR("Error in poll:%d", errno); - errno = 0; - return ret; - } else if (ret == 0) { - if (client->pending.timeout != 0 && coap_pending_cycle(&client->pending)) { - LOG_ERR("Timeout in poll, retrying send"); - send_request(client->fd, client->request.data, - client->request.offset, 0, &client->address, - client->socklen); - } else { - /* No more retries left, don't retry */ - LOG_ERR("Timeout in poll, no more retries"); - ret = -EFAULT; - break; - } - } else { - if (fds.revents & POLLERR) { - LOG_ERR("Error in poll"); - ret = -EIO; - break; - } - - if (fds.revents & POLLHUP) { - LOG_ERR("Error in poll: POLLHUP"); - ret = -ECONNRESET; - break; - } - - if (fds.revents & POLLNVAL) { - LOG_ERR("Error in poll: POLLNVAL - fd not open"); - ret = -EINVAL; - break; - } - - if (!(fds.revents & POLLIN)) { - LOG_ERR("Unknown poll error"); - ret = -EINVAL; - break; - } - - ret = 0; - break; - } - } - - return ret; -} - -static bool token_compare(struct coap_client *client, const struct coap_packet *resp) -{ - uint8_t response_token[COAP_TOKEN_MAX_LEN]; - uint8_t response_tkl; - - response_tkl = coap_header_get_token(resp, response_token); - - if (client->request_tkl != response_tkl) { - return false; - } - - return memcmp(&client->request_token, &response_token, response_tkl) == 0; -} - -static int recv_response(struct coap_client *client, struct coap_packet *response) -{ - int len; - int ret; - - memset(client->recv_buf, 0, sizeof(client->recv_buf)); - len = receive(client->fd, client->recv_buf, sizeof(client->recv_buf), MSG_DONTWAIT, - &client->address, &client->socklen); - - if (len < 0) { - LOG_ERR("Error reading response: %d", errno); - return -EINVAL; - } else if (len == 0) { - LOG_ERR("Zero length recv"); - return -EINVAL; - } - - LOG_DBG("Received %d bytes", len); - - ret = coap_packet_parse(response, client->recv_buf, len, NULL, 0); - if (ret < 0) { - LOG_ERR("Invalid data received"); - return ret; - } - - return ret; -} - -static void report_callback_error(struct coap_client *client, int error_code) -{ - if (client->coap_request->cb) { - client->coap_request->cb(error_code, 0, NULL, 0, true, - client->coap_request->user_data); - } -} - -static int send_ack(struct coap_client *client, const struct coap_packet *req, - uint8_t response_code) -{ - int ret; - - ret = coap_ack_init(&client->request, req, client->send_buf, MAX_COAP_MSG_LEN, - response_code); - if (ret < 0) { - LOG_ERR("Failed to initialize CoAP ACK-message"); - return ret; - } - - ret = send_request(client->fd, client->request.data, client->request.offset, 0, - &client->address, client->socklen); - if (ret < 0) { - LOG_ERR("Error sending a CoAP ACK-message"); - return ret; - } - - return 0; -} - -static int send_reset(struct coap_client *client, const struct coap_packet *req, - uint8_t response_code) -{ - int ret; - uint16_t id; - uint8_t token[COAP_TOKEN_MAX_LEN]; - uint8_t tkl; - - id = coap_header_get_id(req); - tkl = response_code ? coap_header_get_token(req, token) : 0; - ret = coap_packet_init(&client->request, client->send_buf, MAX_COAP_MSG_LEN, COAP_VERSION, - COAP_TYPE_RESET, tkl, token, response_code, id); - - if (ret < 0) { - LOG_ERR("Error creating CoAP reset message"); - return ret; - } - - ret = send_request(client->fd, client->request.data, client->request.offset, 0, - &client->address, client->socklen); - if (ret < 0) { - LOG_ERR("Error sending CoAP reset message"); - return ret; - } - - return 0; -} - -static int handle_response(struct coap_client *client, const struct coap_packet *response) -{ - int ret = 0; - int response_type; - int block_option; - int block_num; - bool blockwise_transfer = false; - bool last_block = false; - - /* Handle different types, ACK might be separate or piggybacked - * CON and NCON contains a separate response, CON needs an empty response - * CON request results as ACK and possibly separate CON or NCON response - * NCON request results only as a separate CON or NCON message as there is no ACK - * With RESET, just drop gloves and call the callback. - */ - response_type = coap_header_get_type(response); - - /* Reset and Ack need to match the message ID with request */ - if ((response_type == COAP_TYPE_ACK || response_type == COAP_TYPE_RESET) && - coap_header_get_id(response) != client->pending.id) { - LOG_ERR("Unexpected ACK or Reset"); - return -EFAULT; - } else if (response_type == COAP_TYPE_RESET) { - coap_pending_clear(&client->pending); - } - - /* CON, NON_CON and piggybacked ACK need to match the token with original request */ - uint16_t payload_len; - uint8_t response_code = coap_header_get_code(response); - const uint8_t *payload = coap_packet_get_payload(response, &payload_len); - - /* Separate response */ - if (payload_len == 0 && response_type == COAP_TYPE_ACK && - response_code == COAP_CODE_EMPTY) { - /* Clear the pending, poll uses now the separate timeout for the response. */ - coap_pending_clear(&client->pending); - return 1; - } - - /* Check for tokens */ - if (!token_compare(client, response)) { - LOG_ERR("Not matching tokens, respond with reset"); - ret = send_reset(client, response, COAP_RESPONSE_CODE_NOT_FOUND); - return 1; - } - - /* Send ack for CON */ - if (response_type == COAP_TYPE_CON) { - /* CON response is always a separate response, respond with empty ACK. */ - ret = send_ack(client, response, COAP_CODE_EMPTY); - if (ret < 0) { - goto fail; - } - } - - if (client->pending.timeout != 0) { - coap_pending_clear(&client->pending); - } - - /* Check if block2 exists */ - block_option = coap_get_option_int(response, COAP_OPTION_BLOCK2); - if (block_option > 0) { - blockwise_transfer = true; - last_block = !GET_MORE(block_option); - block_num = GET_BLOCK_NUM(block_option); - - if (block_num == 0) { - coap_block_transfer_init(&client->recv_blk_ctx, - coap_client_default_block_size(), - 0); - client->offset = 0; - } - - ret = coap_update_from_block(response, &client->recv_blk_ctx); - if (ret < 0) { - LOG_ERR("Error updating block context"); - } - coap_next_block(response, &client->recv_blk_ctx); - } else { - client->offset = 0; - last_block = true; - } - - /* Check if this was a response to last blockwise send */ - if (client->send_blk_ctx.total_size > 0) { - blockwise_transfer = true; - if (client->send_blk_ctx.total_size == client->send_blk_ctx.current) { - last_block = true; - } else { - last_block = false; - } - } - - /* Call user callback */ - if (client->coap_request->cb) { - client->coap_request->cb(response_code, client->offset, payload, payload_len, - last_block, client->coap_request->user_data); - - /* Update the offset for next callback in a blockwise transfer */ - if (blockwise_transfer) { - client->offset += payload_len; - } - } - - /* If this wasn't last block, send the next request */ - if (blockwise_transfer && !last_block) { - ret = coap_client_init_request(client, client->coap_request); - - if (ret < 0) { - LOG_ERR("Error creating a CoAP request"); - goto fail; - } - - if (client->pending.timeout != 0) { - LOG_ERR("Previous pending hasn't arrived"); - goto fail; - } - - ret = coap_pending_init(&client->pending, &client->request, &client->address, - client->retry_count); - if (ret < 0) { - LOG_ERR("Error creating pending"); - goto fail; - } - coap_pending_cycle(&client->pending); - - ret = send_request(client->fd, client->request.data, client->request.offset, 0, - &client->address, client->socklen); - if (ret < 0) { - LOG_ERR("Error sending a CoAP request"); - goto fail; - } else { - return 1; - } - } -fail: - return ret; -} - -void coap_client_recv(void *coap_cl, void *a, void *b) -{ - int ret; - struct coap_client *const client = coap_cl; - - reset_block_contexts(client); - k_sem_take(&client->coap_client_recv_sem, K_FOREVER); - while (true) { - struct coap_packet response; - - atomic_set(&client->coap_client_recv_active, 1); - ret = handle_poll(client); - if (ret < 0) { - /* Error in polling, clear pending. */ - LOG_ERR("Error in poll"); - coap_pending_clear(&client->pending); - report_callback_error(client, ret); - goto idle; - } - - ret = recv_response(client, &response); - if (ret < 0) { - LOG_ERR("Error receiving response"); - report_callback_error(client, ret); - goto idle; - } - - ret = handle_response(client, &response); - if (ret < 0) { - LOG_ERR("Error handling respnse"); - report_callback_error(client, ret); - goto idle; - } - - /* There are more messages coming for the original request */ - if (ret > 0) { - continue; - } else { -idle: - reset_block_contexts(client); - atomic_set(&client->coap_client_recv_active, 0); - k_sem_take(&client->coap_client_recv_sem, K_FOREVER); - } - } -} - -int coap_client_init(struct coap_client *client, const char *info) -{ - if (client == NULL) { - return -EINVAL; - } - - client->fd = -1; - k_sem_init(&client->coap_client_recv_sem, 0, 1); - - client->tid = - k_thread_create(&client->thread, client->coap_thread_stack, - K_THREAD_STACK_SIZEOF(client->coap_thread_stack), - coap_client_recv, client, NULL, NULL, - CONFIG_COAP_CLIENT_THREAD_PRIORITY, 0, K_NO_WAIT); - - if (IS_ENABLED(CONFIG_THREAD_NAME)) { - if (info != NULL) { - k_thread_name_set(client->tid, info); - } else { - k_thread_name_set(client->tid, "coap_client"); - } - } - - return 0; -} From 0c6be809b28ed63877d3ec188794d8e48e7dd5a8 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:18 +0200 Subject: [PATCH 197/528] Revert "[nrf fromtree] boards: nrf5340: use nrf_reset_network_force_off" This reverts commit c6f38ecdee5e42f4812c2f33053638a1f8cb2cb8. Signed-off-by: Robert Lubos --- boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c | 3 +-- .../nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c | 3 +-- boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c | 3 +-- boards/arm/thingy53_nrf5340/board.c | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c index 49c0e5a1c730..7cf2b399985f 100644 --- a/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c +++ b/boards/arm/bl5340_dvk/bl5340_dvk_cpunet_reset.c @@ -10,7 +10,6 @@ #include #include -#include LOG_MODULE_REGISTER(bl5340_dvk_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); @@ -50,7 +49,7 @@ static int remoteproc_mgr_boot(void) */ /* Release the Network MCU, 'Release force off signal' */ - nrf_reset_network_force_off(NRF_RESET, false); + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; LOG_DBG("Network MCU released."); #endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ diff --git a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c index 4368ca303fc1..5f30e0d9a66f 100644 --- a/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c +++ b/boards/arm/nrf5340_audio_dk_nrf5340/nrf5340_audio_dk_cpunet_reset.c @@ -9,7 +9,6 @@ #include #include -#include #include @@ -72,7 +71,7 @@ static int remoteproc_mgr_boot(void) */ /* Release the Network MCU, 'Release force off signal' */ - nrf_reset_network_force_off(NRF_RESET, false); + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; LOG_DBG("Network MCU released."); #endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ diff --git a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c index dadba8c0f54a..68700225f4ed 100644 --- a/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c +++ b/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c @@ -9,7 +9,6 @@ #include #include -#include LOG_MODULE_REGISTER(nrf5340dk_nrf5340_cpuapp, CONFIG_LOG_DEFAULT_LEVEL); @@ -49,7 +48,7 @@ static int remoteproc_mgr_boot(void) */ /* Release the Network MCU, 'Release force off signal' */ - nrf_reset_network_force_off(NRF_RESET, false); + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; LOG_DBG("Network MCU released."); #endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ diff --git a/boards/arm/thingy53_nrf5340/board.c b/boards/arm/thingy53_nrf5340/board.c index 88d7e365d824..509ec04bdab5 100644 --- a/boards/arm/thingy53_nrf5340/board.c +++ b/boards/arm/thingy53_nrf5340/board.c @@ -8,7 +8,6 @@ #include #include #include -#include LOG_MODULE_REGISTER(thingy53_board_init); @@ -52,7 +51,7 @@ static void enable_cpunet(void) */ /* Release the Network MCU, 'Release force off signal' */ - nrf_reset_network_force_off(NRF_RESET, false); + NRF_RESET->NETWORK.FORCEOFF = RESET_NETWORK_FORCEOFF_FORCEOFF_Release; LOG_DBG("Network MCU released."); #endif /* !CONFIG_TRUSTED_EXECUTION_SECURE */ From 189bdce9b9e37df3b3d62a97e8a082db3042d086 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:18 +0200 Subject: [PATCH 198/528] Revert "[nrf fromtree] net: openthread: Fix `OPENTHREAD_FTD` dependency." This reverts commit 6fb229ca3c88b3c7c1ec9b0a2995703032eae4a8. Signed-off-by: Robert Lubos --- modules/openthread/Kconfig.features | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 823b77a77a7b..4766032cd79a 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -286,4 +286,3 @@ config OPENTHREAD_UDP_FORWARD config OPENTHREAD_UPTIME bool "Openthread uptime counter" - default y if OPENTHREAD_FTD From cf3793b6618d372e365a0ce002b66f05a7d57bb5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:19 +0200 Subject: [PATCH 199/528] Revert "[nrf fromtree] Bluetooth: controller: Move DF feat selection to LL_SW_SPLIT KConfig" This reverts commit 70d3f6dc1d46eada29478ea29374923658991759. Signed-off-by: Robert Lubos --- subsys/bluetooth/controller/Kconfig.df | 17 +++++++++-------- subsys/bluetooth/controller/Kconfig.ll_sw_split | 10 ---------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/subsys/bluetooth/controller/Kconfig.df b/subsys/bluetooth/controller/Kconfig.df index 981d1b8f1fc3..e3f460c7f51a 100644 --- a/subsys/bluetooth/controller/Kconfig.df +++ b/subsys/bluetooth/controller/Kconfig.df @@ -3,14 +3,17 @@ # Copyright (c) 2020 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 -# BT_CTLR_DF_SUPPORT is a wrapper for all DF features. It is referenced by Host -# to enable its DF related Kconfigs when build together with the Controller. -# It is required to enable it when Controller supports any DF related feature -# but particular features are selected individually. +# BT_CTLR_DF_SUPPORT is a wrapper for all DF features. +# If only certain DF features are supported, those should be selected +# individually. config BT_CTLR_DF_SUPPORT bool - -if BT_CTLR_DF_SUPPORT + depends on BT_LL_SW_SPLIT && !BT_CTLR_TIFS_HW + select BT_CTLR_DF_CTE_TX_SUPPORT + select BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT + select BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT + select BT_CTLR_DF_CTE_RX_SUPPORT + select BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT config BT_CTLR_DF_CTE_TX_SUPPORT bool @@ -30,8 +33,6 @@ config BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT config BT_CTLR_CTEINLINE_SUPPORT bool -endif # BT_CTLR_DF_SUPPORT - menuconfig BT_CTLR_DF bool "LE Direction Finding" depends on BT_CTLR_DF_CTE_TX_SUPPORT || BT_CTLR_DF_CTE_RX_SUPPORT diff --git a/subsys/bluetooth/controller/Kconfig.ll_sw_split b/subsys/bluetooth/controller/Kconfig.ll_sw_split index 78ef97a65c6c..fa4483d7a305 100644 --- a/subsys/bluetooth/controller/Kconfig.ll_sw_split +++ b/subsys/bluetooth/controller/Kconfig.ll_sw_split @@ -76,16 +76,6 @@ config BT_LLL_VENDOR_OPENISA help Use OpenISA Lower Link Layer implementation. -# BT_CTLR_DF_SUPPORT is a wrapper for all DF features. Here we select features that are supported by -# Zephyr's BLE Controller. -config BT_CTLR_DF_SUPPORT - depends on BT_LL_SW_SPLIT && !BT_CTLR_TIFS_HW - select BT_CTLR_DF_CTE_TX_SUPPORT - select BT_CTLR_DF_ANT_SWITCH_2US_SUPPORT - select BT_CTLR_DF_ANT_SWITCH_1US_SUPPORT - select BT_CTLR_DF_CTE_RX_SUPPORT - select BT_CTLR_DF_CTE_RX_SAMPLE_1US_SUPPORT - config BT_CTLR_XTAL_ADVANCED_SUPPORT bool From 0679769f39045a3da60007aac1825243aec257b5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:19 +0200 Subject: [PATCH 200/528] Revert "[nrf fromlist] manifest: Update nRF HW models to latest" This reverts commit 9b2ecc048c1a4194ff6bb1e5ae883f979496383e. Signed-off-by: Robert Lubos --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 141368580cfd..b40fa8488d0a 100644 --- a/west.yml +++ b/west.yml @@ -197,7 +197,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 37c571ef7c4a86dad852566fc43eb36f42534e9f + revision: c8d2ecd25d6976d2d77eccf66878420fdb8ef5a1 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: aedcc262f93bbb1b0c2f58026911575729b7465c From 0c5f832c9a47e04d1a3a6be132133d901715fce7 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:19 +0200 Subject: [PATCH 201/528] Revert "[nrf fromtree] manifest: nrf hw models: Use latest w flash" This reverts commit 6c3100f4fd366a3c280f614bd2154b22be023662. Signed-off-by: Robert Lubos --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index b40fa8488d0a..b4c5274e885a 100644 --- a/west.yml +++ b/west.yml @@ -197,7 +197,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: c8d2ecd25d6976d2d77eccf66878420fdb8ef5a1 + revision: bad9877e997b2c2a78dd74eec8978181f4655d14 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: aedcc262f93bbb1b0c2f58026911575729b7465c From 6e0b29fffc5e7f23a0bd2c3670c9f9b6ea08447f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:19 +0200 Subject: [PATCH 202/528] Revert "[nrf noup] tests: drivers: build_all: regulator: use old schema" This reverts commit 4618cfe53df3154a6ee4101c2e68e98531fdda98. Signed-off-by: Robert Lubos --- tests/drivers/build_all/regulator/testcase.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/drivers/build_all/regulator/testcase.yaml b/tests/drivers/build_all/regulator/testcase.yaml index c5dbda1913f3..9b9c25511c4e 100644 --- a/tests/drivers/build_all/regulator/testcase.yaml +++ b/tests/drivers/build_all/regulator/testcase.yaml @@ -3,6 +3,8 @@ tests: drivers.regulator.build: - tags: drivers regulator + tags: + - drivers + - regulator build_only: true platform_allow: native_posix From 61d67bd92a5e9b38166b248b27ff2a8e5a9d17df Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:19 +0200 Subject: [PATCH 203/528] Revert "[nrf fromtree] drivers: regulator: adp5360: remove unused init priority" This reverts commit ecdb1b279f07bd2eba03d3a30630a793e28d9342. Signed-off-by: Robert Lubos --- drivers/regulator/Kconfig.adp5360 | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/Kconfig.adp5360 b/drivers/regulator/Kconfig.adp5360 index 0785ba54abf0..30f4d566254b 100644 --- a/drivers/regulator/Kconfig.adp5360 +++ b/drivers/regulator/Kconfig.adp5360 @@ -9,9 +9,20 @@ config REGULATOR_ADP5360 help Enable the Analog Devices ADP5360 PMIC regulator driver +if REGULATOR_ADP5360 + +config REGULATOR_ADP5360_COMMON_INIT_PRIORITY + int "ADP5360 regulator driver init priority (common part)" + default 75 + help + Init priority for the Analog Devices ADP5360 regulator driver (common + part). It must be greater than I2C init priority. + config REGULATOR_ADP5360_INIT_PRIORITY int "ADP5360 regulator driver init priority" default 76 - depends on REGULATOR_ADP5360 help - Init priority for the Analog Devices ADP5360 regulator driver. + Init priority for the Analog Devices ADP5360 regulator driver. It must + be greater than REGULATOR_ADP5360_COMMON_INIT_PRIORITY. + +endif From d7655173716edad0270596873f56f367d8884f93 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:19 +0200 Subject: [PATCH 204/528] Revert "[nrf fromtree] drivers: regulator: adp5360: initial version" This reverts commit 5eb4ec7a46f7636300f58f59008003fe63f67bc1. Signed-off-by: Robert Lubos --- drivers/regulator/CMakeLists.txt | 1 - drivers/regulator/Kconfig | 1 - drivers/regulator/Kconfig.adp5360 | 28 -- drivers/regulator/regulator_adp5360.c | 308 ------------------ dts/bindings/mfd/adi,adp5360.yaml | 12 - .../regulator/adi,adp5360-regulator.yaml | 85 ----- .../zephyr/dt-bindings/regulator/adp5360.h | 28 -- tests/drivers/build_all/regulator/i2c.dtsi | 12 - 8 files changed, 475 deletions(-) delete mode 100644 drivers/regulator/Kconfig.adp5360 delete mode 100644 drivers/regulator/regulator_adp5360.c delete mode 100644 dts/bindings/mfd/adi,adp5360.yaml delete mode 100644 dts/bindings/regulator/adi,adp5360-regulator.yaml delete mode 100644 include/zephyr/dt-bindings/regulator/adp5360.h diff --git a/drivers/regulator/CMakeLists.txt b/drivers/regulator/CMakeLists.txt index 1f5f9f8b3454..8368d9f37acc 100644 --- a/drivers/regulator/CMakeLists.txt +++ b/drivers/regulator/CMakeLists.txt @@ -4,7 +4,6 @@ zephyr_library() zephyr_library_sources(regulator_common.c) -zephyr_library_sources_ifdef(CONFIG_REGULATOR_ADP5360 regulator_adp5360.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_FAKE regulator_fake.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_FIXED regulator_fixed.c) zephyr_library_sources_ifdef(CONFIG_REGULATOR_NPM1100 regulator_npm1100.c) diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index e8deab647bf1..25b1c711d62c 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig @@ -20,7 +20,6 @@ module = REGULATOR module-str = regulator source "subsys/logging/Kconfig.template.log_config" -source "drivers/regulator/Kconfig.adp5360" source "drivers/regulator/Kconfig.fake" source "drivers/regulator/Kconfig.fixed" source "drivers/regulator/Kconfig.npm1100" diff --git a/drivers/regulator/Kconfig.adp5360 b/drivers/regulator/Kconfig.adp5360 deleted file mode 100644 index 30f4d566254b..000000000000 --- a/drivers/regulator/Kconfig.adp5360 +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX -License-Identifier: Apache-2.0 - -config REGULATOR_ADP5360 - bool "ADP5360 PMIC regulator driver" - default y - depends on DT_HAS_ADI_ADP5360_REGULATOR_ENABLED - select I2C - help - Enable the Analog Devices ADP5360 PMIC regulator driver - -if REGULATOR_ADP5360 - -config REGULATOR_ADP5360_COMMON_INIT_PRIORITY - int "ADP5360 regulator driver init priority (common part)" - default 75 - help - Init priority for the Analog Devices ADP5360 regulator driver (common - part). It must be greater than I2C init priority. - -config REGULATOR_ADP5360_INIT_PRIORITY - int "ADP5360 regulator driver init priority" - default 76 - help - Init priority for the Analog Devices ADP5360 regulator driver. It must - be greater than REGULATOR_ADP5360_COMMON_INIT_PRIORITY. - -endif diff --git a/drivers/regulator/regulator_adp5360.c b/drivers/regulator/regulator_adp5360.c deleted file mode 100644 index c417b6e59858..000000000000 --- a/drivers/regulator/regulator_adp5360.c +++ /dev/null @@ -1,308 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT adi_adp5360_regulator - -#include - -#include -#include -#include -#include -#include - -/* ADP5360 regulator related registers */ -#define ADP5360_BUCK_CFG 0x29U -#define ADP5360_BUCK_OUTPUT 0x2AU -#define ADP5360_BUCKBST_CFG 0x2BU -#define ADP5360_BUCKBST_OUTPUT 0x2CU - -/* Buck/boost configure register. */ -#define ADP5360_BUCK_CFG_SS_MSK GENMASK(7, 6) -#define ADP5360_BUCK_CFG_SS_POS 6U -#define ADP5360_BUCK_CFG_BST_ILIM_MSK GENMASK(5, 3) -#define ADP5360_BUCK_CFG_BST_ILIM_POS 3U -#define ADP5360_BUCK_CFG_BUCK_ILIM_MSK GENMASK(5, 3) -#define ADP5360_BUCK_CFG_BUCK_ILIM_POS 3U -#define ADP5360_BUCK_CFG_BUCK_MODE_MSK BIT(3) -#define ADP5360_BUCK_CFG_BUCK_MODE_POS 3U -#define ADP5360_BUCK_CFG_STP_MSK BIT(2) -#define ADP5360_BUCK_CFG_DISCHG_MSK BIT(1) -#define ADP5360_BUCK_CFG_EN_MSK BIT(0) - -/* Buck/boost output voltage setting register. */ -#define ADP5360_BUCK_OUTPUT_VOUT_MSK GENMASK(5, 0) -#define ADP5360_BUCK_OUTPUT_VOUT_POS 0U -#define ADP5360_BUCK_OUTPUT_DLY_MSK GENMASK(7, 6) -#define ADP5360_BUCK_OUTPUT_DLY_POS 6U - -struct regulator_adp5360_desc { - uint8_t cfg_reg; - uint8_t out_reg; - bool has_modes; - const struct linear_range *ranges; - uint8_t nranges; -}; - -static const struct linear_range buck_ranges[] = { - LINEAR_RANGE_INIT(600000, 50000U, 0x0U, 0x3FU), -}; - -static const struct regulator_adp5360_desc buck_desc = { - .cfg_reg = ADP5360_BUCK_CFG, - .out_reg = ADP5360_BUCK_OUTPUT, - .has_modes = true, - .ranges = buck_ranges, - .nranges = ARRAY_SIZE(buck_ranges), -}; - -static const struct linear_range buckboost_ranges[] = { - LINEAR_RANGE_INIT(1800000, 100000U, 0x0U, 0x0BU), - LINEAR_RANGE_INIT(2950000, 50000U, 0xCU, 0x3FU), -}; - -static const struct regulator_adp5360_desc buckboost_desc = { - .cfg_reg = ADP5360_BUCKBST_CFG, - .out_reg = ADP5360_BUCKBST_OUTPUT, - .has_modes = false, - .ranges = buckboost_ranges, - .nranges = ARRAY_SIZE(buckboost_ranges), -}; - -struct regulator_adp5360_config { - struct regulator_common_config common; - struct i2c_dt_spec i2c; - const struct regulator_adp5360_desc *desc; - int8_t dly_idx; - int8_t ss_idx; - int8_t ilim_idx; - bool stp_en; - bool dis_en; -}; - -struct regulator_adp5360_data { - struct regulator_common_data data; -}; - -static unsigned int regulator_adp5360_count_voltages(const struct device *dev) -{ - const struct regulator_adp5360_config *config = dev->config; - - return linear_range_group_values_count(config->desc->ranges, config->desc->nranges); -} - -static int regulator_adp5360_list_voltage(const struct device *dev, unsigned int idx, - int32_t *volt_uv) -{ - const struct regulator_adp5360_config *config = dev->config; - - return linear_range_group_get_value(config->desc->ranges, config->desc->nranges, idx, - volt_uv); -} - -static int regulator_adp5360_set_voltage(const struct device *dev, int32_t min_uv, int32_t max_uv) -{ - const struct regulator_adp5360_config *config = dev->config; - uint16_t idx; - int ret; - - ret = linear_range_group_get_win_index(config->desc->ranges, config->desc->nranges, min_uv, - max_uv, &idx); - if (ret == -EINVAL) { - return ret; - } - - return i2c_reg_update_byte_dt(&config->i2c, config->desc->out_reg, - ADP5360_BUCK_OUTPUT_VOUT_MSK, - (uint8_t)idx << ADP5360_BUCK_OUTPUT_VOUT_POS); -} - -static int regulator_adp5360_get_voltage(const struct device *dev, int32_t *volt_uv) -{ - const struct regulator_adp5360_config *config = dev->config; - int ret; - uint8_t raw_reg; - - ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->out_reg, &raw_reg); - if (ret < 0) { - return ret; - } - - raw_reg = (raw_reg & ADP5360_BUCK_OUTPUT_VOUT_MSK) >> ADP5360_BUCK_OUTPUT_VOUT_POS; - - return linear_range_group_get_value(config->desc->ranges, config->desc->nranges, raw_reg, - volt_uv); -} - -static int regulator_adp5360_set_mode(const struct device *dev, regulator_mode_t mode) -{ - const struct regulator_adp5360_config *config = dev->config; - - if (!config->desc->has_modes || (mode > ADP5360_MODE_PWM)) { - return -ENOTSUP; - } - - return i2c_reg_update_byte_dt(&config->i2c, config->desc->cfg_reg, - ADP5360_BUCK_CFG_BUCK_MODE_MSK, - mode << ADP5360_BUCK_CFG_BUCK_MODE_POS); -} - -static int regulator_adp5360_get_mode(const struct device *dev, regulator_mode_t *mode) -{ - const struct regulator_adp5360_config *config = dev->config; - uint8_t val; - int ret; - - if (!config->desc->has_modes) { - return -ENOTSUP; - } - - ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->cfg_reg, &val); - if (ret < 0) { - return ret; - } - - *mode = (val & ADP5360_BUCK_CFG_BUCK_MODE_MSK) >> ADP5360_BUCK_CFG_BUCK_MODE_POS; - - return 0; -} - -static int regulator_adp5360_enable(const struct device *dev) -{ - const struct regulator_adp5360_config *config = dev->config; - - return i2c_reg_update_byte_dt(&config->i2c, config->desc->cfg_reg, ADP5360_BUCK_CFG_EN_MSK, - 1U); -} - -static int regulator_adp5360_disable(const struct device *dev) -{ - const struct regulator_adp5360_config *config = dev->config; - - return i2c_reg_update_byte_dt(&config->i2c, config->desc->cfg_reg, ADP5360_BUCK_CFG_EN_MSK, - 0U); -} - -static int regulator_adp5360_init(const struct device *dev) -{ - const struct regulator_adp5360_config *config = dev->config; - int ret; - uint8_t val, nval, msk; - - regulator_common_data_init(dev); - - if (!i2c_is_ready_dt(&config->i2c)) { - return -ENODEV; - } - - /* apply optional delay */ - msk = 0U; - nval = 0U; - - ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->out_reg, &val); - if (ret < 0) { - return ret; - } - - if (config->dly_idx >= 0) { - msk |= ADP5360_BUCK_OUTPUT_DLY_MSK; - nval |= ((uint8_t)config->dly_idx << ADP5360_BUCK_OUTPUT_DLY_POS) & - ADP5360_BUCK_OUTPUT_DLY_MSK; - } - - if (msk != 0U) { - ret = i2c_reg_write_byte_dt(&config->i2c, config->desc->out_reg, - (val & ~msk) | nval); - if (ret < 0) { - return ret; - } - } - - /* apply optional initial configuration */ - msk = 0U; - nval = 0U; - - ret = i2c_reg_read_byte_dt(&config->i2c, config->desc->cfg_reg, &val); - if (ret < 0) { - return ret; - } - - if (config->ss_idx >= 0) { - msk |= ADP5360_BUCK_CFG_SS_MSK; - nval |= ((uint8_t)config->ss_idx << ADP5360_BUCK_CFG_SS_POS) & - ADP5360_BUCK_CFG_SS_MSK; - } - - if (config->ilim_idx >= 0) { - if (config->desc->has_modes) { - msk |= ADP5360_BUCK_CFG_BUCK_ILIM_MSK; - nval |= ((uint8_t)config->ilim_idx << ADP5360_BUCK_CFG_BUCK_ILIM_POS) & - ADP5360_BUCK_CFG_BUCK_ILIM_MSK; - } else { - msk |= ADP5360_BUCK_CFG_BST_ILIM_MSK; - nval |= ((uint8_t)config->ilim_idx << ADP5360_BUCK_CFG_BST_ILIM_POS) & - ADP5360_BUCK_CFG_BST_ILIM_MSK; - } - } - - if (config->stp_en) { - msk |= ADP5360_BUCK_CFG_STP_MSK; - nval |= ADP5360_BUCK_CFG_STP_MSK; - } - - if (config->dis_en) { - msk |= ADP5360_BUCK_CFG_DISCHG_MSK; - nval |= ADP5360_BUCK_CFG_DISCHG_MSK; - } - - if (msk != 0U) { - ret = i2c_reg_write_byte_dt(&config->i2c, config->desc->cfg_reg, - (val & ~msk) | nval); - if (ret < 0) { - return ret; - } - } - - return regulator_common_init(dev, (val & ADP5360_BUCK_CFG_EN_MSK) != 0U); -} - -static const struct regulator_driver_api api = { - .enable = regulator_adp5360_enable, - .disable = regulator_adp5360_disable, - .count_voltages = regulator_adp5360_count_voltages, - .list_voltage = regulator_adp5360_list_voltage, - .set_voltage = regulator_adp5360_set_voltage, - .get_voltage = regulator_adp5360_get_voltage, - .set_mode = regulator_adp5360_set_mode, - .get_mode = regulator_adp5360_get_mode, -}; - -#define REGULATOR_ADP5360_DEFINE(node_id, id, name) \ - static struct regulator_adp5360_data data_##id; \ - \ - static const struct regulator_adp5360_config config_##id = { \ - .common = REGULATOR_DT_COMMON_CONFIG_INIT(node_id), \ - .i2c = I2C_DT_SPEC_GET(DT_GPARENT(node_id)), \ - .desc = &name##_desc, \ - .dly_idx = DT_ENUM_IDX_OR(node_id, adi_switch_delay_us, -1), \ - .ss_idx = DT_ENUM_IDX_OR(node_id, adi_soft_start_ms, -1), \ - .ilim_idx = DT_ENUM_IDX_OR(node_id, adi_ilim_milliamp, -1), \ - .stp_en = DT_PROP(node_id, adi_enable_stop_pulse), \ - .dis_en = DT_PROP(node_id, adi_enable_output_discharge), \ - }; \ - \ - DEVICE_DT_DEFINE(node_id, regulator_adp5360_init, NULL, &data_##id, &config_##id, \ - POST_KERNEL, CONFIG_REGULATOR_ADP5360_INIT_PRIORITY, &api); - -#define REGULATOR_ADP5360_DEFINE_COND(inst, child) \ - COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(inst, child)), \ - (REGULATOR_ADP5360_DEFINE(DT_INST_CHILD(inst, child), child##inst, child)), \ - ()) - -#define REGULATOR_ADP5360_DEFINE_ALL(inst) \ - REGULATOR_ADP5360_DEFINE_COND(inst, buck) \ - REGULATOR_ADP5360_DEFINE_COND(inst, buckboost) - -DT_INST_FOREACH_STATUS_OKAY(REGULATOR_ADP5360_DEFINE_ALL) diff --git a/dts/bindings/mfd/adi,adp5360.yaml b/dts/bindings/mfd/adi,adp5360.yaml deleted file mode 100644 index 982acf66949f..000000000000 --- a/dts/bindings/mfd/adi,adp5360.yaml +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2023, Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: Analog Devices ADP5360 - -compatible: "adi,adp5360" - -include: i2c-device.yaml - -properties: - reg: - required: true diff --git a/dts/bindings/regulator/adi,adp5360-regulator.yaml b/dts/bindings/regulator/adi,adp5360-regulator.yaml deleted file mode 100644 index d683bd694ef7..000000000000 --- a/dts/bindings/regulator/adi,adp5360-regulator.yaml +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (c), 2023 Nordic Semiconductor ASA -# SPDX -License-Identifier: Apache-2.0 - -description: | - Analog Devices ADP3560 PMIC - - The PMIC has one buck converter and one buck-boost converter. Both need to be - defined as children nodes, strictly following the BUCK and BUCKBOOST node - names. For example: - - pmic@46 { - compatible = "adi,adp5360"; - reg = <0x46>; - ... - regulators { - compatible = "adi,adp5360-regulator"; - - BUCK { - /* all properties for BUCK */ - }; - BUCKBOOST { - /* all properties for BUCKBOOST */ - }; - }; - }; - -compatible: "adi,adp5360-regulator" - -include: base.yaml - -child-binding: - include: - - name: regulator.yaml - property-allowlist: - - regulator-always-on - - regulator-boot-on - - regulator-init-microvolt - - regulator-min-microvolt - - regulator-max-microvolt - - regulator-allowed-modes - - regulator-initial-mode - - properties: - adi,switch-delay-us: - type: int - enum: - - 0 - - 5 - - 10 - - 20 - description: Switch delay time in hysteresis. - - adi,soft-start-ms: - type: int - enum: - - 1 - - 8 - - 64 - - 512 - description: Soft start time in milliseconds - - adi,ilim-milliamp: - type: int - enum: - - 100 - - 200 - - 300 - - 400 - - 500 - - 600 - - 700 - - 800 - description: | - Peak current limit, in milliamperes. Values above 400mA are only - applicable to buck boost. - - adi,enable-stop-pulse: - type: boolean - description: | - With this option selected and the buck/boost enabled, the buck/boost - regulator can be stopped using the STP pin. - - adi,enable-output-discharge: - type: boolean - description: Enable output discharge functionality diff --git a/include/zephyr/dt-bindings/regulator/adp5360.h b/include/zephyr/dt-bindings/regulator/adp5360.h deleted file mode 100644 index d3aecacaa72f..000000000000 --- a/include/zephyr/dt-bindings/regulator/adp5360.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_ADP5360_H_ -#define ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_ADP5360_H_ - -/** - * @defgroup regulator_adp5360 ADP5360 Devicetree helpers. - * @ingroup regulator_interface - * @{ - */ - -/** - * @name ADP5360 Regulator modes - * @{ - */ -/** Hysteresis mode */ -#define ADP5360_MODE_HYS 0 -/** PWM mode */ -#define ADP5360_MODE_PWM 1 -/** @} */ - -/** @} */ - -#endif /* ZEPHYR_INCLUDE_DT_BINDINGS_REGULATOR_ADP5360_H_*/ diff --git a/tests/drivers/build_all/regulator/i2c.dtsi b/tests/drivers/build_all/regulator/i2c.dtsi index 36818b03e8fd..2597ab4781f9 100644 --- a/tests/drivers/build_all/regulator/i2c.dtsi +++ b/tests/drivers/build_all/regulator/i2c.dtsi @@ -46,15 +46,3 @@ npm1300@2 { LDO2 {}; }; }; - -apd356x@3 { - compatible = "adi,adp5360"; - reg = <0x3>; - - regulators { - compatible = "adi,adp5360-regulator"; - - BUCK {}; - BUCKBOOST {}; - }; -}; From a24f244c81f4270c4fad5376f90852e85bbbeddb Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:19 +0200 Subject: [PATCH 205/528] Revert "[nrf fromtree] tests: drivers: build_all: regulator: add test" This reverts commit a0af43dc4747107348884d7947cab2c413d671f4. Signed-off-by: Robert Lubos --- MAINTAINERS.yml | 1 - .../build_all/regulator/CMakeLists.txt | 8 ---- tests/drivers/build_all/regulator/app.overlay | 32 ------------- tests/drivers/build_all/regulator/i2c.dtsi | 48 ------------------- tests/drivers/build_all/regulator/misc.dtsi | 16 ------- tests/drivers/build_all/regulator/prj.conf | 1 - tests/drivers/build_all/regulator/src/main.c | 9 ---- .../drivers/build_all/regulator/testcase.yaml | 10 ---- 8 files changed, 125 deletions(-) delete mode 100644 tests/drivers/build_all/regulator/CMakeLists.txt delete mode 100644 tests/drivers/build_all/regulator/app.overlay delete mode 100644 tests/drivers/build_all/regulator/i2c.dtsi delete mode 100644 tests/drivers/build_all/regulator/misc.dtsi delete mode 100644 tests/drivers/build_all/regulator/prj.conf delete mode 100644 tests/drivers/build_all/regulator/src/main.c delete mode 100644 tests/drivers/build_all/regulator/testcase.yaml diff --git a/MAINTAINERS.yml b/MAINTAINERS.yml index ed15c0944900..a09a689391cd 100644 --- a/MAINTAINERS.yml +++ b/MAINTAINERS.yml @@ -1109,7 +1109,6 @@ Release Notes: - include/zephyr/drivers/regulator.h - include/zephyr/dt-bindings/regulator/ - tests/drivers/regulator/ - - tests/drivers/build_all/regulator/ - doc/hardware/peripherals/regulators.rst labels: - "area: Regulators" diff --git a/tests/drivers/build_all/regulator/CMakeLists.txt b/tests/drivers/build_all/regulator/CMakeLists.txt deleted file mode 100644 index 534287220b59..000000000000 --- a/tests/drivers/build_all/regulator/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(build_all) - -target_sources(app PRIVATE src/main.c) diff --git a/tests/drivers/build_all/regulator/app.overlay b/tests/drivers/build_all/regulator/app.overlay deleted file mode 100644 index b6871b7bfd5d..000000000000 --- a/tests/drivers/build_all/regulator/app.overlay +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - test { - #address-cells = <1>; - #size-cells = <1>; - - test_i2c: i2c@11112222 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "vnd,i2c"; - reg = <0x11112222 0x1000>; - status = "okay"; - clock-frequency = <100000>; - - #include "i2c.dtsi" - }; - - test_gpio: gpio@deadbeef { - compatible = "vnd,gpio"; - gpio-controller; - reg = <0xdeadbeef 0x1000>; - #gpio-cells = <0x2>; - status = "okay"; - }; - - #include "misc.dtsi" - }; -}; diff --git a/tests/drivers/build_all/regulator/i2c.dtsi b/tests/drivers/build_all/regulator/i2c.dtsi deleted file mode 100644 index 2597ab4781f9..000000000000 --- a/tests/drivers/build_all/regulator/i2c.dtsi +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -/**************************************** - * PLEASE KEEP REG ADDRESSES SEQUENTIAL * - ***************************************/ - -pca9420@0 { - compatible = "nxp,pca9420"; - reg = <0x0>; - - BUCK1 {}; - BUCK2 {}; - LDO1 {}; - LDO2 {}; -}; - -npm6001@1 { - compatible = "nordic,npm6001"; - reg = <0x1>; - - regulators { - compatible = "nordic,npm6001-regulator"; - - BUCK0 {}; - BUCK1 {}; - BUCK2 {}; - BUCK3 {}; - LDO0 {}; - LDO1 {}; - }; -}; - -npm1300@2 { - compatible = "nordic,npm1300"; - reg = <0x2>; - - regulators { - compatible = "nordic,npm1300-regulator"; - - BUCK1 {}; - BUCK2 {}; - LDO1 {}; - LDO2 {}; - }; -}; diff --git a/tests/drivers/build_all/regulator/misc.dtsi b/tests/drivers/build_all/regulator/misc.dtsi deleted file mode 100644 index dcfa2c285d95..000000000000 --- a/tests/drivers/build_all/regulator/misc.dtsi +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -regulator-fixed { - compatible = "regulator-fixed"; - regulator-name = "test"; - enable-gpios = <&test_gpio 0 GPIO_ACTIVE_HIGH>; -}; - -npm1100 { - compatible = "nordic,npm1100"; - - BUCK {}; -}; diff --git a/tests/drivers/build_all/regulator/prj.conf b/tests/drivers/build_all/regulator/prj.conf deleted file mode 100644 index 5b7c35c8f7bc..000000000000 --- a/tests/drivers/build_all/regulator/prj.conf +++ /dev/null @@ -1 +0,0 @@ -CONFIG_REGULATOR=y diff --git a/tests/drivers/build_all/regulator/src/main.c b/tests/drivers/build_all/regulator/src/main.c deleted file mode 100644 index 62180b5fc3e2..000000000000 --- a/tests/drivers/build_all/regulator/src/main.c +++ /dev/null @@ -1,9 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -int main(void) -{ - return 0; -} diff --git a/tests/drivers/build_all/regulator/testcase.yaml b/tests/drivers/build_all/regulator/testcase.yaml deleted file mode 100644 index 9b9c25511c4e..000000000000 --- a/tests/drivers/build_all/regulator/testcase.yaml +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -tests: - drivers.regulator.build: - tags: - - drivers - - regulator - build_only: true - platform_allow: native_posix From 955999fcc17aeb8bb8c65bedd159705c4a455c9a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:19 +0200 Subject: [PATCH 206/528] Revert "[nrf fromtree] cmake: support snippets scope for `zephyr_get()`" This reverts commit 0933a4b2949889ca924b10aff05b1093dabe7ba0. Signed-off-by: Robert Lubos --- cmake/modules/configuration_files.cmake | 4 ++-- cmake/modules/extensions.cmake | 6 +----- cmake/modules/snippets.cmake | 4 ++++ scripts/snippets.py | 5 +---- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/cmake/modules/configuration_files.cmake b/cmake/modules/configuration_files.cmake index 06ad074f0cef..24d5e9feedd3 100644 --- a/cmake/modules/configuration_files.cmake +++ b/cmake/modules/configuration_files.cmake @@ -116,5 +116,5 @@ DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"") # The DTC_OVERLAY_FILE variable is now set to its final value. zephyr_boilerplate_watch(DTC_OVERLAY_FILE) -zephyr_get(EXTRA_CONF_FILE SYSBUILD LOCAL VAR EXTRA_CONF_FILE OVERLAY_CONFIG MERGE REVERSE) -zephyr_get(EXTRA_DTC_OVERLAY_FILE SYSBUILD LOCAL MERGE REVERSE) +zephyr_get(EXTRA_CONF_FILE SYSBUILD LOCAL VAR EXTRA_CONF_FILE OVERLAY_CONFIG) +zephyr_get(EXTRA_DTC_OVERLAY_FILE SYSBUILD LOCAL) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 172b707aaff3..b0d742703eae 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2568,13 +2568,9 @@ function(zephyr_get variable) else() set(sysbuild_${var}) endif() - - if(TARGET snippets_scope) - get_property(snippets_${var} TARGET snippets_scope PROPERTY ${var}) - endif() endforeach() - set(scopes "sysbuild;CACHE;snippets;ENV;current") + set(scopes "sysbuild;CACHE;ENV;current") if(GET_VAR_REVERSE) list(REVERSE scopes) endif() diff --git a/cmake/modules/snippets.cmake b/cmake/modules/snippets.cmake index 6f8950c5f64a..7121dcf1afce 100644 --- a/cmake/modules/snippets.cmake +++ b/cmake/modules/snippets.cmake @@ -94,6 +94,10 @@ function(zephyr_process_snippets) endif() include(${snippets_generated}) + # Propagate include()d build system settings to the caller. + set(DTC_OVERLAY_FILE ${DTC_OVERLAY_FILE} PARENT_SCOPE) + set(OVERLAY_CONFIG ${OVERLAY_CONFIG} PARENT_SCOPE) + # Create the 'snippets' target. Each snippet is printed in a # separate command because build system files are not fond of # newlines. diff --git a/scripts/snippets.py b/scripts/snippets.py index a79f12584ebe..74e7ebbbfcea 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -133,9 +133,6 @@ def print_cmake(self): # The paths to all the snippet.yml files. One snippet # can have multiple snippet.yml files. set(SNIPPET_PATHS {snippet_path_list}) - -# Create variable scope for snippets build variables -zephyr_create_scope(snippets) ''') for snippet_name in snippet_names: @@ -171,7 +168,7 @@ def print_appends(self, appends: Appends, indent: int): space = ' ' * indent for name, values in appends.items(): for value in values: - self.print(f'{space}zephyr_set({name} {value} SCOPE snippets APPEND)') + self.print(f'{space}list(APPEND {name} {value})') def print(self, *args, **kwargs): kwargs['file'] = self.out_file From 30152cf960e12d32491d857d538bdc743db108c5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 207/528] Revert "[nrf fromtree] cmake: create Zephyr scope functions for variables" This reverts commit 1a2b27689bb2d658675b820bdd5b2d6148743c5a. Signed-off-by: Robert Lubos --- cmake/modules/extensions.cmake | 46 ---------------------------------- 1 file changed, 46 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index b0d742703eae..a18b9b0efeee 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2622,52 +2622,6 @@ function(zephyr_get variable) endif() endfunction(zephyr_get variable) -# Usage: -# zephyr_create_scope() -# -# Create a new scope for creation of scoped variables. -# -# : Name of new scope. -# -function(zephyr_create_scope scope) - if(TARGET ${scope}_scope) - message(FATAL_ERROR "zephyr_create_scope(${scope}) already exists.") - endif() - - add_custom_target(${scope}_scope) -endfunction() - -# Usage: -# zephyr_set( SCOPE [APPEND]) -# -# Zephyr extension of CMake set which allows a variable to be set in a specific -# scope. The scope is used on later zephyr_get() invocation for precedence -# handling when a variable it set in multiple scopes. -# -# : Name of variable -# : Value of variable, multiple values will create a list. -# The SCOPE argument identifies the end of value list. -# SCOPE : Name of scope for the variable -# APPEND : Append values to the already existing variable in -# -function(zephyr_set variable) - cmake_parse_arguments(SET_VAR "APPEND" "SCOPE" "" ${ARGN}) - - zephyr_check_arguments_required_all(zephyr_set SET_VAR SCOPE) - - if(NOT TARGET ${SET_VAR_SCOPE}_scope) - message(FATAL_ERROR "zephyr_set(... SCOPE ${SET_VAR_SCOPE}) doesn't exists.") - endif() - - if(SET_VAR_APPEND) - set(property_args APPEND) - endif() - - set_property(TARGET ${SET_VAR_SCOPE}_scope ${property_args} - PROPERTY ${variable} ${SET_VAR_UNPARSED_ARGUMENTS} - ) -endfunction() - # Usage: # zephyr_check_cache( [REQUIRED]) # From 30cc75adef87b568142b10b689b4011971c55112 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 208/528] Revert "[nrf fromtree] snippets: support for EXTRA_DTC_OVERLAY_FILE and EXTRA_CONF_FILE" This reverts commit b02e3ccafb1d8596b5974e357362c7341cc3ec63. Signed-off-by: Robert Lubos --- doc/build/snippets/writing.rst | 14 +++++++------- scripts/schemas/snippet-schema.yml | 4 ++-- scripts/snippets.py | 2 +- snippets/cdc-acm-console/snippet.yml | 4 ++-- .../extra_snippet_root/snippets/bar/snippet.yml | 2 +- tests/cmake/snippets/snippets/foo/snippet.yml | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/doc/build/snippets/writing.rst b/doc/build/snippets/writing.rst index 5a60a7e73836..66101e8e2b63 100644 --- a/doc/build/snippets/writing.rst +++ b/doc/build/snippets/writing.rst @@ -28,8 +28,8 @@ this: name: foo append: - EXTRA_DTC_OVERLAY_FILE: foo.overlay - EXTRA_CONF_FILE: foo.conf + DTC_OVERLAY_FILE: foo.overlay + OVERLAY_CONFIG: foo.conf Namespacing *********** @@ -113,7 +113,7 @@ This :file:`snippet.yml` adds :file:`foo.overlay` to the build: name: foo append: - EXTRA_DTC_OVERLAY_FILE: foo.overlay + DTC_OVERLAY_FILE: foo.overlay The path to :file:`foo.overlay` is relative to the directory containing :file:`snippet.yml`. @@ -129,7 +129,7 @@ This :file:`snippet.yml` adds :file:`foo.conf` to the build: name: foo append: - EXTRA_CONF_FILE: foo.conf + OVERLAY_CONFIG: foo.conf The path to :file:`foo.conf` is relative to the directory containing :file:`snippet.yml`. @@ -154,10 +154,10 @@ By name boards: bar: # settings for board "bar" go here append: - EXTRA_DTC_OVERLAY_FILE: bar.overlay + DTC_OVERLAY_FILE: bar.overlay baz: # settings for board "baz" go here append: - EXTRA_DTC_OVERLAY_FILE: baz.overlay + DTC_OVERLAY_FILE: baz.overlay The above example uses :file:`bar.overlay` when building for board ``bar``, and :file:`baz.overlay` when building for ``baz``. @@ -180,7 +180,7 @@ For example: boards: /my_vendor_.*/: append: - EXTRA_DTC_OVERLAY_FILE: my_vendor.overlay + DTC_OVERLAY_FILE: my_vendor.overlay The above example uses devicetree overlay :file:`my_vendor.overlay` when building for either board ``my_vendor_board1`` or ``my_vendor_board2``. It diff --git a/scripts/schemas/snippet-schema.yml b/scripts/schemas/snippet-schema.yml index 64cebaedc7c2..d6c46d543238 100644 --- a/scripts/schemas/snippet-schema.yml +++ b/scripts/schemas/snippet-schema.yml @@ -9,9 +9,9 @@ schema;append-schema: # See uses under 'append:' keys below. type: map mapping: - EXTRA_DTC_OVERLAY_FILE: + DTC_OVERLAY_FILE: type: str - EXTRA_CONF_FILE: + OVERLAY_CONFIG: type: str type: map diff --git a/scripts/snippets.py b/scripts/snippets.py index 74e7ebbbfcea..2158613a1490 100644 --- a/scripts/snippets.py +++ b/scripts/snippets.py @@ -52,7 +52,7 @@ def process_data(self, pathobj: Path, snippet_data: dict): '''Process the data in a snippet.yml file, after it is loaded into a python object and validated by pykwalify.''' def append_value(variable, value): - if variable in ('EXTRA_DTC_OVERLAY_FILE', 'EXTRA_CONF_FILE'): + if variable in ('DTC_OVERLAY_FILE', 'OVERLAY_CONFIG'): path = pathobj.parent / value if not path.is_file(): _err(f'snippet file {pathobj}: {variable}: file not found: {path}') diff --git a/snippets/cdc-acm-console/snippet.yml b/snippets/cdc-acm-console/snippet.yml index 98ff05bc14a7..eab58a30a40e 100644 --- a/snippets/cdc-acm-console/snippet.yml +++ b/snippets/cdc-acm-console/snippet.yml @@ -1,4 +1,4 @@ name: cdc-acm-console append: - EXTRA_CONF_FILE: cdc-acm-console.conf - EXTRA_DTC_OVERLAY_FILE: cdc-acm-console.overlay + OVERLAY_CONFIG: cdc-acm-console.conf + DTC_OVERLAY_FILE: cdc-acm-console.overlay diff --git a/tests/cmake/snippets/extra_snippet_root/snippets/bar/snippet.yml b/tests/cmake/snippets/extra_snippet_root/snippets/bar/snippet.yml index 607ad57a2c0b..914371337791 100644 --- a/tests/cmake/snippets/extra_snippet_root/snippets/bar/snippet.yml +++ b/tests/cmake/snippets/extra_snippet_root/snippets/bar/snippet.yml @@ -1,3 +1,3 @@ name: bar append: - EXTRA_DTC_OVERLAY_FILE: bar.overlay + DTC_OVERLAY_FILE: bar.overlay diff --git a/tests/cmake/snippets/snippets/foo/snippet.yml b/tests/cmake/snippets/snippets/foo/snippet.yml index ba39e7db108c..22817d7ebf1b 100644 --- a/tests/cmake/snippets/snippets/foo/snippet.yml +++ b/tests/cmake/snippets/snippets/foo/snippet.yml @@ -1,3 +1,3 @@ name: foo append: - EXTRA_CONF_FILE: foo.conf + OVERLAY_CONFIG: foo.conf From 908110e95efd6dfcc3c839d7c77002b5fd6aad79 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 209/528] Revert "[nrf fromtree] cmake: add reverse option to `zephyr_get(... MERGE)`" This reverts commit d94f71aa34cb16216312e4d13e4fe60e730f6470. Signed-off-by: Robert Lubos --- cmake/modules/extensions.cmake | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index a18b9b0efeee..4f75b41282b5 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2493,13 +2493,10 @@ function(zephyr_var_name variable scope out) endfunction() # Usage: -# zephyr_get( [MERGE [REVERSE]] [SYSBUILD [LOCAL|GLOBAL]] [VAR ...]) +# zephyr_get( [MERGE] [SYSBUILD [LOCAL|GLOBAL]] [VAR ...]) # # Return the value of as local scoped variable of same name. If MERGE -# is supplied, will return a list of found items. If REVERSE is supplied -# together with MERGE, the order of the list will be reversed before being -# returned. Reverse will happen before the list is returned and hence it will -# not change the order of precedence in which the list itself is constructed. +# is supplied, will return a list of found items. # # VAR can be used either to store the result in a variable with a different # name, or to look for values from multiple variables. @@ -2529,7 +2526,7 @@ endfunction() # using `-DZEPHYR_TOOLCHAIN_VARIANT=`, then the value from the cache is # returned. function(zephyr_get variable) - cmake_parse_arguments(GET_VAR "MERGE;REVERSE" "SYSBUILD" "VAR" ${ARGN}) + cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "VAR" ${ARGN}) if(DEFINED GET_VAR_SYSBUILD) if(NOT ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR @@ -2541,10 +2538,6 @@ function(zephyr_get variable) set(GET_VAR_SYSBUILD "GLOBAL") endif() - if(GET_VAR_REVERSE AND NOT GET_VAR_MERGE) - message(FATAL_ERROR "zephyr_get(... REVERSE) missing a required argument: MERGE") - endif() - if(NOT DEFINED GET_VAR_VAR) set(GET_VAR_VAR ${variable}) endif() @@ -2571,9 +2564,6 @@ function(zephyr_get variable) endforeach() set(scopes "sysbuild;CACHE;ENV;current") - if(GET_VAR_REVERSE) - list(REVERSE scopes) - endif() foreach(scope IN LISTS scopes) foreach(var ${GET_VAR_VAR}) zephyr_var_name("${var}" "${scope}" expansion_var) @@ -2611,13 +2601,7 @@ function(zephyr_get variable) endforeach() if(GET_VAR_MERGE) - if(GET_VAR_REVERSE) - list(REVERSE ${variable}) - list(REMOVE_DUPLICATES ${variable}) - list(REVERSE ${variable}) - else() - list(REMOVE_DUPLICATES ${variable}) - endif() + list(REMOVE_DUPLICATES ${variable}) set(${variable} ${${variable}} PARENT_SCOPE) endif() endfunction(zephyr_get variable) From 3dd32ea2bf432aaee7f14a2869e9e52027a827a4 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 210/528] Revert "[nrf fromtree] doc: update Zephyr modules to use EXTRA_ZEPHYR_MODULES" This reverts commit 66d000aaf64e341f1e79fd9c1383ffcc484eba1a. Signed-off-by: Robert Lubos --- doc/develop/application/index.rst | 2 +- doc/develop/env_vars.rst | 2 +- doc/develop/modules.rst | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index e1400b62b55c..ca9591bf44c7 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -422,7 +422,7 @@ should know about. variable, it must be a complete list of all modules to use, as the build system will not automatically pick up any modules from west. -* :makevar:`EXTRA_ZEPHYR_MODULES`: Like :makevar:`ZEPHYR_MODULES`, except these +* :makevar:`ZEPHYR_EXTRA_MODULES`: Like :makevar:`ZEPHYR_MODULES`, except these will be added to the list of modules found via west, instead of replacing it. .. note:: diff --git a/doc/develop/env_vars.rst b/doc/develop/env_vars.rst index 459c62b580ae..e5f7269fba5f 100644 --- a/doc/develop/env_vars.rst +++ b/doc/develop/env_vars.rst @@ -185,7 +185,7 @@ a comprehensive list. See :ref:`important-build-vars`. -.. envvar:: EXTRA_ZEPHYR_MODULES +.. envvar:: ZEPHYR_EXTRA_MODULES See :ref:`important-build-vars`. diff --git a/doc/develop/modules.rst b/doc/develop/modules.rst index ab827e911d1c..88467223481d 100644 --- a/doc/develop/modules.rst +++ b/doc/develop/modules.rst @@ -396,16 +396,16 @@ added to the build using CMake's `add_subdirectory()`_ command, and the If you have :ref:`west ` installed, you don't need to worry about how this variable is defined unless you are adding a new module. The build system knows how to use west to set :makevar:`ZEPHYR_MODULES`. You can add additional -modules to this list by setting the :makevar:`EXTRA_ZEPHYR_MODULES` CMake -variable or by adding a :makevar:`EXTRA_ZEPHYR_MODULES` line to ``.zephyrrc`` +modules to this list by setting the :makevar:`ZEPHYR_EXTRA_MODULES` CMake +variable or by adding a :makevar:`ZEPHYR_EXTRA_MODULES` line to ``.zephyrrc`` (See the section on :ref:`env_vars` for more details). This can be useful if you want to keep the list of modules found with west and also add your own. .. note:: If the module ``FOO`` is provided by :ref:`west ` but also given with - ``-DEXTRA_ZEPHYR_MODULES=//foo`` then the module given by the command - line variable :makevar:`EXTRA_ZEPHYR_MODULES` will take precedence. + ``-DZEPHYR_EXTRA_MODULES=//foo`` then the module given by the command + line variable :makevar:`ZEPHYR_EXTRA_MODULES` will take precedence. This allows you to use a custom version of ``FOO`` when building and still use other Zephyr modules provided by :ref:`west `. This can for example be useful for special test purposes. From 3084eebc06b06490b54d34d45f67f046ea0228a2 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 211/528] Revert "[nrf fromtree] cmake: align Zephyr module variable to EXTRA_ZEPHYR_MODULES" This reverts commit 6a780ae402663cc2ca615aae40ae36e849b2b767. Signed-off-by: Robert Lubos --- CMakeLists.txt | 2 +- cmake/modules/zephyr_module.cmake | 8 ++++---- .../out_of_tree_driver/CMakeLists.txt | 2 +- tests/cmake/overlays/var_expansions/CMakeLists.txt | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index cda9062d0b7d..41e104494673 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1585,7 +1585,7 @@ if(CONFIG_BUILD_OUTPUT_META) COMMAND ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/zephyr_module.py ${WEST_ARG} ${ZEPHYR_MODULES_ARG} - ${EXTRA_ZEPHYR_MODULES_ARG} + ${ZEPHYR_EXTRA_MODULES_ARG} --meta-out ${KERNEL_META_NAME} $<$:--meta-state-propagate> ) diff --git a/cmake/modules/zephyr_module.cmake b/cmake/modules/zephyr_module.cmake index 90afc1f02e5b..05d13cf5f246 100644 --- a/cmake/modules/zephyr_module.cmake +++ b/cmake/modules/zephyr_module.cmake @@ -36,9 +36,9 @@ if(ZEPHYR_MODULES) set(ZEPHYR_MODULES_ARG "--modules" ${ZEPHYR_MODULES}) endif() -zephyr_get(EXTRA_ZEPHYR_MODULES VAR EXTRA_ZEPHYR_MODULES ZEPHYR_EXTRA_MODULES) -if(EXTRA_ZEPHYR_MODULES) - set(EXTRA_ZEPHYR_MODULES_ARG "--extra-modules" ${EXTRA_ZEPHYR_MODULES}) +zephyr_get(ZEPHYR_EXTRA_MODULES) +if(ZEPHYR_EXTRA_MODULES) + set(ZEPHYR_EXTRA_MODULES_ARG "--extra-modules" ${ZEPHYR_EXTRA_MODULES}) endif() file(MAKE_DIRECTORY ${KCONFIG_BINARY_DIR}) @@ -60,7 +60,7 @@ if(WEST OR ZEPHYR_MODULES) ${PYTHON_EXECUTABLE} ${ZEPHYR_BASE}/scripts/zephyr_module.py ${west_arg} ${ZEPHYR_MODULES_ARG} - ${EXTRA_ZEPHYR_MODULES_ARG} + ${ZEPHYR_EXTRA_MODULES_ARG} --kconfig-out ${kconfig_modules_file} --cmake-out ${cmake_modules_file} --sysbuild-kconfig-out ${kconfig_sysbuild_file} diff --git a/samples/application_development/out_of_tree_driver/CMakeLists.txt b/samples/application_development/out_of_tree_driver/CMakeLists.txt index a234427218f3..3f3932363d08 100644 --- a/samples/application_development/out_of_tree_driver/CMakeLists.txt +++ b/samples/application_development/out_of_tree_driver/CMakeLists.txt @@ -2,7 +2,7 @@ # For the sake of demonstration, we add the driver directory as a zephyr module # by hand. If your driver is a project that's managed by west, you can remove this line. -list(APPEND EXTRA_ZEPHYR_MODULES +list(APPEND ZEPHYR_EXTRA_MODULES ${CMAKE_CURRENT_SOURCE_DIR}/hello_world_module ) diff --git a/tests/cmake/overlays/var_expansions/CMakeLists.txt b/tests/cmake/overlays/var_expansions/CMakeLists.txt index a36cc87bf8e2..db382a53e966 100644 --- a/tests/cmake/overlays/var_expansions/CMakeLists.txt +++ b/tests/cmake/overlays/var_expansions/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.20.0) set(ZEPHYR_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/my_module") -set(EXTRA_ZEPHYR_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/my_extra_module") +set(ZEPHYR_EXTRA_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/my_extra_module") find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(overlay_var_expansions) From 89e3a959f90739dd514ee22c9dccfd621d0fdda0 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 212/528] Revert "[nrf fromtree] doc: samples: update OVERLAY_CONFIG to EXTRA_CONF_FILE" This reverts commit 05e299fbbf498c5adcb8618b5daa25b8a2da0126. Signed-off-by: Robert Lubos --- samples/bluetooth/broadcast_audio_sink/README.rst | 2 +- .../bluetooth/broadcast_audio_source/README.rst | 2 +- .../bluetooth/direction_finding_central/README.rst | 2 +- .../direction_finding_connectionless_rx/README.rst | 2 +- .../direction_finding_connectionless_tx/README.rst | 2 +- .../direction_finding_peripheral/README.rst | 2 +- samples/bluetooth/hci_uart/README.rst | 2 +- samples/bluetooth/iso_broadcast/README.rst | 2 +- samples/bluetooth/iso_receive/README.rst | 2 +- samples/drivers/spi_flash_at45/README.rst | 6 +++--- samples/net/cloud/tagoio_http_post/README.rst | 8 ++++---- samples/net/mqtt_publisher/README.rst | 6 +++--- samples/net/openthread/coprocessor/README.rst | 2 +- samples/net/sockets/big_http_download/README.rst | 2 +- samples/net/sockets/echo_client/README.rst | 6 +++--- samples/net/sockets/echo_server/README.rst | 4 ++-- samples/net/sockets/http_client/README.rst | 2 +- samples/net/sockets/http_get/README.rst | 2 +- samples/net/sockets/tcp/README.rst | 2 +- samples/net/sockets/websocket_client/README.rst | 2 +- samples/net/wpanusb/README.rst | 2 +- samples/subsys/fs/fat_fs/README.rst | 2 +- samples/subsys/lorawan/class_a/README.rst | 2 +- samples/subsys/mgmt/mcumgr/smp_svr/README.rst | 10 +++++----- samples/subsys/mgmt/updatehub/README.rst | 14 +++++++------- samples/subsys/modbus/rtu_server/README.rst | 2 +- samples/subsys/usb/dfu/README.rst | 2 +- samples/subsys/usb/shell/README.rst | 2 +- 28 files changed, 48 insertions(+), 48 deletions(-) diff --git a/samples/bluetooth/broadcast_audio_sink/README.rst b/samples/bluetooth/broadcast_audio_sink/README.rst index cb0aabc970d6..f733dc201cf9 100644 --- a/samples/bluetooth/broadcast_audio_sink/README.rst +++ b/samples/bluetooth/broadcast_audio_sink/README.rst @@ -20,7 +20,7 @@ Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/broadcast_audio_sink` in the Zephyr tree. -Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO +Use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/broadcast_audio_source/README.rst b/samples/bluetooth/broadcast_audio_source/README.rst index 12fb6c0ca1a6..223fa27443d4 100644 --- a/samples/bluetooth/broadcast_audio_source/README.rst +++ b/samples/bluetooth/broadcast_audio_source/README.rst @@ -23,7 +23,7 @@ Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/broadcast_audio_source` in the Zephyr tree. -Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable required ISO +Use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/direction_finding_central/README.rst b/samples/bluetooth/direction_finding_central/README.rst index 17cbc599f6bd..0f3e4c0cc542 100644 --- a/samples/bluetooth/direction_finding_central/README.rst +++ b/samples/bluetooth/direction_finding_central/README.rst @@ -32,7 +32,7 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :zephyr-app: samples/bluetooth/direction_finding_central :host-os: unix :board: nrf52833dk_nrf52833 - :gen-args: -DEXTRA_CONF_FILE=overlay-aod.conf + :gen-args: -DOVERLAY_CONFIG=overlay-aod.conf :goals: build flash :compact: diff --git a/samples/bluetooth/direction_finding_connectionless_rx/README.rst b/samples/bluetooth/direction_finding_connectionless_rx/README.rst index b7a970acbc4f..7fb187bc929f 100644 --- a/samples/bluetooth/direction_finding_connectionless_rx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_rx/README.rst @@ -32,7 +32,7 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :zephyr-app: samples/bluetooth/direction_finding_connectionless_rx :host-os: unix :board: nrf52833dk_nrf52833 - :gen-args: -DEXTRA_CONF_FILE=overlay-aod.conf + :gen-args: -DOVERLAY_CONFIG=overlay-aod.conf :goals: build flash :compact: diff --git a/samples/bluetooth/direction_finding_connectionless_tx/README.rst b/samples/bluetooth/direction_finding_connectionless_tx/README.rst index ca27319cbc7e..6fffb9198b59 100644 --- a/samples/bluetooth/direction_finding_connectionless_tx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_tx/README.rst @@ -32,7 +32,7 @@ To use Angle of Arrival mode only, build this application as follows, changing :zephyr-app: samples/bluetooth/direction_finding_connectionless_tx :host-os: unix :board: nrf52833dk_nrf52833 - :gen-args: -DEXTRA_CONF_FILE=overlay-aoa.conf + :gen-args: -DOVERLAY_CONFIG=overlay-aoa.conf :goals: build flash :compact: diff --git a/samples/bluetooth/direction_finding_peripheral/README.rst b/samples/bluetooth/direction_finding_peripheral/README.rst index 36846c84d6f2..0a8e7791c3aa 100644 --- a/samples/bluetooth/direction_finding_peripheral/README.rst +++ b/samples/bluetooth/direction_finding_peripheral/README.rst @@ -31,7 +31,7 @@ changing ``nrf52833dk_nrf52833`` as needed for your board: :zephyr-app: samples/bluetooth/direction_finding_peripheral :host-os: unix :board: nrf52833dk_nrf52833 - :gen-args: -DEXTRA_CONF_FILE=overlay-aoa.conf + :gen-args: -DOVERLAY_CONFIG=overlay-aoa.conf :goals: build flash :compact: diff --git a/samples/bluetooth/hci_uart/README.rst b/samples/bluetooth/hci_uart/README.rst index 21e46970eb6b..1bd915de2117 100644 --- a/samples/bluetooth/hci_uart/README.rst +++ b/samples/bluetooth/hci_uart/README.rst @@ -122,7 +122,7 @@ application. To enable debug over RTT the debug configuration file can be used. .. code-block:: console - west build samples/bluetooth/hci_uart -- -DEXTRA_CONF_FILE='debug.conf' + west build samples/bluetooth/hci_uart -- -DOVERLAY_CONFIG='debug.conf' Then attach RTT as described here: :ref:`Using Segger J-Link ` diff --git a/samples/bluetooth/iso_broadcast/README.rst b/samples/bluetooth/iso_broadcast/README.rst index 6b4bb276ab16..0caec4201579 100644 --- a/samples/bluetooth/iso_broadcast/README.rst +++ b/samples/bluetooth/iso_broadcast/README.rst @@ -21,7 +21,7 @@ Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/iso_broadcast` in -the Zephyr tree. Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable +the Zephyr tree. Use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. Use the sample found under :zephyr_file:`samples/bluetooth/iso_receive` in the diff --git a/samples/bluetooth/iso_receive/README.rst b/samples/bluetooth/iso_receive/README.rst index d4bb1a4951ba..6e5d871bb618 100644 --- a/samples/bluetooth/iso_receive/README.rst +++ b/samples/bluetooth/iso_receive/README.rst @@ -21,7 +21,7 @@ Building and Running ******************** This sample can be found under :zephyr_file:`samples/bluetooth/iso_receive` in -the Zephyr tree. Use `-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf` to enable +the Zephyr tree. Use `-DOVERLAY_CONFIG=overlay-bt_ll_sw_split.conf` to enable required ISO feature support in Zephyr Bluetooth Controller on supported boards. Use the sample found under :zephyr_file:`samples/bluetooth/iso_broadcast` on diff --git a/samples/drivers/spi_flash_at45/README.rst b/samples/drivers/spi_flash_at45/README.rst index c8d5b60c91ef..a53a84bc9bf3 100644 --- a/samples/drivers/spi_flash_at45/README.rst +++ b/samples/drivers/spi_flash_at45/README.rst @@ -51,7 +51,7 @@ To build and flash with device power management enabled: .. zephyr-app-commands:: :zephyr-app: samples/drivers/spi_flash_at45 :board: nrf9160dk_nrf9160 - :gen-args: -DEXTRA_CONF_FILE=overlay-pm.conf + :gen-args: -DOVERLAY_CONFIG=overlay-pm.conf :goals: build flash :compact: @@ -60,7 +60,7 @@ To build and flash with flash page layout enabled: .. zephyr-app-commands:: :zephyr-app: samples/drivers/spi_flash_at45 :board: nrf9160dk_nrf9160 - :gen-args: -DEXTRA_CONF_FILE=overlay-page_layout.conf + :gen-args: -DOVERLAY_CONFIG=overlay-page_layout.conf :goals: build flash :compact: @@ -70,7 +70,7 @@ layout enabled: .. zephyr-app-commands:: :zephyr-app: samples/drivers/spi_flash_at45 :board: nrf9160dk_nrf9160 - :gen-args: -DEXTRA_CONF_FILE="overlay-pm.conf overlay-page_layout.conf" + :gen-args: -DOVERLAY_CONFIG="overlay-pm.conf overlay-page_layout.conf" :goals: build flash :compact: diff --git a/samples/net/cloud/tagoio_http_post/README.rst b/samples/net/cloud/tagoio_http_post/README.rst index 235a35265e4b..62a8491b6187 100644 --- a/samples/net/cloud/tagoio_http_post/README.rst +++ b/samples/net/cloud/tagoio_http_post/README.rst @@ -68,7 +68,7 @@ need fill ``CONFIG_TAGOIO_HTTP_WIFI_SSID`` with your wifi network SSID and .. zephyr-app-commands:: :zephyr-app: samples/net/cloud/tagoio_http_post :board: disco_l475_iot1 - :gen-args: -DEXTRA_CONF_FILE=overlay-wifi.conf + :gen-args: -DOVERLAY_CONFIG=overlay-wifi.conf :goals: build flash :compact: @@ -76,7 +76,7 @@ need fill ``CONFIG_TAGOIO_HTTP_WIFI_SSID`` with your wifi network SSID and :zephyr-app: samples/net/cloud/tagoio_http_post :board: [sam_v71_xult | frdm_k64f | nucleo_f767zi] :shield: [esp_8266_arduino | inventek_eswifi_arduino_uart] - :gen-args: -DEXTRA_CONF_FILE=overlay-wifi.conf + :gen-args: -DOVERLAY_CONFIG=overlay-wifi.conf :goals: build flash :compact: @@ -97,14 +97,14 @@ a special designator like defined at ``arduino.overlay``. .. zephyr-app-commands:: :zephyr-app: samples/net/cloud/tagoio_http_post :board: sam4e_xpro - :gen-args: -DEXTRA_CONF_FILE=overlay-modem.conf + :gen-args: -DOVERLAY_CONFIG=overlay-modem.conf :goals: build flash :compact: .. zephyr-app-commands:: :zephyr-app: samples/net/cloud/tagoio_http_post :board: frdm_k64f - :gen-args: -DEXTRA_CONF_FILE=overlay-modem.conf -DDTC_OVERLAY_FILE=arduino.overlay + :gen-args: -DOVERLAY_CONFIG=overlay-modem.conf -DDTC_OVERLAY_FILE=arduino.overlay :goals: build flash :compact: diff --git a/samples/net/mqtt_publisher/README.rst b/samples/net/mqtt_publisher/README.rst index 04ff4c47bfd2..05f0541d65d5 100644 --- a/samples/net/mqtt_publisher/README.rst +++ b/samples/net/mqtt_publisher/README.rst @@ -129,7 +129,7 @@ try this sample with TLS enabled, by following these steps: i.e., the IP address of test.mosquitto.org ``"37.187.106.16"`` - In :file:`src/main.c`, set TLS_SNI_HOSTNAME to ``"test.mosquitto.org"`` to match the Common Name (CN) in the downloaded certificate. -- Build the sample by specifying ``-DEXTRA_CONF_FILE=overlay-tls.conf`` +- Build the sample by specifying ``-DOVERLAY_CONFIG=overlay-tls.conf`` when running ``west build`` or ``cmake`` (or refer to the TLS offloading section below if your platform uses the offloading feature). - Flash the binary onto the device to run the sample: @@ -142,7 +142,7 @@ TLS offloading ============== For boards that support this feature, TLS offloading is used by -specifying ``-DEXTRA_CONF_FILE=overlay-tls-offload.conf`` when running ``west +specifying ``-DOVERLAY_CONFIG=overlay-tls-offload.conf`` when running ``west build`` or ``cmake``. Using this overlay enables TLS without bringing in mbedtls. @@ -151,7 +151,7 @@ SOCKS5 proxy support ==================== It is also possible to connect to the MQTT broker through a SOCKS5 proxy. -To enable it, use ``-DEXTRA_CONF_FILE=overlay-socks5.conf`` when running ``west +To enable it, use ``-DOVERLAY_CONFIG=overlay-socks5.conf`` when running ``west build`` or ``cmake``. By default, to make the testing easier, the proxy is expected to run on the diff --git a/samples/net/openthread/coprocessor/README.rst b/samples/net/openthread/coprocessor/README.rst index ee76942c3fcd..1c315d4f4d75 100644 --- a/samples/net/openthread/coprocessor/README.rst +++ b/samples/net/openthread/coprocessor/README.rst @@ -38,7 +38,7 @@ Build the OpenThread NCP sample application which uses CDC ACM UART device: :zephyr-app: samples/net/openthread/coprocessor :board: nrf52840dk_nrf52840 :goals: build flash - :gen-args: -DDTC_OVERLAY_FILE=usb.overlay -DEXTRA_CONF_FILE=overlay-usb-nrf-br.conf + :gen-args: -DDTC_OVERLAY_FILE=usb.overlay -DOVERLAY_CONFIG=overlay-usb-nrf-br.conf :compact: Example building for the nrf52840dk_nrf52840 for RCP: diff --git a/samples/net/sockets/big_http_download/README.rst b/samples/net/sockets/big_http_download/README.rst index 0cefa7320637..3eaa9a19bab9 100644 --- a/samples/net/sockets/big_http_download/README.rst +++ b/samples/net/sockets/big_http_download/README.rst @@ -74,7 +74,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when +An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when running ``west build`` or ``cmake``. The TLS version of this sample downloads a file from diff --git a/samples/net/sockets/echo_client/README.rst b/samples/net/sockets/echo_client/README.rst index 31d03d18202e..bcde370d8ae8 100644 --- a/samples/net/sockets/echo_client/README.rst +++ b/samples/net/sockets/echo_client/README.rst @@ -75,7 +75,7 @@ Example building for the IEEE 802.15.4 RF2XX transceiver: :zephyr-app: samples/net/sockets/echo_client :host-os: unix :board: [atsamr21_xpro | sam4s_xplained | sam_v71_xult] - :gen-args: -DEXTRA_CONF_FILE=overlay-802154.conf + :gen-args: -DOVERLAY_CONFIG=overlay-802154.conf :goals: build flash :compact: @@ -100,7 +100,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when +An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when running ``west build`` or ``cmake``. The certificate and private key used by the sample can be found in the sample's @@ -112,7 +112,7 @@ SOCKS5 proxy support ==================== It is also possible to connect to the echo-server through a SOCKS5 proxy. -To enable it, use ``-DEXTRA_CONF_FILE=overlay-socks5.conf`` when running ``west +To enable it, use ``-DOVERLAY_CONFIG=overlay-socks5.conf`` when running ``west build`` or ``cmake``. By default, to make the testing easier, the proxy is expected to run on the diff --git a/samples/net/sockets/echo_server/README.rst b/samples/net/sockets/echo_server/README.rst index 98260d798730..3be89983a962 100644 --- a/samples/net/sockets/echo_server/README.rst +++ b/samples/net/sockets/echo_server/README.rst @@ -82,7 +82,7 @@ Example building for the atsamr21_xpro with RF2XX driver support: :zephyr-app: samples/net/sockets/echo_server :host-os: unix :board: [atsamr21_xpro | sam4e_xpro | sam_v71_xult] - :gen-args: -DEXTRA_CONF_FILE=overlay-802154.conf + :gen-args: -DOVERLAY_CONFIG=overlay-802154.conf :goals: build flash :compact: @@ -105,7 +105,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when +An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when running ``west build`` or ``cmake``. The certificate used by the sample can be found in the sample's ``src`` diff --git a/samples/net/sockets/http_client/README.rst b/samples/net/sockets/http_client/README.rst index 1d37121ad568..4d1459f8a8fc 100644 --- a/samples/net/sockets/http_client/README.rst +++ b/samples/net/sockets/http_client/README.rst @@ -45,7 +45,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when +An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when running ``west build`` or ``cmake``. The certificate and private key used by the sample can be found in the sample's diff --git a/samples/net/sockets/http_get/README.rst b/samples/net/sockets/http_get/README.rst index bd4a6824d7f3..07c03fa1fae1 100644 --- a/samples/net/sockets/http_get/README.rst +++ b/samples/net/sockets/http_get/README.rst @@ -53,7 +53,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when +An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when running ``west build`` or ``cmake``. For boards that support TLS offloading (e.g. TI's cc3220sf_launchxl), use diff --git a/samples/net/sockets/tcp/README.rst b/samples/net/sockets/tcp/README.rst index 5f43d02d41ff..d574fdfcf94e 100644 --- a/samples/net/sockets/tcp/README.rst +++ b/samples/net/sockets/tcp/README.rst @@ -26,7 +26,7 @@ Build the TCP sample app: cd samples/net/sockets/tcp mkdir build && cd build - cmake -DBOARD=qemu_x86 -DEXTRA_CONF_FILE="overlay-slip.conf" .. + cmake -DBOARD=qemu_x86 -DOVERLAY_CONFIG="overlay-slip.conf" .. make run Compile and run the TCP sanity check `net-test-suites`_: diff --git a/samples/net/sockets/websocket_client/README.rst b/samples/net/sockets/websocket_client/README.rst index d6ae83b568ff..ee115fbe8f02 100644 --- a/samples/net/sockets/websocket_client/README.rst +++ b/samples/net/sockets/websocket_client/README.rst @@ -46,7 +46,7 @@ Enable TLS support in the sample by building the project with the :goals: build :compact: -An alternative way is to specify ``-DEXTRA_CONF_FILE=overlay-tls.conf`` when +An alternative way is to specify ``-DOVERLAY_CONFIG=overlay-tls.conf`` when running ``west build`` or ``cmake``. The certificate and private key used by the sample can be found in the sample's diff --git a/samples/net/wpanusb/README.rst b/samples/net/wpanusb/README.rst index e6e87502a661..bc53cfa3cd15 100644 --- a/samples/net/wpanusb/README.rst +++ b/samples/net/wpanusb/README.rst @@ -39,7 +39,7 @@ Build the wpanusb sample for a board: .. zephyr-app-commands:: :zephyr-app: samples/net/wpanusb :board: - :gen-args: -DEXTRA_CONF_FILE= + :gen-args: -DOVERLAY_CONFIG= :goals: build :compact: diff --git a/samples/subsys/fs/fat_fs/README.rst b/samples/subsys/fs/fat_fs/README.rst index 2f7ecb4952d7..935c93aed60d 100644 --- a/samples/subsys/fs/fat_fs/README.rst +++ b/samples/subsys/fs/fat_fs/README.rst @@ -59,7 +59,7 @@ and DTS overlays need to be also selected. The command would look like this: .. zephyr-app-commands:: :zephyr-app: samples/subsys/fs/fat_fs :board: nrf52840dk_nrf52840 - :gen-args: -DEXTRA_CONF_FILE=nrf52840dk_nrf52840_qspi.conf -DDTC_OVERLAY_FILE=nrf52840dk_nrf52840_qspi.overlay + :gen-args: -DOVERLAY_CONFIG=nrf52840dk_nrf52840_qspi.conf -DDTC_OVERLAY_FILE=nrf52840dk_nrf52840_qspi.overlay :goals: build :compact: diff --git a/samples/subsys/lorawan/class_a/README.rst b/samples/subsys/lorawan/class_a/README.rst index ba72fe1d4dac..4d923903fdf2 100644 --- a/samples/subsys/lorawan/class_a/README.rst +++ b/samples/subsys/lorawan/class_a/README.rst @@ -38,5 +38,5 @@ enabled. :zephyr-app: samples/subsys/lorawan/class_a :board: nucleo_wl55jc :goals: build flash - :gen-args: -DEXTRA_CONF_FILE=overlay-clock-sync.conf + :gen-args: -DOVERLAY_CONFIG=overlay-clock-sync.conf :compact: diff --git a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst index c988e4145648..1559d4123c69 100644 --- a/samples/subsys/mgmt/mcumgr/smp_svr/README.rst +++ b/samples/subsys/mgmt/mcumgr/smp_svr/README.rst @@ -93,7 +93,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b nrf52dk_nrf52832 \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DEXTRA_CONF_FILE=overlay-bt.conf + -DOVERLAY_CONFIG=overlay-bt.conf .. group-tab:: Serial @@ -105,7 +105,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DEXTRA_CONF_FILE='overlay-serial.conf;overlay-fs.conf;overlay-shell-mgmt.conf' + -DOVERLAY_CONFIG='overlay-serial.conf;overlay-fs.conf;overlay-shell-mgmt.conf' .. group-tab:: USB CDC_ACM @@ -117,7 +117,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b nrf52840dk_nrf52840 \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DEXTRA_CONF_FILE=overlay-cdc.conf \ + -DOVERLAY_CONFIG=overlay-cdc.conf \ -DDTC_OVERLAY_FILE=usb.overlay .. group-tab:: Shell @@ -130,7 +130,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DEXTRA_CONF_FILE='overlay-shell.conf' + -DOVERLAY_CONFIG='overlay-shell.conf' .. group-tab:: UDP @@ -146,7 +146,7 @@ Zephyr. The ``smp_svr`` sample comes in different flavours. -b frdm_k64f \ samples/subsys/mgmt/mcumgr/smp_svr \ -- \ - -DEXTRA_CONF_FILE=overlay-udp.conf + -DOVERLAY_CONFIG=overlay-udp.conf .. _smp_svr_sample_sign: diff --git a/samples/subsys/mgmt/updatehub/README.rst b/samples/subsys/mgmt/updatehub/README.rst index 0324ab970254..db16237a0a91 100644 --- a/samples/subsys/mgmt/updatehub/README.rst +++ b/samples/subsys/mgmt/updatehub/README.rst @@ -174,7 +174,7 @@ The ethernet depends only from base configuration. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: [ frdm_k64f | nucleo_f767zi ] :build-dir: app - :gen-args: -DEXTRA_CONF_FILE=overlay-prj.conf + :gen-args: -DOVERLAY_CONFIG=overlay-prj.conf :goals: build :compact: @@ -189,7 +189,7 @@ for details. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: [ frdm_k64f | nrf52840dk_nrf52840 | nucleo_f767zi ] :build-dir: app - :gen-args: -DEXTRA_CONF_FILE="overlay-wifi.conf;overlay-prj.conf" + :gen-args: -DOVERLAY_CONFIG="overlay-wifi.conf;overlay-prj.conf" :shield: esp_8266_arduino :goals: build :compact: @@ -209,7 +209,7 @@ uses PPP over GSM modem, see :ref:`gsm-modem-sample`. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: [ frdm_k64f | nrf52840dk_nrf52840 | nucleo_f767zi ] :build-dir: app - :gen-args: -DEXTRA_CONF_FILE="overlay-modem.conf;overlay-prj.conf" \ + :gen-args: -DOVERLAY_CONFIG="overlay-modem.conf;overlay-prj.conf" \ -DDTC_OVERLAY_FILE=arduino.overlay :goals: build :compact: @@ -228,7 +228,7 @@ tested with both native linux driver and ``atusb`` and with ``wpanusb`` sample. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: nrf52840dk_nrf52840 :build-dir: app - :gen-args: -DEXTRA_CONF_FILE="overlay-802154.conf;overlay-prj.conf" + :gen-args: -DOVERLAY_CONFIG="overlay-802154.conf;overlay-prj.conf" :goals: build :compact: @@ -236,7 +236,7 @@ tested with both native linux driver and ``atusb`` and with ``wpanusb`` sample. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: [ frdm_k64f | nucleo_f767zi ] :build-dir: app - :gen-args: -DEXTRA_CONF_FILE="overlay-802154.conf;overlay-prj.conf" + :gen-args: -DOVERLAY_CONFIG="overlay-802154.conf;overlay-prj.conf" :shield: atmel_rf2xx_arduino :goals: build :compact: @@ -256,7 +256,7 @@ tested with native linux driver and an USB dongle. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: nrf52840dk_nrf52840 :build-dir: app - :gen-args: -DEXTRA_CONF_FILE="overlay-ipsp.conf;overlay-prj.conf" + :gen-args: -DOVERLAY_CONFIG="overlay-ipsp.conf;overlay-prj.conf" :goals: build :compact: @@ -274,7 +274,7 @@ gateway was tested using two boards with OpenThread 1.1.1 on NCP mode. :zephyr-app: zephyr/samples/subsys/mgmt/updatehub :board: nrf52840dk_nrf52840 :build-dir: app - :gen-args: -DEXTRA_CONF_FILE="overlay-ot.conf;overlay-prj.conf" + :gen-args: -DOVERLAY_CONFIG="overlay-ot.conf;overlay-prj.conf" :goals: build :compact: diff --git a/samples/subsys/modbus/rtu_server/README.rst b/samples/subsys/modbus/rtu_server/README.rst index 973339e1cb78..bb29946f7d9c 100644 --- a/samples/subsys/modbus/rtu_server/README.rst +++ b/samples/subsys/modbus/rtu_server/README.rst @@ -67,7 +67,7 @@ The following commands build and flash RTU server sample using CDC ACM UART. :zephyr-app: samples/subsys/modbus/rtu_server :board: nrf52840dk_nrf52840 :goals: build flash - :gen-args: -DDTC_OVERLAY_FILE=cdc-acm.overlay -DEXTRA_CONF_FILE=overlay-cdc-acm.conf + :gen-args: -DDTC_OVERLAY_FILE=cdc-acm.overlay -DOVERLAY_CONFIG=overlay-cdc-acm.conf :compact: On the client side, PC or laptop, the following command connects PyModbus diff --git a/samples/subsys/usb/dfu/README.rst b/samples/subsys/usb/dfu/README.rst index 0ed2d7e6991e..dccb53db10fa 100644 --- a/samples/subsys/usb/dfu/README.rst +++ b/samples/subsys/usb/dfu/README.rst @@ -129,7 +129,7 @@ Both symbols can be enabled with the :file:`overlay-permanent-download.conf` ove west build -b nrf52840dk_nrf52840 zephyr/samples/subsys/usb/dfu -d build-dfu -- \ -DCONFIG_BOOTLOADER_MCUBOOT=y '-DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE="bootloader/mcuboot/root-rsa-2048.pem"' \ - -DEXTRA_CONF_FILE=overlay-permanent-download.conf + -DOVERLAY_CONFIG=overlay-permanent-download.conf The listing below shows the output to the console when downloading via dfu-util. diff --git a/samples/subsys/usb/shell/README.rst b/samples/subsys/usb/shell/README.rst index 12f7c0ae1939..09a57d252069 100644 --- a/samples/subsys/usb/shell/README.rst +++ b/samples/subsys/usb/shell/README.rst @@ -40,7 +40,7 @@ the platform has already defined or not `zephyr_uhc0` or `zephyr_udc0` nodelabel .. zephyr-app-commands:: :zephyr-app: samples/subsys/usb/shell :board: nrf52840dk_nrf52840 - :gen-args: -DEXTRA_CONF_FILE=virtual.conf -DDTC_OVERLAY_FILE=virtual.overlay + :gen-args: -DOVERLAY_CONFIG=virtual.conf -DDTC_OVERLAY_FILE=virtual.overlay :goals: flash :compact: From ca187410f738bc05919680244329e5daa54b99ad Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 213/528] Revert "[nrf fromtree] doc: introduce EXTRA_CONF_FILE and EXTRA_DTC_OVERLAY_FILE" This reverts commit 614c4dbe92af512ccee170e3ea38cb1ad85f6e19. Signed-off-by: Robert Lubos --- doc/build/dts/howtos.rst | 11 +---------- doc/build/kconfig/setting.rst | 3 +-- doc/connectivity/bluetooth/autopts/autopts-linux.rst | 2 +- .../networking/networking_with_multiple_instances.rst | 4 ++-- doc/connectivity/networking/qemu_802154_setup.rst | 6 +++--- doc/connectivity/networking/qemu_eth_setup.rst | 2 +- doc/develop/application/index.rst | 6 +++--- doc/develop/west/build-flash-debug.rst | 2 +- 8 files changed, 13 insertions(+), 23 deletions(-) diff --git a/doc/build/dts/howtos.rst b/doc/build/dts/howtos.rst index f1a003f2f94f..35bcf8ae8137 100644 --- a/doc/build/dts/howtos.rst +++ b/doc/build/dts/howtos.rst @@ -246,18 +246,9 @@ use as devicetree overlays: system will stop looking for more files. #. Otherwise, if :file:`app.overlay` exists, it will be used. -Extra devicetree overlays may be provided using ``EXTRA_DTC_OVERLAY_FILE`` which -will still allow the build system to automatically use devicetree overlays -described in the above steps. - -The build system appends overlays specified in ``EXTRA_DTC_OVERLAY_FILE`` -to the overlays in ``DTC_OVERLAY_FILE`` when processing devicetree overlays. -This means that changes made via ``EXTRA_DTC_OVERLAY_FILE`` have higher -precedence than those made via ``DTC_OVERLAY_FILE``. - All configuration files will be taken from the application's configuration directory except for files with an absolute path that are given with the -``DTC_OVERLAY_FILE`` or ``EXTRA_DTC_OVERLAY_FILE`` argument. +``DTC_OVERLAY_FILE`` argument. See :ref:`Application Configuration Directory ` on how the application configuration directory is defined. diff --git a/doc/build/kconfig/setting.rst b/doc/build/kconfig/setting.rst index 5f37e831e9e0..048aea25fa1b 100644 --- a/doc/build/kconfig/setting.rst +++ b/doc/build/kconfig/setting.rst @@ -170,8 +170,7 @@ used. All configuration files will be taken from the application's configuration directory except for files with an absolute path that are given with the -``CONF_FILE``, ``EXTRA_CONF_FILE``, ``DTC_OVERLAY_FILE``, and -``EXTRA_DTC_OVERLAY_FILE`` arguments. For these, +``CONF_FILE``, ``OVERLAY_CONFIG``, and ``DTC_OVERLAY_FILE`` arguments. For these, a file in a Zephyr module can be referred by escaping the Zephyr module dir variable like this ``\${ZEPHYR__MODULE_DIR}//`` when setting any of said variables in the application's :file:`CMakeLists.txt`. diff --git a/doc/connectivity/bluetooth/autopts/autopts-linux.rst b/doc/connectivity/bluetooth/autopts/autopts-linux.rst index 51ef1eab1fa5..fe300ad9db92 100644 --- a/doc/connectivity/bluetooth/autopts/autopts-linux.rst +++ b/doc/connectivity/bluetooth/autopts/autopts-linux.rst @@ -300,7 +300,7 @@ Testing Zephyr Host Stack on native posix: # A Bluetooth controller needs to be mounted. # For running with HCI UART, please visit: https://docs.zephyrproject.org/latest/samples/bluetooth/hci_uart/README.html#bluetooth-hci-uart - west build -b native_posix zephyr/tests/bluetooth/tester/ -DEXTRA_CONF_FILE=overlay-native.conf + west build -b native_posix zephyr/tests/bluetooth/tester/ -DOVERLAY_CONFIG=overlay-native.conf sudo python ./autoptsclient-zephyr.py "C:\Users\USER_NAME\Documents\Profile Tuning Suite\PTS_PROJECT\PTS_PROJECT.pqw6" \ ~/zephyrproject/build/zephyr/zephyr.exe -i SERVER_IP -l LOCAL_IP --hci 0 diff --git a/doc/connectivity/networking/networking_with_multiple_instances.rst b/doc/connectivity/networking/networking_with_multiple_instances.rst index 6bd4531c8295..783e37addf40 100644 --- a/doc/connectivity/networking/networking_with_multiple_instances.rst +++ b/doc/connectivity/networking/networking_with_multiple_instances.rst @@ -132,7 +132,7 @@ In terminal #4, if you are using QEMU, type this: west build -d build/server -b qemu_x86 -t run \ samples/net/sockets/echo_server -- \ - -DEXTRA_CONF_FILE=overlay-e1000.conf \ + -DOVERLAY_CONFIG=overlay-e1000.conf \ -DCONFIG_NET_CONFIG_MY_IPV4_ADDR=\"198.51.100.1\" \ -DCONFIG_NET_CONFIG_PEER_IPV4_ADDR=\"203.0.113.1\" \ -DCONFIG_NET_CONFIG_MY_IPV6_ADDR=\"2001:db8:100::1\" \ @@ -163,7 +163,7 @@ In terminal #5, if you are using QEMU, type this: west build -d build/client -b qemu_x86 -t run \ samples/net/sockets/echo_client -- \ - -DEXTRA_CONF_FILE=overlay-e1000.conf \ + -DOVERLAY_CONFIG=overlay-e1000.conf \ -DCONFIG_NET_CONFIG_MY_IPV4_ADDR=\"203.0.113.1\" \ -DCONFIG_NET_CONFIG_PEER_IPV4_ADDR=\"198.51.100.1\" \ -DCONFIG_NET_CONFIG_MY_IPV6_ADDR=\"2001:db8:200::1\" \ diff --git a/doc/connectivity/networking/qemu_802154_setup.rst b/doc/connectivity/networking/qemu_802154_setup.rst index 12b0ef74de9c..0e6f0af6aa8a 100644 --- a/doc/connectivity/networking/qemu_802154_setup.rst +++ b/doc/connectivity/networking/qemu_802154_setup.rst @@ -40,7 +40,7 @@ In terminal #1, type: :host-os: unix :board: qemu_x86 :build-dir: server - :gen-args: -DEXTRA_CONF_FILE=overlay-qemu_802154.conf + :gen-args: -DOVERLAY_CONFIG=overlay-qemu_802154.conf :goals: server :compact: @@ -51,7 +51,7 @@ If you want to capture the network traffic between the two QEMUs, type: :host-os: unix :board: qemu_x86 :build-dir: server - :gen-args: -G'Unix Makefiles' -DEXTRA_CONF_FILE=overlay-qemu_802154.conf -DPCAP=capture.pcap + :gen-args: -G'Unix Makefiles' -DOVERLAY_CONFIG=overlay-qemu_802154.conf -DPCAP=capture.pcap :goals: server :compact: @@ -69,7 +69,7 @@ In terminal #2, type: :host-os: unix :board: qemu_x86 :build-dir: client - :gen-args: -DEXTRA_CONF_FILE=overlay-qemu_802154.conf + :gen-args: -DOVERLAY_CONFIG=overlay-qemu_802154.conf :goals: client :compact: diff --git a/doc/connectivity/networking/qemu_eth_setup.rst b/doc/connectivity/networking/qemu_eth_setup.rst index 33a99599527f..f558bae7f4ab 100644 --- a/doc/connectivity/networking/qemu_eth_setup.rst +++ b/doc/connectivity/networking/qemu_eth_setup.rst @@ -78,7 +78,7 @@ In terminal #2, type: :zephyr-app: samples/net/sockets/echo_server :host-os: unix :board: qemu_x86 - :gen-args: -DEXTRA_CONF_FILE=overlay-e1000.conf + :gen-args: -DOVERLAY_CONFIG=overlay-e1000.conf :goals: run :compact: diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index ca9591bf44c7..bf934cf3532e 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -404,7 +404,7 @@ should know about. See :ref:`initial-conf` for more information. -* :makevar:`EXTRA_CONF_FILE`: Additional Kconfig configuration fragment files. +* :makevar:`OVERLAY_CONFIG`: Additional Kconfig configuration fragment files. Multiple filenames can be separated with either spaces or semicolons. This can be useful in order to leave :makevar:`CONF_FILE` at its default value, but "mix in" some additional configuration options. @@ -587,8 +587,8 @@ Application Configuration Directory Zephyr will use configuration files from the application's configuration directory except for files with an absolute path provided by the arguments -described earlier, for example ``CONF_FILE``, ``EXTRA_CONF_FILE``, -``DTC_OVERLAY_FILE``, and ``EXTRA_DTC_OVERLAY_FILE``. +described earlier, for example ``CONF_FILE``, ``OVERLAY_CONFIG``, and +``DTC_OVERLAY_FILE``. The application configuration directory is defined by the ``APPLICATION_CONFIG_DIR`` variable. diff --git a/doc/develop/west/build-flash-debug.rst b/doc/develop/west/build-flash-debug.rst index b6809094f857..44aa0bb500d8 100644 --- a/doc/develop/west/build-flash-debug.rst +++ b/doc/develop/west/build-flash-debug.rst @@ -242,7 +242,7 @@ To set :ref:`DTC_OVERLAY_FILE ` to To merge the :file:`file.conf` Kconfig fragment into your build's :file:`.config`:: - west build -- -DEXTRA_CONF_FILE=file.conf + west build -- -DOVERLAY_CONFIG=file.conf .. _west-building-cmake-config: From 0dc21a3bd722ca2bcd084088e59a6a779051d257 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 214/528] Revert "[nrf fromtree] samples: update nrf53_sync_rtc sample to EXTRA_CONF_FILE" This reverts commit 788882adb1489cf4e07d8997b4b1e5988d744950. Signed-off-by: Robert Lubos --- samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt b/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt index da1ce866e878..32aee7dc0a61 100644 --- a/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt +++ b/samples/boards/nrf/nrf53_sync_rtc/CMakeLists.txt @@ -30,7 +30,7 @@ ExternalProject_Add( INSTALL_COMMAND "" # This particular build system has no install command CMAKE_CACHE_ARGS -DBOARD:STRING=${BOARD_REMOTE} CMAKE_CACHE_ARGS -DDTC_OVERLAY_FILE:STRING=${NET_DTC_OVERLAY_FILE} - CMAKE_CACHE_ARGS -DEXTRA_CONF_FILE:STRING=${NET_OVERLAY_CONF} + CMAKE_CACHE_ARGS -DOVERLAY_CONFIG:STRING=${NET_OVERLAY_CONF} BUILD_BYPRODUCTS "${NET_ZEPHYR_DIR}/${KERNEL_BIN_NAME}" # NB: Do we need to pass on more CMake variables? BUILD_ALWAYS True From 6bb1a7386f5cae9a7c7fc38e4f798a7622907765 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 215/528] Revert "[nrf fromtree] sysbuild: update sysbuild to use EXTRA_CONF_FILE variable" This reverts commit 4f3e84a1360db20e32255db513496061ff07876c. Signed-off-by: Robert Lubos --- .../cmake/modules/sysbuild_extensions.cmake | 8 +++----- .../sysbuild/cmake/modules/sysbuild_kconfig.cmake | 15 +-------------- 2 files changed, 4 insertions(+), 19 deletions(-) diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index 76554c7d840f..d7eb004a17df 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -148,15 +148,13 @@ function(ExternalZephyrProject_Add) # The contents of these are appended to the image existing configuration # when user is not specifying custom fragments. if(NOT "${CONF_FILE_BUILD_TYPE}" STREQUAL "") - set(sysbuild_image_conf_fragment ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}_${CONF_FILE_BUILD_TYPE}.conf) + set(sysbuil_image_conf_fragment ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}_${CONF_FILE_BUILD_TYPE}.conf) else() set(sysbuild_image_conf_fragment ${sysbuild_image_conf_dir}/${ZBUILD_APPLICATION}.conf) endif() - if (NOT (${ZBUILD_APPLICATION}_OVERLAY_CONFIG OR ${ZBUILD_APPLICATION}_EXTRA_CONF_FILE) - AND EXISTS ${sysbuild_image_conf_fragment} - ) - set(${ZBUILD_APPLICATION}_EXTRA_CONF_FILE ${sysbuild_image_conf_fragment} + if (NOT ${ZBUILD_APPLICATION}_OVERLAY_CONFIG AND EXISTS ${sysbuild_image_conf_fragment}) + set(${ZBUILD_APPLICATION}_OVERLAY_CONFIG ${sysbuild_image_conf_fragment} CACHE INTERNAL "Kconfig fragment defined by main application" ) endif() diff --git a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake index 830ad326fd2a..5dbf82728a5e 100644 --- a/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_kconfig.cmake @@ -25,19 +25,7 @@ else() endif() if(DEFINED SB_CONF_FILE AND NOT IS_ABSOLUTE SB_CONF_FILE) - cmake_path(ABSOLUTE_PATH SB_CONF_FILE BASE_DIRECTORY ${APP_DIR}) -endif() - -if(DEFINED SB_OVERLAY_CONFIG AND NOT IS_ABSOLUTE SB_OVERLAY_CONFIG) - cmake_path(ABSOLUTE_PATH SB_OVERLAY_CONFIG BASE_DIRECTORY ${APP_DIR}) -endif() - -if(DEFINED SB_EXTRA_CONF_FILE AND NOT IS_ABSOLUTE SB_EXTRA_CONF_FILE) - cmake_path(ABSOLUTE_PATH SB_EXTRA_CONF_FILE BASE_DIRECTORY ${APP_DIR}) -endif() - -if(NOT DEFINED SB_EXTRA_CONF_FILE AND DEFINED SB_OVERLAY_CONFIG) - set(SB_EXTRA_CONF_FILE ${SB_OVERLAY_CONFIG}) + cmake_path(ABSOLUTE_PATH SB_CONF_FILE BASE_DIRECTORY ${APP_DIR} OUTPUT_VARIABLE SB_CONF_FILE) endif() if(DEFINED SB_CONF_FILE AND NOT DEFINED CACHE{SB_CONF_FILE}) @@ -60,7 +48,6 @@ file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/empty.conf) set(APPLICATION_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(AUTOCONF_H ${CMAKE_CURRENT_BINARY_DIR}/autoconf.h) set(CONF_FILE ${SB_CONF_FILE}) -set(EXTRA_CONF_FILE "${SB_EXTRA_CONF_FILE}") set(BOARD_DEFCONFIG "${CMAKE_CURRENT_BINARY_DIR}/empty.conf") if(DEFINED BOARD_REVISION) set(BOARD_REVISION_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/empty.conf") From 8c0e6b63605ea4c6f77894b0db75f9bea4d4b6fd Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:20 +0200 Subject: [PATCH 216/528] Revert "[nrf fromtree] cmake: update package helper description to use EXTRA_CONF_FILE var" This reverts commit 48ec774711f1f9b64f1facef394ce5737edc59e4. Signed-off-by: Robert Lubos --- cmake/package_helper.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/package_helper.cmake b/cmake/package_helper.cmake index d33b1cf6ddf0..5f48185a57b5 100644 --- a/cmake/package_helper.cmake +++ b/cmake/package_helper.cmake @@ -29,18 +29,18 @@ # It is also possible to pass additional build settings. # If you invoke CMake for 'hello_world' as: # -# $ cmake -DBOARD= -B build -S samples/hello_world -DEXTRA_CONF_FILE=foo.conf +# $ cmake -DBOARD= -B build -S samples/hello_world -DOVERLAY_CONFIG=foo.overlay # # you just add the same argument to the helper like: -# $ cmake -DBOARD= -B build -S samples/hello_world -DEXTRA_CONF_FILE=foo.conf \ +# $ cmake -DBOARD= -B build -S samples/hello_world -DOVERLAY_CONFIG=foo.overlay \ # -DMODULES=dts -P /cmake/package_helper.cmake # # Note: the samples CMakeLists.txt file is not processed by package helper, so # any 'set( )' specified before 'find_package(Zephyr)' must be # manually applied, for example if the CMakeLists.txt contains: -# set(EXTRA_CONF_FILE foo.conf) +# set(OVERLAY_CONFIG foo.overlay) # find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -# the 'foo.conf' must be specified using '-DEXTRA_CONF_FILE=foo.conf' +# the 'foo.overlay' must be specified using '-DOVERLAY_CONFIG=foo.overlay' cmake_minimum_required(VERSION 3.20.5) From 0c6f10322e1eac26a1ebc1a96da204c74dc06295 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 217/528] Revert "[nrf fromtree] cmake: introduce EXTRA_DTC_OVERLAY_FILE for devicetree" This reverts commit 91994930143dbcf3d8d3843935122b19f9519524. Signed-off-by: Robert Lubos --- cmake/modules/configuration_files.cmake | 1 - cmake/modules/dts.cmake | 17 +---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/cmake/modules/configuration_files.cmake b/cmake/modules/configuration_files.cmake index 24d5e9feedd3..5ff3ba991b68 100644 --- a/cmake/modules/configuration_files.cmake +++ b/cmake/modules/configuration_files.cmake @@ -117,4 +117,3 @@ DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"") zephyr_boilerplate_watch(DTC_OVERLAY_FILE) zephyr_get(EXTRA_CONF_FILE SYSBUILD LOCAL VAR EXTRA_CONF_FILE OVERLAY_CONFIG) -zephyr_get(EXTRA_DTC_OVERLAY_FILE SYSBUILD LOCAL) diff --git a/cmake/modules/dts.cmake b/cmake/modules/dts.cmake index e21d9ead887e..42413ceca73d 100644 --- a/cmake/modules/dts.cmake +++ b/cmake/modules/dts.cmake @@ -75,12 +75,6 @@ find_package(Dtc 1.4.6) # - BOARD_DIR: board directory to use when looking for DTS_SOURCE # - BOARD_REVISION_STRING: used when looking for a board revision's # devicetree overlay file in BOARD_DIR -# - DTC_OVERLAY_FILE: list of devicetree overlay files which will be -# used to modify or extend the base devicetree. -# - EXTRA_DTC_OVERLAY_FILE: list of extra devicetree overlay files. -# This variable is is similar to DTC_OVERLAY_FILE but the files in -# EXTRA_DTC_OVERLAY_FILE will be applied after DTC_OVERLAY_FILE and -# thus files specified by EXTRA_DTC_OVERLAY_FILE have higher precedence. # - EXTRA_DTC_FLAGS: list of extra command line options to pass to # dtc when using it to check for additional errors and warnings; # invalid flags are automatically filtered out of the list @@ -88,7 +82,7 @@ find_package(Dtc 1.4.6) # C preprocessor when generating the devicetree from DTS_SOURCE # - DTS_SOURCE: the devicetree source file to use may be pre-set # with this variable; otherwise, it defaults to -# ${BOARD_DIR}/${BOARD}.dts +# ${BOARD_DIR}/${BOARD.dts} # # Variables set by this module and not mentioned above are for internal # use only, and may be removed, renamed, or re-purposed without prior notice. @@ -164,15 +158,6 @@ if(DTC_OVERLAY_FILE) ) endif() -if(EXTRA_DTC_OVERLAY_FILE) - zephyr_list(TRANSFORM EXTRA_DTC_OVERLAY_FILE NORMALIZE_PATHS - OUTPUT_VARIABLE EXTRA_DTC_OVERLAY_FILE_AS_LIST) - list(APPEND - dts_files - ${EXTRA_DTC_OVERLAY_FILE_AS_LIST} - ) -endif() - set(i 0) foreach(dts_file ${dts_files}) if(i EQUAL 0) From 4d14ccc9374f1b25075b67cc62733899fe828323 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 218/528] Revert "[nrf fromtree] cmake: introduce EXTRA_CONF_FILE and deprecate OVERLAY_CONFIG" This reverts commit 591023d1b10b6a11cbd2041ad14590f794f7bcde. Signed-off-by: Robert Lubos --- cmake/modules/configuration_files.cmake | 3 --- cmake/modules/kconfig.cmake | 22 ++++++---------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/cmake/modules/configuration_files.cmake b/cmake/modules/configuration_files.cmake index 5ff3ba991b68..e5db53fd0880 100644 --- a/cmake/modules/configuration_files.cmake +++ b/cmake/modules/configuration_files.cmake @@ -11,7 +11,6 @@ # The following variables will be defined when this CMake module completes: # # - CONF_FILE: List of Kconfig fragments -# - EXTRA_CONF_FILE: List of additional Kconfig fragments # - DTC_OVERLAY_FILE: List of devicetree overlay files # - APPLICATION_CONFIG_DIR: Root folder for application configuration # @@ -115,5 +114,3 @@ DTC_OVERLAY_FILE=\"dts1.overlay dts2.overlay\"") # The DTC_OVERLAY_FILE variable is now set to its final value. zephyr_boilerplate_watch(DTC_OVERLAY_FILE) - -zephyr_get(EXTRA_CONF_FILE SYSBUILD LOCAL VAR EXTRA_CONF_FILE OVERLAY_CONFIG) diff --git a/cmake/modules/kconfig.cmake b/cmake/modules/kconfig.cmake index 97e6aadcf563..3c37e3bce273 100644 --- a/cmake/modules/kconfig.cmake +++ b/cmake/modules/kconfig.cmake @@ -55,9 +55,6 @@ foreach(root ${kconfig_board_root}) endforeach() if(KCONFIG_ROOT) - # Perform any variable substitutions if they are present - string(CONFIGURE "${KCONFIG_ROOT}" KCONFIG_ROOT) - zephyr_file(APPLICATION_ROOT KCONFIG_ROOT) # KCONFIG_ROOT has either been specified as a CMake variable or is # already in the CMakeCache.txt. This has precedence. @@ -79,9 +76,10 @@ if(CONF_FILE) string(REPLACE " " ";" CONF_FILE_AS_LIST "${CONF_FILE_EXPANDED}") endif() -if(EXTRA_CONF_FILE) - string(CONFIGURE "${EXTRA_CONF_FILE}" EXTRA_CONF_FILE_EXPANDED) - string(REPLACE " " ";" EXTRA_CONF_FILE_AS_LIST "${EXTRA_CONF_FILE_EXPANDED}") +zephyr_get(OVERLAY_CONFIG SYSBUILD LOCAL) +if(OVERLAY_CONFIG) + string(CONFIGURE "${OVERLAY_CONFIG}" OVERLAY_CONFIG_EXPANDED) + string(REPLACE " " ";" OVERLAY_CONFIG_AS_LIST "${OVERLAY_CONFIG_EXPANDED}") endif() @@ -115,17 +113,10 @@ string(REPLACE ";" "\\\;" SHIELD_AS_LIST_ESCAPED "${SHIELD_AS_LIST}") # cmake commands are escaped differently string(REPLACE ";" "\\;" SHIELD_AS_LIST_ESCAPED_COMMAND "${SHIELD_AS_LIST}") -if(TOOLCHAIN_HAS_NEWLIB) - set(_local_TOOLCHAIN_HAS_NEWLIB y) -else() - set(_local_TOOLCHAIN_HAS_NEWLIB n) -endif() - set(COMMON_KCONFIG_ENV_SETTINGS PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} srctree=${ZEPHYR_BASE} KERNELVERSION=${KERNELVERSION} - APPVERSION=${APP_VERSION_STRING} CONFIG_=${KCONFIG_NAMESPACE}_ KCONFIG_CONFIG=${DOTCONFIG} # Set environment variables so that Kconfig can prune Kconfig source @@ -135,10 +126,9 @@ set(COMMON_KCONFIG_ENV_SETTINGS BOARD_DIR=${BOARD_DIR} BOARD_REVISION=${BOARD_REVISION} KCONFIG_BINARY_DIR=${KCONFIG_BINARY_DIR} - APPLICATION_SOURCE_DIR=${APPLICATION_SOURCE_DIR} ZEPHYR_TOOLCHAIN_VARIANT=${ZEPHYR_TOOLCHAIN_VARIANT} TOOLCHAIN_KCONFIG_DIR=${TOOLCHAIN_KCONFIG_DIR} - TOOLCHAIN_HAS_NEWLIB=${_local_TOOLCHAIN_HAS_NEWLIB} + TOOLCHAIN_HAS_NEWLIB=$,y,n> EDT_PICKLE=${EDT_PICKLE} # Export all Zephyr modules to Kconfig ${ZEPHYR_KCONFIG_MODULES_DIR} @@ -251,7 +241,7 @@ set( ${BOARD_REVISION_CONFIG} ${CONF_FILE_AS_LIST} ${shield_conf_files} - ${EXTRA_CONF_FILE_AS_LIST} + ${OVERLAY_CONFIG_AS_LIST} ${EXTRA_KCONFIG_OPTIONS_FILE} ${config_files} ) From 27d8af8cef3302a05b6ced28a8221bb24af27fd4 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 219/528] Revert "[nrf fromtree] cmake: extend zephyr_get() to support fetching of multiple variables" This reverts commit 446648238224bee3349f47c378d1f697425ddb7a. Signed-off-by: Robert Lubos --- cmake/modules/extensions.cmake | 150 ++++++++++++++------------------- 1 file changed, 63 insertions(+), 87 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 4f75b41282b5..82285918e64f 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2467,42 +2467,11 @@ function(zephyr_list transform list_var action) endfunction() # Usage: -# zephyr_var_name( ) -# -# Internal function for construction of scoped variable name expansion string. -# Examples: -# reading a current scope FOO variable is identical to expand ${FOO}. -# reading a cache scope FOO variable is identical to expand $CACHE{FOO}. -# -# this functions will return the var name in out var for the scope if it is -# defined, else it will set the outvar to undefined. -function(zephyr_var_name variable scope out) - if(scope STREQUAL "ENV" OR scope STREQUAL "CACHE") - if(DEFINED ${scope}{${variable}}) - set(${out} "$${scope}{${variable}}" PARENT_SCOPE) - else() - set(${out} PARENT_SCOPE) - endif() - else() - if(DEFINED ${scope}_${variable}) - set(${out} "${${scope}_${variable}}" PARENT_SCOPE) - else() - set(${out} PARENT_SCOPE) - endif() - endif() -endfunction() - -# Usage: -# zephyr_get( [MERGE] [SYSBUILD [LOCAL|GLOBAL]] [VAR ...]) +# zephyr_get( [MERGE] [SYSBUILD [LOCAL|GLOBAL]]) # # Return the value of as local scoped variable of same name. If MERGE # is supplied, will return a list of found items. # -# VAR can be used either to store the result in a variable with a different -# name, or to look for values from multiple variables. -# zephyr_get(FOO VAR FOO_A FOO_B) -# zephyr_get(FOO MERGE VAR FOO_A FOO_B) -# # zephyr_get() is a common function to provide a uniform way of supporting # build settings that can be set from sysbuild, CMakeLists.txt, CMake cache, or # in environment. @@ -2526,7 +2495,7 @@ endfunction() # using `-DZEPHYR_TOOLCHAIN_VARIANT=`, then the value from the cache is # returned. function(zephyr_get variable) - cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "VAR" ${ARGN}) + cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "" ${ARGN}) if(DEFINED GET_VAR_SYSBUILD) if(NOT ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR @@ -2538,69 +2507,76 @@ function(zephyr_get variable) set(GET_VAR_SYSBUILD "GLOBAL") endif() - if(NOT DEFINED GET_VAR_VAR) - set(GET_VAR_VAR ${variable}) + if(GET_VAR_MERGE) + # Clear variable before appending items in MERGE mode but keep a backup for + # local appending later + set(local_var_backup ${${variable}}) + set(${variable}) endif() - # Keep current scope variables in internal variables. - # This is needed to properly handle cases where we want to check value against - # environment value or when appending with the MERGE operation. - foreach(var ${GET_VAR_VAR}) - set(current_${var} ${${var}}) - set(${var}) + set(used_global false) - if(SYSBUILD) - get_property(sysbuild_name TARGET sysbuild_cache PROPERTY SYSBUILD_NAME) - get_property(sysbuild_main_app TARGET sysbuild_cache PROPERTY SYSBUILD_MAIN_APP) - get_property(sysbuild_${var} TARGET sysbuild_cache PROPERTY ${sysbuild_name}_${var}) - if(NOT DEFINED sysbuild_${var} AND - ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR sysbuild_main_app) - ) - get_property(sysbuild_${var} TARGET sysbuild_cache PROPERTY ${var}) - endif() - else() - set(sysbuild_${var}) + if(SYSBUILD) + get_property(sysbuild_name TARGET sysbuild_cache PROPERTY SYSBUILD_NAME) + get_property(sysbuild_main_app TARGET sysbuild_cache PROPERTY SYSBUILD_MAIN_APP) + get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${sysbuild_name}_${variable}) + if(NOT DEFINED sysbuild_${variable} AND + ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR sysbuild_main_app) + ) + get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) + set(used_global true) endif() - endforeach() + endif() - set(scopes "sysbuild;CACHE;ENV;current") - foreach(scope IN LISTS scopes) - foreach(var ${GET_VAR_VAR}) - zephyr_var_name("${var}" "${scope}" expansion_var) - if(DEFINED expansion_var) - string(CONFIGURE "${expansion_var}" scope_value) - if(GET_VAR_MERGE) - list(APPEND ${variable} ${scope_value}) - else() - set(${variable} ${scope_value} PARENT_SCOPE) - - if("${scope}" STREQUAL "ENV") - # Set the environment variable in CMake cache, so that a build - # invocation triggering a CMake rerun doesn't rely on the - # environment variable still being available / have identical value. - set(${var} $ENV{${var}} CACHE INTERNAL "Cached environment variable ${var}") - endif() + if(DEFINED sysbuild_${variable}) + if(GET_VAR_MERGE) + list(APPEND ${variable} ${sysbuild_${variable}}) + else() + set(${variable} ${sysbuild_${variable}} PARENT_SCOPE) + return() + endif() + endif() + if(SYSBUILD AND GET_VAR_MERGE AND NOT used_global AND "${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL") + get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) + list(APPEND ${variable} ${sysbuild_${variable}}) + endif() + if(DEFINED CACHE{${variable}}) + if(GET_VAR_MERGE) + list(APPEND ${variable} $CACHE{${variable}}) + else() + set(${variable} $CACHE{${variable}} PARENT_SCOPE) + return() + endif() + endif() + if(DEFINED ENV{${variable}}) + if(GET_VAR_MERGE) + list(APPEND ${variable} $ENV{${variable}}}) + else() + set(${variable} $ENV{${variable}} PARENT_SCOPE) + # Set the environment variable in CMake cache, so that a build invocation + # triggering a CMake rerun doesn't rely on the environment variable still + # being available / have identical value. + set(${variable} $ENV{${variable}} CACHE INTERNAL "") + endif() - if("${scope}" STREQUAL "ENV" AND DEFINED current_${var} - AND NOT "${current_${var}}" STREQUAL "$ENV{${var}}" - ) - # Variable exists as current scoped variable, defined in a CMakeLists.txt - # file, however it is also set in environment. - # This might be a surprise to the user, so warn about it. - message(WARNING "environment variable '${var}' is hiding local " - "variable of same name.\n" - "Environment value (in use): $ENV{${var}}\n" - "Current scope value (hidden): ${current_${var}}\n" - ) - endif() + if(DEFINED ${variable} AND NOT "${${variable}}" STREQUAL "$ENV{${variable}}") + # Variable exists as a local scoped variable, defined in a CMakeLists.txt + # file, however it is also set in environment. + # This might be a surprise to the user, so warn about it. + message(WARNING "environment variable '${variable}' is hiding local " + "variable of same name.\n" + "Environment value (in use): $ENV{${variable}}\n" + "Local scope value (hidden): ${${variable}}\n" + ) + endif() - return() - endif() - endif() - endforeach() - endforeach() + if(NOT GET_VAR_MERGE) + return() + endif() + endif() if(GET_VAR_MERGE) + list(APPEND ${variable} ${local_var_backup}) list(REMOVE_DUPLICATES ${variable}) set(${variable} ${${variable}} PARENT_SCOPE) endif() From 032759dd196ead8bab46473b490972e9d90c75cf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 220/528] Revert "[nrf fromtree] cmake: extensions: Fix missing quotes for zephyr_get function" This reverts commit 5ca6b80c9d29a2cf668e6e8b3599d9ea69625152. Signed-off-by: Robert Lubos --- cmake/modules/extensions.cmake | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 82285918e64f..7505dea3c52a 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2498,8 +2498,8 @@ function(zephyr_get variable) cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "" ${ARGN}) if(DEFINED GET_VAR_SYSBUILD) - if(NOT ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR - "${GET_VAR_SYSBUILD}" STREQUAL "LOCAL") + if(NOT (${GET_VAR_SYSBUILD} STREQUAL "GLOBAL" OR + ${GET_VAR_SYSBUILD} STREQUAL "LOCAL") ) message(FATAL_ERROR "zephyr_get(... SYSBUILD) requires GLOBAL or LOCAL.") endif() @@ -2521,7 +2521,7 @@ function(zephyr_get variable) get_property(sysbuild_main_app TARGET sysbuild_cache PROPERTY SYSBUILD_MAIN_APP) get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${sysbuild_name}_${variable}) if(NOT DEFINED sysbuild_${variable} AND - ("${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL" OR sysbuild_main_app) + (${GET_VAR_SYSBUILD} STREQUAL "GLOBAL" OR sysbuild_main_app) ) get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) set(used_global true) @@ -2536,7 +2536,7 @@ function(zephyr_get variable) return() endif() endif() - if(SYSBUILD AND GET_VAR_MERGE AND NOT used_global AND "${GET_VAR_SYSBUILD}" STREQUAL "GLOBAL") + if(SYSBUILD AND GET_VAR_MERGE AND NOT used_global AND ${GET_VAR_SYSBUILD} STREQUAL "GLOBAL") get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) list(APPEND ${variable} ${sysbuild_${variable}}) endif() From 9c830eb0b8ed164e2209b94c6db5d932ccaae303 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 221/528] Revert "[nrf fromtree] cmake: extensions: Do not clear variable in zephyr_get MERGE mode" This reverts commit a1279afd6b21ad0a4d7212ddb1dbe80a4ef7405d. Signed-off-by: Robert Lubos --- cmake/modules/extensions.cmake | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index 7505dea3c52a..e7e8e12612b6 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2508,9 +2508,7 @@ function(zephyr_get variable) endif() if(GET_VAR_MERGE) - # Clear variable before appending items in MERGE mode but keep a backup for - # local appending later - set(local_var_backup ${${variable}}) + # Clear variable before appending items in MERGE mode set(${variable}) endif() @@ -2576,7 +2574,6 @@ function(zephyr_get variable) endif() if(GET_VAR_MERGE) - list(APPEND ${variable} ${local_var_backup}) list(REMOVE_DUPLICATES ${variable}) set(${variable} ${${variable}} PARENT_SCOPE) endif() From c9a1669b2e3cd38612b8515dd415c9c8c143841f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 222/528] Revert "[nrf fromtree] sysbuild: Fix issue with *_ROOT values not propagating" This reverts commit 002bc5202c53ceb27c3c30d16bb97f4fbd1d4aab. Signed-off-by: Robert Lubos --- cmake/modules/extensions.cmake | 65 +++++++--------------------------- cmake/modules/root.cmake | 7 ---- 2 files changed, 13 insertions(+), 59 deletions(-) diff --git a/cmake/modules/extensions.cmake b/cmake/modules/extensions.cmake index e7e8e12612b6..33951317c1e1 100644 --- a/cmake/modules/extensions.cmake +++ b/cmake/modules/extensions.cmake @@ -2467,10 +2467,10 @@ function(zephyr_list transform list_var action) endfunction() # Usage: -# zephyr_get( [MERGE] [SYSBUILD [LOCAL|GLOBAL]]) +# zephyr_get() +# zephyr_get( SYSBUILD [LOCAL|GLOBAL]) # -# Return the value of as local scoped variable of same name. If MERGE -# is supplied, will return a list of found items. +# Return the value of as local scoped variable of same name. # # zephyr_get() is a common function to provide a uniform way of supporting # build settings that can be set from sysbuild, CMakeLists.txt, CMake cache, or @@ -2484,8 +2484,6 @@ endfunction() # - blinky_BOARD is considered a local sysbuild cache variable only for the # blinky image. # If no sysbuild scope is specified, GLOBAL is assumed. -# If using MERGE then SYSBUILD GLOBAL will get both the local and global -# sysbuild scope variables (in that order, if both exist). # - CMake cache, set by `-D=` or `set( CACHE ...) # - Environment # - Locally in CMakeLists.txt before 'find_package(Zephyr)' @@ -2495,7 +2493,7 @@ endfunction() # using `-DZEPHYR_TOOLCHAIN_VARIANT=`, then the value from the cache is # returned. function(zephyr_get variable) - cmake_parse_arguments(GET_VAR "MERGE" "SYSBUILD" "" ${ARGN}) + cmake_parse_arguments(GET_VAR "" "SYSBUILD" "" ${ARGN}) if(DEFINED GET_VAR_SYSBUILD) if(NOT (${GET_VAR_SYSBUILD} STREQUAL "GLOBAL" OR @@ -2507,13 +2505,6 @@ function(zephyr_get variable) set(GET_VAR_SYSBUILD "GLOBAL") endif() - if(GET_VAR_MERGE) - # Clear variable before appending items in MERGE mode - set(${variable}) - endif() - - set(used_global false) - if(SYSBUILD) get_property(sysbuild_name TARGET sysbuild_cache PROPERTY SYSBUILD_NAME) get_property(sysbuild_main_app TARGET sysbuild_cache PROPERTY SYSBUILD_MAIN_APP) @@ -2522,40 +2513,19 @@ function(zephyr_get variable) (${GET_VAR_SYSBUILD} STREQUAL "GLOBAL" OR sysbuild_main_app) ) get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) - set(used_global true) endif() endif() if(DEFINED sysbuild_${variable}) - if(GET_VAR_MERGE) - list(APPEND ${variable} ${sysbuild_${variable}}) - else() - set(${variable} ${sysbuild_${variable}} PARENT_SCOPE) - return() - endif() - endif() - if(SYSBUILD AND GET_VAR_MERGE AND NOT used_global AND ${GET_VAR_SYSBUILD} STREQUAL "GLOBAL") - get_property(sysbuild_${variable} TARGET sysbuild_cache PROPERTY ${variable}) - list(APPEND ${variable} ${sysbuild_${variable}}) - endif() - if(DEFINED CACHE{${variable}}) - if(GET_VAR_MERGE) - list(APPEND ${variable} $CACHE{${variable}}) - else() - set(${variable} $CACHE{${variable}} PARENT_SCOPE) - return() - endif() - endif() - if(DEFINED ENV{${variable}}) - if(GET_VAR_MERGE) - list(APPEND ${variable} $ENV{${variable}}}) - else() - set(${variable} $ENV{${variable}} PARENT_SCOPE) - # Set the environment variable in CMake cache, so that a build invocation - # triggering a CMake rerun doesn't rely on the environment variable still - # being available / have identical value. - set(${variable} $ENV{${variable}} CACHE INTERNAL "") - endif() + set(${variable} ${sysbuild_${variable}} PARENT_SCOPE) + elseif(DEFINED CACHE{${variable}}) + set(${variable} $CACHE{${variable}} PARENT_SCOPE) + elseif(DEFINED ENV{${variable}}) + set(${variable} $ENV{${variable}} PARENT_SCOPE) + # Set the environment variable in CMake cache, so that a build invocation + # triggering a CMake rerun doesn't rely on the environment variable still + # being available / have identical value. + set(${variable} $ENV{${variable}} CACHE INTERNAL "") if(DEFINED ${variable} AND NOT "${${variable}}" STREQUAL "$ENV{${variable}}") # Variable exists as a local scoped variable, defined in a CMakeLists.txt @@ -2567,15 +2537,6 @@ function(zephyr_get variable) "Local scope value (hidden): ${${variable}}\n" ) endif() - - if(NOT GET_VAR_MERGE) - return() - endif() - endif() - - if(GET_VAR_MERGE) - list(REMOVE_DUPLICATES ${variable}) - set(${variable} ${${variable}} PARENT_SCOPE) endif() endfunction(zephyr_get variable) diff --git a/cmake/modules/root.cmake b/cmake/modules/root.cmake index 603b3b59cc99..4c6ab0ac5e41 100644 --- a/cmake/modules/root.cmake +++ b/cmake/modules/root.cmake @@ -36,13 +36,6 @@ zephyr_file(APPLICATION_ROOT ARCH_ROOT) # Convert paths to absolute, relative from APPLICATION_SOURCE_DIR zephyr_file(APPLICATION_ROOT SCA_ROOT) -# Merge in variables from other sources (e.g. sysbuild) -zephyr_get(MODULE_EXT_ROOT MERGE SYSBUILD GLOBAL) -zephyr_get(BOARD_ROOT MERGE SYSBUILD GLOBAL) -zephyr_get(SOC_ROOT MERGE SYSBUILD GLOBAL) -zephyr_get(ARCH_ROOT MERGE SYSBUILD GLOBAL) -zephyr_get(SCA_ROOT MERGE SYSBUILD GLOBAL) - if(unittest IN_LIST Zephyr_FIND_COMPONENTS) # Zephyr used in unittest mode, use dedicated unittest root. set(BOARD_ROOT ${ZEPHYR_BASE}/subsys/testsuite) From 5bc90c6eaacf7fea8dd53f1376996a19e00bfeca Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 223/528] Revert "[nrf fromtree] net: wifi: Fix cpp compatibility" This reverts commit c59f84dfae3602aaa90a3e4fe5a3e23d861e9236. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index cace143c93d6..d8aa28aa4aad 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -372,7 +372,7 @@ static const char * const twt_err_code_tbl[] = { static inline const char *get_twt_err_code_str(int16_t err_no) { - if ((err_no) < (int16_t)ARRAY_SIZE(twt_err_code_tbl)) { + if ((err_no) < ARRAY_SIZE(twt_err_code_tbl)) { return twt_err_code_tbl[err_no]; } @@ -424,7 +424,7 @@ static const char * const ps_param_config_err_code_tbl[] = { static inline const char *get_ps_config_err_code_str(int16_t err_no) { - if ((err_no) < (int16_t)ARRAY_SIZE(ps_param_config_err_code_tbl)) { + if ((err_no) < ARRAY_SIZE(ps_param_config_err_code_tbl)) { return ps_param_config_err_code_tbl[err_no]; } From d6c1e43b288489b1e58c5c148c32c6d7ec03a66f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 224/528] Revert "[nrf fromtree] net: wifi: Display MFP info in scan results" This reverts commit 7de382d54a3b70851a4faedcf990b0926c69f56a. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_shell.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 47e47830c8e8..4de52f95926c 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -96,21 +96,18 @@ static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) if (scan_result == 1U) { print(context.sh, SHELL_NORMAL, - "\n%-4s | %-32s %-5s | %-13s | %-4s | %-15s | %-17s | %-8s\n", - "Num", "SSID", "(len)", "Chan (Band)", "RSSI", "Security", "BSSID", "MFP"); + "\n%-4s | %-32s %-5s | %-13s | %-4s | %-15s | %s\n", + "Num", "SSID", "(len)", "Chan (Band)", "RSSI", "Security", "BSSID"); } - print(context.sh, SHELL_NORMAL, - "%-4d | %-32s %-5u | %-4u (%-6s) | %-4d | %-15s | %-17s | %-8s\n", + print(context.sh, SHELL_NORMAL, "%-4d | %-32s %-5u | %-4u (%-6s) | %-4d | %-15s | %s\n", scan_result, entry->ssid, entry->ssid_length, entry->channel, wifi_band_txt(entry->band), entry->rssi, wifi_security_txt(entry->security), ((entry->mac_length) ? - net_sprint_ll_addr_buf(entry->mac, WIFI_MAC_ADDR_LEN, - mac_string_buf, - sizeof(mac_string_buf)) : ""), - wifi_mfp_txt(entry->mfp)); + net_sprint_ll_addr_buf(entry->mac, WIFI_MAC_ADDR_LEN, mac_string_buf, + sizeof(mac_string_buf)) : "")); } #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS From 1dd2b4c8187d4d7c43a8a00539c284d38c37d7a2 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 225/528] Revert "[nrf fromtree] net: shell: Fix for PS timeout param type." This reverts commit 9e533ba14c65755c5d1e25ccaab836a765d22d9f. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 4de52f95926c..71f879027791 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -676,7 +676,7 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] } params.timeout_ms = timeout_ms; - params.type = WIFI_PS_PARAM_TIMEOUT; + params.type = WIFI_PS_PARAM_MODE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, From c800f5564e87b08cc552b62680758a3ab3755746 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:21 +0200 Subject: [PATCH 226/528] Revert "[nrf fromtree] manifest: openthread upmerge to `d9abe30`" This reverts commit 830bdd033429a7ea2fc926ff9714575e5d6b4fed. Signed-off-by: Robert Lubos --- modules/openthread/Kconfig.thread | 14 ++++--------- .../platform/openthread-core-zephyr-config.h | 20 +++++-------------- west.yml | 2 +- 3 files changed, 10 insertions(+), 26 deletions(-) diff --git a/modules/openthread/Kconfig.thread b/modules/openthread/Kconfig.thread index d2480c8ca122..a77f699448c7 100644 --- a/modules/openthread/Kconfig.thread +++ b/modules/openthread/Kconfig.thread @@ -87,17 +87,11 @@ config OPENTHREAD_CSL_RECEIVE_TIME_AHEAD int "CSL receiver wake up margin in microseconds" default 5000 -config OPENTHREAD_MIN_RECEIVE_ON_AHEAD - int "Minimum receiving time before start of MHR" - default 192 +config OPENTHREAD_CSL_MIN_RECEIVE_ON + int "Minimum CSL receive window" + default 5696 help - The minimum time (microseconds) that radio has to be in receive mode before the start of the MHR. - -config OPENTHREAD_MIN_RECEIVE_ON_AFTER - int "Minimum receiving time after start of MHR" - default 5504 - help - The minimum time (microseconds) that radio should be in receive mode after the start of the MHR. + The minimum CSL receive window (in microseconds) required to receive a full IEEE 802.15.4 frame config OPENTHREAD_PLATFORM_CSL_UNCERT int "CSL uncertainty" diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 256e433a81b5..54bc73fd869b 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -285,24 +285,14 @@ #endif /* CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD */ /** - * @def OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD + * @def OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON * - * The minimum time (microseconds) that radio has to be in receive mode before the start of the MHR. + * The minimum CSL receive window (in microseconds) required to receive an IEEE 802.15.4 frame. * */ -#ifdef CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD -#define OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AHEAD CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD -#endif /* CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AHEAD */ - -/** - * @def OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER - * - * The minimum time (microseconds) that radio has to be in receive mode after the start of the MHR . - * - */ -#ifdef CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER -#define OPENTHREAD_CONFIG_MIN_RECEIVE_ON_AFTER CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER -#endif /* CONFIG_OPENTHREAD_MIN_RECEIVE_ON_AFTER */ +#ifdef CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON +#define OPENTHREAD_CONFIG_CSL_MIN_RECEIVE_ON CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON +#endif /* CONFIG_OPENTHREAD_CSL_MIN_RECEIVE_ON */ /** * @def OPENTHREAD_CONFIG_MAC_SOFTWARE_TX_SECURITY_ENABLE diff --git a/west.yml b/west.yml index b4c5274e885a..746542a8bc72 100644 --- a/west.yml +++ b/west.yml @@ -203,7 +203,7 @@ manifest: revision: aedcc262f93bbb1b0c2f58026911575729b7465c path: modules/lib/open-amp - name: openthread - revision: d9abe3071c0131a4adb5d7e7451319b735e6d855 + revision: 1f1a826d1891fc99d14822abc0a1de257e9c6e9b path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From 72acc1b4280f3e4fe349c727ec4fa8f73952f707 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:22 +0200 Subject: [PATCH 227/528] Revert "[nrf fromtree] bluetooth: host: Fix NULL pointer dereference in bt_conn_auth_cb_overlay" This reverts commit 2999c4216d49820f1ff7e11c2fa15e27497ce9af. Signed-off-by: Robert Lubos --- subsys/bluetooth/host/conn.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 671229682a3a..10d894a4444b 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -3108,14 +3108,10 @@ int bt_conn_auth_cb_register(const struct bt_conn_auth_cb *cb) #if defined(CONFIG_BT_SMP) int bt_conn_auth_cb_overlay(struct bt_conn *conn, const struct bt_conn_auth_cb *cb) { - CHECKIF(conn == NULL) { - return -EINVAL; - } - /* The cancel callback must always be provided if the app provides * interactive callbacks. */ - if (cb && !cb->cancel && + if (!cb->cancel && (cb->passkey_display || cb->passkey_entry || cb->passkey_confirm || cb->pairing_confirm)) { return -EINVAL; From 8c8775a224d95f935d0330108576ae1dd0f9b0dc Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:22 +0200 Subject: [PATCH 228/528] Revert "[nrf fromtree] net: wifi: Fix typo in event" This reverts commit 523394d8ce07f2a9b0fb5cfb7824f2e6fef57247. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_mgmt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 4548864fe7c7..a1939af6e869 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -409,7 +409,7 @@ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, .status = status, }; - net_mgmt_event_notify_with_info(NET_EVENT_WIFI_DISCONNECT_COMPLETE, + net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, iface, &cnx_status, sizeof(struct wifi_status)); } From 5b3b35309b219643fb9e4d846ccddb9f60c2845c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:22 +0200 Subject: [PATCH 229/528] Revert "[nrf fromtree] net: wifi: Add an event for disconnect complete" This reverts commit b1b22e2fd889c21ee9b2356dcc54edcb3a7e851f. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi_mgmt.h | 5 ----- subsys/net/l2/wifi/wifi_mgmt.c | 12 ------------ 2 files changed, 17 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 8740d6b4bd45..07f37ca8ed2f 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -114,7 +114,6 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_TWT, NET_EVENT_WIFI_CMD_TWT_SLEEP_STATE, NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT, - NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -140,9 +139,6 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_RAW_SCAN_RESULT \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT) - -#define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ - (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) /* Each result is provided to the net_mgmt_event_callback * via its info attribute (see net_mgmt.h) */ @@ -348,7 +344,6 @@ void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, int twt_sleep_state); void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, struct wifi_raw_scan_result *raw_scan_info); #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ -void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, int status); #ifdef __cplusplus } #endif diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index a1939af6e869..6cbdea061692 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -401,15 +401,3 @@ void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, sizeof(*raw_scan_result)); } #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ - -void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, - int status) -{ - struct wifi_status cnx_status = { - .status = status, - }; - - net_mgmt_event_notify_with_info(NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, - iface, &cnx_status, - sizeof(struct wifi_status)); -} From 61f03d121e3dae9b6b44e1118cf47cfd562bb55b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:22 +0200 Subject: [PATCH 230/528] Revert "[nrf fromlist] net: context: Set priority based on DSCP" This reverts commit 8a7a845140d5f39be185962a05a651fcd784d394. Signed-off-by: Robert Lubos --- subsys/net/ip/ipv4.h | 10 ---------- subsys/net/ip/ipv6.h | 10 ---------- subsys/net/ip/net_context.c | 10 ---------- 3 files changed, 30 deletions(-) diff --git a/subsys/net/ip/ipv4.h b/subsys/net/ip/ipv4.h index 1359d04bc032..da1e227cf5f7 100644 --- a/subsys/net/ip/ipv4.h +++ b/subsys/net/ip/ipv4.h @@ -231,16 +231,6 @@ static inline void net_ipv4_set_dscp(uint8_t *tos, uint8_t dscp) *tos |= (dscp << NET_IPV4_DSCP_OFFSET) & NET_IPV4_DSCP_MASK; } -/** - * @brief Convert DSCP value to priority. - * - * @param dscp DSCP value. - */ -static inline uint8_t net_ipv4_dscp_to_priority(uint8_t dscp) -{ - return dscp >> 3; -} - /** * @brief Decode ECN value from ToS field. * diff --git a/subsys/net/ip/ipv6.h b/subsys/net/ip/ipv6.h index be97731577ab..80543084744a 100644 --- a/subsys/net/ip/ipv6.h +++ b/subsys/net/ip/ipv6.h @@ -523,16 +523,6 @@ static inline void net_ipv6_set_dscp(uint8_t *tc, uint8_t dscp) *tc |= (dscp << NET_IPV6_DSCP_OFFSET) & NET_IPV6_DSCP_MASK; } -/** - * @brief Convert DSCP value to priority. - * - * @param dscp DSCP value. - */ -static inline uint8_t net_ipv6_dscp_to_priority(uint8_t dscp) -{ - return dscp >> 3; -} - /** * @brief Decode ECN value from TC field. * diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index d4aa188573d2..10787be335fd 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -895,11 +895,6 @@ int net_context_create_ipv4_new(struct net_context *context, #if defined(CONFIG_NET_CONTEXT_DSCP_ECN) net_pkt_set_ip_dscp(pkt, net_ipv4_get_dscp(context->options.dscp_ecn)); net_pkt_set_ip_ecn(pkt, net_ipv4_get_ecn(context->options.dscp_ecn)); - /* Direct priority takes precedence over DSCP */ - if (!IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) { - net_pkt_set_priority(pkt, net_ipv4_dscp_to_priority( - net_ipv4_get_dscp(context->options.dscp_ecn))); - } #endif return net_ipv4_create(pkt, src, dst); @@ -930,11 +925,6 @@ int net_context_create_ipv6_new(struct net_context *context, #if defined(CONFIG_NET_CONTEXT_DSCP_ECN) net_pkt_set_ip_dscp(pkt, net_ipv6_get_dscp(context->options.dscp_ecn)); net_pkt_set_ip_ecn(pkt, net_ipv6_get_ecn(context->options.dscp_ecn)); - /* Direct priority takes precedence over DSCP */ - if (!IS_ENABLED(CONFIG_NET_CONTEXT_PRIORITY)) { - net_pkt_set_priority(pkt, net_ipv6_dscp_to_priority( - net_ipv6_get_dscp(context->options.dscp_ecn))); - } #endif return net_ipv6_create(pkt, src, dst); From 04a6a38f4902d91ce601ec9d8ed2dfbd3f823581 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:22 +0200 Subject: [PATCH 231/528] Revert "[nrf fromtree] net: wifi_mgmt: Handle ps command error" This reverts commit 942eed74909e99601bada4e1ff38bf7e5a5abdf3. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 36 +-------------------------------- include/zephyr/net/wifi_mgmt.h | 1 - subsys/net/l2/wifi/wifi_mgmt.c | 6 ------ subsys/net/l2/wifi/wifi_shell.c | 33 +++++++----------------------- 4 files changed, 8 insertions(+), 68 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index d8aa28aa4aad..d324ca57beb3 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -380,7 +380,7 @@ static inline const char *get_twt_err_code_str(int16_t err_no) } enum ps_param_type { - WIFI_PS_PARAM_STATE, + WIFI_PS_PARAM_STATE, WIFI_PS_PARAM_LISTEN_INTERVAL, WIFI_PS_PARAM_WAKEUP_MODE, WIFI_PS_PARAM_MODE, @@ -396,38 +396,4 @@ static const char * const wifi_ps_wakeup_mode2str[] = { [WIFI_PS_WAKEUP_MODE_DTIM] = "PS wakeup mode DTIM", [WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL] = "PS wakeup mode listen interval", }; - -enum wifi_config_ps_param_fail_reason { - WIFI_PS_PARAM_FAIL_UNSPECIFIED, - WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL, - WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED, - WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS, - WIFI_PS_PARAM_FAIL_DEVICE_NOT_CONNECTED, - WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED, - WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID, -}; - -static const char * const ps_param_config_err_code_tbl[] = { - [WIFI_PS_PARAM_FAIL_UNSPECIFIED] = "Unspecfied", - [WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", - [WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED] = - "Operation not supported", - [WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS] = - "Unable to get iface status", - [WIFI_PS_PARAM_FAIL_DEVICE_NOT_CONNECTED] = - "Can not set while device not connected", - [WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED] = - "Can not set while device already connected", - [WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID] = - "Can not set due to invalid range", -}; - -static inline const char *get_ps_config_err_code_str(int16_t err_no) -{ - if ((err_no) < ARRAY_SIZE(ps_param_config_err_code_tbl)) { - return ps_param_config_err_code_tbl[err_no]; - } - - return ""; -} #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 07f37ca8ed2f..b0e306c94360 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -201,7 +201,6 @@ struct wifi_ps_params { enum wifi_ps_mode mode; int timeout_ms; enum ps_param_type type; - enum wifi_config_ps_param_fail_reason fail_reason; }; struct wifi_twt_params { diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 6cbdea061692..38e993914512 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -254,14 +254,10 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, case WIFI_PS_PARAM_MODE: if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, sizeof(struct wifi_iface_status))) { - ps_params->fail_reason = - WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS; return -EIO; } if (info.state == WIFI_STATE_COMPLETED) { - ps_params->fail_reason = - WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED; return -ENOTSUP; } break; @@ -270,8 +266,6 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, case WIFI_PS_PARAM_TIMEOUT: break; default: - ps_params->fail_reason = - WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED; return -ENOTSUP; } diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 71f879027791..ba89ca0cbdee 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -617,10 +617,8 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) params.type = WIFI_PS_PARAM_STATE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, - "PS %s failed. Reason: %s\n", - params.enabled ? "enable" : "disable", - get_ps_config_err_code_str(params.fail_reason)); + shell_fprintf(sh, SHELL_WARNING, "Power save %s failed\n", + params.enabled ? "enable" : "disable"); return -ENOEXEC; } @@ -648,9 +646,7 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) params.type = WIFI_PS_PARAM_MODE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s failed Reason : %s\n", - wifi_ps_mode2str[params.mode], - get_ps_config_err_code_str(params.fail_reason)); + shell_fprintf(sh, SHELL_WARNING, "%s failed\n", wifi_ps_mode2str[params.mode]); return -ENOEXEC; } @@ -679,9 +675,7 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] params.type = WIFI_PS_PARAM_MODE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, - "Setting PS timeout failed. Reason : %s\n", - get_ps_config_err_code_str(params.fail_reason)); + shell_fprintf(sh, SHELL_WARNING, "Setting PS timeout failed\n"); return -ENOEXEC; } @@ -989,18 +983,7 @@ static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *a params.type = WIFI_PS_PARAM_LISTEN_INTERVAL; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - if (params.fail_reason == - WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID) { - shell_fprintf(sh, SHELL_WARNING, - "Setting listen interval failed. Reason :%s\n", - get_ps_config_err_code_str(params.fail_reason)); - shell_fprintf(sh, SHELL_WARNING, - "Hardware support valid range : 3 - 65535\n"); - } else { - shell_fprintf(sh, SHELL_WARNING, - "Setting listen interval failed. Reason :%s\n", - get_ps_config_err_code_str(params.fail_reason)); - } + shell_fprintf(sh, SHELL_WARNING, "Setting listen interval failed\n"); return -ENOEXEC; } @@ -1031,10 +1014,8 @@ static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *ar params.type = WIFI_PS_PARAM_WAKEUP_MODE; if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, - "Setting PS wake up mode to %s failed..Reason :%s\n", - params.wakeup_mode ? "Listen interval" : "DTIM interval", - get_ps_config_err_code_str(params.fail_reason)); + shell_fprintf(sh, SHELL_WARNING, "Setting PS wake up mode to %s failed\n", + params.wakeup_mode ? "Listen interval" : "DTIM interval"); return -ENOEXEC; } From 9018cc1e6579a40140e1a06c7cc569d90f372095 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:22 +0200 Subject: [PATCH 232/528] Revert "[nrf noup] ci: clang: parallel execution" This reverts commit 5e2f4ecc0bd4171ff60bfbc9f60271d0a30142cc. Signed-off-by: Robert Lubos --- .github/workflows/clang.yaml | 21 +++++---------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index f2f67c4923a2..b30ccbd9516e 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -8,7 +8,8 @@ concurrency: jobs: clang-build: - runs-on: ubuntu-latest + if: github.repository_owner == 'zephyrproject-rtos' + runs-on: zephyr-runner-linux-x64-4xlarge container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.1 options: '--entrypoint /bin/bash' @@ -18,13 +19,11 @@ jobs: fail-fast: false matrix: platform: ["native_posix"] - subset: [1, 2, 3, 4, 5] env: ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.0 LLVM_TOOLCHAIN_PATH: /usr/lib/llvm-16 COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} BASE_REF: ${{ github.base_ref }} - MATRIX_SIZE: 5 outputs: report_needed: ${{ steps.twister.outputs.report_needed }} steps: @@ -86,7 +85,7 @@ jobs: id: cache-ccache uses: zephyrproject-rtos/action-s3-cache@v1.2.0 with: - key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.subset }}-ccache + key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.platform }}-ccache path: /github/home/.ccache aws-s3-bucket: ccache.zephyrproject.org aws-access-key-id: ${{ secrets.CCACHE_S3_ACCESS_KEY_ID }} @@ -98,16 +97,6 @@ jobs: test -d github/home/.ccache && rm -rf /github/home/.ccache && mv github/home/.ccache /github/home/.ccache ccache -M 10G -s - - name: Build test plan with Twister - id: twister_test_plan - run: | - export ZEPHYR_BASE=${PWD} - export ZEPHYR_TOOLCHAIN_VARIANT=llvm - - # check if we need to run a full twister or not based on files changed - python3 ./scripts/ci/test_plan.py -p native_posix -c origin/${BASE_REF}.. - - - name: Run Tests with Twister id: twister run: | @@ -121,7 +110,7 @@ jobs: if [ -s testplan.json ]; then echo "report_needed=1" >> $GITHUB_OUTPUT # Full twister but with options based on changes - ./scripts/twister --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 --subset ${{matrix.subset}}/${MATRIX_SIZE} + ./scripts/twister --force-color --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 else # if nothing is run, skip reporting step echo "report_needed=0" >> $GITHUB_OUTPUT @@ -135,7 +124,7 @@ jobs: if: always() && steps.twister.outputs.report_needed != 0 uses: actions/upload-artifact@v3 with: - name: Unit Test Results (Subset ${{ matrix.subset }}) + name: Unit Test Results (Subset ${{ matrix.platform }}) path: twister-out/twister.xml clang-build-results: From 995853da0142fb1db12a8bbe5c718eb5adabf31c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:22 +0200 Subject: [PATCH 233/528] Revert "[nrf fromtree] net: shell: Code cleanup for ps related commands" This reverts commit f9aa02a461c8dc10769112c2000ee0f47975c12d. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 2 -- include/zephyr/net/wifi_mgmt.h | 14 +++++++-- subsys/net/l2/wifi/wifi_mgmt.c | 56 ++++++++++++++++++++++++++------- subsys/net/l2/wifi/wifi_shell.c | 53 ++++++++++++++----------------- 4 files changed, 81 insertions(+), 44 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index d324ca57beb3..f3f9452cbab3 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -383,8 +383,6 @@ enum ps_param_type { WIFI_PS_PARAM_STATE, WIFI_PS_PARAM_LISTEN_INTERVAL, WIFI_PS_PARAM_WAKEUP_MODE, - WIFI_PS_PARAM_MODE, - WIFI_PS_PARAM_TIMEOUT, }; enum wifi_ps_wakeup_mode { diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index b0e306c94360..7faf29cac513 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -198,9 +198,15 @@ struct wifi_ps_params { enum wifi_ps enabled; unsigned short listen_interval; enum wifi_ps_wakeup_mode wakeup_mode; + enum ps_param_type type; +}; + +struct wifi_ps_mode_params { enum wifi_ps_mode mode; +}; + +struct wifi_ps_timeout_params { int timeout_ms; - enum ps_param_type type; }; struct wifi_twt_params { @@ -253,8 +259,9 @@ struct wifi_twt_flow_info { }; struct wifi_ps_config { - char num_twt_flows; struct wifi_twt_flow_info twt_flows[WIFI_MAX_TWT_FLOWS]; + enum wifi_ps_mode mode; + char num_twt_flows; struct wifi_ps_params ps_params; }; @@ -322,9 +329,12 @@ struct net_wifi_mgmt_offload { int (*get_stats)(const struct device *dev, struct net_stats_wifi *stats); #endif /* CONFIG_NET_STATISTICS_WIFI */ int (*set_power_save)(const struct device *dev, struct wifi_ps_params *params); + int (*set_power_save_mode)(const struct device *dev, struct wifi_ps_mode_params *params); int (*set_twt)(const struct device *dev, struct wifi_twt_params *params); int (*get_power_save_config)(const struct device *dev, struct wifi_ps_config *config); int (*reg_domain)(const struct device *dev, struct wifi_reg_domain *reg_domain); + int (*set_power_save_timeout)(const struct device *dev, + struct wifi_ps_timeout_params *ps_timeout); }; /* Make sure that the network interface API is properly setup inside diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 38e993914512..54950bded98f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -250,8 +250,7 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, } switch (ps_params->type) { - case WIFI_PS_PARAM_LISTEN_INTERVAL: - case WIFI_PS_PARAM_MODE: + case WIFI_PS_PARAM_LISTEN_INTERVAL: if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, sizeof(struct wifi_iface_status))) { return -EIO; @@ -260,15 +259,12 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, if (info.state == WIFI_STATE_COMPLETED) { return -ENOTSUP; } - break; - case WIFI_PS_PARAM_STATE: - case WIFI_PS_PARAM_WAKEUP_MODE: - case WIFI_PS_PARAM_TIMEOUT: - break; - default: - return -ENOTSUP; - } - + break; + case WIFI_PS_PARAM_STATE: + case WIFI_PS_PARAM_WAKEUP_MODE: + default: + break; + } return off_api->set_power_save(dev, ps_params); } @@ -295,6 +291,23 @@ static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *ifac NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_CONFIG, wifi_get_power_save_config); +static int wifi_set_power_save_mode(uint32_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + struct net_wifi_mgmt_offload *off_api = + (struct net_wifi_mgmt_offload *) dev->api; + struct wifi_ps_mode_params *ps_mode_params = data; + + if (off_api == NULL || off_api->set_power_save_mode == NULL) { + return -ENOTSUP; + } + + return off_api->set_power_save_mode(dev, ps_mode_params); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_MODE, wifi_set_power_save_mode); + static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { @@ -371,6 +384,27 @@ static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface, NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN, wifi_reg_domain); +static int wifi_set_power_save_timeout(uint32_t mgmt_request, struct net_if *iface, + void *data, size_t len) +{ + const struct device *dev = net_if_get_device(iface); + struct net_wifi_mgmt_offload *off_api = + (struct net_wifi_mgmt_offload *) dev->api; + struct wifi_ps_timeout_params *ps_timeout = data; + + if (off_api == NULL || off_api->set_power_save_timeout == NULL) { + return -ENOTSUP; + } + + if (!data || len != sizeof(*ps_timeout)) { + return -EINVAL; + } + + return off_api->set_power_save_timeout(dev, ps_timeout); +} + +NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_TIMEOUT, wifi_set_power_save_timeout); + void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, int twt_sleep_state) { diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index ba89ca0cbdee..b7806296a482 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -572,9 +572,9 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS status: %s\n", wifi_ps2str[config.ps_params.enabled]); - if (config.ps_params.enabled) { + if (config.enabled) { shell_fprintf(sh, SHELL_NORMAL, "PS mode: %s\n", - wifi_ps_mode2str[config.ps_params.mode]); + wifi_ps_mode2str[config.mode]); } shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", @@ -583,9 +583,6 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS wake up mode: %s\n", config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", - config.ps_params.timeout_ms); - if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); } else { @@ -630,22 +627,25 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_default(); - struct wifi_ps_params params = { 0 }; + struct wifi_ps_mode_params params = { 0 }; context.sh = sh; + if (argc != 2) { + shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); + return -ENOEXEC; + } + if (!strncmp(argv[1], "legacy", 6)) { params.mode = WIFI_PS_MODE_LEGACY; } else if (!strncmp(argv[1], "wmm", 3)) { params.mode = WIFI_PS_MODE_WMM; } else { - shell_fprintf(sh, SHELL_WARNING, "Invalid PS mode\n"); + shell_fprintf(sh, SHELL_WARNING, "Invalid power save mode\n"); return -ENOEXEC; } - params.type = WIFI_PS_PARAM_MODE; - - if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { + if (net_mgmt(NET_REQUEST_WIFI_PS_MODE, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "%s failed\n", wifi_ps_mode2str[params.mode]); return -ENOEXEC; } @@ -658,12 +658,17 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_default(); - struct wifi_ps_params params = { 0 }; + struct wifi_ps_timeout_params params = { 0 }; long timeout_ms = 0; int err = 0; context.sh = sh; + if (argc != 2) { + shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); + return -ENOEXEC; + } + timeout_ms = shell_strtol(argv[1], 10, &err); if (err) { @@ -672,15 +677,14 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] } params.timeout_ms = timeout_ms; - params.type = WIFI_PS_PARAM_MODE; - if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Setting PS timeout failed\n"); + if (net_mgmt(NET_REQUEST_WIFI_PS_TIMEOUT, iface, ¶ms, sizeof(params))) { + shell_fprintf(sh, SHELL_WARNING, "Setting power save timeout failed\n"); return -ENOEXEC; } shell_fprintf(sh, SHELL_NORMAL, - "PS timeout %d ms\n", params.timeout_ms); + "Power save timeout %d ms\n", params.timeout_ms); return 0; } @@ -1068,15 +1072,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, cmd_wifi_connect), SHELL_CMD(disconnect, NULL, "Disconnect from the Wi-Fi AP", cmd_wifi_disconnect), - SHELL_CMD(ps, NULL, "Configure Wi-F PS on/off, no arguments will dump config", + SHELL_CMD(ps, NULL, "Configure Wi-Fi power save on/off, no arguments will dump config", cmd_wifi_ps), - SHELL_CMD_ARG(ps_mode, - NULL, - "\n" - "", - cmd_wifi_ps_mode, - 2, - 0), + SHELL_CMD(ps_mode, NULL, "Configure Wi-Fi power save mode legacy/wmm", cmd_wifi_ps_mode), SHELL_CMD(scan, NULL, "Scan for Wi-Fi APs", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), @@ -1088,12 +1086,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "-f: Force to use this regulatory hint over any other regulatory hints\n" "Note: This may cause regulatory compliance issues, use it at your own risk.", cmd_wifi_reg_domain), - SHELL_CMD_ARG(ps_timeout, - NULL, - " - PS inactivity timer(in ms)", - cmd_wifi_ps_timeout, - 2, - 0), + SHELL_CMD(ps_timeout, NULL, + "Configure Wi-Fi power save inactivity timer(in ms)", + cmd_wifi_ps_timeout), SHELL_CMD_ARG(ps_listen_interval, NULL, " - Listen interval in the range of <0-65535>", From eae6f825eddc394c8422d8b957b3dda1c41b96eb Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:22 +0200 Subject: [PATCH 234/528] Revert "[nrf fromtree] net: wifi_mgmt: Configure ps wakeup mode" This reverts commit a4a7cf2106c9b9dc8f6799e8d2d939f0519e9bb7. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 11 --------- include/zephyr/net/wifi_mgmt.h | 1 - subsys/net/l2/wifi/wifi_mgmt.c | 1 - subsys/net/l2/wifi/wifi_shell.c | 41 --------------------------------- 4 files changed, 54 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index f3f9452cbab3..f5d09880c600 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -382,16 +382,5 @@ static inline const char *get_twt_err_code_str(int16_t err_no) enum ps_param_type { WIFI_PS_PARAM_STATE, WIFI_PS_PARAM_LISTEN_INTERVAL, - WIFI_PS_PARAM_WAKEUP_MODE, -}; - -enum wifi_ps_wakeup_mode { - WIFI_PS_WAKEUP_MODE_DTIM = 0, - WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL, -}; - -static const char * const wifi_ps_wakeup_mode2str[] = { - [WIFI_PS_WAKEUP_MODE_DTIM] = "PS wakeup mode DTIM", - [WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL] = "PS wakeup mode listen interval", }; #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 7faf29cac513..c8144db1afd6 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -197,7 +197,6 @@ struct wifi_iface_status { struct wifi_ps_params { enum wifi_ps enabled; unsigned short listen_interval; - enum wifi_ps_wakeup_mode wakeup_mode; enum ps_param_type type; }; diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 54950bded98f..68281c0fd9e1 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -261,7 +261,6 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, } break; case WIFI_PS_PARAM_STATE: - case WIFI_PS_PARAM_WAKEUP_MODE: default: break; } diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index b7806296a482..163bb4b24d7f 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -580,9 +580,6 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", config.ps_params.listen_interval); - shell_fprintf(sh, SHELL_NORMAL, "PS wake up mode: %s\n", - config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); - if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); } else { @@ -997,37 +994,6 @@ static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *a return 0; } -static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *argv[]) -{ - struct net_if *iface = net_if_get_default(); - struct wifi_ps_params params = { 0 }; - - context.sh = sh; - - if (!strncmp(argv[1], "dtim", 4)) { - params.wakeup_mode = WIFI_PS_WAKEUP_MODE_DTIM; - } else if (!strncmp(argv[1], "listen_interval", 15)) { - params.wakeup_mode = WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL; - } else { - shell_fprintf(sh, SHELL_WARNING, "Invalid argument\n"); - shell_fprintf(sh, SHELL_INFO, - "Valid argument : / \n"); - return -ENOEXEC; - } - - params.type = WIFI_PS_PARAM_WAKEUP_MODE; - - if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Setting PS wake up mode to %s failed\n", - params.wakeup_mode ? "Listen interval" : "DTIM interval"); - return -ENOEXEC; - } - - shell_fprintf(sh, SHELL_NORMAL, "%s\n", - wifi_ps_wakeup_mode2str[params.wakeup_mode]); - - return 0; -} SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_CMD(disable, NULL, @@ -1095,13 +1061,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, cmd_wifi_listen_interval, 2, 0), - SHELL_CMD_ARG(ps_wakeup_mode, - NULL, - " : Set PS wake up mode to DTIM interval\n" - " : Set PS wake up mode to listen interval", - cmd_wifi_ps_wakeup_mode, - 2, - 0), SHELL_SUBCMD_SET_END ); From 88402233befa3c352f4e10b81f993659d35238a6 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:23 +0200 Subject: [PATCH 235/528] Revert "[nrf fromtree] net: wifi_mgmt: Configure listen interval" This reverts commit 2bbd5535b02c355e55b3d58a12f0dae59497ad39. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 8 ------- include/zephyr/net/wifi_mgmt.h | 4 +--- subsys/net/l2/wifi/wifi_mgmt.c | 16 ------------- subsys/net/l2/wifi/wifi_shell.c | 42 +-------------------------------- 4 files changed, 2 insertions(+), 68 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index f5d09880c600..00b7a827743f 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -16,9 +16,6 @@ #define WIFI_COUNTRY_CODE_LEN 2 -#define WIFI_LISTEN_INTERVAL_MIN 0 -#define WIFI_LISTEN_INTERVAL_MAX 65535 - /* Not having support for legacy types is deliberate to enforce * higher security. */ @@ -378,9 +375,4 @@ static inline const char *get_twt_err_code_str(int16_t err_no) return ""; } - -enum ps_param_type { - WIFI_PS_PARAM_STATE, - WIFI_PS_PARAM_LISTEN_INTERVAL, -}; #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index c8144db1afd6..0034f1589b62 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -196,8 +196,6 @@ struct wifi_iface_status { struct wifi_ps_params { enum wifi_ps enabled; - unsigned short listen_interval; - enum ps_param_type type; }; struct wifi_ps_mode_params { @@ -259,9 +257,9 @@ struct wifi_twt_flow_info { struct wifi_ps_config { struct wifi_twt_flow_info twt_flows[WIFI_MAX_TWT_FLOWS]; + bool enabled; enum wifi_ps_mode mode; char num_twt_flows; - struct wifi_ps_params ps_params; }; /* Generic get/set operation for any command*/ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 68281c0fd9e1..c74ba278183f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -243,27 +243,11 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; struct wifi_ps_params *ps_params = data; - struct wifi_iface_status info = { 0 }; if (off_api == NULL || off_api->set_power_save == NULL) { return -ENOTSUP; } - switch (ps_params->type) { - case WIFI_PS_PARAM_LISTEN_INTERVAL: - if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, - sizeof(struct wifi_iface_status))) { - return -EIO; - } - - if (info.state == WIFI_STATE_COMPLETED) { - return -ENOTSUP; - } - break; - case WIFI_PS_PARAM_STATE: - default: - break; - } return off_api->set_power_save(dev, ps_params); } diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 163bb4b24d7f..9a71324b2429 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -571,15 +571,12 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) } shell_fprintf(sh, SHELL_NORMAL, "PS status: %s\n", - wifi_ps2str[config.ps_params.enabled]); + wifi_ps2str[config.enabled]); if (config.enabled) { shell_fprintf(sh, SHELL_NORMAL, "PS mode: %s\n", wifi_ps_mode2str[config.mode]); } - shell_fprintf(sh, SHELL_NORMAL, "PS listen_interval: %d\n", - config.ps_params.listen_interval); - if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); } else { @@ -608,8 +605,6 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) return -ENOEXEC; } - params.type = WIFI_PS_PARAM_STATE; - if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "Power save %s failed\n", params.enabled ? "enable" : "disable"); @@ -966,35 +961,6 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, return 0; } -static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *argv[]) -{ - struct net_if *iface = net_if_get_default(); - struct wifi_ps_params params = { 0 }; - long interval = 0; - - context.sh = sh; - - if (!parse_number(sh, &interval, argv[1], - WIFI_LISTEN_INTERVAL_MIN, - WIFI_LISTEN_INTERVAL_MAX)) { - return -EINVAL; - } - - params.listen_interval = interval; - params.type = WIFI_PS_PARAM_LISTEN_INTERVAL; - - if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Setting listen interval failed\n"); - return -ENOEXEC; - } - - shell_fprintf(sh, SHELL_NORMAL, - "Listen interval %hu\n", params.listen_interval); - - return 0; -} - - SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_CMD(disable, NULL, "Disable Access Point mode", @@ -1055,12 +1021,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(ps_timeout, NULL, "Configure Wi-Fi power save inactivity timer(in ms)", cmd_wifi_ps_timeout), - SHELL_CMD_ARG(ps_listen_interval, - NULL, - " - Listen interval in the range of <0-65535>", - cmd_wifi_listen_interval, - 2, - 0), SHELL_SUBCMD_SET_END ); From de1fd8de730c0fca790b11d1953340206f5728c2 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:23 +0200 Subject: [PATCH 236/528] Revert "[nrf fromtree] net: shell: Fix CI warning implicit declaration" This reverts commit 5e46751f2fd5f9138b10852f0dda8c36470b933c. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 00b7a827743f..3088deed9bcc 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -12,8 +12,6 @@ #ifndef ZEPHYR_INCLUDE_NET_WIFI_H_ #define ZEPHYR_INCLUDE_NET_WIFI_H_ -#include /* for ARRAY_SIZE */ - #define WIFI_COUNTRY_CODE_LEN 2 /* Not having support for legacy types is deliberate to enforce From 4efc7f6b2fb60d16ca242b1d4b7050deeb542506 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:23 +0200 Subject: [PATCH 237/528] Revert "[nrf fromtree] net: shell: Check connection & capabilities in any TWT operation" This reverts commit 4d2abca02509dbac1d22afcae7a35b295a2574ec. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 37 --------------------------------- include/zephyr/net/wifi_mgmt.h | 2 -- subsys/net/l2/wifi/wifi_mgmt.c | 31 --------------------------- subsys/net/l2/wifi/wifi_shell.c | 26 +++++++---------------- 4 files changed, 8 insertions(+), 88 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 3088deed9bcc..eb9270042c22 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -336,41 +336,4 @@ enum wifi_twt_setup_resp_status { WIFI_TWT_RESP_NOT_RECEIVED, }; -enum wifi_twt_fail_reason { - WIFI_TWT_FAIL_UNSPECIFIED, - WIFI_TWT_FAIL_CMD_EXEC_FAIL, - WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED, - WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS, - WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED, - WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB, - WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB, - WIFI_TWT_FAIL_OPERATION_IN_PROGRESS, - WIFI_TWT_FAIL_INVALID_FLOW_ID, -}; - -static const char * const twt_err_code_tbl[] = { - [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecfied", - [WIFI_TWT_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", - [WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED] = - "Operation not supported", - [WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS] = - "Unable to get iface status", - [WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED] = - "Device not connected", - [WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB] = "Peer not HE capable", - [WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB] = "Peer not TWT capable", - [WIFI_TWT_FAIL_OPERATION_IN_PROGRESS] = - "Operation already in progress", - [WIFI_TWT_FAIL_INVALID_FLOW_ID] = - "Invalid negotiated flow id", -}; - -static inline const char *get_twt_err_code_str(int16_t err_no) -{ - if ((err_no) < ARRAY_SIZE(twt_err_code_tbl)) { - return twt_err_code_tbl[err_no]; - } - - return ""; -} #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 0034f1589b62..d136c0b69526 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -191,7 +191,6 @@ struct wifi_iface_status { int rssi; unsigned char dtim_period; unsigned short beacon_interval; - bool twt_capable; }; struct wifi_ps_params { @@ -231,7 +230,6 @@ struct wifi_twt_params { bool teardown_all; } teardown; }; - enum wifi_twt_fail_reason fail_reason; }; /* Flow ID is only 3 bits */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index c74ba278183f..77d0e8322adc 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -298,43 +298,12 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; struct wifi_twt_params *twt_params = data; - struct wifi_iface_status info = { 0 }; if (off_api == NULL || off_api->set_twt == NULL) { - twt_params->fail_reason = - WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED; return -ENOTSUP; } - if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, - sizeof(struct wifi_iface_status))) { - twt_params->fail_reason = - WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS; - goto fail; - } - - if (info.state != WIFI_STATE_COMPLETED) { - twt_params->fail_reason = - WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED; - goto fail; - } - - if (info.link_mode < WIFI_6) { - twt_params->fail_reason = - WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB; - goto fail; - } - - if (!info.twt_capable) { - twt_params->fail_reason = - WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB; - goto fail; - } - return off_api->set_twt(dev, twt_params); -fail: - return -ENOEXEC; - } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_TWT, wifi_set_twt); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 9a71324b2429..3502fe551af0 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -492,8 +492,6 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "RSSI: %d\n", status.rssi); shell_fprintf(sh, SHELL_NORMAL, "Beacon Interval: %d\n", status.beacon_interval); shell_fprintf(sh, SHELL_NORMAL, "DTIM: %d\n", status.dtim_period); - shell_fprintf(sh, SHELL_NORMAL, "TWT: %s\n", - status.twt_capable ? "Supported" : "Not supported"); } return 0; @@ -714,11 +712,9 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, return -EINVAL; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", + shell_fprintf(sh, SHELL_WARNING, "%s with %s failed\n", wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type], - get_twt_err_code_str(params.fail_reason)); - + wifi_twt_negotiation_type2str[params.negotiation_type]); return -ENOEXEC; } @@ -770,11 +766,9 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, params.setup_cmd = setup_cmd; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s with %s failed. reason : %s\n", + shell_fprintf(sh, SHELL_WARNING, "%s with %s failed\n", wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type], - get_twt_err_code_str(params.fail_reason)); - + wifi_twt_negotiation_type2str[params.negotiation_type]); return -ENOEXEC; } @@ -816,11 +810,9 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, return -EINVAL; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", + shell_fprintf(sh, SHELL_WARNING, "%s with %s failed\n", wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type], - get_twt_err_code_str(params.fail_reason)); - + wifi_twt_negotiation_type2str[params.negotiation_type]); return -ENOEXEC; } @@ -843,11 +835,9 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, params.teardown.teardown_all = 1; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "%s with %s failed, reason : %s\n", + shell_fprintf(sh, SHELL_WARNING, "%s with %s failed\n", wifi_twt_operation2str[params.operation], - wifi_twt_negotiation_type2str[params.negotiation_type], - get_twt_err_code_str(params.fail_reason)); - + wifi_twt_negotiation_type2str[params.negotiation_type]); return -ENOEXEC; } From e52ec7a8a764ece2b6b2782e006de5b5f7c680e9 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:23 +0200 Subject: [PATCH 238/528] Revert "[nrf fromtree] net: wifi_mgmt: Support to provide raw scan data" This reverts commit c9c548d6f01611aabe7d72aa4137dbb492ed5ca5. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi_mgmt.h | 20 -------- subsys/net/ip/net_private.h | 3 -- subsys/net/l2/Kconfig | 1 - subsys/net/l2/wifi/Kconfig | 29 ----------- subsys/net/l2/wifi/wifi_mgmt.c | 19 ------- subsys/net/l2/wifi/wifi_shell.c | 91 +-------------------------------- 6 files changed, 1 insertion(+), 162 deletions(-) delete mode 100644 subsys/net/l2/wifi/Kconfig diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index d136c0b69526..f6b5e38f1c79 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -113,7 +113,6 @@ enum net_event_wifi_cmd { NET_EVENT_WIFI_CMD_IFACE_STATUS, NET_EVENT_WIFI_CMD_TWT, NET_EVENT_WIFI_CMD_TWT_SLEEP_STATE, - NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT, }; #define NET_EVENT_WIFI_SCAN_RESULT \ @@ -136,9 +135,6 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_TWT_SLEEP_STATE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_TWT_SLEEP_STATE) - -#define NET_EVENT_WIFI_RAW_SCAN_RESULT \ - (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT) /* Each result is provided to the net_mgmt_event_callback * via its info attribute (see net_mgmt.h) */ @@ -278,23 +274,11 @@ enum wifi_twt_sleep_state { WIFI_TWT_STATE_AWAKE = 1, }; -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS -struct wifi_raw_scan_result { - int8_t rssi; - int frame_length; - unsigned short frequency; - uint8_t data[CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH]; -}; -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ #include typedef void (*scan_result_cb_t)(struct net_if *iface, int status, struct wifi_scan_result *entry); -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS -typedef void (*raw_scan_result_cb_t)(struct net_if *iface, int status, - struct wifi_raw_scan_result *entry); -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ struct net_wifi_mgmt_offload { /** * Mandatory to get in first position. @@ -344,10 +328,6 @@ void wifi_mgmt_raise_iface_status_event(struct net_if *iface, void wifi_mgmt_raise_twt_event(struct net_if *iface, struct wifi_twt_params *twt_params); void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, int twt_sleep_state); -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS -void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, - struct wifi_raw_scan_result *raw_scan_info); -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ #ifdef __cplusplus } #endif diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 351c87c61466..918fa070f99c 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -30,9 +30,6 @@ union net_mgmt_events { #endif /* CONFIG_NET_DHCPV4 */ #if defined(CONFIG_NET_L2_WIFI_MGMT) struct wifi_scan_result wifi_scan_result; -#if defined(CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS) - struct wifi_raw_scan_result raw_scan_result; -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ #endif /* CONFIG_NET_L2_WIFI_MGMT */ #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV6_MLD) struct net_event_ipv6_route ipv6_route; diff --git a/subsys/net/l2/Kconfig b/subsys/net/l2/Kconfig index 468e1729dd78..3bdc0810af39 100644 --- a/subsys/net/l2/Kconfig +++ b/subsys/net/l2/Kconfig @@ -110,7 +110,6 @@ module-dep = NET_LOG module-str = Log level for Wi-Fi management layer module-help = Enables Wi-Fi management interface to output debug messages. source "subsys/net/Kconfig.template.log_config.net" -source "subsys/net/l2/wifi/Kconfig" endif # NET_L2_WIFI_MGMT config NET_L2_WIFI_SHELL diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig deleted file mode 100644 index ecd1d002bc3d..000000000000 --- a/subsys/net/l2/wifi/Kconfig +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -config WIFI_MGMT_RAW_SCAN_RESULTS - bool "Raw scan results" - help - This option enables raw scan results. When enabled, the raw scan - results (beacons or probe responses) are provided to the application. - Enabling this config will increase the net_mgmt event size - considerably. - -if WIFI_MGMT_RAW_SCAN_RESULTS - -config WIFI_MGMT_RAW_SCAN_RESULT_LENGTH - int "Maximum length of raw scan results" - default 512 - help - This option defines the maximum length of raw scan results. - -config WIFI_MGMT_RAW_SCAN_RESULTS_ONLY - bool "Only raw scan results" - help - This option enables only raw scan results. When enabled, the raw scan - results (beacons or probe responses) are provided to the application. - The scan results are not parsed and the application is responsible - for parsing the scan results. Normal scan results are not provided - to the application. - -endif # WIFI_MGMT_RAW_SCAN_RESULTS diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 77d0e8322adc..3a0f41f63d26 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -81,10 +81,8 @@ static void scan_result_cb(struct net_if *iface, int status, return; } -#ifndef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY net_mgmt_event_notify_with_info(NET_EVENT_WIFI_SCAN_RESULT, iface, entry, sizeof(struct wifi_scan_result)); -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */ } static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, @@ -364,20 +362,3 @@ void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, iface, INT_TO_POINTER(twt_sleep_state), sizeof(twt_sleep_state)); } - -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS -void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, - struct wifi_raw_scan_result *raw_scan_result) -{ - if (raw_scan_result->frame_length > CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH) { - LOG_INF("raw scan result frame length = %d too big," - "saving upto max raw scan length = %d", - raw_scan_result->frame_length, - CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH); - } - - net_mgmt_event_notify_with_info(NET_EVENT_WIFI_RAW_SCAN_RESULT, - iface, raw_scan_result, - sizeof(*raw_scan_result)); -} -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 3502fe551af0..1fbbf54fd3c9 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -26,20 +26,11 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #define WIFI_SHELL_MODULE "wifi" -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY -#define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_RAW_SCAN_RESULT | \ - NET_EVENT_WIFI_SCAN_DONE | \ - NET_EVENT_WIFI_CONNECT_RESULT | \ - NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_TWT) -#else #define WIFI_SHELL_MGMT_EVENTS (NET_EVENT_WIFI_SCAN_RESULT | \ NET_EVENT_WIFI_SCAN_DONE | \ NET_EVENT_WIFI_CONNECT_RESULT | \ NET_EVENT_WIFI_DISCONNECT_RESULT | \ - NET_EVENT_WIFI_TWT | \ - NET_EVENT_WIFI_RAW_SCAN_RESULT) -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS_ONLY */ + NET_EVENT_WIFI_TWT) static struct { const struct shell *sh; @@ -110,81 +101,6 @@ static void handle_wifi_scan_result(struct net_mgmt_event_callback *cb) sizeof(mac_string_buf)) : "")); } -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS -static int wifi_freq_to_channel(int frequency) -{ - int channel = 0; - - if (frequency == 2484) { /* channel 14 */ - channel = 14; - } else if ((frequency <= 2472) && (frequency >= 2412)) { - channel = ((frequency - 2412) / 5) + 1; - } else if ((frequency <= 5320) && (frequency >= 5180)) { - channel = ((frequency - 5180) / 5) + 36; - } else if ((frequency <= 5720) && (frequency >= 5500)) { - channel = ((frequency - 5500) / 5) + 100; - } else if ((frequency <= 5895) && (frequency >= 5745)) { - channel = ((frequency - 5745) / 5) + 149; - } else { - channel = frequency; - } - - return channel; -} - -static enum wifi_frequency_bands wifi_freq_to_band(int frequency) -{ - enum wifi_frequency_bands band = WIFI_FREQ_BAND_2_4_GHZ; - - if ((frequency >= 2401) && (frequency <= 2495)) { - band = WIFI_FREQ_BAND_2_4_GHZ; - } else if ((frequency >= 5170) && (frequency <= 5895)) { - band = WIFI_FREQ_BAND_5_GHZ; - } else { - band = WIFI_FREQ_BAND_6_GHZ; - } - - return band; -} - -static void handle_wifi_raw_scan_result(struct net_mgmt_event_callback *cb) -{ - struct wifi_raw_scan_result *raw = - (struct wifi_raw_scan_result *)cb->info; - int channel; - int band; - int rssi; - int i = 0; - uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; - - scan_result++; - - if (scan_result == 1U) { - print(context.sh, SHELL_NORMAL, - "\n%-4s | %-13s | %-4s | %-15s | %-15s | %-32s\n", - "Num", "Channel (Band)", "RSSI", "BSSID", "Frame length", "Frame Body"); - } - - rssi = raw->rssi; - channel = wifi_freq_to_channel(raw->frequency); - band = wifi_freq_to_band(raw->frequency); - - print(context.sh, SHELL_NORMAL, "%-4d | %-4u (%-6s) | %-4d | %s | %-4d ", - scan_result, - channel, - wifi_band_txt(band), - rssi, - net_sprint_ll_addr_buf(raw->data + 10, WIFI_MAC_ADDR_LEN, mac_string_buf, - sizeof(mac_string_buf)), raw->frame_length); - - for (i = 0; i < 32; i++) { - print(context.sh, SHELL_NORMAL, "%02X ", *(raw->data + i)); - } - - print(context.sh, SHELL_NORMAL, "\n"); -} -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ - static void handle_wifi_scan_done(struct net_mgmt_event_callback *cb) { const struct wifi_status *status = @@ -300,11 +216,6 @@ static void wifi_mgmt_event_handler(struct net_mgmt_event_callback *cb, case NET_EVENT_WIFI_TWT: handle_wifi_twt_event(cb); break; -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS - case NET_EVENT_WIFI_RAW_SCAN_RESULT: - handle_wifi_raw_scan_result(cb); - break; -#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ default: break; } From 0b8fb82951d164d48f708b6c2eac87570fd620af Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:23 +0200 Subject: [PATCH 239/528] Revert "[nrf fromlist] wifi: thingy53: Update dts and dtsi files to support nrf7002 eval board" This reverts commit 47179329c92210fb71baad46ad5aa7b20cd506ba. Signed-off-by: Robert Lubos --- .../thingy53_nrf5340_common-pinctrl.dtsi | 18 ------------ .../thingy53_nrf5340_common.dts | 23 --------------- .../gpio/nordic,thingy53-edge-connector.yaml | 29 ------------------- 3 files changed, 70 deletions(-) delete mode 100644 dts/bindings/gpio/nordic,thingy53-edge-connector.yaml diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common-pinctrl.dtsi b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common-pinctrl.dtsi index 2a9fa480bab9..6f3e5631de9c 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common-pinctrl.dtsi +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common-pinctrl.dtsi @@ -108,22 +108,4 @@ }; }; - spi4_default: spi4_default { - group1 { - psels = , - , - ; - nordic,drive-mode = ; - }; - }; - - spi4_sleep: spi4_sleep { - group1 { - psels = , - , - ; - low-power-enable; - }; - }; - }; diff --git a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts index 01d8590e2756..3ce47a68f628 100644 --- a/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts +++ b/boards/arm/thingy53_nrf5340/thingy53_nrf5340_common.dts @@ -64,20 +64,6 @@ }; }; - edge_connector: connector { - compatible = "nordic,thingy53-edge-connector"; - #gpio-cells = <2>; - gpio-map-mask = <0xffffffff 0xffffffc0>; - gpio-map-pass-thru = <0 0x3f>; - gpio-map = <8 0 &gpio0 5 0>, /* P8, P0.05/AIN1 */ - <9 0 &gpio0 4 0>, /* P9, P0.04/AIN0 */ - <15 0 &gpio0 8 0>, /* P15, P0.08/TRACEDATA3 */ - <16 0 &gpio0 9 0>, /* P16, P0.09/TRACEDATA2 */ - <17 0 &gpio0 10 0>, /* P17, P0.10/TRACEDATA1 */ - <18 0 &gpio0 11 0>, /* P18, P0.11/TRACEDATA0 */ - <19 0 &gpio0 12 0>; /* P19, P0.12/TRACECLK */ - }; - npm1100_force_pwm_mode: npm1100_force_pwm_mode { compatible = "regulator-fixed"; regulator-name = "npm1100_force_pwm_mode"; @@ -264,15 +250,6 @@ }; }; -edge_connector_spi: &spi4 { - compatible = "nordic,nrf-spim"; - status = "okay"; - cs-gpios = <&edge_connector 18 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&spi4_default>; - pinctrl-1 = <&spi4_sleep>; - pinctrl-names = "default", "sleep"; -}; - &flash0 { partitions { compatible = "fixed-partitions"; diff --git a/dts/bindings/gpio/nordic,thingy53-edge-connector.yaml b/dts/bindings/gpio/nordic,thingy53-edge-connector.yaml deleted file mode 100644 index 32a7641c2a8c..000000000000 --- a/dts/bindings/gpio/nordic,thingy53-edge-connector.yaml +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -description: | - This binding provides a nexus mapping for 20 pins (HW rev 1.1.0) as depicted below - P1 VLi-Ion - P2 VBat - P3 VOUTB - P4 VDD_nRF53 - P5 P1.01/GRANT - P6 P1.00/REQ - P7 RESET - P8 P0.05/AIN1 - P9 P0.04/AIN0 - P10 LOAD_SW_DISABLE - P11 VOUTB_2 - P12 VDD_nRF21540 - P13 VDD_EXP_BRD - P14 3V3 - P15 P0.08/TRACEDATA3 - P16 P0.09/TRACEDATA2 - P17 P0.10/TRACEDATA1 - P18 P0.11/TRACEDATA0 - P19 P0.12/TRACECLK - P20 GND - -compatible: "nordic,thingy53-edge-connector" - -include: [gpio-nexus.yaml, base.yaml] From 8b81a18f3dabcbdde6f8612bfb82557a95f5fb95 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:23 +0200 Subject: [PATCH 240/528] Revert "[nrf fromtree] net: wifi: Fix TWT interval" This reverts commit 07f9d80e9c395de29b71bce27a679fcbe48ef10c. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi_mgmt.h | 2 +- subsys/net/l2/wifi/wifi_shell.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index f6b5e38f1c79..302c395da54b 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -230,7 +230,7 @@ struct wifi_twt_params { /* Flow ID is only 3 bits */ #define WIFI_MAX_TWT_FLOWS 8 -#define WIFI_MAX_TWT_INTERVAL_US (LONG_MAX - 1) +#define WIFI_MAX_TWT_INTERVAL_US (ULONG_MAX - 1) /* 256 (u8) * 1TU */ #define WIFI_MAX_TWT_WAKE_INTERVAL_US 262144 struct wifi_twt_flow_info { diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 1fbbf54fd3c9..067c3f99cbd9 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -59,7 +59,7 @@ static struct net_mgmt_event_callback wifi_shell_mgmt_cb; } \ } while (false) -static bool parse_number(const struct shell *sh, long *param, char *str, long min, long max) +static bool parse_number(const struct shell *sh, long *param, char *str, int min, int max) { char *endptr; char *str_tmp = str; @@ -70,7 +70,7 @@ static bool parse_number(const struct shell *sh, long *param, char *str, long mi return false; } if ((num) < (min) || (num) > (max)) { - print(sh, SHELL_WARNING, "Value out of range: %s, (%ld-%ld)", str_tmp, min, max); + print(sh, SHELL_WARNING, "Value out of range: %s, (%d-%d)", str_tmp, min, max); return false; } *param = num; @@ -873,13 +873,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_cmd_ap, SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, SHELL_CMD(quick_setup, NULL, " Start a TWT flow with defaults:\n" - " \n", + " \n", cmd_wifi_twt_setup_quick), SHELL_CMD(setup, NULL, " Start a TWT flow:\n" "\n" "\n" " " - " \n", + " \n", cmd_wifi_twt_setup), SHELL_CMD(teardown, NULL, " Teardown a TWT flow:\n" "\n" From 01c0f3209d425e740254d26f1eba21b302761657 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:23 +0200 Subject: [PATCH 241/528] Revert "[nrf fromtree] net: wifi_shell: Updated TWT flow id range" This reverts commit e5835470c5af70b52538164ec5f2ef621a978af8. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_shell.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 067c3f99cbd9..67137a5c6427 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -610,7 +610,7 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, params.negotiation_type = WIFI_TWT_INDIVIDUAL; params.setup_cmd = WIFI_TWT_SETUP_CMD_REQUEST; params.dialog_token = 1; - params.flow_id = 0; + params.flow_id = 1; params.setup.responder = 0; params.setup.implicit = 1; params.setup.trigger = 1; @@ -661,8 +661,7 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, !parse_number(sh, &setup_cmd, argv[idx++], WIFI_TWT_SETUP_CMD_REQUEST, WIFI_TWT_SETUP_CMD_DEMAND) || !parse_number(sh, (long *)¶ms.dialog_token, argv[idx++], 1, 255) || - !parse_number(sh, (long *)¶ms.flow_id, argv[idx++], 0, - (WIFI_MAX_TWT_FLOWS - 1)) || + !parse_number(sh, (long *)¶ms.flow_id, argv[idx++], 1, WIFI_MAX_TWT_FLOWS) || !parse_number(sh, (long *)¶ms.setup.responder, argv[idx++], 0, 1) || !parse_number(sh, (long *)¶ms.setup.trigger, argv[idx++], 0, 1) || !parse_number(sh, (long *)¶ms.setup.implicit, argv[idx++], 0, 1) || @@ -716,8 +715,7 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, !parse_number(sh, &setup_cmd, argv[idx++], WIFI_TWT_SETUP_CMD_REQUEST, WIFI_TWT_SETUP_CMD_DEMAND) || !parse_number(sh, (long *)¶ms.dialog_token, argv[idx++], 1, 255) || - !parse_number(sh, (long *)¶ms.flow_id, argv[idx++], 0, - (WIFI_MAX_TWT_FLOWS - 1))) + !parse_number(sh, (long *)¶ms.flow_id, argv[idx++], 1, WIFI_MAX_TWT_FLOWS)) return -EINVAL; if (net_mgmt(NET_REQUEST_WIFI_TWT, iface, ¶ms, sizeof(params))) { @@ -878,13 +876,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_twt_ops, SHELL_CMD(setup, NULL, " Start a TWT flow:\n" "\n" "\n" - " " + " " " \n", cmd_wifi_twt_setup), SHELL_CMD(teardown, NULL, " Teardown a TWT flow:\n" "\n" "\n" - " \n", + " \n", cmd_wifi_twt_teardown), SHELL_CMD(teardown_all, NULL, " Teardown all TWT flows\n", cmd_wifi_twt_teardown_all), From ed9fdbbfb9d8d3a40c1e4e37ed9d1ac2b1a37534 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:23 +0200 Subject: [PATCH 242/528] Revert "[nrf fromtree] drivers: spi: nrfx: add multithreading Kconfig dependency" This reverts commit 271e795ac88d3e5c8a3aae96d26f76391a72306b. Signed-off-by: Robert Lubos --- drivers/spi/Kconfig.nrfx | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/spi/Kconfig.nrfx b/drivers/spi/Kconfig.nrfx index 56df44355d3c..044e3ae09c28 100644 --- a/drivers/spi/Kconfig.nrfx +++ b/drivers/spi/Kconfig.nrfx @@ -5,7 +5,6 @@ menuconfig SPI_NRFX bool "nRF SPI nrfx drivers" default y depends on SOC_FAMILY_NRF - depends on MULTITHREADING help Enable support for nrfx SPI drivers for nRF MCU series. From d012190700d63f265ebfd36dd1617c47bb22b9dc Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 243/528] Revert "[nrf fromtree] boards: arm: nrf9160dk_nrf9160: disable external flash by default" This reverts commit 20290957bca33d798cd1211c627a1fa0f999b8c9. Signed-off-by: Robert Lubos --- .../arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi index 5589f9ac9f23..e5b62be419f7 100644 --- a/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi +++ b/boards/arm/nrf9160dk_nrf9160/nrf9160dk_nrf9160_common_0_14_0.dtsi @@ -42,7 +42,6 @@ <&gpio0 25 GPIO_ACTIVE_LOW>; mx25r64: mx25r6435f@1 { compatible = "jedec,spi-nor"; - status = "disabled"; reg = <1>; spi-max-frequency = <8000000>; label = "MX25R64"; From 7d99a79a36bc57165fa622c79d886f2d5fe4451a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 244/528] Revert "[nrf fromtree] boards: arm: nrf9161dk_nrf9161: disable external flash by default" This reverts commit 9a4611834feff85874e6914993d291bae670a259. Signed-off-by: Robert Lubos --- boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi | 1 - 1 file changed, 1 deletion(-) diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi index 52543f0be9bd..9bcd6753f6e4 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_common.dtsi @@ -192,7 +192,6 @@ arduino_spi: &spi3 { gd25lb256: gd25lb256e3ir@1 { compatible = "jedec,spi-nor"; - status = "disabled"; reg = <1>; spi-max-frequency = <60000000>; jedec-id = [c8 67 19]; From a3bc41202cdc075d7e2e9d59be7a6ccfe8236b86 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 245/528] Revert "[nrf fromtree] samples: tfm_integration: Add nrf9161dk_nrf9161_ns to TF-M test samples" This reverts commit 4a67d5d325d7c7080148311bee8ab08c64c09208. Signed-off-by: Robert Lubos --- samples/tfm_integration/tfm_psa_test/sample.yaml | 2 +- samples/tfm_integration/tfm_regression_test/sample.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/tfm_integration/tfm_psa_test/sample.yaml b/samples/tfm_integration/tfm_psa_test/sample.yaml index 606df91cf966..e1779a139dfa 100644 --- a/samples/tfm_integration/tfm_psa_test/sample.yaml +++ b/samples/tfm_integration/tfm_psa_test/sample.yaml @@ -2,7 +2,7 @@ common: tags: tfm platform_allow: mps2_an521_ns nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160_ns - nrf9161dk_nrf9161_ns v2m_musca_s1_ns + v2m_musca_s1_ns integration_platforms: - mps2_an521_ns harness: console diff --git a/samples/tfm_integration/tfm_regression_test/sample.yaml b/samples/tfm_integration/tfm_regression_test/sample.yaml index e64a84aa7259..a6a4f3fbd3d6 100644 --- a/samples/tfm_integration/tfm_regression_test/sample.yaml +++ b/samples/tfm_integration/tfm_regression_test/sample.yaml @@ -1,7 +1,7 @@ common: tags: tfm platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160_ns - nrf9161dk_nrf9161_ns v2m_musca_s1_ns + v2m_musca_s1_ns integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns From 4b8072a3600798b8505ddafa1e0e3b39c7f4eaa5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 246/528] Revert "[nrf fromtree] boards: nrf9161dk_nrf9161: Remove TF-M not supported note" This reverts commit 21084ce1d7b91d1b700fa1ede4be6cb8b12946a7. Signed-off-by: Robert Lubos --- boards/arm/nrf9161dk_nrf9161/doc/index.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/boards/arm/nrf9161dk_nrf9161/doc/index.rst b/boards/arm/nrf9161dk_nrf9161/doc/index.rst index 835ba29c1de4..32fc047d24dd 100644 --- a/boards/arm/nrf9161dk_nrf9161/doc/index.rst +++ b/boards/arm/nrf9161dk_nrf9161/doc/index.rst @@ -138,6 +138,9 @@ have to set the IDAU (SPU) configuration to allow Non-Secure access to all CPU resources utilized by the Non-Secure application firmware. SPU configuration shall take place before jumping to the Non-Secure application. +.. note:: + Trusted Firmware-M (TF-M) and building the ``ns`` target is not supported for this board. + Building a Secure only application ================================== From e310cc1e09e38af904c9757075bdc3308d479be5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 247/528] Revert "[nrf fromtree] boards: nrf9161dk_nrf9161_ns: Add TF-M support to nrf9161 DK" This reverts commit 625fc579ec6cbc4a5378887470a27e976177b640. Signed-off-by: Robert Lubos --- boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig | 15 --------------- boards/arm/nrf9161dk_nrf9161/board.cmake | 2 +- .../nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts | 5 ----- modules/trusted-firmware-m/Kconfig.tfm | 1 - 4 files changed, 1 insertion(+), 22 deletions(-) diff --git a/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig b/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig index 2674e87cad49..ea7150ede5fe 100644 --- a/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig +++ b/boards/arm/nrf9161dk_nrf9161/Kconfig.defconfig @@ -8,21 +8,6 @@ if BOARD_NRF9161DK_NRF9161 || BOARD_NRF9161DK_NRF9161_NS config BOARD default "nrf9161dk_nrf9161" -# By default, if we build for a Non-Secure version of the board, -# enable building with TF-M as the Secure Execution Environment. -config BUILD_WITH_TFM - default y if BOARD_NRF9161DK_NRF9161_NS - -if BUILD_WITH_TFM - -# By default, if we build with TF-M, instruct build system to -# flash the combined TF-M (Secure) & Zephyr (Non Secure) image -config TFM_FLASH_MERGED_BINARY - bool - default y - -endif # BUILD_WITH_TFM - # For the secure version of the board the firmware is linked at the beginning # of the flash, or into the code-partition defined in DT if it is intended to # be loaded by MCUboot. If the secure firmware is to be combined with a non- diff --git a/boards/arm/nrf9161dk_nrf9161/board.cmake b/boards/arm/nrf9161dk_nrf9161/board.cmake index 883208b78326..73fe4dee8000 100644 --- a/boards/arm/nrf9161dk_nrf9161/board.cmake +++ b/boards/arm/nrf9161dk_nrf9161/board.cmake @@ -5,7 +5,7 @@ if(CONFIG_BOARD_NRF9161DK_NRF9161_NS) endif() if(CONFIG_TFM_FLASH_MERGED_BINARY) - set_property(TARGET runners_yaml_props_target PROPERTY hex_file tfm_merged.hex) + set_property(TARGET runners_yaml_props_target PROPERTY hex_file "${CMAKE_BINARY_DIR}/tfm_merged.hex") endif() # TODO: change to nRF9161_xxAA when such device is available in JLink diff --git a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts index 15648e11f419..623410dc8027 100644 --- a/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts +++ b/boards/arm/nrf9161dk_nrf9161/nrf9161dk_nrf9161_ns.dts @@ -15,8 +15,3 @@ zephyr,code-partition = &slot0_ns_partition; }; }; - -/* Disable UART1, because it is used by default in TF-M */ -&uart1 { - status = "disabled"; -}; diff --git a/modules/trusted-firmware-m/Kconfig.tfm b/modules/trusted-firmware-m/Kconfig.tfm index 2a22e0b30dbb..b1dad87c62f9 100644 --- a/modules/trusted-firmware-m/Kconfig.tfm +++ b/modules/trusted-firmware-m/Kconfig.tfm @@ -10,7 +10,6 @@ config ZEPHYR_TRUSTED_FIRMWARE_M_MODULE config TFM_BOARD string default "nordic_nrf/nrf9160dk_nrf9160" if BOARD_NRF9160DK_NRF9160_NS - default "nordic_nrf/nrf9161dk_nrf9161" if BOARD_NRF9161DK_NRF9161_NS default "nordic_nrf/nrf5340dk_nrf5340_cpuapp" if BOARD_NRF5340DK_NRF5340_CPUAPP_NS default "nxp/lpcxpresso55s69" if BOARD_LPCXPRESSO55S69_CPU0 default "arm/mps2/an521" if BOARD_MPS2_AN521_CPU0_NS From 037526db295d729376de9480dd8473c036726e5a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 248/528] Revert "[nrf fromtree] Bluetooth: Host: Fix double conversion of phy" This reverts commit 417f8466d90dbf547e09d3b65c92c75a1c0072f1. Signed-off-by: Robert Lubos --- subsys/bluetooth/host/scan.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 187a91fa566c..c48f40502a59 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1034,7 +1034,7 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) memset(&sync_info, 0, sizeof(sync_info)); sync_info.interval = pending_per_adv_sync->interval; - sync_info.phy = pending_per_adv_sync->phy; + sync_info.phy = bt_get_phy(pending_per_adv_sync->phy); if (atomic_test_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCING_USE_LIST)) { From 3d5a5ed3f6a75d8109c13c832f1ab2da986e4d1d Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 249/528] Revert "[nrf fromtree] getopt: extend ztests scope" This reverts commit 67c774827758444101e1808981f6a5f4af858dda. Signed-off-by: Robert Lubos --- tests/posix/getopt/testcase.yaml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/posix/getopt/testcase.yaml b/tests/posix/getopt/testcase.yaml index 31e808fbc446..158297f49d07 100644 --- a/tests/posix/getopt/testcase.yaml +++ b/tests/posix/getopt/testcase.yaml @@ -16,9 +16,3 @@ tests: filter: CONFIG_PICOLIBC_SUPPORTED extra_configs: - CONFIG_PICOLIBC=y - portability.posix.getopt.logger: - integration_platforms: - - qemu_x86 - extra_configs: - - CONFIG_LOG=y - build_only: true From 1cef7c200a97893ad4f921fcc1eff1f3475400bf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 250/528] Revert "[nrf fromtree] lib: getopt: Fix compiler warning." This reverts commit 5c4420d4541aecca51d012f9375df2ceb255e997. Signed-off-by: Robert Lubos --- lib/posix/getopt/getopt_long.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/posix/getopt/getopt_long.c b/lib/posix/getopt/getopt_long.c index d38cd8258a80..a13ebaf18f46 100644 --- a/lib/posix/getopt/getopt_long.c +++ b/lib/posix/getopt/getopt_long.c @@ -172,7 +172,7 @@ parse_long_options(struct getopt_state *state, char * const *nargv, { char *current_argv, *has_equal; #ifdef GNU_COMPATIBLE - char *current_dash = ""; + char *current_dash; #endif size_t current_argv_len; int i, match, exact_match, second_partial_match; @@ -191,6 +191,7 @@ parse_long_options(struct getopt_state *state, char * const *nargv, current_dash = "-W "; break; default: + current_dash = ""; break; } } From 2936c845e2be7585aabbc30f75537847dce0bd90 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:24 +0200 Subject: [PATCH 251/528] Revert "[nrf fromlist] mgmt/MCUmgr/grp/img: Rework image list to support DirectXIP" This reverts commit 5dc97da98200519c7cd340d4bc772035c3528a27. Signed-off-by: Robert Lubos --- .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 29 ------------------- 1 file changed, 29 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 559a15e139e1..6cdb6e4b8d08 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -54,7 +54,6 @@ LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); /** * Collects information about the specified image slot. */ -#ifndef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP uint8_t img_mgmt_state_flags(int query_slot) { @@ -106,34 +105,6 @@ img_mgmt_state_flags(int query_slot) return flags; } -#else -uint8_t -img_mgmt_state_flags(int query_slot) -{ - uint8_t flags = 0; - int image = query_slot / 2; /* We support max 2 images for now */ - int active_slot = img_mgmt_active_slot(image); - - /* In case when MCUboot is configured for DirectXIP slot may only be - * active or pending. Slot is marked pending only when version in that slot - * is higher than version of active slot. - */ - if (image == img_mgmt_active_image() && query_slot == active_slot) { - flags = IMG_MGMT_STATE_F_ACTIVE; - } else { - struct image_version sver; - struct image_version aver; - int rcs = img_mgmt_read_info(query_slot, &sver, NULL, NULL); - int rca = img_mgmt_read_info(active_slot, &aver, NULL, NULL); - - if (rcs == 0 && rca == 0 && img_mgmt_vercmp(&aver, &sver) < 0) { - flags = IMG_MGMT_STATE_F_PENDING; - } - } - - return flags; -} -#endif /** * Indicates whether any image slot is pending (i.e., whether a test swap will From 652cb0ff5a0b649fe3adbe51cb079d3f93775f52 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:25 +0200 Subject: [PATCH 252/528] Revert "[nrf fromtree] mgmt/mcumgr/grp/img: No MCUboot flags setting in DirectXIP" This reverts commit 397cb90fd5304c6d6516196050c2987885c618fe. Signed-off-by: Robert Lubos --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 4 ---- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 15 +++++---------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index b4aa59ae7389..c490b0ea5314 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -701,11 +701,7 @@ img_mgmt_my_version(struct image_version *ver) static const struct mgmt_handler img_mgmt_handlers[] = { [IMG_MGMT_ID_STATE] = { .mh_read = img_mgmt_state_read, -#ifdef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP - .mh_write = NULL -#else .mh_write = img_mgmt_state_write, -#endif }, [IMG_MGMT_ID_UPLOAD] = { .mh_read = NULL, diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 6cdb6e4b8d08..a006e2899750 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -124,18 +124,13 @@ img_mgmt_state_any_pending(void) int img_mgmt_slot_in_use(int slot) { + uint8_t state_flags; int active_slot = img_mgmt_active_slot(img_mgmt_active_image()); -#ifndef CONFIG_MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP - uint8_t state_flags = img_mgmt_state_flags(slot); - - if (state_flags & IMG_MGMT_STATE_F_CONFIRMED || - state_flags & IMG_MGMT_STATE_F_PENDING) { - return 1; - } -#endif - - return (active_slot == slot); + state_flags = img_mgmt_state_flags(slot); + return slot == active_slot || + state_flags & IMG_MGMT_STATE_F_CONFIRMED || + state_flags & IMG_MGMT_STATE_F_PENDING; } /** From 9cfc9c36138ba95df381da4e0ad5490c7124d6cd Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:25 +0200 Subject: [PATCH 253/528] Revert "[nrf fromtree] mgmt/mcumgr/grp/img: No upload for MCUboot in single app mode" This reverts commit 4e68c2a7f451d228c4b51e44a11ccba581549ee6. Signed-off-by: Robert Lubos --- subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig index 7f0c714d370f..ec7d17f43d17 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig @@ -16,7 +16,6 @@ menuconfig MCUMGR_GRP_IMG bool "Mcumgr handlers for image management" depends on FLASH depends on IMG_MANAGER - depends on !MCUBOOT_BOOTLOADER_MODE_SINGLE_APP select MPU_ALLOW_FLASH_WRITE if ARM_MPU select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_2 help From 5b21374f4eba07519cad2779628eb9adcb631edf Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:25 +0200 Subject: [PATCH 254/528] Revert "[nrf fromtree] mcuboot: Kconfig options allowing to inform on MCUboot config" This reverts commit 76c56af9b7ce93228ca7f7afa762ef33be85b48b. Signed-off-by: Robert Lubos --- Kconfig.mcuboot | 42 ------------------------------------------ 1 file changed, 42 deletions(-) diff --git a/Kconfig.mcuboot b/Kconfig.mcuboot index 7057331a572f..ef1cae5f021f 100644 --- a/Kconfig.mcuboot +++ b/Kconfig.mcuboot @@ -127,46 +127,4 @@ config MCUBOOT_GENERATE_CONFIRMED_IMAGE The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN and CONFIG_BUILD_OUTPUT_HEX. -choice MCUBOOT_BOOTLOADER_MODE - prompt "Application assumed MCUboot mode of operation" - default MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH # MCUBOOT_BOOTLOADER_MODE - help - Informs application build on assumed MCUboot mode of operation. - This is important for validataing application against DT configuration, - which is done by west sign. - -config MCUBOOT_BOOTLOADER_MODE_SINGLE_APP - bool "MCUboot has been configured for single slot execution" - help - MCUboot will only boot slot0_partition placed application and does - not care about other slots. In this mode application is not able - to DFU its own update to secondary slot and all updates need to - be performed using MCUboot serial recovery. - -config MCUBOOT_BOOTLOADER_MODE_SWAP_WITHOUT_SCRATCH - bool "MCUboot has been configured for swap without scratch operation" - help - MCUboot expects slot0_partition and slot1_partition to be present - in DT and application will boot from slot0_partition. - -config MCUBOOT_BOOTLOADER_MODE_SWAP_SCRATCH - bool "MCUboot has been configured for swap using scratch operation" - help - MCUboot expects slot0_partition, slot1_partition and scratch_partition - to be present in DT, and application will boot from slot0_partition. - In this mode scratch_partition is used as temporary storage when - MCUboot swaps application from the secondary slot to the primary - slot. - -config MCUBOOT_BOOTLOADER_MODE_DIRECT_XIP - bool "MCUboot has been configured for DirectXIP operation" - help - MCUboot expects slot0_partition and slot1_partition to exist in DT. - In this mode MCUboot can boot from either partition and will - select one with higher application image version, which usually - means major.minor.patch triple, unless BOOT_VERSION_CMP_USE_BUILD_NUMBER - is also selected that enables comparison of build number. - -endchoice # MCUBOOT_BOOTLOADER_MODE - endif # BOOTLOADER_MCUBOOT From 12bef783e4bbbb24aa5a2196b4a9e56c67e6ebf6 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:25 +0200 Subject: [PATCH 255/528] Revert "[nrf fromtree] kconfig: Separate MCUboot options to Kconfig.mcuboot" This reverts commit 7edf308c6d26915fa2d13f132b623484852e3c15. Signed-off-by: Robert Lubos --- Kconfig.mcuboot | 130 ------------------------------------------------ Kconfig.zephyr | 125 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 123 insertions(+), 132 deletions(-) delete mode 100644 Kconfig.mcuboot diff --git a/Kconfig.mcuboot b/Kconfig.mcuboot deleted file mode 100644 index ef1cae5f021f..000000000000 --- a/Kconfig.mcuboot +++ /dev/null @@ -1,130 +0,0 @@ -# General configuration options - -# Copyright (c) 2014-2015 Wind River Systems, Inc. -# Copyright (c) 2016 Intel Corporation -# Copyright (c) 2023 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 - -config MCUBOOT - bool - help - Hidden option used to indicate that the current image is MCUBoot - -config BOOTLOADER_MCUBOOT - bool "MCUboot bootloader support" - select USE_DT_CODE_PARTITION - imply INIT_ARCH_HW_AT_BOOT if ARCH_SUPPORTS_ARCH_HW_INIT - depends on !MCUBOOT - help - This option signifies that the target uses MCUboot as a bootloader, - or in other words that the image is to be chain-loaded by MCUboot. - This sets several required build system and Device Tree options in - order for the image generated to be bootable using the MCUboot open - source bootloader. Currently this includes: - - * Setting ROM_START_OFFSET to a default value that allows space - for the MCUboot image header - * Activating SW_VECTOR_RELAY_CLIENT on Cortex-M0 - (or Armv8-M baseline) targets with no built-in vector relocation - mechanisms - - By default, this option instructs Zephyr to initialize the core - architecture HW registers during boot, when this is supported by - the application. This removes the need by MCUboot to reset - the core registers' state itself. - -if BOOTLOADER_MCUBOOT - -config MCUBOOT_CMAKE_WEST_SIGN_PARAMS - string "Extra parameters to west sign" - default "--quiet" - help - Parameters that are passed by cmake to west sign, just after - the command, before all other parameters needed for image - signing. - By default this is set to "--quiet" to prevent extra, non-error, - diagnostic messages from west sign. This does not affect signing - tool for which extra parameters are passed with - MCUBOOT_EXTRA_IMGTOOL_ARGS. - -config MCUBOOT_SIGNATURE_KEY_FILE - string "Path to the mcuboot signing key file" - default "" - depends on !MCUBOOT_GENERATE_UNSIGNED_IMAGE - help - The file contains a key pair whose public half is verified - by your target's MCUboot image. The file is in PEM format. - - If set to a non-empty value, the build system tries to - sign the final binaries using a 'west sign -t imgtool' command. - The signed binaries are placed in the build directory - at zephyr/zephyr.signed.bin and zephyr/zephyr.signed.hex. - - The file names can be customized with CONFIG_KERNEL_BIN_NAME. - The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN - and CONFIG_BUILD_OUTPUT_HEX. - - This option should contain a path to the same file as the - BOOT_SIGNATURE_KEY_FILE option in your MCUboot .config. The path - may be absolute or relative to the west workspace topdir. (The MCUboot - config option is used for the MCUboot bootloader image; this option is - for your application which is to be loaded by MCUboot. The MCUboot - config option can be a relative path from the MCUboot repository - root.) - - If left empty, you must sign the Zephyr binaries manually. - -config MCUBOOT_ENCRYPTION_KEY_FILE - string "Path to the mcuboot encryption key file" - default "" - depends on MCUBOOT_SIGNATURE_KEY_FILE != "" - help - The file contains the public key that is used to encrypt the - ephemeral key that encrypts the image. The corresponding - private key is hard coded in the MCUboot source code and is - used to decrypt the ephemeral key that is embedded in the - image. The file is in PEM format. - - If set to a non-empty value, the build system tries to - sign and encrypt the final binaries using a 'west sign -t imgtool' - command. The binaries are placed in the build directory at - zephyr/zephyr.signed.encrypted.bin and - zephyr/zephyr.signed.encrypted.hex. - - The file names can be customized with CONFIG_KERNEL_BIN_NAME. - The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN - and CONFIG_BUILD_OUTPUT_HEX. - - This option should either be an absolute path or a path relative to - the west workspace topdir. - Example: './bootloader/mcuboot/enc-rsa2048-pub.pem' - - If left empty, you must encrypt the Zephyr binaries manually. - -config MCUBOOT_EXTRA_IMGTOOL_ARGS - string "Extra arguments to pass to imgtool when signing" - default "" - help - When signing (CONFIG_MCUBOOT_SIGNATURE_KEY_FILE is a non-empty - string) you can use this option to pass extra options to - imgtool. For example, you could set this to "--version 1.2". - -config MCUBOOT_GENERATE_UNSIGNED_IMAGE - bool "Generate unsigned binary image bootable with MCUboot" - help - Enabling this configuration allows automatic unsigned binary image - generation when MCUboot signing key is not provided, - i.e., MCUBOOT_SIGNATURE_KEY_FILE is left empty. - -config MCUBOOT_GENERATE_CONFIRMED_IMAGE - bool "Also generate a padded, confirmed image" - help - The signed, padded, and confirmed binaries are placed in the build - directory at zephyr/zephyr.signed.confirmed.bin and - zephyr/zephyr.signed.confirmed.hex. - - The file names can be customized with CONFIG_KERNEL_BIN_NAME. - The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN - and CONFIG_BUILD_OUTPUT_HEX. - -endif # BOOTLOADER_MCUBOOT diff --git a/Kconfig.zephyr b/Kconfig.zephyr index 2b94489a16b6..827b19a6ce4d 100644 --- a/Kconfig.zephyr +++ b/Kconfig.zephyr @@ -2,7 +2,6 @@ # Copyright (c) 2014-2015 Wind River Systems, Inc. # Copyright (c) 2016 Intel Corporation -# Copyright (c) 2023 Nordic Semiconductor ASA # SPDX-License-Identifier: Apache-2.0 @@ -784,7 +783,129 @@ config BOOTLOADER_SRAM_SIZE - Zephyr is a !XIP image, which implicitly assumes existence of a bootloader that loads the Zephyr !XIP image onto SRAM. -source "Kconfig.mcuboot" +config MCUBOOT + bool + help + Hidden option used to indicate that the current image is MCUBoot + +config BOOTLOADER_MCUBOOT + bool "MCUboot bootloader support" + select USE_DT_CODE_PARTITION + imply INIT_ARCH_HW_AT_BOOT if ARCH_SUPPORTS_ARCH_HW_INIT + depends on !MCUBOOT + help + This option signifies that the target uses MCUboot as a bootloader, + or in other words that the image is to be chain-loaded by MCUboot. + This sets several required build system and Device Tree options in + order for the image generated to be bootable using the MCUboot open + source bootloader. Currently this includes: + + * Setting ROM_START_OFFSET to a default value that allows space + for the MCUboot image header + * Activating SW_VECTOR_RELAY_CLIENT on Cortex-M0 + (or Armv8-M baseline) targets with no built-in vector relocation + mechanisms + + By default, this option instructs Zephyr to initialize the core + architecture HW registers during boot, when this is supported by + the application. This removes the need by MCUboot to reset + the core registers' state itself. + +if BOOTLOADER_MCUBOOT + +config MCUBOOT_CMAKE_WEST_SIGN_PARAMS + string "Extra parameters to west sign" + default "--quiet" + help + Parameters that are passed by cmake to west sign, just after + the command, before all other parameters needed for image + signing. + By default this is set to "--quiet" to prevent extra, non-error, + diagnostic messages from west sign. This does not affect signing + tool for which extra parameters are passed with + MCUBOOT_EXTRA_IMGTOOL_ARGS. + +config MCUBOOT_SIGNATURE_KEY_FILE + string "Path to the mcuboot signing key file" + default "" + depends on !MCUBOOT_GENERATE_UNSIGNED_IMAGE + help + The file contains a key pair whose public half is verified + by your target's MCUboot image. The file is in PEM format. + + If set to a non-empty value, the build system tries to + sign the final binaries using a 'west sign -t imgtool' command. + The signed binaries are placed in the build directory + at zephyr/zephyr.signed.bin and zephyr/zephyr.signed.hex. + + The file names can be customized with CONFIG_KERNEL_BIN_NAME. + The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN + and CONFIG_BUILD_OUTPUT_HEX. + + This option should contain a path to the same file as the + BOOT_SIGNATURE_KEY_FILE option in your MCUboot .config. The path + may be absolute or relative to the west workspace topdir. (The MCUboot + config option is used for the MCUboot bootloader image; this option is + for your application which is to be loaded by MCUboot. The MCUboot + config option can be a relative path from the MCUboot repository + root.) + + If left empty, you must sign the Zephyr binaries manually. + +config MCUBOOT_ENCRYPTION_KEY_FILE + string "Path to the mcuboot encryption key file" + default "" + depends on MCUBOOT_SIGNATURE_KEY_FILE != "" + help + The file contains the public key that is used to encrypt the + ephemeral key that encrypts the image. The corresponding + private key is hard coded in the MCUboot source code and is + used to decrypt the ephemeral key that is embedded in the + image. The file is in PEM format. + + If set to a non-empty value, the build system tries to + sign and encrypt the final binaries using a 'west sign -t imgtool' + command. The binaries are placed in the build directory at + zephyr/zephyr.signed.encrypted.bin and + zephyr/zephyr.signed.encrypted.hex. + + The file names can be customized with CONFIG_KERNEL_BIN_NAME. + The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN + and CONFIG_BUILD_OUTPUT_HEX. + + This option should either be an absolute path or a path relative to + the west workspace topdir. + Example: './bootloader/mcuboot/enc-rsa2048-pub.pem' + + If left empty, you must encrypt the Zephyr binaries manually. + +config MCUBOOT_EXTRA_IMGTOOL_ARGS + string "Extra arguments to pass to imgtool when signing" + default "" + help + When signing (CONFIG_MCUBOOT_SIGNATURE_KEY_FILE is a non-empty + string) you can use this option to pass extra options to + imgtool. For example, you could set this to "--version 1.2". + +config MCUBOOT_GENERATE_UNSIGNED_IMAGE + bool "Generate unsigned binary image bootable with MCUboot" + help + Enabling this configuration allows automatic unsigned binary image + generation when MCUboot signing key is not provided, + i.e., MCUBOOT_SIGNATURE_KEY_FILE is left empty. + +config MCUBOOT_GENERATE_CONFIRMED_IMAGE + bool "Also generate a padded, confirmed image" + help + The signed, padded, and confirmed binaries are placed in the build + directory at zephyr/zephyr.signed.confirmed.bin and + zephyr/zephyr.signed.confirmed.hex. + + The file names can be customized with CONFIG_KERNEL_BIN_NAME. + The existence of bin and hex files depends on CONFIG_BUILD_OUTPUT_BIN + and CONFIG_BUILD_OUTPUT_HEX. + +endif # BOOTLOADER_MCUBOOT config BOOTLOADER_ESP_IDF bool "ESP-IDF bootloader support" From 599997a9781ed9eea4291b8670a2b7a8a9c9e845 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:25 +0200 Subject: [PATCH 256/528] Revert "[nrf fromtree] manifest: openthread upmerge up to commit 1f1a826" This reverts commit f587bf11821e068b24fa472545daeca3668aa6df. Signed-off-by: Robert Lubos --- modules/openthread/CMakeLists.txt | 6 +++--- modules/openthread/Kconfig.features | 2 +- west.yml | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 78d9f835ff6e..508c888e0f3c 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -184,10 +184,10 @@ else() set(OT_DNS_DSO OFF CACHE BOOL "Enable DNS Stateful Operations (DSO) support" FORCE) endif() -if(CONFIG_OPENTHREAD_DNS_QUERY_UPSTREAM) - set(OT_DNS_QUERY_UPSTREAM ON CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) +if(CONFIG_OPENTHREAD_DNS_UPSTREAM_QUERY) + set(OT_DNS_UPSTREAM_QUERY ON CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) else() - set(OT_DNS_QUERY_UPSTREAM OFF CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) + set(OT_DNS_UPSTREAM_QUERY OFF CACHE BOOL "Enable forwarding DNS queries to upstream" FORCE) endif() if(CONFIG_OPENTHREAD_DNSSD_SERVER) diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 4766032cd79a..2a84e3e9a534 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -112,7 +112,7 @@ config OPENTHREAD_DNS_CLIENT_OVER_TCP config OPENTHREAD_DNS_DSO bool "DNS Stateful Operations (DSO) support" -config OPENTHREAD_DNS_QUERY_UPSTREAM +config OPENTHREAD_DNS_UPSTREAM_QUERY bool "Forwarding DNS queries to upstream" help Enable forwarding DNS queries to platform DNS upstream API diff --git a/west.yml b/west.yml index 746542a8bc72..efeb1f8bd159 100644 --- a/west.yml +++ b/west.yml @@ -203,7 +203,7 @@ manifest: revision: aedcc262f93bbb1b0c2f58026911575729b7465c path: modules/lib/open-amp - name: openthread - revision: 1f1a826d1891fc99d14822abc0a1de257e9c6e9b + revision: 25942910ab57b32f73d9c56d8c6cf07c7cf98c49 path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From 2addb4c5f153c198b5df35e7aee546787d10d621 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:25 +0200 Subject: [PATCH 257/528] Revert "[nrf fromtree] net: openthread: Add implementation of crypto api." This reverts commit 148596ee59989b4df059b8f038d61d0f50be7600. Signed-off-by: Robert Lubos --- modules/openthread/platform/crypto_psa.c | 79 ------------------------ 1 file changed, 79 deletions(-) diff --git a/modules/openthread/platform/crypto_psa.c b/modules/openthread/platform/crypto_psa.c index d9deb114f369..8132e6013a96 100644 --- a/modules/openthread/platform/crypto_psa.c +++ b/modules/openthread/platform/crypto_psa.c @@ -563,83 +563,4 @@ otError otPlatCryptoEcdsaVerify(const otPlatCryptoEcdsaPublicKey *aPublicKey, return psaToOtError(status); } -otError otPlatCryptoEcdsaSignUsingKeyRef(otCryptoKeyRef aKeyRef, - const otPlatCryptoSha256Hash *aHash, - otPlatCryptoEcdsaSignature *aSignature) -{ - psa_status_t status; - size_t signature_length; - - status = psa_sign_hash(aKeyRef, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8, - OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8, - OT_CRYPTO_ECDSA_SIGNATURE_SIZE, &signature_length); - if (status != PSA_SUCCESS) { - goto out; - } - - __ASSERT_NO_MSG(signature_length == OT_CRYPTO_ECDSA_SIGNATURE_SIZE); -out: - return psaToOtError(status); -} - -otError otPlatCryptoEcdsaVerifyUsingKeyRef(otCryptoKeyRef aKeyRef, - const otPlatCryptoSha256Hash *aHash, - const otPlatCryptoEcdsaSignature *aSignature) -{ - psa_status_t status; - - status = psa_verify_hash(aKeyRef, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256), aHash->m8, - OT_CRYPTO_SHA256_HASH_SIZE, aSignature->m8, - OT_CRYPTO_ECDSA_SIGNATURE_SIZE); - if (status != PSA_SUCCESS) { - goto out; - } - -out: - return psaToOtError(status); -} - -otError otPlatCryptoEcdsaExportPublicKey(otCryptoKeyRef aKeyRef, - otPlatCryptoEcdsaPublicKey *aPublicKey) -{ - psa_status_t status; - size_t exported_length; - uint8_t buffer[1 + OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE]; - - status = psa_export_public_key(aKeyRef, buffer, sizeof(buffer), &exported_length); - if (status != PSA_SUCCESS) { - goto out; - } - - __ASSERT_NO_MSG(exported_length == sizeof(buffer)); - memcpy(aPublicKey->m8, buffer + 1, OT_CRYPTO_ECDSA_PUBLIC_KEY_SIZE); - -out: - return psaToOtError(status); -} - -otError otPlatCryptoEcdsaGenerateAndImportKey(otCryptoKeyRef aKeyRef) -{ - psa_key_attributes_t attributes = PSA_KEY_ATTRIBUTES_INIT; - psa_status_t status; - psa_key_id_t key_id = (psa_key_id_t)aKeyRef; - - psa_set_key_usage_flags(&attributes, PSA_KEY_USAGE_VERIFY_HASH | PSA_KEY_USAGE_SIGN_HASH); - psa_set_key_algorithm(&attributes, PSA_ALG_DETERMINISTIC_ECDSA(PSA_ALG_SHA_256)); - psa_set_key_type(&attributes, PSA_KEY_TYPE_ECC_KEY_PAIR(PSA_ECC_FAMILY_SECP_R1)); - psa_set_key_lifetime(&attributes, PSA_KEY_LIFETIME_PERSISTENT); - psa_set_key_id(&attributes, key_id); - psa_set_key_bits(&attributes, 256); - - status = psa_generate_key(&attributes, &key_id); - if (status != PSA_SUCCESS) { - goto out; - } - -out: - psa_reset_key_attributes(&attributes); - - return psaToOtError(status); -} - #endif /* #if CONFIG_OPENTHREAD_ECDSA */ From 71e38ee047a0cc7bdb39b94b62f95b65ccdc3fd5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:25 +0200 Subject: [PATCH 258/528] Revert "[nrf fromtree] net: openthread: Remove not needed `OPENTHREAD_EXCLUDE_TCPLP_LIB`" This reverts commit ab6dc44191d88437776df3884588b93831112bd9. Signed-off-by: Robert Lubos --- modules/openthread/CMakeLists.txt | 6 ++++++ modules/openthread/Kconfig.features | 3 +++ 2 files changed, 9 insertions(+) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 508c888e0f3c..a263e2256082 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -214,6 +214,12 @@ else() set(OT_SERVICE OFF CACHE BOOL "Enable Service entries in Thread Network Data" FORCE) endif() +if(CONFIG_OPENTHREAD_EXCLUDE_TCPLP_LIB) + set(OT_EXCLUDE_TCPLP_LIB ON CACHE BOOL "Exclude TCPlp library from build" FORCE) +else() + set(OT_EXCLUDE_TCPLP_LIB OFF CACHE BOOL "Exclude TCPlp library from build" FORCE) +endif() + if(CONFIG_OPENTHREAD_EXTERNAL_HEAP) set(OT_EXTERNAL_HEAP ON CACHE BOOL "Enable external heap support" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index 2a84e3e9a534..a57de4b31c16 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -133,6 +133,9 @@ config OPENTHREAD_ENABLE_SERVICE help Enable Thread Services capability in OpenThread stack +config OPENTHREAD_EXCLUDE_TCPLP_LIB + bool "Exclude TCPlp library from build" + config OPENTHREAD_EXTERNAL_HEAP bool "External heap support" From 5eec506d1e0e0ddc9b1bbe8a65c0046549a9ddc0 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:25 +0200 Subject: [PATCH 259/528] Revert "[nrf fromtree] samples: shields: npm1300_ek: Added initial charger sensor" This reverts commit 9aa6e9baa3777c7361da5e1eafdd6511a89c4d10. Signed-off-by: Robert Lubos --- samples/shields/npm1300_ek/src/main.c | 45 +-------------------------- 1 file changed, 1 insertion(+), 44 deletions(-) diff --git a/samples/shields/npm1300_ek/src/main.c b/samples/shields/npm1300_ek/src/main.c index 896604249ae6..af7e6b92decc 100644 --- a/samples/shields/npm1300_ek/src/main.c +++ b/samples/shields/npm1300_ek/src/main.c @@ -8,21 +8,16 @@ #include #include #include -#include -#include #include #include #include -#define SLEEP_TIME_MS 100 -#define UPDATE_TIME_MS 2000 +#define SLEEP_TIME_MS 100 static const struct gpio_dt_spec button1 = GPIO_DT_SPEC_GET(DT_ALIAS(sw0), gpios); static const struct device *regulators = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_regulators)); -static const struct device *charger = DEVICE_DT_GET(DT_NODELABEL(npm1300_ek_charger)); - void configure_ui(void) { int ret; @@ -42,31 +37,6 @@ void configure_ui(void) printk("Set up button at %s pin %d\n", button1.port->name, button1.pin); } -void read_sensors(void) -{ - struct sensor_value volt; - struct sensor_value current; - struct sensor_value temp; - struct sensor_value error; - struct sensor_value status; - - sensor_sample_fetch(charger); - sensor_channel_get(charger, SENSOR_CHAN_GAUGE_VOLTAGE, &volt); - sensor_channel_get(charger, SENSOR_CHAN_GAUGE_AVG_CURRENT, ¤t); - sensor_channel_get(charger, SENSOR_CHAN_GAUGE_TEMP, &temp); - sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_STATUS, &status); - sensor_channel_get(charger, SENSOR_CHAN_NPM1300_CHARGER_ERROR, &error); - - printk("V: %d.%03d ", volt.val1, volt.val2 / 1000); - - printk("I: %s%d.%04d ", ((current.val1 < 0) || (current.val2 < 0)) ? "-" : "", - abs(current.val1), abs(current.val2) / 100); - - printk("T: %d.%02d\n", temp.val1, temp.val2 / 10000); - - printk("Charger Status: %d, Error: %d\n", status.val1, error.val1); -} - int main(void) { configure_ui(); @@ -76,11 +46,6 @@ int main(void) return 0; } - if (!device_is_ready(charger)) { - printk("Charger device not ready.\n"); - return 0; - } - while (1) { /* Cycle regulator control GPIOs when first button pressed */ static bool last_button; @@ -92,14 +57,6 @@ int main(void) regulator_parent_dvs_state_set(regulators, dvs_state); } - /* Read and display charger status */ - static int count; - - if (++count > (UPDATE_TIME_MS / SLEEP_TIME_MS)) { - read_sensors(); - count = 0; - } - last_button = button_state; k_msleep(SLEEP_TIME_MS); } From 57c77c4f37773a88b6b4f46de2d3ad818a1835a8 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:26 +0200 Subject: [PATCH 260/528] Revert "[nrf fromtree] boards: shields: npm1300_ek: Added initial charger sensor" This reverts commit 39cfa75a48c3659a4d7f1fa574570274f885f69c. Signed-off-by: Robert Lubos --- boards/shields/npm1300_ek/Kconfig.defconfig | 3 --- boards/shields/npm1300_ek/npm1300_ek.overlay | 12 ------------ 2 files changed, 15 deletions(-) diff --git a/boards/shields/npm1300_ek/Kconfig.defconfig b/boards/shields/npm1300_ek/Kconfig.defconfig index 72b27a4f2906..9c9b0573e2bd 100644 --- a/boards/shields/npm1300_ek/Kconfig.defconfig +++ b/boards/shields/npm1300_ek/Kconfig.defconfig @@ -9,7 +9,4 @@ config REGULATOR config GPIO default y -config SENSOR - default y - endif # SHIELD_NPM1300_EK diff --git a/boards/shields/npm1300_ek/npm1300_ek.overlay b/boards/shields/npm1300_ek/npm1300_ek.overlay index 3c9d8d707c76..455a4b925ab1 100644 --- a/boards/shields/npm1300_ek/npm1300_ek.overlay +++ b/boards/shields/npm1300_ek/npm1300_ek.overlay @@ -46,17 +46,5 @@ enable-gpios = <&npm1300_ek_gpio 2 GPIO_ACTIVE_LOW>; }; }; - - npm1300_ek_charger: charger { - compatible = "nordic,npm1300-charger"; - term-microvolt = <4150000>; - term-warm-microvolt = <4000000>; - current-microamp = <150000>; - dischg-limit-microamp = <1000000>; - vbus-limit-microamp = <500000>; - thermistor-ohms = <10000>; - thermistor-beta = <3380>; - charging-enable; - }; }; }; From 8f122c8fdf18b613c1c2468170a1f31c907028e3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:26 +0200 Subject: [PATCH 261/528] Revert "[nrf fromtree] drivers: sensor: npm1300_charger: NPM1300 charger driver" This reverts commit d121698904a177644f7bbeec5f7460f2b42b0f3d. Signed-off-by: Robert Lubos --- drivers/sensor/CMakeLists.txt | 1 - drivers/sensor/Kconfig | 2 - drivers/sensor/npm1300_charger/CMakeLists.txt | 7 - drivers/sensor/npm1300_charger/Kconfig | 12 - .../sensor/npm1300_charger/npm1300_charger.c | 421 ------------------ .../sensor/nordic,npm1300-charger.yaml | 68 --- .../zephyr/drivers/sensor/npm1300_charger.h | 17 - 7 files changed, 528 deletions(-) delete mode 100644 drivers/sensor/npm1300_charger/CMakeLists.txt delete mode 100644 drivers/sensor/npm1300_charger/Kconfig delete mode 100644 drivers/sensor/npm1300_charger/npm1300_charger.c delete mode 100644 dts/bindings/sensor/nordic,npm1300-charger.yaml delete mode 100644 include/zephyr/drivers/sensor/npm1300_charger.h diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index d9bb2b5fc89e..d895d3190beb 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -83,7 +83,6 @@ add_subdirectory_ifdef(CONFIG_MPU6050 mpu6050) add_subdirectory_ifdef(CONFIG_MPU9250 mpu9250) add_subdirectory_ifdef(CONFIG_MS5607 ms5607) add_subdirectory_ifdef(CONFIG_MS5837 ms5837) -add_subdirectory_ifdef(CONFIG_NPM1300_CHARGER npm1300_charger) add_subdirectory_ifdef(CONFIG_OPT3001 opt3001) add_subdirectory_ifdef(CONFIG_PMS7003 pms7003) add_subdirectory_ifdef(CONFIG_QDEC_MCUX qdec_mcux) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index a00e01e47965..449de52c82ec 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -209,8 +209,6 @@ source "drivers/sensor/ms5837/Kconfig" source "drivers/sensor/ms5607/Kconfig" -source "drivers/sensor/npm1300_charger/Kconfig" - source "drivers/sensor/nrf5/Kconfig" source "drivers/sensor/opt3001/Kconfig" diff --git a/drivers/sensor/npm1300_charger/CMakeLists.txt b/drivers/sensor/npm1300_charger/CMakeLists.txt deleted file mode 100644 index 51083775eff7..000000000000 --- a/drivers/sensor/npm1300_charger/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library() - -zephyr_library_sources(npm1300_charger.c) diff --git a/drivers/sensor/npm1300_charger/Kconfig b/drivers/sensor/npm1300_charger/Kconfig deleted file mode 100644 index 12a3e6937cf5..000000000000 --- a/drivers/sensor/npm1300_charger/Kconfig +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 - -config NPM1300_CHARGER - bool "NPM1300 Charger" - default y - depends on DT_HAS_NORDIC_NPM1300_CHARGER_ENABLED - select I2C - select REQUIRES_FULL_LIBC - help - Enable NPM1300 charger driver. diff --git a/drivers/sensor/npm1300_charger/npm1300_charger.c b/drivers/sensor/npm1300_charger/npm1300_charger.c deleted file mode 100644 index 8a5ff935777d..000000000000 --- a/drivers/sensor/npm1300_charger/npm1300_charger.c +++ /dev/null @@ -1,421 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT nordic_npm1300_charger - -#include -#include -#include -#include -#include -#include - -struct npm1300_charger_config { - struct i2c_dt_spec i2c; - int32_t term_microvolt; - int32_t term_warm_microvolt; - int32_t current_microamp; - int32_t dischg_limit_microamp; - int32_t vbus_limit_microamp; - uint8_t thermistor_idx; - uint16_t thermistor_beta; - bool charging_enable; -}; - -struct npm1300_charger_data { - uint16_t voltage; - uint16_t current; - uint16_t temp; - uint8_t status; - uint8_t error; - uint8_t ibat_stat; - uint8_t vbus_stat; -}; - -/* nPM1300 base addresses */ -#define CHGR_BASE 0x03U -#define ADC_BASE 0x05U -#define VBUS_BASE 0x02U - -/* nPM1300 charger register offsets */ -#define CHGR_OFFSET_EN_SET 0x04U -#define CHGR_OFFSET_EN_CLR 0x05U -#define CHGR_OFFSET_ISET 0x08U -#define CHGR_OFFSET_ISET_DISCHG 0x0AU -#define CHGR_OFFSET_VTERM 0x0CU -#define CHGR_OFFSET_VTERM_R 0x0DU -#define CHGR_OFFSET_CHG_STAT 0x34U -#define CHGR_OFFSET_ERR_REASON 0x36U - -/* nPM1300 ADC register offsets */ -#define ADC_OFFSET_TASK_VBAT 0x00U -#define ADC_OFFSET_TASK_TEMP 0x01U -#define ADC_OFFSET_CONFIG 0x09U -#define ADC_OFFSET_NTCR_SEL 0x0AU -#define ADC_OFFSET_RESULTS 0x10U -#define ADC_OFFSET_IBAT_EN 0x24U - -/* nPM1300 VBUS register offsets */ -#define VBUS_OFFSET_TASK_UPDATE 0x00U -#define VBUS_OFFSET_ILIM 0x01U -#define VBUS_OFFSET_STATUS 0x07U - -/* Ibat status */ -#define IBAT_STAT_DISCHARGE 0x04U -#define IBAT_STAT_CHARGE_TRICKLE 0x0CU -#define IBAT_STAT_CHARGE_COOL 0x0DU -#define IBAT_STAT_CHARGE_NORMAL 0x0FU - -struct adc_results_t { - uint8_t ibat_stat; - uint8_t msb_vbat; - uint8_t msb_ntc; - uint8_t msb_die; - uint8_t msb_vsys; - uint8_t lsb_a; - uint8_t reserved1; - uint8_t reserved2; - uint8_t msb_ibat; - uint8_t msb_vbus; - uint8_t lsb_b; -} __packed; - -/* ADC result masks */ -#define ADC_MSB_SHIFT 2U -#define ADC_LSB_MASK 0x03U -#define ADC_LSB_VBAT_SHIFT 0U -#define ADC_LSB_NTC_SHIFT 2U -#define ADC_LSB_IBAT_SHIFT 4U - -/* Linear range for charger terminal voltage */ -static const struct linear_range charger_volt_ranges[] = { - LINEAR_RANGE_INIT(3500000, 50000, 0U, 3U), LINEAR_RANGE_INIT(4000000, 50000, 4U, 13U)}; - -/* Linear range for charger current */ -static const struct linear_range charger_current_range = LINEAR_RANGE_INIT(32000, 2000, 16U, 400U); - -/* Linear range for Discharge limit */ -static const struct linear_range discharge_limit_range = LINEAR_RANGE_INIT(268090, 3230, 83U, 415U); - -/* Linear range for vbusin current limit */ -static const struct linear_range vbus_current_ranges[] = { - LINEAR_RANGE_INIT(100000, 0, 1U, 1U), LINEAR_RANGE_INIT(500000, 100000, 5U, 15U)}; - -/* Read multiple registers from specified address */ -static int reg_read_burst(const struct device *dev, uint8_t base, uint8_t offset, void *data, - size_t len) -{ - const struct npm1300_charger_config *const config = dev->config; - uint8_t buff[] = {base, offset}; - - return i2c_write_read_dt(&config->i2c, buff, sizeof(buff), data, len); -} - -static int reg_read(const struct device *dev, uint8_t base, uint8_t offset, uint8_t *data) -{ - return reg_read_burst(dev, base, offset, data, 1U); -} - -/* Write single register to specified address */ -static int reg_write(const struct device *dev, uint8_t base, uint8_t offset, uint8_t data) -{ - const struct npm1300_charger_config *const config = dev->config; - uint8_t buff[] = {base, offset, data}; - - return i2c_write_dt(&config->i2c, buff, sizeof(buff)); -} - -static int reg_write2(const struct device *dev, uint8_t base, uint8_t offset, uint8_t data1, - uint8_t data2) -{ - const struct npm1300_charger_config *const config = dev->config; - uint8_t buff[] = {base, offset, data1, data2}; - - return i2c_write_dt(&config->i2c, buff, sizeof(buff)); -} - -static void calc_temp(const struct npm1300_charger_config *const config, uint16_t code, - struct sensor_value *valp) -{ - /* Ref: Datasheet Figure 42: Battery temperature (Kelvin) */ - float log_result = log((1024.f / (float)code) - 1); - float inv_temp_k = (1.f / 298.15f) - (log_result / (float)config->thermistor_beta); - - float temp = (1.f / inv_temp_k) - 273.15f; - - valp->val1 = (int32_t)temp; - valp->val2 = (int32_t)(fmodf(temp, 1.f) * 1000000.f); -} - -static uint16_t adc_get_res(uint8_t msb, uint8_t lsb, uint16_t lsb_shift) -{ - return ((uint16_t)msb << ADC_MSB_SHIFT) | ((lsb >> lsb_shift) & ADC_LSB_MASK); -} - -static void calc_current(const struct npm1300_charger_config *const config, - struct npm1300_charger_data *const data, struct sensor_value *valp) -{ - int32_t full_scale_ma; - int32_t current; - - switch (data->ibat_stat) { - case IBAT_STAT_DISCHARGE: - full_scale_ma = config->dischg_limit_microamp / 1000; - break; - case IBAT_STAT_CHARGE_TRICKLE: - full_scale_ma = -config->current_microamp / 10000; - break; - case IBAT_STAT_CHARGE_COOL: - full_scale_ma = -config->current_microamp / 2000; - break; - case IBAT_STAT_CHARGE_NORMAL: - full_scale_ma = -config->current_microamp / 1000; - break; - default: - full_scale_ma = 0; - break; - } - - current = (data->current * full_scale_ma) / 1024; - - valp->val1 = current / 1000; - valp->val2 = (current % 1000) * 1000; -} - -int npm1300_charger_channel_get(const struct device *dev, enum sensor_channel chan, - struct sensor_value *valp) -{ - const struct npm1300_charger_config *const config = dev->config; - struct npm1300_charger_data *const data = dev->data; - int32_t tmp; - - switch ((uint32_t)chan) { - case SENSOR_CHAN_GAUGE_VOLTAGE: - tmp = data->voltage * 5000 / 1024; - valp->val1 = tmp / 1000; - valp->val2 = (tmp % 1000) * 1000; - break; - case SENSOR_CHAN_GAUGE_TEMP: - calc_temp(config, data->temp, valp); - break; - case SENSOR_CHAN_GAUGE_AVG_CURRENT: - calc_current(config, data, valp); - break; - case SENSOR_CHAN_NPM1300_CHARGER_STATUS: - valp->val1 = data->status; - valp->val2 = 0; - break; - case SENSOR_CHAN_NPM1300_CHARGER_ERROR: - valp->val1 = data->error; - valp->val2 = 0; - break; - case SENSOR_CHAN_GAUGE_DESIRED_CHARGING_CURRENT: - valp->val1 = config->current_microamp / 1000000; - valp->val2 = config->current_microamp % 1000000; - break; - case SENSOR_CHAN_GAUGE_MAX_LOAD_CURRENT: - valp->val1 = config->dischg_limit_microamp / 1000000; - valp->val2 = config->dischg_limit_microamp % 1000000; - break; - default: - return -ENOTSUP; - } - - return 0; -} - -int npm1300_charger_sample_fetch(const struct device *dev, enum sensor_channel chan) -{ - struct npm1300_charger_data *data = dev->data; - struct adc_results_t results; - bool last_vbus; - int ret; - - /* Read charge status and error reason */ - ret = reg_read(dev, CHGR_BASE, CHGR_OFFSET_CHG_STAT, &data->status); - if (ret != 0) { - return ret; - } - - ret = reg_read(dev, CHGR_BASE, CHGR_OFFSET_ERR_REASON, &data->error); - if (ret != 0) { - return ret; - } - - /* Read adc results */ - ret = reg_read_burst(dev, ADC_BASE, ADC_OFFSET_RESULTS, &results, sizeof(results)); - if (ret != 0) { - return ret; - } - - data->voltage = adc_get_res(results.msb_vbat, results.lsb_a, ADC_LSB_VBAT_SHIFT); - data->temp = adc_get_res(results.msb_ntc, results.lsb_a, ADC_LSB_NTC_SHIFT); - data->current = adc_get_res(results.msb_ibat, results.lsb_b, ADC_LSB_IBAT_SHIFT); - data->ibat_stat = results.ibat_stat; - - /* Trigger temperature measurement */ - ret = reg_write(dev, ADC_BASE, ADC_OFFSET_TASK_TEMP, 1U); - if (ret != 0) { - return ret; - } - - /* Trigger current and voltage measurement */ - ret = reg_write(dev, ADC_BASE, ADC_OFFSET_TASK_VBAT, 1U); - if (ret != 0) { - return ret; - } - - /* Read vbus status, and set SW current limit on new vbus detection */ - last_vbus = (data->vbus_stat & 1U) != 0U; - ret = reg_read(dev, VBUS_BASE, VBUS_OFFSET_STATUS, &data->vbus_stat); - if (ret != 0) { - return ret; - } - - if (!last_vbus && ((data->vbus_stat & 1U) != 0U)) { - ret = reg_write(dev, VBUS_BASE, VBUS_OFFSET_TASK_UPDATE, 1U); - - if (ret != 0) { - return ret; - } - } - - return ret; -} - -int npm1300_charger_init(const struct device *dev) -{ - const struct npm1300_charger_config *const config = dev->config; - uint16_t idx; - int ret; - - if (!i2c_is_ready_dt(&config->i2c)) { - return -ENODEV; - } - - /* Configure thermistor */ - ret = reg_write(dev, ADC_BASE, ADC_OFFSET_NTCR_SEL, config->thermistor_idx + 1U); - if (ret != 0) { - return ret; - } - - /* Configure termination voltages */ - ret = linear_range_group_get_win_index(charger_volt_ranges, ARRAY_SIZE(charger_volt_ranges), - config->term_microvolt, config->term_microvolt, - &idx); - if (ret == -EINVAL) { - return ret; - } - ret = reg_write(dev, CHGR_BASE, CHGR_OFFSET_VTERM, idx); - if (ret != 0) { - return ret; - } - - ret = linear_range_group_get_win_index(charger_volt_ranges, ARRAY_SIZE(charger_volt_ranges), - config->term_warm_microvolt, - config->term_warm_microvolt, &idx); - if (ret == -EINVAL) { - return ret; - } - - ret = reg_write(dev, CHGR_BASE, CHGR_OFFSET_VTERM_R, idx); - if (ret != 0) { - return ret; - } - - /* Set current, allow rounding down to closest value */ - ret = linear_range_get_win_index(&charger_current_range, - config->current_microamp - charger_current_range.step, - config->current_microamp, &idx); - if (ret == -EINVAL) { - return ret; - } - - ret = reg_write2(dev, CHGR_BASE, CHGR_OFFSET_ISET, idx / 2U, idx & 1U); - if (ret != 0) { - return ret; - } - - /* Set discharge limit, allow rounding down to closest value */ - ret = linear_range_get_win_index(&discharge_limit_range, - config->dischg_limit_microamp - discharge_limit_range.step, - config->dischg_limit_microamp, &idx); - if (ret == -EINVAL) { - return ret; - } - - ret = reg_write2(dev, CHGR_BASE, CHGR_OFFSET_ISET_DISCHG, idx / 2U, idx & 1U); - if (ret != 0) { - return ret; - } - - /* Configure vbus current limit */ - ret = linear_range_group_get_win_index(vbus_current_ranges, ARRAY_SIZE(vbus_current_ranges), - config->vbus_limit_microamp, - config->vbus_limit_microamp, &idx); - if (ret == -EINVAL) { - return ret; - } - ret = reg_write(dev, VBUS_BASE, VBUS_OFFSET_ILIM, idx); - if (ret != 0) { - return ret; - } - - /* Enable current measurement */ - ret = reg_write(dev, ADC_BASE, ADC_OFFSET_IBAT_EN, 1U); - if (ret != 0) { - return ret; - } - - /* Trigger current and voltage measurement */ - ret = reg_write(dev, ADC_BASE, ADC_OFFSET_TASK_VBAT, 1U); - if (ret != 0) { - return ret; - } - - /* Trigger temperature measurement */ - ret = reg_write(dev, ADC_BASE, ADC_OFFSET_TASK_TEMP, 1U); - if (ret != 0) { - return ret; - } - - /* Enable charging if configured */ - if (config->charging_enable) { - ret = reg_write(dev, CHGR_BASE, CHGR_OFFSET_EN_SET, 1U); - if (ret != 0) { - return ret; - } - } - - return 0; -} - -static const struct sensor_driver_api npm1300_charger_battery_driver_api = { - .sample_fetch = npm1300_charger_sample_fetch, - .channel_get = npm1300_charger_channel_get, -}; - -#define NPM1300_CHARGER_INIT(n) \ - static struct npm1300_charger_data npm1300_charger_data_##n; \ - \ - static const struct npm1300_charger_config npm1300_charger_config_##n = { \ - .i2c = I2C_DT_SPEC_GET(DT_INST_PARENT(n)), \ - .term_microvolt = DT_INST_PROP(n, term_microvolt), \ - .term_warm_microvolt = \ - DT_INST_PROP_OR(n, term_warm_microvolt, DT_INST_PROP(n, term_microvolt)), \ - .current_microamp = DT_INST_PROP(n, current_microamp), \ - .dischg_limit_microamp = DT_INST_PROP(n, dischg_limit_microamp), \ - .vbus_limit_microamp = DT_INST_PROP(n, vbus_limit_microamp), \ - .thermistor_idx = DT_INST_ENUM_IDX(n, thermistor_ohms), \ - .thermistor_beta = DT_INST_PROP(n, thermistor_beta), \ - .charging_enable = DT_INST_PROP(n, charging_enable), \ - }; \ - \ - SENSOR_DEVICE_DT_INST_DEFINE(n, &npm1300_charger_init, NULL, &npm1300_charger_data_##n, \ - &npm1300_charger_config_##n, POST_KERNEL, \ - CONFIG_SENSOR_INIT_PRIORITY, \ - &npm1300_charger_battery_driver_api); - -DT_INST_FOREACH_STATUS_OKAY(NPM1300_CHARGER_INIT) diff --git a/dts/bindings/sensor/nordic,npm1300-charger.yaml b/dts/bindings/sensor/nordic,npm1300-charger.yaml deleted file mode 100644 index 86a22b7a3b5d..000000000000 --- a/dts/bindings/sensor/nordic,npm1300-charger.yaml +++ /dev/null @@ -1,68 +0,0 @@ -# -# Copyright (c) 2023 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: Apache-2.0 -# - -description: NPM1300 PMIC Charger - -compatible: "nordic,npm1300-charger" - -include: [sensor-device.yaml] - -properties: - term-microvolt: - type: int - required: true - description: | - Charge termination voltage in uV. - Available range is 3.5 V to 3.65 V and 4.0 V to 4.45 V in 50 mV steps. - - term-warm-microvolt: - type: int - description: | - Charge termination voltage when warm in uV. - Available range is 3.5 V to 3.65 V and 4.0 V to 4.45 V in 50 mV steps. - If omitted, the term-microvolt value will be used. - - current-microamp: - type: int - required: true - description: | - Charge current in uA. - Available range is 32 mA to 800 mA in 2mA steps. - The value specified will be rounded down to the closest implemented value. - - dischg-limit-microamp: - type: int - required: true - description: | - Discharge current limit in uA. - Available range is 270 mA to 1340 mA in 3.23 mA steps. - The value specified will be rounded down to the closest implemented value. - - vbus-limit-microamp: - type: int - description: | - Vbus current limit in uA. - Available values are 100 mA, or between 500 mA and 1500 mA in 100 mA steps. - If omitted, the default value of 100 mA will be used. - - thermistor-ohms: - type: int - required: true - enum: - - 10000 - - 47000 - - 100000 - description: Thermistor nominal resistance type in ohms. - - thermistor-beta: - type: int - required: true - description: Beta value of selected thermistor. - - charging-enable: - type: boolean - description: | - Enable charging. diff --git a/include/zephyr/drivers/sensor/npm1300_charger.h b/include/zephyr/drivers/sensor/npm1300_charger.h deleted file mode 100644 index eb13f959a466..000000000000 --- a/include/zephyr/drivers/sensor/npm1300_charger.h +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DRIVERS_SENSOR_NPM1300_CHARGER_H_ -#define ZEPHYR_INCLUDE_DRIVERS_SENSOR_NPM1300_CHARGER_H_ - -#include - -/* NPM1300 charger specific channels */ -enum sensor_channel_npm1300_charger { - SENSOR_CHAN_NPM1300_CHARGER_STATUS = SENSOR_CHAN_PRIV_START, - SENSOR_CHAN_NPM1300_CHARGER_ERROR, -}; - -#endif From 1e1a1f56f2b7020b93a82ae572cbd2aab3a59de3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:26 +0200 Subject: [PATCH 262/528] Revert "[nrf fromtree] Bluetooth: Mesh: Remove outdated RPL entries in settings work item" This reverts commit dab6fbfc28872a36326b9d83f6af032b4a8444d9. Signed-off-by: Robert Lubos --- subsys/bluetooth/mesh/rpl.c | 156 +++++++++++------------------------- 1 file changed, 49 insertions(+), 107 deletions(-) diff --git a/subsys/bluetooth/mesh/rpl.c b/subsys/bluetooth/mesh/rpl.c index 717bd11242f1..d055f278e4fc 100644 --- a/subsys/bluetooth/mesh/rpl.c +++ b/subsys/bluetooth/mesh/rpl.c @@ -37,12 +37,7 @@ struct rpl_val { static struct bt_mesh_rpl replay_list[CONFIG_BT_MESH_CRPL]; static ATOMIC_DEFINE(store, CONFIG_BT_MESH_CRPL); - -enum { - PENDING_CLEAR, - PENDING_RESET, -}; -static atomic_t rpl_flags; +static atomic_t clear; static inline int rpl_idx(const struct bt_mesh_rpl *rpl) { @@ -58,8 +53,6 @@ static void clear_rpl(struct bt_mesh_rpl *rpl) return; } - atomic_clear_bit(store, rpl_idx(rpl)); - snprintk(path, sizeof(path), "bt/mesh/RPL/%x", rpl->src); err = settings_delete(path); if (err) { @@ -67,6 +60,9 @@ static void clear_rpl(struct bt_mesh_rpl *rpl) } else { LOG_DBG("Cleared RPL"); } + + (void)memset(rpl, 0, sizeof(*rpl)); + atomic_clear_bit(store, rpl_idx(rpl)); } static void schedule_rpl_store(struct bt_mesh_rpl *entry, bool force) @@ -109,7 +105,6 @@ void bt_mesh_rpl_update(struct bt_mesh_rpl *rpl, bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, struct bt_mesh_rpl **match) { - struct bt_mesh_rpl *rpl; int i; /* Don't bother checking messages from ourselves */ @@ -123,33 +118,34 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, } for (i = 0; i < ARRAY_SIZE(replay_list); i++) { - rpl = &replay_list[i]; + struct bt_mesh_rpl *rpl = &replay_list[i]; /* Empty slot */ if (!rpl->src) { - goto match; + if (match) { + *match = rpl; + } else { + bt_mesh_rpl_update(rpl, rx); + } + + return false; } /* Existing slot for given address */ if (rpl->src == rx->ctx.addr) { - if (!rpl->old_iv && - atomic_test_bit(&rpl_flags, PENDING_RESET) && - !atomic_test_bit(store, i)) { - /* Until rpl reset is finished, entry with old_iv == false and - * without "store" bit set will be removed, therefore it can be - * reused. If such entry is reused, "store" bit will be set and - * the entry won't be removed. - */ - goto match; - } - if (rx->old_iv && !rpl->old_iv) { return true; } if ((!rx->old_iv && rpl->old_iv) || rpl->seq < rx->seq) { - goto match; + if (match) { + *match = rpl; + } else { + bt_mesh_rpl_update(rpl, rx); + } + + return false; } else { return true; } @@ -158,15 +154,6 @@ bool bt_mesh_rpl_check(struct bt_mesh_net_rx *rx, LOG_ERR("RPL is full!"); return true; - -match: - if (match) { - *match = rpl; - } else { - bt_mesh_rpl_update(rpl, rx); - } - - return false; } void bt_mesh_rpl_clear(void) @@ -178,7 +165,7 @@ void bt_mesh_rpl_clear(void) return; } - atomic_set_bit(&rpl_flags, PENDING_CLEAR); + (void)atomic_cas(&clear, 0, 1); bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); } @@ -212,56 +199,41 @@ static struct bt_mesh_rpl *bt_mesh_rpl_alloc(uint16_t src) void bt_mesh_rpl_reset(void) { + int shift = 0; + int last = 0; + /* Discard "old old" IV Index entries from RPL and flag * any other ones (which are valid) as old. */ - if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - int i; - - for (i = 0; i < ARRAY_SIZE(replay_list); i++) { - struct bt_mesh_rpl *rpl = &replay_list[i]; - - if (!rpl->src) { - continue; - } - - /* Entries with "store" bit set will be stored, other entries will be - * removed. - */ - atomic_set_bit_to(store, i, !rpl->old_iv); - rpl->old_iv = !rpl->old_iv; - } - - if (i != 0) { - atomic_set_bit(&rpl_flags, PENDING_RESET); - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_RPL_PENDING); - } - } else { - int shift = 0; - int last = 0; - - for (int i = 0; i < ARRAY_SIZE(replay_list); i++) { - struct bt_mesh_rpl *rpl = &replay_list[i]; + for (int i = 0; i < ARRAY_SIZE(replay_list); i++) { + struct bt_mesh_rpl *rpl = &replay_list[i]; - if (rpl->src) { - if (rpl->old_iv) { + if (rpl->src) { + if (rpl->old_iv) { + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + clear_rpl(rpl); + } else { (void)memset(rpl, 0, sizeof(*rpl)); + } - shift++; - } else { - rpl->old_iv = true; + shift++; + } else { + rpl->old_iv = true; - if (shift > 0) { - replay_list[i - shift] = *rpl; - } + if (shift > 0) { + replay_list[i - shift] = *rpl; } - last = i; + if (IS_ENABLED(CONFIG_BT_SETTINGS)) { + schedule_rpl_store(&replay_list[i - shift], true); + } } - } - (void)memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift); + last = i; + } } + + (void) memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift); } static int rpl_set(const char *name, size_t len_rd, @@ -343,10 +315,7 @@ static void store_rpl(struct bt_mesh_rpl *entry) void bt_mesh_rpl_pending_store(uint16_t addr) { - int shift = 0; - int last = 0; bool clr; - bool rst; if (!IS_ENABLED(CONFIG_BT_SETTINGS) || (!BT_MESH_ADDR_IS_UNICAST(addr) && @@ -358,49 +327,22 @@ void bt_mesh_rpl_pending_store(uint16_t addr) bt_mesh_settings_store_cancel(BT_MESH_SETTINGS_RPL_PENDING); } - clr = atomic_test_and_clear_bit(&rpl_flags, PENDING_CLEAR); - rst = atomic_test_bit(&rpl_flags, PENDING_RESET); + clr = atomic_cas(&clear, 1, 0); for (int i = 0; i < ARRAY_SIZE(replay_list); i++) { - struct bt_mesh_rpl *rpl = &replay_list[i]; - - if (addr != BT_MESH_ADDR_ALL_NODES && addr != rpl->src) { + if (addr != BT_MESH_ADDR_ALL_NODES && + addr != replay_list[i].src) { continue; } if (clr) { - clear_rpl(rpl); - shift++; - } else if (atomic_test_and_clear_bit(store, i)) { - if (shift > 0) { - replay_list[i - shift] = *rpl; - } - - store_rpl(&replay_list[i - shift]); - } else if (rst) { - clear_rpl(rpl); - - /* Check if this entry was re-used during removal. If so, shift it as well. - * Otherwise, increment shift counter. - */ - if (atomic_test_and_clear_bit(store, i)) { - replay_list[i - shift] = *rpl; - atomic_set_bit(store, i - shift); - } else { - shift++; - } + clear_rpl(&replay_list[i]); + } else if (atomic_test_and_clear_bit(store, rpl_idx(&replay_list[i]))) { + store_rpl(&replay_list[i]); } - last = i; - if (addr != BT_MESH_ADDR_ALL_NODES) { break; } } - - atomic_test_and_clear_bit(&rpl_flags, PENDING_RESET); - - if (addr == BT_MESH_ADDR_ALL_NODES) { - (void)memset(&replay_list[last - shift + 1], 0, sizeof(struct bt_mesh_rpl) * shift); - } } From 9dc861400cf5e6db72ba72bc1a8ad985c934f584 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:26 +0200 Subject: [PATCH 263/528] Revert "[nrf fromtree] Bluetooth: Mesh: Add API to store model's user data in settings work" This reverts commit dd149c1d2f95eff1f881c753f03947dded8680a5. Signed-off-by: Robert Lubos --- .../bluetooth/api/mesh/access.rst | 16 ------------- include/zephyr/bluetooth/mesh/access.h | 23 ------------------- subsys/bluetooth/mesh/access.c | 11 --------- subsys/bluetooth/mesh/access.h | 1 - 4 files changed, 51 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/access.rst b/doc/connectivity/bluetooth/api/mesh/access.rst index 37d5d6fddef8..06236f98cb67 100644 --- a/doc/connectivity/bluetooth/api/mesh/access.rst +++ b/doc/connectivity/bluetooth/api/mesh/access.rst @@ -149,22 +149,6 @@ storage. The model can retrieve the data by calling the ``read_cb`` passed as a parameter to the callback. See the :ref:`settings_api` module documentation for details. -When model data changes frequently, storing it on every change may lead to -increased wear of flash. To reduce the wear, the model can postpone storing of -data by calling :c:func:`bt_mesh_model_data_store_schedule`. The stack will -schedule a work item with delay defined by the -:kconfig:option:`CONFIG_BT_MESH_STORE_TIMEOUT` option. When the work item is -running, the stack will call the :c:member:`bt_mesh_model_cb.pending_store` -callback for every model that has requested storing of data. The model can -then call :c:func:`bt_mesh_model_data_store` to store the data. - -If :kconfig:option:`CONFIG_BT_MESH_SETTINGS_WORKQ` is enabled, the -:c:member:`bt_mesh_model_cb.pending_store` callback is called from a dedicated -thread. This allows the stack to process other incoming and outgoing messages -while model data is being stored. It is recommended to use this option and the -:c:func:`bt_mesh_model_data_store_schedule` function when large amount of data -needs to be stored. - API reference ************* diff --git a/include/zephyr/bluetooth/mesh/access.h b/include/zephyr/bluetooth/mesh/access.h index 75fa81c90893..80e3948f1eb4 100644 --- a/include/zephyr/bluetooth/mesh/access.h +++ b/include/zephyr/bluetooth/mesh/access.h @@ -662,16 +662,6 @@ struct bt_mesh_model_cb { * @param model Model this callback belongs to. */ void (*const reset)(struct bt_mesh_model *model); - - /** @brief Callback used to store pending model's user data. - * - * Triggered by @ref bt_mesh_model_data_store_schedule. - * - * To store the user data, call @ref bt_mesh_model_data_store. - * - * @param model Model this callback belongs to. - */ - void (*const pending_store)(struct bt_mesh_model *model); }; /** Vendor model ID */ @@ -852,19 +842,6 @@ int bt_mesh_model_data_store(struct bt_mesh_model *mod, bool vnd, const char *name, const void *data, size_t data_len); -/** @brief Schedule the model's user data store in persistent storage. - * - * This function triggers the @ref bt_mesh_model_cb.pending_store callback - * for the corresponding model after delay defined by - * @kconfig{CONFIG_BT_MESH_STORE_TIMEOUT}. - * - * The delay is global for all models. Once scheduled, the callback can - * not be re-scheduled until previous schedule completes. - * - * @param mod Mesh model. - */ -void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod); - /** @brief Let a model extend another. * * Mesh models may be extended to reuse their functionality, forming a more diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index d8ba60cbb46f..d009837c167c 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -1850,11 +1850,6 @@ static void store_pending_mod(struct bt_mesh_model *mod, mod->flags &= ~BT_MESH_MOD_PUB_PENDING; store_pending_mod_pub(mod, vnd); } - - if (mod->flags & BT_MESH_MOD_DATA_PENDING) { - mod->flags &= ~BT_MESH_MOD_DATA_PENDING; - mod->cb->pending_store(mod); - } } void bt_mesh_model_pending_store(void) @@ -2139,9 +2134,3 @@ void bt_mesh_model_settings_commit(void) { bt_mesh_model_foreach(commit_mod, NULL); } - -void bt_mesh_model_data_store_schedule(struct bt_mesh_model *mod) -{ - mod->flags |= BT_MESH_MOD_DATA_PENDING; - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_MOD_PENDING); -} diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 43ec18391600..86d7a2123440 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -17,7 +17,6 @@ enum { BT_MESH_MOD_PUB_PENDING = BIT(2), BT_MESH_MOD_EXTENDED = BIT(3), BT_MESH_MOD_DEVKEY_ONLY = BIT(4), - BT_MESH_MOD_DATA_PENDING = BIT(5), }; void bt_mesh_elem_register(struct bt_mesh_elem *elem, uint8_t count); From 4bd9ffa55f2eea1d4cafd8c2a93f85d241cc1ecd Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:26 +0200 Subject: [PATCH 264/528] Revert "[nrf fromtree] Bluetooth: Mesh: Use separate workq for storing mesh settings" This reverts commit d764834a58c487d26975b26353de6b176675fe00. Signed-off-by: Robert Lubos --- doc/connectivity/bluetooth/api/mesh/core.rst | 40 -------------------- subsys/bluetooth/mesh/Kconfig | 28 -------------- subsys/bluetooth/mesh/settings.c | 36 +----------------- 3 files changed, 2 insertions(+), 102 deletions(-) diff --git a/doc/connectivity/bluetooth/api/mesh/core.rst b/doc/connectivity/bluetooth/api/mesh/core.rst index e27f29a31350..c06ce3771e2d 100644 --- a/doc/connectivity/bluetooth/api/mesh/core.rst +++ b/doc/connectivity/bluetooth/api/mesh/core.rst @@ -67,46 +67,6 @@ vulnerability and flash wear out. the RPL between reboots, will make the device vulnerable to replay attacks and not perform the replay protection required by the spec. -Persistent storage -****************** - -The mesh stack uses the :ref:`Settings Subsystem ` for storing the -device configuration persistently. When the stack configuration changes and -the change needs to be stored persistently, the stack schedules a work item. -The delay between scheduling the work item and submitting it to the workqueue -is defined by the :kconfig:option:`CONFIG_BT_MESH_STORE_TIMEOUT` option. Once -storing of data is scheduled, it can not be rescheduled until the work item is -processed. Exceptions are made in certain cases as described below. - -When IV index, Sequence Number or CDB configuration have to be stored, the work -item is submitted to the workqueue without the delay. If the work item was -previously scheduled, it will be rescheduled without the delay. - -The Replay Protection List uses the same work item to store RPL entries. If -storing of RPL entries is requested and no other configuration is pending to be -stored, the delay is set to :kconfig:option:`CONFIG_BT_MESH_RPL_STORE_TIMEOUT`. -If other stack configuration has to be stored, the delay defined by -the :kconfig:option:`CONFIG_BT_MESH_STORE_TIMEOUT` option is less than -:kconfig:option:`CONFIG_BT_MESH_RPL_STORE_TIMEOUT`, and the work item was -scheduled by the Replay Protection List, the work item will be rescheduled. - -When the work item is running, the stack will store all pending configuration, -including the RPL entries. - -Work item execution context -=========================== - -The :kconfig:option:`CONFIG_BT_MESH_SETTINGS_WORKQ` option configures the -context from which the work item is executed. This option is enabled by -default, and results in stack using a dedicated cooperative thread to -process the work item. This allows the stack to process other incoming and -outgoing messages, as well as other work items submitted to the system -workqueue, while the stack configuration is being stored. - -When this option is disabled, the work item is submitted to the system workqueue. -This means that the system workqueue is blocked for the time it takes to store -the stack's configuration. It is not recommended to disable this option as this -will make the device non-responsive for a noticeable amount of time. API reference ************** diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 3957fd4e1f16..9ac042f464c7 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1584,34 +1584,6 @@ config BT_MESH_SEQ_STORE_RATE off with a value that's guaranteed to be larger than the last one used before power off. -config BT_MESH_SETTINGS_WORKQ - bool "Store the Bluetooth mesh settings in a separate work queue" - default y - help - This option enables a separate cooperative thread which is used to - store Bluetooth mesh configuration. When this option is disabled, - the stack's configuration is stored in the system workqueue. This - means that the system workqueue will be blocked for the time needed - to store the pending data. This time may significantly increase if - the flash driver does the erase operation. Enabling this option - allows Bluetooth mesh not to block the system workqueue, and thus - process the incoming and outgoing messages while the flash driver - waits for the controller to allocate the time needed to write the - data and/or erase the required flash pages. - -if BT_MESH_SETTINGS_WORKQ - -config BT_MESH_SETTINGS_WORKQ_PRIO - int - default 1 - -config BT_MESH_SETTINGS_WORKQ_STACK_SIZE - int "Stack size of the settings workq" - default 880 - help - Size of the settings workqueue stack. - -endif # BT_MESH_SETTINGS_WORKQ endif # BT_SETTINGS if BT_MESH_LOG_LEVEL_DBG diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 2c3ef3bc9022..56149cf70257 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -40,21 +40,6 @@ LOG_MODULE_REGISTER(bt_mesh_settings); #define RPL_STORE_TIMEOUT (-1) #endif -#ifdef CONFIG_BT_MESH_SETTINGS_WORKQ_PRIO -#define SETTINGS_WORKQ_PRIO CONFIG_BT_MESH_SETTINGS_WORKQ_PRIO -#else -#define SETTINGS_WORKQ_PRIO 1 -#endif - -#ifdef CONFIG_BT_MESH_SETTINGS_WORKQ_STACK_SIZE -#define SETTINGS_WORKQ_STACK_SIZE CONFIG_BT_MESH_SETTINGS_WORKQ_STACK_SIZE -#else -#define SETTINGS_WORKQ_STACK_SIZE 0 -#endif - -static struct k_work_q settings_work_q; -static K_THREAD_STACK_DEFINE(settings_work_stack, SETTINGS_WORKQ_STACK_SIZE); - static struct k_work_delayable pending_store; static ATOMIC_DEFINE(pending_flags, BT_MESH_SETTINGS_FLAG_COUNT); @@ -159,19 +144,9 @@ void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) * deadline. */ if (timeout_ms < remaining_ms) { - if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) { - k_work_reschedule_for_queue(&settings_work_q, &pending_store, - K_MSEC(timeout_ms)); - } else { - k_work_reschedule(&pending_store, K_MSEC(timeout_ms)); - } + k_work_reschedule(&pending_store, K_MSEC(timeout_ms)); } else { - if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) { - k_work_schedule_for_queue(&settings_work_q, &pending_store, - K_MSEC(timeout_ms)); - } else { - k_work_schedule(&pending_store, K_MSEC(timeout_ms)); - } + k_work_schedule(&pending_store, K_MSEC(timeout_ms)); } } @@ -265,13 +240,6 @@ static void store_pending(struct k_work *work) void bt_mesh_settings_init(void) { - if (IS_ENABLED(CONFIG_BT_MESH_SETTINGS_WORKQ)) { - k_work_queue_start(&settings_work_q, settings_work_stack, - K_THREAD_STACK_SIZEOF(settings_work_stack), - K_PRIO_COOP(SETTINGS_WORKQ_PRIO), NULL); - k_thread_name_set(&settings_work_q.thread, "BT Mesh settings workq"); - } - k_work_init_delayable(&pending_store, store_pending); } From 722e7c5e1e892cc9987488411fa073e26190b0f9 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:26 +0200 Subject: [PATCH 265/528] Revert "[nrf fromtree] Bluetooth: Mesh: Store device key candidate asynchronously" This reverts commit 585a48b38c1276522ac91628e819daf6faf332d5. Signed-off-by: Robert Lubos --- subsys/bluetooth/mesh/net.c | 11 ++--------- subsys/bluetooth/mesh/net.h | 2 -- subsys/bluetooth/mesh/settings.c | 8 +------- subsys/bluetooth/mesh/settings.h | 1 - 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index 11412112ea43..c60e1df758c0 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -1066,11 +1066,9 @@ static int dev_key_cand_set(const char *name, size_t len_rd, settings_read_cb re } BT_MESH_SETTINGS_DEFINE(dev_key, "DevKeyC", dev_key_cand_set); -#endif -void bt_mesh_net_pending_dev_key_cand_store(void) +void bt_mesh_net_dev_key_cand_store(void) { -#if defined(CONFIG_BT_MESH_RPR_SRV) int err; if (atomic_test_bit(bt_mesh.flags, BT_MESH_DEVKEY_CAND)) { @@ -1084,13 +1082,8 @@ void bt_mesh_net_pending_dev_key_cand_store(void) } else { LOG_DBG("Stored DevKey candidate value"); } -#endif -} - -void bt_mesh_net_dev_key_cand_store(void) -{ - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING); } +#endif static void clear_iv(void) { diff --git a/subsys/bluetooth/mesh/net.h b/subsys/bluetooth/mesh/net.h index 84f5c8998e91..02286b1ae403 100644 --- a/subsys/bluetooth/mesh/net.h +++ b/subsys/bluetooth/mesh/net.h @@ -311,8 +311,6 @@ void bt_mesh_net_header_parse(struct net_buf_simple *buf, void bt_mesh_net_pending_net_store(void); void bt_mesh_net_pending_iv_store(void); void bt_mesh_net_pending_seq_store(void); - -void bt_mesh_net_pending_dev_key_cand_store(void); void bt_mesh_net_dev_key_cand_store(void); void bt_mesh_net_store(void); diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 56149cf70257..89082264ea7a 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -116,8 +116,7 @@ SETTINGS_STATIC_HANDLER_DEFINE(bt_mesh, "bt/mesh", NULL, NULL, mesh_commit, BIT(BT_MESH_SETTINGS_MOD_PENDING) | \ BIT(BT_MESH_SETTINGS_VA_PENDING) | \ BIT(BT_MESH_SETTINGS_SSEQ_PENDING) | \ - BIT(BT_MESH_SETTINGS_COMP_PENDING) | \ - BIT(BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING)) + BIT(BT_MESH_SETTINGS_COMP_PENDING)) void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) { @@ -189,11 +188,6 @@ static void store_pending(struct k_work *work) bt_mesh_net_pending_seq_store(); } - if (atomic_test_and_clear_bit(pending_flags, - BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING)) { - bt_mesh_net_pending_dev_key_cand_store(); - } - if (atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_HB_PUB_PENDING)) { bt_mesh_hb_pub_pending_store(); diff --git a/subsys/bluetooth/mesh/settings.h b/subsys/bluetooth/mesh/settings.h index bd6db9c3cdc2..10ce23d1106f 100644 --- a/subsys/bluetooth/mesh/settings.h +++ b/subsys/bluetooth/mesh/settings.h @@ -20,7 +20,6 @@ enum bt_mesh_settings_flag { BT_MESH_SETTINGS_SRPL_PENDING, BT_MESH_SETTINGS_SSEQ_PENDING, BT_MESH_SETTINGS_COMP_PENDING, - BT_MESH_SETTINGS_DEV_KEY_CAND_PENDING, BT_MESH_SETTINGS_FLAG_COUNT, }; From 35e3fc05633268a773eba81bb37a8553a4350c66 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:26 +0200 Subject: [PATCH 266/528] Revert "[nrf fromtree] Bluetooth: Mesh: Move storing of new prov data to settings work item" This reverts commit 341b076ee35b1320726e8e3d67cec0a2171c5c1e. Signed-off-by: Robert Lubos --- subsys/bluetooth/mesh/access.c | 15 ++------------- subsys/bluetooth/mesh/access.h | 5 ++--- subsys/bluetooth/mesh/main.c | 9 +++++---- subsys/bluetooth/mesh/net.c | 12 +++--------- subsys/bluetooth/mesh/net.h | 2 -- subsys/bluetooth/mesh/settings.c | 8 +------- subsys/bluetooth/mesh/settings.h | 1 - 7 files changed, 13 insertions(+), 39 deletions(-) diff --git a/subsys/bluetooth/mesh/access.c b/subsys/bluetooth/mesh/access.c index d009837c167c..30f1b9547671 100644 --- a/subsys/bluetooth/mesh/access.c +++ b/subsys/bluetooth/mesh/access.c @@ -1905,7 +1905,7 @@ int bt_mesh_comp_change_prepare(void) return bt_mesh_comp_store(); } -static void comp_data_clear(void) +void bt_mesh_comp_clear(void) { int err; @@ -2073,7 +2073,7 @@ int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset) } #endif -static void models_metadata_clear(void) +void bt_mesh_models_metadata_clear(void) { int err; @@ -2087,17 +2087,6 @@ static void models_metadata_clear(void) atomic_clear_bit(bt_mesh.flags, BT_MESH_METADATA_DIRTY); } -void bt_mesh_comp_data_pending_clear(void) -{ - comp_data_clear(); - models_metadata_clear(); -} - -void bt_mesh_comp_data_clear(void) -{ - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_COMP_PENDING); -} - int bt_mesh_models_metadata_change_prepare(void) { #if !IS_ENABLED(CONFIG_BT_MESH_LARGE_COMP_DATA_SRV) diff --git a/subsys/bluetooth/mesh/access.h b/subsys/bluetooth/mesh/access.h index 86d7a2123440..7c86de4282c4 100644 --- a/subsys/bluetooth/mesh/access.h +++ b/subsys/bluetooth/mesh/access.h @@ -62,14 +62,13 @@ int bt_mesh_model_recv(struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf); int bt_mesh_comp_register(const struct bt_mesh_comp *comp); int bt_mesh_comp_store(void); +void bt_mesh_comp_clear(void); int bt_mesh_comp_read(struct net_buf_simple *buf); int bt_mesh_models_metadata_store(void); +void bt_mesh_models_metadata_clear(void); int bt_mesh_models_metadata_read(struct net_buf_simple *buf, size_t offset); -void bt_mesh_comp_data_pending_clear(void); -void bt_mesh_comp_data_clear(void); - void bt_mesh_model_pending_store(void); void bt_mesh_model_bind_store(struct bt_mesh_model *mod); void bt_mesh_model_sub_store(struct bt_mesh_model *mod); diff --git a/subsys/bluetooth/mesh/main.c b/subsys/bluetooth/mesh/main.c index 099ed2891123..25de16bf1047 100644 --- a/subsys/bluetooth/mesh/main.c +++ b/subsys/bluetooth/mesh/main.c @@ -130,7 +130,7 @@ int bt_mesh_provision(const uint8_t net_key[16], uint16_t net_idx, } if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_net_store(); + bt_mesh_net_pending_net_store(); } bt_mesh_start(); @@ -159,9 +159,10 @@ void bt_mesh_reprovision(uint16_t addr) if (IS_ENABLED(CONFIG_BT_SETTINGS)) { LOG_DBG("Storing network information persistently"); - bt_mesh_net_store(); - bt_mesh_net_seq_store(true); - bt_mesh_comp_data_clear(); + bt_mesh_net_pending_net_store(); + bt_mesh_net_pending_seq_store(); + bt_mesh_comp_clear(); + bt_mesh_models_metadata_clear(); } } diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index c60e1df758c0..88f91a1ac835 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -189,10 +189,9 @@ static void store_iv(bool only_duration) } } -void bt_mesh_net_seq_store(bool force) +static void store_seq(void) { - if (!force && - CONFIG_BT_MESH_SEQ_STORE_RATE > 1 && + if (CONFIG_BT_MESH_SEQ_STORE_RATE > 1 && (bt_mesh.seq % CONFIG_BT_MESH_SEQ_STORE_RATE)) { return; } @@ -380,7 +379,7 @@ uint32_t bt_mesh_next_seq(void) uint32_t seq = bt_mesh.seq++; if (IS_ENABLED(CONFIG_BT_SETTINGS)) { - bt_mesh_net_seq_store(false); + store_seq(); } if (!atomic_test_bit(bt_mesh.flags, BT_MESH_IVU_IN_PROGRESS) && @@ -1186,11 +1185,6 @@ void bt_mesh_net_pending_seq_store(void) } } -void bt_mesh_net_store(void) -{ - bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING); -} - void bt_mesh_net_clear(void) { bt_mesh_settings_store_schedule(BT_MESH_SETTINGS_NET_PENDING); diff --git a/subsys/bluetooth/mesh/net.h b/subsys/bluetooth/mesh/net.h index 02286b1ae403..2d9309a0ff7d 100644 --- a/subsys/bluetooth/mesh/net.h +++ b/subsys/bluetooth/mesh/net.h @@ -303,7 +303,6 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi, void bt_mesh_net_loopback_clear(uint16_t net_idx); uint32_t bt_mesh_next_seq(void); -void bt_mesh_net_seq_store(bool force); void bt_mesh_net_init(void); void bt_mesh_net_header_parse(struct net_buf_simple *buf, @@ -313,7 +312,6 @@ void bt_mesh_net_pending_iv_store(void); void bt_mesh_net_pending_seq_store(void); void bt_mesh_net_dev_key_cand_store(void); -void bt_mesh_net_store(void); void bt_mesh_net_clear(void); void bt_mesh_net_settings_commit(void); diff --git a/subsys/bluetooth/mesh/settings.c b/subsys/bluetooth/mesh/settings.c index 89082264ea7a..7413407681e3 100644 --- a/subsys/bluetooth/mesh/settings.c +++ b/subsys/bluetooth/mesh/settings.c @@ -115,8 +115,7 @@ SETTINGS_STATIC_HANDLER_DEFINE(bt_mesh, "bt/mesh", NULL, NULL, mesh_commit, BIT(BT_MESH_SETTINGS_CFG_PENDING) | \ BIT(BT_MESH_SETTINGS_MOD_PENDING) | \ BIT(BT_MESH_SETTINGS_VA_PENDING) | \ - BIT(BT_MESH_SETTINGS_SSEQ_PENDING) | \ - BIT(BT_MESH_SETTINGS_COMP_PENDING)) + BIT(BT_MESH_SETTINGS_SSEQ_PENDING)) void bt_mesh_settings_store_schedule(enum bt_mesh_settings_flag flag) { @@ -198,11 +197,6 @@ static void store_pending(struct k_work *work) bt_mesh_cfg_pending_store(); } - if (atomic_test_and_clear_bit(pending_flags, - BT_MESH_SETTINGS_COMP_PENDING)) { - bt_mesh_comp_data_pending_clear(); - } - if (atomic_test_and_clear_bit(pending_flags, BT_MESH_SETTINGS_MOD_PENDING)) { bt_mesh_model_pending_store(); diff --git a/subsys/bluetooth/mesh/settings.h b/subsys/bluetooth/mesh/settings.h index 10ce23d1106f..ac019e2e60e8 100644 --- a/subsys/bluetooth/mesh/settings.h +++ b/subsys/bluetooth/mesh/settings.h @@ -19,7 +19,6 @@ enum bt_mesh_settings_flag { BT_MESH_SETTINGS_CDB_PENDING, BT_MESH_SETTINGS_SRPL_PENDING, BT_MESH_SETTINGS_SSEQ_PENDING, - BT_MESH_SETTINGS_COMP_PENDING, BT_MESH_SETTINGS_FLAG_COUNT, }; From b8cd0c8c1f56fa2de80c22c43daf0c2c9245ddad Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:26 +0200 Subject: [PATCH 267/528] Revert "[nrf fromtree] doc: Bluetooth: Mesh: update proxy solicitation docs" This reverts commit 428fefd2e794190560dc526d44d8f6173f2ccdb6. Signed-off-by: Robert Lubos --- .../bluetooth/api/mesh/models.rst | 6 +-- doc/connectivity/bluetooth/api/mesh/od.rst | 14 ++++++ .../bluetooth/api/mesh/od_cli.rst | 18 +------- .../bluetooth/api/mesh/od_srv.rst | 17 +------ doc/connectivity/bluetooth/api/mesh/proxy.rst | 46 ------------------- doc/connectivity/bluetooth/api/mesh/shell.rst | 4 +- doc/connectivity/bluetooth/api/mesh/srpl.rst | 16 +++++++ .../bluetooth/api/mesh/srpl_cli.rst | 20 +------- .../bluetooth/api/mesh/srpl_srv.rst | 19 +------- subsys/bluetooth/mesh/Kconfig | 4 +- 10 files changed, 40 insertions(+), 124 deletions(-) create mode 100644 doc/connectivity/bluetooth/api/mesh/od.rst create mode 100644 doc/connectivity/bluetooth/api/mesh/srpl.rst diff --git a/doc/connectivity/bluetooth/api/mesh/models.rst b/doc/connectivity/bluetooth/api/mesh/models.rst index 5269790944cd..85453a788082 100644 --- a/doc/connectivity/bluetooth/api/mesh/models.rst +++ b/doc/connectivity/bluetooth/api/mesh/models.rst @@ -22,10 +22,8 @@ used by network administrators to configure and diagnose mesh nodes. op_agg_srv rpr_cli rpr_srv - od_cli - od_srv - srpl_cli - srpl_srv + srpl + od Model specification models ************************** diff --git a/doc/connectivity/bluetooth/api/mesh/od.rst b/doc/connectivity/bluetooth/api/mesh/od.rst new file mode 100644 index 000000000000..bece6d9a1a92 --- /dev/null +++ b/doc/connectivity/bluetooth/api/mesh/od.rst @@ -0,0 +1,14 @@ +.. _bluetooth_mesh_od: + +On-Demand Private GATT Proxy models +################################### + +On-Demand Private GATT Proxy state defines how long a node will advertise Mesh Proxy Service with Private Network Identity type after it receives Solicitation PDU. + +On-Demand Private GATT Proxy models are: + +.. toctree:: + :maxdepth: 1 + + od_srv + od_cli diff --git a/doc/connectivity/bluetooth/api/mesh/od_cli.rst b/doc/connectivity/bluetooth/api/mesh/od_cli.rst index ea2deae79b9f..dfdb6df234ef 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_cli.rst @@ -3,23 +3,7 @@ On-Demand Private Proxy Client ############################## -The On-Demand Private Proxy Client model is a foundation model defined by the Bluetooth -mesh specification. The model is optional, and is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` option. - -The On-Demand Private Proxy Client model was introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and is used to set and retrieve the On-Demand Private GATT Proxy state. The state defines -how long a node will advertise Mesh Proxy Service with Private Network Identity type after it receives a Solicitation PDU. - -The On-Demand Private Proxy Client model communicates with an On-Demand Private Proxy Server model -using the device key of the node containing the target On-Demand Private Proxy Server model instance. - -Configurations -************** - -The On-Demand Private Proxy Client model behavior can be configured with the transmission timeout option :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT`. -The :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT`controls how long the Client waits for a state response message to arrive -in milliseconds. This value can be changed at runtime using :c:func:`bt_mesh_od_priv_proxy_cli_timeout_set`. - +On-Demand Private Proxy Client model is used to set and retrieve the On-Demand Private GATT Proxy state, and to adjust message transmission timeout. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/od_srv.rst b/doc/connectivity/bluetooth/api/mesh/od_srv.rst index 241ce5f155cf..969100ed8118 100644 --- a/doc/connectivity/bluetooth/api/mesh/od_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/od_srv.rst @@ -3,22 +3,7 @@ On-Demand Private Proxy Server ############################## -The On-Demand Private Proxy Server model is a foundation model defined by the Bluetooth -mesh specification. It is enabled with the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_SRV` option. - -The On-Demand Private Proxy Server model was introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and supports the configuration of advertising with Private Network Identity type of a node -that is a recipient of Solicitation PDUs by managing its On-Demand Private GATT Proxy state. - -When enabled, the :ref:`bluetooth_mesh_srpl_srv` is also enabled. The On-Demand Private Proxy Server is dependent on the -:ref:`bluetooth_mesh_models_priv_beacon_srv` to be present on the node. - -The On-Demand Private Proxy Server does not have an API of its own, and relies on a -:ref:`bluetooth_mesh_od_cli` to control it. The On-Demand Private Proxy Server -model only accepts messages encrypted with the node's device key. - -If present, the On-Demand Private Proxy Server model must be instantiated on the primary -element. +On-Demand Private Proxy Server manages the On-Demand Private GATT Proxy state of the node that is a recipient of Solicitation PDUs. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/proxy.rst b/doc/connectivity/bluetooth/api/mesh/proxy.rst index 87ee3b07f1d7..9c004909eb5b 100644 --- a/doc/connectivity/bluetooth/api/mesh/proxy.rst +++ b/doc/connectivity/bluetooth/api/mesh/proxy.rst @@ -9,52 +9,6 @@ mesh network through GATT. The Proxy feature is only compiled in if the controlled by the :ref:`bluetooth_mesh_models_cfg_srv`, and the initial value can be set with :c:member:`bt_mesh_cfg_srv.gatt_proxy`. -Nodes with the Proxy feature enabled can advertise with Network Identity and Node Identity, -which is controlled by the :ref:`bluetooth_mesh_models_cfg_cli`. - -The GATT Proxy state indicates if the Proxy feature is supported. - -Private Proxy -************* - -A node supporting the Proxy feature and the :ref:`bluetooth_mesh_models_priv_beacon_srv` model can advertise with -Private Network Identity and Private Node Identity types, which is controlled by the -:ref:`bluetooth_mesh_models_priv_beacon_cli`. By advertising with this set of identification types, -the node allows the legacy device to connect to the network over GATT while maintaining the -privacy of the network. - -The Private GATT Proxy state indicates whether the Private Proxy functionality is supported. - -Proxy Solicitation -****************** - -In the case where both GATT Proxy and Private GATT Proxy states are disabled on a node, a legacy device cannot -connect to it. A node supporting the :ref:`bluetooth_mesh_od_srv` may however be -solicited to advertise connectable advertising events without enabling the Private GATT Proxy state. -To solicit the node, the legacy device can send a Solicitation PDU by calling the :func:`bt_mesh_proxy_solicit` function. -To enable this feature, the client must to be compiled with the :kconfig:option:`CONFIG_BT_MESH_PROXY_SOLICITATION` -option set. - -Solicitation PDUs are non-mesh, non-connectable, undirected advertising messages -containing Proxy Solicitation UUID, encrypted with the network key of the subnet that the legacy device -wants to connect to. The PDU contains the source address of the legacy device and a sequence number. The -sequence number is maintained by the legacy device and is incremented for every new Solicitation PDU sent. - -Each node supporting the Solicitation PDU reception holds its own Solicitation Replay Protection List (SRPL). -The SRPL protects the solicitation mechanism from replay attacks by storing solicitation sequence number (SSEQ) -and solicitation source (SSRC) pairs of valid Solicitation PDUs processed by the node. The delay between updating the -SRPL and storing the change to the persistent storage is defined by :kconfig:option:`CONFIG_BT_MESH_RPL_STORE_TIMEOUT`. - -The Solicitation PDU RPL Configuration models, :ref:`bluetooth_mesh_srpl_cli` and -:ref:`bluetooth_mesh_srpl_srv`, provide the functionality of saving and clearing SRPL entries. -A node that supports the Solicitation PDU RPL Configuration Client model can clear a section of the SRPL on the target by calling the :func:`bt_mesh_sol_pdu_rpl_clear` function. -Communication between the Solicitation PDU RPL Configuration Client and Server is encrypted using the application key, therefore, -the Solicitation PDU RPL Configuration Client can be instantiated on any device in the network. - -When the node receives the Solicitation PDU and successfully authenticates it, it will start -advertising connectable advertisements with the Private Network Identity type. The duration of the -advertisement can be configured by the On-Demand Private Proxy Client model. - API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index 7a3f2e1b291e..e1d1ec0f31d1 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -1669,7 +1669,7 @@ The On-Demand Private GATT Proxy Client model is an optional mesh subsystem that ``mesh models od_priv_proxy od-priv-gatt-proxy [Dur(s)]`` --------------------------------------------------------- - Set the On-Demand Private GATT Proxy state on active target, or fetch the value of this state from it. + Set the On-Demand Private GATT Proxy state on active target, or fetch the value of this state from it. This feature can be enabled through the :kconfig:option:`CONFIG_BT_MESH_OD_PRIV_PROXY_CLI` configuration option. * ``Dur``: If given, set the state of On-Demand Private GATT Proxy to this value in seconds. Fetch this value otherwise. @@ -1682,7 +1682,7 @@ The Solicitation PDU RPL Client model is an optional mesh subsystem that can be ``mesh models sol_pdu_rpl sol-pdu-rpl-clear [RngLen]`` ------------------------------------------------------------------------ - Clear active target's solicitation replay protection list (SRPL) in given range of solicitation source (SSRC) addresses. + Clear active target's solicitation replay protection list (SRPL) in given range of solicitation source (SSRC) addresses. This feature can be enabled through the :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI` configuration option. * ``RngStart``: Start address of the SSRC range. * ``Ackd``: This argument decides on whether an acknowledged or unacknowledged message will be sent. diff --git a/doc/connectivity/bluetooth/api/mesh/srpl.rst b/doc/connectivity/bluetooth/api/mesh/srpl.rst new file mode 100644 index 000000000000..6d4a12aea77e --- /dev/null +++ b/doc/connectivity/bluetooth/api/mesh/srpl.rst @@ -0,0 +1,16 @@ +.. _bluetooth_mesh_srpl: + +Solicitation PDU RPL Configuration models +######################################### + +Solicitation PDU RPL Configuration models provide functionality for saving and clearing the solicitation replay protection list (SRPL). + +Solicitation RPL secures the solicitation mechanism from replay attacks by storing solicitation sequence number (SSEQ) and solicitation source (SSRC) pairs of valid Solicitation PDUs processed by a node. + +Solicitation PDU RPL Configuration models are: + +.. toctree:: + :maxdepth: 1 + + srpl_srv + srpl_cli diff --git a/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst b/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst index e940158dd2ef..bed85d381ce3 100644 --- a/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst +++ b/doc/connectivity/bluetooth/api/mesh/srpl_cli.rst @@ -3,25 +3,7 @@ Solicitation PDU RPL Configuration Client ######################################### -The Solicitation PDU RPL Configuration Client model is a foundation model defined by the Bluetooth -mesh specification. The model is optional, and is enabled through the :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI` option. - -The Solicitation PDU RPL Configuration Client model was introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and supports the functionality of removing addresses from the solicitation -replay protection list (SRPL) of a node that supports the :ref:`bluetooth_mesh_srpl_srv` model. - -The Solicitation PDU RPL Configuration Client model communicates with a Solicitation PDU RPL Configuration Server model -using the application keys configured by the Configuration Client. - -If present, the Solicitation PDU RPL Configuration Client model must be instantiated on the primary -element. - -Configurations -************** - -The Solicitation PDU RPL Configuration Client model behavior can be configured with the transmission timeout option :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT`. -The :kconfig:option:`CONFIG_BT_MESH_SOL_PDU_RPL_CLI_TIMEOUT` controls how long the Solicitation PDU RPL Configuration Client waits -for a response message to arrive in milliseconds. This value can be changed at runtime using :c:func:`bt_mesh_sol_pdu_rpl_cli_timeout_set`. +Solicitation PDU RPL Configuration Client model is used for clearing the solicitation replay protection list (SRPL) of a node that supports the Solicitation PDU RPL Configuration Server model. API reference ************* diff --git a/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst b/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst index a8c5379e3052..4d87f754fa92 100644 --- a/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst +++ b/doc/connectivity/bluetooth/api/mesh/srpl_srv.rst @@ -3,24 +3,7 @@ Solicitation PDU RPL Configuration Server ######################################### -The Solicitation PDU RPL Configuration Server model is a foundation model defined by the Bluetooth -mesh specification. The model is enabled if the node has the :ref:`bluetooth_mesh_od_srv` enabled. - -The Solicitation PDU RPL Configuration Server model was introduced in the Bluetooth Mesh Protocol -Specification version 1.1, and manages the Solicitation Replay Protection List (SRPL) saved on the device. -The SRPL is used to reject Solicitation PDUs that are already processed by a node. When a valid Solicitation PDU message is -successfully processed by a node, the SSRC field and SSEQ field of the message are stored in the node's SRPL. - -The Solicitation PDU RPL Configuration Server does not have an API of its own, and relies on a :ref:`bluetooth_mesh_srpl_cli` to control it. -The model only accepts messages encrypted with an application key as configured by the Configuration Client. - -If present, the Solicitation PDU RPL Configuration Server model must be instantiated on the primary -element. - -Configurations -************** - -For the Solicitation PDU RPL Configuration Server model, the :kconfig:option:`CONFIG_BT_MESH_PROXY_SRPL_SIZE` option can be configured to set the size of the SRPL. +Solicitation PDU RPL Configuration Server model manages the solicitation RPL saved on the device. API reference ************* diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 9ac042f464c7..2c1ffb241c6e 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1354,9 +1354,9 @@ config BT_MESH_OD_PRIV_PROXY_CLI_TIMEOUT default 5000 depends on BT_MESH_OD_PRIV_PROXY_CLI help - This timeout controls how long the On-Demand Private Proxy Client waits + This timeout controls how long the Solicitation PDU RPL Configuration Client waits for a response message to arrive. This value can be changed at runtime - using @ref bt_mesh_od_priv_proxy_cli_timeout_set. + using @ref bt_mesh_sol_pdu_rpl_cli_timeout_set. config BT_MESH_OD_PRIV_PROXY_SRV bool "Support for On-Demand Private Proxy Server model" From 1dff36324f1dc58e77d47ae27cef1055c66b976c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:27 +0200 Subject: [PATCH 268/528] Revert "[nrf fromtree] Bluetooth: Mesh: Add callback for received beacons" This reverts commit 134a065cff348e851c083911edf4b6d79e765145. Signed-off-by: Robert Lubos --- include/zephyr/bluetooth/mesh/main.h | 67 ------------------- .../zephyr/linker/common-rom/common-rom-bt.ld | 4 -- subsys/bluetooth/mesh/beacon.c | 30 --------- 3 files changed, 101 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/main.h b/include/zephyr/bluetooth/mesh/main.h index 00309b352f8c..5ac5447acea5 100644 --- a/include/zephyr/bluetooth/mesh/main.h +++ b/include/zephyr/bluetooth/mesh/main.h @@ -762,73 +762,6 @@ struct bt_mesh_friend_cb { static const STRUCT_SECTION_ITERABLE(bt_mesh_friend_cb, \ _CONCAT(bt_mesh_friend_cb_, \ _name)) -#if defined(CONFIG_BT_TESTING) -struct bt_mesh_snb { - /** Flags */ - uint8_t flags; - - /** Network ID */ - uint64_t net_id; - - /** IV Index */ - uint32_t iv_idx; - - /** Authentication Value */ - uint64_t auth_val; -}; - -#if defined(CONFIG_BT_MESH_V1d1) -struct bt_mesh_prb { - /** Random */ - uint8_t random[13]; - - /** Flags */ - uint8_t flags; - - /** IV Index */ - uint32_t iv_idx; - - /** Authentication tag */ - uint64_t auth_tag; -}; -#endif - -/** Beacon callback functions. */ -struct bt_mesh_beacon_cb { - /** @brief Secure Network Beacon received. - * - * This callback notifies the application that Secure Network Beacon - * was received. - * - * @param snb Structure describing received Secure Network Beacon - */ - void (*snb_received)(const struct bt_mesh_snb *snb); - -#if defined(CONFIG_BT_MESH_V1d1) - /** @brief Private Beacon received. - * - * This callback notifies the application that Private Beacon - * was received and successfully decrypted. - * - * @param prb Structure describing received Private Beacon - */ - void (*priv_received)(const struct bt_mesh_prb *prb); -#endif -}; - -/** - * @brief Register a callback structure for beacon events. - * - * Registers a callback structure that will be called whenever beacon advertisement - * is received. - * - * @param _name Name of callback structure. - */ -#define BT_MESH_BEACON_CB_DEFINE(_name) \ - static const STRUCT_SECTION_ITERABLE(bt_mesh_beacon_cb, \ - _CONCAT(bt_mesh_beacon_cb_, \ - _name)) -#endif /** @brief Terminate Friendship. * diff --git a/include/zephyr/linker/common-rom/common-rom-bt.ld b/include/zephyr/linker/common-rom/common-rom-bt.ld index ecd9ae05e3d2..1d6c55c0afe0 100644 --- a/include/zephyr/linker/common-rom/common-rom-bt.ld +++ b/include/zephyr/linker/common-rom/common-rom-bt.ld @@ -17,10 +17,6 @@ ITERABLE_SECTION_ROM(bt_mesh_app_key_cb, 4) ITERABLE_SECTION_ROM(bt_mesh_hb_cb, 4) - -#if defined(CONFIG_BT_TESTING) - ITERABLE_SECTION_ROM(bt_mesh_beacon_cb, 4) -#endif #endif #if defined(CONFIG_BT_MESH_FRIEND) diff --git a/subsys/bluetooth/mesh/beacon.c b/subsys/bluetooth/mesh/beacon.c index fc4f6e491bcd..bdcb18f1a27c 100644 --- a/subsys/bluetooth/mesh/beacon.c +++ b/subsys/bluetooth/mesh/beacon.c @@ -501,21 +501,6 @@ static bool secure_beacon_authenticate(struct bt_mesh_subnet *sub, void *cb_data for (int i = 0; i < ARRAY_SIZE(sub->keys); i++) { if (sub->keys[i].valid && auth_match(&sub->keys[i], params)) { params->new_key = (i > 0); -#if defined(CONFIG_BT_TESTING) - struct bt_mesh_snb beacon_info; - - beacon_info.flags = params->flags; - memcpy(&beacon_info.net_id, params->net_id, 8); - beacon_info.iv_idx = params->iv_index; - memcpy(&beacon_info.auth_val, params->auth, 8); - - STRUCT_SECTION_FOREACH(bt_mesh_beacon_cb, cb) { - if (cb->snb_received) { - cb->snb_received(&beacon_info); - } - } -#endif - return true; } } @@ -541,21 +526,6 @@ static bool priv_beacon_decrypt(struct bt_mesh_subnet *sub, void *cb_data) params->new_key = (i > 0); params->flags = out[0]; params->iv_index = sys_get_be32(&out[1]); - -#if defined(CONFIG_BT_TESTING) - struct bt_mesh_prb beacon_info; - - memcpy(beacon_info.random, params->random, 13); - beacon_info.flags = params->flags; - beacon_info.iv_idx = params->iv_index; - memcpy(&beacon_info.auth_tag, params->auth, 8); - - STRUCT_SECTION_FOREACH(bt_mesh_beacon_cb, cb) { - if (cb->priv_received) { - cb->priv_received(&beacon_info); - } - } -#endif return true; } } From 2fcb25b16ea1c24c507e14626a1622e5cb4e31d8 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:27 +0200 Subject: [PATCH 269/528] Revert "[nrf fromtree] Bluetooth: Mesh: Add async API for Large Comp Data Client" This reverts commit 57d4f110f34acec2be279453a08c40a7e9d75412. Signed-off-by: Robert Lubos --- .../bluetooth/mesh/large_comp_data_cli.h | 103 ++------------ subsys/bluetooth/mesh/large_comp_data_cli.c | 133 +++++++++--------- subsys/bluetooth/mesh/shell/large_comp_data.c | 46 +++--- tests/bluetooth/mesh_shell/src/main.c | 6 +- tests/bsim/bluetooth/mesh/src/test_lcd.c | 82 +++++------ 5 files changed, 129 insertions(+), 241 deletions(-) diff --git a/include/zephyr/bluetooth/mesh/large_comp_data_cli.h b/include/zephyr/bluetooth/mesh/large_comp_data_cli.h index 40ee0316637e..ae23cda468f7 100644 --- a/include/zephyr/bluetooth/mesh/large_comp_data_cli.h +++ b/include/zephyr/bluetooth/mesh/large_comp_data_cli.h @@ -19,123 +19,44 @@ extern "C" { #endif -struct bt_mesh_large_comp_data_cli; - -/** Large Composition Data response. */ -struct bt_mesh_large_comp_data_rsp { - /** Page number. */ - uint8_t page; - /** Offset within the page. */ - uint16_t offset; - /** Total size of the page. */ - uint16_t total_size; - /** Pointer to allocated buffer for storing received data. */ - struct net_buf_simple *data; -}; - -/** Large Composition Data Status messages callbacks */ -struct bt_mesh_large_comp_data_cli_cb { - /** @brief Optional callback for Large Composition Data Status message. - * - * Handles received Large Composition Data Status messages from a Large Composition Data - * Server. - * - * If the content of @c rsp is needed after exiting this callback, a user should - * deep copy it. - * - * @param cli Large Composition Data Client context. - * @param addr Address of the sender. - * @param rsp Response received from the server. - */ - void (*large_comp_data_status)(struct bt_mesh_large_comp_data_cli *cli, uint16_t addr, - struct bt_mesh_large_comp_data_rsp *rsp); - - /** @brief Optional callback for Models Metadata Status message. - * - * Handles received Models Metadata Status messages from a Large Composition Data - * Server. - * - * If the content of @c rsp is needed after exiting this callback, a user should - * deep copy it. - * - * @param cli Large Composition Data Client context. - * @param addr Address of the sender. - * @param rsp Response received from the server. - */ - void (*models_metadata_status)(struct bt_mesh_large_comp_data_cli *cli, uint16_t addr, - struct bt_mesh_large_comp_data_rsp *rsp); -}; - -/** Large Composition Data Client model context */ -struct bt_mesh_large_comp_data_cli { - /** Model entry pointer. */ - struct bt_mesh_model *model; - - /** Internal parameters for tracking message responses. */ - struct bt_mesh_msg_ack_ctx ack_ctx; - - /** Optional callback for Large Composition Data Status messages. */ - const struct bt_mesh_large_comp_data_cli_cb *cb; -}; - /** * - * @brief Large Composition Data Client model Composition Data entry. - * - * @param cli_data Pointer to a @ref bt_mesh_large_comp_data_cli instance. + * @brief Large Composition Data Client model composition data entry. */ -#define BT_MESH_MODEL_LARGE_COMP_DATA_CLI(cli_data) \ - BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_LARGE_COMP_DATA_CLI, \ - _bt_mesh_large_comp_data_cli_op, NULL, cli_data, \ +#define BT_MESH_MODEL_LARGE_COMP_DATA_CLI \ + BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_LARGE_COMP_DATA_CLI, \ + _bt_mesh_large_comp_data_cli_op, NULL, NULL, \ &_bt_mesh_large_comp_data_cli_cb) /** @brief Send Large Composition Data Get message. * - * This API is used to read a portion of a Composition Data Page. - * - * This API can be used asynchronously by setting @p rsp as NULL. This way, the - * method will not wait for a response and will return immediately after sending - * the command. - * - * When @c rsp is set, the user is responsible for providing a buffer for the - * Composition Data in @ref bt_mesh_large_comp_data_rsp::data. If a buffer is - * not provided, the metadata won't be copied. + * This API is used to read a portion of a page of the Composition Data. * * @param net_idx Network index to encrypt with. * @param addr Target node element address. - * @param page Composition Data Page to read. + * @param page Composition Data page to read. * @param offset Offset within the Composition Data Page. - * @param rsp Pointer to a struct storing the received response from - * the server, or NULL to not wait for a response. + * @param comp Output buffer for storing received Composition data. * * @return 0 on success, or (negative) error code on failure. */ int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, - size_t offset, struct bt_mesh_large_comp_data_rsp *rsp); + size_t offset, struct net_buf_simple *comp); /** @brief Send Models Metadata Get message. * - * This API is used to read a portion of a Models Metadata Page. - * - * This API can be used asynchronously by setting @p rsp as NULL. This way, the - * method will not wait for a response and will return immediately after sending - * the command. - * - * When @c rsp is set, a user is responsible for providing a buffer for - * metadata in @ref bt_mesh_large_comp_data_rsp::data. If a buffer is not - * provided, the metadata won't be copied. + * This API is used to read a portion of a page of the Models Metadata state. * * @param net_idx Network index to encrypt with. * @param addr Target node element address. - * @param page Models Metadata Page to read. + * @param page Models Metadata page to read. * @param offset Offset within the Models Metadata Page. - * @param rsp Pointer to a struct storing the received response from - * the server, or NULL to not wait for a response. + * @param metadata Output buffer for storing received Models Metadata. * * @return 0 on success, or (negative) error code on failure. */ int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, - size_t offset, struct bt_mesh_large_comp_data_rsp *rsp); + size_t offset, struct net_buf_simple *metadata); /** @cond INTERNAL_HIDDEN */ extern const struct bt_mesh_model_op _bt_mesh_large_comp_data_cli_op[]; diff --git a/subsys/bluetooth/mesh/large_comp_data_cli.c b/subsys/bluetooth/mesh/large_comp_data_cli.c index 614569d54ae6..47c8db5b1f52 100644 --- a/subsys/bluetooth/mesh/large_comp_data_cli.c +++ b/subsys/bluetooth/mesh/large_comp_data_cli.c @@ -30,68 +30,63 @@ LOG_MODULE_REGISTER(bt_mesh_large_comp_data_cli); #include "access.h" #include "foundation.h" -static struct bt_mesh_large_comp_data_cli *cli; +/** Mesh Large Composition Data Client Model Context */ +static struct bt_mesh_large_comp_data_cli { + /** Composition data model entry pointer. */ + struct bt_mesh_model *model; + + /* Internal parameters for tracking message responses. */ + struct bt_mesh_msg_ack_ctx ack_ctx; +} cli; + static int32_t msg_timeout; -static int data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, uint32_t op, - void (*cb)(struct bt_mesh_large_comp_data_cli *cli, uint16_t addr, - struct bt_mesh_large_comp_data_rsp *rsp)) +static int large_comp_data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - struct bt_mesh_large_comp_data_rsp *rsp; - uint8_t page; - uint16_t offset; - uint16_t total_size; + struct net_buf_simple *comp; + size_t to_copy; LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, bt_hex(buf->data, buf->len)); - page = net_buf_simple_pull_u8(buf); - offset = net_buf_simple_pull_le16(buf); - total_size = net_buf_simple_pull_le16(buf); - - if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, op, ctx->addr, (void **)&rsp)) { - rsp->page = page; - rsp->offset = offset; - rsp->total_size = total_size; - - if (rsp->data) { - net_buf_simple_add_mem(rsp->data, buf->data, - MIN(net_buf_simple_tailroom(rsp->data), buf->len)); - } - - bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); + if (!bt_mesh_msg_ack_ctx_match(&cli.ack_ctx, OP_LARGE_COMP_DATA_STATUS, + ctx->addr, (void **)&comp)) { + return 0; } - if (cb) { - struct bt_mesh_large_comp_data_rsp status_rsp = { - .page = page, - .offset = offset, - .total_size = total_size, - .data = buf, - }; + to_copy = MIN(net_buf_simple_tailroom(comp), buf->len); + net_buf_simple_add_mem(comp, buf->data, to_copy); - cb(cli, ctx->addr, &status_rsp); - } + bt_mesh_msg_ack_ctx_rx(&cli.ack_ctx); return 0; } -static int large_comp_data_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) -{ - return data_status(model, ctx, buf, OP_LARGE_COMP_DATA_STATUS, - (cli->cb && cli->cb->large_comp_data_status ? - cli->cb->large_comp_data_status : NULL)); -} - static int models_metadata_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - return data_status(model, ctx, buf, OP_MODELS_METADATA_STATUS, - (cli->cb && cli->cb->models_metadata_status ? - cli->cb->models_metadata_status : NULL)); + struct net_buf_simple *metadata; + size_t to_copy; + + LOG_DBG("net_idx 0x%04x app_idx 0x%04x src 0x%04x len %u: %s", + ctx->net_idx, ctx->app_idx, ctx->addr, buf->len, + bt_hex(buf->data, buf->len)); + + if (!bt_mesh_msg_ack_ctx_match(&cli.ack_ctx, OP_MODELS_METADATA_STATUS, + ctx->addr, (void **)&metadata)) { + return 0; + } + + metadata = (struct net_buf_simple *)cli.ack_ctx.user_data; + + to_copy = MIN(net_buf_simple_tailroom(metadata), buf->len); + net_buf_simple_add_mem(metadata, buf->data, to_copy); + + bt_mesh_msg_ack_ctx_rx(&cli.ack_ctx); + + return 0; } const struct bt_mesh_model_op _bt_mesh_large_comp_data_cli_op[] = { @@ -103,18 +98,17 @@ const struct bt_mesh_model_op _bt_mesh_large_comp_data_cli_op[] = { static int large_comp_data_cli_init(struct bt_mesh_model *model) { if (!bt_mesh_model_in_primary(model)) { - LOG_ERR("Large Comp Data Client only allowed in primary element"); + LOG_ERR("Configuration Client only allowed in primary element"); return -EINVAL; } model->keys[0] = BT_MESH_KEY_DEV_ANY; model->flags |= BT_MESH_MOD_DEVKEY_ONLY; - cli = model->user_data; - cli->model = model; + cli.model = model; msg_timeout = 5000; - bt_mesh_msg_ack_ctx_init(&cli->ack_ctx); + bt_mesh_msg_ack_ctx_init(&cli.ack_ctx); return 0; } @@ -123,35 +117,40 @@ const struct bt_mesh_model_cb _bt_mesh_large_comp_data_cli_cb = { .init = large_comp_data_cli_init, }; -static int data_get(uint16_t net_idx, uint16_t addr, uint32_t op, uint32_t status_op, uint8_t page, - size_t offset, struct bt_mesh_large_comp_data_rsp *rsp) +int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, + size_t offset, struct net_buf_simple *comp) { - BT_MESH_MODEL_BUF_DEFINE(msg, op, 3); + BT_MESH_MODEL_BUF_DEFINE(msg, OP_LARGE_COMP_DATA_GET, 3); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); - const struct bt_mesh_msg_rsp_ctx rsp_ctx = { - .ack = &cli->ack_ctx, - .op = status_op, - .user_data = rsp, + const struct bt_mesh_msg_rsp_ctx rsp = { + .ack = &cli.ack_ctx, + .op = OP_LARGE_COMP_DATA_STATUS, + .user_data = comp, .timeout = msg_timeout, }; - bt_mesh_model_msg_init(&msg, op); + bt_mesh_model_msg_init(&msg, OP_LARGE_COMP_DATA_GET); net_buf_simple_add_u8(&msg, page); net_buf_simple_add_le16(&msg, offset); - return bt_mesh_msg_ackd_send(cli->model, &ctx, &msg, rsp ? &rsp_ctx : NULL); -} - -int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, - size_t offset, struct bt_mesh_large_comp_data_rsp *rsp) -{ - return data_get(net_idx, addr, OP_LARGE_COMP_DATA_GET, OP_LARGE_COMP_DATA_STATUS, - page, offset, rsp); + return bt_mesh_msg_ackd_send(cli.model, &ctx, &msg, comp ? &rsp : NULL); } int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, - size_t offset, struct bt_mesh_large_comp_data_rsp *rsp) + size_t offset, struct net_buf_simple *metadata) { - return data_get(net_idx, addr, OP_MODELS_METADATA_GET, OP_MODELS_METADATA_STATUS, - page, offset, rsp); + BT_MESH_MODEL_BUF_DEFINE(msg, OP_MODELS_METADATA_STATUS, 3); + struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); + const struct bt_mesh_msg_rsp_ctx rsp = { + .ack = &cli.ack_ctx, + .op = OP_MODELS_METADATA_STATUS, + .user_data = metadata, + .timeout = msg_timeout, + }; + + bt_mesh_model_msg_init(&msg, OP_MODELS_METADATA_GET); + net_buf_simple_add_u8(&msg, page); + net_buf_simple_add_le16(&msg, offset); + + return bt_mesh_msg_ackd_send(cli.model, &ctx, &msg, metadata ? &rsp : NULL); } diff --git a/subsys/bluetooth/mesh/shell/large_comp_data.c b/subsys/bluetooth/mesh/shell/large_comp_data.c index 750f7b318fd7..d278bbfc936c 100644 --- a/subsys/bluetooth/mesh/shell/large_comp_data.c +++ b/subsys/bluetooth/mesh/shell/large_comp_data.c @@ -11,28 +11,9 @@ #include "utils.h" -extern const struct shell *bt_mesh_shell_ctx_shell; - -static void status_print(int err, char *msg, uint16_t addr, struct bt_mesh_large_comp_data_rsp *rsp) -{ - if (err) { - shell_error(bt_mesh_shell_ctx_shell, - "Failed to send %s Get message (err %d)", msg, err); - return; - } - - shell_print(bt_mesh_shell_ctx_shell, - "%s [0x%04x]: page: %u offset: %u total size: %u", msg, addr, rsp->page, - rsp->offset, rsp->total_size); - shell_hexdump(bt_mesh_shell_ctx_shell, rsp->data->data, rsp->data->len); -} - static int cmd_large_comp_data_get(const struct shell *sh, size_t argc, char *argv[]) { NET_BUF_SIMPLE_DEFINE(comp, 64); - struct bt_mesh_large_comp_data_rsp rsp = { - .data = &comp, - }; uint8_t page; uint16_t offset; int err = 0; @@ -48,18 +29,21 @@ static int cmd_large_comp_data_get(const struct shell *sh, size_t argc, char *ar } err = bt_mesh_large_comp_data_get(bt_mesh_shell_target_ctx.net_idx, - bt_mesh_shell_target_ctx.dst, page, offset, &rsp); - status_print(err, "Composition Data", bt_mesh_shell_target_ctx.dst, &rsp); + bt_mesh_shell_target_ctx.dst, page, offset, + &comp); + if (err) { + shell_print(sh, "Failed to send Large Composition Data Get (err=%d)", err); + return err; + } - return err; + shell_print(sh, "Large Composition Data Get len=%d", comp.len); + + return 0; } static int cmd_models_metadata_get(const struct shell *sh, size_t argc, char *argv[]) { NET_BUF_SIMPLE_DEFINE(metadata, 64); - struct bt_mesh_large_comp_data_rsp rsp = { - .data = &metadata, - }; uint8_t page; uint16_t offset; int err = 0; @@ -75,10 +59,16 @@ static int cmd_models_metadata_get(const struct shell *sh, size_t argc, char *ar } err = bt_mesh_models_metadata_get(bt_mesh_shell_target_ctx.net_idx, - bt_mesh_shell_target_ctx.dst, page, offset, &rsp); - status_print(err, "Models Metadata", bt_mesh_shell_target_ctx.dst, &rsp); + bt_mesh_shell_target_ctx.dst, page, offset, + &metadata); + if (err) { + shell_print(sh, "Failed to send Models Metadata Get (err=%d)", err); + return err; + } + + shell_print(sh, "Models Metadata Get len=%d", metadata.len); - return err; + return 0; } SHELL_STATIC_SUBCMD_SET_CREATE( diff --git a/tests/bluetooth/mesh_shell/src/main.c b/tests/bluetooth/mesh_shell/src/main.c index 4e0394c234d0..e2b2a5ad60d3 100644 --- a/tests/bluetooth/mesh_shell/src/main.c +++ b/tests/bluetooth/mesh_shell/src/main.c @@ -37,10 +37,6 @@ static struct bt_mesh_sol_pdu_rpl_cli srpl_cli; static struct bt_mesh_od_priv_proxy_cli od_priv_proxy_cli; #endif -#if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) -struct bt_mesh_large_comp_data_cli large_comp_data_cli; -#endif - BT_MESH_SHELL_HEALTH_PUB_DEFINE(health_pub); static struct bt_mesh_model root_models[] = { @@ -87,7 +83,7 @@ static struct bt_mesh_model root_models[] = { BT_MESH_MODEL_LARGE_COMP_DATA_SRV, #endif #if defined(CONFIG_BT_MESH_LARGE_COMP_DATA_CLI) - BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&large_comp_data_cli), + BT_MESH_MODEL_LARGE_COMP_DATA_CLI, #endif #if defined(CONFIG_BT_MESH_PRIV_BEACON_SRV) diff --git a/tests/bsim/bluetooth/mesh/src/test_lcd.c b/tests/bsim/bluetooth/mesh/src/test_lcd.c index 1dc5fc70054f..7797a1854745 100644 --- a/tests/bsim/bluetooth/mesh/src/test_lcd.c +++ b/tests/bsim/bluetooth/mesh/src/test_lcd.c @@ -27,7 +27,6 @@ LOG_MODULE_REGISTER(test_lcd, LOG_LEVEL_INF); #define DUMMY_2_BYTE_OP BT_MESH_MODEL_OP_2(0xff, 0xff) #define BT_MESH_LCD_PAYLOAD_MAX \ (BT_MESH_TX_SDU_MAX - BT_MESH_MODEL_OP_LEN(DUMMY_2_BYTE_OP) - \ - LCD_STATUS_FIELDS_LEN - \ BT_MESH_MIC_SHORT) /* 378 bytes */ #define TEST_MODEL_CNT_CB(_dummy_op, _metadata) \ @@ -68,14 +67,13 @@ static const struct bt_mesh_test_cfg srv_cfg = { static struct bt_mesh_prov prov; static struct bt_mesh_cfg_cli cfg_cli; -static struct bt_mesh_large_comp_data_cli lcd_cli; /* Creates enough composition data to send a max SDU comp status message + 1 byte */ static struct bt_mesh_elem elements_1[] = { BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), - BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), + BT_MESH_MODEL_LARGE_COMP_DATA_CLI, BT_MESH_MODEL_LARGE_COMP_DATA_SRV), BT_MESH_MODEL_NONE), LISTIFY(88, DUMMY_ELEM, (,)), @@ -86,7 +84,7 @@ static struct bt_mesh_elem elements_2[] = { BT_MESH_ELEM(1, MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_CFG_CLI(&cfg_cli), - BT_MESH_MODEL_LARGE_COMP_DATA_CLI(&lcd_cli), + BT_MESH_MODEL_LARGE_COMP_DATA_CLI, BT_MESH_MODEL_LARGE_COMP_DATA_SRV), BT_MESH_MODEL_NONE), LISTIFY(186, DUMMY_ELEM, (,)), @@ -142,12 +140,16 @@ static void merge_and_compare_assert(struct net_buf_simple *sample1, struct net_ /* Assert that the received status fields are equal to local values. Buffer state is saved. */ -static void verify_status_fields(struct bt_mesh_large_comp_data_rsp *srv_rsp, uint8_t page_local, +static void verify_status_fields(struct net_buf_simple *srv_rsp, uint8_t page_local, uint16_t offset_local, uint16_t total_size_local) { - ASSERT_EQUAL(page_local, srv_rsp->page); - ASSERT_EQUAL(offset_local, srv_rsp->offset); - ASSERT_EQUAL(total_size_local, srv_rsp->total_size); + uint8_t byte_value[LCD_STATUS_FIELDS_LEN]; + + byte_value[0] = page_local; + memcpy(&byte_value[1], &offset_local, 2); + memcpy(&byte_value[3], &total_size_local, 2); + + ASSERT_TRUE(memcmp(srv_rsp->data, byte_value, LCD_STATUS_FIELDS_LEN) == 0); } /* Compare response data with local data. @@ -156,7 +158,7 @@ static void verify_status_fields(struct bt_mesh_large_comp_data_rsp *srv_rsp, ui * * local_data: state is preserved. * * prev_len: Set to NULL if irrelevant. Used for split and merge testing. */ -static void rsp_equals_local_data_assert(uint16_t addr, struct bt_mesh_large_comp_data_rsp *srv_rsp, +static void rsp_equals_local_data_assert(uint16_t addr, struct net_buf_simple *srv_rsp, struct net_buf_simple *local_data, uint8_t page, uint16_t offset, uint16_t total_size, uint16_t *prev_len) { @@ -164,6 +166,8 @@ static void rsp_equals_local_data_assert(uint16_t addr, struct bt_mesh_large_com /* Check that status field data matches local values. */ verify_status_fields(srv_rsp, page, offset, total_size); + /* Remove field data bytes before comparing comp data */ + net_buf_simple_pull_mem(srv_rsp, LCD_STATUS_FIELDS_LEN); net_buf_simple_save(local_data, &local_state); @@ -174,7 +178,7 @@ static void rsp_equals_local_data_assert(uint16_t addr, struct bt_mesh_large_com } /* Check that local and rsp data are equal */ - ASSERT_TRUE(memcmp(srv_rsp->data->data, local_data->data, srv_rsp->data->len) == 0); + ASSERT_TRUE(memcmp(srv_rsp->data, local_data->data, srv_rsp->len) == 0); net_buf_simple_restore(local_data, &local_state); } @@ -196,13 +200,9 @@ static void test_cli_max_sdu_comp_data_request(void) uint16_t offset, total_size; NET_BUF_SIMPLE_DEFINE(local_comp, 500); - NET_BUF_SIMPLE_DEFINE(srv_rsp_comp, 500); + NET_BUF_SIMPLE_DEFINE(srv_rsp, 500); net_buf_simple_init(&local_comp, 0); - net_buf_simple_init(&srv_rsp_comp, 0); - - struct bt_mesh_large_comp_data_rsp srv_rsp = { - .data = &srv_rsp_comp, - }; + net_buf_simple_init(&srv_rsp, 0); bt_mesh_device_setup(&prov, &comp_1); prov_and_conf(cli_cfg); @@ -223,7 +223,7 @@ static void test_cli_max_sdu_comp_data_request(void) /* Get server composition data and check integrity */ ASSERT_OK(bt_mesh_large_comp_data_get(0, SRV_ADDR, page, offset, &srv_rsp)); - ASSERT_EQUAL(srv_rsp_comp.len, BT_MESH_LCD_PAYLOAD_MAX); + ASSERT_EQUAL(srv_rsp.len, BT_MESH_LCD_PAYLOAD_MAX); rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp, &local_comp, page, offset, total_size, NULL); @@ -237,18 +237,11 @@ static void test_cli_split_comp_data_request(void) uint16_t offset, total_size, prev_len = 0; NET_BUF_SIMPLE_DEFINE(local_comp, 200); - NET_BUF_SIMPLE_DEFINE(srv_rsp_comp_1, 64); - NET_BUF_SIMPLE_DEFINE(srv_rsp_comp_2, 64); + NET_BUF_SIMPLE_DEFINE(srv_rsp_1, 64); + NET_BUF_SIMPLE_DEFINE(srv_rsp_2, 64); net_buf_simple_init(&local_comp, 0); - net_buf_simple_init(&srv_rsp_comp_1, 0); - net_buf_simple_init(&srv_rsp_comp_2, 0); - - struct bt_mesh_large_comp_data_rsp srv_rsp_1 = { - .data = &srv_rsp_comp_1, - }; - struct bt_mesh_large_comp_data_rsp srv_rsp_2 = { - .data = &srv_rsp_comp_2, - }; + net_buf_simple_init(&srv_rsp_1, 0); + net_buf_simple_init(&srv_rsp_2, 0); bt_mesh_device_setup(&prov, &comp_1); prov_and_conf(cli_cfg); @@ -269,7 +262,7 @@ static void test_cli_split_comp_data_request(void) rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp_1, &local_comp, page, offset, total_size, &prev_len); - prev_len = srv_rsp_comp_1.len; + prev_len = srv_rsp_1.len; offset += prev_len; /* Get next server composition data sample */ @@ -278,7 +271,7 @@ static void test_cli_split_comp_data_request(void) &prev_len); /* Check data integrity of merged sample data */ - merge_and_compare_assert(&srv_rsp_comp_1, &srv_rsp_comp_2, &local_comp); + merge_and_compare_assert(&srv_rsp_1, &srv_rsp_2, &local_comp); PASS(); } @@ -290,13 +283,9 @@ static void test_cli_max_sdu_metadata_request(void) uint16_t offset, total_size; NET_BUF_SIMPLE_DEFINE(local_metadata, 500); - NET_BUF_SIMPLE_DEFINE(srv_rsp_metadata, 500); + NET_BUF_SIMPLE_DEFINE(srv_rsp, 500); net_buf_simple_init(&local_metadata, 0); - net_buf_simple_init(&srv_rsp_metadata, 0); - - struct bt_mesh_large_comp_data_rsp srv_rsp = { - .data = &srv_rsp_metadata, - }; + net_buf_simple_init(&srv_rsp, 0); bt_mesh_device_setup(&prov, &comp_2); prov_and_conf(cli_cfg); @@ -317,7 +306,7 @@ static void test_cli_max_sdu_metadata_request(void) /* Get server metadata and check integrity */ ASSERT_OK(bt_mesh_models_metadata_get(0, SRV_ADDR, page, offset, &srv_rsp)); - ASSERT_EQUAL(srv_rsp_metadata.len, BT_MESH_LCD_PAYLOAD_MAX); + ASSERT_EQUAL(srv_rsp.len, BT_MESH_LCD_PAYLOAD_MAX); rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp, &local_metadata, page, offset, total_size, NULL); @@ -330,18 +319,11 @@ static void test_cli_split_metadata_request(void) uint16_t offset, total_size, prev_len = 0; NET_BUF_SIMPLE_DEFINE(local_metadata, 500); - NET_BUF_SIMPLE_DEFINE(srv_rsp_metadata_1, 64); - NET_BUF_SIMPLE_DEFINE(srv_rsp_metadata_2, 64); + NET_BUF_SIMPLE_DEFINE(srv_rsp_1, 64); + NET_BUF_SIMPLE_DEFINE(srv_rsp_2, 64); net_buf_simple_init(&local_metadata, 0); - net_buf_simple_init(&srv_rsp_metadata_1, 0); - net_buf_simple_init(&srv_rsp_metadata_2, 0); - - struct bt_mesh_large_comp_data_rsp srv_rsp_1 = { - .data = &srv_rsp_metadata_1, - }; - struct bt_mesh_large_comp_data_rsp srv_rsp_2 = { - .data = &srv_rsp_metadata_2, - }; + net_buf_simple_init(&srv_rsp_1, 0); + net_buf_simple_init(&srv_rsp_2, 0); bt_mesh_device_setup(&prov, &comp_2); prov_and_conf(cli_cfg); @@ -362,7 +344,7 @@ static void test_cli_split_metadata_request(void) rsp_equals_local_data_assert(SRV_ADDR, &srv_rsp_1, &local_metadata, page, offset, total_size, &prev_len); - prev_len = srv_rsp_metadata_1.len; + prev_len = srv_rsp_1.len; offset += prev_len; /* Get next server composition data sample and check integrity */ @@ -371,7 +353,7 @@ static void test_cli_split_metadata_request(void) total_size, &prev_len); /* Check data integrity of merged sample data */ - merge_and_compare_assert(&srv_rsp_metadata_1, &srv_rsp_metadata_2, &local_metadata); + merge_and_compare_assert(&srv_rsp_1, &srv_rsp_2, &local_metadata); PASS(); } From ca60e8c00988f4d357687867b338874bcd7a9d02 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:27 +0200 Subject: [PATCH 270/528] Revert "[nrf fromtree] Bluetooth: Mesh: Use bt_mesh_msg_ackd_send API in LCD Client" This reverts commit 0074273db330d765ac090f9959fee1344f572a44. Signed-off-by: Robert Lubos --- subsys/bluetooth/mesh/large_comp_data_cli.c | 49 ++++++++++++++------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/subsys/bluetooth/mesh/large_comp_data_cli.c b/subsys/bluetooth/mesh/large_comp_data_cli.c index 47c8db5b1f52..e8d5f5cbba51 100644 --- a/subsys/bluetooth/mesh/large_comp_data_cli.c +++ b/subsys/bluetooth/mesh/large_comp_data_cli.c @@ -18,8 +18,6 @@ #include #include -#include "msg.h" - #include #define LOG_LEVEL CONFIG_BT_MESH_MODEL_LOG_LEVEL @@ -117,23 +115,35 @@ const struct bt_mesh_model_cb _bt_mesh_large_comp_data_cli_cb = { .init = large_comp_data_cli_init, }; +static int cli_prepare(void *param, uint32_t op, uint16_t addr) +{ + return bt_mesh_msg_ack_ctx_prepare(&cli.ack_ctx, op, addr, param); +} + int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, size_t offset, struct net_buf_simple *comp) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_LARGE_COMP_DATA_GET, 3); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); - const struct bt_mesh_msg_rsp_ctx rsp = { - .ack = &cli.ack_ctx, - .op = OP_LARGE_COMP_DATA_STATUS, - .user_data = comp, - .timeout = msg_timeout, - }; + int err; + + err = cli_prepare(comp, OP_LARGE_COMP_DATA_STATUS, addr); + if (err) { + return err; + } bt_mesh_model_msg_init(&msg, OP_LARGE_COMP_DATA_GET); net_buf_simple_add_u8(&msg, page); net_buf_simple_add_le16(&msg, offset); - return bt_mesh_msg_ackd_send(cli.model, &ctx, &msg, comp ? &rsp : NULL); + err = bt_mesh_model_send(cli.model, &ctx, &msg, NULL, NULL); + if (err) { + LOG_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli.ack_ctx); + return err; + } + + return bt_mesh_msg_ack_ctx_wait(&cli.ack_ctx, K_MSEC(msg_timeout)); } int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, @@ -141,16 +151,23 @@ int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, { BT_MESH_MODEL_BUF_DEFINE(msg, OP_MODELS_METADATA_STATUS, 3); struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); - const struct bt_mesh_msg_rsp_ctx rsp = { - .ack = &cli.ack_ctx, - .op = OP_MODELS_METADATA_STATUS, - .user_data = metadata, - .timeout = msg_timeout, - }; + int err; + + err = cli_prepare(metadata, OP_MODELS_METADATA_STATUS, addr); + if (err) { + return err; + } bt_mesh_model_msg_init(&msg, OP_MODELS_METADATA_GET); net_buf_simple_add_u8(&msg, page); net_buf_simple_add_le16(&msg, offset); - return bt_mesh_msg_ackd_send(cli.model, &ctx, &msg, metadata ? &rsp : NULL); + err = bt_mesh_model_send(cli.model, &ctx, &msg, NULL, NULL); + if (err) { + LOG_ERR("model_send() failed (err %d)", err); + bt_mesh_msg_ack_ctx_clear(&cli.ack_ctx); + return err; + } + + return bt_mesh_msg_ack_ctx_wait(&cli.ack_ctx, K_MSEC(msg_timeout)); } From 23f61988ecd595f0fb24fa410856aa3e28cda958 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:27 +0200 Subject: [PATCH 271/528] Revert "[nrf fromtree] Bluetooth: Mesh: Use BT_MESH_MSG_CTX_INIT_DEV macro in LCD Client" This reverts commit 7e63dfc689ff90e9818d245383d878b0d152c364. Signed-off-by: Robert Lubos --- subsys/bluetooth/mesh/large_comp_data_cli.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/mesh/large_comp_data_cli.c b/subsys/bluetooth/mesh/large_comp_data_cli.c index e8d5f5cbba51..5ec45239bc82 100644 --- a/subsys/bluetooth/mesh/large_comp_data_cli.c +++ b/subsys/bluetooth/mesh/large_comp_data_cli.c @@ -124,7 +124,12 @@ int bt_mesh_large_comp_data_get(uint16_t net_idx, uint16_t addr, uint8_t page, size_t offset, struct net_buf_simple *comp) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_LARGE_COMP_DATA_GET, 3); - struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; int err; err = cli_prepare(comp, OP_LARGE_COMP_DATA_STATUS, addr); @@ -150,7 +155,12 @@ int bt_mesh_models_metadata_get(uint16_t net_idx, uint16_t addr, uint8_t page, size_t offset, struct net_buf_simple *metadata) { BT_MESH_MODEL_BUF_DEFINE(msg, OP_MODELS_METADATA_STATUS, 3); - struct bt_mesh_msg_ctx ctx = BT_MESH_MSG_CTX_INIT_DEV(net_idx, addr); + struct bt_mesh_msg_ctx ctx = { + .net_idx = net_idx, + .app_idx = BT_MESH_KEY_DEV_REMOTE, + .addr = addr, + .send_ttl = BT_MESH_TTL_DEFAULT, + }; int err; err = cli_prepare(metadata, OP_MODELS_METADATA_STATUS, addr); From 3e715eedf0fe70b8361e0ede58ad3daf86b8ed12 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:27 +0200 Subject: [PATCH 272/528] Revert "[nrf noup] mcumgr: img_mgmt: Fix check for chosen code partition" This reverts commit 36961d6b72f53b9ff0eef1e398f08da84dae5032. Signed-off-by: Robert Lubos --- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 22 +------------------ 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index c490b0ea5314..73f96eaf8b58 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -34,34 +34,14 @@ #include #endif -#if USE_PARTITION_MANAGER -#include - -#ifdef PM_MCUBOOT_SECONDARY_PAD_SIZE -BUILD_ASSERT(PM_MCUBOOT_PAD_SIZE == PM_MCUBOOT_SECONDARY_PAD_SIZE); -#endif - -#if CONFIG_BUILD_WITH_TFM - #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE + PM_TFM_SIZE) -#else - #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE) -#endif - -#define FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(label) \ - (FIXED_PARTITION_OFFSET(label) == (PM_ADDRESS - PM_ADDRESS_OFFSET)) - -#else /* ! USE_PARTITION_MANAGER */ - #define FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(label) \ DT_SAME_NODE(DT_NODELABEL(label), DT_CHOSEN(zephyr_code_partition)) -#endif /* USE_PARTITION_MANAGER */ - #if !(FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_partition) || \ FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_ns_partition) || \ FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot1_partition) || \ FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot2_partition)) -#error "Unsupported chosen code partition for boot application." +#error "Unsupported chosen zephyr,code-partition for boot application." #endif LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); From fa2cdc5894cbeb024dfe6e51b996c3a5c84dccf4 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:27 +0200 Subject: [PATCH 273/528] Revert "[nrf fromtree] mcumgr: img_mgmt: Let image version comparison use build number" This reverts commit 63516e45a77ada31e13aa961540f127a6fdf7d7d. Signed-off-by: Robert Lubos --- subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig | 7 ------- subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 8 +------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig index ec7d17f43d17..106a29006f41 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig @@ -94,13 +94,6 @@ config MCUMGR_GRP_IMG_FRUGAL_LIST a device but requires support in client software, which has to default omitted values. Works correctly with mcumgr-cli. -config MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER - bool "Use build number while comparing image version" - help - By default, the image version comparison relies only on version major, - minor and revision. Enable this option to take into account the build - number as well. - config MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK bool "Upload check hook" depends on MCUMGR_MGMT_NOTIFICATION_HOOKS diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index ccf02564d487..e4ea3b568f77 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -278,13 +278,7 @@ img_mgmt_vercmp(const struct image_version *a, const struct image_version *b) return 1; } -#if defined(CONFIG_MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER) - if (a->iv_build_num < b->iv_build_num) { - return -1; - } else if (a->iv_build_num > b->iv_build_num) { - return 1; - } -#endif + /* Note: For semver compatibility, don't compare the 32-bit build num. */ return 0; } From dceaaee5d4a613aeac14296d02c6a67942b015a6 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:27 +0200 Subject: [PATCH 274/528] Revert "[nrf fromtree] mcumgr: img_mgmt: Fix check for upgrade-only" This reverts commit 977d57d98719280c1b27857d6f50aeb9b9fa8b09. Signed-off-by: Robert Lubos --- subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index e4ea3b568f77..81bdf56dc9e8 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -646,7 +646,7 @@ img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req, if (req->upgrade) { - /* User specified upgrade-only. Make sure new image version is + /* User specified upgrade-only. Make sure new image version is * greater than that of the currently running image. */ rc = img_mgmt_my_version(&cur_ver); @@ -654,7 +654,7 @@ img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req, return MGMT_ERR_EUNKNOWN; } - if (img_mgmt_vercmp(&cur_ver, &hdr->ih_ver) >= 0) { + if (img_mgmt_vercmp(&cur_ver, &hdr->ih_ver) > 0) { IMG_MGMT_UPLOAD_ACTION_SET_RC_RSN(action, img_mgmt_err_str_downgrade); return MGMT_ERR_EBADSTATE; From dd1b2eb0a9ed3ccf7f6ffc8575d451229344ae8e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:28 +0200 Subject: [PATCH 275/528] Revert "[nrf fromlist] net: conn_mgr: Bulk convenience functions" This reverts commit 518e45afefd835f88bc6e5137ddf82e136a9fc01. Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 51 --- subsys/net/conn_mgr/conn_mgr_connectivity.c | 142 ------- tests/net/conn_mgr_conn/prj.conf | 4 - tests/net/conn_mgr_conn/src/main.c | 439 -------------------- 4 files changed, 636 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index f39a47b0f785..a48b84473ce5 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -424,57 +424,6 @@ int conn_mgr_if_set_timeout(struct net_if *iface, int timeout); */ void conn_mgr_conn_init(void); -/** - * @brief Convenience function that takes all available ifaces into the admin-up state. - * - * Essentially a wrapper for net_if_up. - * - * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. - * Otherwise, affect all ifaces. - * @return 0 if all net_if_up calls returned 0, otherwise the first nonzero value - * returned by a net_if_up call. - */ -int conn_mgr_all_if_up(bool skip_ignored); - - -/** - * @brief Convenience function that takes all available ifaces into the admin-down state. - * - * Essentially a wrapper for net_if_down. - * - * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. - * Otherwise, affect all ifaces. - * @return 0 if all net_if_down calls returned 0, otherwise the first nonzero value - * returned by a net_if_down call. - */ -int conn_mgr_all_if_down(bool skip_ignored); - -/** - * @brief Convenience function that takes all available ifaces into the admin-up state, and - * connects those that support connectivity. - * - * Essentially a wrapper for net_if_up and conn_mgr_if_connect. - * - * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. - * Otherwise, affect all ifaces. - * @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero - * value returned by either net_if_up or conn_mgr_if_connect. - */ -int conn_mgr_all_if_connect(bool skip_ignored); - -/** - * @brief Convenience function that disconnects all available ifaces that support connectivity - * without putting them into admin-down state (unless auto-down is enabled for the iface). - * - * Essentially a wrapper for net_if_down. - * - * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. - * Otherwise, affect all ifaces. - * @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero - * value returned by either net_if_up or conn_mgr_if_connect. - */ -int conn_mgr_all_if_disconnect(bool skip_ignored); - /** * @} */ diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index f20bb9fcd5df..7e8629de9752 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -9,7 +9,6 @@ LOG_MODULE_REGISTER(conn_mgr_conn, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include -#include #include "conn_mgr_private.h" int conn_mgr_if_connect(struct net_if *iface) @@ -411,144 +410,3 @@ void conn_mgr_conn_init(void) } } } - -enum conn_mgr_conn_all_if_oper { - ALL_IF_UP, - ALL_IF_DOWN, - ALL_IF_CONNECT, - ALL_IF_DISCONNECT -}; - -struct conn_mgr_conn_all_if_ctx { - bool skip_ignored; - enum conn_mgr_conn_all_if_oper operation; - int status; -}; - -/* Per-iface callback for conn_mgr_conn_all_if_up */ -static void conn_mgr_conn_all_if_cb(struct net_if *iface, void *user_data) -{ - int status = 0; - struct conn_mgr_conn_all_if_ctx *context = (struct conn_mgr_conn_all_if_ctx *)user_data; - - /* Skip ignored ifaces if so desired */ - if (context->skip_ignored && conn_mgr_is_iface_ignored(iface)) { - return; - } - - /* Perform the requested operation */ - switch (context->operation) { - case ALL_IF_UP: - /* Do not take iface admin up if it already is. */ - if (net_if_is_admin_up(iface)) { - return; - } - - status = net_if_up(iface); - break; - case ALL_IF_DOWN: - /* Do not take iface admin down if it already is. */ - if (!net_if_is_admin_up(iface)) { - return; - } - - status = net_if_down(iface); - break; - case ALL_IF_CONNECT: - /* Connect operation only supported if iface is bound */ - if (!conn_mgr_if_is_bound(iface)) { - return; - } - - status = conn_mgr_if_connect(iface); - break; - case ALL_IF_DISCONNECT: - /* Disconnect operation only supported if iface is bound */ - if (!conn_mgr_if_is_bound(iface)) { - return; - } - - status = conn_mgr_if_disconnect(iface); - break; - } - - if (status == 0) { - return; - } - - if (context->status == 0) { - context->status = status; - } - - NET_ERR("%s failed for iface %d (%p). Error: %d", - context->operation == ALL_IF_UP ? "net_if_up" : - context->operation == ALL_IF_DOWN ? "net_if_down" : - context->operation == ALL_IF_CONNECT ? "conn_mgr_if_connect" : - context->operation == ALL_IF_DISCONNECT ? "conn_mgr_if_disconnect" : - "invalid", - net_if_get_by_iface(iface), iface, status - ); -} - -int conn_mgr_all_if_up(bool skip_ignored) -{ - struct conn_mgr_conn_all_if_ctx context = { - .operation = ALL_IF_UP, - .skip_ignored = skip_ignored, - .status = 0 - }; - - net_if_foreach(conn_mgr_conn_all_if_cb, &context); - - return context.status; -} - -int conn_mgr_all_if_down(bool skip_ignored) -{ - struct conn_mgr_conn_all_if_ctx context = { - .operation = ALL_IF_DOWN, - .skip_ignored = skip_ignored, - .status = 0 - }; - - net_if_foreach(conn_mgr_conn_all_if_cb, &context); - - return context.status; -} - -int conn_mgr_all_if_connect(bool skip_ignored) -{ - /* First, take all ifaces up. - * All bound ifaces will do this automatically when connect is called, but non-bound ifaces - * won't, so we must request it explicitly. - */ - struct conn_mgr_conn_all_if_ctx context = { - .operation = ALL_IF_UP, - .skip_ignored = skip_ignored, - .status = 0 - }; - - net_if_foreach(conn_mgr_conn_all_if_cb, &context); - - /* Now connect all ifaces. - * We are delibarately not resetting context.status between these two calls so that - * the first nonzero status code encountered between the two of them is what is returned. - */ - context.operation = ALL_IF_CONNECT; - net_if_foreach(conn_mgr_conn_all_if_cb, &context); - - return context.status; -} - -int conn_mgr_all_if_disconnect(bool skip_ignored) -{ - struct conn_mgr_conn_all_if_ctx context = { - .operation = ALL_IF_DISCONNECT, - .skip_ignored = skip_ignored, - .status = 0 - }; - - net_if_foreach(conn_mgr_conn_all_if_cb, &context); - - return context.status; -} diff --git a/tests/net/conn_mgr_conn/prj.conf b/tests/net/conn_mgr_conn/prj.conf index ec6b62f6be3f..5ffa0ba9d9fc 100644 --- a/tests/net/conn_mgr_conn/prj.conf +++ b/tests/net/conn_mgr_conn/prj.conf @@ -24,7 +24,3 @@ CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=6 CONFIG_NET_IF_MAX_IPV6_COUNT=6 CONFIG_TEST_USERSPACE=y - -# Increased net event queue size needed since this test performs simultaneous events on a -# large number of ifaces. -CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=16 diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index 9942ba576659..e7154329d5a8 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -15,7 +15,6 @@ #include #include #include -#include #include "conn_mgr_private.h" #include "test_conn_impl.h" #include "test_ifaces.h" @@ -55,9 +54,6 @@ static void reset_test_iface_state(struct net_if *iface) struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface); struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); - /* Some tests mark ifaces as ignored, this must be reset between each test. */ - conn_mgr_unignore_iface(iface); - if (iface_binding) { /* Reset all flags and settings for the binding */ iface_binding->flags = 0; @@ -1143,440 +1139,5 @@ ZTEST(conn_mgr_conn, test_auto_down_fatal) "Auto-down should not trigger on fatal error if it is disabled."); } -/* Verify that all_if_up brings all ifaces up, but only if they are not ignored or - * skip_ignored is false - */ -ZTEST(conn_mgr_conn, test_all_if_up) -{ - /* Ignore an iface */ - conn_mgr_ignore_iface(ifa1); - - /* Take all ifaces up (do not skip ignored) */ - zassert_equal(conn_mgr_all_if_up(false), 0, "conn_mgr_all_if_up should succeed."); - k_sleep(K_MSEC(1)); - - /* Verify all ifaces are up */ - zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); - - - /* Manually take all ifaces down */ - zassert_equal(net_if_down(ifa1), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifa2), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifni), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifnull), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifnone), 0, "net_if_down should succeed for all ifaces."); - k_sleep(K_MSEC(1)); - - /* Take all ifaces up (skip ignored) */ - zassert_equal(conn_mgr_all_if_up(true), 0, "conn_mgr_all_if_up should succeed."); - k_sleep(K_MSEC(1)); - - /* Verify all except ignored are up */ - zassert_true(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All non-ignored ifaces should be admin-up."); - - zassert_false(net_if_is_admin_up(ifa1), "Ignored iface should not be admin-up."); -} - -/* Verify that all_if_connect brings all ifaces up, and connects all bound ifaces, but only those - * that are not ignored, or all of them if skip_ignored is false - */ -ZTEST(conn_mgr_conn, test_all_if_connect) -{ - /* Ignore a bound and an unbound iface */ - conn_mgr_ignore_iface(ifa1); - conn_mgr_ignore_iface(ifnone); - - /* Connect all ifaces (do not skip ignored) */ - zassert_equal(conn_mgr_all_if_connect(false), 0, "conn_mgr_all_if_connect should succeed."); - k_sleep(K_MSEC(1)); - - /* Verify all ifaces are up */ - zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); - - /* Verify bound ifaces are connected */ - zassert_true(net_if_is_up(ifa1), "All bound ifaces should be connected."); - zassert_true(net_if_is_up(ifa2), "All bound ifaces should be connected."); - zassert_true(net_if_is_up(ifb), "All bound ifaces should be connected."); - zassert_true(net_if_is_up(ifni), "All bound ifaces should be connected."); - - /* Manually take all ifaces down */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "net_if_disconnect should succeed."); - zassert_equal(conn_mgr_if_disconnect(ifa2), 0, "net_if_disconnect should succeed."); - zassert_equal(conn_mgr_if_disconnect(ifb), 0, "net_if_disconnect should succeed."); - zassert_equal(conn_mgr_if_disconnect(ifni), 0, "net_if_disconnect should succeed."); - - zassert_equal(net_if_down(ifa1), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifa2), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifni), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifnull), 0, "net_if_down should succeed for all ifaces."); - zassert_equal(net_if_down(ifnone), 0, "net_if_down should succeed for all ifaces."); - k_sleep(K_MSEC(1)); - - /* Connect all ifaces (skip ignored) */ - zassert_equal(conn_mgr_all_if_connect(true), 0, "conn_mgr_all_if_connect should succeed."); - k_sleep(K_MSEC(1)); - - /* Verify all except ignored are up */ - zassert_true(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-up."); - - zassert_false(net_if_is_admin_up(ifa1), "All ignored ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifnone), "All ignored ifaces should be admin-down."); - - /* Verify bound ifaces are connected, except for ignored */ - zassert_true(net_if_is_up(ifa2), "All non-ignored bound ifaces should be connected."); - zassert_true(net_if_is_up(ifb), "All non-ignored bound ifaces should be connected."); - zassert_true(net_if_is_up(ifni), "All non-ignored bound ifaces should be connected."); - - zassert_false(net_if_is_up(ifa1), "Ignored iface should not be connected."); -} - -/* Verify that all_if_down takes all ifaces down, but only if they are not ignored, - * or skip_ignored is false - */ -ZTEST(conn_mgr_conn, test_all_if_down) -{ - /* Ignore an iface */ - conn_mgr_ignore_iface(ifa1); - - /* Manually take all ifaces up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); - k_sleep(K_MSEC(1)); - - /* Take all ifaces down (do not skip ignored) */ - zassert_equal(conn_mgr_all_if_down(false), 0, "conn_mgr_all_if_down should succeed."); - k_sleep(K_MSEC(1)); - - /* Verify all ifaces are down */ - zassert_false(net_if_is_admin_up(ifa1), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifa2), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifb), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifni), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifnull), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifnone), "All ifaces should be admin-down."); - - /* Manually take all ifaces up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); - k_sleep(K_MSEC(1)); - - /* Take all ifaces down (skip ignored) */ - zassert_equal(conn_mgr_all_if_down(true), 0, "conn_mgr_all_if_down should succeed."); - k_sleep(K_MSEC(1)); - - /* Verify that all except the ignored iface is down */ - zassert_false(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifnone), "All non-ignored ifaces should be admin-down."); - - zassert_true(net_if_is_admin_up(ifa1), "Ignored iface should be admin-up."); -} - -/* Verify that all_if_disconnect disconnects all bound ifaces, but only if they are not ignored, - * or skip_ignored is false - */ -ZTEST(conn_mgr_conn, test_all_if_disconnect) -{ - /* Ignore a bound iface */ - conn_mgr_ignore_iface(ifa1); - - /* Manually take all ifaces up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); - k_sleep(K_MSEC(1)); - - /* Manually connect all bound ifaces */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); - k_sleep(K_MSEC(1)); - - /* Disconnect all ifaces (do not skip ignored) */ - zassert_equal(conn_mgr_all_if_disconnect(false), 0, - "conn_mgr_all_if_disconnect should succeed."); - k_sleep(K_MSEC(1)); - - /* Verify that all bound ifaces are disconnected */ - zassert_false(net_if_is_up(ifa1), "All bound ifaces should be disconnected."); - zassert_false(net_if_is_up(ifa2), "All bound ifaces should be disconnected."); - zassert_false(net_if_is_up(ifb), "All bound ifaces should be disconnected."); - zassert_false(net_if_is_up(ifni), "All bound ifaces should be disconnected."); - - /* Verify that all ifaces are still up, even if disconnected */ - zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); - - /* Manually reconnect bound ifaces */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); - k_sleep(K_MSEC(1)); - - /* Disconnect all ifaces (skip ignored) */ - zassert_equal(conn_mgr_all_if_disconnect(true), 0, - "conn_mgr_all_if_disconnect should succeed."); - k_sleep(K_MSEC(1)); - - /* Verify that all bound ifaces are disconnected, except the ignored iface */ - zassert_false(net_if_is_up(ifa2), "All non-ignored bound ifaces should be disconnected."); - zassert_false(net_if_is_up(ifb), "All non-ignored bound ifaces should be disconnected."); - zassert_false(net_if_is_up(ifni), "All non-ignored bound ifaces should be disconnected."); - - zassert_true(net_if_is_up(ifa1), "Ignored iface should still be connected"); -} - - -/* Verify that double calls to all_if_up do not raise errors */ -ZTEST(conn_mgr_conn, test_all_if_up_double) -{ - /* Take all ifaces up twice in a row */ - zassert_equal(conn_mgr_all_if_up(false), 0, - "conn_mgr_all_if_up should succeed."); - zassert_equal(conn_mgr_all_if_up(false), 0, - "conn_mgr_all_if_up should succeed twice in a row."); - - /* One more time, after a delay, to be sure */ - k_sleep(K_MSEC(1)); - zassert_equal(conn_mgr_all_if_up(false), 0, - "conn_mgr_all_if_up should succeed twice in a row."); - k_sleep(K_MSEC(1)); - - /* Verify all ifaces are up */ - zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); -} - -/* Verify that double calls to all_if_down do not raise errors */ -ZTEST(conn_mgr_conn, test_all_if_down_double) -{ - /* Manually take all ifaces up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); - k_sleep(K_MSEC(1)); - - /* Take all ifaces down twice in a row */ - zassert_equal(conn_mgr_all_if_down(false), 0, - "conn_mgr_all_if_down should succeed."); - zassert_equal(conn_mgr_all_if_down(false), 0, - "conn_mgr_all_if_down should succeed twice in a row."); - - /* One more time, after a delay, to be sure */ - k_sleep(K_MSEC(1)); - zassert_equal(conn_mgr_all_if_down(false), 0, - "conn_mgr_all_if_down should succeed twice in a row."); - k_sleep(K_MSEC(1)); - - /* Verify all ifaces are down */ - zassert_false(net_if_is_admin_up(ifa1), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifa2), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifb), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifni), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifnull), "All ifaces should be admin-down."); - zassert_false(net_if_is_admin_up(ifnone), "All ifaces should be admin-down."); -} - -/* Verify that double calls to all_if_connect do not raise errors */ -ZTEST(conn_mgr_conn, test_all_if_connect_double) -{ - /* Connect all ifaces twice in a row */ - zassert_equal(conn_mgr_all_if_connect(false), 0, - "conn_mgr_all_if_connect should succeed."); - zassert_equal(conn_mgr_all_if_connect(false), 0, - "conn_mgr_all_if_connect should succeed twice in a row."); - - /* One more time, after a delay, to be sure */ - k_sleep(K_MSEC(1)); - zassert_equal(conn_mgr_all_if_connect(false), 0, - "conn_mgr_all_if_connect should succeed twice in a row."); - k_sleep(K_MSEC(1)); - - /* Verify all ifaces are up */ - zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); - - /* Verify all bound ifaces are connected */ -} - -/* Verify that double calls to all_if_disconnect do not raise errors */ -ZTEST(conn_mgr_conn, test_all_if_disconnect_double) -{ - /* Manually take all ifaces up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); - k_sleep(K_MSEC(1)); - - /* Manually connect all bound ifaces */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); - k_sleep(K_MSEC(1)); - - /* Connect all ifaces twice in a row */ - zassert_equal(conn_mgr_all_if_disconnect(false), 0, - "conn_mgr_all_if_disconnect should succeed."); - zassert_equal(conn_mgr_all_if_disconnect(false), 0, - "conn_mgr_all_if_disconnect should succeed twice in a row."); - - /* One more time, after a delay, to be sure */ - k_sleep(K_MSEC(1)); - zassert_equal(conn_mgr_all_if_disconnect(false), 0, - "conn_mgr_all_if_disconnect should succeed twice in a row."); - k_sleep(K_MSEC(1)); - - /* Verify all bound ifaces are disconnected */ - zassert_false(net_if_is_up(ifa1), "All bound ifaces should be disconnected."); - zassert_false(net_if_is_up(ifa2), "All bound ifaces should be disconnected."); - zassert_false(net_if_is_up(ifb), "All bound ifaces should be disconnected."); - zassert_false(net_if_is_up(ifni), "All bound ifaces should be disconnected."); - - /* Verify all ifaces are up */ - zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); -} - - - -/* Testing error passing for all_if_up/all_if_down is not possible without using an L2 other than - * Dummy, since the dummy L2 is not capable of erroring in response to either of these. - * - * However, since all bulk convenience functions share a single implementation, testing - * connect and disconnect is sufficient to gain acceptable coverage of this behavior for all of - * them. - */ - -/* Verify that all_if_connect successfully forwards errors encountered on individual ifaces */ -ZTEST(conn_mgr_conn, test_all_if_connect_err) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Schedule a connect error on one of the ifaces */ - ifa1_data->api_err = -ECHILD; - - /* Verify that this error is passed to all_if_connect */ - zassert_equal(conn_mgr_all_if_connect(false), -ECHILD, - "conn_mgr_all_if_connect should fail with the requested error."); - k_sleep(K_MSEC(1)); - - /* Verify that all ifaces went admin-up */ - zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); - - /* Verify that all the non-error ifaces are connected */ - zassert_true(net_if_is_up(ifa2), "All non-failing ifaces should be connected."); - zassert_true(net_if_is_up(ifb), "All non-failing ifaces should be connected."); - zassert_true(net_if_is_up(ifni), "All non-failing ifaces should be connected."); - - /* Verify that the error iface is not connected */ - zassert_false(net_if_is_up(ifa1), "The failing iface should not be connected."); -} - -/* Verify that all_if_disconnect successfully forwards errors encountered on individual ifaces */ -ZTEST(conn_mgr_conn, test_all_if_disconnect_err) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Manually take all ifaces up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); - zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); - k_sleep(K_MSEC(1)); - - /* Manually connect all bound ifaces */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); - zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); - k_sleep(K_MSEC(1)); - - /* Schedule a disconnect error on one of the ifaces */ - ifa1_data->api_err = -ECHILD; - - /* Verify that this error is passed to all_if_disconnect */ - zassert_equal(conn_mgr_all_if_disconnect(false), -ECHILD, - "conn_mgr_all_if_disconnect should fail with the requested error."); - - /* Verify that all ifaces are still admin-up */ - zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); - zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); - - /* Verify that all the non-error ifaces are disconnected */ - zassert_false(net_if_is_up(ifa2), "All non-failing ifaces should be disconnected."); - zassert_false(net_if_is_up(ifb), "All non-failing ifaces should be disconnected."); - zassert_false(net_if_is_up(ifni), "All non-failing ifaces should be disconnected."); - - /* Verify that the error iface is not connected */ - zassert_true(net_if_is_up(ifa1), "The failing iface should not be disconnected."); -} ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); From 38c38177dec5f7d1a43be4ed203336eef06ccf21 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:28 +0200 Subject: [PATCH 276/528] Revert "[nrf fromlist] net: conn_mgr: Support Auto-Down" This reverts commit 91b6eaa73b67b3cc0bcdd86e4870513202f04aef. Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 8 - subsys/net/conn_mgr/Kconfig | 4 - subsys/net/conn_mgr/conn_mgr_connectivity.c | 94 -------- subsys/net/conn_mgr/conn_mgr_private.h | 6 +- tests/net/conn_mgr/src/main.c | 43 ++++ tests/net/conn_mgr_conn/src/main.c | 223 +------------------ tests/net/conn_mgr_conn/src/test_conn_impl.c | 7 +- tests/net/conn_mgr_conn/src/test_conn_impl.h | 19 -- 8 files changed, 46 insertions(+), 358 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index a48b84473ce5..52e116d38572 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -185,12 +185,6 @@ enum conn_mgr_if_flag { */ CONN_MGR_IF_NO_AUTO_CONNECT, - /* No auto-down - * When set, conn_mgr will not automatically take the iface admin-down when it stops - * trying to connect, even if NET_CONNECTION_MANAGER_AUTO_IF_DOWN is enabled. - */ - CONN_MGR_IF_NO_AUTO_DOWN, - /** @cond INTERNAL_HIDDEN */ /* Total number of flags - must be at the end of the enum */ CONN_MGR_NUM_IF_FLAGS, @@ -277,8 +271,6 @@ struct conn_mgr_conn_binding { * * Non-Blocking. * - * TODO: Talk about persistence and timeouts in this PR for docs. - * * @param iface Pointer to network interface * @retval 0 on success. * @retval -ESHUTDOWN if the iface is not admin-up. diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig index e74a243b4a0a..a8e37b68b5ee 100644 --- a/subsys/net/conn_mgr/Kconfig +++ b/subsys/net/conn_mgr/Kconfig @@ -37,8 +37,4 @@ config NET_CONNECTION_MANAGER_PRIORITY help This sets the starting priority of the connection manager thread. -config NET_CONNECTION_MANAGER_AUTO_IF_DOWN - bool "Automatically take ifaces admin-down if they have stopped trying to connect" - default y - endif # NET_CONNECTION_MANAGER diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index 7e8629de9752..fc4f628a8f76 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -46,8 +46,6 @@ int conn_mgr_if_connect(struct net_if *iface) return status; } -static void conn_mgr_conn_handle_iface_hard_down(struct net_if *iface); - int conn_mgr_if_disconnect(struct net_if *iface) { struct conn_mgr_conn_binding *binding; @@ -77,11 +75,6 @@ int conn_mgr_if_disconnect(struct net_if *iface) out: k_mutex_unlock(binding->mutex); - /* Inform conn_mgr that this is a hard-down scenario, since it won't know from the - * if_down event alone. - */ - conn_mgr_conn_handle_iface_hard_down(iface); - return status; } @@ -268,59 +261,6 @@ static void conn_mgr_conn_handle_iface_admin_up(struct net_if *iface) } } -/** - * @brief Perform automated behaviors in response to any iface that loses - * connection and does not expect to regain it (referred to, here, as hard-down). - * - * This is how conn_mgr_conn automatically takes such ifaces admin-down. - * - * @param iface - The iface which experienced hard-down. - */ -static void conn_mgr_conn_handle_iface_hard_down(struct net_if *iface) -{ - /* NOTE: This will be double-fired for ifaces that are both non-persistent - * and are being directly requested to disconnect, since both of these conditions - * separately trigger conn_mgr_conn_handle_iface_hard_down. - * - * This is fine, because net_if_down is idempotent, but if you are adding other - * behaviors to this function, bear it in mind. - */ - - /* Ignore ifaces that don't have connectivity implementations */ - if (!conn_mgr_if_is_bound(iface)) { - return; - } - - /* Take the iface admin-down if AUTO_DOWN is enabled */ - if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN) && - !conn_mgr_if_get_flag(iface, CONN_MGR_IF_NO_AUTO_DOWN)) { - net_if_down(iface); - } -} - -/** - * @brief Perform automated behaviors in response to any iface that loses oper-up state. - * - * This is how conn_mgr_conn automatically takes such ifaces admin-down if they are not persistent. - * - * @param iface - The iface which lost oper-up state. - */ -static void conn_mgr_conn_handle_iface_down(struct net_if *iface) -{ - /* Ignore ifaces that don't have connectivity implementations */ - if (!conn_mgr_if_is_bound(iface)) { - return; - } - - /* If the iface is persistent, do not treat any disconnect as hard-down */ - if (conn_mgr_if_get_flag(iface, CONN_MGR_IF_PERSISTENT)) { - return; - } - - /* Otherwise, treat as a hard-down */ - conn_mgr_conn_handle_iface_hard_down(iface); -} - static struct net_mgmt_event_callback conn_mgr_conn_iface_cb; static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) @@ -330,42 +270,12 @@ static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint } switch (NET_MGMT_GET_COMMAND(mgmt_event)) { - case NET_EVENT_IF_CMD_DOWN: - conn_mgr_conn_handle_iface_down(iface); - break; case NET_EVENT_IF_CMD_ADMIN_UP: conn_mgr_conn_handle_iface_admin_up(iface); break; } } -static struct net_mgmt_event_callback conn_mgr_conn_self_cb; -static void conn_mgr_conn_self_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, - struct net_if *iface) -{ - if ((mgmt_event & CONN_MGR_CONN_SELF_EVENTS_MASK) != mgmt_event) { - return; - } - - switch (NET_MGMT_GET_COMMAND(mgmt_event)) { - case NET_EVENT_CONN_CMD_IF_FATAL_ERROR: - if (cb->info) { - NET_ERR("Fatal connectivity error on iface %d (%p). Reason: %d.", - net_if_get_by_iface(iface), iface, *((int *)cb->info) - ); - } else { - NET_ERR("Unknown fatal connectivity error on iface %d (%p).", - net_if_get_by_iface(iface), iface - ); - } - __fallthrough; - case NET_EVENT_CONN_CMD_IF_TIMEOUT: - conn_mgr_conn_handle_iface_hard_down(iface); - break; - } - -} - void conn_mgr_conn_init(void) { /* Initialize connectivity bindings. */ @@ -393,10 +303,6 @@ void conn_mgr_conn_init(void) CONN_MGR_CONN_IFACE_EVENTS_MASK); net_mgmt_add_event_callback(&conn_mgr_conn_iface_cb); - net_mgmt_init_event_callback(&conn_mgr_conn_self_cb, conn_mgr_conn_self_handler, - CONN_MGR_CONN_SELF_EVENTS_MASK); - net_mgmt_add_event_callback(&conn_mgr_conn_self_cb); - /* Trigger any initial automated behaviors for ifaces */ STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { if (binding->impl->api) { diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 0290f3d2b5a2..18f5c7da73fa 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -36,11 +36,7 @@ #define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ NET_EVENT_IF_UP) -#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP |\ - NET_EVENT_IF_DOWN) - -#define CONN_MGR_CONN_SELF_EVENTS_MASK (NET_EVENT_CONN_IF_TIMEOUT | \ - NET_EVENT_CONN_IF_FATAL_ERROR) +#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP) #define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ NET_EVENT_IPV6_ADDR_DEL | \ diff --git a/tests/net/conn_mgr/src/main.c b/tests/net/conn_mgr/src/main.c index a7680ff05878..5b7584ab4173 100644 --- a/tests/net/conn_mgr/src/main.c +++ b/tests/net/conn_mgr/src/main.c @@ -44,6 +44,9 @@ static void reset_test_iface(struct net_if *iface) struct in6_addr *ll_ipv6; if (net_if_is_admin_up(iface)) { + if (conn_mgr_if_is_bound(iface)) { + (void)conn_mgr_if_disconnect(iface); + } (void)net_if_down(iface); } @@ -203,6 +206,10 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_disconnect(ifa), 0, + "conn_mgr_if_disconnect should succeed for ifa."); + } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect no events */ @@ -212,6 +219,10 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifb."); + } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect connectivity loss */ @@ -255,6 +266,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifb."); + } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -285,6 +300,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifba."); + } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -294,6 +313,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_disconnect(ifa), 0, + "conn_mgr_if_disconnect should succeed for ifa."); + } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect connectivity lost */ @@ -330,6 +353,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifb."); + } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -341,6 +368,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -361,6 +392,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) zassert_equal(stats.dconn_iface, ifa, "ifa should be blamed."); /* Take B down */ + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_disconnect(ifb), 0, + "conn_mgr_if_disconnect should succeed for ifb."); + } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -531,6 +566,10 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* (10 -> 00): Lose oper-up from semi-ready state */ /* Take iface down */ + if (conn_mgr_if_is_bound(iface)) { + zassert_equal(conn_mgr_if_disconnect(iface), 0, + "conn_mgr_if_disconnect should succeed."); + } zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); /* Verify there are no events fired */ @@ -580,6 +619,10 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* (11 -> 01): Lose oper-up from ready state */ /* Take iface down */ + if (conn_mgr_if_is_bound(iface)) { + zassert_equal(conn_mgr_if_disconnect(iface), 0, + "conn_mgr_if_disconnect should succeed."); + } zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); /* Verify events are fired */ diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index e7154329d5a8..fbb88d7732d1 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -59,9 +59,8 @@ static void reset_test_iface_state(struct net_if *iface) iface_binding->flags = 0; iface_binding->timeout = CONN_MGR_IF_NO_TIMEOUT; - /* Disable auto-connect and auto-down */ + /* Disable auto-connect */ conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT, true); - conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_DOWN, true); } if (iface_data) { @@ -920,224 +919,4 @@ ZTEST(conn_mgr_conn, test_auto_connect) zassert_true(net_if_is_up(ifa1), "Auto-connect should succeed if enabled."); } -/* Verify that if auto-down is enabled, disconnecting an iface also takes it down, - * regardless of whether persistence is enabled, but only if auto-down is disabled. - */ -ZTEST(conn_mgr_conn, test_auto_down_disconnect) -{ - /* For convenience, use auto-connect for this test. */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); - - /* Enable auto-down, disable persistence */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify connected */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Connection should succeed."); - - /* Disconnect iface */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, - "conn_mgr_if_disconnect should succeed."); - - /* Verify down */ - k_sleep(K_MSEC(1)); - zassert_false(net_if_is_admin_up(ifa1), - "Auto-down should trigger on direct disconnect."); - - - - /* Enable persistence */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify connected */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Connection should succeed."); - - /* Disconnect iface */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, - "conn_mgr_if_disconnect should succeed."); - - /* Verify down */ - k_sleep(K_MSEC(1)); - zassert_false(net_if_is_admin_up(ifa1), - "Auto-down should trigger on direct disconnect, even if persistence is enabled."); - - - - /* Disable auto-down */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify connected */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Connection should succeed."); - - /* Disconnect iface */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, - "conn_mgr_if_disconnect should succeed."); - - /* Verify up */ - zassert_true(net_if_is_admin_up(ifa1), - "Auto-down should not trigger if it is disabled."); -} - -/* Verify that auto-down takes an iface down if connection is lost, but only if persistence is not - * enabled, and only if auto-down is enabled. - */ -ZTEST(conn_mgr_conn, test_auto_down_conn_loss) -{ - /* For convenience, use auto-connect for this test. */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); - - /* Enable auto-down, disable persistence */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify connected */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Connection should succeed."); - - /* Simulate connection loss */ - simulate_connection_loss(ifa1); - - /* Verify down */ - k_sleep(K_MSEC(1)); - zassert_false(net_if_is_admin_up(ifa1), - "Auto-down should trigger on connection loss if persistence is disabled."); - - /* Enable persistence */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify connected */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Connection should succeed."); - - /* Simulate connection loss */ - simulate_connection_loss(ifa1); - - /* Verify up */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_admin_up(ifa1), - "Auto-down should not trigger on connection loss if persistence is enabled."); - - /* Disable persistence and disable auto-down*/ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); - - /* Reconnect iface */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); - - /* Verify connected */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Connection should succeed."); - - /* Simulate connection loss */ - simulate_connection_loss(ifa1); - - /* Verify up */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_admin_up(ifa1), - "Auto-down should not trigger on connection loss if it is disabled."); -} - -/* Verify that timeout takes the iface down, even if - * persistence is enabled, but only if auto-down is enabled. - */ -ZTEST(conn_mgr_conn, test_auto_down_timeout) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* For convenience, use auto-connect for this test. */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); - - /* Enable auto-down and persistence*/ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); - - /* Schedule timeout */ - ifa1_data->timeout = true; - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify iface down after timeout */ - k_sleep(SIMULATED_EVENT_WAIT_TIME); - zassert_false(net_if_is_admin_up(ifa1), - "Auto-down should trigger on connection timeout, even if persistence is enabled."); - - /* Disable auto-down */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); - - /* Take iface up (timing out again) */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify iface up after timeout */ - k_sleep(SIMULATED_EVENT_WAIT_TIME); - zassert_true(net_if_is_admin_up(ifa1), - "Auto-down should not trigger on connection timeout if it is disabled."); -} - - -/* Verify that fatal error takes the iface down, even if - * persistence is enabled, but only if auto-down is enabled. - */ -ZTEST(conn_mgr_conn, test_auto_down_fatal) -{ - /* For convenience, use auto-connect for this test. */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); - - /* Enable auto-down and persistence */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify connected */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Connection should succeed."); - - /* Raise fatal error */ - simulate_fatal_error(ifa1, -EAGAIN); - - /* Verify iface down after fatal error */ - k_sleep(SIMULATED_EVENT_WAIT_TIME); - zassert_false(net_if_is_admin_up(ifa1), - "Auto-down should trigger on fatal error, even if persistence is enabled."); - - /* Disable auto-down */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); - - /* Verify connected */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Connection should succeed."); - - /* Raise fatal error */ - simulate_fatal_error(ifa1, -EAGAIN); - - /* Verify iface still up after fatal error */ - k_sleep(SIMULATED_EVENT_WAIT_TIME); - zassert_true(net_if_is_admin_up(ifa1), - "Auto-down should not trigger on fatal error if it is disabled."); -} - - ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c index a0f2de45c545..c6e4cff6a2d0 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -67,16 +67,11 @@ static void simulate_timeout(struct net_if *target) simulate_event(target, 0); } -void simulate_fatal_error(struct net_if *target, int reason) +static void simulate_fatal_error(struct net_if *target, int reason) { simulate_event(target, reason); } -void simulate_connection_loss(struct net_if *target) -{ - net_if_dormant_on(target); -} - /* Connectivity implementations */ static void inc_call_count(struct test_conn_data *data, bool a) diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h index bab0c9b3aa9a..1df7e6d02011 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -80,25 +80,6 @@ CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); #define SIMULATED_EVENT_DELAY_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS) #define SIMULATED_EVENT_WAIT_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS + 10) -/* Helper API for controlling implementations from tests */ - -/** - * @brief Simulate a connection loss on the target iface. - * - * @param target - iface to simulate connection loss on. - */ -void simulate_connection_loss(struct net_if *target); - -/** - * @brief Simulate a fatal error on the target iface - * - * Please do not simulate events on more than one iface at a time. - * - * @param target - iface to simulate fatal error on. - * @param reason - Reason to be given for the fatal error. - */ -void simulate_fatal_error(struct net_if *target, int reason); - #ifdef __cplusplus } #endif From 0622f0d61012cb67f0c3fb0c81e351763cdd438c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:28 +0200 Subject: [PATCH 277/528] Revert "[nrf fromlist] net: conn_mgr: Support Auto-Connect" This reverts commit 4e087cc2e96ed230ab4f0442757097b6b69e0d7f. Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 6 -- subsys/net/conn_mgr/conn_mgr_connectivity.c | 62 -------------------- subsys/net/conn_mgr/conn_mgr_private.h | 2 - tests/net/conn_mgr/src/main.c | 41 +++++++++++++ tests/net/conn_mgr_conn/src/main.c | 64 +-------------------- 5 files changed, 42 insertions(+), 133 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 52e116d38572..0b54224c448e 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -179,12 +179,6 @@ enum conn_mgr_if_flag { */ CONN_MGR_IF_PERSISTENT, - /* No auto-connect - * When set, conn_mgr will not automatically attempt to connect this iface when it reaches - * admin-up. - */ - CONN_MGR_IF_NO_AUTO_CONNECT, - /** @cond INTERNAL_HIDDEN */ /* Total number of flags - must be at the end of the enum */ CONN_MGR_NUM_IF_FLAGS, diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index fc4f628a8f76..2cc075074fbd 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -233,52 +233,8 @@ int conn_mgr_if_set_timeout(struct net_if *iface, int timeout) return 0; } -/* Automated behavior handling */ - -/** - * @brief Perform automated behaviors in response to ifaces going admin-up. - * - * @param iface - The iface which became admin-up. - */ -static void conn_mgr_conn_handle_iface_admin_up(struct net_if *iface) -{ - int err; - - /* Ignore ifaces that don't have connectivity implementations */ - if (!conn_mgr_if_is_bound(iface)) { - return; - } - - /* Ignore ifaces for which auto-connect is disabled */ - if (conn_mgr_if_get_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT)) { - return; - } - - /* Otherwise, automatically instruct the iface to connect */ - err = conn_mgr_if_connect(iface); - if (err < 0) { - NET_ERR("iface auto-connect failed: %d", err); - } -} - -static struct net_mgmt_event_callback conn_mgr_conn_iface_cb; -static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, - struct net_if *iface) -{ - if ((mgmt_event & CONN_MGR_CONN_IFACE_EVENTS_MASK) != mgmt_event) { - return; - } - - switch (NET_MGMT_GET_COMMAND(mgmt_event)) { - case NET_EVENT_IF_CMD_ADMIN_UP: - conn_mgr_conn_handle_iface_admin_up(iface); - break; - } -} - void conn_mgr_conn_init(void) { - /* Initialize connectivity bindings. */ STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { if (!(binding->impl->api)) { LOG_ERR("Connectivity implementation has NULL API, and will be treated as " @@ -297,22 +253,4 @@ void conn_mgr_conn_init(void) k_mutex_unlock(binding->mutex); } } - - /* Set up event listeners for automated behaviors */ - net_mgmt_init_event_callback(&conn_mgr_conn_iface_cb, conn_mgr_conn_iface_handler, - CONN_MGR_CONN_IFACE_EVENTS_MASK); - net_mgmt_add_event_callback(&conn_mgr_conn_iface_cb); - - /* Trigger any initial automated behaviors for ifaces */ - STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { - if (binding->impl->api) { - /* We need to fire conn_mgr_conn_handle_iface_admin_up for any - * (connectivity-enabled) ifaces that went admin-up before we registerred - * the event callback that typically handles this. - */ - if (net_if_is_admin_up(binding->iface)) { - conn_mgr_conn_handle_iface_admin_up(binding->iface); - } - } - } } diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 18f5c7da73fa..76dcd0c7f639 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -36,8 +36,6 @@ #define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ NET_EVENT_IF_UP) -#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP) - #define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ NET_EVENT_IPV6_ADDR_DEL | \ NET_EVENT_IPV6_DAD_SUCCEED | \ diff --git a/tests/net/conn_mgr/src/main.c b/tests/net/conn_mgr/src/main.c index 5b7584ab4173..f5399b92e743 100644 --- a/tests/net/conn_mgr/src/main.c +++ b/tests/net/conn_mgr/src/main.c @@ -186,6 +186,10 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_connect(ifa), 0, + "conn_mgr_if_connect should succeed for ifa."); + } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -198,6 +202,10 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -258,6 +266,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -280,6 +292,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_connect(ifa), 0, + "conn_mgr_if_connect should succeed for ifa."); + } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -292,6 +308,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -333,6 +353,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); + if (conn_mgr_if_is_bound(ifb)) { + zassert_equal(conn_mgr_if_connect(ifb), 0, + "conn_mgr_if_connect should succeed for ifb."); + } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -342,6 +366,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_connect(ifa), 0, + "conn_mgr_if_connect should succeed for ifa."); + } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -380,6 +408,10 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ + if (conn_mgr_if_is_bound(ifa)) { + zassert_equal(conn_mgr_if_disconnect(ifa), 0, + "conn_mgr_if_disconnect should succeed for ifa."); + } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect connectivity lost */ @@ -449,6 +481,11 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* Take iface up */ zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); + if (conn_mgr_if_is_bound(iface)) { + zassert_equal(conn_mgr_if_connect(iface), 0, + "conn_mgr_if_connect should succeed."); + } + /* Verify that no events have been fired yet */ k_sleep(EVENT_WAIT_TIME); stats = get_reset_stats(); @@ -606,6 +643,10 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* Take iface up */ zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); + if (conn_mgr_if_is_bound(iface)) { + zassert_equal(conn_mgr_if_connect(iface), 0, + "conn_mgr_if_connect should succeed."); + } /* Verify events are fired */ k_sleep(EVENT_WAIT_TIME); diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index fbb88d7732d1..373dcdd04265 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -55,12 +55,8 @@ static void reset_test_iface_state(struct net_if *iface) struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); if (iface_binding) { - /* Reset all flags and settings for the binding */ iface_binding->flags = 0; iface_binding->timeout = CONN_MGR_IF_NO_TIMEOUT; - - /* Disable auto-connect */ - conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT, true); } if (iface_data) { @@ -765,9 +761,6 @@ ZTEST(conn_mgr_conn, test_flags) { struct conn_mgr_conn_binding *ifa1_binding = conn_mgr_if_get_binding(ifa1); - /* Firstly, clear all flags (some are automatically enabled before each test) */ - ifa1_binding->flags = 0; - /* Try setting persistence flag */ zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true), 0, "Setting persistence flag should succeed for ifa1"); @@ -780,19 +773,6 @@ ZTEST(conn_mgr_conn, test_flags) zassert_equal(ifa1_binding->flags, BIT(CONN_MGR_IF_PERSISTENT), "Persistence flag set should affect conn struct"); - /* Try setting no-autoconnect flag */ - zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, true), 0, - "Setting no-autoconnect flag should succeed for ifa1"); - - /* Verify success */ - zassert_true(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT), - "No-autoconnect should be set for ifa1"); - - /* Verify that the conn struct agrees, since this is what implementations may use */ - zassert_equal(ifa1_binding->flags, - BIT(CONN_MGR_IF_PERSISTENT) | BIT(CONN_MGR_IF_NO_AUTO_CONNECT), - "Persistence flag set should affect conn struct"); - /* Try unsetting persistence flag */ zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false), 0, "Unsetting persistence flag should succeed for ifa1"); @@ -801,21 +781,9 @@ ZTEST(conn_mgr_conn, test_flags) zassert_false(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_PERSISTENT), "Persistence should be unset for ifa1"); - /* Verify that the conn struct agrees, since this is what implementations may use */ - zassert_equal(ifa1_binding->flags, BIT(CONN_MGR_IF_NO_AUTO_CONNECT), - "Persistence flag unset should affect conn struct"); - - /* Try unsetting no-autoconnect flag */ - zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false), 0, - "Clearing no-autoconnect flag should succeed for ifa1"); - - /* Verify success */ - zassert_false(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT), - "No-autoconnect should be set for ifa1"); - /* Verify that the conn struct agrees, since this is what implementations may use */ zassert_equal(ifa1_binding->flags, 0, - "No-autoconnect flag set should affect conn struct"); + "Persistence flag unset should affect conn struct"); } /* Verify that flag get/set fail and behave as expected respectively for invalid ifaces and @@ -889,34 +857,4 @@ ZTEST(conn_mgr_conn, test_timeout_invalid) "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnone"); } -/* Verify that auto-connect works as expected. */ -ZTEST(conn_mgr_conn, test_auto_connect) -{ - /* Disable auto-connect. - * Not strictly necessary, since this is the default for this suite, but do it anyways - * since this test case specifically focuses on auto-connect. - */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, true); - - /* Take the iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail."); - - /* Verify no connection */ - k_sleep(K_MSEC(1)); - zassert_false(net_if_is_up(ifa1), "Auto-connect should not trigger if disabled."); - - /* Take the iface down */ - zassert_equal(net_if_down(ifa1), 0, "net_if_down should not fail."); - - /* Enable auto-connect */ - conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); - - /* Take the iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail."); - - /* Verify connection */ - k_sleep(K_MSEC(1)); - zassert_true(net_if_is_up(ifa1), "Auto-connect should succeed if enabled."); -} - ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); From ba372399e4a385f66fb45049c5e6cc7548245f43 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:28 +0200 Subject: [PATCH 278/528] Revert "[nrf fromlist] net: conn_mgr: Minor fixes" This reverts commit d19310968bf7c435fc12b52b1db84117f009e5d2. Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 4 +- subsys/net/conn_mgr/conn_mgr_private.h | 2 +- tests/net/conn_mgr_conn/src/main.c | 42 +++++--------------- tests/net/conn_mgr_conn/src/test_conn_impl.c | 2 +- tests/net/conn_mgr_conn/src/test_conn_impl.h | 4 +- 5 files changed, 13 insertions(+), 41 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 0b54224c448e..cad0bdfb4d56 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -15,7 +15,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { @@ -34,8 +33,7 @@ extern "C" { /* Connectivity Events */ #define _NET_MGMT_CONN_LAYER NET_MGMT_LAYER(NET_MGMT_LAYER_L2) #define _NET_MGMT_CONN_CODE NET_MGMT_LAYER_CODE(0x207) -#define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE | \ - NET_MGMT_EVENT_BIT) +#define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE) #define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_BASE) enum net_event_ethernet_cmd { diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 76dcd0c7f639..b21e61bf0aa6 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -26,7 +26,7 @@ /* Configuration flags */ #define CONN_MGR_IF_IGNORED BIT(7) -/* Internal state flags */ +/* Internal state flags*/ #define CONN_MGR_IF_READY BIT(14) /* Event flags */ diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index 373dcdd04265..dbe1d4cb3374 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -29,12 +29,7 @@ static inline struct test_conn_data *conn_mgr_if_get_data(struct net_if *iface) return binding->ctx; } -/** - * @brief Reset the network state of the provided iface. - * - * @param iface - iface to reset. - */ -static void reset_test_iface_networking(struct net_if *iface) +static void reset_test_iface(struct net_if *iface) { if (net_if_is_admin_up(iface)) { (void)net_if_down(iface); @@ -42,15 +37,7 @@ static void reset_test_iface_networking(struct net_if *iface) /* Some tests can leave the iface in a bad state where it is admin-down but not dormant */ net_if_dormant_on(iface); -} -/** - * @brief Reset testing state for the provided iface. - * - * @param iface - iface to reset. - */ -static void reset_test_iface_state(struct net_if *iface) -{ struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface); struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); @@ -111,22 +98,12 @@ static void conn_mgr_conn_handler(struct net_mgmt_event_callback *cb, static void conn_mgr_conn_before(void *data) { ARG_UNUSED(data); - reset_test_iface_networking(ifa1); - reset_test_iface_networking(ifa2); - reset_test_iface_networking(ifb); - reset_test_iface_networking(ifni); - reset_test_iface_networking(ifnone); - reset_test_iface_networking(ifnull); - - /* Allow any triggered events to shake out */ - k_sleep(SIMULATED_EVENT_WAIT_TIME); - - reset_test_iface_state(ifa1); - reset_test_iface_state(ifa2); - reset_test_iface_state(ifb); - reset_test_iface_state(ifni); - reset_test_iface_state(ifnone); - reset_test_iface_state(ifnull); + reset_test_iface(ifa1); + reset_test_iface(ifa2); + reset_test_iface(ifb); + reset_test_iface(ifni); + reset_test_iface(ifnone); + reset_test_iface(ifnull); k_mutex_lock(&event_mutex, K_FOREVER); @@ -194,7 +171,6 @@ ZTEST(conn_mgr_conn, test_connect_disconnect) zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); zassert_equal(net_if_up(ifa2), 0, "net_if_up should not fail"); zassert_equal(net_if_up(ifb), 0, "net_if_up should not fail"); - k_sleep(K_MSEC(1)); /* Verify ifaces are still disconnected */ zassert_false(net_if_is_up(ifa1), "Ifaces must be disconnected before test"); @@ -550,7 +526,7 @@ ZTEST(conn_mgr_conn, test_connect_timeout) zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); /* Ensure timeout event is fired */ - k_sleep(SIMULATED_EVENT_WAIT_TIME); + k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); k_mutex_lock(&event_mutex, K_FOREVER); stats = test_event_stats; @@ -581,7 +557,7 @@ ZTEST(conn_mgr_conn, test_connect_fatal_error) zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); /* Ensure fatal_error event is fired */ - k_sleep(SIMULATED_EVENT_WAIT_TIME); + k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); k_mutex_lock(&event_mutex, K_FOREVER); stats = test_event_stats; diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c index c6e4cff6a2d0..8d2395160590 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -57,7 +57,7 @@ static void simulate_event(struct net_if *target, int event) simulated_event = event; simulated_event_iface = target; - k_work_reschedule(&simulate_event_work, SIMULATED_EVENT_DELAY_TIME); + k_work_reschedule(&simulate_event_work, K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS)); k_mutex_unlock(&simulated_event_mutex); } diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h index 1df7e6d02011..6408bb802cfc 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -76,9 +76,7 @@ CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_N); #define TEST_L2_CONN_IMPL_NI_CTX_TYPE struct test_conn_data CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); -#define SIMULATED_EVENT_DELAY_MS 100 -#define SIMULATED_EVENT_DELAY_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS) -#define SIMULATED_EVENT_WAIT_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS + 10) +#define SIMULATED_EVENT_DELAY_SECONDS 5 #ifdef __cplusplus } From 7409338e2b03cedba9966b6717b8bdd0c7a85008 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:28 +0200 Subject: [PATCH 279/528] Revert "[nrf fromlist] net: conn_mgr: Add test suite" This reverts commit 30e2e33a84913c834725c550c0b87c541da2eb44. Signed-off-by: Robert Lubos --- tests/net/conn_mgr/CMakeLists.txt | 9 - tests/net/conn_mgr/prj.conf | 30 - tests/net/conn_mgr/src/main.c | 939 --------------------------- tests/net/conn_mgr/src/test_ifaces.c | 155 ----- tests/net/conn_mgr/src/test_ifaces.h | 27 - tests/net/conn_mgr/testcase.yaml | 11 - 6 files changed, 1171 deletions(-) delete mode 100644 tests/net/conn_mgr/CMakeLists.txt delete mode 100644 tests/net/conn_mgr/prj.conf delete mode 100644 tests/net/conn_mgr/src/main.c delete mode 100644 tests/net/conn_mgr/src/test_ifaces.c delete mode 100644 tests/net/conn_mgr/src/test_ifaces.h delete mode 100644 tests/net/conn_mgr/testcase.yaml diff --git a/tests/net/conn_mgr/CMakeLists.txt b/tests/net/conn_mgr/CMakeLists.txt deleted file mode 100644 index dba2a43f052e..000000000000 --- a/tests/net/conn_mgr/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(iface) - -target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/conn_mgr/prj.conf b/tests/net/conn_mgr/prj.conf deleted file mode 100644 index 1e60d8327ed2..000000000000 --- a/tests/net/conn_mgr/prj.conf +++ /dev/null @@ -1,30 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NET_TEST=y -CONFIG_NET_IPV6=y -CONFIG_NET_IPV4=y -CONFIG_NET_L2_ETHERNET=y -CONFIG_NET_MAX_CONTEXTS=4 -CONFIG_NET_L2_DUMMY=y -CONFIG_NET_CONNECTION_MANAGER=y -CONFIG_ENTROPY_GENERATOR=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NET_IPV6_MLD=n -CONFIG_NET_PKT_TX_COUNT=10 -CONFIG_NET_PKT_RX_COUNT=5 -CONFIG_NET_BUF_RX_COUNT=10 -CONFIG_NET_BUF_TX_COUNT=10 -CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 -CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2 -CONFIG_NET_MAX_NEXTHOPS=8 -CONFIG_NET_IPV6_MAX_NEIGHBORS=8 -CONFIG_NET_IPV6_ND=n -CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y -CONFIG_NET_IF_MAX_IPV4_COUNT=6 -CONFIG_NET_IF_MAX_IPV6_COUNT=6 -CONFIG_TEST_USERSPACE=y - -# Enable for help debugging this test suite: -# CONFIG_NET_LOG=y -# CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL_DBG=y -# CONFIG_NET_IF_LOG_LEVEL_DBG=y diff --git a/tests/net/conn_mgr/src/main.c b/tests/net/conn_mgr/src/main.c deleted file mode 100644 index f5399b92e743..000000000000 --- a/tests/net/conn_mgr/src/main.c +++ /dev/null @@ -1,939 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include "conn_mgr_private.h" -#include "test_ifaces.h" -#include - -#include - -/* Time to wait for NET_MGMT events to finish firing */ -#define EVENT_WAIT_TIME K_MSEC(1) - -/* Time to wait for IPv6 DAD to finish */ -#define DAD_WAIT_TIME K_MSEC(110) - -/* IP addresses -- Two of each are needed because address sharing will cause address removal to - * fail silently (Address is only removed from one iface). - */ -static struct in_addr test_ipv4_a = { { { 10, 0, 0, 1 } } }; -static struct in_addr test_ipv4_b = { { { 10, 0, 0, 2 } } }; -static struct in6_addr test_ipv6_a = { { { - 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 -} } }; - -/* Helpers */ -static void reset_test_iface(struct net_if *iface) -{ - struct in6_addr *ll_ipv6; - - if (net_if_is_admin_up(iface)) { - if (conn_mgr_if_is_bound(iface)) { - (void)conn_mgr_if_disconnect(iface); - } - (void)net_if_down(iface); - } - - net_if_ipv4_addr_rm(iface, &test_ipv4_a); - net_if_ipv4_addr_rm(iface, &test_ipv4_b); - net_if_ipv6_addr_rm(iface, &test_ipv6_a); - - /* DAD adds the link-local address automatically. Check for it, and remove it if present. */ - ll_ipv6 = net_if_ipv6_get_ll(iface, NET_ADDR_ANY_STATE); - if (ll_ipv6) { - net_if_ipv6_addr_rm(iface, ll_ipv6); - } - - conn_mgr_unignore_iface(iface); -} - -/* Thread-safe test statistics */ -K_MUTEX_DEFINE(stats_mutex); -static struct test_stats { - /** The number of times conn_mgr has raised a connect event */ - int conn_count; - - /** The number of times conn_mgr has raised a disconnect event */ - int dconn_count; - - /** The total number of connectivity events fired by conn_mgr */ - int event_count; - - /** The iface blamed for the last disconnect event */ - struct net_if *dconn_iface; - - /** The iface blamed for the last connect event */ - struct net_if *conn_iface; -} global_stats; - -static void reset_stats(void) -{ - k_mutex_lock(&stats_mutex, K_FOREVER); - - global_stats.conn_count = 0; - global_stats.dconn_count = 0; - global_stats.event_count = 0; - global_stats.dconn_iface = NULL; - global_stats.conn_iface = NULL; - - k_mutex_unlock(&stats_mutex); -} - -/** - * @brief Copy and then reset global test stats. - * - * @return struct test_stats -- The copy of the global test stats struct before it was reset - */ -static struct test_stats get_reset_stats(void) -{ - struct test_stats copy; - - k_mutex_lock(&stats_mutex, K_FOREVER); - copy = global_stats; - reset_stats(); - k_mutex_unlock(&stats_mutex); - return copy; -} - -/* Callback hooks */ -struct net_mgmt_event_callback l4_callback; - -void l4_handler(struct net_mgmt_event_callback *cb, uint32_t event, struct net_if *iface) -{ - if (event == NET_EVENT_L4_CONNECTED) { - k_mutex_lock(&stats_mutex, K_FOREVER); - global_stats.conn_count += 1; - global_stats.event_count += 1; - global_stats.conn_iface = iface; - k_mutex_unlock(&stats_mutex); - } else if (event == NET_EVENT_L4_DISCONNECTED) { - k_mutex_lock(&stats_mutex, K_FOREVER); - global_stats.dconn_count += 1; - global_stats.event_count += 1; - global_stats.dconn_iface = iface; - k_mutex_unlock(&stats_mutex); - } -} - - -/* Test suite shared functions & routines */ - -static void *conn_mgr_setup(void) -{ - net_mgmt_init_event_callback( - &l4_callback, l4_handler, NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED - ); - net_mgmt_add_event_callback(&l4_callback); - return NULL; -} - - -static void conn_mgr_before(void *data) -{ - ARG_UNUSED(data); - - reset_test_iface(if_simp_a); - reset_test_iface(if_simp_b); - reset_test_iface(if_conn_a); - reset_test_iface(if_conn_b); - - /* Allow any triggered events to shake out */ - k_sleep(EVENT_WAIT_TIME); - - reset_stats(); -} - -/** - * @brief Cycles two ifaces through several transitions from readiness to unreadiness. - * - * Ifaces are assigned a single IPv4 address at the start, and cycled through oper-states, since - * the other manners in which an iface can become L4-ready are covered by cycle_iface_pre_ready - * - * It is not necessary to cover all possible state transitions, only half of them, since - * this will be called twice by the test suites for each combination of iface type (except - * combinations where both ifaces are of the same type). - */ - -static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) -{ - struct test_stats stats; - - /* Add IPv4 addresses */ - net_if_ipv4_addr_add(ifa, &test_ipv4_a, NET_ADDR_MANUAL, 0); - net_if_ipv4_addr_add(ifb, &test_ipv4_b, NET_ADDR_MANUAL, 0); - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take A up */ - zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } - - /* Expect connectivity gained */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.conn_count, 1, - "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); - - /* Take B up */ - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } - zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } - zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); - - /* Expect connectivity loss */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.dconn_count, 1, - "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.dconn_iface, ifb, "ifb should be blamed."); -} - -/** - * @brief Ignores and then toggles ifb's readiness several times, ensuring no events are fired. - * - * At several points, change the readiness state of ifa and ensure events are fired. - * - * @param ifa - * @param ifb - */ -static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) -{ - struct test_stats stats; - - /* Ignore B */ - conn_mgr_ignore_iface(ifb); - - /* Add IPv4 addresses */ - net_if_ipv4_addr_add(ifa, &test_ipv4_a, NET_ADDR_MANUAL, 0); - net_if_ipv4_addr_add(ifb, &test_ipv4_b, NET_ADDR_MANUAL, 0); - - /* Set one: Change A state between B state toggles */ - - /* Take B up */ - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } - zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take A up */ - zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } - - /* Expect connectivity gained */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.conn_count, 1, - "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); - - /* Take B up */ - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifba."); - } - zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } - zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); - - /* Expect connectivity lost */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.dconn_count, 1, - "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.dconn_iface, ifa, "ifa should be blamed."); - - - /* Set two: Change A state during B state toggles */ - - /* Take B up */ - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take A up */ - zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } - - /* Expect connectivity gained */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.conn_count, 1, - "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); - - /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } - zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - - /* Take B up */ - zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } - zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); - - /* Expect connectivity lost */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.dconn_count, 1, - "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.dconn_iface, ifa, "ifa should be blamed."); - - /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } - zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); - - /* Expect no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); -} - -enum ip_order { - IPV4_FIRST, - IPV6_FIRST -}; - -/** - * @brief Cycles a single iface through all possible ready and pre-ready states, - * ensuring the correct events are observed and generated by conn_mgr. - * - * Ifaces can be in one of four states that are relevant to L4 readiness: - * 00: oper-down, no IPs associated (unready state) - * 01: Has IP, is oper-down (semi-ready state) - * 10: Is oper-up, has no IP (semi-ready state) - * 11: Has IP and is oper-up (ready state) - * - * In total there are eight possible state transitions: - * - * (00 -> 10): Gain oper-up from unready state - * (10 -> 11): Gain IP from semi-ready state - * (11 -> 10): Lose IP from ready state - * (10 -> 00): Lose oper-up from semi-ready state - * (00 -> 01): Gain IP from unready state - * (01 -> 11): Gain Oper-up from semi-ready state - * (11 -> 01): Lose oper-up from ready state - * (01 -> 00): Lose IP from semi-ready state - * - * We test these state transitions in that order. - * - * This is slightly complicated by the fact that ifaces can be assigned multiple IPs, and multiple - * types of IPs. Whenever IPs are assigned or removed, two of them, an IPv6 and IPv4 address is - * added or removed. - * - * @param iface - * @param ifa_ipm - */ -static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) -{ - struct test_stats stats; - - /* (00 -> 10): Gain oper-up from unready state */ - - /* Take iface up */ - zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); - - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_connect(iface), 0, - "conn_mgr_if_connect should succeed."); - } - - /* Verify that no events have been fired yet */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* (10 -> 11): Gain IP from semi-ready state */ - switch (ifa_ipm) { - case IPV4_FIRST: - /* Add IPv4 */ - net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0); - - /* Verify correct events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.conn_count, 1, - "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.conn_iface, iface, "The test iface should be blamed."); - - - /* Add IPv6 */ - net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0); - k_sleep(DAD_WAIT_TIME); - - /* Verify no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - break; - case IPV6_FIRST: - /* Add IPv6 */ - net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0); - k_sleep(DAD_WAIT_TIME); - - /* Verify correct events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.conn_count, 1, - "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.conn_iface, iface, "The test iface should be blamed."); - - /* Add IPv4 */ - net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0); - - /* Verify no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - break; - } - - /* (11 -> 10): Lose IP from ready state */ - switch (ifa_ipm) { - case IPV4_FIRST: - /* Remove IPv4 */ - zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a), - "IPv4 removal should succeed."); - - /* Verify no events (because IPv6 addr is still active) */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Remove IPv6 */ - zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a), - "IPv6 removal should succeed."); - - /* Verify correct events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.dconn_count, 1, - "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity " - "is lost."); - zassert_equal(stats.dconn_iface, iface, "The test iface should be blamed."); - - break; - case IPV6_FIRST: - /* Remove IPv6 */ - zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a), - "IPv6 removal should succeed."); - - /* Verify no events (because IPv4 addr is still active) */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* Remove IPv4 */ - zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a), - "IPv4 removal should succeed."); - - /* Verify correct events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.dconn_count, 1, - "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity " - "is lost."); - zassert_equal(stats.dconn_iface, iface, "The test iface should be blamed."); - - break; - } - - /* (10 -> 00): Lose oper-up from semi-ready state */ - - /* Take iface down */ - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_disconnect(iface), 0, - "conn_mgr_if_disconnect should succeed."); - } - zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); - - /* Verify there are no events fired */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* (00 -> 01): Gain IP from unready state */ - - /* Add IP addresses to iface */ - switch (ifa_ipm) { - case IPV4_FIRST: - /* Add IPv4 and IPv6 */ - net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0); - net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0); - k_sleep(DAD_WAIT_TIME); - break; - case IPV6_FIRST: - /* Add IPv6 then IPv4 */ - net_if_ipv6_addr_add(iface, &test_ipv6_a, NET_ADDR_MANUAL, 0); - k_sleep(DAD_WAIT_TIME); - net_if_ipv4_addr_add(iface, &test_ipv4_a, NET_ADDR_MANUAL, 0); - break; - } - - /* Verify that no events are fired */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); - - /* (01 -> 11): Gain Oper-up from semi-ready state */ - - /* Take iface up */ - zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_connect(iface), 0, - "conn_mgr_if_connect should succeed."); - } - - /* Verify events are fired */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.conn_count, 1, - "NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_CONNECTED should be fired when connectivity is gained."); - zassert_equal(stats.conn_iface, iface, "The test iface should be blamed."); - - /* (11 -> 01): Lose oper-up from ready state */ - - /* Take iface down */ - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_disconnect(iface), 0, - "conn_mgr_if_disconnect should succeed."); - } - zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); - - /* Verify events are fired */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.dconn_count, 1, - "NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_DISCONNECTED should be fired when connectivity is lost."); - zassert_equal(stats.dconn_iface, iface, "The test iface should be blamed."); - - /* (01 -> 00): Lose IP from semi-ready state */ - - /* Remove IPs */ - switch (ifa_ipm) { - case IPV4_FIRST: - /* Remove IPv4 then IPv6 */ - zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a), - "IPv4 removal should succeed."); - zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a), - "IPv6 removal should succeed."); - break; - case IPV6_FIRST: - /* Remove IPv6 then IPv4 */ - zassert_true(net_if_ipv6_addr_rm(iface, &test_ipv6_a), - "IPv6 removal should succeed."); - zassert_true(net_if_ipv4_addr_rm(iface, &test_ipv4_a), - "IPv4 removal should succeed."); - break; - } - - /* Verify no events fired */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connectivity availability did not change."); -} - -/* Cases */ - -/* Make sure all readiness transitions of a pair of connectivity-enabled ifaces results in all - * expected events. - */ -ZTEST(conn_mgr, test_cycle_ready_CC) -{ - cycle_ready_ifaces(if_conn_a, if_conn_b); -} - -/* Make sure half of all readiness transitions of a connectivity-enabled iface and a simple - * iface results in all expected events. - */ -ZTEST(conn_mgr, test_cycle_ready_CNC) -{ - cycle_ready_ifaces(if_conn_a, if_simp_a); -} - -/* Make sure the other half of all readiness transitions of a connectivity-enabled iface and a - * simple iface results in all expected events. - */ -ZTEST(conn_mgr, test_cycle_ready_NCC) -{ - cycle_ready_ifaces(if_simp_a, if_conn_a); -} - -/* Make sure all readiness transitions of a pair of simple ifaces results in all expected events. - */ -ZTEST(conn_mgr, test_cycle_ready_NCNC) -{ - cycle_ready_ifaces(if_simp_a, if_simp_b); -} - -/* Make sure that a simple iface can be successfully ignored without interfering with the events - * fired by another simple iface - */ -ZTEST(conn_mgr, test_cycle_ready_NCINC) -{ - cycle_ignored_iface(if_simp_a, if_simp_b); -} - -/* Make sure that a connectivity-enabled iface can be successfully ignored without interfering - * with the events fired by another connectivity-enabled iface - */ -ZTEST(conn_mgr, test_cycle_ready_CIC) -{ - cycle_ignored_iface(if_conn_a, if_conn_b); -} - -/* Make sure that a connectivity-enabled iface can be successfully ignored without interfering - * with the events fired by a simple iface - */ -ZTEST(conn_mgr, test_cycle_ready_CINC) -{ - cycle_ignored_iface(if_conn_a, if_simp_a); -} - -/* Make sure that a simple iface can be successfully ignored without interfering - * with the events fired by a connectivity-enabled iface - */ -ZTEST(conn_mgr, test_cycle_ready_NCIC) -{ - cycle_ignored_iface(if_simp_a, if_conn_a); -} - -/* Make sure that DAD readiness is actually verified by conn_mgr */ -ZTEST(conn_mgr, test_DAD) -{ - struct test_stats stats; - - /* This test specifically requires DAD to function */ - Z_TEST_SKIP_IFNDEF(CONFIG_NET_IPV6_DAD); - - /* Take iface up */ - zassert_equal(net_if_up(if_simp_a), 0, "net_if_up should succeed."); - - /* Add IPv6 */ - net_if_ipv6_addr_add(if_simp_a, &test_ipv6_a, NET_ADDR_MANUAL, 0); - - /* After a delay too short for DAD, ensure no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired before DAD success."); - - /* After a delay long enough for DAD, ensure connectivity acquired */ - k_sleep(DAD_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.conn_count, 1, - "NET_EVENT_L4_CONNECTED should be fired after DAD success."); -} - -/* Test whether ignoring and un-ignoring a ready iface fires the appropriate events */ -ZTEST(conn_mgr, test_ignore_while_ready) -{ - struct test_stats stats; - - /* Ignore iface */ - conn_mgr_ignore_iface(if_simp_a); - - /* Add IP and take iface up */ - net_if_ipv4_addr_add(if_simp_a, &test_ipv4_a, NET_ADDR_MANUAL, 0); - zassert_equal(net_if_up(if_simp_a), 0, "net_if_up should succeed for if_simp_a."); - - /* Ensure no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if connecting iface is ignored."); - - /* Un-ignore iface */ - conn_mgr_unignore_iface(if_simp_a); - - /* Ensure connectivity gained */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.conn_count, 1, - "NET_EVENT_L4_CONNECTED should be fired when online iface is unignored."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_CONNECTED should be fired."); - zassert_equal(stats.conn_iface, if_simp_a, "if_simp_a should be blamed."); - - /* Ignore iface */ - conn_mgr_ignore_iface(if_simp_a); - - /* Ensure connectivity lost */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.dconn_count, 1, - "NET_EVENT_L4_DISCONNECTED should be fired when online iface is ignored."); - zassert_equal(stats.event_count, 1, - "Only NET_EVENT_L4_DISCONNECTED should be fired."); - zassert_equal(stats.dconn_iface, if_simp_a, "if_simp_a should be blamed"); - - /* Take iface down*/ - zassert_equal(net_if_down(if_simp_a), 0, "net_if_down should succeed for if_simp_a."); - - /* Ensure no events */ - k_sleep(EVENT_WAIT_TIME); - stats = get_reset_stats(); - zassert_equal(stats.event_count, 0, - "No events should be fired if disconnecting iface is ignored."); -} - -/* Test L2 and iface ignore API */ -ZTEST(conn_mgr, test_ignores) -{ - /* Ignore if_simp_a, ensuring if_simp_b is unaffected */ - conn_mgr_ignore_iface(if_simp_a); - zassert_true(conn_mgr_is_iface_ignored(if_simp_a), - "if_simp_a should be ignored."); - zassert_false(conn_mgr_is_iface_ignored(if_simp_b), - "if_simp_b should not be affected."); - - /* Ignore if_simp_b, ensuring if_simp_a is unaffected */ - conn_mgr_ignore_iface(if_simp_b); - zassert_true(conn_mgr_is_iface_ignored(if_simp_b), - "if_simp_b should be ignored."); - zassert_true(conn_mgr_is_iface_ignored(if_simp_a), - "if_simp_a should not be affected."); - - /* Unignore if_simp_a, ensuring if_simp_b is unaffected */ - conn_mgr_unignore_iface(if_simp_a); - zassert_false(conn_mgr_is_iface_ignored(if_simp_a), - "if_simp_a should be unignored."); - zassert_true(conn_mgr_is_iface_ignored(if_simp_b), - "if_simp_b should not be affected."); - - /* Unignore if_simp_b, ensuring if_simp_a is unaffected */ - conn_mgr_unignore_iface(if_simp_b); - zassert_false(conn_mgr_is_iface_ignored(if_simp_b), - "if_simp_b should be unignored."); - zassert_false(conn_mgr_is_iface_ignored(if_simp_a), - "if_simp_a should not be affected."); - - /* Ignore the entire DUMMY_L2, ensuring all ifaces except if_dummy_eth are affected */ - conn_mgr_ignore_l2(&NET_L2_GET_NAME(DUMMY)); - zassert_true(conn_mgr_is_iface_ignored(if_simp_a), - "All DUMMY_L2 ifaces should be ignored."); - zassert_true(conn_mgr_is_iface_ignored(if_simp_b), - "All DUMMY_L2 ifaces should be ignored."); - zassert_true(conn_mgr_is_iface_ignored(if_conn_a), - "All DUMMY_L2 ifaces should be ignored."); - zassert_true(conn_mgr_is_iface_ignored(if_conn_b), - "All DUMMY_L2 ifaces should be ignored."); - zassert_false(conn_mgr_is_iface_ignored(if_dummy_eth), - "if_dummy_eth should not be affected."); - - /* Unignore the entire DUMMY_L2, ensuring all ifaces except if_dummy_eth are affected */ - conn_mgr_unignore_l2(&NET_L2_GET_NAME(DUMMY)); - zassert_false(conn_mgr_is_iface_ignored(if_simp_a), - "All DUMMY_L2 ifaces should be unignored."); - zassert_false(conn_mgr_is_iface_ignored(if_simp_b), - "All DUMMY_L2 ifaces should be unignored."); - zassert_false(conn_mgr_is_iface_ignored(if_conn_a), - "All DUMMY_L2 ifaces should be unignored."); - zassert_false(conn_mgr_is_iface_ignored(if_conn_b), - "All DUMMY_L2 ifaces should be unignored."); - zassert_false(conn_mgr_is_iface_ignored(if_dummy_eth), - "if_dummy_eth should not be affected."); -} - -/* Make sure all state transitions of a single connectivity-enabled iface result in all expected - * events. Perform IPv4 changes before IPv6 changes. - */ -ZTEST(conn_mgr, test_cycle_states_connected_ipv46) -{ - cycle_iface_states(if_conn_a, IPV4_FIRST); -} - -/* Make sure all state transitions of a single connectivity-enabled iface result in all expected - * events. Perform IPv6 changes before IPv4 changes. - */ -ZTEST(conn_mgr, test_cycle_states_connected_ipv64) -{ - cycle_iface_states(if_conn_a, IPV6_FIRST); -} - -/* Make sure all state transitions of a single simple iface result in all expected events. - * Perform IPv4 changes before IPv6 changes. - */ -ZTEST(conn_mgr, test_cycle_states_simple_ipv46) -{ - cycle_iface_states(if_simp_a, IPV4_FIRST); -} - -/* Make sure all state transitions of a single simple iface result in all expected events. - * Perform IPv6 changes before IPv4 changes. - */ -ZTEST(conn_mgr, test_cycle_states_simple_ipv64) -{ - cycle_iface_states(if_simp_a, IPV6_FIRST); -} - -ZTEST_SUITE(conn_mgr, NULL, conn_mgr_setup, conn_mgr_before, NULL, NULL); diff --git a/tests/net/conn_mgr/src/test_ifaces.c b/tests/net/conn_mgr/src/test_ifaces.c deleted file mode 100644 index 6dd0ab4ded9f..000000000000 --- a/tests/net/conn_mgr/src/test_ifaces.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include -#include -#include "test_ifaces.h" - -/* Create test ifaces */ - -/* Generic iface initializer, shared by all test ifaces */ -static void test_iface_init(struct net_if *iface) -{ - /* Fake link layer address is needed to silence assertions inside the net core */ - static uint8_t fake_lladdr[] = { 0x01 }; - - net_if_set_link_addr(iface, fake_lladdr, sizeof(fake_lladdr), NET_LINK_DUMMY); - - /* Do not automatically start the iface */ - net_if_flag_set(iface, NET_IF_NO_AUTO_START); -} - -/* Mandatory stub for NET_DEVICE_INIT */ -static int test_iface_netdev_init(const struct device *dev) -{ - return 0; -} - -/* This is needed specifically for IPv6 DAD. - * DAD tries to send a packet, and the test will hang if send is not implemented. - */ -static int test_iface_send(const struct device *dev, struct net_pkt *pkt) -{ - return 0; -} - -static struct dummy_api test_iface_api = { - .iface_api.init = test_iface_init, - .send = test_iface_send, -}; - -static struct ethernet_api dummy_eth_api = { - .iface_api.init = test_iface_init, -}; - -NET_DEVICE_INIT(test_if_simple_a, - "test_if_simple_a", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); - -NET_DEVICE_INIT(test_if_simple_b, - "test_if_simple_b", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); - -NET_DEVICE_INIT(test_if_connected_a, - "test_if_connected_a", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); - -NET_DEVICE_INIT(test_if_connected_b, - "test_if_connected_b", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); - -/* A dummy ETHERNET_L2 iface so that we can test L2 ignore. - * This iface is not properly defined, do not attempt to use it. - */ -NET_DEVICE_INIT(test_if_dummy_eth, - "test_if_dummy_eth", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_ETH_INIT_PRIORITY, - &dummy_eth_api, - ETHERNET_L2, - NET_L2_GET_CTX_TYPE(ETHERNET_L2), - 127); - - -static void test_conn_api_init(struct conn_mgr_conn_binding *const binding) -{ - /* Mark the iface dormant (disconnected) on initialization */ - net_if_dormant_on(binding->iface); -} - -static int test_conn_api_connect(struct conn_mgr_conn_binding *const binding) -{ - /* Mark iface as connected */ - net_if_dormant_off(binding->iface); - return 0; -} - -static int test_conn_api_disconnect(struct conn_mgr_conn_binding *const binding) -{ - /* Mark iface as dormant (disconnected) */ - net_if_dormant_on(binding->iface); - return 0; -} - -static struct conn_mgr_conn_api test_conn_api = { - .init = test_conn_api_init, - .connect = test_conn_api_connect, - .disconnect = test_conn_api_disconnect, -}; - -/* Dummy struct */ -struct test_conn_data { -}; - -#define TEST_CONN_IMPL_CTX_TYPE struct test_conn_data -CONN_MGR_CONN_DEFINE(TEST_CONN_IMPL, &test_conn_api); - -/* Bind connectivity implementation to ifaces */ -CONN_MGR_BIND_CONN(test_if_connected_a, TEST_CONN_IMPL); -CONN_MGR_BIND_CONN(test_if_connected_b, TEST_CONN_IMPL); - - -struct net_if *if_simp_a = NET_IF_GET(test_if_simple_a, 0); -struct net_if *if_simp_b = NET_IF_GET(test_if_simple_b, 0); -struct net_if *if_conn_a = NET_IF_GET(test_if_connected_a, 0); -struct net_if *if_conn_b = NET_IF_GET(test_if_connected_b, 0); -struct net_if *if_dummy_eth = NET_IF_GET(test_if_dummy_eth, 0); diff --git a/tests/net/conn_mgr/src/test_ifaces.h b/tests/net/conn_mgr/src/test_ifaces.h deleted file mode 100644 index a7aabaa95e9a..000000000000 --- a/tests/net/conn_mgr/src/test_ifaces.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_TEST_IFACES_H_ -#define ZEPHYR_INCLUDE_TEST_IFACES_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Public accessors for static iface structs */ -extern struct net_if *if_simp_a; -extern struct net_if *if_simp_b; -extern struct net_if *if_conn_a; -extern struct net_if *if_conn_b; -extern struct net_if *if_dummy_eth; - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_TEST_IFACES_H_ */ diff --git a/tests/net/conn_mgr/testcase.yaml b/tests/net/conn_mgr/testcase.yaml deleted file mode 100644 index 64ce1efacec0..000000000000 --- a/tests/net/conn_mgr/testcase.yaml +++ /dev/null @@ -1,11 +0,0 @@ -common: - min_ram: 16 - depends_on: netif - tags: net iface -tests: - net.conn_mgr_nodad: - extra_configs: - - CONFIG_NET_IPV6_DAD=n - net.conn_mgr_dad: - extra_configs: - - CONFIG_NET_IPV6_DAD=y From 55972f633b0026b09005bec04886ab6f707d60c9 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:29 +0200 Subject: [PATCH 280/528] Revert "[nrf fromlist] net: conn_mgr: connect/disconnect adjustments" This reverts commit e50f48465a09ca70250bfd5428ee5d0104433717. Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 4 -- subsys/net/conn_mgr/conn_mgr_connectivity.c | 14 +++--- tests/net/conn_mgr_conn/src/main.c | 55 ++++++++------------- 3 files changed, 27 insertions(+), 46 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index cad0bdfb4d56..7f035a277b51 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -259,8 +259,6 @@ struct conn_mgr_conn_binding { * If the provided iface has been bound to a connectivity implementation, initiate * network connect/association. * - * Automatically takes the iface admin-up (by calling net_if_up) if it isn't already. - * * Non-Blocking. * * @param iface Pointer to network interface @@ -277,8 +275,6 @@ int conn_mgr_if_connect(struct net_if *iface); * If the provided iface has been bound to a connectivity implementation, disconnect/dissassociate * it from the network, and cancel any pending attempts to connect/associate. * - * Does nothing if the iface is currently admin-down. - * * @param iface Pointer to network interface * * @retval 0 on success. diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index 2cc075074fbd..ac33ce68bce7 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -31,11 +31,9 @@ int conn_mgr_if_connect(struct net_if *iface) k_mutex_lock(binding->mutex, K_FOREVER); - if (!net_if_is_admin_up(iface)) { - status = net_if_up(iface); - if (status) { - goto out; - } + if (!net_if_flag_is_set(iface, NET_IF_UP)) { + status = -ESHUTDOWN; + goto out; } status = api->connect(binding); @@ -50,7 +48,7 @@ int conn_mgr_if_disconnect(struct net_if *iface) { struct conn_mgr_conn_binding *binding; struct conn_mgr_conn_api *api; - int status = 0; + int status; LOG_DBG("iface %p disconnect", iface); @@ -64,9 +62,11 @@ int conn_mgr_if_disconnect(struct net_if *iface) return -ENOTSUP; } + k_mutex_lock(binding->mutex, K_FOREVER); - if (!net_if_is_admin_up(iface)) { + if (!net_if_flag_is_set(iface, NET_IF_UP)) { + status = -EALREADY; goto out; } diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index dbe1d4cb3374..9111aa89b510 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -392,41 +392,6 @@ ZTEST(conn_mgr_conn, test_connect_disconnect_double_instant) zassert_equal(ifa1_data->call_cnt_a, 4, "ifa1->disconnect should have been called once."); } -/* Verify that calling connect on a down iface automatically takes the iface up. */ -ZTEST(conn_mgr_conn, test_connect_autoup) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Connect iface */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify net_if_up was called */ - zassert_true(net_if_is_admin_up(ifa1), "ifa1 should be admin-up after conn_mgr_if_connect"); - - /* Verify that connection succeeds */ - zassert_true(net_if_is_up(ifa1), "ifa1 should be oper-up after conn_mgr_if_connect"); - zassert_equal(ifa1_data->conn_bal, 1, "ifa1->connect should have been called once."); - zassert_equal(ifa1_data->call_cnt_a, 1, "ifa1->connect should have been called once."); -} - -/* Verify that calling disconnect on a down iface has no effect and raises no error. */ -ZTEST(conn_mgr_conn, test_disconnect_down) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Disconnect iface */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail."); - k_sleep(K_MSEC(1)); - - /* Verify iface is still down */ - zassert_false(net_if_is_admin_up(ifa1), "ifa1 should be still be admin-down."); - - /* Verify that no callbacks were fired */ - zassert_equal(ifa1_data->conn_bal, 0, "No callbacks should have been fired."); - zassert_equal(ifa1_data->call_cnt_a, 0, "No callbacks should have been fired."); -} - /** * Verify that invalid bound ifaces are treated as though they are not bound at all. */ @@ -443,10 +408,20 @@ ZTEST(conn_mgr_conn, test_invalid_ignored) */ ZTEST(conn_mgr_conn, test_connect_invalid) { + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + /* Bring ifnull and ifnone up */ zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for ifnull"); zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for ifnone"); + /* Attempts to connect ifa1 without bringing it up should fail */ + zassert_equal(conn_mgr_if_connect(ifa1), -ESHUTDOWN, + "conn_mgr_if_connect should give -ENOTSUP for down iface"); + zassert_equal(ifa1_data->conn_bal, 0, + "conn_mgr_if_connect should not affect down iface"); + zassert_equal(ifa1_data->call_cnt_a, 0, + "conn_mgr_if_connect should not affect down iface"); + /* Attempts to connect ifnull should fail, even if it is up */ zassert_equal(conn_mgr_if_connect(ifnull), -ENOTSUP, "conn_mgr_if_connect should give -ENOTSUP for ifnull"); @@ -461,10 +436,20 @@ ZTEST(conn_mgr_conn, test_connect_invalid) */ ZTEST(conn_mgr_conn, test_disconnect_invalid) { + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + /* Bring ifnull and ifnone up */ zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for ifnull"); zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for ifnone"); + /* Attempts to disconnect ifa1 without bringing it up should fail */ + zassert_equal(conn_mgr_if_disconnect(ifa1), -EALREADY, + "conn_mgr_if_disconnect should give -ENOTSUP for down iface"); + zassert_equal(ifa1_data->conn_bal, 0, + "conn_mgr_if_disconnect should not affect down iface"); + zassert_equal(ifa1_data->call_cnt_a, 0, + "conn_mgr_if_disconnect should not affect down iface"); + /* Attempts to disconnect ifnull should fail, even if it is up */ zassert_equal(conn_mgr_if_disconnect(ifnull), -ENOTSUP, "conn_mgr_if_disconnect should give -ENOTSUP for ifnull"); From bca8f15eee68656b704f28b7fa6b25a114410648 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:29 +0200 Subject: [PATCH 281/528] Revert "[nrf fromlist] net: conn_mgr: Simplify DAD handling" This reverts commit bf31d7373dbe8fbfb6d3c1cfbbe3bd7f4ab72058. Signed-off-by: Robert Lubos --- subsys/net/conn_mgr/conn_mgr.c | 45 ++++++++++++++++++++------ subsys/net/conn_mgr/conn_mgr_private.h | 9 +++++- subsys/net/conn_mgr/events_handler.c | 19 +++++++---- 3 files changed, 56 insertions(+), 17 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index faf14a6d3802..9f9c791c1956 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -39,6 +39,34 @@ K_SEM_DEFINE(conn_mgr_event_signal, 1, 1); /* Used to protect conn_mgr state */ K_MUTEX_DEFINE(conn_mgr_lock); +#if defined(CONFIG_NET_IPV6) +static bool conn_mgr_is_if_ipv6_ready(int index) +{ + if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == CONN_MGR_IPV6_STATUS_MASK) { + NET_DBG("IPv6 connected on iface index %u", index + 1); + return true; + } + + return false; +} +#else +#define conn_mgr_is_if_ipv6_ready(...) false +#endif /* CONFIG_NET_IPV6 */ + +#if defined(CONFIG_NET_IPV4) +static bool conn_mgr_is_if_ipv4_ready(int index) +{ + if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == CONN_MGR_IPV4_STATUS_MASK) { + NET_DBG("IPv4 connected on iface index %u", index + 1); + return true; + } + + return false; +} +#else +#define conn_mgr_is_if_ipv4_ready(...) false +#endif /* CONFIG_NET_IPV4 */ + /** * @brief Retrieves pointer to an iface by the index that corresponds to it in iface_states * @@ -82,8 +110,6 @@ static void conn_mgr_act_on_changes(void) int idx; int original_ready_count; bool is_ip_ready; - bool is_ipv6_ready; - bool is_ipv4_ready; bool is_l4_ready; bool is_oper_up; bool was_l4_ready; @@ -108,13 +134,11 @@ static void conn_mgr_act_on_changes(void) iface_states[idx] &= ~CONN_MGR_IF_CHANGED; /* Detect whether the iface is currently or was L4 ready */ - was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY; - is_ipv6_ready = iface_states[idx] & CONN_MGR_IF_IPV6_SET; - is_ipv4_ready = iface_states[idx] & CONN_MGR_IF_IPV4_SET; - is_oper_up = iface_states[idx] & CONN_MGR_IF_UP; - is_ignored = iface_states[idx] & CONN_MGR_IF_IGNORED; - is_ip_ready = is_ipv6_ready || is_ipv4_ready; - is_l4_ready = is_oper_up && is_ip_ready && !is_ignored; + is_ip_ready = conn_mgr_is_if_ipv6_ready(idx) || conn_mgr_is_if_ipv4_ready(idx); + is_oper_up = iface_states[idx] & CONN_MGR_IF_UP; + was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY; + is_ignored = iface_states[idx] & CONN_MGR_IF_IGNORED; + is_l4_ready = is_oper_up && is_ip_ready && !is_ignored; /* Respond to changes to iface readiness */ if (was_l4_ready != is_l4_ready) { @@ -158,6 +182,9 @@ static void conn_mgr_initial_state(struct net_if *iface) if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6)) { if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { NET_DBG("IPv6 addr set"); + iface_states[idx] |= CONN_MGR_IF_IPV6_SET | CONN_MGR_IF_IPV6_DAD_OK; + } else if (net_if_ipv6_get_global_addr(NET_ADDR_TENTATIVE, + &iface)) { iface_states[idx] |= CONN_MGR_IF_IPV6_SET; } } diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index b21e61bf0aa6..42c41e318f10 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -21,7 +21,8 @@ /* External state flags */ #define CONN_MGR_IF_UP BIT(0) #define CONN_MGR_IF_IPV6_SET BIT(1) -#define CONN_MGR_IF_IPV4_SET BIT(2) +#define CONN_MGR_IF_IPV6_DAD_OK BIT(2) +#define CONN_MGR_IF_IPV4_SET BIT(3) /* Configuration flags */ #define CONN_MGR_IF_IGNORED BIT(7) @@ -44,6 +45,12 @@ #define CONN_MGR_IPV4_EVENTS_MASK (NET_EVENT_IPV4_ADDR_ADD | \ NET_EVENT_IPV4_ADDR_DEL) +/* Internal event masks */ +#define CONN_MGR_IPV6_STATUS_MASK (CONN_MGR_IF_IPV6_SET | \ + CONN_MGR_IF_IPV6_DAD_OK) + +#define CONN_MGR_IPV4_STATUS_MASK (CONN_MGR_IF_IPV4_SET) + extern struct k_sem conn_mgr_event_signal; extern struct k_mutex conn_mgr_lock; diff --git a/subsys/net/conn_mgr/events_handler.c b/subsys/net/conn_mgr/events_handler.c index a3cdc903c6c8..81a4ea6f7e40 100644 --- a/subsys/net/conn_mgr/events_handler.c +++ b/subsys/net/conn_mgr/events_handler.c @@ -77,20 +77,25 @@ static void conn_mgr_ipv6_events_handler(struct net_mgmt_event_callback *cb, k_mutex_lock(&conn_mgr_lock, K_FOREVER); switch (NET_MGMT_GET_COMMAND(mgmt_event)) { - case NET_EVENT_IPV6_CMD_DAD_SUCCEED: - __fallthrough; case NET_EVENT_IPV6_CMD_ADDR_ADD: + iface_states[idx] |= CONN_MGR_IF_IPV6_SET; + break; + case NET_EVENT_IPV6_CMD_ADDR_DEL: if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { - iface_states[idx] |= CONN_MGR_IF_IPV6_SET; + break; } + + iface_states[idx] &= ~CONN_MGR_IF_IPV6_SET; + break; + case NET_EVENT_IPV6_CMD_DAD_SUCCEED: + iface_states[idx] |= CONN_MGR_IF_IPV6_DAD_OK; break; case NET_EVENT_IPV6_CMD_DAD_FAILED: - __fallthrough; - case NET_EVENT_IPV6_CMD_ADDR_DEL: - if (!net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { - iface_states[idx] &= ~CONN_MGR_IF_IPV6_SET; + if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { + break; } + iface_states[idx] &= ~CONN_MGR_IF_IPV6_DAD_OK; break; default: goto done; From 0c00efcb120671a3459355bffd12554a4dffcaea Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:29 +0200 Subject: [PATCH 282/528] Revert "[nrf fromlist] net: conn_mgr: Fire events only on connectivity gain/loss" This reverts commit 3b0ca1e118685b033bccbb6d308842fe20ea4eb1. Signed-off-by: Robert Lubos --- subsys/net/conn_mgr/conn_mgr.c | 67 +++++++++++++++------------------- 1 file changed, 29 insertions(+), 38 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index 9f9c791c1956..628bd2ba4d65 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -23,16 +23,8 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #define THREAD_PRIORITY K_PRIO_PREEMPT(7) #endif -/* Tracks per-iface state and event flags */ uint16_t iface_states[CONN_MGR_IFACE_MAX]; -/* Tracks the total number of L4-ready ifaces */ -static uint16_t ready_count; - -/* Tracks the last ifaces to change state in each respective direction */ -static int last_iface_down; -static int last_iface_up; - /* Used to signal when modifications have been made that need to be responded to */ K_SEM_DEFINE(conn_mgr_event_signal, 1, 1); @@ -89,36 +81,50 @@ static int conn_mgr_get_index_for_if(struct net_if *iface) return net_if_get_by_iface(iface) - 1; } +/** + * @brief Notifies listeners of the current readiness state of the iface at the given index + * + * @param index - Index of the iface (in iface_states) + */ +static void conn_mgr_notify_if_readiness(int index) +{ + struct net_if *iface = conn_mgr_get_if_by_index(index); + bool readiness = iface_states[index] & CONN_MGR_IF_READY; + + if (iface == NULL) { + return; + } + + NET_DBG("Iface %d (%p) %s", net_if_get_by_iface(iface), + iface, readiness ? "ready" : "unready"); + + net_mgmt_event_notify( + readiness ? NET_EVENT_L4_CONNECTED : NET_EVENT_L4_DISCONNECTED, + iface + ); + +} + static void conn_mgr_set_ready(int idx, bool readiness) { /* Clear and then update the L4-readiness bit */ iface_states[idx] &= ~CONN_MGR_IF_READY; - if (readiness) { iface_states[idx] |= CONN_MGR_IF_READY; - - ready_count += 1; - last_iface_up = idx; - } else { - ready_count -= 1; - last_iface_down = idx; } } static void conn_mgr_act_on_changes(void) { int idx; - int original_ready_count; bool is_ip_ready; bool is_l4_ready; bool is_oper_up; bool was_l4_ready; bool is_ignored; - struct net_if *last_iface; k_mutex_lock(&conn_mgr_lock, K_FOREVER); - original_ready_count = ready_count; for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { if (iface_states[idx] == 0) { /* This interface is not used */ @@ -144,22 +150,11 @@ static void conn_mgr_act_on_changes(void) if (was_l4_ready != is_l4_ready) { /* Track the iface readiness change */ conn_mgr_set_ready(idx, is_l4_ready); - } - } - /* If the total number of ready ifaces changed, possibly send an event */ - if (ready_count != original_ready_count) { - if (ready_count == 0) { - /* We just lost connectivity */ - last_iface = conn_mgr_get_if_by_index(last_iface_down); - net_mgmt_event_notify(NET_EVENT_L4_DISCONNECTED, last_iface); - } else if (original_ready_count == 0) { - /* We just gained connectivity */ - last_iface = conn_mgr_get_if_by_index(last_iface_up); - net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, last_iface); + /* Notify listeners of the readiness change */ + conn_mgr_notify_if_readiness(idx); } } - k_mutex_unlock(&conn_mgr_lock); } @@ -238,16 +233,12 @@ K_THREAD_DEFINE(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE, void conn_mgr_resend_status(void) { - struct net_if *last_iface; + int idx; k_mutex_lock(&conn_mgr_lock, K_FOREVER); - if (ready_count == 0) { - last_iface = conn_mgr_get_if_by_index(last_iface_down); - net_mgmt_event_notify(NET_EVENT_L4_DISCONNECTED, last_iface); - } else { - last_iface = conn_mgr_get_if_by_index(last_iface_up); - net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, last_iface); + for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { + conn_mgr_notify_if_readiness(idx); } k_mutex_unlock(&conn_mgr_lock); From 41313910c7c959d2ea2189c6414950c9ca0dd654 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:29 +0200 Subject: [PATCH 283/528] Revert "[nrf fromlist] samples: net: sockets: echo_server: Use conn_mgr ignore_iface" This reverts commit 2eee4cbf787218c8acf88d2359623d96801fd38a. Signed-off-by: Robert Lubos --- samples/net/sockets/echo_server/src/echo-server.c | 8 +++++--- samples/net/sockets/echo_server/src/tunnel.c | 3 --- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/samples/net/sockets/echo_server/src/echo-server.c b/samples/net/sockets/echo_server/src/echo-server.c index fbf189f898ad..c5a1ae0e0a6f 100644 --- a/samples/net/sockets/echo_server/src/echo-server.c +++ b/samples/net/sockets/echo_server/src/echo-server.c @@ -84,9 +84,6 @@ static void stop_udp_and_tcp(void) static void event_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) { - ARG_UNUSED(iface); - ARG_UNUSED(cb); - if ((mgmt_event & EVENT_MASK) != mgmt_event) { return; } @@ -96,6 +93,11 @@ static void event_handler(struct net_mgmt_event_callback *cb, want_to_quit = false; } + if (is_tunnel(iface)) { + /* Tunneling is handled separately, so ignore it here */ + return; + } + if (mgmt_event == NET_EVENT_L4_CONNECTED) { LOG_INF("Network connected"); diff --git a/samples/net/sockets/echo_server/src/tunnel.c b/samples/net/sockets/echo_server/src/tunnel.c index 91d1aa7108d1..e1cb98fb9cec 100644 --- a/samples/net/sockets/echo_server/src/tunnel.c +++ b/samples/net/sockets/echo_server/src/tunnel.c @@ -42,9 +42,6 @@ static int setup_iface(struct net_if *iface, const char *ipaddr) struct net_if_addr *ifaddr; struct sockaddr addr; - /* Before setting up tunnel, make sure it will be ignored by conn_mgr */ - conn_mgr_ignore_iface(iface); - if (!net_ipaddr_parse(ipaddr, strlen(ipaddr), &addr)) { LOG_ERR("Tunnel peer address \"%s\" invalid.", ipaddr); return -EINVAL; From b1f5c5a80154e440527e39f81140833ec7fab120 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:29 +0200 Subject: [PATCH 284/528] Revert "[nrf fromlist] net: conn_mgr: Ignore ifaces and L2s" This reverts commit 734675e0e6d1c92aeef38a53653a81a4cfe105b1. Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr.h | 64 -------------- subsys/net/conn_mgr/Kconfig | 3 +- subsys/net/conn_mgr/conn_mgr.c | 111 +------------------------ subsys/net/conn_mgr/conn_mgr_private.h | 5 +- 4 files changed, 5 insertions(+), 178 deletions(-) diff --git a/include/zephyr/net/conn_mgr.h b/include/zephyr/net/conn_mgr.h index 55a57135a593..bd6b4e5d3fc5 100644 --- a/include/zephyr/net/conn_mgr.h +++ b/include/zephyr/net/conn_mgr.h @@ -13,75 +13,11 @@ extern "C" { #if defined(CONFIG_NET_CONNECTION_MANAGER) -struct net_if; -struct net_l2; - -/** - * @brief Resend either NET_L4_CONNECTED or NET_L4_DISCONNECTED depending on whether connectivity - * is currently available. - */ void conn_mgr_resend_status(void); -/** - * @brief Mark an iface to be ignored by conn_mgr. - * - * Ignoring an iface forces conn_mgr to consider it unready/disconnected. - * - * This means that events related to the iface connecting/disconnecting will not be fired, - * and if the iface was connected before being ignored, events will be fired as though it - * disconnected at that moment. - * - * @param iface - iface to be ignored. - */ -void conn_mgr_ignore_iface(struct net_if *iface); - -/** - * @brief Stop ignoring an iface. - * - * conn_mgr will no longer be forced to consider the iface unreadly/disconnected. - * - * Events related to the iface connecting/disconnecting will no longer be blocked, - * and if the iface was connected before being unignored, events will be fired as though - * it connected in that moment. - * - * @param iface - iface to no longer ignore. - */ -void conn_mgr_unignore_iface(struct net_if *iface); - -/** - * @brief Check whether the provided iface is currently ignored. - * - * @param iface - The iface to check. - * @retval true if the iface is being ignored by conn_mgr. - * @retval false otherwise. - */ -bool conn_mgr_is_iface_ignored(struct net_if *iface); - -/** - * @brief Mark an L2 to be ignored by conn_mgr. - * - * This is a wrapper for conn_mgr_ignore_iface that ignores all ifaces that use the L2. - * - * @param l2 - L2 to be ignored. - */ -void conn_mgr_ignore_l2(const struct net_l2 *l2); - -/** - * @brief Stop ignoring an L2. - * - * This is a wrapper for conn_mgr_ignore_iface that unignores all ifaces that use the L2. - * - * @param l2 - L2 to no longer ignore. - */ -void conn_mgr_unignore_l2(const struct net_l2 *l2); - #else #define conn_mgr_resend_status(...) -#define conn_mgr_ignore_iface(...) -#define conn_mgr_unignore_iface(...) -#define conn_mgr_ignore_l2(...) -#define conn_mgr_unignore_l2(...) #endif /* CONFIG_NET_CONNECTION_MANAGER */ diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig index a8e37b68b5ee..54700a62e58e 100644 --- a/subsys/net/conn_mgr/Kconfig +++ b/subsys/net/conn_mgr/Kconfig @@ -32,8 +32,7 @@ config NET_CONNECTION_MANAGER_STACK_SIZE config NET_CONNECTION_MANAGER_PRIORITY int "Thread starting priority" - default 1 - range 1 99 + default 0 help This sets the starting priority of the connection manager thread. diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index 628bd2ba4d65..5dd28eb28f20 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -70,17 +70,6 @@ static struct net_if *conn_mgr_get_if_by_index(int index) return net_if_get_by_index(index + 1); } -/** - * @brief Gets the index in iface_states for the state corresponding to a provided iface. - * - * @param iface - iface to find the index of. - * @return int - The index found. - */ -static int conn_mgr_get_index_for_if(struct net_if *iface) -{ - return net_if_get_by_iface(iface) - 1; -} - /** * @brief Notifies listeners of the current readiness state of the iface at the given index * @@ -121,11 +110,11 @@ static void conn_mgr_act_on_changes(void) bool is_l4_ready; bool is_oper_up; bool was_l4_ready; - bool is_ignored; k_mutex_lock(&conn_mgr_lock, K_FOREVER); for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { + if (iface_states[idx] == 0) { /* This interface is not used */ continue; @@ -143,8 +132,7 @@ static void conn_mgr_act_on_changes(void) is_ip_ready = conn_mgr_is_if_ipv6_ready(idx) || conn_mgr_is_if_ipv4_ready(idx); is_oper_up = iface_states[idx] & CONN_MGR_IF_UP; was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY; - is_ignored = iface_states[idx] & CONN_MGR_IF_IGNORED; - is_l4_ready = is_oper_up && is_ip_ready && !is_ignored; + is_l4_ready = is_oper_up && is_ip_ready; /* Respond to changes to iface readiness */ if (was_l4_ready != is_l4_ready) { @@ -171,7 +159,7 @@ static void conn_mgr_initial_state(struct net_if *iface) if (net_if_is_up(iface)) { NET_DBG("Iface %p UP", iface); - iface_states[idx] |= CONN_MGR_IF_UP; + iface_states[idx] = CONN_MGR_IF_UP; } if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6)) { @@ -244,99 +232,6 @@ void conn_mgr_resend_status(void) k_mutex_unlock(&conn_mgr_lock); } -void conn_mgr_ignore_iface(struct net_if *iface) -{ - int idx = conn_mgr_get_index_for_if(iface); - - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - - if (!(iface_states[idx] & CONN_MGR_IF_IGNORED)) { - /* Set ignored flag and mark state as changed */ - iface_states[idx] |= CONN_MGR_IF_IGNORED; - iface_states[idx] |= CONN_MGR_IF_CHANGED; - k_sem_give(&conn_mgr_event_signal); - } - - k_mutex_unlock(&conn_mgr_lock); -} - -void conn_mgr_unignore_iface(struct net_if *iface) -{ - int idx = conn_mgr_get_index_for_if(iface); - - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - - if (iface_states[idx] & CONN_MGR_IF_IGNORED) { - /* Clear ignored flag and mark state as changed */ - iface_states[idx] &= ~CONN_MGR_IF_IGNORED; - iface_states[idx] |= CONN_MGR_IF_CHANGED; - k_sem_give(&conn_mgr_event_signal); - } - - k_mutex_unlock(&conn_mgr_lock); -} - -bool conn_mgr_is_iface_ignored(struct net_if *iface) -{ - int idx = conn_mgr_get_index_for_if(iface); - - bool ret = false; - - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - - ret = iface_states[idx] & CONN_MGR_IF_IGNORED; - - k_mutex_unlock(&conn_mgr_lock); - - return ret; -} - -/** - * @brief Check whether a provided iface uses the provided L2. - * - * @param iface - iface to check. - * @param l2 - L2 to check. NULL will match offloaded ifaces. - * @retval true if the iface uses the provided L2. - * @retval false otherwise. - */ -static bool iface_uses_l2(struct net_if *iface, const struct net_l2 *l2) -{ - return (!l2 && net_if_offload(iface)) || - (net_if_l2(iface) == l2); -} - -void conn_mgr_ignore_l2(const struct net_l2 *l2) -{ - /* conn_mgr_ignore_iface already locks the mutex, but we lock it here too - * so that all matching ifaces are updated simultaneously. - */ - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - - STRUCT_SECTION_FOREACH(net_if, iface) { - if (iface_uses_l2(iface, l2)) { - conn_mgr_ignore_iface(iface); - } - } - - k_mutex_unlock(&conn_mgr_lock); -} - -void conn_mgr_unignore_l2(const struct net_l2 *l2) -{ - /* conn_mgr_unignore_iface already locks the mutex, but we lock it here too - * so that all matching ifaces are updated simultaneously. - */ - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - - STRUCT_SECTION_FOREACH(net_if, iface) { - if (iface_uses_l2(iface, l2)) { - conn_mgr_unignore_iface(iface); - } - } - - k_mutex_unlock(&conn_mgr_lock); -} - static int conn_mgr_init(void) { int i; diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 42c41e318f10..097b501d682f 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -24,10 +24,7 @@ #define CONN_MGR_IF_IPV6_DAD_OK BIT(2) #define CONN_MGR_IF_IPV4_SET BIT(3) -/* Configuration flags */ -#define CONN_MGR_IF_IGNORED BIT(7) - -/* Internal state flags*/ +/* Internal state flags */ #define CONN_MGR_IF_READY BIT(14) /* Event flags */ From 5622265e68bc86191a0d51b4e3a0c12967fc951f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:29 +0200 Subject: [PATCH 285/528] Revert "[nrf fromlist] net: conn_mgr: refactor event logic" This reverts commit 160fd21baacd4a0b17a829f9b86ce890f99b14b7. Signed-off-by: Robert Lubos --- subsys/net/conn_mgr/conn_mgr.c | 127 ++++++++++++------------- subsys/net/conn_mgr/conn_mgr_private.h | 5 + 2 files changed, 64 insertions(+), 68 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index 5dd28eb28f20..4a800dfe5204 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -31,89 +31,72 @@ K_SEM_DEFINE(conn_mgr_event_signal, 1, 1); /* Used to protect conn_mgr state */ K_MUTEX_DEFINE(conn_mgr_lock); +static enum conn_mgr_state conn_mgr_iface_status(int index) +{ + if (iface_states[index] & CONN_MGR_IF_UP) { + return CONN_MGR_STATE_CONNECTED; + } + + return CONN_MGR_STATE_DISCONNECTED; +} + #if defined(CONFIG_NET_IPV6) -static bool conn_mgr_is_if_ipv6_ready(int index) +static enum conn_mgr_state conn_mgr_ipv6_status(int index) { - if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == CONN_MGR_IPV6_STATUS_MASK) { + if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == + CONN_MGR_IPV6_STATUS_MASK) { NET_DBG("IPv6 connected on iface index %u", index + 1); - return true; + return CONN_MGR_STATE_CONNECTED; } - return false; + return CONN_MGR_STATE_DISCONNECTED; } #else -#define conn_mgr_is_if_ipv6_ready(...) false +#define conn_mgr_ipv6_status(...) CONN_MGR_STATE_CONNECTED #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) -static bool conn_mgr_is_if_ipv4_ready(int index) +static enum conn_mgr_state conn_mgr_ipv4_status(int index) { - if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == CONN_MGR_IPV4_STATUS_MASK) { + if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == + CONN_MGR_IPV4_STATUS_MASK) { NET_DBG("IPv4 connected on iface index %u", index + 1); - return true; + return CONN_MGR_STATE_CONNECTED; } - return false; + return CONN_MGR_STATE_DISCONNECTED; } #else -#define conn_mgr_is_if_ipv4_ready(...) false +#define conn_mgr_ipv4_status(...) CONN_MGR_STATE_CONNECTED #endif /* CONFIG_NET_IPV4 */ -/** - * @brief Retrieves pointer to an iface by the index that corresponds to it in iface_states - * - * @param index - The index in iface_states to find the corresponding iface for. - * @return net_if* - The corresponding iface. - */ -static struct net_if *conn_mgr_get_if_by_index(int index) +static void conn_mgr_notify_status(int index) { - return net_if_get_by_index(index + 1); -} - -/** - * @brief Notifies listeners of the current readiness state of the iface at the given index - * - * @param index - Index of the iface (in iface_states) - */ -static void conn_mgr_notify_if_readiness(int index) -{ - struct net_if *iface = conn_mgr_get_if_by_index(index); - bool readiness = iface_states[index] & CONN_MGR_IF_READY; + struct net_if *iface = net_if_get_by_index(index + 1); if (iface == NULL) { return; } - NET_DBG("Iface %d (%p) %s", net_if_get_by_iface(iface), - iface, readiness ? "ready" : "unready"); - - net_mgmt_event_notify( - readiness ? NET_EVENT_L4_CONNECTED : NET_EVENT_L4_DISCONNECTED, - iface - ); - -} - -static void conn_mgr_set_ready(int idx, bool readiness) -{ - /* Clear and then update the L4-readiness bit */ - iface_states[idx] &= ~CONN_MGR_IF_READY; - if (readiness) { - iface_states[idx] |= CONN_MGR_IF_READY; + if (iface_states[index] & CONN_MGR_IF_READY) { + NET_DBG("Iface %d (%p) connected", + net_if_get_by_iface(iface), iface); + net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, iface); + } else { + NET_DBG("Iface %d (%p) disconnected", + net_if_get_by_iface(iface), iface); + net_mgmt_event_notify(NET_EVENT_L4_DISCONNECTED, iface); } } static void conn_mgr_act_on_changes(void) { int idx; - bool is_ip_ready; - bool is_l4_ready; - bool is_oper_up; - bool was_l4_ready; k_mutex_lock(&conn_mgr_lock, K_FOREVER); for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { + enum conn_mgr_state state; if (iface_states[idx] == 0) { /* This interface is not used */ @@ -121,36 +104,44 @@ static void conn_mgr_act_on_changes(void) } if (!(iface_states[idx] & CONN_MGR_IF_CHANGED)) { - /* No changes on this iface */ continue; } - /* Clear the state-change flag */ + state = CONN_MGR_STATE_CONNECTED; + + state &= conn_mgr_iface_status(idx); + if (state) { + enum conn_mgr_state ip_state = CONN_MGR_STATE_DISCONNECTED; + + if (IS_ENABLED(CONFIG_NET_IPV6)) { + ip_state |= conn_mgr_ipv6_status(idx); + } + + if (IS_ENABLED(CONFIG_NET_IPV4)) { + ip_state |= conn_mgr_ipv4_status(idx); + } + + state &= ip_state; + } + iface_states[idx] &= ~CONN_MGR_IF_CHANGED; - /* Detect whether the iface is currently or was L4 ready */ - is_ip_ready = conn_mgr_is_if_ipv6_ready(idx) || conn_mgr_is_if_ipv4_ready(idx); - is_oper_up = iface_states[idx] & CONN_MGR_IF_UP; - was_l4_ready = iface_states[idx] & CONN_MGR_IF_READY; - is_l4_ready = is_oper_up && is_ip_ready; + if (state == CONN_MGR_STATE_CONNECTED && + !(iface_states[idx] & CONN_MGR_IF_READY)) { + iface_states[idx] |= CONN_MGR_IF_READY; - /* Respond to changes to iface readiness */ - if (was_l4_ready != is_l4_ready) { - /* Track the iface readiness change */ - conn_mgr_set_ready(idx, is_l4_ready); + conn_mgr_notify_status(idx); + } else if (state != CONN_MGR_STATE_CONNECTED && + (iface_states[idx] & CONN_MGR_IF_READY)) { + iface_states[idx] &= ~CONN_MGR_IF_READY; - /* Notify listeners of the readiness change */ - conn_mgr_notify_if_readiness(idx); + conn_mgr_notify_status(idx); } } + k_mutex_unlock(&conn_mgr_lock); } -/** - * @brief Initialize the internal state flags for the given iface using its current status - * - * @param iface - iface to initialize from. - */ static void conn_mgr_initial_state(struct net_if *iface) { int idx = net_if_get_by_iface(iface) - 1; @@ -226,7 +217,7 @@ void conn_mgr_resend_status(void) k_mutex_lock(&conn_mgr_lock, K_FOREVER); for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { - conn_mgr_notify_if_readiness(idx); + conn_mgr_notify_status(idx); } k_mutex_unlock(&conn_mgr_lock); diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 097b501d682f..04c5898c9ef0 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -51,6 +51,11 @@ extern struct k_sem conn_mgr_event_signal; extern struct k_mutex conn_mgr_lock; +enum conn_mgr_state { + CONN_MGR_STATE_DISCONNECTED = 0, + CONN_MGR_STATE_CONNECTED = 1, +}; + void conn_mgr_init_events_handler(void); /** From d5ff6974e6f4f40d194b14fad787053fee0bd7a2 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 286/528] Revert "[nrf fromlist] net: conn_mgr: Add thread-safety" This reverts commit 606e61fc2ef24bb758ec0c50dd0d249fea8f0f84. Signed-off-by: Robert Lubos --- subsys/net/conn_mgr/conn_mgr.c | 26 ++----------------------- subsys/net/conn_mgr/conn_mgr_private.h | 3 +-- subsys/net/conn_mgr/events_handler.c | 27 ++++++-------------------- 3 files changed, 9 insertions(+), 47 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index 4a800dfe5204..e8f336ac28a7 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -25,11 +25,7 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); uint16_t iface_states[CONN_MGR_IFACE_MAX]; -/* Used to signal when modifications have been made that need to be responded to */ -K_SEM_DEFINE(conn_mgr_event_signal, 1, 1); - -/* Used to protect conn_mgr state */ -K_MUTEX_DEFINE(conn_mgr_lock); +K_SEM_DEFINE(conn_mgr_lock, 1, K_SEM_MAX_LIMIT); static enum conn_mgr_state conn_mgr_iface_status(int index) { @@ -93,8 +89,6 @@ static void conn_mgr_act_on_changes(void) { int idx; - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { enum conn_mgr_state state; @@ -138,16 +132,12 @@ static void conn_mgr_act_on_changes(void) conn_mgr_notify_status(idx); } } - - k_mutex_unlock(&conn_mgr_lock); } static void conn_mgr_initial_state(struct net_if *iface) { int idx = net_if_get_by_iface(iface) - 1; - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - if (net_if_is_up(iface)) { NET_DBG("Iface %p UP", iface); iface_states[idx] = CONN_MGR_IF_UP; @@ -172,8 +162,6 @@ static void conn_mgr_initial_state(struct net_if *iface) } iface_states[idx] |= CONN_MGR_IF_CHANGED; - - k_mutex_unlock(&conn_mgr_lock); } static void conn_mgr_init_cb(struct net_if *iface, void *user_data) @@ -185,23 +173,17 @@ static void conn_mgr_init_cb(struct net_if *iface, void *user_data) static void conn_mgr_handler(void) { - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - conn_mgr_conn_init(); conn_mgr_init_events_handler(); net_if_foreach(conn_mgr_init_cb, NULL); - k_mutex_unlock(&conn_mgr_lock); - NET_DBG("Connection Manager started"); while (true) { - /* Wait for changes */ - k_sem_take(&conn_mgr_event_signal, K_FOREVER); + k_sem_take(&conn_mgr_lock, K_FOREVER); - /* Respond to changes */ conn_mgr_act_on_changes(); } } @@ -214,13 +196,9 @@ void conn_mgr_resend_status(void) { int idx; - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { conn_mgr_notify_status(idx); } - - k_mutex_unlock(&conn_mgr_lock); } static int conn_mgr_init(void) diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 04c5898c9ef0..ecdf4523f545 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -48,8 +48,7 @@ #define CONN_MGR_IPV4_STATUS_MASK (CONN_MGR_IF_IPV4_SET) -extern struct k_sem conn_mgr_event_signal; -extern struct k_mutex conn_mgr_lock; +extern struct k_sem conn_mgr_lock; enum conn_mgr_state { CONN_MGR_STATE_DISCONNECTED = 0, diff --git a/subsys/net/conn_mgr/events_handler.c b/subsys/net/conn_mgr/events_handler.c index 81a4ea6f7e40..b5b4dfab9689 100644 --- a/subsys/net/conn_mgr/events_handler.c +++ b/subsys/net/conn_mgr/events_handler.c @@ -36,8 +36,6 @@ static void conn_mgr_iface_events_handler(struct net_mgmt_event_callback *cb, NET_DBG("Iface index %u", idx); - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IF_CMD_DOWN: iface_states[idx] &= ~CONN_MGR_IF_UP; @@ -46,14 +44,11 @@ static void conn_mgr_iface_events_handler(struct net_mgmt_event_callback *cb, iface_states[idx] |= CONN_MGR_IF_UP; break; default: - goto done; + return; } iface_states[idx] |= CONN_MGR_IF_CHANGED; - k_sem_give(&conn_mgr_event_signal); - -done: - k_mutex_unlock(&conn_mgr_lock); + k_sem_give(&conn_mgr_lock); } #if defined(CONFIG_NET_IPV6) @@ -74,8 +69,6 @@ static void conn_mgr_ipv6_events_handler(struct net_mgmt_event_callback *cb, NET_DBG("Iface index %u", idx); - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IPV6_CMD_ADDR_ADD: iface_states[idx] |= CONN_MGR_IF_IPV6_SET; @@ -98,14 +91,11 @@ static void conn_mgr_ipv6_events_handler(struct net_mgmt_event_callback *cb, iface_states[idx] &= ~CONN_MGR_IF_IPV6_DAD_OK; break; default: - goto done; + return; } iface_states[idx] |= CONN_MGR_IF_CHANGED; - k_sem_give(&conn_mgr_event_signal); - -done: - k_mutex_unlock(&conn_mgr_lock); + k_sem_give(&conn_mgr_lock); } #else static inline @@ -137,8 +127,6 @@ static void conn_mgr_ipv4_events_handler(struct net_mgmt_event_callback *cb, NET_DBG("Iface index %u", idx); - k_mutex_lock(&conn_mgr_lock, K_FOREVER); - switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IPV4_CMD_ADDR_ADD: iface_states[idx] |= CONN_MGR_IF_IPV4_SET; @@ -151,14 +139,11 @@ static void conn_mgr_ipv4_events_handler(struct net_mgmt_event_callback *cb, iface_states[idx] &= ~CONN_MGR_IF_IPV4_SET; break; default: - goto done; + return; } iface_states[idx] |= CONN_MGR_IF_CHANGED; - k_sem_give(&conn_mgr_event_signal); - -done: - k_mutex_unlock(&conn_mgr_lock); + k_sem_give(&conn_mgr_lock); } #else static inline From 999222691917600167cd4113d5c73598e9bf4bc1 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 287/528] Revert "[nrf fromlist] net: conn_mgr: Rename flags" This reverts commit 56a84417b6607ad93dbfaa179524e096611a4ee0. Signed-off-by: Robert Lubos --- subsys/net/conn_mgr/conn_mgr.c | 27 ++++++++++---------- subsys/net/conn_mgr/conn_mgr_private.h | 34 +++++++++++--------------- subsys/net/conn_mgr/events_handler.c | 22 ++++++++--------- 3 files changed, 39 insertions(+), 44 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index e8f336ac28a7..ebae5e1df750 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -29,7 +29,7 @@ K_SEM_DEFINE(conn_mgr_lock, 1, K_SEM_MAX_LIMIT); static enum conn_mgr_state conn_mgr_iface_status(int index) { - if (iface_states[index] & CONN_MGR_IF_UP) { + if (iface_states[index] & NET_STATE_IFACE_UP) { return CONN_MGR_STATE_CONNECTED; } @@ -74,7 +74,7 @@ static void conn_mgr_notify_status(int index) return; } - if (iface_states[index] & CONN_MGR_IF_READY) { + if (iface_states[index] & NET_STATE_CONNECTED) { NET_DBG("Iface %d (%p) connected", net_if_get_by_iface(iface), iface); net_mgmt_event_notify(NET_EVENT_L4_CONNECTED, iface); @@ -97,7 +97,7 @@ static void conn_mgr_act_on_changes(void) continue; } - if (!(iface_states[idx] & CONN_MGR_IF_CHANGED)) { + if (!(iface_states[idx] & NET_STATE_CHANGED)) { continue; } @@ -118,16 +118,16 @@ static void conn_mgr_act_on_changes(void) state &= ip_state; } - iface_states[idx] &= ~CONN_MGR_IF_CHANGED; + iface_states[idx] &= ~NET_STATE_CHANGED; if (state == CONN_MGR_STATE_CONNECTED && - !(iface_states[idx] & CONN_MGR_IF_READY)) { - iface_states[idx] |= CONN_MGR_IF_READY; + !(iface_states[idx] & NET_STATE_CONNECTED)) { + iface_states[idx] |= NET_STATE_CONNECTED; conn_mgr_notify_status(idx); } else if (state != CONN_MGR_STATE_CONNECTED && - (iface_states[idx] & CONN_MGR_IF_READY)) { - iface_states[idx] &= ~CONN_MGR_IF_READY; + (iface_states[idx] & NET_STATE_CONNECTED)) { + iface_states[idx] &= ~NET_STATE_CONNECTED; conn_mgr_notify_status(idx); } @@ -140,28 +140,29 @@ static void conn_mgr_initial_state(struct net_if *iface) if (net_if_is_up(iface)) { NET_DBG("Iface %p UP", iface); - iface_states[idx] = CONN_MGR_IF_UP; + iface_states[idx] = NET_STATE_IFACE_UP; } if (IS_ENABLED(CONFIG_NET_NATIVE_IPV6)) { if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { NET_DBG("IPv6 addr set"); - iface_states[idx] |= CONN_MGR_IF_IPV6_SET | CONN_MGR_IF_IPV6_DAD_OK; + iface_states[idx] |= NET_STATE_IPV6_ADDR_SET | + NET_STATE_IPV6_DAD_OK; } else if (net_if_ipv6_get_global_addr(NET_ADDR_TENTATIVE, &iface)) { - iface_states[idx] |= CONN_MGR_IF_IPV6_SET; + iface_states[idx] |= NET_STATE_IPV6_ADDR_SET; } } if (IS_ENABLED(CONFIG_NET_NATIVE_IPV4)) { if (net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) { NET_DBG("IPv4 addr set"); - iface_states[idx] |= CONN_MGR_IF_IPV4_SET; + iface_states[idx] |= NET_STATE_IPV4_ADDR_SET; } } - iface_states[idx] |= CONN_MGR_IF_CHANGED; + iface_states[idx] |= NET_STATE_CHANGED; } static void conn_mgr_init_cb(struct net_if *iface, void *user_data) diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index ecdf4523f545..d92318e629d7 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -18,35 +18,29 @@ #define CONN_MGR_IFACE_MAX CONFIG_NET_IF_MAX_IPV4_COUNT #endif -/* External state flags */ -#define CONN_MGR_IF_UP BIT(0) -#define CONN_MGR_IF_IPV6_SET BIT(1) -#define CONN_MGR_IF_IPV6_DAD_OK BIT(2) -#define CONN_MGR_IF_IPV4_SET BIT(3) +#define NET_STATE_IFACE_UP BIT(0) +#define NET_STATE_IPV6_ADDR_SET BIT(1) +#define NET_STATE_IPV6_DAD_OK BIT(2) +#define NET_STATE_IPV4_ADDR_SET BIT(3) -/* Internal state flags */ -#define CONN_MGR_IF_READY BIT(14) +#define NET_STATE_CONNECTED BIT(14) +#define NET_STATE_CHANGED BIT(15) -/* Event flags */ -#define CONN_MGR_IF_CHANGED BIT(15) - -/* NET_MGMT event masks */ -#define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ +#define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ NET_EVENT_IF_UP) -#define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ - NET_EVENT_IPV6_ADDR_DEL | \ - NET_EVENT_IPV6_DAD_SUCCEED | \ +#define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ + NET_EVENT_IPV6_ADDR_DEL | \ + NET_EVENT_IPV6_DAD_SUCCEED | \ NET_EVENT_IPV6_DAD_FAILED) -#define CONN_MGR_IPV4_EVENTS_MASK (NET_EVENT_IPV4_ADDR_ADD | \ +#define CONN_MGR_IPV4_EVENTS_MASK (NET_EVENT_IPV4_ADDR_ADD | \ NET_EVENT_IPV4_ADDR_DEL) -/* Internal event masks */ -#define CONN_MGR_IPV6_STATUS_MASK (CONN_MGR_IF_IPV6_SET | \ - CONN_MGR_IF_IPV6_DAD_OK) +#define CONN_MGR_IPV6_STATUS_MASK (NET_STATE_IPV6_ADDR_SET | \ + NET_STATE_IPV6_DAD_OK) -#define CONN_MGR_IPV4_STATUS_MASK (CONN_MGR_IF_IPV4_SET) +#define CONN_MGR_IPV4_STATUS_MASK (NET_STATE_IPV4_ADDR_SET) extern struct k_sem conn_mgr_lock; diff --git a/subsys/net/conn_mgr/events_handler.c b/subsys/net/conn_mgr/events_handler.c index b5b4dfab9689..fa227048e238 100644 --- a/subsys/net/conn_mgr/events_handler.c +++ b/subsys/net/conn_mgr/events_handler.c @@ -38,16 +38,16 @@ static void conn_mgr_iface_events_handler(struct net_mgmt_event_callback *cb, switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IF_CMD_DOWN: - iface_states[idx] &= ~CONN_MGR_IF_UP; + iface_states[idx] &= ~NET_STATE_IFACE_UP; break; case NET_EVENT_IF_CMD_UP: - iface_states[idx] |= CONN_MGR_IF_UP; + iface_states[idx] |= NET_STATE_IFACE_UP; break; default: return; } - iface_states[idx] |= CONN_MGR_IF_CHANGED; + iface_states[idx] |= NET_STATE_CHANGED; k_sem_give(&conn_mgr_lock); } @@ -71,30 +71,30 @@ static void conn_mgr_ipv6_events_handler(struct net_mgmt_event_callback *cb, switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IPV6_CMD_ADDR_ADD: - iface_states[idx] |= CONN_MGR_IF_IPV6_SET; + iface_states[idx] |= NET_STATE_IPV6_ADDR_SET; break; case NET_EVENT_IPV6_CMD_ADDR_DEL: if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { break; } - iface_states[idx] &= ~CONN_MGR_IF_IPV6_SET; + iface_states[idx] &= ~NET_STATE_IPV6_ADDR_SET; break; case NET_EVENT_IPV6_CMD_DAD_SUCCEED: - iface_states[idx] |= CONN_MGR_IF_IPV6_DAD_OK; + iface_states[idx] |= NET_STATE_IPV6_DAD_OK; break; case NET_EVENT_IPV6_CMD_DAD_FAILED: if (net_if_ipv6_get_global_addr(NET_ADDR_PREFERRED, &iface)) { break; } - iface_states[idx] &= ~CONN_MGR_IF_IPV6_DAD_OK; + iface_states[idx] &= ~NET_STATE_IPV6_DAD_OK; break; default: return; } - iface_states[idx] |= CONN_MGR_IF_CHANGED; + iface_states[idx] |= NET_STATE_CHANGED; k_sem_give(&conn_mgr_lock); } #else @@ -129,20 +129,20 @@ static void conn_mgr_ipv4_events_handler(struct net_mgmt_event_callback *cb, switch (NET_MGMT_GET_COMMAND(mgmt_event)) { case NET_EVENT_IPV4_CMD_ADDR_ADD: - iface_states[idx] |= CONN_MGR_IF_IPV4_SET; + iface_states[idx] |= NET_STATE_IPV4_ADDR_SET; break; case NET_EVENT_IPV4_CMD_ADDR_DEL: if (net_if_ipv4_get_global_addr(iface, NET_ADDR_PREFERRED)) { break; } - iface_states[idx] &= ~CONN_MGR_IF_IPV4_SET; + iface_states[idx] &= ~NET_STATE_IPV4_ADDR_SET; break; default: return; } - iface_states[idx] |= CONN_MGR_IF_CHANGED; + iface_states[idx] |= NET_STATE_CHANGED; k_sem_give(&conn_mgr_lock); } #else From 991f99e0f1b7e60de75531368ad4b0d5aeb20e84 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 288/528] Revert "[nrf fromlist] net: conn_mgr: relocate if_get_binding" This reverts commit af4070afb9dc09ebcf0881d6055d8e421bb02c0c. Signed-off-by: Robert Lubos --- subsys/net/conn_mgr/conn_mgr_connectivity.c | 23 +++++++++++++++- subsys/net/conn_mgr/conn_mgr_private.h | 24 ----------------- tests/net/conn_mgr_conn/src/main.c | 29 ++++++++++++--------- 3 files changed, 39 insertions(+), 37 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index ac33ce68bce7..c0812dac1727 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -9,7 +9,28 @@ LOG_MODULE_REGISTER(conn_mgr_conn, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include -#include "conn_mgr_private.h" + +/** + * @brief Retrieves the conn_mgr binding struct for a provided iface if it exists. + * + * Bindings for connectivity implementations with missing API structs are ignored. + * + * @param iface - bound network interface to obtain the binding struct for. + * @return struct conn_mgr_conn_binding* Pointer to the retrieved binding struct if it exists, + * NULL otherwise. + */ +static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) +{ + STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { + if (iface == binding->iface) { + if (binding->impl->api) { + return binding; + } + return NULL; + } + } + return NULL; +} int conn_mgr_if_connect(struct net_if *iface) { diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index d92318e629d7..821780aeda4b 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -7,8 +7,6 @@ #ifndef __CONN_MGR_PRV_H__ #define __CONN_MGR_PRV_H__ -#include - #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV4) #define CONN_MGR_IFACE_MAX MAX(CONFIG_NET_IF_MAX_IPV6_COUNT, \ CONFIG_NET_IF_MAX_IPV4_COUNT) @@ -51,26 +49,4 @@ enum conn_mgr_state { void conn_mgr_init_events_handler(void); -/** - * @brief Retrieves the conn_mgr binding struct for a provided iface if it exists. - * - * Bindings for connectivity implementations with missing API structs are ignored. - * - * @param iface - bound network interface to obtain the binding struct for. - * @return struct conn_mgr_conn_binding* Pointer to the retrieved binding struct if it exists, - * NULL otherwise. - */ -static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) -{ - STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { - if (iface == binding->iface) { - if (binding->impl->api) { - return binding; - } - return NULL; - } - } - return NULL; -} - #endif /* __CONN_MGR_PRV_H__ */ diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index 9111aa89b510..3906d9729e66 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -15,10 +15,26 @@ #include #include #include -#include "conn_mgr_private.h" #include "test_conn_impl.h" #include "test_ifaces.h" + +/* This is a duplicate of conn_mgr_if_get_binding in net_if.c, + * which is currently not exposed. + */ +static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) +{ + STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { + if (iface == binding->iface) { + if (binding->impl->api) { + return binding; + } + return NULL; + } + } + return NULL; +} + static inline struct test_conn_data *conn_mgr_if_get_data(struct net_if *iface) { struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); @@ -392,17 +408,6 @@ ZTEST(conn_mgr_conn, test_connect_disconnect_double_instant) zassert_equal(ifa1_data->call_cnt_a, 4, "ifa1->disconnect should have been called once."); } -/** - * Verify that invalid bound ifaces are treated as though they are not bound at all. - */ -ZTEST(conn_mgr_conn, test_invalid_ignored) -{ - zassert_is_null(conn_mgr_if_get_binding(ifnull)); - zassert_is_null(conn_mgr_if_get_binding(ifnone)); - zassert_false(conn_mgr_if_is_bound(ifnull)); - zassert_false(conn_mgr_if_is_bound(ifnone)); -} - /* Verify that connecting an iface that isn't up, missing an API, * or isn't connectivity-bound raises an error. */ From 2814718a23d4b14c6adc29cf21cb69d4ab46a66b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 289/528] Revert "[nrf fromlist] net: conn_mgr: Reorganize files" This reverts commit dc47180586120e29d2f80b5372565fc433356d36. Signed-off-by: Robert Lubos --- .../zephyr/net/{conn_mgr.h => net_conn_mgr.h} | 10 ++--- include/zephyr/shell/shell_mqtt.h | 2 +- samples/net/gsm_modem/src/main.c | 2 +- samples/net/mqtt_sn_publisher/src/main.c | 4 +- samples/net/mqtt_sn_publisher/src/udp.c | 2 +- .../sockets/dumb_http_server_mt/src/main.c | 4 +- .../net/sockets/echo_client/src/echo-client.c | 4 +- .../net/sockets/echo_server/src/echo-server.c | 6 +-- samples/net/sockets/txtime/src/main.c | 6 +-- samples/subsys/mgmt/updatehub/src/main.c | 4 +- subsys/mgmt/mcumgr/transport/src/smp_udp.c | 4 +- subsys/net/CMakeLists.txt | 1 - subsys/net/Kconfig | 2 - subsys/net/lib/CMakeLists.txt | 1 + subsys/net/lib/Kconfig | 2 + subsys/net/{ => lib}/conn_mgr/CMakeLists.txt | 0 subsys/net/{ => lib}/conn_mgr/Kconfig | 0 subsys/net/{ => lib}/conn_mgr/conn_mgr.c | 37 ++++++++++--------- .../conn_mgr/conn_mgr.h} | 12 +++--- subsys/net/{ => lib}/conn_mgr/conn_mgr.ld | 0 .../conn_mgr/conn_mgr_connectivity.c | 0 .../net/{ => lib}/conn_mgr/events_handler.c | 2 +- subsys/shell/backends/shell_mqtt.c | 2 +- 23 files changed, 54 insertions(+), 53 deletions(-) rename include/zephyr/net/{conn_mgr.h => net_conn_mgr.h} (56%) rename subsys/net/{ => lib}/conn_mgr/CMakeLists.txt (100%) rename subsys/net/{ => lib}/conn_mgr/Kconfig (100%) rename subsys/net/{ => lib}/conn_mgr/conn_mgr.c (82%) rename subsys/net/{conn_mgr/conn_mgr_private.h => lib/conn_mgr/conn_mgr.h} (87%) rename subsys/net/{ => lib}/conn_mgr/conn_mgr.ld (100%) rename subsys/net/{ => lib}/conn_mgr/conn_mgr_connectivity.c (100%) rename subsys/net/{ => lib}/conn_mgr/events_handler.c (99%) diff --git a/include/zephyr/net/conn_mgr.h b/include/zephyr/net/net_conn_mgr.h similarity index 56% rename from include/zephyr/net/conn_mgr.h rename to include/zephyr/net/net_conn_mgr.h index bd6b4e5d3fc5..1d85a23a5cdf 100644 --- a/include/zephyr/net/conn_mgr.h +++ b/include/zephyr/net/net_conn_mgr.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef ZEPHYR_INCLUDE_CONN_MGR_H_ -#define ZEPHYR_INCLUDE_CONN_MGR_H_ +#ifndef ZEPHYR_INCLUDE_NET_CONN_MGR_H_ +#define ZEPHYR_INCLUDE_NET_CONN_MGR_H_ #ifdef __cplusplus extern "C" { @@ -13,11 +13,11 @@ extern "C" { #if defined(CONFIG_NET_CONNECTION_MANAGER) -void conn_mgr_resend_status(void); +void net_conn_mgr_resend_status(void); #else -#define conn_mgr_resend_status(...) +#define net_conn_mgr_resend_status(...) #endif /* CONFIG_NET_CONNECTION_MANAGER */ @@ -25,4 +25,4 @@ void conn_mgr_resend_status(void); } #endif -#endif /* ZEPHYR_INCLUDE_CONN_MGR_H_ */ +#endif /* ZEPHYR_INCLUDE_NET_CONN_MGR_H_ */ diff --git a/include/zephyr/shell/shell_mqtt.h b/include/zephyr/shell/shell_mqtt.h index c1120527f5d0..f709ffd1ed0e 100644 --- a/include/zephyr/shell/shell_mqtt.h +++ b/include/zephyr/shell/shell_mqtt.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include #include diff --git a/samples/net/gsm_modem/src/main.c b/samples/net/gsm_modem/src/main.c index 8e9d0a7521a8..3ee50df53e09 100644 --- a/samples/net/gsm_modem/src/main.c +++ b/samples/net/gsm_modem/src/main.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/samples/net/mqtt_sn_publisher/src/main.c b/samples/net/mqtt_sn_publisher/src/main.c index efacb696dd08..ebeda9f455a2 100644 --- a/samples/net/mqtt_sn_publisher/src/main.c +++ b/samples/net/mqtt_sn_publisher/src/main.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #include @@ -79,7 +79,7 @@ static void init_app(void) net_mgmt_init_event_callback(&mgmt_cb, net_event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); } } diff --git a/samples/net/mqtt_sn_publisher/src/udp.c b/samples/net/mqtt_sn_publisher/src/udp.c index a47bc6932216..fb96e71ae79f 100644 --- a/samples/net/mqtt_sn_publisher/src/udp.c +++ b/samples/net/mqtt_sn_publisher/src/udp.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include #include diff --git a/samples/net/sockets/dumb_http_server_mt/src/main.c b/samples/net/sockets/dumb_http_server_mt/src/main.c index 77b7a836f756..a4f3d1365f5f 100644 --- a/samples/net/sockets/dumb_http_server_mt/src/main.c +++ b/samples/net/sockets/dumb_http_server_mt/src/main.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(net_dumb_http_srv_mt_sample); #include #include -#include +#include #define MY_PORT 8080 @@ -426,7 +426,7 @@ int main(void) event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); } if (!IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) { diff --git a/samples/net/sockets/echo_client/src/echo-client.c b/samples/net/sockets/echo_client/src/echo-client.c index c211de8f3c93..351131edbf70 100644 --- a/samples/net/sockets/echo_client/src/echo-client.c +++ b/samples/net/sockets/echo_client/src/echo-client.c @@ -29,7 +29,7 @@ LOG_MODULE_REGISTER(net_echo_client_sample, LOG_LEVEL_DBG); #include #include -#include +#include #if defined(CONFIG_USERSPACE) #include @@ -271,7 +271,7 @@ static void init_app(void) event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); } init_vlan(); diff --git a/samples/net/sockets/echo_server/src/echo-server.c b/samples/net/sockets/echo_server/src/echo-server.c index c5a1ae0e0a6f..2b9cd2785148 100644 --- a/samples/net/sockets/echo_server/src/echo-server.c +++ b/samples/net/sockets/echo_server/src/echo-server.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(net_echo_server_sample, LOG_LEVEL_DBG); #include #include -#include +#include #include "common.h" #include "certificate.h" @@ -196,7 +196,7 @@ static void init_app(void) event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); } init_vlan(); @@ -210,7 +210,7 @@ static int cmd_sample_quit(const struct shell *sh, { want_to_quit = true; - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); quit(); diff --git a/samples/net/sockets/txtime/src/main.c b/samples/net/sockets/txtime/src/main.c index 38ed702797b3..674fd83e54eb 100644 --- a/samples/net/sockets/txtime/src/main.c +++ b/samples/net/sockets/txtime/src/main.c @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(net_txtime_sample, LOG_LEVEL_DBG); #include #include -#include +#include #include #include @@ -497,7 +497,7 @@ static int cmd_sample_quit(const struct shell *sh, quit(); - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); return 0; } @@ -535,7 +535,7 @@ int main(void) net_mgmt_add_event_callback(&dhcpv4_cb); } - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); } /* The VLAN in this example is created for demonstration purposes. diff --git a/samples/subsys/mgmt/updatehub/src/main.c b/samples/subsys/mgmt/updatehub/src/main.c index 9e51c7e7b2dc..efb941d7f536 100644 --- a/samples/subsys/mgmt/updatehub/src/main.c +++ b/samples/subsys/mgmt/updatehub/src/main.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #if defined(CONFIG_UPDATEHUB_DTLS) @@ -150,6 +150,6 @@ int main(void) net_mgmt_init_event_callback(&mgmt_cb, event_handler, EVENT_MASK); net_mgmt_add_event_callback(&mgmt_cb); - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); return 0; } diff --git a/subsys/mgmt/mcumgr/transport/src/smp_udp.c b/subsys/mgmt/mcumgr/transport/src/smp_udp.c index ef01ac8515b0..aab40d4e2119 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_udp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_udp.c @@ -30,7 +30,7 @@ #include #include #include -#include +#include #endif #define LOG_LEVEL CONFIG_MCUMGR_LOG_LEVEL @@ -316,7 +316,7 @@ static void smp_udp_start(void) net_mgmt_init_event_callback(&smp_udp_mgmt_cb, smp_udp_net_event_handler, (NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED)); net_mgmt_add_event_callback(&smp_udp_mgmt_cb); - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); } MCUMGR_HANDLER_DEFINE(smp_udp, smp_udp_start); diff --git a/subsys/net/CMakeLists.txt b/subsys/net/CMakeLists.txt index f9cf4940a438..35fab9994e4f 100644 --- a/subsys/net/CMakeLists.txt +++ b/subsys/net/CMakeLists.txt @@ -20,4 +20,3 @@ if(CONFIG_NETWORKING) endif() add_subdirectory(lib) -add_subdirectory_ifdef(CONFIG_NET_CONNECTION_MANAGER conn_mgr) diff --git a/subsys/net/Kconfig b/subsys/net/Kconfig index fad47cfe8816..a8b8f94c44b2 100644 --- a/subsys/net/Kconfig +++ b/subsys/net/Kconfig @@ -80,8 +80,6 @@ source "subsys/net/pkt_filter/Kconfig" source "subsys/net/lib/Kconfig" -source "subsys/net/conn_mgr/Kconfig" - endif endmenu diff --git a/subsys/net/lib/CMakeLists.txt b/subsys/net/lib/CMakeLists.txt index 6c045b586928..9161026d910a 100644 --- a/subsys/net/lib/CMakeLists.txt +++ b/subsys/net/lib/CMakeLists.txt @@ -11,6 +11,7 @@ add_subdirectory_ifdef(CONFIG_TFTP_LIB tftp) add_subdirectory_ifdef(CONFIG_NET_CONFIG_SETTINGS config) add_subdirectory_ifdef(CONFIG_NET_SOCKETS sockets) add_subdirectory_ifdef(CONFIG_TLS_CREDENTIALS tls_credentials) +add_subdirectory_ifdef(CONFIG_NET_CONNECTION_MANAGER conn_mgr) add_subdirectory_ifdef(CONFIG_NET_CAPTURE capture) add_subdirectory_ifdef(CONFIG_NET_ZPERF zperf) diff --git a/subsys/net/lib/Kconfig b/subsys/net/lib/Kconfig index 5df4a445885a..ca59d89a66b6 100644 --- a/subsys/net/lib/Kconfig +++ b/subsys/net/lib/Kconfig @@ -37,6 +37,8 @@ endmenu menu "Network additional services" +source "subsys/net/lib/conn_mgr/Kconfig" + source "subsys/net/lib/capture/Kconfig" source "subsys/net/lib/zperf/Kconfig" diff --git a/subsys/net/conn_mgr/CMakeLists.txt b/subsys/net/lib/conn_mgr/CMakeLists.txt similarity index 100% rename from subsys/net/conn_mgr/CMakeLists.txt rename to subsys/net/lib/conn_mgr/CMakeLists.txt diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/lib/conn_mgr/Kconfig similarity index 100% rename from subsys/net/conn_mgr/Kconfig rename to subsys/net/lib/conn_mgr/Kconfig diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/lib/conn_mgr/conn_mgr.c similarity index 82% rename from subsys/net/conn_mgr/conn_mgr.c rename to subsys/net/lib/conn_mgr/conn_mgr.c index ebae5e1df750..c81033ec30d8 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/lib/conn_mgr/conn_mgr.c @@ -15,7 +15,7 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include -#include "conn_mgr_private.h" +#include #if defined(CONFIG_NET_TC_THREAD_COOPERATIVE) #define THREAD_PRIORITY K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1) @@ -27,43 +27,43 @@ uint16_t iface_states[CONN_MGR_IFACE_MAX]; K_SEM_DEFINE(conn_mgr_lock, 1, K_SEM_MAX_LIMIT); -static enum conn_mgr_state conn_mgr_iface_status(int index) +static enum net_conn_mgr_state conn_mgr_iface_status(int index) { if (iface_states[index] & NET_STATE_IFACE_UP) { - return CONN_MGR_STATE_CONNECTED; + return NET_CONN_MGR_STATE_CONNECTED; } - return CONN_MGR_STATE_DISCONNECTED; + return NET_CONN_MGR_STATE_DISCONNECTED; } #if defined(CONFIG_NET_IPV6) -static enum conn_mgr_state conn_mgr_ipv6_status(int index) +static enum net_conn_mgr_state conn_mgr_ipv6_status(int index) { if ((iface_states[index] & CONN_MGR_IPV6_STATUS_MASK) == CONN_MGR_IPV6_STATUS_MASK) { NET_DBG("IPv6 connected on iface index %u", index + 1); - return CONN_MGR_STATE_CONNECTED; + return NET_CONN_MGR_STATE_CONNECTED; } - return CONN_MGR_STATE_DISCONNECTED; + return NET_CONN_MGR_STATE_DISCONNECTED; } #else -#define conn_mgr_ipv6_status(...) CONN_MGR_STATE_CONNECTED +#define conn_mgr_ipv6_status(...) NET_CONN_MGR_STATE_CONNECTED #endif /* CONFIG_NET_IPV6 */ #if defined(CONFIG_NET_IPV4) -static enum conn_mgr_state conn_mgr_ipv4_status(int index) +static enum net_conn_mgr_state conn_mgr_ipv4_status(int index) { if ((iface_states[index] & CONN_MGR_IPV4_STATUS_MASK) == CONN_MGR_IPV4_STATUS_MASK) { NET_DBG("IPv4 connected on iface index %u", index + 1); - return CONN_MGR_STATE_CONNECTED; + return NET_CONN_MGR_STATE_CONNECTED; } - return CONN_MGR_STATE_DISCONNECTED; + return NET_CONN_MGR_STATE_DISCONNECTED; } #else -#define conn_mgr_ipv4_status(...) CONN_MGR_STATE_CONNECTED +#define conn_mgr_ipv4_status(...) NET_CONN_MGR_STATE_CONNECTED #endif /* CONFIG_NET_IPV4 */ static void conn_mgr_notify_status(int index) @@ -90,7 +90,7 @@ static void conn_mgr_act_on_changes(void) int idx; for (idx = 0; idx < ARRAY_SIZE(iface_states); idx++) { - enum conn_mgr_state state; + enum net_conn_mgr_state state; if (iface_states[idx] == 0) { /* This interface is not used */ @@ -101,11 +101,12 @@ static void conn_mgr_act_on_changes(void) continue; } - state = CONN_MGR_STATE_CONNECTED; + state = NET_CONN_MGR_STATE_CONNECTED; state &= conn_mgr_iface_status(idx); if (state) { - enum conn_mgr_state ip_state = CONN_MGR_STATE_DISCONNECTED; + enum net_conn_mgr_state ip_state = + NET_CONN_MGR_STATE_DISCONNECTED; if (IS_ENABLED(CONFIG_NET_IPV6)) { ip_state |= conn_mgr_ipv6_status(idx); @@ -120,12 +121,12 @@ static void conn_mgr_act_on_changes(void) iface_states[idx] &= ~NET_STATE_CHANGED; - if (state == CONN_MGR_STATE_CONNECTED && + if (state == NET_CONN_MGR_STATE_CONNECTED && !(iface_states[idx] & NET_STATE_CONNECTED)) { iface_states[idx] |= NET_STATE_CONNECTED; conn_mgr_notify_status(idx); - } else if (state != CONN_MGR_STATE_CONNECTED && + } else if (state != NET_CONN_MGR_STATE_CONNECTED && (iface_states[idx] & NET_STATE_CONNECTED)) { iface_states[idx] &= ~NET_STATE_CONNECTED; @@ -193,7 +194,7 @@ K_THREAD_DEFINE(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE, (k_thread_entry_t)conn_mgr_handler, NULL, NULL, NULL, THREAD_PRIORITY, 0, 0); -void conn_mgr_resend_status(void) +void net_conn_mgr_resend_status(void) { int idx; diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/lib/conn_mgr/conn_mgr.h similarity index 87% rename from subsys/net/conn_mgr/conn_mgr_private.h rename to subsys/net/lib/conn_mgr/conn_mgr.h index 821780aeda4b..0f1c8ecd24b5 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/lib/conn_mgr/conn_mgr.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -#ifndef __CONN_MGR_PRV_H__ -#define __CONN_MGR_PRV_H__ +#ifndef __CONN_MGR_H__ +#define __CONN_MGR_H__ #if defined(CONFIG_NET_IPV6) && defined(CONFIG_NET_IPV4) #define CONN_MGR_IFACE_MAX MAX(CONFIG_NET_IF_MAX_IPV6_COUNT, \ @@ -42,11 +42,11 @@ extern struct k_sem conn_mgr_lock; -enum conn_mgr_state { - CONN_MGR_STATE_DISCONNECTED = 0, - CONN_MGR_STATE_CONNECTED = 1, +enum net_conn_mgr_state { + NET_CONN_MGR_STATE_DISCONNECTED = 0, + NET_CONN_MGR_STATE_CONNECTED = 1, }; void conn_mgr_init_events_handler(void); -#endif /* __CONN_MGR_PRV_H__ */ +#endif /* __CONN_MGR_H__ */ diff --git a/subsys/net/conn_mgr/conn_mgr.ld b/subsys/net/lib/conn_mgr/conn_mgr.ld similarity index 100% rename from subsys/net/conn_mgr/conn_mgr.ld rename to subsys/net/lib/conn_mgr/conn_mgr.ld diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/lib/conn_mgr/conn_mgr_connectivity.c similarity index 100% rename from subsys/net/conn_mgr/conn_mgr_connectivity.c rename to subsys/net/lib/conn_mgr/conn_mgr_connectivity.c diff --git a/subsys/net/conn_mgr/events_handler.c b/subsys/net/lib/conn_mgr/events_handler.c similarity index 99% rename from subsys/net/conn_mgr/events_handler.c rename to subsys/net/lib/conn_mgr/events_handler.c index fa227048e238..551420df49f2 100644 --- a/subsys/net/conn_mgr/events_handler.c +++ b/subsys/net/lib/conn_mgr/events_handler.c @@ -11,7 +11,7 @@ LOG_MODULE_DECLARE(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include -#include "conn_mgr_private.h" +#include extern uint16_t iface_states[CONN_MGR_IFACE_MAX]; diff --git a/subsys/shell/backends/shell_mqtt.c b/subsys/shell/backends/shell_mqtt.c index 58654dcf4000..8b535a960153 100644 --- a/subsys/shell/backends/shell_mqtt.c +++ b/subsys/shell/backends/shell_mqtt.c @@ -716,7 +716,7 @@ static int enable(const struct shell_transport *transport, bool blocking) /* Listen for network connection status */ net_mgmt_add_event_callback(&sh_mqtt->mgmt_cb); - conn_mgr_resend_status(); + net_conn_mgr_resend_status(); return 0; } From 7855ac133f574aa9561d637169ff4074aea69a81 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 290/528] Revert "[nrf fromtree] net: conn_mgr: Fix event definitions" This reverts commit 62ed73d1c9af8b3ad6767f02470556a205052fe5. Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 2 +- tests/net/conn_mgr_conn/src/main.c | 126 +------------------ tests/net/conn_mgr_conn/src/test_conn_impl.c | 81 ------------ tests/net/conn_mgr_conn/src/test_conn_impl.h | 9 -- 4 files changed, 2 insertions(+), 216 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 7f035a277b51..023b043a249a 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -34,7 +34,7 @@ extern "C" { #define _NET_MGMT_CONN_LAYER NET_MGMT_LAYER(NET_MGMT_LAYER_L2) #define _NET_MGMT_CONN_CODE NET_MGMT_LAYER_CODE(0x207) #define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE) -#define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_BASE) +#define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_EVENT) enum net_event_ethernet_cmd { NET_EVENT_CONN_CMD_IF_TIMEOUT = 1, diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index 3906d9729e66..e8da4e9d7d58 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -67,50 +67,11 @@ static void reset_test_iface(struct net_if *iface) iface_data->call_cnt_b = 0; iface_data->conn_bal = 0; iface_data->api_err = 0; - iface_data->fatal_error = 0; - iface_data->timeout = false; memset(iface_data->data_x, 0, sizeof(iface_data->data_x)); memset(iface_data->data_y, 0, sizeof(iface_data->data_y)); } } - -/* NET_MGMT event tracking */ - -static K_MUTEX_DEFINE(event_mutex); -static struct event_stats { - int timeout_count; - int fatal_error_count; - int event_count; - int event_info; - struct net_if *event_iface; -} test_event_stats; - -struct net_mgmt_event_callback conn_mgr_conn_callback; - -static void conn_mgr_conn_handler(struct net_mgmt_event_callback *cb, - uint32_t event, struct net_if *iface) -{ - k_mutex_lock(&event_mutex, K_FOREVER); - - if (event == NET_EVENT_CONN_IF_TIMEOUT) { - test_event_stats.timeout_count += 1; - } else if (event == NET_EVENT_CONN_IF_FATAL_ERROR) { - test_event_stats.fatal_error_count += 1; - } - - test_event_stats.event_count += 1; - test_event_stats.event_iface = iface; - - if (cb->info) { - test_event_stats.event_info = *((int *)cb->info); - } else { - test_event_stats.event_info = 0; - } - - k_mutex_unlock(&event_mutex); -} - static void conn_mgr_conn_before(void *data) { ARG_UNUSED(data); @@ -120,24 +81,6 @@ static void conn_mgr_conn_before(void *data) reset_test_iface(ifni); reset_test_iface(ifnone); reset_test_iface(ifnull); - - k_mutex_lock(&event_mutex, K_FOREVER); - - test_event_stats.event_count = 0; - test_event_stats.timeout_count = 0; - test_event_stats.fatal_error_count = 0; - test_event_stats.event_iface = NULL; - test_event_stats.event_info = 0; - - k_mutex_unlock(&event_mutex); -} - -static void *conn_mgr_conn_setup(void) -{ - net_mgmt_init_event_callback(&conn_mgr_conn_callback, conn_mgr_conn_handler, - NET_EVENT_CONN_IF_TIMEOUT | NET_EVENT_CONN_IF_FATAL_ERROR); - net_mgmt_add_event_callback(&conn_mgr_conn_callback); - return NULL; } /* This suite uses k_sleep(K_MSEC(1)) to allow Zephyr to perform event propagation. @@ -498,73 +441,6 @@ ZTEST(conn_mgr_conn, test_disconnect_fail) "conn_mgr_if_disconnect should give -EDOM"); } -/* Verify that the NET_EVENT_CONN_IF_TIMEOUT event works as expected. */ -ZTEST(conn_mgr_conn, test_connect_timeout) -{ - struct event_stats stats; - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* instruct ifa1 to timeout on connect */ - ifa1_data->timeout = true; - - /* Take up and attempt to connect iface */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed"); - - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed"); - - /* Confirm iface is not immediately connected */ - zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); - - /* Ensure timeout event is fired */ - k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); - - k_mutex_lock(&event_mutex, K_FOREVER); - stats = test_event_stats; - k_mutex_unlock(&event_mutex); - - zassert_equal(stats.timeout_count, 1, - "NET_EVENT_CONN_IF_TIMEOUT should have been fired"); - zassert_equal(stats.event_count, 1, - "only NET_EVENT_CONN_IF_TIMEOUT should have been fired"); - zassert_equal(stats.event_iface, ifa1, - "Timeout event should be raised on ifa1"); -} - -/* Verify that the NET_EVENT_CONN_IF_FATAL_ERROR event works as expected. */ -ZTEST(conn_mgr_conn, test_connect_fatal_error) -{ - struct event_stats stats; - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* instruct ifa1 to have fatal error on connect. */ - ifa1_data->fatal_error = -EADDRINUSE; - - /* Take up and attempt to connect iface */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed"); - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed"); - - /* Confirm iface is not immediately connected */ - zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); - - /* Ensure fatal_error event is fired */ - k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); - - k_mutex_lock(&event_mutex, K_FOREVER); - stats = test_event_stats; - k_mutex_unlock(&event_mutex); - - zassert_equal(stats.fatal_error_count, 1, - "NET_EVENT_CONN_IF_FATAL_ERROR should have been fired"); - zassert_equal(stats.event_count, 1, - "only NET_EVENT_CONN_IF_FATAL_ERROR should have been fired"); - zassert_equal(stats.event_iface, ifa1, - "Fatal error event should be raised on ifa1"); - zassert_equal(stats.event_info, -EADDRINUSE, - "Fatal error info should be -EADDRINUSE"); -} - - - /* Verify that conn_mgr_if_is_bound gives correct results */ ZTEST(conn_mgr_conn, test_supports_connectivity) { @@ -823,4 +699,4 @@ ZTEST(conn_mgr_conn, test_timeout_invalid) "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnone"); } -ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); +ZTEST_SUITE(conn_mgr_conn, NULL, NULL, conn_mgr_conn_before, NULL, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c index 8d2395160590..6004fe34974b 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -8,72 +8,6 @@ #include #include "test_conn_impl.h" -/* Event simulation */ -static int simulated_event; -static struct net_if *simulated_event_iface; -static K_MUTEX_DEFINE(simulated_event_mutex); - -/* Static storage for fatal error info */ -static int fatal_error; - -void simulate_event_handler(struct k_work *work) -{ - ARG_UNUSED(*work); - - k_mutex_lock(&simulated_event_mutex, K_FOREVER); - - if (simulated_event == 0) { - net_mgmt_event_notify( - NET_EVENT_CONN_IF_TIMEOUT, - simulated_event_iface - ); - } else { - fatal_error = simulated_event; - net_mgmt_event_notify_with_info( - NET_EVENT_CONN_IF_FATAL_ERROR, - simulated_event_iface, &fatal_error, sizeof(fatal_error) - ); - } - - k_mutex_unlock(&simulated_event_mutex); -} - -static K_WORK_DELAYABLE_DEFINE(simulate_event_work, simulate_event_handler); - -/** - * @brief Simulates an event on the target iface. - * - * Do not attempt to simulate multiple events simultaneously -- only the last event requested - * will be fired. - * - * @param target - iface to simulate the event on. - * @param event - Event to simulate. - * If 0, simulate a timeout. - * Otherwise, simulate a fatal error with this value as the reason/info. - */ -static void simulate_event(struct net_if *target, int event) -{ - k_mutex_lock(&simulated_event_mutex, K_FOREVER); - - simulated_event = event; - simulated_event_iface = target; - k_work_reschedule(&simulate_event_work, K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS)); - - k_mutex_unlock(&simulated_event_mutex); -} - -static void simulate_timeout(struct net_if *target) -{ - simulate_event(target, 0); -} - -static void simulate_fatal_error(struct net_if *target, int reason) -{ - simulate_event(target, reason); -} - -/* Connectivity implementations */ - static void inc_call_count(struct test_conn_data *data, bool a) { if (a) { @@ -89,26 +23,11 @@ static int test_connect(struct conn_mgr_conn_binding *const binding, bool a) inc_call_count(data, a); - /* Fail immediately if requested */ if (data->api_err != 0) { return data->api_err; } - /* Fail after a delay if requested */ - if (data->fatal_error) { - simulate_fatal_error(binding->iface, data->fatal_error); - return 0; - } - - if (data->timeout) { - simulate_timeout(binding->iface); - return 0; - } - - /* Succeed otherwise */ - data->conn_bal += 1; - /* Mark iface as connected */ net_if_dormant_off(binding->iface); return 0; diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h index 6408bb802cfc..170ffc436bf4 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -15,7 +15,6 @@ #define ZEPHYR_INCLUDE_TEST_CONN_IMPL_H_ #include -#include #ifdef __cplusplus extern "C" { @@ -44,12 +43,6 @@ struct test_conn_data { /* If nonzero, an error code the APIs should return. */ int api_err; - /* If true, the implementation should time out on connect. */ - bool timeout; - - /* If nonzero, the implementation should fail to connect and raise this fatal error. */ - int fatal_error; - /* Places to store data from set_opt calls */ char data_x[TEST_CONN_DATA_LEN + 1]; char data_y[TEST_CONN_DATA_LEN + 1]; @@ -76,8 +69,6 @@ CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_N); #define TEST_L2_CONN_IMPL_NI_CTX_TYPE struct test_conn_data CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); -#define SIMULATED_EVENT_DELAY_SECONDS 5 - #ifdef __cplusplus } #endif From 65969f4c4c220dc9c56b5b72328aa1a466c30867 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 291/528] Revert "[nrf fromtree] tests: net: Add tests for conn_mgr_conn" This reverts commit 031eb6e1b954e01aee3e4f259880667f8d00711d. Signed-off-by: Robert Lubos --- tests/net/conn_mgr_conn/CMakeLists.txt | 9 - tests/net/conn_mgr_conn/prj.conf | 26 - tests/net/conn_mgr_conn/src/main.c | 702 ------------------- tests/net/conn_mgr_conn/src/test_conn_impl.c | 187 ----- tests/net/conn_mgr_conn/src/test_conn_impl.h | 76 -- tests/net/conn_mgr_conn/src/test_ifaces.c | 125 ---- tests/net/conn_mgr_conn/src/test_ifaces.h | 29 - tests/net/conn_mgr_conn/testcase.yaml | 6 - 8 files changed, 1160 deletions(-) delete mode 100644 tests/net/conn_mgr_conn/CMakeLists.txt delete mode 100644 tests/net/conn_mgr_conn/prj.conf delete mode 100644 tests/net/conn_mgr_conn/src/main.c delete mode 100644 tests/net/conn_mgr_conn/src/test_conn_impl.c delete mode 100644 tests/net/conn_mgr_conn/src/test_conn_impl.h delete mode 100644 tests/net/conn_mgr_conn/src/test_ifaces.c delete mode 100644 tests/net/conn_mgr_conn/src/test_ifaces.h delete mode 100644 tests/net/conn_mgr_conn/testcase.yaml diff --git a/tests/net/conn_mgr_conn/CMakeLists.txt b/tests/net/conn_mgr_conn/CMakeLists.txt deleted file mode 100644 index c1807456006c..000000000000 --- a/tests/net/conn_mgr_conn/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(test_conn_mgr_conn) - -target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/ip) -FILE(GLOB app_sources src/*.c) -target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/conn_mgr_conn/prj.conf b/tests/net/conn_mgr_conn/prj.conf deleted file mode 100644 index 5ffa0ba9d9fc..000000000000 --- a/tests/net/conn_mgr_conn/prj.conf +++ /dev/null @@ -1,26 +0,0 @@ -CONFIG_NETWORKING=y -CONFIG_NET_TEST=y -CONFIG_NET_IPV6=y -CONFIG_NET_IPV4=y -CONFIG_NET_MAX_CONTEXTS=4 -CONFIG_NET_L2_DUMMY=y -CONFIG_NET_LOG=y -CONFIG_NET_CONNECTION_MANAGER=y -CONFIG_ENTROPY_GENERATOR=y -CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NET_IPV6_DAD=n -CONFIG_NET_IPV6_MLD=n -CONFIG_NET_PKT_TX_COUNT=10 -CONFIG_NET_PKT_RX_COUNT=5 -CONFIG_NET_BUF_RX_COUNT=10 -CONFIG_NET_BUF_TX_COUNT=10 -CONFIG_NET_IF_UNICAST_IPV6_ADDR_COUNT=6 -CONFIG_NET_IF_UNICAST_IPV4_ADDR_COUNT=2 -CONFIG_NET_MAX_NEXTHOPS=8 -CONFIG_NET_IPV6_MAX_NEIGHBORS=8 -CONFIG_NET_IPV6_ND=n -CONFIG_ZTEST=y -CONFIG_ZTEST_NEW_API=y -CONFIG_NET_IF_MAX_IPV4_COUNT=6 -CONFIG_NET_IF_MAX_IPV6_COUNT=6 -CONFIG_TEST_USERSPACE=y diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c deleted file mode 100644 index e8da4e9d7d58..000000000000 --- a/tests/net/conn_mgr_conn/src/main.c +++ /dev/null @@ -1,702 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include "test_conn_impl.h" -#include "test_ifaces.h" - - -/* This is a duplicate of conn_mgr_if_get_binding in net_if.c, - * which is currently not exposed. - */ -static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) -{ - STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { - if (iface == binding->iface) { - if (binding->impl->api) { - return binding; - } - return NULL; - } - } - return NULL; -} - -static inline struct test_conn_data *conn_mgr_if_get_data(struct net_if *iface) -{ - struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); - - if (!binding) { - return NULL; - } - return binding->ctx; -} - -static void reset_test_iface(struct net_if *iface) -{ - if (net_if_is_admin_up(iface)) { - (void)net_if_down(iface); - } - - /* Some tests can leave the iface in a bad state where it is admin-down but not dormant */ - net_if_dormant_on(iface); - - struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface); - struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); - - if (iface_binding) { - iface_binding->flags = 0; - iface_binding->timeout = CONN_MGR_IF_NO_TIMEOUT; - } - - if (iface_data) { - iface_data->call_cnt_a = 0; - iface_data->call_cnt_b = 0; - iface_data->conn_bal = 0; - iface_data->api_err = 0; - memset(iface_data->data_x, 0, sizeof(iface_data->data_x)); - memset(iface_data->data_y, 0, sizeof(iface_data->data_y)); - } -} - -static void conn_mgr_conn_before(void *data) -{ - ARG_UNUSED(data); - reset_test_iface(ifa1); - reset_test_iface(ifa2); - reset_test_iface(ifb); - reset_test_iface(ifni); - reset_test_iface(ifnone); - reset_test_iface(ifnull); -} - -/* This suite uses k_sleep(K_MSEC(1)) to allow Zephyr to perform event propagation. - * This is not guaranteed to execute in the fastest possible time, nor is it technically guaranteed - * that Zephyr will finish its operations in less than a millisecond, but for this test suite, - * event propagation times longer than a millisecond would be a sign of a problem, - * a few milliseconds of delay are miniscule compared to the time it takes to build the suite, - * and using k_sleep has the advantage of being completely agnostic to the underlying operation - * of the events. - */ - -/* Verify that the correct init APIs were called. */ -ZTEST(conn_mgr_conn, test_inspect_init) -{ - /* This isn't a proper test in that it only verifies the result of an exterior operation, - * but it increases coverage and costs next to nothing to add. - */ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - struct test_conn_data *ifa2_data = conn_mgr_if_get_data(ifa2); - struct test_conn_data *ifb_data = conn_mgr_if_get_data(ifb); - struct test_conn_data *ifni_data = conn_mgr_if_get_data(ifni); - - - zassert_equal(ifa1_data->init_calls_a, 1, "ifa1->init should be called exactly once."); - zassert_equal(ifa1_data->init_calls_b, 0, "ifa1 should use implementation A"); - - zassert_equal(ifa2_data->init_calls_a, 1, "ifa2->init should be called exactly once."); - zassert_equal(ifa2_data->init_calls_b, 0, "ifa2 should use implementation A"); - - zassert_equal(ifb_data->init_calls_b, 1, "ifb->init should be called exactly once."); - zassert_equal(ifb_data->init_calls_a, 0, "ifb should use implementation B"); - - zassert_equal(ifni_data->init_calls_a, 0, "ifni->init should not be called."); - zassert_equal(ifni_data->init_calls_b, 0, "ifni->init should not be called."); -} - -/* Verify that conn_mgr_if_connect and conn_mgr_if_disconnect perform the - * correct API calls to the correct interfaces and connectivity implementations - */ -ZTEST(conn_mgr_conn, test_connect_disconnect) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - struct test_conn_data *ifa2_data = conn_mgr_if_get_data(ifa2); - struct test_conn_data *ifb_data = conn_mgr_if_get_data(ifb); - - /* Take all ifaces up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); - zassert_equal(net_if_up(ifa2), 0, "net_if_up should not fail"); - zassert_equal(net_if_up(ifb), 0, "net_if_up should not fail"); - - /* Verify ifaces are still disconnected */ - zassert_false(net_if_is_up(ifa1), "Ifaces must be disconnected before test"); - zassert_false(net_if_is_up(ifa2), "Ifaces must be disconnected before test"); - zassert_false(net_if_is_up(ifb), "Ifaces must be disconnected before test"); - - /* Connect one of the A ifaces */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success, and that only the target iface/conn impl were affected/invoked */ - zassert_true(net_if_is_up(ifa1), "ifa1 should be oper-up after conn_mgr_if_connect"); - zassert_false(net_if_is_up(ifa2), "ifa2 should not be affected by ifa1"); - zassert_false(net_if_is_up(ifb), "ifb should not be affected by ifa1"); - - /* Verify that all ifaces have the expected call counts and types */ - zassert_equal(ifa1_data->conn_bal, 1, "ifa1->connect should be called once"); - zassert_equal(ifa1_data->call_cnt_a, 1, "Implementation A should be used for ifa1"); - zassert_equal(ifa1_data->call_cnt_b, 0, "Implementation A should be used for ifa1"); - - zassert_equal(ifa2_data->conn_bal, 0, "ifa2 should not be affected by ifa1"); - zassert_equal(ifa2_data->call_cnt_a, 0, "ifa2 should not be affected by ifa1"); - zassert_equal(ifa2_data->call_cnt_b, 0, "ifa2 should not be affected by ifa1"); - - zassert_equal(ifb_data->conn_bal, 0, "ifb should not be affected by ifa1"); - zassert_equal(ifb_data->call_cnt_a, 0, "ifb should not be affected by ifa1"); - zassert_equal(ifb_data->call_cnt_b, 0, "ifb should not be affected by ifa1"); - - /* Now connect the B iface */ - zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success, and that only the target iface/conn impl were affected/invoked */ - zassert_true(net_if_is_up(ifa1), "ifa1 should still be connected"); - zassert_false(net_if_is_up(ifa2), "ifa2 should not be affected by ifb"); - zassert_true(net_if_is_up(ifb), "ifb should be oper-up after conn_mgr_if_connect"); - - /* Verify that all ifaces have the expected call counts and types */ - zassert_equal(ifa1_data->conn_bal, 1, "ifa1 should not be affected by ifb"); - zassert_equal(ifa1_data->call_cnt_a, 1, "ifa1 should not be affected by ifb"); - zassert_equal(ifa1_data->call_cnt_b, 0, "ifa1 should not be affected by ifb"); - - zassert_equal(ifa2_data->conn_bal, 0, "ifa2 should not be affected by ifb"); - zassert_equal(ifa2_data->call_cnt_a, 0, "ifa2 should not be affected by ifb"); - zassert_equal(ifa2_data->call_cnt_b, 0, "ifa2 should not be affected by ifb"); - - zassert_equal(ifb_data->conn_bal, 1, "ifb->connect should be called once"); - zassert_equal(ifb_data->call_cnt_a, 0, "Implementation B should be used for ifb"); - zassert_equal(ifb_data->call_cnt_b, 1, "Implementation B should be used for ifb"); - - /* Now connect the other A iface */ - zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success, and that only the target iface/conn impl were affected/invoked */ - zassert_true(net_if_is_up(ifa1), "ifa1 should still be connected"); - zassert_true(net_if_is_up(ifa2), "ifa2 should be oper-up after conn_mgr_if_connect"); - zassert_true(net_if_is_up(ifb), "ifb should still be connected"); - - /* Verify that all ifaces have the expected call counts and types */ - zassert_equal(ifa1_data->conn_bal, 1, "ifa1 should not be affected by ifa2"); - zassert_equal(ifa1_data->call_cnt_a, 1, "ifa1 should not be affected by ifa2"); - zassert_equal(ifa1_data->call_cnt_b, 0, "ifa1 should not be affected by ifa2"); - - zassert_equal(ifa2_data->conn_bal, 1, "ifa2->connect should be called once"); - zassert_equal(ifa2_data->call_cnt_a, 1, "Implementation A should be used for ifa2"); - zassert_equal(ifa2_data->call_cnt_b, 0, "Implementation A should be used for ifa2"); - - zassert_equal(ifb_data->conn_bal, 1, "ifb should not be affected by ifa2"); - zassert_equal(ifb_data->call_cnt_a, 0, "ifb should not be affected by ifa2"); - zassert_equal(ifb_data->call_cnt_b, 1, "ifb should not be affected by ifa2"); - - /* Now disconnect the original A iface */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); - k_sleep(K_MSEC(1)); - - - /* Verify success, and that only the target iface/conn impl were affected/invoked */ - zassert_false(net_if_is_up(ifa1), "ifa1 should be oper-down after conn_mgr_if_disconnect"); - zassert_true(net_if_is_up(ifa2), "ifa2 should not be affected by ifa1"); - zassert_true(net_if_is_up(ifb), "ifb should not be affected by ifa1"); - - /* Verify that all ifaces have the expected call counts and types */ - zassert_equal(ifa1_data->conn_bal, 0, "ifa1->disconnect should be called once"); - zassert_equal(ifa1_data->call_cnt_a, 2, "Implementation A should be used for ifa1"); - zassert_equal(ifa1_data->call_cnt_b, 0, "Implementation A should be used for ifa1"); - - zassert_equal(ifa2_data->conn_bal, 1, "ifa2 should not be affected by ifa1"); - zassert_equal(ifa2_data->call_cnt_a, 1, "ifa2 should not be affected by ifa1"); - zassert_equal(ifa2_data->call_cnt_b, 0, "ifa2 should not be affected by ifa1"); - - zassert_equal(ifb_data->conn_bal, 1, "ifb should not be affected by ifa1"); - zassert_equal(ifb_data->call_cnt_a, 0, "ifb should not be affected by ifa1"); - zassert_equal(ifb_data->call_cnt_b, 1, "ifb should not be affected by ifa1"); - - /* Now disconnect the B iface */ - zassert_equal(conn_mgr_if_disconnect(ifb), 0, "conn_mgr_if_disconnect should not fail"); - k_sleep(K_MSEC(1)); - - - /* Verify success, and that only the target iface/conn impl were affected/invoked */ - zassert_false(net_if_is_up(ifa1), "ifa1 should still be disconnected"); - zassert_true(net_if_is_up(ifa2), "ifa2 should not be affected by ifb"); - zassert_false(net_if_is_up(ifb), "ifb should be oper-down after conn_mgr_if_disconnect"); - - /* Verify that all ifaces have the expected call counts and types */ - zassert_equal(ifa1_data->conn_bal, 0, "ifa1 should not be affected by ifb"); - zassert_equal(ifa1_data->call_cnt_a, 2, "ifa1 should not be affected by ifb"); - zassert_equal(ifa1_data->call_cnt_b, 0, "ifa1 should not be affected by ifb"); - - zassert_equal(ifa2_data->conn_bal, 1, "ifa1 should not be affected by ifb"); - zassert_equal(ifa2_data->call_cnt_a, 1, "ifa1 should not be affected by ifb"); - zassert_equal(ifa2_data->call_cnt_b, 0, "ifa1 should not be affected by ifb"); - - zassert_equal(ifb_data->conn_bal, 0, "ifa1->disconnect should be called once"); - zassert_equal(ifb_data->call_cnt_a, 0, "Implementation B should be used for ifb"); - zassert_equal(ifb_data->call_cnt_b, 2, "Implementation B should be used for ifb"); - - /* Finally, disconnect the last A iface */ - zassert_equal(conn_mgr_if_disconnect(ifa2), 0, "conn_mgr_if_disconnect should not fail"); - k_sleep(K_MSEC(1)); - - - /* Verify success, and that only the target iface/conn impl were affected/invoked */ - zassert_false(net_if_is_up(ifa1), "ifa1 should still be disconnected"); - zassert_false(net_if_is_up(ifa2), "ifa2 should be oper-down after conn_mgr_if_disconnect"); - zassert_false(net_if_is_up(ifb), "ifb should still be disconnected"); - - /* Verify that all ifaces have the expected call counts and types */ - zassert_equal(ifa1_data->conn_bal, 0, "ifa1 should not be affected by ifa2"); - zassert_equal(ifa1_data->call_cnt_a, 2, "ifa1 should not be affected by ifa2"); - zassert_equal(ifa1_data->call_cnt_b, 0, "ifa1 should not be affected by ifa2"); - - zassert_equal(ifa2_data->conn_bal, 0, "ifa2->disconnect should be called once"); - zassert_equal(ifa2_data->call_cnt_a, 2, "Implementation A should be used for ifa2"); - zassert_equal(ifa2_data->call_cnt_b, 0, "Implementation A should be used for ifa2"); - - zassert_equal(ifb_data->conn_bal, 0, "ifb should not be affected by ifa2"); - zassert_equal(ifb_data->call_cnt_a, 0, "ifb should not be affected by ifa2"); - zassert_equal(ifb_data->call_cnt_b, 2, "ifb should not be affected by ifa2"); -} - -/* Verify that double calls to conn_mgr_if_connect and conn_mgr_if_disconnect cause no problems */ -ZTEST(conn_mgr_conn, test_connect_disconnect_double_delayed) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); - - /* Connect iface */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success */ - zassert_true(net_if_is_up(ifa1), "ifa1 should be oper-up after conn_mgr_if_connect"); - zassert_equal(ifa1_data->conn_bal, 1, "ifa1->connect should have been called once."); - zassert_equal(ifa1_data->call_cnt_a, 1, "ifa1->connect should have been called once."); - - /* Connect iface again */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success - * To be clear: Yes, ifa1->connect should be called twice. It is up to the L2 - * connectivity implementation to either handle idempotence - */ - zassert_true(net_if_is_up(ifa1), "ifa1 should still be connected"); - zassert_equal(ifa1_data->conn_bal, 2, "ifa1->connect should have been called again."); - zassert_equal(ifa1_data->call_cnt_a, 2, "ifa1->connect should have been called again."); - - /* Now disconnect the iface */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success */ - zassert_false(net_if_is_up(ifa1), "ifa1 should be oper-down after conn_mgr_if_disconnect"); - zassert_equal(ifa1_data->conn_bal, 1, "ifa1->disconnect should have been called once."); - zassert_equal(ifa1_data->call_cnt_a, 3, "ifa1->disconnect should have been called once."); - - /* Disconnect again! */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success */ - zassert_false(net_if_is_up(ifa1), "ifa1 should be oper-down after conn_mgr_if_disconnect"); - zassert_equal(ifa1_data->conn_bal, 0, "ifa1->disconnect should have been called again."); - zassert_equal(ifa1_data->call_cnt_a, 4, "ifa1->disconnect should have been called again."); -} - -/* Verify that fast double calls to conn_mgr_if_connect and conn_mgr_if_disconnect - * do not fail - */ -ZTEST(conn_mgr_conn, test_connect_disconnect_double_instant) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Take iface up */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); - - /* Connect twice */ - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success */ - zassert_true(net_if_is_up(ifa1), "ifa1 should be oper-up after conn_mgr_if_connect"); - zassert_equal(ifa1_data->conn_bal, 2, "ifa1->connect should have been called once."); - zassert_equal(ifa1_data->call_cnt_a, 2, "ifa1->connect should have been called once."); - - /* Now disconnect twice */ - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); - zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "conn_mgr_if_disconnect should not fail"); - k_sleep(K_MSEC(1)); - - /* Verify success */ - zassert_false(net_if_is_up(ifa1), "ifa1 should be oper-down after conn_mgr_if_disconnect"); - zassert_equal(ifa1_data->conn_bal, 0, "ifa1->disconnect should have been called once."); - zassert_equal(ifa1_data->call_cnt_a, 4, "ifa1->disconnect should have been called once."); -} - -/* Verify that connecting an iface that isn't up, missing an API, - * or isn't connectivity-bound raises an error. - */ -ZTEST(conn_mgr_conn, test_connect_invalid) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Bring ifnull and ifnone up */ - zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for ifnull"); - zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for ifnone"); - - /* Attempts to connect ifa1 without bringing it up should fail */ - zassert_equal(conn_mgr_if_connect(ifa1), -ESHUTDOWN, - "conn_mgr_if_connect should give -ENOTSUP for down iface"); - zassert_equal(ifa1_data->conn_bal, 0, - "conn_mgr_if_connect should not affect down iface"); - zassert_equal(ifa1_data->call_cnt_a, 0, - "conn_mgr_if_connect should not affect down iface"); - - /* Attempts to connect ifnull should fail, even if it is up */ - zassert_equal(conn_mgr_if_connect(ifnull), -ENOTSUP, - "conn_mgr_if_connect should give -ENOTSUP for ifnull"); - - /* Attempts to connect ifnone should fail, even if it is up */ - zassert_equal(conn_mgr_if_connect(ifnone), -ENOTSUP, - "conn_mgr_if_connect should give -ENOTSUP for ifnone"); -} - -/* Verify that disconnecting an iface that isn't up, missing an API, - * or isn't connectivity-bound raises an error. - */ -ZTEST(conn_mgr_conn, test_disconnect_invalid) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Bring ifnull and ifnone up */ - zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for ifnull"); - zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for ifnone"); - - /* Attempts to disconnect ifa1 without bringing it up should fail */ - zassert_equal(conn_mgr_if_disconnect(ifa1), -EALREADY, - "conn_mgr_if_disconnect should give -ENOTSUP for down iface"); - zassert_equal(ifa1_data->conn_bal, 0, - "conn_mgr_if_disconnect should not affect down iface"); - zassert_equal(ifa1_data->call_cnt_a, 0, - "conn_mgr_if_disconnect should not affect down iface"); - - /* Attempts to disconnect ifnull should fail, even if it is up */ - zassert_equal(conn_mgr_if_disconnect(ifnull), -ENOTSUP, - "conn_mgr_if_disconnect should give -ENOTSUP for ifnull"); - - /* Attempts to disconnect ifnone should fail, even if it is up */ - zassert_equal(conn_mgr_if_disconnect(ifnone), -ENOTSUP, - "conn_mgr_if_disconnect should give -ENOTSUP for ifnone"); -} - -/* Verify that conn_mgr_if_connect forwards error codes from API */ -ZTEST(conn_mgr_conn, test_connect_fail) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Instruct ifa1 to fail on connect attempt */ - ifa1_data->api_err = -ECHILD; - - /* Take ifa1 up before attempting to connect */ - zassert_equal(net_if_up(ifa1), 0, - "conn_mgr_if_connect should succeed"); - - /* Attempts to connect ifa1 should return the expected error*/ - zassert_equal(conn_mgr_if_connect(ifa1), -ECHILD, - "conn_mgr_if_connect should give -ECHILD"); -} - -/* Verify that conn_mgr_if_disconnect forwards error codes from API */ -ZTEST(conn_mgr_conn, test_disconnect_fail) -{ - struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); - - /* Take up and connect iface first */ - zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed"); - zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed"); - - /* Instruct ifa1 to fail on disconnect attempt */ - ifa1_data->api_err = -EDOM; - - /* Attempts to disconnect ifa1 should return the expected error*/ - zassert_equal(conn_mgr_if_disconnect(ifa1), -EDOM, - "conn_mgr_if_disconnect should give -EDOM"); -} - -/* Verify that conn_mgr_if_is_bound gives correct results */ -ZTEST(conn_mgr_conn, test_supports_connectivity) -{ - zassert_true(conn_mgr_if_is_bound(ifa1)); - zassert_true(conn_mgr_if_is_bound(ifa2)); - zassert_true(conn_mgr_if_is_bound(ifb)); - zassert_false(conn_mgr_if_is_bound(ifnull)); - zassert_false(conn_mgr_if_is_bound(ifnone)); -} - -/* 60 characters long */ -#define TEST_STR_LONG "AAAAAaaaaaBBBBBbbbbbCCCCCcccccDDDDDdddddEEEEEeeeeeFFFFFfffff" - -/* Verify that conn_opt get/set functions operate correctly and affect only the target iface */ -ZTEST(conn_mgr_conn, test_conn_opt) -{ - char buf[100]; - size_t buf_len = 0; - - /* Set ifa1->X to "A" */ - strcpy(buf, "A"); - zassert_equal(conn_mgr_if_set_opt(ifa1, TEST_CONN_OPT_X, &buf, strlen(buf) + 1), 0, - "conn_mgr_if_set_opt should succeed for valid parameters"); - - /* Verify success */ - memset(buf, 0, sizeof(buf)); - buf_len = sizeof(buf); - zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, &buf, &buf_len), - 0, "conn_mgr_if_get_opt should succeed for valid parameters"); - printk("%d, %d", buf_len, strlen(buf) + 1); - zassert_equal(buf_len, strlen(buf) + 1, "conn_mgr_if_get_opt should return valid optlen"); - zassert_equal(strcmp(buf, "A"), 0, "conn_mgr_if_get_opt should retrieve \"A\""); - - /* Verify that ifa1->Y was not affected */ - memset(buf, 0, sizeof(buf)); - buf_len = sizeof(buf); - zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_Y, &buf, &buf_len), - 0, "conn_mgr_if_get_opt should succeed for valid parameters"); - zassert_equal(buf_len, 1, "conn_mgr_if_get_opt should yield nothing for ifa1->Y"); - zassert_equal(buf[0], 0, "conn_mgr_if_get_opt should yield nothing for ifa1->Y"); - - /* Verify that ifa2->X was not affected */ - memset(buf, 0, sizeof(buf)); - buf_len = sizeof(buf); - zassert_equal(conn_mgr_if_get_opt(ifa2, TEST_CONN_OPT_X, &buf, &buf_len), - 0, "conn_mgr_if_get_opt should succeed for valid parameters"); - zassert_equal(buf_len, 1, "conn_mgr_if_get_opt should yield nothing for ifa2->X"); - zassert_equal(buf[0], 0, "conn_mgr_if_get_opt should yield nothing for ifa2->X"); - - /* Now, set ifa->Y to "ABC" */ - strcpy(buf, "ABC"); - zassert_equal(conn_mgr_if_set_opt(ifa1, TEST_CONN_OPT_Y, &buf, strlen(buf) + 1), 0, - "conn_mgr_if_set_opt should succeed for valid parameters"); - - /* Verify success */ - memset(buf, 0, sizeof(buf)); - buf_len = sizeof(buf); - zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_Y, &buf, &buf_len), - 0, "conn_mgr_if_get_opt should succeed for valid parameters"); - zassert_equal(buf_len, strlen(buf) + 1, "conn_mgr_if_get_opt should return valid optlen"); - zassert_equal(strcmp(buf, "ABC"), 0, "conn_mgr_if_get_opt should retrieve \"ABC\""); - - /* Verify that ifa1->X was not affected */ - memset(buf, 0, sizeof(buf)); - buf_len = sizeof(buf); - zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, &buf, &buf_len), - 0, "conn_mgr_if_get_opt should succeed for valid parameters"); - zassert_equal(buf_len, strlen(buf) + 1, "conn_mgr_if_get_opt should return valid optlen"); - zassert_equal(strcmp(buf, "A"), 0, "conn_mgr_if_get_opt should retrieve \"A\""); - - /* Next, we pass some buffers that are too large or too small. - * This is an indirect way of verifying that buf_len is passed correctly. - */ - - /* Try writing a string that is too large to ifa1->X */ - strcpy(buf, TEST_STR_LONG); - zassert_equal(conn_mgr_if_set_opt(ifa1, TEST_CONN_OPT_X, &buf, strlen(buf) + 1), 0, - "conn_mgr_if_set_opt should succeed for valid parameters"); - - /* Verify partial success */ - memset(buf, 0, sizeof(buf)); - buf_len = sizeof(buf); - zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, &buf, &buf_len), 0, - "conn_mgr_if_get_opt should succeed for valid parameters"); - zassert_equal(buf_len, strlen(buf) + 1, - "conn_mgr_if_get_opt should return valid optlen"); - - /* This does, technically, test the test harness, but this test will fail if - * the unit under test (conn_mgr_if_set_opt) fails to pass along the optlen - */ - zassert_true(strlen(buf) < strlen(TEST_STR_LONG), - "test_set_opt_a should truncate long values"); - - /* For the same reason, verify that get_opt truncates given a small destination buffer */ - memset(buf, 0, sizeof(buf)); - buf_len = 10; - zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, &buf, &buf_len), 0, - "conn_mgr_if_get_opt should succeed for valid parameters"); - zassert_equal(buf_len, strlen(buf) + 1, - "conn_mgr_if_get_opt should return valid optlen"); - zassert_equal(buf_len, 10, - "test_get_opt_a should truncate if dest. buffer is too small."); -} - -/* Verify that conn_mgr_if_get_opt and conn_mgr_if_set_opt behave as expected when given invalid - * arguments. - */ -ZTEST(conn_mgr_conn, test_conn_opt_invalid) -{ - char buf[100]; - size_t buf_len; - - /* Verify that getting/setting non-existent option on ifa1 fails */ - zassert_equal(conn_mgr_if_set_opt(ifa1, -1, "A", strlen("A")), -ENOPROTOOPT, - "conn_mgr_if_set_opt should fail with invalid optname"); - buf_len = sizeof(buf_len); - zassert_equal(conn_mgr_if_get_opt(ifa1, -1, buf, &buf_len), -ENOPROTOOPT, - "conn_mgr_if_get_opt should fail with invalid optname"); - zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); - - /* Verify that getting/setting with NULL buffer on ifa1 fails */ - zassert_equal(conn_mgr_if_set_opt(ifa1, TEST_CONN_OPT_X, NULL, 100), -EINVAL, - "conn_mgr_if_set_opt should fail with invalid buffer"); - buf_len = sizeof(buf_len); - zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, NULL, &buf_len), -EINVAL, - "conn_mgr_if_get_opt should fail with invalid buffer"); - zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); - - /* Verify that getting with NULL buffer length on ifa1 fails */ - zassert_equal(conn_mgr_if_get_opt(ifa1, TEST_CONN_OPT_X, buf, NULL), -EINVAL, - "conn_mgr_if_get_opt should fail with invalid buffer length"); - - /* Verify that getting/setting with ifnull fails */ - zassert_equal(conn_mgr_if_set_opt(ifnull, TEST_CONN_OPT_X, "A", strlen("A")), -ENOTSUP, - "conn_mgr_if_set_opt should fail for ifnull"); - buf_len = sizeof(buf_len); - zassert_equal(conn_mgr_if_get_opt(ifnull, TEST_CONN_OPT_X, buf, &buf_len), -ENOTSUP, - "conn_mgr_if_get_opt should fail for ifnull"); - zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); - - /* Verify that getting/setting with ifnone fails */ - zassert_equal(conn_mgr_if_set_opt(ifnone, TEST_CONN_OPT_X, "A", strlen("A")), -ENOTSUP, - "conn_mgr_if_set_opt should fail for ifnull"); - buf_len = sizeof(buf_len); - zassert_equal(conn_mgr_if_get_opt(ifnone, TEST_CONN_OPT_X, buf, &buf_len), -ENOTSUP, - "conn_mgr_if_get_opt should fail for ifnull"); - zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); - - /* Verify that getting/setting with ifb fails (since implementation B doesn't support it) */ - zassert_equal(conn_mgr_if_set_opt(ifb, TEST_CONN_OPT_X, "A", strlen("A")), -ENOTSUP, - "conn_mgr_if_set_opt should fail for ifb"); - buf_len = sizeof(buf_len); - zassert_equal(conn_mgr_if_get_opt(ifb, TEST_CONN_OPT_X, buf, &buf_len), -ENOTSUP, - "conn_mgr_if_get_opt should fail for ifb"); - zassert_equal(buf_len, 0, "failed conn_mgr_if_get_opt should always set buf_len to zero."); -} - -/* Verify that flag get/set functions operate correctly */ -ZTEST(conn_mgr_conn, test_flags) -{ - struct conn_mgr_conn_binding *ifa1_binding = conn_mgr_if_get_binding(ifa1); - - /* Try setting persistence flag */ - zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true), 0, - "Setting persistence flag should succeed for ifa1"); - - /* Verify success */ - zassert_true(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_PERSISTENT), - "Persistence should be set for ifa1"); - - /* Verify that the conn struct agrees, since this is what implementations may use */ - zassert_equal(ifa1_binding->flags, BIT(CONN_MGR_IF_PERSISTENT), - "Persistence flag set should affect conn struct"); - - /* Try unsetting persistence flag */ - zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false), 0, - "Unsetting persistence flag should succeed for ifa1"); - - /* Verify success */ - zassert_false(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_PERSISTENT), - "Persistence should be unset for ifa1"); - - /* Verify that the conn struct agrees, since this is what implementations may use */ - zassert_equal(ifa1_binding->flags, 0, - "Persistence flag unset should affect conn struct"); -} - -/* Verify that flag get/set fail and behave as expected respectively for invalid ifaces and - * invalid flags. - */ -ZTEST(conn_mgr_conn, test_flags_invalid) -{ - int invalid_flag = CONN_MGR_NUM_IF_FLAGS; - - /* Verify set failure for invalid ifaces / flags */ - zassert_equal(conn_mgr_if_set_flag(ifnull, CONN_MGR_IF_PERSISTENT, true), -ENOTSUP, - "Setting persistence flag should fail for ifnull"); - zassert_equal(conn_mgr_if_set_flag(ifnone, CONN_MGR_IF_PERSISTENT, true), -ENOTSUP, - "Setting persistence flag should fail for ifnone"); - zassert_equal(conn_mgr_if_set_flag(ifa1, invalid_flag, true), -EINVAL, - "Setting invalid flag should fail for ifa1"); - - /* Verify get graceful behavior for invalid ifaces / flags */ - zassert_false(conn_mgr_if_get_flag(ifnull, CONN_MGR_IF_PERSISTENT), - "Getting persistence flag should yield false for ifnull"); - zassert_false(conn_mgr_if_get_flag(ifnone, CONN_MGR_IF_PERSISTENT), - "Getting persistence flag should yield false for ifnone"); - zassert_false(conn_mgr_if_get_flag(ifa1, invalid_flag), - "Getting invalid flag should yield false for ifa1"); -} - - -/* Verify that timeout get/set functions operate correctly (A/B) */ -ZTEST(conn_mgr_conn, test_timeout) -{ - struct conn_mgr_conn_binding *ifa1_binding = conn_mgr_if_get_binding(ifa1); - - /* Try setting timeout */ - zassert_equal(conn_mgr_if_set_timeout(ifa1, 99), 0, - "Setting timeout should succeed for ifa1"); - - /* Verify success */ - zassert_equal(conn_mgr_if_get_timeout(ifa1), 99, - "Timeout should be set to 99 for ifa1"); - - /* Verify that the conn struct agrees, since this is what implementations may use */ - zassert_equal(ifa1_binding->timeout, 99, - "Timeout set should affect conn struct"); - - /* Try unsetting timeout */ - zassert_equal(conn_mgr_if_set_timeout(ifa1, CONN_MGR_IF_NO_TIMEOUT), 0, - "Unsetting timeout should succeed for ifa1"); - - /* Verify success */ - zassert_equal(conn_mgr_if_get_timeout(ifa1), CONN_MGR_IF_NO_TIMEOUT, - "Timeout should be unset for ifa1"); - - /* Verify that the conn struct agrees, since this is what implementations may use */ - zassert_equal(ifa1_binding->timeout, CONN_MGR_IF_NO_TIMEOUT, - "Timeout unset should affect conn struct"); -} - -/* Verify that timeout get/set fail and behave as expected respectively for invalid ifaces */ -ZTEST(conn_mgr_conn, test_timeout_invalid) -{ - /* Verify set failure */ - zassert_equal(conn_mgr_if_set_timeout(ifnull, 99), -ENOTSUP, - "Setting timeout should fail for ifnull"); - zassert_equal(conn_mgr_if_set_timeout(ifnone, 99), -ENOTSUP, - "Setting timeout should fail for ifnone"); - - /* Verify get graceful behavior */ - zassert_equal(conn_mgr_if_get_timeout(ifnull), CONN_MGR_IF_NO_TIMEOUT, - "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnull"); - zassert_equal(conn_mgr_if_get_timeout(ifnone), CONN_MGR_IF_NO_TIMEOUT, - "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnone"); -} - -ZTEST_SUITE(conn_mgr_conn, NULL, NULL, conn_mgr_conn_before, NULL, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c deleted file mode 100644 index 6004fe34974b..000000000000 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include "test_conn_impl.h" - -static void inc_call_count(struct test_conn_data *data, bool a) -{ - if (a) { - data->call_cnt_a += 1; - } else { - data->call_cnt_b += 1; - } -} - -static int test_connect(struct conn_mgr_conn_binding *const binding, bool a) -{ - struct test_conn_data *data = binding->ctx; - - inc_call_count(data, a); - - if (data->api_err != 0) { - return data->api_err; - } - - data->conn_bal += 1; - /* Mark iface as connected */ - net_if_dormant_off(binding->iface); - return 0; -} - -static int test_disconnect(struct conn_mgr_conn_binding *const binding, bool a) -{ - struct test_conn_data *data = binding->ctx; - - inc_call_count(data, a); - - if (data->api_err != 0) { - return data->api_err; - } - - data->conn_bal -= 1; - - /* Mark iface as dormant (disconnected) */ - net_if_dormant_on(binding->iface); - return 0; -} - -char *opt_pointer(struct test_conn_data *data, int optname) -{ - switch (optname) { - case TEST_CONN_OPT_X: - return data->data_x; - case TEST_CONN_OPT_Y: - return data->data_y; - } - return NULL; -} - -int test_set_opt_a(struct conn_mgr_conn_binding *const binding, int optname, - const void *optval, size_t optlen) -{ - struct test_conn_data *data = binding->ctx; - char *target = opt_pointer(data, optname); - int len = MIN(optlen, TEST_CONN_DATA_LEN); - - /* get/set opt are only implemented for implementation A */ - inc_call_count(data, true); - - if (target == NULL) { - return -ENOPROTOOPT; - } - - if (data->api_err) { - return data->api_err; - } - - (void)memset(target, 0, TEST_CONN_DATA_LEN); - (void)memcpy(target, optval, len); - - return 0; -} - -int test_get_opt_a(struct conn_mgr_conn_binding *const binding, int optname, - void *optval, size_t *optlen) -{ - struct test_conn_data *data = binding->ctx; - char *target = opt_pointer(data, optname); - int len; - - /* get/set opt are only implemented for implementation A */ - inc_call_count(data, true); - - if (target == NULL) { - *optlen = 0; - return -ENOPROTOOPT; - } - - len = MIN(strlen(target) + 1, *optlen); - - if (data->api_err) { - *optlen = 0; - return data->api_err; - } - *optlen = len; - (void)memset(optval, 0, len); - (void)memcpy(optval, target, len-1); - - return 0; -} - -static void test_init(struct conn_mgr_conn_binding *const binding, bool a) -{ - struct test_conn_data *data = binding->ctx; - - if (a) { - data->init_calls_a += 1; - } else { - data->init_calls_b += 1; - } - - /* Mark the iface dormant (disconnected) on initialization */ - net_if_dormant_on(binding->iface); -} - -static void test_init_a(struct conn_mgr_conn_binding *const binding) -{ - test_init(binding, true); -} - -static void test_init_b(struct conn_mgr_conn_binding *const binding) -{ - test_init(binding, false); -} - -static int test_connect_a(struct conn_mgr_conn_binding *const binding) -{ - return test_connect(binding, true); -} - -static int test_connect_b(struct conn_mgr_conn_binding *const binding) -{ - return test_connect(binding, false); -} - -static int test_disconnect_a(struct conn_mgr_conn_binding *const binding) -{ - return test_disconnect(binding, true); -} - -static int test_disconnect_b(struct conn_mgr_conn_binding *const binding) -{ - return test_disconnect(binding, false); -} - -static struct conn_mgr_conn_api test_conn_api_a = { - .connect = test_connect_a, - .disconnect = test_disconnect_a, - .init = test_init_a, - .get_opt = test_get_opt_a, - .set_opt = test_set_opt_a -}; - -static struct conn_mgr_conn_api test_conn_api_b = { - .connect = test_connect_b, - .disconnect = test_disconnect_b, - .init = test_init_b, -}; - -static struct conn_mgr_conn_api test_conn_api_ni = { - .connect = test_connect_a, - .disconnect = test_disconnect_a, -}; - -/* Equivalent but distinct implementations */ -CONN_MGR_CONN_DEFINE(TEST_L2_CONN_IMPL_A, &test_conn_api_a); -CONN_MGR_CONN_DEFINE(TEST_L2_CONN_IMPL_B, &test_conn_api_b); - -/* Implementation without init */ -CONN_MGR_CONN_DEFINE(TEST_L2_CONN_IMPL_NI, &test_conn_api_ni); - -/* Bad implementation, should be handled gracefully */ -CONN_MGR_CONN_DEFINE(TEST_L2_CONN_IMPL_N, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h deleted file mode 100644 index 170ffc436bf4..000000000000 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - - - -/* test_conn_impl is separated into its own file specifically in order to test that - * CONN_MGR_CONN_DECLARE_PUBLIC functions as expected. - */ - - -#ifndef ZEPHYR_INCLUDE_TEST_CONN_IMPL_H_ -#define ZEPHYR_INCLUDE_TEST_CONN_IMPL_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define TEST_CONN_OPT_X 0 -#define TEST_CONN_OPT_Y 1 -#define TEST_CONN_DATA_LEN 50 - -struct test_conn_data { - /* The number of times an A-implementation API func has been called (other than init) */ - int call_cnt_a; - - /* The number of times a B-implementation API func has been called (other than init) */ - int call_cnt_b; - - /* Increases on each connect call, decreases on each disconnect call */ - int conn_bal; - - /* The number of times A-implementation init was called (should always be 1) */ - int init_calls_a; - - /* The number of times B-implementation init was called (should always be 1) */ - int init_calls_b; - - /* If nonzero, an error code the APIs should return. */ - int api_err; - - /* Places to store data from set_opt calls */ - char data_x[TEST_CONN_DATA_LEN + 1]; - char data_y[TEST_CONN_DATA_LEN + 1]; -}; - -/* Create test L2 connectivity implementations A and B - * - * A and B share generic connect/disconnect implementations that differ only in which call counter - * they increment. - * - * Additionally, A has conn_opt callbacks, whereas B does not. - */ -#define TEST_L2_CONN_IMPL_A_CTX_TYPE struct test_conn_data -CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_A); - -#define TEST_L2_CONN_IMPL_B_CTX_TYPE struct test_conn_data -CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_B); - -/* Create an invalid L2 connectivity implementation with NULL API */ -#define TEST_L2_CONN_IMPL_N_CTX_TYPE struct test_conn_data -CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_N); - -/* Create an L2 connectivity implementation without the optional init */ -#define TEST_L2_CONN_IMPL_NI_CTX_TYPE struct test_conn_data -CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_TEST_CONN_IMPL_H_ */ diff --git a/tests/net/conn_mgr_conn/src/test_ifaces.c b/tests/net/conn_mgr_conn/src/test_ifaces.c deleted file mode 100644 index 23accdd1e803..000000000000 --- a/tests/net/conn_mgr_conn/src/test_ifaces.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include "test_conn_impl.h" -#include "test_ifaces.h" - -/* Create test ifaces */ - -/* Generic iface initializer, shared by all three ifaces */ -static void test_iface_init(struct net_if *iface) -{ - /* Fake link layer address is needed to silence assertions inside the net core */ - static uint8_t fake_lladdr[] = { 0x01 }; - - net_if_set_link_addr(iface, fake_lladdr, sizeof(fake_lladdr), NET_LINK_DUMMY); - - /* Do not automatically start the iface */ - net_if_flag_set(iface, NET_IF_NO_AUTO_START); -} - -/* Mandatory stub for NET_DEVICE_INIT */ -static int test_iface_netdev_init(const struct device *dev) -{ - return 0; -} - -static struct dummy_api test_iface_api = { - .iface_api.init = test_iface_init, -}; - -/* Create three ifaces, a1, a2, b such that: - * iface a1 and a2 share L2 connectivity implementation a - * iface b uses connectivity implementation b - */ -NET_DEVICE_INIT(test_iface_a1, - "test_iface_a1", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); -NET_DEVICE_INIT(test_iface_a2, - "test_iface_a2", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); -NET_DEVICE_INIT(test_iface_b, - "test_iface_b", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); - -/* Create an ifaces with NULL implementation, NULL init, and no connectivity at all */ -NET_DEVICE_INIT(test_iface_null, - "test_iface_null", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); -NET_DEVICE_INIT(test_iface_ni, - "test_iface_ni", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); -NET_DEVICE_INIT(test_iface_none, - "test_iface_none", - test_iface_netdev_init, - NULL, - NULL, - NULL, - CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, - &test_iface_api, - DUMMY_L2, - NET_L2_GET_CTX_TYPE(DUMMY_L2), - 127); - -/* Bind L2 connectivity implementations to ifaces */ -CONN_MGR_BIND_CONN(test_iface_a1, TEST_L2_CONN_IMPL_A); -CONN_MGR_BIND_CONN(test_iface_a2, TEST_L2_CONN_IMPL_A); -CONN_MGR_BIND_CONN(test_iface_b, TEST_L2_CONN_IMPL_B); - -/* Bind edge-case L2 connectivity implementations to ifaces */ -CONN_MGR_BIND_CONN(test_iface_null, TEST_L2_CONN_IMPL_N); -CONN_MGR_BIND_CONN(test_iface_ni, TEST_L2_CONN_IMPL_NI); - -/* Public accessors for static iface structs */ -struct net_if *ifa1 = NET_IF_GET(test_iface_a1, 0); -struct net_if *ifa2 = NET_IF_GET(test_iface_a2, 0); -struct net_if *ifb = NET_IF_GET(test_iface_b, 0); -struct net_if *ifni = NET_IF_GET(test_iface_ni, 0); -struct net_if *ifnull = NET_IF_GET(test_iface_null, 0); -struct net_if *ifnone = NET_IF_GET(test_iface_none, 0); diff --git a/tests/net/conn_mgr_conn/src/test_ifaces.h b/tests/net/conn_mgr_conn/src/test_ifaces.h deleted file mode 100644 index acae7cf78bf3..000000000000 --- a/tests/net/conn_mgr_conn/src/test_ifaces.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_TEST_IFACES_H_ -#define ZEPHYR_INCLUDE_TEST_IFACES_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* Public accessors for static iface structs */ - -extern struct net_if *ifa1; -extern struct net_if *ifa2; -extern struct net_if *ifb; -extern struct net_if *ifni; -extern struct net_if *ifnull; -extern struct net_if *ifnone; - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_TEST_IFACES_H_ */ diff --git a/tests/net/conn_mgr_conn/testcase.yaml b/tests/net/conn_mgr_conn/testcase.yaml deleted file mode 100644 index 77cf06a13095..000000000000 --- a/tests/net/conn_mgr_conn/testcase.yaml +++ /dev/null @@ -1,6 +0,0 @@ -common: - min_ram: 16 - depends_on: netif -tests: - net.conn_mgr_conn: - tags: net iface From 6e2b574bd97d8e14ed9163294177f2e29dadeabd Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 292/528] Revert "[nrf fromtree] net: conn_mgr: connectivity API" This reverts commit 10dd35561631401f40c9f8f49ea47e46e4d0419f. Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 415 ------------------ subsys/net/lib/conn_mgr/CMakeLists.txt | 4 - subsys/net/lib/conn_mgr/conn_mgr.c | 3 - subsys/net/lib/conn_mgr/conn_mgr.ld | 7 - .../net/lib/conn_mgr/conn_mgr_connectivity.c | 277 ------------ 5 files changed, 706 deletions(-) delete mode 100644 include/zephyr/net/conn_mgr_connectivity.h delete mode 100644 subsys/net/lib/conn_mgr/conn_mgr.ld delete mode 100644 subsys/net/lib/conn_mgr/conn_mgr_connectivity.c diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h deleted file mode 100644 index 023b043a249a..000000000000 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ /dev/null @@ -1,415 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief API for defining generic interfaces for configuring and firing network association - * routines on network devices that support it. - */ - -#ifndef ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_ -#define ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Connection Manager Connectivity API - * @defgroup conn_mgr_connectivity Connection Manager Connectivity API - * @ingroup networking - * @{ - */ - - -/** @cond INTERNAL_HIDDEN */ - -/* Connectivity Events */ -#define _NET_MGMT_CONN_LAYER NET_MGMT_LAYER(NET_MGMT_LAYER_L2) -#define _NET_MGMT_CONN_CODE NET_MGMT_LAYER_CODE(0x207) -#define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE) -#define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_EVENT) - -enum net_event_ethernet_cmd { - NET_EVENT_CONN_CMD_IF_TIMEOUT = 1, - NET_EVENT_CONN_CMD_IF_FATAL_ERROR, -}; - -#define NET_EVENT_CONN_IF_TIMEOUT \ - (_NET_MGMT_CONN_IF_EVENT | NET_EVENT_CONN_CMD_IF_TIMEOUT) - -#define NET_EVENT_CONN_IF_FATAL_ERROR \ - (_NET_MGMT_CONN_IF_EVENT | NET_EVENT_CONN_CMD_IF_FATAL_ERROR) - -/** @endcond */ - -/** - * @brief Connectivity Manager Connectivity API structure - * - * Used to provide generic access to network association parameters and procedures - */ -struct conn_mgr_conn_binding; -struct conn_mgr_conn_api { - /** - * @brief When called, the connectivity implementation should start attempting to - * establish connectivity for (associate with a network) the bound iface pointed - * to by if_conn->iface. - * - * Must be non-blocking. - * - * Called by conn_mgr_if_connect. - */ - int (*connect)(struct conn_mgr_conn_binding *const binding); - - /** - * @brief When called, the connectivity implementation should disconnect (dissasociate), or - * stop any in-progress attempts to associate to a network, the bound iface pointed to by - * if_conn->iface. - * - * Must be non-blocking. - * - * Called by conn_mgr_if_disconnect. - */ - int (*disconnect)(struct conn_mgr_conn_binding *const binding); - - /** - * @brief Called once for each iface that has been bound to a connectivity implementation - * using this API. - * - * Connectivity implementations should use this callback to perform any required - * per-bound-iface initialization. - * - * Implementations may choose to gracefully handle invalid buffer lengths with partial - * writes, rather than raise errors, if deemed appropriate. - */ - void (*init)(struct conn_mgr_conn_binding *const binding); - - /** - * @brief Implementation callback for conn_mgr_if_set_opt. - * - * Used to set implementation-specific connectivity settings. - * - * Calls to conn_mgr_if_set_opt on an iface will result in calls to this callback with - * the conn_mgr_conn_binding struct bound to that iface. - * - * It is up to the connectivity implementation to interpret optname. Options can be - * specific to the bound iface (pointed to by if_conn->iface), or can apply to the whole - * connectivity implementation. - * - * See the description of conn_mgr_if_set_opt for more details. - * set_opt implementations should conform to that description. - * - * Implementations may choose to gracefully handle invalid buffer lengths with partial - * reads, rather than raise errors, if deemed appropriate. - */ - int (*set_opt)(struct conn_mgr_conn_binding *const binding, - int optname, const void *optval, size_t optlen); - - /** - * @brief Implementation callback for conn_mgr_if_get_opt. - * - * Used to retrieve implementation-specific connectivity settings. - * - * Calls to conn_mgr_if_get_opt on an iface will result in calls to this callback with - * the conn_mgr_conn_binding struct bound to that iface. - * - * It is up to the connectivity implementation to interpret optname. Options can be - * specific to the bound iface (pointed to by if_conn->iface), or can apply to the whole - * connectivity implementation. - * - * See the description of conn_mgr_if_get_opt for more details. - * get_opt implementations should conform to that description. - */ - int (*get_opt)(struct conn_mgr_conn_binding *const binding, - int optname, void *optval, size_t *optlen); -}; - -/** @cond INTERNAL_HIDDEN */ -#define CONN_MGR_CONN_IMPL_GET_NAME(conn_id) __conn_mgr_conn_##conn_id -#define CONN_MGR_CONN_IMPL_GET_CTX_TYPE(conn_id) conn_id##_CTX_TYPE -/** @endcond */ - -/** - * @brief conn_mgr Connectivity Implementation struct - * Declares a conn_mgr connectivity layer implementation with the provided API - */ -struct conn_mgr_conn_impl { - /* The connectivity API used by the implementation */ - struct conn_mgr_conn_api *api; -}; - -/** - * @brief Define a conn_mgr connectivity implementation that can be bound to network devices. - * - * @param conn_id The name of the new connectivity implementation - * @param conn_api A pointer to a conn_mgr_conn_api struct - */ -#define CONN_MGR_CONN_DEFINE(conn_id, conn_api) \ - const struct conn_mgr_conn_impl CONN_MGR_CONN_IMPL_GET_NAME(conn_id) = { \ - .api = conn_api, \ - }; - -/** - * @brief Helper macro to make a conn_mgr connectivity implementation publicly available. - */ -#define CONN_MGR_CONN_DECLARE_PUBLIC(conn_id) \ - extern const struct conn_mgr_conn_impl CONN_MGR_CONN_IMPL_GET_NAME(conn_id) - -/** @cond INTERNAL_HIDDEN */ -#define CONN_MGR_CONN_BINDING_GET_NAME(dev_id, sfx) __conn_mgr_bndg_##dev_id##_##sfx -#define CONN_MGR_CONN_BINDING_GET_DATA(dev_id, sfx) __conn_mgr_bndg_data_##dev_id##_##sfx -#define CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, sfx) __conn_mgr_bndg_mutex_##dev_id##_##sfx -/** @endcond */ - -/** - * @brief Per-iface connectivity flags - */ -enum conn_mgr_if_flag { - /* Persistent - * When set, indicates that the connectivity implementation bound to this iface should - * attempt to persist connectivity by automatically reconnecting after connection loss. - */ - CONN_MGR_IF_PERSISTENT, - -/** @cond INTERNAL_HIDDEN */ - /* Total number of flags - must be at the end of the enum */ - CONN_MGR_NUM_IF_FLAGS, -/** @endcond */ -}; - -/* Value to use with conn_mgr_conn_binding->timeout to indicate no timeout */ -#define CONN_MGR_IF_NO_TIMEOUT 0 - -/** - * @brief Connectivity Manager network interface binding structure - * - * Binds a conn_mgr connectivity implementation to an iface / network device. - * Stores per-iface state for the connectivity implementation. - */ -struct conn_mgr_conn_binding { - /* The network interface the connectivity implementation is bound to */ - struct net_if *iface; - - /* The connectivity implementation the network device is bound to */ - const struct conn_mgr_conn_impl *impl; - - /* Pointer to private, per-iface connectivity context */ - void *ctx; - - /* Generic connectivity state - Flags - * Public boolean state and configuration values supported by all bindings. - * See conn_mgr_if_flag for options. - */ - uint32_t flags; - - /* Generic connectivity state - Timeout (seconds) - * Indicates to the connectivity implementation how long it should attempt to - * establish connectivity for during a connection attempt before giving up. - * - * The connectivity implementation should give up on establishing connectivity after this - * timeout, even if persistence is enabled. - * - * Set to CONN_MGR_IF_NO_TIMEOUT to indicate that no timeout should be used. - */ - int timeout; - -/** @cond INTERNAL_HIDDEN */ - /* Internal-use mutex for protecting access to the binding and API functions. */ - struct k_mutex *mutex; -/** @endcond */ -}; - -/** - * @brief Associate a connectivity implementation with an existing network device instance - * - * @param dev_id Network device id. - * @param inst Network device instance. - * @param conn_id Name of the connectivity implementation to associate. - */ -#define CONN_MGR_BIND_CONN_INST(dev_id, inst, conn_id) \ - K_MUTEX_DEFINE(CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, inst)); \ - static CONN_MGR_CONN_IMPL_GET_CTX_TYPE(conn_id) \ - CONN_MGR_CONN_BINDING_GET_DATA(dev_id, inst); \ - static STRUCT_SECTION_ITERABLE(conn_mgr_conn_binding, \ - CONN_MGR_CONN_BINDING_GET_NAME(dev_id, inst)) = { \ - .iface = NET_IF_GET(dev_id, inst), \ - .impl = &(CONN_MGR_CONN_IMPL_GET_NAME(conn_id)), \ - .ctx = &(CONN_MGR_CONN_BINDING_GET_DATA(dev_id, inst)), \ - .mutex = &(CONN_MGR_CONN_BINDING_GET_MUTEX(dev_id, inst)) \ - }; - -/** - * @brief Associate a connectivity implementation with an existing network device - * - * @param dev_id Network device id. - * @param conn_id Name of the connectivity implementation to associate. - */ -#define CONN_MGR_BIND_CONN(dev_id, conn_id) \ - CONN_MGR_BIND_CONN_INST(dev_id, 0, conn_id) - -/** - * @brief Connect interface - * - * If the provided iface has been bound to a connectivity implementation, initiate - * network connect/association. - * - * Non-Blocking. - * - * @param iface Pointer to network interface - * @retval 0 on success. - * @retval -ESHUTDOWN if the iface is not admin-up. - * @retval -ENOTSUP if the iface does not have a connectivity implementation. - * @retval implementation-specific status code otherwise. - */ -int conn_mgr_if_connect(struct net_if *iface); - -/** - * @brief Disconnect interface - * - * If the provided iface has been bound to a connectivity implementation, disconnect/dissassociate - * it from the network, and cancel any pending attempts to connect/associate. - * - * @param iface Pointer to network interface - * - * @retval 0 on success. - * @retval -ENOTSUP if the iface does not have a connectivity implementation. - * @retval implementation-specific status code otherwise. - */ -int conn_mgr_if_disconnect(struct net_if *iface); - -/** - * @brief Check whether the provided network interface supports connectivity / has been bound - * to a connectivity implementation. - * - * @param iface Pointer to the iface to check. - * @retval true if connectivity is supported (a connectivity implementation has been bound). - * @retval false otherwise. - */ -bool conn_mgr_if_is_bound(struct net_if *iface); - -/** - * @brief Set implementation-specific connectivity options. - * - * If the provided iface has been bound to a connectivity implementation that supports it, - * implementation-specific connectivity options related to the iface. - * - * @param iface Pointer to the network interface. - * @param optname Integer value representing the option to set. - * The meaning of values is up to the conn_mgr_conn_api implementation. - * Some settings may affect multiple ifaces. - * @param optval Pointer to the value to be assigned to the option. - * @param optlen Length (in bytes) of the value to be assigned to the option. - * @retval 0 if successful. - * @retval -ENOTSUP if conn_mgr_if_set_opt not implemented by the iface. - * @retval -ENOBUFS if optlen is too long. - * @retval -EINVAL if NULL optval pointer provided. - * @retval -ENOPROTOOPT if the optname is not recognized. - * @retval implementation-specific error code otherwise. - */ -int conn_mgr_if_set_opt(struct net_if *iface, int optname, const void *optval, size_t optlen); - -/** - * @brief Get implementation-specific connectivity options. - * - * If the provided iface has been bound to a connectivity implementation that supports it, - * retrieves implementation-specific connectivity options related to the iface. - * - * @param iface Pointer to the network interface. - * @param optname Integer value representing the option to set. - * The meaning of values is up to the conn_mgr_conn_api implementation. - * Some settings may be shared by multiple ifaces. - * @param optval Pointer to where the retrieved value should be stored. - * @param optlen Pointer to length (in bytes) of the destination buffer available for storing the - * retrieved value. If the available space is less than what is needed, -ENOBUFS - * is returned. If the available space is invalid, -EINVAL is returned. - * - * optlen will always be set to the total number of bytes written, regardless of - * whether an error is returned, even if zero bytes were written. - * - * @retval 0 if successful. - * @retval -ENOTSUP if conn_mgr_if_get_opt is not implemented by the iface. - * @retval -ENOBUFS if retrieval buffer is too small. - * @retval -EINVAL if invalid retrieval buffer length is provided, or if NULL optval or - * optlen pointer provided. - * @retval -ENOPROTOOPT if the optname is not recognized. - * @retval implementation-specific error code otherwise. - */ -int conn_mgr_if_get_opt(struct net_if *iface, int optname, void *optval, size_t *optlen); - -/** - * @brief Check the value of connectivity flags - * - * If the provided iface is bound to a connectivity implementation, retrieves the value of the - * specified connectivity flag associated with that iface. - * - * @param iface - Pointer to the network interface to check. - * @param flag - The flag to check. - * @return True if the flag is set, otherwise False. - * Also returns False if the provided iface is not bound to a connectivity implementation, - * or the requested flag doesn't exist. - */ -bool conn_mgr_if_get_flag(struct net_if *iface, enum conn_mgr_if_flag flag); - -/** - * @brief Set the value of a connectivity flags - * - * If the provided iface is bound to a connectivity implementation, sets the value of the - * specified connectivity flag associated with that iface. - * - * @param iface - Pointer to the network interface to modify. - * @param flag - The flag to set. - * @param value - Whether the flag should be enabled or disabled. - * @retval 0 on success. - * @retval -EINVAL if the flag does not exist. - * @retval -ENOTSUP if the provided iface is not bound to a connectivity implementation. - */ -int conn_mgr_if_set_flag(struct net_if *iface, enum conn_mgr_if_flag flag, bool value); - -/** - * @brief Get the connectivity timeout for an iface - * - * If the provided iface is bound to a connectivity implementation, retrieves the timeout setting - * in seconds for it. - * - * @param iface - Pointer to the iface to check. - * @return int - The connectivity timeout value (in seconds) if it could be retrieved, otherwise - * CONN_MGR_IF_NO_TIMEOUT. - */ -int conn_mgr_if_get_timeout(struct net_if *iface); - -/** - * @brief Set the connectivity timeout for an iface. - * - * If the provided iface is bound to a connectivity implementation, sets the timeout setting in - * seconds for it. - * - * @param iface - Pointer to the network interface to modify. - * @param timeout - The timeout value to set (in seconds). - * Pass CONN_MGR_IF_NO_TIMEOUT to disable the timeout. - * @retval 0 on success. - * @retval -ENOTSUP if the provided iface is not bound to a connectivity implementation. - */ -int conn_mgr_if_set_timeout(struct net_if *iface, int timeout); - -/** - * @brief Initialize all connectivity implementation bindings - * - * - */ -void conn_mgr_conn_init(void); - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_CONN_MGR_CONNECTIVITY_H_ */ diff --git a/subsys/net/lib/conn_mgr/CMakeLists.txt b/subsys/net/lib/conn_mgr/CMakeLists.txt index 2f2d233196f0..7bb98d963c78 100644 --- a/subsys/net/lib/conn_mgr/CMakeLists.txt +++ b/subsys/net/lib/conn_mgr/CMakeLists.txt @@ -6,8 +6,4 @@ zephyr_library() zephyr_library_sources( conn_mgr.c events_handler.c - conn_mgr_connectivity.c ) - -zephyr_linker_sources(DATA_SECTIONS conn_mgr.ld) -zephyr_iterable_section(NAME conn_mgr_conn_binding GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) diff --git a/subsys/net/lib/conn_mgr/conn_mgr.c b/subsys/net/lib/conn_mgr/conn_mgr.c index c81033ec30d8..345e5a5736e2 100644 --- a/subsys/net/lib/conn_mgr/conn_mgr.c +++ b/subsys/net/lib/conn_mgr/conn_mgr.c @@ -14,7 +14,6 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include #include -#include #include #if defined(CONFIG_NET_TC_THREAD_COOPERATIVE) @@ -175,8 +174,6 @@ static void conn_mgr_init_cb(struct net_if *iface, void *user_data) static void conn_mgr_handler(void) { - conn_mgr_conn_init(); - conn_mgr_init_events_handler(); net_if_foreach(conn_mgr_init_cb, NULL); diff --git a/subsys/net/lib/conn_mgr/conn_mgr.ld b/subsys/net/lib/conn_mgr/conn_mgr.ld deleted file mode 100644 index 352dde5c6472..000000000000 --- a/subsys/net/lib/conn_mgr/conn_mgr.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -ITERABLE_SECTION_RAM(conn_mgr_conn_binding, 4) diff --git a/subsys/net/lib/conn_mgr/conn_mgr_connectivity.c b/subsys/net/lib/conn_mgr/conn_mgr_connectivity.c deleted file mode 100644 index c0812dac1727..000000000000 --- a/subsys/net/lib/conn_mgr/conn_mgr_connectivity.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -LOG_MODULE_REGISTER(conn_mgr_conn, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); - -#include -#include - -/** - * @brief Retrieves the conn_mgr binding struct for a provided iface if it exists. - * - * Bindings for connectivity implementations with missing API structs are ignored. - * - * @param iface - bound network interface to obtain the binding struct for. - * @return struct conn_mgr_conn_binding* Pointer to the retrieved binding struct if it exists, - * NULL otherwise. - */ -static inline struct conn_mgr_conn_binding *conn_mgr_if_get_binding(struct net_if *iface) -{ - STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { - if (iface == binding->iface) { - if (binding->impl->api) { - return binding; - } - return NULL; - } - } - return NULL; -} - -int conn_mgr_if_connect(struct net_if *iface) -{ - struct conn_mgr_conn_binding *binding; - struct conn_mgr_conn_api *api; - int status; - - LOG_DBG("iface %p connect", iface); - - binding = conn_mgr_if_get_binding(iface); - if (!binding) { - return -ENOTSUP; - } - - api = binding->impl->api; - if (!api->connect) { - return -ENOTSUP; - } - - k_mutex_lock(binding->mutex, K_FOREVER); - - if (!net_if_flag_is_set(iface, NET_IF_UP)) { - status = -ESHUTDOWN; - goto out; - } - - status = api->connect(binding); - -out: - k_mutex_unlock(binding->mutex); - - return status; -} - -int conn_mgr_if_disconnect(struct net_if *iface) -{ - struct conn_mgr_conn_binding *binding; - struct conn_mgr_conn_api *api; - int status; - - LOG_DBG("iface %p disconnect", iface); - - binding = conn_mgr_if_get_binding(iface); - if (!binding) { - return -ENOTSUP; - } - - api = binding->impl->api; - if (!api->disconnect) { - return -ENOTSUP; - } - - - k_mutex_lock(binding->mutex, K_FOREVER); - - if (!net_if_flag_is_set(iface, NET_IF_UP)) { - status = -EALREADY; - goto out; - } - - status = api->disconnect(binding); - -out: - k_mutex_unlock(binding->mutex); - - return status; -} - -bool conn_mgr_if_is_bound(struct net_if *iface) -{ - struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); - - return binding != NULL; -} - -int conn_mgr_if_get_opt(struct net_if *iface, int optname, void *optval, size_t *optlen) -{ - struct conn_mgr_conn_binding *binding; - struct conn_mgr_conn_api *api; - int status; - - if (!optlen) { - return -EINVAL; - } - - if (!optval) { - *optlen = 0; - return -EINVAL; - } - - binding = conn_mgr_if_get_binding(iface); - if (!binding) { - *optlen = 0; - return -ENOTSUP; - } - - api = binding->impl->api; - if (!api->get_opt) { - *optlen = 0; - return -ENOTSUP; - } - - k_mutex_lock(binding->mutex, K_FOREVER); - - status = api->get_opt(binding, optname, optval, optlen); - - k_mutex_unlock(binding->mutex); - - return status; -} - -int conn_mgr_if_set_opt(struct net_if *iface, int optname, const void *optval, size_t optlen) -{ - struct conn_mgr_conn_binding *binding; - struct conn_mgr_conn_api *api; - int status; - - if (!optval) { - return -EINVAL; - } - - binding = conn_mgr_if_get_binding(iface); - if (!binding) { - return -ENOTSUP; - } - - api = binding->impl->api; - if (!api->set_opt) { - return -ENOTSUP; - } - - k_mutex_lock(binding->mutex, K_FOREVER); - - status = api->set_opt(binding, optname, optval, optlen); - - k_mutex_unlock(binding->mutex); - - return status; -} - -int conn_mgr_if_set_flag(struct net_if *iface, enum conn_mgr_if_flag flag, bool value) -{ - struct conn_mgr_conn_binding *binding; - - if (flag >= CONN_MGR_NUM_IF_FLAGS) { - return -EINVAL; - } - - binding = conn_mgr_if_get_binding(iface); - if (!binding) { - return -ENOTSUP; - } - - k_mutex_lock(binding->mutex, K_FOREVER); - - binding->flags &= ~BIT(flag); - if (value) { - binding->flags |= BIT(flag); - } - - k_mutex_unlock(binding->mutex); - - return 0; -} - -bool conn_mgr_if_get_flag(struct net_if *iface, enum conn_mgr_if_flag flag) -{ - struct conn_mgr_conn_binding *binding; - bool value; - - if (flag >= CONN_MGR_NUM_IF_FLAGS) { - return false; - } - - binding = conn_mgr_if_get_binding(iface); - if (!binding) { - return false; - } - - k_mutex_lock(binding->mutex, K_FOREVER); - - value = !!(binding->flags & BIT(flag)); - - k_mutex_unlock(binding->mutex); - - return value; -} - -int conn_mgr_if_get_timeout(struct net_if *iface) -{ - struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); - int value; - - if (!binding) { - return false; - } - - k_mutex_lock(binding->mutex, K_FOREVER); - - value = binding->timeout; - - k_mutex_unlock(binding->mutex); - - return value; -} - -int conn_mgr_if_set_timeout(struct net_if *iface, int timeout) -{ - struct conn_mgr_conn_binding *binding = conn_mgr_if_get_binding(iface); - - if (!binding) { - return -ENOTSUP; - } - - k_mutex_lock(binding->mutex, K_FOREVER); - - binding->timeout = timeout; - - k_mutex_unlock(binding->mutex); - - return 0; -} - -void conn_mgr_conn_init(void) -{ - STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { - if (!(binding->impl->api)) { - LOG_ERR("Connectivity implementation has NULL API, and will be treated as " - "non-existent."); - } else if (binding->impl->api->init) { - k_mutex_lock(binding->mutex, K_FOREVER); - - /* Set initial default values for binding state */ - - binding->timeout = CONN_MGR_IF_NO_TIMEOUT; - - /* Call binding initializer */ - - binding->impl->api->init(binding); - - k_mutex_unlock(binding->mutex); - } - } -} From ac85d5b3f924ffdde91425ecdf6f0bed40eb56bd Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 293/528] Revert "[nrf fromtree] net: shell: Display TWT response details" This reverts commit 2336257f3b8d7646eddac1bc5f291e8c292b07d5. Signed-off-by: Robert Lubos --- subsys/net/l2/wifi/wifi_shell.c | 77 +++++++++++++-------------------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 67137a5c6427..7ccf57b8fc2a 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -148,50 +148,23 @@ static void handle_wifi_disconnect_result(struct net_mgmt_event_callback *cb) } } -static void print_twt_params(uint8_t dialog_token, uint8_t flow_id, - enum wifi_twt_negotiation_type negotiation_type, - bool responder, bool implicit, bool announce, - bool trigger, uint32_t twt_wake_interval, - uint64_t twt_interval) -{ - shell_fprintf(context.sh, SHELL_NORMAL, "TWT Dialog token: %d\n", - dialog_token); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT flow ID: %d\n", - flow_id); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT negotiation type: %s\n", - wifi_twt_negotiation_type2str[negotiation_type]); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT responder: %s\n", - responder ? "true" : "false"); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT implicit: %s\n", - implicit ? "true" : "false"); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT announce: %s\n", - announce ? "true" : "false"); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT trigger: %s\n", - trigger ? "true" : "false"); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT wake interval: %d us\n", - twt_wake_interval); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT interval: %lld us\n", - twt_interval); - shell_fprintf(context.sh, SHELL_NORMAL, "========================\n"); -} - static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) { const struct wifi_twt_params *resp = (const struct wifi_twt_params *)cb->info; if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { - print(context.sh, SHELL_NORMAL, "TWT response: %s\n", - wifi_twt_setup_cmd2str[resp->setup_cmd]); - print_twt_params(resp->dialog_token, - resp->flow_id, - resp->negotiation_type, - resp->setup.responder, - resp->setup.implicit, - resp->setup.announce, - resp->setup.trigger, - resp->setup.twt_wake_interval, - resp->setup.twt_interval); + print(context.sh, SHELL_NORMAL, "TWT response: %s for dialog: %d and flow: %d\n", + wifi_twt_setup_cmd2str[resp->setup_cmd], resp->dialog_token, resp->flow_id); + + /* If accepted, then no need to print TWT params */ + if (resp->setup_cmd != WIFI_TWT_SETUP_CMD_ACCEPT) { + print(context.sh, SHELL_NORMAL, + "TWT parameters: trigger: %s wake_interval: %d us, interval: %lld us\n", + resp->setup.trigger ? "trigger" : "no_trigger", + resp->setup.twt_wake_interval, + resp->setup.twt_interval); + } } else { print(context.sh, SHELL_NORMAL, "TWT response timed out\n"); } @@ -490,16 +463,26 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); } else { for (int i = 0; i < config.num_twt_flows; i++) { - print_twt_params( - config.twt_flows[i].dialog_token, - config.twt_flows[i].flow_id, - config.twt_flows[i].negotiation_type, - config.twt_flows[i].responder, - config.twt_flows[i].implicit, - config.twt_flows[i].announce, - config.twt_flows[i].trigger, - config.twt_flows[i].twt_wake_interval, + shell_fprintf(sh, SHELL_NORMAL, "TWT Dialog token: %d\n", + config.twt_flows[i].dialog_token); + shell_fprintf(sh, SHELL_NORMAL, "TWT flow ID: %d\n", + config.twt_flows[i].flow_id); + shell_fprintf(sh, SHELL_NORMAL, "TWT negotiation type: %s\n", + wifi_twt_negotiation_type2str[ + config.twt_flows[i].negotiation_type]); + shell_fprintf(sh, SHELL_NORMAL, "TWT responder: %s\n", + config.twt_flows[i].responder ? "true" : "false"); + shell_fprintf(sh, SHELL_NORMAL, "TWT implicit: %s\n", + config.twt_flows[i].implicit ? "true" : "false"); + shell_fprintf(sh, SHELL_NORMAL, "TWT trigger: %s\n", + config.twt_flows[i].trigger ? "true" : "false"); + shell_fprintf(sh, SHELL_NORMAL, "TWT announce: %s\n", + config.twt_flows[i].announce ? "true" : "false"); + shell_fprintf(sh, SHELL_NORMAL, "TWT wake interval: %d us\n", + config.twt_flows[i].twt_wake_interval); + shell_fprintf(sh, SHELL_NORMAL, "TWT interval: %lld us\n", config.twt_flows[i].twt_interval); + shell_fprintf(sh, SHELL_NORMAL, "========================\n"); } } return 0; From 18361ed31668a275513642400f984dc5e4d083c8 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:30 +0200 Subject: [PATCH 294/528] Revert "[nrf fromtree] Samples: Bluetooth: Fix PAwR sample backing store array" This reverts commit 9ff8fc26ec0560b26744c96944ae620b884f9a5f. Signed-off-by: Robert Lubos --- samples/bluetooth/periodic_adv_conn/src/main.c | 2 +- samples/bluetooth/periodic_adv_rsp/src/main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/bluetooth/periodic_adv_conn/src/main.c b/samples/bluetooth/periodic_adv_conn/src/main.c index 00464b43ead2..c1070009b2c2 100644 --- a/samples/bluetooth/periodic_adv_conn/src/main.c +++ b/samples/bluetooth/periodic_adv_conn/src/main.c @@ -26,7 +26,7 @@ static const struct bt_le_per_adv_param per_adv_params = { static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS]; static struct net_buf_simple bufs[NUM_SUBEVENTS]; -static uint8_t backing_store[NUM_SUBEVENTS][PACKET_SIZE]; +static uint8_t backing_store[PACKET_SIZE][NUM_SUBEVENTS]; BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params)); BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params)); diff --git a/samples/bluetooth/periodic_adv_rsp/src/main.c b/samples/bluetooth/periodic_adv_rsp/src/main.c index 0b0db7766928..a7e180edecff 100644 --- a/samples/bluetooth/periodic_adv_rsp/src/main.c +++ b/samples/bluetooth/periodic_adv_rsp/src/main.c @@ -35,7 +35,7 @@ static const struct bt_le_per_adv_param per_adv_params = { static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS]; static struct net_buf_simple bufs[NUM_SUBEVENTS]; -static uint8_t backing_store[NUM_SUBEVENTS][PACKET_SIZE]; +static uint8_t backing_store[PACKET_SIZE][NUM_SUBEVENTS]; BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params)); BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params)); From 0230ca6b910d9598d8491b6d525ad51fbe81b6b5 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:31 +0200 Subject: [PATCH 295/528] Revert "[nrf fromtree] Bluetooth: Host: Fix setting missing params in create connection v2." This reverts commit 41e70dde6455d3cbc76db6368b93d3122d8f4de3. Signed-off-by: Robert Lubos --- subsys/bluetooth/host/hci_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index c3d2afef8a09..1b9d97e2e1b9 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -654,8 +654,6 @@ int bt_le_create_conn_synced(const struct bt_conn *conn, const struct bt_le_ext_ cp = net_buf_add(buf, sizeof(*cp)); (void)memset(cp, 0, sizeof(*cp)); - cp->subevent = subevent; - cp->adv_handle = adv->handle; bt_addr_le_copy(&cp->peer_addr, &conn->le.dst); cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_NO_FILTER; cp->own_addr_type = own_addr_type; From da07dcf8a7398c5b868e23c278251fb87feed351 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:31 +0200 Subject: [PATCH 296/528] Revert "[nrf fromtree] Bluetooth: Host: Fix PHY translation from HCI" This reverts commit 2080584f6dcfcc0c5c6cdc9c72e397a01892fbd8. Signed-off-by: Robert Lubos --- subsys/bluetooth/host/scan.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index c48f40502a59..6630951ba8ed 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1030,7 +1030,7 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) pending_per_adv_sync->interval = sys_le16_to_cpu(evt->interval); pending_per_adv_sync->clock_accuracy = sys_le16_to_cpu(evt->clock_accuracy); - pending_per_adv_sync->phy = bt_get_phy(evt->phy); + pending_per_adv_sync->phy = evt->phy; memset(&sync_info, 0, sizeof(sync_info)); sync_info.interval = pending_per_adv_sync->interval; @@ -1227,7 +1227,7 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) per_adv_sync->handle = sys_le16_to_cpu(evt->sync_handle); per_adv_sync->interval = sys_le16_to_cpu(evt->interval); per_adv_sync->clock_accuracy = sys_le16_to_cpu(evt->clock_accuracy); - per_adv_sync->phy = bt_get_phy(evt->phy); + per_adv_sync->phy = evt->phy; bt_addr_le_copy(&per_adv_sync->addr, &id_addr); per_adv_sync->sid = evt->adv_sid; @@ -1239,7 +1239,7 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) #endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ sync_info.interval = per_adv_sync->interval; - sync_info.phy = per_adv_sync->phy; + sync_info.phy = bt_get_phy(per_adv_sync->phy); sync_info.addr = &per_adv_sync->addr; sync_info.sid = per_adv_sync->sid; sync_info.service_data = sys_le16_to_cpu(evt->service_data); @@ -1320,7 +1320,7 @@ void bt_hci_le_biginfo_adv_report(struct net_buf *buf) biginfo.max_pdu = sys_le16_to_cpu(evt->max_pdu); biginfo.sdu_interval = sys_get_le24(evt->sdu_interval); biginfo.max_sdu = sys_le16_to_cpu(evt->max_sdu); - biginfo.phy = bt_get_phy(evt->phy); + biginfo.phy = evt->phy; biginfo.framing = evt->framing; biginfo.encryption = evt->encryption ? true : false; From 4fa8c710f9c11eb589d0a7dcbf4a34839a1d740e Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:31 +0200 Subject: [PATCH 297/528] Revert "[nrf noup] samples: cleanup void main usage." This reverts commit d4c8639105054b2b562520e921ff3cef0d6a6808. Signed-off-by: Robert Lubos --- samples/bluetooth/periodic_adv_conn/src/main.c | 14 ++++++-------- samples/bluetooth/periodic_adv_rsp/src/main.c | 18 ++++++++---------- samples/bluetooth/periodic_sync_rsp/src/main.c | 12 +++++------- 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/samples/bluetooth/periodic_adv_conn/src/main.c b/samples/bluetooth/periodic_adv_conn/src/main.c index c1070009b2c2..65b119062719 100644 --- a/samples/bluetooth/periodic_adv_conn/src/main.c +++ b/samples/bluetooth/periodic_adv_conn/src/main.c @@ -160,7 +160,7 @@ static void init_bufs(void) } } -int main(void) +void main(void) { int err; struct bt_le_ext_adv *pawr_adv; @@ -173,40 +173,38 @@ int main(void) err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); - return 0; + return; } /* Create a non-connectable non-scannable advertising set */ err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, &adv_cb, &pawr_adv); if (err) { printk("Failed to create advertising set (err %d)\n", err); - return 0; + return; } /* Set periodic advertising parameters */ err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params); if (err) { printk("Failed to set periodic advertising parameters (err %d)\n", err); - return 0; + return; } /* Enable Periodic Advertising */ err = bt_le_per_adv_start(pawr_adv); if (err) { printk("Failed to enable periodic advertising (err %d)\n", err); - return 0; + return; } printk("Start Periodic Advertising\n"); err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT); if (err) { printk("Failed to start extended advertising (err %d)\n", err); - return 0; + return; } while (true) { k_sleep(K_SECONDS(1)); } - - return 0; } diff --git a/samples/bluetooth/periodic_adv_rsp/src/main.c b/samples/bluetooth/periodic_adv_rsp/src/main.c index a7e180edecff..463ecedf10a9 100644 --- a/samples/bluetooth/periodic_adv_rsp/src/main.c +++ b/samples/bluetooth/periodic_adv_rsp/src/main.c @@ -247,7 +247,7 @@ struct pawr_timing { static uint8_t num_synced; -int main(void) +void main(void) { int err; struct bt_le_ext_adv *pawr_adv; @@ -263,42 +263,42 @@ int main(void) err = bt_enable(NULL); if (err) { printk("Bluetooth init failed (err %d)\n", err); - return 0; + return; } /* Create a non-connectable non-scannable advertising set */ err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, &adv_cb, &pawr_adv); if (err) { printk("Failed to create advertising set (err %d)\n", err); - return 0; + return; } /* Set periodic advertising parameters */ err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params); if (err) { printk("Failed to set periodic advertising parameters (err %d)\n", err); - return 0; + return; } /* Enable Periodic Advertising */ err = bt_le_per_adv_start(pawr_adv); if (err) { printk("Failed to enable periodic advertising (err %d)\n", err); - return 0; + return; } printk("Start Periodic Advertising\n"); err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT); if (err) { printk("Failed to start extended advertising (err %d)\n", err); - return 0; + return; } while (num_synced < MAX_SYNCS) { err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); if (err) { printk("Scanning failed to start (err %d)\n", err); - return 0; + return; } printk("Scanning successfully started\n"); @@ -368,7 +368,7 @@ int main(void) disconnect: err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); if (err) { - return 0; + return; } k_sem_take(&sem_disconnected, K_FOREVER); @@ -379,6 +379,4 @@ int main(void) while (true) { k_sleep(K_SECONDS(1)); } - - return 0; } diff --git a/samples/bluetooth/periodic_sync_rsp/src/main.c b/samples/bluetooth/periodic_sync_rsp/src/main.c index d39a7814943f..a4a8a1cb852e 100644 --- a/samples/bluetooth/periodic_sync_rsp/src/main.c +++ b/samples/bluetooth/periodic_sync_rsp/src/main.c @@ -195,7 +195,7 @@ BT_CONN_CB_DEFINE(conn_cb) = { .disconnected = disconnected, }; -int main(void) +void main(void) { struct bt_le_per_adv_sync_transfer_param past_param; int err; @@ -206,7 +206,7 @@ int main(void) if (err) { printk("Bluetooth init failed (err %d)\n", err); - return 0; + return; } bt_le_per_adv_sync_cb_register(&sync_callbacks); @@ -218,7 +218,7 @@ int main(void) if (err) { printk("PAST subscribe failed (err %d)\n", err); - return 0; + return; } do { @@ -231,7 +231,7 @@ int main(void) if (err && err != -EALREADY) { printk("Advertising failed to start (err %d)\n", err); - return 0; + return; } printk("Waiting for periodic sync...\n"); @@ -248,11 +248,9 @@ int main(void) if (err) { printk("failed (err %d)\n", err); - return 0; + return; } printk("Periodic sync lost.\n"); } while (true); - - return 0; } From 2272b14d04419e8cafd30c3771c8a2825106afdb Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:31 +0200 Subject: [PATCH 298/528] Revert "[nrf fromtree] Bluetooth: Host: Fix sync subevent cmd length" This reverts commit 3dee54c3ca1b7eebde47d42d91a10d6f00fc742b. Signed-off-by: Robert Lubos --- subsys/bluetooth/host/scan.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 6630951ba8ed..00f0147a35af 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -1092,12 +1092,7 @@ int bt_le_per_adv_sync_subevent(struct bt_le_per_adv_sync *per_adv_sync, struct bt_hci_cp_le_set_pawr_sync_subevent *cp; struct net_buf *buf; - if (params->num_subevents > BT_HCI_PAWR_SUBEVENT_MAX) { - return -EINVAL; - } - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, - sizeof(*cp) + params->num_subevents); + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, sizeof(*cp)); if (!buf) { return -ENOBUFS; From f8e56fb29634f6b7fb2d31659960ed0c7c547e0b Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:32 +0200 Subject: [PATCH 299/528] Revert "[nrf fromtree] Bluetooth: Host: Fix typos and inaccuracies for PAwR" This reverts commit 435907725065d9da43c460d2550ed2edf4fdb97f. Signed-off-by: Robert Lubos --- include/zephyr/bluetooth/bluetooth.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index f93eb3d210cf..42ab174abc68 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -2595,8 +2595,8 @@ struct bt_le_per_adv_response_params { /** * @brief Set the data for a response slot in a specific subevent of the PAwR. * - * This function is called by the application to set the response data. - * The data for a response slot shall be transmitted only once. + * This function is called by the Host to set the response dat. + * The data for a repsonse slot shall be transmitted only once. * * @param per_adv_sync The periodic advertising sync object. * @param params Parameters. From d444de34478562440c3b5b11868bf722055d6716 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:32 +0200 Subject: [PATCH 300/528] Revert "[nrf fromtree] Samples: Bluetooth: Add samples for PADV Connection Procedure" This reverts commit 50570ca2c19bd7029713db78222a7687b584b57a. Signed-off-by: Robert Lubos --- .../periodic_adv_conn/CMakeLists.txt | 7 - .../bluetooth/periodic_adv_conn/README.rst | 32 --- samples/bluetooth/periodic_adv_conn/prj.conf | 14 - .../bluetooth/periodic_adv_conn/sample.yaml | 12 - .../bluetooth/periodic_adv_conn/src/main.c | 210 -------------- .../periodic_sync_conn/CMakeLists.txt | 7 - .../bluetooth/periodic_sync_conn/README.rst | 32 --- samples/bluetooth/periodic_sync_conn/prj.conf | 15 - .../bluetooth/periodic_sync_conn/sample.yaml | 12 - .../bluetooth/periodic_sync_conn/src/main.c | 267 ------------------ 10 files changed, 608 deletions(-) delete mode 100644 samples/bluetooth/periodic_adv_conn/CMakeLists.txt delete mode 100644 samples/bluetooth/periodic_adv_conn/README.rst delete mode 100644 samples/bluetooth/periodic_adv_conn/prj.conf delete mode 100644 samples/bluetooth/periodic_adv_conn/sample.yaml delete mode 100644 samples/bluetooth/periodic_adv_conn/src/main.c delete mode 100644 samples/bluetooth/periodic_sync_conn/CMakeLists.txt delete mode 100644 samples/bluetooth/periodic_sync_conn/README.rst delete mode 100644 samples/bluetooth/periodic_sync_conn/prj.conf delete mode 100644 samples/bluetooth/periodic_sync_conn/sample.yaml delete mode 100644 samples/bluetooth/periodic_sync_conn/src/main.c diff --git a/samples/bluetooth/periodic_adv_conn/CMakeLists.txt b/samples/bluetooth/periodic_adv_conn/CMakeLists.txt deleted file mode 100644 index 796bd5e5d8ed..000000000000 --- a/samples/bluetooth/periodic_adv_conn/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(periodic_adv) - -target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/periodic_adv_conn/README.rst b/samples/bluetooth/periodic_adv_conn/README.rst deleted file mode 100644 index 149e81439902..000000000000 --- a/samples/bluetooth/periodic_adv_conn/README.rst +++ /dev/null @@ -1,32 +0,0 @@ -.. _bluetooth-periodic-advertising-conn-sample: - -Bluetooth: Periodic Advertising Connection Procedure - Initiator -################################################################ - -Overview -******** - -A simple application demonstrating the initiator side of the BLE -Periodic Advertising Connection Procedure. - -How the initiator decides the address of the synced device to connect to -is application specific. This sample will connect to any synced device -responding with its address. Once the connection is established, it will -wait for disconnect before connecting to another synced device. - -Requirements -************ - -* A board with BLE support -* A controller that supports the Periodic Advertising with Responses (PAwR) - Advertiser feature - -Building and Running -******************** - -This sample can be found under :zephyr_file:`samples/bluetooth/periodic_adv_conn` in -the Zephyr tree. - -Use the sample found under :zephyr_file:`samples/bluetooth/periodic_sync_conn` in the -Zephyr tree that will synchronize and respond to this sample. - -See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/periodic_adv_conn/prj.conf b/samples/bluetooth/periodic_adv_conn/prj.conf deleted file mode 100644 index 2f5aed3551cf..000000000000 --- a/samples/bluetooth/periodic_adv_conn/prj.conf +++ /dev/null @@ -1,14 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_BROADCASTER=y -CONFIG_BT_EXT_ADV=y -CONFIG_BT_PER_ADV=y -CONFIG_BT_DEVICE_NAME="PAwR conn sample" -CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y -CONFIG_BT_PER_ADV_RSP=y - -CONFIG_BT_MAX_CONN=1 -CONFIG_BT_CENTRAL=y -CONFIG_BT_PRIVACY=y -CONFIG_BT_SMP=y - -CONFIG_LOG=y diff --git a/samples/bluetooth/periodic_adv_conn/sample.yaml b/samples/bluetooth/periodic_adv_conn/sample.yaml deleted file mode 100644 index ff64f1d1208e..000000000000 --- a/samples/bluetooth/periodic_adv_conn/sample.yaml +++ /dev/null @@ -1,12 +0,0 @@ -sample: - name: Bluetooth Periodic Advertising with Responses Advertiser -tests: - sample.bluetooth.periodic_adv: - harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840 - tags: bluetooth - integration_platforms: - - nrf52840dk_nrf52840 - extra_configs: - - CONFIG_BT_CTLR=n - - CONFIG_BT_NO_DRIVER=y diff --git a/samples/bluetooth/periodic_adv_conn/src/main.c b/samples/bluetooth/periodic_adv_conn/src/main.c deleted file mode 100644 index 65b119062719..000000000000 --- a/samples/bluetooth/periodic_adv_conn/src/main.c +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include - -#define NUM_RSP_SLOTS 5 -#define NUM_SUBEVENTS 5 -#define PACKET_SIZE 5 -#define SUBEVENT_INTERVAL 0x30 - -static const struct bt_le_per_adv_param per_adv_params = { - .interval_min = 0xFF, - .interval_max = 0xFF, - .options = 0, - .num_subevents = NUM_SUBEVENTS, - .subevent_interval = SUBEVENT_INTERVAL, - .response_slot_delay = 0x5, - .response_slot_spacing = 0x50, - .num_response_slots = NUM_RSP_SLOTS, -}; - -static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS]; -static struct net_buf_simple bufs[NUM_SUBEVENTS]; -static uint8_t backing_store[PACKET_SIZE][NUM_SUBEVENTS]; - -BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params)); -BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params)); - -static void request_cb(struct bt_le_ext_adv *adv, const struct bt_le_per_adv_data_request *request) -{ - int err; - uint8_t to_send; - - /* Continuously send the same dummy data and listen to all response slots */ - - to_send = MIN(request->count, ARRAY_SIZE(subevent_data_params)); - for (size_t i = 0; i < to_send; i++) { - subevent_data_params[i].subevent = - (request->start + i) % per_adv_params.num_subevents; - subevent_data_params[i].response_slot_start = 0; - subevent_data_params[i].response_slot_count = NUM_RSP_SLOTS; - subevent_data_params[i].data = &bufs[i]; - } - - err = bt_le_per_adv_set_subevent_data(adv, to_send, subevent_data_params); - if (err) { - printk("Failed to set subevent data (err %d)\n", err); - } -} - -static bool get_address(struct bt_data *data, void *user_data) -{ - bt_addr_le_t *addr = user_data; - - if (data->type == BT_DATA_LE_BT_DEVICE_ADDRESS) { - memcpy(addr->a.val, data->data, sizeof(addr->a.val)); - addr->type = data->data[sizeof(addr->a)]; - - return false; - } - - return true; -} - -static struct bt_conn *default_conn; - -static void response_cb(struct bt_le_ext_adv *adv, struct bt_le_per_adv_response_info *info, - struct net_buf_simple *buf) -{ - int err; - bt_addr_le_t peer; - char addr_str[BT_ADDR_LE_STR_LEN]; - struct bt_conn_le_create_synced_param synced_param; - struct bt_le_conn_param conn_param; - - if (!buf) { - return; - } - - if (default_conn) { - /* Do not initiate new connections while already connected */ - return; - } - - bt_addr_le_copy(&peer, &bt_addr_le_none); - bt_data_parse(buf, get_address, &peer); - if (bt_addr_le_eq(&peer, &bt_addr_le_none)) { - /* No address found */ - return; - } - - bt_addr_le_to_str(&peer, addr_str, sizeof(addr_str)); - printk("Connecting to %s in subevent %d\n", addr_str, info->subevent); - - synced_param.peer = &peer; - synced_param.subevent = info->subevent; - - /* Choose same interval as PAwR advertiser to avoid scheduling conflicts */ - conn_param.interval_min = SUBEVENT_INTERVAL; - conn_param.interval_max = SUBEVENT_INTERVAL; - - /* Default values */ - conn_param.latency = 0; - conn_param.timeout = 400; - - err = bt_conn_le_create_synced(adv, &synced_param, &conn_param, &default_conn); - if (err) { - printk("Failed to initiate connection (err %d)", err); - } -} - -static const struct bt_le_ext_adv_cb adv_cb = { - .pawr_data_request = request_cb, - .pawr_response = response_cb, -}; - -static void connected_cb(struct bt_conn *conn, uint8_t err) -{ - printk("Connected (err 0x%02X)\n", err); - - __ASSERT(conn == default_conn, "Unexpected connected callback"); - - if (err) { - bt_conn_unref(default_conn); - default_conn = NULL; - } -} - -static void disconnected_cb(struct bt_conn *conn, uint8_t reason) -{ - printk("Disconnected (reason 0x%02X)\n", reason); - - __ASSERT(conn == default_conn, "Unexpected disconnected callback"); - - bt_conn_unref(default_conn); - default_conn = NULL; -} - -BT_CONN_CB_DEFINE(conn_cb) = { - .connected = connected_cb, - .disconnected = disconnected_cb, -}; - -static void init_bufs(void) -{ - /* Set up some dummy data to send */ - for (size_t i = 0; i < ARRAY_SIZE(backing_store); i++) { - backing_store[i][0] = ARRAY_SIZE(backing_store[i]) - 1; - backing_store[i][1] = BT_DATA_MANUFACTURER_DATA; - backing_store[i][2] = 0x59; /* Nordic */ - backing_store[i][3] = 0x00; - - net_buf_simple_init_with_data(&bufs[i], &backing_store[i], - ARRAY_SIZE(backing_store[i])); - } -} - -void main(void) -{ - int err; - struct bt_le_ext_adv *pawr_adv; - - init_bufs(); - - printk("Starting Periodic Advertising Demo\n"); - - /* Initialize the Bluetooth Subsystem */ - err = bt_enable(NULL); - if (err) { - printk("Bluetooth init failed (err %d)\n", err); - return; - } - - /* Create a non-connectable non-scannable advertising set */ - err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, &adv_cb, &pawr_adv); - if (err) { - printk("Failed to create advertising set (err %d)\n", err); - return; - } - - /* Set periodic advertising parameters */ - err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params); - if (err) { - printk("Failed to set periodic advertising parameters (err %d)\n", err); - return; - } - - /* Enable Periodic Advertising */ - err = bt_le_per_adv_start(pawr_adv); - if (err) { - printk("Failed to enable periodic advertising (err %d)\n", err); - return; - } - - printk("Start Periodic Advertising\n"); - err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT); - if (err) { - printk("Failed to start extended advertising (err %d)\n", err); - return; - } - - while (true) { - k_sleep(K_SECONDS(1)); - } -} diff --git a/samples/bluetooth/periodic_sync_conn/CMakeLists.txt b/samples/bluetooth/periodic_sync_conn/CMakeLists.txt deleted file mode 100644 index ab801447a2b9..000000000000 --- a/samples/bluetooth/periodic_sync_conn/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(periodic_sync) - -target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/periodic_sync_conn/README.rst b/samples/bluetooth/periodic_sync_conn/README.rst deleted file mode 100644 index 9f050ac38fb2..000000000000 --- a/samples/bluetooth/periodic_sync_conn/README.rst +++ /dev/null @@ -1,32 +0,0 @@ -.. _bluetooth-periodic-advertising-sync-conn-sample: - -Bluetooth: Periodic Advertising Connection Procedure - Responder -##################################################################### - -Overview -******** - -A simple application demonstrating the responder side of the BLE -Periodic Advertising Connection Procedure. - -This sample will send its address in response to the advertiser when receiving -subevent data. Once the connection is established, it will disconnect and wait -for a new connection to be established. - -Requirements -************ - -* A board with BLE support -* A controller that supports the Periodic Advertising with Responses (PAwR) - Scanner feature - -Building and Running -******************** - -This sample can be found under :zephyr_file:`samples/bluetooth/periodic_sync_conn` in -the Zephyr tree. - -Use the sample found under :zephyr_file:`samples/bluetooth/periodic_adv_conn` on -another board that will start periodic advertising and connect to this sample -once synced. - -See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/periodic_sync_conn/prj.conf b/samples/bluetooth/periodic_sync_conn/prj.conf deleted file mode 100644 index 16f52f609830..000000000000 --- a/samples/bluetooth/periodic_sync_conn/prj.conf +++ /dev/null @@ -1,15 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_OBSERVER=y -CONFIG_BT_EXT_ADV=y -CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y -CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER=y -CONFIG_BT_PER_ADV_SYNC=y -CONFIG_BT_PER_ADV_SYNC_RSP=y -CONFIG_BT_PER_ADV_SYNC_BUF_SIZE=247 - -CONFIG_BT_MAX_CONN=1 -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_PRIVACY=y -CONFIG_BT_SMP=y - -CONFIG_LOG=y diff --git a/samples/bluetooth/periodic_sync_conn/sample.yaml b/samples/bluetooth/periodic_sync_conn/sample.yaml deleted file mode 100644 index 8146eeecdbf2..000000000000 --- a/samples/bluetooth/periodic_sync_conn/sample.yaml +++ /dev/null @@ -1,12 +0,0 @@ -sample: - name: Bluetooth Periodic Advertising with Responses Synchronization -tests: - sample.bluetooth.periodic_sync: - harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840 - tags: bluetooth - integration_platforms: - - nrf52840dk_nrf52840 - extra_configs: - - CONFIG_BT_CTLR=n - - CONFIG_BT_NO_DRIVER=y diff --git a/samples/bluetooth/periodic_sync_conn/src/main.c b/samples/bluetooth/periodic_sync_conn/src/main.c deleted file mode 100644 index c5b964b1c957..000000000000 --- a/samples/bluetooth/periodic_sync_conn/src/main.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include - -#define NAME_LEN 30 - -static K_SEM_DEFINE(sem_per_adv, 0, 1); -static K_SEM_DEFINE(sem_per_sync, 0, 1); -static K_SEM_DEFINE(sem_connected, 0, 1); -static K_SEM_DEFINE(sem_disconnected, 0, 1); - -static struct bt_conn *default_conn; -static bool per_adv_found; -static bt_addr_le_t per_addr; -static uint8_t per_sid; - -static void sync_cb(struct bt_le_per_adv_sync *sync, struct bt_le_per_adv_sync_synced_info *info) -{ - struct bt_le_per_adv_sync_subevent_params params; - uint8_t subevents[1]; - char le_addr[BT_ADDR_LE_STR_LEN]; - int err; - - bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); - printk("Synced to %s with %d subevents\n", le_addr, info->num_subevents); - - params.properties = 0; - params.num_subevents = 1; - params.subevents = subevents; - subevents[0] = 0; - err = bt_le_per_adv_sync_subevent(sync, ¶ms); - if (err) { - printk("Failed to set subevents to sync to (err %d)\n", err); - } - - k_sem_give(&sem_per_sync); -} - -static void term_cb(struct bt_le_per_adv_sync *sync, - const struct bt_le_per_adv_sync_term_info *info) -{ - char le_addr[BT_ADDR_LE_STR_LEN]; - - bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); - - printk("Sync terminated (reason %d)\n", info->reason); -} - -static struct bt_le_per_adv_response_params rsp_params; - -NET_BUF_SIMPLE_DEFINE_STATIC(rsp_buf, sizeof(bt_addr_le_t) + 2 * sizeof(uint8_t)); - -static void recv_cb(struct bt_le_per_adv_sync *sync, - const struct bt_le_per_adv_sync_recv_info *info, struct net_buf_simple *buf) -{ - int err; - struct bt_le_oob oob; - char addr_str[BT_ADDR_LE_STR_LEN]; - - if (default_conn) { - /* Only respond with address if not already connected */ - return; - } - - if (buf && buf->len) { - /* Respond with own address for the advertiser to connect to */ - net_buf_simple_reset(&rsp_buf); - - rsp_params.request_event = info->periodic_event_counter; - rsp_params.request_subevent = info->subevent; - rsp_params.response_subevent = info->subevent; - rsp_params.response_slot = 0; - - err = bt_le_oob_get_local(BT_ID_DEFAULT, &oob); - if (err) { - printk("Failed to get OOB data (err %d)\n", err); - - return; - } - - bt_addr_le_to_str(&oob.addr, addr_str, sizeof(addr_str)); - printk("Responding with own addr: %s\n", addr_str); - - net_buf_simple_add_u8(&rsp_buf, sizeof(bt_addr_le_t)); - net_buf_simple_add_u8(&rsp_buf, BT_DATA_LE_BT_DEVICE_ADDRESS); - net_buf_simple_add_mem(&rsp_buf, &oob.addr.a, sizeof(oob.addr.a)); - net_buf_simple_add_u8(&rsp_buf, oob.addr.type); - - err = bt_le_per_adv_set_response_data(sync, &rsp_params, &rsp_buf); - if (err) { - printk("Failed to send response (err %d)\n", err); - } - } else if (buf) { - printk("Received empty indication: subevent %d\n", info->subevent); - } else { - printk("Failed to receive indication: subevent %d\n", info->subevent); - } -} - -static struct bt_le_per_adv_sync_cb sync_callbacks = { - .synced = sync_cb, - .term = term_cb, - .recv = recv_cb, -}; - -static void connected_cb(struct bt_conn *conn, uint8_t err) -{ - printk("Connected (err 0x%02X)\n", err); - - if (err) { - return; - } - - default_conn = bt_conn_ref(conn); - k_sem_give(&sem_connected); -} - -static void disconnected_cb(struct bt_conn *conn, uint8_t reason) -{ - bt_conn_unref(default_conn); - default_conn = NULL; - - printk("Disconnected (reason 0x%02X)\n", reason); - - k_sem_give(&sem_disconnected); -} - -BT_CONN_CB_DEFINE(conn_cb) = { - .connected = connected_cb, - .disconnected = disconnected_cb, -}; - -static bool data_cb(struct bt_data *data, void *user_data) -{ - char *name = user_data; - uint8_t len; - - switch (data->type) { - case BT_DATA_NAME_SHORTENED: - case BT_DATA_NAME_COMPLETE: - len = MIN(data->data_len, NAME_LEN - 1); - memcpy(name, data->data, len); - name[len] = '\0'; - return false; - default: - return true; - } -} - -static void scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *buf) -{ - char name[NAME_LEN]; - - (void)memset(name, 0, sizeof(name)); - bt_data_parse(buf, data_cb, name); - - if (strcmp(name, "PAwR conn sample")) { - return; - } - - if (!per_adv_found && info->interval) { - per_adv_found = true; - - per_sid = info->sid; - bt_addr_le_copy(&per_addr, info->addr); - - k_sem_give(&sem_per_adv); - } -} - -static struct bt_le_scan_cb scan_callbacks = { - .recv = scan_recv, -}; - -int main(void) -{ - struct bt_le_per_adv_sync_param sync_create_param; - struct bt_le_per_adv_sync *sync; - int err; - - printk("Starting Periodic Advertising with Responses Synchronization Demo\n"); - - err = bt_enable(NULL); - if (err) { - printk("Bluetooth init failed (err %d)\n", err); - - return 0; - } - - bt_le_scan_cb_register(&scan_callbacks); - bt_le_per_adv_sync_cb_register(&sync_callbacks); - - err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, NULL); - if (err) { - printk("failed (err %d)\n", err); - - return 0; - } - - err = k_sem_take(&sem_per_adv, K_FOREVER); - if (err) { - printk("failed (err %d)\n", err); - - return 0; - } - printk("Found periodic advertising.\n"); - - printk("Creating Periodic Advertising Sync"); - bt_addr_le_copy(&sync_create_param.addr, &per_addr); - sync_create_param.options = 0; - sync_create_param.sid = per_sid; - sync_create_param.skip = 0; - sync_create_param.timeout = 0xaa; - err = bt_le_per_adv_sync_create(&sync_create_param, &sync); - if (err) { - printk("Failed to create sync (err %d)\n", err); - - return 0; - } - - printk("Waiting for periodic sync\n"); - err = k_sem_take(&sem_per_sync, K_FOREVER); - if (err) { - printk("Failed (err %d)\n", err); - - return 0; - } - - printk("Periodic sync established.\n"); - - err = bt_le_scan_stop(); - if (err) { - printk("Failed to stop scanning (err %d)\n", err); - } - - printk("Stopped scanning\n"); - - do { - err = k_sem_take(&sem_connected, K_FOREVER); - if (err) { - printk("failed (err %d)\n", err); - - return 0; - } - - printk("Disconnecting\n"); - - err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - if (err) { - return 0; - } - - err = k_sem_take(&sem_disconnected, K_FOREVER); - if (err) { - printk("failed (err %d)\n", err); - - return 0; - } - } while (true); -} From 397477f51c4a28d9580a99c107eb87a33a0bc835 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:32 +0200 Subject: [PATCH 301/528] Revert "[nrf fromtree] Bluetooth: Host: Add support for receiving connections while synced" This reverts commit 0e9435e8031fa89f3f1c9d86a86deeb3f33ad824. Signed-off-by: Robert Lubos --- subsys/bluetooth/host/hci_core.c | 109 ++----------------------------- 1 file changed, 5 insertions(+), 104 deletions(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 1b9d97e2e1b9..024720547b3d 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1450,95 +1450,12 @@ void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) } } -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) -void bt_hci_le_enh_conn_complete_sync(struct bt_hci_evt_le_enh_conn_complete_v2 *evt, - struct bt_le_per_adv_sync *sync) -{ - uint16_t handle = sys_le16_to_cpu(evt->handle); - bool is_disconnected = conn_handle_is_disconnected(handle); - bt_addr_le_t peer_addr, id_addr; - struct bt_conn *conn; - - if (!sync->num_subevents) { - LOG_ERR("Unexpected connection complete event"); - - return; - } - - conn = bt_conn_add_le(BT_ID_DEFAULT, BT_ADDR_LE_ANY); - if (!conn) { - LOG_ERR("Unable to allocate connection"); - /* Tell the controller to disconnect to keep it in sync with - * the host state and avoid a "rogue" connection. - */ - bt_hci_disconnect(handle, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - - return; - } - - LOG_DBG("status 0x%02x handle %u role %u peer %s peer RPA %s", evt->status, handle, - evt->role, bt_addr_le_str(&evt->peer_addr), bt_addr_str(&evt->peer_rpa)); - LOG_DBG("local RPA %s", bt_addr_str(&evt->local_rpa)); - - if (evt->role != BT_HCI_ROLE_PERIPHERAL) { - LOG_ERR("PAwR sync always becomes peripheral"); - - return; - } - -#if defined(CONFIG_BT_SMP) - bt_id_pending_keys_update(); -#endif - - if (evt->status) { - LOG_ERR("Unexpected status 0x%02x", evt->status); - - return; - } - - translate_addrs(&peer_addr, &id_addr, (const struct bt_hci_evt_le_enh_conn_complete *)evt, - BT_ID_DEFAULT); - update_conn(conn, &id_addr, (const struct bt_hci_evt_le_enh_conn_complete *)evt); - -#if defined(CONFIG_BT_USER_PHY_UPDATE) - /* The connection is always initated on the same phy as the PAwR advertiser */ - conn->le.phy.tx_phy = sync->phy; - conn->le.phy.rx_phy = sync->phy; -#endif - - bt_addr_le_copy(&conn->le.init_addr, &peer_addr); - - /* There is no random addr to get, set responder addr to local identity addr. */ - bt_addr_le_copy(&conn->le.resp_addr, &bt_dev.id_addr[conn->id]); - - bt_conn_set_state(conn, BT_CONN_CONNECTED); - - if (is_disconnected) { - /* Mark the connection as already disconnected before calling - * the connected callback, so that the application cannot - * start sending packets - */ - bt_conn_set_state(conn, BT_CONN_DISCONNECT_COMPLETE); - } - - bt_conn_connected(conn); - - /* Since we don't give the application a reference to manage - * for peripheral connections, we need to release this reference here. - */ - bt_conn_unref(conn); - - /* Start auto-initiated procedures */ - conn_auto_initiate(conn); -} -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ - static void le_enh_conn_complete(struct net_buf *buf) { enh_conn_complete((void *)buf->data); } -#if defined(CONFIG_BT_PER_ADV_RSP) || defined(CONFIG_BT_PER_ADV_SYNC_RSP) +#if defined(CONFIG_BT_PER_ADV_RSP) static void le_enh_conn_complete_v2(struct net_buf *buf) { struct bt_hci_evt_le_enh_conn_complete_v2 *evt = @@ -1556,27 +1473,11 @@ static void le_enh_conn_complete_v2(struct net_buf *buf) enh_conn_complete((struct bt_hci_evt_le_enh_conn_complete *)evt); } #endif /* CONFIG_BT_PER_ADV_RSP */ -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - else if (evt->adv_handle == BT_HCI_ADV_HANDLE_INVALID && - evt->sync_handle != BT_HCI_SYNC_HANDLE_INVALID) { - /* Created via PAwR sync, no adv set terminated event, needs separate handling */ - struct bt_le_per_adv_sync *sync; - - sync = bt_hci_get_per_adv_sync(evt->sync_handle); - if (!sync) { - LOG_ERR("Unknown sync handle %d", evt->sync_handle); - - return; - } - - bt_hci_le_enh_conn_complete_sync(evt, sync); - } -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ else { LOG_ERR("Invalid connection complete event"); } } -#endif /* CONFIG_BT_PER_ADV_RSP || CONFIG_BT_PER_ADV_SYNC_RSP */ +#endif /* CONFIG_BT_PER_ADV_RSP */ static void le_legacy_conn_complete(struct net_buf *buf) { @@ -2530,10 +2431,10 @@ static const struct event_handler meta_events[] = { sizeof(struct bt_hci_evt_le_per_adv_response_report)), #endif /* CONFIG_BT_PER_ADV_RSP */ #if defined(CONFIG_BT_CONN) -#if defined(CONFIG_BT_PER_ADV_RSP) || defined(CONFIG_BT_PER_ADV_SYNC_RSP) +#if defined(CONFIG_BT_PER_ADV_RSP) EVENT_HANDLER(BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2, le_enh_conn_complete_v2, sizeof(struct bt_hci_evt_le_enh_conn_complete_v2)), -#endif /* CONFIG_BT_PER_ADV_RSP || CONFIG_BT_PER_ADV_SYNC_RSP */ +#endif /* CONFIG_BT_PER_ADV_RSP */ #endif /* CONFIG_BT_CONN */ }; @@ -3121,7 +3022,7 @@ static int le_set_event_mask(void) } if (IS_ENABLED(CONFIG_BT_CONN) && - (IS_ENABLED(CONFIG_BT_PER_ADV_RSP) || IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP))) { + IS_ENABLED(CONFIG_BT_PER_ADV_RSP)) { mask |= BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2; } From ba378fda51eaa33445a9c638732f1a0c36c8b395 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:32 +0200 Subject: [PATCH 302/528] Revert "[nrf fromtree] Bluetooth: Host: Add support for initiating connections from PAwR" This reverts commit 1bf676d9c1d4e2a32087aa7a74baa4b397e74575. Signed-off-by: Robert Lubos --- include/zephyr/bluetooth/conn.h | 34 ------- include/zephyr/bluetooth/hci.h | 28 ------ subsys/bluetooth/host/adv.c | 2 - subsys/bluetooth/host/conn.c | 101 +++---------------- subsys/bluetooth/host/hci_core.c | 160 ++++++------------------------- subsys/bluetooth/host/hci_core.h | 7 -- 6 files changed, 43 insertions(+), 289 deletions(-) diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index 1ee7cda5f176..dd0c1f8f182c 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -709,40 +709,6 @@ int bt_conn_le_create(const bt_addr_le_t *peer, const struct bt_le_conn_param *conn_param, struct bt_conn **conn); -struct bt_conn_le_create_synced_param { - - /** @brief Remote address - * - * The peer must be synchronized to the PAwR train. - * - */ - const bt_addr_le_t *peer; - - /** The subevent where the connection will be initiated. */ - uint8_t subevent; -}; - -/** @brief Create a connection to a synced device - * - * Initiate a connection to a synced device from a Periodic Advertising - * with Responses (PAwR) train. - * - * The caller gets a new reference to the connection object which must be - * released with bt_conn_unref() once done using the object. - * - * This uses the Periodic Advertising Connection Procedure. - * - * @param[in] adv The adverting set the PAwR advertiser belongs to. - * @param[in] synced_param Create connection parameters. - * @param[in] conn_param Initial connection parameters. - * @param[out] conn Valid connection object on success. - * - * @return Zero on success or (negative) error code on failure. - */ -int bt_conn_le_create_synced(const struct bt_le_ext_adv *adv, - const struct bt_conn_le_create_synced_param *synced_param, - const struct bt_le_conn_param *conn_param, struct bt_conn **conn); - /** @brief Automatically connect to remote devices in the filter accept list.. * * This uses the Auto Connection Establishment procedure. diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index 70fa845027a9..375e10a81572 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -1480,7 +1480,6 @@ struct bt_hci_cp_le_set_ext_scan_enable { } __packed; #define BT_HCI_OP_LE_EXT_CREATE_CONN BT_OP(BT_OGF_LE, 0x0043) -#define BT_HCI_OP_LE_EXT_CREATE_CONN_V2 BT_OP(BT_OGF_LE, 0x0085) struct bt_hci_ext_conn_phy { uint16_t scan_interval; uint16_t scan_window; @@ -1500,16 +1499,6 @@ struct bt_hci_cp_le_ext_create_conn { struct bt_hci_ext_conn_phy p[0]; } __packed; -struct bt_hci_cp_le_ext_create_conn_v2 { - uint8_t adv_handle; - uint8_t subevent; - uint8_t filter_policy; - uint8_t own_addr_type; - bt_addr_le_t peer_addr; - uint8_t phys; - struct bt_hci_ext_conn_phy p[0]; -} __packed; - #define BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA BT_OP(BT_OGF_LE, 0x0082) struct bt_hci_cp_le_set_pawr_subevent_data_element { uint8_t subevent; @@ -2437,22 +2426,6 @@ struct bt_hci_evt_le_per_adv_response_report { struct bt_hci_evt_le_per_adv_response responses[0]; } __packed; -#define BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2 0x29 -struct bt_hci_evt_le_enh_conn_complete_v2 { - uint8_t status; - uint16_t handle; - uint8_t role; - bt_addr_le_t peer_addr; - bt_addr_t local_rpa; - bt_addr_t peer_rpa; - uint16_t interval; - uint16_t latency; - uint16_t supv_timeout; - uint8_t clock_accuracy; - uint8_t adv_handle; - uint16_t sync_handle; -} __packed; - #define BT_HCI_EVT_SYNC_CONN_COMPLETE 0x2c struct bt_hci_evt_sync_conn_complete { uint8_t status; @@ -2982,7 +2955,6 @@ struct bt_hci_evt_le_biginfo_adv_report { #define BT_EVT_MASK_LE_PAST_RECEIVED_V2 BT_EVT_BIT(37) #define BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ BT_EVT_BIT(38) #define BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT BT_EVT_BIT(39) -#define BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2 BT_EVT_BIT(40) /** Allocate a HCI command buffer. * diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 619a9170fd96..7963b39f99b9 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -1153,8 +1153,6 @@ static int le_ext_adv_param_set(struct bt_le_ext_adv *adv, cp->filter_policy = get_filter_policy(param->options); cp->tx_power = BT_HCI_LE_ADV_TX_POWER_NO_PREF; - adv->options = param->options; - cp->prim_adv_phy = BT_HCI_LE_PHY_1M; if (param->options & BT_LE_ADV_OPT_EXT_ADV) { if (param->options & BT_LE_ADV_OPT_NO_2M) { diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 10d894a4444b..54b05cbdb460 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1135,8 +1135,7 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) * will handle connection timeout. */ if (IS_ENABLED(CONFIG_BT_CENTRAL) && - conn->type == BT_CONN_TYPE_LE && - bt_dev.create_param.timeout != 0) { + conn->type == BT_CONN_TYPE_LE) { k_work_schedule(&conn->deferred_work, K_MSEC(10 * bt_dev.create_param.timeout)); } @@ -2813,9 +2812,14 @@ int bt_conn_create_auto_stop(void) } #endif /* defined(CONFIG_BT_FILTER_ACCEPT_LIST) */ -static int conn_le_create_common_checks(const bt_addr_le_t *peer, - const struct bt_le_conn_param *conn_param) +int bt_conn_le_create(const bt_addr_le_t *peer, + const struct bt_conn_le_create_param *create_param, + const struct bt_le_conn_param *conn_param, + struct bt_conn **ret_conn) { + struct bt_conn *conn; + bt_addr_le_t dst; + int err; if (!atomic_test_bit(bt_dev.flags, BT_DEV_READY)) { return -EAGAIN; @@ -2825,6 +2829,10 @@ static int conn_le_create_common_checks(const bt_addr_le_t *peer, return -EINVAL; } + if (!create_param_validate(create_param)) { + return -EINVAL; + } + if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { return -EAGAIN; } @@ -2841,15 +2849,6 @@ static int conn_le_create_common_checks(const bt_addr_le_t *peer, return -EINVAL; } - return 0; -} - -static struct bt_conn *conn_le_create_helper(const bt_addr_le_t *peer, - const struct bt_le_conn_param *conn_param) -{ - bt_addr_le_t dst; - struct bt_conn *conn; - if (bt_addr_le_is_resolved(peer)) { bt_addr_le_copy_resolved(&dst, peer); } else { @@ -2858,35 +2857,11 @@ static struct bt_conn *conn_le_create_helper(const bt_addr_le_t *peer, /* Only default identity supported for now */ conn = bt_conn_add_le(BT_ID_DEFAULT, &dst); - if (!conn) { - return NULL; - } - - bt_conn_set_param_le(conn, conn_param); - - return conn; -} - -int bt_conn_le_create(const bt_addr_le_t *peer, const struct bt_conn_le_create_param *create_param, - const struct bt_le_conn_param *conn_param, struct bt_conn **ret_conn) -{ - struct bt_conn *conn; - int err; - - err = conn_le_create_common_checks(peer, conn_param); - if (err) { - return err; - } - - if (!create_param_validate(create_param)) { - return -EINVAL; - } - - conn = conn_le_create_helper(peer, conn_param); if (!conn) { return -ENOMEM; } + bt_conn_set_param_le(conn, conn_param); create_param_setup(create_param); #if defined(CONFIG_BT_SMP) @@ -2923,56 +2898,6 @@ int bt_conn_le_create(const bt_addr_le_t *peer, const struct bt_conn_le_create_p return 0; } -int bt_conn_le_create_synced(const struct bt_le_ext_adv *adv, - const struct bt_conn_le_create_synced_param *synced_param, - const struct bt_le_conn_param *conn_param, struct bt_conn **ret_conn) -{ - struct bt_conn *conn; - int err; - - err = conn_le_create_common_checks(synced_param->peer, conn_param); - if (err) { - return err; - } - - if (!atomic_test_bit(adv->flags, BT_PER_ADV_ENABLED)) { - return -EINVAL; - } - - if (!BT_FEAT_LE_PAWR_ADVERTISER(bt_dev.le.features)) { - return -ENOTSUP; - } - - if (synced_param->subevent >= BT_HCI_PAWR_SUBEVENT_MAX) { - return -EINVAL; - } - - conn = conn_le_create_helper(synced_param->peer, conn_param); - if (!conn) { - return -ENOMEM; - } - - /* The connection creation timeout is not really useful for PAwR. - * The controller will give a result for the connection attempt - * within a periodic interval. We do not know the periodic interval - * used, so disable the timeout. - */ - bt_dev.create_param.timeout = 0; - bt_conn_set_state(conn, BT_CONN_CONNECTING); - - err = bt_le_create_conn_synced(conn, adv, synced_param->subevent); - if (err) { - conn->err = 0; - bt_conn_set_state(conn, BT_CONN_DISCONNECTED); - bt_conn_unref(conn); - - return err; - } - - *ret_conn = conn; - return 0; -} - #if !defined(CONFIG_BT_FILTER_ACCEPT_LIST) int bt_le_set_auto_conn(const bt_addr_le_t *addr, const struct bt_le_conn_param *param) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 024720547b3d..9457c52ce21a 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -630,52 +630,6 @@ int bt_le_create_conn_ext(const struct bt_conn *conn) return bt_hci_cmd_send_sync(BT_HCI_OP_LE_EXT_CREATE_CONN, buf, NULL); } -int bt_le_create_conn_synced(const struct bt_conn *conn, const struct bt_le_ext_adv *adv, - uint8_t subevent) -{ - struct bt_hci_cp_le_ext_create_conn_v2 *cp; - struct bt_hci_ext_conn_phy *phy; - struct bt_hci_cmd_state_set state; - struct net_buf *buf; - uint8_t own_addr_type; - int err; - - err = bt_id_set_create_conn_own_addr(false, &own_addr_type); - if (err) { - return err; - } - - /* There shall only be one Initiating_PHYs */ - buf = bt_hci_cmd_create(BT_HCI_OP_LE_EXT_CREATE_CONN_V2, sizeof(*cp) + sizeof(*phy)); - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - (void)memset(cp, 0, sizeof(*cp)); - - bt_addr_le_copy(&cp->peer_addr, &conn->le.dst); - cp->filter_policy = BT_HCI_LE_CREATE_CONN_FP_NO_FILTER; - cp->own_addr_type = own_addr_type; - - /* The Initiating_PHY is the secondary phy of the corresponding ext adv set */ - if (adv->options & BT_LE_ADV_OPT_CODED) { - cp->phys = BT_HCI_LE_EXT_SCAN_PHY_CODED; - } else if (adv->options & BT_LE_ADV_OPT_NO_2M) { - cp->phys = BT_HCI_LE_EXT_SCAN_PHY_1M; - } else { - cp->phys = BT_HCI_LE_EXT_SCAN_PHY_2M; - } - - phy = net_buf_add(buf, sizeof(*phy)); - (void)memset(phy, 0, sizeof(*phy)); - set_phy_conn_param(conn, phy); - - bt_hci_cmd_state_set_init(buf, &state, bt_dev.flags, BT_DEV_INITIATING, true); - - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_EXT_CREATE_CONN_V2, buf, NULL); -} - static int bt_le_create_conn_legacy(const struct bt_conn *conn) { struct bt_hci_cp_le_create_conn *cp; @@ -1116,7 +1070,7 @@ static void conn_auto_initiate(struct bt_conn *conn) } } -static void le_conn_complete_cancel(uint8_t err) +static void le_conn_complete_cancel(void) { struct bt_conn *conn; @@ -1131,7 +1085,7 @@ static void le_conn_complete_cancel(uint8_t err) return; } - conn->err = err; + conn->err = BT_HCI_ERR_UNKNOWN_CONN_ID; /* Handle cancellation of outgoing connection attempt. */ if (!IS_ENABLED(CONFIG_BT_FILTER_ACCEPT_LIST)) { @@ -1226,46 +1180,12 @@ static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) bt_hci_le_enh_conn_complete(evt); } -static void translate_addrs(bt_addr_le_t *peer_addr, bt_addr_le_t *id_addr, - const struct bt_hci_evt_le_enh_conn_complete *evt, uint8_t id) -{ - if (bt_addr_le_is_resolved(&evt->peer_addr)) { - bt_addr_le_copy_resolved(id_addr, &evt->peer_addr); - - bt_addr_copy(&peer_addr->a, &evt->peer_rpa); - peer_addr->type = BT_ADDR_LE_RANDOM; - } else { - bt_addr_le_copy(id_addr, bt_lookup_id_addr(id, &evt->peer_addr)); - bt_addr_le_copy(peer_addr, &evt->peer_addr); - } -} - -static void update_conn(struct bt_conn *conn, const bt_addr_le_t *id_addr, - const struct bt_hci_evt_le_enh_conn_complete *evt) -{ - conn->handle = sys_le16_to_cpu(evt->handle); - bt_addr_le_copy(&conn->le.dst, id_addr); - conn->le.interval = sys_le16_to_cpu(evt->interval); - conn->le.latency = sys_le16_to_cpu(evt->latency); - conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout); - conn->role = evt->role; - conn->err = 0U; - -#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE) - conn->le.data_len.tx_max_len = BT_GAP_DATA_LEN_DEFAULT; - conn->le.data_len.tx_max_time = BT_GAP_DATA_TIME_DEFAULT; - conn->le.data_len.rx_max_len = BT_GAP_DATA_LEN_DEFAULT; - conn->le.data_len.rx_max_time = BT_GAP_DATA_TIME_DEFAULT; -#endif -} - void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) { uint16_t handle = sys_le16_to_cpu(evt->handle); bool is_disconnected = conn_handle_is_disconnected(handle); bt_addr_le_t peer_addr, id_addr; struct bt_conn *conn; - uint8_t id; LOG_DBG("status 0x%02x handle %u role %u peer %s peer RPA %s", evt->status, handle, evt->role, bt_addr_le_str(&evt->peer_addr), bt_addr_str(&evt->peer_rpa)); @@ -1284,27 +1204,29 @@ void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) if (IS_ENABLED(CONFIG_BT_CENTRAL) && evt->status == BT_HCI_ERR_UNKNOWN_CONN_ID) { - le_conn_complete_cancel(evt->status); + le_conn_complete_cancel(); bt_le_scan_update(false); return; } - if (IS_ENABLED(CONFIG_BT_CENTRAL) && IS_ENABLED(CONFIG_BT_PER_ADV_RSP) && - evt->status == BT_HCI_ERR_CONN_FAIL_TO_ESTAB) { - le_conn_complete_cancel(evt->status); - - atomic_clear_bit(bt_dev.flags, BT_DEV_INITIATING); - - return; - } - LOG_WRN("Unexpected status 0x%02x", evt->status); return; } - id = evt->role == BT_HCI_ROLE_PERIPHERAL ? bt_dev.adv_conn_id : BT_ID_DEFAULT; - translate_addrs(&peer_addr, &id_addr, evt, id); + if (bt_addr_le_is_resolved(&evt->peer_addr)) { + bt_addr_le_copy_resolved(&id_addr, &evt->peer_addr); + + bt_addr_copy(&peer_addr.a, &evt->peer_rpa); + peer_addr.type = BT_ADDR_LE_RANDOM; + } else { + uint8_t id = evt->role == BT_HCI_ROLE_PERIPHERAL ? bt_dev.adv_conn_id : + BT_ID_DEFAULT; + + bt_addr_le_copy(&id_addr, + bt_lookup_id_addr(id, &evt->peer_addr)); + bt_addr_le_copy(&peer_addr, &evt->peer_addr); + } conn = find_pending_connect(evt->role, &id_addr); @@ -1334,7 +1256,20 @@ void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt) return; } - update_conn(conn, &id_addr, evt); + conn->handle = handle; + bt_addr_le_copy(&conn->le.dst, &id_addr); + conn->le.interval = sys_le16_to_cpu(evt->interval); + conn->le.latency = sys_le16_to_cpu(evt->latency); + conn->le.timeout = sys_le16_to_cpu(evt->supv_timeout); + conn->role = evt->role; + conn->err = 0U; + +#if defined(CONFIG_BT_USER_DATA_LEN_UPDATE) + conn->le.data_len.tx_max_len = BT_GAP_DATA_LEN_DEFAULT; + conn->le.data_len.tx_max_time = BT_GAP_DATA_TIME_DEFAULT; + conn->le.data_len.rx_max_len = BT_GAP_DATA_LEN_DEFAULT; + conn->le.data_len.rx_max_time = BT_GAP_DATA_TIME_DEFAULT; +#endif #if defined(CONFIG_BT_USER_PHY_UPDATE) conn->le.phy.tx_phy = BT_GAP_LE_PHY_1M; @@ -1455,30 +1390,6 @@ static void le_enh_conn_complete(struct net_buf *buf) enh_conn_complete((void *)buf->data); } -#if defined(CONFIG_BT_PER_ADV_RSP) -static void le_enh_conn_complete_v2(struct net_buf *buf) -{ - struct bt_hci_evt_le_enh_conn_complete_v2 *evt = - (struct bt_hci_evt_le_enh_conn_complete_v2 *)buf->data; - - if (evt->adv_handle == BT_HCI_ADV_HANDLE_INVALID && - evt->sync_handle == BT_HCI_SYNC_HANDLE_INVALID) { - /* The connection was not created via PAwR, handle the event like v1 */ - enh_conn_complete((struct bt_hci_evt_le_enh_conn_complete *)evt); - } -#if defined(CONFIG_BT_PER_ADV_RSP) - else if (evt->adv_handle != BT_HCI_ADV_HANDLE_INVALID && - evt->sync_handle == BT_HCI_SYNC_HANDLE_INVALID) { - /* The connection was created via PAwR advertiser, it can be handled like v1 */ - enh_conn_complete((struct bt_hci_evt_le_enh_conn_complete *)evt); - } -#endif /* CONFIG_BT_PER_ADV_RSP */ - else { - LOG_ERR("Invalid connection complete event"); - } -} -#endif /* CONFIG_BT_PER_ADV_RSP */ - static void le_legacy_conn_complete(struct net_buf *buf) { struct bt_hci_evt_le_conn_complete *evt = (void *)buf->data; @@ -2430,12 +2341,6 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_RESPONSE_REPORT, bt_hci_le_per_adv_response_report, sizeof(struct bt_hci_evt_le_per_adv_response_report)), #endif /* CONFIG_BT_PER_ADV_RSP */ -#if defined(CONFIG_BT_CONN) -#if defined(CONFIG_BT_PER_ADV_RSP) - EVENT_HANDLER(BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2, le_enh_conn_complete_v2, - sizeof(struct bt_hci_evt_le_enh_conn_complete_v2)), -#endif /* CONFIG_BT_PER_ADV_RSP */ -#endif /* CONFIG_BT_CONN */ }; @@ -3021,11 +2926,6 @@ static int le_set_event_mask(void) mask |= BT_EVT_MASK_LE_PAST_RECEIVED_V2; } - if (IS_ENABLED(CONFIG_BT_CONN) && - IS_ENABLED(CONFIG_BT_PER_ADV_RSP)) { - mask |= BT_EVT_MASK_LE_ENH_CONN_COMPLETE_V2; - } - sys_put_le64(mask, cp_mask->events); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL); } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 0859c342ddf4..18fd0e35b2a8 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -156,11 +156,6 @@ struct bt_le_ext_adv { #endif /* defined(CONFIG_BT_EXT_ADV) */ struct k_work_delayable lim_adv_timeout_work; - - /** The options used to set the parameters for this advertising set - * @ref bt_le_adv_param - */ - uint32_t options; }; enum { @@ -434,8 +429,6 @@ int bt_le_scan_update(bool fast_scan); int bt_le_create_conn(const struct bt_conn *conn); int bt_le_create_conn_cancel(void); -int bt_le_create_conn_synced(const struct bt_conn *conn, const struct bt_le_ext_adv *adv, - uint8_t subevent); bool bt_addr_le_is_bonded(uint8_t id, const bt_addr_le_t *addr); const bt_addr_le_t *bt_lookup_id_addr(uint8_t id, const bt_addr_le_t *addr); From 0bfef3506115dabe905f5496c84e75e08c245b18 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:32 +0200 Subject: [PATCH 303/528] Revert "[nrf fromtree] Bluetooth: Host: Fix periodic sync reassembly" This reverts commit 39cd3a2a915556fe170e709d63da1bb815f0043a. Signed-off-by: Robert Lubos --- subsys/bluetooth/host/scan.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 00f0147a35af..3b2fdb543237 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -717,13 +717,6 @@ static struct bt_le_per_adv_sync *per_adv_sync_new(void) (void)memset(per_adv_sync, 0, sizeof(*per_adv_sync)); atomic_set_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CREATED); -#if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 - net_buf_simple_init_with_data(&per_adv_sync->reassembly, - per_adv_sync->reassembly_data, - CONFIG_BT_PER_ADV_SYNC_BUF_SIZE); - net_buf_simple_reset(&per_adv_sync->reassembly); -#endif /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */ - return per_adv_sync; } @@ -1023,6 +1016,12 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) } pending_per_adv_sync->report_truncated = false; +#if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 + net_buf_simple_init_with_data(&pending_per_adv_sync->reassembly, + pending_per_adv_sync->reassembly_data, + CONFIG_BT_PER_ADV_SYNC_BUF_SIZE); + net_buf_simple_reset(&pending_per_adv_sync->reassembly); +#endif /* CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 */ atomic_set_bit(pending_per_adv_sync->flags, BT_PER_ADV_SYNC_SYNCED); From 78c1f83b1f9d1cbad57c9b89a16570898d3e6711 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:32 +0200 Subject: [PATCH 304/528] Revert "[nrf fromtree] Samples: Bluetooth: Add samples for PAwR" This reverts commit 6b53826a1dfa964e7b9d6dc6d727dc4f0893ba39. Signed-off-by: Robert Lubos --- .../bluetooth/periodic_adv_rsp/CMakeLists.txt | 7 - samples/bluetooth/periodic_adv_rsp/README.rst | 38 -- samples/bluetooth/periodic_adv_rsp/prj.conf | 16 - .../bluetooth/periodic_adv_rsp/sample.yaml | 12 - samples/bluetooth/periodic_adv_rsp/src/main.c | 382 ------------------ .../periodic_sync_rsp/CMakeLists.txt | 7 - .../bluetooth/periodic_sync_rsp/README.rst | 40 -- samples/bluetooth/periodic_sync_rsp/prj.conf | 16 - .../bluetooth/periodic_sync_rsp/sample.yaml | 12 - .../bluetooth/periodic_sync_rsp/src/main.c | 256 ------------ 10 files changed, 786 deletions(-) delete mode 100644 samples/bluetooth/periodic_adv_rsp/CMakeLists.txt delete mode 100644 samples/bluetooth/periodic_adv_rsp/README.rst delete mode 100644 samples/bluetooth/periodic_adv_rsp/prj.conf delete mode 100644 samples/bluetooth/periodic_adv_rsp/sample.yaml delete mode 100644 samples/bluetooth/periodic_adv_rsp/src/main.c delete mode 100644 samples/bluetooth/periodic_sync_rsp/CMakeLists.txt delete mode 100644 samples/bluetooth/periodic_sync_rsp/README.rst delete mode 100644 samples/bluetooth/periodic_sync_rsp/prj.conf delete mode 100644 samples/bluetooth/periodic_sync_rsp/sample.yaml delete mode 100644 samples/bluetooth/periodic_sync_rsp/src/main.c diff --git a/samples/bluetooth/periodic_adv_rsp/CMakeLists.txt b/samples/bluetooth/periodic_adv_rsp/CMakeLists.txt deleted file mode 100644 index 796bd5e5d8ed..000000000000 --- a/samples/bluetooth/periodic_adv_rsp/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(periodic_adv) - -target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/periodic_adv_rsp/README.rst b/samples/bluetooth/periodic_adv_rsp/README.rst deleted file mode 100644 index 4446313997d2..000000000000 --- a/samples/bluetooth/periodic_adv_rsp/README.rst +++ /dev/null @@ -1,38 +0,0 @@ -.. _bluetooth-periodic-advertising-rsp-sample: - -Bluetooth: Periodic Advertising with Responses (PAwR) Advertiser -################################################################ - -Overview -******** - -A simple application demonstrating the BLE Periodic Advertising with -Responses Advertiser functionality. - -This sample will scan for the corresponding sync sample and send the required -synchronization info to it. The advertising data is a counter that increases -for each subevent. - -Multiple devices can synchronize and respond to one advertiser. - -Which subevent to listen to and in which response slot to respond is -application specific. In this sample it is decided by the PAwR advertiser. -Upon connection it will write to a GATT characteristic -the assigned subevent and response slot. - -Requirements -************ - -* A board with BLE support -* A controller that supports the Periodic Advertising with Responses (PAwR) - Advertiser feature - -Building and Running -******************** - -This sample can be found under :zephyr_file:`samples/bluetooth/periodic_adv_rsp` in -the Zephyr tree. - -Use the sample found under :zephyr_file:`samples/bluetooth/periodic_sync_rsp` in the -Zephyr tree that will synchronize and respond to this sample. - -See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/periodic_adv_rsp/prj.conf b/samples/bluetooth/periodic_adv_rsp/prj.conf deleted file mode 100644 index 5b7aba46a49c..000000000000 --- a/samples/bluetooth/periodic_adv_rsp/prj.conf +++ /dev/null @@ -1,16 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_BROADCASTER=y -CONFIG_BT_EXT_ADV=y -CONFIG_BT_PER_ADV=y -CONFIG_BT_DEVICE_NAME="PAwR adv sample" - -CONFIG_BT_MAX_CONN=1 -CONFIG_BT_CENTRAL=y -CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y - -CONFIG_BT_PER_ADV_RSP=y - -CONFIG_BT_REMOTE_INFO=y -CONFIG_BT_GATT_CLIENT=y - -CONFIG_LOG=y diff --git a/samples/bluetooth/periodic_adv_rsp/sample.yaml b/samples/bluetooth/periodic_adv_rsp/sample.yaml deleted file mode 100644 index ff64f1d1208e..000000000000 --- a/samples/bluetooth/periodic_adv_rsp/sample.yaml +++ /dev/null @@ -1,12 +0,0 @@ -sample: - name: Bluetooth Periodic Advertising with Responses Advertiser -tests: - sample.bluetooth.periodic_adv: - harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840 - tags: bluetooth - integration_platforms: - - nrf52840dk_nrf52840 - extra_configs: - - CONFIG_BT_CTLR=n - - CONFIG_BT_NO_DRIVER=y diff --git a/samples/bluetooth/periodic_adv_rsp/src/main.c b/samples/bluetooth/periodic_adv_rsp/src/main.c deleted file mode 100644 index 463ecedf10a9..000000000000 --- a/samples/bluetooth/periodic_adv_rsp/src/main.c +++ /dev/null @@ -1,382 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include - -#define NUM_RSP_SLOTS 5 -#define NUM_SUBEVENTS 5 -#define PACKET_SIZE 5 -#define NAME_LEN 30 - -static K_SEM_DEFINE(sem_connected, 0, 1); -static K_SEM_DEFINE(sem_discovered, 0, 1); -static K_SEM_DEFINE(sem_written, 0, 1); -static K_SEM_DEFINE(sem_disconnected, 0, 1); - -static struct bt_uuid_128 pawr_char_uuid = - BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1)); -static uint16_t pawr_attr_handle; -static const struct bt_le_per_adv_param per_adv_params = { - .interval_min = 0xFF, - .interval_max = 0xFF, - .options = 0, - .num_subevents = NUM_SUBEVENTS, - .subevent_interval = 0x30, - .response_slot_delay = 0x5, - .response_slot_spacing = 0x50, - .num_response_slots = NUM_RSP_SLOTS, -}; - -static struct bt_le_per_adv_subevent_data_params subevent_data_params[NUM_SUBEVENTS]; -static struct net_buf_simple bufs[NUM_SUBEVENTS]; -static uint8_t backing_store[PACKET_SIZE][NUM_SUBEVENTS]; - -BUILD_ASSERT(ARRAY_SIZE(bufs) == ARRAY_SIZE(subevent_data_params)); -BUILD_ASSERT(ARRAY_SIZE(backing_store) == ARRAY_SIZE(subevent_data_params)); - -static uint8_t counter; - -static void request_cb(struct bt_le_ext_adv *adv, const struct bt_le_per_adv_data_request *request) -{ - int err; - uint8_t to_send; - struct net_buf_simple *buf; - - to_send = MIN(request->count, ARRAY_SIZE(subevent_data_params)); - - for (size_t i = 0; i < to_send; i++) { - buf = &bufs[i]; - buf->data[buf->len - 1] = counter++; - - subevent_data_params[i].subevent = - (request->start + i) % per_adv_params.num_subevents; - subevent_data_params[i].response_slot_start = 0; - subevent_data_params[i].response_slot_count = NUM_RSP_SLOTS; - subevent_data_params[i].data = buf; - } - - err = bt_le_per_adv_set_subevent_data(adv, to_send, subevent_data_params); - if (err) { - printk("Failed to set subevent data (err %d)\n", err); - } else { - printk("Subevent data set %d\n", counter); - } -} - -static bool print_ad_field(struct bt_data *data, void *user_data) -{ - ARG_UNUSED(user_data); - - printk(" 0x%02X: ", data->type); - for (size_t i = 0; i < data->data_len; i++) { - printk("%02X", data->data[i]); - } - - printk("\n"); - - return true; -} - -static struct bt_conn *default_conn; - -static void response_cb(struct bt_le_ext_adv *adv, struct bt_le_per_adv_response_info *info, - struct net_buf_simple *buf) -{ - if (buf) { - printk("Response: subevent %d, slot %d\n", info->subevent, info->response_slot); - bt_data_parse(buf, print_ad_field, NULL); - } else { - printk("Failed to receive response: subevent %d, slot %d\n", info->subevent, - info->response_slot); - } -} - -static const struct bt_le_ext_adv_cb adv_cb = { - .pawr_data_request = request_cb, - .pawr_response = response_cb, -}; - -void connected_cb(struct bt_conn *conn, uint8_t err) -{ - printk("Connected (err 0x%02X)\n", err); - - __ASSERT(conn == default_conn, "Unexpected connected callback"); - - if (err) { - bt_conn_unref(default_conn); - default_conn = NULL; - } -} - -void disconnected_cb(struct bt_conn *conn, uint8_t reason) -{ - printk("Disconnected (reason 0x%02X)\n", reason); - - bt_conn_unref(default_conn); - default_conn = NULL; - - k_sem_give(&sem_disconnected); -} - -void remote_info_available_cb(struct bt_conn *conn, struct bt_conn_remote_info *remote_info) -{ - /* Need to wait for remote info before initiating PAST */ - k_sem_give(&sem_connected); -} - -BT_CONN_CB_DEFINE(conn_cb) = { - .connected = connected_cb, - .disconnected = disconnected_cb, - .remote_info_available = remote_info_available_cb, -}; - -static bool data_cb(struct bt_data *data, void *user_data) -{ - char *name = user_data; - uint8_t len; - - switch (data->type) { - case BT_DATA_NAME_SHORTENED: - case BT_DATA_NAME_COMPLETE: - len = MIN(data->data_len, NAME_LEN - 1); - memcpy(name, data->data, len); - name[len] = '\0'; - return false; - default: - return true; - } -} - -static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type, - struct net_buf_simple *ad) -{ - char addr_str[BT_ADDR_LE_STR_LEN]; - char name[NAME_LEN]; - int err; - - if (default_conn) { - return; - } - - /* We're only interested in connectable events */ - if (type != BT_GAP_ADV_TYPE_ADV_IND && type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) { - return; - } - - (void)memset(name, 0, sizeof(name)); - bt_data_parse(ad, data_cb, name); - - if (strcmp(name, "PAwR sync sample")) { - return; - } - - if (bt_le_scan_stop()) { - return; - } - - err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, - &default_conn); - if (err) { - printk("Create conn to %s failed (%u)\n", addr_str, err); - } -} - -static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr, - struct bt_gatt_discover_params *params) -{ - struct bt_gatt_chrc *chrc; - char str[BT_UUID_STR_LEN]; - - printk("Discovery: attr %p\n", attr); - - if (!attr) { - return BT_GATT_ITER_STOP; - } - - chrc = (struct bt_gatt_chrc *)attr->user_data; - - bt_uuid_to_str(chrc->uuid, str, sizeof(str)); - printk("UUID %s\n", str); - - if (!bt_uuid_cmp(chrc->uuid, &pawr_char_uuid.uuid)) { - pawr_attr_handle = chrc->value_handle; - - printk("Characteristic handle: %d\n", pawr_attr_handle); - - k_sem_give(&sem_discovered); - } - - return BT_GATT_ITER_STOP; -} - -static void write_func(struct bt_conn *conn, uint8_t err, struct bt_gatt_write_params *params) -{ - if (err) { - printk("Write failed (err %d)\n", err); - - return; - } - - k_sem_give(&sem_written); -} - -void init_bufs(void) -{ - for (size_t i = 0; i < ARRAY_SIZE(backing_store); i++) { - backing_store[i][0] = ARRAY_SIZE(backing_store[i]) - 1; - backing_store[i][1] = BT_DATA_MANUFACTURER_DATA; - backing_store[i][2] = 0x59; /* Nordic */ - backing_store[i][3] = 0x00; - - net_buf_simple_init_with_data(&bufs[i], &backing_store[i], - ARRAY_SIZE(backing_store[i])); - } -} - -#define MAX_SYNCS (NUM_SUBEVENTS * NUM_RSP_SLOTS) -struct pawr_timing { - uint8_t subevent; - uint8_t response_slot; -} __packed; - -static uint8_t num_synced; - -void main(void) -{ - int err; - struct bt_le_ext_adv *pawr_adv; - struct bt_gatt_discover_params discover_params; - struct bt_gatt_write_params write_params; - struct pawr_timing sync_config; - - init_bufs(); - - printk("Starting Periodic Advertising Demo\n"); - - /* Initialize the Bluetooth Subsystem */ - err = bt_enable(NULL); - if (err) { - printk("Bluetooth init failed (err %d)\n", err); - return; - } - - /* Create a non-connectable non-scannable advertising set */ - err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, &adv_cb, &pawr_adv); - if (err) { - printk("Failed to create advertising set (err %d)\n", err); - return; - } - - /* Set periodic advertising parameters */ - err = bt_le_per_adv_set_param(pawr_adv, &per_adv_params); - if (err) { - printk("Failed to set periodic advertising parameters (err %d)\n", err); - return; - } - - /* Enable Periodic Advertising */ - err = bt_le_per_adv_start(pawr_adv); - if (err) { - printk("Failed to enable periodic advertising (err %d)\n", err); - return; - } - - printk("Start Periodic Advertising\n"); - err = bt_le_ext_adv_start(pawr_adv, BT_LE_EXT_ADV_START_DEFAULT); - if (err) { - printk("Failed to start extended advertising (err %d)\n", err); - return; - } - - while (num_synced < MAX_SYNCS) { - err = bt_le_scan_start(BT_LE_SCAN_PASSIVE, device_found); - if (err) { - printk("Scanning failed to start (err %d)\n", err); - return; - } - - printk("Scanning successfully started\n"); - - k_sem_take(&sem_connected, K_FOREVER); - - err = bt_le_per_adv_set_info_transfer(pawr_adv, default_conn, 0); - if (err) { - printk("Failed to send PAST (err %d)\n", err); - - goto disconnect; - } - - printk("PAST sent\n"); - - discover_params.uuid = &pawr_char_uuid.uuid; - discover_params.func = discover_func; - discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE; - discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE; - discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC; - err = bt_gatt_discover(default_conn, &discover_params); - if (err) { - printk("Discovery failed (err %d)\n", err); - - goto disconnect; - } - - printk("Discovery started\n"); - - err = k_sem_take(&sem_discovered, K_SECONDS(10)); - if (err) { - printk("Timed out during GATT discovery\n"); - - goto disconnect; - } - - sync_config.subevent = num_synced % NUM_SUBEVENTS; - sync_config.response_slot = num_synced / NUM_RSP_SLOTS; - num_synced++; - - write_params.func = write_func; - write_params.handle = pawr_attr_handle; - write_params.offset = 0; - write_params.data = &sync_config; - write_params.length = sizeof(sync_config); - - err = bt_gatt_write(default_conn, &write_params); - if (err) { - printk("Write failed (err %d)\n", err); - num_synced--; - - goto disconnect; - } - - printk("Write started\n"); - - err = k_sem_take(&sem_written, K_SECONDS(10)); - if (err) { - printk("Timed out during GATT write\n"); - num_synced--; - - goto disconnect; - } - - printk("PAwR config written to sync %d, disconnecting\n", num_synced - 1); - -disconnect: - err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); - if (err) { - return; - } - - k_sem_take(&sem_disconnected, K_FOREVER); - } - - printk("Maximum numnber of syncs onboarded\n"); - - while (true) { - k_sleep(K_SECONDS(1)); - } -} diff --git a/samples/bluetooth/periodic_sync_rsp/CMakeLists.txt b/samples/bluetooth/periodic_sync_rsp/CMakeLists.txt deleted file mode 100644 index ab801447a2b9..000000000000 --- a/samples/bluetooth/periodic_sync_rsp/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: Apache-2.0 - -cmake_minimum_required(VERSION 3.20.0) -find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(periodic_sync) - -target_sources(app PRIVATE src/main.c) diff --git a/samples/bluetooth/periodic_sync_rsp/README.rst b/samples/bluetooth/periodic_sync_rsp/README.rst deleted file mode 100644 index 787061f2e3ae..000000000000 --- a/samples/bluetooth/periodic_sync_rsp/README.rst +++ /dev/null @@ -1,40 +0,0 @@ -.. _bluetooth-periodic-advertising-sync-rsp-sample: - -Bluetooth: Periodic Advertising with Responses (PAwR) Synchronization -##################################################################### - -Overview -******** - -A simple application demonstrating the BLE Periodic Advertising with -Responses Synchronization functionality. - -This sample will echo the data received in subevent indications back to the -advertiser. - -Which subevent to listen to and in which response slot to respond is -application specific. In this sample it is decided by the PAwR advertiser. -Upon connection it will write to a GATT characteristic -the assigned subevent and response slot. - -Flash this sample to multiple devices and they will be given different -subevents and response slots, to that they can communicate with the -advertiser concurrently. - -Requirements -************ - -* A board with BLE support -* A controller that supports the Periodic Advertising with Responses (PAwR) - Scanner feature - -Building and Running -******************** - -This sample can be found under :zephyr_file:`samples/bluetooth/periodic_sync_rsp` in -the Zephyr tree. - -Use the sample found under :zephyr_file:`samples/bluetooth/periodic_adv_rsp` on -another board that will start periodic advertising, which will connect to this -sample and transfer the synchronization info. - -See :ref:`bluetooth samples section ` for details. diff --git a/samples/bluetooth/periodic_sync_rsp/prj.conf b/samples/bluetooth/periodic_sync_rsp/prj.conf deleted file mode 100644 index bd4f97e60d94..000000000000 --- a/samples/bluetooth/periodic_sync_rsp/prj.conf +++ /dev/null @@ -1,16 +0,0 @@ -CONFIG_BT=y -CONFIG_BT_OBSERVER=y -CONFIG_BT_BROADCASTER=y -CONFIG_BT_EXT_ADV=y -CONFIG_BT_PER_ADV_SYNC=y -CONFIG_BT_DEVICE_NAME="PAwR sync sample" - -CONFIG_BT_MAX_CONN=1 -CONFIG_BT_PERIPHERAL=y -CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER=y -CONFIG_BT_PER_ADV_SYNC_TRANSFER_RECEIVER=y - -CONFIG_BT_PER_ADV_SYNC_RSP=y -CONFIG_BT_PER_ADV_SYNC_BUF_SIZE=247 - -CONFIG_LOG=y diff --git a/samples/bluetooth/periodic_sync_rsp/sample.yaml b/samples/bluetooth/periodic_sync_rsp/sample.yaml deleted file mode 100644 index 8146eeecdbf2..000000000000 --- a/samples/bluetooth/periodic_sync_rsp/sample.yaml +++ /dev/null @@ -1,12 +0,0 @@ -sample: - name: Bluetooth Periodic Advertising with Responses Synchronization -tests: - sample.bluetooth.periodic_sync: - harness: bluetooth - platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840 - tags: bluetooth - integration_platforms: - - nrf52840dk_nrf52840 - extra_configs: - - CONFIG_BT_CTLR=n - - CONFIG_BT_NO_DRIVER=y diff --git a/samples/bluetooth/periodic_sync_rsp/src/main.c b/samples/bluetooth/periodic_sync_rsp/src/main.c deleted file mode 100644 index a4a8a1cb852e..000000000000 --- a/samples/bluetooth/periodic_sync_rsp/src/main.c +++ /dev/null @@ -1,256 +0,0 @@ -/* - * Copyright (c) 2023 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#define NAME_LEN 30 - -static K_SEM_DEFINE(sem_per_adv, 0, 1); -static K_SEM_DEFINE(sem_per_sync, 0, 1); -static K_SEM_DEFINE(sem_per_sync_lost, 0, 1); - -static struct bt_conn *default_conn; -static struct bt_le_per_adv_sync *default_sync; -static struct __packed { - uint8_t subevent; - uint8_t response_slot; - -} pawr_timing; - -static void sync_cb(struct bt_le_per_adv_sync *sync, struct bt_le_per_adv_sync_synced_info *info) -{ - struct bt_le_per_adv_sync_subevent_params params; - uint8_t subevents[1]; - char le_addr[BT_ADDR_LE_STR_LEN]; - int err; - - bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); - printk("Synced to %s with %d subevents\n", le_addr, info->num_subevents); - - default_sync = sync; - - params.properties = 0; - params.num_subevents = 1; - params.subevents = subevents; - subevents[0] = pawr_timing.subevent; - - err = bt_le_per_adv_sync_subevent(sync, ¶ms); - if (err) { - printk("Failed to set subevents to sync to (err %d)\n", err); - } - - k_sem_give(&sem_per_sync); -} - -static void term_cb(struct bt_le_per_adv_sync *sync, - const struct bt_le_per_adv_sync_term_info *info) -{ - char le_addr[BT_ADDR_LE_STR_LEN]; - - bt_addr_le_to_str(info->addr, le_addr, sizeof(le_addr)); - - printk("Sync terminated (reason %d)\n", info->reason); - - default_sync = NULL; - - k_sem_give(&sem_per_sync_lost); -} - -static bool print_ad_field(struct bt_data *data, void *user_data) -{ - ARG_UNUSED(user_data); - - printk(" 0x%02X: ", data->type); - for (size_t i = 0; i < data->data_len; i++) { - printk("%02X", data->data[i]); - } - - printk("\n"); - - return true; -} - -int bt_le_per_adv_set_response_data(struct bt_le_per_adv_sync *per_adv_sync, - const struct bt_le_per_adv_response_params *params, - const struct net_buf_simple *data); - -static struct bt_le_per_adv_response_params rsp_params; - -NET_BUF_SIMPLE_DEFINE_STATIC(rsp_buf, 247); - -static void recv_cb(struct bt_le_per_adv_sync *sync, - const struct bt_le_per_adv_sync_recv_info *info, struct net_buf_simple *buf) -{ - int err; - - if (buf && buf->len) { - /* Echo the data back to the advertiser */ - net_buf_simple_reset(&rsp_buf); - net_buf_simple_add_mem(&rsp_buf, buf->data, buf->len); - - rsp_params.request_event = info->periodic_event_counter; - rsp_params.request_subevent = info->subevent; - /* Respond in current subevent and assigned response slot */ - rsp_params.response_subevent = info->subevent; - rsp_params.response_slot = pawr_timing.response_slot; - - printk("Indication: subevent %d, responding in slot %d\n", info->subevent, - pawr_timing.response_slot); - bt_data_parse(buf, print_ad_field, NULL); - - err = bt_le_per_adv_set_response_data(sync, &rsp_params, &rsp_buf); - if (err) { - printk("Failed to send response (err %d)\n", err); - } - } else if (buf) { - printk("Received empty indication: subevent %d\n", info->subevent); - } else { - printk("Failed to receive indication: subevent %d\n", info->subevent); - } -} - -static struct bt_le_per_adv_sync_cb sync_callbacks = { - .synced = sync_cb, - .term = term_cb, - .recv = recv_cb, -}; - -static struct bt_uuid_128 pawr_svc_uuid = - BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0)); -static struct bt_uuid_128 pawr_char_uuid = - BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1)); - -static ssize_t write_timing(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf, - uint16_t len, uint16_t offset, uint8_t flags) -{ - if (offset) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); - } - - if (len != sizeof(pawr_timing)) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); - } - - memcpy(&pawr_timing, buf, len); - - printk("New timing: subevent %d, response slot %d\n", pawr_timing.subevent, - pawr_timing.response_slot); - - struct bt_le_per_adv_sync_subevent_params params; - uint8_t subevents[1]; - int err; - - params.properties = 0; - params.num_subevents = 1; - params.subevents = subevents; - subevents[0] = pawr_timing.subevent; - - if (default_sync) { - err = bt_le_per_adv_sync_subevent(default_sync, ¶ms); - if (err) { - printk("Failed to set subevents to sync to (err %d)\n", err); - } - } else { - printk("Not synced yet\n"); - } - - return len; -} - -BT_GATT_SERVICE_DEFINE(pawr_svc, BT_GATT_PRIMARY_SERVICE(&pawr_svc_uuid.uuid), - BT_GATT_CHARACTERISTIC(&pawr_char_uuid.uuid, BT_GATT_CHRC_WRITE, - BT_GATT_PERM_WRITE, NULL, write_timing, - &pawr_timing)); - -void connected(struct bt_conn *conn, uint8_t err) -{ - printk("Connected (err 0x%02X)\n", err); - - if (err) { - default_conn = NULL; - - return; - } - - default_conn = bt_conn_ref(conn); -} - -void disconnected(struct bt_conn *conn, uint8_t reason) -{ - bt_conn_unref(default_conn); - default_conn = NULL; - - printk("Disconnected (reason 0x%02X)\n", reason); -} - -BT_CONN_CB_DEFINE(conn_cb) = { - .connected = connected, - .disconnected = disconnected, -}; - -void main(void) -{ - struct bt_le_per_adv_sync_transfer_param past_param; - int err; - - printk("Starting Periodic Advertising with Responses Synchronization Demo\n"); - - err = bt_enable(NULL); - if (err) { - printk("Bluetooth init failed (err %d)\n", err); - - return; - } - - bt_le_per_adv_sync_cb_register(&sync_callbacks); - - past_param.skip = 1; - past_param.timeout = 1000; /* 10 seconds */ - past_param.options = BT_LE_PER_ADV_SYNC_TRANSFER_OPT_NONE; - err = bt_le_per_adv_sync_transfer_subscribe(NULL, &past_param); - if (err) { - printk("PAST subscribe failed (err %d)\n", err); - - return; - } - - do { - err = bt_le_adv_start( - BT_LE_ADV_PARAM(BT_LE_ADV_OPT_ONE_TIME | BT_LE_ADV_OPT_CONNECTABLE | - BT_LE_ADV_OPT_USE_NAME | - BT_LE_ADV_OPT_FORCE_NAME_IN_AD, - BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, NULL), - NULL, 0, NULL, 0); - if (err && err != -EALREADY) { - printk("Advertising failed to start (err %d)\n", err); - - return; - } - - printk("Waiting for periodic sync...\n"); - err = k_sem_take(&sem_per_sync, K_SECONDS(10)); - if (err) { - printk("Timed out while synchronizing\n"); - - continue; - } - - printk("Periodic sync established.\n"); - - err = k_sem_take(&sem_per_sync_lost, K_FOREVER); - if (err) { - printk("failed (err %d)\n", err); - - return; - } - - printk("Periodic sync lost.\n"); - } while (true); -} From 6c04e8d8a71241cea7cc273fd1ef9c5707b3077d Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:33 +0200 Subject: [PATCH 305/528] Revert "[nrf fromtree] Bluetooth: Host: Add support for PAwR Sync" This reverts commit 7660f3da7bb8047d1f31b120b0ec3135409b8597. Signed-off-by: Robert Lubos --- include/zephyr/bluetooth/bluetooth.h | 97 -------------- include/zephyr/bluetooth/hci.h | 72 ---------- subsys/bluetooth/Kconfig.adv | 8 -- subsys/bluetooth/controller/Kconfig | 13 -- subsys/bluetooth/host/hci_core.c | 15 --- subsys/bluetooth/host/hci_core.h | 17 --- subsys/bluetooth/host/scan.c | 192 +-------------------------- 7 files changed, 3 insertions(+), 411 deletions(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 42ab174abc68..8b5be28dfce3 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -1388,20 +1388,6 @@ struct bt_le_per_adv_sync_synced_info { * */ struct bt_conn *conn; -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - /** Number of subevents */ - uint8_t num_subevents; - - /** Subevent interval (N * 1.25 ms) */ - uint8_t subevent_interval; - - /** Response slot delay (N * 1.25 ms) */ - uint8_t response_slot_delay; - - /** Response slot spacing (N * 1.25 ms) */ - uint8_t response_slot_spacing; - -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ }; struct bt_le_per_adv_sync_term_info { @@ -1430,13 +1416,6 @@ struct bt_le_per_adv_sync_recv_info { /** The Constant Tone Extension (CTE) of the advertisement (@ref bt_df_cte_type) */ uint8_t cte_type; -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - /** The value of the event counter where the subevent indication was received. */ - uint16_t periodic_event_counter; - - /** The subevent where the subevend indication was received. */ - uint8_t subevent; -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ }; @@ -1480,9 +1459,6 @@ struct bt_le_per_adv_sync_cb { * @param sync The advertising set object. * @param info Information about the periodic advertising event. * @param buf Buffer containing the periodic advertising data. - * NULL if the controller failed to receive a subevent - * indication. Only happens if - * @kconfig{CONFIG_BT_PER_ADV_SYNC_RSP} is enabled. */ void (*recv)(struct bt_le_per_adv_sync *sync, const struct bt_le_per_adv_sync_recv_info *info, @@ -2535,79 +2511,6 @@ void bt_foreach_bond(uint8_t id, void (*func)(const struct bt_bond_info *info, int bt_configure_data_path(uint8_t dir, uint8_t id, uint8_t vs_config_len, const uint8_t *vs_config); -struct bt_le_per_adv_sync_subevent_params { - /** @brief Periodic Advertising Properties. - * - * Bit 6 is include TxPower, all others RFU. - * - */ - uint16_t properties; - - /** Number of subevents to sync to */ - uint8_t num_subevents; - - /** @brief The subevent(s) to synchronize with - * - * The array must have @ref num_subevents elements. - * - */ - uint8_t *subevents; -}; - -/** @brief Synchronize with a subset of subevents - * - * Until this command is issued, the subevent(s) the controller is synchronized - * to is unspecified. - * - * @param per_adv_sync The periodic advertising sync object. - * @param params Parameters. - * - * @return 0 in case of success or negative value in case of error. - */ -int bt_le_per_adv_sync_subevent(struct bt_le_per_adv_sync *per_adv_sync, - struct bt_le_per_adv_sync_subevent_params *params); - -struct bt_le_per_adv_response_params { - /** @brief The periodic event counter of the request the response is sent to. - * - * @ref bt_le_per_adv_sync_recv_info - * - * @note The response can be sent up to one periodic interval after - * the request was received. - * - */ - uint16_t request_event; - - /** @brief The subevent counter of the request the response is sent to. - * - * @ref bt_le_per_adv_sync_recv_info - * - */ - uint8_t request_subevent; - - /** The subevent the response shall be sent in */ - uint8_t response_subevent; - - /** The response slot the response shall be sent in */ - uint8_t response_slot; -}; - -/** - * @brief Set the data for a response slot in a specific subevent of the PAwR. - * - * This function is called by the Host to set the response dat. - * The data for a repsonse slot shall be transmitted only once. - * - * @param per_adv_sync The periodic advertising sync object. - * @param params Parameters. - * @param data The response data to send. - * - * @return Zero on success or (negative) error code otherwise. - */ -int bt_le_per_adv_set_response_data(struct bt_le_per_adv_sync *per_adv_sync, - const struct bt_le_per_adv_response_params *params, - const struct net_buf_simple *data); - /** * @} */ diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index 375e10a81572..456d06d8dc6e 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -178,7 +178,6 @@ struct bt_hci_cmd_hdr { #define BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION 39 #define BT_LE_FEAT_BIT_PAWR_ADVERTISER 43 -#define BT_LE_FEAT_BIT_PAWR_SCANNER 44 #define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \ BIT((n) & 7)) @@ -245,8 +244,6 @@ struct bt_hci_cmd_hdr { BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION) #define BT_FEAT_LE_PAWR_ADVERTISER(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_PAWR_ADVERTISER) -#define BT_FEAT_LE_PAWR_SCANNER(feat) BT_LE_FEAT_TEST(feat, \ - BT_LE_FEAT_BIT_PAWR_SCANNER) #define BT_FEAT_LE_CIS(feat) (BT_FEAT_LE_CIS_CENTRAL(feat) | \ BT_FEAT_LE_CIS_PERIPHERAL(feat)) @@ -1514,27 +1511,6 @@ struct bt_hci_cp_le_set_pawr_subevent_data { struct bt_hci_cp_le_set_pawr_subevent_data_element subevents[0]; } __packed; - -#define BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA BT_OP(BT_OGF_LE, 0x0083) -struct bt_hci_cp_le_set_pawr_response_data { - uint16_t sync_handle; - uint16_t request_event; - uint8_t request_subevent; - uint8_t response_subevent; - uint8_t response_slot; - uint8_t response_data_length; - uint8_t response_data[0]; -} __packed; - -#define BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT BT_OP(BT_OGF_LE, 0x0084) -struct bt_hci_cp_le_set_pawr_sync_subevent { - uint16_t sync_handle; - uint16_t periodic_adv_properties; - uint8_t num_subevents; - uint8_t subevents[0]; -} __packed; - - #define BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2 BT_OP(BT_OGF_LE, 0x0086) struct bt_hci_cp_le_set_per_adv_param_v2 { uint8_t handle; @@ -2354,51 +2330,6 @@ struct bt_hci_evt_remote_ext_features { uint8_t features[8]; } __packed; -#define BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED_V2 0x24 -struct bt_hci_evt_le_per_adv_sync_established_v2 { - uint8_t status; - uint16_t handle; - uint8_t sid; - bt_addr_le_t adv_addr; - uint8_t phy; - uint16_t interval; - uint8_t clock_accuracy; - uint8_t num_subevents; - uint8_t subevent_interval; - uint8_t response_slot_delay; - uint8_t response_slot_spacing; -} __packed; - -#define BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2 0x25 -struct bt_hci_evt_le_per_advertising_report_v2 { - uint16_t handle; - int8_t tx_power; - int8_t rssi; - uint8_t cte_type; - uint16_t periodic_event_counter; - uint8_t subevent; - uint8_t data_status; - uint8_t length; - uint8_t data[0]; -} __packed; - -#define BT_HCI_EVT_LE_PAST_RECEIVED_V2 0x26 -struct bt_hci_evt_le_past_received_v2 { - uint8_t status; - uint16_t conn_handle; - uint16_t service_data; - uint16_t sync_handle; - uint8_t adv_sid; - bt_addr_le_t addr; - uint8_t phy; - uint16_t interval; - uint8_t clock_accuracy; - uint8_t num_subevents; - uint8_t subevent_interval; - uint8_t response_slot_delay; - uint8_t response_slot_spacing; -} __packed; - #define BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST 0x27 struct bt_hci_evt_le_per_adv_subevent_data_request { uint8_t adv_handle; @@ -2950,9 +2881,6 @@ struct bt_hci_evt_le_biginfo_adv_report { #define BT_EVT_MASK_LE_TRANSMIT_POWER_REPORTING BT_EVT_BIT(32) #define BT_EVT_MASK_LE_BIGINFO_ADV_REPORT BT_EVT_BIT(33) -#define BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED_V2 BT_EVT_BIT(35) -#define BT_EVT_MASK_LE_PER_ADVERTISING_REPORT_V2 BT_EVT_BIT(36) -#define BT_EVT_MASK_LE_PAST_RECEIVED_V2 BT_EVT_BIT(37) #define BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ BT_EVT_BIT(38) #define BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT BT_EVT_BIT(39) diff --git a/subsys/bluetooth/Kconfig.adv b/subsys/bluetooth/Kconfig.adv index 233ee20d4cbd..d978d8d7e34e 100644 --- a/subsys/bluetooth/Kconfig.adv +++ b/subsys/bluetooth/Kconfig.adv @@ -60,14 +60,6 @@ config BT_PER_ADV_SYNC and deterministic receive data from that device in a connectionless manner. -config BT_PER_ADV_SYNC_RSP - bool "Periodic Advertising with Responses sync support [EXPERIMENTAL]" - select EXPERIMENTAL - depends on BT_OBSERVER - help - Select this to enable Periodic Advertising with Responses Sync - API support. - if BT_PER_ADV_SYNC config BT_PER_ADV_SYNC_MAX diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index f5c5ad66b5af..d2490a426b4f 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -51,10 +51,6 @@ config BT_CTLR_SYNC_PERIODIC_SUPPORT depends on BT_CTLR_ADV_EXT_SUPPORT bool -config BT_CTLR_SYNC_PERIODIC_RSP_SUPPORT - depends on BT_CTLR_SYNC_PERIODIC_SUPPORT - bool - config BT_CTLR_SYNC_TRANSFER_SENDER_SUPPORT depends on BT_CTLR_SYNC_PERIODIC_SUPPORT || BT_CTLR_ADV_PERIODIC_SUPPORT bool @@ -655,15 +651,6 @@ config BT_CTLR_SYNC_PERIODIC Enable support for Bluetooth 5.0 LE Periodic Advertising in Synchronization state in the Controller. -config BT_CTLR_SYNC_PERIODIC_RSP - bool "LE Periodic Advertising with Responses in Synchronization State" - depends on BT_OBSERVER && BT_CTLR_SYNC_PERIODIC_RSP_SUPPORT - select BT_CTLR_CHAN_SEL_2 - default y if BT_PER_ADV_SYNC_RSP - help - Enable support for Bluetooth 5.4 LE Periodic Advertising with - Responses in Synchronization state in the Controller. - if BT_CTLR_SYNC_PERIODIC config BT_CTLR_SYNC_PERIODIC_ADV_LIST diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 9457c52ce21a..3e9488ffdffe 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -2325,15 +2325,6 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_CTE_REQUEST_FAILED, bt_hci_le_df_cte_req_failed, sizeof(struct bt_hci_evt_le_cte_req_failed)), #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */ -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADVERTISING_REPORT_V2, bt_hci_le_per_adv_report_v2, - sizeof(struct bt_hci_evt_le_per_advertising_report_v2)), - EVENT_HANDLER(BT_HCI_EVT_LE_PAST_RECEIVED_V2, bt_hci_le_past_received_v2, - sizeof(struct bt_hci_evt_le_past_received_v2)), - EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SYNC_ESTABLISHED_V2, - bt_hci_le_per_adv_sync_established_v2, - sizeof(struct bt_hci_evt_le_per_adv_sync_established_v2)), -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ #if defined(CONFIG_BT_PER_ADV_RSP) EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST, bt_hci_le_per_adv_subevent_data_request, @@ -2920,12 +2911,6 @@ static int le_set_event_mask(void) mask |= BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT; } - if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) { - mask |= BT_EVT_MASK_LE_PER_ADVERTISING_REPORT_V2; - mask |= BT_EVT_MASK_LE_PER_ADV_SYNC_ESTABLISHED_V2; - mask |= BT_EVT_MASK_LE_PAST_RECEIVED_V2; - } - sys_put_le64(mask, cp_mask->events); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL); } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 18fd0e35b2a8..3f41073f9682 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -227,20 +227,6 @@ struct bt_le_per_adv_sync { /** Flags */ ATOMIC_DEFINE(flags, BT_PER_ADV_SYNC_NUM_FLAGS); - -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - /** Number of subevents */ - uint8_t num_subevents; - - /** Subevent interval (N * 1.25ms) */ - uint8_t subevent_interval; - - /** Response slot delay (N * 1.25ms) */ - uint8_t response_slot_delay; - - /** Response slot spacing (N * 1.25ms) */ - uint8_t response_slot_spacing; -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ }; struct bt_dev_le { @@ -473,15 +459,12 @@ void bt_hci_le_adv_report(struct net_buf *buf); void bt_hci_le_scan_timeout(struct net_buf *buf); void bt_hci_le_adv_ext_report(struct net_buf *buf); void bt_hci_le_per_adv_sync_established(struct net_buf *buf); -void bt_hci_le_per_adv_sync_established_v2(struct net_buf *buf); void bt_hci_le_per_adv_report(struct net_buf *buf); -void bt_hci_le_per_adv_report_v2(struct net_buf *buf); void bt_hci_le_per_adv_sync_lost(struct net_buf *buf); void bt_hci_le_biginfo_adv_report(struct net_buf *buf); void bt_hci_le_df_connectionless_iq_report(struct net_buf *buf); void bt_hci_le_vs_df_connectionless_iq_report(struct net_buf *buf); void bt_hci_le_past_received(struct net_buf *buf); -void bt_hci_le_past_received_v2(struct net_buf *buf); /* Adv HCI event handlers */ void bt_hci_le_adv_set_terminated(struct net_buf *buf); diff --git a/subsys/bluetooth/host/scan.c b/subsys/bluetooth/host/scan.c index 3b2fdb543237..70955ce78288 100644 --- a/subsys/bluetooth/host/scan.c +++ b/subsys/bluetooth/host/scan.c @@ -768,28 +768,9 @@ void bt_hci_le_per_adv_report_recv(struct bt_le_per_adv_sync *per_adv_sync, } } -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) && (CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0) -static void bt_hci_le_per_adv_report_recv_failure(struct bt_le_per_adv_sync *per_adv_sync, - const struct bt_le_per_adv_sync_recv_info *info) -{ - struct bt_le_per_adv_sync_cb *listener; - - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { - if (listener->recv) { - listener->recv(per_adv_sync, info, NULL); - } - } -} -#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) && (CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0) */ - -static void bt_hci_le_per_adv_report_common(struct net_buf *buf) +void bt_hci_le_per_adv_report(struct net_buf *buf) { -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - struct bt_hci_evt_le_per_advertising_report_v2 *evt; -#else struct bt_hci_evt_le_per_advertising_report *evt; -#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ - struct bt_le_per_adv_sync *per_adv_sync; struct bt_le_per_adv_sync_recv_info info; @@ -820,11 +801,6 @@ static void bt_hci_le_per_adv_report_common(struct net_buf *buf) info.addr = &per_adv_sync->addr; info.sid = per_adv_sync->sid; -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - info.periodic_event_counter = sys_le16_to_cpu(evt->periodic_event_counter); - info.subevent = evt->subevent; -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ - if (!per_adv_sync->report_truncated) { #if CONFIG_BT_PER_ADV_SYNC_BUF_SIZE > 0 if (net_buf_simple_tailroom(&per_adv_sync->reassembly) < evt->length) { @@ -859,11 +835,6 @@ static void bt_hci_le_per_adv_report_common(struct net_buf *buf) } else if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL) { net_buf_simple_add_mem(&per_adv_sync->reassembly, buf->data, evt->length); -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - } else if (evt->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED && - per_adv_sync->num_subevents) { - bt_hci_le_per_adv_report_recv_failure(per_adv_sync, &info); -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ } else { __ASSERT(false, "Invalid data status 0x%02X", evt->data_status); } @@ -879,17 +850,6 @@ static void bt_hci_le_per_adv_report_common(struct net_buf *buf) } } -void bt_hci_le_per_adv_report(struct net_buf *buf) -{ - if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) { - LOG_ERR("The controller shall raise the latest unmasked version of the event"); - - return; - } - - bt_hci_le_per_adv_report_common(buf); -} - static int per_adv_sync_terminate(uint16_t handle) { struct bt_hci_cp_le_per_adv_terminate_sync *cp; @@ -933,16 +893,10 @@ static void per_adv_sync_terminated(struct bt_le_per_adv_sync *per_adv_sync, } } -static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) +void bt_hci_le_per_adv_sync_established(struct net_buf *buf) { -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - struct bt_hci_evt_le_per_adv_sync_established_v2 *evt = - (struct bt_hci_evt_le_per_adv_sync_established_v2 *)buf->data; -#else struct bt_hci_evt_le_per_adv_sync_established *evt = (struct bt_hci_evt_le_per_adv_sync_established *)buf->data; -#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ - struct bt_le_per_adv_sync_synced_info sync_info; struct bt_le_per_adv_sync *pending_per_adv_sync; struct bt_le_per_adv_sync_cb *listener; @@ -1050,17 +1004,6 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) sync_info.addr = &pending_per_adv_sync->addr; sync_info.sid = pending_per_adv_sync->sid; -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - sync_info.num_subevents = evt->num_subevents; - sync_info.subevent_interval = evt->subevent_interval; - sync_info.response_slot_delay = evt->response_slot_delay; - sync_info.response_slot_spacing = evt->response_slot_spacing; - - pending_per_adv_sync->num_subevents = evt->num_subevents; - pending_per_adv_sync->subevent_interval = evt->subevent_interval; - pending_per_adv_sync->response_slot_delay = evt->response_slot_delay; - pending_per_adv_sync->response_slot_spacing = evt->response_slot_spacing; -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ sync_info.recv_enabled = !atomic_test_bit(pending_per_adv_sync->flags, @@ -1073,85 +1016,6 @@ static void bt_hci_le_per_adv_sync_established_common(struct net_buf *buf) } } -void bt_hci_le_per_adv_sync_established(struct net_buf *buf) -{ - if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) { - LOG_ERR("The controller shall raise the latest unmasked version of the event"); - - return; - } - - bt_hci_le_per_adv_sync_established_common(buf); -} - -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) -int bt_le_per_adv_sync_subevent(struct bt_le_per_adv_sync *per_adv_sync, - struct bt_le_per_adv_sync_subevent_params *params) -{ - struct bt_hci_cp_le_set_pawr_sync_subevent *cp; - struct net_buf *buf; - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, sizeof(*cp)); - - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - (void)memset(cp, 0, sizeof(*cp)); - cp->sync_handle = sys_cpu_to_le16(per_adv_sync->handle); - cp->periodic_adv_properties = sys_cpu_to_le16(params->properties); - cp->num_subevents = params->num_subevents; - net_buf_add_mem(buf, params->subevents, cp->num_subevents); - - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_SYNC_SUBEVENT, buf, NULL); -} - -int bt_le_per_adv_set_response_data(struct bt_le_per_adv_sync *per_adv_sync, - const struct bt_le_per_adv_response_params *param, - const struct net_buf_simple *data) -{ - struct bt_hci_cp_le_set_pawr_response_data *cp; - struct net_buf *buf; - - if (per_adv_sync->num_subevents == 0) { - return -EINVAL; - } - - if (param->request_subevent >= per_adv_sync->num_subevents) { - return -EINVAL; - } - - if (param->response_subevent >= per_adv_sync->num_subevents) { - return -EINVAL; - } - - if (data->len > 247) { - return -EINVAL; - } - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA, - sizeof(*cp) + data->len); - - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - (void)memset(cp, 0, sizeof(*cp)); - cp->sync_handle = sys_cpu_to_le16(per_adv_sync->handle); - cp->request_event = sys_cpu_to_le16(param->request_event); - cp->request_subevent = param->request_subevent; - cp->response_subevent = param->response_subevent; - cp->response_slot = param->response_slot; - cp->response_data_length = data->len; - - net_buf_add_mem(buf, data->data, cp->response_data_length); - - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_RESPONSE_DATA, buf, NULL); -} -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ - void bt_hci_le_per_adv_sync_lost(struct net_buf *buf) { struct bt_hci_evt_le_per_adv_sync_lost *evt = @@ -1171,16 +1035,10 @@ void bt_hci_le_per_adv_sync_lost(struct net_buf *buf) } #if defined(CONFIG_BT_CONN) -static void bt_hci_le_past_received_common(struct net_buf *buf) +void bt_hci_le_past_received(struct net_buf *buf) { -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - struct bt_hci_evt_le_past_received_v2 *evt = - (struct bt_hci_evt_le_past_received_v2 *)buf->data; -#else struct bt_hci_evt_le_past_received *evt = (struct bt_hci_evt_le_past_received *)buf->data; -#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ - struct bt_le_per_adv_sync_synced_info sync_info; struct bt_le_per_adv_sync_cb *listener; struct bt_le_per_adv_sync *per_adv_sync; @@ -1225,26 +1083,12 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) bt_addr_le_copy(&per_adv_sync->addr, &id_addr); per_adv_sync->sid = evt->adv_sid; -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - per_adv_sync->num_subevents = evt->num_subevents; - per_adv_sync->subevent_interval = evt->subevent_interval; - per_adv_sync->response_slot_delay = evt->response_slot_delay; - per_adv_sync->response_slot_spacing = evt->response_slot_spacing; -#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ - sync_info.interval = per_adv_sync->interval; sync_info.phy = bt_get_phy(per_adv_sync->phy); sync_info.addr = &per_adv_sync->addr; sync_info.sid = per_adv_sync->sid; sync_info.service_data = sys_le16_to_cpu(evt->service_data); -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) - sync_info.num_subevents = per_adv_sync->num_subevents; - sync_info.subevent_interval = per_adv_sync->subevent_interval; - sync_info.response_slot_delay = per_adv_sync->response_slot_delay; - sync_info.response_slot_spacing = per_adv_sync->response_slot_spacing; -#endif /* defined(CONFIG_BT_PER_ADV_SYNC_RSP) */ - SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) { if (listener->synced) { listener->synced(per_adv_sync, &sync_info); @@ -1253,38 +1097,8 @@ static void bt_hci_le_past_received_common(struct net_buf *buf) bt_conn_unref(sync_info.conn); } - -void bt_hci_le_past_received(struct net_buf *buf) -{ - if (IS_ENABLED(CONFIG_BT_PER_ADV_SYNC_RSP)) { - LOG_ERR("The controller shall raise the latest unmasked version of the event"); - - return; - } - - bt_hci_le_past_received_common(buf); -} - -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) -void bt_hci_le_past_received_v2(struct net_buf *buf) -{ - bt_hci_le_past_received_common(buf); -} -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ #endif /* CONFIG_BT_CONN */ -#if defined(CONFIG_BT_PER_ADV_SYNC_RSP) -void bt_hci_le_per_adv_sync_established_v2(struct net_buf *buf) -{ - bt_hci_le_per_adv_sync_established_common(buf); -} - -void bt_hci_le_per_adv_report_v2(struct net_buf *buf) -{ - bt_hci_le_per_adv_report_common(buf); -} -#endif /* CONFIG_BT_PER_ADV_SYNC_RSP */ - #if defined(CONFIG_BT_ISO_BROADCAST) void bt_hci_le_biginfo_adv_report(struct net_buf *buf) { From 972628fcc980392903cc983ee21aa92cda97f494 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:33 +0200 Subject: [PATCH 306/528] Revert "[nrf fromtree] Bluetooth: Host: Add support for PAwR Advertiser" This reverts commit 77991d31c48e4fba925fd3c853dd19fdc8ee0bd5. Signed-off-by: Robert Lubos --- include/zephyr/bluetooth/bluetooth.h | 128 ------------------- include/zephyr/bluetooth/hci.h | 68 ---------- subsys/bluetooth/Kconfig.adv | 8 -- subsys/bluetooth/controller/Kconfig | 13 -- subsys/bluetooth/host/adv.c | 178 +-------------------------- subsys/bluetooth/host/hci_core.c | 12 -- subsys/bluetooth/host/hci_core.h | 3 - 7 files changed, 5 insertions(+), 405 deletions(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index 8b5be28dfce3..fd0c638bb966 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -74,39 +74,6 @@ struct bt_le_ext_adv_scanned_info { bt_addr_le_t *addr; }; -struct bt_le_per_adv_data_request { - /** The first subevent data can be set for */ - uint8_t start; - - /** The number of subevents data can be set for */ - uint8_t count; -}; - -struct bt_le_per_adv_response_info { - /** The subevent the response was received in */ - uint8_t subevent; - - /** @brief Status of the subevent indication. - * - * 0 if subevent indication was transmitted. - * 1 if subevent indication was not transmitted. - * All other values RFU. - */ - uint8_t tx_status; - - /** The TX power of the response in dBm */ - int8_t tx_power; - - /** The RSSI of the response in dBm */ - int8_t rssi; - - /** The Constant Tone Extension (CTE) of the advertisement (@ref bt_df_cte_type) */ - uint8_t cte_type; - - /** The slot the response was received in */ - uint8_t response_slot; -}; - struct bt_le_ext_adv_cb { /** * @brief The advertising set has finished sending adv data. @@ -162,32 +129,6 @@ struct bt_le_ext_adv_cb { */ bool (*rpa_expired)(struct bt_le_ext_adv *adv); #endif /* defined(CONFIG_BT_PRIVACY) */ - -#if defined(CONFIG_BT_PER_ADV_RSP) - /** - * @brief The Controller indicates it is ready to transmit one or more subevent. - * - * This callback notifies the application that the controller has requested - * data for upcoming subevents. - * - * @param adv The advertising set object. - * @param request Information about the upcoming subevents. - */ - void (*pawr_data_request)(struct bt_le_ext_adv *adv, - const struct bt_le_per_adv_data_request *request); - /** - * @brief The Controller indicates that one or more synced devices have - * responded to a periodic advertising subevent indication. - * - * @param adv The advertising set object. - * @param info Information about the responses received. - * @param buf The received data. NULL if the controller reported - * that it did not receive any response. - */ - void (*pawr_response)(struct bt_le_ext_adv *adv, struct bt_le_per_adv_response_info *info, - struct net_buf_simple *buf); - -#endif /* defined(CONFIG_BT_PER_ADV_RSP) */ }; /** @@ -790,43 +731,6 @@ struct bt_le_per_adv_param { /** Bit-field of periodic advertising options */ uint32_t options; - -#if defined(CONFIG_BT_PER_ADV_RSP) - /** - * @brief Number of subevents - * - * If zero, the periodic advertiser will be a broadcaster, without responses. - */ - uint8_t num_subevents; - - /** - * @brief Interval between subevents (N * 1.25 ms) - * - * Shall be between 7.5ms and 318.75 ms. - */ - uint8_t subevent_interval; - - /** - * @brief Time between the advertising packet in a subevent and the - * first response slot (N * 1.25 ms) - * - */ - uint8_t response_slot_delay; - - /** - * @brief Time between response slots (N * 0.125 ms) - * - * Shall be between 0.25 and 31.875 ms. - */ - uint8_t response_slot_spacing; - - /** - * @brief Number of subevent response slots - * - * If zero, response_slot_delay and response_slot_spacing are ignored. - */ - uint8_t num_response_slots; -#endif /* CONFIG_BT_PER_ADV_RSP */ }; /** @@ -1294,38 +1198,6 @@ int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv, int bt_le_per_adv_set_data(const struct bt_le_ext_adv *adv, const struct bt_data *ad, size_t ad_len); -struct bt_le_per_adv_subevent_data_params { - /** The subevent to set data for */ - uint8_t subevent; - - /** The first response slot to listen to */ - uint8_t response_slot_start; - - /** The number of response slots to listen to */ - uint8_t response_slot_count; - - /** The data to send */ - const struct net_buf_simple *data; -}; - -/** - * @brief Set the periodic advertising with response subevent data. - * - * Set the data for one or more subevents of a Periodic Advertising with - * Responses Advertiser in reply data request. - * - * @pre There are @p num_subevents elements in @p params. - * @pre The controller has requested data for the subevents in @p params. - * - * @param adv The extended advertiser the PAwR train belongs to. - * @param num_subevents The number of subevents to set data for. - * @param params Subevent parameters. - * - * @return Zero on success or (negative) error code otherwise. - */ -int bt_le_per_adv_set_subevent_data(const struct bt_le_ext_adv *adv, uint8_t num_subevents, - const struct bt_le_per_adv_subevent_data_params *params); - /** * @brief Starts periodic advertising. * diff --git a/include/zephyr/bluetooth/hci.h b/include/zephyr/bluetooth/hci.h index 456d06d8dc6e..f0625de39711 100644 --- a/include/zephyr/bluetooth/hci.h +++ b/include/zephyr/bluetooth/hci.h @@ -35,10 +35,6 @@ extern "C" { #define BT_ENC_KEY_SIZE_MIN 0x07 #define BT_ENC_KEY_SIZE_MAX 0x10 -#define BT_HCI_ADV_HANDLE_INVALID 0xff -#define BT_HCI_SYNC_HANDLE_INVALID 0xffff -#define BT_HCI_PAWR_SUBEVENT_MAX 128 - struct bt_hci_evt_hdr { uint8_t evt; uint8_t len; @@ -177,8 +173,6 @@ struct bt_hci_cmd_hdr { #define BT_LE_FEAT_BIT_CONN_SUBRATING_HOST_SUPP 38 #define BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION 39 -#define BT_LE_FEAT_BIT_PAWR_ADVERTISER 43 - #define BT_LE_FEAT_TEST(feat, n) (feat[(n) >> 3] & \ BIT((n) & 7)) @@ -242,8 +236,6 @@ struct bt_hci_cmd_hdr { BT_LE_FEAT_BIT_CONN_SUBRATING_HOST_SUPP) #define BT_FEAT_LE_CHANNEL_CLASSIFICATION(feat) BT_LE_FEAT_TEST(feat, \ BT_LE_FEAT_BIT_CHANNEL_CLASSIFICATION) -#define BT_FEAT_LE_PAWR_ADVERTISER(feat) BT_LE_FEAT_TEST(feat, \ - BT_LE_FEAT_BIT_PAWR_ADVERTISER) #define BT_FEAT_LE_CIS(feat) (BT_FEAT_LE_CIS_CENTRAL(feat) | \ BT_FEAT_LE_CIS_PERIPHERAL(feat)) @@ -1496,35 +1488,6 @@ struct bt_hci_cp_le_ext_create_conn { struct bt_hci_ext_conn_phy p[0]; } __packed; -#define BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA BT_OP(BT_OGF_LE, 0x0082) -struct bt_hci_cp_le_set_pawr_subevent_data_element { - uint8_t subevent; - uint8_t response_slot_start; - uint8_t response_slot_count; - uint8_t subevent_data_length; - uint8_t subevent_data[0]; -} __packed; - -struct bt_hci_cp_le_set_pawr_subevent_data { - uint8_t adv_handle; - uint8_t num_subevents; - struct bt_hci_cp_le_set_pawr_subevent_data_element subevents[0]; -} __packed; - -#define BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2 BT_OP(BT_OGF_LE, 0x0086) -struct bt_hci_cp_le_set_per_adv_param_v2 { - uint8_t handle; - uint16_t min_interval; - uint16_t max_interval; - uint16_t props; - uint8_t num_subevents; - uint8_t subevent_interval; - uint8_t response_slot_delay; - uint8_t response_slot_spacing; - uint8_t num_response_slots; -} __packed; - - #define BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_USE_LIST BIT(0) #define BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_REPORTS_DISABLED BIT(1) #define BT_HCI_LE_PER_ADV_CREATE_SYNC_FP_FILTER_DUPLICATE BIT(2) @@ -2330,33 +2293,6 @@ struct bt_hci_evt_remote_ext_features { uint8_t features[8]; } __packed; -#define BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST 0x27 -struct bt_hci_evt_le_per_adv_subevent_data_request { - uint8_t adv_handle; - uint8_t subevent_start; - uint8_t subevent_data_count; -} __packed; - -#define BT_HCI_EVT_LE_PER_ADV_RESPONSE_REPORT 0x28 - -struct bt_hci_evt_le_per_adv_response { - int8_t tx_power; - int8_t rssi; - uint8_t cte_type; - uint8_t response_slot; - uint8_t data_status; - uint8_t data_length; - uint8_t data[0]; -} __packed; - -struct bt_hci_evt_le_per_adv_response_report { - uint8_t adv_handle; - uint8_t subevent; - uint8_t tx_status; - uint8_t num_responses; - struct bt_hci_evt_le_per_adv_response responses[0]; -} __packed; - #define BT_HCI_EVT_SYNC_CONN_COMPLETE 0x2c struct bt_hci_evt_sync_conn_complete { uint8_t status; @@ -2562,7 +2498,6 @@ struct bt_hci_evt_le_phy_update_complete { #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE 0 #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL 1 #define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE 2 -#define BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED 0xFF struct bt_hci_evt_le_ext_advertising_info { uint16_t evt_type; @@ -2881,9 +2816,6 @@ struct bt_hci_evt_le_biginfo_adv_report { #define BT_EVT_MASK_LE_TRANSMIT_POWER_REPORTING BT_EVT_BIT(32) #define BT_EVT_MASK_LE_BIGINFO_ADV_REPORT BT_EVT_BIT(33) -#define BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ BT_EVT_BIT(38) -#define BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT BT_EVT_BIT(39) - /** Allocate a HCI command buffer. * * This function allocates a new buffer for a HCI command. It is given diff --git a/subsys/bluetooth/Kconfig.adv b/subsys/bluetooth/Kconfig.adv index d978d8d7e34e..1633e48bd0c7 100644 --- a/subsys/bluetooth/Kconfig.adv +++ b/subsys/bluetooth/Kconfig.adv @@ -43,14 +43,6 @@ config BT_PER_ADV intervals. Scanners can synchronize to the periodic advertisements to periodically get the data. -config BT_PER_ADV_RSP - bool "Periodic Advertising with Responses support [EXPERIMENTAL]" - select EXPERIMENTAL - depends on BT_PER_ADV - help - Select this to enable Periodic Advertising with Responses - API support. - config BT_PER_ADV_SYNC bool "Periodic advertising sync support" depends on BT_OBSERVER diff --git a/subsys/bluetooth/controller/Kconfig b/subsys/bluetooth/controller/Kconfig index d2490a426b4f..1154d4ac3a6f 100644 --- a/subsys/bluetooth/controller/Kconfig +++ b/subsys/bluetooth/controller/Kconfig @@ -43,10 +43,6 @@ config BT_CTLR_ADV_PERIODIC_SUPPORT depends on BT_CTLR_ADV_EXT_SUPPORT bool -config BT_CTLR_ADV_PERIODIC_RSP_SUPPORT - depends on BT_CTLR_ADV_PERIODIC_SUPPORT - bool - config BT_CTLR_SYNC_PERIODIC_SUPPORT depends on BT_CTLR_ADV_EXT_SUPPORT bool @@ -612,15 +608,6 @@ config BT_CTLR_ADV_PERIODIC Enable support for Bluetooth 5.0 LE Periodic Advertising in the Controller. -config BT_CTLR_ADV_PERIODIC_RSP - bool "LE Periodic Advertising with Responses in Advertising State" - depends on BT_BROADCASTER && BT_CTLR_ADV_PERIODIC_RSP_SUPPORT - select BT_CTLR_CHAN_SEL_2 - default y if BT_PER_ADV_RSP - help - Enable support for Bluetooth 5.4 LE Periodic Advertising with - Responses in the Controller. - if BT_CTLR_ADV_PERIODIC config BT_CTLR_ADV_PERIODIC_ADI_SUPPORT diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 7963b39f99b9..2a7b0cab419d 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -1779,29 +1779,12 @@ static void adv_timeout(struct k_work *work) int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv, const struct bt_le_per_adv_param *param) { -#if defined(CONFIG_BT_PER_ADV_RSP) - /* The v2 struct can be used even if we end up sending a v1 command - * because they have the same layout for the common fields. - * V2 simply adds fields at the end of the v1 command. - */ - struct bt_hci_cp_le_set_per_adv_param_v2 *cp; -#else struct bt_hci_cp_le_set_per_adv_param *cp; -#endif /* CONFIG_BT_PER_ADV_RSP */ - - uint16_t opcode; - uint16_t size; struct net_buf *buf; int err; uint16_t props = 0; - if (IS_ENABLED(CONFIG_BT_PER_ADV_RSP) && BT_FEAT_LE_PAWR_ADVERTISER(bt_dev.le.features)) { - opcode = BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2; - size = sizeof(struct bt_hci_cp_le_set_per_adv_param_v2); - } else if (BT_FEAT_LE_EXT_PER_ADV(bt_dev.le.features)) { - opcode = BT_HCI_OP_LE_SET_PER_ADV_PARAM; - size = sizeof(struct bt_hci_cp_le_set_per_adv_param); - } else { + if (!BT_FEAT_LE_EXT_PER_ADV(bt_dev.le.features)) { return -ENOTSUP; } @@ -1824,13 +1807,13 @@ int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv, return -ENOTSUP; } - buf = bt_hci_cmd_create(opcode, size); + buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_PARAM, sizeof(*cp)); if (!buf) { return -ENOBUFS; } - cp = net_buf_add(buf, size); - (void)memset(cp, 0, size); + cp = net_buf_add(buf, sizeof(*cp)); + (void)memset(cp, 0, sizeof(*cp)); cp->handle = adv->handle; cp->min_interval = sys_cpu_to_le16(param->interval_min); @@ -1841,18 +1824,7 @@ int bt_le_per_adv_set_param(struct bt_le_ext_adv *adv, } cp->props = sys_cpu_to_le16(props); - -#if defined(CONFIG_BT_PER_ADV_RSP) - if (opcode == BT_HCI_OP_LE_SET_PER_ADV_PARAM_V2) { - cp->num_subevents = param->num_subevents; - cp->subevent_interval = param->subevent_interval; - cp->response_slot_delay = param->response_slot_delay; - cp->response_slot_spacing = param->response_slot_spacing; - cp->num_response_slots = param->num_response_slots; - } -#endif /* CONFIG_BT_PER_ADV_RSP */ - - err = bt_hci_cmd_send_sync(opcode, buf, NULL); + err = bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_PARAM, buf, NULL); if (err) { return err; } @@ -1900,48 +1872,6 @@ int bt_le_per_adv_set_data(const struct bt_le_ext_adv *adv, return hci_set_per_adv_data(adv, ad, ad_len); } -int bt_le_per_adv_set_subevent_data(const struct bt_le_ext_adv *adv, uint8_t num_subevents, - const struct bt_le_per_adv_subevent_data_params *params) -{ - struct bt_hci_cp_le_set_pawr_subevent_data *cp; - struct bt_hci_cp_le_set_pawr_subevent_data_element *element; - struct net_buf *buf; - size_t cmd_length = sizeof(*cp); - - if (!BT_FEAT_LE_PAWR_ADVERTISER(bt_dev.le.features)) { - return -ENOTSUP; - } - - for (size_t i = 0; i < num_subevents; i++) { - cmd_length += sizeof(struct bt_hci_cp_le_set_pawr_subevent_data_element); - cmd_length += params[i].data->len; - } - - if (cmd_length > 0xFF) { - return -EINVAL; - } - - buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA, (uint8_t)cmd_length); - if (!buf) { - return -ENOBUFS; - } - - cp = net_buf_add(buf, sizeof(*cp)); - cp->adv_handle = adv->handle; - cp->num_subevents = num_subevents; - - for (size_t i = 0; i < num_subevents; i++) { - element = net_buf_add(buf, sizeof(*element)); - element->subevent = params[i].subevent; - element->response_slot_start = params[i].response_slot_start; - element->response_slot_count = params[i].response_slot_count; - element->subevent_data_length = params[i].data->len; - net_buf_add_mem(buf, params[i].data->data, params[i].data->len); - } - - return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_PER_ADV_SUBEVENT_DATA, buf, NULL); -} - static int bt_le_per_adv_enable(struct bt_le_ext_adv *adv, bool enable) { struct bt_hci_cp_le_set_per_adv_enable *cp; @@ -2003,104 +1933,6 @@ int bt_le_per_adv_stop(struct bt_le_ext_adv *adv) return bt_le_per_adv_enable(adv, false); } -#if defined(CONFIG_BT_PER_ADV_RSP) -void bt_hci_le_per_adv_subevent_data_request(struct net_buf *buf) -{ - struct bt_hci_evt_le_per_adv_subevent_data_request *evt; - struct bt_le_per_adv_data_request request; - struct bt_le_ext_adv *adv; - - if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request)) { - LOG_ERR("Invalid data request"); - - return; - } - - evt = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request)); - adv = bt_adv_lookup_handle(evt->adv_handle); - if (!adv) { - LOG_ERR("Unknown advertising handle %d", evt->adv_handle); - - return; - } - - request.start = evt->subevent_start; - request.count = evt->subevent_data_count; - - if (adv->cb && adv->cb->pawr_data_request) { - adv->cb->pawr_data_request(adv, &request); - } -} - -void bt_hci_le_per_adv_response_report(struct net_buf *buf) -{ - struct bt_hci_evt_le_per_adv_response_report *evt; - struct bt_hci_evt_le_per_adv_response *response; - struct bt_le_ext_adv *adv; - struct bt_le_per_adv_response_info info; - struct net_buf_simple data; - - if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_response_report)) { - LOG_ERR("Invalid response report"); - - return; - } - - evt = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_response_report)); - adv = bt_adv_lookup_handle(evt->adv_handle); - if (!adv) { - LOG_ERR("Unknown advertising handle %d", evt->adv_handle); - - return; - } - - info.subevent = evt->subevent; - info.tx_status = evt->tx_status; - - for (uint8_t i = 0; i < evt->num_responses; i++) { - if (buf->len < sizeof(struct bt_hci_evt_le_per_adv_response)) { - LOG_ERR("Invalid response report"); - - return; - } - - response = net_buf_pull_mem(buf, sizeof(struct bt_hci_evt_le_per_adv_response)); - info.tx_power = response->tx_power; - info.rssi = response->rssi; - info.cte_type = BIT(response->cte_type); - info.response_slot = response->response_slot; - - if (buf->len < response->data_length) { - LOG_ERR("Invalid response report"); - - return; - } - - if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL) { - LOG_WRN("Incomplete response report received, discarding"); - (void)net_buf_pull_mem(buf, response->data_length); - } else if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_RX_FAILED) { - (void)net_buf_pull_mem(buf, response->data_length); - - if (adv->cb && adv->cb->pawr_response) { - adv->cb->pawr_response(adv, &info, NULL); - } - } else if (response->data_status == BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE) { - net_buf_simple_init_with_data(&data, - net_buf_pull_mem(buf, response->data_length), - response->data_length); - - if (adv->cb && adv->cb->pawr_response) { - adv->cb->pawr_response(adv, &info, &data); - } - } else { - LOG_ERR("Invalid data status %d", response->data_status); - (void)net_buf_pull_mem(buf, response->data_length); - } - } -} -#endif /* CONFIG_BT_PER_ADV_RSP */ - #if defined(CONFIG_BT_PER_ADV_SYNC_TRANSFER_SENDER) int bt_le_per_adv_set_info_transfer(const struct bt_le_ext_adv *adv, const struct bt_conn *conn, diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 3e9488ffdffe..cab4c10e5a39 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -2325,13 +2325,6 @@ static const struct event_handler meta_events[] = { EVENT_HANDLER(BT_HCI_EVT_LE_CTE_REQUEST_FAILED, bt_hci_le_df_cte_req_failed, sizeof(struct bt_hci_evt_le_cte_req_failed)), #endif /* CONFIG_BT_DF_CONNECTION_CTE_REQ */ -#if defined(CONFIG_BT_PER_ADV_RSP) - EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_SUBEVENT_DATA_REQUEST, - bt_hci_le_per_adv_subevent_data_request, - sizeof(struct bt_hci_evt_le_per_adv_subevent_data_request)), - EVENT_HANDLER(BT_HCI_EVT_LE_PER_ADV_RESPONSE_REPORT, bt_hci_le_per_adv_response_report, - sizeof(struct bt_hci_evt_le_per_adv_response_report)), -#endif /* CONFIG_BT_PER_ADV_RSP */ }; @@ -2906,11 +2899,6 @@ static int le_set_event_mask(void) mask |= BT_EVT_MASK_LE_CTE_REQUEST_FAILED; } - if (IS_ENABLED(CONFIG_BT_PER_ADV_RSP)) { - mask |= BT_EVT_MASK_LE_PER_ADV_SUBEVENT_DATA_REQ; - mask |= BT_EVT_MASK_LE_PER_ADV_RESPONSE_REPORT; - } - sys_put_le64(mask, cp_mask->events); return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL); } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 3f41073f9682..c0e4dddaffa7 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -488,6 +488,3 @@ void bt_hci_synchronous_conn_complete(struct net_buf *buf); void bt_hci_le_df_connection_iq_report(struct net_buf *buf); void bt_hci_le_vs_df_connection_iq_report(struct net_buf *buf); void bt_hci_le_df_cte_req_failed(struct net_buf *buf); - -void bt_hci_le_per_adv_subevent_data_request(struct net_buf *buf); -void bt_hci_le_per_adv_response_report(struct net_buf *buf); From 78d96d754421009677f8ea7e47de2e8f1274eb13 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:33 +0200 Subject: [PATCH 307/528] Revert "[nrf fromtree] net: Make net_mgmt queue timeout configurable" This reverts commit 946db8886691802b8700c332334d3e47ec504b91. Signed-off-by: Robert Lubos --- subsys/net/ip/Kconfig.mgmt | 8 -------- subsys/net/ip/net_mgmt.c | 6 ++---- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/subsys/net/ip/Kconfig.mgmt b/subsys/net/ip/Kconfig.mgmt index 281d38c7a488..8166f4315ae1 100644 --- a/subsys/net/ip/Kconfig.mgmt +++ b/subsys/net/ip/Kconfig.mgmt @@ -38,14 +38,6 @@ config NET_MGMT_EVENT_QUEUE_SIZE notification. Thus the size of this queue has to be tweaked depending on the load of the system, planned for the usage. -config NET_MGMT_EVENT_QUEUE_TIMEOUT - int "Timeout for event queue" - default 10 - range 1 10000 - help - Timeout in milliseconds for the event queue. This timeout is used to - wait for the queue to be available. - config NET_MGMT_EVENT_INFO bool "Passing information along with an event" help diff --git a/subsys/net/ip/net_mgmt.c b/subsys/net/ip/net_mgmt.c index 94dac5ef6efe..4fc0ea1c7274 100644 --- a/subsys/net/ip/net_mgmt.c +++ b/subsys/net/ip/net_mgmt.c @@ -79,11 +79,9 @@ static inline void mgmt_push_event(uint32_t mgmt_event, struct net_if *iface, new_event.event = mgmt_event; new_event.iface = iface; - if (k_msgq_put(&event_msgq, &new_event, - K_MSEC(CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT)) != 0) { + if (k_msgq_put(&event_msgq, &new_event, K_MSEC(10)) != 0) { NET_WARN("Failure to push event (%u), " - "try increasing the 'CONFIG_NET_MGMT_EVENT_QUEUE_SIZE' " - "or 'CONFIG_NET_MGMT_EVENT_QUEUE_TIMEOUT' options.", + "try increasing the 'CONFIG_NET_MGMT_EVENT_QUEUE_SIZE'", mgmt_event); } From c1023867a9b65e7801b0d3dc7acd338469e9dabb Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:33 +0200 Subject: [PATCH 308/528] Revert "[nrf fromtree] net: update tfm dependency for psa" This reverts commit 35460d14d9f39ec81aedac076a2c7315a64e0b49. Signed-off-by: Robert Lubos --- subsys/net/l2/openthread/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/openthread/Kconfig b/subsys/net/l2/openthread/Kconfig index f8803b316de1..51cb0c2cceb3 100644 --- a/subsys/net/l2/openthread/Kconfig +++ b/subsys/net/l2/openthread/Kconfig @@ -316,7 +316,7 @@ config OPENTHREAD_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE config OPENTHREAD_CRYPTO_PSA bool "ARM PSA crypto API" - depends on MBEDTLS_PSA_CRYPTO_C || BUILD_WITH_TFM + depends on BUILD_WITH_TFM select OPENTHREAD_PLATFORM_KEY_REFERENCES_ENABLE select OPENTHREAD_PLATFORM_KEYS_EXPORTABLE_ENABLE help From b3249ce1ea021fd2d334274d7900e999e3849fde Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:33 +0200 Subject: [PATCH 309/528] Revert "[nrf fromtree] twister: Bring back scope selection rule using platform_allow" This reverts commit 6e436e015ca26840add95eac4df926f2492cf97c. Signed-off-by: Robert Lubos --- scripts/pylib/twister/twisterlib/testplan.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 3b56f2da00c2..3dffbc21213d 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -685,8 +685,10 @@ def apply_filters(self, **kwargs): b = set(filter(lambda item: item.name in ts.platform_allow, self.platforms)) c = a.intersection(b) if not c: - platform_scope = list(filter(lambda item: item.name in ts.platform_allow, \ + _platform_scope = list(filter(lambda item: item.name in ts.platform_allow, \ self.platforms)) + if len(_platform_scope) > 0: + platform_scope = _platform_scope[:1] # list of instances per testsuite, aka configurations. From 3d68e4e6665af76cfd3991579e876a643514e1d3 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:33 +0200 Subject: [PATCH 310/528] Revert "[nrf fromtree] twister: add options to shuffle tests across subsets" This reverts commit c07ed8f4501e565e5b6b4ab3e61d2ba556c9b78f. Signed-off-by: Robert Lubos --- .../pylib/twister/twisterlib/environment.py | 19 ------------------- scripts/pylib/twister/twisterlib/testplan.py | 12 ------------ 2 files changed, 31 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/environment.py b/scripts/pylib/twister/twisterlib/environment.py index 318a0449f1c4..028c42b5f57d 100644 --- a/scripts/pylib/twister/twisterlib/environment.py +++ b/scripts/pylib/twister/twisterlib/environment.py @@ -247,17 +247,6 @@ def add_parse_arguments(parser = None): "This option is useful when running a large number of tests on " "different hosts to speed up execution time.") - parser.add_argument( - "--shuffle-tests", action="store_true", default=None, - help="""Shuffle test execution order to get randomly distributed tests across subsets. - Used only when --subset is provided.""") - - parser.add_argument( - "--shuffle-tests-seed", action="store", default=None, - help="""Seed value for random generator used to shuffle tests. - If not provided, seed in generated by system. - Used only when --shuffle-tests is provided.""") - parser.add_argument("-C", "--coverage", action="store_true", help="Generate coverage reports. Implies " "--enable-coverage.") @@ -709,14 +698,6 @@ def parse_arguments(parser, args, options = None): logger.error("--device-flash-with-test requires --device-testing") sys.exit(1) - if options.shuffle_tests and options.subset is None: - logger.error("--shuffle-tests requires --subset") - sys.exit(1) - - if options.shuffle_tests_seed and options.shuffle_tests is None: - logger.error("--shuffle-tests-seed requires --shuffle-tests") - sys.exit(1) - if options.coverage_formats and (options.coverage_tool != "gcovr"): logger.error("""--coverage-formats can only be used when coverage tool is set to gcovr""") diff --git a/scripts/pylib/twister/twisterlib/testplan.py b/scripts/pylib/twister/twisterlib/testplan.py index 3dffbc21213d..ad2486e4b0db 100755 --- a/scripts/pylib/twister/twisterlib/testplan.py +++ b/scripts/pylib/twister/twisterlib/testplan.py @@ -15,7 +15,6 @@ import logging import copy import shutil -import random logger = logging.getLogger('twister') logger.setLevel(logging.DEBUG) @@ -252,17 +251,6 @@ def generate_subset(self, subset, sets): else: self.instances = OrderedDict(sorted(self.instances.items())) - if self.options.shuffle_tests: - seed_value = int.from_bytes(os.urandom(8), byteorder="big") - if self.options.shuffle_tests_seed is not None: - seed_value = self.options.shuffle_tests_seed - - logger.info(f"Shuffle tests with seed: {seed_value}") - random.seed(seed_value) - temp_list = list(self.instances.items()) - random.shuffle(temp_list) - self.instances = OrderedDict(temp_list) - # Do calculation based on what is actually going to be run and evaluated # at runtime, ignore the cases we already know going to be skipped. # This fixes an issue where some sets would get majority of skips and From c63b6bac7803cc5de51952e405c50074c0d7486a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:34 +0200 Subject: [PATCH 311/528] Revert "[nrf fromtree] west.yaml: MCUboot synchronization from upstream" This reverts commit 885b316642588ffe6fa9ef9aeae7a13090bde4c4. Signed-off-by: Robert Lubos --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index efeb1f8bd159..a984ab9acfc5 100644 --- a/west.yml +++ b/west.yml @@ -181,7 +181,7 @@ manifest: groups: - crypto - name: mcuboot - revision: 1558e7ab0aadb4eac11f03befb5ccd3fa3f0aafe + revision: 6902abba270c0fbcbe8ee3bb56fe39bc9acc2774 path: bootloader/mcuboot - name: mipi-sys-t path: modules/debug/mipi-sys-t From 43dbb2c2a5111346ebf7edd9d727a0abaa211100 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:34 +0200 Subject: [PATCH 312/528] Revert "[nrf fromtree] net: wifi: Fix backward compatibility" This reverts commit f51a134c9a66c6082c14fccead2fb03413f022ce. Signed-off-by: Robert Lubos --- include/zephyr/net/wifi.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index eb9270042c22..0ec71c56b5e8 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -19,13 +19,13 @@ */ enum wifi_security_type { WIFI_SECURITY_TYPE_NONE = 0, + WIFI_SECURITY_TYPE_WEP, + WIFI_SECURITY_TYPE_WPA_PSK, WIFI_SECURITY_TYPE_PSK, WIFI_SECURITY_TYPE_PSK_SHA256, WIFI_SECURITY_TYPE_SAE, WIFI_SECURITY_TYPE_WAPI, WIFI_SECURITY_TYPE_EAP, - WIFI_SECURITY_TYPE_WEP, - WIFI_SECURITY_TYPE_WPA_PSK, __WIFI_SECURITY_TYPE_AFTER_LAST, WIFI_SECURITY_TYPE_MAX = __WIFI_SECURITY_TYPE_AFTER_LAST - 1, From bc5b7074b466f11131b2805f30ad29cf8de77f5a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:34 +0200 Subject: [PATCH 313/528] Revert "[nrf fromtree] Bluetooth: BAP: Fix missing remove of streams from slist" This reverts commit cfe7e71c632a1d41ca0b97d9def36590d2003aed. Signed-off-by: Robert Lubos --- subsys/bluetooth/audio/bap_broadcast_sink.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_sink.c b/subsys/bluetooth/audio/bap_broadcast_sink.c index 65b9a0b2fab0..6c9fb4c815d4 100644 --- a/subsys/bluetooth/audio/bap_broadcast_sink.c +++ b/subsys/bluetooth/audio/bap_broadcast_sink.c @@ -347,6 +347,7 @@ static void broadcast_sink_iso_disconnected(struct bt_iso_chan *chan, struct bt_bap_stream *stream; struct bt_bap_ep *ep = iso->rx.ep; struct bt_bap_broadcast_sink *sink; + bool all_disconnected; if (ep == NULL) { LOG_ERR("iso %p not bound with ep", chan); @@ -377,12 +378,17 @@ static void broadcast_sink_iso_disconnected(struct bt_iso_chan *chan, return; } - if (!sys_slist_find_and_remove(&sink->streams, &stream->_node)) { - LOG_DBG("Could not find and remove stream %p from sink %p", stream, sink); + all_disconnected = true; + SYS_SLIST_FOR_EACH_CONTAINER(&sink->streams, stream, _node) { + /* stream->ep is cleared when the steam disconnects */ + if (stream->ep != NULL) { + all_disconnected = false; + break; + } } /* Clear sink->big if not already cleared */ - if (sys_slist_is_empty(&sink->streams) && sink->big) { + if (all_disconnected && sink->big) { broadcast_sink_clear_big(sink, reason); } } From 994e814536894ee07707cb32ce6081fa746c048f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:34 +0200 Subject: [PATCH 314/528] Revert "[nrf fromtree] Bluetooth: Shell: Add testcases for AUDIO_RX and TX disabled" This reverts commit 62c50cbf56b1b802cb2f6f14c9e7adcdcfcf1939. Signed-off-by: Robert Lubos --- subsys/bluetooth/audio/shell/bap.c | 22 +++++++--------------- tests/bluetooth/shell/testcase.yaml | 16 ---------------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index d7676a3ec9bf..e895ecfda0c7 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -61,7 +61,10 @@ static struct bt_codec_qos broadcast_source_qos; static struct bt_bap_stream broadcast_sink_streams[BROADCAST_SNK_STREAM_CNT]; static struct bt_bap_broadcast_sink *default_sink; #endif /* CONFIG_BT_BAP_BROADCAST_SINK */ +static struct bt_bap_stream *txing_stream; static struct bt_bap_stream *default_stream; +static uint16_t seq_num; +static size_t rx_cnt; static const struct named_lc3_preset lc3_unicast_presets[] = { {"8_1_1", BT_BAP_LC3_UNICAST_PRESET_8_1_1(LOCATION, CONTEXT)}, @@ -141,10 +144,6 @@ const struct named_lc3_preset *default_source_preset = &lc3_unicast_presets[3]; static const struct named_lc3_preset *default_broadcast_source_preset = &lc3_broadcast_presets[3]; static bool initialized; -#if defined(CONFIG_BT_AUDIO_TX) -static struct bt_bap_stream *txing_stream; -static uint16_t seq_num; - static uint16_t get_next_seq_num(uint32_t interval_us) { static int64_t last_ticks; @@ -166,9 +165,8 @@ static uint16_t get_next_seq_num(uint32_t interval_us) return (uint16_t)next_seq_num; } -#endif /* CONFIG_BT_AUDIO_TX */ -#if defined(CONFIG_LIBLC3) && defined(CONFIG_BT_AUDIO_TX) +#if defined(CONFIG_LIBLC3) NET_BUF_POOL_FIXED_DEFINE(sine_tx_pool, CONFIG_BT_ISO_TX_BUF_COUNT, CONFIG_BT_ISO_TX_MTU + BT_ISO_CHAN_SEND_RESERVE, 8, NULL); @@ -365,7 +363,7 @@ static void lc3_audio_timer_timeout(struct k_work *work) } static K_WORK_DELAYABLE_DEFINE(audio_send_work, lc3_audio_timer_timeout); -#endif /* CONFIG_LIBLC3 && CONFIG_BT_AUDIO_TX */ +#endif /* CONFIG_LIBLC3 */ static void print_codec(const struct bt_codec *codec) { @@ -536,9 +534,7 @@ static int lc3_start(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp) { shell_print(ctx_shell, "Start: stream %p", stream); -#if defined(CONFIG_BT_AUDIO_TX) seq_num = 0; -#endif /* CONFIG_BT_AUDIO_TX */ return 0; } @@ -1729,7 +1725,6 @@ static void audio_recv(struct bt_bap_stream *stream, struct net_buf *buf) { static struct bt_iso_recv_info last_info; - static size_t rx_cnt; /* TODO: Make it possible to only print every X packets, and make X settable by the shell */ if ((rx_cnt % 100) == 0) { @@ -2385,7 +2380,6 @@ static int cmd_init(const struct shell *sh, size_t argc, char *argv[]) return 0; } -#if defined(CONFIG_BT_AUDIO_TX) #define DATA_MTU CONFIG_BT_ISO_TX_MTU NET_BUF_POOL_FIXED_DEFINE(tx_pool, 1, DATA_MTU, 8, NULL); @@ -2492,7 +2486,6 @@ static int cmd_stop_sine(const struct shell *sh, size_t argc, char *argv[]) return 0; } #endif /* CONFIG_LIBLC3 */ -#endif /* CONFIG_BT_AUDIO_TX */ #if defined(CONFIG_BT_BAP_UNICAST_SERVER) static void print_ase_info(struct bt_bap_ep *ep, void *user_data) @@ -2557,17 +2550,16 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_CMD_ARG(start, NULL, NULL, cmd_start, 1, 0), SHELL_CMD_ARG(disable, NULL, NULL, cmd_disable, 1, 0), SHELL_CMD_ARG(release, NULL, NULL, cmd_release, 1, 0), - SHELL_CMD_ARG(select_unicast, NULL, "", cmd_select_unicast, 2, 0), + SHELL_CMD_ARG(select_unicast, NULL, "", + cmd_select_unicast, 2, 0), #endif /* CONFIG_BT_BAP_UNICAST */ SHELL_CMD_ARG(preset, NULL, " [preset]", cmd_preset, 2, 1), -#if defined(CONFIG_BT_AUDIO_TX) SHELL_CMD_ARG(send, NULL, "Send to Audio Stream [data]", cmd_send, 1, 1), #if defined(CONFIG_LIBLC3) SHELL_CMD_ARG(start_sine, NULL, "Start sending a LC3 encoded sine wave", cmd_start_sine, 1, 0), SHELL_CMD_ARG(stop_sine, NULL, "Stop sending a LC3 encoded sine wave", cmd_stop_sine, 1, 0), #endif /* CONFIG_LIBLC3 */ -#endif /* CONFIG_BT_AUDIO_TX */ SHELL_COND_CMD_ARG(CONFIG_BT_PACS, set_location, NULL, " ", cmd_set_loc, 3, 0), SHELL_COND_CMD_ARG(CONFIG_BT_PACS, set_context, NULL, diff --git a/tests/bluetooth/shell/testcase.yaml b/tests/bluetooth/shell/testcase.yaml index 642e3388f621..7f8419700b91 100644 --- a/tests/bluetooth/shell/testcase.yaml +++ b/tests/bluetooth/shell/testcase.yaml @@ -237,22 +237,6 @@ tests: platform_allow: native_posix extra_configs: - CONFIG_BT_BAP_BROADCAST_SINK=n - bluetooth.audio_shell.no_audio_tx: - extra_args: CONF_FILE="audio.conf" - build_only: true - platform_allow: native_posix - extra_configs: - - CONFIG_BT_BAP_BROADCAST_SOURCE=n - - CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SNK_COUNT=0 - - CONFIG_BT_ASCS_ASE_SRC_COUNT=0 - bluetooth.audio_shell.no_audio_rx: - extra_args: CONF_FILE="audio.conf" - build_only: true - platform_allow: native_posix - extra_configs: - - CONFIG_BT_BAP_BROADCAST_SINK=n - - CONFIG_BT_BAP_UNICAST_CLIENT_ASE_SRC_COUNT=0 - - CONFIG_BT_ASCS_ASE_SNK_COUNT=0 bluetooth.audio_shell.no_has: extra_args: CONF_FILE="audio.conf" build_only: true From 64b5ee38f8cdd8351ceb1c57156a5d92c2de7243 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:34 +0200 Subject: [PATCH 315/528] Revert "[nrf fromtree] Bluetooth: BAP: Add guard before accessing qos->latency" This reverts commit 99f0de8ca2d681b5c6e11080ba45e867f4d7a634. Signed-off-by: Robert Lubos --- subsys/bluetooth/audio/bap_stream.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 9dd32a8dc76a..b2de44830334 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -160,13 +160,11 @@ enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos) return BT_BAP_ASCS_REASON_SDU; } -#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE) || defined(CONFIG_BT_BAP_UNICAST) if (qos->latency < BT_ISO_LATENCY_MIN || qos->latency > BT_ISO_LATENCY_MAX) { LOG_DBG("Invalid Latency %u", qos->latency); return BT_BAP_ASCS_REASON_LATENCY; } -#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_UNICAST */ if (qos->pd > BT_AUDIO_PD_MAX) { LOG_DBG("Invalid presentation delay %u", qos->pd); From 1de256a72fac56955f0c06de2b53e5f7fe1ba1fa Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:34 +0200 Subject: [PATCH 316/528] Revert "[nrf fromtree] Bluetooth: BAP: Move TX guard to not cover verify funcs" This reverts commit 9a1e63d3004d7ca2e76e5289c6a5d19f6d23853e. Signed-off-by: Robert Lubos --- subsys/bluetooth/audio/bap_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index b2de44830334..2be984607384 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -134,6 +134,7 @@ int bt_bap_ep_get_info(const struct bt_bap_ep *ep, struct bt_bap_ep_info *info) return 0; } +#if defined(CONFIG_BT_AUDIO_TX) enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos) { if (qos->interval < BT_ISO_SDU_INTERVAL_MIN || @@ -225,7 +226,6 @@ bool bt_audio_valid_codec(const struct bt_codec *codec) return true; } -#if defined(CONFIG_BT_AUDIO_TX) int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, uint16_t seq_num, uint32_t ts) { From c1e590a70749928371022391669354ba9883aa89 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:34 +0200 Subject: [PATCH 317/528] Revert "[nrf fromtree] Bluetooth: BAP: Add missing Broadcast source param checks" This reverts commit 99facf30f40d3d864ede649a60e8916da786d5c9. Signed-off-by: Robert Lubos --- subsys/bluetooth/audio/bap_broadcast_source.c | 88 +------------------ subsys/bluetooth/audio/bap_stream.c | 56 ------------ subsys/bluetooth/audio/bap_stream.h | 2 - 3 files changed, 4 insertions(+), 142 deletions(-) diff --git a/subsys/bluetooth/audio/bap_broadcast_source.c b/subsys/bluetooth/audio/bap_broadcast_source.c index 248b5d979ec0..21f2d41248b9 100644 --- a/subsys/bluetooth/audio/bap_broadcast_source.c +++ b/subsys/bluetooth/audio/bap_broadcast_source.c @@ -545,40 +545,18 @@ static bool valid_create_param(const struct bt_bap_broadcast_source_create_param return false; } - CHECKIF(param->qos->rtn > BT_ISO_BROADCAST_RTN_MAX) { - LOG_DBG("param->qos->rtn %u invalid", param->qos->rtn); - return false; - } - - CHECKIF(param->params == NULL) { - LOG_DBG("param->params is NULL"); - return false; - } - - CHECKIF(param->params_count == 0) { - LOG_DBG("param->params_count is 0"); - return false; - } - for (size_t i = 0U; i < param->params_count; i++) { const struct bt_bap_broadcast_source_subgroup_param *subgroup_param; subgroup_param = ¶m->params[i]; - CHECKIF(subgroup_param->params == NULL) { - LOG_DBG("subgroup_params[%zu].params is NULL", i); + CHECKIF(subgroup_param->params_count == 0U) { + LOG_DBG("subgroup_params[%zu].count is 0", i); return false; } - CHECKIF(!IN_RANGE(subgroup_param->params_count, 1U, - CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT)) { - LOG_DBG("subgroup_params[%zu].count (%zu) is invalid", i, - subgroup_param->params_count); - return false; - } - - CHECKIF(!bt_audio_valid_codec(subgroup_param->codec)) { - LOG_DBG("subgroup_params[%zu].codec is invalid", i); + CHECKIF(subgroup_param->codec == NULL) { + LOG_DBG("subgroup_params[%zu].codec is NULL", i); return false; } @@ -599,34 +577,7 @@ static bool valid_create_param(const struct bt_bap_broadcast_source_create_param i, j, stream_param->stream->group); return false; } - - CHECKIF(stream_param->data == NULL && stream_param->data_count != 0) { - LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data is " - "NULL with count %zu", - i, j, stream_param->data_count); - return false; - } - -#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 - CHECKIF(stream_param->data_count > CONFIG_BT_CODEC_MAX_DATA_COUNT) { - LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data_count too " - "large: %zu/%d", - i, j, stream_param->data_count, - CONFIG_BT_CODEC_MAX_DATA_COUNT); - return false; - } - - for (size_t k = 0U; k < stream_param->data_count; k++) { - CHECKIF(!(bt_audio_valid_codec_data(&stream_param->data[k]))) { - LOG_DBG("subgroup_params[%zu].stream_params[%zu]->data[%zu]" - " invalid", - i, j, k); - - return false; - } - } } -#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */ } return true; @@ -680,7 +631,6 @@ int bt_bap_broadcast_source_create(struct bt_bap_broadcast_source_create_param * LOG_DBG("out_source is NULL"); return -EINVAL; } - /* Set out_source to NULL until the source has actually been created */ *out_source = NULL; @@ -805,26 +755,6 @@ int bt_bap_broadcast_source_reconfig(struct bt_bap_broadcast_source *source, str return -EINVAL; } - CHECKIF(!bt_audio_valid_codec(codec)) { - LOG_DBG("codec is invalid"); - return -EINVAL; - } - - CHECKIF(qos == NULL) { - LOG_DBG("qos is NULL"); - return -EINVAL; - } - - CHECKIF(bt_audio_verify_qos(qos) != BT_BAP_ASCS_REASON_NONE) { - LOG_DBG("qos is invalid"); - return -EINVAL; - } - - CHECKIF(qos->rtn > BT_ISO_BROADCAST_RTN_MAX) { - LOG_DBG("qos->rtn %u invalid", qos->rtn); - return -EINVAL; - } - broadcast_state = broadcast_source_get_state(source); if (broadcast_source_get_state(source) != BT_BAP_EP_STATE_QOS_CONFIGURED) { LOG_DBG("Broadcast source invalid state: %u", broadcast_state); @@ -1057,16 +987,6 @@ int bt_bap_broadcast_source_get_id(const struct bt_bap_broadcast_source *source, int bt_bap_broadcast_source_get_base(struct bt_bap_broadcast_source *source, struct net_buf_simple *base_buf) { - CHECKIF(source == NULL) { - LOG_DBG("source is NULL"); - return -EINVAL; - } - - CHECKIF(base_buf == NULL) { - LOG_DBG("base_buf is NULL"); - return -EINVAL; - } - if (!encode_base(source, base_buf)) { LOG_DBG("base_buf %p with size %u not large enough", base_buf, base_buf->size); diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index 2be984607384..bdb8b3bff090 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -167,65 +167,9 @@ enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos) return BT_BAP_ASCS_REASON_LATENCY; } - if (qos->pd > BT_AUDIO_PD_MAX) { - LOG_DBG("Invalid presentation delay %u", qos->pd); - return BT_BAP_ASCS_REASON_PD; - } - return BT_BAP_ASCS_REASON_NONE; } -#if CONFIG_BT_CODEC_MAX_DATA_LEN > 0 -bool bt_audio_valid_codec_data(const struct bt_codec_data *data) -{ - if (data->data.data_len > ARRAY_SIZE(data->value)) { - LOG_DBG("data invalid length: %zu/%zu", data->data.data_len, - ARRAY_SIZE(data->value)); - return false; - } - - return true; -} -#endif /* CONFIG_BT_CODEC_MAX_DATA_LEN > 0 */ - -bool bt_audio_valid_codec(const struct bt_codec *codec) -{ - if (codec == NULL) { - LOG_DBG("codec is NULL"); - return false; - } - -#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 - if (codec->data_count > CONFIG_BT_CODEC_MAX_DATA_COUNT) { - LOG_DBG("codec->data_count (%zu) is invalid", codec->data_count); - return false; - } - - for (size_t i = 0U; i < codec->data_count; i++) { - if (!bt_audio_valid_codec_data(&codec->data[i])) { - LOG_DBG("codec->data[%zu] invalid", i); - return false; - } - } -#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */ - -#if CONFIG_BT_CODEC_MAX_METADATA_COUNT > 0 - if (codec->meta_count > CONFIG_BT_CODEC_MAX_METADATA_COUNT) { - LOG_DBG("codec->meta_count (%zu) is invalid", codec->meta_count); - return false; - } - - for (size_t i = 0U; i < codec->meta_count; i++) { - if (!bt_audio_valid_codec_data(&codec->meta[i])) { - LOG_DBG("codec->meta[%zu] invalid", i); - return false; - } - } -#endif /* CONFIG_BT_CODEC_MAX_METADATA_COUNT > 0 */ - - return true; -} - int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, uint16_t seq_num, uint32_t ts) { diff --git a/subsys/bluetooth/audio/bap_stream.h b/subsys/bluetooth/audio/bap_stream.h index f2074932f162..378b8dbcc88f 100644 --- a/subsys/bluetooth/audio/bap_stream.h +++ b/subsys/bluetooth/audio/bap_stream.h @@ -25,8 +25,6 @@ void bt_audio_codec_qos_to_iso_qos(struct bt_iso_chan_io_qos *io, void bt_bap_stream_detach(struct bt_bap_stream *stream); enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos); -bool bt_audio_valid_codec_data(const struct bt_codec_data *data); -bool bt_audio_valid_codec(const struct bt_codec *codec); enum bt_bap_ascs_reason bt_bap_stream_verify_qos(const struct bt_bap_stream *stream, const struct bt_codec_qos *qos); From 18c63106d1060ac104adace0be44de21bd13999d Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:35 +0200 Subject: [PATCH 318/528] Revert "[nrf fromtree] Bluetooth: BAP: Add guard of BIS specific CC data" This reverts commit 2cdb33462b5c0169d18d5c32b44a053cbb918669. Signed-off-by: Robert Lubos --- include/zephyr/bluetooth/audio/bap.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/zephyr/bluetooth/audio/bap.h b/include/zephyr/bluetooth/audio/bap.h index 7379275266a7..7badeb955e9f 100644 --- a/include/zephyr/bluetooth/audio/bap.h +++ b/include/zephyr/bluetooth/audio/bap.h @@ -1327,7 +1327,6 @@ struct bt_bap_broadcast_source_stream_param { /** Audio stream */ struct bt_bap_stream *stream; -#if CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 /** * @brief The number of elements in the @p data array. * @@ -1337,7 +1336,6 @@ struct bt_bap_broadcast_source_stream_param { /** BIS Codec Specific Configuration */ struct bt_codec_data *data; -#endif /* CONFIG_BT_CODEC_MAX_DATA_COUNT > 0 */ }; /** Broadcast Source subgroup parameters*/ From 703c27cee087f25a244f44e4cb1c36bd7eaa622c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:35 +0200 Subject: [PATCH 319/528] Revert "[nrf fromtree] manifest: openthread: Regular openthread upmerge to `2594291`" This reverts commit 420241edec7a2e1314ed04f636fd62f1e16fd9dc. Signed-off-by: Robert Lubos --- modules/openthread/CMakeLists.txt | 12 ++++++------ modules/openthread/Kconfig.features | 6 +++--- west.yml | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index a263e2256082..3c428b999a57 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -316,6 +316,12 @@ else() set(OT_MLR OFF CACHE BOOL "Enable Multicast Listener Registration feature for Thread 1.2" FORCE) endif() +if(CONFIG_OPENTHREAD_MTD_NETDIAG) + set(OT_MTD_NETDIAG ON CACHE BOOL "Enable TMF network diagnostics on MTDs" FORCE) +else() + set(OT_MTD_NETDIAG OFF CACHE BOOL "Enable TMF network diagnostics on MTDs" FORCE) +endif() + if(CONFIG_OPENTHREAD_MULTIPLE_INSTANCE) set(OT_MULTIPLE_INSTANCE ON CACHE BOOL "Enable multiple instances" FORCE) else() @@ -340,12 +346,6 @@ else() set(OT_NEIGHBOR_DISCOVERY_AGENT OFF CACHE BOOL "Enable neighbor discovery agent support" FORCE) endif() -if(CONFIG_OPENTHREAD_NETDIAG_CLIENT) - set(OT_NETDIAG_CLIENT ON CACHE BOOL "Enable TMF network diagnostics on clients" FORCE) -else() - set(OT_NETDIAG_CLIENT OFF CACHE BOOL "Enable TMF network diagnostics on clients" FORCE) -endif() - if(CONFIG_OPENTHREAD_NETDATA_PUBLISHER) set(OT_NETDATA_PUBLISHER ON CACHE BOOL "Enable Thread Network Data publisher" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index a57de4b31c16..ce531ad2abe9 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -193,6 +193,9 @@ config OPENTHREAD_MLR help Enable Multicast Listener Registration support for Thread 1.2 +config OPENTHREAD_MTD_NETDIAG + bool "TMF network diagnostics on MTDs" + config OPENTHREAD_MULTIPLE_INSTANCE bool "OpenThread multiple instances" @@ -202,9 +205,6 @@ config OPENTHREAD_NAT64_BORDER_ROUTING config OPENTHREAD_NAT64_TRANSLATOR bool "NAT64 translator support" -config OPENTHREAD_NETDIAG_CLIENT - bool "TMF network diagnostics on client" - config OPENTHREAD_NEIGHBOR_DISCOVERY_AGENT bool "Neighbor discovery agent support" diff --git a/west.yml b/west.yml index a984ab9acfc5..f228a5db7984 100644 --- a/west.yml +++ b/west.yml @@ -203,7 +203,7 @@ manifest: revision: aedcc262f93bbb1b0c2f58026911575729b7465c path: modules/lib/open-amp - name: openthread - revision: 25942910ab57b32f73d9c56d8c6cf07c7cf98c49 + revision: 7bdcf8a5d49838ce6e3e227e2780e4f12c461330 path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From b19415087c36fb4457876999c7f65e41131e999f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:35 +0200 Subject: [PATCH 320/528] Revert "[nrf fromtree] mgmt/mcumgr: Fix image erase returning MGMT_ERR_EMSGSIZE" This reverts commit fac25b2b5d404ddc863daebd963af0a07cd85319. Signed-off-by: Robert Lubos --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 73f96eaf8b58..292d275ce958 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -319,6 +319,7 @@ img_mgmt_erase(struct smp_streamer *ctxt) struct image_version ver; int rc; zcbor_state_t *zsd = ctxt->reader->zs; + zcbor_state_t *zse = ctxt->writer->zs; bool ok; uint32_t slot = img_mgmt_get_other_slot(); size_t decoded = 0; @@ -358,15 +359,12 @@ img_mgmt_erase(struct smp_streamer *ctxt) return rc; } - if (IS_ENABLED(CONFIG_MCUMGR_SMP_LEGACY_RC_BEHAVIOUR)) { - zcbor_state_t *zse = ctxt->writer->zs; - - if (!zcbor_tstr_put_lit(zse, "rc") || !zcbor_int32_put(zse, 0)) { - return MGMT_ERR_EMSGSIZE; - } + if (IS_ENABLED(CONFIG_MCUMGR_SMP_LEGACY_RC_BEHAVIOUR) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, 0)) { + return MGMT_ERR_EOK; } - return MGMT_ERR_EOK; + return MGMT_ERR_EMSGSIZE; } static int From 1cc71b1a2d14f35331de92dba191424cd731dd9a Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:35 +0200 Subject: [PATCH 321/528] Revert "[nrf fromlist] mgmt/mcumgr: Use boot_set_next to set image for test or confirm" This reverts commit 982d29e522c69d3eda21143a72ec25fcf8893d18. Signed-off-by: Robert Lubos --- .../mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h | 3 +- .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 60 +++---------------- .../mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c | 2 +- 3 files changed, 9 insertions(+), 56 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h b/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h index 57ed3854f0be..2aac063eae32 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * Copyright (c) 2022 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -141,7 +141,6 @@ int img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver); int img_mgmt_find_by_ver(struct image_version *find, uint8_t *hash); int img_mgmt_state_read(struct smp_streamer *ctxt); int img_mgmt_state_write(struct smp_streamer *njb); -int img_mgmt_flash_area_id(int slot); #ifdef __cplusplus } diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index a006e2899750..6f7750c68a09 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -7,15 +7,13 @@ #include #include +#include #include -#include #include #include #include -#include - #include #include #include @@ -29,8 +27,6 @@ #include #endif -LOG_MODULE_DECLARE(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); - /* The value here sets how many "characteristics" that describe image is * encoded into a map per each image (like bootable flags, and so on). * This value is only used for zcbor to predict map size and map encoding @@ -269,53 +265,6 @@ img_mgmt_state_read(struct smp_streamer *ctxt) return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; } -int img_mgmt_set_boot_next(int slot, bool confirm) -{ - const struct flash_area *fa; - int area_id = img_mgmt_flash_area_id(slot); - int rc = 0; - bool active = (slot == img_mgmt_active_slot(img_mgmt_active_image())); - - if (active) { - confirm = true; - } else { - if (slot != 1 && - !(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 && slot == 3)) { - return MGMT_ERR_EINVAL; - } - } - - /* Confirm disallowed if a test is pending. */ - if (active && img_mgmt_state_any_pending()) { - return MGMT_ERR_EBADSTATE; - } - - if (flash_area_open(area_id, &fa) != 0) { - return MGMT_ERR_EUNKNOWN; - } - - rc = boot_set_next(fa, active, confirm); - if (rc != 0) { - /* Failed to set next slot for boot as desired */ - if (active) { - LOG_ERR("Failed to write confirmed flag: %d", rc); - } else { - LOG_ERR("Failed to write pending flag for slot %d: %d", slot, rc); - } - rc = MGMT_ERR_EUNKNOWN; - } - flash_area_close(fa); - -#if CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS - if (active) { - /* Confirm event is only sent for active slot */ - (void)mgmt_callback_notify(MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED, NULL, 0); - } -#endif - - return rc; -} - /** * Command handler: image state write */ @@ -367,7 +316,12 @@ img_mgmt_state_write(struct smp_streamer *ctxt) } } - rc = img_mgmt_set_boot_next(slot, confirm); + if (slot == img_mgmt_active_slot() && confirm) { + /* Confirm current setup. */ + rc = img_mgmt_state_confirm(); + } else { + rc = img_mgmt_state_set_pending(slot, confirm); + } if (rc != 0) { return rc; } diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c index 81bdf56dc9e8..c62ee53b4378 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/zephyr_img_mgmt.c @@ -152,7 +152,7 @@ static int img_mgmt_flash_check_empty(uint8_t fa_id) * image_2 and so on. The function treats slot numbers as absolute * slot number starting at 0. */ -int +static int img_mgmt_flash_area_id(int slot) { uint8_t fa_id; From 12e546bff7282626e97244c9835c17b3bd875d0c Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:35 +0200 Subject: [PATCH 322/528] Revert "[nrf fromlist] mgmt/mcumgr: Add img_mgmt_active_slot() and img_mgmt_active_image()" This reverts commit 045dc290b0116df9dcb7e715bf08075eb487e83c. Signed-off-by: Robert Lubos --- .../mgmt/mcumgr/grp/img_mgmt/img_mgmt.h | 20 +----- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 61 ++----------------- .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 28 +++++---- 3 files changed, 20 insertions(+), 89 deletions(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h index c3ab8bf6104b..a5acf784fb47 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * Copyright (c) 2022 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -143,24 +143,6 @@ int img_mgmt_my_version(struct image_version *ver); */ int img_mgmt_ver_str(const struct image_version *ver, char *dst); -/** - * @brief Get active, running application slot number for an image - * - * @param image image number to get active slot for. - * - * @return Non-negative slot number - */ -int img_mgmt_active_slot(int image); - -/** - * @brief Get active image number - * - * Gets 0 based number for running application. - * - * @return Non-negative image number. - */ -int img_mgmt_active_image(void); - /** * @brief Check if the image slot is in use. * diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 292d275ce958..526a03a80d3b 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * Copyright (c) 2022 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -23,6 +23,7 @@ #include #include +#include #include #include @@ -34,16 +35,6 @@ #include #endif -#define FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(label) \ - DT_SAME_NODE(DT_NODELABEL(label), DT_CHOSEN(zephyr_code_partition)) - -#if !(FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_partition) || \ - FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_ns_partition) || \ - FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot1_partition) || \ - FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot2_partition)) -#error "Unsupported chosen zephyr,code-partition for boot application." -#endif - LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); struct img_mgmt_state g_img_mgmt_state; @@ -87,31 +78,6 @@ img_mgmt_find_tlvs(int slot, size_t *start_off, size_t *end_off, return 0; } -int img_mgmt_active_slot(int image) -{ -#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 - if (image == 1) { - return 2; - } -#endif - /* Image 0 */ - if (FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot1_partition)) { - return 1; - } - return 0; -} - -int img_mgmt_active_image(void) -{ -#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 - if (!(FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_partition) || - FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot0_ns_partition) || - FIXED_PARTITION_IS_CHOSEN_CODE_PARTITION(slot1_partition))) { - return 1; - } -#endif - return 0; -} /* * Reads the version and build hash from the specified image slot. */ @@ -292,24 +258,6 @@ void img_mgmt_reset_upload(void) g_img_mgmt_state.area_id = -1; } -static int -img_mgmt_get_other_slot(void) -{ - int slot = img_mgmt_active_slot(img_mgmt_active_image()); - - switch (slot) { - case 1: - return 0; -#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER - case 2: - return 3; - case 3: - return 2; - } -#endif - return 1; -} - /** * Command handler: image erase */ @@ -321,7 +269,7 @@ img_mgmt_erase(struct smp_streamer *ctxt) zcbor_state_t *zsd = ctxt->reader->zs; zcbor_state_t *zse = ctxt->writer->zs; bool ok; - uint32_t slot = img_mgmt_get_other_slot(); + uint32_t slot = 1; size_t decoded = 0; struct zcbor_map_decode_key_val image_erase_decode[] = { @@ -672,8 +620,7 @@ img_mgmt_upload(struct smp_streamer *ctxt) int img_mgmt_my_version(struct image_version *ver) { - return img_mgmt_read_info(img_mgmt_active_slot(img_mgmt_active_image()), - ver, NULL, NULL); + return img_mgmt_read_info(IMG_MGMT_BOOT_CURR_SLOT, ver, NULL, NULL); } static const struct mgmt_handler img_mgmt_handlers[] = { diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index 6f7750c68a09..a5ef02196df1 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2018-2021 mcumgr authors - * Copyright (c) 2022-2023 Nordic Semiconductor ASA + * Copyright (c) 2022 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -55,8 +56,6 @@ img_mgmt_state_flags(int query_slot) { uint8_t flags; int swap_type; - int image = query_slot / 2; /* We support max 2 images for now */ - int active_slot = img_mgmt_active_slot(image); flags = 0; @@ -66,13 +65,14 @@ img_mgmt_state_flags(int query_slot) swap_type = img_mgmt_swap_type(query_slot); switch (swap_type) { case IMG_MGMT_SWAP_TYPE_NONE: - if (query_slot == active_slot) { + if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { flags |= IMG_MGMT_STATE_F_CONFIRMED; + flags |= IMG_MGMT_STATE_F_ACTIVE; } break; case IMG_MGMT_SWAP_TYPE_TEST: - if (query_slot == active_slot) { + if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { flags |= IMG_MGMT_STATE_F_CONFIRMED; } else { flags |= IMG_MGMT_STATE_F_PENDING; @@ -80,7 +80,7 @@ img_mgmt_state_flags(int query_slot) break; case IMG_MGMT_SWAP_TYPE_PERM: - if (query_slot == active_slot) { + if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { flags |= IMG_MGMT_STATE_F_CONFIRMED; } else { flags |= IMG_MGMT_STATE_F_PENDING | IMG_MGMT_STATE_F_PERMANENT; @@ -88,14 +88,17 @@ img_mgmt_state_flags(int query_slot) break; case IMG_MGMT_SWAP_TYPE_REVERT: - if (query_slot != active_slot) { + if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { + flags |= IMG_MGMT_STATE_F_ACTIVE; + } else { flags |= IMG_MGMT_STATE_F_CONFIRMED; } break; } - /* Only running application is active */ - if (image == img_mgmt_active_image() && query_slot == active_slot) { + /* Slot 0 is always active. */ + /* XXX: The slot 0 assumption only holds when running from flash. */ + if (query_slot == IMG_MGMT_BOOT_CURR_SLOT) { flags |= IMG_MGMT_STATE_F_ACTIVE; } @@ -121,10 +124,9 @@ int img_mgmt_slot_in_use(int slot) { uint8_t state_flags; - int active_slot = img_mgmt_active_slot(img_mgmt_active_image()); state_flags = img_mgmt_state_flags(slot); - return slot == active_slot || + return state_flags & IMG_MGMT_STATE_F_ACTIVE || state_flags & IMG_MGMT_STATE_F_CONFIRMED || state_flags & IMG_MGMT_STATE_F_PENDING; } @@ -295,7 +297,7 @@ img_mgmt_state_write(struct smp_streamer *ctxt) /* Determine which slot is being operated on. */ if (zhash.len == 0) { if (confirm) { - slot = img_mgmt_active_slot(img_mgmt_active_image()); + slot = IMG_MGMT_BOOT_CURR_SLOT; } else { /* A 'test' without a hash is invalid. */ return MGMT_ERR_EINVAL; @@ -316,7 +318,7 @@ img_mgmt_state_write(struct smp_streamer *ctxt) } } - if (slot == img_mgmt_active_slot() && confirm) { + if (slot == IMG_MGMT_BOOT_CURR_SLOT && confirm) { /* Confirm current setup. */ rc = img_mgmt_state_confirm(); } else { From 9997ea52d583bf1f4daea6a3edeaf0d1bde00642 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:35 +0200 Subject: [PATCH 323/528] Revert "[nrf fromtree] bluetooth: tester: Restore removed nrf5340_hci_rpmsg.conf" This reverts commit 9a894b9b04faa373d01ec6d743071a09909611b7. Signed-off-by: Robert Lubos --- tests/bluetooth/tester/nrf5340_hci_rpmsg.conf | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 tests/bluetooth/tester/nrf5340_hci_rpmsg.conf diff --git a/tests/bluetooth/tester/nrf5340_hci_rpmsg.conf b/tests/bluetooth/tester/nrf5340_hci_rpmsg.conf deleted file mode 100644 index 16d6d2ab402c..000000000000 --- a/tests/bluetooth/tester/nrf5340_hci_rpmsg.conf +++ /dev/null @@ -1,13 +0,0 @@ -# Those have to be the same as in the controller (hci_rpmsg) -CONFIG_BT_MAX_CONN=2 -CONFIG_BT_BUF_EVT_RX_COUNT=16 -CONFIG_BT_BUF_EVT_RX_SIZE=255 -CONFIG_BT_BUF_CMD_TX_SIZE=255 -CONFIG_BT_BUF_ACL_TX_SIZE=251 - -# L2CAP SDU/PDU TX MTU -CONFIG_BT_L2CAP_TX_MTU=247 - -# The minimum value for this is -# L2AP MPS + L2CAP header (4) -CONFIG_BT_BUF_ACL_RX_SIZE=255 From ec661557d8a4e57a800ec2fbcd7ffff38d9293ed Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:35 +0200 Subject: [PATCH 324/528] Revert "[nrf fromlist] Bluetooth: BAP: Guard bt_bap_stream_send with CONFIG_BT_AUDIO_TX" This reverts commit b5e62e59ac1cab9ee2854347479fb985f3856672. Signed-off-by: Robert Lubos --- subsys/bluetooth/audio/bap_stream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/audio/bap_stream.c b/subsys/bluetooth/audio/bap_stream.c index bdb8b3bff090..1f037bb6655c 100644 --- a/subsys/bluetooth/audio/bap_stream.c +++ b/subsys/bluetooth/audio/bap_stream.c @@ -134,7 +134,7 @@ int bt_bap_ep_get_info(const struct bt_bap_ep *ep, struct bt_bap_ep_info *info) return 0; } -#if defined(CONFIG_BT_AUDIO_TX) +#if defined(CONFIG_BT_BAP_UNICAST) || defined(CONFIG_BT_BAP_BROADCAST_SOURCE) enum bt_bap_ascs_reason bt_audio_verify_qos(const struct bt_codec_qos *qos) { if (qos->interval < BT_ISO_SDU_INTERVAL_MIN || @@ -192,7 +192,7 @@ int bt_bap_stream_send(struct bt_bap_stream *stream, struct net_buf *buf, return bt_iso_chan_send(bt_bap_stream_iso_chan_get(stream), buf, seq_num, ts); } -#endif /* CONFIG_BT_AUDIO_TX */ +#endif /* CONFIG_BT_BAP_UNICAST || CONFIG_BT_BAP_BROADCAST_SOURCE */ #if defined(CONFIG_BT_BAP_UNICAST) static bool bt_bap_stream_is_broadcast(const struct bt_bap_stream *stream) From 86f206e1cb36c855411c0ef6f9a49d6f26982e66 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:35 +0200 Subject: [PATCH 325/528] Revert "[nrf fromlist] Bluetooth: BAP: Fix missing guards of sent and recv in uni cli" This reverts commit 3370d8abe426c03b539b6a290accd2d8eb2acb7c. Signed-off-by: Robert Lubos --- subsys/bluetooth/audio/bap_unicast_client.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 5897afc5628e..3c5530fea6b9 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -207,7 +207,6 @@ static struct bt_bap_stream *audio_stream_by_ep_id(const struct bt_conn *conn, return NULL; } -#if defined(CONFIG_BT_AUDIO_RX) static void unicast_client_ep_iso_recv(struct bt_iso_chan *chan, const struct bt_iso_recv_info *info, struct net_buf *buf) { @@ -257,9 +256,7 @@ static void unicast_client_ep_iso_recv(struct bt_iso_chan *chan, LOG_WRN("No callback for recv set"); } } -#endif /* CONFIG_BT_AUDIO_RX */ -#if defined(CONFIG_BT_AUDIO_TX) static void unicast_client_ep_iso_sent(struct bt_iso_chan *chan) { struct bt_bap_iso *iso = CONTAINER_OF(chan, struct bt_bap_iso, chan); @@ -285,7 +282,6 @@ static void unicast_client_ep_iso_sent(struct bt_iso_chan *chan) stream->ops->sent(stream); } } -#endif /* CONFIG_BT_AUDIO_TX */ static void unicast_client_ep_iso_connected(struct bt_bap_ep *ep) { @@ -396,12 +392,8 @@ static void unicast_client_iso_disconnected(struct bt_iso_chan *chan, uint8_t re } static struct bt_iso_chan_ops unicast_client_iso_ops = { -#if defined(CONFIG_BT_AUDIO_RX) .recv = unicast_client_ep_iso_recv, -#endif /* CONFIG_BT_AUDIO_RX */ -#if defined(CONFIG_BT_AUDIO_TX) .sent = unicast_client_ep_iso_sent, -#endif /* CONFIG_BT_AUDIO_TX */ .connected = unicast_client_iso_connected, .disconnected = unicast_client_iso_disconnected, }; From ef8fc457979439a00a90763ae64db0b54bf45062 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:36 +0200 Subject: [PATCH 326/528] Revert "[nrf fromtree] modules: openthread: fix handling tx done when sleep to tx is supported" This reverts commit 0fed1a68a04ac2212b9a4b925f3fc22e7e6f7901. Signed-off-by: Robert Lubos --- modules/openthread/platform/radio.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index df3266b1274b..69a4e1f73211 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -529,8 +529,7 @@ void platformRadioProcess(otInstance *aInstance) if (is_pending_event_set(PENDING_EVENT_TX_DONE)) { reset_pending_event(PENDING_EVENT_TX_DONE); - if (sState == OT_RADIO_STATE_TRANSMIT || - radio_api->get_capabilities(radio_dev) & IEEE802154_HW_SLEEP_TO_TX) { + if (sState == OT_RADIO_STATE_TRANSMIT) { sState = OT_RADIO_STATE_RECEIVE; handle_tx_done(aInstance); } From b7b4c8a63c05a2e147bd2c90254d980ee0970a69 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:36 +0200 Subject: [PATCH 327/528] Revert "[nrf fromtree] modules: openthread: align received frame timestamp to SFD" This reverts commit 40010edf12eb94038090e7f3072b91f4beefd0c1. Signed-off-by: Robert Lubos --- include/zephyr/net/net_pkt.h | 5 +---- modules/openthread/platform/radio.c | 13 +++++-------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 5725aefbeb8f..893689523487 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -95,10 +95,7 @@ struct net_pkt { #endif #if defined(CONFIG_NET_PKT_TIMESTAMP) - /** - * Timestamp if available. - * For IEEE 802.15.4 packets this refers to the first symbol of the MAC Header. - */ + /** Timestamp if available. */ struct net_ptp_time timestamp; #endif diff --git a/modules/openthread/platform/radio.c b/modules/openthread/platform/radio.c index 69a4e1f73211..1c8b2896e8c5 100644 --- a/modules/openthread/platform/radio.c +++ b/modules/openthread/platform/radio.c @@ -38,8 +38,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_OPENTHREAD_L2_LOG_LEVEL); #define SHORT_ADDRESS_SIZE 2 -#define FCS_SIZE 2 -#define PHR_DURATION 32 +#define FCS_SIZE 2 #if defined(CONFIG_IEEE802154_2015) #define ACK_PKT_LENGTH 127 #else @@ -186,9 +185,8 @@ enum net_verdict ieee802154_radio_handle_ack(struct net_if *iface, #if defined(CONFIG_NET_PKT_TIMESTAMP) struct net_ptp_time *pkt_time = net_pkt_timestamp(pkt); - /* OpenThread expects the timestamp to point to the end of SFD */ - ack_frame.mInfo.mRxInfo.mTimestamp = pkt_time->second * USEC_PER_SEC + - pkt_time->nanosecond / NSEC_PER_USEC - PHR_DURATION; + ack_frame.mInfo.mRxInfo.mTimestamp = + pkt_time->second * USEC_PER_SEC + pkt_time->nanosecond / NSEC_PER_USEC; #endif return NET_OK; @@ -396,9 +394,8 @@ static void openthread_handle_received_frame(otInstance *instance, #if defined(CONFIG_NET_PKT_TIMESTAMP) struct net_ptp_time *pkt_time = net_pkt_timestamp(pkt); - /* OpenThread expects the timestamp to point to the end of SFD */ - recv_frame.mInfo.mRxInfo.mTimestamp = pkt_time->second * USEC_PER_SEC + - pkt_time->nanosecond / NSEC_PER_USEC - PHR_DURATION; + recv_frame.mInfo.mRxInfo.mTimestamp = + pkt_time->second * USEC_PER_SEC + pkt_time->nanosecond / NSEC_PER_USEC; #endif #if defined(CONFIG_IEEE802154_2015) From 2c5577bab110f8ab5563e52c55f2c452abb4f436 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:36 +0200 Subject: [PATCH 328/528] Revert "[nrf fromtree] apps: misc void main -> int main fixes" This reverts commit b1b412685610a94fc236d1100b1c4f437add7ecb. Signed-off-by: Robert Lubos --- samples/bluetooth/encrypted_advertising/central/src/main.c | 6 ++---- .../bluetooth/encrypted_advertising/peripheral/src/main.c | 5 ++--- samples/shields/npm1300_ek/src/main.c | 4 ++-- .../bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c | 3 +-- tests/drivers/build_all/i2c/src/main.c | 3 +-- 5 files changed, 8 insertions(+), 13 deletions(-) diff --git a/samples/bluetooth/encrypted_advertising/central/src/main.c b/samples/bluetooth/encrypted_advertising/central/src/main.c index 888940af780b..ecff673e9f64 100644 --- a/samples/bluetooth/encrypted_advertising/central/src/main.c +++ b/samples/bluetooth/encrypted_advertising/central/src/main.c @@ -103,18 +103,16 @@ static int setup_btn(void) return 0; } -int main(void) +void main(void) { int err; err = setup_btn(); if (err) { - return 0; + return; } LOG_DBG("Starting central sample..."); (void)run_central_sample(get_passkey_confirmation, NULL, 0, NULL); - - return 0; } diff --git a/samples/bluetooth/encrypted_advertising/peripheral/src/main.c b/samples/bluetooth/encrypted_advertising/peripheral/src/main.c index 6b269d30513b..86ca785accc8 100644 --- a/samples/bluetooth/encrypted_advertising/peripheral/src/main.c +++ b/samples/bluetooth/encrypted_advertising/peripheral/src/main.c @@ -97,17 +97,16 @@ static int setup_btn(void) return 0; } -int main(void) +void main(void) { int err; err = setup_btn(); if (err) { - return 0; + return; } LOG_DBG("Starting peripheral sample..."); (void)run_peripheral_sample(get_passkey_confirmation); - return 0; } diff --git a/samples/shields/npm1300_ek/src/main.c b/samples/shields/npm1300_ek/src/main.c index af7e6b92decc..b133a26aed77 100644 --- a/samples/shields/npm1300_ek/src/main.c +++ b/samples/shields/npm1300_ek/src/main.c @@ -37,13 +37,13 @@ void configure_ui(void) printk("Set up button at %s pin %d\n", button1.port->name, button1.pin); } -int main(void) +void main(void) { configure_ui(); if (!device_is_ready(regulators)) { printk("Error: Regulator device is not ready\n"); - return 0; + return; } while (1) { diff --git a/tests/bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c b/tests/bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c index 9abc66fcb5f9..445d1e8b3b41 100644 --- a/tests/bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c +++ b/tests/bsim/bluetooth/host/adv/encrypted/ead_sample/src/main.c @@ -149,8 +149,7 @@ struct bst_test_list *test_ead_sample_install(struct bst_test_list *tests) bst_test_install_t test_installers[] = {test_ead_sample_install, NULL}; -int main(void) +void main(void) { bst_main(); - return 0; } diff --git a/tests/drivers/build_all/i2c/src/main.c b/tests/drivers/build_all/i2c/src/main.c index d0d8b7b2b502..9620d82627e8 100644 --- a/tests/drivers/build_all/i2c/src/main.c +++ b/tests/drivers/build_all/i2c/src/main.c @@ -4,7 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -int main(void) +void main(void) { - return 0; } From 290c596113a964ab862f8395362b5c8a28e34381 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:36 +0200 Subject: [PATCH 329/528] Revert "[nrf noup] include: net: add NCS extensions" This reverts commit cf7645feef8bb6dac4b37a689146d0bab3741a4c. Signed-off-by: Robert Lubos --- include/zephyr/net/socket.h | 2 - include/zephyr/net/socket_ncs.h | 144 -------------------------------- 2 files changed, 146 deletions(-) delete mode 100644 include/zephyr/net/socket_ncs.h diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index 2d82039a47ab..1209bc0cc736 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -27,7 +27,6 @@ #include #include #include -#include #include #ifdef __cplusplus @@ -139,7 +138,6 @@ struct zsock_pollfd { */ #define TLS_DTLS_HANDSHAKE_TIMEOUT_MIN 8 #define TLS_DTLS_HANDSHAKE_TIMEOUT_MAX 9 - /** Socket option for preventing certificates from being copied to the mbedTLS * heap if possible. The option is only effective for DER certificates and is * ignored for PEM certificates. diff --git a/include/zephyr/net/socket_ncs.h b/include/zephyr/net/socket_ncs.h deleted file mode 100644 index 20502ffa550c..000000000000 --- a/include/zephyr/net/socket_ncs.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2021 Nordic Semiconductor - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ -#define ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ - -/** - * @file - * @brief NCS specific additions to the BSD sockets API definitions - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* When CONFIG_NET_SOCKETS_OFFLOAD is enabled, offloaded sockets take precedence - * when creating a new socket. Combine this flag with a socket type when - * creating a socket, to enforce native socket creation (e. g. SOCK_STREAM | SOCK_NATIVE). - * If it's desired to create a native TLS socket, but still offload the - * underlying TCP/UDP socket, use e. g. SOCK_STREAM | SOCK_NATIVE_TLS. - */ -#define SOCK_NATIVE 0x80000000 -#define SOCK_NATIVE_TLS 0x40000000 - -/* NCS specific TLS options */ - -/** Socket option to set DTLS handshake timeout, specifically for nRF sockets. - * The option accepts an integer, indicating the total handshake timeout, - * including retransmissions, in seconds. - * Accepted values for the option are: 1, 3, 7, 15, 31, 63, 123. - */ -#define TLS_DTLS_HANDSHAKE_TIMEO 14 - -/** Socket option to set and get DTLS CID setting, specifically for nRF sockets. - * The option accepts an integer, indicating the setting. - * Accepted vaules for the option are: 0, 1 and 2. - */ -#define TLS_DTLS_CID 17 - -/** Socket option to get DTLS CID status, specifically for nRF sockets. - * The option accepts an integer, indicating the setting. - * Accepted vaules for the option are: 0, 1, 2 and 3. - */ -#define TLS_DTLS_CID_STATUS 18 - -/** Socket option to save DTLS connection, specifically for nRF sockets. - */ -#define TLS_DTLS_CONN_SAVE 19 - -/** Socket option to load DTLS connection, specifically for nRF sockets. - */ -#define TLS_DTLS_CONN_LOAD 20 - -/** Socket option to get result of latest TLS/DTLS completed handshakes end status, - * specifically for nRF sockets. - * The option accepts an integer, indicating the setting. - * Accepted vaules for the option are: 0 and 1. - */ -#define TLS_DTLS_HANDSHAKE_STATUS 21 - -/* Valid values for TLS_SESSION_CACHE option */ -#define TLS_SESSION_CACHE_DISABLED 0 /**< Disable TLS session caching. */ -#define TLS_SESSION_CACHE_ENABLED 1 /**< Enable TLS session caching. */ - -/* Valid values for TLS_DTLS_HANDSHAKE_TIMEO option */ -#define TLS_DTLS_HANDSHAKE_TIMEO_NONE 0 /**< No timeout */ -#define TLS_DTLS_HANDSHAKE_TIMEO_1S 1 /**< 1 second */ -#define TLS_DTLS_HANDSHAKE_TIMEO_3S 3 /**< 1s + 2s */ -#define TLS_DTLS_HANDSHAKE_TIMEO_7S 7 /**< 1s + 2s + 4s */ -#define TLS_DTLS_HANDSHAKE_TIMEO_15S 15 /**< 1s + 2s + 4s + 8s */ -#define TLS_DTLS_HANDSHAKE_TIMEO_31S 31 /**< 1s + 2s + 4s + 8s + 16s */ -#define TLS_DTLS_HANDSHAKE_TIMEO_63S 63 /**< 1s + 2s + 4s + 8s + 16s + 32s */ -#define TLS_DTLS_HANDSHAKE_TIMEO_123S 123 /**< 1s + 2s + 4s + 8s + 16s + 32s + 60s */ - -/* Valid values for TLS_DTLS_CID option */ -#define TLS_DTLS_CID_DISABLED 0 -#define TLS_DTLS_CID_SUPPORTED 1 -#define TLS_DTLS_CID_ENABLED 2 - -/* Valid values for TLS_DTLS_CID_STATUS option */ -#define TLS_DTLS_CID_STATUS_DISABLED 0 -#define TLS_DTLS_CID_STATUS_DOWNLINK 1 -#define TLS_DTLS_CID_STATUS_UPLINK 2 -#define TLS_DTLS_CID_STATUS_BIDIRECTIONAL 3 - -/* Valid values for TLS_DTLS_HANDSHAKE_STATUS option */ -#define TLS_DTLS_HANDSHAKE_STATUS_FULL 0 -#define TLS_DTLS_HANDSHAKE_STATUS_CACHED 1 - -/* NCS specific socket options */ - -/** sockopt: disable all replies to unexpected traffics */ -#define SO_SILENCE_ALL 30 -/** sockopt: disable IPv4 ICMP replies */ -#define SO_IP_ECHO_REPLY 31 -/** sockopt: disable IPv6 ICMP replies */ -#define SO_IPV6_ECHO_REPLY 32 -/** sockopt: Release Assistance Indication feature: This will indicate that the - * application will not send any more data. - */ -#define SO_RAI_NO_DATA 50 -/** sockopt: Release Assistance Indication feature: This will indicate that the - * next call to send/sendto will be the last one for some time. - */ -#define SO_RAI_LAST 51 -/** sockopt: Release Assistance Indication feature: This will indicate that - * after the next call to send/sendto, the application is expecting to receive - * one more data packet before this socket will not be used again for some time. - */ -#define SO_RAI_ONE_RESP 52 -/** sockopt: Release Assistance Indication feature: If a client application - * expects to use the socket more it can indicate that by setting this socket - * option before the next send call which will keep the network up longer. - */ -#define SO_RAI_ONGOING 53 -/** sockopt: Release Assistance Indication feature: If a server application - * expects to use the socket more it can indicate that by setting this socket - * option before the next send call. - */ -#define SO_RAI_WAIT_MORE 54 -/** sockopt: Configurable TCP server session timeout in minutes. - * Range is 0 to 135. 0 is no timeout and 135 is 2 h 15 min. Default is 0 (no timeout). - */ -#define SO_TCP_SRV_SESSTIMEO 55 - -/* NCS specific gettaddrinfo() flags */ - -/** Assume `service` contains a Packet Data Network (PDN) ID. - * When specified together with the AI_NUMERICSERV flag, - * `service` shall be formatted as follows: "port:pdn_id" - * where "port" is the port number and "pdn_id" is the PDN ID. - * Example: "8080:1", port 8080 PDN ID 1. - * Example: "42:0", port 42 PDN ID 0. - */ -#define AI_PDNSERV 0x1000 - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ */ From a7366ca86089772bcf699ed95fb73ac8a5abcd96 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 28 Jun 2023 10:32:36 +0200 Subject: [PATCH 330/528] Revert "[nrf noup] tree-wide: support NCS Partition Manager (PM) definitions" This reverts commit 68110ee5a75167e8e2c65746211571315618a3e1. Signed-off-by: Robert Lubos --- cmake/modules/kernel.cmake | 4 -- drivers/flash/soc_flash_nrf.c | 11 ----- .../arm/aarch32/cortex_m/scripts/linker.ld | 46 ------------------- include/zephyr/storage/flash_map.h | 6 --- soc/arm/common/cortex_m/arm_mpu_regions.c | 13 ------ subsys/fs/littlefs_fs.c | 7 +-- subsys/ipc/rpmsg_service/rpmsg_backend.h | 27 ----------- 7 files changed, 1 insertion(+), 113 deletions(-) diff --git a/cmake/modules/kernel.cmake b/cmake/modules/kernel.cmake index 28ee922d40b0..7e65c9cd186d 100644 --- a/cmake/modules/kernel.cmake +++ b/cmake/modules/kernel.cmake @@ -242,7 +242,3 @@ if("${CMAKE_EXTRA_GENERATOR}" STREQUAL "Eclipse CDT4") include(${ZEPHYR_BASE}/cmake/ide/eclipse_cdt4_generator_amendment.cmake) eclipse_cdt4_generator_amendment(1) endif() - -if(ZEPHYR_NRF_MODULE_DIR) - include(${ZEPHYR_NRF_MODULE_DIR}/cmake/partition_manager.cmake) -endif() diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index e170b507c7a7..e7f5fb27bafc 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -37,11 +37,6 @@ LOG_MODULE_REGISTER(flash_nrf); #define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) -#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER -#include -#include -#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER */ - #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE #define FLASH_SLOT_WRITE 7500 #if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE) @@ -142,12 +137,6 @@ static int flash_nrf_read(const struct device *dev, off_t addr, return 0; } -#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER && PM_APP_ADDRESS - if (addr < PM_APP_ADDRESS) { - return soc_secure_mem_read(data, (void *)addr, len); - } -#endif - memcpy(data, (void *)addr, len); return 0; diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld index 56c5271462f1..567e213fe6d1 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld @@ -26,35 +26,6 @@ #endif #define RAMABLE_REGION RAM -#if USE_PARTITION_MANAGER - -#include - -#if CONFIG_NCS_IS_VARIANT_IMAGE && defined(PM_S0_ID) -/* We are linking against S1, create symbol containing the flash ID of S0. - * This is used when writing code operating on the "other" slot. - */ -_image_1_primary_slot_id = PM_S0_ID; - -#else /* ! CONFIG_NCS_IS_VARIANT_IMAGE */ - -#ifdef PM_S1_ID -/* We are linking against S0, create symbol containing the flash ID of S1. - * This is used when writing code operating on the "other" slot. - */ -_image_1_primary_slot_id = PM_S1_ID; -#endif /* PM_S1_ID */ - -#endif /* CONFIG_NCS_IS_VARIANT_IMAGE */ - -#define ROM_ADDR PM_ADDRESS -#define ROM_SIZE PM_SIZE - -#define RAM_SIZE PM_SRAM_SIZE -#define RAM_ADDR PM_SRAM_ADDRESS - -#else /* ! USE_PARTITION_MANAGER */ - #if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0) #define ROM_ADDR RAM_ADDR #else @@ -81,23 +52,6 @@ _image_1_primary_slot_id = PM_S1_ID; #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS #endif -#endif /* USE_PARTITION_MANAGER */ - -#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ccm), okay) -#define CCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ccm)) -#define CCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ccm)) -#endif - -#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) -#define ITCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_itcm)) -#define ITCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_itcm)) -#endif - -#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) -#define DTCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm)) -#define DTCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm)) -#endif - #if defined(CONFIG_CUSTOM_SECTION_ALIGN) _region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE; #else diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index 2bda4a8d980d..e07305cddaa6 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -255,10 +255,6 @@ const struct device *flash_area_get_device(const struct flash_area *fa); */ uint8_t flash_area_erased_val(const struct flash_area *fa); -#if USE_PARTITION_MANAGER -#include -#else - #define FLASH_AREA_LABEL_EXISTS(label) __DEPRECATED_MACRO \ DT_HAS_FIXED_PARTITION_LABEL(label) @@ -331,8 +327,6 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #define FIXED_PARTITION_DEVICE(label) \ DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))) -#endif /* USE_PARTITION_MANAGER */ - #ifdef __cplusplus } #endif diff --git a/soc/arm/common/cortex_m/arm_mpu_regions.c b/soc/arm/common/cortex_m/arm_mpu_regions.c index d44c2ee05b3d..477dc30566c7 100644 --- a/soc/arm/common/cortex_m/arm_mpu_regions.c +++ b/soc/arm/common/cortex_m/arm_mpu_regions.c @@ -9,9 +9,6 @@ #include #include "arm_mpu_mem_cfg.h" -#if USE_PARTITION_MANAGER -#include -#endif static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ @@ -25,14 +22,6 @@ static const struct arm_mpu_region mpu_regions[] = { #endif /* Region 1 */ MPU_REGION_ENTRY("SRAM_0", -#if USE_PARTITION_MANAGER - PM_SRAM_ADDRESS, -#if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) - REGION_RAM_ATTR(PM_SRAM_ADDRESS, PM_SRAM_SIZE)), -#else - REGION_RAM_ATTR(REGION_SRAM_SIZE)), -#endif -#else CONFIG_SRAM_BASE_ADDRESS, #if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) REGION_RAM_ATTR(CONFIG_SRAM_BASE_ADDRESS, \ @@ -41,8 +30,6 @@ static const struct arm_mpu_region mpu_regions[] = { REGION_RAM_ATTR(REGION_SRAM_SIZE)), #endif -#endif /* USE_PARTITION_MANAGER */ - /* DT-defined regions */ LINKER_DT_REGION_MPU(ARM_MPU_REGION_INIT) }; diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c index ff190c74edb8..2a4915b4d1cb 100644 --- a/subsys/fs/littlefs_fs.c +++ b/subsys/fs/littlefs_fs.c @@ -1009,12 +1009,7 @@ struct fs_mount_t FS_FSTAB_ENTRY(DT_DRV_INST(inst)) = { \ .type = FS_LITTLEFS, \ .mnt_point = DT_INST_PROP(inst, mount_point), \ .fs_data = &fs_data_##inst, \ - .storage_dev = (void *) \ - COND_CODE_1(USE_PARTITION_MANAGER, \ - (COND_CODE_1(FIXED_PARTITION_EXISTS(littlefs_storage), \ - (FIXED_PARTITION_ID(littlefs_storage)), \ - (FIXED_PARTITION_ID(storage)))), \ - (DT_FIXED_PARTITION_ID(FS_PARTITION(inst)))), \ + .storage_dev = (void *)DT_FIXED_PARTITION_ID(FS_PARTITION(inst)), \ .flags = FSTAB_ENTRY_DT_MOUNT_FLAGS(DT_DRV_INST(inst)), \ }; diff --git a/subsys/ipc/rpmsg_service/rpmsg_backend.h b/subsys/ipc/rpmsg_service/rpmsg_backend.h index 9996e1d74d9b..a74e46b85207 100644 --- a/subsys/ipc/rpmsg_service/rpmsg_backend.h +++ b/subsys/ipc/rpmsg_service/rpmsg_backend.h @@ -13,35 +13,8 @@ extern "C" { #endif -#if CONFIG_PARTITION_MANAGER_ENABLED - -#include "pm_config.h" - -#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) - -#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) -#define VDEV_START_ADDR PM_RPMSG_NRF53_SRAM_ADDRESS -#define VDEV_SIZE PM_RPMSG_NRF53_SRAM_SIZE -#else -/* The current image is a child image in a different domain than the image - * which defined the required values. To reach the values of the parent domain - * we use the 'PM__' variant of the define. - */ -#define VDEV_START_ADDR PM__RPMSG_NRF53_SRAM_ADDRESS -#define VDEV_SIZE PM__RPMSG_NRF53_SRAM_SIZE -#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) */ - -#else #define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) #define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) -#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) */ - -#else - -#define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) -#define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) - -#endif /* CONFIG_PARTITION_MANAGER_ENABLED */ #define VDEV_STATUS_ADDR VDEV_START_ADDR #define VDEV_STATUS_SIZE 0x400 From 12d1ebfb98a4f89dc018af4e7872382222b3b74a Mon Sep 17 00:00:00 2001 From: Sigvart Hovland Date: Fri, 3 May 2019 14:21:52 +0200 Subject: [PATCH 331/528] [nrf noup] tree-wide: support NCS Partition Manager (PM) definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Partition Manager (PM) is a component of the nRF Connect SDK (NCS) which uses yaml files to resolve flash partition placement with a holistic view of the entire device, including each firmware image present on the flash device, and various subsystems, such as settings and NFFS. When this NCS extension is used, various source files which would use partition information from devicetree in "vanilla" zephyr instead use defines generated by PM instead. This commit removes support for HEX_FILES_TO_MERGE, as it conflicts with PM. The settings subsystem pm.yml defines a partition 'settings_storage'. The nffs subsystem pm.yml defines 'nffs_storage'. Leverage label translation to avoid patching partition names. Refer to the NCS documentation page for this feature for more details. This is a long-running out of tree patch which has been worked on by several people. The following sign-offs are in alphabetical order by first name. Signed-off-by: Andrzej Głąbek Signed-off-by: Andrzej Puzdrowski Signed-off-by: Dominik Ermel Signed-off-by: Håkon Øye Amundsen Signed-off-by: Ioannis Glaropoulos Signed-off-by: Joakim Andersson Signed-off-by: Johann Fischer Signed-off-by: Martí Bolívar Signed-off-by: Ole Sæther Signed-off-by: Robert Lubos Signed-off-by: Sebastian Bøe Signed-off-by: Sigvart Hovland Signed-off-by: Thomas Stenersen Signed-off-by: Torsten Rasmussen Signed-off-by: Øyvind Rønningstad Signed-off-by: Trond Einar Snekvik Signed-off-by: Gerard Marull-Paretas Signed-off-by: Tomasz Moń (cherry picked from commit ba54fe88dcfe3b25aca4c02f01e47f232b0f8bf7) (cherry picked from commit 68110ee5a75167e8e2c65746211571315618a3e1) Signed-off-by: Dominik Ermel --- cmake/modules/kernel.cmake | 4 ++ drivers/flash/soc_flash_nrf.c | 11 +++++ .../arm/aarch32/cortex_m/scripts/linker.ld | 46 +++++++++++++++++++ include/zephyr/storage/flash_map.h | 6 +++ soc/arm/common/cortex_m/arm_mpu_regions.c | 13 ++++++ subsys/fs/littlefs_fs.c | 7 ++- subsys/ipc/rpmsg_service/rpmsg_backend.h | 27 +++++++++++ 7 files changed, 113 insertions(+), 1 deletion(-) diff --git a/cmake/modules/kernel.cmake b/cmake/modules/kernel.cmake index 7e65c9cd186d..28ee922d40b0 100644 --- a/cmake/modules/kernel.cmake +++ b/cmake/modules/kernel.cmake @@ -242,3 +242,7 @@ if("${CMAKE_EXTRA_GENERATOR}" STREQUAL "Eclipse CDT4") include(${ZEPHYR_BASE}/cmake/ide/eclipse_cdt4_generator_amendment.cmake) eclipse_cdt4_generator_amendment(1) endif() + +if(ZEPHYR_NRF_MODULE_DIR) + include(${ZEPHYR_NRF_MODULE_DIR}/cmake/partition_manager.cmake) +endif() diff --git a/drivers/flash/soc_flash_nrf.c b/drivers/flash/soc_flash_nrf.c index fa433d1044b9..f38492a41d1d 100644 --- a/drivers/flash/soc_flash_nrf.c +++ b/drivers/flash/soc_flash_nrf.c @@ -37,6 +37,11 @@ LOG_MODULE_REGISTER(flash_nrf); #define SOC_NV_FLASH_NODE DT_INST(0, soc_nv_flash) +#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER +#include +#include +#endif /* CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER */ + #ifndef CONFIG_SOC_FLASH_NRF_RADIO_SYNC_NONE #define FLASH_SLOT_WRITE 7500 #if defined(CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE) @@ -137,6 +142,12 @@ static int flash_nrf_read(const struct device *dev, off_t addr, return 0; } +#if CONFIG_TRUSTED_EXECUTION_NONSECURE && USE_PARTITION_MANAGER && PM_APP_ADDRESS + if (addr < PM_APP_ADDRESS) { + return soc_secure_mem_read(data, (void *)addr, len); + } +#endif + nrf_nvmc_buffer_read(data, (uint32_t)addr, len); return 0; diff --git a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld index 567e213fe6d1..56c5271462f1 100644 --- a/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld +++ b/include/zephyr/arch/arm/aarch32/cortex_m/scripts/linker.ld @@ -26,6 +26,35 @@ #endif #define RAMABLE_REGION RAM +#if USE_PARTITION_MANAGER + +#include + +#if CONFIG_NCS_IS_VARIANT_IMAGE && defined(PM_S0_ID) +/* We are linking against S1, create symbol containing the flash ID of S0. + * This is used when writing code operating on the "other" slot. + */ +_image_1_primary_slot_id = PM_S0_ID; + +#else /* ! CONFIG_NCS_IS_VARIANT_IMAGE */ + +#ifdef PM_S1_ID +/* We are linking against S0, create symbol containing the flash ID of S1. + * This is used when writing code operating on the "other" slot. + */ +_image_1_primary_slot_id = PM_S1_ID; +#endif /* PM_S1_ID */ + +#endif /* CONFIG_NCS_IS_VARIANT_IMAGE */ + +#define ROM_ADDR PM_ADDRESS +#define ROM_SIZE PM_SIZE + +#define RAM_SIZE PM_SRAM_SIZE +#define RAM_ADDR PM_SRAM_ADDRESS + +#else /* ! USE_PARTITION_MANAGER */ + #if !defined(CONFIG_XIP) && (CONFIG_FLASH_SIZE == 0) #define ROM_ADDR RAM_ADDR #else @@ -52,6 +81,23 @@ #define RAM_ADDR CONFIG_SRAM_BASE_ADDRESS #endif +#endif /* USE_PARTITION_MANAGER */ + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_ccm), okay) +#define CCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ccm)) +#define CCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ccm)) +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_itcm), okay) +#define ITCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_itcm)) +#define ITCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_itcm)) +#endif + +#if DT_NODE_HAS_STATUS(DT_CHOSEN(zephyr_dtcm), okay) +#define DTCM_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_dtcm)) +#define DTCM_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_dtcm)) +#endif + #if defined(CONFIG_CUSTOM_SECTION_ALIGN) _region_min_align = CONFIG_CUSTOM_SECTION_MIN_ALIGN_SIZE; #else diff --git a/include/zephyr/storage/flash_map.h b/include/zephyr/storage/flash_map.h index 380e58691e9a..cc4a246105d3 100644 --- a/include/zephyr/storage/flash_map.h +++ b/include/zephyr/storage/flash_map.h @@ -271,6 +271,10 @@ const char *flash_area_label(const struct flash_area *fa); */ uint8_t flash_area_erased_val(const struct flash_area *fa); +#if USE_PARTITION_MANAGER +#include +#else + #define FLASH_AREA_LABEL_EXISTS(label) __DEPRECATED_MACRO \ DT_HAS_FIXED_PARTITION_LABEL(label) @@ -343,6 +347,8 @@ uint8_t flash_area_erased_val(const struct flash_area *fa); #define FIXED_PARTITION_DEVICE(label) \ DEVICE_DT_GET(DT_MTD_FROM_FIXED_PARTITION(DT_NODELABEL(label))) +#endif /* USE_PARTITION_MANAGER */ + #ifdef __cplusplus } #endif diff --git a/soc/arm/common/cortex_m/arm_mpu_regions.c b/soc/arm/common/cortex_m/arm_mpu_regions.c index 477dc30566c7..d44c2ee05b3d 100644 --- a/soc/arm/common/cortex_m/arm_mpu_regions.c +++ b/soc/arm/common/cortex_m/arm_mpu_regions.c @@ -9,6 +9,9 @@ #include #include "arm_mpu_mem_cfg.h" +#if USE_PARTITION_MANAGER +#include +#endif static const struct arm_mpu_region mpu_regions[] = { /* Region 0 */ @@ -22,6 +25,14 @@ static const struct arm_mpu_region mpu_regions[] = { #endif /* Region 1 */ MPU_REGION_ENTRY("SRAM_0", +#if USE_PARTITION_MANAGER + PM_SRAM_ADDRESS, +#if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) + REGION_RAM_ATTR(PM_SRAM_ADDRESS, PM_SRAM_SIZE)), +#else + REGION_RAM_ATTR(REGION_SRAM_SIZE)), +#endif +#else CONFIG_SRAM_BASE_ADDRESS, #if defined(CONFIG_ARMV8_M_BASELINE) || defined(CONFIG_ARMV8_M_MAINLINE) REGION_RAM_ATTR(CONFIG_SRAM_BASE_ADDRESS, \ @@ -30,6 +41,8 @@ static const struct arm_mpu_region mpu_regions[] = { REGION_RAM_ATTR(REGION_SRAM_SIZE)), #endif +#endif /* USE_PARTITION_MANAGER */ + /* DT-defined regions */ LINKER_DT_REGION_MPU(ARM_MPU_REGION_INIT) }; diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c index 4e57a4b17803..12fb790c3d65 100644 --- a/subsys/fs/littlefs_fs.c +++ b/subsys/fs/littlefs_fs.c @@ -1054,7 +1054,12 @@ struct fs_mount_t FS_FSTAB_ENTRY(DT_DRV_INST(inst)) = { \ .type = FS_LITTLEFS, \ .mnt_point = DT_INST_PROP(inst, mount_point), \ .fs_data = &fs_data_##inst, \ - .storage_dev = (void *)DT_FIXED_PARTITION_ID(FS_PARTITION(inst)), \ + .storage_dev = (void *) \ + COND_CODE_1(USE_PARTITION_MANAGER, \ + (COND_CODE_1(FIXED_PARTITION_EXISTS(littlefs_storage), \ + (FIXED_PARTITION_ID(littlefs_storage)), \ + (FIXED_PARTITION_ID(storage)))), \ + (DT_FIXED_PARTITION_ID(FS_PARTITION(inst)))), \ .flags = FSTAB_ENTRY_DT_MOUNT_FLAGS(DT_DRV_INST(inst)), \ }; diff --git a/subsys/ipc/rpmsg_service/rpmsg_backend.h b/subsys/ipc/rpmsg_service/rpmsg_backend.h index a74e46b85207..9996e1d74d9b 100644 --- a/subsys/ipc/rpmsg_service/rpmsg_backend.h +++ b/subsys/ipc/rpmsg_service/rpmsg_backend.h @@ -13,8 +13,35 @@ extern "C" { #endif +#if CONFIG_PARTITION_MANAGER_ENABLED + +#include "pm_config.h" + +#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) + +#if defined(PM_RPMSG_NRF53_SRAM_ADDRESS) +#define VDEV_START_ADDR PM_RPMSG_NRF53_SRAM_ADDRESS +#define VDEV_SIZE PM_RPMSG_NRF53_SRAM_SIZE +#else +/* The current image is a child image in a different domain than the image + * which defined the required values. To reach the values of the parent domain + * we use the 'PM__' variant of the define. + */ +#define VDEV_START_ADDR PM__RPMSG_NRF53_SRAM_ADDRESS +#define VDEV_SIZE PM__RPMSG_NRF53_SRAM_SIZE +#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) */ + +#else #define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) #define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) +#endif /* defined(PM_RPMSG_NRF53_SRAM_ADDRESS) || defined(PM__RPMSG_NRF53_SRAM_ADDRESS) */ + +#else + +#define VDEV_START_ADDR DT_REG_ADDR(DT_CHOSEN(zephyr_ipc_shm)) +#define VDEV_SIZE DT_REG_SIZE(DT_CHOSEN(zephyr_ipc_shm)) + +#endif /* CONFIG_PARTITION_MANAGER_ENABLED */ #define VDEV_STATUS_ADDR VDEV_START_ADDR #define VDEV_STATUS_SIZE 0x400 From 46c99f885eda4b186366e10014c54409208c6679 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 1 Oct 2018 10:27:32 +0200 Subject: [PATCH 332/528] [nrf noup] include: net: add NCS extensions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add some socket options and address family extensions to Zephyr headers, which will be useful for nRF Connect SDK. Add secure socket options: * Add CID socket options to NCS specific options. * Add TLS/DTLS tls ciphersuite chosen socket option to NCS specific options. * Add TLS/DTLS connection save/load socket options to NCS specific options. * Add TLS/DTLS handshake status socket option to NCS specific options. The "author" of this commit is a contact person; various people with s-o-b lines following here have contributed to the maintenance of this patch. Signed-off-by: Andreas Moltumyr Signed-off-by: Andrzej Głąbek Signed-off-by: Christopher Métrailler Signed-off-by: Dominik Ermel Signed-off-by: Emanuele Di Santo Signed-off-by: Glenn Ruben Bakke Signed-off-by: Håkon Alseth Signed-off-by: Ioannis Glaropoulos Signed-off-by: Jan Tore Guggedal Signed-off-by: Joakim Andersson Signed-off-by: Martí Bolívar Signed-off-by: Mirko Covizzi Signed-off-by: Petri Honkala Signed-off-by: Robert Lubos Signed-off-by: Tommi Mammela Signed-off-by: Trond Einar Snekvik Signed-off-by: Torsten Rasmussen Signed-off-by: Eivind Jølsgard Signed-off-by: Emanuele Di Santo (cherry picked from commit 11a73e1d2d9ce98d8610281c9b00da688dc31802) (cherry picked from commit 1fbee9f184e0047bc98fe96629dcafe45de5ab09) (cherry picked from commit cf7645feef8bb6dac4b37a689146d0bab3741a4c) Signed-off-by: Dominik Ermel --- include/zephyr/net/socket.h | 2 + include/zephyr/net/socket_ncs.h | 144 ++++++++++++++++++++++++++++++++ 2 files changed, 146 insertions(+) create mode 100644 include/zephyr/net/socket_ncs.h diff --git a/include/zephyr/net/socket.h b/include/zephyr/net/socket.h index 5a28e42ca3b3..18fbdf108c53 100644 --- a/include/zephyr/net/socket.h +++ b/include/zephyr/net/socket.h @@ -28,6 +28,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -139,6 +140,7 @@ struct zsock_pollfd { */ #define TLS_DTLS_HANDSHAKE_TIMEOUT_MIN 8 #define TLS_DTLS_HANDSHAKE_TIMEOUT_MAX 9 + /** Socket option for preventing certificates from being copied to the mbedTLS * heap if possible. The option is only effective for DER certificates and is * ignored for PEM certificates. diff --git a/include/zephyr/net/socket_ncs.h b/include/zephyr/net/socket_ncs.h new file mode 100644 index 000000000000..20502ffa550c --- /dev/null +++ b/include/zephyr/net/socket_ncs.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ +#define ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ + +/** + * @file + * @brief NCS specific additions to the BSD sockets API definitions + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* When CONFIG_NET_SOCKETS_OFFLOAD is enabled, offloaded sockets take precedence + * when creating a new socket. Combine this flag with a socket type when + * creating a socket, to enforce native socket creation (e. g. SOCK_STREAM | SOCK_NATIVE). + * If it's desired to create a native TLS socket, but still offload the + * underlying TCP/UDP socket, use e. g. SOCK_STREAM | SOCK_NATIVE_TLS. + */ +#define SOCK_NATIVE 0x80000000 +#define SOCK_NATIVE_TLS 0x40000000 + +/* NCS specific TLS options */ + +/** Socket option to set DTLS handshake timeout, specifically for nRF sockets. + * The option accepts an integer, indicating the total handshake timeout, + * including retransmissions, in seconds. + * Accepted values for the option are: 1, 3, 7, 15, 31, 63, 123. + */ +#define TLS_DTLS_HANDSHAKE_TIMEO 14 + +/** Socket option to set and get DTLS CID setting, specifically for nRF sockets. + * The option accepts an integer, indicating the setting. + * Accepted vaules for the option are: 0, 1 and 2. + */ +#define TLS_DTLS_CID 17 + +/** Socket option to get DTLS CID status, specifically for nRF sockets. + * The option accepts an integer, indicating the setting. + * Accepted vaules for the option are: 0, 1, 2 and 3. + */ +#define TLS_DTLS_CID_STATUS 18 + +/** Socket option to save DTLS connection, specifically for nRF sockets. + */ +#define TLS_DTLS_CONN_SAVE 19 + +/** Socket option to load DTLS connection, specifically for nRF sockets. + */ +#define TLS_DTLS_CONN_LOAD 20 + +/** Socket option to get result of latest TLS/DTLS completed handshakes end status, + * specifically for nRF sockets. + * The option accepts an integer, indicating the setting. + * Accepted vaules for the option are: 0 and 1. + */ +#define TLS_DTLS_HANDSHAKE_STATUS 21 + +/* Valid values for TLS_SESSION_CACHE option */ +#define TLS_SESSION_CACHE_DISABLED 0 /**< Disable TLS session caching. */ +#define TLS_SESSION_CACHE_ENABLED 1 /**< Enable TLS session caching. */ + +/* Valid values for TLS_DTLS_HANDSHAKE_TIMEO option */ +#define TLS_DTLS_HANDSHAKE_TIMEO_NONE 0 /**< No timeout */ +#define TLS_DTLS_HANDSHAKE_TIMEO_1S 1 /**< 1 second */ +#define TLS_DTLS_HANDSHAKE_TIMEO_3S 3 /**< 1s + 2s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_7S 7 /**< 1s + 2s + 4s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_15S 15 /**< 1s + 2s + 4s + 8s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_31S 31 /**< 1s + 2s + 4s + 8s + 16s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_63S 63 /**< 1s + 2s + 4s + 8s + 16s + 32s */ +#define TLS_DTLS_HANDSHAKE_TIMEO_123S 123 /**< 1s + 2s + 4s + 8s + 16s + 32s + 60s */ + +/* Valid values for TLS_DTLS_CID option */ +#define TLS_DTLS_CID_DISABLED 0 +#define TLS_DTLS_CID_SUPPORTED 1 +#define TLS_DTLS_CID_ENABLED 2 + +/* Valid values for TLS_DTLS_CID_STATUS option */ +#define TLS_DTLS_CID_STATUS_DISABLED 0 +#define TLS_DTLS_CID_STATUS_DOWNLINK 1 +#define TLS_DTLS_CID_STATUS_UPLINK 2 +#define TLS_DTLS_CID_STATUS_BIDIRECTIONAL 3 + +/* Valid values for TLS_DTLS_HANDSHAKE_STATUS option */ +#define TLS_DTLS_HANDSHAKE_STATUS_FULL 0 +#define TLS_DTLS_HANDSHAKE_STATUS_CACHED 1 + +/* NCS specific socket options */ + +/** sockopt: disable all replies to unexpected traffics */ +#define SO_SILENCE_ALL 30 +/** sockopt: disable IPv4 ICMP replies */ +#define SO_IP_ECHO_REPLY 31 +/** sockopt: disable IPv6 ICMP replies */ +#define SO_IPV6_ECHO_REPLY 32 +/** sockopt: Release Assistance Indication feature: This will indicate that the + * application will not send any more data. + */ +#define SO_RAI_NO_DATA 50 +/** sockopt: Release Assistance Indication feature: This will indicate that the + * next call to send/sendto will be the last one for some time. + */ +#define SO_RAI_LAST 51 +/** sockopt: Release Assistance Indication feature: This will indicate that + * after the next call to send/sendto, the application is expecting to receive + * one more data packet before this socket will not be used again for some time. + */ +#define SO_RAI_ONE_RESP 52 +/** sockopt: Release Assistance Indication feature: If a client application + * expects to use the socket more it can indicate that by setting this socket + * option before the next send call which will keep the network up longer. + */ +#define SO_RAI_ONGOING 53 +/** sockopt: Release Assistance Indication feature: If a server application + * expects to use the socket more it can indicate that by setting this socket + * option before the next send call. + */ +#define SO_RAI_WAIT_MORE 54 +/** sockopt: Configurable TCP server session timeout in minutes. + * Range is 0 to 135. 0 is no timeout and 135 is 2 h 15 min. Default is 0 (no timeout). + */ +#define SO_TCP_SRV_SESSTIMEO 55 + +/* NCS specific gettaddrinfo() flags */ + +/** Assume `service` contains a Packet Data Network (PDN) ID. + * When specified together with the AI_NUMERICSERV flag, + * `service` shall be formatted as follows: "port:pdn_id" + * where "port" is the port number and "pdn_id" is the PDN ID. + * Example: "8080:1", port 8080 PDN ID 1. + * Example: "42:0", port 42 PDN ID 0. + */ +#define AI_PDNSERV 0x1000 + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_NET_SOCKET_NCS_H_ */ From 76ad781c59d359eb4e100440c9ce558f188822ca Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Fri, 5 May 2023 11:12:26 +0200 Subject: [PATCH 333/528] [nrf noup] mcumgr: img_mgmt: Fix check for chosen code partition The "zephyr-code-partition" chosen DTS node cannot be used when build uses Partition Manager. In that case, mcumgr must rely on the definitions provided by the Partition Manager. Jira: NCSDK-21381 Signed-off-by: Marek Pieta (cherry picked from commit 394faafd215eaa2405f58f6aa7793afcc62b6e99) (cherry picked from commit 36961d6b72f53b9ff0eef1e398f08da84dae5032) Signed-off-by: Dominik Ermel --- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 953c3776c4c9..75e19f057623 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -34,6 +34,23 @@ #include #endif +#if USE_PARTITION_MANAGER +#include + +#ifdef PM_MCUBOOT_SECONDARY_PAD_SIZE +BUILD_ASSERT(PM_MCUBOOT_PAD_SIZE == PM_MCUBOOT_SECONDARY_PAD_SIZE); +#endif + +#if CONFIG_BUILD_WITH_TFM + #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE + PM_TFM_SIZE) +#else + #define PM_ADDRESS_OFFSET (PM_MCUBOOT_PAD_SIZE) +#endif + +#define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ + (FIXED_PARTITION_OFFSET(label) == (PM_ADDRESS - PM_ADDRESS_OFFSET)) + +#else /* ! USE_PARTITION_MANAGER */ #ifndef CONFIG_FLASH_LOAD_OFFSET #error MCUmgr requires application to be built with CONFIG_FLASH_LOAD_OFFSET set \ to be able to figure out application running slot. @@ -41,12 +58,13 @@ #define FIXED_PARTITION_IS_RUNNING_APP_PARTITION(label) \ (FIXED_PARTITION_OFFSET(label) == CONFIG_FLASH_LOAD_OFFSET) +#endif /* USE_PARTITION_MANAGER */ #if !(FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_partition) || \ FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_ns_partition) || \ FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition) || \ FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot2_partition)) -#error "Unsupported chosen zephyr,code-partition for boot application." +#error "Unsupported chosen code partition for boot application." #endif LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); From 0948638f2e3a857bdfcd4bad0e1b5bd6d4760fb6 Mon Sep 17 00:00:00 2001 From: Maciej Perkowski Date: Fri, 28 Jan 2022 12:02:58 +0100 Subject: [PATCH 334/528] [nrf noup] ci: clang: parallel execution MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bring back parallel execution to the clang action. In the upstream they went to use a single dedicated powerful agent to run this. We need to keep this as we have to base on agents available in github's cloud. zephyr_runner is upstream's proprietary agent inaccessible outside of upstream's CI. Use ubuntu-latest instead. Signed-off-by: Maciej Perkowski Signed-off-by: Gerard Marull-Paretas Signed-off-by: Dominik Ermel Signed-off-by: Torsten Rasmussen Signed-off-by: Tomasz Moń Signed-off-by: Stephanos Ioannidis Signed-off-by: Vinayak Kariappa Chettimada (cherry picked from commit 5b3d0ff9ab29e66d52fd7c3ffbd50e9e97b1d7d5) (cherry picked from commit 5e2f4ecc0bd4171ff60bfbc9f60271d0a30142cc) Signed-off-by: Dominik Ermel --- .github/workflows/clang.yaml | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/.github/workflows/clang.yaml b/.github/workflows/clang.yaml index 9108d31b45b8..402cbae9f951 100644 --- a/.github/workflows/clang.yaml +++ b/.github/workflows/clang.yaml @@ -8,8 +8,7 @@ concurrency: jobs: clang-build: - if: github.repository_owner == 'zephyrproject-rtos' - runs-on: zephyr-runner-linux-x64-4xlarge + runs-on: ubuntu-latest container: image: ghcr.io/zephyrproject-rtos/ci:v0.26.4 options: '--entrypoint /bin/bash' @@ -19,11 +18,13 @@ jobs: fail-fast: false matrix: platform: ["native_posix"] + subset: [1, 2, 3, 4, 5] env: ZEPHYR_SDK_INSTALL_DIR: /opt/toolchains/zephyr-sdk-0.16.1 LLVM_TOOLCHAIN_PATH: /usr/lib/llvm-16 COMMIT_RANGE: ${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }} BASE_REF: ${{ github.base_ref }} + MATRIX_SIZE: 5 outputs: report_needed: ${{ steps.twister.outputs.report_needed }} steps: @@ -85,7 +86,7 @@ jobs: id: cache-ccache uses: zephyrproject-rtos/action-s3-cache@v1.2.0 with: - key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.platform }}-ccache + key: ${{ steps.ccache_cache_timestamp.outputs.repo }}-${{ github.ref_name }}-clang-${{ matrix.subset }}-ccache path: /github/home/.cache/ccache aws-s3-bucket: ccache.zephyrproject.org aws-access-key-id: ${{ vars.AWS_CCACHE_ACCESS_KEY_ID }} @@ -98,6 +99,16 @@ jobs: test -d github/home/.cache/ccache && rm -rf /github/home/.cache/ccache && mv github/home/.cache/ccache /github/home/.cache/ccache ccache -M 10G -s + - name: Build test plan with Twister + id: twister_test_plan + run: | + export ZEPHYR_BASE=${PWD} + export ZEPHYR_TOOLCHAIN_VARIANT=llvm + + # check if we need to run a full twister or not based on files changed + python3 ./scripts/ci/test_plan.py -p native_posix -c origin/${BASE_REF}.. + + - name: Run Tests with Twister id: twister run: | @@ -111,7 +122,7 @@ jobs: if [ -s testplan.json ]; then echo "report_needed=1" >> $GITHUB_OUTPUT # Full twister but with options based on changes - ./scripts/twister --force-color --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 + ./scripts/twister --inline-logs -M -N -v --load-tests testplan.json --retry-failed 2 --subset ${{matrix.subset}}/${MATRIX_SIZE} else # if nothing is run, skip reporting step echo "report_needed=0" >> $GITHUB_OUTPUT @@ -126,7 +137,7 @@ jobs: if: always() && steps.twister.outputs.report_needed != 0 uses: actions/upload-artifact@v3 with: - name: Unit Test Results (Subset ${{ matrix.platform }}) + name: Unit Test Results (Subset ${{ matrix.subset }}) path: twister-out/twister.xml clang-build-results: From c01ee451273ccb33c211f5b10fa2858ff8a271b9 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 1 Jun 2023 15:58:56 +0200 Subject: [PATCH 335/528] [nrf noup] tests: drivers: build_all: regulator: use old schema New Twister schema is not supported yet in sdk-zephyr, drop this patch once Twister is updated. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 4618cfe53df3154a6ee4101c2e68e98531fdda98) Signed-off-by: Dominik Ermel --- tests/drivers/build_all/regulator/testcase.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/drivers/build_all/regulator/testcase.yaml b/tests/drivers/build_all/regulator/testcase.yaml index 9b9c25511c4e..c5dbda1913f3 100644 --- a/tests/drivers/build_all/regulator/testcase.yaml +++ b/tests/drivers/build_all/regulator/testcase.yaml @@ -3,8 +3,6 @@ tests: drivers.regulator.build: - tags: - - drivers - - regulator + tags: drivers regulator build_only: true platform_allow: native_posix From 972da45e0aeefda92eba410d0908cffe3fa767dd Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 16 Jun 2023 10:09:08 +0100 Subject: [PATCH 336/528] [nrf fromtree] mgmt: mcumgr: grp: img_mgmt: Add optional mutex lock support Adds an optional Kconfig that adds mutex locks to image management group functions, this prevents collision between multiple threads and/or transports. Signed-off-by: Jamie McCrae (cherry picked from commit 0b6077443db7cdca6242f165f910b9e1721f5919) --- .../mgmt/mcumgr/grp/img_mgmt/img_mgmt.h | 9 +++++ subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig | 11 ++++++ .../mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h | 12 ++++++ .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 38 ++++++++++++++++++- .../mcumgr/grp/img_mgmt/src/img_mgmt_state.c | 9 +++++ 5 files changed, 78 insertions(+), 1 deletion(-) diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h index 35a129b6ad37..36220c1d128f 100644 --- a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt.h @@ -332,6 +332,15 @@ int img_mgmt_state_confirm(void); */ int img_mgmt_vercmp(const struct image_version *a, const struct image_version *b); +#if IS_ENABLED(CONFIG_MCUMGR_GRP_IMG_MUTEX) +/* + * @brief Will reset the image management state back to default (no ongoing upload), + * requires that CONFIG_MCUMGR_GRP_IMG_MUTEX be enabled to allow for mutex + * locking of the image management state object. + */ +void img_mgmt_reset_upload(void); +#endif + #ifdef CONFIG_MCUMGR_SMP_SUPPORT_ORIGINAL_PROTOCOL /* * @brief Translate IMG mgmt group error code into MCUmgr error code diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig index 1a028c0743f7..b97b6db84f3c 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/Kconfig @@ -25,6 +25,7 @@ menuconfig MCUMGR_GRP_IMG if MCUMGR_GRP_IMG if HEAP_MEM_POOL_SIZE > 0 + config MCUMGR_GRP_IMG_USE_HEAP_FOR_FLASH_IMG_CONTEXT bool "Use heap mem pool for flash image DFU context" help @@ -38,6 +39,7 @@ config MCUMGR_GRP_IMG_USE_HEAP_FOR_FLASH_IMG_CONTEXT to allocate this context or it will not be possible to perform DFU; it may also not be possible to allocate such context when heap is under pressure, due to application operation, an issue that should also be addressed within application. + endif config MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER @@ -112,6 +114,15 @@ config MCUMGR_GRP_IMG_STATUS_HOOKS uploads. Note that these are status checking only, to allow inspecting of a file upload or prevent it, CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK must be used. +config MCUMGR_GRP_IMG_MUTEX + bool "Mutex locking" + help + This will enable use of a mutex to lock the image group object access, preventing issues + of concurrent thread (i.e. multiple transport) access. This option also makes the + ``img_mgmt_reset_upload()`` function visible in the image management group header, which + can be used by applications to reset the image management state (useful if there are + multiple ways that firmware updates can be loaded). + module = MCUMGR_GRP_IMG module-str = mcumgr_grp_img source "subsys/logging/Kconfig.template.log_config" diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h b/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h index 57ed3854f0be..df26b4d10111 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/include/mgmt/mcumgr/grp/img_mgmt/img_mgmt_priv.h @@ -134,6 +134,18 @@ int img_mgmt_erase_if_needed(uint32_t off, uint32_t len); int img_mgmt_upload_inspect(const struct img_mgmt_upload_req *req, struct img_mgmt_upload_action *action); +/** + * @brief Takes the image management lock (if enabled) to prevent other + * threads interfering with an ongoing operation. + */ +void img_mgmt_take_lock(void); + +/** + * @brief Releases the held image management lock (if enabled) to allow + * other threads to use image management operations. + */ +void img_mgmt_release_lock(void); + #define ERASED_VAL_32(x) (((x) << 24) | ((x) << 16) | ((x) << 8) | (x)) int img_mgmt_erased_val(int slot, uint8_t *erased_val); diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 75e19f057623..48d79edd4d24 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -71,6 +71,10 @@ LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); struct img_mgmt_state g_img_mgmt_state; +#ifdef CONFIG_MCUMGR_GRP_IMG_MUTEX +static K_MUTEX_DEFINE(img_mgmt_mutex); +#endif + #ifdef CONFIG_MCUMGR_GRP_IMG_VERBOSE_ERR const char *img_mgmt_err_str_app_reject = "app reject"; const char *img_mgmt_err_str_hdr_malformed = "header malformed"; @@ -83,6 +87,20 @@ const char *img_mgmt_err_str_downgrade = "downgrade"; const char *img_mgmt_err_str_image_bad_flash_addr = "img addr mismatch"; #endif +void img_mgmt_take_lock(void) +{ +#ifdef CONFIG_MCUMGR_GRP_IMG_MUTEX + k_mutex_lock(&img_mgmt_mutex, K_FOREVER); +#endif +} + +void img_mgmt_release_lock(void) +{ +#ifdef CONFIG_MCUMGR_GRP_IMG_MUTEX + k_mutex_unlock(&img_mgmt_mutex); +#endif +} + /** * Finds the TLVs in the specified image slot, if any. */ @@ -133,6 +151,7 @@ int img_mgmt_active_image(void) #endif return 0; } + /* * Reads the version and build hash from the specified image slot. */ @@ -281,10 +300,16 @@ img_mgmt_find_by_hash(uint8_t *find, struct image_version *ver) /* * Resets upload status to defaults (no upload in progress) */ +#ifdef CONFIG_MCUMGR_GRP_IMG_MUTEX void img_mgmt_reset_upload(void) +#else +static void img_mgmt_reset_upload(void) +#endif { + img_mgmt_take_lock(); memset(&g_img_mgmt_state, 0, sizeof(g_img_mgmt_state)); g_img_mgmt_state.area_id = -1; + img_mgmt_release_lock(); } static int @@ -330,6 +355,8 @@ img_mgmt_erase(struct smp_streamer *ctxt) return MGMT_ERR_EINVAL; } + img_mgmt_take_lock(); + /* * First check if image info is valid. * This check is done incase the flash area has a corrupted image. @@ -363,11 +390,14 @@ img_mgmt_erase(struct smp_streamer *ctxt) if (IS_ENABLED(CONFIG_MCUMGR_SMP_LEGACY_RC_BEHAVIOUR)) { if (!zcbor_tstr_put_lit(zse, "rc") || !zcbor_int32_put(zse, 0)) { + img_mgmt_release_lock(); return MGMT_ERR_EMSGSIZE; } } end: + img_mgmt_release_lock(); + return MGMT_ERR_EOK; } @@ -482,6 +512,8 @@ img_mgmt_upload(struct smp_streamer *ctxt) return MGMT_ERR_EINVAL; } + img_mgmt_take_lock(); + /* Determine what actions to take as a result of this request. */ rc = img_mgmt_upload_inspect(&req, &action); if (rc != 0) { @@ -500,7 +532,9 @@ img_mgmt_upload(struct smp_streamer *ctxt) /* Request specifies incorrect offset. Respond with a success code and * the correct offset. */ - return img_mgmt_upload_good_rsp(ctxt); + rc = img_mgmt_upload_good_rsp(ctxt); + img_mgmt_release_lock(); + return rc; } #if defined(CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK) @@ -696,6 +730,8 @@ img_mgmt_upload(struct smp_streamer *ctxt) } } + img_mgmt_release_lock(); + if (!ok) { return MGMT_ERR_EMSGSIZE; } diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c index eae5aaa3e8bd..2e673fff9780 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt_state.c @@ -245,6 +245,8 @@ img_mgmt_state_read(struct smp_streamer *ctxt) ok = zcbor_tstr_put_lit(zse, "images") && zcbor_list_start_encode(zse, 2 * CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER); + img_mgmt_take_lock(); + for (i = 0; ok && i < 2 * CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER; i++) { int rc = img_mgmt_read_info(i, &ver, hash, &flags); if (rc != 0) { @@ -291,6 +293,8 @@ img_mgmt_state_read(struct smp_streamer *ctxt) zcbor_int32_put(zse, 0); } + img_mgmt_release_lock(); + return ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE; } @@ -385,6 +389,8 @@ img_mgmt_state_write(struct smp_streamer *ctxt) return MGMT_ERR_EINVAL; } + img_mgmt_take_lock(); + /* Determine which slot is being operated on. */ if (zhash.len == 0) { if (confirm) { @@ -423,10 +429,13 @@ img_mgmt_state_write(struct smp_streamer *ctxt) /* Send the current image state in the response. */ rc = img_mgmt_state_read(ctxt); if (rc != 0) { + img_mgmt_release_lock(); return rc; } end: + img_mgmt_release_lock(); + if (!ok) { return MGMT_ERR_EMSGSIZE; } From d2bc2c3c6ce3d08628a93c3bd246fd688dc6a446 Mon Sep 17 00:00:00 2001 From: Dawid Przybylo Date: Fri, 23 Jun 2023 08:15:25 +0200 Subject: [PATCH 337/528] [nrf noup] ci: Update test-spec.yml with adding FEM to CI Extend sdk-zephyr CI with FEM test label. Signed-off-by: Dawid Przybylo --- .github/test-spec.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 3fe9ba5fbecf..5dd281919bcc 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -60,6 +60,9 @@ "CI-crypto-test": - "**/*" +"CI-fem-test": + - "**/*" + "CI-rs-test": - "**/*" From d0a5660c5fe55d4aba10995c085d8c2ba708ec5f Mon Sep 17 00:00:00 2001 From: Marcin Niestroj Date: Wed, 21 Jun 2023 18:24:52 +0200 Subject: [PATCH 338/528] [nrf fromtree] posix: eventfd: fix waking up poll() Fix a regression introduced by commit e6eb0a705bc8 ("posix: eventfd: revise locking, signaling, and allocation"), which was a complete rewrite stating that: The `wait_q` and `k_poll_signal` entries were removed from `struct eventfd` as they were unnecessary. In fact, `k_poll_signal` (both `read_sig` and `write_sig`) were used to wake-up blocking `poll()` invocation in another thread. This is no longer the case now, i.e. `poll(..., POLLIN)` does not return after calling `eventfd_write()` on the observed (polled) FD. Fix this regression by bringing back `read_sig` and `write_sig` to very similar state as it was before. Fixes: e6eb0a705bc8 ("posix: eventfd: revise locking, signaling, and allocation") Signed-off-by: Marcin Niestroj (cherry picked from commit 44d61bde848377a32f4f9f12d5d20aa9b86bc04f) Signed-off-by: Robert Lubos --- lib/posix/eventfd.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/posix/eventfd.c b/lib/posix/eventfd.c index a8cc059cb20f..d32ac4c06b42 100644 --- a/lib/posix/eventfd.c +++ b/lib/posix/eventfd.c @@ -17,6 +17,8 @@ #define EFD_FLAGS_SET_INTERNAL (EFD_SEMAPHORE | EFD_NONBLOCK) struct eventfd { + struct k_poll_signal read_sig; + struct k_poll_signal write_sig; struct k_spinlock lock; eventfd_t cnt; int flags; @@ -49,12 +51,29 @@ static int eventfd_poll_prepare(struct eventfd *efd, struct k_poll_event **pev, struct k_poll_event *pev_end) { - if ((pfd->events & (ZSOCK_POLLOUT | ZSOCK_POLLIN)) != 0) { + if (pfd->events & ZSOCK_POLLIN) { if (*pev == pev_end) { errno = ENOMEM; return -1; } - **pev = (struct k_poll_event){0}; + + (*pev)->obj = &efd->read_sig; + (*pev)->type = K_POLL_TYPE_SIGNAL; + (*pev)->mode = K_POLL_MODE_NOTIFY_ONLY; + (*pev)->state = K_POLL_STATE_NOT_READY; + (*pev)++; + } + + if (pfd->events & ZSOCK_POLLOUT) { + if (*pev == pev_end) { + errno = ENOMEM; + return -1; + } + + (*pev)->obj = &efd->write_sig; + (*pev)->type = K_POLL_TYPE_SIGNAL; + (*pev)->mode = K_POLL_MODE_NOTIFY_ONLY; + (*pev)->state = K_POLL_STATE_NOT_READY; (*pev)++; } @@ -99,6 +118,12 @@ static int eventfd_read_locked(struct eventfd *efd, eventfd_t *value) efd->cnt = 0; } + if (efd->cnt == 0) { + k_poll_signal_reset(&efd->read_sig); + } + + k_poll_signal_raise(&efd->write_sig, 0); + return 0; } @@ -124,6 +149,12 @@ static int eventfd_write_locked(struct eventfd *efd, eventfd_t *value) /* successful write */ efd->cnt = result; + if (efd->cnt == (UINT64_MAX - 1)) { + k_poll_signal_reset(&efd->write_sig); + } + + k_poll_signal_raise(&efd->read_sig, 0); + return 0; } @@ -398,6 +429,16 @@ int eventfd(unsigned int initval, int flags) efd->flags = EFD_IN_USE_INTERNAL | flags; efd->cnt = initval; + k_poll_signal_init(&efd->write_sig); + k_poll_signal_init(&efd->read_sig); + + if (initval != 0) { + k_poll_signal_raise(&efd->read_sig, 0); + } + if (initval < UINT64_MAX - 1) { + k_poll_signal_raise(&efd->write_sig, 0); + } + z_finalize_fd(fd, efd, &eventfd_fd_vtable); return fd; From 2fa627b1f0823193791183ef1197c7dd1474935b Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Fri, 28 Apr 2023 14:38:23 -0700 Subject: [PATCH 339/528] [nrf fromlist] net: conn_mgr: Minor fixes Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57399 - Add missing event sleep after taking all ifaces up in test_connect_disconnect. - Add missing event sleep after resetting ifaces in conn_mgr_conn_before - Fix typo in comment for internal state flags. - Add missing NET_MGMT_EVENT_BIT to conn_mgr_connectivity event definitions. - Missing net_mgmt.h include in conn_mgr_connectivity.h - Split conn_mgr_conn iface reset into network and state resets, before and after event sleep, so that triggered events do not corrupt the state reset. - Reduce SIMULATED_EVENT_DELAY to 100ms to avoid timeouts on real-time targets. - Use macro for simulated event wait times. Signed-off-by: Georges Oates_Larsen Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 4 +- subsys/net/conn_mgr/conn_mgr_private.h | 2 +- tests/net/conn_mgr_conn/src/main.c | 42 +++++++++++++++----- tests/net/conn_mgr_conn/src/test_conn_impl.c | 2 +- tests/net/conn_mgr_conn/src/test_conn_impl.h | 4 +- 5 files changed, 41 insertions(+), 13 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 34b885d86321..e877ad97fabf 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef __cplusplus extern "C" { @@ -34,7 +35,8 @@ extern "C" { /* Connectivity Events */ #define _NET_MGMT_CONN_LAYER NET_MGMT_LAYER(NET_MGMT_LAYER_L2) #define _NET_MGMT_CONN_CODE NET_MGMT_LAYER_CODE(0x207) -#define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE) +#define _NET_MGMT_CONN_BASE (_NET_MGMT_CONN_LAYER | _NET_MGMT_CONN_CODE | \ + NET_MGMT_EVENT_BIT) #define _NET_MGMT_CONN_IF_EVENT (NET_MGMT_IFACE_BIT | _NET_MGMT_CONN_BASE) enum net_event_ethernet_cmd { diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 9e147653828b..94e7a0b79580 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -27,7 +27,7 @@ /* Configuration flags */ #define CONN_MGR_IF_IGNORED BIT(7) -/* Internal state flags*/ +/* Internal state flags */ #define CONN_MGR_IF_READY BIT(14) /* Event flags */ diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index dbe1d4cb3374..373dcdd04265 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -29,7 +29,12 @@ static inline struct test_conn_data *conn_mgr_if_get_data(struct net_if *iface) return binding->ctx; } -static void reset_test_iface(struct net_if *iface) +/** + * @brief Reset the network state of the provided iface. + * + * @param iface - iface to reset. + */ +static void reset_test_iface_networking(struct net_if *iface) { if (net_if_is_admin_up(iface)) { (void)net_if_down(iface); @@ -37,7 +42,15 @@ static void reset_test_iface(struct net_if *iface) /* Some tests can leave the iface in a bad state where it is admin-down but not dormant */ net_if_dormant_on(iface); +} +/** + * @brief Reset testing state for the provided iface. + * + * @param iface - iface to reset. + */ +static void reset_test_iface_state(struct net_if *iface) +{ struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface); struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); @@ -98,12 +111,22 @@ static void conn_mgr_conn_handler(struct net_mgmt_event_callback *cb, static void conn_mgr_conn_before(void *data) { ARG_UNUSED(data); - reset_test_iface(ifa1); - reset_test_iface(ifa2); - reset_test_iface(ifb); - reset_test_iface(ifni); - reset_test_iface(ifnone); - reset_test_iface(ifnull); + reset_test_iface_networking(ifa1); + reset_test_iface_networking(ifa2); + reset_test_iface_networking(ifb); + reset_test_iface_networking(ifni); + reset_test_iface_networking(ifnone); + reset_test_iface_networking(ifnull); + + /* Allow any triggered events to shake out */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + + reset_test_iface_state(ifa1); + reset_test_iface_state(ifa2); + reset_test_iface_state(ifb); + reset_test_iface_state(ifni); + reset_test_iface_state(ifnone); + reset_test_iface_state(ifnull); k_mutex_lock(&event_mutex, K_FOREVER); @@ -171,6 +194,7 @@ ZTEST(conn_mgr_conn, test_connect_disconnect) zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail"); zassert_equal(net_if_up(ifa2), 0, "net_if_up should not fail"); zassert_equal(net_if_up(ifb), 0, "net_if_up should not fail"); + k_sleep(K_MSEC(1)); /* Verify ifaces are still disconnected */ zassert_false(net_if_is_up(ifa1), "Ifaces must be disconnected before test"); @@ -526,7 +550,7 @@ ZTEST(conn_mgr_conn, test_connect_timeout) zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); /* Ensure timeout event is fired */ - k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); + k_sleep(SIMULATED_EVENT_WAIT_TIME); k_mutex_lock(&event_mutex, K_FOREVER); stats = test_event_stats; @@ -557,7 +581,7 @@ ZTEST(conn_mgr_conn, test_connect_fatal_error) zassert_false(net_if_is_up(ifa1), "ifa1 should not be up if instructed to time out"); /* Ensure fatal_error event is fired */ - k_sleep(K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS + 1)); + k_sleep(SIMULATED_EVENT_WAIT_TIME); k_mutex_lock(&event_mutex, K_FOREVER); stats = test_event_stats; diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c index 8d2395160590..c6e4cff6a2d0 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -57,7 +57,7 @@ static void simulate_event(struct net_if *target, int event) simulated_event = event; simulated_event_iface = target; - k_work_reschedule(&simulate_event_work, K_SECONDS(SIMULATED_EVENT_DELAY_SECONDS)); + k_work_reschedule(&simulate_event_work, SIMULATED_EVENT_DELAY_TIME); k_mutex_unlock(&simulated_event_mutex); } diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h index 6408bb802cfc..1df7e6d02011 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -76,7 +76,9 @@ CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_N); #define TEST_L2_CONN_IMPL_NI_CTX_TYPE struct test_conn_data CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); -#define SIMULATED_EVENT_DELAY_SECONDS 5 +#define SIMULATED_EVENT_DELAY_MS 100 +#define SIMULATED_EVENT_DELAY_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS) +#define SIMULATED_EVENT_WAIT_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS + 10) #ifdef __cplusplus } From 020bd507ee48b835801c574919a70b9082b303bb Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Wed, 26 Apr 2023 13:58:47 -0700 Subject: [PATCH 340/528] [nrf fromlist] net: conn_mgr: Support Auto-Connect Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57399 To reduce the need for boilerplate in application code, conn_mgr now supports an auto-connect feature on all ifaces with connectivity bindings. conn_mgr will automatically call conn_mgr_if_connect on any iface with a connectivity binding that enters the admin-up state, unless the newly added CONN_MGR_IF_NO_AUTO_CONNECT flag has been set for that iface. Also adjust automated tests to account for and take advantage of this behavior. Signed-off-by: Georges Oates_Larsen Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 6 ++ subsys/net/conn_mgr/conn_mgr_connectivity.c | 62 ++++++++++++++++++++ subsys/net/conn_mgr/conn_mgr_private.h | 2 + tests/net/conn_mgr/src/main.c | 41 ------------- tests/net/conn_mgr_conn/src/main.c | 64 ++++++++++++++++++++- 5 files changed, 133 insertions(+), 42 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index e877ad97fabf..2ea5eff203fd 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -180,6 +180,12 @@ enum conn_mgr_if_flag { */ CONN_MGR_IF_PERSISTENT, + /* No auto-connect + * When set, conn_mgr will not automatically attempt to connect this iface when it reaches + * admin-up. + */ + CONN_MGR_IF_NO_AUTO_CONNECT, + /** @cond INTERNAL_HIDDEN */ /* Total number of flags - must be at the end of the enum */ CONN_MGR_NUM_IF_FLAGS, diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index 8fae71acec17..9ea08cccde44 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -235,8 +235,52 @@ int conn_mgr_if_set_timeout(struct net_if *iface, int timeout) return 0; } +/* Automated behavior handling */ + +/** + * @brief Perform automated behaviors in response to ifaces going admin-up. + * + * @param iface - The iface which became admin-up. + */ +static void conn_mgr_conn_handle_iface_admin_up(struct net_if *iface) +{ + int err; + + /* Ignore ifaces that don't have connectivity implementations */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + /* Ignore ifaces for which auto-connect is disabled */ + if (conn_mgr_if_get_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT)) { + return; + } + + /* Otherwise, automatically instruct the iface to connect */ + err = conn_mgr_if_connect(iface); + if (err < 0) { + NET_ERR("iface auto-connect failed: %d", err); + } +} + +static struct net_mgmt_event_callback conn_mgr_conn_iface_cb; +static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, + struct net_if *iface) +{ + if ((mgmt_event & CONN_MGR_CONN_IFACE_EVENTS_MASK) != mgmt_event) { + return; + } + + switch (mgmt_event) { + case NET_EVENT_IF_UP: + conn_mgr_conn_handle_iface_admin_up(iface); + break; + } +} + void conn_mgr_conn_init(void) { + /* Initialize connectivity bindings. */ STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { if (!(binding->impl->api)) { LOG_ERR("Connectivity implementation has NULL API, and will be treated as " @@ -255,4 +299,22 @@ void conn_mgr_conn_init(void) k_mutex_unlock(binding->mutex); } } + + /* Set up event listeners for automated behaviors */ + net_mgmt_init_event_callback(&conn_mgr_conn_iface_cb, conn_mgr_conn_iface_handler, + CONN_MGR_CONN_IFACE_EVENTS_MASK); + net_mgmt_add_event_callback(&conn_mgr_conn_iface_cb); + + /* Trigger any initial automated behaviors for ifaces */ + STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { + if (binding->impl->api) { + /* We need to fire conn_mgr_conn_handle_iface_admin_up for any + * (connectivity-enabled) ifaces that went admin-up before we registerred + * the event callback that typically handles this. + */ + if (net_if_is_admin_up(binding->iface)) { + conn_mgr_conn_handle_iface_admin_up(binding->iface); + } + } + } } diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 94e7a0b79580..1e20b33b49e5 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -37,6 +37,8 @@ #define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ NET_EVENT_IF_UP) +#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP) + #define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ NET_EVENT_IPV6_ADDR_DEL | \ NET_EVENT_IPV6_DAD_SUCCEED | \ diff --git a/tests/net/conn_mgr/src/main.c b/tests/net/conn_mgr/src/main.c index ee7c0c9cbd90..33e50fdde8c4 100644 --- a/tests/net/conn_mgr/src/main.c +++ b/tests/net/conn_mgr/src/main.c @@ -186,10 +186,6 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -202,10 +198,6 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -266,10 +258,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -292,10 +280,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -308,10 +292,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -353,10 +333,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -366,10 +342,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take A up */ zassert_equal(net_if_up(ifa), 0, "net_if_up should succeed for ifa."); - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_connect(ifa), 0, - "conn_mgr_if_connect should succeed for ifa."); - } /* Expect connectivity gained */ k_sleep(EVENT_WAIT_TIME); @@ -408,10 +380,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect connectivity lost */ @@ -481,11 +449,6 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* Take iface up */ zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_connect(iface), 0, - "conn_mgr_if_connect should succeed."); - } - /* Verify that no events have been fired yet */ k_sleep(EVENT_WAIT_TIME); stats = get_reset_stats(); @@ -643,10 +606,6 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* Take iface up */ zassert_equal(net_if_up(iface), 0, "net_if_up should succeed."); - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_connect(iface), 0, - "conn_mgr_if_connect should succeed."); - } /* Verify events are fired */ k_sleep(EVENT_WAIT_TIME); diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index 373dcdd04265..fbb88d7732d1 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -55,8 +55,12 @@ static void reset_test_iface_state(struct net_if *iface) struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); if (iface_binding) { + /* Reset all flags and settings for the binding */ iface_binding->flags = 0; iface_binding->timeout = CONN_MGR_IF_NO_TIMEOUT; + + /* Disable auto-connect */ + conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT, true); } if (iface_data) { @@ -761,6 +765,9 @@ ZTEST(conn_mgr_conn, test_flags) { struct conn_mgr_conn_binding *ifa1_binding = conn_mgr_if_get_binding(ifa1); + /* Firstly, clear all flags (some are automatically enabled before each test) */ + ifa1_binding->flags = 0; + /* Try setting persistence flag */ zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true), 0, "Setting persistence flag should succeed for ifa1"); @@ -773,6 +780,19 @@ ZTEST(conn_mgr_conn, test_flags) zassert_equal(ifa1_binding->flags, BIT(CONN_MGR_IF_PERSISTENT), "Persistence flag set should affect conn struct"); + /* Try setting no-autoconnect flag */ + zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, true), 0, + "Setting no-autoconnect flag should succeed for ifa1"); + + /* Verify success */ + zassert_true(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT), + "No-autoconnect should be set for ifa1"); + + /* Verify that the conn struct agrees, since this is what implementations may use */ + zassert_equal(ifa1_binding->flags, + BIT(CONN_MGR_IF_PERSISTENT) | BIT(CONN_MGR_IF_NO_AUTO_CONNECT), + "Persistence flag set should affect conn struct"); + /* Try unsetting persistence flag */ zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false), 0, "Unsetting persistence flag should succeed for ifa1"); @@ -782,8 +802,20 @@ ZTEST(conn_mgr_conn, test_flags) "Persistence should be unset for ifa1"); /* Verify that the conn struct agrees, since this is what implementations may use */ - zassert_equal(ifa1_binding->flags, 0, + zassert_equal(ifa1_binding->flags, BIT(CONN_MGR_IF_NO_AUTO_CONNECT), "Persistence flag unset should affect conn struct"); + + /* Try unsetting no-autoconnect flag */ + zassert_equal(conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false), 0, + "Clearing no-autoconnect flag should succeed for ifa1"); + + /* Verify success */ + zassert_false(conn_mgr_if_get_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT), + "No-autoconnect should be set for ifa1"); + + /* Verify that the conn struct agrees, since this is what implementations may use */ + zassert_equal(ifa1_binding->flags, 0, + "No-autoconnect flag set should affect conn struct"); } /* Verify that flag get/set fail and behave as expected respectively for invalid ifaces and @@ -857,4 +889,34 @@ ZTEST(conn_mgr_conn, test_timeout_invalid) "Getting timeout should yield CONN_MGR_IF_NO_TIMEOUT for ifnone"); } +/* Verify that auto-connect works as expected. */ +ZTEST(conn_mgr_conn, test_auto_connect) +{ + /* Disable auto-connect. + * Not strictly necessary, since this is the default for this suite, but do it anyways + * since this test case specifically focuses on auto-connect. + */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, true); + + /* Take the iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail."); + + /* Verify no connection */ + k_sleep(K_MSEC(1)); + zassert_false(net_if_is_up(ifa1), "Auto-connect should not trigger if disabled."); + + /* Take the iface down */ + zassert_equal(net_if_down(ifa1), 0, "net_if_down should not fail."); + + /* Enable auto-connect */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Take the iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should not fail."); + + /* Verify connection */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Auto-connect should succeed if enabled."); +} + ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); From 9e855501350c5eb59c106875f0d2fbbee7185e75 Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Wed, 26 Apr 2023 16:30:23 -0700 Subject: [PATCH 341/528] [nrf fromlist] net: conn_mgr: Support Auto-Down Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57399 To reduce the amount of boiler-plate needed in applications, this commit grants conn_mgr the ability to automatically take ifaces that have given up on connecting into the admin-down state. Tests adjusted as appropriate. This behavior can be disabled globally by disabling NET_CONNECTION_MANAGER_AUTO_IF_DOWN, or disabled per-iface using the CONN_MGR_IF_NO_AUTO_DOWN flag. Signed-off-by: Georges Oates_Larsen Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 6 + subsys/net/conn_mgr/Kconfig | 4 + subsys/net/conn_mgr/conn_mgr_connectivity.c | 106 ++++++++- subsys/net/conn_mgr/conn_mgr_private.h | 6 +- tests/net/conn_mgr/src/main.c | 43 ---- tests/net/conn_mgr_conn/src/main.c | 223 ++++++++++++++++++- tests/net/conn_mgr_conn/src/test_conn_impl.c | 7 +- tests/net/conn_mgr_conn/src/test_conn_impl.h | 19 ++ 8 files changed, 367 insertions(+), 47 deletions(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 2ea5eff203fd..34d8e04e1537 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -186,6 +186,12 @@ enum conn_mgr_if_flag { */ CONN_MGR_IF_NO_AUTO_CONNECT, + /* No auto-down + * When set, conn_mgr will not automatically take the iface admin-down when it stops + * trying to connect, even if NET_CONNECTION_MANAGER_AUTO_IF_DOWN is enabled. + */ + CONN_MGR_IF_NO_AUTO_DOWN, + /** @cond INTERNAL_HIDDEN */ /* Total number of flags - must be at the end of the enum */ CONN_MGR_NUM_IF_FLAGS, diff --git a/subsys/net/conn_mgr/Kconfig b/subsys/net/conn_mgr/Kconfig index a8e37b68b5ee..e74a243b4a0a 100644 --- a/subsys/net/conn_mgr/Kconfig +++ b/subsys/net/conn_mgr/Kconfig @@ -37,4 +37,8 @@ config NET_CONNECTION_MANAGER_PRIORITY help This sets the starting priority of the connection manager thread. +config NET_CONNECTION_MANAGER_AUTO_IF_DOWN + bool "Automatically take ifaces admin-down if they have stopped trying to connect" + default y + endif # NET_CONNECTION_MANAGER diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index 9ea08cccde44..02ea35219f4e 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -48,6 +48,8 @@ int conn_mgr_if_connect(struct net_if *iface) return status; } +static void conn_mgr_conn_if_auto_admin_down(struct net_if *iface); + int conn_mgr_if_disconnect(struct net_if *iface) { struct conn_mgr_conn_binding *binding; @@ -77,6 +79,16 @@ int conn_mgr_if_disconnect(struct net_if *iface) out: k_mutex_unlock(binding->mutex); + /* Since the connectivity implementation will not automatically attempt to reconnect after + * a call to conn_mgr_if_disconnect, conn_mgr_conn_if_auto_admin_down should be called. + * + * conn_mgr_conn_handle_iface_down will only call conn_mgr_conn_if_auto_admin_down if + * persistence is disabled. To ensure conn_mgr_conn_if_auto_admin_down is called in all + * cases, we must call it directly from here. If persistence is disabled, this will result + * in conn_mgr_conn_if_auto_admin_down being called twice, but that is not an issue. + */ + conn_mgr_conn_if_auto_admin_down(iface); + return status; } @@ -263,6 +275,61 @@ static void conn_mgr_conn_handle_iface_admin_up(struct net_if *iface) } } +/** + * @brief Take the provided iface admin-down. + * + * Called automatically by conn_mgr when an iface loses connection and does not expect to regain it, + * and AUTO_IF_DOWN is enabled for the iface. + * + * @param iface - The iface to take admin-down + */ +static void conn_mgr_conn_if_auto_admin_down(struct net_if *iface) +{ + /* NOTE: This will be double-fired for ifaces that are both non-persistent + * and are being directly requested to disconnect, since both of these conditions + * separately trigger conn_mgr_conn_if_auto_admin_down. + * + * This is fine, because net_if_down is idempotent, but if you are adding other + * behaviors to this function, bear it in mind. + */ + + /* Ignore ifaces that don't have connectivity implementations */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + /* Take the iface admin-down if AUTO_DOWN is enabled */ + if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER_AUTO_IF_DOWN) && + !conn_mgr_if_get_flag(iface, CONN_MGR_IF_NO_AUTO_DOWN)) { + net_if_down(iface); + } +} + +/** + * @brief Perform automated behaviors in response to any iface that loses oper-up state. + * + * This is how conn_mgr_conn automatically takes such ifaces admin-down if they are not persistent. + * + * @param iface - The iface which lost oper-up state. + */ +static void conn_mgr_conn_handle_iface_down(struct net_if *iface) +{ + /* Ignore ifaces that don't have connectivity implementations */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + /* If the iface is persistent, we expect it to try to reconnect, so nothing else to do */ + if (conn_mgr_if_get_flag(iface, CONN_MGR_IF_PERSISTENT)) { + return; + } + + /* Otherwise, we do not expect the iface to reconnect, and we should call + * conn_mgr_conn_if_auto_admin_down + */ + conn_mgr_conn_if_auto_admin_down(iface); +} + static struct net_mgmt_event_callback conn_mgr_conn_iface_cb; static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) @@ -272,12 +339,45 @@ static void conn_mgr_conn_iface_handler(struct net_mgmt_event_callback *cb, uint } switch (mgmt_event) { - case NET_EVENT_IF_UP: + case NET_EVENT_IF_DOWN: + conn_mgr_conn_handle_iface_down(iface); + break; + case NET_EVENT_IF_ADMIN_UP: conn_mgr_conn_handle_iface_admin_up(iface); break; } } +static struct net_mgmt_event_callback conn_mgr_conn_self_cb; +static void conn_mgr_conn_self_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, + struct net_if *iface) +{ + if ((mgmt_event & CONN_MGR_CONN_SELF_EVENTS_MASK) != mgmt_event) { + return; + } + + switch (NET_MGMT_GET_COMMAND(mgmt_event)) { + case NET_EVENT_CONN_CMD_IF_FATAL_ERROR: + if (cb->info) { + NET_ERR("Fatal connectivity error on iface %d (%p). Reason: %d.", + net_if_get_by_iface(iface), iface, *((int *)cb->info) + ); + } else { + NET_ERR("Unknown fatal connectivity error on iface %d (%p).", + net_if_get_by_iface(iface), iface + ); + } + __fallthrough; + case NET_EVENT_CONN_CMD_IF_TIMEOUT: + /* If a timeout or fatal error occurs, we do not expect the iface to try to + * reconnect, so call conn_mgr_conn_if_auto_admin_down. + */ + conn_mgr_conn_if_auto_admin_down(iface); + break; + } + +} + void conn_mgr_conn_init(void) { /* Initialize connectivity bindings. */ @@ -305,6 +405,10 @@ void conn_mgr_conn_init(void) CONN_MGR_CONN_IFACE_EVENTS_MASK); net_mgmt_add_event_callback(&conn_mgr_conn_iface_cb); + net_mgmt_init_event_callback(&conn_mgr_conn_self_cb, conn_mgr_conn_self_handler, + CONN_MGR_CONN_SELF_EVENTS_MASK); + net_mgmt_add_event_callback(&conn_mgr_conn_self_cb); + /* Trigger any initial automated behaviors for ifaces */ STRUCT_SECTION_FOREACH(conn_mgr_conn_binding, binding) { if (binding->impl->api) { diff --git a/subsys/net/conn_mgr/conn_mgr_private.h b/subsys/net/conn_mgr/conn_mgr_private.h index 1e20b33b49e5..c2f3097a8d46 100644 --- a/subsys/net/conn_mgr/conn_mgr_private.h +++ b/subsys/net/conn_mgr/conn_mgr_private.h @@ -37,7 +37,11 @@ #define CONN_MGR_IFACE_EVENTS_MASK (NET_EVENT_IF_DOWN | \ NET_EVENT_IF_UP) -#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP) +#define CONN_MGR_CONN_IFACE_EVENTS_MASK (NET_EVENT_IF_ADMIN_UP |\ + NET_EVENT_IF_DOWN) + +#define CONN_MGR_CONN_SELF_EVENTS_MASK (NET_EVENT_CONN_IF_TIMEOUT | \ + NET_EVENT_CONN_IF_FATAL_ERROR) #define CONN_MGR_IPV6_EVENTS_MASK (NET_EVENT_IPV6_ADDR_ADD | \ NET_EVENT_IPV6_ADDR_DEL | \ diff --git a/tests/net/conn_mgr/src/main.c b/tests/net/conn_mgr/src/main.c index 33e50fdde8c4..9a225c3fb113 100644 --- a/tests/net/conn_mgr/src/main.c +++ b/tests/net/conn_mgr/src/main.c @@ -44,9 +44,6 @@ static void reset_test_iface(struct net_if *iface) struct in6_addr *ll_ipv6; if (net_if_is_admin_up(iface)) { - if (conn_mgr_if_is_bound(iface)) { - (void)conn_mgr_if_disconnect(iface); - } (void)net_if_down(iface); } @@ -206,10 +203,6 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect no events */ @@ -219,10 +212,6 @@ static void cycle_ready_ifaces(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect connectivity loss */ @@ -266,10 +255,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -300,10 +285,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifba."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -313,10 +294,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) "No events should be fired if connectivity availability did not change."); /* Take A down */ - if (conn_mgr_if_is_bound(ifa)) { - zassert_equal(conn_mgr_if_disconnect(ifa), 0, - "conn_mgr_if_disconnect should succeed for ifa."); - } zassert_equal(net_if_down(ifa), 0, "net_if_down should succeed for ifa."); /* Expect connectivity lost */ @@ -353,10 +330,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) zassert_equal(stats.conn_iface, ifa, "ifa should be blamed."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -368,10 +341,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) /* Take B up */ zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for ifb."); - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_connect(ifb), 0, - "conn_mgr_if_connect should succeed for ifb."); - } /* Expect no events */ k_sleep(EVENT_WAIT_TIME); @@ -392,10 +361,6 @@ static void cycle_ignored_iface(struct net_if *ifa, struct net_if *ifb) zassert_equal(stats.dconn_iface, ifa, "ifa should be blamed."); /* Take B down */ - if (conn_mgr_if_is_bound(ifb)) { - zassert_equal(conn_mgr_if_disconnect(ifb), 0, - "conn_mgr_if_disconnect should succeed for ifb."); - } zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for ifb."); /* Expect no events */ @@ -566,10 +531,6 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* (10 -> 00): Lose oper-up from semi-ready state */ /* Take iface down */ - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_disconnect(iface), 0, - "conn_mgr_if_disconnect should succeed."); - } zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); /* Verify there are no events fired */ @@ -619,10 +580,6 @@ static void cycle_iface_states(struct net_if *iface, enum ip_order ifa_ipm) /* (11 -> 01): Lose oper-up from ready state */ /* Take iface down */ - if (conn_mgr_if_is_bound(iface)) { - zassert_equal(conn_mgr_if_disconnect(iface), 0, - "conn_mgr_if_disconnect should succeed."); - } zassert_equal(net_if_down(iface), 0, "net_if_down should succeed."); /* Verify events are fired */ diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index fbb88d7732d1..e7154329d5a8 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -59,8 +59,9 @@ static void reset_test_iface_state(struct net_if *iface) iface_binding->flags = 0; iface_binding->timeout = CONN_MGR_IF_NO_TIMEOUT; - /* Disable auto-connect */ + /* Disable auto-connect and auto-down */ conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_CONNECT, true); + conn_mgr_if_set_flag(iface, CONN_MGR_IF_NO_AUTO_DOWN, true); } if (iface_data) { @@ -919,4 +920,224 @@ ZTEST(conn_mgr_conn, test_auto_connect) zassert_true(net_if_is_up(ifa1), "Auto-connect should succeed if enabled."); } +/* Verify that if auto-down is enabled, disconnecting an iface also takes it down, + * regardless of whether persistence is enabled, but only if auto-down is disabled. + */ +ZTEST(conn_mgr_conn, test_auto_down_disconnect) +{ + /* For convenience, use auto-connect for this test. */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Enable auto-down, disable persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Disconnect iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, + "conn_mgr_if_disconnect should succeed."); + + /* Verify down */ + k_sleep(K_MSEC(1)); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on direct disconnect."); + + + + /* Enable persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Disconnect iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, + "conn_mgr_if_disconnect should succeed."); + + /* Verify down */ + k_sleep(K_MSEC(1)); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on direct disconnect, even if persistence is enabled."); + + + + /* Disable auto-down */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Disconnect iface */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, + "conn_mgr_if_disconnect should succeed."); + + /* Verify up */ + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger if it is disabled."); +} + +/* Verify that auto-down takes an iface down if connection is lost, but only if persistence is not + * enabled, and only if auto-down is enabled. + */ +ZTEST(conn_mgr_conn, test_auto_down_conn_loss) +{ + /* For convenience, use auto-connect for this test. */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Enable auto-down, disable persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Simulate connection loss */ + simulate_connection_loss(ifa1); + + /* Verify down */ + k_sleep(K_MSEC(1)); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on connection loss if persistence is disabled."); + + /* Enable persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Simulate connection loss */ + simulate_connection_loss(ifa1); + + /* Verify up */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger on connection loss if persistence is enabled."); + + /* Disable persistence and disable auto-down*/ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, false); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); + + /* Reconnect iface */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Simulate connection loss */ + simulate_connection_loss(ifa1); + + /* Verify up */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger on connection loss if it is disabled."); +} + +/* Verify that timeout takes the iface down, even if + * persistence is enabled, but only if auto-down is enabled. + */ +ZTEST(conn_mgr_conn, test_auto_down_timeout) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* For convenience, use auto-connect for this test. */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Enable auto-down and persistence*/ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); + + /* Schedule timeout */ + ifa1_data->timeout = true; + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify iface down after timeout */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on connection timeout, even if persistence is enabled."); + + /* Disable auto-down */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); + + /* Take iface up (timing out again) */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify iface up after timeout */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger on connection timeout if it is disabled."); +} + + +/* Verify that fatal error takes the iface down, even if + * persistence is enabled, but only if auto-down is enabled. + */ +ZTEST(conn_mgr_conn, test_auto_down_fatal) +{ + /* For convenience, use auto-connect for this test. */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_CONNECT, false); + + /* Enable auto-down and persistence */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_PERSISTENT, true); + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, false); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Raise fatal error */ + simulate_fatal_error(ifa1, -EAGAIN); + + /* Verify iface down after fatal error */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + zassert_false(net_if_is_admin_up(ifa1), + "Auto-down should trigger on fatal error, even if persistence is enabled."); + + /* Disable auto-down */ + conn_mgr_if_set_flag(ifa1, CONN_MGR_IF_NO_AUTO_DOWN, true); + + /* Take iface up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed."); + + /* Verify connected */ + k_sleep(K_MSEC(1)); + zassert_true(net_if_is_up(ifa1), "Connection should succeed."); + + /* Raise fatal error */ + simulate_fatal_error(ifa1, -EAGAIN); + + /* Verify iface still up after fatal error */ + k_sleep(SIMULATED_EVENT_WAIT_TIME); + zassert_true(net_if_is_admin_up(ifa1), + "Auto-down should not trigger on fatal error if it is disabled."); +} + + ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.c b/tests/net/conn_mgr_conn/src/test_conn_impl.c index c6e4cff6a2d0..a0f2de45c545 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.c +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.c @@ -67,11 +67,16 @@ static void simulate_timeout(struct net_if *target) simulate_event(target, 0); } -static void simulate_fatal_error(struct net_if *target, int reason) +void simulate_fatal_error(struct net_if *target, int reason) { simulate_event(target, reason); } +void simulate_connection_loss(struct net_if *target) +{ + net_if_dormant_on(target); +} + /* Connectivity implementations */ static void inc_call_count(struct test_conn_data *data, bool a) diff --git a/tests/net/conn_mgr_conn/src/test_conn_impl.h b/tests/net/conn_mgr_conn/src/test_conn_impl.h index 1df7e6d02011..bab0c9b3aa9a 100644 --- a/tests/net/conn_mgr_conn/src/test_conn_impl.h +++ b/tests/net/conn_mgr_conn/src/test_conn_impl.h @@ -80,6 +80,25 @@ CONN_MGR_CONN_DECLARE_PUBLIC(TEST_L2_CONN_IMPL_NI); #define SIMULATED_EVENT_DELAY_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS) #define SIMULATED_EVENT_WAIT_TIME K_MSEC(SIMULATED_EVENT_DELAY_MS + 10) +/* Helper API for controlling implementations from tests */ + +/** + * @brief Simulate a connection loss on the target iface. + * + * @param target - iface to simulate connection loss on. + */ +void simulate_connection_loss(struct net_if *target); + +/** + * @brief Simulate a fatal error on the target iface + * + * Please do not simulate events on more than one iface at a time. + * + * @param target - iface to simulate fatal error on. + * @param reason - Reason to be given for the fatal error. + */ +void simulate_fatal_error(struct net_if *target, int reason); + #ifdef __cplusplus } #endif From a0cec8f2d2444b8f24993c6fa4225d3390065a8e Mon Sep 17 00:00:00 2001 From: Georges Oates_Larsen Date: Tue, 2 May 2023 16:46:30 -0700 Subject: [PATCH 342/528] [nrf fromlist] net: conn_mgr: Bulk convenience functions Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/57399 To further reduce the need for networking boilerplate in applications, provide bulk versions of net_if_up, net_if_down, conn_mgr_if_connect, and conn_mgr_if_disconnect that affect all available / eligible ifaces at once. Since it is not intuitive whether these functions should affect ifaces which conn_mgr is ignoring, these functions take an argument that allows this to be specified by the application. Signed-off-by: Georges Oates_Larsen Signed-off-by: Robert Lubos --- include/zephyr/net/conn_mgr_connectivity.h | 51 +++ subsys/net/conn_mgr/conn_mgr_connectivity.c | 145 ++++++- tests/net/conn_mgr_conn/prj.conf | 4 + tests/net/conn_mgr_conn/src/main.c | 439 ++++++++++++++++++++ 4 files changed, 638 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/conn_mgr_connectivity.h b/include/zephyr/net/conn_mgr_connectivity.h index 34d8e04e1537..ba7041a038b3 100644 --- a/include/zephyr/net/conn_mgr_connectivity.h +++ b/include/zephyr/net/conn_mgr_connectivity.h @@ -423,6 +423,57 @@ int conn_mgr_if_set_timeout(struct net_if *iface, int timeout); */ void conn_mgr_conn_init(void); +/** + * @brief Convenience function that takes all available ifaces into the admin-up state. + * + * Essentially a wrapper for net_if_up. + * + * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. + * Otherwise, affect all ifaces. + * @return 0 if all net_if_up calls returned 0, otherwise the first nonzero value + * returned by a net_if_up call. + */ +int conn_mgr_all_if_up(bool skip_ignored); + + +/** + * @brief Convenience function that takes all available ifaces into the admin-down state. + * + * Essentially a wrapper for net_if_down. + * + * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. + * Otherwise, affect all ifaces. + * @return 0 if all net_if_down calls returned 0, otherwise the first nonzero value + * returned by a net_if_down call. + */ +int conn_mgr_all_if_down(bool skip_ignored); + +/** + * @brief Convenience function that takes all available ifaces into the admin-up state, and + * connects those that support connectivity. + * + * Essentially a wrapper for net_if_up and conn_mgr_if_connect. + * + * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. + * Otherwise, affect all ifaces. + * @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero + * value returned by either net_if_up or conn_mgr_if_connect. + */ +int conn_mgr_all_if_connect(bool skip_ignored); + +/** + * @brief Convenience function that disconnects all available ifaces that support connectivity + * without putting them into admin-down state (unless auto-down is enabled for the iface). + * + * Essentially a wrapper for net_if_down. + * + * @param skip_ignored - If true, only affect ifaces that aren't ignored by conn_mgr. + * Otherwise, affect all ifaces. + * @return 0 if all net_if_up and conn_mgr_if_connect calls returned 0, otherwise the first nonzero + * value returned by either net_if_up or conn_mgr_if_connect. + */ +int conn_mgr_all_if_disconnect(bool skip_ignored); + /** * @} */ diff --git a/subsys/net/conn_mgr/conn_mgr_connectivity.c b/subsys/net/conn_mgr/conn_mgr_connectivity.c index 02ea35219f4e..e9fb3766484b 100644 --- a/subsys/net/conn_mgr/conn_mgr_connectivity.c +++ b/subsys/net/conn_mgr/conn_mgr_connectivity.c @@ -8,8 +8,10 @@ LOG_MODULE_REGISTER(conn_mgr_conn, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #include -#include #include +#include + +#include #include "conn_mgr_private.h" @@ -422,3 +424,144 @@ void conn_mgr_conn_init(void) } } } + +enum conn_mgr_conn_all_if_oper { + ALL_IF_UP, + ALL_IF_DOWN, + ALL_IF_CONNECT, + ALL_IF_DISCONNECT +}; + +struct conn_mgr_conn_all_if_ctx { + bool skip_ignored; + enum conn_mgr_conn_all_if_oper operation; + int status; +}; + +/* Per-iface callback for conn_mgr_conn_all_if_up */ +static void conn_mgr_conn_all_if_cb(struct net_if *iface, void *user_data) +{ + int status = 0; + struct conn_mgr_conn_all_if_ctx *context = (struct conn_mgr_conn_all_if_ctx *)user_data; + + /* Skip ignored ifaces if so desired */ + if (context->skip_ignored && conn_mgr_is_iface_ignored(iface)) { + return; + } + + /* Perform the requested operation */ + switch (context->operation) { + case ALL_IF_UP: + /* Do not take iface admin up if it already is. */ + if (net_if_is_admin_up(iface)) { + return; + } + + status = net_if_up(iface); + break; + case ALL_IF_DOWN: + /* Do not take iface admin down if it already is. */ + if (!net_if_is_admin_up(iface)) { + return; + } + + status = net_if_down(iface); + break; + case ALL_IF_CONNECT: + /* Connect operation only supported if iface is bound */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + status = conn_mgr_if_connect(iface); + break; + case ALL_IF_DISCONNECT: + /* Disconnect operation only supported if iface is bound */ + if (!conn_mgr_if_is_bound(iface)) { + return; + } + + status = conn_mgr_if_disconnect(iface); + break; + } + + if (status == 0) { + return; + } + + if (context->status == 0) { + context->status = status; + } + + NET_ERR("%s failed for iface %d (%p). Error: %d", + context->operation == ALL_IF_UP ? "net_if_up" : + context->operation == ALL_IF_DOWN ? "net_if_down" : + context->operation == ALL_IF_CONNECT ? "conn_mgr_if_connect" : + context->operation == ALL_IF_DISCONNECT ? "conn_mgr_if_disconnect" : + "invalid", + net_if_get_by_iface(iface), iface, status + ); +} + +int conn_mgr_all_if_up(bool skip_ignored) +{ + struct conn_mgr_conn_all_if_ctx context = { + .operation = ALL_IF_UP, + .skip_ignored = skip_ignored, + .status = 0 + }; + + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + return context.status; +} + +int conn_mgr_all_if_down(bool skip_ignored) +{ + struct conn_mgr_conn_all_if_ctx context = { + .operation = ALL_IF_DOWN, + .skip_ignored = skip_ignored, + .status = 0 + }; + + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + return context.status; +} + +int conn_mgr_all_if_connect(bool skip_ignored) +{ + /* First, take all ifaces up. + * All bound ifaces will do this automatically when connect is called, but non-bound ifaces + * won't, so we must request it explicitly. + */ + struct conn_mgr_conn_all_if_ctx context = { + .operation = ALL_IF_UP, + .skip_ignored = skip_ignored, + .status = 0 + }; + + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + /* Now connect all ifaces. + * We are delibarately not resetting context.status between these two calls so that + * the first nonzero status code encountered between the two of them is what is returned. + */ + context.operation = ALL_IF_CONNECT; + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + return context.status; +} + +int conn_mgr_all_if_disconnect(bool skip_ignored) +{ + struct conn_mgr_conn_all_if_ctx context = { + .operation = ALL_IF_DISCONNECT, + .skip_ignored = skip_ignored, + .status = 0 + }; + + net_if_foreach(conn_mgr_conn_all_if_cb, &context); + + return context.status; +} diff --git a/tests/net/conn_mgr_conn/prj.conf b/tests/net/conn_mgr_conn/prj.conf index 5ffa0ba9d9fc..ec6b62f6be3f 100644 --- a/tests/net/conn_mgr_conn/prj.conf +++ b/tests/net/conn_mgr_conn/prj.conf @@ -24,3 +24,7 @@ CONFIG_ZTEST_NEW_API=y CONFIG_NET_IF_MAX_IPV4_COUNT=6 CONFIG_NET_IF_MAX_IPV6_COUNT=6 CONFIG_TEST_USERSPACE=y + +# Increased net event queue size needed since this test performs simultaneous events on a +# large number of ifaces. +CONFIG_NET_MGMT_EVENT_QUEUE_SIZE=16 diff --git a/tests/net/conn_mgr_conn/src/main.c b/tests/net/conn_mgr_conn/src/main.c index e7154329d5a8..9d36688ae879 100644 --- a/tests/net/conn_mgr_conn/src/main.c +++ b/tests/net/conn_mgr_conn/src/main.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "conn_mgr_private.h" #include "test_conn_impl.h" #include "test_ifaces.h" @@ -54,6 +55,9 @@ static void reset_test_iface_state(struct net_if *iface) struct conn_mgr_conn_binding *iface_binding = conn_mgr_if_get_binding(iface); struct test_conn_data *iface_data = conn_mgr_if_get_data(iface); + /* Some tests mark ifaces as ignored, this must be reset between each test. */ + conn_mgr_watch_iface(iface); + if (iface_binding) { /* Reset all flags and settings for the binding */ iface_binding->flags = 0; @@ -1139,5 +1143,440 @@ ZTEST(conn_mgr_conn, test_auto_down_fatal) "Auto-down should not trigger on fatal error if it is disabled."); } +/* Verify that all_if_up brings all ifaces up, but only if they are not ignored or + * skip_ignored is false + */ +ZTEST(conn_mgr_conn, test_all_if_up) +{ + /* Ignore an iface */ + conn_mgr_ignore_iface(ifa1); + + /* Take all ifaces up (do not skip ignored) */ + zassert_equal(conn_mgr_all_if_up(false), 0, "conn_mgr_all_if_up should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + + /* Manually take all ifaces down */ + zassert_equal(net_if_down(ifa1), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifa2), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifni), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifnull), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifnone), 0, "net_if_down should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Take all ifaces up (skip ignored) */ + zassert_equal(conn_mgr_all_if_up(true), 0, "conn_mgr_all_if_up should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all except ignored are up */ + zassert_true(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All non-ignored ifaces should be admin-up."); + + zassert_false(net_if_is_admin_up(ifa1), "Ignored iface should not be admin-up."); +} + +/* Verify that all_if_connect brings all ifaces up, and connects all bound ifaces, but only those + * that are not ignored, or all of them if skip_ignored is false + */ +ZTEST(conn_mgr_conn, test_all_if_connect) +{ + /* Ignore a bound and an unbound iface */ + conn_mgr_ignore_iface(ifa1); + conn_mgr_ignore_iface(ifnone); + + /* Connect all ifaces (do not skip ignored) */ + zassert_equal(conn_mgr_all_if_connect(false), 0, "conn_mgr_all_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Verify bound ifaces are connected */ + zassert_true(net_if_is_up(ifa1), "All bound ifaces should be connected."); + zassert_true(net_if_is_up(ifa2), "All bound ifaces should be connected."); + zassert_true(net_if_is_up(ifb), "All bound ifaces should be connected."); + zassert_true(net_if_is_up(ifni), "All bound ifaces should be connected."); + + /* Manually take all ifaces down */ + zassert_equal(conn_mgr_if_disconnect(ifa1), 0, "net_if_disconnect should succeed."); + zassert_equal(conn_mgr_if_disconnect(ifa2), 0, "net_if_disconnect should succeed."); + zassert_equal(conn_mgr_if_disconnect(ifb), 0, "net_if_disconnect should succeed."); + zassert_equal(conn_mgr_if_disconnect(ifni), 0, "net_if_disconnect should succeed."); + + zassert_equal(net_if_down(ifa1), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifa2), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifb), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifni), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifnull), 0, "net_if_down should succeed for all ifaces."); + zassert_equal(net_if_down(ifnone), 0, "net_if_down should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Connect all ifaces (skip ignored) */ + zassert_equal(conn_mgr_all_if_connect(true), 0, "conn_mgr_all_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all except ignored are up */ + zassert_true(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-up."); + + zassert_false(net_if_is_admin_up(ifa1), "All ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnone), "All ignored ifaces should be admin-down."); + + /* Verify bound ifaces are connected, except for ignored */ + zassert_true(net_if_is_up(ifa2), "All non-ignored bound ifaces should be connected."); + zassert_true(net_if_is_up(ifb), "All non-ignored bound ifaces should be connected."); + zassert_true(net_if_is_up(ifni), "All non-ignored bound ifaces should be connected."); + + zassert_false(net_if_is_up(ifa1), "Ignored iface should not be connected."); +} + +/* Verify that all_if_down takes all ifaces down, but only if they are not ignored, + * or skip_ignored is false + */ +ZTEST(conn_mgr_conn, test_all_if_down) +{ + /* Ignore an iface */ + conn_mgr_ignore_iface(ifa1); + + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Take all ifaces down (do not skip ignored) */ + zassert_equal(conn_mgr_all_if_down(false), 0, "conn_mgr_all_if_down should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are down */ + zassert_false(net_if_is_admin_up(ifa1), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifa2), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifb), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifni), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnull), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnone), "All ifaces should be admin-down."); + + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Take all ifaces down (skip ignored) */ + zassert_equal(conn_mgr_all_if_down(true), 0, "conn_mgr_all_if_down should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify that all except the ignored iface is down */ + zassert_false(net_if_is_admin_up(ifa2), "All non-ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifb), "All non-ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifni), "All non-ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnull), "All non-ignored ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnone), "All non-ignored ifaces should be admin-down."); + + zassert_true(net_if_is_admin_up(ifa1), "Ignored iface should be admin-up."); +} + +/* Verify that all_if_disconnect disconnects all bound ifaces, but only if they are not ignored, + * or skip_ignored is false + */ +ZTEST(conn_mgr_conn, test_all_if_disconnect) +{ + /* Ignore a bound iface */ + conn_mgr_ignore_iface(ifa1); + + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Manually connect all bound ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Disconnect all ifaces (do not skip ignored) */ + zassert_equal(conn_mgr_all_if_disconnect(false), 0, + "conn_mgr_all_if_disconnect should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify that all bound ifaces are disconnected */ + zassert_false(net_if_is_up(ifa1), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifa2), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifb), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifni), "All bound ifaces should be disconnected."); + + /* Verify that all ifaces are still up, even if disconnected */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Manually reconnect bound ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Disconnect all ifaces (skip ignored) */ + zassert_equal(conn_mgr_all_if_disconnect(true), 0, + "conn_mgr_all_if_disconnect should succeed."); + k_sleep(K_MSEC(1)); + + /* Verify that all bound ifaces are disconnected, except the ignored iface */ + zassert_false(net_if_is_up(ifa2), "All non-ignored bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifb), "All non-ignored bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifni), "All non-ignored bound ifaces should be disconnected."); + + zassert_true(net_if_is_up(ifa1), "Ignored iface should still be connected"); +} + + +/* Verify that double calls to all_if_up do not raise errors */ +ZTEST(conn_mgr_conn, test_all_if_up_double) +{ + /* Take all ifaces up twice in a row */ + zassert_equal(conn_mgr_all_if_up(false), 0, + "conn_mgr_all_if_up should succeed."); + zassert_equal(conn_mgr_all_if_up(false), 0, + "conn_mgr_all_if_up should succeed twice in a row."); + + /* One more time, after a delay, to be sure */ + k_sleep(K_MSEC(1)); + zassert_equal(conn_mgr_all_if_up(false), 0, + "conn_mgr_all_if_up should succeed twice in a row."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); +} + +/* Verify that double calls to all_if_down do not raise errors */ +ZTEST(conn_mgr_conn, test_all_if_down_double) +{ + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Take all ifaces down twice in a row */ + zassert_equal(conn_mgr_all_if_down(false), 0, + "conn_mgr_all_if_down should succeed."); + zassert_equal(conn_mgr_all_if_down(false), 0, + "conn_mgr_all_if_down should succeed twice in a row."); + + /* One more time, after a delay, to be sure */ + k_sleep(K_MSEC(1)); + zassert_equal(conn_mgr_all_if_down(false), 0, + "conn_mgr_all_if_down should succeed twice in a row."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are down */ + zassert_false(net_if_is_admin_up(ifa1), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifa2), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifb), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifni), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnull), "All ifaces should be admin-down."); + zassert_false(net_if_is_admin_up(ifnone), "All ifaces should be admin-down."); +} + +/* Verify that double calls to all_if_connect do not raise errors */ +ZTEST(conn_mgr_conn, test_all_if_connect_double) +{ + /* Connect all ifaces twice in a row */ + zassert_equal(conn_mgr_all_if_connect(false), 0, + "conn_mgr_all_if_connect should succeed."); + zassert_equal(conn_mgr_all_if_connect(false), 0, + "conn_mgr_all_if_connect should succeed twice in a row."); + + /* One more time, after a delay, to be sure */ + k_sleep(K_MSEC(1)); + zassert_equal(conn_mgr_all_if_connect(false), 0, + "conn_mgr_all_if_connect should succeed twice in a row."); + k_sleep(K_MSEC(1)); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Verify all bound ifaces are connected */ +} + +/* Verify that double calls to all_if_disconnect do not raise errors */ +ZTEST(conn_mgr_conn, test_all_if_disconnect_double) +{ + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Manually connect all bound ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Connect all ifaces twice in a row */ + zassert_equal(conn_mgr_all_if_disconnect(false), 0, + "conn_mgr_all_if_disconnect should succeed."); + zassert_equal(conn_mgr_all_if_disconnect(false), 0, + "conn_mgr_all_if_disconnect should succeed twice in a row."); + + /* One more time, after a delay, to be sure */ + k_sleep(K_MSEC(1)); + zassert_equal(conn_mgr_all_if_disconnect(false), 0, + "conn_mgr_all_if_disconnect should succeed twice in a row."); + k_sleep(K_MSEC(1)); + + /* Verify all bound ifaces are disconnected */ + zassert_false(net_if_is_up(ifa1), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifa2), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifb), "All bound ifaces should be disconnected."); + zassert_false(net_if_is_up(ifni), "All bound ifaces should be disconnected."); + + /* Verify all ifaces are up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); +} + + + +/* Testing error passing for all_if_up/all_if_down is not possible without using an L2 other than + * Dummy, since the dummy L2 is not capable of erroring in response to either of these. + * + * However, since all bulk convenience functions share a single implementation, testing + * connect and disconnect is sufficient to gain acceptable coverage of this behavior for all of + * them. + */ + +/* Verify that all_if_connect successfully forwards errors encountered on individual ifaces */ +ZTEST(conn_mgr_conn, test_all_if_connect_err) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Schedule a connect error on one of the ifaces */ + ifa1_data->api_err = -ECHILD; + + /* Verify that this error is passed to all_if_connect */ + zassert_equal(conn_mgr_all_if_connect(false), -ECHILD, + "conn_mgr_all_if_connect should fail with the requested error."); + k_sleep(K_MSEC(1)); + + /* Verify that all ifaces went admin-up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Verify that all the non-error ifaces are connected */ + zassert_true(net_if_is_up(ifa2), "All non-failing ifaces should be connected."); + zassert_true(net_if_is_up(ifb), "All non-failing ifaces should be connected."); + zassert_true(net_if_is_up(ifni), "All non-failing ifaces should be connected."); + + /* Verify that the error iface is not connected */ + zassert_false(net_if_is_up(ifa1), "The failing iface should not be connected."); +} + +/* Verify that all_if_disconnect successfully forwards errors encountered on individual ifaces */ +ZTEST(conn_mgr_conn, test_all_if_disconnect_err) +{ + struct test_conn_data *ifa1_data = conn_mgr_if_get_data(ifa1); + + /* Manually take all ifaces up */ + zassert_equal(net_if_up(ifa1), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifa2), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifb), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifni), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnull), 0, "net_if_up should succeed for all ifaces."); + zassert_equal(net_if_up(ifnone), 0, "net_if_up should succeed for all ifaces."); + k_sleep(K_MSEC(1)); + + /* Manually connect all bound ifaces */ + zassert_equal(conn_mgr_if_connect(ifa1), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifa2), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifb), 0, "conn_mgr_if_connect should succeed."); + zassert_equal(conn_mgr_if_connect(ifni), 0, "conn_mgr_if_connect should succeed."); + k_sleep(K_MSEC(1)); + + /* Schedule a disconnect error on one of the ifaces */ + ifa1_data->api_err = -ECHILD; + + /* Verify that this error is passed to all_if_disconnect */ + zassert_equal(conn_mgr_all_if_disconnect(false), -ECHILD, + "conn_mgr_all_if_disconnect should fail with the requested error."); + + /* Verify that all ifaces are still admin-up */ + zassert_true(net_if_is_admin_up(ifa1), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifa2), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifb), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifni), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnull), "All ifaces should be admin-up."); + zassert_true(net_if_is_admin_up(ifnone), "All ifaces should be admin-up."); + + /* Verify that all the non-error ifaces are disconnected */ + zassert_false(net_if_is_up(ifa2), "All non-failing ifaces should be disconnected."); + zassert_false(net_if_is_up(ifb), "All non-failing ifaces should be disconnected."); + zassert_false(net_if_is_up(ifni), "All non-failing ifaces should be disconnected."); + + /* Verify that the error iface is not connected */ + zassert_true(net_if_is_up(ifa1), "The failing iface should not be disconnected."); +} ZTEST_SUITE(conn_mgr_conn, NULL, conn_mgr_conn_setup, conn_mgr_conn_before, NULL, NULL); From c8af5dced7cc77c427621aa8149b35ced2d31666 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 26 Jun 2023 13:06:43 +0200 Subject: [PATCH 343/528] [nrf noup] ci: scripts: Update net.mqtt.tls quarantine fixup! [nrf noup] ci: scripts: add quarantine file Add nrf9160dk_nrf9160_ns platform to net.mqtt.tls quarantine, due to FLASH overflow. Signed-off-by: Robert Lubos --- scripts/quarantine.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/quarantine.yaml b/scripts/quarantine.yaml index ca85bcb8cfa4..b2d68b5d3e63 100644 --- a/scripts/quarantine.yaml +++ b/scripts/quarantine.yaml @@ -68,6 +68,7 @@ - net.mqtt.tls platforms: - nrf5340dk_nrf5340_cpuapp_ns + - nrf9160dk_nrf9160_ns comment: "Ram/flash overflows, also in the upstream" - scenarios: From a1202d14b4f5022953829b1567de0204904c193c Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 19 Jun 2023 14:37:04 +0300 Subject: [PATCH 344/528] [nrf fromtree] net: lwm2m: Ensure string termination When writing string data to resources which are string types, we should count in the terminating character into the data length. Corner cases exist where LwM2M resource type is opaque but lwm2m_get_string() or lwm2m_set_string() are used to read/write the data. We must ensure string termination on those case, but terminating character must not be stored in the engine buffer or counted in the data length as this might be considered as part of the binary data. Fixes #59196 Signed-off-by: Seppo Takalo (cherry picked from commit 95cef5f3ab69d3afe93d7fc2498dd509f9847ec0) --- include/zephyr/net/lwm2m.h | 8 +-- subsys/net/lib/lwm2m/lwm2m_registry.c | 53 ++++++++++++----- .../lwm2m/lwm2m_registry/src/lwm2m_registry.c | 57 +++++++++++++++++++ 3 files changed, 99 insertions(+), 19 deletions(-) diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index 222a90026c3d..378ca20b5d63 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -1149,23 +1149,23 @@ int lwm2m_get_opaque(const struct lwm2m_obj_path *path, void *buf, uint16_t bufl * * @param[in] pathstr LwM2M path string "obj/obj-inst/res(/res-inst)" * @param[out] str String buffer to copy data into - * @param[in] strlen Length of buffer + * @param[in] buflen Length of buffer * * @return 0 for success or negative in case of error. */ __deprecated -int lwm2m_engine_get_string(const char *pathstr, void *str, uint16_t strlen); +int lwm2m_engine_get_string(const char *pathstr, void *str, uint16_t buflen); /** * @brief Get resource (instance) value (string) * * @param[in] path LwM2M path as a struct * @param[out] str String buffer to copy data into - * @param[in] strlen Length of buffer + * @param[in] buflen Length of buffer * * @return 0 for success or negative in case of error. */ -int lwm2m_get_string(const struct lwm2m_obj_path *path, void *str, uint16_t strlen); +int lwm2m_get_string(const struct lwm2m_obj_path *path, void *str, uint16_t buflen); /** * @brief Get resource (instance) value (u8) diff --git a/subsys/net/lib/lwm2m/lwm2m_registry.c b/subsys/net/lib/lwm2m/lwm2m_registry.c index cd5191c4c464..bbf0591121d6 100644 --- a/subsys/net/lib/lwm2m/lwm2m_registry.c +++ b/subsys/net/lib/lwm2m/lwm2m_registry.c @@ -436,6 +436,22 @@ int path_to_objs(const struct lwm2m_obj_path *path, struct lwm2m_engine_obj_inst return 0; } + +static bool is_string(const struct lwm2m_obj_path *path) +{ + struct lwm2m_engine_obj_field *obj_field; + int ret; + + ret = path_to_objs(path, NULL, &obj_field, NULL, NULL); + if (ret < 0 || !obj_field) { + return false; + } + if (obj_field->data_type == LWM2M_RES_TYPE_STRING) { + return true; + } + return false; +} + /* User data setter functions */ int lwm2m_set_res_buf(const struct lwm2m_obj_path *path, void *buffer_ptr, uint16_t buffer_len, @@ -632,15 +648,8 @@ static int lwm2m_engine_set(const struct lwm2m_obj_path *path, const void *value break; case LWM2M_RES_TYPE_STRING: - /* check length (note: we add 1 to string length for NULL pad) */ - if (len > max_data_len - 1) { - LOG_ERR("String length %u is too long for res instance %d data", len, - path->res_id); - k_mutex_unlock(®istry_lock); - return -ENOMEM; - } - memcpy((uint8_t *)data_ptr, value, len); - ((uint8_t *)data_ptr)[len] = '\0'; + strncpy(data_ptr, value, len - 1); + ((char *)data_ptr)[len - 1] = '\0'; break; case LWM2M_RES_TYPE_U32: @@ -753,7 +762,14 @@ int lwm2m_engine_set_opaque(const char *pathstr, const char *data_ptr, uint16_t int lwm2m_set_string(const struct lwm2m_obj_path *path, const char *data_ptr) { - return lwm2m_engine_set(path, data_ptr, strlen(data_ptr)); + uint16_t len = strlen(data_ptr); + + /* String resources contain terminator as well, opaque resources don't */ + if (is_string(path)) { + len += 1; + } + + return lwm2m_engine_set(path, data_ptr, len); } int lwm2m_engine_set_string(const char *pathstr, const char *data_ptr) @@ -1134,7 +1150,8 @@ static int lwm2m_engine_get(const struct lwm2m_obj_path *path, void *buf, uint16 break; case LWM2M_RES_TYPE_STRING: - strncpy((uint8_t *)buf, (uint8_t *)data_ptr, buflen); + strncpy(buf, data_ptr, buflen - 1); + ((char *)buf)[buflen - 1] = '\0'; break; case LWM2M_RES_TYPE_U32: @@ -1229,12 +1246,18 @@ int lwm2m_engine_get_opaque(const char *pathstr, void *buf, uint16_t buflen) return lwm2m_get_opaque(&path, buf, buflen); } -int lwm2m_get_string(const struct lwm2m_obj_path *path, void *str, uint16_t strlen) +int lwm2m_get_string(const struct lwm2m_obj_path *path, void *str, uint16_t buflen) { - return lwm2m_engine_get(path, str, strlen); + /* Ensure termination, in case resource is not a string type */ + if (!is_string(path)) { + memset(str, 0, buflen); + buflen -= 1; /* Last terminator cannot be overwritten */ + } + + return lwm2m_engine_get(path, str, buflen); } -int lwm2m_engine_get_string(const char *pathstr, void *str, uint16_t strlen) +int lwm2m_engine_get_string(const char *pathstr, void *str, uint16_t buflen) { struct lwm2m_obj_path path; int ret = 0; @@ -1243,7 +1266,7 @@ int lwm2m_engine_get_string(const char *pathstr, void *str, uint16_t strlen) if (ret < 0) { return ret; } - return lwm2m_get_opaque(&path, str, strlen); + return lwm2m_get_string(&path, str, buflen); } int lwm2m_get_u8(const struct lwm2m_obj_path *path, uint8_t *value) diff --git a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c index 7ffd17d196c6..aa927e6eb0b9 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c +++ b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c @@ -294,3 +294,60 @@ ZTEST(lwm2m_registry, test_callbacks) zassert_equal(ret, 0); zassert_equal(callback_checker, 0x7F); } + +ZTEST(lwm2m_registry, test_strings) +{ + int ret; + char buf[256] = {0}; + struct lwm2m_obj_path path = LWM2M_OBJ(0, 0, 0); + static const char uri[] = "coap://127.0.0.1"; + uint16_t len; + uint8_t *p; + + ret = lwm2m_get_res_buf(&path, (void **)&p, &len, NULL, NULL); + zassert_equal(ret, 0); + memset(p, 0xff, len); /* Pre-fill buffer to check */ + + /* Handle strings in string resources */ + ret = lwm2m_set_string(&path, uri); + zassert_equal(ret, 0); + ret = lwm2m_get_res_buf(&path, (void **)&p, NULL, &len, NULL); + zassert_equal(ret, 0); + zassert_equal(len, sizeof(uri)); + zassert_equal(p[len - 1], '\0'); /* string terminator in buffer */ + zassert_equal(p[len], 0xff); + + ret = lwm2m_get_string(&path, buf, sizeof(buf)); + zassert_equal(ret, 0); + zassert_equal(memcmp(uri, buf, sizeof(uri)), 0); + ret = lwm2m_get_string(&path, buf, sizeof(uri)); + zassert_equal(ret, 0); + ret = lwm2m_get_string(&path, buf, strlen(uri)); + zassert_equal(ret, -ENOMEM); + + /* Handle strings in opaque resources (no terminator) */ + path = LWM2M_OBJ(0, 0, 3); + ret = lwm2m_get_res_buf(&path, (void **)&p, &len, NULL, NULL); + zassert_equal(ret, 0); + memset(p, 0xff, len); /* Pre-fill buffer to check */ + + ret = lwm2m_set_string(&path, uri); + zassert_equal(ret, 0); + ret = lwm2m_get_res_buf(&path, (void **)&p, NULL, &len, NULL); + zassert_equal(ret, 0); + zassert_equal(len, strlen(uri)); /* No terminator counted in data length */ + zassert_equal(p[len - 1], '1'); /* Last character in buffer is not terminator */ + zassert_equal(p[len], 0xff); + memset(buf, 0xff, sizeof(buf)); + ret = lwm2m_get_string(&path, buf, sizeof(buf)); /* get_string ensures termination */ + zassert_equal(ret, 0); + zassert_equal(memcmp(uri, buf, sizeof(uri)), 0); + ret = lwm2m_get_string(&path, buf, sizeof(uri)); + zassert_equal(ret, 0); + ret = lwm2m_get_string(&path, buf, strlen(uri)); + zassert_equal(ret, -ENOMEM); + /* Corner case: we request exactly as much is stored in opaque resource, */ + /* but because we request as a string, it must have room for terminator. */ + ret = lwm2m_get_string(&path, buf, len); + zassert_equal(ret, -ENOMEM); +} From 089ff53159cf3d9def5a9e40e34b09eea1987feb Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 7 Jun 2023 16:39:13 +0300 Subject: [PATCH 345/528] [nrf fromtree] net: lwm2m: Add support for X509 certificates Add support for using X509 certificates. Default settings use ECDSA certificates with SHA256 hash. When different settings are required clients should overwrite struct lwm2m_ctx->load_credentials() and struct lwm2m_ctx->set_socketoptions() Signed-off-by: Seppo Takalo (cherry picked from commit 5c1228770e032a09726a41f5b7efdf0d846cb313) --- include/zephyr/net/lwm2m.h | 33 +++ .../net/lwm2m_client/overlay-dtls-cert.conf | 38 +++ subsys/net/lib/lwm2m/Kconfig | 1 - subsys/net/lib/lwm2m/lwm2m_engine.c | 254 ++++++++++++++---- subsys/net/lib/lwm2m/lwm2m_obj_security.c | 17 +- .../net/lib/lwm2m/lwm2m_engine/CMakeLists.txt | 1 + tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c | 1 + tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h | 2 + 8 files changed, 291 insertions(+), 56 deletions(-) create mode 100644 samples/net/lwm2m_client/overlay-dtls-cert.conf diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index 378ca20b5d63..1cc1b425d0dc 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -2239,5 +2239,38 @@ int lwm2m_engine_enable_cache(char const *resource_path, struct lwm2m_time_serie int lwm2m_enable_cache(const struct lwm2m_obj_path *path, struct lwm2m_time_series_elem *data_cache, size_t cache_len); +/** + * @brief Security modes as defined in LwM2M Security object. + */ +enum lwm2m_security_mode_e { + LWM2M_SECURITY_PSK = 0, /**< Pre-Shared Key mode */ + LWM2M_SECURITY_RAW_PK = 1, /**< Raw Public Key mode */ + LWM2M_SECURITY_CERT = 2, /**< Certificate mode */ + LWM2M_SECURITY_NOSEC = 3, /**< NoSec mode */ + LWM2M_SECURITY_CERT_EST = 4, /**< Certificate mode with EST */ +}; + +/** + * @brief Read security mode from selected security object instance. + * + * This data is only valid if RD client is running. + * + * @param ctx Pointer to client context. + * @return int Positive values are @ref lwm2m_security_mode_e, negative error codes otherwise. + */ +int lwm2m_security_mode(struct lwm2m_ctx *ctx); + +/** + * @brief Set default socket options for DTLS connections. + * + * Engine calls this when @ref lwm2m_ctx::set_socketoptions is not overwritten. + * You may call this from overwritten callback to set extra options after or + * before defaults. + * + * @param ctx Client context + * @return 0 for success or negative in case of error. + */ +int lwm2m_set_default_sockopt(struct lwm2m_ctx *ctx); + #endif /* ZEPHYR_INCLUDE_NET_LWM2M_H_ */ /**@} */ diff --git a/samples/net/lwm2m_client/overlay-dtls-cert.conf b/samples/net/lwm2m_client/overlay-dtls-cert.conf new file mode 100644 index 000000000000..1362115f7466 --- /dev/null +++ b/samples/net/lwm2m_client/overlay-dtls-cert.conf @@ -0,0 +1,38 @@ +CONFIG_LWM2M_DTLS_SUPPORT=y +CONFIG_LWM2M_PEER_PORT=5684 + +# I need room to store certificates +CONFIG_LWM2M_SECURITY_KEY_SIZE=2048 + +# Select Zephyr mbedtls +CONFIG_MBEDTLS=y +CONFIG_MBEDTLS_TLS_VERSION_1_2=y + +# Special MbedTLS changes +CONFIG_MBEDTLS_ENABLE_HEAP=y +CONFIG_MBEDTLS_HEAP_SIZE=32768 +CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN=1500 +CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y + +# Disable RSA, use only ECC certificates +CONFIG_MBEDTLS_KEY_EXCHANGE_RSA_ENABLED=n +# Enable PSK and ECDHE_ECDSA +CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED=y +CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED=y +# We only need prime256v1 curve +CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y +CONFIG_MBEDTLS_ECDH_C=y +CONFIG_MBEDTLS_ECDSA_C=y +CONFIG_MBEDTLS_ECP_C=y +CONFIG_MBEDTLS_CIPHER_CCM_ENABLED=y +CONFIG_MBEDTLS_CIPHER_GCM_ENABLED=y +# Optional: we could use just binary DER certificates +CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT=y + +CONFIG_NET_SOCKETS_SOCKOPT_TLS=y +CONFIG_NET_SOCKETS_TLS_MAX_CONTEXTS=4 +CONFIG_NET_SOCKETS_ENABLE_DTLS=y + +# MbedTLS needs a larger stack +CONFIG_MAIN_STACK_SIZE=2048 +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index 30a25a100f0d..be770b798031 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -316,7 +316,6 @@ config LWM2M_SECURITY_INSTANCE_COUNT config LWM2M_SECURITY_KEY_SIZE int "Buffer size of the security key resources" default 16 - range 16 256 help This setting establishes the size of the key (pre-shared / public) resources in the security object instances. diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index ad11ba61db8d..5c9396e361b5 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -40,6 +40,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #if defined(CONFIG_LWM2M_DTLS_SUPPORT) #include +#include #endif #if defined(CONFIG_DNS_RESOLVER) #include @@ -753,20 +754,40 @@ static void socket_loop(void) } } -#if defined(CONFIG_LWM2M_DTLS_SUPPORT) && defined(CONFIG_TLS_CREDENTIALS) -static int load_tls_credential(struct lwm2m_ctx *client_ctx, uint16_t res_id, +#if defined(CONFIG_LWM2M_DTLS_SUPPORT) +#if defined(CONFIG_TLS_CREDENTIALS) +static void delete_tls_credentials(sec_tag_t tag) +{ + tls_credential_delete(tag, TLS_CREDENTIAL_PSK_ID); + tls_credential_delete(tag, TLS_CREDENTIAL_PSK); + tls_credential_delete(tag, TLS_CREDENTIAL_SERVER_CERTIFICATE); + tls_credential_delete(tag, TLS_CREDENTIAL_PRIVATE_KEY); + tls_credential_delete(tag, TLS_CREDENTIAL_CA_CERTIFICATE); +} + +static bool is_pem(const void *buf, size_t len) +{ + static const char pem_start[] = "-----BEGIN"; + + if (len < sizeof(pem_start)) { + return false; + } + if (strncmp(pem_start, (const char *) buf, sizeof(pem_start) - 1) == 0) { + return true; + } + return false; +} + +static int load_tls_type(struct lwm2m_ctx *client_ctx, uint16_t res_id, enum tls_credential_type type) { int ret = 0; void *cred = NULL; uint16_t cred_len; - uint8_t cred_flags; - - /* ignore error value */ - tls_credential_delete(client_ctx->tls_tag, type); + uint16_t max_len; - ret = lwm2m_get_res_buf(&LWM2M_OBJ(0, client_ctx->sec_obj_inst, res_id), &cred, NULL, - &cred_len, &cred_flags); + ret = lwm2m_get_res_buf(&LWM2M_OBJ(0, client_ctx->sec_obj_inst, res_id), &cred, &max_len, + &cred_len, NULL); if (ret < 0) { LOG_ERR("Unable to get resource data for %d/%d/%d", 0, client_ctx->sec_obj_inst, res_id); @@ -778,6 +799,18 @@ static int load_tls_credential(struct lwm2m_ctx *client_ctx, uint16_t res_id, return -EINVAL; } + /* LwM2M registry stores strings without NULL-terminator, so we need to ensure that + * string based PEM credentials are terminated properly. + */ + if (is_pem(cred, cred_len)) { + if (cred_len >= max_len) { + LOG_ERR("No space for string terminator, cannot handle PEM"); + return -EINVAL; + } + ((uint8_t *) cred)[cred_len] = 0; + cred_len += 1; + } + ret = tls_credential_add(client_ctx->tls_tag, type, cred, cred_len); if (ret < 0) { LOG_ERR("Error setting cred tag %d type %d: Error %d", client_ctx->tls_tag, type, @@ -786,99 +819,212 @@ static int load_tls_credential(struct lwm2m_ctx *client_ctx, uint16_t res_id, return ret; } -#endif /* CONFIG_LWM2M_DTLS_SUPPORT && CONFIG_TLS_CREDENTIALS*/ -int lwm2m_socket_start(struct lwm2m_ctx *client_ctx) +static int lwm2m_load_psk_credentials(struct lwm2m_ctx *ctx) { - socklen_t addr_len; - int flags; int ret; -#if defined(CONFIG_LWM2M_DTLS_SUPPORT) - uint8_t tmp; + delete_tls_credentials(ctx->tls_tag); - if (client_ctx->load_credentials) { - ret = client_ctx->load_credentials(client_ctx); - if (ret < 0) { - return ret; - } + ret = load_tls_type(ctx, 3, TLS_CREDENTIAL_PSK_ID); + if (ret < 0) { + return ret; } -#if defined(CONFIG_TLS_CREDENTIALS) - else { - ret = load_tls_credential(client_ctx, 3, TLS_CREDENTIAL_PSK_ID); - if (ret < 0) { - return ret; - } - ret = load_tls_credential(client_ctx, 5, TLS_CREDENTIAL_PSK); - if (ret < 0) { - return ret; - } + ret = load_tls_type(ctx, 5, TLS_CREDENTIAL_PSK); + return ret; +} + +static int lwm2m_load_x509_credentials(struct lwm2m_ctx *ctx) +{ + int ret; + + delete_tls_credentials(ctx->tls_tag); + + ret = load_tls_type(ctx, 3, TLS_CREDENTIAL_SERVER_CERTIFICATE); + if (ret < 0) { + return ret; + } + ret = load_tls_type(ctx, 5, TLS_CREDENTIAL_PRIVATE_KEY); + if (ret < 0) { + return ret; } -#endif /* CONFIG_TLS_CREDENTIALS */ -#endif /* CONFIG_LWM2M_DTLS_SUPPORT */ - if (client_ctx->sock_fd < 0) { - ret = lwm2m_open_socket(client_ctx); - if (ret) { - return ret; - } + ret = load_tls_type(ctx, 4, TLS_CREDENTIAL_CA_CERTIFICATE); + if (ret < 0) { + return ret; } + return ret; +} +#else - if (client_ctx->set_socketoptions) { - ret = client_ctx->set_socketoptions(client_ctx); - if (ret) { - return ret; +int lwm2m_load_psk_credentials(struct lwm2m_ctx *ctx) +{ + return -EOPNOTSUPP; +} + +int lwm2m_load_x509_credentials(struct lwm2m_ctx *ctx) +{ + return -EOPNOTSUPP; +} +#endif /* CONFIG_TLS_CREDENTIALS*/ + +static int lwm2m_load_tls_credentials(struct lwm2m_ctx *ctx) +{ + switch (lwm2m_security_mode(ctx)) { + case LWM2M_SECURITY_NOSEC: + if (ctx->use_dtls) { + return -EINVAL; } + return 0; + case LWM2M_SECURITY_PSK: + return lwm2m_load_psk_credentials(ctx); + case LWM2M_SECURITY_CERT: + return lwm2m_load_x509_credentials(ctx); + default: + return -EOPNOTSUPP; } +} + +static const int cipher_list_psk[] = { + MBEDTLS_TLS_PSK_WITH_AES_128_CCM_8, +}; + +static const int cipher_list_cert[] = { + MBEDTLS_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, +}; + +#endif /* CONFIG_LWM2M_DTLS_SUPPORT */ + +int lwm2m_set_default_sockopt(struct lwm2m_ctx *ctx) +{ #if defined(CONFIG_LWM2M_DTLS_SUPPORT) - else if (client_ctx->use_dtls) { + if (ctx->use_dtls) { + int ret; + uint8_t tmp; sec_tag_t tls_tag_list[] = { - client_ctx->tls_tag, + ctx->tls_tag, }; - ret = zsock_setsockopt(client_ctx->sock_fd, SOL_TLS, TLS_SEC_TAG_LIST, tls_tag_list, + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_SEC_TAG_LIST, tls_tag_list, sizeof(tls_tag_list)); if (ret < 0) { ret = -errno; LOG_ERR("Failed to set TLS_SEC_TAG_LIST option: %d", ret); - goto error; + return ret; } if (IS_ENABLED(CONFIG_LWM2M_TLS_SESSION_CACHING)) { int session_cache = TLS_SESSION_CACHE_ENABLED; - ret = zsock_setsockopt(client_ctx->sock_fd, SOL_TLS, TLS_SESSION_CACHE, + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_SESSION_CACHE, &session_cache, sizeof(session_cache)); if (ret < 0) { ret = -errno; LOG_ERR("Failed to set TLS_SESSION_CACHE option: %d", errno); - goto error; + return ret; } } - if (client_ctx->hostname_verify && (client_ctx->desthostname != NULL)) { + if (ctx->hostname_verify && (ctx->desthostname != NULL)) { /** store character at len position */ - tmp = client_ctx->desthostname[client_ctx->desthostnamelen]; + tmp = ctx->desthostname[ctx->desthostnamelen]; /** change it to '\0' to pass to socket*/ - client_ctx->desthostname[client_ctx->desthostnamelen] = '\0'; + ctx->desthostname[ctx->desthostnamelen] = '\0'; /** mbedtls ignores length */ - ret = zsock_setsockopt(client_ctx->sock_fd, SOL_TLS, TLS_HOSTNAME, - client_ctx->desthostname, - client_ctx->desthostnamelen); + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_HOSTNAME, + ctx->desthostname, ctx->desthostnamelen); /** restore character */ - client_ctx->desthostname[client_ctx->desthostnamelen] = tmp; + ctx->desthostname[ctx->desthostnamelen] = tmp; if (ret < 0) { ret = -errno; LOG_ERR("Failed to set TLS_HOSTNAME option: %d", ret); - goto error; + return ret; + } + + int verify = TLS_PEER_VERIFY_REQUIRED; + + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_PEER_VERIFY, &verify, + sizeof(verify)); + if (ret) { + LOG_ERR("Failed to set TLS_PEER_VERIFY"); + } + + } else { + /* By default, Mbed TLS tries to verify peer hostname, disable it */ + int verify = TLS_PEER_VERIFY_NONE; + + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_PEER_VERIFY, &verify, + sizeof(verify)); + if (ret) { + LOG_ERR("Failed to set TLS_PEER_VERIFY"); } } + + switch (lwm2m_security_mode(ctx)) { + case LWM2M_SECURITY_PSK: + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_CIPHERSUITE_LIST, + cipher_list_psk, sizeof(cipher_list_psk)); + if (ret) { + LOG_ERR("Failed to set TLS_CIPHERSUITE_LIST"); + } + break; + case LWM2M_SECURITY_CERT: + ret = zsock_setsockopt(ctx->sock_fd, SOL_TLS, TLS_CIPHERSUITE_LIST, + cipher_list_cert, sizeof(cipher_list_cert)); + if (ret) { + LOG_ERR("Failed to set TLS_CIPHERSUITE_LIST (rc %d, errno %d)", ret, + errno); + } + break; + default: + return -EOPNOTSUPP; + } + } +#else + if (!IS_ENABLED(CONFIG_LWM2M_DTLS_SUPPORT) && ctx->use_dtls) { + return -EOPNOTSUPP; + } +#endif /* CONFIG_LWM2M_DTLS_SUPPORT */ + return 0; +} + +int lwm2m_socket_start(struct lwm2m_ctx *client_ctx) +{ + socklen_t addr_len; + int flags; + int ret; + +#if defined(CONFIG_LWM2M_DTLS_SUPPORT) + if (client_ctx->load_credentials) { + ret = client_ctx->load_credentials(client_ctx); + } else { + ret = lwm2m_load_tls_credentials(client_ctx); + } + if (ret < 0) { + return ret; } #endif /* CONFIG_LWM2M_DTLS_SUPPORT */ + + if (client_ctx->sock_fd < 0) { + ret = lwm2m_open_socket(client_ctx); + if (ret) { + return ret; + } + } + + if (client_ctx->set_socketoptions) { + ret = client_ctx->set_socketoptions(client_ctx); + } else { + ret = lwm2m_set_default_sockopt(client_ctx); + } + if (ret) { + goto error; + } + if ((client_ctx->remote_addr).sa_family == AF_INET) { addr_len = sizeof(struct sockaddr_in); } else if ((client_ctx->remote_addr).sa_family == AF_INET6) { diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_security.c b/subsys/net/lib/lwm2m/lwm2m_obj_security.c index c590350e61d1..874925c39d89 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_security.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_security.c @@ -56,7 +56,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define MAX_INSTANCE_COUNT CONFIG_LWM2M_SECURITY_INSTANCE_COUNT #define SECURITY_URI_LEN 255 -#define IDENTITY_LEN 128 +#define IDENTITY_LEN CONFIG_LWM2M_SECURITY_KEY_SIZE #define KEY_LEN CONFIG_LWM2M_SECURITY_KEY_SIZE /* @@ -212,6 +212,21 @@ int lwm2m_security_index_to_inst_id(int index) return inst[index].obj_inst_id; } +int lwm2m_security_mode(struct lwm2m_ctx *ctx) +{ + int ret; + uint8_t mode; + struct lwm2m_obj_path path = + LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, ctx->sec_obj_inst, SECURITY_MODE_ID); + + ret = lwm2m_get_u8(&path, &mode); + if (ret) { + return ret; + } + return (int)mode; +} + + static int lwm2m_security_init(void) { struct lwm2m_engine_obj_inst *obj_inst = NULL; diff --git a/tests/net/lib/lwm2m/lwm2m_engine/CMakeLists.txt b/tests/net/lib/lwm2m/lwm2m_engine/CMakeLists.txt index 8d4a0e1ddf42..36e161c6b11d 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/CMakeLists.txt +++ b/tests/net/lib/lwm2m/lwm2m_engine/CMakeLists.txt @@ -15,6 +15,7 @@ target_sources(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/lwm2m/lwm2m_engine.c) target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src) target_include_directories(app PRIVATE ${ZEPHYR_BASE}/include/) target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/net/lib/lwm2m/) +target_include_directories(app PRIVATE ${ZEPHYR_BASE}/../modules/crypto/mbedtls/include/) add_compile_definitions(CONFIG_LWM2M_ENGINE_MAX_PENDING=2) add_compile_definitions(CONFIG_LWM2M_ENGINE_MAX_REPLIES=2) diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c index 2611687f4758..95790e39cdb0 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c @@ -39,6 +39,7 @@ DEFINE_FAKE_VALUE_FUNC(struct lwm2m_engine_obj_field *, lwm2m_get_engine_obj_fie DEFINE_FAKE_VALUE_FUNC(int, lwm2m_get_bool, const struct lwm2m_obj_path *, bool *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_delete_obj_inst, uint16_t, uint16_t); DEFINE_FAKE_VOID_FUNC(lwm2m_clear_block_contexts); +DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_mode, struct lwm2m_ctx *); static sys_slist_t obs_obj_path_list = SYS_SLIST_STATIC_INIT(&obs_obj_path_list); sys_slist_t *lwm2m_obs_obj_path_list(void) diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h index a27c658642c7..c6a61ac180b1 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.h @@ -54,6 +54,7 @@ DECLARE_FAKE_VALUE_FUNC(int, lwm2m_get_bool, const struct lwm2m_obj_path *, bool DECLARE_FAKE_VALUE_FUNC(int, lwm2m_delete_obj_inst, uint16_t, uint16_t); DECLARE_FAKE_VOID_FUNC(lwm2m_clear_block_contexts); DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_connect, int, const struct sockaddr *, socklen_t); +DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_mode, struct lwm2m_ctx *); #define DO_FOREACH_FAKE(FUNC) \ do { \ @@ -81,6 +82,7 @@ DECLARE_FAKE_VALUE_FUNC(int, z_impl_zsock_connect, int, const struct sockaddr *, FUNC(lwm2m_delete_obj_inst) \ FUNC(lwm2m_clear_block_contexts) \ FUNC(z_impl_zsock_connect) \ + FUNC(lwm2m_security_mode) \ } while (0) #endif /* STUBS_H */ From 4a5d19fbe742529f2d19224ff28c4421ee823b8d Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 15 Jun 2023 14:40:20 +0300 Subject: [PATCH 346/528] [nrf fromtree] doc: Document various LwM2M security modes Add documentation regarding various LwM2M security modes. Signed-off-by: Seppo Takalo (cherry picked from commit 55451c6d6e3229a0e65737fc2a045ebfd2052e6b) --- doc/connectivity/networking/api/lwm2m.rst | 73 +++++++++++++++++------ include/zephyr/net/lwm2m.h | 18 +++--- 2 files changed, 63 insertions(+), 28 deletions(-) diff --git a/doc/connectivity/networking/api/lwm2m.rst b/doc/connectivity/networking/api/lwm2m.rst index 0ee4eb01d429..6d26205511e3 100644 --- a/doc/connectivity/networking/api/lwm2m.rst +++ b/doc/connectivity/networking/api/lwm2m.rst @@ -364,14 +364,44 @@ endpoint name. This is important as it needs to be unique per LwM2M server: (void)memset(&client, 0x0, sizeof(client)); lwm2m_rd_client_start(&client, "unique-endpoint-name", 0, rd_client_event); -Using LwM2M library with DTLS -***************************** +.. _lwm2m_security: -The Zephyr LwM2M library can be used with DTLS transport for secure -communication by selecting :kconfig:option:`CONFIG_LWM2M_DTLS_SUPPORT`. In the client -initialization we need to create a PSK and identity. These need to match -the security information loaded onto the LwM2M server. Normally, the -endpoint name is used to lookup the related security information: +LwM2M security modes +******************** + +The Zephyr LwM2M library can be used either without security or use DTLS to secure the communication channel. +When using DTLS with the LwM2M engine, PSK (Pre-Shared Key) and X.509 certificates are the security modes that can be used to secure the communication. +The engine uses LwM2M Security object (Id 0) to read the stored credentials and feed keys from the security object into +the TLS credential subsystem, see :ref:`secure sockets documentation `. +Enable the :kconfig:option:`CONFIG_LWM2M_DTLS_SUPPORT` Kconfig option to use the security. + +Depending on the selected mode, the security object must contain following data: + +PSK + Security Mode (Resource ID 2) set to zero (Pre-Shared Key mode). + Identity (Resource ID 3) contains PSK ID in binary form. + Secret key (Resource ID 5) contains the PSK key in binary form. + If the key or identity is provided as a hex string, it must be converted to binary before storing into the security object. + +X509 + When X509 certificates are used, set Security Mode (ID 2) to ``2`` (Certificate mode). + Identity (ID 3) is used to store the client certificate and Secret key (ID 5) must have a private key associated with the certificate. + Server Public Key resource (ID 4) must contain a server certificate or CA certificate used to sign the certificate chain. + If the :kconfig:option:`CONFIG_MBEDTLS_PEM_CERTIFICATE_FORMAT` Kconfig option is enabled, certificates and private key can be entered in PEM format. + Otherwise, they must be in binary DER format. + +NoSec + When no security is used, set Security Mode (Resource ID 2) to ``3`` (NoSec). + +In all modes, Server URI resource (ID 0) must contain the full URI for the target server. +When DNS names are used, the DNS resolver must be enabled. + +LwM2M stack provides callbacks in the :c:struct:`lwm2m_ctx` structure. +They are used to feed keys from the LwM2M security object into the TLS credential subsystem. +By default, these callbacks can be left as NULL pointers, in which case default callbacks are used. +When an external TLS stack, or non-default socket options are required, you can overwrite the :c:func:`lwm2m_ctx.load_credentials` or :c:func:`lwm2m_ctx.set_socketoptions` callbacks. + +An example of setting up the security object for PSK mode: .. code-block:: c @@ -383,21 +413,26 @@ endpoint name is used to lookup the related security information: static const char client_identity[] = "Client_identity"; -Next we alter the ``Security`` object resources to include DTLS security -information. The server URL should begin with ``coaps://`` to indicate security -is required. Assign a 0 value (Pre-shared Key mode) to the ``Security Mode`` -resource. Lastly, set the client identity and PSK resources. + lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 0), "coaps://lwm2m.example.com"); + lwm2m_set_u8(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 2), LWM2M_SECURITY_PSK); + /* Set the client identity as a string, but this could be binary as well */ + lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 3), client_identity); + /* Set the client pre-shared key (PSK) */ + lwm2m_set_opaque(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 5), client_psk, sizeof(client_psk)); + +An example of setting up the security object for X509 certificate mode: .. code-block:: c - /* Use coaps:// for server URL protocol */ - lwm2m_set_string(&LWM2M_OBJ(0, 0, 0), "coaps://5.39.83.206"); - /* 0 = Pre-Shared Key mode */ - lwm2m_set_u8(&LWM2M_OBJ(0, 0, 2), 0); - /* Set the client identity */ - lwm2m_set_string(&LWM2M_OBJ(0, 0, 3), (char *)client_identity); - /* Set the client pre-shared key (PSK) */ - lwm2m_set_opaque(&LWM2M_OBJ(0, 0, 5), (void *)client_psk, sizeof(client_psk)); + static const char certificate[] = "-----BEGIN CERTIFICATE-----\nMIIB6jCCAY+gAw..."; + static const char key[] = "-----BEGIN EC PRIVATE KEY-----\nMHcCAQ..."; + static const char root_ca[] = "-----BEGIN CERTIFICATE-----\nMIIBaz..."; + + lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 0), "coaps://lwm2m.example.com"); + lwm2m_set_u8(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 2), LWM2M_SECURITY_CERT); + lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 3), certificate); + lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 5), key); + lwm2m_set_string(&LWM2M_OBJ(LWM2M_OBJECT_SECURITY_ID, 0, 5), root_ca); Before calling :c:func:`lwm2m_rd_client_start` assign the tls_tag # where the LwM2M library should store the DTLS information prior to connection (normally a diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index 1cc1b425d0dc..dea6c1ebb538 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -145,7 +145,7 @@ struct lwm2m_ctx { */ void *processed_req; -#if defined(CONFIG_LWM2M_DTLS_SUPPORT) +#if defined(CONFIG_LWM2M_DTLS_SUPPORT) || defined(__DOXYGEN__) /** TLS tag is set by client as a reference used when the * LwM2M engine calls tls_credential_(add|delete) */ @@ -182,7 +182,7 @@ struct lwm2m_ctx { */ bool connection_suspended; -#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED) +#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED) || defined(__DOXYGEN__) /** * Flag to indicate that the client is buffering Notifications and Send messages. * True value buffer Notifications and Send messages. @@ -416,7 +416,7 @@ int lwm2m_device_add_err(uint8_t error_code); #define RESULT_UPDATE_FAILED 8 #define RESULT_UNSUP_PROTO 9 -#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_OBJ_SUPPORT) +#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_OBJ_SUPPORT) || defined(__DOXYGEN__) /** * @brief Set data callback for firmware block transfer. * @@ -489,7 +489,7 @@ void lwm2m_firmware_set_cancel_cb_inst(uint16_t obj_inst_id, lwm2m_engine_user_c */ lwm2m_engine_user_cb_t lwm2m_firmware_get_cancel_cb_inst(uint16_t obj_inst_id); -#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_SUPPORT) +#if defined(CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_SUPPORT) || defined(__DOXYGEN__) /** * @brief Set data callback to handle firmware update execute events. * @@ -529,7 +529,7 @@ lwm2m_engine_execute_cb_t lwm2m_firmware_get_update_cb_inst(uint16_t obj_inst_id #endif -#if defined(CONFIG_LWM2M_SWMGMT_OBJ_SUPPORT) +#if defined(CONFIG_LWM2M_SWMGMT_OBJ_SUPPORT) || defined(__DOXYGEN__) /** * @brief Set callback to handle software activation requests @@ -623,7 +623,7 @@ int lwm2m_swmgmt_install_completed(uint16_t obj_inst_id, int error_code); #endif -#if defined(CONFIG_LWM2M_EVENT_LOG_OBJ_SUPPORT) +#if defined(CONFIG_LWM2M_EVENT_LOG_OBJ_SUPPORT) || defined(__DOXYGEN__) /** * @brief Set callback to read log data @@ -2253,7 +2253,7 @@ enum lwm2m_security_mode_e { /** * @brief Read security mode from selected security object instance. * - * This data is only valid if RD client is running. + * This data is valid only if RD client is running. * * @param ctx Pointer to client context. * @return int Positive values are @ref lwm2m_security_mode_e, negative error codes otherwise. @@ -2263,8 +2263,8 @@ int lwm2m_security_mode(struct lwm2m_ctx *ctx); /** * @brief Set default socket options for DTLS connections. * - * Engine calls this when @ref lwm2m_ctx::set_socketoptions is not overwritten. - * You may call this from overwritten callback to set extra options after or + * The engine calls this when @ref lwm2m_ctx::set_socketoptions is not overwritten. + * You can call this from the overwritten callback to set extra options after or * before defaults. * * @param ctx Client context From 12e265f4a25aa98dc8cb101be28c3af1641ad556 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 14 Jun 2023 14:47:20 +0300 Subject: [PATCH 347/528] [nrf fromtree] net: lwm2m: Fix pause and resume on non-closed sockets Pause and resume functionality was written into assumption that sockets are closed before resuming. With use new options CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE or CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE this is not always true. Fix the state machine, so that on those cases, sockets are not closed and resume is always similar like from the QUEUE mode. Signed-off-by: Seppo Takalo (cherry picked from commit dc7fbc5d2eef67dba66c6387c57d4aee973ea952) --- subsys/net/lib/lwm2m/lwm2m_engine.c | 39 +++++----- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 72 ++++++++++--------- .../lib/lwm2m/lwm2m_rd_client/CMakeLists.txt | 1 + .../net/lib/lwm2m/lwm2m_rd_client/src/stubs.c | 1 + .../net/lib/lwm2m/lwm2m_rd_client/src/stubs.h | 1 + 5 files changed, 60 insertions(+), 54 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 5c9396e361b5..fa74666f0925 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -155,29 +155,27 @@ int lwm2m_open_socket(struct lwm2m_ctx *client_ctx) int lwm2m_close_socket(struct lwm2m_ctx *client_ctx) { - int ret = 0; - if (client_ctx->sock_fd >= 0) { - ret = zsock_close(client_ctx->sock_fd); + int ret = zsock_close(client_ctx->sock_fd); + if (ret) { LOG_ERR("Failed to close socket: %d", errno); ret = -errno; return ret; } + } - client_ctx->sock_fd = -1; - client_ctx->connection_suspended = true; + client_ctx->sock_fd = -1; + client_ctx->connection_suspended = true; #if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED) - /* Enable Queue mode buffer store */ - client_ctx->buffer_client_messages = true; + /* Enable Queue mode buffer store */ + client_ctx->buffer_client_messages = true; #endif - lwm2m_socket_update(client_ctx); - } + lwm2m_socket_update(client_ctx); - return ret; + return 0; } - int lwm2m_socket_suspend(struct lwm2m_ctx *client_ctx) { int ret = 0; @@ -185,13 +183,11 @@ int lwm2m_socket_suspend(struct lwm2m_ctx *client_ctx) if (client_ctx->sock_fd >= 0 && !client_ctx->connection_suspended) { int socket_temp_id = client_ctx->sock_fd; + /* Prevent closing */ client_ctx->sock_fd = -1; - client_ctx->connection_suspended = true; -#if defined(CONFIG_LWM2M_QUEUE_MODE_ENABLED) - /* Enable Queue mode buffer store */ - client_ctx->buffer_client_messages = true; -#endif - lwm2m_socket_update(client_ctx); + /* Just mark as suspended */ + lwm2m_close_socket(client_ctx); + /* store back the socket handle */ client_ctx->sock_fd = socket_temp_id; } @@ -203,16 +199,19 @@ int lwm2m_engine_connection_resume(struct lwm2m_ctx *client_ctx) int ret; if (client_ctx->connection_suspended) { - if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE)) { + if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE) || + IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE)) { + LOG_DBG("Resume suspended connection"); lwm2m_socket_update(client_ctx); + client_ctx->connection_suspended = false; } else { + LOG_DBG("Close and resume a new connection"); lwm2m_close_socket(client_ctx); - client_ctx->connection_suspended = false; ret = lwm2m_open_socket(client_ctx); if (ret) { return ret; } - LOG_DBG("Resume suspended connection"); + client_ctx->connection_suspended = false; return lwm2m_socket_start(client_ctx); } } diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index d89ea3c5f79c..3686b8855a24 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -1415,17 +1415,24 @@ int lwm2m_rd_client_pause(void) k_mutex_unlock(&client.mutex); LOG_ERR("Cannot pause. No context"); return -EPERM; - } else if (client.engine_state == ENGINE_SUSPENDED) { + } else if (sm_is_suspended()) { k_mutex_unlock(&client.mutex); LOG_ERR("LwM2M client already suspended"); return 0; } LOG_INF("Suspend client"); - if (!client.ctx->connection_suspended && client.ctx->event_cb) { + if (client.ctx->event_cb) { client.ctx->event_cb(client.ctx, event); } + /* Suspend or close the socket */ + if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_CLOSE_SOCKET_AT_IDLE)) { + lwm2m_close_socket(client.ctx); + } else { + lwm2m_socket_suspend(client.ctx); + } + suspended_client_state = get_sm_state(); client.engine_state = ENGINE_SUSPENDED; @@ -1436,26 +1443,18 @@ int lwm2m_rd_client_pause(void) int lwm2m_rd_client_resume(void) { - int ret; - k_mutex_lock(&client.mutex, K_FOREVER); - if (!client.ctx) { + if (!lwm2m_rd_client_is_suspended(client.ctx)) { k_mutex_unlock(&client.mutex); - LOG_WRN("Cannot resume. No context"); - return -EPERM; - } - - if (client.engine_state != ENGINE_SUSPENDED) { - k_mutex_unlock(&client.mutex); - LOG_WRN("Cannot resume state is not Suspended"); + LOG_WRN("Cannot resume, state is not suspended"); return -EPERM; } LOG_INF("Resume Client state"); - lwm2m_close_socket(client.ctx); + if (suspended_client_state == ENGINE_UPDATE_SENT) { - /* Set back to Registration done for enable trigger Update */ + /* Set back to Registration done and trigger an update */ suspended_client_state = ENGINE_REGISTRATION_DONE; } /* Clear Possible pending RD Client message */ @@ -1463,18 +1462,24 @@ int lwm2m_rd_client_resume(void) client.engine_state = suspended_client_state; - if (!client.last_update || - (client.lifetime <= (k_uptime_get() - client.last_update) / 1000)) { - client.engine_state = ENGINE_DO_REGISTRATION; - } else { - lwm2m_rd_client_connection_resume(client.ctx); - client.trigger_update = true; + /* Do we need to resume the bootstrap? */ +#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) + if (sm_is_bootstrap()) { + client.engine_state = ENGINE_DO_BOOTSTRAP_REG; } - - ret = lwm2m_open_socket(client.ctx); - if (ret) { - LOG_ERR("Socket Open Fail"); - client.engine_state = ENGINE_INIT; +#endif + /* Or do we resume into registration state */ + if (client.engine_state >= ENGINE_DO_REGISTRATION && + client.engine_state <= ENGINE_SUSPENDED) { + if (!client.last_update || + (client.lifetime <= (k_uptime_get() - client.last_update) / 1000)) { + /* No lifetime left, register again */ + client.engine_state = ENGINE_DO_REGISTRATION; + } else { + /* Resume similarly like from QUEUE mode */ + client.engine_state = ENGINE_REGISTRATION_DONE_RX_OFF; + lwm2m_rd_client_connection_resume(client.ctx); + } } k_mutex_unlock(&client.mutex); @@ -1499,22 +1504,21 @@ int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx) } if (client.engine_state == ENGINE_REGISTRATION_DONE_RX_OFF) { -#ifdef CONFIG_LWM2M_DTLS_SUPPORT /* - * Switch state for triggering a proper registration message - * if CONFIG_LWM2M_TLS_SESSION_CACHING is false we force full - * registration after Fully DTLS handshake + * Switch state to triggering a proper registration message + * If the socket stays open (Connection ID or no-sec), or we have TLS session cache, + * we can trigger the update, otherwise fall back to full registration. */ - if (IS_ENABLED(CONFIG_LWM2M_TLS_SESSION_CACHING)) { + if ((IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUSPEND_SOCKET_AT_IDLE) && + IS_ENABLED(CONFIG_LWM2M_TLS_SESSION_CACHING)) || + (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE) || + IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE)) || + !IS_ENABLED(CONFIG_LWM2M_DTLS_SUPPORT)) { client.engine_state = ENGINE_REGISTRATION_DONE; client.trigger_update = true; } else { client.engine_state = ENGINE_DO_REGISTRATION; } -#else - client.engine_state = ENGINE_REGISTRATION_DONE; - client.trigger_update = true; -#endif } return 0; diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt index 2a6e8141a1ce..d69ed3856211 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/CMakeLists.txt @@ -30,3 +30,4 @@ add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_UPTIME=10) add_compile_definitions(CONFIG_LWM2M_LOG_LEVEL=4) add_compile_definitions(CONFIG_LWM2M_QUEUE_MODE_ENABLED=1) add_compile_definitions(CONFIG_LWM2M_TLS_SESSION_CACHING=1) +add_compile_definitions(CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE=1) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c index 7d0bd84c1ac0..c0df43d3b931 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c @@ -66,6 +66,7 @@ int lwm2m_get_bool_fake_default(const struct lwm2m_obj_path *path, bool *value) DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_start, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_close, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_close_socket, struct lwm2m_ctx *); +DEFINE_FAKE_VALUE_FUNC(int, lwm2m_socket_suspend, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_inst_id_to_index, uint16_t); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_engine_connection_resume, struct lwm2m_ctx *); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_push_queued_buffers, struct lwm2m_ctx *); diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h index b07346de889b..70c073afbdbc 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h @@ -51,6 +51,7 @@ int lwm2m_get_bool_fake_default(const struct lwm2m_obj_path *path, bool *value); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_start, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_close, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_close_socket, struct lwm2m_ctx *); +DECLARE_FAKE_VALUE_FUNC(int, lwm2m_socket_suspend, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_inst_id_to_index, uint16_t); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_engine_connection_resume, struct lwm2m_ctx *); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_push_queued_buffers, struct lwm2m_ctx *); From 5bc266621a7ae68ba6ae07c401b40d49662965a6 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 19 Jun 2023 12:25:43 +0100 Subject: [PATCH 348/528] [nrf fromtree] mgmt: mcumgr: smp: Allow preventing command execution via hook Adds status checking to the command status hook which allows an application to inspect a request and, optionally, reject it. Signed-off-by: Jamie McCrae (cherry picked from commit 6877ad413f076d7aa48582a1877748b1cca13d5f) --- subsys/mgmt/mcumgr/smp/src/smp.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/subsys/mgmt/mcumgr/smp/src/smp.c b/subsys/mgmt/mcumgr/smp/src/smp.c index 75e11f2b6c63..56c9cc17b3b0 100644 --- a/subsys/mgmt/mcumgr/smp/src/smp.c +++ b/subsys/mgmt/mcumgr/smp/src/smp.c @@ -201,6 +201,7 @@ static int smp_handle_single_payload(struct smp_streamer *cbuf, const struct smp mgmt_handler_fn handler_fn; int rc; #if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS) + enum mgmt_cb_return status; struct mgmt_evt_op_cmd_arg cmd_recv; int32_t ret_rc; uint16_t ret_group; @@ -229,18 +230,39 @@ static int smp_handle_single_payload(struct smp_streamer *cbuf, const struct smp zcbor_map_start_encode(cbuf->writer->zs, CONFIG_MCUMGR_SMP_CBOR_MAX_MAIN_MAP_ENTRIES); + MGMT_CTXT_SET_RC_RSN(cbuf, NULL); + #if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS) cmd_recv.group = req_hdr->nh_group; cmd_recv.id = req_hdr->nh_id; cmd_recv.err = MGMT_ERR_EOK; - (void)mgmt_callback_notify(MGMT_EVT_OP_CMD_RECV, &cmd_recv, sizeof(cmd_recv), - &ret_rc, &ret_group); + /* Send request to application to check if handler should run or not. */ + status = mgmt_callback_notify(MGMT_EVT_OP_CMD_RECV, &cmd_recv, sizeof(cmd_recv), + &ret_rc, &ret_group); + + /* Skip running the command if a handler reported an error and return that + * instead. + */ + if (status != MGMT_CB_OK) { + if (status == MGMT_CB_ERROR_RC) { + rc = ret_rc; + } else { + bool ok = smp_add_cmd_ret(cbuf->writer->zs, ret_group, + (uint16_t)ret_rc); + + rc = (ok ? MGMT_ERR_EOK : MGMT_ERR_EMSGSIZE); + } + + goto end; + } #endif - MGMT_CTXT_SET_RC_RSN(cbuf, NULL); rc = handler_fn(cbuf); +#if defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS) +end: +#endif /* End response payload. */ if (!zcbor_map_end_encode(cbuf->writer->zs, CONFIG_MCUMGR_SMP_CBOR_MAX_MAIN_MAP_ENTRIES) && From 3e34453cd9067f83338eb26e1bfffa740549b98a Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Mon, 19 Jun 2023 12:23:53 +0100 Subject: [PATCH 349/528] [nrf fromtree] mgmt: mcumgr: grp: img_mgmt: Fix missing define Fixes a missing define which causes a build failure. Signed-off-by: Jamie McCrae (cherry picked from commit 3e71797ba229121413103e787a49630bc06520ef) --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 48d79edd4d24..5b1699c620f7 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -474,7 +474,9 @@ img_mgmt_upload(struct smp_streamer *ctxt) bool data_match = false; #endif -#if defined(CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK) || defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS) +#if defined(CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK) || \ +defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS) || \ +defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS) enum mgmt_cb_return status; int32_t ret_rc; uint16_t ret_group; From 975c26115311332f0a501fa103fd84e71b9542ba Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Sun, 25 Jun 2023 13:41:09 +0200 Subject: [PATCH 350/528] [nrf fromtree] mcumgr: img_mgmt: Fix unused "status" variable warning Changes aligns ifdefs to fix compilation warnings related to unused "status" variable. Signed-off-by: Marek Pieta (cherry picked from commit 6bbd6d37946be78f22451a234b15c9918f213183) --- subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 5b1699c620f7..3a5f87ba8620 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -474,10 +474,13 @@ img_mgmt_upload(struct smp_streamer *ctxt) bool data_match = false; #endif +#if defined(CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK) + enum mgmt_cb_return status; +#endif + #if defined(CONFIG_MCUMGR_GRP_IMG_UPLOAD_CHECK_HOOK) || \ defined(CONFIG_MCUMGR_GRP_IMG_STATUS_HOOKS) || \ defined(CONFIG_MCUMGR_SMP_COMMAND_STATUS_HOOKS) - enum mgmt_cb_return status; int32_t ret_rc; uint16_t ret_group; #endif From cb9dbd647ccaacaa9cc9079f65e4af36d76ab108 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 26 Jun 2023 17:32:04 +0300 Subject: [PATCH 351/528] [nrf fromlist] net: lwm2m: Allow setting string to zero length Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/59765 Lwm2m firmware object have defined a write of zero length string as a cancel operation. So allow lwm2m_set_opaque(path, NULL, 0); Signed-off-by: Seppo Takalo --- subsys/net/lib/lwm2m/lwm2m_registry.c | 14 +++++--- .../lwm2m/lwm2m_registry/src/lwm2m_registry.c | 34 +++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_registry.c b/subsys/net/lib/lwm2m/lwm2m_registry.c index bbf0591121d6..f34a01fe5ead 100644 --- a/subsys/net/lib/lwm2m/lwm2m_registry.c +++ b/subsys/net/lib/lwm2m/lwm2m_registry.c @@ -626,7 +626,7 @@ static int lwm2m_engine_set(const struct lwm2m_obj_path *path, const void *value return ret; } - if (memcmp(data_ptr, value, len) != 0) { + if (memcmp(data_ptr, value, len) != 0 || res_inst->data_len != len) { changed = true; } @@ -644,12 +644,18 @@ static int lwm2m_engine_set(const struct lwm2m_obj_path *path, const void *value switch (obj_field->data_type) { case LWM2M_RES_TYPE_OPAQUE: - memcpy((uint8_t *)data_ptr, value, len); + if (len) { + memcpy((uint8_t *)data_ptr, value, len); + } break; case LWM2M_RES_TYPE_STRING: - strncpy(data_ptr, value, len - 1); - ((char *)data_ptr)[len - 1] = '\0'; + if (len) { + strncpy(data_ptr, value, len - 1); + ((char *)data_ptr)[len - 1] = '\0'; + } else { + ((char *)data_ptr)[0] = '\0'; + } break; case LWM2M_RES_TYPE_U32: diff --git a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c index aa927e6eb0b9..a5d1240fd909 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c +++ b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c @@ -351,3 +351,37 @@ ZTEST(lwm2m_registry, test_strings) ret = lwm2m_get_string(&path, buf, len); zassert_equal(ret, -ENOMEM); } + +ZTEST(lwm2m_registry, test_null_strings) +{ + int ret; + char buf[256] = {0}; + struct lwm2m_obj_path path = LWM2M_OBJ(0, 0, 0); + + ret = lwm2m_register_post_write_callback(&path, post_write_cb); + zassert_equal(ret, 0); + + callback_checker = 0; + ret = lwm2m_set_string(&path, "string"); + zassert_equal(ret, 0); + zassert_equal(callback_checker, 0x02); + ret = lwm2m_get_string(&path, buf, sizeof(buf)); + zassert_equal(ret, 0); + zassert_equal(strlen(buf), strlen("string")); + + callback_checker = 0; + ret = lwm2m_set_string(&path, ""); + zassert_equal(ret, 0); + zassert_equal(callback_checker, 0x02); + ret = lwm2m_get_string(&path, buf, sizeof(buf)); + zassert_equal(ret, 0); + zassert_equal(strlen(buf), 0); + + callback_checker = 0; + ret = lwm2m_set_opaque(&path, NULL, 0); + zassert_equal(ret, 0); + zassert_equal(callback_checker, 0x02); + ret = lwm2m_get_string(&path, buf, sizeof(buf)); + zassert_equal(ret, 0); + zassert_equal(strlen(buf), 0); +} From 2d89aaf49fca9d2e5853b48f0646b47b09ce3cb9 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 23 Jun 2023 01:53:52 +0530 Subject: [PATCH 352/528] [nrf fromtree] net: wifi: Fix a typo Typo in TWT error strings. Signed-off-by: Chaitanya Tata (cherry picked from commit e4167632df7eab91a2dd15e9def9a87b26cb4ab3) --- include/zephyr/net/wifi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 75139ae36c48..806424475f09 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -355,7 +355,7 @@ enum wifi_twt_fail_reason { }; static const char * const twt_err_code_tbl[] = { - [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecfied", + [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecified", [WIFI_TWT_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", [WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED] = "Operation not supported", From cca8d5acc0916bb088184d521e4745621c7bcaae Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 23 Jun 2023 02:06:18 +0530 Subject: [PATCH 353/528] [nrf fromtree] net: wifi: Do TWT checks only for setup For tear down the checks doesn't make any sense, as TWT flow is already established. Signed-off-by: Chaitanya Tata (cherry picked from commit 456859a65dd4ca7bc64bb2aa4c68013eecf499e7) --- subsys/net/l2/wifi/wifi_mgmt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 4c2526372f99..8f2727cb5a98 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -316,6 +316,10 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, return -ENOTSUP; } + if (twt_params->operation == WIFI_TWT_TEARDOWN) { + return off_api->set_twt(dev, twt_params); + } + if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, sizeof(struct wifi_iface_status))) { twt_params->fail_reason = From 5a402fbc2d2d2ecb9f98aa2b268b3d32da491bd6 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 23 Jun 2023 14:15:26 +0530 Subject: [PATCH 354/528] [nrf fromtree] net: wifi: Disable trigger in TWT quick setup Most AP's are not sending proper HE triggers or stopping triggers after sometime, so, change the default to non-triggered based TWT. Signed-off-by: Chaitanya Tata (cherry picked from commit 97bd70fa05336b2441237fd6f7b8567a11701a05) --- subsys/net/l2/wifi/wifi_shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 47e47830c8e8..5d833c25f750 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -717,7 +717,7 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, params.flow_id = 0; params.setup.responder = 0; params.setup.implicit = 1; - params.setup.trigger = 1; + params.setup.trigger = 0; params.setup.announce = 0; if (!parse_number(sh, (long *)¶ms.setup.twt_wake_interval, argv[idx++], From d26c34037de64657df72c34abfd9ebd6a16d8195 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 25 Jun 2023 21:18:19 +0530 Subject: [PATCH 355/528] [nrf fromtree] net: wifi: Add an error code for TWT duplicate flow request This is to handle duplicate TWT setup request. Signed-off-by: Chaitanya Tata (cherry picked from commit 15476aa3985fc5c9f2886dac6d382622136e85e2) --- include/zephyr/net/wifi.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 806424475f09..ae9f8cfa6db4 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -352,6 +352,7 @@ enum wifi_twt_fail_reason { WIFI_TWT_FAIL_OPERATION_IN_PROGRESS, WIFI_TWT_FAIL_INVALID_FLOW_ID, WIFI_TWT_FAIL_IP_NOT_ASSIGNED, + WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS, }; static const char * const twt_err_code_tbl[] = { @@ -371,6 +372,8 @@ static const char * const twt_err_code_tbl[] = { "Invalid negotiated flow id", [WIFI_TWT_FAIL_IP_NOT_ASSIGNED] = "IP address not assigned", + [WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS] = + "Flow already exists", }; static inline const char *get_twt_err_code_str(int16_t err_no) From 8038b739d803e9b89e0d1fd21943ad993f34a8d8 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 25 Jun 2023 21:37:16 +0530 Subject: [PATCH 356/528] [nrf fromtree] net: wifi: Fix tear down messages TWT tear down is a synchronous call, so, once it returns the operation is done. Signed-off-by: Chaitanya Tata (cherry picked from commit 3be72657378673e2a055d28927c1a13d6e4c4497) --- subsys/net/l2/wifi/wifi_shell.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 5d833c25f750..3500743b1148 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -837,7 +837,7 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d requested\n", + shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s with dg: %d, flow_id: %d success\n", wifi_twt_operation2str[params.operation], params.dialog_token, params.flow_id); @@ -864,7 +864,7 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s all flows\n", + shell_fprintf(sh, SHELL_NORMAL, "TWT operation %s all flows success\n", wifi_twt_operation2str[params.operation]); return 0; From 77de32019bdab051c518faa54a59052464cf17fc Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 25 Jun 2023 22:07:18 +0530 Subject: [PATCH 357/528] [nrf fromtree] net: wifi: Add a demarcation print This helps see the response status and details separately. Signed-off-by: Chaitanya Tata (cherry picked from commit a3ab624f5deb22b1617c67ee1bd5514550c05dde) --- subsys/net/l2/wifi/wifi_shell.c | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 3500743b1148..31e722e21229 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -270,6 +270,7 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { print(context.sh, SHELL_NORMAL, "TWT response: %s\n", wifi_twt_setup_cmd2str[resp->setup_cmd]); + print(context.sh, SHELL_NORMAL, "== TWT negotiated parameters ==\n"); print_twt_params(resp->dialog_token, resp->flow_id, resp->negotiation_type, From 53c0cb16552ff02e1fc905682350c67291b23d92 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 25 Jun 2023 22:40:22 +0530 Subject: [PATCH 358/528] [nrf fromtree] net: wifi: Add a message for unsolicited TWT tear down This is for TWT tear down by AP. Signed-off-by: Chaitanya Tata (cherry picked from commit 8042218948f671673fd2104fa9eb6f94c745f89a) --- subsys/net/l2/wifi/wifi_shell.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 31e722e21229..503b009707d4 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -267,6 +267,12 @@ static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) const struct wifi_twt_params *resp = (const struct wifi_twt_params *)cb->info; + if (resp->operation == WIFI_TWT_TEARDOWN) { + print(context.sh, SHELL_NORMAL, "TWT teardown received for flow ID %d\n", + resp->flow_id); + return; + } + if (resp->resp_status == WIFI_TWT_RESP_RECEIVED) { print(context.sh, SHELL_NORMAL, "TWT response: %s\n", wifi_twt_setup_cmd2str[resp->setup_cmd]); From 527571f195ec6189f8f48e3994c7e895e405b6ac Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 23 Jun 2023 00:49:04 +0530 Subject: [PATCH 359/528] [nrf fromtree] net: wifi: Fix power save timeout data type This should be an unsigned integer. Also, add a comment to explain this feature. Signed-off-by: Chaitanya Tata (cherry picked from commit a71bff7f49f78aa3d8526ab71e4c9709e9bc51aa) --- include/zephyr/net/wifi_mgmt.h | 8 +++++++- subsys/net/l2/wifi/wifi_shell.c | 16 ++++++++++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 8740d6b4bd45..7f9cb68c5e99 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -203,7 +203,13 @@ struct wifi_ps_params { unsigned short listen_interval; enum wifi_ps_wakeup_mode wakeup_mode; enum wifi_ps_mode mode; - int timeout_ms; + /* This is the time out to wait after sending a TX packet + * before going back to power save (in ms) to receive any replies + * from the AP. Zero means this feature is disabled. + * + * It's a tradeoff between power consumption and latency. + */ + unsigned int timeout_ms; enum ps_param_type type; enum wifi_config_ps_param_fail_reason fail_reason; }; diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 503b009707d4..36ac32e67224 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -593,8 +593,13 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_NORMAL, "PS wake up mode: %s\n", config.ps_params.wakeup_mode ? "Listen interval" : "DTIM"); - shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", - config.ps_params.timeout_ms); + if (config.ps_params.timeout_ms) { + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", + config.ps_params.timeout_ms); + } else { + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: disabled\n"); + } + if (config.num_twt_flows == 0) { shell_fprintf(sh, SHELL_NORMAL, "No TWT flows\n"); @@ -695,8 +700,11 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] return -ENOEXEC; } - shell_fprintf(sh, SHELL_NORMAL, - "PS timeout %d ms\n", params.timeout_ms); + if (params.timeout_ms) { + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: %d ms\n", params.timeout_ms); + } else { + shell_fprintf(sh, SHELL_NORMAL, "PS timeout: disabled\n"); + } return 0; } From e14b878dcafb93281b9443f1b1fe74937765bc88 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Fri, 23 Jun 2023 19:40:50 +0000 Subject: [PATCH 360/528] [nrf fromlist] mgmt/MCUmgr/img: Fix build issue with slot0_ns_partition The commit fixes build issue when building for two application images in board that does not have slot0_ns_partition. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/59719 Signed-off-by: Dominik Ermel Signed-off-by: Robert Lubos --- .../mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c | 46 +++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c index 3a5f87ba8620..6b6581149e15 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c @@ -60,11 +60,38 @@ BUILD_ASSERT(PM_MCUBOOT_PAD_SIZE == PM_MCUBOOT_SECONDARY_PAD_SIZE); (FIXED_PARTITION_OFFSET(label) == CONFIG_FLASH_LOAD_OFFSET) #endif /* USE_PARTITION_MANAGER */ -#if !(FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_partition) || \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_ns_partition) || \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition) || \ - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot2_partition)) -#error "Unsupported chosen code partition for boot application." +#if FIXED_PARTITION_EXISTS(slot0_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_partition) +#define NUMBER_OF_ACTIVE_IMAGE 0 +#endif +#endif + +#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot0_ns_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_ns_partition) +#define NUMBER_OF_ACTIVE_IMAGE 0 +#endif +#endif + +#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot1_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition) +#define NUMBER_OF_ACTIVE_IMAGE 0 +#endif +#endif + +#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot2_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot2_partition) +#define NUMBER_OF_ACTIVE_IMAGE 1 +#endif +#endif + +#if !defined(NUMBER_OF_ACTIVE_IMAGE) && FIXED_PARTITION_EXISTS(slot3_partition) +#if FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot3_partition) +#define NUMBER_OF_ACTIVE_IMAGE 1 +#endif +#endif + +#ifndef NUMBER_OF_ACTIVE_IMAGE +#error "Unsupported code parition is set as active application partition" #endif LOG_MODULE_REGISTER(mcumgr_img_grp, CONFIG_MCUMGR_GRP_IMG_LOG_LEVEL); @@ -142,14 +169,7 @@ int img_mgmt_active_slot(int image) int img_mgmt_active_image(void) { -#if CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER == 2 - if (!(FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_partition) || - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot0_ns_partition) || - FIXED_PARTITION_IS_RUNNING_APP_PARTITION(slot1_partition))) { - return 1; - } -#endif - return 0; + return NUMBER_OF_ACTIVE_IMAGE; } /* From 1fa7001a1a286ed114cbd1203b8c549b544df447 Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Mon, 19 Jun 2023 13:14:05 +0200 Subject: [PATCH 361/528] [nrf fromtree] bsim: net: Add delay to echo client in ot bsim tests. This change ensures that openthread network topology will be formed properly, by delaing start of echo client application. Signed-off-by: Przemyslaw Bida (cherry picked from commit 936dc5b6dd3131ac24b57512b21802cfc8673fbf) Signed-off-by: Robert Lubos --- .../bsim/net/sockets/echo_test/tests_scripts/echo_test_ot.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bsim/net/sockets/echo_test/tests_scripts/echo_test_ot.sh b/tests/bsim/net/sockets/echo_test/tests_scripts/echo_test_ot.sh index 653f96802403..56a364528a50 100755 --- a/tests/bsim/net/sockets/echo_test/tests_scripts/echo_test_ot.sh +++ b/tests/bsim/net/sockets/echo_test/tests_scripts/echo_test_ot.sh @@ -18,13 +18,13 @@ EXECUTE_TIMEOUT=100 cd ${BSIM_OUT_PATH}/bin Execute ./bs_${BOARD}_tests_bsim_net_sockets_echo_test_prj_conf_overlay-ot_conf \ - -v=${verbosity_level} -s=${simulation_id} -d=0 -RealEncryption=1 \ + -v=${verbosity_level} -s=${simulation_id} -start_offset=2e6 -d=0 -RealEncryption=1 \ -testid=echo_client Execute ./bs_${BOARD}_samples_net_sockets_echo_server_prj_conf_overlay-ot_conf\ -v=${verbosity_level} -s=${simulation_id} -d=1 -RealEncryption=1 \ Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \ - -D=2 -sim_length=26e6 -argschannel -at=40 -argsmain $@ + -D=2 -sim_length=40e6 -argschannel -at=40 -argsmain $@ wait_for_background_jobs #Wait for all programs in background and return != 0 if any fails From cc84ffea7210488ec24db09db25dd6df107f0209 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 19 Jun 2023 12:19:05 +0200 Subject: [PATCH 362/528] [nrf noup] Revert "twister: Use natural sort when generating hardware map" This reverts commit c37deeb0c4602dc3eeb700a7dc3ed317283fff17. This is only a temporary change, until we align our CI. To be removed once natsort is avaialble in the NCS CI. Signed-off-by: Robert Lubos --- scripts/pylib/twister/twisterlib/hardwaremap.py | 3 +-- scripts/requirements-run-test.txt | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/scripts/pylib/twister/twisterlib/hardwaremap.py b/scripts/pylib/twister/twisterlib/hardwaremap.py index 5e90b7c84c6f..a0ea7c59a8eb 100644 --- a/scripts/pylib/twister/twisterlib/hardwaremap.py +++ b/scripts/pylib/twister/twisterlib/hardwaremap.py @@ -13,7 +13,6 @@ import scl import logging from pathlib import Path -from natsort import natsorted from twisterlib.environment import ZEPHYR_BASE @@ -322,7 +321,7 @@ def readlink(link): def save(self, hwm_file): # use existing map - self.detected = natsorted(self.detected, key=lambda x: x.serial or '') + self.detected.sort(key=lambda x: x.serial or '') if os.path.exists(hwm_file): with open(hwm_file, 'r') as yaml_file: hwm = yaml.load(yaml_file, Loader=SafeLoader) diff --git a/scripts/requirements-run-test.txt b/scripts/requirements-run-test.txt index 836921281102..3bb0b21c44e8 100644 --- a/scripts/requirements-run-test.txt +++ b/scripts/requirements-run-test.txt @@ -7,7 +7,6 @@ pyocd>=0.35.0 # used by twister for board/hardware map tabulate -natsort # used by mcuboot cbor>=1.0.0 From ad7ef6496a43a293a5cad7dd74831d92f333cc98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Battrel?= Date: Wed, 28 Jun 2023 08:25:45 +0200 Subject: [PATCH 363/528] [nrf fromtree] Bluetooth: Host: Abort pairing if disconnected MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If disconnection has been triggered in between the security update and the call to `smp_pairing_complete` we need to abort the pairing. The disconnection may have been triggered by `bt_unpair`, in that case the keys will have been erased and it will lead to an assertion to continue as if nothing happened. To resolve this issue, at the beginning of `smp_pairing_complete` the `status` is set to `BT_SMP_ERR_UNSPECIFIED` if there is no connection. Signed-off-by: Théo Battrel (cherry picked from commit cd264b21e4a90ed85a63116bd148b890ab347db8) Signed-off-by: Robert Lubos --- subsys/bluetooth/host/smp.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 2fad1ea235f7..9b40910cb304 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -1632,7 +1632,15 @@ static void smp_pairing_complete(struct bt_smp *smp, uint8_t status) { struct bt_conn *conn = smp->chan.chan.conn; - LOG_DBG("status 0x%x", status); + LOG_DBG("got status 0x%x", status); + + if (conn->state != BT_CONN_CONNECTED) { + /* If disconnection has been triggered in between the security update + * and the call to this function we need to abort the pairing. + */ + LOG_WRN("Not connected!"); + status = BT_SMP_ERR_UNSPECIFIED; + } if (!status) { #if defined(CONFIG_BT_BREDR) @@ -1701,7 +1709,7 @@ static void smp_pairing_complete(struct bt_smp *smp, uint8_t status) smp_reset(smp); - if (conn->sec_level != conn->required_sec_level) { + if (conn->state == BT_CONN_CONNECTED && conn->sec_level != conn->required_sec_level) { bt_smp_start_security(conn); } } From 1ff52962ebce37d536949bcc1804fcf502011af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 20 Jun 2023 13:27:15 +0200 Subject: [PATCH 364/528] [nrf noup] mbedtls: Add config support for PBKDF2_HMAC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add config support for PBKDF2_HMAC. This patches an existing noup commit and is therefore also noup. Signed-off-by: Sebastian Bøe --- modules/mbedtls/Kconfig.psa | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index b91d767285aa..5b8f6e33aaf2 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -275,9 +275,8 @@ config PSA_WANT_ALG_HKDF config PSA_WANT_ALG_PBKDF2_HMAC bool + prompt "PSA PBKDF2 HMAC support" if !PSA_PROMPTLESS depends on PSA_WANT_ALG_HMAC - help - PBKDF2-HMAC is not yet supported via the PSA APIs in Mbed TLS. config PSA_WANT_ALG_TLS12_PRF bool From 743f99947369088ecba6820a720ede8054893866 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20B=C3=B8e?= Date: Tue, 20 Jun 2023 15:04:46 +0200 Subject: [PATCH 365/528] [nrf noup] mbedtls: Add config support for PBKDF2_AES_CMAC_PRF_128 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add config support for PBKDF2_AES_CMAC_PRF_128 Signed-off-by: Sebastian Bøe --- modules/mbedtls/Kconfig.psa | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 5b8f6e33aaf2..b95f8483e34a 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -261,6 +261,7 @@ config PSA_HAS_KEY_DERIVATION default y depends on PSA_WANT_ALG_HKDF || \ PSA_WANT_ALG_PBKDF2_HMAC || \ + PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 || \ PSA_WANT_ALG_TLS12_PRF || \ PSA_WANT_ALG_TLS12_PSK_TO_MS || \ PSA_WANT_ALG_TLS12_ECJPAKE_TO_PMS @@ -278,6 +279,11 @@ config PSA_WANT_ALG_PBKDF2_HMAC prompt "PSA PBKDF2 HMAC support" if !PSA_PROMPTLESS depends on PSA_WANT_ALG_HMAC +config PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 + bool + prompt "PSA PBKDF2-AES-CMAC-PRF-128 support" if !PSA_PROMPTLESS + depends on PSA_WANT_ALG_CMAC + config PSA_WANT_ALG_TLS12_PRF bool prompt "PSA PRF support (TLS1.2)" if !PSA_PROMPTLESS From f32e3dea609fcd93037a8b1af251b0d209237f2d Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Thu, 13 Apr 2023 12:10:08 +0200 Subject: [PATCH 366/528] [nrf fromlist] cmake: add Zephyr image output files as byproducts Export Zephyr image byproducts through `BYPRODUCT_` cache variables. This allow external tools, such as sysbuild, to read information on products produced by a Zephyr build from the image CMake cache. For sysbuild, this means that all byproducts will be added to a phony build target, which again allow sysbuild itself to depends on target output and properly describe dependencies between byproducts and their producing targets. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/59054 Signed-off-by: Torsten Rasmussen (cherry picked from commit 10fc47872b0c98f6dc1810773efe003c49d03ed2) --- CMakeLists.txt | 6 +++++ cmake/mcuboot.cmake | 18 +++++++++++++ .../cmake/modules/sysbuild_extensions.cmake | 25 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6b06937f873..7dd1e539ae73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1429,6 +1429,7 @@ toolchain_ld_link_elf( target_byproducts(TARGET ${ZEPHYR_LINK_STAGE_EXECUTABLE} BYPRODUCTS ${PROJECT_BINARY_DIR}/${ZEPHYR_LINK_STAGE_EXECUTABLE}.map ) +set(BYPRODUCT_KERNEL_ELF_NAME "${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME}" CACHE FILEPATH "Kernel elf file" FORCE) set_property(TARGET ${ZEPHYR_LINK_STAGE_EXECUTABLE} PROPERTY LINK_DEPENDS ${PROJECT_BINARY_DIR}/${ZEPHYR_CURRENT_LINKER_CMD} @@ -1576,6 +1577,7 @@ if(CONFIG_BUILD_OUTPUT_HEX OR BOARD_FLASH_RUNNER STREQUAL openocd) ${KERNEL_HEX_NAME} # ${out_hex_byprod} # Is this needed ? ) + set(BYPRODUCT_KERNEL_HEX_NAME "${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME}" CACHE FILEPATH "Kernel hex file" FORCE) endif() endif() @@ -1598,6 +1600,7 @@ if(CONFIG_BUILD_OUTPUT_BIN) ${KERNEL_BIN_NAME} # ${out_hex_byprod} # Is this needed ? ) + set(BYPRODUCT_KERNEL_BIN_NAME "${PROJECT_BINARY_DIR}/${KERNEL_BIN_NAME}" CACHE FILEPATH "Kernel binary file" FORCE) endif() endif() @@ -1630,6 +1633,7 @@ if(CONFIG_BUILD_OUTPUT_BIN AND CONFIG_BUILD_OUTPUT_UF2) post_build_byproducts ${KERNEL_UF2_NAME} ) + set(BYPRODUCT_KERNEL_UF2_NAME "${PROJECT_BINARY_DIR}/${KERNEL_UF2_NAME}" CACHE FILEPATH "Kernel uf2 file" FORCE) endif() if(CONFIG_BUILD_OUTPUT_META) @@ -1681,6 +1685,7 @@ if(CONFIG_BUILD_OUTPUT_S19) # ${out_S19_byprod} # Is this needed ? ) + set(BYPRODUCT_KERNEL_S19_NAME "${PROJECT_BINARY_DIR}/${KERNEL_S19_NAME}" CACHE FILEPATH "Kernel s19 file" FORCE) endif() endif() @@ -1764,6 +1769,7 @@ if(CONFIG_BUILD_OUTPUT_EXE) post_build_byproducts ${KERNEL_EXE_NAME} ) + set(BYPRODUCT_KERNEL_EXE_NAME "${PROJECT_BINARY_DIR}/${KERNEL_EXE_NAME}" CACHE FILEPATH "Kernel exe file" FORCE) endif() if(CONFIG_BUILD_OUTPUT_INFO_HEADER) diff --git a/cmake/mcuboot.cmake b/cmake/mcuboot.cmake index f551466a4113..3b29069ca354 100644 --- a/cmake/mcuboot.cmake +++ b/cmake/mcuboot.cmake @@ -114,15 +114,24 @@ function(zephyr_mcuboot_tasks) list(APPEND unconfirmed_args --bin --sbin ${output}.signed.bin) list(APPEND byproducts ${output}.signed.bin) zephyr_runner_file(bin ${output}.signed.bin) + set(BYPRODUCT_KERNEL_SIGNED_BIN_NAME "${output}.signed.bin" + CACHE FILEPATH "Signed kernel bin file" FORCE + ) if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE) list(APPEND confirmed_args --bin --sbin ${output}.signed.confirmed.bin) list(APPEND byproducts ${output}.signed.confirmed.bin) + set(BYPRODUCT_KERNEL_SIGNED_CONFIRMED_BIN_NAME "${output}.signed.confirmed.bin" + CACHE FILEPATH "Signed and confirmed kernel bin file" FORCE + ) endif() if(NOT "${keyfile_enc}" STREQUAL "") list(APPEND encrypted_args --bin --sbin ${output}.signed.encrypted.bin) list(APPEND byproducts ${output}.signed.encrypted.bin) + set(BYPRODUCT_KERNEL_SIGNED_ENCRYPTED_BIN_NAME "${output}.signed.encrypted.bin" + CACHE FILEPATH "Signed and encrypted kernel bin file" FORCE + ) endif() endif() @@ -131,15 +140,24 @@ function(zephyr_mcuboot_tasks) list(APPEND unconfirmed_args --hex --shex ${output}.signed.hex) list(APPEND byproducts ${output}.signed.hex) zephyr_runner_file(hex ${output}.signed.hex) + set(BYPRODUCT_KERNEL_SIGNED_HEX_NAME "${output}.signed.hex" + CACHE FILEPATH "Signed kernel hex file" FORCE + ) if(CONFIG_MCUBOOT_GENERATE_CONFIRMED_IMAGE) list(APPEND confirmed_args --hex --shex ${output}.signed.confirmed.hex) list(APPEND byproducts ${output}.signed.confirmed.hex) + set(BYPRODUCT_KERNEL_SIGNED_CONFIRMED_HEX_NAME "${output}.signed.confirmed.hex" + CACHE FILEPATH "Signed and confirmed kernel hex file" FORCE + ) endif() if(NOT "${keyfile_enc}" STREQUAL "") list(APPEND encrypted_args --hex --shex ${output}.signed.encrypted.hex) list(APPEND byproducts ${output}.signed.encrypted.hex) + set(BYPRODUCT_KERNEL_SIGNED_ENCRYPTED_HEX_NAME "${output}.signed.encrypted.hex" + CACHE FILEPATH "Signed and encrypted kernel hex file" FORCE + ) endif() endif() diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index bdf8f88b8055..8505b8569d69 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -34,6 +34,11 @@ function(load_cache) set_property(TARGET ${LOAD_CACHE_IMAGE}_cache APPEND PROPERTY "CACHE:VARIABLES" "${CMAKE_MATCH_1}") set_property(TARGET ${LOAD_CACHE_IMAGE}_cache PROPERTY "${CMAKE_MATCH_1}:TYPE" "${CMAKE_MATCH_2}") set_property(TARGET ${LOAD_CACHE_IMAGE}_cache PROPERTY "${CMAKE_MATCH_1}" "${variable_value}") + if("${CMAKE_MATCH_1}" MATCHES "^BYPRODUCT_.*") + set_property(TARGET ${LOAD_CACHE_IMAGE}_cache APPEND + PROPERTY "EXTRA_BYPRODUCTS" "${variable_value}" + ) + endif() endif() endforeach() endfunction() @@ -290,6 +295,17 @@ endfunction() # If the application is not due to ExternalZephyrProject_Add() being called, # then an error is raised. # +# The image output files are added as target properties on the image target as: +# ELF_OUT: property specifying the generated elf file. +# BIN_OUT: property specifying the generated bin file. +# HEX_OUT: property specifying the generated hex file. +# S19_OUT: property specifying the generated s19 file. +# UF2_OUT: property specifying the generated uf2 file. +# EXE_OUT: property specifying the generated exe file. +# +# the property is only set if the image is configured to generate the output +# format. Elf files are always created. +# # APPLICATION: : Name of the application. # function(ExternalZephyrProject_Cmake) @@ -401,6 +417,15 @@ function(ExternalZephyrProject_Cmake) endif() load_cache(IMAGE ${ZCMAKE_APPLICATION} BINARY_DIR ${BINARY_DIR}) import_kconfig(CONFIG_ ${BINARY_DIR}/zephyr/.config TARGET ${ZCMAKE_APPLICATION}) + + # This custom target informs CMake how the BYPRODUCTS are generated if a target + # depends directly on the BYPRODUCT instead of depending on the image target. + get_target_property(${ZCMAKE_APPLICATION}_byproducts ${ZCMAKE_APPLICATION}_cache EXTRA_BYPRODUCTS) + add_custom_target(${ZCMAKE_APPLICATION}_extra_byproducts + COMMAND ${CMAKE_COMMAND} -E true + BYPRODUCTS ${${ZCMAKE_APPLICATION}_byproducts} + DEPENDS ${ZCMAKE_APPLICATION} + ) endfunction() # Usage: From 7ea0068af38e548e0e43fc644baa4c57771832a5 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Fri, 23 Jun 2023 13:01:32 +0200 Subject: [PATCH 367/528] [nrf fromlist] sysbuild: refactor image_config.cmake handling Refactor image_config.cmake so that it is no longer sourced unconditionally for all images. Instead image_config.cmake has been split into BOOTLOADER_image_default.cmake and MAIN_image_default.cmake and is set as property on the image. This means the code in image_config.cmake can be split into dedicated files which depends on the image type. Furthermore it allows sysbuild modules to append extra config snippets to process for sysbuild kconfig overwrite, or even remove the default snippet and have full control. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/59665 Signed-off-by: Torsten Rasmussen (cherry picked from commit fd35606394bcb8d030f0a60c89f5f413f4a5179e) --- share/sysbuild/CMakeLists.txt | 1 - .../cmake/modules/sysbuild_extensions.cmake | 13 +++++ share/sysbuild/image_config.cmake | 48 ------------------- .../BOOTLOADER_image_default.cmake | 37 ++++++++++++++ .../MAIN_image_default.cmake | 19 ++++++++ 5 files changed, 69 insertions(+), 49 deletions(-) delete mode 100644 share/sysbuild/image_config.cmake create mode 100644 share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake create mode 100644 share/sysbuild/image_configurations/MAIN_image_default.cmake diff --git a/share/sysbuild/CMakeLists.txt b/share/sysbuild/CMakeLists.txt index 12a6f4f15bb9..84cb937cc7e8 100644 --- a/share/sysbuild/CMakeLists.txt +++ b/share/sysbuild/CMakeLists.txt @@ -86,7 +86,6 @@ endwhile() sysbuild_module_call(PRE_CMAKE MODULES ${SYSBUILD_MODULE_NAMES} IMAGES ${IMAGES}) foreach(image ${IMAGES}) - include(image_config.cmake) ExternalZephyrProject_Cmake(APPLICATION ${image}) endforeach() sysbuild_module_call(POST_CMAKE MODULES ${SYSBUILD_MODULE_NAMES} IMAGES ${IMAGES}) diff --git a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake index 8505b8569d69..e1339107430f 100644 --- a/share/sysbuild/cmake/modules/sysbuild_extensions.cmake +++ b/share/sysbuild/cmake/modules/sysbuild_extensions.cmake @@ -268,6 +268,11 @@ function(ExternalZephyrProject_Add) set_target_properties(${ZBUILD_APPLICATION} PROPERTIES MAIN_APP True) endif() + if(DEFINED ZBUILD_APP_TYPE) + set(image_default "${CMAKE_SOURCE_DIR}/image_configurations/${ZBUILD_APP_TYPE}_image_default.cmake") + set_target_properties(${ZBUILD_APPLICATION} PROPERTIES IMAGE_CONF_SCRIPT ${image_default}) + endif() + if(DEFINED ZBUILD_BOARD) # Only set image specific board if provided. # The sysbuild BOARD is exported through sysbuild cache, and will be used @@ -342,6 +347,10 @@ function(ExternalZephyrProject_Cmake) get_target_property(${ZCMAKE_APPLICATION}_BOARD ${ZCMAKE_APPLICATION} BOARD) get_target_property(${ZCMAKE_APPLICATION}_MAIN_APP ${ZCMAKE_APPLICATION} MAIN_APP) + get_property(${ZCMAKE_APPLICATION}_CONF_SCRIPT TARGET ${ZCMAKE_APPLICATION} + PROPERTY IMAGE_CONF_SCRIPT + ) + # Update ROOT variables with relative paths to use absolute paths based on # the source application directory. foreach(type MODULE_EXT BOARD SOC ARCH SCA) @@ -393,6 +402,10 @@ function(ExternalZephyrProject_Cmake) ${${ZCMAKE_APPLICATION}_CACHE_FILE} ONLY_IF_DIFFERENT ) + foreach(script ${${ZCMAKE_APPLICATION}_CONF_SCRIPT}) + include(${script}) + endforeach() + set(dotconfigsysbuild ${BINARY_DIR}/zephyr/.config.sysbuild) get_target_property(config_content ${ZCMAKE_APPLICATION} CONFIG) string(CONFIGURE "${config_content}" config_content) diff --git a/share/sysbuild/image_config.cmake b/share/sysbuild/image_config.cmake deleted file mode 100644 index 0d44f379789c..000000000000 --- a/share/sysbuild/image_config.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright (c) 2023 Nordic Semiconductor -# -# SPDX-License-Identifier: Apache-2.0 - -# This sysbuild CMake file sets the sysbuild controlled settings as properties -# on Zephyr images. - -get_target_property(image_board ${image} BOARD) -if((NOT image_board) OR ("${image_BOARD}" STREQUAL "${BOARD}")) - get_target_property(${image}_APP_TYPE ${image} APP_TYPE) - if(NOT "${${image}_APP_TYPE}" STREQUAL "BOOTLOADER") - set_config_bool(${image} CONFIG_BOOTLOADER_MCUBOOT "${SB_CONFIG_BOOTLOADER_MCUBOOT}") - set_config_string(${image} CONFIG_MCUBOOT_SIGNATURE_KEY_FILE - "${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}" - ) - else() - set(keytypes CONFIG_BOOT_SIGNATURE_TYPE_NONE - CONFIG_BOOT_SIGNATURE_TYPE_RSA - CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 - CONFIG_BOOT_SIGNATURE_TYPE_ED25519) - - if(SB_CONFIG_BOOT_SIGNATURE_TYPE_NONE) - set(keytype CONFIG_BOOT_SIGNATURE_TYPE_NONE) - elseif(SB_CONFIG_BOOT_SIGNATURE_TYPE_RSA) - set(keytype CONFIG_BOOT_SIGNATURE_TYPE_RSA) - elseif(SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) - set(keytype CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) - elseif(SB_CONFIG_BOOT_SIGNATURE_TYPE_ED25519) - set(keytype CONFIG_BOOT_SIGNATURE_TYPE_ED25519) - endif() - - foreach(loopkeytype ${keytypes}) - if("${loopkeytype}" STREQUAL "${keytype}") - set_config_bool(${image} ${loopkeytype} y) - else() - set_config_bool(${image} ${loopkeytype} n) - endif() - endforeach() - endif() - - if(SB_CONFIG_BOOTLOADER_MCUBOOT) - if("${SB_CONFIG_SIGNATURE_TYPE}" STREQUAL "NONE") - set_config_bool(${image} CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE y) - else() - set_config_bool(${image} CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE n) - endif() - endif() -endif() diff --git a/share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake b/share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake new file mode 100644 index 000000000000..5594109668b4 --- /dev/null +++ b/share/sysbuild/image_configurations/BOOTLOADER_image_default.cmake @@ -0,0 +1,37 @@ +# Copyright (c) 2023 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# This sysbuild CMake file sets the sysbuild controlled settings as properties +# on Zephyr MCUboot / bootloader image. + +set(keytypes CONFIG_BOOT_SIGNATURE_TYPE_NONE + CONFIG_BOOT_SIGNATURE_TYPE_RSA + CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256 + CONFIG_BOOT_SIGNATURE_TYPE_ED25519) + +if(SB_CONFIG_BOOT_SIGNATURE_TYPE_NONE) + set(keytype CONFIG_BOOT_SIGNATURE_TYPE_NONE) +elseif(SB_CONFIG_BOOT_SIGNATURE_TYPE_RSA) + set(keytype CONFIG_BOOT_SIGNATURE_TYPE_RSA) +elseif(SB_CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) + set(keytype CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256) +elseif(SB_CONFIG_BOOT_SIGNATURE_TYPE_ED25519) + set(keytype CONFIG_BOOT_SIGNATURE_TYPE_ED25519) +endif() + +foreach(loopkeytype ${keytypes}) + if("${loopkeytype}" STREQUAL "${keytype}") + set_config_bool(${ZCMAKE_APPLICATION} ${loopkeytype} y) + else() + set_config_bool(${ZCMAKE_APPLICATION} ${loopkeytype} n) + endif() +endforeach() + +if(SB_CONFIG_BOOTLOADER_MCUBOOT) + if("${SB_CONFIG_SIGNATURE_TYPE}" STREQUAL "NONE") + set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE y) + else() + set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE n) + endif() +endif() diff --git a/share/sysbuild/image_configurations/MAIN_image_default.cmake b/share/sysbuild/image_configurations/MAIN_image_default.cmake new file mode 100644 index 000000000000..a6bd72d7d1a1 --- /dev/null +++ b/share/sysbuild/image_configurations/MAIN_image_default.cmake @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Nordic Semiconductor +# +# SPDX-License-Identifier: Apache-2.0 + +# This sysbuild CMake file sets the sysbuild controlled settings as properties +# on the main Zephyr image. + +set_config_bool(${ZCMAKE_APPLICATION} CONFIG_BOOTLOADER_MCUBOOT "${SB_CONFIG_BOOTLOADER_MCUBOOT}") +set_config_string(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_SIGNATURE_KEY_FILE + "${SB_CONFIG_BOOT_SIGNATURE_KEY_FILE}" +) + +if(SB_CONFIG_BOOTLOADER_MCUBOOT) + if("${SB_CONFIG_SIGNATURE_TYPE}" STREQUAL "NONE") + set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE y) + else() + set_config_bool(${ZCMAKE_APPLICATION} CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE n) + endif() +endif() From a77ca8caf2c4edfd74088a9709a1e91e485c17d7 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 15 Jun 2023 13:40:14 +0530 Subject: [PATCH 368/528] Revert "[nrf noup] net: wifi: Add support for WPA supplicant" This reverts commit 6f270fa5a6b68e485184bd551ac4b18033333d6a. Signed-off-by: Chaitanya Tata --- subsys/net/l2/wifi/wifi_mgmt.c | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 8f2727cb5a98..266938b38518 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -12,9 +12,6 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include -#ifdef CONFIG_WPA_SUPP -#include "supp_api.h" -#endif static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) @@ -22,15 +19,12 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, struct wifi_connect_req_params *params = (struct wifi_connect_req_params *)data; const struct device *dev = net_if_get_device(iface); -#ifndef CONFIG_WPA_SUPP struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; - if (off_api == NULL || off_api->connect == NULL) { return -ENOTSUP; } -#endif /* CONFIG_WPA_SUPP */ LOG_HEXDUMP_DBG(params->ssid, params->ssid_length, "ssid"); LOG_HEXDUMP_DBG(params->psk, params->psk_length, "psk"); @@ -54,11 +48,8 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, !params->ssid) { return -EINVAL; } -#ifdef CONFIG_WPA_SUPP - return z_wpa_supplicant_connect(dev, params); -#else + return off_api->connect(dev, params); -#endif /* CONFIG_WPA_SUPP */ } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT, wifi_connect); @@ -108,10 +99,6 @@ static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - -#ifdef CONFIG_WPA_SUPP - return z_wpa_supplicant_disconnect(dev); -#else struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; @@ -120,7 +107,6 @@ static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface, } return off_api->disconnect(dev); -#endif /* CONFIG_WPA_SUPP */ } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT, wifi_disconnect); @@ -185,24 +171,19 @@ static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct wifi_iface_status *status = data; - - if (!data || len != sizeof(*status)) { - return -EINVAL; - } - -#ifdef CONFIG_WPA_SUPP - return z_wpa_supplicant_status(dev, status); -#else struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + struct wifi_iface_status *status = data; if (off_api == NULL || off_api->iface_status == NULL) { return -ENOTSUP; } + if (!data || len != sizeof(*status)) { + return -EINVAL; + } + return off_api->iface_status(dev, status); -#endif /* CONFIG_WPA_SUPP */ } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_IFACE_STATUS, wifi_iface_status); From 95b823d0670de1f5395988e0f5f658fb52fba155 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 6 Jun 2023 01:54:19 +0530 Subject: [PATCH 369/528] [nrf fromtree] net: l2: Fix the define in comment This was a typo. Signed-off-by: Chaitanya Tata (cherry picked from commit bb281e4fdebb8625f18db383ad92ab775bf7373d) --- include/zephyr/net/net_l2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/zephyr/net/net_l2.h b/include/zephyr/net/net_l2.h index dc443e0a3f54..7f221f913671 100644 --- a/include/zephyr/net/net_l2.h +++ b/include/zephyr/net/net_l2.h @@ -99,7 +99,7 @@ NET_L2_DECLARE_PUBLIC(DUMMY_L2); #if defined(CONFIG_NET_OFFLOAD) || defined(CONFIG_NET_SOCKETS_OFFLOAD) #define OFFLOADED_NETDEV_L2 OFFLOADED_NETDEV NET_L2_DECLARE_PUBLIC(OFFLOADED_NETDEV_L2); -#endif /* CONFIG_NET_L2_ETHERNET */ +#endif /* CONFIG_NET_OFFLOAD || CONFIG_NET_SOCKETS_OFFLOAD */ #ifdef CONFIG_NET_L2_ETHERNET #define ETHERNET_L2 ETHERNET From 09ac6315dd7c411f7ab2baa13abbdd123d779d15 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 6 Jun 2023 01:54:20 +0530 Subject: [PATCH 370/528] [nrf fromtree] net: l2: Add support to identify Wi-Fi interfaces Wi-Fi is based on L2 Ethernet, so, all drivers are registered as Ethernet L2, but in order to distinguish true Ethernet and Wi-Fi devices, add a L2 type within Ethernet. Also, handle offloaded net devices that also offload Wi-Fi. This approach is better than adding a new Wi-Fi L2 as that would mean invasive changes which are unnecessary. Signed-off-by: Chaitanya Tata (cherry picked from commit 2606ba445b137b4a4e8d344768c5d74057742636) --- include/zephyr/net/ethernet.h | 28 +++++++++++++++++++++++ include/zephyr/net/net_if.h | 10 ++++++++ include/zephyr/net/offloaded_netdev.h | 33 +++++++++++++++++++++++++++ subsys/net/ip/net_if.c | 13 +++++++++++ 4 files changed, 84 insertions(+) diff --git a/include/zephyr/net/ethernet.h b/include/zephyr/net/ethernet.h index 0807c2be33ec..afa5b34f19bf 100644 --- a/include/zephyr/net/ethernet.h +++ b/include/zephyr/net/ethernet.h @@ -347,6 +347,16 @@ enum ethernet_filter_type { /** @endcond */ +/** Types of Ethernet L2 */ +enum ethernet_if_types { + /** IEEE 802.3 Ethernet (default) */ + L2_ETH_IF_TYPE_ETHERNET, + + /** IEEE 802.11 Wi-Fi*/ + L2_ETH_IF_TYPE_WIFI, +} __packed; + + struct ethernet_filter { /** Type of filter */ enum ethernet_filter_type type; @@ -595,6 +605,9 @@ struct ethernet_context { /** Is this context already initialized */ bool is_init : 1; + + /** Types of Ethernet network interfaces */ + enum ethernet_if_types eth_if_type; }; /** @@ -1004,6 +1017,21 @@ static inline int net_eth_get_ptp_port(struct net_if *iface) void net_eth_set_ptp_port(struct net_if *iface, int port); #endif /* CONFIG_NET_L2_PTP */ +/** + * @brief Check if the Ethernet L2 network interface can perform Wi-Fi. + * + * @param iface Pointer to network interface + * + * @return True if interface supports Wi-Fi, False otherwise. + */ +static inline bool net_eth_type_is_wifi(struct net_if *iface) +{ + const struct ethernet_context *ctx = (struct ethernet_context *) + net_if_l2_data(iface); + + return ctx->eth_if_type == L2_ETH_IF_TYPE_WIFI; +} + /** * @} */ diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index cedfe9f1db51..2c04e64e0dcf 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -2526,6 +2526,16 @@ int net_if_resume(struct net_if *iface); bool net_if_is_suspended(struct net_if *iface); #endif /* CONFIG_NET_POWER_MANAGEMENT */ +/** + * @brief Check if the network interface supports Wi-Fi. + * + * @param iface Pointer to network interface + * + * @return True if interface supports Wi-Fi, False otherwise. + */ +bool net_if_is_wifi(struct net_if *iface); + + /** @cond INTERNAL_HIDDEN */ struct net_if_api { void (*init)(struct net_if *iface); diff --git a/include/zephyr/net/offloaded_netdev.h b/include/zephyr/net/offloaded_netdev.h index 5f778680ba27..ce90cf77bf37 100644 --- a/include/zephyr/net/offloaded_netdev.h +++ b/include/zephyr/net/offloaded_netdev.h @@ -29,6 +29,21 @@ extern "C" { * @{ */ +/** Types of offloaded netdev L2 */ +enum offloaded_net_if_types { + /** Unknown, device hasn't register a type */ + L2_OFFLOADED_NET_IF_TYPE_UNKNOWN, + + /** Ethernet devices */ + L2_OFFLOADED_NET_IF_TYPE_ETHERNET, + + /** Modem */ + L2_OFFLOADED_NET_IF_TYPE_MODEM, + + /** IEEE 802.11 Wi-Fi */ + L2_OFFLOADED_NET_IF_TYPE_WIFI, +}; + /** * @brief Extended net_if_api for offloaded ifaces/network devices, allowing handling of * admin up/down state changes @@ -42,11 +57,29 @@ struct offloaded_if_api { /** Enable or disable the device (in response to admin state change) */ int (*enable)(const struct net_if *iface, bool state); + + /* Types of offloaded net device */ + enum offloaded_net_if_types (*get_type)(void); }; /* Ensure offloaded_if_api is compatible with net_if_api */ BUILD_ASSERT(offsetof(struct offloaded_if_api, iface_api) == 0); +/** + * @brief Check if the offloaded network interface supports Wi-Fi. + * + * @param iface Pointer to network interface + * + * @return True if interface supports Wi-Fi, False otherwise. + */ +static inline bool net_off_is_wifi_offloaded(struct net_if *iface) +{ + const struct offloaded_if_api *api = (const struct offloaded_if_api *) + net_if_get_device(iface)->api; + + return api->get_type && api->get_type() == L2_OFFLOADED_NET_IF_TYPE_WIFI; +} + /** * @} */ diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 5da2a664678d..361e6ebc4e89 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -20,6 +20,7 @@ LOG_MODULE_REGISTER(net_if, CONFIG_NET_IF_LOG_LEVEL); #include #include #include +#include #include #include @@ -4592,6 +4593,18 @@ void net_if_add_tx_timestamp(struct net_pkt *pkt) } #endif /* CONFIG_NET_PKT_TIMESTAMP_THREAD */ +bool net_if_is_wifi(struct net_if *iface) +{ + if (is_iface_offloaded(iface)) { + return net_off_is_wifi_offloaded(iface); + } +#if defined(CONFIG_NET_L2_ETHERNET) + return net_eth_type_is_wifi(iface); +#else + return false; +#endif +} + void net_if_init(void) { int if_count = 0; From 2bc29501379fcf321879fab56724a2d4039ffe9f Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 6 Jun 2023 01:54:20 +0530 Subject: [PATCH 371/528] [nrf fromtree] drivers: wifi: Register Wi-Fi architecture type Identify the Wi-Fi capability to the networking stack and also the type of Wi-Fi (Native vs Offloaded), this helps identifying Wi-Fi interfaces that can be used by applications. Signed-off-by: Chaitanya Tata (cherry picked from commit 79870984975d4c11873553247b2873b117148a15) --- drivers/wifi/esp32/src/esp_wifi_drv.c | 2 ++ drivers/wifi/esp_at/esp.c | 5 +++++ drivers/wifi/eswifi/eswifi_core.c | 6 ++++++ drivers/wifi/simplelink/simplelink.c | 6 ++++++ drivers/wifi/winc1500/wifi_winc1500.c | 6 ++++++ subsys/net/ip/net_if.c | 3 ++- 6 files changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/wifi/esp32/src/esp_wifi_drv.c b/drivers/wifi/esp32/src/esp_wifi_drv.c index 88e214548686..5f69c88c02d1 100644 --- a/drivers/wifi/esp32/src/esp_wifi_drv.c +++ b/drivers/wifi/esp32/src/esp_wifi_drv.c @@ -547,7 +547,9 @@ static void esp32_wifi_init(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); struct esp32_wifi_runtime *dev_data = dev->data; + struct ethernet_context *eth_ctx = net_if_l2_data(iface); + eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI; esp32_wifi_iface = iface; dev_data->state = ESP32_STA_STOPPED; diff --git a/drivers/wifi/esp_at/esp.c b/drivers/wifi/esp_at/esp.c index 316a804f5494..614d7fb517ac 100644 --- a/drivers/wifi/esp_at/esp.c +++ b/drivers/wifi/esp_at/esp.c @@ -1215,8 +1215,13 @@ static void esp_iface_init(struct net_if *iface) esp_offload_init(iface); } +static enum offloaded_net_if_types esp_offload_get_type(void) +{ + return L2_OFFLOADED_NET_IF_TYPE_WIFI; +} static const struct net_wifi_mgmt_offload esp_api = { .wifi_iface.iface_api.init = esp_iface_init, + .wifi_iface.get_type = esp_offload_get_type, .scan = esp_mgmt_scan, .connect = esp_mgmt_connect, .disconnect = esp_mgmt_disconnect, diff --git a/drivers/wifi/eswifi/eswifi_core.c b/drivers/wifi/eswifi/eswifi_core.c index ad8976aee3aa..a92991e4552d 100644 --- a/drivers/wifi/eswifi/eswifi_core.c +++ b/drivers/wifi/eswifi/eswifi_core.c @@ -777,8 +777,14 @@ static int eswifi_init(const struct device *dev) return 0; } +static enum offloaded_net_if_types eswifi_get_type(void) +{ + return L2_OFFLOADED_NET_IF_TYPE_WIFI; +} + static const struct net_wifi_mgmt_offload eswifi_offload_api = { .wifi_iface.iface_api.init = eswifi_iface_init, + .wifi_iface.get_type = eswifi_get_type, .scan = eswifi_mgmt_scan, .connect = eswifi_mgmt_connect, .disconnect = eswifi_mgmt_disconnect, diff --git a/drivers/wifi/simplelink/simplelink.c b/drivers/wifi/simplelink/simplelink.c index b75329e49f43..a959d8c14402 100644 --- a/drivers/wifi/simplelink/simplelink.c +++ b/drivers/wifi/simplelink/simplelink.c @@ -263,8 +263,14 @@ static void simplelink_iface_init(struct net_if *iface) } +static enum offloaded_net_if_types simplelink_get_type(void) +{ + return L2_OFFLOADED_NET_IF_TYPE_WIFI; +} + static const struct net_wifi_mgmt_offload simplelink_api = { .wifi_iface.iface_api.init = simplelink_iface_init, + .wifi_iface.get_type = simplelink_get_type, .scan = simplelink_mgmt_scan, .connect = simplelink_mgmt_connect, .disconnect = simplelink_mgmt_disconnect, diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index 329e18a8a68c..19525cc2fd0e 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -1099,8 +1099,14 @@ static void winc1500_iface_init(struct net_if *iface) w1500_data.iface = iface; } +static enum offloaded_net_if_types winc1500_get_wifi_type(void) +{ + return L2_OFFLOADED_NET_IF_TYPE_WIFI; +} + static const struct net_wifi_mgmt_offload winc1500_api = { .wifi_iface.iface_api.init = winc1500_iface_init, + .wifi_iface.get_type = winc1500_get_wifi_type, .scan = winc1500_mgmt_scan, .connect = winc1500_mgmt_connect, .disconnect = winc1500_mgmt_disconnect, diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 361e6ebc4e89..adf68fa33b13 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -4599,7 +4599,8 @@ bool net_if_is_wifi(struct net_if *iface) return net_off_is_wifi_offloaded(iface); } #if defined(CONFIG_NET_L2_ETHERNET) - return net_eth_type_is_wifi(iface); + return net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET) && + net_eth_type_is_wifi(iface); #else return false; #endif From 9874915c6151eb323b66fc5b2715bd50320a6df5 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Tue, 6 Jun 2023 23:36:14 +0530 Subject: [PATCH 372/528] [nrf fromtree] net: ethernet: Fix build and doc error The API should be defined independent of L2_PTP define, this fixes build error and also the doc error, as the next function will have two doxygen headers. Signed-off-by: Chaitanya Tata (cherry picked from commit b9411b75df77a58fac9e9ba71815c4143ed351ad) --- include/zephyr/net/ethernet.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/zephyr/net/ethernet.h b/include/zephyr/net/ethernet.h index afa5b34f19bf..4f4374f7b5fb 100644 --- a/include/zephyr/net/ethernet.h +++ b/include/zephyr/net/ethernet.h @@ -1015,6 +1015,12 @@ static inline int net_eth_get_ptp_port(struct net_if *iface) */ #if defined(CONFIG_NET_L2_PTP) void net_eth_set_ptp_port(struct net_if *iface, int port); +#else +static inline void net_eth_set_ptp_port(struct net_if *iface, int port) +{ + ARG_UNUSED(iface); + ARG_UNUSED(port); +} #endif /* CONFIG_NET_L2_PTP */ /** From e5b32d4a5cbb036ad317a765bdaa8604fb0a5ae5 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 14 Jun 2023 20:53:11 +0530 Subject: [PATCH 373/528] [nrf fromtree] net: wifi: Add support to get and set Wi-Fi as default interface Add a configuration option to set Wi-Fi as default interface and also add an API to get first available Wi-Fi interface. Signed-off-by: Chaitanya Tata (cherry picked from commit 91b5b4424cf3472a978217a23a01442d8f031237) --- include/zephyr/net/net_if.h | 7 +++++++ subsys/net/ip/Kconfig | 4 ++++ subsys/net/ip/net_if.c | 17 ++++++++++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 2c04e64e0dcf..63f1e3549c48 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -2535,6 +2535,13 @@ bool net_if_is_suspended(struct net_if *iface); */ bool net_if_is_wifi(struct net_if *iface); +/** + * @brief Get first Wi-Fi network interface. + * + * @return Pointer to network interface, NULL if not found. + */ +struct net_if *net_if_get_first_wifi(void); + /** @cond INTERNAL_HIDDEN */ struct net_if_api { diff --git a/subsys/net/ip/Kconfig b/subsys/net/ip/Kconfig index 2ce2e35171fe..e5f096e594f5 100644 --- a/subsys/net/ip/Kconfig +++ b/subsys/net/ip/Kconfig @@ -828,6 +828,10 @@ config NET_DEFAULT_IF_PPP bool "PPP interface" depends on NET_L2_PPP +config NET_DEFAULT_IF_WIFI + bool "WiFi interface" + depends on NET_L2_ETHERNET + endchoice config NET_PKT_TIMESTAMP diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index adf68fa33b13..ac90fbd0e96a 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -619,7 +619,9 @@ struct net_if *net_if_get_default(void) #if defined(CONFIG_NET_DEFAULT_IF_UP) iface = net_if_get_first_up(); #endif - +#if defined(CONFIG_NET_DEFAULT_IF_WIFI) + iface = net_if_get_first_wifi(); +#endif return iface ? iface : _net_if_list_start; } @@ -4601,9 +4603,18 @@ bool net_if_is_wifi(struct net_if *iface) #if defined(CONFIG_NET_L2_ETHERNET) return net_if_l2(iface) == &NET_L2_GET_NAME(ETHERNET) && net_eth_type_is_wifi(iface); -#else - return false; #endif + return false; +} + +struct net_if *net_if_get_first_wifi(void) +{ + STRUCT_SECTION_FOREACH(net_if, iface) { + if (net_if_is_wifi(iface)) { + return iface; + } + } + return NULL; } void net_if_init(void) From ce848f67f9eb1783b8fd133a90b78c9e713b6c09 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 14 Jun 2023 20:54:36 +0530 Subject: [PATCH 374/528] [nrf fromtree] net: wifi: Use only Wi-Fi interfaces As this is Wi-Fi shell use only Wi-Fi interfaces, if none are found fail. Signed-off-by: Chaitanya Tata (cherry picked from commit 5aced7130dd2511fdb7cdb84dc0f991d6e78da6b) --- subsys/net/l2/wifi/wifi_shell.c | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 36ac32e67224..9546eaa49fd5 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -389,7 +389,7 @@ static int __wifi_args_to_params(size_t argc, char *argv[], static int cmd_wifi_connect(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_connect_req_params cnx_params = { 0 }; if (__wifi_args_to_params(argc - 1, &argv[1], &cnx_params)) { @@ -417,7 +417,7 @@ static int cmd_wifi_connect(const struct shell *sh, size_t argc, static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); int status; context.disconnecting = true; @@ -446,7 +446,7 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); context.sh = sh; @@ -463,7 +463,7 @@ static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_iface_status status = { 0 }; context.sh = sh; @@ -538,7 +538,7 @@ static int cmd_wifi_stats(const struct shell *sh, size_t argc, char *argv[]) { #if defined(CONFIG_NET_STATISTICS_WIFI) && \ defined(CONFIG_NET_STATISTICS_USER_API) - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct net_stats_wifi stats = { 0 }; int ret; @@ -561,7 +561,7 @@ static int cmd_wifi_stats(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_ps_params params = { 0 }; context.sh = sh; @@ -646,7 +646,7 @@ static int cmd_wifi_ps(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_ps_params params = { 0 }; context.sh = sh; @@ -676,7 +676,7 @@ static int cmd_wifi_ps_mode(const struct shell *sh, size_t argc, char *argv[]) static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_ps_params params = { 0 }; long timeout_ms = 0; int err = 0; @@ -712,7 +712,7 @@ static int cmd_wifi_ps_timeout(const struct shell *sh, size_t argc, char *argv[] static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_twt_params params = { 0 }; int idx = 1; @@ -761,7 +761,7 @@ static int cmd_wifi_twt_setup_quick(const struct shell *sh, size_t argc, static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_twt_params params = { 0 }; int idx = 1; long neg_type; @@ -816,7 +816,7 @@ static int cmd_wifi_twt_setup(const struct shell *sh, size_t argc, static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_twt_params params = { 0 }; long neg_type = 0; long setup_cmd = 0; @@ -862,7 +862,7 @@ static int cmd_wifi_twt_teardown(const struct shell *sh, size_t argc, static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_twt_params params = { 0 }; context.sh = sh; @@ -888,7 +888,7 @@ static int cmd_wifi_twt_teardown_all(const struct shell *sh, size_t argc, static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); static struct wifi_connect_req_params cnx_params; int ret; @@ -914,7 +914,7 @@ static int cmd_wifi_ap_enable(const struct shell *sh, size_t argc, static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); int ret; ret = net_mgmt(NET_REQUEST_WIFI_AP_DISABLE, iface, NULL, 0); @@ -932,7 +932,7 @@ static int cmd_wifi_ap_disable(const struct shell *sh, size_t argc, static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_reg_domain regd = {0}; int ret; @@ -991,7 +991,7 @@ static int cmd_wifi_reg_domain(const struct shell *sh, size_t argc, static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_ps_params params = { 0 }; long interval = 0; @@ -1030,7 +1030,7 @@ static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *a static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *argv[]) { - struct net_if *iface = net_if_get_default(); + struct net_if *iface = net_if_get_first_wifi(); struct wifi_ps_params params = { 0 }; context.sh = sh; From 7d0f1725a27bc7fdefec2b78e36c5929b9bad528 Mon Sep 17 00:00:00 2001 From: Ajay Parida Date: Tue, 6 Jun 2023 19:44:24 +0530 Subject: [PATCH 375/528] [nrf fromtree] net: mgmt: Support for forced Passive scan Default scan mode is Active. User can force the scan mode to passive through Kconfig option or using 'passive' option from shell. Using either of this option will override regulatory settings and forces all scan channels to be passive only. Signed-off-by: Ajay Parida (cherry picked from commit 69fead199828a418c31a2f4f8362e6d94dc703ef) --- drivers/wifi/esp32/src/esp_wifi_drv.c | 9 ++++++++- drivers/wifi/esp_at/esp.c | 6 +++++- drivers/wifi/eswifi/eswifi_core.c | 6 +++++- drivers/wifi/simplelink/simplelink.c | 6 +++++- drivers/wifi/winc1500/wifi_winc1500.c | 6 +++++- include/zephyr/net/wifi.h | 5 +++++ include/zephyr/net/wifi_mgmt.h | 14 +++++++++++++- subsys/net/l2/wifi/Kconfig | 8 ++++++++ subsys/net/l2/wifi/wifi_mgmt.c | 9 ++++++++- subsys/net/l2/wifi/wifi_shell.c | 26 ++++++++++++++++++++++++-- 10 files changed, 86 insertions(+), 9 deletions(-) diff --git a/drivers/wifi/esp32/src/esp_wifi_drv.c b/drivers/wifi/esp32/src/esp_wifi_drv.c index 5f69c88c02d1..5272b6df21e4 100644 --- a/drivers/wifi/esp32/src/esp_wifi_drv.c +++ b/drivers/wifi/esp32/src/esp_wifi_drv.c @@ -388,7 +388,9 @@ static int esp32_wifi_connect(const struct device *dev, return 0; } -static int esp32_wifi_scan(const struct device *dev, scan_result_cb_t cb) +static int esp32_wifi_scan(const struct device *dev, + struct wifi_scan_params *params, + scan_result_cb_t cb) { struct esp32_wifi_runtime *data = dev->data; int ret = 0; @@ -402,6 +404,11 @@ static int esp32_wifi_scan(const struct device *dev, scan_result_cb_t cb) wifi_scan_config_t scan_config = { 0 }; + if (params) { + /* The enum values are same, so, no conversion needed */ + scan_config->scan_type = params->scan_type; + } + ret = esp_wifi_set_mode(ESP32_WIFI_MODE_STA); ret |= esp_wifi_scan_start(&scan_config, false); diff --git a/drivers/wifi/esp_at/esp.c b/drivers/wifi/esp_at/esp.c index 614d7fb517ac..e245c2073ff6 100644 --- a/drivers/wifi/esp_at/esp.c +++ b/drivers/wifi/esp_at/esp.c @@ -899,10 +899,14 @@ static void esp_mgmt_scan_work(struct k_work *work) dev->scan_cb = NULL; } -static int esp_mgmt_scan(const struct device *dev, scan_result_cb_t cb) +static int esp_mgmt_scan(const struct device *dev, + struct wifi_scan_params *params, + scan_result_cb_t cb) { struct esp_data *data = dev->data; + ARG_UNUSED(params); + if (data->scan_cb != NULL) { return -EINPROGRESS; } diff --git a/drivers/wifi/eswifi/eswifi_core.c b/drivers/wifi/eswifi/eswifi_core.c index a92991e4552d..44c911831dfe 100644 --- a/drivers/wifi/eswifi/eswifi_core.c +++ b/drivers/wifi/eswifi/eswifi_core.c @@ -520,10 +520,14 @@ int eswifi_mgmt_iface_status(const struct device *dev, return 0; } -static int eswifi_mgmt_scan(const struct device *dev, scan_result_cb_t cb) +static int eswifi_mgmt_scan(const struct device *dev, + struct wifi_scan_params *params, + scan_result_cb_t cb) { struct eswifi_dev *eswifi = dev->data; + ARG_UNUSED(params); + LOG_DBG(""); eswifi_lock(eswifi); diff --git a/drivers/wifi/simplelink/simplelink.c b/drivers/wifi/simplelink/simplelink.c index a959d8c14402..c7e7e9ab725a 100644 --- a/drivers/wifi/simplelink/simplelink.c +++ b/drivers/wifi/simplelink/simplelink.c @@ -136,11 +136,15 @@ static void simplelink_scan_work_handler(struct k_work *work) } } -static int simplelink_mgmt_scan(const struct device *dev, scan_result_cb_t cb) +static int simplelink_mgmt_scan(const struct device *dev, + struct wifi_scan_params *params, + scan_result_cb_t cb) { int err; int status; + ARG_UNUSED(params); + /* Cancel any previous scan processing in progress: */ k_work_cancel_delayable(&simplelink_data.work); diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index 19525cc2fd0e..acab7e94d006 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -976,8 +976,12 @@ static void winc1500_thread(void) } } -static int winc1500_mgmt_scan(const struct device *dev, scan_result_cb_t cb) +static int winc1500_mgmt_scan(const struct device *dev, + struct wifi_scan_params *params, + scan_result_cb_t cb) { + ARG_UNUSED(params); + if (w1500_data.scan_cb) { return -EALREADY; } diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index ae9f8cfa6db4..9c65f3197901 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -264,6 +264,11 @@ static inline const char *wifi_link_mode_txt(enum wifi_link_mode link_mode) } } +enum wifi_scan_type { + WIFI_SCAN_TYPE_ACTIVE = 0, + WIFI_SCAN_TYPE_PASSIVE, +}; + enum wifi_ps { WIFI_PS_DISABLED = 0, WIFI_PS_ENABLED, diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 7f9cb68c5e99..b303d01fc1bd 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -143,6 +143,16 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) + +struct wifi_scan_params { + /* The scan_type is only a hint to the underlying Wi-Fi chip for the + * preferred mode of scan. The actual mode of scan can depend on factors + * such as the Wi-Fi chip implementation support, regulatory domain + * restrictions etc. + */ + enum wifi_scan_type scan_type; +}; + /* Each result is provided to the net_mgmt_event_callback * via its info attribute (see net_mgmt.h) */ @@ -321,7 +331,9 @@ struct net_wifi_mgmt_offload { * result by the driver. The wifi mgmt part will take care of * raising the necessary event etc... */ - int (*scan)(const struct device *dev, scan_result_cb_t cb); + int (*scan)(const struct device *dev, + struct wifi_scan_params *params, + scan_result_cb_t cb); int (*connect)(const struct device *dev, struct wifi_connect_req_params *params); int (*disconnect)(const struct device *dev); diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 48bcff3943e6..ade546fac7d0 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -38,3 +38,11 @@ config WIFI_MGMT_TWT_CHECK_IP being unreachable (IP Level) or unable to receive down link traffic even when it is awake intervals. Rejecting TWT setup till Wi-Fi interface has a valid IP address might be desirable in most scenarios. + +config WIFI_MGMT_FORCED_PASSIVE_SCAN + bool "Force Passive scan" + help + Force passive scan (typically used to reduce power consumption), + the scan type is always sent as passive. + This doesn't guarantee that passive scan will be used, it depends + on the underlying chip implementation to support and honour scan type. diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 266938b38518..c3bc788132c3 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -84,12 +84,19 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + struct wifi_scan_params *params = data; if (off_api == NULL || off_api->scan == NULL) { return -ENOTSUP; } - return off_api->scan(dev, scan_result_cb); + if (data && (len == sizeof(*params))) { +#ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN + params->scan_type = WIFI_SCAN_TYPE_PASSIVE; +#endif + } + + return off_api->scan(dev, params, scan_result_cb); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_SCAN, wifi_scan); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 9546eaa49fd5..5372f8746d73 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -447,10 +447,29 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); + struct wifi_scan_params params = { 0 }; context.sh = sh; - if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, NULL, 0)) { + if (argc > 2) { + shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); + return -ENOEXEC; + } + + if (argc == 2) { + if (!strcmp(argv[1], "passive")) { + params.scan_type = WIFI_SCAN_TYPE_PASSIVE; + } else if (!strcmp(argv[1], "active")) { + params.scan_type = WIFI_SCAN_TYPE_ACTIVE; + } else { + shell_fprintf(sh, SHELL_WARNING, "Invalid argument\n"); + shell_fprintf(sh, SHELL_INFO, + "Valid argument : / \n"); + return -ENOEXEC; + } + } + + if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "Scan request failed\n"); return -ENOEXEC; @@ -1114,7 +1133,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, cmd_wifi_ps_mode, 2, 0), - SHELL_CMD(scan, NULL, "Scan for Wi-Fi APs", cmd_wifi_scan), + SHELL_CMD(scan, NULL, + "Scan for Wi-Fi APs\n" + " : >\n", + cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), SHELL_CMD(twt, &wifi_twt_ops, "Manage TWT flows", NULL), From f1d99846d258d258b3f36cce5d838e89a19845f0 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 14 Jun 2023 01:34:14 +0530 Subject: [PATCH 376/528] [nrf fromlist] net: wifi: Move Wi-Fi ops to a separate struct Decouple interface and Wi-Fi APIs, Wi-Fi APIs are common independent of Wi-Fi offload or implemented natively (This is preparation for introducing Native Wi-Fi). Upstream-Pr: https://github.com/zephyrproject-rtos/zephyr/pull/59249 Signed-off-by: Chaitanya Tata --- drivers/wifi/esp32/src/esp_wifi_drv.c | 24 ++++++---- drivers/wifi/esp_at/esp.c | 19 +++++--- drivers/wifi/eswifi/eswifi_core.c | 18 ++++--- drivers/wifi/simplelink/simplelink.c | 12 +++-- drivers/wifi/winc1500/wifi_winc1500.c | 15 +++--- include/zephyr/net/wifi_mgmt.h | 29 ++++++------ subsys/net/l2/wifi/wifi_mgmt.c | 67 +++++++++++++++++---------- 7 files changed, 112 insertions(+), 72 deletions(-) diff --git a/drivers/wifi/esp32/src/esp_wifi_drv.c b/drivers/wifi/esp32/src/esp_wifi_drv.c index 5272b6df21e4..7f2908b7bc09 100644 --- a/drivers/wifi/esp32/src/esp_wifi_drv.c +++ b/drivers/wifi/esp32/src/esp_wifi_drv.c @@ -624,18 +624,22 @@ static int esp32_wifi_dev_init(const struct device *dev) return 0; } +static const struct wifi_mgmt_ops esp32_wifi_mgmt = { + .scan = esp32_wifi_scan, + .connect = esp32_wifi_connect, + .disconnect = esp32_wifi_disconnect, + .ap_enable = esp32_wifi_ap_enable, + .ap_disable = esp32_wifi_ap_disable, + .iface_status = esp32_wifi_status, +#if defined(CONFIG_NET_STATISTICS_WIFI) + .get_stats = esp32_wifi_stats, +#endif +}; + static const struct net_wifi_mgmt_offload esp32_api = { - .wifi_iface.iface_api.init = esp32_wifi_init, + .wifi_iface.iface_api.init = esp32_wifi_init, .wifi_iface.send = esp32_wifi_send, -#if defined(CONFIG_NET_STATISTICS_WIFI) - .get_stats = esp32_wifi_stats, - #endif - .scan = esp32_wifi_scan, - .connect = esp32_wifi_connect, - .disconnect = esp32_wifi_disconnect, - .ap_enable = esp32_wifi_ap_enable, - .ap_disable = esp32_wifi_ap_disable, - .iface_status = esp32_wifi_status, + .wifi_mgmt_api = &esp32_wifi_mgmt, }; NET_DEVICE_DT_INST_DEFINE(0, diff --git a/drivers/wifi/esp_at/esp.c b/drivers/wifi/esp_at/esp.c index e245c2073ff6..6cd41709096d 100644 --- a/drivers/wifi/esp_at/esp.c +++ b/drivers/wifi/esp_at/esp.c @@ -1223,15 +1223,20 @@ static enum offloaded_net_if_types esp_offload_get_type(void) { return L2_OFFLOADED_NET_IF_TYPE_WIFI; } + +static const struct wifi_mgmt_ops esp_mgmt_ops = { + .scan = esp_mgmt_scan, + .connect = esp_mgmt_connect, + .disconnect = esp_mgmt_disconnect, + .ap_enable = esp_mgmt_ap_enable, + .ap_disable = esp_mgmt_ap_disable, + .iface_status = esp_mgmt_iface_status, +}; + static const struct net_wifi_mgmt_offload esp_api = { .wifi_iface.iface_api.init = esp_iface_init, - .wifi_iface.get_type = esp_offload_get_type, - .scan = esp_mgmt_scan, - .connect = esp_mgmt_connect, - .disconnect = esp_mgmt_disconnect, - .ap_enable = esp_mgmt_ap_enable, - .ap_disable = esp_mgmt_ap_disable, - .iface_status = esp_mgmt_iface_status, + .wifi_iface.get_type = esp_offload_get_type, + .wifi_mgmt_api = &esp_mgmt_ops, }; static int esp_init(const struct device *dev); diff --git a/drivers/wifi/eswifi/eswifi_core.c b/drivers/wifi/eswifi/eswifi_core.c index 44c911831dfe..b05c980500d0 100644 --- a/drivers/wifi/eswifi/eswifi_core.c +++ b/drivers/wifi/eswifi/eswifi_core.c @@ -786,15 +786,19 @@ static enum offloaded_net_if_types eswifi_get_type(void) return L2_OFFLOADED_NET_IF_TYPE_WIFI; } +static const struct wifi_mgmt_ops eswifi_mgmt_api = { + .scan = eswifi_mgmt_scan, + .connect = eswifi_mgmt_connect, + .disconnect = eswifi_mgmt_disconnect, + .ap_enable = eswifi_mgmt_ap_enable, + .ap_disable = eswifi_mgmt_ap_disable, + .iface_status = eswifi_mgmt_iface_status, +}; + static const struct net_wifi_mgmt_offload eswifi_offload_api = { .wifi_iface.iface_api.init = eswifi_iface_init, - .wifi_iface.get_type = eswifi_get_type, - .scan = eswifi_mgmt_scan, - .connect = eswifi_mgmt_connect, - .disconnect = eswifi_mgmt_disconnect, - .ap_enable = eswifi_mgmt_ap_enable, - .ap_disable = eswifi_mgmt_ap_disable, - .iface_status = eswifi_mgmt_iface_status, + .wifi_iface.get_type = eswifi_get_type, + .wifi_mgmt_api = &eswifi_mgmt_api, }; NET_DEVICE_DT_INST_OFFLOAD_DEFINE(0, eswifi_init, NULL, diff --git a/drivers/wifi/simplelink/simplelink.c b/drivers/wifi/simplelink/simplelink.c index c7e7e9ab725a..6e89275ee6fc 100644 --- a/drivers/wifi/simplelink/simplelink.c +++ b/drivers/wifi/simplelink/simplelink.c @@ -272,12 +272,16 @@ static enum offloaded_net_if_types simplelink_get_type(void) return L2_OFFLOADED_NET_IF_TYPE_WIFI; } +static const struct wifi_mgmt_ops simplelink_mgmt = { + .scan = simplelink_mgmt_scan, + .connect = simplelink_mgmt_connect, + .disconnect = simplelink_mgmt_disconnect, +}; + static const struct net_wifi_mgmt_offload simplelink_api = { .wifi_iface.iface_api.init = simplelink_iface_init, - .wifi_iface.get_type = simplelink_get_type, - .scan = simplelink_mgmt_scan, - .connect = simplelink_mgmt_connect, - .disconnect = simplelink_mgmt_disconnect, + .wifi_iface.get_type = simplelink_get_type, + .wifi_mgmt_api = &simplelink_mgmt, }; static int simplelink_init(const struct device *dev) diff --git a/drivers/wifi/winc1500/wifi_winc1500.c b/drivers/wifi/winc1500/wifi_winc1500.c index acab7e94d006..264882936283 100644 --- a/drivers/wifi/winc1500/wifi_winc1500.c +++ b/drivers/wifi/winc1500/wifi_winc1500.c @@ -1108,14 +1108,17 @@ static enum offloaded_net_if_types winc1500_get_wifi_type(void) return L2_OFFLOADED_NET_IF_TYPE_WIFI; } +static const struct wifi_mgmt_ops winc1500_mgmt_ops = { + .scan = winc1500_mgmt_scan, + .connect = winc1500_mgmt_connect, + .disconnect = winc1500_mgmt_disconnect, + .ap_enable = winc1500_mgmt_ap_enable, + .ap_disable = winc1500_mgmt_ap_disable, +}; static const struct net_wifi_mgmt_offload winc1500_api = { .wifi_iface.iface_api.init = winc1500_iface_init, - .wifi_iface.get_type = winc1500_get_wifi_type, - .scan = winc1500_mgmt_scan, - .connect = winc1500_mgmt_connect, - .disconnect = winc1500_mgmt_disconnect, - .ap_enable = winc1500_mgmt_ap_enable, - .ap_disable = winc1500_mgmt_ap_disable, + .wifi_iface.get_type = winc1500_get_wifi_type, + .wifi_mgmt_api = &winc1500_mgmt_ops, }; static int winc1500_init(const struct device *dev) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index b303d01fc1bd..fdb2814408b1 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -314,19 +314,7 @@ typedef void (*scan_result_cb_t)(struct net_if *iface, int status, typedef void (*raw_scan_result_cb_t)(struct net_if *iface, int status, struct wifi_raw_scan_result *entry); #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ -struct net_wifi_mgmt_offload { - /** - * Mandatory to get in first position. - * A network device should indeed provide a pointer on such - * net_if_api structure. So we make current structure pointer - * that can be casted to a net_if_api structure pointer. - */ -#ifdef CONFIG_WIFI_USE_NATIVE_NETWORKING - struct ethernet_api wifi_iface; -#else - struct offloaded_if_api wifi_iface; -#endif - +struct wifi_mgmt_ops { /* cb parameter is the cb that should be called for each * result by the driver. The wifi mgmt part will take care of * raising the necessary event etc... @@ -350,6 +338,21 @@ struct net_wifi_mgmt_offload { int (*reg_domain)(const struct device *dev, struct wifi_reg_domain *reg_domain); }; +struct net_wifi_mgmt_offload { + /** + * Mandatory to get in first position. + * A network device should indeed provide a pointer on such + * net_if_api structure. So we make current structure pointer + * that can be casted to a net_if_api structure pointer. + */ +#ifdef CONFIG_WIFI_USE_NATIVE_NETWORKING + struct ethernet_api wifi_iface; +#else + struct offloaded_if_api wifi_iface; +#endif + const struct wifi_mgmt_ops *const wifi_mgmt_api; +}; + /* Make sure that the network interface API is properly setup inside * Wifi mgmt offload API struct (it is the first one). */ diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index c3bc788132c3..e0444d8477c5 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -12,6 +12,15 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include +#include +static const struct wifi_mgmt_ops *const get_wifi_api(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct net_wifi_mgmt_offload *off_api = + (struct net_wifi_mgmt_offload *) dev->api; + + return off_api ? off_api->wifi_mgmt_api : NULL; +} static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) @@ -21,8 +30,9 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; - if (off_api == NULL || off_api->connect == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->connect == NULL) { return -ENOTSUP; } @@ -49,7 +59,7 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, return -EINVAL; } - return off_api->connect(dev, params); + return wifi_mgmt_api->connect(dev, params); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_CONNECT, wifi_connect); @@ -82,11 +92,10 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; struct wifi_scan_params *params = data; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; - if (off_api == NULL || off_api->scan == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) { return -ENOTSUP; } @@ -96,24 +105,24 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, #endif } - return off_api->scan(dev, params, scan_result_cb); + return wifi_mgmt_api->scan(dev, params, scan_result_cb); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_SCAN, wifi_scan); - static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; - if (off_api == NULL || off_api->disconnect == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->disconnect == NULL) { return -ENOTSUP; } - return off_api->disconnect(dev); + return wifi_mgmt_api->disconnect(dev); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_DISCONNECT, wifi_disconnect); @@ -148,12 +157,13 @@ static int wifi_ap_enable(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; - if (off_api == NULL || off_api->ap_enable == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) { return -ENOTSUP; } - return off_api->ap_enable(dev, params); + return wifi_mgmt_api->ap_enable(dev, params); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_ENABLE, wifi_ap_enable); @@ -164,12 +174,13 @@ static int wifi_ap_disable(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; - if (off_api == NULL || off_api->ap_enable == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) { return -ENOTSUP; } - return off_api->ap_disable(dev); + return wifi_mgmt_api->ap_disable(dev); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_DISABLE, wifi_ap_disable); @@ -180,9 +191,10 @@ static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; struct wifi_iface_status *status = data; - if (off_api == NULL || off_api->iface_status == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->iface_status == NULL) { return -ENOTSUP; } @@ -190,7 +202,7 @@ static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface, return -EINVAL; } - return off_api->iface_status(dev, status); + return wifi_mgmt_api->iface_status(dev, status); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_IFACE_STATUS, wifi_iface_status); @@ -209,9 +221,10 @@ static int wifi_iface_stats(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; struct net_stats_wifi *stats = data; - if (off_api == NULL || off_api->get_stats == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_stats == NULL) { return -ENOTSUP; } @@ -219,7 +232,7 @@ static int wifi_iface_stats(uint32_t mgmt_request, struct net_if *iface, return -EINVAL; } - return off_api->get_stats(dev, stats); + return wifi_mgmt_api->get_stats(dev, stats); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_STATS_GET_WIFI, wifi_iface_stats); #endif /* CONFIG_NET_STATISTICS_WIFI */ @@ -230,10 +243,11 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; struct wifi_ps_params *ps_params = data; struct wifi_iface_status info = { 0 }; - if (off_api == NULL || off_api->set_power_save == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_power_save == NULL) { return -ENOTSUP; } @@ -263,7 +277,7 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, return -ENOTSUP; } - return off_api->set_power_save(dev, ps_params); + return wifi_mgmt_api->set_power_save(dev, ps_params); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS, wifi_set_power_save); @@ -274,9 +288,10 @@ static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *ifac const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; struct wifi_ps_config *ps_config = data; - if (off_api == NULL || off_api->get_power_save_config == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_power_save_config == NULL) { return -ENOTSUP; } @@ -284,7 +299,7 @@ static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *ifac return -EINVAL; } - return off_api->get_power_save_config(dev, ps_config); + return wifi_mgmt_api->get_power_save_config(dev, ps_config); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_CONFIG, wifi_get_power_save_config); @@ -295,10 +310,11 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; struct wifi_twt_params *twt_params = data; struct wifi_iface_status info = { 0 }; - if (off_api == NULL || off_api->set_twt == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_twt == NULL) { twt_params->fail_reason = WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED; return -ENOTSUP; @@ -345,7 +361,7 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, goto fail; } - return off_api->set_twt(dev, twt_params); + return wifi_mgmt_api->set_twt(dev, twt_params); fail: return -ENOEXEC; @@ -366,9 +382,10 @@ static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; + const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; struct wifi_reg_domain *reg_domain = data; - if (off_api == NULL || off_api->reg_domain == NULL) { + if (wifi_mgmt_api == NULL || wifi_mgmt_api->reg_domain == NULL) { return -ENOTSUP; } @@ -376,7 +393,7 @@ static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface, return -EINVAL; } - return off_api->reg_domain(dev, reg_domain); + return wifi_mgmt_api->reg_domain(dev, reg_domain); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN, wifi_reg_domain); From 6ef7200a6d5316e04dad1e5cba53510eaee39942 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 14 Jun 2023 02:20:54 +0530 Subject: [PATCH 377/528] [nrf fromlist] net: wifi: Introduce Wi-Fi network managers This introduces support for Wi-Fi network managers in Zephyr. The motivation is for the Wi-Fi management layer to work with both Network managers and offloaded Wi-Fi drivers. The device driver decides which one to use. network manager : Apps -> Wi-Fi Mgmt -> Network Manager -> Wi-Fi interface offloaded : Apps -> Wi-Fi Mgmt -> Wi-Fi offloaded interface Support for multiple network managers has been added, each device can choose its own network manager and there can be mix and match: wlan0 - Offloaded wlan1 - Network manager 1 wlan2 - Network manager 2 Upstream-Pr: https://github.com/zephyrproject-rtos/zephyr/pull/59249 Signed-off-by: Chaitanya Tata --- include/zephyr/net/wifi_nm.h | 100 ++++++++++++++++++++++++++++++ subsys/net/l2/wifi/CMakeLists.txt | 7 +++ subsys/net/l2/wifi/Kconfig | 22 +++++++ subsys/net/l2/wifi/wifi_nm.c | 75 ++++++++++++++++++++++ subsys/net/l2/wifi/wifi_nm.ld | 7 +++ 5 files changed, 211 insertions(+) create mode 100644 include/zephyr/net/wifi_nm.h create mode 100644 subsys/net/l2/wifi/wifi_nm.c create mode 100644 subsys/net/l2/wifi/wifi_nm.ld diff --git a/include/zephyr/net/wifi_nm.h b/include/zephyr/net/wifi_nm.h new file mode 100644 index 000000000000..dd97fcdd8b61 --- /dev/null +++ b/include/zephyr/net/wifi_nm.h @@ -0,0 +1,100 @@ +/** @file + * @brief Wi-Fi Network manager API + * + * This file contains the Wi-Fi network manager API. These APIs are used by the + * any network management application to register as a Wi-Fi network manager. + */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ZEPHYR_NET_WIFI_NM_H_ +#define ZEPHYR_INCLUDE_ZEPHYR_NET_WIFI_NM_H_ + +#include +#include +#include +#include +#include +/** + * @brief Wi-Fi Network manager API + * @defgroup wifi_nm Wi-Fi Network Manager API + * @ingroup networking + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief WiFi Network manager instance + */ +struct wifi_nm_instance { + /** Name of the Network manager instance */ + const char *name; + /** Wi-Fi Management operations */ + const struct wifi_mgmt_ops *ops; + /** List of Managed interfaces */ + struct net_if *mgd_ifaces[CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES]; +}; + +#define WIFI_NM_NAME(name) wifi_nm_##name + +#define DEFINE_WIFI_NM_INSTANCE(_name, _ops) \ + static STRUCT_SECTION_ITERABLE(wifi_nm_instance, WIFI_NM_NAME(_name)) = { \ + .name = STRINGIFY(_name), \ + .ops = _ops, \ + .mgd_ifaces = { NULL }, \ + } + +/** + * @brief Get a Network manager instance for a given name + * + * @param name Name of the Network manager instance + * + */ +struct wifi_nm_instance *wifi_nm_get_instance(const char *name); + +/** + * @brief Get a Network manager instance for a given interface + * + * @param iface Interface + * + */ +struct wifi_nm_instance *wifi_nm_get_instance_iface(struct net_if *iface); + +/** + * @brief Register a managed interface + * + * @param nm Pointer to Network manager instance + * @param iface Managed interface + * + * @retval 0 If successful. + * @retval -EINVAL If invalid parameters were passed. + * @retval -ENOTSUP If the interface is not a Wi-Fi interface. + * @retval -ENOMEM If the maximum number of managed interfaces has been reached. + */ +int wifi_nm_register_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface); + +/** + * @brief Unregister managed interface + * + * @param nm Pointer to Network manager instance + * @param iface Interface + * @return int 0 for OK; -EINVAL for invalid parameters; -ENOENT if interface is not registered + * with the Network manager. + */ +int wifi_nm_unregister_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif /* ZEPHYR_INCLUDE_ZEPHYR_NET_WIFI_NM_H_ */ diff --git a/subsys/net/l2/wifi/CMakeLists.txt b/subsys/net/l2/wifi/CMakeLists.txt index 3fb8eebd6150..6935d4e2a45c 100644 --- a/subsys/net/l2/wifi/CMakeLists.txt +++ b/subsys/net/l2/wifi/CMakeLists.txt @@ -8,3 +8,10 @@ zephyr_library_compile_definitions_ifdef( zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_MGMT wifi_mgmt.c) zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_SHELL wifi_shell.c) +zephyr_library_sources_ifdef(CONFIG_WIFI_NM wifi_nm.c) + +# Linker section placement for wifi_nm_instance iterable structure +zephyr_linker_sources_ifdef(CONFIG_WIFI_NM DATA_SECTIONS wifi_nm.ld) +if (CONFIG_WIFI_NM) +zephyr_iterable_section(NAME wifi_nm_instance GROUP DATA_REGION ${XIP_ALIGN_WITH_INPUT} SUBALIGN 4) +endif() diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index ade546fac7d0..ea55a499d18c 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -46,3 +46,25 @@ config WIFI_MGMT_FORCED_PASSIVE_SCAN the scan type is always sent as passive. This doesn't guarantee that passive scan will be used, it depends on the underlying chip implementation to support and honour scan type. + +config WIFI_NM + bool "Wi-Fi Network manager support" + help + This option enables using the Wi-Fi Network managers (e.g. wpa_supplicant) to + manage the Wi-Fi network interfaces. + +if WIFI_NM + +config WIFI_NM_MAX_MANAGED_INTERFACES + int "Maximum number of managed interfaces per Wi-Fi network manager" + default 1 + help + This option defines the maximum number of managed interfaces per Wi-Fi + network manager instance that can be used simultaneously. + +module = WIFI_NM +module-dep = NET_LOG +module-str = Log level for Wi-Fi Network manager module +module-help = Enables using the Wi-Fi Network managers to manage the Wi-Fi network interfaces. +source "subsys/net/Kconfig.template.log_config.net" +endif # WIFI_NM diff --git a/subsys/net/l2/wifi/wifi_nm.c b/subsys/net/l2/wifi/wifi_nm.c new file mode 100644 index 000000000000..4f3e2d239a1a --- /dev/null +++ b/subsys/net/l2/wifi/wifi_nm.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +LOG_MODULE_REGISTER(wifi_nm, CONFIG_WIFI_NM_LOG_LEVEL); + +#include +#include + +struct wifi_nm_instance *wifi_nm_get_instance(const char *name) +{ + STRUCT_SECTION_FOREACH(wifi_nm_instance, nm) { + if (!strcmp(nm->name, name)) { + return nm; + } + } + + return NULL; +} + +struct wifi_nm_instance *wifi_nm_get_instance_iface(struct net_if *iface) +{ + if (!iface || !net_if_is_wifi(iface)) { + return false; + } + + STRUCT_SECTION_FOREACH(wifi_nm_instance, nm) { + for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) { + if (nm->mgd_ifaces[i] == iface) { + return nm; + } + } + } + + return NULL; +} + +int wifi_nm_register_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface) +{ + if (!nm || !iface) { + return -EINVAL; + } + + if (!net_if_is_wifi(iface)) { + return -ENOTSUP; + } + + for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) { + if (!nm->mgd_ifaces[i]) { + nm->mgd_ifaces[i] = iface; + return 0; + } + } + + return -ENOMEM; +} + +int wifi_nm_unregister_mgd_iface(struct wifi_nm_instance *nm, struct net_if *iface) +{ + if (!nm || !iface) { + return -EINVAL; + } + + for (int i = 0; i < CONFIG_WIFI_NM_MAX_MANAGED_INTERFACES; i++) { + if (nm->mgd_ifaces[i] == iface) { + nm->mgd_ifaces[i] = NULL; + return 0; + } + } + + return -ENOENT; +} diff --git a/subsys/net/l2/wifi/wifi_nm.ld b/subsys/net/l2/wifi/wifi_nm.ld new file mode 100644 index 000000000000..73bc53f881a5 --- /dev/null +++ b/subsys/net/l2/wifi/wifi_nm.ld @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +ITERABLE_SECTION_RAM(wifi_nm_instance, 4) From 80f1eb307607d2c85548db166432d3567ebb3a7c Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 14 Jun 2023 20:27:22 +0530 Subject: [PATCH 378/528] [nrf fromlist] net: wifi: Add support to handle Wi-Fi NM's in Wi-Fi management Check if a network interface is managed by a network manager before falling back to offload API. Upstream-Pr: https://github.com/zephyrproject-rtos/zephyr/pull/59249 Signed-off-by: Chaitanya Tata --- subsys/net/l2/wifi/wifi_mgmt.c | 56 ++++++++++++++-------------------- 1 file changed, 23 insertions(+), 33 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index e0444d8477c5..59e40304d83f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -12,13 +12,22 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include -#include +#ifdef CONFIG_WIFI_NM +#include +#endif /* CONFIG_WIFI_NM */ + static const struct wifi_mgmt_ops *const get_wifi_api(struct net_if *iface) { const struct device *dev = net_if_get_device(iface); struct net_wifi_mgmt_offload *off_api = (struct net_wifi_mgmt_offload *) dev->api; +#ifdef CONFIG_WIFI_NM + struct wifi_nm_instance *nm = wifi_nm_get_instance_iface(iface); + if (nm) { + return nm->ops; + } +#endif /* CONFIG_WIFI_NM */ return off_api ? off_api->wifi_mgmt_api : NULL; } @@ -28,9 +37,8 @@ static int wifi_connect(uint32_t mgmt_request, struct net_if *iface, struct wifi_connect_req_params *params = (struct wifi_connect_req_params *)data; const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); if (wifi_mgmt_api == NULL || wifi_mgmt_api->connect == NULL) { return -ENOTSUP; @@ -93,7 +101,7 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, { const struct device *dev = net_if_get_device(iface); struct wifi_scan_params *params = data; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) { return -ENOTSUP; @@ -114,9 +122,7 @@ static int wifi_disconnect(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); if (wifi_mgmt_api == NULL || wifi_mgmt_api->disconnect == NULL) { return -ENOTSUP; @@ -155,9 +161,7 @@ static int wifi_ap_enable(uint32_t mgmt_request, struct net_if *iface, struct wifi_connect_req_params *params = (struct wifi_connect_req_params *)data; const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) { return -ENOTSUP; @@ -172,9 +176,7 @@ static int wifi_ap_disable(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); if (wifi_mgmt_api == NULL || wifi_mgmt_api->ap_enable == NULL) { return -ENOTSUP; @@ -189,9 +191,7 @@ static int wifi_iface_status(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); struct wifi_iface_status *status = data; if (wifi_mgmt_api == NULL || wifi_mgmt_api->iface_status == NULL) { @@ -219,9 +219,7 @@ static int wifi_iface_stats(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); struct net_stats_wifi *stats = data; if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_stats == NULL) { @@ -241,9 +239,7 @@ static int wifi_set_power_save(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); struct wifi_ps_params *ps_params = data; struct wifi_iface_status info = { 0 }; @@ -286,9 +282,7 @@ static int wifi_get_power_save_config(uint32_t mgmt_request, struct net_if *ifac void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); struct wifi_ps_config *ps_config = data; if (wifi_mgmt_api == NULL || wifi_mgmt_api->get_power_save_config == NULL) { @@ -308,9 +302,7 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); struct wifi_twt_params *twt_params = data; struct wifi_iface_status info = { 0 }; @@ -321,7 +313,7 @@ static int wifi_set_twt(uint32_t mgmt_request, struct net_if *iface, } if (twt_params->operation == WIFI_TWT_TEARDOWN) { - return off_api->set_twt(dev, twt_params); + return wifi_mgmt_api->set_twt(dev, twt_params); } if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &info, @@ -380,9 +372,7 @@ static int wifi_reg_domain(uint32_t mgmt_request, struct net_if *iface, void *data, size_t len) { const struct device *dev = net_if_get_device(iface); - struct net_wifi_mgmt_offload *off_api = - (struct net_wifi_mgmt_offload *) dev->api; - const struct wifi_mgmt_ops *const wifi_mgmt_api = off_api ? off_api->wifi_mgmt_api : NULL; + const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); struct wifi_reg_domain *reg_domain = data; if (wifi_mgmt_api == NULL || wifi_mgmt_api->reg_domain == NULL) { From 7fd8d500641d1d10be48a9ba5823e408bc822578 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 16 Jun 2023 00:47:54 +0530 Subject: [PATCH 379/528] [nrf fromlist] tests: wifi: Add Wi-Fi test suite This adds Wi-Fi tests for both offloaded and newly introduced network manager managed interface. Only scan op is used to verify the network manager code. Upstream-Pr: https://github.com/zephyrproject-rtos/zephyr/pull/59249 Signed-off-by: Chaitanya Tata --- tests/net/wifi/wifi_nm/CMakeLists.txt | 8 ++ tests/net/wifi/wifi_nm/Kconfig | 14 ++ tests/net/wifi/wifi_nm/prj.conf | 19 +++ tests/net/wifi/wifi_nm/src/main.c | 186 ++++++++++++++++++++++++++ tests/net/wifi/wifi_nm/testcase.yaml | 6 + 5 files changed, 233 insertions(+) create mode 100644 tests/net/wifi/wifi_nm/CMakeLists.txt create mode 100644 tests/net/wifi/wifi_nm/Kconfig create mode 100644 tests/net/wifi/wifi_nm/prj.conf create mode 100644 tests/net/wifi/wifi_nm/src/main.c create mode 100644 tests/net/wifi/wifi_nm/testcase.yaml diff --git a/tests/net/wifi/wifi_nm/CMakeLists.txt b/tests/net/wifi/wifi_nm/CMakeLists.txt new file mode 100644 index 000000000000..4a2a6013031f --- /dev/null +++ b/tests/net/wifi/wifi_nm/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(wifi_nm) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/net/wifi/wifi_nm/Kconfig b/tests/net/wifi/wifi_nm/Kconfig new file mode 100644 index 000000000000..57e1217d10a0 --- /dev/null +++ b/tests/net/wifi/wifi_nm/Kconfig @@ -0,0 +1,14 @@ +# Configuration opions for Wi-Fi test + +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + + +source "Kconfig.zephyr" + +# The purpose of this Kconfig is to select the hidden symbol +config WIFI_TEST_ENABLE + bool "Enable Wi-Fi test" + default y + select WIFI + select WIFI_USE_NATIVE_NETWORKING diff --git a/tests/net/wifi/wifi_nm/prj.conf b/tests/net/wifi/wifi_nm/prj.conf new file mode 100644 index 000000000000..abeb08fca4fa --- /dev/null +++ b/tests/net/wifi/wifi_nm/prj.conf @@ -0,0 +1,19 @@ +CONFIG_NETWORKING=y +CONFIG_NET_TEST=y +CONFIG_NET_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_MAX_CONTEXTS=4 +CONFIG_NET_L2_ETHERNET=y +CONFIG_NET_L2_WIFI_MGMT=y +CONFIG_WIFI_NM=y +CONFIG_NET_LOG=y +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_ENTROPY_GENERATOR=y +CONFIG_TEST_RANDOM_GENERATOR=y +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y + +# Disable internal ethernet drivers as the test is self contained +# and does not need the on board driver to function. +CONFIG_ETH_DRIVER=n diff --git a/tests/net/wifi/wifi_nm/src/main.c b/tests/net/wifi/wifi_nm/src/main.c new file mode 100644 index 000000000000..0ca9e6335531 --- /dev/null +++ b/tests/net/wifi/wifi_nm/src/main.c @@ -0,0 +1,186 @@ +/* main.c - Application main entry point */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define NET_LOG_LEVEL CONFIG_NET_L2_ETHERNET_LOG_LEVEL + +#include +LOG_MODULE_REGISTER(net_test, NET_LOG_LEVEL); + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#if NET_LOG_LEVEL >= LOG_LEVEL_DBG +#define DBG(fmt, ...) printk(fmt, ##__VA_ARGS__) +#else +#define DBG(fmt, ...) +#endif + +struct wifi_drv_context { + struct net_if *iface; + uint8_t mac_addr[6]; + enum ethernet_if_types eth_if_type; +}; + +static struct wifi_drv_context wifi_context; + +bool wifi_nm_op_called; +bool wifi_offload_op_called; + +static void wifi_iface_init(struct net_if *iface) +{ + const struct device *dev = net_if_get_device(iface); + struct wifi_drv_context *context = dev->data; + struct ethernet_context *eth_ctx = net_if_l2_data(iface); + + net_if_set_link_addr(iface, context->mac_addr, + sizeof(context->mac_addr), + NET_LINK_ETHERNET); + + eth_ctx->eth_if_type = L2_ETH_IF_TYPE_WIFI; + + ethernet_init(iface); +} + +static int wifi_scan(const struct device *dev, struct wifi_scan_params *params, + scan_result_cb_t cb) +{ + ARG_UNUSED(dev); + ARG_UNUSED(params); + ARG_UNUSED(cb); + + wifi_offload_op_called = true; + + return 0; +} + +static struct wifi_mgmt_ops wifi_mgmt_api = { + .scan = wifi_scan, +}; + +static struct net_wifi_mgmt_offload api_funcs = { + .wifi_iface.iface_api.init = wifi_iface_init, + .wifi_mgmt_api = &wifi_mgmt_api, +}; + +static void generate_mac(uint8_t *mac_addr) +{ + /* 00-00-5E-00-53-xx Documentation RFC 7042 */ + mac_addr[0] = 0x00; + mac_addr[1] = 0x00; + mac_addr[2] = 0x5E; + mac_addr[3] = 0x00; + mac_addr[4] = 0x53; + mac_addr[5] = sys_rand32_get(); +} + +static int wifi_init(const struct device *dev) +{ + struct wifi_drv_context *context = dev->data; + + context->eth_if_type = L2_ETH_IF_TYPE_WIFI; + + generate_mac(context->mac_addr); + + return 0; +} + +ETH_NET_DEVICE_INIT(wlan0, "wifi_test", + wifi_init, NULL, + &wifi_context, NULL, CONFIG_ETH_INIT_PRIORITY, + &api_funcs, NET_ETH_MTU); + +static int wifi_nm_scan(const struct device *dev, struct wifi_scan_params *params, + scan_result_cb_t cb) +{ + ARG_UNUSED(dev); + ARG_UNUSED(params); + ARG_UNUSED(cb); + + wifi_nm_op_called = true; + + return 0; +} + +static struct wifi_mgmt_ops wifi_nm_test_ops = { + .scan = wifi_nm_scan, +}; + +DEFINE_WIFI_NM_INSTANCE(test, &wifi_nm_test_ops); + +static int request_scan(void) +{ + struct net_if *iface = net_if_get_first_wifi(); + + if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, NULL, 0)) { + printk("Scan request failed\n"); + + return -ENOEXEC; + } + + return 0; +} + +ZTEST(net_wifi, test_wifi_offload) +{ + + int ret; +#ifdef CONFIG_WIFI_NM + struct wifi_nm_instance *nm = wifi_nm_get_instance("test"); + + if (wifi_nm_get_instance_iface(net_if_get_first_wifi())) { + ret = wifi_nm_unregister_mgd_iface(nm, net_if_get_first_wifi()); + zassert_equal(ret, 0, "Failed to unregister managed interface"); + } +#endif /* CONFIG_WIFI_NM */ + + ret = request_scan(); + zassert_equal(ret, 0, "Scan request failed"); + zassert_true(wifi_offload_op_called, "Scan callback not called"); +} + +ZTEST(net_wifi, test_wifi_nm_managed) +{ + + int ret; + struct wifi_nm_instance *nm = wifi_nm_get_instance("test"); + + zassert_equal(nm->ops, &wifi_nm_test_ops, + "Invalid wifi nm ops"); + + /* Offload: in presence of registered NM but with no managed + * interfaces. + */ + ret = request_scan(); + zassert_equal(ret, 0, "Scan request failed"); + zassert_true(wifi_offload_op_called, "Scan callback not called"); + + ret = wifi_nm_register_mgd_iface(nm, net_if_get_first_wifi()); + zassert_equal(ret, 0, "Failed to register managed interface"); + + zassert_equal(nm->ops, &wifi_nm_test_ops, + "Invalid wifi nm ops"); + + ret = request_scan(); + zassert_equal(ret, 0, "Scan request failed"); + zassert_true(wifi_nm_op_called, "Scan callback not called"); +} + + +ZTEST_SUITE(net_wifi, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/net/wifi/wifi_nm/testcase.yaml b/tests/net/wifi/wifi_nm/testcase.yaml new file mode 100644 index 000000000000..227f39feaac1 --- /dev/null +++ b/tests/net/wifi/wifi_nm/testcase.yaml @@ -0,0 +1,6 @@ +common: + depends_on: netif +tests: + net.wifi: + min_ram: 32 + tags: wifi From 2dcb7abfee0a00db4f8b751b82b9cf10d41df792 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 16 Jun 2023 01:00:02 +0530 Subject: [PATCH 380/528] [nrf fromlist] doc: net: Add an entry for Wi-Fi Management This was missing all along. Upstream-Pr: https://github.com/zephyrproject-rtos/zephyr/pull/59249 Signed-off-by: Chaitanya Tata --- doc/connectivity/networking/overview.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/doc/connectivity/networking/overview.rst b/doc/connectivity/networking/overview.rst index 5c885e9d287a..32d08015abc2 100644 --- a/doc/connectivity/networking/overview.rst +++ b/doc/connectivity/networking/overview.rst @@ -99,12 +99,16 @@ can be disabled if not needed. listen management events generated by core stack when for example IP address is added to the device, or network interface is coming up etc. +* **Wi-Fi Management API.** Applications can use Wi-Fi management API to + manage the interface, in example to connect to Wi-Fi network and to scan + available Wi-Fi networks. + * **Multiple Network Technologies.** The Zephyr OS can be configured to support multiple network technologies at the same time simply by enabling - them in Kconfig: for example, Ethernet and 802.15.4 support. Note that no - automatic IP routing functionality is provided between these technologies. - Applications can send data according to their needs to desired network - interface. + them in Kconfig: for example, Ethernet, Wi-Fi and 802.15.4 support. Note + that no automatic IP routing functionality is provided between these + technologies. Applications can send data according to their needs to desired + network interface. * **Minimal Copy Network Buffer Management.** It is possible to have minimal copy network data path. This means that the system tries to avoid copying From 52222dc79450304fe4a32e5e0e77b9a460a93a86 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 16 Jun 2023 01:03:28 +0530 Subject: [PATCH 381/528] [nrf fromlist] doc: net: Add an entry about Wi-Fi Network managers Add the entry to convey support for Wi-Fi Network Managers in Zephyr. Upstream-Pr: https://github.com/zephyrproject-rtos/zephyr/pull/59249 Signed-off-by: Chaitanya Tata --- doc/connectivity/networking/overview.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/connectivity/networking/overview.rst b/doc/connectivity/networking/overview.rst index 32d08015abc2..c339632fdf18 100644 --- a/doc/connectivity/networking/overview.rst +++ b/doc/connectivity/networking/overview.rst @@ -103,6 +103,10 @@ can be disabled if not needed. manage the interface, in example to connect to Wi-Fi network and to scan available Wi-Fi networks. +* **Wi-Fi Network Manager API.** Wi-Fi Network Managers can now register + themselves to the Wi-Fi stack. The Network Managers can then implement + the Wi-Fi Management API and manage the Wi-Fi interface. + * **Multiple Network Technologies.** The Zephyr OS can be configured to support multiple network technologies at the same time simply by enabling them in Kconfig: for example, Ethernet, Wi-Fi and 802.15.4 support. Note From 0185eeb3e903ecc32c5aadce5f97d2ce3323c0f6 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 16 May 2023 13:49:53 +0200 Subject: [PATCH 382/528] [nrf noup] modules: mbedtls: Update PSA configuration curve names fixup! [nrf noup] modules: mbedtls: add PSA configurations Update PSA configuration curve names. These names have many different spelling variants, use PSA names, with commonly used variants in parenthesis. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index b95f8483e34a..c1aa323051a6 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -359,13 +359,13 @@ config PSA_WANT_ECC_BRAINPOOL_P_R1_512 bool "PSA ECC Brainpool512r1 support" config PSA_WANT_ECC_MONTGOMERY_255 - bool "PSA ECC Curve X25519 support" + bool "PSA ECC Curve25519 (X25519) support" config PSA_WANT_ECC_MONTGOMERY_448 - bool "PSA ECC Curve X448 support" + bool "PSA ECC Curve448 (X448) support" config PSA_WANT_ECC_TWISTED_EDWARDS_255 - bool "PSA ECC Curve Ed25519 support" + bool "PSA ECC Edwards25519 (Ed25519) support" config PSA_WANT_ECC_SECP_K1_192 bool "PSA ECC secp192k1 support" From 63f9035205c24bdac9093b6cda6b26716270ad0c Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 4 Jul 2023 14:15:13 +0200 Subject: [PATCH 383/528] [nrf noup] modules: mbedtls: Document RSA as PKCS#1 v1.5 fixup! [nrf noup] modules: mbedtls: add PSA configurations Improve documentation text, change all references to PKCS1V15 to PKCS#1 v1.5. NCSDK-21520 Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index c1aa323051a6..f2ddcd64ec1b 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -419,11 +419,11 @@ config PSA_WANT_ALG_RSA_OAEP config PSA_WANT_ALG_RSA_PKCS1V15_CRYPT bool - prompt "PSA RSA crypt support (PKCS1V15 mode)" if !PSA_PROMPTLESS + prompt "PSA RSA crypt support (PKCS#1 v1.5 mode)" if !PSA_PROMPTLESS config PSA_WANT_ALG_RSA_PKCS1V15_SIGN bool - prompt "PSA RSA signature support (PKCS1V15 mode)" if !PSA_PROMPTLESS + prompt "PSA RSA signature support (PKCS#1 v1.5 mode)" if !PSA_PROMPTLESS config PSA_WANT_ALG_RSA_PSS bool From f5413fa60c1efeb1fda46c9bfca03adb64742de6 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 4 Jul 2023 14:58:04 +0200 Subject: [PATCH 384/528] [nrf noup] modules: mbedtls: Remove mention of AES in block ciphers fixup! [nrf noup] modules: mbedtls: add PSA configurations Remove mention of AES in block ciphers. The block cipher modes can use different block cipher algorithms besides AES as the underlying block cipher. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index f2ddcd64ec1b..8bd15a73fc29 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -107,12 +107,12 @@ config PSA_HAS_AEAD_SUPPORT config PSA_WANT_ALG_CCM bool - prompt "PSA AES CCM support" if !PSA_PROMPTLESS + prompt "PSA CCM support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_GCM bool - prompt "PSA AES GCM support" if !PSA_PROMPTLESS + prompt "PSA GCM support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CHACHA20_POLY1305 @@ -141,7 +141,7 @@ config PSA_WANT_ALG_CBC_MAC config PSA_WANT_ALG_CMAC bool - prompt "PSA AES CMAC support" if !PSA_PROMPTLESS + prompt "PSA CMAC support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_HMAC @@ -220,7 +220,7 @@ config PSA_HAS_CIPHER_SUPPORT config PSA_WANT_ALG_ECB_NO_PADDING bool - prompt "PSA AES ECB (no padding)" if !PSA_PROMPTLESS + prompt "PSA ECB (no padding)" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CBC_NO_PADDING @@ -235,21 +235,21 @@ config PSA_WANT_ALG_CBC_PKCS7 config PSA_WANT_ALG_CFB bool - prompt "PSA AES CFB support" if !PSA_PROMPTLESS + prompt "PSA CFB support" if !PSA_PROMPTLESS config PSA_WANT_ALG_CTR bool - prompt "PSA AES CTR mode support" if !PSA_PROMPTLESS + prompt "PSA CTR mode support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_OFB bool - prompt "PSA AES OFB mode support" if !PSA_PROMPTLESS + prompt "PSA OFB mode support" if !PSA_PROMPTLESS config PSA_WANT_ALG_XTS bool help - AES XTS is currently not supported + PSA XTS is currently not supported endmenu # PSA Cipher Support From b0ba254d82e38ca37ba55c5f43d89433ba40e726 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 4 Jul 2023 15:02:07 +0200 Subject: [PATCH 385/528] [nrf noup] modules: mbedtls: Fix naming of chachapoly PSA algorithm fixup! [nrf noup] modules: mbedtls: add PSA configurations Use the same naming of this algorithm as the PSA specification is using. Given that this is a PSA configuration that makes the most sense. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 8bd15a73fc29..7190bcd71d0b 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -117,7 +117,7 @@ config PSA_WANT_ALG_GCM config PSA_WANT_ALG_CHACHA20_POLY1305 bool - prompt "PSA ChaCha20/Poly1305 support" if !PSA_PROMPTLESS + prompt "PSA ChaCha20-Poly1305 support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF endmenu # PSA AEAD support From a5d159c128c72e31719b22c26b45ce8548fe8ec7 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 20 Jun 2023 18:30:01 +0200 Subject: [PATCH 386/528] [nrf noup] modules: mbedtls: PSA XTS not supported is driver specific fixup! [nrf noup] modules: mbedtls: add PSA configurations PSA XTS algorithm not being supported depends on the drivers that are enabled. This should not make the generic symbol unavailable from the application to enable it. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 7190bcd71d0b..83a5a9d59643 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -248,8 +248,7 @@ config PSA_WANT_ALG_OFB config PSA_WANT_ALG_XTS bool - help - PSA XTS is currently not supported + prompt "PSA XTS mode support" if !PSA_PROMPTLESS endmenu # PSA Cipher Support From af893573d76d1aed6bc9c383ee404fc1e8b4c56d Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 4 Jul 2023 15:17:27 +0200 Subject: [PATCH 387/528] [nrf noup] modules: mbedtls: Improve cipher config name and organization fixup! [nrf noup] modules: mbedtls: add PSA configurations Improve cipher configuration name and organization. Move Stream cipher into cipher menu. Add block cipher mode to naming. Use consistent text on padding support. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 83a5a9d59643..9b75ee4d00ef 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -220,35 +220,40 @@ config PSA_HAS_CIPHER_SUPPORT config PSA_WANT_ALG_ECB_NO_PADDING bool - prompt "PSA ECB (no padding)" if !PSA_PROMPTLESS + prompt "PSA ECB block cipher mode support (with no padding)" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CBC_NO_PADDING bool - prompt "PSA CBC support (without padding)" if !PSA_PROMPTLESS + prompt "PSA CBC block cipher mode support (with no padding)" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CBC_PKCS7 bool - prompt "PSA CBC support (padded with PKCS#7)" if !PSA_PROMPTLESS + prompt "PSA CBC block cipher mode support (with PKCS#7 padding)" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CFB bool - prompt "PSA CFB support" if !PSA_PROMPTLESS + prompt "PSA stream cipher using CFB block cipher mode support" if !PSA_PROMPTLESS config PSA_WANT_ALG_CTR bool - prompt "PSA CTR mode support" if !PSA_PROMPTLESS + prompt "PSA stream cipher using CTR block cipher mode support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_OFB bool - prompt "PSA OFB mode support" if !PSA_PROMPTLESS + prompt "PSA stream cipher using OFB block cipher mode support" if !PSA_PROMPTLESS config PSA_WANT_ALG_XTS bool - prompt "PSA XTS mode support" if !PSA_PROMPTLESS + prompt "PSA XTS block cipher mode support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_STREAM_CIPHER + bool + prompt "PSA stream cipher support" if !PSA_PROMPTLESS + default y if !PSA_DEFAULT_OFF endmenu # PSA Cipher Support @@ -430,11 +435,6 @@ config PSA_WANT_ALG_RSA_PSS endmenu # PSA Asymmetric support -config PSA_WANT_ALG_STREAM_CIPHER - bool - prompt "PSA stream cipher support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF - config PSA_WANT_ALG_JPAKE bool prompt "PSA EC J-PAKE support" if !PSA_PROMPTLESS From 8f6492e06354fdaa8a8bd60049410702547c2100 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 4 Jul 2023 17:29:46 +0200 Subject: [PATCH 388/528] [nrf noup] modules: mbedtls: Fix PSA AES key type auto-support fixup! [nrf noup] modules: mbedtls: add PSA configurations Fix automatic enabling of PSA AES key type support. We enable AES key type for all algorithms that can possible use it, because it is the only block cipher key type that we support. This fixes AES key type not auto enabled for MAC algorithms, and does not auto-enable it for AEAD using chachapoly algorithm. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 9b75ee4d00ef..8c111bee5ac2 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -55,7 +55,18 @@ config PSA_WANT_KEY_TYPE_HMAC config PSA_WANT_KEY_TYPE_AES bool default y - depends on PSA_HAS_CIPHER_SUPPORT || PSA_HAS_AEAD_SUPPORT + depends on PSA_WANT_ALG_ECB_NO_PADDING || \ + PSA_WANT_ALG_CBC_NO_PADDING || \ + PSA_WANT_ALG_CBC_PKCS7 || \ + PSA_WANT_ALG_CFB || \ + PSA_WANT_ALG_CTR || \ + PSA_WANT_ALG_OFB || \ + PSA_WANT_ALG_CTR || \ + PSA_WANT_ALG_XTS || \ + PSA_WANT_ALG_CCM || \ + PSA_WANT_ALG_GCM || \ + PSA_WANT_ALG_CBC_MAC || \ + PSA_WANT_ALG_CMAC help Prompt-less configuration that states that AES key type is used. From fcff2f8d6d5ec026e4bc80a1c9f3292f79ffb024 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 4 Jul 2023 17:30:04 +0200 Subject: [PATCH 389/528] [nrf noup] modules: mbedtls: Fix auto-enabling of Chacha-poly key type fixup! [nrf noup] modules: mbedtls: add PSA configurations Fix auto-enabling of chacha-poly key type for stream cipher. This key type is the only one supported by PSA stream cipher. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 8c111bee5ac2..faca334df362 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -73,7 +73,8 @@ config PSA_WANT_KEY_TYPE_AES config PSA_WANT_KEY_TYPE_CHACHA20 bool default y - depends on PSA_WANT_ALG_CHACHA20_POLY1305 + depends on PSA_WANT_ALG_CHACHA20_POLY1305 || \ + PSA_WANT_ALG_STREAM_CIPHER help Prompt-less configuration that states that CHACHA20 key type is used. From df688f9b40f9f0495cc34b55bb9527cf8c962e0f Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 4 Jul 2023 17:32:01 +0200 Subject: [PATCH 390/528] [nrf noup] modules: mbedtls: Fix stream cipher not enabling PSA cipher fixup! [nrf noup] modules: mbedtls: add PSA configurations Fix bug for only enabling the stream cipher of of the PSA ciphers. This would end up not compiling in the PSA cipher support. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index faca334df362..89bb72f6a748 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -226,7 +226,8 @@ config PSA_HAS_CIPHER_SUPPORT PSA_WANT_ALG_CTR || \ PSA_WANT_ALG_OFB || \ PSA_WANT_ALG_CTR || \ - PSA_WANT_ALG_XTS + PSA_WANT_ALG_XTS || \ + PSA_WANT_ALG_STREAM_CIPHER help Prompt-less configuration that states that cipher is supported. From 56415b34fb49a3a9110fa2f64c174254d71ddc62 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Wed, 5 Jul 2023 12:24:03 +0200 Subject: [PATCH 391/528] [nrf noup] modules: mbedtls: Improve PSA RNG and PRNG prompt and help fixup! [nrf noup] modules: mbedtls: add PSA configurations Imrove the help text and prompt for PSA RNG and PRNG algorithms. This should clarify which option enables PRNG support, and which selects the PRNG algorithm to use. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 89bb72f6a748..9cc0f66ea673 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -9,19 +9,25 @@ config PSA_WANT_GENERATE_RANDOM bool prompt "PSA RNG support" default y + help + Provide random number generator (RNG) support. config PSA_WANT_ALG_CTR_DRBG bool - prompt "PSA RNG using CTR_DRBG" + prompt "PSA RNG using CTR-DRBG as PRNG" help - Provide CTR_DRBG as the random number generator. + Provide random number generator (RNG) using CTR-DRBG as the + pseudo-random number generator (PRNG), seeded by a true random + number generator (TRNG). Note: This configuration is currently not described and has no effect. config PSA_WANT_ALG_HMAC_DRBG bool - prompt "PSA RNG using HMAC_DRBG" + prompt "PSA RNG using HMAC-DRBG as PRNG" help - Provide HMAC_DRBG as the random number generator. + Provide random number generator (RNG) using HMAC-DRBG as the + pseudo-random number generator (PRNG), seeded by a true random + number generator (TRNG). Note: This configuration is currently not described and has no effect. endmenu # RNG support From 4a5b99b17f765f8d1ff29d5df3aeb6d1581fa0f5 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 16 Jun 2023 18:43:30 +0200 Subject: [PATCH 392/528] [nrf noup] modules: mbedtls: Fix mispelled config name for SHA-256 fixup! [nrf noup] modules: mbedtls: add PSA configurations Fix mispelled configuration name for SHA-256. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 9cc0f66ea673..340d205fb591 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -197,7 +197,7 @@ config PSA_WANT_ALG_SHA_224 config PSA_WANT_ALG_SHA_256 bool - prompt "PSA SSH-256 support" if !PSA_PROMPTLESS + prompt "PSA SHA-256 support" if !PSA_PROMPTLESS default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_SHA_384 From 1db5d8fb12589848618e2ccf260d511e86aceeac Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 16 Jun 2023 18:45:41 +0200 Subject: [PATCH 393/528] [nrf noup] modules: mbedtls: Fix whitespace issues fixup! [nrf noup] modules: mbedtls: add PSA configurations Fix whitespace issue: alignment, and empty lines. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig | 1 + modules/mbedtls/Kconfig.psa | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig b/modules/mbedtls/Kconfig index 7ee4888400b1..9c0a94aec5d3 100644 --- a/modules/mbedtls/Kconfig +++ b/modules/mbedtls/Kconfig @@ -5,6 +5,7 @@ config ZEPHYR_MBEDTLS_MODULE bool + config MBEDTLS_PROMPTLESS bool help diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 340d205fb591..52af9c05368b 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -328,7 +328,7 @@ config PSA_HAS_ASYM_ENCRYPT_SUPPORT bool default y depends on PSA_WANT_ALG_RSA_OAEP || \ - PSA_WANT_ALG_RSA_PKCS1V15_CRYPT + PSA_WANT_ALG_RSA_PKCS1V15_CRYPT help Prompt-less configuration that states that asymmetric encryption is supported. @@ -341,7 +341,6 @@ config PSA_HAS_ASYM_SIGN_SUPPORT PSA_WANT_ALG_ECDSA || \ PSA_WANT_ALG_RSA_PKCS1V15_SIGN || \ PSA_WANT_ALG_RSA_PSS - help Prompt-less configuration that states that asymmetric signing is supported. From 01e2e4c9ce8294d74032a2d33e0dcb1b74802568 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 27 Jun 2023 15:36:55 +0200 Subject: [PATCH 394/528] [nrf noup] modules: mbedtls: Remove incorrect help text about no effect fixup! [nrf noup] modules: mbedtls: add PSA configurations Remove incorrect help text stating the the RNG algorithm options has no effect. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 52af9c05368b..ed375e056cfb 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -19,7 +19,6 @@ config PSA_WANT_ALG_CTR_DRBG Provide random number generator (RNG) using CTR-DRBG as the pseudo-random number generator (PRNG), seeded by a true random number generator (TRNG). - Note: This configuration is currently not described and has no effect. config PSA_WANT_ALG_HMAC_DRBG bool @@ -28,7 +27,6 @@ config PSA_WANT_ALG_HMAC_DRBG Provide random number generator (RNG) using HMAC-DRBG as the pseudo-random number generator (PRNG), seeded by a true random number generator (TRNG). - Note: This configuration is currently not described and has no effect. endmenu # RNG support From 77ed2a43ed4f52fd9ce19c71525617ac2a9948a7 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Thu, 6 Jul 2023 13:32:27 +0200 Subject: [PATCH 395/528] [nrf fromlist] soc: arm: nrf53: workaround pop lr after wfi crash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On nRF5340 net core it was observed that when `wfi` instruction was followed by `pop {r0, lr}` in the `arch_cpu_idle` function, the value of `lr` sometimes got read as 0 from memory despite having correct value stored in the memory. This commit inserts additional `nop` instruction after waking up to delay access to the memory. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60099 Signed-off-by: Andrzej Kuroś --- arch/arm/Kconfig | 16 ++++++++++++++++ arch/arm/core/aarch32/cpu_idle.S | 9 +++++++++ soc/arm/nordic_nrf/nrf53/Kconfig.soc | 1 + soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h | 20 ++++++++++++++++++++ 4 files changed, 46 insertions(+) create mode 100644 soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ec82b1e50ee1..e17cf3f9b310 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -53,6 +53,22 @@ config ARM_ON_ENTER_CPU_IDLE_HOOK If needed, this hook can be used to prevent the CPU from actually entering sleep by skipping the WFE/WFI instruction. +config ARM_ON_EXIT_CPU_IDLE + bool + help + Enables a possibility to inject SoC-specific code just after WFI/WFE + instructions of the cpu idle implementation. + + Enabling this option requires that the SoC provides a soc_cpu_idle.h + header file which defines SOC_ON_EXIT_CPU_IDLE macro guarded by + _ASMLANGUAGE. + + The SOC_ON_EXIT_CPU_IDLE macro is expanded just after + WFI/WFE instructions before any memory access is performed. The purpose + of the SOC_ON_EXIT_CPU_IDLE is to perform an action that mitigate issues + observed on some SoCs caused by a memory access following WFI/WFE + instructions. + rsource "core/aarch32/Kconfig" rsource "core/aarch32/Kconfig.vfp" diff --git a/arch/arm/core/aarch32/cpu_idle.S b/arch/arm/core/aarch32/cpu_idle.S index 90f51f476b56..8164959ab291 100644 --- a/arch/arm/core/aarch32/cpu_idle.S +++ b/arch/arm/core/aarch32/cpu_idle.S @@ -13,6 +13,10 @@ #include #include +#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE) +#include +#endif + _ASM_FILE_PROLOGUE GTEXT(z_arm_cpu_idle_init) @@ -64,6 +68,11 @@ SECTION_FUNC(TEXT, z_arm_cpu_idle_init) dsb \wait_instruction +#if defined(CONFIG_ARM_ON_EXIT_CPU_IDLE) + /* Inline the macro provided by SoC-specific code */ + SOC_ON_EXIT_CPU_IDLE +#endif /* CONFIG_ARM_ON_EXIT_CPU_IDLE */ + #if defined(CONFIG_ARM_ON_ENTER_CPU_IDLE_HOOK) _skip_\@: #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 967376088004..67cb8a08a6f7 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -13,6 +13,7 @@ config SOC_NRF5340_CPUAPP config SOC_NRF5340_CPUNET bool select HAS_NO_PM + select ARM_ON_EXIT_CPU_IDLE imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED choice diff --git a/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h b/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h new file mode 100644 index 000000000000..b6cd92ca092a --- /dev/null +++ b/soc/arm/nordic_nrf/nrf53/soc_cpu_idle.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file SoC extensions of cpu_idle.S for the Nordic Semiconductor nRF53 processors family. + */ + + +#if defined(_ASMLANGUAGE) + +#define SOC_ON_EXIT_CPU_IDLE \ + nop; \ + nop; \ + nop; \ + nop; + +#endif /* _ASMLANGUAGE */ From 22bfbb4003124d476940fb24dfe87b15643245fa Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Fri, 16 Jun 2023 18:49:14 +0200 Subject: [PATCH 396/528] [nrf noup] modules: mbedtls: Make PSA configurations default disabled fixup! [nrf noup] modules: mbedtls: add PSA configurations Make PSA configurations as default disabled. This makes it easier for users of the PSA APIs to only enable the configurations they depend on and not have to disable unneeded configurations in order to optimize flash usage for their use-case. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index ed375e056cfb..54ef35957b97 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -8,7 +8,6 @@ menu "PSA RNG support" config PSA_WANT_GENERATE_RANDOM bool prompt "PSA RNG support" - default y help Provide random number generator (RNG) support. @@ -124,17 +123,14 @@ config PSA_HAS_AEAD_SUPPORT config PSA_WANT_ALG_CCM bool prompt "PSA CCM support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_GCM bool prompt "PSA GCM support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CHACHA20_POLY1305 bool prompt "PSA ChaCha20-Poly1305 support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF endmenu # PSA AEAD support @@ -158,12 +154,10 @@ config PSA_WANT_ALG_CBC_MAC config PSA_WANT_ALG_CMAC bool prompt "PSA CMAC support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_HMAC bool prompt "PSA HMAC support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF endmenu # PSA MAC support @@ -186,27 +180,22 @@ config PSA_HAS_HASH_SUPPORT config PSA_WANT_ALG_SHA_1 bool prompt "PSA SHA1 support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_SHA_224 bool prompt "PSA SHA-224 support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_SHA_256 bool prompt "PSA SHA-256 support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_SHA_384 bool prompt "PSA SHA-384 support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_SHA_512 bool prompt "PSA SHA-512 support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_RIPEMD160 bool @@ -238,17 +227,14 @@ config PSA_HAS_CIPHER_SUPPORT config PSA_WANT_ALG_ECB_NO_PADDING bool prompt "PSA ECB block cipher mode support (with no padding)" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CBC_NO_PADDING bool prompt "PSA CBC block cipher mode support (with no padding)" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CBC_PKCS7 bool prompt "PSA CBC block cipher mode support (with PKCS#7 padding)" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_CFB bool @@ -257,7 +243,6 @@ config PSA_WANT_ALG_CFB config PSA_WANT_ALG_CTR bool prompt "PSA stream cipher using CTR block cipher mode support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_OFB bool @@ -270,7 +255,6 @@ config PSA_WANT_ALG_XTS config PSA_WANT_ALG_STREAM_CIPHER bool prompt "PSA stream cipher support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF endmenu # PSA Cipher Support @@ -292,7 +276,6 @@ config PSA_HAS_KEY_DERIVATION config PSA_WANT_ALG_HKDF bool prompt "PSA HKDF support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF depends on PSA_WANT_ALG_HMAC config PSA_WANT_ALG_PBKDF2_HMAC @@ -353,17 +336,14 @@ config PSA_HAS_ECC_SUPPORT config PSA_WANT_ALG_ECDH bool prompt "PSA ECDH support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_ECDSA bool prompt "PSA ECDSA support" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ALG_DETERMINISTIC_ECDSA bool prompt "PSA ECDSA support (deterministic mode)" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF menu "Elliptic Curve type support" depends on PSA_HAS_ECC_SUPPORT @@ -411,7 +391,6 @@ config PSA_WANT_ECC_SECP_R1_224 config PSA_WANT_ECC_SECP_R1_256 bool prompt "PSA ECC secp256r1" if !PSA_PROMPTLESS - default y if !PSA_DEFAULT_OFF config PSA_WANT_ECC_SECP_R1_384 bool From 938f032d7b48a7d3ee9699500f7da3115de4375b Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Tue, 27 Jun 2023 12:44:03 +0200 Subject: [PATCH 397/528] [nrf noup] drivers: entropy: PSA entropy driver wants PSA RNG fixup! [nrf noup] modules: mbedtls: add PSA configurations Select the PSA_WANT_GENERATE_RANDOM option for the zephyr entropy driver using the PSA interface. Signed-off-by: Joakim Andersson --- drivers/entropy/Kconfig.psa_crypto | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/entropy/Kconfig.psa_crypto b/drivers/entropy/Kconfig.psa_crypto index 50f315090040..455a2c9b55bc 100644 --- a/drivers/entropy/Kconfig.psa_crypto +++ b/drivers/entropy/Kconfig.psa_crypto @@ -8,6 +8,7 @@ config ENTROPY_PSA_CRYPTO_RNG depends on BUILD_WITH_TFM depends on DT_HAS_ZEPHYR_PSA_CRYPTO_RNG_ENABLED select ENTROPY_HAS_DRIVER + select PSA_WANT_GENERATE_RANDOM default y help Enable the PSA Crypto source Entropy driver. From 35510c3d8e95826803ffaee1bb678163e1846320 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Wed, 28 Jun 2023 16:54:06 +0200 Subject: [PATCH 398/528] [nrf noup] modules: mbedtls: Remove dependency on MBEDTLS for PSA config fixup! [nrf noup] modules: mbedtls: add PSA configurations Remove dependency on MBEDTLS for PSA configurations. PSA can be supplied by other PSA API providers, such as TF-M. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig b/modules/mbedtls/Kconfig index 9c0a94aec5d3..a33561a9b1c4 100644 --- a/modules/mbedtls/Kconfig +++ b/modules/mbedtls/Kconfig @@ -231,7 +231,7 @@ config APP_LINK_WITH_MBEDTLS disabled if the include paths for MBEDTLS are causing aliasing issues for 'app'. +endif # MBEDTLS + # Add PSA configurations rsource "Kconfig.psa" - -endif # MBEDTLS From af259ad5617ef5c72c53f69273db7ec1a92d2d16 Mon Sep 17 00:00:00 2001 From: Tommi Kangas Date: Tue, 27 Jun 2023 11:45:49 +0300 Subject: [PATCH 399/528] [nrf fromtree] net: lib: coap: Use zsock_ functions Use Zephyr internal zsock_ calls to remove dependency to NET_SOCKETS_POSIX_NAMES. Signed-off-by: Tommi Kangas (cherry picked from commit f124c0d06ac16662ee8cdad8b041e750b2af8218) --- subsys/net/lib/coap/coap_client.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/subsys/net/lib/coap/coap_client.c b/subsys/net/lib/coap/coap_client.c index 1640a701de94..ec0c4d1f7fb9 100644 --- a/subsys/net/lib/coap/coap_client.c +++ b/subsys/net/lib/coap/coap_client.c @@ -38,9 +38,9 @@ static int send_request(int sock, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { if (addrlen == 0) { - return sendto(sock, buf, len, flags, NULL, 0); + return zsock_sendto(sock, buf, len, flags, NULL, 0); } else { - return sendto(sock, buf, len, flags, dest_addr, addrlen); + return zsock_sendto(sock, buf, len, flags, dest_addr, addrlen); } } @@ -48,9 +48,9 @@ static int receive(int sock, void *buf, size_t max_len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { if (*addrlen == 0) { - return recvfrom(sock, buf, max_len, flags, NULL, NULL); + return zsock_recvfrom(sock, buf, max_len, flags, NULL, NULL); } else { - return recvfrom(sock, buf, max_len, flags, src_addr, addrlen); + return zsock_recvfrom(sock, buf, max_len, flags, src_addr, addrlen); } } @@ -369,16 +369,16 @@ static int handle_poll(struct coap_client *client) int ret = 0; while (1) { - struct pollfd fds; + struct zsock_pollfd fds; fds.fd = client->fd; - fds.events = POLLIN; + fds.events = ZSOCK_POLLIN; fds.revents = 0; /* rfc7252#section-5.2.2, use separate timeout value for a separate response */ if (client->pending.timeout != 0) { - ret = poll(&fds, 1, client->pending.timeout); + ret = zsock_poll(&fds, 1, client->pending.timeout); } else { - ret = poll(&fds, 1, COAP_SEPARATE_TIMEOUT); + ret = zsock_poll(&fds, 1, COAP_SEPARATE_TIMEOUT); } if (ret < 0) { @@ -403,25 +403,25 @@ static int handle_poll(struct coap_client *client) break; } } else { - if (fds.revents & POLLERR) { + if (fds.revents & ZSOCK_POLLERR) { LOG_ERR("Error in poll"); ret = -EIO; break; } - if (fds.revents & POLLHUP) { + if (fds.revents & ZSOCK_POLLHUP) { LOG_ERR("Error in poll: POLLHUP"); ret = -ECONNRESET; break; } - if (fds.revents & POLLNVAL) { + if (fds.revents & ZSOCK_POLLNVAL) { LOG_ERR("Error in poll: POLLNVAL - fd not open"); ret = -EINVAL; break; } - if (!(fds.revents & POLLIN)) { + if (!(fds.revents & ZSOCK_POLLIN)) { LOG_ERR("Unknown poll error"); ret = -EINVAL; break; @@ -455,7 +455,7 @@ static int recv_response(struct coap_client *client, struct coap_packet *respons int ret; memset(client->recv_buf, 0, sizeof(client->recv_buf)); - len = receive(client->fd, client->recv_buf, sizeof(client->recv_buf), MSG_DONTWAIT, + len = receive(client->fd, client->recv_buf, sizeof(client->recv_buf), ZSOCK_MSG_DONTWAIT, &client->address, &client->socklen); if (len < 0) { From de3958787f61e7da7f80da27ac2ade2cc4dfa6ad Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 5 Jul 2023 10:13:08 -0700 Subject: [PATCH 400/528] [nrf fromtree] cmake/compiler: Add linker_script compiler property This property specifies the flag used to pass the linker script filename through the compiler front end tot he linker. For clang, we use the general purpose linker-pass through -Wl flag with -T: -Wl,-T as clang doesn't support -T. For gcc, we use -T directly as this keeps the picolibc specs file from inserting the picolibc linker script as well. If the compiler doesn't specify a value, we continue to use -Wl,-T as before. Signed-off-by: Keith Packard (cherry picked from commit 424590f7d84df361e03b62128dd3c7032aa71656) --- CMakeLists.txt | 5 +++-- cmake/compiler/clang/compiler_flags.cmake | 3 +++ cmake/compiler/compiler_flags_template.cmake | 3 +++ cmake/compiler/gcc/compiler_flags.cmake | 3 +++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7dd1e539ae73..66eb7bbbd475 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -480,8 +480,9 @@ if(CONFIG_USERSPACE) endif() get_property(TOPT GLOBAL PROPERTY TOPT) -set_ifndef( TOPT -Wl,-T) # clang doesn't pick -T for some reason and complains, - # while -Wl,-T works for both, gcc and clang +get_property(COMPILER_TOPT TARGET compiler PROPERTY linker_script) +set_ifndef( TOPT "${COMPILER_TOPT}") +set_ifndef( TOPT -Wl,-T) # Use this if the compiler driver doesn't set a value if(CONFIG_HAVE_CUSTOM_LINKER_SCRIPT) set(LINKER_SCRIPT ${APPLICATION_SOURCE_DIR}/${CONFIG_CUSTOM_LINKER_SCRIPT}) diff --git a/cmake/compiler/clang/compiler_flags.cmake b/cmake/compiler/clang/compiler_flags.cmake index 7a3fbdc1c3a8..12868539d2f7 100644 --- a/cmake/compiler/clang/compiler_flags.cmake +++ b/cmake/compiler/clang/compiler_flags.cmake @@ -23,6 +23,9 @@ set_compiler_property(PROPERTY diagnostic -fcolor-diagnostics) # clang flag to save temporary object files set_compiler_property(PROPERTY save_temps -save-temps) +# clang doesn't handle the -T flag +set_compiler_property(PROPERTY linker_script -Wl,-T) + ####################################################### # This section covers flags related to warning levels # ####################################################### diff --git a/cmake/compiler/compiler_flags_template.cmake b/cmake/compiler/compiler_flags_template.cmake index 4614866b2ce0..5f15d1b80074 100644 --- a/cmake/compiler/compiler_flags_template.cmake +++ b/cmake/compiler/compiler_flags_template.cmake @@ -106,6 +106,9 @@ set_compiler_property(PROPERTY debug) # Flags to save temporary object files set_compiler_property(PROPERTY save_temps) +# Flag to specify linker script +set_compiler_property(PROPERTY linker_script) + set_compiler_property(PROPERTY no_common) # Flags for imacros. The specific header must be appended by user. diff --git a/cmake/compiler/gcc/compiler_flags.cmake b/cmake/compiler/gcc/compiler_flags.cmake index f2c2845923bf..cca947e3d0fa 100644 --- a/cmake/compiler/gcc/compiler_flags.cmake +++ b/cmake/compiler/gcc/compiler_flags.cmake @@ -182,6 +182,9 @@ set_compiler_property(PROPERTY debug -g) # Flags to save temporary object files set_compiler_property(PROPERTY save_temps -save-temps=obj) +# Flag to specify linker script +set_compiler_property(PROPERTY linker_script -T) + # Flags to not track macro expansion set_compiler_property(PROPERTY no_track_macro_expansion -ftrack-macro-expansion=0) From c86202d9e5de9096aefeaff43a9ed16694c4addd Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 5 Jul 2023 10:16:23 -0700 Subject: [PATCH 401/528] [nrf fromtree] libc/picolibc: Remove -T /dev/null linker arguments Now that the gcc compiler driver uses the -T flag instead of -Wl,-T, we can remove the hack here that kept the picolibc specs file from inserting the picolibc linker script. Signed-off-by: Keith Packard (cherry picked from commit 4e7930b099771ecc5ad5c05b95a158cc0ceee0d2) --- lib/libc/picolibc/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/picolibc/CMakeLists.txt b/lib/libc/picolibc/CMakeLists.txt index c32295e1d271..3bbe8128a1f5 100644 --- a/lib/libc/picolibc/CMakeLists.txt +++ b/lib/libc/picolibc/CMakeLists.txt @@ -13,7 +13,7 @@ if(NOT CONFIG_PICOLIBC_USE_MODULE) zephyr_compile_options(--specs=picolibc.specs) zephyr_compile_definitions(_POSIX_C_SOURCE=200809) - zephyr_libc_link_libraries(-T/dev/null --specs=picolibc.specs c -lgcc) + zephyr_libc_link_libraries(--specs=picolibc.specs c -lgcc) if(CONFIG_PICOLIBC_IO_FLOAT) zephyr_compile_definitions(PICOLIBC_DOUBLE_PRINTF_SCANF) zephyr_link_libraries(-DPICOLIBC_DOUBLE_PRINTF_SCANF) From 9a0b8a317a91089f048c38233635240f21ab298d Mon Sep 17 00:00:00 2001 From: Mateusz Kapala Date: Mon, 3 Jul 2023 13:45:30 +0200 Subject: [PATCH 402/528] [nrf fromtree] bluetooth: host: smp: Add bondable flag overlay per connection The current API for changing the bondable mode uses the global flag. With Zephyr support for multiple Bluetooth identities, the API for changing the bondable mode should be more fine-grained. The bondable requirements of one identity should not have an impact on another identity which can have a different set of requirements. This change introduces function to overlay bondable flag per connection. Signed-off-by: Mateusz Kapala (cherry picked from commit 5b44ebe1595a8d4a46f5721271557d4159498673) --- include/zephyr/bluetooth/conn.h | 20 +++++++++++++++++ subsys/bluetooth/host/Kconfig | 7 ++++++ subsys/bluetooth/host/smp.c | 38 +++++++++++++++++++++++++++++++-- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/include/zephyr/bluetooth/conn.h b/include/zephyr/bluetooth/conn.h index a6c6d3b0366c..0403a5a69001 100644 --- a/include/zephyr/bluetooth/conn.h +++ b/include/zephyr/bluetooth/conn.h @@ -1081,6 +1081,26 @@ void bt_conn_cb_register(struct bt_conn_cb *cb); */ void bt_set_bondable(bool enable); +/** @brief Set/clear the bonding flag for a given connection. + * + * Set/clear the Bonding flag in the Authentication Requirements of + * SMP Pairing Request/Response data for a given connection. + * + * The bonding flag for a given connection cannot be set/cleared if + * security procedures in the SMP module have already started. + * This function can be called only once per connection. + * + * If the bonding flag is not set/cleared for a given connection, + * the value will depend on global configuration which is set using + * bt_set_bondable. + * The default value of the global configuration is defined using + * CONFIG_BT_BONDABLE Kconfig option. + * + * @param conn Connection object. + * @param enable Value allowing/disallowing to be bondable. + */ +int bt_conn_set_bondable(struct bt_conn *conn, bool enable); + /** @brief Allow/disallow remote LE SC OOB data to be used for pairing. * * Set/clear the OOB data flag for LE SC SMP Pairing Request/Response data. diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index ee5d0f0b0e33..f93e9d20a329 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -600,6 +600,13 @@ config BT_BONDING_REQUIRED set the bondable flag in their pairing request. Any other kind of requests will be rejected. +config BT_BONDABLE_PER_CONNECTION + bool "Set/clear the bonding flag per-connection [EXPERIMENTAL]" + select EXPERIMENTAL + help + Enable support for the bt_conn_set_bondable API function that is + used to set/clear the bonding flag on a per-connection basis. + config BT_STORE_DEBUG_KEYS bool "Store Debug Mode bonds" help diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 9b40910cb304..86fbd723cd57 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -209,6 +209,9 @@ struct bt_smp { /* Used Bluetooth authentication callbacks. */ atomic_ptr_t auth_cb; + + /* Bondable flag */ + atomic_t bondable; }; static unsigned int fixed_passkey = BT_PASSKEY_INVALID; @@ -288,6 +291,11 @@ static K_SEM_DEFINE(sc_local_pkey_ready, 0, 1); */ #define BT_SMP_AUTH_CB_UNINITIALIZED ((atomic_ptr_val_t)bt_smp_pool) +/* Value used to mark that per-connection bondable flag is not initialized. + * Value false/true represent if flag is cleared or set and cannot be used for that purpose. + */ +#define BT_SMP_BONDABLE_UNINITIALIZED ((atomic_val_t)-1) + static bool le_sc_supported(void) { /* @@ -310,6 +318,13 @@ static const struct bt_conn_auth_cb *latch_auth_cb(struct bt_smp *smp) return atomic_ptr_get(&smp->auth_cb); } +static bool latch_bondable(struct bt_smp *smp) +{ + atomic_cas(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED, (atomic_val_t)bondable); + + return atomic_get(&smp->bondable); +} + static uint8_t get_io_capa(struct bt_smp *smp) { const struct bt_conn_auth_cb *smp_auth_cb = latch_auth_cb(smp); @@ -2592,7 +2607,7 @@ static uint8_t get_auth(struct bt_smp *smp, uint8_t auth) auth |= BT_SMP_AUTH_MITM; } - if (bondable) { + if (latch_bondable(smp)) { auth |= BT_SMP_AUTH_BONDING; } else { auth &= ~BT_SMP_AUTH_BONDING; @@ -3977,7 +3992,7 @@ static uint8_t smp_security_request(struct bt_smp *smp, struct net_buf *buf) } if (IS_ENABLED(CONFIG_BT_BONDING_REQUIRED) && - !(bondable && (auth & BT_SMP_AUTH_BONDING))) { + !(latch_bondable(smp) && (auth & BT_SMP_AUTH_BONDING))) { /* Reject security req if not both intend to bond */ LOG_DBG("Bonding required"); return BT_SMP_ERR_UNSPECIFIED; @@ -4541,6 +4556,7 @@ static void bt_smp_connected(struct bt_l2cap_chan *chan) smp_reset(smp); atomic_ptr_set(&smp->auth_cb, BT_SMP_AUTH_CB_UNINITIALIZED); + atomic_set(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED); } static void bt_smp_disconnected(struct bt_l2cap_chan *chan) @@ -5291,6 +5307,24 @@ static inline int smp_self_test(void) } #endif +#if defined(CONFIG_BT_BONDABLE_PER_CONNECTION) +int bt_conn_set_bondable(struct bt_conn *conn, bool enable) +{ + struct bt_smp *smp; + + smp = smp_chan_get(conn); + if (!smp) { + return -EINVAL; + } + + if (atomic_cas(&smp->bondable, BT_SMP_BONDABLE_UNINITIALIZED, (atomic_val_t)enable)) { + return 0; + } else { + return -EALREADY; + } +} +#endif + int bt_smp_auth_cb_overlay(struct bt_conn *conn, const struct bt_conn_auth_cb *cb) { struct bt_smp *smp; From ee800e57d9d10e234ad1d6154de76ab89141683b Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Fri, 16 Jun 2023 09:18:28 +0200 Subject: [PATCH 403/528] [nrf fromtree] manifest: openthread: Regular openthread upmerge to `6d55738` Openthread upmerge to `6d55738`. Includes implementing of: - `OPENTHREAD_CONFIG_RADIO_STATS_ENABLE` - `OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE` Signed-off-by: Przemyslaw Bida (cherry picked from commit f940a5a988304f4dfb3f79b7ec819f0bdbc0c9c8) Signed-off-by: Maciej Baczmanski --- modules/openthread/CMakeLists.txt | 6 ++++++ modules/openthread/Kconfig.features | 6 ++++++ .../platform/openthread-core-zephyr-config.h | 11 +++++++++++ west.yml | 2 +- 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index 508c888e0f3c..fdc466b19419 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -82,6 +82,12 @@ else() set(OT_BORDER_ROUTING_COUNTERS OFF CACHE BOOL "Enable Border routing counters" FORCE) endif() +if(CONFIG_OPENTHREAD_BORDER_ROUTING_DHCP6_PD) + set(OT_BORDER_ROUTING_DHCP6_PD ON CACHE BOOL "DHCPv6-PD support in border routing" FORCE) +else() + set(OT_BORDER_ROUTING_DHCP6_PD OFF CACHE BOOL "DHCPv6-PD support in border routing" FORCE) +endif() + if(CONFIG_OPENTHREAD_CHANNEL_MANAGER) set(OT_CHANNEL_MANAGER ON CACHE BOOL "Enable channel manager support" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index dc0624edca17..e793a9bfaa4a 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -51,6 +51,9 @@ config OPENTHREAD_BORDER_ROUTING config OPENTHREAD_BORDER_ROUTING_COUNTERS bool "Border routing counters support" +config OPENTHREAD_BORDER_ROUTING_DHCP6_PD + bool "DHCPv6-PD support in border routing" + config OPENTHREAD_CHANNEL_MONITOR bool "Channel monitor support" @@ -247,6 +250,9 @@ config OPENTHREAD_POWER_SUPPLY default "EXTERNAL_UNSTABLE" if OPENTHREAD_POWER_SUPPLY_EXTERNAL_UNSTABLE default "" +config OPENTHREAD_RADIO_STATS + bool "Support for Radio Statistics" + config OPENTHREAD_RAW bool "Raw Link support" diff --git a/modules/openthread/platform/openthread-core-zephyr-config.h b/modules/openthread/platform/openthread-core-zephyr-config.h index 7eaccf7948df..8d6b5e54fd08 100644 --- a/modules/openthread/platform/openthread-core-zephyr-config.h +++ b/modules/openthread/platform/openthread-core-zephyr-config.h @@ -446,4 +446,15 @@ #define OPENTHREAD_CONFIG_PLATFORM_POWER_CALIBRATION_ENABLE 0 #endif + +/** + * @def OPENTHREAD_CONFIG_RADIO_STATS + * + * Enable support for Radio Statistics. + * + */ +#ifdef CONFIG_OPENTHREAD_RADIO_STATS +#define OPENTHREAD_CONFIG_RADIO_STATS_ENABLE CONFIG_OPENTHREAD_RADIO_STATS +#endif + #endif /* OPENTHREAD_CORE_ZEPHYR_CONFIG_H_ */ diff --git a/west.yml b/west.yml index 215cc46f50ba..50447869f255 100644 --- a/west.yml +++ b/west.yml @@ -290,7 +290,7 @@ manifest: revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad path: modules/lib/open-amp - name: openthread - revision: d9abe3071c0131a4adb5d7e7451319b735e6d855 + revision: 6d557383e8bc8654f813674e8631c2e56b8e70d0 path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From eb28632680089351c7bd4365cf3742bf7eff70d3 Mon Sep 17 00:00:00 2001 From: Przemyslaw Bida Date: Thu, 6 Jul 2023 09:57:30 +0200 Subject: [PATCH 404/528] [nrf fromtree] manifest: openthread: regular openthread upmerge `37fb770` Implementation of new option: `OPENTHREAD_OPERATIONAL_DATASET_AUTO_INIT` Signed-off-by: Przemyslaw Bida (cherry picked from commit 8a78148e6101836158bfa14a7c33f4fe6e1f6069) Signed-off-by: Maciej Baczmanski --- modules/openthread/CMakeLists.txt | 6 ++++++ modules/openthread/Kconfig.features | 4 ++++ west.yml | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/modules/openthread/CMakeLists.txt b/modules/openthread/CMakeLists.txt index fdc466b19419..267e1a443cda 100644 --- a/modules/openthread/CMakeLists.txt +++ b/modules/openthread/CMakeLists.txt @@ -352,6 +352,12 @@ else() set(OT_NETDATA_PUBLISHER OFF CACHE BOOL "Enable Thread Network Data publisher" FORCE) endif() +if(CONFIG_OPENTHREAD_OPERATIONAL_DATASET_AUTO_INIT) + set(OT_OPERATIONAL_DATASET_AUTO_INIT ON CACHE BOOL "Enable operational dataset auto init" FORCE) +else() + set(OT_OPERATIONAL_DATASET_AUTO_INIT OFF CACHE BOOL "Enable operational dataset auto init" FORCE) +endif() + if(CONFIG_OPENTHREAD_OTNS) set(OT_OTNS ON CACHE BOOL "Enable OTNS support" FORCE) else() diff --git a/modules/openthread/Kconfig.features b/modules/openthread/Kconfig.features index e793a9bfaa4a..a6834ce924fa 100644 --- a/modules/openthread/Kconfig.features +++ b/modules/openthread/Kconfig.features @@ -212,6 +212,10 @@ config OPENTHREAD_NEIGHBOR_DISCOVERY_AGENT config OPENTHREAD_NETDATA_PUBLISHER bool "Thread Network Data publisher" +config OPENTHREAD_OPERATIONAL_DATASET_AUTO_INIT + bool "Operational dataset auto init" + default y + config OPENTHREAD_OTNS bool "OTNS support" diff --git a/west.yml b/west.yml index 50447869f255..78ed9fcfa4f8 100644 --- a/west.yml +++ b/west.yml @@ -290,7 +290,7 @@ manifest: revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad path: modules/lib/open-amp - name: openthread - revision: 6d557383e8bc8654f813674e8631c2e56b8e70d0 + revision: 37fb77098982d17555dd7a3f58832714bb9df56e path: modules/lib/openthread - name: picolibc path: modules/lib/picolibc From b37ce40878ec52295afe6350d17712d60eb6639a Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Tue, 11 Jul 2023 15:26:22 +0200 Subject: [PATCH 405/528] [nrf fromtree] drivers: sensor: qdec_nrfx: Workaround spurious samplerdy event The underlying HAL driver may improperly forward an samplerdy event even if it's disabled in the configuration. Ignore the event to prevent error logs until the issue is fixed in HAL. Signed-off-by: Marek Pieta (cherry picked from commit 1601725354e0e099d3b3d90f334bcf49a9300fdf) --- drivers/sensor/qdec_nrfx/qdec_nrfx.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/sensor/qdec_nrfx/qdec_nrfx.c b/drivers/sensor/qdec_nrfx/qdec_nrfx.c index c8c053f29af3..7d8f71cede20 100644 --- a/drivers/sensor/qdec_nrfx/qdec_nrfx.c +++ b/drivers/sensor/qdec_nrfx/qdec_nrfx.c @@ -135,6 +135,13 @@ static void qdec_nrfx_event_handler(nrfx_qdec_event_t event, void *p_context) unsigned int key; switch (event.type) { + case NRF_QDEC_EVENT_SAMPLERDY: + /* The underlying HAL driver may improperly forward an samplerdy event even if it's + * disabled in the configuration. Ignore the event to prevent error logs until the + * issue is fixed in HAL. + */ + break; + case NRF_QDEC_EVENT_REPORTRDY: accumulate(dev_data, event.data.report.acc); From 1cdcadb94cee4f1e6a3dd7b34cc9cf276b245519 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 16 Jul 2023 01:13:49 +0530 Subject: [PATCH 406/528] [nrf fromtree] net: l2: wifi: Fix printing of TWT parameters Use the macro to print to handle for cases where shell context is NULL, this is possible because in this net management event handler shell context is not passed. Signed-off-by: Chaitanya Tata (cherry picked from commit 7a6288a87150e27d6a9d7882725406ee71d2e53c) --- subsys/net/l2/wifi/wifi_shell.c | 38 ++++++++++++++++----------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 5372f8746d73..a2ef9e6d242c 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -241,25 +241,25 @@ static void print_twt_params(uint8_t dialog_token, uint8_t flow_id, bool trigger, uint32_t twt_wake_interval, uint64_t twt_interval) { - shell_fprintf(context.sh, SHELL_NORMAL, "TWT Dialog token: %d\n", - dialog_token); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT flow ID: %d\n", - flow_id); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT negotiation type: %s\n", - wifi_twt_negotiation_type2str[negotiation_type]); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT responder: %s\n", - responder ? "true" : "false"); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT implicit: %s\n", - implicit ? "true" : "false"); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT announce: %s\n", - announce ? "true" : "false"); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT trigger: %s\n", - trigger ? "true" : "false"); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT wake interval: %d us\n", - twt_wake_interval); - shell_fprintf(context.sh, SHELL_NORMAL, "TWT interval: %lld us\n", - twt_interval); - shell_fprintf(context.sh, SHELL_NORMAL, "========================\n"); + print(context.sh, SHELL_NORMAL, "TWT Dialog token: %d\n", + dialog_token); + print(context.sh, SHELL_NORMAL, "TWT flow ID: %d\n", + flow_id); + print(context.sh, SHELL_NORMAL, "TWT negotiation type: %s\n", + wifi_twt_negotiation_type2str[negotiation_type]); + print(context.sh, SHELL_NORMAL, "TWT responder: %s\n", + responder ? "true" : "false"); + print(context.sh, SHELL_NORMAL, "TWT implicit: %s\n", + implicit ? "true" : "false"); + print(context.sh, SHELL_NORMAL, "TWT announce: %s\n", + announce ? "true" : "false"); + print(context.sh, SHELL_NORMAL, "TWT trigger: %s\n", + trigger ? "true" : "false"); + print(context.sh, SHELL_NORMAL, "TWT wake interval: %d us\n", + twt_wake_interval); + print(context.sh, SHELL_NORMAL, "TWT interval: %lld us\n", + twt_interval); + print(context.sh, SHELL_NORMAL, "========================\n"); } static void handle_wifi_twt_event(struct net_mgmt_event_callback *cb) From 434be7b575ce338645801140fbd2e64738f8994e Mon Sep 17 00:00:00 2001 From: Jonathan Rico Date: Wed, 21 Jun 2023 09:02:30 +0200 Subject: [PATCH 407/528] [nrf fromtree] tests: Bluetooth: don't assume handle is 0 Don't assume the connection handle will always be 0. This is currently the case with the Zephyr link layer, but recently changed in the Softdevice Controller. Another problem is that apparently the spec allows the controller to just blackhole data instead of returning `BT_HCI_ERR_UNKNOWN_CONN_ID` if the host uses a wrong handle. Signed-off-by: Jonathan Rico (cherry picked from commit 8a65b3f337f4a13ce46f74ddae61de5cbf6e179b) --- tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c b/tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c index 7dab3cbc3b0f..f762ee824737 100644 --- a/tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c +++ b/tests/bsim/bluetooth/host/l2cap/split/tester/src/main.c @@ -41,6 +41,7 @@ static K_SEM_DEFINE(cmd_sem, 1, 1); static struct k_sem acl_pkts; static struct k_sem tx_credits; static uint16_t peer_mps; +static uint16_t conn_handle; static uint16_t active_opcode = 0xFFFF; static struct net_buf *cmd_rsp; @@ -123,6 +124,9 @@ static void handle_meta_event(struct net_buf *buf) switch (code) { case BT_HCI_EVT_LE_ENH_CONN_COMPLETE: + case BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2: + conn_handle = sys_get_le16(&buf->data[4]); + LOG_DBG("connected: handle: %d", conn_handle); SET_FLAG(is_connected); break; case BT_HCI_EVT_LE_DATA_LEN_CHANGE: @@ -488,7 +492,7 @@ static int send_acl(struct net_buf *buf) uint8_t flags = BT_ACL_START_NO_FLUSH; hdr = net_buf_push(buf, sizeof(*hdr)); - hdr->handle = sys_cpu_to_le16(bt_acl_handle_pack(0, flags)); + hdr->handle = sys_cpu_to_le16(bt_acl_handle_pack(conn_handle, flags)); hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr)); bt_buf_set_type(buf, BT_BUF_ACL_OUT); From 60166d9f304b48febbbaad58a210d0017ed8fdd3 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 13 Jul 2023 13:42:10 +0000 Subject: [PATCH 408/528] [nrf noup] drivers/flashdisk: Add support for Partition Manager The commits adds support for generating flash disks from Partition Manager defined partitions. Signed-off-by: Dominik Ermel --- drivers/disk/flashdisk.c | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/drivers/disk/flashdisk.c b/drivers/disk/flashdisk.c index 6336ad4dfd03..3e43716c2b3c 100644 --- a/drivers/disk/flashdisk.c +++ b/drivers/disk/flashdisk.c @@ -420,6 +420,8 @@ static const struct disk_operations flash_disk_ops = { .ioctl = disk_flash_access_ioctl, }; +#ifndef USE_PARTITION_MANAGER +/* The non-Partition manager, DTS based generators below */ #define DT_DRV_COMPAT zephyr_flash_disk #define PARTITION_PHANDLE(n) DT_PHANDLE_BY_IDX(DT_DRV_INST(n), partition, 0) @@ -461,6 +463,82 @@ DT_INST_FOREACH_STATUS_OKAY(VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY) "Devicetree node " DT_NODE_PATH(DT_DRV_INST(n)) \ " has cache size which is not a multiple of its sector size"); DT_INST_FOREACH_STATUS_OKAY(VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE) +#else /* ifndef USE_PARTITION_MANAGER */ +/* Partition Manager based generators below */ + +/* Gets the PM_..._EXTRA_PARAM_##param value */ +#define PM_FLASH_DISK_ENTRY_EXTRA_PARAM(name, param) PM_##name##_EXTRA_PARAM_disk_##param + +/* Gets the PM_..._NAME value which is originally cased, as in yaml, partition name */ +#define PM_FLASH_DISK_ENTRY_PARTITION_NAME(name) PM_##name##_NAME + +/* Generates flashdiskN_cache variable name, where N is partition ID */ +#define PM_FLASH_DISK_CACHE_VARIABLE(n) UTIL_CAT(flashdisk, UTIL_CAT(FIXED_PARTITION_ID(n), _cache)) + +/* Generate cache buffers */ +#define CACHE_SIZE(n) (COND_CODE_1(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, read_only), (0), (1)) * \ + PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size)) +#define DEFINE_FLASHDISKS_CACHE(n) \ + static uint8_t __aligned(4) PM_FLASH_DISK_CACHE_VARIABLE(n)[CACHE_SIZE(n)]; + +PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_CACHE) + +/* Generated single Flash Disk device data from Partition Manager partition. + * Partition is required to have type set to disk in partition definitions: + * type: disk + * and following extra params can be provided: + * extra_params: { + * name = "", + * cache_size = , + * sector_size = , + * read_only = + * } + * where: + * is mandatory device name that will be used by Disk Access and FAT FS to mount device; + * is cache r/w cache size, which is mandatory if read_only = 0 or not present, + * and should be multiple of ; + * is mandatory device sector size information, usually should be erase page size, + * for flash devices, for example 4096 bytes; + * read_only is optional, if not present then assumed false; can be 0(false) or 1(true). + */ +#define DEFINE_FLASHDISKS_DEVICE(n) \ +{ \ + .info = { \ + .ops = &flash_disk_ops, \ + .name = STRINGIFY(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, name)), \ + }, \ + .area_id = FIXED_PARTITION_ID(n), \ + .offset = FIXED_PARTITION_OFFSET(n), \ + .cache = PM_FLASH_DISK_CACHE_VARIABLE(n), \ + .cache_size = sizeof(PM_FLASH_DISK_CACHE_VARIABLE(n)), \ + .size = FIXED_PARTITION_SIZE(n), \ + .sector_size = PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, sector_size), \ +}, + +/* The bellow used PM_FOREACH_TYPE_disk is generated by Partition Manager foreach + * loop macro. The lower case _disk is type name for which the macro has been generated; + * partition entry can have multiple types set and foreach macro will be generated + * for every type found across partition definitions. + */ +static struct flashdisk_data flash_disks[] = { + PM_FOREACH_AFFILIATED_TO_disk(DEFINE_FLASHDISKS_DEVICE) +}; + +#define VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY(n) \ + COND_CODE_1(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, read_only), \ + (/* cache-size is not used for read-only disks */), \ + (BUILD_ASSERT(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size) != 0, \ + "Flash disk partition " STRINGIFY(PM_FLASH_DISK_ENTRY_PARTITION_NAME(n))\ + " must have non-zero cache-size");)) +PM_FOREACH_AFFILIATED_TO_disk(VERIFY_CACHE_SIZE_IS_NOT_ZERO_IF_NOT_READ_ONLY) + +#define VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE(n) \ + BUILD_ASSERT(PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, cache_size) % \ + PM_FLASH_DISK_ENTRY_EXTRA_PARAM(n, sector_size) == 0, \ + "Devicetree node " STRINGIFY(PM_FLASH_DISK_ENTRY_PARTITION_NAME(n)) \ + " has cache size which is not a multiple of its sector size"); +PM_FOREACH_AFFILIATED_TO_disk(VERIFY_CACHE_SIZE_IS_MULTIPLY_OF_SECTOR_SIZE) +#endif /* USE_PARTITION_MANAGER */ static int disk_flash_init(void) { From d3e16944bf989227c487afdebaac541079f6cb9f Mon Sep 17 00:00:00 2001 From: Marcin Gasiorek Date: Thu, 6 Jul 2023 14:21:46 +0200 Subject: [PATCH 409/528] [nrf fromtree] tests: net: pkt_filter: Add TCs for new hooks Add new TCs to cover new hooks functionality. These tests implement simple IP filter. Signed-off-by: Marcin Gasiorek (cherry picked from commit f161233fa128acd9c9252d35a3e7b2ff28cf3579) --- tests/net/npf/prj.conf | 4 + tests/net/npf/src/main.c | 176 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) diff --git a/tests/net/npf/prj.conf b/tests/net/npf/prj.conf index b1e779aa96e2..57d622130907 100644 --- a/tests/net/npf/prj.conf +++ b/tests/net/npf/prj.conf @@ -12,3 +12,7 @@ CONFIG_NET_BUF_TX_COUNT=20 CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y CONFIG_COMPILER_COLOR_DIAGNOSTICS=n +CONFIG_NET_IPV4=y +CONFIG_NET_PKT_FILTER_IPV4_HOOK=y +CONFIG_NET_IPV6=y +CONFIG_NET_PKT_FILTER_IPV6_HOOK=y diff --git a/tests/net/npf/src/main.c b/tests/net/npf/src/main.c index 992ff535ed6e..39aa63daac20 100644 --- a/tests/net/npf/src/main.c +++ b/tests/net/npf/src/main.c @@ -16,6 +16,9 @@ LOG_MODULE_REGISTER(npf_test, NET_LOG_LEVEL); #include #include +#include "ipv4.h" +#include "ipv6.h" + #include #include @@ -72,6 +75,31 @@ static struct net_pkt *build_test_pkt(int type, int size, struct net_if *iface) return pkt; } +static struct net_pkt *build_test_ip_pkt(void *src, void *dst, + sa_family_t family, struct net_if *iface) +{ + struct net_pkt *pkt; + int ret = -1; + int size; + + size = (family == AF_INET) ? sizeof(struct net_ipv4_hdr) : + (family == AF_INET6) ? sizeof(struct net_ipv6_hdr) : 0U; + + pkt = net_pkt_rx_alloc_with_buffer(iface, size, family, 0, K_NO_WAIT); + zassert_not_null(pkt, ""); + + if (family == AF_INET) { + ret = net_ipv4_create(pkt, (struct in_addr *)src, (struct in_addr *)dst); + } else if (family == AF_INET6) { + ret = net_ipv6_create(pkt, (struct in6_addr *)src, (struct in6_addr *)dst); + } + zassert_equal(ret, 0, "Cannot create %s packet (%d)", + (family == AF_INET) ? "IPv4" : "IPv6", ret); + + DBG("pkt %p: iface %p size %d sa_family %d\n", pkt, iface, size, family); + return pkt; +} + /* * Declare some fake interfaces and test their filter conditions. */ @@ -274,6 +302,8 @@ static void test_npf_eth_mac_address(void) zassert_true(npf_remove_recv_rule(&accept_matched_dst_addr), ""); zassert_false(net_pkt_filter_recv_ok(pkt), ""); zassert_true(npf_remove_recv_rule(&accept_unmatched_dst_addr), ""); + + net_pkt_unref(pkt); } static NPF_ETH_SRC_ADDR_MASK_MATCH(matched_src_addr_mask, mac_address_list, @@ -299,6 +329,8 @@ static void test_npf_eth_mac_addr_mask(void) /* cleanup */ zassert_true(npf_remove_all_recv_rules(), ""); + + net_pkt_unref(pkt); } ZTEST(net_pkt_filter_test_suite, test_npf_address_mask) @@ -307,4 +339,148 @@ ZTEST(net_pkt_filter_test_suite, test_npf_address_mask) test_npf_eth_mac_addr_mask(); } +/* + * IP address filtering + */ + +static struct in_addr ipv4_address_list[4] = { + { { { 192, 168, 1, 1 } } }, + { { { 192, 0, 2, 1 } } }, + { { { 172, 16, 0, 1 } } }, + { { { 10, 49, 0, 252 } } } +}; + +static struct in6_addr ipv6_address_list[4] = { + { { { 0x20, 0x01, 0x0d, 0xb8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }, + { { { 0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }, + { { { 0x20, 0x01, 0x0d, 0xb8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }, + { { { 0x20, 0x01, 0x0d, 0xb8, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1 } } }, +}; + +static NPF_IP_SRC_ADDR_ALLOWLIST(allowlist_ipv4_src_addr, (void *)ipv4_address_list, + ARRAY_SIZE(ipv4_address_list), AF_INET); +static NPF_IP_SRC_ADDR_BLOCKLIST(blocklist_ipv4_src_addr, (void *)ipv4_address_list, + ARRAY_SIZE(ipv4_address_list), AF_INET); + +static NPF_RULE(ipv4_allowlist, NET_OK, allowlist_ipv4_src_addr); +static NPF_RULE(ipv4_blocklist, NET_OK, blocklist_ipv4_src_addr); + +ZTEST(net_pkt_filter_test_suite, test_npf_ipv4_address_filtering) +{ + struct in_addr dst = { { { 192, 168, 2, 1 } } }; + struct in_addr bad_addr = { { { 192, 168, 2, 3 } } }; + struct net_pkt *pkt_v4 = build_test_ip_pkt(&ipv4_address_list[0], &dst, AF_INET, + &dummy_iface_a); + struct net_pkt *pkt_v6 = build_test_ip_pkt(&ipv6_address_list[0], &ipv6_address_list[1], + AF_INET6, &dummy_iface_a); + + /* make sure pkt is initially accepted */ + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + + /* validate allowlist */ + npf_insert_ipv4_recv_rule(&ipv4_allowlist); + + for (int it = 0; it < ARRAY_SIZE(ipv4_address_list); it++) { + memcpy((struct in_addr *)NET_IPV4_HDR(pkt_v4)->src, &ipv4_address_list[it], + sizeof(struct in_addr)); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + } + + /* And one not listed */ + memcpy((struct in_addr *)NET_IPV4_HDR(pkt_v4)->src, + &bad_addr, sizeof(struct in_addr)); + zassert_false(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + + /* Prepare new test */ + zassert_true(npf_remove_all_ipv4_recv_rules(), ""); + + /* make sure pkt is initially accepted */ + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + + /* validate blocklist */ + npf_insert_ipv4_recv_rule(&ipv4_blocklist); + + for (int it = 0; it < ARRAY_SIZE(ipv4_address_list); it++) { + memcpy((struct in_addr *)NET_IPV4_HDR(pkt_v4)->src, &ipv4_address_list[it], + sizeof(struct in_addr)); + zassert_false(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + } + + /* And one not listed */ + memcpy((struct in_addr *)NET_IPV4_HDR(pkt_v4)->src, + &bad_addr, sizeof(struct in_addr)); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + + zassert_true(npf_remove_all_ipv4_recv_rules(), ""); + net_pkt_unref(pkt_v6); + net_pkt_unref(pkt_v4); +} + +static NPF_IP_SRC_ADDR_ALLOWLIST(allowlist_ipv6_src_addr, (void *)ipv6_address_list, + ARRAY_SIZE(ipv6_address_list), AF_INET6); +static NPF_IP_SRC_ADDR_BLOCKLIST(blocklist_ipv6_src_addr, (void *)ipv6_address_list, + ARRAY_SIZE(ipv6_address_list), AF_INET6); + +static NPF_RULE(ipv6_allowlist, NET_OK, allowlist_ipv6_src_addr); +static NPF_RULE(ipv6_blocklist, NET_OK, blocklist_ipv6_src_addr); + +ZTEST(net_pkt_filter_test_suite, test_npf_ipv6_address_filtering) +{ + struct in6_addr dst = { { { 0xfe, 0x80, 0x43, 0xb8, 0, 0, 0, 0, + 0, 0, 0, 0xf2, 0xaa, 0x29, 0x02, 0x04 } } }; + struct in6_addr bad_addr = { { { 0x20, 0x01, 0x0d, 0xb8, 8, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0x1 } } }; + struct net_pkt *pkt_v6 = build_test_ip_pkt(&ipv6_address_list[0], &dst, AF_INET6, + &dummy_iface_a); + struct net_pkt *pkt_v4 = build_test_ip_pkt(&ipv4_address_list[0], &ipv4_address_list[1], + AF_INET, &dummy_iface_a); + + /* make sure pkt is initially accepted */ + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + + /* validate allowlist */ + npf_insert_ipv6_recv_rule(&ipv6_allowlist); + + for (int it = 0; it < ARRAY_SIZE(ipv6_address_list); it++) { + memcpy((struct in6_addr *)NET_IPV6_HDR(pkt_v6)->src, + &ipv6_address_list[it], sizeof(struct in6_addr)); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + } + + /* And one not listed */ + memcpy((struct in6_addr *)NET_IPV6_HDR(pkt_v6)->src, + &bad_addr, sizeof(struct in6_addr)); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + zassert_false(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + + /* Prepare new test */ + zassert_true(npf_remove_all_ipv6_recv_rules(), ""); + + /* make sure pkt is initially accepted */ + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v4), ""); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + + /* validate blocklist */ + npf_insert_ipv6_recv_rule(&ipv6_blocklist); + + for (int it = 0; it < ARRAY_SIZE(ipv6_address_list); it++) { + memcpy((struct in6_addr *)NET_IPV6_HDR(pkt_v6)->src, + &ipv6_address_list[it], sizeof(struct in6_addr)); + zassert_false(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + } + + /* And one not listed */ + memcpy((struct in6_addr *)NET_IPV4_HDR(pkt_v6)->src, + &bad_addr, sizeof(struct in6_addr)); + zassert_true(net_pkt_filter_ip_recv_ok(pkt_v6), ""); + + zassert_true(npf_remove_all_ipv6_recv_rules(), ""); + net_pkt_unref(pkt_v6); + net_pkt_unref(pkt_v4); +} + ZTEST_SUITE(net_pkt_filter_test_suite, NULL, test_npf_iface, NULL, NULL, NULL); From c60f4de9f45b0bc5e83dcd4a904db55d55a8f80a Mon Sep 17 00:00:00 2001 From: Marcin Gasiorek Date: Thu, 6 Jul 2023 14:17:51 +0200 Subject: [PATCH 410/528] [nrf fromtree] net: pkt_filter: Introduce additional hooks for pkt_filter The additional hooks provide infrastructure to construct rules on another network stack levels. Main benefit of this approach is packets are pre-parsed and e.g. IP filter is easier to implement. These hooks are equivalent of prerouting and local_in in linux's netfilter. Signed-off-by: Marcin Gasiorek (cherry picked from commit 5febda39d3196498dc2670c6d197798159663ef2) --- include/zephyr/net/net_pkt.h | 31 +++++++++ include/zephyr/net/net_pkt_filter.h | 81 ++++++++++++++++++++++++ subsys/net/ip/connection.c | 5 ++ subsys/net/ip/ipv4.c | 13 ++-- subsys/net/ip/ipv6.c | 5 ++ subsys/net/pkt_filter/Kconfig | 22 +++++++ subsys/net/pkt_filter/base.c | 98 +++++++++++++++++++++++++++++ 7 files changed, 251 insertions(+), 4 deletions(-) diff --git a/include/zephyr/net/net_pkt.h b/include/zephyr/net/net_pkt.h index 0ffd066981ad..d540a91d9ffa 100644 --- a/include/zephyr/net/net_pkt.h +++ b/include/zephyr/net/net_pkt.h @@ -1275,6 +1275,37 @@ static inline bool net_pkt_filter_recv_ok(struct net_pkt *pkt) #endif /* CONFIG_NET_PKT_FILTER */ +#if defined(CONFIG_NET_PKT_FILTER) && \ + (defined(CONFIG_NET_PKT_FILTER_IPV4_HOOK) || defined(CONFIG_NET_PKT_FILTER_IPV6_HOOK)) + +bool net_pkt_filter_ip_recv_ok(struct net_pkt *pkt); + +#else + +static inline bool net_pkt_filter_ip_recv_ok(struct net_pkt *pkt) +{ + ARG_UNUSED(pkt); + + return true; +} + +#endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK || CONFIG_NET_PKT_FILTER_IPV6_HOOK */ + +#if defined(CONFIG_NET_PKT_FILTER) && defined(CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK) + +bool net_pkt_filter_local_in_recv_ok(struct net_pkt *pkt); + +#else + +static inline bool net_pkt_filter_local_in_recv_ok(struct net_pkt *pkt) +{ + ARG_UNUSED(pkt); + + return true; +} + +#endif /* CONFIG_NET_PKT_FILTER && CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */ + /* @endcond */ /** diff --git a/include/zephyr/net/net_pkt_filter.h b/include/zephyr/net/net_pkt_filter.h index 735352253000..aa1ad89b0e61 100644 --- a/include/zephyr/net/net_pkt_filter.h +++ b/include/zephyr/net/net_pkt_filter.h @@ -67,6 +67,12 @@ struct npf_rule_list { extern struct npf_rule_list npf_send_rules; /** @brief rule list applied to incoming packets */ extern struct npf_rule_list npf_recv_rules; +/** @brief rule list applied for local incoming packets */ +extern struct npf_rule_list npf_local_in_recv_rules; +/** @brief rule list applied for IPv4 incoming packets */ +extern struct npf_rule_list npf_ipv4_recv_rules; +/** @brief rule list applied for IPv6 incoming packets */ +extern struct npf_rule_list npf_ipv6_recv_rules; /** * @brief Insert a rule at the front of given rule list @@ -111,6 +117,27 @@ bool npf_remove_all_rules(struct npf_rule_list *rules); #define npf_remove_all_send_rules() npf_remove_all_rules(&npf_send_rules) #define npf_remove_all_recv_rules() npf_remove_all_rules(&npf_recv_rules) +#ifdef CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK +#define npf_insert_local_in_recv_rule(rule) npf_insert_rule(&npf_local_in_recv_rules, rule) +#define npf_append_local_in_recv_rule(rule) npf_append_rule(&npf_local_in_recv_rules, rule) +#define npf_remove_local_in_recv_rule(rule) npf_remove_rule(&npf_local_in_recv_rules, rule) +#define npf_remove_all_local_in_recv_rules() npf_remove_all_rules(&npf_local_in_recv_rules) +#endif /* CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */ + +#ifdef CONFIG_NET_PKT_FILTER_IPV4_HOOK +#define npf_insert_ipv4_recv_rule(rule) npf_insert_rule(&npf_ipv4_recv_rules, rule) +#define npf_append_ipv4_recv_rule(rule) npf_append_rule(&npf_ipv4_recv_rules, rule) +#define npf_remove_ipv4_recv_rule(rule) npf_remove_rule(&npf_ipv4_recv_rules, rule) +#define npf_remove_all_ipv4_recv_rules() npf_remove_all_rules(&npf_ipv4_recv_rules) +#endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK */ + +#ifdef CONFIG_NET_PKT_FILTER_IPV6_HOOK +#define npf_insert_ipv6_recv_rule(rule) npf_insert_rule(&npf_ipv6_recv_rules, rule) +#define npf_append_ipv6_recv_rule(rule) npf_append_rule(&npf_ipv6_recv_rules, rule) +#define npf_remove_ipv6_recv_rule(rule) npf_remove_rule(&npf_ipv6_recv_rules, rule) +#define npf_remove_all_ipv6_recv_rules() npf_remove_all_rules(&npf_ipv6_recv_rules) +#endif /* CONFIG_NET_PKT_FILTER_IPV6_HOOK */ + /** * @brief Statically define one packet filter rule * @@ -296,6 +323,60 @@ extern npf_test_fn_t npf_size_inbounds; .test.fn = npf_size_inbounds, \ } +/** @cond INTERNAL_HIDDEN */ + +struct npf_test_ip { + struct npf_test test; + uint8_t addr_family; + void *ipaddr; + uint32_t ipaddr_num; +}; + +extern npf_test_fn_t npf_ip_src_addr_match; +extern npf_test_fn_t npf_ip_src_addr_unmatch; + +/** @endcond */ + +/** + * @brief Statically define a "ip address allowlist" packet filter condition + * + * This tests if the packet source ip address matches any of the ip + * addresses contained in the provided set. + * + * @param _name Name of the condition + * @param _ip_addr_array Array of struct in_addr or struct in6_addr items to test + *against + * @param _ip_addr_num number of IP addresses in the array + * @param _af Addresses family type (AF_INET / AF_INET6) in the array + */ +#define NPF_IP_SRC_ADDR_ALLOWLIST(_name, _ip_addr_array, _ip_addr_num, _af) \ + struct npf_test_ip _name = { \ + .addr_family = _af, \ + .ipaddr = (_ip_addr_array), \ + .ipaddr_num = _ip_addr_num, \ + .test.fn = npf_ip_src_addr_match, \ + } + +/** + * @brief Statically define a "ip address blocklist" packet filter condition + * + * This tests if the packet source ip address matches any of the ip + * addresses contained in the provided set. + * + * @param _name Name of the condition + * @param _ip_addr_array Array of struct in_addr or struct in6_addr items to test + *against + * @param _ip_addr_num number of IP addresses in the array + * @param _af Addresses family type (AF_INET / AF_INET6) in the array + */ +#define NPF_IP_SRC_ADDR_BLOCKLIST(_name, _ip_addr_array, _ip_addr_num, _af) \ + struct npf_test_ip _name = { \ + .addr_family = _af, \ + .ipaddr = (_ip_addr_array), \ + .ipaddr_num = _ip_addr_num, \ + .test.fn = npf_ip_src_addr_unmatch, \ + } + /** @} */ /** diff --git a/subsys/net/ip/connection.c b/subsys/net/ip/connection.c index b370bc1835fc..225a3fdbaade 100644 --- a/subsys/net/ip/connection.c +++ b/subsys/net/ip/connection.c @@ -576,6 +576,11 @@ enum net_verdict net_conn_input(struct net_pkt *pkt, uint8_t pkt_family = net_pkt_family(pkt); uint16_t src_port = 0U, dst_port = 0U; + if (!net_pkt_filter_local_in_recv_ok(pkt)) { + /* drop the packet */ + return NET_DROP; + } + if (IS_ENABLED(CONFIG_NET_IP) && (pkt_family == AF_INET || pkt_family == AF_INET6)) { if (IS_ENABLED(CONFIG_NET_UDP) && proto == IPPROTO_UDP) { src_port = proto_hdr->udp->src_port; diff --git a/subsys/net/ip/ipv4.c b/subsys/net/ip/ipv4.c index 0392e75cec1c..83827303f6e7 100644 --- a/subsys/net/ip/ipv4.c +++ b/subsys/net/ip/ipv4.c @@ -302,6 +302,15 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt) goto drop; } + net_pkt_set_ipv4_ttl(pkt, hdr->ttl); + + net_pkt_set_family(pkt, PF_INET); + + if (!net_pkt_filter_ip_recv_ok(pkt)) { + /* drop the packet */ + return NET_DROP; + } + if ((!net_ipv4_is_my_addr((struct in_addr *)hdr->dst) && !net_ipv4_is_addr_mcast((struct in_addr *)hdr->dst) && !(hdr->proto == IPPROTO_UDP && @@ -326,10 +335,6 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt) } } - net_pkt_set_ipv4_ttl(pkt, hdr->ttl); - - net_pkt_set_family(pkt, PF_INET); - if (IS_ENABLED(CONFIG_NET_IPV4_FRAGMENT)) { /* Check if this is a fragmented packet, and if so, handle reassembly */ if ((ntohs(*((uint16_t *)&hdr->offset[0])) & diff --git a/subsys/net/ip/ipv6.c b/subsys/net/ip/ipv6.c index 48165099759c..7ef758314060 100644 --- a/subsys/net/ip/ipv6.c +++ b/subsys/net/ip/ipv6.c @@ -520,6 +520,11 @@ enum net_verdict net_ipv6_input(struct net_pkt *pkt, bool is_loopback) net_pkt_set_ipv6_hop_limit(pkt, NET_IPV6_HDR(pkt)->hop_limit); net_pkt_set_family(pkt, PF_INET6); + if (!net_pkt_filter_ip_recv_ok(pkt)) { + /* drop the packet */ + return NET_DROP; + } + if (IS_ENABLED(CONFIG_NET_ROUTE_MCAST) && net_ipv6_is_addr_mcast((struct in6_addr *)hdr->dst)) { /* If the packet is a multicast packet and multicast routing diff --git a/subsys/net/pkt_filter/Kconfig b/subsys/net/pkt_filter/Kconfig index ef3a02ad45e7..8b95a67caa63 100644 --- a/subsys/net/pkt_filter/Kconfig +++ b/subsys/net/pkt_filter/Kconfig @@ -12,6 +12,28 @@ config NET_PKT_FILTER transmission and reception. if NET_PKT_FILTER + +config NET_PKT_FILTER_IPV4_HOOK + bool "Additional network packet filtering hook inside IPv4 stack" + depends on NET_IPV4 + help + This additional hook provides infrastructure to construct custom + rules on the IP packet. + +config NET_PKT_FILTER_IPV6_HOOK + bool "Additional network packet filtering hook inside IPv6 stack" + depends on NET_IPV6 + help + This additional hook provides infrastructure to construct custom + rules on the IP packet. + +config NET_PKT_FILTER_LOCAL_IN_HOOK + bool "Additional network packet filtering hook for connection input" + depends on NET_IP + help + This additional hook provides infrastructure to construct custom + rules for e.g. TCP/UDP packets. + module = NET_PKT_FILTER module-dep = NET_LOG module-str = Log level for packet filtering diff --git a/subsys/net/pkt_filter/base.c b/subsys/net/pkt_filter/base.c index e33091e7af74..bb2eb9f085ba 100644 --- a/subsys/net/pkt_filter/base.c +++ b/subsys/net/pkt_filter/base.c @@ -25,6 +25,50 @@ struct npf_rule_list npf_recv_rules = { .lock = { }, }; +#ifdef CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK +struct npf_rule_list npf_local_in_recv_rules = { + .rule_head = SYS_SLIST_STATIC_INIT(&local_in_recv_rules.rule_head), + .lock = { }, +}; +#endif /* CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */ + +#ifdef CONFIG_NET_PKT_FILTER_IPV4_HOOK +struct npf_rule_list npf_ipv4_recv_rules = { + .rule_head = SYS_SLIST_STATIC_INIT(&ipv4_recv_rules.rule_head), + .lock = { }, +}; +#endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK */ + +#ifdef CONFIG_NET_PKT_FILTER_IPV6_HOOK +struct npf_rule_list npf_ipv6_recv_rules = { + .rule_head = SYS_SLIST_STATIC_INIT(&ipv6_recv_rules.rule_head), + .lock = { }, +}; +#endif /* CONFIG_NET_PKT_FILTER_IPV6_HOOK */ + +/* + * Helper function + */ +static struct npf_rule_list *get_ip_rules(uint8_t pf) +{ + switch (pf) { + case PF_INET: +#ifdef CONFIG_NET_PKT_FILTER_IPV4_HOOK + return &npf_ipv4_recv_rules; +#endif + break; + case PF_INET6: +#ifdef CONFIG_NET_PKT_FILTER_IPV6_HOOK + return &npf_ipv6_recv_rules; +#endif + break; + default: + return NULL; + } + + return NULL; +} + /* * Rule application */ @@ -98,6 +142,31 @@ bool net_pkt_filter_recv_ok(struct net_pkt *pkt) return result == NET_OK; } +#ifdef CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK +bool net_pkt_filter_local_in_recv_ok(struct net_pkt *pkt) +{ + enum net_verdict result = lock_evaluate(&npf_local_in_recv_rules, pkt); + + return result == NET_OK; +} +#endif /* CONFIG_NET_PKT_FILTER_LOCAL_IN_HOOK */ + +#if defined(CONFIG_NET_PKT_FILTER_IPV4_HOOK) || defined(CONFIG_NET_PKT_FILTER_IPV6_HOOK) +bool net_pkt_filter_ip_recv_ok(struct net_pkt *pkt) +{ + struct npf_rule_list *rules = get_ip_rules(net_pkt_family(pkt)); + + if (!rules) { + NET_DBG("no rules"); + return true; + } + + enum net_verdict result = lock_evaluate(rules, pkt); + + return result == NET_OK; +} +#endif /* CONFIG_NET_PKT_FILTER_IPV4_HOOK || CONFIG_NET_PKT_FILTER_IPV6_HOOK */ + /* * Rule management */ @@ -199,3 +268,32 @@ bool npf_size_inbounds(struct npf_test *test, struct net_pkt *pkt) return pkt_size >= bounds->min && pkt_size <= bounds->max; } + +bool npf_ip_src_addr_match(struct npf_test *test, struct net_pkt *pkt) +{ + struct npf_test_ip *test_ip = + CONTAINER_OF(test, struct npf_test_ip, test); + uint8_t pkt_family = net_pkt_family(pkt); + + for (uint32_t ip_it = 0; ip_it < test_ip->ipaddr_num; ip_it++) { + if (IS_ENABLED(CONFIG_NET_IPV4) && pkt_family == AF_INET) { + struct in_addr *addr = (struct in_addr *)NET_IPV4_HDR(pkt)->src; + + if (net_ipv4_addr_cmp(addr, &((struct in_addr *)test_ip->ipaddr)[ip_it])) { + return true; + } + } else if (IS_ENABLED(CONFIG_NET_IPV6) && pkt_family == AF_INET6) { + struct in6_addr *addr = (struct in6_addr *)NET_IPV6_HDR(pkt)->src; + + if (net_ipv6_addr_cmp(addr, &((struct in6_addr *)test_ip->ipaddr)[ip_it])) { + return true; + } + } + } + return false; +} + +bool npf_ip_src_addr_unmatch(struct npf_test *test, struct net_pkt *pkt) +{ + return !npf_ip_src_addr_match(test, pkt); +} From 8b323dd9fef4729e933364131aaac6b1a302cb6d Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Thu, 29 Jun 2023 16:14:27 +0200 Subject: [PATCH 411/528] [nrf fromtree] Bluetooth: Mesh: add statistic module PR adds the statistic module to estimate frame handling. The module helps to understand the ratio of the received\relayed\dropped\transmited frames. That shows the efficiency of the current configuration\implementation. Signed-off-by: Aleksandr Khromykh (cherry picked from commit 7199425792e8321d48ab082909d9bded92f7f46c) Signed-off-by: Alperen Sener --- doc/connectivity/bluetooth/api/mesh.rst | 1 + .../bluetooth/api/mesh/statistic.rst | 19 +++++ include/zephyr/bluetooth/mesh.h | 1 + include/zephyr/bluetooth/mesh/statistic.h | 69 +++++++++++++++++++ subsys/bluetooth/mesh/CMakeLists.txt | 2 + subsys/bluetooth/mesh/Kconfig | 8 +++ subsys/bluetooth/mesh/adv.c | 29 ++++++++ subsys/bluetooth/mesh/adv.h | 24 +------ subsys/bluetooth/mesh/net.c | 5 ++ subsys/bluetooth/mesh/statistic.c | 64 +++++++++++++++++ subsys/bluetooth/mesh/statistic.h | 14 ++++ 11 files changed, 213 insertions(+), 23 deletions(-) create mode 100644 doc/connectivity/bluetooth/api/mesh/statistic.rst create mode 100644 include/zephyr/bluetooth/mesh/statistic.h create mode 100644 subsys/bluetooth/mesh/statistic.c create mode 100644 subsys/bluetooth/mesh/statistic.h diff --git a/doc/connectivity/bluetooth/api/mesh.rst b/doc/connectivity/bluetooth/api/mesh.rst index d954348841dd..1eb691b96c8a 100644 --- a/doc/connectivity/bluetooth/api/mesh.rst +++ b/doc/connectivity/bluetooth/api/mesh.rst @@ -21,4 +21,5 @@ Read more about Bluetooth mesh on the mesh/proxy.rst mesh/heartbeat.rst mesh/cfg.rst + mesh/statistic.rst mesh/shell.rst diff --git a/doc/connectivity/bluetooth/api/mesh/statistic.rst b/doc/connectivity/bluetooth/api/mesh/statistic.rst new file mode 100644 index 000000000000..bf974b9ae91c --- /dev/null +++ b/doc/connectivity/bluetooth/api/mesh/statistic.rst @@ -0,0 +1,19 @@ +.. _bluetooth_mesh_stat: + +Frame statistic +############### + +The frame statistic API allows monitoring the number of received frames over +different interfaces, and the number of planned and succeeded transmission and +relaying attempts. + +The API helps the user to estimate the efficiency of the advertiser configuration +parameters and the scanning ability of the device. The number of the monitored +parameters can be easily extended by customer values. + +An application can read out and clean up statistics at any time. + +API reference +************* + +.. doxygengroup:: bt_mesh_stat diff --git a/include/zephyr/bluetooth/mesh.h b/include/zephyr/bluetooth/mesh.h index eeea9e4bccaa..a4ef70dc6ded 100644 --- a/include/zephyr/bluetooth/mesh.h +++ b/include/zephyr/bluetooth/mesh.h @@ -48,5 +48,6 @@ #include #include #include +#include #endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_H_ */ diff --git a/include/zephyr/bluetooth/mesh/statistic.h b/include/zephyr/bluetooth/mesh/statistic.h new file mode 100644 index 000000000000..c5403d2fd546 --- /dev/null +++ b/include/zephyr/bluetooth/mesh/statistic.h @@ -0,0 +1,69 @@ +/** @file + * @brief BLE mesh statistic APIs. + */ + +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_BLUETOOTH_MESH_STATISTIC_H_ +#define ZEPHYR_INCLUDE_BLUETOOTH_MESH_STATISTIC_H_ + +#include + +/** + * @brief Statistic + * @defgroup bt_mesh_stat Statistic + * @ingroup bt_mesh + * @{ + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** The structure that keeps statistics of mesh frames handling. */ +struct bt_mesh_statistic { + /** All received frames passed basic validation and decryption. */ + /** Received frames over advertiser. */ + uint32_t rx_adv; + /** Received frames over loopback. */ + uint32_t rx_loopback; + /** Received frames over proxy. */ + uint32_t rx_proxy; + /** Received over unknown interface. */ + uint32_t rx_uknown; + /** Counter of frames that were initiated to relay over advertiser bearer. */ + uint32_t tx_adv_relay_planned; + /** Counter of frames that succeeded relaying over advertiser bearer. */ + uint32_t tx_adv_relay_succeeded; + /** Counter of frames that were initiated to send over advertiser bearer locally. */ + uint32_t tx_local_planned; + /** Counter of frames that succeeded to send over advertiser bearer locally. */ + uint32_t tx_local_succeeded; + /** Counter of frames that were initiated to send over friend bearer. */ + uint32_t tx_friend_planned; + /** Counter of frames that succeeded to send over friend bearer. */ + uint32_t tx_friend_succeeded; +}; + +/** @brief Get mesh frame handling statistic. + * + * @param st BLE mesh statistic. + */ +void bt_mesh_stat_get(struct bt_mesh_statistic *st); + +/** @brief Reset mesh frame handling statistic. + */ +void bt_mesh_stat_reset(void); + +#ifdef __cplusplus +} +#endif +/** + * @} + */ + +#endif /* ZEPHYR_INCLUDE_BLUETOOTH_MESH_STATISTIC_H_ */ diff --git a/subsys/bluetooth/mesh/CMakeLists.txt b/subsys/bluetooth/mesh/CMakeLists.txt index df97ee49d0ff..10b142e87f59 100644 --- a/subsys/bluetooth/mesh/CMakeLists.txt +++ b/subsys/bluetooth/mesh/CMakeLists.txt @@ -120,6 +120,8 @@ zephyr_library_sources_ifdef(CONFIG_BT_MESH_OD_PRIV_PROXY_SRV sol_pdu_rpl_srv.c) zephyr_library_sources_ifdef(CONFIG_BT_MESH_SOLICITATION solicitation.c) +zephyr_library_sources_ifdef(CONFIG_BT_MESH_STATISTIC statistic.c) + if (CONFIG_BT_MESH_USES_TINYCRYPT) zephyr_library_sources(crypto_tc.c) else() diff --git a/subsys/bluetooth/mesh/Kconfig b/subsys/bluetooth/mesh/Kconfig index 7fb163ecb153..02be4ba1c6ad 100644 --- a/subsys/bluetooth/mesh/Kconfig +++ b/subsys/bluetooth/mesh/Kconfig @@ -1667,4 +1667,12 @@ config BT_MESH_DEBUG_USE_ID_ADDR endif # BT_MESH_LOG_LEVEL_DBG +config BT_MESH_STATISTIC + bool "The frame handling statistics [EXPERIMENTAL]" + select EXPERIMENTAL + help + The module gathers statistics of received, relayed, and transmitted + frames. This helps to estimate the quality of the communication and + the sufficiency of configured advertiser instances. + endif # BT_MESH diff --git a/subsys/bluetooth/mesh/adv.c b/subsys/bluetooth/mesh/adv.c index fd5e84a6db1e..2132c14e1519 100644 --- a/subsys/bluetooth/mesh/adv.c +++ b/subsys/bluetooth/mesh/adv.c @@ -25,6 +25,7 @@ #include "proxy.h" #include "pb_gatt_srv.h" #include "solicitation.h" +#include "statistic.h" #define LOG_LEVEL CONFIG_BT_MESH_ADV_LOG_LEVEL #include @@ -46,6 +47,30 @@ static K_FIFO_DEFINE(bt_mesh_adv_queue); static K_FIFO_DEFINE(bt_mesh_relay_queue); static K_FIFO_DEFINE(bt_mesh_friend_queue); +void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv) +{ + if (!adv->started) { + adv->started = 1; + + if (adv->cb && adv->cb->start) { + adv->cb->start(duration, err, adv->cb_data); + } + + if (err) { + adv->cb = NULL; + } else if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) { + bt_mesh_stat_succeeded_count(adv); + } + } +} + +static void bt_mesh_adv_send_end(int err, struct bt_mesh_adv const *adv) +{ + if (adv->started && adv->cb && adv->cb->end) { + adv->cb->end(err, adv->cb_data); + } +} + static void adv_buf_destroy(struct net_buf *buf) { struct bt_mesh_adv adv = *BT_MESH_ADV(buf); @@ -230,6 +255,10 @@ void bt_mesh_adv_send(struct net_buf *buf, const struct bt_mesh_send_cb *cb, BT_MESH_ADV(buf)->cb_data = cb_data; BT_MESH_ADV(buf)->busy = 1U; + if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) { + bt_mesh_stat_planned_count(BT_MESH_ADV(buf)); + } + if (IS_ENABLED(CONFIG_BT_MESH_ADV_EXT_FRIEND_SEPARATE) && BT_MESH_ADV(buf)->tag == BT_MESH_FRIEND_ADV) { net_buf_put(&bt_mesh_friend_queue, net_buf_ref(buf)); diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index 9f886c8980bb..3d0acf8a7ac5 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -83,29 +83,7 @@ int bt_mesh_adv_gatt_start(const struct bt_le_adv_param *param, int32_t duration const struct bt_data *ad, size_t ad_len, const struct bt_data *sd, size_t sd_len); -static inline void bt_mesh_adv_send_start(uint16_t duration, int err, - struct bt_mesh_adv *adv) -{ - if (!adv->started) { - adv->started = 1; - - if (adv->cb && adv->cb->start) { - adv->cb->start(duration, err, adv->cb_data); - } - - if (err) { - adv->cb = NULL; - } - } -} - -static inline void bt_mesh_adv_send_end( - int err, struct bt_mesh_adv const *adv) -{ - if (adv->started && adv->cb && adv->cb->end) { - adv->cb->end(err, adv->cb_data); - } -} +void bt_mesh_adv_send_start(uint16_t duration, int err, struct bt_mesh_adv *adv); int bt_mesh_scan_active_set(bool active); diff --git a/subsys/bluetooth/mesh/net.c b/subsys/bluetooth/mesh/net.c index 7a65ffe2e6fe..4632d6f7164f 100644 --- a/subsys/bluetooth/mesh/net.c +++ b/subsys/bluetooth/mesh/net.c @@ -35,6 +35,7 @@ #include "settings.h" #include "prov.h" #include "cfg.h" +#include "statistic.h" #ifdef CONFIG_BT_MESH_V1d1 #include "sar_cfg_internal.h" @@ -851,6 +852,10 @@ void bt_mesh_net_recv(struct net_buf_simple *data, int8_t rssi, return; } + if (IS_ENABLED(CONFIG_BT_MESH_STATISTIC)) { + bt_mesh_stat_rx(net_if); + } + /* Save the state so the buffer can later be relayed */ net_buf_simple_save(&buf, &state); diff --git a/subsys/bluetooth/mesh/statistic.c b/subsys/bluetooth/mesh/statistic.c new file mode 100644 index 000000000000..5b1ffe7e0f53 --- /dev/null +++ b/subsys/bluetooth/mesh/statistic.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +#include "adv.h" +#include "net.h" +#include "statistic.h" + +static struct bt_mesh_statistic stat; + +void bt_mesh_stat_get(struct bt_mesh_statistic *st) +{ + memcpy(st, &stat, sizeof(struct bt_mesh_statistic)); +} + +void bt_mesh_stat_reset(void) +{ + memset(&stat, 0, sizeof(struct bt_mesh_statistic)); +} + +void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv) +{ + if (adv->tag & BT_MESH_LOCAL_ADV) { + stat.tx_local_planned++; + } else if (adv->tag & BT_MESH_RELAY_ADV) { + stat.tx_adv_relay_planned++; + } else if (adv->tag & BT_MESH_FRIEND_ADV) { + stat.tx_friend_planned++; + } +} + +void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv) +{ + if (adv->tag & BT_MESH_LOCAL_ADV) { + stat.tx_local_succeeded++; + } else if (adv->tag & BT_MESH_RELAY_ADV) { + stat.tx_adv_relay_succeeded++; + } else if (adv->tag & BT_MESH_FRIEND_ADV) { + stat.tx_friend_succeeded++; + } +} + +void bt_mesh_stat_rx(enum bt_mesh_net_if net_if) +{ + switch (net_if) { + case BT_MESH_NET_IF_ADV: + stat.rx_adv++; + break; + case BT_MESH_NET_IF_LOCAL: + stat.rx_loopback++; + break; + case BT_MESH_NET_IF_PROXY: + case BT_MESH_NET_IF_PROXY_CFG: + stat.rx_proxy++; + break; + default: + stat.rx_uknown++; + break; + } +} diff --git a/subsys/bluetooth/mesh/statistic.h b/subsys/bluetooth/mesh/statistic.h new file mode 100644 index 000000000000..fdb488f0d81b --- /dev/null +++ b/subsys/bluetooth/mesh/statistic.h @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ +#define ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ + +void bt_mesh_stat_planned_count(struct bt_mesh_adv *adv); +void bt_mesh_stat_succeeded_count(struct bt_mesh_adv *adv); +void bt_mesh_stat_rx(enum bt_mesh_net_if net_if); + +#endif /* ZEPHYR_SUBSYS_BLUETOOTH_MESH_STATISTIC_H_ */ From 090f9b9522200d585b370a3883aa303a4b329c1a Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Mon, 3 Jul 2023 16:10:29 +0200 Subject: [PATCH 412/528] [nrf fromtree] Bluetooth: Mesh: add shell statistic commands Commit adds commands to get and to clear the frame statistic. Signed-off-by: Aleksandr Khromykh (cherry picked from commit 9b4d0804199debcae6d488ce47dead182ba9b84c) Signed-off-by: Alperen Sener --- doc/connectivity/bluetooth/api/mesh/shell.rst | 15 +++++++ subsys/bluetooth/mesh/shell/shell.c | 40 +++++++++++++++++++ tests/bluetooth/mesh_shell/prj.conf | 1 + 3 files changed, 56 insertions(+) diff --git a/doc/connectivity/bluetooth/api/mesh/shell.rst b/doc/connectivity/bluetooth/api/mesh/shell.rst index 7a3f2e1b291e..83a0d045d455 100644 --- a/doc/connectivity/bluetooth/api/mesh/shell.rst +++ b/doc/connectivity/bluetooth/api/mesh/shell.rst @@ -1687,3 +1687,18 @@ The Solicitation PDU RPL Client model is an optional mesh subsystem that can be * ``RngStart``: Start address of the SSRC range. * ``Ackd``: This argument decides on whether an acknowledged or unacknowledged message will be sent. * ``RngLen``: Range length for the SSRC addresses to be cleared from the solicitiation RPL list. This parameter is optional; if absent, only a single SSRC address will be cleared. + + +Frame statistic +=============== + +``mesh stat get`` +----------------- + + Get the frame statistic. The command prints numbers of received frames, as well as numbers of planned and succeeded transmission attempts. + + +``mesh stat clear`` +------------------- + + Clear all statistics collected before. diff --git a/subsys/bluetooth/mesh/shell/shell.c b/subsys/bluetooth/mesh/shell/shell.c index a5231ce2e7d0..3cf577ea6a82 100644 --- a/subsys/bluetooth/mesh/shell/shell.c +++ b/subsys/bluetooth/mesh/shell/shell.c @@ -1595,6 +1595,35 @@ static int cmd_appidx(const struct shell *sh, size_t argc, char *argv[]) return 0; } +#if defined(CONFIG_BT_MESH_STATISTIC) +static int cmd_stat_get(const struct shell *sh, size_t argc, char *argv[]) +{ + struct bt_mesh_statistic st; + + bt_mesh_stat_get(&st); + + shell_print(sh, "Received frames over:"); + shell_print(sh, "adv: %d", st.rx_adv); + shell_print(sh, "loopback: %d", st.rx_loopback); + shell_print(sh, "proxy: %d", st.rx_proxy); + shell_print(sh, "unknown: %d", st.rx_uknown); + + shell_print(sh, "Transmitted frames: - "); + shell_print(sh, "relay adv: %d - %d", st.tx_adv_relay_planned, st.tx_adv_relay_succeeded); + shell_print(sh, "local adv: %d - %d", st.tx_local_planned, st.tx_local_succeeded); + shell_print(sh, "friend: %d - %d", st.tx_friend_planned, st.tx_friend_succeeded); + + return 0; +} + +static int cmd_stat_clear(const struct shell *sh, size_t argc, char *argv[]) +{ + bt_mesh_stat_reset(); + + return 0; +} +#endif + #if defined(CONFIG_BT_MESH_SHELL_CDB) SHELL_STATIC_SUBCMD_SET_CREATE( cdb_cmds, @@ -1723,6 +1752,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(target_cmds, SHELL_CMD_ARG(app, NULL, "[AppKeyIdx]", cmd_appidx, 1, 1), SHELL_SUBCMD_SET_END); +#if defined(CONFIG_BT_MESH_STATISTIC) +SHELL_STATIC_SUBCMD_SET_CREATE(stat_cmds, + SHELL_CMD_ARG(get, NULL, NULL, cmd_stat_get, 1, 0), + SHELL_CMD_ARG(clear, NULL, NULL, cmd_stat_clear, 1, 0), + SHELL_SUBCMD_SET_END); +#endif + /* Placeholder for model shell modules that is configured in the application */ SHELL_SUBCMD_SET_CREATE(model_cmds, (mesh, models)); @@ -1760,6 +1796,10 @@ SHELL_STATIC_SUBCMD_SET_CREATE(mesh_cmds, #endif SHELL_CMD(target, &target_cmds, "Target commands", bt_mesh_shell_mdl_cmds_help), +#if defined(CONFIG_BT_MESH_STATISTIC) + SHELL_CMD(stat, &stat_cmds, "Statistic commands", bt_mesh_shell_mdl_cmds_help), +#endif + SHELL_SUBCMD_SET_END ); diff --git a/tests/bluetooth/mesh_shell/prj.conf b/tests/bluetooth/mesh_shell/prj.conf index 0672ec6cbb31..6535b77c3ab3 100644 --- a/tests/bluetooth/mesh_shell/prj.conf +++ b/tests/bluetooth/mesh_shell/prj.conf @@ -78,3 +78,4 @@ CONFIG_BT_MESH_IV_UPDATE_TEST=y CONFIG_BT_MESH_LOG_LEVEL_DBG=y CONFIG_BT_MESH_CDB=y CONFIG_BT_MESH_PROVISIONER=y +CONFIG_BT_MESH_STATISTIC=y From a76720de8e6e0ddf978e9e1fa836d98f6f035c7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20Kopy=C5=9Bci=C5=84ski?= Date: Fri, 26 May 2023 14:11:12 +0200 Subject: [PATCH 413/528] [nrf fromtree] Tests: Bluetooth: tester: add BTP command for connecting Proxy Client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This allows to execute MESH/CL/MPXS tests. Signed-off-by: Krzysztof Kopyściński (cherry picked from commit 7d7874c75b42f391a08de112b42f0b048da1b50b) Signed-off-by: Alperen Sener --- tests/bluetooth/tester/overlay-mesh.conf | 1 + tests/bluetooth/tester/src/btp/btp_mesh.h | 6 ++++++ tests/bluetooth/tester/src/btp_mesh.c | 24 +++++++++++++++++++++++ 3 files changed, 31 insertions(+) diff --git a/tests/bluetooth/tester/overlay-mesh.conf b/tests/bluetooth/tester/overlay-mesh.conf index 963b864ba2b9..840af06c1c08 100644 --- a/tests/bluetooth/tester/overlay-mesh.conf +++ b/tests/bluetooth/tester/overlay-mesh.conf @@ -22,3 +22,4 @@ CONFIG_BT_MESH_CDB=y CONFIG_BT_MESH_CDB_NODE_COUNT=3 CONFIG_BT_MESH_PROV_OOB_PUBLIC_KEY=y CONFIG_BT_MESH_MSG_CACHE_SIZE=10 +CONFIG_BT_MESH_PROXY_CLIENT=y diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 5aa191d7d7b8..096f61bcb161 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -747,6 +747,12 @@ struct btp_mesh_cfg_krp_set_rp { uint8_t phase; } __packed; +#define BTP_MESH_PROXY_CONNECT 0x77 + +struct btp_proxy_connect_cmd { + uint16_t net_idx; +} __packed; + /* events */ #define BTP_MESH_EV_OUT_NUMBER_ACTION 0x80 struct btp_mesh_out_number_action_ev { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 9af4867a84a3..37dd04ab3e47 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -916,6 +916,23 @@ static uint8_t proxy_identity_enable(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +#if defined(CONFIG_BT_MESH_PROXY_CLIENT) +static uint8_t proxy_connect(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_proxy_connect_cmd *cp = cmd; + int err; + + err = bt_mesh_proxy_connect(cp->net_idx); + if (err) { + LOG_ERR("Failed to connect to GATT Proxy (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} +#endif + static uint8_t composition_data_get(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -2849,6 +2866,13 @@ static const struct btp_handler handlers[] = { .expect_len = 0, .func = proxy_identity_enable, }, +#if defined(CONFIG_BT_MESH_PROXY_CLIENT) + { + .opcode = BTP_MESH_PROXY_CONNECT, + .expect_len = sizeof(struct btp_proxy_connect_cmd), + .func = proxy_connect + }, +#endif }; void net_recv_ev(uint8_t ttl, uint8_t ctl, uint16_t src, uint16_t dst, const void *payload, From eec94c109222b6616b99c02f91ecb9446273cf70 Mon Sep 17 00:00:00 2001 From: Pavel Vasilyev Date: Wed, 21 Jun 2023 13:50:18 +0200 Subject: [PATCH 414/528] [nrf fromtree] bluetooth: tester: Add commands to add and delete virtual addresses Virtual address behavior has been changed in this PR: https://github.com/zephyrproject-rtos/zephyr/pull/57878 Now it is required to register virtual address before using it. Corresponding PR to auto-pts: https://github.com/auto-pts/auto-pts/pull/961 Signed-off-by: Pavel Vasilyev (cherry picked from commit 4d56a318f162b758daf04525143380da373e1814) Signed-off-by: Alperen Sener --- tests/bluetooth/tester/src/btp/btp_mesh.h | 13 +++++ tests/bluetooth/tester/src/btp_mesh.c | 63 +++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/tests/bluetooth/tester/src/btp/btp_mesh.h b/tests/bluetooth/tester/src/btp/btp_mesh.h index 096f61bcb161..d7d2b2cdc7b8 100644 --- a/tests/bluetooth/tester/src/btp/btp_mesh.h +++ b/tests/bluetooth/tester/src/btp/btp_mesh.h @@ -747,6 +747,19 @@ struct btp_mesh_cfg_krp_set_rp { uint8_t phase; } __packed; +#define BTP_MESH_VA_ADD 0x4D +struct btp_mesh_va_add_cmd { + uint8_t label_uuid[16]; +} __packed; +struct btp_mesh_va_add_rp { + uint16_t addr; +} __packed; + +#define BTP_MESH_VA_DEL 0x4E +struct btp_mesh_va_del_cmd { + uint8_t label_uuid[16]; +} __packed; + #define BTP_MESH_PROXY_CONNECT 0x77 struct btp_proxy_connect_cmd { diff --git a/tests/bluetooth/tester/src/btp_mesh.c b/tests/bluetooth/tester/src/btp_mesh.c index 37dd04ab3e47..c922c812631d 100644 --- a/tests/bluetooth/tester/src/btp_mesh.c +++ b/tests/bluetooth/tester/src/btp_mesh.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #define LOG_MODULE_NAME bttester_mesh @@ -172,6 +173,8 @@ static uint8_t supported_commands(const void *cmd, uint16_t cmd_len, tester_set_bit(rp->data, BTP_MESH_PROVISION_ADV); tester_set_bit(rp->data, BTP_MESH_CFG_KRP_GET); tester_set_bit(rp->data, BTP_MESH_CFG_KRP_SET); + tester_set_bit(rp->data, BTP_MESH_VA_ADD); + tester_set_bit(rp->data, BTP_MESH_VA_DEL); *rsp_len = sizeof(*rp) + 10; @@ -736,6 +739,10 @@ static uint8_t net_send(const void *cmd, uint16_t cmd_len, .send_ttl = cp->ttl, }; + if (BT_MESH_ADDR_IS_VIRTUAL(ctx.addr)) { + ctx.uuid = bt_mesh_va_uuid_get(ctx.addr, NULL, NULL); + } + LOG_DBG("ttl 0x%02x dst 0x%04x payload_len %d", ctx.send_ttl, ctx.addr, cp->payload_len); @@ -756,6 +763,48 @@ static uint8_t net_send(const void *cmd, uint16_t cmd_len, return BTP_STATUS_SUCCESS; } +static uint8_t va_add(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_va_add_cmd *cp = cmd; + struct btp_mesh_va_add_rp *rp = rsp; + const struct bt_mesh_va *va; + int err; + + err = bt_mesh_va_add(cp->label_uuid, &va); + if (err) { + LOG_ERR("Failed to add Label UUID (err %d)", err); + return BTP_STATUS_FAILED; + } + + rp->addr = sys_cpu_to_le16(va->addr); + *rsp_len = sizeof(*rp); + + return BTP_STATUS_SUCCESS; +} + +static uint8_t va_del(const void *cmd, uint16_t cmd_len, + void *rsp, uint16_t *rsp_len) +{ + const struct btp_mesh_va_del_cmd *cp = cmd; + const struct bt_mesh_va *va; + int err; + + va = bt_mesh_va_find(cp->label_uuid); + if (!va) { + LOG_ERR("Failed to find Label UUID"); + return BTP_STATUS_FAILED; + } + + err = bt_mesh_va_del(va->uuid); + if (err) { + LOG_ERR("Failed to delete Label UUID (err %d)", err); + return BTP_STATUS_FAILED; + } + + return BTP_STATUS_SUCCESS; +} + static uint8_t health_generate_faults(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len) { @@ -815,6 +864,10 @@ static uint8_t model_send(const void *cmd, uint16_t cmd_len, .send_ttl = BT_MESH_TTL_DEFAULT, }; + if (BT_MESH_ADDR_IS_VIRTUAL(ctx.addr)) { + ctx.uuid = bt_mesh_va_uuid_get(ctx.addr, NULL, NULL); + } + src = sys_le16_to_cpu(cp->src); /* Lookup source address */ @@ -2844,6 +2897,16 @@ static const struct btp_handler handlers[] = { .expect_len = sizeof(struct btp_mesh_cfg_krp_set_cmd), .func = config_krp_set, }, + { + .opcode = BTP_MESH_VA_ADD, + .expect_len = sizeof(struct btp_mesh_va_add_cmd), + .func = va_add, + }, + { + .opcode = BTP_MESH_VA_DEL, + .expect_len = sizeof(struct btp_mesh_va_del_cmd), + .func = va_del, + }, #if defined(CONFIG_BT_TESTING) { .opcode = BTP_MESH_LPN_SUBSCRIBE, From 1fca4103604192a907773a139415744a2d1f9280 Mon Sep 17 00:00:00 2001 From: Alperen Sener Date: Mon, 24 Jul 2023 12:26:53 +0200 Subject: [PATCH 415/528] [nrf fromtree] bluetooth: mesh: increase mesh scan window Increaing mesh scan window in order to reduce the number of messages colliding into scan window end which happens every 30ms currently. Increasing the window to 3000ms in order to improve performance. Keeping 30ms window only for legacy advertiser support. Signed-off-by: Alperen Sener (cherry picked from commit dbb0b30bdd8d3aa1a32faf2aabee441a0c749794) Signed-off-by: Alperen Sener --- subsys/bluetooth/mesh/adv.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/subsys/bluetooth/mesh/adv.h b/subsys/bluetooth/mesh/adv.h index 3d0acf8a7ac5..eec6ae2fd74f 100644 --- a/subsys/bluetooth/mesh/adv.h +++ b/subsys/bluetooth/mesh/adv.h @@ -13,8 +13,14 @@ #define BT_MESH_ADV(buf) (*(struct bt_mesh_adv **)net_buf_user_data(buf)) #define BT_MESH_ADV_SCAN_UNIT(_ms) ((_ms) * 8 / 5) + +#if defined(CONFIG_BT_EXT_ADV) +#define BT_MESH_SCAN_INTERVAL_MS 3000 +#define BT_MESH_SCAN_WINDOW_MS 3000 +#else #define BT_MESH_SCAN_INTERVAL_MS 30 #define BT_MESH_SCAN_WINDOW_MS 30 +#endif enum bt_mesh_adv_type { BT_MESH_ADV_PROV, From 609d7ab6ce3eef5c30822165e014c5d9f216549b Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Fri, 30 Jun 2023 10:03:12 +0100 Subject: [PATCH 416/528] [nrf fromlist] modules: hal_nordic: nrf_802154: Make paths relative Makes the files listed in the cmake file relative as they do not need to be absolute paths. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/59867 Signed-off-by: Jamie McCrae --- modules/hal_nordic/nrf_802154/CMakeLists.txt | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/modules/hal_nordic/nrf_802154/CMakeLists.txt b/modules/hal_nordic/nrf_802154/CMakeLists.txt index 1ec8afbfdfb9..e2b42cff8c53 100644 --- a/modules/hal_nordic/nrf_802154/CMakeLists.txt +++ b/modules/hal_nordic/nrf_802154/CMakeLists.txt @@ -7,12 +7,12 @@ zephyr_interface_library_named(zephyr-802154-interface) if (CONFIG_NRF_802154_RADIO_DRIVER) target_sources(nrf-802154-platform PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/radio/platform/nrf_802154_random_zephyr.c - ${CMAKE_CURRENT_SOURCE_DIR}/sl_opensource/platform/nrf_802154_gpiote_crit_sect.c - ${CMAKE_CURRENT_SOURCE_DIR}/sl_opensource/platform/nrf_802154_clock_zephyr.c - ${CMAKE_CURRENT_SOURCE_DIR}/sl_opensource/platform/nrf_802154_gpiote_zephyr.c - ${CMAKE_CURRENT_SOURCE_DIR}/sl_opensource/platform/nrf_802154_irq_zephyr.c - ${CMAKE_CURRENT_SOURCE_DIR}/sl_opensource/platform/nrf_802154_temperature_zephyr.c + radio/platform/nrf_802154_random_zephyr.c + sl_opensource/platform/nrf_802154_gpiote_crit_sect.c + sl_opensource/platform/nrf_802154_clock_zephyr.c + sl_opensource/platform/nrf_802154_gpiote_zephyr.c + sl_opensource/platform/nrf_802154_irq_zephyr.c + sl_opensource/platform/nrf_802154_temperature_zephyr.c ) target_compile_definitions(zephyr-802154-interface @@ -37,17 +37,17 @@ endif () if (CONFIG_NRF_802154_SERIALIZATION) target_sources(nrf-802154-platform PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/serialization/platform/nrf_802154_serialization_crit_sect.c - ${CMAKE_CURRENT_SOURCE_DIR}/serialization/platform/nrf_802154_spinel_log.c - ${CMAKE_CURRENT_SOURCE_DIR}/serialization/platform/nrf_802154_spinel_backend_ipc.c - ${CMAKE_CURRENT_SOURCE_DIR}/serialization/platform/nrf_802154_spinel_response_notifier.c + serialization/platform/nrf_802154_serialization_crit_sect.c + serialization/platform/nrf_802154_spinel_log.c + serialization/platform/nrf_802154_spinel_backend_ipc.c + serialization/platform/nrf_802154_spinel_response_notifier.c ) endif () if (CONFIG_NRF_802154_SER_RADIO) target_sources(nrf-802154-platform PRIVATE - ${CMAKE_CURRENT_SOURCE_DIR}/serialization/platform/nrf_802154_init_net.c + serialization/platform/nrf_802154_init_net.c ) endif () From be17dda0e8942eb1be7fa6055f12d2ca9de0e914 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Thu, 13 Jul 2023 18:51:53 +0200 Subject: [PATCH 417/528] [nrf fromtree] Bluetooth: Host: Introduce BT_CONN_PARAM_ANY Some controllers support additional connection parameter ranges beyond what is described in the specification. Enabling this new option allows the application to set any value to all connection parameters. Tbe Host will perform no limits nor consistency checks on any of the connection parameters (conn interval min and max, latency and timeou). However, the Host will still use numerical comparisons between the min and max connection intervals in order to verify whether the desired parameters have been established in the connection. Signed-off-by: Carles Cufi Signed-off-by: Martin Tverdal (cherry picked from commit 5824e95b1e513fef259716e876f3d594a8e91895) --- subsys/bluetooth/host/Kconfig | 12 ++++++++++++ subsys/bluetooth/host/Kconfig.gatt | 8 ++++---- subsys/bluetooth/host/hci_core.c | 4 ++++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index f93e9d20a329..8287747878ec 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -299,6 +299,18 @@ config BT_CONN_TX_MAX callback. Normally this can be left to the default value, which is equal to the number of TX buffers in the stack-internal pool. +config BT_CONN_PARAM_ANY + bool "Accept any values for connection parameters" + help + Some controllers support additional connection parameter ranges + beyond what is described in the specification. Enabling this option + allows the application to set any value to all connection parameters. + Tbe Host will perform no limits nor consistency checks on any of the + connection parameters (conn interval min and max, latency and timeout). + However, the Host will still use numerical comparisons between the + min and max connection intervals in order to verify whether the + desired parameters have been established in the connection. + config BT_USER_PHY_UPDATE bool "User control of PHY Update Procedure" depends on BT_PHY_UPDATE diff --git a/subsys/bluetooth/host/Kconfig.gatt b/subsys/bluetooth/host/Kconfig.gatt index d3cf7146db34..e405a56d1473 100644 --- a/subsys/bluetooth/host/Kconfig.gatt +++ b/subsys/bluetooth/host/Kconfig.gatt @@ -223,26 +223,26 @@ if BT_GAP_PERIPHERAL_PREF_PARAMS config BT_PERIPHERAL_PREF_MIN_INT int "Peripheral preferred minimum connection interval in 1.25ms units" default 24 - range 6 65535 + range 6 65535 if !BT_CONN_PARAM_ANY help Range 3200 to 65534 is invalid. 65535 represents no specific value. config BT_PERIPHERAL_PREF_MAX_INT int "Peripheral preferred maximum connection interval in 1.25ms units" default 40 - range 6 65535 + range 6 65535 if !BT_CONN_PARAM_ANY help Range 3200 to 65534 is invalid. 65535 represents no specific value. config BT_PERIPHERAL_PREF_LATENCY int "Peripheral preferred peripheral latency in Connection Intervals" default 0 - range 0 499 + range 0 499 if !BT_CONN_PARAM_ANY config BT_PERIPHERAL_PREF_TIMEOUT int "Peripheral preferred supervision timeout in 10ms units" default 42 - range 10 65535 + range 10 65535 if !BT_CONN_PARAM_ANY help It is up to user to provide valid timeout which pass required minimum value: in milliseconds it shall be larger than diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 8a793d3108f4..6c5cee9cf0a3 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -1698,6 +1698,10 @@ static void le_phy_update_complete(struct net_buf *buf) bool bt_le_conn_params_valid(const struct bt_le_conn_param *param) { + if (IS_ENABLED(CONFIG_BT_CONN_PARAM_ANY)) { + return true; + } + /* All limits according to BT Core spec 5.0 [Vol 2, Part E, 7.8.12] */ if (param->interval_min > param->interval_max || From c12c4d8b2dfebef1bb8aa8ed48c30f96bb31b04c Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 13 Jul 2023 15:42:23 +0200 Subject: [PATCH 418/528] [nrf noup] modules: mbedtls Use same text naming as PSA spec fixup! [nrf noup] modules: mbedtls: add PSA configurations Use same text naming as PSA spec for RIPEMD-160 and SHA-1. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 54ef35957b97..04a234a5890c 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -179,7 +179,7 @@ config PSA_HAS_HASH_SUPPORT config PSA_WANT_ALG_SHA_1 bool - prompt "PSA SHA1 support" if !PSA_PROMPTLESS + prompt "PSA SHA-1 support" if !PSA_PROMPTLESS config PSA_WANT_ALG_SHA_224 bool @@ -199,7 +199,7 @@ config PSA_WANT_ALG_SHA_512 config PSA_WANT_ALG_RIPEMD160 bool - prompt "PSA RIPEMD160 support" if !PSA_PROMPTLESS + prompt "PSA RIPEMD-160 support" if !PSA_PROMPTLESS config PSA_WANT_ALG_MD5 bool From 5083c4b71b3e835c267fa056874631c4d71939a5 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 13 Jul 2023 15:44:09 +0200 Subject: [PATCH 419/528] [nrf noup] modules: mbedtls: Add help text for unsafe PSA algorithms fixup! [nrf noup] modules: mbedtls: add PSA configurations Add help text for for unsafe PSA algorithms. These should not be used for security. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 04a234a5890c..b331a3adb910 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -179,7 +179,10 @@ config PSA_HAS_HASH_SUPPORT config PSA_WANT_ALG_SHA_1 bool - prompt "PSA SHA-1 support" if !PSA_PROMPTLESS + prompt "PSA SHA-1 support (weak)" if !PSA_PROMPTLESS + help + Warning: The SHA-1 hash is weak and deprecated and is only recommended + for use in legacy protocols. config PSA_WANT_ALG_SHA_224 bool @@ -203,7 +206,10 @@ config PSA_WANT_ALG_RIPEMD160 config PSA_WANT_ALG_MD5 bool - prompt "PSA MD5 support" if !PSA_PROMPTLESS + prompt "PSA MD5 support (weak)" if !PSA_PROMPTLESS + help + Warning: The MD5 hash is weak and deprecated and is only recommended + for use in legacy protocols. endmenu # PSA Hash support From a2a683b95343e47116caf936e695e754076e3c53 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 13 Jul 2023 16:24:00 +0200 Subject: [PATCH 420/528] [nrf noup] modules: mbedtls: Make PSA key types user configurations fixup! [nrf noup] modules: mbedtls: add PSA configurations Make the PSA key type configurations be user configurations instead of implictly enabled based on other configurations. While AES is the most likely to be used in this case the user can choose different block ciphers for block cipher modes, and others stream ciphers also exists. This also allows applications to enable key generation without any algorithms for ECC and RSA keys. Also add the full key types configurations, even though not all may be supported. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 95 ++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index b331a3adb910..5980e137032e 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -29,6 +29,8 @@ config PSA_WANT_ALG_HMAC_DRBG endmenu # RNG support +menu "PSA key type support" + config PSA_HAS_KEY_SUPPORT bool default y @@ -39,75 +41,74 @@ config PSA_HAS_KEY_SUPPORT PSA_WANT_KEY_TYPE_ECC_KEY_PAIR || \ PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY || \ PSA_WANT_KEY_TYPE_RSA_KEY_PAIR || \ - PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || \ + PSA_WANT_KEY_TYPE_DH_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_DH_KEY_PAIR config PSA_WANT_KEY_TYPE_DERIVE - bool - default y - depends on PSA_HAS_KEY_DERIVATION + bool "PSA derive key type support" help - Prompt-less configuration that states that the derived key type is used. + This key type is for high-entropy secrets only. + For low-entropy secrets, password key type should be used instead. + +config PSA_WANT_KEY_TYPE_RAW_DATA + bool "PSA raw data key type support" + help + A "key" of this type cannot be used for any cryptographic operation. + Applications can use this type to store arbitrary data in the keystore. config PSA_WANT_KEY_TYPE_HMAC - bool - default y - depends on PSA_HAS_MAC_SUPPORT + bool "PSA HMAC key type support" help - Prompt-less configuration that states that the HMAC key type is used. + HMAC key. config PSA_WANT_KEY_TYPE_AES - bool - default y - depends on PSA_WANT_ALG_ECB_NO_PADDING || \ - PSA_WANT_ALG_CBC_NO_PADDING || \ - PSA_WANT_ALG_CBC_PKCS7 || \ - PSA_WANT_ALG_CFB || \ - PSA_WANT_ALG_CTR || \ - PSA_WANT_ALG_OFB || \ - PSA_WANT_ALG_CTR || \ - PSA_WANT_ALG_XTS || \ - PSA_WANT_ALG_CCM || \ - PSA_WANT_ALG_GCM || \ - PSA_WANT_ALG_CBC_MAC || \ - PSA_WANT_ALG_CMAC + bool "PSA AES key type support" help - Prompt-less configuration that states that AES key type is used. + Key for cipher, AEAD or MAC algorithm based on the AES block cipher. config PSA_WANT_KEY_TYPE_CHACHA20 - bool + bool "PSA ChaCha20 key type support" default y depends on PSA_WANT_ALG_CHACHA20_POLY1305 || \ PSA_WANT_ALG_STREAM_CIPHER help - Prompt-less configuration that states that CHACHA20 key type is used. + Key for the ChaCha20 stream cipher or the ChaCha20-Poly1305 AEAD algorithm. config PSA_WANT_KEY_TYPE_ECC_KEY_PAIR - bool - default y - depends on PSA_HAS_ECC_SUPPORT + bool "PSA ECC key pair support" + select PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY help - Prompt-less configuration that states that ECC key pair type is used. + Elliptic curve key pair: both the private and public key. config PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY - bool - default y - depends on PSA_HAS_ECC_SUPPORT + bool "PSA ECC public key support" help - Prompt-less configuration that states that ECC public key type is used. + Elliptic curve public key. config PSA_WANT_KEY_TYPE_RSA_KEY_PAIR - bool - default y - depends on PSA_HAS_RSA_SUPPORT + bool "PSA RSA key pair type support" + select PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY help - Prompt-less configuration that states that RSA key pair type is used. + RSA key pair: both the private and public key. config PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY - bool - default y - depends on PSA_HAS_RSA_SUPPORT + bool "PSA RSA public key support" help - Prompt-less configuration that states that RSA public key type is used. + RSA public key. + +config PSA_WANT_KEY_TYPE_DH_KEY_PAIR + bool "PSA DH key pair type support" + select PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + help + Finite-field Diffie-Hellman key pair: both the private key and public key. + +config PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY + bool "PSA DH public key support" + help + Finite-field Diffie-Hellman public key. + +endmenu # PSA Key type support menu "PSA AEAD support" @@ -334,7 +335,11 @@ config PSA_HAS_ASYM_SIGN_SUPPORT config PSA_HAS_ECC_SUPPORT bool - depends on PSA_WANT_ALG_ECDH || PSA_WANT_ALG_ECDSA || PSA_WANT_ALG_DETERMINISTIC_ECDSA + depends on PSA_WANT_ALG_ECDH || \ + PSA_WANT_ALG_ECDSA || \ + PSA_WANT_ALG_DETERMINISTIC_ECDSA || \ + PSA_WANT_KEY_TYPE_ECC_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_ECC_PUBLIC_KEY default y help Prompt-less configuration that states that ECC is supported. @@ -413,7 +418,9 @@ config PSA_HAS_RSA_SUPPORT depends on PSA_WANT_ALG_RSA_OAEP || \ PSA_WANT_ALG_RSA_PKCS1V15_CRYPT || \ PSA_WANT_ALG_RSA_PKCS1V15_SIGN || \ - PSA_WANT_ALG_RSA_PSS + PSA_WANT_ALG_RSA_PSS || \ + PSA_WANT_KEY_TYPE_RSA_KEY_PAIR || \ + PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY default y help Prompt-less configuration that states that RSA is supported. From f8818ca669fada5bcbe97f51c4dcde5ebfe69afc Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 24 Jul 2023 15:26:32 +0200 Subject: [PATCH 421/528] [nrf fromtree] net: dhcpv4: Accept unicast replies Some DHCPv4 servers do not respect BROADCAST flag set on DHCP Discover, replying with unicast packet, making it impossible to obtain DHCP address by Zephyr in such cases. RFC1542 chapter 3.1.1 makes the following statement about the BROADCAST flag: This addition to the protocol is a workaround for old host implementations. Such implementations SHOULD be modified so that they may receive unicast BOOTREPLY messages, thus making use of this workaround unnecessary. In general, the use of this mechanism is discouraged. Making it clear that being able to process unicast replies from the DHCP server is not only an optional behavior, but a recommended solution. Therefore, introduce a support for unicast DHCPv4 in Zephyr. To achieve this, add additional filtering rule at the IPv4 level - in case DHCPv4 is enabled, there is an active query and the packet is destined for the DHCPv4 module, let it through for the DHCPv4 module to process, regardless of the destination IP address. Signed-off-by: Robert Lubos (cherry picked from commit a22f7e777b01c40025e52971bbb13ce39d1d8e1e) --- subsys/net/ip/Kconfig.ipv4 | 8 +++++++ subsys/net/ip/dhcpv4.c | 47 +++++++++++++++++++++++++++++++++++++- subsys/net/ip/dhcpv4.h | 33 +++++++++++++++++++++++--- subsys/net/ip/ipv4.c | 4 +++- 4 files changed, 87 insertions(+), 5 deletions(-) diff --git a/subsys/net/ip/Kconfig.ipv4 b/subsys/net/ip/Kconfig.ipv4 index a16e025a9482..a5e073051de8 100644 --- a/subsys/net/ip/Kconfig.ipv4 +++ b/subsys/net/ip/Kconfig.ipv4 @@ -82,6 +82,14 @@ config NET_DHCPV4_OPTION_CALLBACKS can be added. These can be used to support otherwise DHCP options not used by the rest of the system. +config NET_DHCPV4_ACCEPT_UNICAST + bool "Accept unicast DHCPv4 traffic" + depends on NET_DHCPV4 + default y + help + If set, the network stack will accept unicast DHCPv4 responses from + servers, before the assigned address is configured on the interface. + config NET_IPV4_AUTO bool "IPv4 autoconfiguration [EXPERIMENTAL]" depends on NET_ARP diff --git a/subsys/net/ip/dhcpv4.c b/subsys/net/ip/dhcpv4.c index be01851bd894..d5aefb3ba90a 100644 --- a/subsys/net/ip/dhcpv4.c +++ b/subsys/net/ip/dhcpv4.c @@ -211,7 +211,8 @@ static struct net_pkt *dhcpv4_create_message(struct net_if *iface, uint8_t type, msg->htype = HARDWARE_ETHERNET_TYPE; msg->hlen = net_if_get_link_addr(iface)->len; msg->xid = htonl(iface->config.dhcpv4.xid); - msg->flags = htons(DHCPV4_MSG_BROADCAST); + msg->flags = IS_ENABLED(CONFIG_NET_DHCPV4_ACCEPT_UNICAST) ? + htons(DHCPV4_MSG_UNICAST) : htons(DHCPV4_MSG_BROADCAST); if (ciaddr) { /* The ciaddr field was zero'd out above, if we are @@ -1397,3 +1398,47 @@ int net_dhcpv4_init(void) #endif return 0; } + +#if defined(CONFIG_NET_DHCPV4_ACCEPT_UNICAST) +bool net_dhcpv4_accept_unicast(struct net_pkt *pkt) +{ + NET_PKT_DATA_ACCESS_DEFINE(udp_access, struct net_udp_hdr); + struct net_pkt_cursor backup; + struct net_udp_hdr *udp_hdr; + struct net_if *iface; + bool accept = false; + + iface = net_pkt_iface(pkt); + if (iface == NULL) { + return false; + } + + /* Only accept DHCPv4 packets during active query. */ + if (iface->config.dhcpv4.state != NET_DHCPV4_SELECTING && + iface->config.dhcpv4.state != NET_DHCPV4_REQUESTING && + iface->config.dhcpv4.state != NET_DHCPV4_RENEWING && + iface->config.dhcpv4.state != NET_DHCPV4_REBINDING) { + return false; + } + + net_pkt_cursor_backup(pkt, &backup); + net_pkt_skip(pkt, net_pkt_ip_hdr_len(pkt)); + + /* Verify destination UDP port. */ + udp_hdr = (struct net_udp_hdr *)net_pkt_get_data(pkt, &udp_access); + if (udp_hdr == NULL) { + goto out; + } + + if (udp_hdr->dst_port != htons(DHCPV4_CLIENT_PORT)) { + goto out; + } + + accept = true; + +out: + net_pkt_cursor_restore(pkt, &backup); + + return accept; +} +#endif /* CONFIG_NET_DHCPV4_ACCEPT_UNICAST */ diff --git a/subsys/net/ip/dhcpv4.h b/subsys/net/ip/dhcpv4.h index 52663f7ee07e..a274e3a6aeae 100644 --- a/subsys/net/ip/dhcpv4.h +++ b/subsys/net/ip/dhcpv4.h @@ -81,9 +81,7 @@ struct dhcp_msg { /* TODO: - * 1) Support for UNICAST flag (some dhcpv4 servers will not reply if - * DISCOVER message contains BROADCAST FLAG). - * 2) Support T2(Rebind) timer. + * 1) Support T2(Rebind) timer. */ /* Maximum number of REQUEST or RENEWAL retransmits before reverting @@ -115,4 +113,33 @@ int net_dhcpv4_init(void); #endif /* CONFIG_NET_DHCPV4 */ +#if defined(CONFIG_NET_DHCPV4) && defined(CONFIG_NET_DHCPV4_ACCEPT_UNICAST) + +/** + * @brief Verify if the incoming packet should be accepted for the DHCPv4 + * module to process. + * + * In case server responds with an unicast IP packet, the IP stack needs to + * pass it through for the DHCPv4 module to process, before the actual + * destination IP address is configured on an interface. + * This function allows to determine whether there is an active DHCPv4 query on + * the interface and the packet is destined for the DHCPv4 module to process. + * + * @param pkt A packet to analyze + * + * @return true if the packet shall be accepted, false otherwise + */ +bool net_dhcpv4_accept_unicast(struct net_pkt *pkt); + +#else + +static inline bool net_dhcpv4_accept_unicast(struct net_pkt *pkt) +{ + ARG_UNUSED(pkt); + + return false; +} + +#endif /* CONFIG_NET_DHCPV4 && CONFIG_NET_DHCPV4_ACCEPT_UNICAST */ + #endif /* __INTERNAL_DHCPV4_H */ diff --git a/subsys/net/ip/ipv4.c b/subsys/net/ip/ipv4.c index 83827303f6e7..922068274f72 100644 --- a/subsys/net/ip/ipv4.c +++ b/subsys/net/ip/ipv4.c @@ -23,6 +23,7 @@ LOG_MODULE_REGISTER(net_ipv4, CONFIG_NET_IPV4_LOG_LEVEL); #include "icmpv4.h" #include "udp_internal.h" #include "tcp_internal.h" +#include "dhcpv4.h" #include "ipv4.h" BUILD_ASSERT(sizeof(struct in_addr) == NET_IPV4_ADDR_SIZE); @@ -318,7 +319,8 @@ enum net_verdict net_ipv4_input(struct net_pkt *pkt) /* RFC 1122 ch. 3.3.6 The 0.0.0.0 is non-standard bcast addr */ (IS_ENABLED(CONFIG_NET_IPV4_ACCEPT_ZERO_BROADCAST) && net_ipv4_addr_cmp((struct in_addr *)hdr->dst, - net_ipv4_unspecified_address()))))) || + net_ipv4_unspecified_address())) || + net_dhcpv4_accept_unicast(pkt)))) || (hdr->proto == IPPROTO_TCP && net_ipv4_is_addr_bcast(net_pkt_iface(pkt), (struct in_addr *)hdr->dst))) { NET_DBG("DROP: not for me"); From d8a9060bac7d0e4b0003ba69e4395c2209f8e98a Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Fri, 28 Jul 2023 14:13:41 +0200 Subject: [PATCH 422/528] [nrf noup] ci: NCS-specific CI tweaks fixup! [nrf noup] ci: NCS-specific CI tweaks - Now that gitlint supports --commits with a single commit natively, remove the extra logic: https://github.com/jorisroovers/gitlint/pull/412 - Fix gitlint ncs extension matching logic: the group was wrong (group 1 is the Revert, group 2 is the actual sauce tag). Signed-off-by: Carles Cufi --- .github/workflows/compliance.yml | 6 ++---- scripts/gitlint/ncs.py | 6 +++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.github/workflows/compliance.yml b/.github/workflows/compliance.yml index a41ab9a47199..002179b67406 100644 --- a/.github/workflows/compliance.yml +++ b/.github/workflows/compliance.yml @@ -41,11 +41,9 @@ jobs: #[[ "$(git rev-list --merges --count origin/${BASE_REF}..)" == "0" ]] || \ #(echo "::error ::Merge commits not allowed, rebase instead";false) # Sauce tag checks before rebasing - # Handle single commit separately - if [[ "$(git rev-list --first-parent --count origin/${BASE_REF}..HEAD)" == "1" ]]; then COMMITS="--commit"; else COMMITS="--commits"; fi - git rev-list --first-parent origin/${BASE_REF}..HEAD | paste -sd, | \ + git rev-list --first-parent origin/${BASE_REF}..HEAD | tr '\n' ',' | \ xargs gitlint -c ncs-sauce-tags.enable=true \ - -c title-starts-with-subsystem.regex=".*" $COMMITS + -c title-starts-with-subsystem.regex=".*" --commits git rebase origin/${BASE_REF} # debug git log --pretty=oneline | head -n 10 diff --git a/scripts/gitlint/ncs.py b/scripts/gitlint/ncs.py index a70ce4c900c2..3ec805550c24 100644 --- a/scripts/gitlint/ncs.py +++ b/scripts/gitlint/ncs.py @@ -31,7 +31,11 @@ def validate(self, commit): return [RuleViolation(self.id, 'Title does not contain a sauce tag', line_nr=1)] - tag = m.group(1) + tag = m.group(2) + + if not tag: + return [RuleViolation(self.id, 'Title does not contain a sauce tag', + line_nr=1)] self.log.debug(f'Matched sauce tag {tag}') if tag == 'mergeup': From 00ddd1a50374a7efb11acf4d7b694680f85c836a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Mon, 3 Jul 2023 11:38:02 +0200 Subject: [PATCH 423/528] [nrf fromtree] manifest: Update nRF HW models to latest The nRF HW models have been updated to include the following fixes and improvements. * GPIO & GPIOTE: Add HW models, including PPI connections and HAL glue. * NRF_NVMC: Avoid segfault on double call of cleanup * BLECrypt_if: Avoid segfault on double call of cleanup Signed-off-by: Alberto Escolar Piedras (cherry picked from commit e0e88394f57f9e48c82bf72fc5668cd1a8be61b4) Signed-off-by: Ilhan Ates --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 78ed9fcfa4f8..ecd1b80d4f13 100644 --- a/west.yml +++ b/west.yml @@ -284,7 +284,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 37c571ef7c4a86dad852566fc43eb36f42534e9f + revision: 33b999d50093da88cf935383da2bdac70ffd9456 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad From 71ef42785d1e18a99701be388ae1d5762ec1a67b Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 20 Jul 2023 15:58:26 +0200 Subject: [PATCH 424/528] [nrf fromtree] manifest: Update nRF HW models to latest Which include a more complete model of the CLOCK peripheral. Signed-off-by: Alberto Escolar Piedras (cherry picked from commit b69cd3cbc101cae3558a4730fa320e25a43b1543) Signed-off-by: Ilhan Ates --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ecd1b80d4f13..5dddc4b29943 100644 --- a/west.yml +++ b/west.yml @@ -284,7 +284,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 33b999d50093da88cf935383da2bdac70ffd9456 + revision: 7a5b67d9ee66d84e4ef5cb1f56c8f0f3252d5aa2 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad From f9824e074c84816ccfef23b723663d30895c20d6 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 27 Jul 2023 10:32:10 +0200 Subject: [PATCH 425/528] [nrf fromtree] manifest: Update nRF HW models to latest The nRF HW models have been updated to include the following fixes and improvements. * RADIO: Improve T_IFS support, and fix for low latency mode * docs: Miscelaneous improvements Signed-off-by: Alberto Escolar Piedras (cherry picked from commit b89ff1b3d6816606d24403738844a8257c2db173) Signed-off-by: Ilhan Ates --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 5dddc4b29943..f793f74eb79d 100644 --- a/west.yml +++ b/west.yml @@ -284,7 +284,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 7a5b67d9ee66d84e4ef5cb1f56c8f0f3252d5aa2 + revision: cee41373eb0bb720a370586de1ee5eb693e62c95 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad From 7c07fb2dae39f59ee9761a13304f39e5fee17a84 Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Wed, 29 Mar 2023 13:27:45 +0300 Subject: [PATCH 426/528] [nrf fromtree] mgmt: smp: SMP Client enabler SMP client support for generate request and handling response message. Updated SMP transport for send request. Added API for register SMP transport. Signed-off-by: Juha Heiskanen (cherry picked from commit 5797e4241e8978a25025ef949676bd181ce717b3) --- include/zephyr/mgmt/mcumgr/smp/smp_client.h | 109 ++++++ include/zephyr/mgmt/mcumgr/transport/smp.h | 45 +++ subsys/mgmt/mcumgr/CMakeLists.txt | 1 + subsys/mgmt/mcumgr/Kconfig | 6 + subsys/mgmt/mcumgr/smp/src/smp.c | 61 ++-- subsys/mgmt/mcumgr/smp_client/CMakeLists.txt | 9 + subsys/mgmt/mcumgr/smp_client/Kconfig | 42 +++ subsys/mgmt/mcumgr/smp_client/src/client.c | 327 ++++++++++++++++++ .../mgmt/mcumgr/transport/smp_internal.h | 10 + subsys/mgmt/mcumgr/transport/src/smp.c | 43 +++ subsys/mgmt/mcumgr/transport/src/smp_bt.c | 12 + subsys/mgmt/mcumgr/transport/src/smp_shell.c | 11 + subsys/mgmt/mcumgr/transport/src/smp_uart.c | 8 + subsys/mgmt/mcumgr/transport/src/smp_udp.c | 21 +- 14 files changed, 681 insertions(+), 24 deletions(-) create mode 100644 include/zephyr/mgmt/mcumgr/smp/smp_client.h create mode 100644 subsys/mgmt/mcumgr/smp_client/CMakeLists.txt create mode 100644 subsys/mgmt/mcumgr/smp_client/Kconfig create mode 100644 subsys/mgmt/mcumgr/smp_client/src/client.c diff --git a/include/zephyr/mgmt/mcumgr/smp/smp_client.h b/include/zephyr/mgmt/mcumgr/smp/smp_client.h new file mode 100644 index 000000000000..88b2af701b09 --- /dev/null +++ b/include/zephyr/mgmt/mcumgr/smp/smp_client.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_SMP_CLIENT_ +#define H_SMP_CLIENT_ + +#include +#include +#include +#include +#include + +/** + * @brief SMP client object + */ +struct smp_client_object { + /** Must be the first member. */ + struct k_work work; + /** FIFO for client TX queue */ + struct k_fifo tx_fifo; + /** SMP transport object */ + struct smp_transport *smpt; + /** SMP SEQ */ + uint8_t smp_seq; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize a SMP client object. + * + * @param smp_client The Client to construct. + * @param smp_type SMP transport type for discovering transport object + * + * @return 0 if successful + * @return mcumgr_err_t code on failure + */ +int smp_client_object_init(struct smp_client_object *smp_client, int smp_type); + +/** + * @brief Response callback for SMP send. + * + * @param nb net_buf for response + * @param user_data same user data that was provided as part of the request + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +typedef int (*smp_client_res_fn)(struct net_buf *nb, void *user_data); + +/** + * @brief SMP client response handler. + * + * @param nb response net_buf + * @param res_hdr Parsed SMP header + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int smp_client_single_response(struct net_buf *nb, const struct smp_hdr *res_hdr); + +/** + * @brief Allocate buffer and initialize with SMP header. + * + * @param smp_client SMP client object + * @param group SMP group id + * @param command_id SMP command id + * @param op SMP operation type + * @param version SMP MCUmgr version + * + * @return A newly-allocated buffer net_buf on success + * @return NULL on failure. + */ +struct net_buf *smp_client_buf_allocation(struct smp_client_object *smp_client, uint16_t group, + uint8_t command_id, uint8_t op, + enum smp_mcumgr_version_t version); +/** + * @brief Free a SMP client buffer. + * + * @param nb The net_buf to free. + */ +void smp_client_buf_free(struct net_buf *nb); + +/** + * @brief SMP client data send request. + * + * @param smp_client SMP client object + * @param nb net_buf packet for send + * @param cb Callback for response handler + * @param user_data user defined data pointer which will be returned back to response callback + * @param timeout_in_sec Timeout in seconds for send process. Client will retry transport + * based CONFIG_SMP_CMD_RETRY_TIME + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int smp_client_send_cmd(struct smp_client_object *smp_client, struct net_buf *nb, + smp_client_res_fn cb, void *user_data, int timeout_in_sec); + +#ifdef __cplusplus +} +#endif + +#endif /* H_SMP_CLIENT_ */ diff --git a/include/zephyr/mgmt/mcumgr/transport/smp.h b/include/zephyr/mgmt/mcumgr/transport/smp.h index 55c9c7b0826e..d8cec6878f79 100644 --- a/include/zephyr/mgmt/mcumgr/transport/smp.h +++ b/include/zephyr/mgmt/mcumgr/transport/smp.h @@ -134,6 +134,35 @@ struct smp_transport { #endif }; +/** + * @brief SMP transport type for client registration + */ +enum smp_transport_type { + /** SMP serial */ + SMP_SERIAL_TRANSPORT = 0, + /** SMP bluetooth */ + SMP_BLUETOOTH_TRANSPORT, + /** SMP shell*/ + SMP_SHELL_TRANSPORT, + /** SMP UDP IPv4 */ + SMP_UDP_IPV4_TRANSPORT, + /** SMP UDP IPv6 */ + SMP_UDP_IPV6_TRANSPORT, + /** SMP user defined type */ + SMP_USER_DEFINED_TRANSPORT +}; + +/** + * @brief SMP Client transport structure + */ +struct smp_client_transport_entry { + sys_snode_t node; + /** Transport structure pointer */ + struct smp_transport *smpt; + /** Transport type */ + int smpt_type; +}; + /** * @brief Initializes a Zephyr SMP transport object. * @@ -162,6 +191,22 @@ void smp_rx_remove_invalid(struct smp_transport *zst, void *arg); */ void smp_rx_clear(struct smp_transport *zst); +/** + * @brief Register a Zephyr SMP transport object for client. + * + * @param entry The transport to construct. + */ +void smp_client_transport_register(struct smp_client_transport_entry *entry); + +/** + * @brief Discover a registered SMP transport client object. + * + * @param smpt_type Type of transport + * + * @return Pointer to registered object. Unknown type return NULL. + */ +struct smp_transport *smp_client_transport_get(int smpt_type); + /** * @} */ diff --git a/subsys/mgmt/mcumgr/CMakeLists.txt b/subsys/mgmt/mcumgr/CMakeLists.txt index d0f0c55e19cd..ad088eca0677 100644 --- a/subsys/mgmt/mcumgr/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/CMakeLists.txt @@ -13,6 +13,7 @@ add_subdirectory(smp) add_subdirectory(util) add_subdirectory(grp) add_subdirectory(transport) +add_subdirectory_ifdef(CONFIG_SMP_CLIENT smp_client) zephyr_library_link_libraries(mgmt_mcumgr) diff --git a/subsys/mgmt/mcumgr/Kconfig b/subsys/mgmt/mcumgr/Kconfig index dfe81d4f91d2..b21c7dd8c0d0 100644 --- a/subsys/mgmt/mcumgr/Kconfig +++ b/subsys/mgmt/mcumgr/Kconfig @@ -34,6 +34,12 @@ config MCUMGR_SMP_LEGACY_RC_BEHAVIOUR response will be empty with the new behaviour enabled, as opposed to the old behaviour where the rc field will be present in the response. +menu "SMP Client" + +rsource "smp_client/Kconfig" + +endmenu + menu "Command Handlers" rsource "grp/Kconfig" diff --git a/subsys/mgmt/mcumgr/smp/src/smp.c b/subsys/mgmt/mcumgr/smp/src/smp.c index 56c9cc17b3b0..2646587cd61c 100644 --- a/subsys/mgmt/mcumgr/smp/src/smp.c +++ b/subsys/mgmt/mcumgr/smp/src/smp.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -86,12 +87,9 @@ static int smp_translate_error_code(uint16_t group, uint16_t ret) static void cbor_nb_reader_init(struct cbor_nb_reader *cnr, struct net_buf *nb) { - /* Skip the smp_hdr */ - void *new_ptr = net_buf_pull(nb, sizeof(struct smp_hdr)); - cnr->nb = nb; - zcbor_new_decode_state(cnr->zs, ARRAY_SIZE(cnr->zs), new_ptr, - cnr->nb->len, 1); + zcbor_new_decode_state(cnr->zs, ARRAY_SIZE(cnr->zs), nb->data, + nb->len, 1); } static void cbor_nb_writer_init(struct cbor_nb_writer *cnw, struct net_buf *nb) @@ -421,37 +419,54 @@ int smp_process_request_packet(struct smp_streamer *streamer, void *vreq) if (rc != 0) { rc = MGMT_ERR_ECORRUPT; break; - } else { - valid_hdr = true; } + + valid_hdr = true; + /* Skip the smp_hdr */ + net_buf_pull(req, sizeof(struct smp_hdr)); /* Does buffer contain whole message? */ - if (req->len < (req_hdr.nh_len + MGMT_HDR_SIZE)) { + if (req->len < req_hdr.nh_len) { rc = MGMT_ERR_ECORRUPT; break; } - rsp = smp_alloc_rsp(req, streamer->smpt); - if (rsp == NULL) { - rc = MGMT_ERR_ENOMEM; - break; - } + if (req_hdr.nh_op == MGMT_OP_READ || req_hdr.nh_op == MGMT_OP_WRITE) { + rsp = smp_alloc_rsp(req, streamer->smpt); + if (rsp == NULL) { + rc = MGMT_ERR_ENOMEM; + break; + } - cbor_nb_reader_init(streamer->reader, req); - cbor_nb_writer_init(streamer->writer, rsp); + cbor_nb_reader_init(streamer->reader, req); + cbor_nb_writer_init(streamer->writer, rsp); - /* Process the request payload and build the response. */ - rc = smp_handle_single_req(streamer, &req_hdr, &handler_found, &rsn); - if (rc != 0) { - break; + /* Process the request payload and build the response. */ + rc = smp_handle_single_req(streamer, &req_hdr, &handler_found, &rsn); + if (rc != 0) { + break; + } + + /* Send the response. */ + rc = streamer->smpt->functions.output(rsp); + rsp = NULL; + } else if (IS_ENABLED(CONFIG_SMP_CLIENT) && (req_hdr.nh_op == MGMT_OP_READ_RSP || + req_hdr.nh_op == MGMT_OP_WRITE_RSP)) { + rc = smp_client_single_response(req, &req_hdr); + + if (rc == MGMT_ERR_EOK) { + handler_found = true; + } else { + /* Server shuold not send error response for response */ + valid_hdr = false; + } + + } else { + rc = MGMT_ERR_ENOTSUP; } - /* Send the response. */ - rc = streamer->smpt->functions.output(rsp); - rsp = NULL; if (rc != 0) { break; } - /* Trim processed request to free up space for subsequent responses. */ net_buf_pull(req, req_hdr.nh_len); diff --git a/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt b/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt new file mode 100644 index 000000000000..061d28b30638 --- /dev/null +++ b/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt @@ -0,0 +1,9 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +# Protocol API is only exposed to MCUmgr internals. + +zephyr_library(mgmt_mcumgr_client_protocol) +zephyr_library_sources(src/client.c) diff --git a/subsys/mgmt/mcumgr/smp_client/Kconfig b/subsys/mgmt/mcumgr/smp_client/Kconfig new file mode 100644 index 000000000000..b946efe1b324 --- /dev/null +++ b/subsys/mgmt/mcumgr/smp_client/Kconfig @@ -0,0 +1,42 @@ +# Copyright Nordic Semiconductor ASA 2023. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# The Kconfig file is dedicated to smp_client subdirectory of MCUmgr +# subsystem and provides Kconfig options to control aspects of +# Simple Management Protocol Client (SMP) processing source code provided +# under the subdirectory. + +config SMP_CLIENT + bool "SMP Client support" + help + This will enable SMP Request generation and response handling. + +if SMP_CLIENT || ZTEST + +config SMP_CMD_DEFAULT_LIFE_TIME + int "SMP command lifetime in seconds" + range 2 30 + default 5 + help + This define lifetime for SMP client send request. This configure is used if a request + with a timeout of 0 is used. + +config SMP_CMD_RETRY_TIME + int "SMP command re-send period in ms" + range 100 1000 + default 500 + help + The time (in ms) which the SMP client will wait for a response before re-sending + a command. + +config SMP_CLIENT_CMD_MAX + int "SMP client max buffer count" + default 4 + help + Define how many active requests that the client can handle + +module = MCUMGR_SMP_CLIENT +module-str = mcumgr_smp_client +source "subsys/logging/Kconfig.template.log_config" + +endif # SMP_CLIENT diff --git a/subsys/mgmt/mcumgr/smp_client/src/client.c b/subsys/mgmt/mcumgr/smp_client/src/client.c new file mode 100644 index 000000000000..cca1738f117e --- /dev/null +++ b/subsys/mgmt/mcumgr/smp_client/src/client.c @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** SMP - Simple Management Client Protocol. */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(mcumgr_smp_client, CONFIG_MCUMGR_SMP_CLIENT_LOG_LEVEL); + +struct smp_client_cmd_req { + sys_snode_t node; + struct net_buf *nb; + struct smp_client_object *smp_client; + void *user_data; + smp_client_res_fn cb; + int64_t timestamp; + int retry_cnt; +}; + +struct smp_client_data_base { + struct k_work_delayable work_delay; + sys_slist_t cmd_free_list; + sys_slist_t cmd_list; +}; + +static struct smp_client_cmd_req smp_cmd_req_bufs[CONFIG_SMP_CLIENT_CMD_MAX]; +static struct smp_client_data_base smp_client_data; + +static void smp_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr); +static void smp_client_cmd_req_free(struct smp_client_cmd_req *cmd_req); + +/** + * Send all SMP client request packets. + */ +static void smp_client_handle_reqs(struct k_work *work) +{ + struct smp_client_object *smp_client; + struct smp_transport *smpt; + struct net_buf *nb; + + smp_client = (void *)work; + smpt = smp_client->smpt; + + while ((nb = net_buf_get(&smp_client->tx_fifo, K_NO_WAIT)) != NULL) { + smpt->functions.output(nb); + } +} + +static void smp_header_init(struct smp_hdr *header, uint16_t group, uint8_t id, uint8_t op, + uint16_t payload_len, uint8_t seq, enum smp_mcumgr_version_t version) +{ + /* Pre config SMP header structure */ + memset(header, 0, sizeof(struct smp_hdr)); + header->nh_version = version; + header->nh_op = op; + header->nh_len = sys_cpu_to_be16(payload_len); + header->nh_group = sys_cpu_to_be16(group); + header->nh_id = id; + header->nh_seq = seq; +} + +static void smp_client_transport_work_fn(struct k_work *work) +{ + struct smp_client_cmd_req *entry, *tmp; + smp_client_res_fn cb; + void *user_data; + int backoff_ms = CONFIG_SMP_CMD_RETRY_TIME; + int64_t time_stamp_cmp; + int64_t time_stamp_ref; + int64_t time_stamp_delta; + + ARG_UNUSED(work); + + if (sys_slist_is_empty(&smp_client_data.cmd_list)) { + /* No more packet for Transport */ + return; + } + + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&smp_client_data.cmd_list, entry, tmp, node) { + time_stamp_ref = entry->timestamp; + /* Check Time delta and get current time to reference */ + time_stamp_delta = k_uptime_delta(&time_stamp_ref); + + if (time_stamp_delta < 0) { + time_stamp_cmp = entry->timestamp - time_stamp_ref; + if (time_stamp_cmp < CONFIG_SMP_CMD_RETRY_TIME && + time_stamp_cmp < backoff_ms) { + /* Update new shorter shedule */ + backoff_ms = time_stamp_cmp; + } + continue; + } else if (entry->retry_cnt) { + /* Increment reference for re-transmission */ + entry->nb = net_buf_ref(entry->nb); + entry->retry_cnt--; + entry->timestamp = time_stamp_ref + CONFIG_SMP_CMD_RETRY_TIME; + net_buf_put(&entry->smp_client->tx_fifo, entry->nb); + smp_tx_req(&entry->smp_client->work); + continue; + } + + cb = entry->cb; + user_data = entry->user_data; + smp_client_cmd_req_free(entry); + if (cb) { + cb(NULL, user_data); + } + } + + if (!sys_slist_is_empty(&smp_client_data.cmd_list)) { + /* Re-schedule new timeout to next */ + k_work_reschedule(&smp_client_data.work_delay, K_MSEC(backoff_ms)); + } +} + +static int smp_client_init(void) +{ + k_work_init_delayable(&smp_client_data.work_delay, smp_client_transport_work_fn); + sys_slist_init(&smp_client_data.cmd_list); + sys_slist_init(&smp_client_data.cmd_free_list); + for (int i = 0; i < CONFIG_SMP_CLIENT_CMD_MAX; i++) { + sys_slist_append(&smp_client_data.cmd_free_list, &smp_cmd_req_bufs[i].node); + } + return 0; +} + +static struct smp_client_cmd_req *smp_client_cmd_req_allocate(void) +{ + sys_snode_t *cmd_node; + struct smp_client_cmd_req *req; + + cmd_node = sys_slist_get(&smp_client_data.cmd_free_list); + if (!cmd_node) { + return NULL; + } + + req = SYS_SLIST_CONTAINER(cmd_node, req, node); + + return req; +} + +static void smp_cmd_add_to_list(struct smp_client_cmd_req *cmd_req) +{ + if (sys_slist_is_empty(&smp_client_data.cmd_list)) { + /* Enable timer */ + k_work_reschedule(&smp_client_data.work_delay, K_MSEC(CONFIG_SMP_CMD_RETRY_TIME)); + } + sys_slist_append(&smp_client_data.cmd_list, &cmd_req->node); +} + +static void smp_client_cmd_req_free(struct smp_client_cmd_req *cmd_req) +{ + smp_client_buf_free(cmd_req->nb); + cmd_req->nb = NULL; + sys_slist_find_and_remove(&smp_client_data.cmd_list, &cmd_req->node); + /* Add to free list */ + sys_slist_append(&smp_client_data.cmd_free_list, &cmd_req->node); + + if (sys_slist_is_empty(&smp_client_data.cmd_list)) { + /* cancel delay */ + k_work_cancel_delayable(&smp_client_data.work_delay); + } +} + +static struct smp_client_cmd_req *smp_client_response_discover(const struct smp_hdr *res_hdr) +{ + struct smp_hdr smp_header; + enum mcumgr_op_t response; + struct smp_client_cmd_req *cmd_req; + + if (sys_slist_is_empty(&smp_client_data.cmd_list)) { + return NULL; + } + + SYS_SLIST_FOR_EACH_CONTAINER(&smp_client_data.cmd_list, cmd_req, node) { + smp_read_hdr(cmd_req->nb, &smp_header); + if (smp_header.nh_op == MGMT_OP_READ) { + response = MGMT_OP_READ_RSP; + } else { + response = MGMT_OP_WRITE_RSP; + } + + if (smp_header.nh_seq != res_hdr->nh_seq) { + continue; + } else if (res_hdr->nh_op != response) { + continue; + } + + return cmd_req; + } + return NULL; +} + +int smp_client_object_init(struct smp_client_object *smp_client, int smp_type) +{ + smp_client->smpt = smp_client_transport_get(smp_type); + if (!smp_client->smpt) { + return MGMT_ERR_EINVAL; + } + + /* Init TX FIFO */ + k_work_init(&smp_client->work, smp_client_handle_reqs); + k_fifo_init(&smp_client->tx_fifo); + + return MGMT_ERR_EOK; +} + +int smp_client_single_response(struct net_buf *nb, const struct smp_hdr *res_hdr) +{ + struct smp_client_cmd_req *cmd_req; + smp_client_res_fn cb; + void *user_data; + + /* Discover request for incoming response */ + cmd_req = smp_client_response_discover(res_hdr); + LOG_DBG("Response Header len %d, flags %d OP: %d group %d id %d seq %d", res_hdr->nh_len, + res_hdr->nh_flags, res_hdr->nh_op, res_hdr->nh_group, res_hdr->nh_id, + res_hdr->nh_seq); + + if (cmd_req) { + cb = cmd_req->cb; + user_data = cmd_req->user_data; + smp_client_cmd_req_free(cmd_req); + if (cb) { + cb(nb, user_data); + return MGMT_ERR_EOK; + } + } + + return MGMT_ERR_ENOENT; +} + +struct net_buf *smp_client_buf_allocation(struct smp_client_object *smp_client, uint16_t group, + uint8_t command_id, uint8_t op, + enum smp_mcumgr_version_t version) +{ + struct net_buf *nb; + struct smp_hdr smp_header; + + nb = smp_packet_alloc(); + + if (nb) { + /* Write SMP header with payload length 0 */ + smp_header_init(&smp_header, group, command_id, op, 0, smp_client->smp_seq++, + version); + memcpy(nb->data, &smp_header, sizeof(smp_header)); + nb->len = sizeof(smp_header); + } + return nb; +} + +void smp_client_buf_free(struct net_buf *nb) +{ + smp_packet_free(nb); +} + +static void smp_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr) +{ + memcpy(dst_hdr, nb->data, sizeof(*dst_hdr)); + dst_hdr->nh_len = sys_be16_to_cpu(dst_hdr->nh_len); + dst_hdr->nh_group = sys_be16_to_cpu(dst_hdr->nh_group); +} + +int smp_client_send_cmd(struct smp_client_object *smp_client, struct net_buf *nb, + smp_client_res_fn cb, void *user_data, int timeout_in_sec) +{ + struct smp_hdr smp_header; + struct smp_client_cmd_req *cmd_req; + + if (timeout_in_sec > 30) { + LOG_ERR("Command timeout can't be over 30 seconds"); + return MGMT_ERR_EINVAL; + } + + if (timeout_in_sec == 0) { + timeout_in_sec = CONFIG_SMP_CMD_DEFAULT_LIFE_TIME; + } + + smp_read_hdr(nb, &smp_header); + if (nb->len < sizeof(smp_header)) { + return MGMT_ERR_EINVAL; + } + /* Update Length */ + smp_header.nh_len = sys_cpu_to_be16(nb->len - sizeof(smp_header)); + smp_header.nh_group = sys_cpu_to_be16(smp_header.nh_group), + memcpy(nb->data, &smp_header, sizeof(smp_header)); + + cmd_req = smp_client_cmd_req_allocate(); + if (!cmd_req) { + return MGMT_ERR_ENOMEM; + } + + LOG_DBG("Command send Header flags %d OP: %d group %d id %d seq %d", smp_header.nh_flags, + smp_header.nh_op, sys_be16_to_cpu(smp_header.nh_group), smp_header.nh_id, + smp_header.nh_seq); + cmd_req->nb = nb; + cmd_req->cb = cb; + cmd_req->smp_client = smp_client; + cmd_req->user_data = user_data; + cmd_req->retry_cnt = timeout_in_sec * (1000 / CONFIG_SMP_CMD_RETRY_TIME); + cmd_req->timestamp = k_uptime_get() + CONFIG_SMP_CMD_RETRY_TIME; + /* Increment reference for re-transmission and read smp header */ + nb = net_buf_ref(nb); + smp_cmd_add_to_list(cmd_req); + net_buf_put(&smp_client->tx_fifo, nb); + smp_tx_req(&smp_client->work); + return MGMT_ERR_EOK; +} + +SYS_INIT(smp_client_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); diff --git a/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h b/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h index 828a15ffb162..898f2134c26c 100644 --- a/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h +++ b/subsys/mgmt/mcumgr/transport/include/mgmt/mcumgr/transport/smp_internal.h @@ -9,6 +9,7 @@ #define MGMT_MCUMGR_SMP_INTERNAL_H_ #include +#include #include #include @@ -47,6 +48,15 @@ struct zephyr_smp_transport; */ void smp_rx_req(struct smp_transport *smtp, struct net_buf *nb); +#ifdef CONFIG_SMP_CLIENT +/** + * @brief Trig SMP client request packet for transmission. + * + * @param work The transport to use to send the corresponding response(s). + */ +void smp_tx_req(struct k_work *work); +#endif + __deprecated static inline void zephyr_smp_rx_req(struct zephyr_smp_transport *smpt, struct net_buf *nb) { diff --git a/subsys/mgmt/mcumgr/transport/src/smp.c b/subsys/mgmt/mcumgr/transport/src/smp.c index 1052b82cd04f..0f23bd4c44db 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp.c @@ -31,6 +31,10 @@ K_THREAD_STACK_DEFINE(smp_work_queue_stack, CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_ST static struct k_work_q smp_work_queue; +#ifdef CONFIG_SMP_CLIENT +static sys_slist_t smp_transport_clients; +#endif + static const struct k_work_queue_config smp_work_queue_config = { .name = "mcumgr smp" }; @@ -131,6 +135,7 @@ smp_handle_reqs(struct k_work *work) smpt = (void *)work; + /* Read and handle received messages */ while ((nb = net_buf_get(&smpt->fifo, K_NO_WAIT)) != NULL) { smp_process_packet(smpt, nb); } @@ -155,6 +160,33 @@ int smp_transport_init(struct smp_transport *smpt) return 0; } +#ifdef CONFIG_SMP_CLIENT +struct smp_transport *smp_client_transport_get(int smpt_type) +{ + struct smp_client_transport_entry *entry; + + SYS_SLIST_FOR_EACH_CONTAINER(&smp_transport_clients, entry, node) { + if (entry->smpt_type == smpt_type) { + return entry->smpt; + } + } + + return NULL; +} + +void smp_client_transport_register(struct smp_client_transport_entry *entry) +{ + if (smp_client_transport_get(entry->smpt_type)) { + /* Already in list */ + return; + } + + sys_slist_append(&smp_transport_clients, &entry->node); + +} + +#endif /* CONFIG_SMP_CLIENT */ + /** * @brief Enqueues an incoming SMP request packet for processing. * @@ -171,6 +203,13 @@ smp_rx_req(struct smp_transport *smpt, struct net_buf *nb) k_work_submit_to_queue(&smp_work_queue, &smpt->work); } +#ifdef CONFIG_SMP_CLIENT +void smp_tx_req(struct k_work *work) +{ + k_work_submit_to_queue(&smp_work_queue, work); +} +#endif + void smp_rx_remove_invalid(struct smp_transport *zst, void *arg) { struct net_buf *nb; @@ -227,6 +266,10 @@ void smp_rx_clear(struct smp_transport *zst) static int smp_init(void) { +#ifdef CONFIG_SMP_CLIENT + sys_slist_init(&smp_transport_clients); +#endif + k_work_queue_init(&smp_work_queue); k_work_queue_start(&smp_work_queue, smp_work_queue_stack, diff --git a/subsys/mgmt/mcumgr/transport/src/smp_bt.c b/subsys/mgmt/mcumgr/transport/src/smp_bt.c index 6cd2d53d9ffd..87706fd8f47f 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_bt.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_bt.c @@ -109,6 +109,10 @@ BT_CONN_CB_DEFINE(mcumgr_bt_callbacks) = { .disconnected = disconnected, }; +#ifdef CONFIG_SMP_CLIENT +static struct smp_client_transport_entry smp_client_transport; +#endif + /* Helper function that allocates conn_param_data for a conn. */ static struct conn_param_data *conn_param_data_alloc(struct bt_conn *conn) { @@ -665,6 +669,14 @@ static void smp_bt_setup(void) rc = smp_bt_register(); } +#ifdef CONFIG_SMP_CLIENT + if (rc == 0) { + smp_client_transport.smpt = &smp_bt_transport; + smp_client_transport.smpt_type = SMP_BLUETOOTH_TRANSPORT; + rc = smp_client_transport_register(&smp_client_transport); + } +#endif + if (rc != 0) { LOG_ERR("Bluetooth SMP transport register failed (err %d)", rc); } diff --git a/subsys/mgmt/mcumgr/transport/src/smp_shell.c b/subsys/mgmt/mcumgr/transport/src/smp_shell.c index ac196c100854..c30874070bac 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_shell.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_shell.c @@ -39,6 +39,10 @@ static struct smp_transport smp_shell_transport; static struct mcumgr_serial_rx_ctxt smp_shell_rx_ctxt; +#ifdef CONFIG_SMP_CLIENT +static struct smp_client_transport_entry smp_client_transport; +#endif + /** SMP mcumgr frame fragments. */ enum smp_shell_esc_mcumgr { ESC_MCUMGR_PKT_1, @@ -241,6 +245,13 @@ int smp_shell_init(void) smp_shell_transport.functions.get_mtu = smp_shell_get_mtu; rc = smp_transport_init(&smp_shell_transport); +#ifdef CONFIG_SMP_CLIENT + if (rc == 0) { + smp_client_transport.smpt = &CONFIG_SMP_CLIENT; + smp_client_transport.smpt_type = SMP_SHELL_TRANSPORT; + smp_client_transport_register(&smp_client_transport); + } +#endif return rc; } diff --git a/subsys/mgmt/mcumgr/transport/src/smp_uart.c b/subsys/mgmt/mcumgr/transport/src/smp_uart.c index 9c3dade2f8e3..643caf6eb48a 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_uart.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_uart.c @@ -31,6 +31,9 @@ K_WORK_DEFINE(smp_uart_work, smp_uart_process_rx_queue); static struct mcumgr_serial_rx_ctxt smp_uart_rx_ctxt; static struct smp_transport smp_uart_transport; +#ifdef CONFIG_SMP_CLIENT +static struct smp_client_transport_entry smp_client_transport; +#endif /** * Processes a single line (fragment) coming from the mcumgr UART driver. @@ -101,6 +104,11 @@ static int smp_uart_init(void) if (rc == 0) { uart_mcumgr_register(smp_uart_rx_frag); +#ifdef CONFIG_SMP_CLIENT + smp_client_transport.smpt = &smp_uart_transport; + smp_client_transport.smpt_type = SMP_SERIAL_TRANSPORT; + smp_client_transport_register(&smp_client_transport); +#endif } return rc; diff --git a/subsys/mgmt/mcumgr/transport/src/smp_udp.c b/subsys/mgmt/mcumgr/transport/src/smp_udp.c index e772cf499de7..6f8f9a137353 100644 --- a/subsys/mgmt/mcumgr/transport/src/smp_udp.c +++ b/subsys/mgmt/mcumgr/transport/src/smp_udp.c @@ -66,9 +66,15 @@ struct config { struct configs { #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV4 struct config ipv4; +#ifdef CONFIG_SMP_CLIENT + struct smp_client_transport_entry ipv4_transport; +#endif #endif #ifdef CONFIG_MCUMGR_TRANSPORT_UDP_IPV6 struct config ipv6; +#ifdef CONFIG_SMP_CLIENT + struct smp_client_transport_entry ipv6_transport; +#endif #endif }; @@ -381,7 +387,13 @@ static void smp_udp_start(void) configs.ipv4.smp_transport.functions.ud_copy = smp_udp_ud_copy; rc = smp_transport_init(&configs.ipv4.smp_transport); - +#ifdef CONFIG_SMP_CLIENT + if (rc == 0) { + configs.ipv4_transport.smpt = &configs.ipv4.smp_transport; + configs.ipv4_transport.smpt_type = SMP_UDP_IPV4_TRANSPORT; + smp_client_transport_register(&configs.ipv4_transport); + } +#endif if (rc) { LOG_ERR("Failed to register IPv4 UDP MCUmgr SMP transport: %d", rc); } @@ -394,6 +406,13 @@ static void smp_udp_start(void) configs.ipv6.smp_transport.functions.ud_copy = smp_udp_ud_copy; rc = smp_transport_init(&configs.ipv6.smp_transport); +#ifdef CONFIG_SMP_CLIENT + if (rc == 0) { + configs.ipv6_transport.smpt = &configs.ipv6.smp_transport; + configs.ipv6_transport.smpt_type = SMP_UDP_IPV6_TRANSPORT; + smp_client_transport_register(&configs.ipv6_transport); + } +#endif if (rc) { LOG_ERR("Failed to register IPv6 UDP MCUmgr SMP transport: %d", rc); From c657c74ad15a6871ab4dafddd9488143b83513e2 Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Tue, 30 May 2023 12:06:03 +0300 Subject: [PATCH 427/528] [nrf fromtree] mgmt: smp: MCUmgr Client support MCUmgr client basic implementation for support Image and OS grpup commands. Image Group: * Image state read/write * Image Upload secondary slot * Image Erase secondary slot OS group: * Reset * Echo service, disabled by default Opeartion's are blocked call and cant't call inside worker queue. IMG and OS need to be SMP client object for transport. Signed-off-by: Juha Heiskanen (cherry picked from commit d77a657526bff5a0e75ae2f535a3400ab5fdccec) --- .../mcumgr/grp/img_mgmt/img_mgmt_client.h | 193 ++++++ .../mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h | 61 ++ subsys/mgmt/mcumgr/grp/CMakeLists.txt | 14 +- subsys/mgmt/mcumgr/grp/Kconfig | 4 + .../mcumgr/grp/img_mgmt_client/CMakeLists.txt | 15 + .../mgmt/mcumgr/grp/img_mgmt_client/Kconfig | 39 ++ .../grp/img_mgmt_client/src/img_mgmt_client.c | 606 ++++++++++++++++++ .../mcumgr/grp/os_mgmt_client/CMakeLists.txt | 11 + subsys/mgmt/mcumgr/grp/os_mgmt_client/Kconfig | 35 + .../grp/os_mgmt_client/src/os_mgmt_client.c | 168 +++++ 10 files changed, 1140 insertions(+), 6 deletions(-) create mode 100644 include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h create mode 100644 include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h create mode 100644 subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt create mode 100644 subsys/mgmt/mcumgr/grp/img_mgmt_client/Kconfig create mode 100644 subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c create mode 100644 subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt create mode 100644 subsys/mgmt/mcumgr/grp/os_mgmt_client/Kconfig create mode 100644 subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c diff --git a/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h new file mode 100644 index 000000000000..6ee12fb5a612 --- /dev/null +++ b/include/zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_client.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_IMG_MGMT_CLIENT_ +#define H_IMG_MGMT_CLIENT_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Image list flags. + */ +struct mcumgr_image_list_flags { + /** Bootable image */ + bool bootable: 1; + /** Pending update state */ + bool pending: 1; + /** Confirmed image */ + bool confirmed: 1; + /** Active image */ + bool active: 1; + /** Permanent image state */ + bool permanent: 1; +}; + +/** + * @brief Image list data. + */ +struct mcumgr_image_data { + /** Image slot num */ + uint32_t slot_num; + /** Image number */ + uint32_t img_num; + /** Image SHA256 checksum */ + char hash[IMG_MGMT_HASH_LEN]; + /** Image Version */ + char version[IMG_MGMT_VER_MAX_STR_LEN + 1]; + /** Image Flags */ + struct mcumgr_image_list_flags flags; +}; + +/** + * @brief MCUmgr Image list response. + */ +struct mcumgr_image_state { + /** Status */ + enum mcumgr_err_t status; + /** Length of image_list */ + int image_list_length; + /** Image list pointer */ + struct mcumgr_image_data *image_list; +}; + +/** + * @brief MCUmgr Image upload response. + */ +struct mcumgr_image_upload { + /** Status */ + enum mcumgr_err_t status; + /** Reported image offset */ + size_t image_upload_offset; +}; + +/** + * @brief IMG mgmt client upload structure + * + * Structure is used internally by the client + */ +struct img_gr_upload { + /** Image 256-bit hash */ + char sha256[IMG_MGMT_HASH_LEN]; + /** True when Hash is configured, false when not */ + bool hash_initialized; + /** Image size */ + size_t image_size; + /** Image upload offset state */ + size_t offset; + /** Worst case init upload message size */ + size_t upload_header_size; + /** Image slot num */ + uint32_t image_num; +}; + +/** + * @brief IMG mgmt client object. + */ +struct img_mgmt_client { + /** SMP client object */ + struct smp_client_object *smp_client; + /** Image Upload state data for client internal use */ + struct img_gr_upload upload; + /** Client image list buffer size */ + int image_list_length; + /** Image list buffer */ + struct mcumgr_image_data *image_list; + /** Command status */ + int status; +}; + +/** + * @brief Inilialize image group client. + * + * Function initializes image group client for given SMP client using supplied image data. + * + * @param client IMG mgmt client object + * @param smp_client SMP client object + * @param image_list_size Length of image_list buffer. + * @param image_list Image list buffer pointer. + * + */ +void img_mgmt_client_init(struct img_mgmt_client *client, struct smp_client_object *smp_client, + int image_list_size, struct mcumgr_image_data *image_list); + +/** + * @brief Initialize image upload. + * + * @param client IMG mgmt client object + * @param image_size Size of image in bytes. + * @param image_num Image slot Num. + * @param image_hash Pointer to HASH for image must be SHA256 hash of entire upload + * if present (32 bytes). Use NULL when HASH from image is not available. + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int img_mgmt_client_upload_init(struct img_mgmt_client *client, size_t image_size, + uint32_t image_num, const char *image_hash); + +/** + * @brief Upload part of image. + * + * @param client IMG mgmt client object + * @param data Pointer to data. + * @param length Length of data + * @param res_buf Pointer for command response structure. + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int img_mgmt_client_upload(struct img_mgmt_client *client, const uint8_t *data, size_t length, + struct mcumgr_image_upload *res_buf); + +/** + * @brief Write image state. + * + * @param client IMG mgmt client object + * @param hash Pointer to Hash (Needed for test). + * @param confirm Set false for test and true for confirmation. + * @param res_buf Pointer for command response structure. + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ + +int img_mgmt_client_state_write(struct img_mgmt_client *client, char *hash, bool confirm, + struct mcumgr_image_state *res_buf); + +/** + * @brief Read image state. + * + * @param client IMG mgmt client object + * @param res_buf Pointer for command response structure. + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int img_mgmt_client_state_read(struct img_mgmt_client *client, struct mcumgr_image_state *res_buf); + +/** + * @brief Erase selected Image Slot + * + * @param client IMG mgmt client object + * @param slot Slot number + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ + +int img_mgmt_client_erase(struct img_mgmt_client *client, uint32_t slot); + +#ifdef __cplusplus +} +#endif + +#endif /* H_IMG_MGMT_CLIENT_ */ diff --git a/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h new file mode 100644 index 000000000000..12e8abde246c --- /dev/null +++ b/include/zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_client.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_OS_MGMT_CLIENT_ +#define H_OS_MGMT_CLIENT_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief OS mgmt client object + */ +struct os_mgmt_client { + /** SMP client object */ + struct smp_client_object *smp_client; + /** Command status */ + int status; +}; + +/** + * @brief Initialize OS management client. + * + * @param client OS mgmt client object + * @param smp_client SMP client object + * + */ +void os_mgmt_client_init(struct os_mgmt_client *client, struct smp_client_object *smp_client); + +/** + * @brief Send SMP message for Echo command. + * + * @param client OS mgmt client object + * @param echo_string Echo string + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string); + +/** + * @brief Send SMP Reset command. + * + * @param client OS mgmt client object + * + * @return 0 on success. + * @return @ref mcumgr_err_t code on failure. + */ +int os_mgmt_client_reset(struct os_mgmt_client *client); + +#ifdef __cplusplus +} +#endif + +#endif /* H_OS_MGMT_CLIENT_ */ diff --git a/subsys/mgmt/mcumgr/grp/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/CMakeLists.txt index 56df0fb51766..b77fcddf25e0 100644 --- a/subsys/mgmt/mcumgr/grp/CMakeLists.txt +++ b/subsys/mgmt/mcumgr/grp/CMakeLists.txt @@ -5,9 +5,11 @@ # SPDX-License-Identifier: Apache-2.0 # -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_FS fs_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_IMG img_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_OS os_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_STAT stat_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_SHELL shell_mgmt) -add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_ZBASIC zephyr_basic) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_FS fs_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_IMG img_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_IMG_CLIENT img_mgmt_client) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_OS os_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_OS_CLIENT os_mgmt_client) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_STAT stat_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_SHELL shell_mgmt) +add_subdirectory_ifdef(CONFIG_MCUMGR_GRP_ZBASIC zephyr_basic) diff --git a/subsys/mgmt/mcumgr/grp/Kconfig b/subsys/mgmt/mcumgr/grp/Kconfig index b0a018ca4d3e..6005d57a8504 100644 --- a/subsys/mgmt/mcumgr/grp/Kconfig +++ b/subsys/mgmt/mcumgr/grp/Kconfig @@ -6,8 +6,12 @@ rsource "fs_mgmt/Kconfig" rsource "img_mgmt/Kconfig" +rsource "img_mgmt_client/Kconfig" + rsource "os_mgmt/Kconfig" +rsource "os_mgmt_client/Kconfig" + rsource "shell_mgmt/Kconfig" rsource "stat_mgmt/Kconfig" diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt new file mode 100644 index 000000000000..693891896d8e --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Image management client group public API is exported by MCUmgr interface API, +# when Image Management client is enabled. + +zephyr_library(mcumgr_grp_img_client) +zephyr_library_sources( + src/img_mgmt_client.c +) + +zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/Kconfig b/subsys/mgmt/mcumgr/grp/img_mgmt_client/Kconfig new file mode 100644 index 000000000000..dbdb4c4eb603 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/Kconfig @@ -0,0 +1,39 @@ +# Copyright Nordic Semiconductor ASA 2023. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# The Kconfig file is dedicated to Application Image management group of +# of MCUmgr client subsystem and provides Kconfig options to configure +# group commands behaviour and other aspects. +# +# Options defined in this file should be prefixed: +# MCUMGR_GRP_IMG_CLIENT_ -- general group options; +# +# When adding Kconfig options, that control the same feature, +# try to group them together by the same stem after prefix. + +menuconfig MCUMGR_GRP_IMG_CLIENT + bool "MCUmgr client handlers for image management" + depends on SMP_CLIENT + select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_3 + help + Enables MCUmgr client handlers for image management. + +if MCUMGR_GRP_IMG_CLIENT + +config MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE + int "MCUmgr upload data alignment size" + default 4 + help + Change default value when platform needs different data alignment. + +config MCUMGR_GRP_IMG_FLASH_OPERATION_TIMEOUT + int "MCUmgr reset or upload command timeout" + default 15 + help + Change default value when platform needs a different time. + +module = MCUMGR_GRP_IMG_CLIENT +module-str = mcumgr_grp_img_client +source "subsys/logging/Kconfig.template.log_config" + +endif diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c new file mode 100644 index 000000000000..2bb9743160db --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c @@ -0,0 +1,606 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +LOG_MODULE_REGISTER(mcumgr_grp_img_client, CONFIG_MCUMGR_GRP_IMG_CLIENT_LOG_LEVEL); + +#define MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE 128 + +/* Pointer for active Client */ +static struct img_mgmt_client *active_client; +/* Image State read or set response pointer */ +static struct mcumgr_image_state *image_info; +/* Image upload response pointer */ +static struct mcumgr_image_upload *image_upload_buf; + +static K_SEM_DEFINE(mcumgr_img_client_grp_sem, 0, 1); +static K_MUTEX_DEFINE(mcumgr_img_client_grp_mutex); + +static const char smp_images_str[] = "images"; +#define IMAGES_STR_LEN (sizeof(smp_images_str) - 1) + +static int image_state_res_fn(struct net_buf *nb, void *user_data) +{ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + struct zcbor_string value = {0}; + int buf_len, rc; + uint32_t img_num, slot_num; + struct zcbor_string hash, version; + bool bootable, pending, confirmed, active, permanent, ok; + size_t decoded; + struct zcbor_map_decode_key_val list_res_decode[] = { + /* Mandatory */ + ZCBOR_MAP_DECODE_KEY_DECODER("version", zcbor_tstr_decode, &version), + ZCBOR_MAP_DECODE_KEY_DECODER("hash", zcbor_bstr_decode, &hash), + ZCBOR_MAP_DECODE_KEY_DECODER("slot", zcbor_uint32_decode, &slot_num), + /* Optional */ + ZCBOR_MAP_DECODE_KEY_DECODER("image", zcbor_uint32_decode, &img_num), + ZCBOR_MAP_DECODE_KEY_DECODER("bootable", zcbor_bool_decode, &bootable), + ZCBOR_MAP_DECODE_KEY_DECODER("pending", zcbor_bool_decode, &pending), + ZCBOR_MAP_DECODE_KEY_DECODER("confirmed", zcbor_bool_decode, &confirmed), + ZCBOR_MAP_DECODE_KEY_DECODER("active", zcbor_bool_decode, &active), + ZCBOR_MAP_DECODE_KEY_DECODER("permanent", zcbor_bool_decode, &permanent) + }; + + buf_len = active_client->image_list_length; + + if (!nb) { + image_info->status = MGMT_ERR_ETIMEOUT; + goto out; + } + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + + ok = zcbor_map_start_decode(zsd); + if (!ok) { + image_info->status = MGMT_ERR_ECORRUPT; + goto out; + } + + ok = zcbor_tstr_decode(zsd, &value); + if (!ok) { + image_info->status = MGMT_ERR_ECORRUPT; + goto out; + } + if (value.len != IMAGES_STR_LEN || memcmp(value.value, smp_images_str, IMAGES_STR_LEN)) { + image_info->status = MGMT_ERR_EINVAL; + goto out; + } + + ok = zcbor_list_start_decode(zsd); + if (!ok) { + image_info->status = MGMT_ERR_ECORRUPT; + goto out; + } + + rc = 0; + /* Parse Image map info to configured buffer */ + while (rc == 0) { + decoded = 0; + zcbor_map_decode_bulk_reset(list_res_decode, ARRAY_SIZE(list_res_decode)); + /* Init buffer values */ + active = false; + bootable = false; + confirmed = false; + pending = false; + permanent = false; + img_num = 0; + slot_num = UINT32_MAX; + hash.len = 0; + version.len = 0; + + rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), + &decoded); + if (rc) { + if (image_info->image_list_length) { + /* No more map */ + break; + } + LOG_ERR("Corrupted Image data %d", rc); + image_info->status = MGMT_ERR_EINVAL; + goto out; + } + /* Check that mandatory parameters have decoded */ + if (hash.len != IMG_MGMT_HASH_LEN || !version.len || + !zcbor_map_decode_bulk_key_found(list_res_decode, ARRAY_SIZE(list_res_decode), + "slot")) { + LOG_ERR("Missing mandatory parametrs"); + image_info->status = MGMT_ERR_EINVAL; + goto out; + } + /* Store parsed values */ + if (buf_len) { + image_info->image_list[image_info->image_list_length].img_num = img_num; + image_info->image_list[image_info->image_list_length].slot_num = slot_num; + memcpy(image_info->image_list[image_info->image_list_length].hash, + hash.value, IMG_MGMT_HASH_LEN); + if (version.len > IMG_MGMT_VER_MAX_STR_LEN) { + LOG_WRN("Version truncated len %d -> %d", version.len, + IMG_MGMT_VER_MAX_STR_LEN); + version.len = IMG_MGMT_VER_MAX_STR_LEN; + } + memcpy(image_info->image_list[image_info->image_list_length].version, + version.value, version.len); + image_info->image_list[image_info->image_list_length].version[version.len] = + '\0'; + /* Set Image flags */ + image_info->image_list[image_info->image_list_length].flags.bootable = + bootable; + image_info->image_list[image_info->image_list_length].flags.pending = + pending; + image_info->image_list[image_info->image_list_length].flags.confirmed = + confirmed; + image_info->image_list[image_info->image_list_length].flags.active = active; + image_info->image_list[image_info->image_list_length].flags.permanent = + permanent; + /* Update valid image count */ + image_info->image_list_length++; + buf_len--; + } else { + LOG_INF("User configured image list buffer size %d can't store all info", + active_client->image_list_length); + } + } + + ok = zcbor_list_end_decode(zsd); + if (!ok) { + image_info->status = MGMT_ERR_ECORRUPT; + } else { + + image_info->status = MGMT_ERR_EOK; + } + +out: + if (image_info->status != MGMT_ERR_EOK) { + image_info->image_list_length = 0; + } + rc = image_info->status; + k_sem_give(user_data); + return rc; +} + +static int image_upload_res_fn(struct net_buf *nb, void *user_data) +{ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + size_t decoded; + int rc; + int32_t res_rc = MGMT_ERR_EOK; + + struct zcbor_map_decode_key_val upload_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("off", zcbor_size_decode, + &image_upload_buf->image_upload_offset), + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &res_rc)}; + + if (!nb) { + image_upload_buf->status = MGMT_ERR_ETIMEOUT; + goto end; + } + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + + rc = zcbor_map_decode_bulk(zsd, upload_res_decode, ARRAY_SIZE(upload_res_decode), &decoded); + if (rc || image_upload_buf->image_upload_offset == SIZE_MAX) { + image_upload_buf->status = MGMT_ERR_EINVAL; + goto end; + } + image_upload_buf->status = res_rc; + + active_client->upload.offset = image_upload_buf->image_upload_offset; +end: + /* Set status for Upload request handler */ + rc = image_upload_buf->status; + k_sem_give(user_data); + return rc; +} + +static int erase_res_fn(struct net_buf *nb, void *user_data) +{ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + size_t decoded; + int rc, status = MGMT_ERR_EOK; + + struct zcbor_map_decode_key_val upload_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("rc", zcbor_int32_decode, &status) + }; + + if (!nb) { + active_client->status = MGMT_ERR_ETIMEOUT; + goto end; + } + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + + rc = zcbor_map_decode_bulk(zsd, upload_res_decode, ARRAY_SIZE(upload_res_decode), &decoded); + if (rc) { + LOG_ERR("Erase fail %d", rc); + active_client->status = MGMT_ERR_EINVAL; + goto end; + } + active_client->status = status; +end: + rc = active_client->status; + k_sem_give(user_data); + return rc; +} + +static size_t upload_message_header_size(struct img_gr_upload *upload_state) +{ + bool ok; + size_t cbor_length; + int map_count; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + uint8_t temp_buf[MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE]; + uint8_t temp_data; + + /* Calculation of message header with data length of 1 */ + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), temp_buf, MCUMGR_UPLOAD_INIT_HEADER_BUF_SIZE, + 0); + if (upload_state->hash_initialized) { + map_count = 12; + } else { + map_count = 10; + } + + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "image") && + zcbor_uint32_put(zse, upload_state->image_num) && zcbor_tstr_put_lit(zse, "data") && + zcbor_bstr_encode_ptr(zse, &temp_data, 1) && zcbor_tstr_put_lit(zse, "len") && + zcbor_size_put(zse, upload_state->image_size) && zcbor_tstr_put_lit(zse, "off") && + zcbor_size_put(zse, upload_state->offset); + + /* Write hash when it defined and offset is 0 */ + if (ok && upload_state->hash_initialized) { + ok = zcbor_tstr_put_lit(zse, "sha") && + zcbor_bstr_encode_ptr(zse, upload_state->sha256, IMG_MGMT_HASH_LEN); + } + + if (ok) { + ok = zcbor_map_end_encode(zse, map_count); + } + + if (!ok) { + LOG_ERR("Failed to encode Image Upload packet"); + return 0; + } + cbor_length = zse->payload - temp_buf; + /* Return Message header length */ + return cbor_length + (CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE - 1); +} + +void img_mgmt_client_init(struct img_mgmt_client *client, struct smp_client_object *smp_client, + int image_list_size, struct mcumgr_image_data *image_list) +{ + client->smp_client = smp_client; + client->image_list_length = image_list_size; + client->image_list = image_list; +} + +int img_mgmt_client_upload_init(struct img_mgmt_client *client, size_t image_size, + uint32_t image_num, const char *image_hash) +{ + int rc; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + client->upload.image_size = image_size; + client->upload.offset = 0; + client->upload.image_num = image_num; + if (image_hash) { + memcpy(client->upload.sha256, image_hash, IMG_MGMT_HASH_LEN); + client->upload.hash_initialized = true; + } else { + client->upload.hash_initialized = false; + } + + /* Calculate worst case header size for adapt payload length */ + client->upload.upload_header_size = upload_message_header_size(&client->upload); + if (client->upload.upload_header_size) { + rc = MGMT_ERR_EOK; + } else { + rc = MGMT_ERR_ENOMEM; + } + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + return rc; +} + +int img_mgmt_client_upload(struct img_mgmt_client *client, const uint8_t *data, size_t length, + struct mcumgr_image_upload *res_buf) +{ + struct net_buf *nb; + const uint8_t *write_ptr; + int rc; + uint32_t map_count; + bool ok; + size_t write_length, max_data_length, offset_before_send, request_length, wrote_length; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + active_client = client; + image_upload_buf = res_buf; + + request_length = length; + wrote_length = 0; + /* Calculate max data length based on net_buf size - (SMP header + CBOR message_len) */ + max_data_length = CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE - + (active_client->upload.upload_header_size + MGMT_HDR_SIZE); + /* Trim length based on CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE */ + if (max_data_length % CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE) { + max_data_length -= + (max_data_length % CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE); + } + + while (request_length != wrote_length) { + write_ptr = data + wrote_length; + write_length = request_length - wrote_length; + if (write_length > max_data_length) { + write_length = max_data_length; + } + + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE, + IMG_MGMT_ID_UPLOAD, MGMT_OP_WRITE, + SMP_MCUMGR_VERSION_1); + if (!nb) { + image_upload_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, + net_buf_tailroom(nb), 0); + if (active_client->upload.offset) { + map_count = 6; + } else if (active_client->upload.hash_initialized) { + map_count = 12; + } else { + map_count = 10; + } + + /* Init map start and write image info, data and offset */ + ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "image") && + zcbor_uint32_put(zse, active_client->upload.image_num) && + zcbor_tstr_put_lit(zse, "data") && + zcbor_bstr_encode_ptr(zse, write_ptr, write_length) && + zcbor_tstr_put_lit(zse, "off") && + zcbor_size_put(zse, active_client->upload.offset); + /* Write Len and configured hash when offset is zero */ + if (ok && !active_client->upload.offset) { + ok = zcbor_tstr_put_lit(zse, "len") && + zcbor_size_put(zse, active_client->upload.image_size); + if (ok && active_client->upload.hash_initialized) { + ok = zcbor_tstr_put_lit(zse, "sha") && + zcbor_bstr_encode_ptr(zse, active_client->upload.sha256, + IMG_MGMT_HASH_LEN); + } + } + + if (ok) { + ok = zcbor_map_end_encode(zse, map_count); + } + + if (!ok) { + LOG_ERR("Failed to encode Image Upload packet"); + smp_packet_free(nb); + image_upload_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + offset_before_send = active_client->upload.offset; + nb->len = zse->payload - nb->data; + k_sem_reset(&mcumgr_img_client_grp_sem); + + image_upload_buf->status = MGMT_ERR_EINVAL; + image_upload_buf->image_upload_offset = SIZE_MAX; + + rc = smp_client_send_cmd(active_client->smp_client, nb, image_upload_res_fn, + &mcumgr_img_client_grp_sem, + CONFIG_MCUMGR_GRP_IMG_FLASH_OPERATION_TIMEOUT); + if (rc) { + LOG_ERR("Failed to send SMP Upload init packet, err: %d", rc); + smp_packet_free(nb); + image_upload_buf->status = rc; + goto end; + + } + k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER); + if (image_upload_buf->status) { + LOG_ERR("Upload Fail: %d", image_upload_buf->status); + goto end; + } + + if (offset_before_send + write_length < active_client->upload.offset) { + /* Offset further than expected which indicate upload session resume */ + goto end; + } + + wrote_length += write_length; + } +end: + rc = image_upload_buf->status; + active_client = NULL; + image_upload_buf = NULL; + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + + return rc; +} + +int img_mgmt_client_state_write(struct img_mgmt_client *client, char *hash, bool confirm, + struct mcumgr_image_state *res_buf) +{ + struct net_buf *nb; + int rc; + uint32_t map_count; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS]; + bool ok; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + active_client = client; + image_info = res_buf; + /* Init Response */ + res_buf->image_list_length = 0; + res_buf->image_list = active_client->image_list; + + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE, + IMG_MGMT_ID_STATE, MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (!nb) { + res_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); + if (hash) { + map_count = 4; + } else { + map_count = 2; + } + + /* Write map start init and confirm params */ + ok = zcbor_map_start_encode(zse, map_count) && zcbor_tstr_put_lit(zse, "confirm") && + zcbor_bool_put(zse, confirm); + /* Write hash data */ + if (ok && hash) { + ok = zcbor_tstr_put_lit(zse, "hash") && + zcbor_bstr_encode_ptr(zse, hash, IMG_MGMT_HASH_LEN); + } + /* Close map */ + if (ok) { + ok = zcbor_map_end_encode(zse, map_count); + } + + if (!ok) { + smp_packet_free(nb); + res_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + nb->len = zse->payload - nb->data; + k_sem_reset(&mcumgr_img_client_grp_sem); + rc = smp_client_send_cmd(active_client->smp_client, nb, image_state_res_fn, + &mcumgr_img_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME); + if (rc) { + res_buf->status = rc; + smp_packet_free(nb); + goto end; + } + k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER); +end: + rc = res_buf->status; + active_client = NULL; + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + return rc; +} + +int img_mgmt_client_state_read(struct img_mgmt_client *client, struct mcumgr_image_state *res_buf) +{ + struct net_buf *nb; + int rc; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS]; + bool ok; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + active_client = client; + /* Init Response */ + res_buf->image_list_length = 0; + res_buf->image_list = active_client->image_list; + + image_info = res_buf; + + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE, + IMG_MGMT_ID_STATE, MGMT_OP_READ, SMP_MCUMGR_VERSION_1); + if (!nb) { + res_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); + ok = zcbor_map_start_encode(zse, 1) && zcbor_map_end_encode(zse, 1); + if (!ok) { + smp_packet_free(nb); + res_buf->status = MGMT_ERR_ENOMEM; + goto end; + } + + nb->len = zse->payload - nb->data; + k_sem_reset(&mcumgr_img_client_grp_sem); + rc = smp_client_send_cmd(active_client->smp_client, nb, image_state_res_fn, + &mcumgr_img_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME); + if (rc) { + smp_packet_free(nb); + res_buf->status = rc; + goto end; + } + k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER); +end: + rc = res_buf->status; + image_info = NULL; + active_client = NULL; + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + return rc; +} + +int img_mgmt_client_erase(struct img_mgmt_client *client, uint32_t slot) +{ + struct net_buf *nb; + int rc; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS]; + bool ok; + + k_mutex_lock(&mcumgr_img_client_grp_mutex, K_FOREVER); + active_client = client; + + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_IMAGE, + IMG_MGMT_ID_ERASE, MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (!nb) { + active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); + + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "slot") && + zcbor_uint32_put(zse, slot) && zcbor_map_end_encode(zse, 2); + if (!ok) { + smp_packet_free(nb); + active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + + nb->len = zse->payload - nb->data; + k_sem_reset(&mcumgr_img_client_grp_sem); + rc = smp_client_send_cmd(client->smp_client, nb, erase_res_fn, &mcumgr_img_client_grp_sem, + CONFIG_MCUMGR_GRP_IMG_FLASH_OPERATION_TIMEOUT); + if (rc) { + smp_packet_free(nb); + active_client->status = rc; + goto end; + } + k_sem_take(&mcumgr_img_client_grp_sem, K_FOREVER); +end: + rc = active_client->status; + active_client = NULL; + k_mutex_unlock(&mcumgr_img_client_grp_mutex); + return rc; +} diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt b/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt new file mode 100644 index 000000000000..b033b363fa67 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt_client/CMakeLists.txt @@ -0,0 +1,11 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +# OS Management client group public API is exposed through zephyr_interface, +# when OS Management is enabled. +zephyr_library(mgmt_mcumgr_grp_os_client) +zephyr_library_sources(src/os_mgmt_client.c) +zephyr_library_include_directories(include) diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt_client/Kconfig b/subsys/mgmt/mcumgr/grp/os_mgmt_client/Kconfig new file mode 100644 index 000000000000..46c95a3cf871 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt_client/Kconfig @@ -0,0 +1,35 @@ +# Copyright Nordic Semiconductor ASA 2023. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# The Kconfig file is dedicated to OS management group of +# of MCUmgr client subsystem and provides Kconfig options to configure +# group commands behaviour and other aspects. +# +# Options defined in this file should be prefixed: +# MCUMGR_GRP_OS_CLIENT_ -- general group options; +# +# When adding Kconfig options, that control the same feature, +# try to group them together by the same stem after prefix. + +menuconfig MCUMGR_GRP_OS_CLIENT + bool "MCUmgr client request and response handlers for OS management" + depends on SMP_CLIENT + select MCUMGR_SMP_CBOR_MIN_DECODING_LEVEL_3 + help + Enables MCUmgr client request and response handlers for OS management. + +if MCUMGR_GRP_OS_CLIENT + +config MCUMGR_GRP_OS_CLIENT_ECHO + default y + bool "Support for echo command request" + +config MCUMGR_GRP_OS_CLIENT_RESET + default y + bool "support for reset command request" + +module = MCUMGR_GRP_OS_CLIENT +module-str = mcumgr_grp_os_client +source "subsys/logging/Kconfig.template.log_config" + +endif diff --git a/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c b/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c new file mode 100644 index 000000000000..2bd804494c41 --- /dev/null +++ b/subsys/mgmt/mcumgr/grp/os_mgmt_client/src/os_mgmt_client.c @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +LOG_MODULE_REGISTER(mcumgr_grp_os_client, CONFIG_MCUMGR_GRP_OS_CLIENT_LOG_LEVEL); + +static struct os_mgmt_client *active_client; +static K_SEM_DEFINE(mcummgr_os_client_grp_sem, 0, 1); +static K_MUTEX_DEFINE(mcummgr_os_client_grp_mutex); + +void os_mgmt_client_init(struct os_mgmt_client *client, struct smp_client_object *smp_client) +{ + client->smp_client = smp_client; +} + +#ifdef CONFIG_MCUMGR_GRP_OS_CLIENT_RESET + +static int reset_res_fn(struct net_buf *nb, void *user_data) +{ + if (!nb) { + active_client->status = MGMT_ERR_ETIMEOUT; + } else { + active_client->status = MGMT_ERR_EOK; + } + k_sem_give(user_data); + return 0; +} + +int os_mgmt_client_reset(struct os_mgmt_client *client) +{ + struct net_buf *nb; + int rc; + + k_mutex_lock(&mcummgr_os_client_grp_mutex, K_FOREVER); + active_client = client; + /* allocate buffer */ + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_OS, + OS_MGMT_ID_RESET, MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (!nb) { + active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + k_sem_reset(&mcummgr_os_client_grp_sem); + rc = smp_client_send_cmd(active_client->smp_client, nb, reset_res_fn, + &mcummgr_os_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME); + if (rc) { + active_client->status = rc; + smp_packet_free(nb); + goto end; + } + /* Wait for process end update event */ + k_sem_take(&mcummgr_os_client_grp_sem, K_FOREVER); +end: + rc = active_client->status; + active_client = NULL; + k_mutex_unlock(&mcummgr_os_client_grp_mutex); + return rc; +} + +#endif /* CONFIG_MCUMGR_GRP_OS_CLIENT_RESET */ + +#ifdef CONFIG_MCUMGR_GRP_OS_CLIENT_ECHO + +static int echo_res_fn(struct net_buf *nb, void *user_data) +{ + struct zcbor_string val = {0}; + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + size_t decoded; + bool ok; + int rc; + struct zcbor_map_decode_key_val echo_response[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("r", zcbor_tstr_decode, &val) + }; + + if (!nb) { + LOG_ERR("Echo command timeout"); + active_client->status = MGMT_ERR_ETIMEOUT; + goto end; + } + + /* Init ZCOR decoder state */ + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data, nb->len, 1); + + ok = zcbor_map_decode_bulk(zsd, echo_response, ARRAY_SIZE(echo_response), &decoded) == 0; + + if (!ok) { + active_client->status = MGMT_ERR_ECORRUPT; + goto end; + } + active_client->status = MGMT_ERR_EOK; +end: + rc = active_client->status; + k_sem_give(user_data); + return rc; +} + +int os_mgmt_client_echo(struct os_mgmt_client *client, const char *echo_string) +{ + struct net_buf *nb; + int rc; + bool ok; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS]; + + k_mutex_lock(&mcummgr_os_client_grp_mutex, K_FOREVER); + active_client = client; + nb = smp_client_buf_allocation(active_client->smp_client, MGMT_GROUP_ID_OS, OS_MGMT_ID_ECHO, + MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (!nb) { + rc = active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data + nb->len, net_buf_tailroom(nb), 0); + + ok = zcbor_map_start_encode(zse, 2) && + zcbor_tstr_put_lit(zse, "d") && zcbor_tstr_put_term(zse, echo_string) && + zcbor_map_end_encode(zse, 2); + + if (!ok) { + smp_packet_free(nb); + rc = active_client->status = MGMT_ERR_ENOMEM; + goto end; + } + + nb->len = zse->payload - nb->data; + + LOG_DBG("Echo Command packet len %d", nb->len); + k_sem_reset(&mcummgr_os_client_grp_sem); + rc = smp_client_send_cmd(active_client->smp_client, nb, echo_res_fn, + &mcummgr_os_client_grp_sem, CONFIG_SMP_CMD_DEFAULT_LIFE_TIME); + if (rc) { + smp_packet_free(nb); + } else { + k_sem_take(&mcummgr_os_client_grp_sem, K_FOREVER); + /* Take response status */ + rc = active_client->status; + } +end: + active_client = NULL; + k_mutex_unlock(&mcummgr_os_client_grp_mutex); + return rc; +} +#endif From 6041f17ccc0ff4454817c6275fbdadce0841269d Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Mon, 22 May 2023 14:37:54 +0300 Subject: [PATCH 428/528] [nrf fromtree] tests: mcumgr: MCUmgr and smp client unit test Added unit test for testing IMG and OS group component's. Added Unit test for SMP Client. Signed-off-by: Juha Heiskanen (cherry picked from commit 9a06ce19ad7aa92582a2ab13e08aab88e88cb93d) --- .../mgmt/mcumgr/mcumgr_client/CMakeLists.txt | 17 + .../subsys/mgmt/mcumgr/mcumgr_client/prj.conf | 25 ++ .../mcumgr/mcumgr_client/src/img_gr_stub.c | 298 ++++++++++++++++++ .../mcumgr/mcumgr_client/src/img_gr_stub.h | 34 ++ .../mgmt/mcumgr/mcumgr_client/src/main.c | 256 +++++++++++++++ .../mcumgr/mcumgr_client/src/os_gr_stub.c | 98 ++++++ .../mcumgr/mcumgr_client/src/os_gr_stub.h | 24 ++ .../mgmt/mcumgr/mcumgr_client/src/smp_stub.c | 124 ++++++++ .../mgmt/mcumgr/mcumgr_client/src/smp_stub.h | 30 ++ .../mgmt/mcumgr/smp_client/CMakeLists.txt | 15 + tests/subsys/mgmt/mcumgr/smp_client/prj.conf | 19 ++ .../subsys/mgmt/mcumgr/smp_client/src/main.c | 128 ++++++++ .../smp_client/src/smp_transport_stub.c | 51 +++ .../smp_client/src/smp_transport_stub.h | 24 ++ 14 files changed, 1143 insertions(+) create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.h create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.h create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.c create mode 100644 tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.h create mode 100644 tests/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt create mode 100644 tests/subsys/mgmt/mcumgr/smp_client/prj.conf create mode 100644 tests/subsys/mgmt/mcumgr/smp_client/src/main.c create mode 100644 tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.c create mode 100644 tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.h diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt b/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt new file mode 100644 index 000000000000..a0f765546295 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(mcumgr_client) + +FILE(GLOB app_sources + src/*.c +) + +target_sources(app PRIVATE ${app_sources}) + +add_compile_definitions(CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER=1) diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf new file mode 100644 index 000000000000..46835a49dc78 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/prj.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +# ZTEST config +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST_STACK_SIZE=2048 + +CONFIG_NET_BUF=y +CONFIG_BASE64=y +CONFIG_ZCBOR=y +CONFIG_CRC=y +# Enable mcumgr +CONFIG_MCUMGR=y +CONFIG_SMP_CLIENT=y +CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER=1 +CONFIG_MCUMGR_GRP_OS_CLIENT=y +CONFIG_MCUMGR_GRP_IMG_CLIENT=y +CONFIG_MCUMGR_GRP_OS_CLIENT_ECHO=y +CONFIG_MCUMGR_GRP_OS_CLIENT_RESET=y + +# Extend System Workqueue stack size +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c new file mode 100644 index 000000000000..5bd784a3954b --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.c @@ -0,0 +1,298 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "smp_stub.h" +#include "img_gr_stub.h" + +static struct mcumgr_image_data image_dummy_info[2]; +static size_t test_offset; +static uint8_t *image_hash_ptr; + +#define ZCBOR_ENCODE_FLAG(zse, label, value) \ + (zcbor_tstr_put_lit(zse, label) && zcbor_bool_put(zse, value)) + +void img_upload_stub_init(void) +{ + test_offset = 0; +} + +void img_upload_response(size_t offset, int status) +{ + struct net_buf *nb; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + /* Init map start and write image info and data */ + if (status) { + ok = zcbor_map_start_encode(zse, 4) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, status) && zcbor_tstr_put_lit(zse, "off") && + zcbor_size_put(zse, offset) && zcbor_map_end_encode(zse, 4); + } else { + /* Drop Status away from response */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "off") && + zcbor_size_put(zse, offset) && zcbor_map_end_encode(zse, 4); + } + + + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void img_fail_response(int status) +{ + struct net_buf *nb; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, status) && zcbor_map_end_encode(zse, 2); + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void img_read_response(int count) +{ + struct net_buf *nb; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + ok = zcbor_map_start_encode(zse, 15) && zcbor_tstr_put_lit(zse, "images") && + zcbor_list_start_encode(zse, 2); + + for (int i = 0; ok && i < count; i++) { + + ok = zcbor_map_start_encode(zse, 15) && + ((zcbor_tstr_put_lit(zse, "image") && + zcbor_uint32_put(zse, image_dummy_info[i].img_num))) && + zcbor_tstr_put_lit(zse, "slot") && + zcbor_uint32_put(zse, image_dummy_info[i].slot_num) && + zcbor_tstr_put_lit(zse, "version") && + zcbor_tstr_put_term(zse, image_dummy_info[i].version) && + + zcbor_tstr_put_term(zse, "hash") && + zcbor_bstr_encode_ptr(zse, image_dummy_info[i].hash, IMG_MGMT_HASH_LEN) && + ZCBOR_ENCODE_FLAG(zse, "bootable", image_dummy_info[i].flags.bootable) && + ZCBOR_ENCODE_FLAG(zse, "pending", image_dummy_info[i].flags.pending) && + ZCBOR_ENCODE_FLAG(zse, "confirmed", image_dummy_info[i].flags.confirmed) && + ZCBOR_ENCODE_FLAG(zse, "active", image_dummy_info[i].flags.active) && + ZCBOR_ENCODE_FLAG(zse, "permanent", image_dummy_info[i].flags.permanent) && + zcbor_map_end_encode(zse, 15); + } + + ok = ok && zcbor_list_end_encode(zse, 2 * CONFIG_MCUMGR_GRP_IMG_UPDATABLE_IMAGE_NUMBER); + + ok = ok && zcbor_map_end_encode(zse, 15); + + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void img_erase_response(int status) +{ + struct net_buf *nb; + zcbor_state_t zse[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, status) && zcbor_map_end_encode(zse, 2); + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void img_state_write_verify(struct net_buf *nb) +{ + /* Parse CBOR data: hash and confirm */ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + int rc; + struct zcbor_string hash; + bool confirm; + size_t decoded; + struct zcbor_map_decode_key_val list_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("confirm", zcbor_bool_decode, &confirm), + ZCBOR_MAP_DECODE_KEY_DECODER("hash", zcbor_bstr_decode, &hash) + }; + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + + decoded = 0; + /* Init buffer values */ + confirm = false; + hash.len = 0; + + rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), &decoded); + if (rc) { + printf("Corrupted data %d\r\n", rc); + img_fail_response(MGMT_ERR_EINVAL); + return; + } + if (hash.len) { + printf("HASH %d", hash.len); + if (memcmp(hash.value, image_dummy_info[1].hash, 32) == 0) { + if (confirm) { + /* Set Permanent bit */ + image_dummy_info[1].flags.permanent = true; + } else { + /* Set pending */ + image_dummy_info[1].flags.pending = true; + } + img_read_response(2); + } else { + img_fail_response(MGMT_ERR_EINVAL); + } + } else { + if (confirm) { + image_dummy_info[0].flags.confirmed = true; + } + img_read_response(2); + } +} + +void img_upload_init_verify(struct net_buf *nb) +{ + /* Parse CBOR data: hash and confirm */ + zcbor_state_t zsd[CONFIG_MCUMGR_SMP_CBOR_MAX_DECODING_LEVELS + 2]; + int rc; + uint32_t image; + struct zcbor_string sha, data; + size_t decoded, length, offset; + struct zcbor_map_decode_key_val list_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("image", zcbor_uint32_decode, &image), + ZCBOR_MAP_DECODE_KEY_DECODER("data", zcbor_bstr_decode, &data), + ZCBOR_MAP_DECODE_KEY_DECODER("len", zcbor_size_decode, &length), + ZCBOR_MAP_DECODE_KEY_DECODER("off", zcbor_size_decode, &offset), + ZCBOR_MAP_DECODE_KEY_DECODER("sha", zcbor_bstr_decode, &sha) + }; + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + + decoded = 0; + /* Init buffer values */ + sha.len = 0; + data.len = 0; + length = SIZE_MAX; + offset = SIZE_MAX; + image = UINT32_MAX; + + rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), &decoded); + if (rc || data.len == 0 || offset == SIZE_MAX || image != TEST_IMAGE_NUM) { + printf("Corrupted data %d or %d data len\r\n", rc, data.len); + img_upload_response(0, MGMT_ERR_EINVAL); + return; + } + + if (sha.len) { + if (memcmp(sha.value, image_hash_ptr, 32)) { + printf("Hash not same\r\n"); + img_upload_response(0, MGMT_ERR_EINVAL); + return; + } + } + + if (offset != test_offset) { + printf("Offset not exepected %d vs received %d\r\n", test_offset, offset); + } + + if (offset == 0) { + if (length != TEST_IMAGE_SIZE) { + img_upload_response(0, MGMT_ERR_EINVAL); + } + } + + test_offset += data.len; + printf("Upload offset %d\r\n", test_offset); + if (test_offset <= TEST_IMAGE_SIZE) { + img_upload_response(test_offset, MGMT_ERR_EOK); + } else { + img_upload_response(0, MGMT_ERR_EINVAL); + } +} + +void img_gr_stub_data_init(uint8_t *hash_ptr) +{ + image_hash_ptr = hash_ptr; + for (int i = 0; i < 32; i++) { + image_hash_ptr[i] = i; + image_dummy_info[0].hash[i] = i + 32; + image_dummy_info[1].hash[i] = i + 64; + } + /* Set dummy image list data */ + for (int i = 0; i < 2; i++) { + image_dummy_info[i].img_num = i; + image_dummy_info[i].slot_num = i; + /* Write version */ + snprintf(image_dummy_info[i].version, IMG_MGMT_VER_MAX_STR_LEN, "1.1.%u", i); + image_dummy_info[i].version[sizeof(image_dummy_info[i].version) - 1] = '\0'; + image_dummy_info[i].flags.bootable = true; + image_dummy_info[i].flags.pending = false; + if (i) { + image_dummy_info[i].flags.confirmed = false; + image_dummy_info[i].flags.active = false; + } else { + image_dummy_info[i].flags.confirmed = true; + image_dummy_info[i].flags.active = true; + } + image_dummy_info[i].flags.permanent = false; + } +} diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.h b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.h new file mode 100644 index 000000000000..95fdbc8203b2 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/img_gr_stub.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_IMG_GR_STUB_ +#define H_IMG_GR_STUB_ + +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#define TEST_IMAGE_NUM 1 +#define TEST_IMAGE_SIZE 2048 +#define TEST_SLOT_NUMBER 2 + +void img_upload_stub_init(void); +void img_upload_response(size_t offset, int status); +void img_fail_response(int status); +void img_read_response(int count); +void img_erase_response(int status); +void img_upload_init_verify(struct net_buf *nb); +void img_state_write_verify(struct net_buf *nb); +void img_gr_stub_data_init(uint8_t *hash_ptr); + +#ifdef __cplusplus +} +#endif + +#endif /* H_IMG_GR_STUB_ */ diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c new file mode 100644 index 000000000000..a15e82f17a64 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/main.c @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +/* Include stubbed test helpers */ +#include "smp_stub.h" +#include "img_gr_stub.h" +#include "os_gr_stub.h" + +/* IMG group data */ +static uint8_t image_hash[32]; +static struct mcumgr_image_data image_info[2]; +static uint8_t image_dummy[1024]; + +static const char os_echo_test[] = "TestString"; +static struct smp_client_object smp_client; +static struct img_mgmt_client img_client; +static struct os_mgmt_client os_client; + +ZTEST(mcumgr_client, img_upload) +{ + int rc; + struct mcumgr_image_upload response; + + smp_stub_set_rx_data_verify(NULL); + img_upload_stub_init(); + + img_mgmt_client_init(&img_client, &smp_client, 2, image_info); + + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + /* Start upload and test Timeout */ + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + zassert_equal(MGMT_ERR_ETIMEOUT, response.status, "Expected to receive %d response %d\n", + MGMT_ERR_ETIMEOUT, response.status); + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + /* Start upload and test Timeout */ + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + zassert_equal(MGMT_ERR_ETIMEOUT, response.status, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, response.status); + + smp_client_send_status_stub(MGMT_ERR_EOK); + + /* Allocate response buf */ + img_upload_response(0, MGMT_ERR_EINVAL); + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EINVAL, rc, "Expected to receive %d response %d", MGMT_ERR_EINVAL, + rc); + zassert_equal(MGMT_ERR_EINVAL, response.status, "Expected to receive %d response %d", + MGMT_ERR_EINVAL, response.status); + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, image_hash); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d\n", MGMT_ERR_EOK, rc); + img_upload_response(1024, MGMT_ERR_EOK); + + smp_stub_set_rx_data_verify(img_upload_init_verify); + img_upload_stub_init(); + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d", + MGMT_ERR_EOK, response.status); + zassert_equal(1024, response.image_upload_offset, + "Expected to receive offset %d response %d", 1024, + response.image_upload_offset); + /* Send last frame from image */ + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d", + MGMT_ERR_EOK, response.status); + zassert_equal(TEST_IMAGE_SIZE, response.image_upload_offset, + "Expected to receive offset %d response %d", TEST_IMAGE_SIZE, + response.image_upload_offset); + + /* Test without hash */ + rc = img_mgmt_client_upload_init(&img_client, TEST_IMAGE_SIZE, TEST_IMAGE_NUM, NULL); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + img_upload_stub_init(); + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d", + MGMT_ERR_EOK, response.status); + zassert_equal(1024, response.image_upload_offset, + "Expected to receive offset %d response %d", 1024, + response.image_upload_offset); + /* Send last frame from image */ + rc = img_mgmt_client_upload(&img_client, image_dummy, 1024, &response); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(MGMT_ERR_EOK, response.status, "Expected to receive %d response %d", + MGMT_ERR_EOK, response.status); + zassert_equal(TEST_IMAGE_SIZE, response.image_upload_offset, + "Expected to receive offset %d response %d", TEST_IMAGE_SIZE, + response.image_upload_offset); +} + +ZTEST(mcumgr_client, img_erase) +{ + int rc; + + smp_client_send_status_stub(MGMT_ERR_EOK); + + /* Test timeout */ + rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + + /* Test erase fail */ + img_erase_response(MGMT_ERR_EINVAL); + rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER); + zassert_equal(MGMT_ERR_EINVAL, rc, "Expected to receive %d response %d", MGMT_ERR_EINVAL, + rc); + /* Tesk ok */ + img_erase_response(MGMT_ERR_EOK); + rc = img_mgmt_client_erase(&img_client, TEST_SLOT_NUMBER); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); +} + +ZTEST(mcumgr_client, image_state_read) +{ + int rc; + struct mcumgr_image_state res_buf; + + smp_client_send_status_stub(MGMT_ERR_EOK); + /* Test timeout */ + rc = img_mgmt_client_state_read(&img_client, &res_buf); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + /* Testing read successfully 1 image info and print that */ + img_read_response(1); + rc = img_mgmt_client_state_read(&img_client, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(1, res_buf.image_list_length, "Expected to receive %d response %d", 1, + res_buf.image_list_length); + img_read_response(2); + rc = img_mgmt_client_state_read(&img_client, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2, + res_buf.image_list_length); +} + +ZTEST(mcumgr_client, image_state_set) +{ + int rc; + char hash[32]; + struct mcumgr_image_state res_buf; + + smp_client_response_buf_clean(); + smp_stub_set_rx_data_verify(NULL); + smp_client_send_status_stub(MGMT_ERR_EOK); + /* Test timeout */ + rc = img_mgmt_client_state_write(&img_client, NULL, false, &res_buf); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + + printf("Timeout OK\r\n"); + /* Read secondary image hash for testing */ + img_read_response(2); + rc = img_mgmt_client_state_read(&img_client, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2, + res_buf.image_list_length); + zassert_equal(false, image_info[1].flags.pending, "Expected to receive %d response %d", + false, image_info[1].flags.pending); + /* Copy hash for set pending flag */ + memcpy(hash, image_info[1].hash, 32); + printf("Read OK\r\n"); + + /* Read secondary image hash for testing */ + smp_stub_set_rx_data_verify(img_state_write_verify); + rc = img_mgmt_client_state_write(&img_client, hash, false, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2, + res_buf.image_list_length); + zassert_equal(true, image_info[1].flags.pending, "Expected to receive %d response %d", + true, image_info[1].flags.pending); + /* Test to set confirmed bit */ + image_info[0].flags.confirmed = false; + smp_stub_set_rx_data_verify(img_state_write_verify); + rc = img_mgmt_client_state_write(&img_client, NULL, true, &res_buf); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + zassert_equal(2, res_buf.image_list_length, "Expected to receive %d response %d", 2, + res_buf.image_list_length); + zassert_equal(true, image_info[0].flags.confirmed, "Expected to receive %d response %d", + true, image_info[0].flags.confirmed); +} + +ZTEST(mcumgr_client, os_reset) +{ + int rc; + + smp_client_response_buf_clean(); + smp_stub_set_rx_data_verify(NULL); + + smp_client_send_status_stub(MGMT_ERR_EOK); + /* Test timeout */ + rc = os_mgmt_client_reset(&os_client); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + /* Testing reset successfully handling */ + os_reset_response(); + rc = os_mgmt_client_reset(&os_client); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); +} + +ZTEST(mcumgr_client, os_echo) +{ + int rc; + + smp_client_response_buf_clean(); + smp_stub_set_rx_data_verify(NULL); + smp_client_send_status_stub(MGMT_ERR_EOK); + /* Test timeout */ + rc = os_mgmt_client_echo(&os_client, os_echo_test); + zassert_equal(MGMT_ERR_ETIMEOUT, rc, "Expected to receive %d response %d", + MGMT_ERR_ETIMEOUT, rc); + /* Test successfully operation */ + smp_stub_set_rx_data_verify(os_echo_verify); + rc = os_mgmt_client_echo(&os_client, os_echo_test); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); +} + +static void *setup_custom_os(void) +{ + stub_smp_client_transport_register(); + smp_client_object_init(&smp_client, SMP_SERIAL_TRANSPORT); + os_mgmt_client_init(&os_client, &smp_client); + img_mgmt_client_init(&img_client, &smp_client, 2, image_info); + + img_gr_stub_data_init(image_hash); + os_stub_init(os_echo_test); + return NULL; +} + +static void cleanup_test(void *p) +{ + smp_client_response_buf_clean(); + smp_stub_set_rx_data_verify(NULL); +} + +/* Main test set */ +ZTEST_SUITE(mcumgr_client, NULL, setup_custom_os, NULL, cleanup_test, NULL); diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c new file mode 100644 index 000000000000..888f00dba38d --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "smp_stub.h" + +static const char *echo_ptr; + +void os_stub_init(const char *echo_str) +{ + echo_ptr = echo_str; +} + +void os_reset_response(void) +{ + struct net_buf *nb; + + nb = smp_response_buf_allocation(); + if (nb) { + nb->len = 0; + } +} + +static void os_echo_response(int status, struct zcbor_string *echo_data) +{ + struct net_buf *nb; + zcbor_state_t zse[3 + 2]; + bool ok; + + nb = smp_response_buf_allocation(); + + if (!nb) { + return; + } + + zcbor_new_encode_state(zse, ARRAY_SIZE(zse), nb->data, net_buf_tailroom(nb), 0); + + if (status) { + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "rc") && + zcbor_int32_put(zse, status) && zcbor_map_end_encode(zse, 2); + } else { + /* Init map start and write image info and data */ + ok = zcbor_map_start_encode(zse, 2) && zcbor_tstr_put_lit(zse, "r") && + zcbor_tstr_encode_ptr(zse, echo_data->value, echo_data->len) && + zcbor_map_end_encode(zse, 2); + } + + if (!ok) { + smp_client_response_buf_clean(); + } else { + nb->len = zse->payload - nb->data; + } +} + +void os_echo_verify(struct net_buf *nb) +{ + /* Parse CBOR data: hash and confirm */ + zcbor_state_t zsd[3 + 2]; + int rc; + int response_status; + struct zcbor_string echo_data; + size_t decoded; + struct zcbor_map_decode_key_val list_res_decode[] = { + ZCBOR_MAP_DECODE_KEY_DECODER("d", zcbor_tstr_decode, &echo_data) + }; + + zcbor_new_decode_state(zsd, ARRAY_SIZE(zsd), nb->data + sizeof(struct smp_hdr), nb->len, 1); + echo_data.len = 0; + + rc = zcbor_map_decode_bulk(zsd, list_res_decode, ARRAY_SIZE(list_res_decode), &decoded); + if (rc || !echo_data.len) { + printf("Corrupted data %d or no echo data %d\r\n", rc, echo_data.len); + response_status = MGMT_ERR_EINVAL; + } else if (memcmp(echo_data.value, echo_ptr, echo_data.len)) { + response_status = MGMT_ERR_EINVAL; + } else { + response_status = MGMT_ERR_EOK; + } + + os_echo_response(response_status, &echo_data); +} diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.h b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.h new file mode 100644 index 000000000000..ec6f3408979f --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/os_gr_stub.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_OS_GR_STUB_ +#define H_OS_GR_STUB_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void os_stub_init(const char *echo_str); +void os_reset_response(void); +void os_echo_verify(struct net_buf *nb); + +#ifdef __cplusplus +} +#endif + +#endif /* H_OS_GR_STUB_ */ diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.c b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.c new file mode 100644 index 000000000000..9b476082dd8e --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "smp_stub.h" + +K_THREAD_STACK_DEFINE(smp_stub_work_queue_stack, CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_STACK_SIZE); + +static mcmgr_client_data_check_fn rx_verify_cb; +static int send_client_failure; +static struct net_buf *response_buf; +static struct smp_hdr res_hdr; +static struct smp_transport smpt_test; +static struct smp_client_transport_entry smp_client_transport; +static struct k_work_q smp_work_queue; +static struct k_work stub_work; + +static const struct k_work_queue_config smp_work_queue_config = { + .name = "mcumgr smp" +}; + +void smp_stub_set_rx_data_verify(mcmgr_client_data_check_fn cb) +{ + rx_verify_cb = cb; +} + +void smp_client_send_status_stub(int status) +{ + send_client_failure = status; +} + +struct net_buf *smp_response_buf_allocation(void) +{ + smp_client_response_buf_clean(); + + response_buf = smp_packet_alloc(); + + return response_buf; +} + +void smp_client_response_buf_clean(void) +{ + if (response_buf) { + smp_client_buf_free(response_buf); + response_buf = NULL; + } +} + +void smp_transport_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr) +{ + memcpy(dst_hdr, nb->data, sizeof(*dst_hdr)); + dst_hdr->nh_len = sys_be16_to_cpu(dst_hdr->nh_len); + dst_hdr->nh_group = sys_be16_to_cpu(dst_hdr->nh_group); +} + + +static uint16_t smp_uart_get_mtu(const struct net_buf *nb) +{ + return 256; +} + +static int smp_uart_tx_pkt(struct net_buf *nb) +{ + if (send_client_failure) { + /* Test Send cmd fail */ + return send_client_failure; + } + + memcpy(&res_hdr, nb->data, sizeof(res_hdr)); + res_hdr.nh_len = sys_be16_to_cpu(res_hdr.nh_len); + res_hdr.nh_group = sys_be16_to_cpu(res_hdr.nh_group); + res_hdr.nh_op += 1; /* Request to response */ + + /* Validate Input data if callback is configured */ + if (rx_verify_cb) { + rx_verify_cb(nb); + } + + /* Free tx buf */ + net_buf_unref(nb); + + if (response_buf) { + k_work_submit_to_queue(&smp_work_queue, &stub_work); + } + + return 0; +} + +static void smp_client_handle_reqs(struct k_work *work) +{ + if (response_buf) { + smp_client_single_response(response_buf, &res_hdr); + } +} + +void stub_smp_client_transport_register(void) +{ + + smpt_test.functions.output = smp_uart_tx_pkt; + smpt_test.functions.get_mtu = smp_uart_get_mtu; + + smp_transport_init(&smpt_test); + smp_client_transport.smpt = &smpt_test; + smp_client_transport.smpt_type = SMP_SERIAL_TRANSPORT; + smp_client_transport_register(&smp_client_transport); + + + k_work_queue_init(&smp_work_queue); + + k_work_queue_start(&smp_work_queue, smp_stub_work_queue_stack, + K_THREAD_STACK_SIZEOF(smp_stub_work_queue_stack), + CONFIG_MCUMGR_TRANSPORT_WORKQUEUE_THREAD_PRIO, &smp_work_queue_config); + + k_work_init(&stub_work, smp_client_handle_reqs); +} diff --git a/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.h b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.h new file mode 100644 index 000000000000..c8668a033d2e --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/mcumgr_client/src/smp_stub.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_SMP_STUB_ +#define H_SMP_STUB_ + +#include +#include +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef void (*mcmgr_client_data_check_fn)(struct net_buf *nb); + +void smp_stub_set_rx_data_verify(mcmgr_client_data_check_fn cb); +void smp_client_send_status_stub(int status); +void smp_client_response_buf_clean(void); +struct net_buf *smp_response_buf_allocation(void); +void stub_smp_client_transport_register(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_SMP_STUB_ */ diff --git a/tests/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt b/tests/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt new file mode 100644 index 000000000000..2d5fea068dbc --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/CMakeLists.txt @@ -0,0 +1,15 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(smp_client) + +FILE(GLOB app_sources + src/*.c +) + +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/subsys/mgmt/mcumgr/smp_client/prj.conf b/tests/subsys/mgmt/mcumgr/smp_client/prj.conf new file mode 100644 index 000000000000..22740657b784 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/prj.conf @@ -0,0 +1,19 @@ +# +# Copyright (c) 2023 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 +# +# ZTEST config +CONFIG_ZTEST=y +CONFIG_ZTEST_NEW_API=y +CONFIG_ZTEST_STACK_SIZE=2048 + +CONFIG_NET_BUF=y +CONFIG_BASE64=y +CONFIG_CRC=y +CONFIG_ZCBOR=y +CONFIG_MCUMGR=y +CONFIG_SMP_CLIENT=y + +# Extend System Workqueue stack size +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2304 diff --git a/tests/subsys/mgmt/mcumgr/smp_client/src/main.c b/tests/subsys/mgmt/mcumgr/smp_client/src/main.c new file mode 100644 index 000000000000..be1a3968274a --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/src/main.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "smp_transport_stub.h" + +static struct net_buf *buf[5]; + +static uint32_t testing_user_data; +static void *response_ptr; +static struct net_buf *res_buf; +static struct smp_client_object smp_client; + +int smp_client_res_cb(struct net_buf *nb, void *user_data) +{ + res_buf = nb; + response_ptr = user_data; + return 0; +} + +ZTEST(smp_client, buf_alloc) +{ + struct smp_client_object smp_client; + + /* Allocate all 4 buffer's and verify that 5th fail */ + for (int i = 0; i < 5; i++) { + buf[i] = smp_client_buf_allocation(&smp_client, MGMT_GROUP_ID_IMAGE, 1, + MGMT_OP_WRITE, SMP_MCUMGR_VERSION_1); + if (i == 4) { + zassert_is_null(buf[i], "Buffer was not Null"); + } else { + zassert_not_null(buf[i], "Buffer was Null"); + zassert_equal(sizeof(struct smp_hdr), buf[i]->len, + "Expected to receive %d response %d", + sizeof(struct smp_hdr), buf[i]->len); + } + } + + for (int i = 0; i < 4; i++) { + smp_client_buf_free(buf[i]); + buf[i] = NULL; + } +} + +ZTEST(smp_client, msg_send_timeout) +{ + struct net_buf *nb; + + int rc; + + nb = smp_client_buf_allocation(&smp_client, MGMT_GROUP_ID_IMAGE, 1, MGMT_OP_WRITE, + SMP_MCUMGR_VERSION_1); + zassert_not_null(nb, "Buffer was Null"); + rc = smp_client_send_cmd(&smp_client, nb, smp_client_res_cb, &testing_user_data, 2); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + k_sleep(K_SECONDS(3)); + zassert_is_null(res_buf, "NULL pointer was not returned"); + zassert_equal_ptr(response_ptr, &testing_user_data, "User data not returned correctly"); +} + +ZTEST(smp_client, msg_response_handler) +{ + struct smp_hdr dst_hdr; + int rc; + + + response_ptr = NULL; + res_buf = NULL; + + buf[0] = smp_client_buf_allocation(&smp_client, MGMT_GROUP_ID_IMAGE, 1, MGMT_OP_WRITE, + SMP_MCUMGR_VERSION_1); + zassert_not_null(buf[0], "Buffer was Null"); + rc = smp_client_send_cmd(&smp_client, buf[0], smp_client_res_cb, &testing_user_data, 8); + zassert_equal(MGMT_ERR_EOK, rc, "Expected to receive %d response %d", MGMT_ERR_EOK, rc); + buf[1] = smp_client_buf_allocation(&smp_client, MGMT_GROUP_ID_IMAGE, 1, MGMT_OP_WRITE, + SMP_MCUMGR_VERSION_1); + zassert_not_null(buf[0], "Buffer was Null"); + /* Read Pushed packet Header */ + smp_transport_read_hdr(buf[0], &dst_hdr); + smp_client_single_response(buf[1], &dst_hdr); + zassert_is_null(res_buf, "NULL pointer was not returned"); + zassert_is_null(response_ptr, "NULL pointer was not returned"); + /* Set Correct OP */ + dst_hdr.nh_op = MGMT_OP_WRITE_RSP; + smp_client_single_response(buf[1], &dst_hdr); + zassert_equal_ptr(res_buf, buf[1], "Response Buf not correct"); + zassert_equal_ptr(response_ptr, &testing_user_data, "User data not returned correctly"); + response_ptr = NULL; + res_buf = NULL; + smp_client_single_response(buf[1], &dst_hdr); + zassert_is_null(res_buf, "NULL pointer was not returned"); + zassert_is_null(response_ptr, "NULL pointer was not returned"); +} + +static void *setup_custom_os(void) +{ + /* Registre tarnsport and init client */ + stub_smp_client_transport_register(); + smp_client_object_init(&smp_client, SMP_SERIAL_TRANSPORT); + return NULL; +} + +static void cleanup_test(void *p) +{ + for (int i = 0; i < 5; i++) { + if (buf[i]) { + smp_client_buf_free(buf[i]); + buf[i] = NULL; + } + } +} + +/* Main test set */ +ZTEST_SUITE(smp_client, NULL, setup_custom_os, NULL, cleanup_test, NULL); diff --git a/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.c b/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.c new file mode 100644 index 000000000000..d3248755e5ab --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include + +static struct smp_transport smpt_test; +static struct smp_client_transport_entry smp_client_transport; + +/* Stubbed functions */ + +void smp_transport_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr) +{ + memcpy(dst_hdr, nb->data, sizeof(*dst_hdr)); + dst_hdr->nh_len = sys_be16_to_cpu(dst_hdr->nh_len); + dst_hdr->nh_group = sys_be16_to_cpu(dst_hdr->nh_group); +} + + + + +static uint16_t smp_uart_get_mtu(const struct net_buf *nb) +{ + return 256; +} + +static int smp_uart_tx_pkt(struct net_buf *nb) +{ + smp_packet_free(nb); + return 0; +} + +void stub_smp_client_transport_register(void) +{ + + smpt_test.functions.output = smp_uart_tx_pkt; + smpt_test.functions.get_mtu = smp_uart_get_mtu; + + smp_transport_init(&smpt_test); + smp_client_transport.smpt = &smpt_test; + smp_client_transport.smpt_type = SMP_SERIAL_TRANSPORT; + smp_client_transport_register(&smp_client_transport); +} diff --git a/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.h b/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.h new file mode 100644 index 000000000000..9046aff622c0 --- /dev/null +++ b/tests/subsys/mgmt/mcumgr/smp_client/src/smp_transport_stub.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef H_OS_GR_STUB_ +#define H_OS_GR_STUB_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void smp_transport_read_hdr(const struct net_buf *nb, struct smp_hdr *dst_hdr); +void stub_smp_client_transport_register(void); + +#ifdef __cplusplus +} +#endif + +#endif /* H_OS_GR_STUB_ */ From 88100438df99515471414adb8f677fc159e3f144 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 13 Jul 2023 13:33:16 +0200 Subject: [PATCH 429/528] [nrf fromtree] net: if: Fix if_ipv4_get_addr() locking net_if_lock() should be called only after iface pointer is verified not to be NULL, otherwise we can end up dereferencing NULL pointer in certain corner cases. Signed-off-by: Robert Lubos (cherry picked from commit cc81dca5566c5cddbb8a92675579398dae01740d) --- subsys/net/ip/net_if.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index ac90fbd0e96a..2f27531c4bba 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -3262,12 +3262,12 @@ static struct in_addr *if_ipv4_get_addr(struct net_if *iface, struct net_if_ipv4 *ipv4; int i; - net_if_lock(iface); - if (!iface) { - goto out; + return NULL; } + net_if_lock(iface); + ipv4 = iface->config.ip.ipv4; if (!ipv4) { goto out; From dda2f66fd5cd676c99b8b87b8c1546fe559790b7 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Tue, 11 Jul 2023 14:05:28 +0200 Subject: [PATCH 430/528] [nrf fromtree] net: conn_mgr: Create conn_mgr thread dynamically Statically created threads with K_THREAD_DEFINE() are launched only after the SYS_INIT phase. This does not play well with NET_CONFIG library, which may block during SYS_INIT until network interface is UP and RUNNING. In order to be able to connect to L2 network and thus mark the network interface as running and unblock NET_CONFIG, we need to be able to run conn_mgr thread during SYS_INIT. This can be achieved, by starting the thread dynamically during SYS_INIT phase, instead of relying on static thread creation. Signed-off-by: Robert Lubos (cherry picked from commit c15e3d448c0ec801a48ba7683fe14c0c22a39caf) --- subsys/net/conn_mgr/conn_mgr.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/subsys/net/conn_mgr/conn_mgr.c b/subsys/net/conn_mgr/conn_mgr.c index b202c8745664..3374a1acf604 100644 --- a/subsys/net/conn_mgr/conn_mgr.c +++ b/subsys/net/conn_mgr/conn_mgr.c @@ -23,6 +23,10 @@ LOG_MODULE_REGISTER(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_LOG_LEVEL); #define THREAD_PRIORITY K_PRIO_PREEMPT(7) #endif +static K_THREAD_STACK_DEFINE(conn_mgr_thread_stack, + CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE); +static struct k_thread conn_mgr_thread; + /* Internal state array tracking readiness, flags, and other state information for all available * ifaces. Note that indexing starts at 0, whereas Zephyr iface indices start at 1. * conn_mgr_get_if_by_index and conn_mgr_get_index_for_if are used to go back and forth between @@ -212,10 +216,6 @@ static void conn_mgr_handler(void) } } -K_THREAD_DEFINE(conn_mgr, CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE, - (k_thread_entry_t)conn_mgr_handler, NULL, NULL, NULL, - THREAD_PRIORITY, 0, 0); - void conn_mgr_resend_status(void) { k_mutex_lock(&conn_mgr_lock, K_FOREVER); @@ -326,12 +326,14 @@ static int conn_mgr_init(void) { int i; - for (i = 0; i < ARRAY_SIZE(iface_states); i++) { iface_states[i] = 0; } - k_thread_start(conn_mgr); + k_thread_create(&conn_mgr_thread, conn_mgr_thread_stack, + CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE, + (k_thread_entry_t)conn_mgr_handler, + NULL, NULL, NULL, THREAD_PRIORITY, 0, K_NO_WAIT); return 0; } From 8bf9d185bf901e036fca28017cfb45256241f140 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 12 Jul 2023 14:53:56 +0200 Subject: [PATCH 431/528] [nrf fromtree] samples: net: echo_client/server: Fix mbed TLS dependency All application level TLS operations should be guarded with "#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS)" and not mbed TLS configs only. Otherwise, in case mbed TLS is enabled, but the sample is not configured to use TLS (hence TLS credential library is not available for example), the build may fail or produce spurious warnings. Signed-off-by: Robert Lubos (cherry picked from commit 1f1f550ad69e46afa1719d6b63e8273bb4b8771c) --- samples/net/sockets/echo_client/CMakeLists.txt | 5 +++-- samples/net/sockets/echo_client/src/echo-client.c | 5 +++-- samples/net/sockets/echo_server/CMakeLists.txt | 5 +++-- samples/net/sockets/echo_server/src/echo-server.c | 13 +++++-------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/samples/net/sockets/echo_client/CMakeLists.txt b/samples/net/sockets/echo_client/CMakeLists.txt index 3222441653b3..0fe1ad126cc1 100644 --- a/samples/net/sockets/echo_client/CMakeLists.txt +++ b/samples/net/sockets/echo_client/CMakeLists.txt @@ -5,8 +5,9 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(sockets_echo_client) -if(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED AND - (CONFIG_NET_SAMPLE_PSK_HEADER_FILE STREQUAL "dummy_psk.h")) +if(CONFIG_NET_SOCKETS_SOCKOPT_TLS AND + CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED AND + (CONFIG_NET_SAMPLE_PSK_HEADER_FILE STREQUAL "dummy_psk.h")) add_custom_target(development_psk COMMAND ${CMAKE_COMMAND} -E echo "----------------------------------------------------------" COMMAND ${CMAKE_COMMAND} -E echo "--- WARNING: Using dummy PSK! Only suitable for ---" diff --git a/samples/net/sockets/echo_client/src/echo-client.c b/samples/net/sockets/echo_client/src/echo-client.c index c211de8f3c93..a8388604ba2e 100644 --- a/samples/net/sockets/echo_client/src/echo-client.c +++ b/samples/net/sockets/echo_client/src/echo-client.c @@ -247,7 +247,6 @@ static void init_app(void) if (err < 0) { LOG_ERR("Failed to register public certificate: %d", err); } -#endif #if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) err = tls_credential_add(PSK_TAG, @@ -264,7 +263,9 @@ static void init_app(void) if (err < 0) { LOG_ERR("Failed to register PSK ID: %d", err); } -#endif +#endif /* defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) */ +#endif /* defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) */ + if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) { net_mgmt_init_event_callback(&mgmt_cb, diff --git a/samples/net/sockets/echo_server/CMakeLists.txt b/samples/net/sockets/echo_server/CMakeLists.txt index 5203e1d16408..8e01b63e70c5 100644 --- a/samples/net/sockets/echo_server/CMakeLists.txt +++ b/samples/net/sockets/echo_server/CMakeLists.txt @@ -5,8 +5,9 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(sockets_echo_server) -if(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED AND - (CONFIG_NET_SAMPLE_PSK_HEADER_FILE STREQUAL "dummy_psk.h")) +if(CONFIG_NET_SOCKETS_SOCKOPT_TLS AND + CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED AND + (CONFIG_NET_SAMPLE_PSK_HEADER_FILE STREQUAL "dummy_psk.h")) add_custom_target(development_psk COMMAND ${CMAKE_COMMAND} -E echo "----------------------------------------------------------" COMMAND ${CMAKE_COMMAND} -E echo "--- WARNING: Using dummy PSK! Only suitable for ---" diff --git a/samples/net/sockets/echo_server/src/echo-server.c b/samples/net/sockets/echo_server/src/echo-server.c index fbf189f898ad..7343b1e82174 100644 --- a/samples/net/sockets/echo_server/src/echo-server.c +++ b/samples/net/sockets/echo_server/src/echo-server.c @@ -135,16 +135,13 @@ static void init_app(void) ARG_UNUSED(ret); #endif -#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) || \ - defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) - int err; -#endif - k_sem_init(&quit_lock, 0, K_SEM_MAX_LIMIT); LOG_INF(APP_BANNER); #if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) + int err; + #if defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) err = tls_credential_add(SERVER_CERTIFICATE_TAG, TLS_CREDENTIAL_CA_CERTIFICATE, @@ -153,7 +150,7 @@ static void init_app(void) if (err < 0) { LOG_ERR("Failed to register CA certificate: %d", err); } -#endif +#endif /* defined(CONFIG_NET_SAMPLE_CERTS_WITH_SC) */ err = tls_credential_add(SERVER_CERTIFICATE_TAG, TLS_CREDENTIAL_SERVER_CERTIFICATE, @@ -170,7 +167,6 @@ static void init_app(void) if (err < 0) { LOG_ERR("Failed to register private key: %d", err); } -#endif #if defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) err = tls_credential_add(PSK_TAG, @@ -187,7 +183,8 @@ static void init_app(void) if (err < 0) { LOG_ERR("Failed to register PSK ID: %d", err); } -#endif +#endif /* defined(CONFIG_MBEDTLS_KEY_EXCHANGE_PSK_ENABLED) */ +#endif /* defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) */ if (IS_ENABLED(CONFIG_NET_CONNECTION_MANAGER)) { net_mgmt_init_event_callback(&mgmt_cb, From 283577d93df3ba367f2cf38588bb0c65799a047f Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 12 Jul 2023 15:24:34 +0200 Subject: [PATCH 432/528] [nrf fromtree] samples: net: echo_client: Fix build with UDP disabled In case UDP is disabled, init_udp() is not compiled and the build fails. Fix this, by providing dummy implementations for UDP functions, in case UDP is disabled. Signed-off-by: Robert Lubos (cherry picked from commit 87ee12ae7238e685324a89e18c85d1af099264e2) --- samples/net/sockets/echo_client/src/common.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/samples/net/sockets/echo_client/src/common.h b/samples/net/sockets/echo_client/src/common.h index debfa3fbb652..e0b06b7ee141 100644 --- a/samples/net/sockets/echo_client/src/common.h +++ b/samples/net/sockets/echo_client/src/common.h @@ -73,6 +73,7 @@ extern const char lorem_ipsum[]; extern const int ipsum_len; extern struct configs conf; +#if defined(CONFIG_NET_UDP) /* init_udp initializes kernel objects, hence it has to be called from * supervisor thread. */ @@ -80,6 +81,12 @@ void init_udp(void); int start_udp(void); int process_udp(void); void stop_udp(void); +#else +static inline void init_udp(void) { } +static inline int start_udp(void) { return 0; } +static inline int process_udp(void) { return 0; } +static inline void stop_udp(void) { } +#endif /* defined(CONFIG_NET_UDP) */ int start_tcp(void); int process_tcp(void); From 085f4c5819fa89e3ce7eec017cacfc89f6702cfd Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Mon, 17 Jul 2023 15:12:36 +0200 Subject: [PATCH 433/528] [nrf fromtree] net: if: Add functions to loop over IPv4/IPv6 addresses Add new net_if API functions which allow to loop over all valid IPv4/IPv6 addresses assigned to the interface and execute a callback function on them. Signed-off-by: Robert Lubos (cherry picked from commit b2314c83629f170fb766bf5b8e1c78f85ce046d6) --- include/zephyr/net/net_if.h | 34 +++++++++++++++++++++ subsys/net/ip/net_if.c | 60 +++++++++++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) diff --git a/include/zephyr/net/net_if.h b/include/zephyr/net/net_if.h index 63f1e3549c48..16f104b501f3 100644 --- a/include/zephyr/net/net_if.h +++ b/include/zephyr/net/net_if.h @@ -1208,6 +1208,29 @@ bool net_if_ipv6_addr_rm(struct net_if *iface, const struct in6_addr *addr); __syscall bool net_if_ipv6_addr_rm_by_index(int index, const struct in6_addr *addr); +/** + * @typedef net_if_ip_addr_cb_t + * @brief Callback used while iterating over network interface IP addresses + * + * @param iface Pointer to the network interface the address belongs to + * @param addr Pointer to current IP address + * @param user_data A valid pointer to user data or NULL + */ +typedef void (*net_if_ip_addr_cb_t)(struct net_if *iface, + struct net_if_addr *addr, + void *user_data); + +/** + * @brief Go through all IPv6 addresses on a network interface and call callback + * for each used address. + * + * @param iface Pointer to the network interface + * @param cb User-supplied callback function to call + * @param user_data User specified data + */ +void net_if_ipv6_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb, + void *user_data); + /** * @brief Add a IPv6 multicast address to an interface * @@ -1839,6 +1862,17 @@ __syscall bool net_if_ipv4_addr_add_by_index(int index, __syscall bool net_if_ipv4_addr_rm_by_index(int index, const struct in_addr *addr); +/** + * @brief Go through all IPv4 addresses on a network interface and call callback + * for each used address. + * + * @param iface Pointer to the network interface + * @param cb User-supplied callback function to call + * @param user_data User specified data + */ +void net_if_ipv4_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb, + void *user_data); + /** * @brief Add a IPv4 multicast address to an interface * diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c index 2f27531c4bba..e1d3fd5d226a 100644 --- a/subsys/net/ip/net_if.c +++ b/subsys/net/ip/net_if.c @@ -1959,6 +1959,36 @@ bool z_vrfy_net_if_ipv6_addr_rm_by_index(int index, #include #endif /* CONFIG_USERSPACE */ +void net_if_ipv6_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb, + void *user_data) +{ + struct net_if_ipv6 *ipv6; + + if (iface == NULL) { + return; + } + + net_if_lock(iface); + + ipv6 = iface->config.ip.ipv6; + if (ipv6 == NULL) { + goto out; + } + + for (int i = 0; i < NET_IF_MAX_IPV6_ADDR; i++) { + struct net_if_addr *if_addr = &ipv6->unicast[i]; + + if (!if_addr->is_used) { + continue; + } + + cb(iface, if_addr, user_data); + } + +out: + net_if_unlock(iface); +} + struct net_if_mcast_addr *net_if_ipv6_maddr_add(struct net_if *iface, const struct in6_addr *addr) { @@ -3761,6 +3791,36 @@ bool z_vrfy_net_if_ipv4_addr_rm_by_index(int index, #include #endif /* CONFIG_USERSPACE */ +void net_if_ipv4_addr_foreach(struct net_if *iface, net_if_ip_addr_cb_t cb, + void *user_data) +{ + struct net_if_ipv4 *ipv4; + + if (iface == NULL) { + return; + } + + net_if_lock(iface); + + ipv4 = iface->config.ip.ipv4; + if (ipv4 == NULL) { + goto out; + } + + for (int i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { + struct net_if_addr *if_addr = &ipv4->unicast[i]; + + if (!if_addr->is_used) { + continue; + } + + cb(iface, if_addr, user_data); + } + +out: + net_if_unlock(iface); +} + static struct net_if_mcast_addr *ipv4_maddr_find(struct net_if *iface, bool is_used, const struct in_addr *addr) From 164badac20cca5dc7167cc73be38e9f201659ee2 Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Wed, 12 Jul 2023 13:39:43 +0200 Subject: [PATCH 434/528] [nrf fromtree] samples: net: dns_resolve: Improve DHCPv4 handling There is some ambiguity with the DHCPv4 handling in the dns_resolve sample. On one hand, the sample uses net_config library, which does initiate the DHCPv4 on the interface (if enabled) and may block the initialization until the address is assigned (in case there is no other statically assigned IPv4 addresses.) On the other hand, the sample registers for NET_EVENT_IPV4_ADDR_ADD in case DHCPv4 is in use, delaying the DNS queries until address is assigned. In case net_config delayed the initialization however, this will not work, as the event handler will be registered only after DHCPv4 address is assigned, so the callback will not get executed. Fix this, by checking if DHCPv4 assigned address already exists on an interface - if so, schedule DNS queries immediately. Otherwise (for example in case when net_config was not configured to wait for address) register an event callback, and schedule queries from there. Signed-off-by: Robert Lubos (cherry picked from commit 9866a5229d697a115a027ce9e39b7e85efc57b80) --- samples/net/dns_resolve/src/main.c | 103 ++++++++++++++++++++--------- 1 file changed, 71 insertions(+), 32 deletions(-) diff --git a/samples/net/dns_resolve/src/main.c b/samples/net/dns_resolve/src/main.c index 62cd71d9e22d..0aa5f2a98863 100644 --- a/samples/net/dns_resolve/src/main.c +++ b/samples/net/dns_resolve/src/main.c @@ -152,57 +152,96 @@ static void do_ipv4_lookup(struct k_work *work) LOG_DBG("DNS id %u", dns_id); } +static void schedule_ipv4_queries(void) +{ + k_work_init_delayable(&ipv4_timer, do_ipv4_lookup); + k_work_reschedule(&ipv4_timer, K_NO_WAIT); + +#if defined(CONFIG_MDNS_RESOLVER) + k_work_init_delayable(&mdns_ipv4_timer, do_mdns_ipv4_lookup); + k_work_reschedule(&mdns_ipv4_timer, K_NO_WAIT); +#endif +} + +static void print_dhcpv4_addr(struct net_if *iface, struct net_if_addr *if_addr, + void *user_data) +{ + bool *found = (bool *)user_data; + char hr_addr[NET_IPV4_ADDR_LEN]; + + if (*found) { + return; + } + + if (if_addr->addr_type != NET_ADDR_DHCP) { + return; + } + + LOG_INF("IPv4 address: %s", + net_addr_ntop(AF_INET, &if_addr->address.in_addr, + hr_addr, NET_IPV4_ADDR_LEN)); + LOG_INF("Lease time: %u seconds", iface->config.dhcpv4.lease_time); + LOG_INF("Subnet: %s", + net_addr_ntop(AF_INET, + &iface->config.ip.ipv4->netmask, + hr_addr, NET_IPV4_ADDR_LEN)); + LOG_INF("Router: %s", + net_addr_ntop(AF_INET, + &iface->config.ip.ipv4->gw, + hr_addr, NET_IPV4_ADDR_LEN)); + + *found = true; +} + static void ipv4_addr_add_handler(struct net_mgmt_event_callback *cb, uint32_t mgmt_event, struct net_if *iface) { - char hr_addr[NET_IPV4_ADDR_LEN]; - int i; + + bool found = false; if (mgmt_event != NET_EVENT_IPV4_ADDR_ADD) { return; } - for (i = 0; i < NET_IF_MAX_IPV4_ADDR; i++) { - struct net_if_addr *if_addr = - &iface->config.ip.ipv4->unicast[i]; - - if (if_addr->addr_type != NET_ADDR_DHCP || !if_addr->is_used) { - continue; - } - - LOG_INF("IPv4 address: %s", - net_addr_ntop(AF_INET, - &if_addr->address.in_addr, - hr_addr, NET_IPV4_ADDR_LEN)); - LOG_INF("Lease time: %u seconds", - iface->config.dhcpv4.lease_time); - LOG_INF("Subnet: %s", - net_addr_ntop(AF_INET, - &iface->config.ip.ipv4->netmask, - hr_addr, NET_IPV4_ADDR_LEN)); - LOG_INF("Router: %s", - net_addr_ntop(AF_INET, - &iface->config.ip.ipv4->gw, - hr_addr, NET_IPV4_ADDR_LEN)); - break; - } + net_if_ipv4_addr_foreach(iface, print_dhcpv4_addr, &found); /* We cannot run DNS lookup directly from this thread as the * management event thread stack is very small by default. * So run it from work queue instead. */ - k_work_init_delayable(&ipv4_timer, do_ipv4_lookup); - k_work_reschedule(&ipv4_timer, K_NO_WAIT); + schedule_ipv4_queries(); +} -#if defined(CONFIG_MDNS_RESOLVER) - k_work_init_delayable(&mdns_ipv4_timer, do_mdns_ipv4_lookup); - k_work_reschedule(&mdns_ipv4_timer, K_NO_WAIT); -#endif +static void check_dhcpv4_addr(struct net_if *iface, struct net_if_addr *if_addr, + void *user_data) +{ + bool *found = (bool *)user_data; + + if (if_addr->addr_type != NET_ADDR_DHCP) { + return; + } + + *found = true; } static void setup_dhcpv4(struct net_if *iface) { + bool found; + + /* If DHCP registers an IP address before we register the + * ipv4_addr_add_handler() callback, we won't be notified. Check + * whether this is the case. + */ + net_if_ipv4_addr_foreach(iface, check_dhcpv4_addr, &found); + + if (found) { + /* Already have DHCP assigned address, schedule queries. */ + schedule_ipv4_queries(); + return; + } + + /* Otherwise, wait for DHCP to assign an address. */ LOG_INF("Getting IPv4 address via DHCP before issuing DNS query"); net_mgmt_init_event_callback(&mgmt4_cb, ipv4_addr_add_handler, From 4579f028e1e6139786491e352c50bc9528b09c7d Mon Sep 17 00:00:00 2001 From: Robert Lubos Date: Thu, 13 Jul 2023 15:32:45 +0200 Subject: [PATCH 435/528] [nrf noup] samples: net: Add support for nRF700x Add support for nRF700x to selected networking samples, by providing appropriate overlay configuration files. Signed-off-by: Robert Lubos --- .../net/dhcpv4_client/overlay-nrf700x.conf | 14 ++++++++++ samples/net/dns_resolve/overlay-nrf700x.conf | 18 +++++++++++++ .../net/ipv4_autoconf/overlay-nrf700x.conf | 14 ++++++++++ .../net/mdns_responder/overlay-nrf700x.conf | 18 +++++++++++++ .../net/mqtt_publisher/overlay-nrf700x.conf | 19 ++++++++++++++ .../mqtt_sn_publisher/overlay-nrf700x.conf | 20 ++++++++++++++ .../sockets/coap_client/overlay-nrf700x.conf | 16 ++++++++++++ .../sockets/coap_server/overlay-nrf700x.conf | 26 +++++++++++++++++++ samples/net/sockets/echo/overlay-nrf700x.conf | 18 +++++++++++++ .../sockets/echo_async/overlay-nrf700x.conf | 18 +++++++++++++ .../sockets/echo_client/overlay-nrf700x.conf | 20 ++++++++++++++ .../sockets/echo_server/overlay-nrf700x.conf | 20 ++++++++++++++ .../net/sockets/http_get/overlay-nrf700x.conf | 18 +++++++++++++ .../sockets/sntp_client/overlay-nrf700x.conf | 18 +++++++++++++ samples/net/syslog_net/overlay-nrf700x.conf | 18 +++++++++++++ samples/net/telnet/overlay-nrf700x.conf | 18 +++++++++++++ 16 files changed, 293 insertions(+) create mode 100644 samples/net/dhcpv4_client/overlay-nrf700x.conf create mode 100644 samples/net/dns_resolve/overlay-nrf700x.conf create mode 100644 samples/net/ipv4_autoconf/overlay-nrf700x.conf create mode 100644 samples/net/mdns_responder/overlay-nrf700x.conf create mode 100644 samples/net/mqtt_publisher/overlay-nrf700x.conf create mode 100644 samples/net/mqtt_sn_publisher/overlay-nrf700x.conf create mode 100644 samples/net/sockets/coap_client/overlay-nrf700x.conf create mode 100644 samples/net/sockets/coap_server/overlay-nrf700x.conf create mode 100644 samples/net/sockets/echo/overlay-nrf700x.conf create mode 100644 samples/net/sockets/echo_async/overlay-nrf700x.conf create mode 100644 samples/net/sockets/echo_client/overlay-nrf700x.conf create mode 100644 samples/net/sockets/echo_server/overlay-nrf700x.conf create mode 100644 samples/net/sockets/http_get/overlay-nrf700x.conf create mode 100644 samples/net/sockets/sntp_client/overlay-nrf700x.conf create mode 100644 samples/net/syslog_net/overlay-nrf700x.conf create mode 100644 samples/net/telnet/overlay-nrf700x.conf diff --git a/samples/net/dhcpv4_client/overlay-nrf700x.conf b/samples/net/dhcpv4_client/overlay-nrf700x.conf new file mode 100644 index 000000000000..2d552e9c6231 --- /dev/null +++ b/samples/net/dhcpv4_client/overlay-nrf700x.conf @@ -0,0 +1,14 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/dns_resolve/overlay-nrf700x.conf b/samples/net/dns_resolve/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/dns_resolve/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/ipv4_autoconf/overlay-nrf700x.conf b/samples/net/ipv4_autoconf/overlay-nrf700x.conf new file mode 100644 index 000000000000..2d552e9c6231 --- /dev/null +++ b/samples/net/ipv4_autoconf/overlay-nrf700x.conf @@ -0,0 +1,14 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/mdns_responder/overlay-nrf700x.conf b/samples/net/mdns_responder/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/mdns_responder/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/mqtt_publisher/overlay-nrf700x.conf b/samples/net/mqtt_publisher/overlay-nrf700x.conf new file mode 100644 index 000000000000..a812c7896f62 --- /dev/null +++ b/samples/net/mqtt_publisher/overlay-nrf700x.conf @@ -0,0 +1,19 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_CONFIG_NEED_IPV4=y +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf b/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf new file mode 100644 index 000000000000..cbc47b965727 --- /dev/null +++ b/samples/net/mqtt_sn_publisher/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/coap_client/overlay-nrf700x.conf b/samples/net/sockets/coap_client/overlay-nrf700x.conf new file mode 100644 index 000000000000..a0e436e3537d --- /dev/null +++ b/samples/net/sockets/coap_client/overlay-nrf700x.conf @@ -0,0 +1,16 @@ +CONFIG_HEAP_MEM_POOL_SIZE=153000 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/coap_server/overlay-nrf700x.conf b/samples/net/sockets/coap_server/overlay-nrf700x.conf new file mode 100644 index 000000000000..4817a4f73ba6 --- /dev/null +++ b/samples/net/sockets/coap_server/overlay-nrf700x.conf @@ -0,0 +1,26 @@ +CONFIG_HEAP_MEM_POOL_SIZE=153000 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# The sample can run either IPv4 or IPv6, not both +CONFIG_NET_IPV6=n +CONFIG_NET_CONFIG_NEED_IPV6=n +CONFIG_NET_IPV4=y +CONFIG_NET_CONFIG_NEED_IPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo/overlay-nrf700x.conf b/samples/net/sockets/echo/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/sockets/echo/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_async/overlay-nrf700x.conf b/samples/net/sockets/echo_async/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/sockets/echo_async/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_client/overlay-nrf700x.conf b/samples/net/sockets/echo_client/overlay-nrf700x.conf new file mode 100644 index 000000000000..cbc47b965727 --- /dev/null +++ b/samples/net/sockets/echo_client/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/echo_server/overlay-nrf700x.conf b/samples/net/sockets/echo_server/overlay-nrf700x.conf new file mode 100644 index 000000000000..cbc47b965727 --- /dev/null +++ b/samples/net/sockets/echo_server/overlay-nrf700x.conf @@ -0,0 +1,20 @@ +CONFIG_POSIX_MAX_FDS=16 + +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/http_get/overlay-nrf700x.conf b/samples/net/sockets/http_get/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/sockets/http_get/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/sockets/sntp_client/overlay-nrf700x.conf b/samples/net/sockets/sntp_client/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/sockets/sntp_client/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/syslog_net/overlay-nrf700x.conf b/samples/net/syslog_net/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/syslog_net/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" diff --git a/samples/net/telnet/overlay-nrf700x.conf b/samples/net/telnet/overlay-nrf700x.conf new file mode 100644 index 000000000000..aa59e5d5ea2d --- /dev/null +++ b/samples/net/telnet/overlay-nrf700x.conf @@ -0,0 +1,18 @@ +# Wi-Fi +CONFIG_WIFI=y +CONFIG_WIFI_NRF700X=y +CONFIG_WPA_SUPP=y +CONFIG_NET_L2_ETHERNET=y + +# DHCPv4 +CONFIG_NET_CONFIG_MY_IPV4_ADDR="" +CONFIG_NET_DHCPV4=y + +# Connection manager +CONFIG_NET_CONNECTION_MANAGER=y + +# Credentials +CONFIG_WIFI_CREDENTIALS=y +CONFIG_WIFI_CREDENTIALS_STATIC=y +CONFIG_WIFI_CREDENTIALS_STATIC_SSID="" +CONFIG_WIFI_CREDENTIALS_STATIC_PASSWORD="" From 62b762a0684e3549953440e64c286e47fd817e60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jarno=20L=C3=A4ms=C3=A4?= Date: Tue, 27 Jun 2023 10:52:12 +0300 Subject: [PATCH 436/528] [nrf fromtree] net: lib: lwm2m: Use int16_t for signal strength MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The signal strength for the connectivity monitor was defined as int8_t, however this was too small for LTE RSRP values, which has range [-140,-44]. Signed-off-by: Jarno Lämsä (cherry picked from commit 7ae4e2472808648e3c13e887c04de2a0306eceb6) --- subsys/net/lib/lwm2m/lwm2m_obj_connmon.c | 4 ++-- .../lwm2m/lwm2m_registry/src/lwm2m_registry.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_obj_connmon.c b/subsys/net/lib/lwm2m/lwm2m_obj_connmon.c index c0e14429c857..aabb9fd3fd1d 100644 --- a/subsys/net/lib/lwm2m/lwm2m_obj_connmon.c +++ b/subsys/net/lib/lwm2m/lwm2m_obj_connmon.c @@ -84,7 +84,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); /* resource state variables */ static int8_t net_bearer; -static int8_t rss; +static int16_t rss; static uint8_t link_quality; static uint32_t cellid; static uint16_t mnc; @@ -99,7 +99,7 @@ static struct lwm2m_engine_obj connmon; static struct lwm2m_engine_obj_field fields[] = { OBJ_FIELD_DATA(CONNMON_NETWORK_BEARER_ID, R, U8), OBJ_FIELD_DATA(CONNMON_AVAIL_NETWORK_BEARER_ID, R, U8), - OBJ_FIELD_DATA(CONNMON_RADIO_SIGNAL_STRENGTH, R, S8), + OBJ_FIELD_DATA(CONNMON_RADIO_SIGNAL_STRENGTH, R, S16), OBJ_FIELD_DATA(CONNMON_LINK_QUALITY, R, U8), OBJ_FIELD_DATA(CONNMON_IP_ADDRESSES, R, STRING), OBJ_FIELD_DATA(CONNMON_ROUTER_IP_ADDRESSES, R_OPT, STRING), diff --git a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c index a5d1240fd909..5b79c476e7f0 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c +++ b/tests/net/lib/lwm2m/lwm2m_registry/src/lwm2m_registry.c @@ -130,12 +130,12 @@ ZTEST(lwm2m_registry, test_connmon) int ret; uint16_t u16_buf = 0; uint32_t u32_buf = 0; - int8_t s8_buf = 0; + int16_t s16_buf = 0; int32_t s32_buf = 0; uint16_t u16_getbuf = 0; uint32_t u32_getbuf = 0; - int8_t s8_getbuf = 0; + int16_t s16_getbuf = 0; int32_t s32_getbuf = 0; ret = lwm2m_set_res_buf(&LWM2M_OBJ(4, 0, 9), &u16_buf, sizeof(u16_buf), @@ -144,8 +144,8 @@ ZTEST(lwm2m_registry, test_connmon) ret = lwm2m_set_res_buf(&LWM2M_OBJ(4, 0, 8), &u32_buf, sizeof(u32_buf), sizeof(u32_buf), 0); zassert_equal(ret, 0); - ret = lwm2m_set_res_buf(&LWM2M_OBJ(4, 0, 2), &s8_buf, sizeof(s8_buf), - sizeof(s8_buf), 0); + ret = lwm2m_set_res_buf(&LWM2M_OBJ(4, 0, 2), &s16_buf, sizeof(s16_buf), + sizeof(s16_buf), 0); zassert_equal(ret, 0); ret = lwm2m_set_res_buf(&LWM2M_OBJ(4, 0, 11), &s32_buf, sizeof(s32_buf), sizeof(s32_buf), 0); @@ -155,28 +155,28 @@ ZTEST(lwm2m_registry, test_connmon) zassert_equal(ret, 0); ret = lwm2m_set_u32(&LWM2M_OBJ(4, 0, 8), 0xDEADBEEF); zassert_equal(ret, 0); - ret = lwm2m_set_s8(&LWM2M_OBJ(4, 0, 2), -5); + ret = lwm2m_set_s16(&LWM2M_OBJ(4, 0, 2), -5); zassert_equal(ret, 0); ret = lwm2m_set_s32(&LWM2M_OBJ(4, 0, 11), 0xCC00CC00); zassert_equal(ret, 0); zassert_equal(u16_buf, 0x5A5A); zassert_equal(u32_buf, 0xDEADBEEF); - zassert_equal(s8_buf, -5); + zassert_equal(s16_buf, -5); zassert_equal(s32_buf, 0xCC00CC00); ret = lwm2m_get_u16(&LWM2M_OBJ(4, 0, 9), &u16_getbuf); zassert_equal(ret, 0); ret = lwm2m_get_u32(&LWM2M_OBJ(4, 0, 8), &u32_getbuf); zassert_equal(ret, 0); - ret = lwm2m_get_s8(&LWM2M_OBJ(4, 0, 2), &s8_getbuf); + ret = lwm2m_get_s16(&LWM2M_OBJ(4, 0, 2), &s16_getbuf); zassert_equal(ret, 0); ret = lwm2m_get_s32(&LWM2M_OBJ(4, 0, 11), &s32_getbuf); zassert_equal(ret, 0); zassert_equal(u16_buf, u16_getbuf); zassert_equal(u32_buf, u32_getbuf); - zassert_equal(s8_buf, s8_getbuf); + zassert_equal(s16_buf, s16_getbuf); zassert_equal(s32_buf, s32_getbuf); } From da6836b73ed2be5c7a3a36c9bcea57f82a6b41e4 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 21 Jun 2023 15:26:19 +0300 Subject: [PATCH 437/528] [nrf fromtree] net: lwm2m: Update next event timestamp on PMAX change When PMAX value is changed, it should update all events. I believe there is a bug that caused the code only to update events that are ongoing (to be send). Now if PMAX changes, next event timestamp is recalculated. Fixes #59397 Signed-off-by: Seppo Takalo (cherry picked from commit aaa9cedf185e4ba674c8d1131060f1fd0c27e4dd) --- subsys/net/lib/lwm2m/lwm2m_observation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.c b/subsys/net/lib/lwm2m/lwm2m_observation.c index 559e33212d9f..696b5e9210f5 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.c +++ b/subsys/net/lib/lwm2m/lwm2m_observation.c @@ -913,7 +913,7 @@ static int lwm2m_engine_observer_timestamp_update(sys_slist_t *observer, /* update observe_node accordingly */ SYS_SLIST_FOR_EACH_CONTAINER(observer, obs, node) { - if (!obs->resource_update) { + if (obs->resource_update) { /* Resource Update on going skip this*/ continue; } From c81924fe7994406ac895a914ef9ee5d38b1f52a5 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 27 Jul 2023 13:13:56 +0300 Subject: [PATCH 438/528] [nrf fromtree] net: lwm2m: Create socketpair that can wake up zsock_poll() Allow socket-loop to wake up immediately, if there are changes, instead of waiting for zsock_poll() to timeout. This change makes engine more reactive and removes hard coded timeout from zsock_poll(). Signed-off-by: Seppo Takalo (cherry picked from commit 1dfa711167bc792867abc9b2504e32df5a330bc3) --- samples/net/lwm2m_client/README.rst | 3 + .../net/lwm2m_client/overlay-tickless.conf | 2 + subsys/net/lib/lwm2m/Kconfig | 14 ++ subsys/net/lib/lwm2m/lwm2m_engine.c | 176 ++++++++++++------ subsys/net/lib/lwm2m/lwm2m_engine.h | 9 + subsys/net/lib/lwm2m/lwm2m_message_handling.c | 2 + subsys/net/lib/lwm2m/lwm2m_observation.c | 1 + tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c | 19 +- 8 files changed, 165 insertions(+), 61 deletions(-) create mode 100644 samples/net/lwm2m_client/overlay-tickless.conf diff --git a/samples/net/lwm2m_client/README.rst b/samples/net/lwm2m_client/README.rst index 6299c097cf62..00ad1a679e28 100644 --- a/samples/net/lwm2m_client/README.rst +++ b/samples/net/lwm2m_client/README.rst @@ -52,6 +52,9 @@ samples/net/lwm2m_client directory: - :file:`overlay-queue.conf` This overlay config can be added to enable LWM2M Queue Mode support. +- :file:`overlay-tickless.conf` + This overlay config can be used to stop LwM2M engine for periodically interrupting socket polls. It can have significant effect on power usage on certain devices. + Build the lwm2m-client sample application like this: .. zephyr-app-commands:: diff --git a/samples/net/lwm2m_client/overlay-tickless.conf b/samples/net/lwm2m_client/overlay-tickless.conf new file mode 100644 index 000000000000..132515f6380f --- /dev/null +++ b/samples/net/lwm2m_client/overlay-tickless.conf @@ -0,0 +1,2 @@ +CONFIG_NET_SOCKETPAIR=y +CONFIG_LWM2M_TICKLESS=y diff --git a/subsys/net/lib/lwm2m/Kconfig b/subsys/net/lib/lwm2m/Kconfig index be770b798031..b33ce66f0853 100644 --- a/subsys/net/lib/lwm2m/Kconfig +++ b/subsys/net/lib/lwm2m/Kconfig @@ -77,6 +77,20 @@ config LWM2M_DNS_SUPPORT bool "DNS support in the LWM2M client" default y if DNS_RESOLVER +choice + prompt "LwM2M Engine operation mode" + default LWM2M_TICKLESS if NET_SOCKETPAIR + default LWM2M_INTERVAL if !NET_SOCKETPAIR + +config LWM2M_TICKLESS + bool "Tickless operation mode" + depends on NET_SOCKETPAIR + +config LWM2M_INTERVAL + bool "Interval based polling mode" + +endchoice + config LWM2M_ENGINE_STACK_SIZE int "LWM2M engine stack size" default 2560 if NET_LOG diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index fa74666f0925..2aeed5a1359e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -73,7 +73,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define THREAD_PRIORITY K_PRIO_PREEMPT(CONFIG_NUM_PREEMPT_PRIORITIES - 1) #endif -#define ENGINE_UPDATE_INTERVAL_MS 500 +#define ENGINE_SLEEP_MS 500 #ifdef CONFIG_LWM2M_VERSION_1_1 #define LWM2M_ENGINE_MAX_OBSERVER_PATH CONFIG_LWM2M_ENGINE_MAX_OBSERVER * 3 @@ -91,7 +91,7 @@ struct service_node { sys_snode_t node; k_work_handler_t service_work; uint32_t min_call_period; /* ms */ - uint64_t last_timestamp; /* ms */ + int64_t last_timestamp; /* ms */ }; static struct service_node service_node_data[MAX_PERIODIC_SERVICE]; @@ -107,6 +107,7 @@ static struct zsock_pollfd sock_fds[MAX_POLL_FD]; static struct lwm2m_ctx *sock_ctx[MAX_POLL_FD]; static int sock_nfds; +static int control_sock; /* Resource wrappers */ #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) @@ -126,6 +127,13 @@ static int lwm2m_socket_update(struct lwm2m_ctx *ctx); /* utility functions */ +void lwm2m_engine_wake_up(void) +{ + if (IS_ENABLED(CONFIG_LWM2M_TICKLESS)) { + zsock_send(control_sock, &(char){0}, 1, 0); + } +} + int lwm2m_open_socket(struct lwm2m_ctx *client_ctx) { if (client_ctx->sock_fd < 0) { @@ -344,14 +352,15 @@ int bootstrap_delete(struct lwm2m_message *msg) return ret; } #endif -/* returns ms until the next retransmission is due, or INT32_MAX + +/* returns timestamp when next retransmission is due, or INT64_MAX * if no retransmissions are necessary */ -static int32_t retransmit_request(struct lwm2m_ctx *client_ctx, const uint32_t timestamp) +static int64_t retransmit_request(struct lwm2m_ctx *client_ctx, const int64_t timestamp) { struct lwm2m_message *msg; struct coap_pending *p; - int32_t remaining, next_retransmission = INT32_MAX; + int64_t remaining, next = INT64_MAX; int i; for (i = 0, p = client_ctx->pendings; i < ARRAY_SIZE(client_ctx->pendings); i++, p++) { @@ -359,8 +368,9 @@ static int32_t retransmit_request(struct lwm2m_ctx *client_ctx, const uint32_t t continue; } - remaining = p->t0 + p->timeout - timestamp; - if (remaining < 0) { + /* TODO: will roll over in 47 days */ + remaining = p->t0 + p->timeout; + if (remaining < timestamp) { msg = find_msg(p, NULL); if (!msg) { LOG_ERR("pending has no valid LwM2M message!"); @@ -386,35 +396,27 @@ static int32_t retransmit_request(struct lwm2m_ctx *client_ctx, const uint32_t t lwm2m_send_message_async(msg); break; } - if (remaining < next_retransmission) { - next_retransmission = remaining; + if (remaining < next) { + next = remaining; } } - return next_retransmission; + return next; } -static int32_t engine_next_service_timeout_ms(uint32_t max_timeout, const int64_t timestamp) +static int64_t engine_next_service_timestamp(void) { struct service_node *srv; - uint64_t time_left_ms; - uint32_t timeout = max_timeout; + int64_t event, next = INT64_MAX; SYS_SLIST_FOR_EACH_CONTAINER(&engine_service_list, srv, node) { - time_left_ms = srv->last_timestamp + srv->min_call_period; - - /* service is due */ - if (time_left_ms < timestamp) { - return 0; - } + event = srv->last_timestamp + srv->min_call_period; - /* service timeout is less than the current timeout */ - time_left_ms -= timestamp; - if (time_left_ms < timeout) { - timeout = time_left_ms; + if (event < next) { + next = event; } } - return timeout; + return next; } int lwm2m_engine_add_service(k_work_handler_t service, uint32_t period_ms) @@ -447,6 +449,8 @@ int lwm2m_engine_add_service(k_work_handler_t service, uint32_t period_ms) sys_slist_append(&engine_service_list, &service_node_data[i].node); + lwm2m_engine_wake_up(); + return 0; } @@ -457,6 +461,7 @@ int lwm2m_engine_update_service_period(k_work_handler_t service, uint32_t period for (i = 0; i < MAX_PERIODIC_SERVICE; i++) { if (service_node_data[i].service_work == service) { service_node_data[i].min_call_period = period_ms; + lwm2m_engine_wake_up(); return 0; } } @@ -464,7 +469,7 @@ int lwm2m_engine_update_service_period(k_work_handler_t service, uint32_t period return -ENOENT; } -static int32_t lwm2m_engine_service(const int64_t timestamp) +static int64_t lwm2m_engine_service(const int64_t timestamp) { struct service_node *srv; int64_t service_due_timestamp; @@ -479,15 +484,22 @@ static int32_t lwm2m_engine_service(const int64_t timestamp) } /* calculate how long to sleep till the next service */ - return engine_next_service_timeout_ms(ENGINE_UPDATE_INTERVAL_MS, timestamp); + return engine_next_service_timestamp(); } /* LwM2M Socket Integration */ int lwm2m_socket_add(struct lwm2m_ctx *ctx) { - if (sock_nfds >= MAX_POLL_FD) { - return -ENOMEM; + if (IS_ENABLED(CONFIG_LWM2M_TICKLESS)) { + /* Last poll-handle is reserved for control socket */ + if (sock_nfds >= (MAX_POLL_FD - 1)) { + return -ENOMEM; + } + } else { + if (sock_nfds >= MAX_POLL_FD) { + return -ENOMEM; + } } sock_ctx[sock_nfds] = ctx; @@ -495,6 +507,8 @@ int lwm2m_socket_add(struct lwm2m_ctx *ctx) sock_fds[sock_nfds].events = ZSOCK_POLLIN; sock_nfds++; + lwm2m_engine_wake_up(); + return 0; } @@ -505,6 +519,7 @@ static int lwm2m_socket_update(struct lwm2m_ctx *ctx) continue; } sock_fds[i].fd = ctx->sock_fd; + lwm2m_engine_wake_up(); return 0; } return -1; @@ -531,6 +546,7 @@ void lwm2m_socket_del(struct lwm2m_ctx *ctx) sock_fds[sock_nfds].fd = -1; break; } + lwm2m_engine_wake_up(); } static void check_notifications(struct lwm2m_ctx *ctx, const int64_t timestamp) @@ -635,10 +651,12 @@ static int socket_send_message(struct lwm2m_ctx *client_ctx) static void socket_reset_pollfd_events(void) { - for (int i = 0; i < sock_nfds; ++i) { + for (int i = 0; i < MAX_POLL_FD; ++i) { sock_fds[i].events = ZSOCK_POLLIN | - (sys_slist_is_empty(&sock_ctx[i]->pending_sends) ? 0 : ZSOCK_POLLOUT); + (!sock_ctx[i] || sys_slist_is_empty(&sock_ctx[i]->pending_sends) + ? 0 + : ZSOCK_POLLOUT); sock_fds[i].revents = 0; } } @@ -647,8 +665,8 @@ static void socket_reset_pollfd_events(void) static void socket_loop(void) { int i, rc; - int64_t timestamp; - int32_t timeout, next_retransmit; + int64_t now, next; + int64_t timeout, next_retransmit; bool rd_client_paused; while (1) { @@ -675,46 +693,53 @@ static void socket_loop(void) } } - timestamp = k_uptime_get(); - timeout = lwm2m_engine_service(timestamp); - - /* wait for sockets */ - if (sock_nfds < 1) { - k_msleep(timeout); - continue; - } + now = k_uptime_get(); + next = lwm2m_engine_service(now); for (i = 0; i < sock_nfds; ++i) { - if (sock_ctx[i] != NULL && - sys_slist_is_empty(&sock_ctx[i]->pending_sends)) { - next_retransmit = retransmit_request(sock_ctx[i], timestamp); - if (next_retransmit < timeout) { - timeout = next_retransmit; - } + if (sock_ctx[i] == NULL) { + continue; + } + if (!sys_slist_is_empty(&sock_ctx[i]->pending_sends)) { + continue; + } + next_retransmit = retransmit_request(sock_ctx[i], now); + if (next_retransmit < next) { + next = next_retransmit; } - if (sock_ctx[i] != NULL && - sys_slist_is_empty(&sock_ctx[i]->pending_sends) && - lwm2m_rd_client_is_registred(sock_ctx[i])) { - check_notifications(sock_ctx[i], timestamp); + if (lwm2m_rd_client_is_registred(sock_ctx[i])) { + check_notifications(sock_ctx[i], now); } } socket_reset_pollfd_events(); - /* - * FIXME: Currently we timeout and restart poll in case fds - * were modified. - */ - rc = zsock_poll(sock_fds, sock_nfds, timeout); + timeout = next > now ? next - now : 0; + if (IS_ENABLED(CONFIG_LWM2M_TICKLESS)) { + /* prevent roll-over */ + timeout = timeout > INT32_MAX ? INT32_MAX : timeout; + } else { + timeout = timeout > ENGINE_SLEEP_MS ? ENGINE_SLEEP_MS : timeout; + } + + rc = zsock_poll(sock_fds, MAX_POLL_FD, timeout); if (rc < 0) { LOG_ERR("Error in poll:%d", errno); errno = 0; - k_msleep(ENGINE_UPDATE_INTERVAL_MS); + k_msleep(ENGINE_SLEEP_MS); continue; } - for (i = 0; i < sock_nfds; i++) { + for (i = 0; i < MAX_POLL_FD; i++) { + if (sock_fds[i].revents & ZSOCK_POLLIN && sock_fds[i].fd != -1 && + sock_ctx[i] == NULL) { + /* This is the control socket, just read and ignore the data */ + char tmp; + + zsock_recv(sock_fds[i].fd, &tmp, 1, 0); + continue; + } if (sock_ctx[i] != NULL && sock_ctx[i]->sock_fd < 0) { continue; } @@ -1135,12 +1160,43 @@ int lwm2m_engine_resume(void) static int lwm2m_engine_init(void) { - int i; - - for (i = 0; i < LWM2M_ENGINE_MAX_OBSERVER_PATH; i++) { + for (int i = 0; i < LWM2M_ENGINE_MAX_OBSERVER_PATH; i++) { sys_slist_append(lwm2m_obs_obj_path_list(), &observe_paths[i].node); } + /* Reset all socket handles to -1 so unused ones are ignored by zsock_poll() */ + for (int i = 0; i < MAX_POLL_FD; ++i) { + sock_fds[i].fd = -1; + } + + if (IS_ENABLED(CONFIG_LWM2M_TICKLESS)) { + /* Create socketpair that is used to wake zsock_poll() in the main loop */ + int s[2]; + int ret = zsock_socketpair(AF_UNIX, SOCK_STREAM, 0, s); + + if (ret) { + LOG_ERR("Error; socketpair() returned %d", ret); + return ret; + } + /* Last poll-handle is reserved for control socket */ + sock_fds[MAX_POLL_FD - 1].fd = s[0]; + control_sock = s[1]; + ret = zsock_fcntl(s[0], F_SETFL, O_NONBLOCK); + if (ret) { + LOG_ERR("zsock_fcntl() %d", ret); + zsock_close(s[0]); + zsock_close(s[1]); + return ret; + } + ret = zsock_fcntl(s[1], F_SETFL, O_NONBLOCK); + if (ret) { + LOG_ERR("zsock_fcntl() %d", ret); + zsock_close(s[0]); + zsock_close(s[1]); + return ret; + } + } + lwm2m_clear_block_contexts(); #if defined(CONFIG_LWM2M_COAP_BLOCK_TRANSFER) (void)memset(output_block_contexts, 0, sizeof(output_block_contexts)); diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.h b/subsys/net/lib/lwm2m/lwm2m_engine.h index 2e589ef15a26..da1f9ef3df55 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.h +++ b/subsys/net/lib/lwm2m/lwm2m_engine.h @@ -306,4 +306,13 @@ int lwm2m_push_queued_buffers(struct lwm2m_ctx *client_ctx); /* Resources */ struct lwm2m_ctx **lwm2m_sock_ctx(void); int lwm2m_sock_nfds(void); + +/** + * @brief Trigger the LwM2M engine to run. + * + * This function wakes up ongoing poll() from the socket-loop. + * It should be called when new transmissions are scheduled or service schedules are modified. + */ +void lwm2m_engine_wake_up(void); + #endif /* LWM2M_ENGINE_H */ diff --git a/subsys/net/lib/lwm2m/lwm2m_message_handling.c b/subsys/net/lib/lwm2m/lwm2m_message_handling.c index 6186f8d50a04..deaf77b92154 100644 --- a/subsys/net/lib/lwm2m/lwm2m_message_handling.c +++ b/subsys/net/lib/lwm2m/lwm2m_message_handling.c @@ -676,6 +676,7 @@ int lwm2m_send_message_async(struct lwm2m_message *msg) if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED)) { engine_update_tx_time(); } + lwm2m_engine_wake_up(); return ret; } @@ -692,6 +693,7 @@ int lwm2m_information_interface_send(struct lwm2m_message *msg) if (msg->ctx->buffer_client_messages) { sys_slist_append(&msg->ctx->queued_messages, &msg->node); + lwm2m_engine_wake_up(); return 0; } #endif diff --git a/subsys/net/lib/lwm2m/lwm2m_observation.c b/subsys/net/lib/lwm2m/lwm2m_observation.c index 696b5e9210f5..91ab9c1709ae 100644 --- a/subsys/net/lib/lwm2m/lwm2m_observation.c +++ b/subsys/net/lib/lwm2m/lwm2m_observation.c @@ -373,6 +373,7 @@ int lwm2m_notify_observer_path(const struct lwm2m_obj_path *path) LOG_DBG("NOTIFY EVENT %u/%u/%u", path->obj_id, path->obj_inst_id, path->res_id); ret++; + lwm2m_engine_wake_up(); } } } diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c index 95790e39cdb0..5632e8fc6c62 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/stubs.c @@ -78,11 +78,24 @@ int z_impl_zsock_close(int sock) return 0; } +#define PAIR_IN 10 +#define PAIR_OUT 11 + +int z_impl_zsock_socketpair(int family, int type, int proto, int *sv) +{ + sv[0] = PAIR_IN; + sv[1] = PAIR_OUT; + return 0; +} + DEFINE_FAKE_VALUE_FUNC(int, z_impl_zsock_connect, int, const struct sockaddr *, socklen_t); ssize_t z_impl_zsock_sendto(int sock, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen) { + if (sock == PAIR_OUT) { + return 1; + } k_sleep(K_MSEC(1)); if (my_events & ZSOCK_POLLOUT) { my_events = 0; @@ -93,6 +106,10 @@ ssize_t z_impl_zsock_sendto(int sock, const void *buf, size_t len, int flags, ssize_t z_impl_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) { + if (sock == PAIR_IN) { + return 1; + } + k_sleep(K_MSEC(1)); if (my_events & ZSOCK_POLLIN) { my_events = 0; @@ -104,7 +121,7 @@ ssize_t z_impl_zsock_recvfrom(int sock, void *buf, size_t max_len, int flags, int z_impl_zsock_poll(struct zsock_pollfd *fds, int nfds, int poll_timeout) { - k_sleep(K_MSEC(poll_timeout)); + k_sleep(K_MSEC(1)); fds->revents = my_events; return 0; } From 421a30eac7af837a948a0f827452587b8ae04ea3 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 27 Jul 2023 16:18:14 +0300 Subject: [PATCH 439/528] [nrf fromtree] net: lwm2m: Add support for non-periodic services Engine now allows registering service callbacks that are called only once on a given timestamp. This allows tickless services to be developed. Signed-off-by: Seppo Takalo (cherry picked from commit 2da8844d190e10f4bc4e4c3536b5d405e1651dcb) --- include/zephyr/net/lwm2m.h | 15 ------ subsys/net/lib/lwm2m/lwm2m_engine.c | 79 ++++++++++++++++++++--------- subsys/net/lib/lwm2m/lwm2m_engine.h | 30 +++++++++++ 3 files changed, 86 insertions(+), 38 deletions(-) diff --git a/include/zephyr/net/lwm2m.h b/include/zephyr/net/lwm2m.h index dea6c1ebb538..6bf0ef0bb371 100644 --- a/include/zephyr/net/lwm2m.h +++ b/include/zephyr/net/lwm2m.h @@ -1911,21 +1911,6 @@ int lwm2m_engine_delete_res_inst(const char *pathstr); */ int lwm2m_delete_res_inst(const struct lwm2m_obj_path *path); -/** - * @brief Update the period of a given service. - * - * Allow the period modification on an existing service created with - * lwm2m_engine_add_service(). - * Example to frequency at which a periodic_service changes it's values : - * lwm2m_engine_update_service(device_periodic_service,5*MSEC_PER_SEC); - * - * @param[in] service Handler of the periodic_service - * @param[in] period_ms New period for the periodic_service (in milliseconds) - * - * @return 0 for success or negative in case of error. - */ -int lwm2m_engine_update_service_period(k_work_handler_t service, uint32_t period_ms); - /** * @brief Update the period of the device service. * diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 2aeed5a1359e..778815b138f5 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -90,8 +90,8 @@ static bool active_engine_thread; struct service_node { sys_snode_t node; k_work_handler_t service_work; - uint32_t min_call_period; /* ms */ - int64_t last_timestamp; /* ms */ + uint32_t call_period; /* ms */ + int64_t next_timestamp; /* ms */ }; static struct service_node service_node_data[MAX_PERIODIC_SERVICE]; @@ -406,20 +406,18 @@ static int64_t retransmit_request(struct lwm2m_ctx *client_ctx, const int64_t ti static int64_t engine_next_service_timestamp(void) { struct service_node *srv; - int64_t event, next = INT64_MAX; + int64_t next = INT64_MAX; SYS_SLIST_FOR_EACH_CONTAINER(&engine_service_list, srv, node) { - event = srv->last_timestamp + srv->min_call_period; - - if (event < next) { - next = event; + if (srv->next_timestamp < next) { + next = srv->next_timestamp; } } return next; } -int lwm2m_engine_add_service(k_work_handler_t service, uint32_t period_ms) +static int engine_add_srv(k_work_handler_t service, uint32_t period_ms, int64_t next) { int i; @@ -444,8 +442,8 @@ int lwm2m_engine_add_service(k_work_handler_t service, uint32_t period_ms) } service_node_data[i].service_work = service; - service_node_data[i].min_call_period = period_ms; - service_node_data[i].last_timestamp = 0U; + service_node_data[i].call_period = period_ms; + service_node_data[i].next_timestamp = next; sys_slist_append(&engine_service_list, &service_node_data[i].node); @@ -454,15 +452,36 @@ int lwm2m_engine_add_service(k_work_handler_t service, uint32_t period_ms) return 0; } +int lwm2m_engine_add_service(k_work_handler_t service, uint32_t period_ms) +{ + return engine_add_srv(service, period_ms, k_uptime_get() + period_ms); +} + +int lwm2m_engine_call_at(k_work_handler_t service, int64_t timestamp) +{ + return engine_add_srv(service, 0, timestamp); +} + +int lwm2m_engine_call_now(k_work_handler_t service) +{ + return engine_add_srv(service, 0, k_uptime_get()); +} + int lwm2m_engine_update_service_period(k_work_handler_t service, uint32_t period_ms) { int i = 0; for (i = 0; i < MAX_PERIODIC_SERVICE; i++) { if (service_node_data[i].service_work == service) { - service_node_data[i].min_call_period = period_ms; - lwm2m_engine_wake_up(); - return 0; + if (period_ms) { + service_node_data[i].call_period = period_ms; + service_node_data[i].next_timestamp = k_uptime_get() + period_ms; + lwm2m_engine_wake_up(); + return 0; + } + sys_slist_find_and_remove(&engine_service_list, &service_node_data[i].node); + service_node_data[i].service_work = NULL; + return 1; } } @@ -471,17 +490,31 @@ int lwm2m_engine_update_service_period(k_work_handler_t service, uint32_t period static int64_t lwm2m_engine_service(const int64_t timestamp) { - struct service_node *srv; - int64_t service_due_timestamp; - - SYS_SLIST_FOR_EACH_CONTAINER(&engine_service_list, srv, node) { - service_due_timestamp = srv->last_timestamp + srv->min_call_period; - /* service is due */ - if (timestamp >= service_due_timestamp) { - srv->last_timestamp = k_uptime_get(); - srv->service_work(NULL); + struct service_node *srv, *tmp; + bool restart; + + do { + restart = false; + SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&engine_service_list, srv, tmp, node) { + /* service is due */ + if (timestamp >= srv->next_timestamp) { + k_work_handler_t work = srv->service_work; + + if (srv->call_period) { + srv->next_timestamp = k_uptime_get() + srv->call_period; + } else { + sys_slist_find_and_remove(&engine_service_list, &srv->node); + srv->service_work = NULL; + } + if (work) { + work(NULL); + } + /* List might have been modified by the callback */ + restart = true; + break; + } } - } + } while (restart); /* calculate how long to sleep till the next service */ return engine_next_service_timestamp(); diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.h b/subsys/net/lib/lwm2m/lwm2m_engine.h index da1f9ef3df55..2306fced197c 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.h +++ b/subsys/net/lib/lwm2m/lwm2m_engine.h @@ -94,6 +94,36 @@ int bootstrap_delete(struct lwm2m_message *msg); */ int lwm2m_engine_add_service(k_work_handler_t service, uint32_t period_ms); +/** + * @brief Update the period of a given service or remove it. + * + * Allow the period modification on an existing service created with + * lwm2m_engine_add_service(). When period is zero, service is removed. + * + * @param[in] service Handler of the periodic_service + * @param[in] period_ms New period for the periodic_service (in milliseconds) or zero. + * + * @return 0 for success, 1 when service was removed or negative in case of error. + */ +int lwm2m_engine_update_service_period(k_work_handler_t service, uint32_t period_ms); + +/** + * @brief Call specific service handler only once at given timestamp. + * + * @param[in] service service to be called + * @param[in] timestamp Time when to call + * @return 0 for success or negative in case of error + */ +int lwm2m_engine_call_at(k_work_handler_t service, int64_t timestamp); + +/** + * @brief Call given handler from engine context. + * + * @param[in] service Service callback to be called. + * @return 0 for success or negative in case of error + */ +int lwm2m_engine_call_now(k_work_handler_t service); + /** * @brief Returns the index in the security objects list corresponding to the object instance * id given by @p obj_inst_id From 1825f0b8a4daeeb818f2007db513eeabfe999cf9 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 27 Jul 2023 16:35:05 +0300 Subject: [PATCH 440/528] [nrf fromtree] net: lwm2m: Refactor RD client to be tickless Call RD client service only when there is state transitioning. Remove periodic 500 ms timer. Signed-off-by: Seppo Takalo (cherry picked from commit 518bbc130327bfa0463a2b075d7f88b1b233990a) --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 72 ++++++++++++++----- .../net/lib/lwm2m/lwm2m_rd_client/src/main.c | 22 ++---- .../net/lib/lwm2m/lwm2m_rd_client/src/stubs.c | 25 ++++--- .../net/lib/lwm2m/lwm2m_rd_client/src/stubs.h | 3 - 4 files changed, 75 insertions(+), 47 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index 3686b8855a24..6bdaad2078d3 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -64,18 +64,16 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #include "lwm2m_util.h" #define LWM2M_RD_CLIENT_URI "rd" - #define SECONDS_TO_UPDATE_EARLY CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY -#define STATE_MACHINE_UPDATE_INTERVAL_MS 500 - #define CLIENT_EP_LEN CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH - #define CLIENT_BINDING_LEN sizeof("UQ") #define CLIENT_QUEUE_LEN sizeof("Q") static void sm_handle_registration_update_failure(void); static int sm_send_registration_msg(void); static bool sm_is_suspended(void); +static void lwm2m_rd_client_service(struct k_work *work); +static int64_t calc_next_event(void); /* The states for the RD client state machine */ /* @@ -117,6 +115,7 @@ struct lwm2m_rd_client_info { int64_t last_update; int64_t last_tx; + int64_t next_event; char ep_name[CLIENT_EP_LEN]; char server_ep[CLIENT_EP_LEN]; @@ -167,6 +166,11 @@ void engine_update_tx_time(void) client.last_tx = k_uptime_get(); } +static void next_event_at(int64_t timestamp) +{ + (void)lwm2m_engine_call_at(lwm2m_rd_client_service, timestamp); +} + static void set_sm_state(uint8_t sm_state) { k_mutex_lock(&client.mutex, K_FOREVER); @@ -228,6 +232,7 @@ static void set_sm_state(uint8_t sm_state) lwm2m_close_socket(client.ctx); } } + next_event_at(0); k_mutex_unlock(&client.mutex); } @@ -453,6 +458,7 @@ int engine_trigger_bootstrap(void) client.use_bootstrap = true; client.trigger_update = false; client.engine_state = ENGINE_INIT; + next_event_at(0); k_mutex_unlock(&client.mutex); return 0; #else @@ -1000,6 +1006,7 @@ static void sm_handle_registration_update_failure(void) client.engine_state = ENGINE_SEND_REGISTRATION; lwm2m_engine_context_close(client.ctx); k_mutex_unlock(&client.mutex); + next_event_at(0); } static int sm_send_registration_msg(void) @@ -1079,28 +1086,49 @@ static int sm_do_registration(void) return ret; } -static int sm_registration_done(void) +static int64_t next_update(void) { - k_mutex_lock(&client.mutex, K_FOREVER); - int ret = 0; - /* * check for lifetime seconds - SECONDS_TO_UPDATE_EARLY * so that we can update early and avoid lifetime timeout */ + return client.last_update + (client.lifetime - SECONDS_TO_UPDATE_EARLY) * 1000; +} + +static int64_t next_rx_off(void) +{ + if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED)) { + return client.last_tx + CONFIG_LWM2M_QUEUE_MODE_UPTIME * 1000; + } else { + return next_update(); + } +} + +/** Return timestamp to next even whether it is RX_OFF or update event */ +static int64_t calc_next_event(void) +{ + return Z_MIN(next_update(), next_rx_off()); +} + +static void sm_registration_done(void) +{ + k_mutex_lock(&client.mutex, K_FOREVER); + + int64_t now = k_uptime_get(); + if (sm_is_registered() && (client.trigger_update || - ((client.lifetime - SECONDS_TO_UPDATE_EARLY) <= - (k_uptime_get() - client.last_update) / 1000))) { + now >= next_update())) { set_sm_state(ENGINE_UPDATE_REGISTRATION); } else if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED) && (client.engine_state != ENGINE_REGISTRATION_DONE_RX_OFF) && - (((k_uptime_get() - client.last_tx) / 1000) >= - CONFIG_LWM2M_QUEUE_MODE_UPTIME)) { + (now >= next_rx_off())) { set_sm_state(ENGINE_REGISTRATION_DONE_RX_OFF); + next_event_at(next_update()); + } else { + next_event_at(calc_next_event()); } k_mutex_unlock(&client.mutex); - return ret; } static int update_registration(void) @@ -1214,7 +1242,9 @@ static void sm_do_network_error(void) { int err; - if (--client.retry_delay > 0) { + if (client.retry_delay) { + client.retry_delay = 0; + next_event_at(k_uptime_get() + client.retry_delay * 1000); return; } @@ -1252,6 +1282,7 @@ static void lwm2m_rd_client_service(struct k_work *work) k_mutex_lock(&client.mutex, K_FOREVER); if (client.ctx) { + LOG_DBG("State: %d", get_sm_state()); switch (get_sm_state()) { case ENGINE_IDLE: if (client.ctx->sock_fd > -1) { @@ -1374,7 +1405,10 @@ int lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name, client.ep_name[CLIENT_EP_LEN - 1] = '\0'; LOG_INF("Start LWM2M Client: %s", client.ep_name); + next_event_at(0); + k_mutex_unlock(&client.mutex); + return 0; } @@ -1402,12 +1436,14 @@ int lwm2m_rd_client_stop(struct lwm2m_ctx *client_ctx, k_mutex_unlock(&client.mutex); + return 0; } int lwm2m_rd_client_pause(void) { enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED; + LOG_DBG("lwm2m_rd_client_pause()"); k_mutex_lock(&client.mutex, K_FOREVER); @@ -1482,6 +1518,7 @@ int lwm2m_rd_client_resume(void) } } + next_event_at(0); k_mutex_unlock(&client.mutex); return 0; @@ -1490,6 +1527,7 @@ int lwm2m_rd_client_resume(void) void lwm2m_rd_client_update(void) { engine_trigger_update(false); + next_event_at(0); } struct lwm2m_ctx *lwm2m_rd_client_ctx(void) @@ -1520,6 +1558,7 @@ int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx) client.engine_state = ENGINE_DO_REGISTRATION; } } + next_event_at(0); return 0; } @@ -1536,6 +1575,7 @@ int lwm2m_rd_client_timeout(struct lwm2m_ctx *client_ctx) k_mutex_lock(&client.mutex, K_FOREVER); LOG_WRN("Confirmable Timeout -> Re-connect and register"); client.engine_state = ENGINE_DO_REGISTRATION; + next_event_at(0); k_mutex_unlock(&client.mutex); return 0; } @@ -1565,9 +1605,7 @@ int lwm2m_rd_client_init(void) client.engine_state = ENGINE_IDLE; k_mutex_init(&client.mutex); - return lwm2m_engine_add_service(lwm2m_rd_client_service, - STATE_MACHINE_UPDATE_INTERVAL_MS); - + return 0; } static int sys_lwm2m_rd_client_init(void) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c index 4d20c3700f27..91f7a18776fa 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -167,7 +167,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -198,10 +197,8 @@ ZTEST(lwm2m_rd_client, test_timeout_resume_registration) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); - wait_for_service(1); lwm2m_get_bool_fake.custom_fake = lwm2m_get_bool_fake_default; lwm2m_sprint_ip_addr_fake.custom_fake = lwm2m_sprint_ip_addr_fake_default; @@ -228,7 +225,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_timeout) test_prepare_pending_message_cb(&message_reply_timeout_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -250,7 +246,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_fail) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -272,7 +267,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -300,7 +294,6 @@ ZTEST(lwm2m_rd_client, test_rx_off) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -329,7 +322,6 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -359,7 +351,6 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -376,12 +367,12 @@ ZTEST(lwm2m_rd_client, test_registration_update_timeout) test_prepare_pending_message_cb(&message_reply_timeout_cb_default); lwm2m_rd_client_update(); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE, 2)); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT, 3), + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE, 1)); + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT, 2), NULL); test_prepare_pending_message_cb(&message_reply_cb_default); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE, 4), + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE, 3), NULL); } @@ -393,7 +384,6 @@ ZTEST(lwm2m_rd_client, test_deregistration_timeout) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -421,7 +411,6 @@ ZTEST(lwm2m_rd_client, test_error_on_registration_update) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -448,7 +437,6 @@ ZTEST(lwm2m_rd_client, test_network_error_on_registration) (void)memset(&ctx, 0x0, sizeof(ctx)); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -461,6 +449,8 @@ ZTEST(lwm2m_rd_client, test_network_error_on_registration) coap_packet_append_option_fake.custom_fake = coap_packet_append_option_fake_err; zassert_true(lwm2m_rd_client_start(&ctx, "Test", 0, lwm2m_event_cb, lwm2m_observe_cb) == 0, NULL); + wait_for_service(100); + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR, 0), NULL); } @@ -472,7 +462,6 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); @@ -506,7 +495,6 @@ ZTEST(lwm2m_rd_client, test_socket_error) test_prepare_pending_message_cb(&message_reply_cb_default); - lwm2m_engine_add_service_fake.custom_fake = lwm2m_engine_add_service_fake_default; lwm2m_rd_client_init(); test_lwm2m_engine_start_service(); wait_for_service(1); diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c index c0df43d3b931..72c59de8c6f8 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c @@ -80,14 +80,14 @@ char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr) DEFINE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t); DEFINE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int); -DEFINE_FAKE_VALUE_FUNC(int, lwm2m_engine_add_service, k_work_handler_t, uint32_t); -k_work_handler_t lwm2m_engine_add_service_service; -uint32_t lwm2m_engine_add_service_period_ms = 20; -int lwm2m_engine_add_service_fake_default(k_work_handler_t service, uint32_t period_ms) +k_work_handler_t service; +int64_t next; + +int lwm2m_engine_call_at(k_work_handler_t work, int64_t timestamp) { - lwm2m_engine_add_service_service = service; - lwm2m_engine_add_service_period_ms = period_ms; + service = work; + next = timestamp ? timestamp : 1; return 0; } @@ -97,18 +97,23 @@ void *(*pending_message_cb)(); static void service_work_fn(struct k_work *work) { - while (lwm2m_engine_add_service_service != NULL) { + while (true) { if (pending_message != NULL && pending_message_cb != NULL) { pending_message_cb(pending_message); pending_message = NULL; } - lwm2m_engine_add_service_service(work); - k_sleep(K_MSEC(lwm2m_engine_add_service_period_ms)); + if (next && next < k_uptime_get()) { + printk("Event!\n"); + next = 0; + service(NULL); + } + k_sleep(K_MSEC(10)); counter--; /* avoid endless loop if rd client is stuck somewhere */ if (counter == 0) { + printk("Counter!\n"); break; } } @@ -119,7 +124,7 @@ void wait_for_service(uint16_t cycles) uint16_t end = counter - cycles; while (counter > end) { - k_sleep(K_MSEC(1)); + k_sleep(K_MSEC(10)); } } diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h index 70c073afbdbc..d15b40f3e444 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.h @@ -61,8 +61,6 @@ DECLARE_FAKE_VALUE_FUNC(char *, lwm2m_sprint_ip_addr, const struct sockaddr *); char *lwm2m_sprint_ip_addr_fake_default(const struct sockaddr *addr); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_server_short_id_to_inst, uint16_t); DECLARE_FAKE_VALUE_FUNC(int, lwm2m_security_index_to_inst_id, int); -DECLARE_FAKE_VALUE_FUNC(int, lwm2m_engine_add_service, k_work_handler_t, uint32_t); -int lwm2m_engine_add_service_fake_default(k_work_handler_t service, uint32_t period_ms); void wait_for_service(uint16_t cycles); void test_lwm2m_engine_start_service(void); void test_lwm2m_engine_stop_service(void); @@ -107,7 +105,6 @@ DECLARE_FAKE_VALUE_FUNC(int, do_register_op_link_format, struct lwm2m_message *) FUNC(lwm2m_sprint_ip_addr) \ FUNC(lwm2m_server_short_id_to_inst) \ FUNC(lwm2m_security_index_to_inst_id) \ - FUNC(lwm2m_engine_add_service) \ FUNC(lwm2m_init_message) \ FUNC(lwm2m_reset_message) \ FUNC(lwm2m_send_message_async) \ From 9cd211de4cbb8f2982d5899c4cb2d8f4e321cc4e Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 1 Aug 2023 12:31:30 +0300 Subject: [PATCH 441/528] [nrf fromtree] net: coap: Use 64bit timestamps Use 64bit timestamps from k_uptime_get() so they don't roll over during the expected device lifetime. Fixes #60826 Signed-off-by: Seppo Takalo (cherry picked from commit 838ab80bca0c1460ff27aa78d58dc03ae39fdfd1) --- include/zephyr/net/coap.h | 2 +- samples/net/sockets/coap_server/src/coap-server.c | 4 ++-- subsys/net/lib/coap/coap.c | 6 +++--- subsys/net/lib/lwm2m/lwm2m_engine.c | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/zephyr/net/coap.h b/include/zephyr/net/coap.h index 216278fd3447..d06a7b23dcd1 100644 --- a/include/zephyr/net/coap.h +++ b/include/zephyr/net/coap.h @@ -269,7 +269,7 @@ typedef int (*coap_reply_t)(const struct coap_packet *response, */ struct coap_pending { struct sockaddr addr; - uint32_t t0; + int64_t t0; uint32_t timeout; uint16_t id; uint8_t *data; diff --git a/samples/net/sockets/coap_server/src/coap-server.c b/samples/net/sockets/coap_server/src/coap-server.c index 0d126bf28d98..fbd112da5eac 100644 --- a/samples/net/sockets/coap_server/src/coap-server.c +++ b/samples/net/sockets/coap_server/src/coap-server.c @@ -954,8 +954,8 @@ static int large_create_post(struct coap_resource *resource, static void schedule_next_retransmission(void) { struct coap_pending *pending; - int32_t remaining; - uint32_t now = k_uptime_get_32(); + int64_t remaining; + int64_t now = k_uptime_get(); /* Get the first pending retransmission to expire after cycling. */ pending = coap_pending_next_to_expire(pendings, NUM_PENDINGS); diff --git a/subsys/net/lib/coap/coap.c b/subsys/net/lib/coap/coap.c index b0a30510fba7..a4dab38eee80 100644 --- a/subsys/net/lib/coap/coap.c +++ b/subsys/net/lib/coap/coap.c @@ -1287,7 +1287,7 @@ int coap_pending_init(struct coap_pending *pending, pending->data = request->data; pending->len = request->offset; - pending->t0 = k_uptime_get_32(); + pending->t0 = k_uptime_get(); pending->retries = retries; return 0; @@ -1382,7 +1382,7 @@ struct coap_pending *coap_pending_next_to_expire( { struct coap_pending *p, *found = NULL; size_t i; - uint32_t expiry, min_expiry; + int64_t expiry, min_expiry = INT64_MAX; for (i = 0, p = pendings; i < len; i++, p++) { if (!p->timeout) { @@ -1391,7 +1391,7 @@ struct coap_pending *coap_pending_next_to_expire( expiry = p->t0 + p->timeout; - if (!found || (int32_t)(expiry - min_expiry) < 0) { + if (expiry < min_expiry) { min_expiry = expiry; found = p; } diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 778815b138f5..27a625105cda 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -368,7 +368,6 @@ static int64_t retransmit_request(struct lwm2m_ctx *client_ctx, const int64_t ti continue; } - /* TODO: will roll over in 47 days */ remaining = p->t0 + p->timeout; if (remaining < timestamp) { msg = find_msg(p, NULL); From 973e7a97aa56276d39177b29339982a6d8f36998 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 26 Jun 2023 16:50:37 +0300 Subject: [PATCH 442/528] [nrf fromtree] tests: lwm2m: Fix too small test buffer ZTEST(lwm2m_registry, test_strings) is using opaque resource 0/0/3 to write a test string "coap://127.0.0.1" which happens to be same length as default key size. Need more room to add end marker and verify it. Signed-off-by: Seppo Takalo (cherry picked from commit 14573fcbf6e38779613418f7b106d701be146ac8) --- tests/net/lib/lwm2m/lwm2m_registry/prj.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/net/lib/lwm2m/lwm2m_registry/prj.conf b/tests/net/lib/lwm2m/lwm2m_registry/prj.conf index 3bbd185d38b5..1825b4175bcc 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_registry/prj.conf @@ -9,6 +9,7 @@ CONFIG_NEWLIB_LIBC=y CONFIG_LWM2M=y CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512 +CONFIG_LWM2M_SECURITY_KEY_SIZE=32 CONFIG_LWM2M_IPSO_SUPPORT=y CONFIG_LWM2M_IPSO_TEMP_SENSOR=y CONFIG_LWM2M_IPSO_TEMP_SENSOR_VERSION_1_1=y From 5ef5dbe9f5dabca7c222d94e3f65586ce0eb72b5 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 19 Jun 2023 13:18:23 +0300 Subject: [PATCH 443/528] [nrf fromtree] test: net: lwm2m: Fix build warning about unitialized Few variables were uninitialized on certain cases. Signed-off-by: Seppo Takalo (cherry picked from commit 0f6ded79898713ea261c76098fb112822902263b) --- tests/net/lib/lwm2m/engine/src/lwm2m_observation.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/net/lib/lwm2m/engine/src/lwm2m_observation.c b/tests/net/lib/lwm2m/engine/src/lwm2m_observation.c index 8106d7180b3d..9371702b2e90 100644 --- a/tests/net/lib/lwm2m/engine/src/lwm2m_observation.c +++ b/tests/net/lib/lwm2m/engine/src/lwm2m_observation.c @@ -49,10 +49,10 @@ static void assert_path_list_order(sys_slist_t *lwm2m_path_list) struct lwm2m_obj_path_list *prev = NULL; struct lwm2m_obj_path_list *entry, *tmp; - uint16_t obj_id_max; - uint16_t obj_inst_id_max; - uint16_t res_id_max; - uint16_t res_inst_id_max; + uint16_t obj_id_max = 0; + uint16_t obj_inst_id_max = 0; + uint16_t res_id_max = 0; + uint16_t res_inst_id_max = 0; if (sys_slist_is_empty(lwm2m_path_list)) { return; From 8cb6e033f5bf9a2b9145524bd431ba645d85fccd Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Wed, 21 Jun 2023 13:15:47 +0300 Subject: [PATCH 444/528] [nrf fromtree] tests: net: lwm2m: Remove timing sensitive assert As the lwm2m_reset_message() is stubbed, it does not remove a message from rettry queue. Therefore depending on the simulation speed, retries can happen one or many times. Signed-off-by: Seppo Takalo (cherry picked from commit e92f8acff91fa2cf75eea51808e65e71439335d9) --- tests/net/lib/lwm2m/lwm2m_engine/src/main.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c index 86811fec805e..6e432f6dca8b 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_engine/src/main.c @@ -57,7 +57,6 @@ static int lwm2m_get_bool_custom_fake(const struct lwm2m_obj_path *path, bool *v static void test_service(struct k_work *work) { - LOG_INF("Test service"); k_sleep(K_MSEC(10)); } @@ -339,8 +338,8 @@ ZTEST(lwm2m_engine, test_retransmit_request) k_sleep(K_MSEC(500)); ret = lwm2m_engine_stop(&ctx); zassert_equal(ret, 0); - zassert_equal(lwm2m_reset_message_fake.call_count, 1, "Message was not reseted"); - zassert_equal(lwm2m_send_message_async_fake.call_count, 1, "Message was not sent"); + zassert_not_equal(lwm2m_reset_message_fake.call_count, 0, "Message was not reseted"); + zassert_not_equal(lwm2m_send_message_async_fake.call_count, 0, "Message was not sent"); } ZTEST(lwm2m_engine, test_socket_recv) From c9d01d05ce83a8cec0fd60bf8e2ba27c1534d08f Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Mon, 19 Jun 2023 13:16:30 +0300 Subject: [PATCH 445/528] [nrf fromtree] tests: net: lwm2m: Remove unnecessary filtering Content-format tests do not require network or Newlibc, so by removing these filters. Defined a native_posix as the only integration platform because all simulated arm-zephyr-eabi platforms are filtered out by Twister. Signed-off-by: Seppo Takalo (cherry picked from commit a7498c39e2d34d33a463fc861f1f39f0a626b8da) --- tests/net/lib/lwm2m/block_transfer/testcase.yaml | 10 +++++++--- tests/net/lib/lwm2m/content_json/prj.conf | 2 -- tests/net/lib/lwm2m/content_json/testcase.yaml | 7 ++++--- tests/net/lib/lwm2m/content_link_format/prj.conf | 2 -- tests/net/lib/lwm2m/content_link_format/testcase.yaml | 7 ++++--- tests/net/lib/lwm2m/content_oma_tlv/prj.conf | 2 -- tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml | 7 ++++--- tests/net/lib/lwm2m/content_plain_text/prj.conf | 2 -- tests/net/lib/lwm2m/content_plain_text/testcase.yaml | 7 ++++--- tests/net/lib/lwm2m/content_raw_cbor/prj.conf | 2 -- tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml | 7 ++++--- tests/net/lib/lwm2m/content_senml_cbor/prj.conf | 2 -- tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml | 7 ++++--- tests/net/lib/lwm2m/engine/prj.conf | 1 - tests/net/lib/lwm2m/engine/testcase.yaml | 7 ++++--- tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml | 7 ++++--- tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml | 11 +++-------- tests/net/lib/lwm2m/lwm2m_registry/prj.conf | 2 -- tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml | 7 ++++--- 19 files changed, 46 insertions(+), 53 deletions(-) diff --git a/tests/net/lib/lwm2m/block_transfer/testcase.yaml b/tests/net/lib/lwm2m/block_transfer/testcase.yaml index 55a40d517eb4..66f145fd18fb 100644 --- a/tests/net/lib/lwm2m/block_transfer/testcase.yaml +++ b/tests/net/lib/lwm2m/block_transfer/testcase.yaml @@ -1,5 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.block_transfer: - tags: lwm2m net + platform_key: + - simulation + tags: + - lwm2m + - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/content_json/prj.conf b/tests/net/lib/lwm2m/content_json/prj.conf index 5f99626db5fb..3f2cd3e60f24 100644 --- a/tests/net/lib/lwm2m/content_json/prj.conf +++ b/tests/net/lib/lwm2m/content_json/prj.conf @@ -5,8 +5,6 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NEWLIB_LIBC=y - CONFIG_LWM2M=y CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512 CONFIG_LWM2M_RW_JSON_SUPPORT=y diff --git a/tests/net/lib/lwm2m/content_json/testcase.yaml b/tests/net/lib/lwm2m/content_json/testcase.yaml index 2004897b6e20..a283ce908ef6 100644 --- a/tests/net/lib/lwm2m/content_json/testcase.yaml +++ b/tests/net/lib/lwm2m/content_json/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.content_json: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + platform_key: + - simulation tags: - lwm2m - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/content_link_format/prj.conf b/tests/net/lib/lwm2m/content_link_format/prj.conf index b70c6003eef6..952b54a4566a 100644 --- a/tests/net/lib/lwm2m/content_link_format/prj.conf +++ b/tests/net/lib/lwm2m/content_link_format/prj.conf @@ -5,8 +5,6 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NEWLIB_LIBC=y - CONFIG_LWM2M=y CONFIG_LWM2M_RW_JSON_SUPPORT=y CONFIG_JSON_LIBRARY=y diff --git a/tests/net/lib/lwm2m/content_link_format/testcase.yaml b/tests/net/lib/lwm2m/content_link_format/testcase.yaml index c075d55edf3c..5448cf68fd05 100644 --- a/tests/net/lib/lwm2m/content_link_format/testcase.yaml +++ b/tests/net/lib/lwm2m/content_link_format/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.content_link_format: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + platform_key: + - simulation tags: - lwm2m - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/content_oma_tlv/prj.conf b/tests/net/lib/lwm2m/content_oma_tlv/prj.conf index 9c9cec3be7c5..6041addad837 100644 --- a/tests/net/lib/lwm2m/content_oma_tlv/prj.conf +++ b/tests/net/lib/lwm2m/content_oma_tlv/prj.conf @@ -5,6 +5,4 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NEWLIB_LIBC=y - CONFIG_LWM2M=y diff --git a/tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml b/tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml index 710858883677..2bf877f73537 100644 --- a/tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml +++ b/tests/net/lib/lwm2m/content_oma_tlv/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.content_oma_tlv: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + platform_key: + - simulation tags: - lwm2m - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/content_plain_text/prj.conf b/tests/net/lib/lwm2m/content_plain_text/prj.conf index 9c9cec3be7c5..6041addad837 100644 --- a/tests/net/lib/lwm2m/content_plain_text/prj.conf +++ b/tests/net/lib/lwm2m/content_plain_text/prj.conf @@ -5,6 +5,4 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NEWLIB_LIBC=y - CONFIG_LWM2M=y diff --git a/tests/net/lib/lwm2m/content_plain_text/testcase.yaml b/tests/net/lib/lwm2m/content_plain_text/testcase.yaml index cc902805c829..bd70dd790b30 100644 --- a/tests/net/lib/lwm2m/content_plain_text/testcase.yaml +++ b/tests/net/lib/lwm2m/content_plain_text/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.content_plain_text: - filter: TOOLCHAIN_HAS_NEWLIB == 1 + platform_key: + - simulation tags: - lwm2m - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/content_raw_cbor/prj.conf b/tests/net/lib/lwm2m/content_raw_cbor/prj.conf index 0fae8dcbbeb4..64ab6f89d22a 100644 --- a/tests/net/lib/lwm2m/content_raw_cbor/prj.conf +++ b/tests/net/lib/lwm2m/content_raw_cbor/prj.conf @@ -5,8 +5,6 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NEWLIB_LIBC=y - CONFIG_LWM2M=y CONFIG_LWM2M_VERSION_1_1=y CONFIG_LWM2M_RW_CBOR_SUPPORT=y diff --git a/tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml b/tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml index 13a564aa97d4..9fc90f109bc0 100644 --- a/tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml +++ b/tests/net/lib/lwm2m/content_raw_cbor/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.content_raw_cbor: - platform_allow: native_posix + platform_key: + - simulation tags: - lwm2m - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/content_senml_cbor/prj.conf b/tests/net/lib/lwm2m/content_senml_cbor/prj.conf index d6bdaceb9345..27a8364af588 100644 --- a/tests/net/lib/lwm2m/content_senml_cbor/prj.conf +++ b/tests/net/lib/lwm2m/content_senml_cbor/prj.conf @@ -5,8 +5,6 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NEWLIB_LIBC=y - CONFIG_LWM2M=y CONFIG_LWM2M_VERSION_1_1=y CONFIG_LWM2M_RW_CBOR_SUPPORT=y diff --git a/tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml b/tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml index 4d2db6e5838b..55cd89a9f51b 100644 --- a/tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml +++ b/tests/net/lib/lwm2m/content_senml_cbor/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.content_senml_cbor: - platform_allow: native_posix + platform_key: + - simulation tags: - lwm2m - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/engine/prj.conf b/tests/net/lib/lwm2m/engine/prj.conf index 18a5df2ad223..4477075056a5 100644 --- a/tests/net/lib/lwm2m/engine/prj.conf +++ b/tests/net/lib/lwm2m/engine/prj.conf @@ -5,7 +5,6 @@ CONFIG_ZTEST_NEW_API=y CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NEWLIB_LIBC=y CONFIG_LWM2M=y CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512 diff --git a/tests/net/lib/lwm2m/engine/testcase.yaml b/tests/net/lib/lwm2m/engine/testcase.yaml index 28047c0fa5f4..3263441b418d 100644 --- a/tests/net/lib/lwm2m/engine/testcase.yaml +++ b/tests/net/lib/lwm2m/engine/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.engine: - platform_allow: native_posix + platform_key: + - simulation tags: - lwm2m - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml b/tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml index 9f58cafdea44..a7f628405ebf 100644 --- a/tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml +++ b/tests/net/lib/lwm2m/lwm2m_engine/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.lwm2m_engine: - platform_allow: native_posix + platform_key: + - simulation tags: - lwm2m - net + integration_platforms: + - native_posix diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml b/tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml index 7e6415395ca9..b5f21f0d9dc5 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/testcase.yaml @@ -1,16 +1,11 @@ common: - depends_on: netif + platform_key: + - simulation tags: - - net - lwm2m - platform_allow: - - native_posix - - qemu_x86 - - qemu_x86_64 + - net integration_platforms: - native_posix - - qemu_x86 - tests: net.lwm2m.lwm2m_rd_client: extra_args: EXTRA_CFLAGS="" diff --git a/tests/net/lib/lwm2m/lwm2m_registry/prj.conf b/tests/net/lib/lwm2m/lwm2m_registry/prj.conf index 1825b4175bcc..0b7b96721227 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/prj.conf +++ b/tests/net/lib/lwm2m/lwm2m_registry/prj.conf @@ -2,10 +2,8 @@ CONFIG_NETWORKING=y CONFIG_NET_TEST=y CONFIG_ZTEST=y CONFIG_ZTEST_NEW_API=y - CONFIG_ENTROPY_GENERATOR=y CONFIG_TEST_RANDOM_GENERATOR=y -CONFIG_NEWLIB_LIBC=y CONFIG_LWM2M=y CONFIG_LWM2M_COAP_MAX_MSG_SIZE=512 diff --git a/tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml b/tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml index b0fda561cff3..ca0f06f58b57 100644 --- a/tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml +++ b/tests/net/lib/lwm2m/lwm2m_registry/testcase.yaml @@ -1,8 +1,9 @@ -common: - depends_on: netif tests: net.lwm2m.lwm2m_registry: + platform_key: + - simulation tags: - lwm2m - net - filter: TOOLCHAIN_HAS_NEWLIB == 1 + integration_platforms: + - native_posix From bfe60a4c636de2f59553344797fa6f6ddfcd3383 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 9 Aug 2023 09:10:02 +0200 Subject: [PATCH 446/528] [nrf fromtree] nrf52_bsim: IRQ handling: dont swap if kernel is uninitialized After an interrupt, do not attempt to swap if the kernel is not yet initialized. Otherwise, if an interrupt is raised with interrupts unlocked while the kernel is not yet fully initialized, a swap would lead to a crash. (This could happen if a PREKERNEK1/2 driver enables interrupts and an interrupt fires before the kernel has swapped to main) Signed-off-by: Alberto Escolar Piedras (cherry picked from commit b6e32e441503e7bbc1b075a1e3d14efa3b0d2245) --- boards/posix/nrf52_bsim/irq_handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/posix/nrf52_bsim/irq_handler.c b/boards/posix/nrf52_bsim/irq_handler.c index c14d197daa88..497ba37e57de 100644 --- a/boards/posix/nrf52_bsim/irq_handler.c +++ b/boards/posix/nrf52_bsim/irq_handler.c @@ -126,7 +126,7 @@ void posix_irq_handler(void) if (may_swap && (hw_irq_ctrl_get_cur_prio() == 256) && (CPU_will_be_awaken_from_WFE == false) - && (_kernel.ready_q.cache != _current)) { + && (_kernel.ready_q.cache) && (_kernel.ready_q.cache != _current)) { z_swap_irqlock(irq_lock); } From 0b2a4fd8d08ca727de726cdbf805ef19e98f712f Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 9 Aug 2023 09:23:15 +0200 Subject: [PATCH 447/528] [nrf fromtree] native_posix: IRQ handling: dont swap if kernel is uninitialized After an interrupt, do not attempt to swap if the kernel is not yet initialized. Otherwise, if an interrupt is raised with interrupts unlocked while the kernel is not yet fully initialized, a swap would lead to a crash. (This could happen if a PREKERNEK1/2 driver enables interrupts and an interrupt fires before the kernel has swapped to main) Signed-off-by: Alberto Escolar Piedras (cherry picked from commit dcd6ee518867de3d2ff02f5b9dea084feef17821) --- boards/posix/native_posix/irq_handler.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boards/posix/native_posix/irq_handler.c b/boards/posix/native_posix/irq_handler.c index 2c962fc79ca5..785851aa524b 100644 --- a/boards/posix/native_posix/irq_handler.c +++ b/boards/posix/native_posix/irq_handler.c @@ -105,7 +105,7 @@ void posix_irq_handler(void) */ if (may_swap && (hw_irq_ctrl_get_cur_prio() == 256) - && (_kernel.ready_q.cache != _current)) { + && (_kernel.ready_q.cache) && (_kernel.ready_q.cache != _current)) { (void)z_swap_irqlock(irq_lock); } From a4313bc1a1c31f5c85a807f528d8b027f0c4fe3b Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 10 Aug 2023 14:30:16 +0300 Subject: [PATCH 448/528] [nrf fromlist] net: lwm2m: Wake up engine on pause/resume Engine wake-up call was missing from pause/resume APIs which caused delay. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/61370 Signed-off-by: Seppo Takalo (cherry picked from commit cb46ff519aa7e99f96955b1150a8d3fd54925a75) --- subsys/net/lib/lwm2m/lwm2m_engine.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/subsys/net/lib/lwm2m/lwm2m_engine.c b/subsys/net/lib/lwm2m/lwm2m_engine.c index 27a625105cda..91d8c3bd605e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_engine.c +++ b/subsys/net/lib/lwm2m/lwm2m_engine.c @@ -1167,6 +1167,7 @@ int lwm2m_engine_pause(void) } suspend_engine_thread = true; + lwm2m_engine_wake_up(); while (active_engine_thread) { k_msleep(10); @@ -1183,6 +1184,7 @@ int lwm2m_engine_resume(void) } k_thread_resume(engine_thread_id); + lwm2m_engine_wake_up(); while (!active_engine_thread) { k_msleep(10); } From 99794f65709ef86eea49852fe5bc57178fbd50cb Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 10 Aug 2023 14:38:33 +0300 Subject: [PATCH 449/528] [nrf fromlist] net: lwm2m: All state changes should go through set_sm_state() Some state changes were do by directly writing into client.engine_state variable, followed by call next_event_at(0); This causes hard-to-find side effects. Refactor all state transitions to use set_sm_state() to have better control for it. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/61370 Signed-off-by: Seppo Takalo (cherry picked from commit b55a3b9ca9de116e87a71b1ace05e3ded9dae055) --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index 6bdaad2078d3..6a2f0486b21e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -457,8 +457,7 @@ int engine_trigger_bootstrap(void) rd_client_message_free(); client.use_bootstrap = true; client.trigger_update = false; - client.engine_state = ENGINE_INIT; - next_event_at(0); + set_sm_state(ENGINE_INIT); k_mutex_unlock(&client.mutex); return 0; #else @@ -1003,10 +1002,9 @@ static void sm_handle_registration_update_failure(void) { k_mutex_lock(&client.mutex, K_FOREVER); LOG_WRN("Registration Update fail -> trigger full registration"); - client.engine_state = ENGINE_SEND_REGISTRATION; lwm2m_engine_context_close(client.ctx); + set_sm_state(ENGINE_SEND_REGISTRATION); k_mutex_unlock(&client.mutex); - next_event_at(0); } static int sm_send_registration_msg(void) @@ -1470,7 +1468,7 @@ int lwm2m_rd_client_pause(void) } suspended_client_state = get_sm_state(); - client.engine_state = ENGINE_SUSPENDED; + set_sm_state(ENGINE_SUSPENDED); k_mutex_unlock(&client.mutex); @@ -1557,8 +1555,8 @@ int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx) } else { client.engine_state = ENGINE_DO_REGISTRATION; } + next_event_at(0); } - next_event_at(0); return 0; } @@ -1574,7 +1572,7 @@ int lwm2m_rd_client_timeout(struct lwm2m_ctx *client_ctx) } k_mutex_lock(&client.mutex, K_FOREVER); LOG_WRN("Confirmable Timeout -> Re-connect and register"); - client.engine_state = ENGINE_DO_REGISTRATION; + set_sm_state(ENGINE_DO_REGISTRATION); next_event_at(0); k_mutex_unlock(&client.mutex); return 0; From 7c57aed3643e7c10d0ce3cca96ef3c3f3387d76d Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Thu, 10 Aug 2023 14:33:31 +0300 Subject: [PATCH 450/528] [nrf fromlist] net: lwm2m: Do not immediately close connection at Bootstrap When BOOTSTRAP FINNISH message was received, it caused engine to immediately switch to BOOTSTRAP_TRANS_DONE state which then closed the connection. Ack packet was still on the send-queue so it never got send before close(). Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/61370 Signed-off-by: Seppo Takalo (cherry picked from commit 42c0a915d0b6565159ed91dc687b72afe62ad2bb) --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 16 +++++++++--- .../lwm2m_rd_client/boards/native_posix.conf | 1 + .../net/lib/lwm2m/lwm2m_rd_client/src/main.c | 26 ++++++++++++------- 3 files changed, 31 insertions(+), 12 deletions(-) create mode 100644 tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index 6a2f0486b21e..f1c110712306 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -74,6 +74,8 @@ static int sm_send_registration_msg(void); static bool sm_is_suspended(void); static void lwm2m_rd_client_service(struct k_work *work); static int64_t calc_next_event(void); +static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms); +static void set_sm_state(uint8_t sm_state); /* The states for the RD client state machine */ /* @@ -171,7 +173,7 @@ static void next_event_at(int64_t timestamp) (void)lwm2m_engine_call_at(lwm2m_rd_client_service, timestamp); } -static void set_sm_state(uint8_t sm_state) +static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms) { k_mutex_lock(&client.mutex, K_FOREVER); enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE; @@ -232,10 +234,15 @@ static void set_sm_state(uint8_t sm_state) lwm2m_close_socket(client.ctx); } } - next_event_at(0); + next_event_at(k_uptime_get() + delay_ms); k_mutex_unlock(&client.mutex); } +static void set_sm_state(uint8_t sm_state) +{ + set_sm_state_delayed(sm_state, 0); +} + static bool sm_is_bootstrap(void) { #if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) @@ -837,7 +844,10 @@ static int sm_do_bootstrap_reg(void) void engine_bootstrap_finish(void) { LOG_INF("Bootstrap data transfer done!"); - set_sm_state(ENGINE_BOOTSTRAP_TRANS_DONE); + /* Delay the state transition, so engine have some time to send ACK + * before we close the socket + */ + set_sm_state_delayed(ENGINE_BOOTSTRAP_TRANS_DONE, 1000); } static int sm_bootstrap_trans_done(void) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf b/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf new file mode 100644 index 000000000000..eb56d825c96d --- /dev/null +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/boards/native_posix.conf @@ -0,0 +1 @@ +CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME=y diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c index 91f7a18776fa..9d8ba7bd9247 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -9,7 +9,9 @@ #include #include #include - +#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME) +#include "timer_model.h" +#endif #include LOG_MODULE_REGISTER(lwm2m_rd_client_test); @@ -127,6 +129,12 @@ static void lwm2m_observe_cb(enum lwm2m_observe_event event, struct lwm2m_obj_pa static void my_suite_before(void *data) { +#if defined(CONFIG_NATIVE_POSIX_SLOWDOWN_TO_REAL_TIME) + /* It is enough that some slow-down is happening on sleeps, it does not have to be + * real time + */ + hwtimer_set_rt_ratio(100.0); +#endif /* Register resets */ DO_FOREACH_FAKE(RESET_FAKE); @@ -185,7 +193,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_ok) coap_header_get_code_fake.custom_fake = coap_header_get_code_fake_deleted; zassert_true(lwm2m_rd_client_stop(&ctx, lwm2m_event_cb, true) == 0, NULL); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT, 2), NULL); + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_DISCONNECT, 1), NULL); zassert_true(!lwm2m_rd_client_is_registred(&ctx), NULL); } @@ -212,7 +220,7 @@ ZTEST(lwm2m_rd_client, test_timeout_resume_registration) NULL); zassert(lwm2m_rd_client_timeout(&ctx) == 0, ""); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE, 2), + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE, 1), NULL); } @@ -282,7 +290,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_update) NULL); lwm2m_rd_client_update(); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE, 3), + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE, 2), NULL); } @@ -339,7 +347,7 @@ ZTEST(lwm2m_rd_client, test_start_registration_update_fail) RESET_FAKE(coap_header_get_code); lwm2m_rd_client_update(); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE, 3), + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE, 2), NULL); } @@ -478,11 +486,11 @@ ZTEST(lwm2m_rd_client, test_suspend_resume_registration) zassert_true(!lwm2m_rd_client_is_suspended(&ctx), NULL); zassert_true(lwm2m_rd_client_pause() == 0, NULL); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED, 2), NULL); + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED, 1), NULL); zassert_true(lwm2m_rd_client_is_suspended(&ctx), NULL); zassert_true(lwm2m_rd_client_resume() == 0, NULL); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE, 4), + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE, 3), NULL); zassert_true(!lwm2m_rd_client_is_suspended(&ctx), NULL); } @@ -510,7 +518,7 @@ ZTEST(lwm2m_rd_client, test_socket_error) NULL); ctx.fault_cb(EIO); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE, 2), NULL); - zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE, 3), + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE, 1), NULL); + zassert_true(check_lwm2m_rd_client_event(LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE, 2), NULL); } From 10f9a86a420ea9577d2bd0c53656adb4b909063b Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Wed, 21 Jun 2023 20:49:08 +0100 Subject: [PATCH 451/528] [nrf fromtree] doc: Make sure message is a string before regexing it There are times when the log message is an exception object and that causes the regex to fail with a TypeError. Here we work around that by converting the input to a string. Signed-off-by: Michael Jones (cherry picked from commit 56d7afeac9408f216e5e785ee5c90b740293fed0) --- doc/_extensions/zephyr/warnings_filter.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/_extensions/zephyr/warnings_filter.py b/doc/_extensions/zephyr/warnings_filter.py index 650a76134b21..d92db7796e39 100644 --- a/doc/_extensions/zephyr/warnings_filter.py +++ b/doc/_extensions/zephyr/warnings_filter.py @@ -52,7 +52,8 @@ def filter(self, record: logging.LogRecord) -> bool: return True for expression in self._expressions: - if re.match(expression, record.msg): + # The message isn't always a string so we convert it before regexing as we can only regex strings + if re.match(expression, str(record.msg)): if self._silent: return False else: From 9c695cd3c1d9b260db9becb06b4598939ff229d6 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Thu, 22 Jun 2023 13:27:56 +0100 Subject: [PATCH 452/528] [nrf fromtree] doc: Add '--keep-going' flag to sphinx-build So that we see all the potential errors in CI and not just the first and can assess how much work there is to do. This was introduced for debuggin but gmarull has suggested keeping it in. Signed-off-by: Michael Jones (cherry picked from commit 343f60c6314689b8942c446708706a5c8ea9fe13) --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 466f9c8afbda..f3ea6b564c8d 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -84,7 +84,7 @@ jobs: DOC_TARGET="html" fi - DOC_TAG=${DOC_TAG} SPHINXOPTS="-q -W -t publish" make -C doc ${DOC_TARGET} + DOC_TAG=${DOC_TAG} SPHINXOPTS="-q -W --keep-going -t publish" make -C doc ${DOC_TARGET} - name: compress-docs run: | From 7991fa5c039886424a97c896787bb545d19e4294 Mon Sep 17 00:00:00 2001 From: Michael Jones Date: Sat, 1 Jul 2023 21:16:50 +0100 Subject: [PATCH 453/528] [nrf fromtree] doc: Log unused log filter patterns This allows us to identify any patterns that we can remove or that we didn't realise are no longer in use. This might happen if issues within doxygen or docleaf are resolved. This allows us to remove the pattern: .*Duplicate C declaration.*\n.*'\.\. c:.*:: uint16_t id'.* which does not match anything in the current set up. We also split the filter patterns in known-warnings out into different sections depending on their cause. Also extend the pattern parser to ignore empty lines so that we can have some formatting in the known-warnings file. fromtree notes: slightly adjusted, docleaf changes not imported Signed-off-by: Michael Jones Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 34e50037f0d94efce10770da5abcf48f7ba33906) --- doc/_extensions/zephyr/warnings_filter.py | 43 ++++++++++++++++++++--- doc/known-warnings.txt | 15 +++++--- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/doc/_extensions/zephyr/warnings_filter.py b/doc/_extensions/zephyr/warnings_filter.py index d92db7796e39..9239776ff793 100644 --- a/doc/_extensions/zephyr/warnings_filter.py +++ b/doc/_extensions/zephyr/warnings_filter.py @@ -24,7 +24,7 @@ import logging import re -from typing import Dict, Any, List +from typing import Dict, Any, List, Optional from sphinx.application import Sphinx from sphinx.util.logging import NAMESPACE @@ -41,6 +41,7 @@ class WarningsFilter(logging.Filter): silent: If true, warning is hidden, otherwise it is shown as INFO. name: Filter name. """ + def __init__(self, expressions: List[str], silent: bool, name: str = "") -> None: super().__init__(name) @@ -53,7 +54,7 @@ def filter(self, record: logging.LogRecord) -> bool: for expression in self._expressions: # The message isn't always a string so we convert it before regexing as we can only regex strings - if re.match(expression, str(record.msg)): + if expression.match(str(record.msg)): if self._silent: return False else: @@ -64,6 +65,21 @@ def filter(self, record: logging.LogRecord) -> bool: return True +class Expression: + """ + Encapsulate a log filter pattern and track if it ever matches a log line. + """ + + def __init__(self, pattern): + self.pattern = pattern + self.matched = False + + def match(self, str): + matches = bool(re.match(self.pattern, str)) + self.matched = matches or self.matched + return matches + + def configure(app: Sphinx) -> None: """Entry point. @@ -75,8 +91,10 @@ def configure(app: Sphinx) -> None: with open(app.config.warnings_filter_config) as f: expressions = list() for line in f.readlines(): - if not line.startswith("#"): - expressions.append(line.rstrip()) + if line.strip() and not line.startswith("#"): + expressions.append(Expression(line.rstrip())) + + app.env.warnings_filter_expressions = expressions # install warnings filter to all the Sphinx logger handlers filter = WarningsFilter(expressions, app.config.warnings_filter_silent) @@ -85,11 +103,28 @@ def configure(app: Sphinx) -> None: handler.filters.insert(0, filter) +def finished(app: Sphinx, exception: Optional[Exception]): + """ + Prints out any patterns that have not matched a log line to allow us to clean up any that are not used. + """ + if exception: + # Early exit if there has been an exception as matching data is only + # valid for complete builds + return + + expressions = app.env.warnings_filter_expressions + + for expression in expressions: + if not expression.matched: + logging.warning(f"Unused expression: {expression.pattern}") + + def setup(app: Sphinx) -> Dict[str, Any]: app.add_config_value("warnings_filter_config", "", "") app.add_config_value("warnings_filter_silent", True, "") app.connect("builder-inited", configure) + app.connect("build-finished", finished) return { "version": __version__, diff --git a/doc/known-warnings.txt b/doc/known-warnings.txt index 2ae3f98729c4..3ea22e16b675 100644 --- a/doc/known-warnings.txt +++ b/doc/known-warnings.txt @@ -1,17 +1,24 @@ # Each line should contain the regular expression of a known Sphinx warning # that should be filtered out -.*Duplicate C declaration.*\n.*'\.\. c:.*:: dma_config'.* + +# Function and (enum or struct) name .*Duplicate C declaration.*\n.*'\.\. c:.*:: flash_img_check'.* -.*Duplicate C declaration.*\n.*'\.\. c:.*:: zsock_fd_set'.* -.*Duplicate C declaration.*\n.*'\.\. c:.*:: net_if_mcast_monitor'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: fs_statvfs'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*dmic_trigger.*'.* -.*Duplicate C declaration.*\n.*'\.\. c:.*:: uint16_t id'.* +.*Duplicate C declaration.*\n.*'\.\. c:.*:: dma_config'.* +.*Duplicate C declaration.*\n.*'\.\. c:.*:: net_if_mcast_monitor'.* + +# Struct and typedef name +.*Duplicate C declaration.*\n.*'\.\. c:.*:: zsock_fd_set'.* + +# Function and extern function .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*net_if_ipv4_addr_mask_cmp.*'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*net_if_ipv4_is_addr_bcast.*'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*net_if_ipv4_addr_lookup.*'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*net_if_ipv6_addr_lookup.*'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*net_if_ipv6_maddr_lookup.*'.* + +# Common field names .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*struct in_addr.*'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*struct in6_addr.*'.* .*Duplicate C declaration.*\n.*'\.\. c:.*:: .*struct net_if.*'.* From f6baa1e593a1070bb2555cc925ec1226c3e7b26f Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 29 Jun 2023 10:55:23 +0200 Subject: [PATCH 454/528] [nrf fromtree] ci: doc-build: use zephyr-runner-linux-x64-4xlarge This should allow us to observe faster build times when using parallelization. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit a211469734b6eb12b575fd33ba48eeb0d75fda8e) --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index f3ea6b564c8d..68a911ff76e4 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -35,7 +35,7 @@ env: jobs: doc-build-html: name: "Documentation Build (HTML)" - runs-on: ubuntu-22.04 + runs-on: zephyr-runner-linux-x64-4xlarge timeout-minutes: 45 concurrency: group: doc-build-html-${{ github.ref }} From 005068b638d29cc4bbc2d0e15b05255d81ca183d Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Fri, 4 Aug 2023 13:01:24 +0200 Subject: [PATCH 455/528] [nrf noup] ci: doc-build: use ubuntu-22.04 runner We can't use Zephyr custom runners downstream. Signed-off-by: Gerard Marull-Paretas --- .github/workflows/doc-build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index 68a911ff76e4..f3ea6b564c8d 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -35,7 +35,7 @@ env: jobs: doc-build-html: name: "Documentation Build (HTML)" - runs-on: zephyr-runner-linux-x64-4xlarge + runs-on: ubuntu-22.04 timeout-minutes: 45 concurrency: group: doc-build-html-${{ github.ref }} From edcbb7606660e3aec698c2f6db1ac0e88a4bd7ed Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 3 Jul 2023 12:20:12 +0200 Subject: [PATCH 456/528] [nrf fromtree] doc: add -W --keep-going to the default SPHINXOPTS list Run Sphinx in warnings as error mode, but keep going so that all issues are reported to the user. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 85ec85384ac48089ad1d32114283d7dbdd11470a) --- doc/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 7c03af46d8c0..cd4ceeb6f8b5 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -12,7 +12,7 @@ message(STATUS "Zephyr base: ${ZEPHYR_BASE}") #------------------------------------------------------------------------------- # Options -set(SPHINXOPTS "-j auto" CACHE STRING "Default Sphinx Options") +set(SPHINXOPTS "-j auto -W --keep-going" CACHE STRING "Default Sphinx Options") set(LATEXMKOPTS "-halt-on-error -no-shell-escape" CACHE STRING "Default latexmk options") set(DT_TURBO_MODE OFF CACHE BOOL "Enable DT turbo mode") set(DOC_TAG "development" CACHE STRING "Documentation tag") From c8c64ce1e724ceb6a295dab1decde7088d9f8d85 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 29 Jun 2023 10:49:09 +0200 Subject: [PATCH 457/528] [nrf fromtree] doc: add cmake SPHINXOPTS_EXTRA option Add a new CMake option to append options to SPHINXOPTS. This allows us to easily extend default SPHINXOPTS. This patch also restores the "-j auto" option in CI (now that we use a custom runner). Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 2c89bf57983782593dedc0f34f105fcde735677f) --- .github/workflows/doc-build.yml | 2 +- doc/CMakeLists.txt | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index f3ea6b564c8d..c2c1097e909d 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -84,7 +84,7 @@ jobs: DOC_TARGET="html" fi - DOC_TAG=${DOC_TAG} SPHINXOPTS="-q -W --keep-going -t publish" make -C doc ${DOC_TARGET} + DOC_TAG=${DOC_TAG} SPHINXOPTS_EXTRA="-q -t publish" make -C doc ${DOC_TARGET} - name: compress-docs run: | diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index cd4ceeb6f8b5..3fd775147fe5 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -13,12 +13,14 @@ message(STATUS "Zephyr base: ${ZEPHYR_BASE}") # Options set(SPHINXOPTS "-j auto -W --keep-going" CACHE STRING "Default Sphinx Options") +set(SPHINXOPTS_EXTRA "" CACHE STRING "Extra Sphinx Options (added to defaults)") set(LATEXMKOPTS "-halt-on-error -no-shell-escape" CACHE STRING "Default latexmk options") set(DT_TURBO_MODE OFF CACHE BOOL "Enable DT turbo mode") set(DOC_TAG "development" CACHE STRING "Documentation tag") set(DTS_ROOTS "${ZEPHYR_BASE}" CACHE STRING "DT bindings root folders") separate_arguments(SPHINXOPTS) +separate_arguments(SPHINXOPTS_EXTRA) separate_arguments(LATEXMKOPTS) #------------------------------------------------------------------------------- @@ -145,6 +147,7 @@ add_doc_target( -w ${DOCS_BUILD_DIR}/html.log -t ${DOC_TAG} ${SPHINXOPTS} + ${SPHINXOPTS_EXTRA} ${DOCS_SRC_DIR} ${DOCS_HTML_DIR} USES_TERMINAL @@ -173,6 +176,7 @@ add_doc_target( -t ${DOC_TAG} -t svgconvert ${SPHINXOPTS} + ${SPHINXOPTS_EXTRA} ${DOCS_SRC_DIR} ${DOCS_LATEX_DIR} USES_TERMINAL @@ -223,6 +227,7 @@ add_doc_target( -w ${DOCS_BUILD_DIR}/linkcheck.log -t ${DOC_TAG} ${SPHINXOPTS} + ${SPHINXOPTS_EXTRA} ${DOCS_SRC_DIR} ${DOCS_LINKCHECK_DIR} USES_TERMINAL From ee874afee6d1ffc5f30021c7fb7435035fa1b62a Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 29 Jun 2023 10:56:18 +0200 Subject: [PATCH 458/528] [nrf fromtree] doc: enable Sphinx tracebacks When something goes wrong in Sphinx or extensions, we'll get a detailed traceback, so we can easily debug issues in CI. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit d3d93d4399dc232a574a547c7d64a61ceb5943bf) --- doc/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 3fd775147fe5..5cfce578a4a9 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -12,7 +12,7 @@ message(STATUS "Zephyr base: ${ZEPHYR_BASE}") #------------------------------------------------------------------------------- # Options -set(SPHINXOPTS "-j auto -W --keep-going" CACHE STRING "Default Sphinx Options") +set(SPHINXOPTS "-j auto -W --keep-going -T" CACHE STRING "Default Sphinx Options") set(SPHINXOPTS_EXTRA "" CACHE STRING "Extra Sphinx Options (added to defaults)") set(LATEXMKOPTS "-halt-on-error -no-shell-escape" CACHE STRING "Default latexmk options") set(DT_TURBO_MODE OFF CACHE BOOL "Enable DT turbo mode") From c6dac97859fbe344494f48707ffb2d66ce786da6 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 29 Jun 2023 11:11:34 +0200 Subject: [PATCH 459/528] [nrf fromtree] doc: move requirements to doc/ Zephyr scripts do not require documentation dependencies, so let's move them from scripts/ to doc/. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 7f9215da0ead2fa5e6ac0a0e0c063f8b4bc6d6c3) --- .github/workflows/doc-build.yml | 10 +++++----- doc/contribute/documentation/generation.rst | 2 +- scripts/requirements-doc.txt => doc/requirements.txt | 0 scripts/requirements.txt | 1 - 4 files changed, 6 insertions(+), 7 deletions(-) rename scripts/requirements-doc.txt => doc/requirements.txt (100%) diff --git a/.github/workflows/doc-build.yml b/.github/workflows/doc-build.yml index c2c1097e909d..4510e21505f9 100644 --- a/.github/workflows/doc-build.yml +++ b/.github/workflows/doc-build.yml @@ -22,7 +22,7 @@ on: - 'west.yml' - '.github/workflows/doc-build.yml' - 'scripts/dts/**' - - 'scripts/requirements-doc.txt' + - 'doc/requirements.txt' env: # NOTE: west docstrings will be extracted from the version listed here @@ -57,12 +57,12 @@ jobs: uses: actions/cache@v3 with: path: ~/.cache/pip - key: pip-${{ hashFiles('scripts/requirements-doc.txt') }} + key: pip-${{ hashFiles('doc/requirements.txt') }} - name: install-pip run: | sudo pip3 install -U setuptools wheel pip - pip3 install -r scripts/requirements-doc.txt + pip3 install -r doc/requirements.txt pip3 install west==${WEST_VERSION} pip3 install cmake==${CMAKE_VERSION} @@ -136,7 +136,7 @@ jobs: uses: actions/cache@v3 with: path: ~/.cache/pip - key: pip-${{ hashFiles('scripts/requirements-doc.txt') }} + key: pip-${{ hashFiles('doc/requirements.txt') }} - name: setup-venv run: | @@ -147,7 +147,7 @@ jobs: - name: install-pip run: | pip3 install -U setuptools wheel pip - pip3 install -r scripts/requirements-doc.txt + pip3 install -r doc/requirements.txt pip3 install west==${WEST_VERSION} pip3 install cmake==${CMAKE_VERSION} diff --git a/doc/contribute/documentation/generation.rst b/doc/contribute/documentation/generation.rst index d7c8d6282bf4..3701e8601385 100644 --- a/doc/contribute/documentation/generation.rst +++ b/doc/contribute/documentation/generation.rst @@ -80,7 +80,7 @@ Our documentation processing has been tested to run with: * Graphviz 2.43 * Latexmk version 4.56 * All Python dependencies listed in the repository file - ``scripts/requirements-doc.txt`` + ``doc/requirements.txt`` In order to install the documentation tools, first install Zephyr as described in :ref:`getting_started`. Then install additional tools diff --git a/scripts/requirements-doc.txt b/doc/requirements.txt similarity index 100% rename from scripts/requirements-doc.txt rename to doc/requirements.txt diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 7bb405afaaa1..e10831d8d605 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,6 +1,5 @@ -r requirements-base.txt -r requirements-build-test.txt --r requirements-doc.txt -r requirements-run-test.txt -r requirements-extras.txt -r requirements-compliance.txt From 065939361a9858e327f137e20d893e86ef23aa98 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 12 Jul 2023 20:47:14 +0200 Subject: [PATCH 460/528] [nrf fromtree] doc: requirements: update Sphinx and rtd theme rtd_theme 1.2.x is required when using Sphinx >= 6.0, otherwise certain features like search are broken. Note that jQuery support needs to be enabled manually now using `sphinxcontrib.jquery` extension. Also update Sphinx to latest 6.x release, 6.2 as it contains some fixes. fromtree notes: slightly adjusted, docleaf not imported. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 7c418a065cfe483c464d9a6e2615afdad68568d1) --- doc/conf.py | 1 + doc/requirements.txt | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/doc/conf.py b/doc/conf.py index 79f2f51b9b59..ef6bbf197511 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -72,6 +72,7 @@ "sphinx.ext.extlinks", "sphinx.ext.autodoc", "sphinx.ext.graphviz", + "sphinxcontrib.jquery", "zephyr.application", "zephyr.html_redirects", "zephyr.kconfig", diff --git a/doc/requirements.txt b/doc/requirements.txt index 691466759d5c..2d90048e16f9 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,8 +1,8 @@ # DOC: used to generate docs breathe>=4.34 -sphinx~=5.0,!=5.2.0.post0 -sphinx_rtd_theme~=1.0 +sphinx~=6.2 +sphinx_rtd_theme~=1.2 sphinx-tabs sphinxcontrib-svg2pdfconverter pygments>=2.9 From 80493dd34fc629cd50462f84ea6bd090a3d17325 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 13 Jul 2023 12:01:42 +0200 Subject: [PATCH 461/528] [nrf fromtree] doc: align pseudo-Makefile with latest CMake changes The SPHINXOPTS option was not aligned with latest changes in CMake, and SPHINXOPTS_EXTRA was not present. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 77aafa51a1b5c643d95938b37fd4c9b60baa2516) --- doc/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/Makefile b/doc/Makefile index c9ae0e700978..321a1b92cc40 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -4,7 +4,8 @@ BUILDDIR ?= _build DOC_TAG ?= development -SPHINXOPTS ?= -j auto +SPHINXOPTS ?= -j auto -W --keep-going -T +SPHINXOPTS_EXTRA ?= LATEXMKOPTS ?= -halt-on-error -no-shell-escape DT_TURBO_MODE ?= 0 @@ -26,6 +27,7 @@ configure: -S. \ -DDOC_TAG=${DOC_TAG} \ -DSPHINXOPTS="${SPHINXOPTS}" \ + -DSPHINXOPTS_EXTRA="${SPHINXOPTS_EXTRA}" \ -DLATEXMKOPTS="${LATEXMKOPTS}" \ -DDT_TURBO_MODE=${DT_TURBO_MODE} From 042fc99b1ecdc0acc14acd03ebddb8c133d87d3a Mon Sep 17 00:00:00 2001 From: Rubin Gerritsen Date: Mon, 7 Aug 2023 15:54:50 +0200 Subject: [PATCH 462/528] [nrf fromtree] Bluetooth: ISO: Fix HCI SDU length sent to controller Fixes a race condition that could occur if the TX queue was read out before iso_has_ts was set. In that case, the provided buffer is of wrong length. Signed-off-by: Rubin Gerritsen (cherry picked from commit 5e44f2761b1f7f60e83186607de90b2850e5b253) --- subsys/bluetooth/host/conn.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index b6d95b83ebd1..572b9ab00afa 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -416,18 +416,24 @@ static struct bt_conn_tx *conn_tx_alloc(void) int bt_conn_send_iso_cb(struct bt_conn *conn, struct net_buf *buf, bt_conn_tx_cb_t cb, bool has_ts) { - int err = bt_conn_send_cb(conn, buf, cb, NULL); - - if (err) { - return err; + if (buf->user_data_size < CONFIG_BT_CONN_TX_USER_DATA_SIZE) { + LOG_ERR("not enough room in user_data %d < %d", + buf->user_data_size, + CONFIG_BT_CONN_TX_USER_DATA_SIZE); + return -EINVAL; } /* Necessary for setting the TS_Flag bit when we pop the buffer from the - * send queue. - * Size check for the user_data is already done in `bt_conn_send_cb`. + * send queue. The flag needs to be set before adding the buffer to the queue. */ tx_data(buf)->iso_has_ts = has_ts; + int err = bt_conn_send_cb(conn, buf, cb, NULL); + + if (err) { + return err; + } + return 0; } From 9f6c9d5acb7d65f5050491f9be3a4a8132459ed1 Mon Sep 17 00:00:00 2001 From: Jamie McCrae Date: Wed, 2 Aug 2023 11:10:09 +0100 Subject: [PATCH 463/528] [nrf fromtree] doc: build: Add details on application version system Adds details on how to use Zephyr's VERSION file for setting the version of an application. Signed-off-by: Jamie McCrae (cherry picked from commit 945b91ca2dde1a727b08fcb4fd23e3d196bdbbb2) --- doc/build/index.rst | 1 + doc/build/version/index.rst | 164 ++++++++++++++++++++++++++++++++++++ 2 files changed, 165 insertions(+) create mode 100644 doc/build/version/index.rst diff --git a/doc/build/index.rst b/doc/build/index.rst index 75be277c7219..4a3e76be3073 100644 --- a/doc/build/index.rst +++ b/doc/build/index.rst @@ -14,3 +14,4 @@ Build and Configuration Systems snippets/index.rst zephyr_cmake_package.rst sysbuild/index.rst + version/index.rst diff --git a/doc/build/version/index.rst b/doc/build/version/index.rst new file mode 100644 index 000000000000..de4e713c6b60 --- /dev/null +++ b/doc/build/version/index.rst @@ -0,0 +1,164 @@ +.. _app-version-details: + +Application version management +****************************** + +Zephyr supports an application version management system for applications which is built around the +system that Zephyr uses for its own version system management. This allows applications to define a +version file and have application (or module) code include the auto-generated file and be able to +access it, just as they can with the kernel version. This version information is available from +multiple scopes, including: + +* Code (C/C++) +* Kconfig +* CMake + +which makes it a very versatile system for lifecycle management of applications. In addition, it +can be used when building applications which target supported bootloaders (e.g. MCUboot) allowing +images to be signed with correct version of the application automatically - no manual signing +steps are required. + +VERSION file +============ + +Application version information is set on a per-application basis in a file named :file:`VERSION`, +which must be placed at the base directory of the application, where the CMakeLists.txt file is +located. This is a simple text file which contains the various version information fields, each on +a newline. The basic ``VERSION`` file has the following structure: + +.. code-block:: none + + VERSION_MAJOR = + VERSION_MINOR = + PATCHLEVEL = + VERSION_TWEAK = + EXTRAVERSION = + +Each field and the values it supports is described below (note that there may be further +restrictions depending upon what the version is used for, e.g. bootloaders might only support some +of these fields or might place limits on the maximum values of fields): + ++---------------+----------------------------------------+ +| Field | Data type | ++---------------+----------------------------------------+ +| VERSION_MAJOR | Numerical | ++---------------+----------------------------------------+ +| VERSION_MINOR | Numerical | ++---------------+----------------------------------------+ +| PATCHLEVEL | Numerical | ++---------------+----------------------------------------+ +| VERSION_TWEAK | Numerical | ++---------------+----------------------------------------+ +| EXTRAVERSION | Alphanumerical (Lowercase a-z and 0-9) | ++---------------+----------------------------------------+ + +When an application is configured using CMake, the version file will be automatically processed, +and will be checked automatically each time the version is changed, so CMake does not need to be +manually re-ran for changes to this file. + +For the sections below, examples are provided for the following :file:`VERSION` file: + +.. code-block:: none + + VERSION_MAJOR = 1 + VERSION_MINOR = 2 + PATCHLEVEL = 3 + VERSION_TWEAK = 4 + EXTRAVERSION = unstable + +Use in code +=========== + +To use the version information in application code, the version file must be included, then the +fields can be freely used. The include file name is :file:`app_version.h` (no path is needed), the +following defines are available: + ++--------------------+-------------------+------------------------------------------------------+-------------------------+ +| Define | Type | Field(s) | Example | ++--------------------+-------------------+------------------------------------------------------+-------------------------+ +| APPVERSION | Numerical | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | +| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | +| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | +| | | ``VERSION_TWEAK`` | | ++--------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_NUMBER | Numerical | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | +| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | +| | | ``PATCHLEVEL`` | | ++--------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | ++--------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | ++--------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | ++--------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_VERSION_STRING | String (quoted) | ``VERSION_MAJOR``, |br| | "1.2.3-unstable" | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` |br| | | ++--------------------+-------------------+------------------------------------------------------+-------------------------+ +| APP_BUILD_VERSION | String (unquoted) | None (value of ``git describe --abbrev=12 --always`` | v3.3.0-18-g2c85d9224fca | +| | | from application repository) | | ++--------------------+-------------------+------------------------------------------------------+-------------------------+ + +Use in Kconfig +============== + +The following variables are available for usage in Kconfig files: + ++------------------+-----------+-------------------------+----------------+ +| Variable | Type | Field(s) | Example | ++------------------+-----------+-------------------------+----------------+ +| $(VERSION_MAJOR) | Numerical | ``VERSION_MAJOR`` | 1 | ++------------------+-----------+-------------------------+----------------+ +| $(VERSION_MINOR) | Numerical | ``VERSION_MINOR`` | 2 | ++------------------+-----------+-------------------------+----------------+ +| $(PATCHLEVEL) | Numerical | ``PATCHLEVEL`` | 3 | ++------------------+-----------+-------------------------+----------------+ +| $(VERSION_TWEAK) | Numerical | ``VERSION_TWEAK`` | 4 | ++------------------+-----------+-------------------------+----------------+ +| $(APPVERSION) | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` | | ++------------------+-----------+-------------------------+----------------+ + +Use in CMake +============ + +The following variable are available for usage in CMake files: + ++--------------------+-----------------+---------------------------------------------------+----------------+ +| Variable | Type | Field(s) | Example | ++--------------------+-----------------+---------------------------------------------------+----------------+ +| APPVERSION | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 24 bits), |br| | 0x1020304 | +| | | ``VERSION_MINOR`` (left shifted by 16 bits), |br| | | +| | | ``PATCHLEVEL`` (left shifted by 8 bits), |br| | | +| | | ``VERSION_TWEAK`` | | ++--------------------+-----------------+---------------------------------------------------+----------------+ +| APP_VERSION_NUMBER | Numerical (hex) | ``VERSION_MAJOR`` (left shifted by 16 bits), |br| | 0x10203 | +| | | ``VERSION_MINOR`` (left shifted by 8 bits), |br| | | +| | | ``PATCHLEVEL`` | | ++--------------------+-----------------+---------------------------------------------------+----------------+ +| APP_VERSION_MAJOR | Numerical | ``VERSION_MAJOR`` | 1 | ++--------------------+-----------------+---------------------------------------------------+----------------+ +| APP_VERSION_MINOR | Numerical | ``VERSION_MINOR`` | 2 | ++--------------------+-----------------+---------------------------------------------------+----------------+ +| APP_PATCHLEVEL | Numerical | ``PATCHLEVEL`` | 3 | ++--------------------+-----------------+---------------------------------------------------+----------------+ +| APP_VERSION_TWEAK | Numerical | ``VERSION_TWEAK`` | 4 | ++--------------------+-----------------+---------------------------------------------------+----------------+ +| APP_VERSION_STRING | String | ``VERSION_MAJOR``, |br| | 1.2.3-unstable | +| | | ``VERSION_MINOR``, |br| | | +| | | ``PATCHLEVEL``, |br| | | +| | | ``EXTRAVERSION`` | | ++--------------------+-----------------+---------------------------------------------------+----------------+ + +Use in MCUboot-supported applications +===================================== + +No additional configuration needs to be done to the target application so long as it is configured +to support MCUboot and a signed image is generated, the version information will be automatically +included in the image data. + +The format used for signing is ``VERSION_MAJOR`` . ``VERSION_MINOR`` . ``PATCHLEVEL``, the tweak +version field is not currently used. From d2a6181eab803b744a04fdcf9ff7a904ccaf860f Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc Date: Wed, 2 Aug 2023 08:55:00 +0200 Subject: [PATCH 464/528] [nrf fromtree] doc: app_development: add header tags Added several header tags on Application Development. Edited header hierarchy under Create Application. Signed-off-by: Grzegorz Ferenc (cherry picked from commit 8b07bf150ec3ea7ce19b56c465422c5dcaebf34a) --- doc/develop/application/index.rst | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index e1400b62b55c..3f21a45a8a49 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -190,11 +190,17 @@ following example, ``app`` is a Zephyr freestanding application: └── src/ └── main.c +.. _zephyr-creating-app: + Creating an Application *********************** -example-application -=================== +In Zephyr, you can either use a reference workspace application or create your application by hand. + +.. _zephyr-creating-app-from-example: + +Using a Reference Workspace Application +======================================= The `example-application`_ Git repository contains a reference :ref:`workspace application `. It is recommended to use it as a reference @@ -210,7 +216,7 @@ commonly-used features, such as: - A custom west :ref:`extension command ` Basic example-application Usage -=============================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ The easiest way to get started with the example-application repository within an existing Zephyr workspace is to follow these steps: @@ -226,7 +232,7 @@ you are using an existing Zephyr workspace, you can use ``west build`` or any other west commands to build, flash, and debug. Advanced example-application Usage -================================== +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You can also use the example-application repository as a starting point for building your own customized Zephyr-based software distribution. This lets you @@ -283,6 +289,8 @@ From now on, you can collaborate on the shared software by pushing changes to the repositories you are using and updating :file:`my-manifest-repo/west.yml` as needed to add and remove repositories, or change their contents. +.. _zephyr-creating-app-by-hand: + Creating an Application by Hand =============================== @@ -430,6 +438,8 @@ should know about. You can use a :ref:`cmake_build_config_package` to share common settings for these variables. +.. _zephyr-app-cmakelists: + Application CMakeLists.txt ************************** @@ -564,6 +574,8 @@ For example: ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} ${app_provision_hex}) +.. _zephyr-app-cmakecache: + CMakeCache.txt ************** From 07e3adced0280b8c703e5c83d742e7a52394b210 Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc Date: Wed, 9 Aug 2023 10:42:14 +0200 Subject: [PATCH 465/528] [nrf fromtree] doc: develop/application: add info about VERSION Added the VERSION file to the list of application files. Added link to the application version management page. Signed-off-by: Grzegorz Ferenc (cherry picked from commit e39b6c5195ad01f9f0c213753efd0808f10e9456) --- doc/develop/application/index.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/doc/develop/application/index.rst b/doc/develop/application/index.rst index 3f21a45a8a49..3fd971ad945f 100644 --- a/doc/develop/application/index.rst +++ b/doc/develop/application/index.rst @@ -45,6 +45,7 @@ Here are the files in a simple Zephyr application: ├── CMakeLists.txt ├── app.overlay ├── prj.conf + ├── VERSION └── src └── main.c @@ -77,6 +78,12 @@ These contents are: See :ref:`application-kconfig` below for more information. +* **VERSION**: A text file that contains several version information fields. + These fields let you manage the lifecycle of the application and automate + providing the application version when signing application images. + + See :ref:`app-version-details` for more information about this file and how to use it. + * **main.c**: A source code file. Applications typically contain source files written in C, C++, or assembly language. The Zephyr convention is to place them in a subdirectory of :file:`` named :file:`src`. From 5919cd652fbc8c49314ae8cc1c25fab546fe8fc4 Mon Sep 17 00:00:00 2001 From: Markus Lassila Date: Fri, 7 Jul 2023 12:49:33 +0300 Subject: [PATCH 466/528] [nrf noup] include: net: add socket option level IPPROTO_ALL fixup! [nrf noup] include: net: add NCS extensions Add socket option level IPPROTO_ALL to socket_ncs.h. Signed-off-by: Markus Lassila --- include/zephyr/net/socket_ncs.h | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/include/zephyr/net/socket_ncs.h b/include/zephyr/net/socket_ncs.h index 20502ffa550c..dce37910187f 100644 --- a/include/zephyr/net/socket_ncs.h +++ b/include/zephyr/net/socket_ncs.h @@ -25,7 +25,7 @@ extern "C" { #define SOCK_NATIVE 0x80000000 #define SOCK_NATIVE_TLS 0x40000000 -/* NCS specific TLS options */ +/* NCS specific TLS level socket options */ /** Socket option to set DTLS handshake timeout, specifically for nRF sockets. * The option accepts an integer, indicating the total handshake timeout, @@ -92,15 +92,6 @@ extern "C" { /* NCS specific socket options */ -/** sockopt: disable all replies to unexpected traffics */ -#define SO_SILENCE_ALL 30 -/** sockopt: disable IPv4 ICMP replies */ -#define SO_IP_ECHO_REPLY 31 -/** sockopt: disable IPv6 ICMP replies */ -#define SO_IPV6_ECHO_REPLY 32 -/** sockopt: Release Assistance Indication feature: This will indicate that the - * application will not send any more data. - */ #define SO_RAI_NO_DATA 50 /** sockopt: Release Assistance Indication feature: This will indicate that the * next call to send/sendto will be the last one for some time. @@ -121,6 +112,26 @@ extern "C" { * option before the next send call. */ #define SO_RAI_WAIT_MORE 54 + +/* NCS specific IPPROTO_ALL level socket options */ + +/** IPv4 and IPv6 protocol level (pseudo-val) for nRF sockets. */ +#define IPPROTO_ALL 512 +/** sockopt: disable all replies to unexpected traffics */ +#define SO_SILENCE_ALL 30 + +/* NCS specific IPPROTO_IP level socket options */ + +/** sockopt: enable IPv4 ICMP replies */ +#define SO_IP_ECHO_REPLY 31 + +/* NCS specific IPPROTO_IPV6 level socket options */ + +/** sockopt: enable IPv6 ICMP replies */ +#define SO_IPV6_ECHO_REPLY 32 + +/* NCS specific TCP level socket options */ + /** sockopt: Configurable TCP server session timeout in minutes. * Range is 0 to 135. 0 is no timeout and 135 is 2 h 15 min. Default is 0 (no timeout). */ From 32185b33b670706361420bbd087c3f9c78ada05e Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 15 Aug 2023 13:10:15 +0300 Subject: [PATCH 467/528] [nrf fromlist] net: lwm2m: Add delay also to exec callbacks Bootstrap executable cause socket to be closed, so it requires some delay for Ack to be send out as well. Similarly, add small delay for Update trigger, so the possible Ack goes out before the actual update message. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/61370 Signed-off-by: Seppo Takalo (cherry picked from commit 8913b7eda9e9218633ddd02884b16e7c67fa16b8) --- subsys/net/lib/lwm2m/lwm2m_rd_client.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/subsys/net/lib/lwm2m/lwm2m_rd_client.c b/subsys/net/lib/lwm2m/lwm2m_rd_client.c index f1c110712306..0967cbdb346e 100644 --- a/subsys/net/lib/lwm2m/lwm2m_rd_client.c +++ b/subsys/net/lib/lwm2m/lwm2m_rd_client.c @@ -68,6 +68,8 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #define CLIENT_EP_LEN CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH #define CLIENT_BINDING_LEN sizeof("UQ") #define CLIENT_QUEUE_LEN sizeof("Q") +#define DELAY_BEFORE_CLOSING (1 * MSEC_PER_SEC) +#define DELAY_FOR_ACK 100U static void sm_handle_registration_update_failure(void); static int sm_send_registration_msg(void); @@ -381,6 +383,8 @@ void engine_trigger_update(bool update_objects) } client.trigger_update = true; + /* short delay for Ack, then trigger an update */ + next_event_at(k_uptime_get() + DELAY_FOR_ACK); if (update_objects) { client.update_objects = true; @@ -464,7 +468,7 @@ int engine_trigger_bootstrap(void) rd_client_message_free(); client.use_bootstrap = true; client.trigger_update = false; - set_sm_state(ENGINE_INIT); + set_sm_state_delayed(ENGINE_INIT, DELAY_BEFORE_CLOSING); k_mutex_unlock(&client.mutex); return 0; #else @@ -847,7 +851,7 @@ void engine_bootstrap_finish(void) /* Delay the state transition, so engine have some time to send ACK * before we close the socket */ - set_sm_state_delayed(ENGINE_BOOTSTRAP_TRANS_DONE, 1000); + set_sm_state_delayed(ENGINE_BOOTSTRAP_TRANS_DONE, DELAY_BEFORE_CLOSING); } static int sm_bootstrap_trans_done(void) @@ -1100,13 +1104,13 @@ static int64_t next_update(void) * check for lifetime seconds - SECONDS_TO_UPDATE_EARLY * so that we can update early and avoid lifetime timeout */ - return client.last_update + (client.lifetime - SECONDS_TO_UPDATE_EARLY) * 1000; + return client.last_update + (client.lifetime - SECONDS_TO_UPDATE_EARLY) * MSEC_PER_SEC; } static int64_t next_rx_off(void) { if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED)) { - return client.last_tx + CONFIG_LWM2M_QUEUE_MODE_UPTIME * 1000; + return client.last_tx + CONFIG_LWM2M_QUEUE_MODE_UPTIME * MSEC_PER_SEC; } else { return next_update(); } @@ -1252,7 +1256,7 @@ static void sm_do_network_error(void) if (client.retry_delay) { client.retry_delay = 0; - next_event_at(k_uptime_get() + client.retry_delay * 1000); + next_event_at(k_uptime_get() + client.retry_delay * MSEC_PER_SEC); return; } @@ -1264,7 +1268,8 @@ static void sm_do_network_error(void) } #endif - if (!client.last_update || (k_uptime_get() - client.last_update) / 1000 > client.lifetime) { + if (!client.last_update || + (k_uptime_get() - client.last_update) / MSEC_PER_SEC > client.lifetime) { /* do full registration as there is no active registration or lifetime exceeded */ lwm2m_engine_context_close(client.ctx); set_sm_state(ENGINE_DO_REGISTRATION); @@ -1516,7 +1521,7 @@ int lwm2m_rd_client_resume(void) if (client.engine_state >= ENGINE_DO_REGISTRATION && client.engine_state <= ENGINE_SUSPENDED) { if (!client.last_update || - (client.lifetime <= (k_uptime_get() - client.last_update) / 1000)) { + (client.lifetime <= (k_uptime_get() - client.last_update) / MSEC_PER_SEC)) { /* No lifetime left, register again */ client.engine_state = ENGINE_DO_REGISTRATION; } else { @@ -1535,7 +1540,6 @@ int lwm2m_rd_client_resume(void) void lwm2m_rd_client_update(void) { engine_trigger_update(false); - next_event_at(0); } struct lwm2m_ctx *lwm2m_rd_client_ctx(void) From d5254ae5f0f9a8182b47ecc984928aa3d5b77c16 Mon Sep 17 00:00:00 2001 From: Seppo Takalo Date: Tue, 15 Aug 2023 13:22:20 +0300 Subject: [PATCH 468/528] [nrf fromlist] test: lwm2m: Allow longer waits and stop properly RD-client tests should wait longer for expected events. Also the stubbed service worker should be stopped properly after tests. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/61370 Signed-off-by: Seppo Takalo (cherry picked from commit 67af91b70779b249d8bfc627cd5a6f17b71a37dd) --- tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c | 7 +++++-- tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c index 9d8ba7bd9247..60a00b9addb9 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/main.c @@ -21,7 +21,7 @@ DEFINE_FFF_GLOBALS; /* Maximum number of iterations within the state machine of RD Client * service that is waited for until a possible event occurs */ -static const uint8_t RD_CLIENT_MAX_LOOKUP_ITERATIONS = 10; +static const uint8_t RD_CLIENT_MAX_LOOKUP_ITERATIONS = 100; FAKE_VOID_FUNC(show_lwm2m_event, enum lwm2m_rd_client_event); FAKE_VOID_FUNC(show_lwm2m_observe, enum lwm2m_observe_event); @@ -143,7 +143,10 @@ static void my_suite_before(void *data) RESET_FAKE(show_lwm2m_event); RESET_FAKE(show_lwm2m_observe); +} +static void my_suite_after(void *data) +{ test_lwm2m_engine_stop_service(); } @@ -165,7 +168,7 @@ void message_reply_timeout_cb_default(struct lwm2m_message *msg) msg->message_timeout_cb(msg); } -ZTEST_SUITE(lwm2m_rd_client, NULL, NULL, my_suite_before, NULL, NULL); +ZTEST_SUITE(lwm2m_rd_client, NULL, NULL, my_suite_before, my_suite_after, NULL); ZTEST(lwm2m_rd_client, test_start_registration_ok) { diff --git a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c index 72c59de8c6f8..877dfdc40d39 100644 --- a/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c +++ b/tests/net/lib/lwm2m/lwm2m_rd_client/src/stubs.c @@ -94,10 +94,11 @@ int lwm2m_engine_call_at(k_work_handler_t work, int64_t timestamp) uint16_t counter = RD_CLIENT_MAX_SERVICE_ITERATIONS; struct lwm2m_message *pending_message; void *(*pending_message_cb)(); +static bool running; static void service_work_fn(struct k_work *work) { - while (true) { + while (running) { if (pending_message != NULL && pending_message_cb != NULL) { pending_message_cb(pending_message); pending_message = NULL; @@ -132,6 +133,7 @@ K_WORK_DEFINE(service_work, service_work_fn); void test_lwm2m_engine_start_service(void) { + running = true; counter = RD_CLIENT_MAX_SERVICE_ITERATIONS; k_work_submit(&service_work); } @@ -139,6 +141,7 @@ void test_lwm2m_engine_start_service(void) void test_lwm2m_engine_stop_service(void) { pending_message_cb = NULL; + running = false; k_work_cancel(&service_work); } From 98ed3ef3d65250f5f34ffbb878a62ae360e2f998 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Thu, 29 Jun 2023 09:31:56 +0200 Subject: [PATCH 469/528] [nrf fromtree] manifest: hal_nordic: Update hal_nordic revision Pull in nrfx 3.1.0 release Signed-off-by: Adam Wojasinski (cherry picked from commit 2460967c5b4de5a20db54f5b4ddec2501d6baf85) --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index f793f74eb79d..430194cdb643 100644 --- a/west.yml +++ b/west.yml @@ -170,7 +170,7 @@ manifest: groups: - hal - name: hal_nordic - revision: a1c3e0fbaafda091139b8744becd4853ada2f747 + revision: 20ae0a7be9030dd58fb59db1c74315a60efb076f path: modules/hal/nordic groups: - hal From 9abbcc75162f1d307f5490abf0052c9b7f610cfa Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Thu, 29 Jun 2023 09:36:25 +0200 Subject: [PATCH 470/528] [nrf fromtree] drivers: pwm: pwm_nrfx: Revert workaround for stopping PWM instance This reverts commit 36f4226b2f3d84954a2ed5000d0c24d918ce52b4. Signed-off-by: Adam Wojasinski (cherry picked from commit 6f201f03f60c3965ebf891077f7cffc14095be02) --- drivers/pwm/pwm_nrfx.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/pwm/pwm_nrfx.c b/drivers/pwm/pwm_nrfx.c index 1b13572dddd4..1a671aaf731d 100644 --- a/drivers/pwm/pwm_nrfx.c +++ b/drivers/pwm/pwm_nrfx.c @@ -198,13 +198,7 @@ static int pwm_nrfx_set_cycles(const struct device *dev, uint32_t channel, * and till that moment, it ignores any start requests, * so ensure here that it is stopped. */ - /* TODO: Remove nrfy_pwm_events_process() that is temporarly - * added as a workaround for missing functionality in - * nrfx_pwm_stopped_check() - */ - while (!nrfx_pwm_stopped_check(&config->pwm) && - !nrfy_pwm_events_process(config->pwm.p_reg, - NRFY_EVENT_TO_INT_BITMASK(NRF_PWM_EVENT_STOPPED))) { + while (!nrfx_pwm_stopped_check(&config->pwm)) { } } From 0549430a3f7c015a6fc4d1c97c06b601af27eca0 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Tue, 11 Jul 2023 16:07:24 +0200 Subject: [PATCH 471/528] [nrf fromtree] modules: hal_nordic: nrfx_config: Align to updates in nrfx 3.1.0 Align config files to templates introduced with nrfx 3.1.0 release Signed-off-by: Adam Wojasinski (cherry picked from commit 9aeb49732171358e2c8a125c2dcaf0bfa339b654) --- modules/hal_nordic/nrfx/nrfx_config_nrf51.h | 51 +++++++++++++++++++ .../hal_nordic/nrfx/nrfx_config_nrf52805.h | 6 +-- .../hal_nordic/nrfx/nrfx_config_nrf52810.h | 6 +-- .../hal_nordic/nrfx/nrfx_config_nrf52811.h | 6 +-- .../hal_nordic/nrfx/nrfx_config_nrf52820.h | 6 +-- .../hal_nordic/nrfx/nrfx_config_nrf52832.h | 15 ++---- .../hal_nordic/nrfx/nrfx_config_nrf52833.h | 6 +-- .../hal_nordic/nrfx/nrfx_config_nrf52840.h | 6 +-- modules/hal_nordic/nrfx/nrfx_config_nrf91.h | 6 +-- 9 files changed, 76 insertions(+), 32 deletions(-) diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf51.h b/modules/hal_nordic/nrfx/nrfx_config_nrf51.h index 3e8f51ca1f4c..51d8bb1b8a51 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf51.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf51.h @@ -280,6 +280,57 @@ #define NRFX_PPI_CONFIG_LOG_LEVEL 3 #endif +/** + * @brief NRFX_PRS_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_ENABLED +#define NRFX_PRS_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_CONFIG_LOG_ENABLED +#define NRFX_PRS_CONFIG_LOG_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_CONFIG_LOG_LEVEL + * + * Integer value. + * Supported values: + * - Off = 0 + * - Error = 1 + * - Warning = 2 + * - Info = 3 + * - Debug = 4 + */ +#ifndef NRFX_PRS_CONFIG_LOG_LEVEL +#define NRFX_PRS_CONFIG_LOG_LEVEL 3 +#endif + +/** + * @brief NRFX_PRS_BOX_0_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_BOX_0_ENABLED +#define NRFX_PRS_BOX_0_ENABLED 0 +#endif + +/** + * @brief NRFX_PRS_BOX_1_ENABLED + * + * Boolean. Accepted values 0 and 1. + */ +#ifndef NRFX_PRS_BOX_1_ENABLED +#define NRFX_PRS_BOX_1_ENABLED 0 +#endif + /** * @brief NRFX_QDEC_ENABLED * diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52805.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52805.h index 46867f13ad59..33074008de43 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52805.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf52805.h @@ -35,9 +35,9 @@ * * Integer value. * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 + * - RC = 0 + * - XTAL = 1 + * - Synth = 2 * - External Low Swing = 131073 * - External Full Swing = 196609 */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52810.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52810.h index 6004836bea5b..ebd63c25ed80 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52810.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf52810.h @@ -35,9 +35,9 @@ * * Integer value. * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 + * - RC = 0 + * - XTAL = 1 + * - Synth = 2 * - External Low Swing = 131073 * - External Full Swing = 196609 */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52811.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52811.h index 4eb1a2cd0a97..01169f7b9839 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52811.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf52811.h @@ -35,9 +35,9 @@ * * Integer value. * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 + * - RC = 0 + * - XTAL = 1 + * - Synth = 2 * - External Low Swing = 131073 * - External Full Swing = 196609 */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52820.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52820.h index 9b3248ddd095..bfa743224582 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52820.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf52820.h @@ -35,9 +35,9 @@ * * Integer value. * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 + * - RC = 0 + * - XTAL = 1 + * - Synth = 2 * - External Low Swing = 131073 * - External Full Swing = 196609 */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52832.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52832.h index 6b1a3d359e76..4e5fe9d58351 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52832.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf52832.h @@ -35,9 +35,9 @@ * * Integer value. * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 + * - RC = 0 + * - XTAL = 1 + * - Synth = 2 * - External Low Swing = 131073 * - External Full Swing = 196609 */ @@ -626,14 +626,7 @@ * @brief NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE - EGU instance used by the nRF52 Anomaly 109 * workaround for PWM. * - * Integer value. - * Supported values: - * - EGU0 = 0 - * - EGU1 = 1 - * - EGU2 = 2 - * - EGU3 = 3 - * - EGU4 = 4 - * - EGU5 = 5 + * Integer value. Minimum: 0 Maximum: 5 */ #ifndef NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE #define NRFX_PWM_NRF52_ANOMALY_109_EGU_INSTANCE 5 diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52833.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52833.h index d842b4c9f728..fc415c59dc3f 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52833.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf52833.h @@ -35,9 +35,9 @@ * * Integer value. * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 + * - RC = 0 + * - XTAL = 1 + * - Synth = 2 * - External Low Swing = 131073 * - External Full Swing = 196609 */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf52840.h b/modules/hal_nordic/nrfx/nrfx_config_nrf52840.h index f35c716c57fa..ac7a62fc9312 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf52840.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf52840.h @@ -35,9 +35,9 @@ * * Integer value. * Supported values: - * - RC = 0 - * - XTAL = 1 - * - Synth = 2 + * - RC = 0 + * - XTAL = 1 + * - Synth = 2 * - External Low Swing = 131073 * - External Full Swing = 196609 */ diff --git a/modules/hal_nordic/nrfx/nrfx_config_nrf91.h b/modules/hal_nordic/nrfx/nrfx_config_nrf91.h index cc787ceee185..873be583a35b 100644 --- a/modules/hal_nordic/nrfx/nrfx_config_nrf91.h +++ b/modules/hal_nordic/nrfx/nrfx_config_nrf91.h @@ -109,8 +109,8 @@ * * Integer value. * Supported values: - * - RC = 1 - * - XTAL = 2 + * - RC = 1 + * - XTAL = 2 */ #ifndef NRFX_CLOCK_CONFIG_LF_SRC #define NRFX_CLOCK_CONFIG_LF_SRC 2 @@ -278,7 +278,7 @@ * Integer value. Minimum: 0 Maximum: 7 */ #ifndef NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY -#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY 3 +#define NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY NRFX_DEFAULT_IRQ_PRIORITY #endif /** From fc48908786dd7f8d93585b994ac2202e5753e446 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Wed, 26 Jul 2023 16:44:42 +0200 Subject: [PATCH 472/528] [nrf fromtree] manifest: hal_nordic: Pull PWM driver fix for nrfx_pwm_stopped_check() When `nrfx_pwm_stopped_check()` was called multiple times it was returning incorrect value after second and next calls. Signed-off-by: Adam Wojasinski (cherry picked from commit f53041cb791feafbed25a61dff236b55cd2129b8) --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 430194cdb643..deee49328441 100644 --- a/west.yml +++ b/west.yml @@ -170,7 +170,7 @@ manifest: groups: - hal - name: hal_nordic - revision: 20ae0a7be9030dd58fb59db1c74315a60efb076f + revision: cf6e9fc5f7c2c98df26f2a4227a95df9a50823e7 path: modules/hal/nordic groups: - hal From 1de973245c4d3473473a4aae5e22ce3f69075817 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Tue, 8 Aug 2023 16:31:58 +0200 Subject: [PATCH 473/528] [nrf fromtree] drivers: spi: spi_nrfx_spim: Add CPOL handling on SCK pin Pin state after SPIM deinitialization is based on pinctrl configuration. On the other hand, CPOL is set during runtime. With the introduction of the power-optimized SPIM driver, it disables the peripheral instance once the transfer is completed. As a result, the GPIO takes control over the SCK pin and drives it based on pinctrl configuration which causes an invalid SCK state when the transaction is configured with CPOL (Clock Polarity). To address this issue, a patch was introduced to the SPIM driver. Now, when a SPIM instance is configured with CPOL, the driver is setting in the runtime the correct state of the SCK pin. Signed-off-by: Adam Wojasinski (cherry picked from commit 315dd0f41cddfeb38654bbcf416aa60cd6e9520f) --- drivers/spi/spi_nrfx_spim.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi_nrfx_spim.c b/drivers/spi/spi_nrfx_spim.c index 89a0235d9d38..ed5b7aefc294 100644 --- a/drivers/spi/spi_nrfx_spim.c +++ b/drivers/spi/spi_nrfx_spim.c @@ -173,6 +173,9 @@ static int configure(const struct device *dev, config.mode = get_nrf_spim_mode(spi_cfg->operation); config.bit_order = get_nrf_spim_bit_order(spi_cfg->operation); + nrfy_gpio_pin_write(nrfy_spim_sck_pin_get(dev_config->spim.p_reg), + spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0); + if (dev_data->initialized) { nrfx_spim_uninit(&dev_config->spim); dev_data->initialized = false; From 451c1c4b439597b6f4fa6466cb070a0b15aea641 Mon Sep 17 00:00:00 2001 From: Adam Wojasinski Date: Wed, 9 Aug 2023 11:13:39 +0200 Subject: [PATCH 474/528] [nrf fromtree] drivers: spi: spi_nrfx_spi: Add CPOL handling on SCK pin Pin state after SPI deinitialization is based on pinctrl configuration. On the other hand, CPOL is set during runtime. When the SPI instance is disabled GPIO takes control over SCK and drives it to state set by pinctrl driver. This might causes an invalid SCK state when the transaction is configured with CPOL (Clock Polarity). To address this issue, a patch was introduced to the SPI driver. Now, when a SPI instance is configured with CPOL, the driver is setting in the runtime the correct state of the SCK pin. Signed-off-by: Adam Wojasinski (cherry picked from commit 9de69aabfddc60c73f8897e38463ef2479201375) --- drivers/spi/spi_nrfx_spi.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/spi/spi_nrfx_spi.c b/drivers/spi/spi_nrfx_spi.c index 75a8745c7d97..825572f3c6d7 100644 --- a/drivers/spi/spi_nrfx_spi.c +++ b/drivers/spi/spi_nrfx_spi.c @@ -131,6 +131,9 @@ static int configure(const struct device *dev, config.mode = get_nrf_spi_mode(spi_cfg->operation); config.bit_order = get_nrf_spi_bit_order(spi_cfg->operation); + nrf_gpio_pin_write(nrf_spi_sck_pin_get(dev_config->spi.p_reg), + spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0); + if (dev_data->initialized) { nrfx_spi_uninit(&dev_config->spi); dev_data->initialized = false; From 0006aed0cc534fd04dbc78f32c7109b179e5d0a6 Mon Sep 17 00:00:00 2001 From: Aleksandr Khromykh Date: Tue, 18 Jul 2023 10:34:13 +0200 Subject: [PATCH 475/528] [nrf fromtree] tests: Bluetooth: Mesh: fix omitted names PR fixes using of the parameter with omitted names. Signed-off-by: Aleksandr Khromykh (cherry picked from commit b8f7c81dd3930ae1dde60dcf1daba32d03176816) --- tests/bsim/bluetooth/mesh/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bsim/bluetooth/mesh/src/main.c b/tests/bsim/bluetooth/mesh/src/main.c index d83ca64eeb79..3c314e24a586 100644 --- a/tests/bsim/bluetooth/mesh/src/main.c +++ b/tests/bsim/bluetooth/mesh/src/main.c @@ -77,7 +77,7 @@ bst_test_install_t test_installers[] = { static struct k_thread bsim_mesh_thread; static K_KERNEL_STACK_DEFINE(bsim_mesh_thread_stack, 4096); -static void bsim_mesh_entry_point(void *, void *, void *) +static void bsim_mesh_entry_point(void *unused1, void *unused2, void *unused3) { bst_main(); } From 53c4b20c15611a9d13b91e5dc025733d6dd65adb Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Fri, 18 Aug 2023 10:20:45 +0200 Subject: [PATCH 476/528] [nrf noup] modules: mbedtls: Fix key support Kconfig PSA_HAS_KEY_SUPPORT was missing the DH_PUBLIC_KEY only Kconfig as the KEY_PAIR was double in there Signed-off-by: Markus Swarowsky --- modules/mbedtls/Kconfig.psa | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 5980e137032e..9b256ead81a2 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -43,7 +43,7 @@ config PSA_HAS_KEY_SUPPORT PSA_WANT_KEY_TYPE_RSA_KEY_PAIR || \ PSA_WANT_KEY_TYPE_RSA_PUBLIC_KEY || \ PSA_WANT_KEY_TYPE_DH_KEY_PAIR || \ - PSA_WANT_KEY_TYPE_DH_KEY_PAIR + PSA_WANT_KEY_TYPE_DH_PUBLIC_KEY config PSA_WANT_KEY_TYPE_DERIVE bool "PSA derive key type support" From c39cbff4b6d0131568183261a0272c1077e9d866 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Fri, 14 Jul 2023 12:28:22 +0200 Subject: [PATCH 477/528] [nrf fromtree] drivers: ieee802154: nrf5: Add transmission with multiple CCA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Kconfig IEEE802154_NRF5_MULTIPLE_CCA option is added. The new functions `z_ieee802154_nrf5_extra_cca_attempts_set` and `z_ieee802154_nrf5_extra_cca_attempts_get` are added. The ieee802154_nrf5.c is updated allowing to pass extra cca attempts to nRF 802.15.4 Radio Driver. Signed-off-by: Andrzej Kuroś (cherry picked from commit 5443d4127bfe38f3f698ec626907b51569b27eaa) --- drivers/ieee802154/Kconfig.nrf5 | 11 ++++++++++ drivers/ieee802154/ieee802154_nrf5.c | 24 ++++++++++++++++++-- drivers/ieee802154/ieee802154_nrf5.h | 33 ++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 2 deletions(-) diff --git a/drivers/ieee802154/Kconfig.nrf5 b/drivers/ieee802154/Kconfig.nrf5 index 3ab0d19c3991..1ce67332db00 100644 --- a/drivers/ieee802154/Kconfig.nrf5 +++ b/drivers/ieee802154/Kconfig.nrf5 @@ -88,4 +88,15 @@ config IEEE802154_NRF5_LOG_RX_FAILURES It can be helpful for the network traffic analyze but it generates also a lot of log records in a stress environment. +config IEEE802154_NRF5_MULTIPLE_CCA + bool "Support for multiple CCA attempts before transmission" + help + This is an optional extension not conforming to IEEE Std. 802.15.4-2015. + When this option is enabled the user of ieee802154_nrf5 has possibility + to express the maximum number of extra CCA attempts for a transmission. + The CCA procedure is repeated back-to-back either until it returns + idle channel and the transmission starts, or until 1 + `extra cca attempts` + CCA attempts are performed. Because of that the moment of transmission can be + delayed by the time taken by the extra CCA operations performed. + endif diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index f11c1953c2c7..205bc3a822c4 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -546,7 +546,8 @@ static uint64_t target_time_convert_to_64_bits(uint32_t target_time) return result; } -static bool nrf5_tx_at(struct net_pkt *pkt, uint8_t *payload, bool cca) +static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, + uint8_t *payload, bool cca) { nrf_802154_transmit_at_metadata_t metadata = { .frame_props = { @@ -561,6 +562,9 @@ static bool nrf5_tx_at(struct net_pkt *pkt, uint8_t *payload, bool cca) .power = net_pkt_ieee802154_txpwr(pkt), #endif }, +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + .extra_cca_attempts = nrf5_radio->extra_cca_attempts +#endif }; uint64_t tx_at = target_time_convert_to_64_bits(net_pkt_txtime(pkt) / NSEC_PER_USEC); @@ -601,7 +605,7 @@ static int nrf5_tx(const struct device *dev, case IEEE802154_TX_MODE_TXTIME: case IEEE802154_TX_MODE_TXTIME_CCA: __ASSERT_NO_MSG(pkt); - ret = nrf5_tx_at(pkt, nrf5_radio->tx_psdu, + ret = nrf5_tx_at(nrf5_radio, pkt, nrf5_radio->tx_psdu, mode == IEEE802154_TX_MODE_TXTIME_CCA); break; #endif /* CONFIG_NET_PKT_TXTIME */ @@ -1157,6 +1161,22 @@ void nrf_802154_serialization_error(const nrf_802154_ser_err_data_t *err) } #endif +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) +void ieee802154_nrf5_extra_cca_attempts_set(const struct device *dev, uint8_t value) +{ + struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev); + + nrf5_radio->extra_cca_attempts = value; +} + +uint8_t ieee802154_nrf5_extra_cca_attempts_get(const struct device *dev) +{ + struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev); + + return nrf5_radio->extra_cca_attempts; +} +#endif /* defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) */ + static const struct nrf5_802154_config nrf5_radio_cfg = { .irq_config_func = nrf5_irq_config, }; diff --git a/drivers/ieee802154/ieee802154_nrf5.h b/drivers/ieee802154/ieee802154_nrf5.h index b5a39ce8dfd5..482e4a2e82af 100644 --- a/drivers/ieee802154/ieee802154_nrf5.h +++ b/drivers/ieee802154/ieee802154_nrf5.h @@ -89,6 +89,39 @@ struct nrf5_802154_data { /* Indicates if currently processed TX frame has dynamic data updated. */ bool tx_frame_mac_hdr_rdy; + +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + /* The maximum number of extra CCA attempts to be performed before transmission. */ + uint8_t extra_cca_attempts; +#endif }; +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) +/** + * @brief Sets the maximum number of extra CCA attempts to be performed by a transmit operation + * + * The default value of extra cca attempts is 0. + * + * The maximum number of extra cca attempts set by this function is applied to transmissions + * requested with mode IEEE802154_TX_MODE_TXTIME_CCA only. This might change in the future, so + * it is recommended to restore previously used value after each transmission. See + * @ref ieee802154_nrf5_extra_cca_attempts_get. + * + * @param dev Pointer to a ieee802154_nrf5 device + * @param value Value to set. Allowed range is 0...254. + */ +void ieee802154_nrf5_extra_cca_attempts_set(const struct device *dev, uint8_t value); + +/** + * @brief Gets the maximum number of extra CCA attempts to be performed by a transmit operation. + * + * @sa @ref ieee802154_nrf5_extra_cca_attempts_set + * + * @param dev Pointer to a ieee802154_nrf5 device + * @return Maximum number of extra CCA attempts. + */ +uint8_t ieee802154_nrf5_extra_cca_attempts_get(const struct device *dev); + +#endif /* defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) */ + #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */ From a8832f1ebc3767e6bffebc4f3219bd8537967966 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Mon, 17 Jul 2023 10:32:08 +0200 Subject: [PATCH 478/528] [nrf fromtree] drivers: ieee802154: nrf5: Revert Add transmission with multiple CCA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 5443d4127bfe38f3f698ec626907b51569b27eaa. Signed-off-by: Andrzej Kuroś (cherry picked from commit 3f4da29a3c78dacbf1a4fc6a46a0747fdd350818) --- drivers/ieee802154/Kconfig.nrf5 | 11 ---------- drivers/ieee802154/ieee802154_nrf5.c | 24 ++------------------ drivers/ieee802154/ieee802154_nrf5.h | 33 ---------------------------- 3 files changed, 2 insertions(+), 66 deletions(-) diff --git a/drivers/ieee802154/Kconfig.nrf5 b/drivers/ieee802154/Kconfig.nrf5 index 1ce67332db00..3ab0d19c3991 100644 --- a/drivers/ieee802154/Kconfig.nrf5 +++ b/drivers/ieee802154/Kconfig.nrf5 @@ -88,15 +88,4 @@ config IEEE802154_NRF5_LOG_RX_FAILURES It can be helpful for the network traffic analyze but it generates also a lot of log records in a stress environment. -config IEEE802154_NRF5_MULTIPLE_CCA - bool "Support for multiple CCA attempts before transmission" - help - This is an optional extension not conforming to IEEE Std. 802.15.4-2015. - When this option is enabled the user of ieee802154_nrf5 has possibility - to express the maximum number of extra CCA attempts for a transmission. - The CCA procedure is repeated back-to-back either until it returns - idle channel and the transmission starts, or until 1 + `extra cca attempts` - CCA attempts are performed. Because of that the moment of transmission can be - delayed by the time taken by the extra CCA operations performed. - endif diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 205bc3a822c4..f11c1953c2c7 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -546,8 +546,7 @@ static uint64_t target_time_convert_to_64_bits(uint32_t target_time) return result; } -static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, - uint8_t *payload, bool cca) +static bool nrf5_tx_at(struct net_pkt *pkt, uint8_t *payload, bool cca) { nrf_802154_transmit_at_metadata_t metadata = { .frame_props = { @@ -562,9 +561,6 @@ static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, .power = net_pkt_ieee802154_txpwr(pkt), #endif }, -#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) - .extra_cca_attempts = nrf5_radio->extra_cca_attempts -#endif }; uint64_t tx_at = target_time_convert_to_64_bits(net_pkt_txtime(pkt) / NSEC_PER_USEC); @@ -605,7 +601,7 @@ static int nrf5_tx(const struct device *dev, case IEEE802154_TX_MODE_TXTIME: case IEEE802154_TX_MODE_TXTIME_CCA: __ASSERT_NO_MSG(pkt); - ret = nrf5_tx_at(nrf5_radio, pkt, nrf5_radio->tx_psdu, + ret = nrf5_tx_at(pkt, nrf5_radio->tx_psdu, mode == IEEE802154_TX_MODE_TXTIME_CCA); break; #endif /* CONFIG_NET_PKT_TXTIME */ @@ -1161,22 +1157,6 @@ void nrf_802154_serialization_error(const nrf_802154_ser_err_data_t *err) } #endif -#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) -void ieee802154_nrf5_extra_cca_attempts_set(const struct device *dev, uint8_t value) -{ - struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev); - - nrf5_radio->extra_cca_attempts = value; -} - -uint8_t ieee802154_nrf5_extra_cca_attempts_get(const struct device *dev) -{ - struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev); - - return nrf5_radio->extra_cca_attempts; -} -#endif /* defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) */ - static const struct nrf5_802154_config nrf5_radio_cfg = { .irq_config_func = nrf5_irq_config, }; diff --git a/drivers/ieee802154/ieee802154_nrf5.h b/drivers/ieee802154/ieee802154_nrf5.h index 482e4a2e82af..b5a39ce8dfd5 100644 --- a/drivers/ieee802154/ieee802154_nrf5.h +++ b/drivers/ieee802154/ieee802154_nrf5.h @@ -89,39 +89,6 @@ struct nrf5_802154_data { /* Indicates if currently processed TX frame has dynamic data updated. */ bool tx_frame_mac_hdr_rdy; - -#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) - /* The maximum number of extra CCA attempts to be performed before transmission. */ - uint8_t extra_cca_attempts; -#endif }; -#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) -/** - * @brief Sets the maximum number of extra CCA attempts to be performed by a transmit operation - * - * The default value of extra cca attempts is 0. - * - * The maximum number of extra cca attempts set by this function is applied to transmissions - * requested with mode IEEE802154_TX_MODE_TXTIME_CCA only. This might change in the future, so - * it is recommended to restore previously used value after each transmission. See - * @ref ieee802154_nrf5_extra_cca_attempts_get. - * - * @param dev Pointer to a ieee802154_nrf5 device - * @param value Value to set. Allowed range is 0...254. - */ -void ieee802154_nrf5_extra_cca_attempts_set(const struct device *dev, uint8_t value); - -/** - * @brief Gets the maximum number of extra CCA attempts to be performed by a transmit operation. - * - * @sa @ref ieee802154_nrf5_extra_cca_attempts_set - * - * @param dev Pointer to a ieee802154_nrf5 device - * @return Maximum number of extra CCA attempts. - */ -uint8_t ieee802154_nrf5_extra_cca_attempts_get(const struct device *dev); - -#endif /* defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) */ - #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */ From 770f0c4c1093326072744457c96c10a50d75318d Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Tue, 18 Jul 2023 08:00:18 +0200 Subject: [PATCH 479/528] [nrf fromtree] net: ieee802154_radio: add extension values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ieee802154_tx_mode and ieee802154_config_type types are given values allowing to extend these types elsewhere. Signed-off-by: Andrzej Kuroś (cherry picked from commit 83ad3fdafa4669f7335c4776bd25e3ff731664eb) --- include/zephyr/net/ieee802154_radio.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index ec8e7f4ae340..68cf1bb29802 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -115,8 +115,17 @@ enum ieee802154_hw_caps { IEEE802154_HW_SUB_GHZ = BIT(13), /* Sub-GHz radio supported * TODO: Replace with channel page attribute. */ + /* Note: Update also IEEE802154_HW_CAPS_BITS_COMMON_COUNT when changing + * the ieee802154_hw_caps type. + */ }; +/** @brief Number of bits used by ieee802154_hw_caps type. */ +#define IEEE802154_HW_CAPS_BITS_COMMON_COUNT (14) + +/** @brief This and higher values are specific to the protocol- or driver-specific extensions. */ +#define IEEE802154_HW_CAPS_BITS_PRIV_START IEEE802154_HW_CAPS_BITS_COMMON_COUNT + enum ieee802154_filter_type { IEEE802154_FILTER_TYPE_IEEE_ADDR, IEEE802154_FILTER_TYPE_SHORT_ADDR, @@ -188,6 +197,12 @@ enum ieee802154_tx_mode { * Requires IEEE802154_HW_TXTIME capability. */ IEEE802154_TX_MODE_TXTIME_CCA, + + /** Number of modes defined in ieee802154_tx_mode. */ + IEEE802154_TX_MODE_COMMON_COUNT, + + /** This and higher values are specific to the protocol- or driver-specific extensions. */ + IEEE802154_TX_MODE_PRIV_START = IEEE802154_TX_MODE_COMMON_COUNT, }; /** IEEE802.15.4 Frame Pending Bit table address matching mode. */ @@ -296,6 +311,12 @@ enum ieee802154_config_type { * should disable it for all enabled addresses. */ IEEE802154_CONFIG_ENH_ACK_HEADER_IE, + + /** Number of types defined in ieee802154_config_type. */ + IEEE802154_CONFIG_COMMON_COUNT, + + /** This and higher values are specific to the protocol- or driver-specific extensions. */ + IEEE802154_CONFIG_PRIV_START = IEEE802154_CONFIG_COMMON_COUNT, }; /** IEEE802.15.4 driver configuration data. */ From 6cfdceb3ffffc3227acaac7ef3817afda2edf189 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Thu, 20 Jul 2023 18:55:13 +0200 Subject: [PATCH 480/528] [nrf fromtree] net: ieee802154_radio: add attribute getter API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `attr_get` method is added to the ieee802154_radio to allow reading of driver specific attributes of given device. The enum `ieee802154_attr` provides common extension pattern allowing to extend the attribute set. Accessor function `ieee802154_radio_attr_get` is provided. Signed-off-by: Andrzej Kuroś (cherry picked from commit a04a059ccc09f1d8f38ddf044785ecd56acc655f) --- include/zephyr/net/ieee802154_radio.h | 26 +++++++++++++++++++++ subsys/net/l2/ieee802154/ieee802154_utils.h | 14 +++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/zephyr/net/ieee802154_radio.h b/include/zephyr/net/ieee802154_radio.h index 68cf1bb29802..1eba2698eaa4 100644 --- a/include/zephyr/net/ieee802154_radio.h +++ b/include/zephyr/net/ieee802154_radio.h @@ -397,6 +397,23 @@ struct ieee802154_config { }; }; +/** IEEE 802.15.4 attributes. */ +enum ieee802154_attr { + /** Number of attributes defined in ieee802154_attr. */ + IEEE802154_ATTR_COMMON_COUNT, + + /** This and higher values are specific to the protocol- or driver-specific extensions. */ + IEEE802154_ATTR_PRIV_START = IEEE802154_ATTR_COMMON_COUNT, +}; + +/** IEEE 802.15.4 attribute value data. */ +struct ieee802154_attr_value { + union { + /* TODO: Please remove when first attribute is added. */ + uint8_t dummy; + }; +}; + /** * @brief IEEE 802.15.4 radio interface API. * @@ -476,6 +493,15 @@ struct ieee802154_radio_api { * Requires IEEE802154_HW_TXTIME and/or IEEE802154_HW_RXTIME capabilities. */ uint8_t (*get_sch_acc)(const struct device *dev); + + /** Get the value of an attribute. + * If the requested attribute is supported by implementation, this function returns 0 + * and fills appropriate version of union in `value`. + * If requested attribute is not supported, this function returns -ENOENT. + */ + int (*attr_get)(const struct device *dev, + enum ieee802154_attr attr, + struct ieee802154_attr_value *value); }; /* Make sure that the network interface API is properly setup inside diff --git a/subsys/net/l2/ieee802154/ieee802154_utils.h b/subsys/net/l2/ieee802154/ieee802154_utils.h index 09450dde7786..b39476bd1696 100644 --- a/subsys/net/l2/ieee802154/ieee802154_utils.h +++ b/subsys/net/l2/ieee802154/ieee802154_utils.h @@ -102,6 +102,20 @@ static inline int ieee802154_stop(struct net_if *iface) return radio->stop(net_if_get_device(iface)); } +static inline int ieee802154_radio_attr_get(struct net_if *iface, + enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + const struct ieee802154_radio_api *radio = + net_if_get_device(iface)->api; + + if (!radio || !radio->attr_get) { + return -ENOENT; + } + + return radio->attr_get(net_if_get_device(iface), attr, value); +} + /** * Sets the radio drivers extended address filter. * From 39ba05ee20b2b30b9f48d679c6e20ec9b27f4267 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Tue, 18 Jul 2023 10:41:33 +0200 Subject: [PATCH 481/528] [nrf fromtree] net: openthread: multiple cca as ieee802154 extensions interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit adds extenstion interface that extends ieee802154_radio.h New OT-specific capability, transmit mode and configuration parameter is added. Signed-off-by: Andrzej Kuroś (cherry picked from commit d6567fc9e2ffa89b4ad718e5e21c31386246c7da) --- .../zephyr/net/ieee802154_radio_openthread.h | 137 ++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 include/zephyr/net/ieee802154_radio_openthread.h diff --git a/include/zephyr/net/ieee802154_radio_openthread.h b/include/zephyr/net/ieee802154_radio_openthread.h new file mode 100644 index 000000000000..56a9bd8de0dd --- /dev/null +++ b/include/zephyr/net/ieee802154_radio_openthread.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief This file extends interface of ieee802154_radio.h for OpenThread. + */ + +#ifndef ZEPHYR_INCLUDE_NET_IEEE802154_RADIO_OPENTHREAD_H_ +#define ZEPHYR_INCLUDE_NET_IEEE802154_RADIO_OPENTHREAD_H_ + +#include + +/** + * OpenThread specific capabilities of ieee802154 driver. + * This type extends @ref ieee802154_hw_caps. + */ +enum ieee802154_openthread_hw_caps { + /** Capability to transmit with @ref IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA + * mode. + */ + IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA = BIT(IEEE802154_HW_CAPS_BITS_PRIV_START), +}; + +enum ieee802154_openthread_tx_mode { + /** + * The @ref IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA mode allows to send + * a scheduled packet if the channel is reported idle after at most + * 1 + max_extra_cca_attempts CCAs performed back-to-back. + * + * This mode is a non-standard experimental OpenThread feature. It allows transmission + * of a packet within a certain time window. + * The earliest transmission time is specified as in the other TXTIME modes: + * When the first CCA reports an idle channel then the first symbol of the packet's SHR + * SHALL be present at the local antenna at the time represented by the scheduled + * TX timestamp (referred to as T_tx below). + * + * If the first CCA reports a busy channel, then additional CCAs up to + * max_extra_cca_attempts will be done until one of them reports an idle channel and + * the packet is sent out or the max number of attempts is reached in which case + * the transmission fails. + * + * The timing of these additional CCAs depends on the capabilities of the driver + * which reports them in the T_recca and T_ccatx driver attributes + * (see @ref IEEE802154_OPENTHREAD_ATTR_T_RECCA and + * @ref IEEE802154_OPENTHREAD_ATTR_T_CCATX). Based on these attributes the upper layer + * can calculate the latest point in time (T_txmax) that the first symbol of the scheduled + * packet's SHR SHALL be present at the local antenna: + * + * T_maxtxdelay = max_extra_cca_attempts * (aCcaTime + T_recca) - T_recca + T_ccatx + * T_txmax = T_tx + T_maxtxdelay + * + * See IEEE 802.15.4-2020, section 11.3, table 11-1 for the definition of aCcaTime. + * + * Drivers implementing this TX mode SHOULD keep T_recca and T_ccatx as short as possible. + * T_ccatx SHALL be less than or equal aTurnaroundTime as defined in ibid., + * section 11.3, table 11-1. + * + * CCA SHALL be executed as defined by the phyCcaMode PHY PIB attribute (see ibid., + * section 11.3, table 11-2). + * + * Requires IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA capability. + */ + IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA = IEEE802154_TX_MODE_PRIV_START +}; + +/** + * OpenThread specific configuration types of ieee802154 driver. + * This type extends @ref ieee802154_config_type. + */ +enum ieee802154_openthread_config_type { + /** Allows to configure extra CCA for transmission requested with mode + * @ref IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA. + * Requires IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA capability. + */ + IEEE802154_OPENTHREAD_CONFIG_MAX_EXTRA_CCA_ATTEMPTS = IEEE802154_CONFIG_PRIV_START +}; + +/** OpenThread specific configuration data of ieee802154 driver. */ +struct ieee802154_openthread_config { + union { + struct ieee802154_config common; + + /** ``IEEE802154_OPENTHREAD_CONFIG_MAX_EXTRA_CCA_ATTEMPTS`` + * + * The maximum number of extra CCAs to be performed when transmission is + * requested with mode @ref IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA. + */ + uint8_t max_extra_cca_attempts; + }; +}; + +/** + * OpenThread specific attributes of ieee802154 driver. + * This type extends @ref ieee802154_attr + */ +enum ieee802154_openthread_attr { + + /** Attribute: Maximum time between consecutive CCAs performed back-to-back. + * + * This is attribute for T_recca parameter mentioned for + * @ref IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA. + * Time is expressed in microseconds. + */ + IEEE802154_OPENTHREAD_ATTR_T_RECCA = IEEE802154_ATTR_PRIV_START, + + /** Attribute: Maximum time between detection of CCA idle channel and the moment of + * start of SHR at the local antenna. + * + * This is attribute for T_ccatx parameter mentioned for + * @ref IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA. + * Time is expressed in microseconds. + */ + IEEE802154_OPENTHREAD_ATTR_T_CCATX +}; + +/** + * OpenThread specific attribute value data of ieee802154 driver. + * This type extends @ref ieee802154_attr_value + */ +struct ieee802154_openthread_attr_value { + union { + struct ieee802154_attr_value common; + + /** @brief Attribute value for @ref IEEE802154_OPENTHREAD_ATTR_T_RECCA */ + uint16_t t_recca; + + /** @brief Attribute value for @ref IEEE802154_OPENTHREAD_ATTR_T_CCATX */ + uint16_t t_ccatx; + + }; +}; + +#endif /* ZEPHYR_INCLUDE_NET_IEEE802154_RADIO_OPENTHREAD_H_ */ From 521f4c4e620e78a61304b5580a83cc350272af39 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Tue, 18 Jul 2023 12:28:33 +0200 Subject: [PATCH 482/528] [nrf fromtree] drivers: ieee802154: nrf5: multiple CCA support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The support for capability IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA is added to the ieee802154_nrf5 driver. Signed-off-by: Andrzej Kuroś (cherry picked from commit 9babac94a7dc61edb9572773cf10acaf3bf064fc) --- drivers/ieee802154/Kconfig.nrf5 | 6 +++ drivers/ieee802154/ieee802154_nrf5.c | 79 ++++++++++++++++++++++++++-- drivers/ieee802154/ieee802154_nrf5.h | 7 ++- 3 files changed, 86 insertions(+), 6 deletions(-) diff --git a/drivers/ieee802154/Kconfig.nrf5 b/drivers/ieee802154/Kconfig.nrf5 index 3ab0d19c3991..9acb811e6b60 100644 --- a/drivers/ieee802154/Kconfig.nrf5 +++ b/drivers/ieee802154/Kconfig.nrf5 @@ -88,4 +88,10 @@ config IEEE802154_NRF5_LOG_RX_FAILURES It can be helpful for the network traffic analyze but it generates also a lot of log records in a stress environment. +config IEEE802154_NRF5_MULTIPLE_CCA + bool "Support for multiple CCA attempts before transmission" + help + When this option is enabled the OpenThread capability + IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA is supported by the ieee802154_nrf5. + endif diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index f11c1953c2c7..70efcfc9a94b 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -1,7 +1,7 @@ /* ieee802154_nrf5.c - nRF5 802.15.4 driver */ /* - * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2017-2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -34,6 +34,7 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME); #if defined(CONFIG_NET_L2_OPENTHREAD) #include +#include #endif #include @@ -229,7 +230,11 @@ static void nrf5_get_capabilities_at_boot(void) ((caps & NRF_802154_CAPABILITY_DELAYED_TX) ? IEEE802154_HW_TXTIME : 0UL) | ((caps & NRF_802154_CAPABILITY_DELAYED_RX) ? IEEE802154_HW_RXTIME : 0UL) | IEEE802154_HW_SLEEP_TO_TX | - ((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL); + ((caps & NRF_802154_CAPABILITY_SECURITY) ? IEEE802154_HW_TX_SEC : 0UL) +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + | IEEE802154_OPENTHREAD_HW_MULTIPLE_CCA +#endif + ; } /* Radio device API */ @@ -546,8 +551,32 @@ static uint64_t target_time_convert_to_64_bits(uint32_t target_time) return result; } -static bool nrf5_tx_at(struct net_pkt *pkt, uint8_t *payload, bool cca) +static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, + uint8_t *payload, enum ieee802154_tx_mode mode) { + bool cca = false; +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + uint8_t max_extra_cca_attempts = 0; +#endif + + switch (mode) { + case IEEE802154_TX_MODE_TXTIME: + break; + case IEEE802154_TX_MODE_TXTIME_CCA: + cca = true; + break; +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + case IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA: + cca = true; + max_extra_cca_attempts = nrf5_radio->max_extra_cca_attempts; + break; +#endif + break; + default: + __ASSERT_NO_MSG(false); + return false; + } + nrf_802154_transmit_at_metadata_t metadata = { .frame_props = { .is_secured = net_pkt_ieee802154_frame_secured(pkt), @@ -561,6 +590,9 @@ static bool nrf5_tx_at(struct net_pkt *pkt, uint8_t *payload, bool cca) .power = net_pkt_ieee802154_txpwr(pkt), #endif }, +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + .extra_cca_attempts = max_extra_cca_attempts, +#endif }; uint64_t tx_at = target_time_convert_to_64_bits(net_pkt_txtime(pkt) / NSEC_PER_USEC); @@ -600,9 +632,11 @@ static int nrf5_tx(const struct device *dev, #if defined(CONFIG_NET_PKT_TXTIME) case IEEE802154_TX_MODE_TXTIME: case IEEE802154_TX_MODE_TXTIME_CCA: +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + case IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA: +#endif __ASSERT_NO_MSG(pkt); - ret = nrf5_tx_at(pkt, nrf5_radio->tx_psdu, - mode == IEEE802154_TX_MODE_TXTIME_CCA); + ret = nrf5_tx_at(nrf5_radio, pkt, nrf5_radio->tx_psdu, mode); break; #endif /* CONFIG_NET_PKT_TXTIME */ default: @@ -973,6 +1007,14 @@ static int nrf5_configure(const struct device *dev, break; #endif /* CONFIG_IEEE802154_CSL_ENDPOINT */ +#if defined(IEEE802154_NRF5_MULTIPLE_CCA) + case IEEE802154_OPENTHREAD_CONFIG_MULTIPLE_CCA: + nrf5_data.max_extra_cca_attempts = + ((const struct ieee802154_openthread_config *)config) + ->max_extra_cca_attempts; + break; +#endif /* IEEE802154_NRF5_MULTIPLE_CCA */ + default: return -EINVAL; } @@ -980,6 +1022,32 @@ static int nrf5_configure(const struct device *dev, return 0; } +static int nrf5_attr_get(const struct device *dev, + enum ieee802154_attr attr, + struct ieee802154_attr_value *value) +{ + ARG_UNUSED(dev); + ARG_UNUSED(value); + + switch (attr) { +#if defined(IEEE802154_NRF5_MULTIPLE_CCA) + /* TODO: t_recca and t_ccatx should be provided by the public API of the + * nRF 802.15.4 Radio Driver. + */ + case IEEE802154_OPENTHREAD_ATTR_T_RECCA: + ((struct ieee802154_openthread_attr_value *)value)->t_recca = 0; + break; + case IEEE802154_OPENTHREAD_ATTR_T_CCATX: + ((struct ieee802154_openthread_attr_value *)value)->t_ccatx = 20; + break; +#endif + default: + return -ENOENT; + } + + return 0; +} + /* nRF5 radio driver callbacks */ void nrf_802154_received_timestamp_raw(uint8_t *data, int8_t power, uint8_t lqi, uint64_t time) @@ -1179,6 +1247,7 @@ static struct ieee802154_radio_api nrf5_radio_api = { .get_time = nrf5_get_time, .get_sch_acc = nrf5_get_acc, .configure = nrf5_configure, + .attr_get = nrf5_attr_get }; #if defined(CONFIG_NET_L2_IEEE802154) diff --git a/drivers/ieee802154/ieee802154_nrf5.h b/drivers/ieee802154/ieee802154_nrf5.h index b5a39ce8dfd5..ffb0eca77b89 100644 --- a/drivers/ieee802154/ieee802154_nrf5.h +++ b/drivers/ieee802154/ieee802154_nrf5.h @@ -1,7 +1,7 @@ /* ieee802154_nrf5.h - nRF5 802.15.4 driver */ /* - * Copyright (c) 2017 Nordic Semiconductor ASA + * Copyright (c) 2017-2023 Nordic Semiconductor ASA * * SPDX-License-Identifier: Apache-2.0 */ @@ -89,6 +89,11 @@ struct nrf5_802154_data { /* Indicates if currently processed TX frame has dynamic data updated. */ bool tx_frame_mac_hdr_rdy; + +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + /* The maximum number of extra CCA attempts to be performed before transmission. */ + uint8_t max_extra_cca_attempts; +#endif }; #endif /* ZEPHYR_DRIVERS_IEEE802154_IEEE802154_NRF5_H_ */ From 036274a34fee62c6404e7a428f6c1d48d69a8966 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Tue, 8 Aug 2023 12:57:48 +0200 Subject: [PATCH 483/528] [nrf fromtree] drivers: ieee802154: nrf5: fix handling multiple CCA Fix a couple of bugs introduced with last commits related to multiple CCA support. Signed-off-by: Eduardo Montoya (cherry picked from commit f4d54fa4b9b510175862f59499c38d2994572bfe) --- drivers/ieee802154/ieee802154_nrf5.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 70efcfc9a94b..395a6ca785e0 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -568,7 +568,7 @@ static bool nrf5_tx_at(struct nrf5_802154_data *nrf5_radio, struct net_pkt *pkt, #if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) case IEEE802154_OPENTHREAD_TX_MODE_TXTIME_MULTIPLE_CCA: cca = true; - max_extra_cca_attempts = nrf5_radio->max_extra_cca_attempts; + max_extra_cca_attempts = nrf5_data.max_extra_cca_attempts; break; #endif break; @@ -1007,13 +1007,13 @@ static int nrf5_configure(const struct device *dev, break; #endif /* CONFIG_IEEE802154_CSL_ENDPOINT */ -#if defined(IEEE802154_NRF5_MULTIPLE_CCA) - case IEEE802154_OPENTHREAD_CONFIG_MULTIPLE_CCA: +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) + case IEEE802154_OPENTHREAD_CONFIG_MAX_EXTRA_CCA_ATTEMPTS: nrf5_data.max_extra_cca_attempts = ((const struct ieee802154_openthread_config *)config) ->max_extra_cca_attempts; break; -#endif /* IEEE802154_NRF5_MULTIPLE_CCA */ +#endif /* CONFIG_IEEE802154_NRF5_MULTIPLE_CCA */ default: return -EINVAL; @@ -1029,8 +1029,8 @@ static int nrf5_attr_get(const struct device *dev, ARG_UNUSED(dev); ARG_UNUSED(value); - switch (attr) { -#if defined(IEEE802154_NRF5_MULTIPLE_CCA) + switch ((uint32_t)attr) { +#if defined(CONFIG_IEEE802154_NRF5_MULTIPLE_CCA) /* TODO: t_recca and t_ccatx should be provided by the public API of the * nRF 802.15.4 Radio Driver. */ From bdc68496c89d368998c547de3a28d8138600f264 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Thu, 17 Aug 2023 13:57:53 +0200 Subject: [PATCH 484/528] [nrf fromtree] manifest: hal_nordic: update 802.15.4 Radio Driver MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit brings in hal_nordic with nRF 802.15.4 Radio Driver. Signed-off-by: Andrzej Kuroś (cherry picked from commit 69ae6cee263337dabe5dd6ee895df1e4221b0b95) --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index deee49328441..ae18171c3d71 100644 --- a/west.yml +++ b/west.yml @@ -170,7 +170,7 @@ manifest: groups: - hal - name: hal_nordic - revision: cf6e9fc5f7c2c98df26f2a4227a95df9a50823e7 + revision: 9ae7c765985ebdea3d9b98c0d3b154794f0b47cf path: modules/hal/nordic groups: - hal From 9e7d6bbdf82f8d1fa17c1dc82c6a868554000025 Mon Sep 17 00:00:00 2001 From: Andrzej Kuros Date: Mon, 10 Jul 2023 16:25:53 +0200 Subject: [PATCH 485/528] [nrf fromtree] drivers: ieee802154_nrf5: energy_detected api change adjust MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The prototype of `nrf_802154_energy_detected` callout has changed. This commit adjusts to this change. Signed-off-by: Andrzej Kuroś (cherry picked from commit 04d3dcb1164535ba93007f532447dfee06acb71c) --- drivers/ieee802154/ieee802154_nrf5.c | 6 ++---- modules/hal_nordic/nrf_802154/CMakeLists.txt | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/ieee802154/ieee802154_nrf5.c b/drivers/ieee802154/ieee802154_nrf5.c index 395a6ca785e0..9639f3071bd1 100644 --- a/drivers/ieee802154/ieee802154_nrf5.c +++ b/drivers/ieee802154/ieee802154_nrf5.c @@ -1195,15 +1195,13 @@ void nrf_802154_cca_failed(nrf_802154_cca_error_t error) k_sem_give(&nrf5_data.cca_wait); } -void nrf_802154_energy_detected(uint8_t result) +void nrf_802154_energy_detected(const nrf_802154_energy_detected_t *result) { if (nrf5_data.energy_scan_done != NULL) { - int16_t dbm; energy_scan_done_cb_t callback = nrf5_data.energy_scan_done; nrf5_data.energy_scan_done = NULL; - dbm = nrf_802154_dbm_from_energy_level_calculate(result); - callback(net_if_get_device(nrf5_data.iface), dbm); + callback(net_if_get_device(nrf5_data.iface), result->ed_dbm); } } diff --git a/modules/hal_nordic/nrf_802154/CMakeLists.txt b/modules/hal_nordic/nrf_802154/CMakeLists.txt index e2b42cff8c53..34bd7e478182 100644 --- a/modules/hal_nordic/nrf_802154/CMakeLists.txt +++ b/modules/hal_nordic/nrf_802154/CMakeLists.txt @@ -95,6 +95,10 @@ else() target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_CARRIER_FUNCTIONS_ENABLED=0) endif() +if (CONFIG_NRF_802154_RADIO_DRIVER OR CONFIG_NRF_802154_SERIALIZATION) + target_compile_definitions(zephyr-802154-interface INTERFACE NRF_802154_ENERGY_DETECTED_VERSION=1) +endif() + set(NRF52_SERIES ${CONFIG_SOC_SERIES_NRF52X}) set(NRF53_SERIES ${CONFIG_SOC_SERIES_NRF53X}) set(SER_HOST ${CONFIG_NRF_802154_SER_HOST}) From 0db8061445fc6e5221cf35ed0312770326c6733d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Ciupis?= Date: Mon, 21 Aug 2023 11:08:42 +0200 Subject: [PATCH 486/528] [nrf fromlist] modules: hal_nordic: remove 802.15.4 gpiote platform MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit removes deprecated GPIOTE platform abstraction for nRF IEEE 802.15.4 radio driver. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/61691 Signed-off-by: Jędrzej Ciupis --- modules/hal_nordic/nrf_802154/CMakeLists.txt | 2 - .../platform/nrf_802154_gpiote_crit_sect.c | 54 ---------- .../platform/nrf_802154_gpiote_zephyr.c | 100 ------------------ 3 files changed, 156 deletions(-) delete mode 100644 modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_gpiote_crit_sect.c delete mode 100644 modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_gpiote_zephyr.c diff --git a/modules/hal_nordic/nrf_802154/CMakeLists.txt b/modules/hal_nordic/nrf_802154/CMakeLists.txt index 34bd7e478182..c338981b651c 100644 --- a/modules/hal_nordic/nrf_802154/CMakeLists.txt +++ b/modules/hal_nordic/nrf_802154/CMakeLists.txt @@ -8,9 +8,7 @@ if (CONFIG_NRF_802154_RADIO_DRIVER) target_sources(nrf-802154-platform PRIVATE radio/platform/nrf_802154_random_zephyr.c - sl_opensource/platform/nrf_802154_gpiote_crit_sect.c sl_opensource/platform/nrf_802154_clock_zephyr.c - sl_opensource/platform/nrf_802154_gpiote_zephyr.c sl_opensource/platform/nrf_802154_irq_zephyr.c sl_opensource/platform/nrf_802154_temperature_zephyr.c ) diff --git a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_gpiote_crit_sect.c b/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_gpiote_crit_sect.c deleted file mode 100644 index eac03895f0c1..000000000000 --- a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_gpiote_crit_sect.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2020 - 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include "platform/nrf_802154_gpiote.h" - -#include "hal/nrf_gpio.h" -#include "nrf_802154_sl_utils.h" -#include "platform/nrf_802154_irq.h" - -static volatile bool m_gpiote_irq_enabled; -static volatile uint32_t m_gpiote_irq_disabled_cnt; - -void nrf_802154_gpiote_critical_section_enter(void) -{ - nrf_802154_sl_mcu_critical_state_t mcu_cs; - uint32_t cnt; - - nrf_802154_sl_mcu_critical_enter(mcu_cs); - cnt = m_gpiote_irq_disabled_cnt; - - if (cnt == 0U) { - m_gpiote_irq_enabled = nrf_802154_irq_is_enabled(GPIOTE_IRQn); - nrf_802154_irq_disable(GPIOTE_IRQn); - } - - cnt++; - m_gpiote_irq_disabled_cnt = cnt; - - nrf_802154_sl_mcu_critical_exit(mcu_cs); -} - -void nrf_802154_gpiote_critical_section_exit(void) -{ - nrf_802154_sl_mcu_critical_state_t mcu_cs; - uint32_t cnt; - - nrf_802154_sl_mcu_critical_enter(mcu_cs); - - cnt = m_gpiote_irq_disabled_cnt; - cnt--; - - if (cnt == 0U) { - if (m_gpiote_irq_enabled) { - nrf_802154_irq_enable(GPIOTE_IRQn); - } - } - - m_gpiote_irq_disabled_cnt = cnt; - - nrf_802154_sl_mcu_critical_exit(mcu_cs); -} diff --git a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_gpiote_zephyr.c b/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_gpiote_zephyr.c deleted file mode 100644 index e7cc9ec5b9d2..000000000000 --- a/modules/hal_nordic/nrf_802154/sl_opensource/platform/nrf_802154_gpiote_zephyr.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2020 - 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -static const struct device *dev; -static struct gpio_callback grant_cb; -static uint32_t pin_number = COEX_GPIO_PIN_INVALID; - -static void gpiote_irq_handler(const struct device *gpiob, struct gpio_callback *cb, - uint32_t pins) -{ - ARG_UNUSED(gpiob); - ARG_UNUSED(cb); - ARG_UNUSED(pins); - - nrf_802154_wifi_coex_gpiote_irqhandler(); -} - -void nrf_802154_gpiote_init(void) -{ - switch (nrf_802154_wifi_coex_interface_type_id_get()) { - case NRF_802154_WIFI_COEX_IF_NONE: - return; - - case NRF_802154_WIFI_COEX_IF_3WIRE: { - nrf_802154_wifi_coex_3wire_if_config_t cfg; - - nrf_802154_wifi_coex_cfg_3wire_get(&cfg); - - pin_number = cfg.grant_cfg.gpio_pin; - __ASSERT_NO_MSG(pin_number != COEX_GPIO_PIN_INVALID); - - bool use_port_1 = (pin_number > P0_PIN_NUM); - - /* Convert to the Zephyr primitive */ - pin_number = use_port_1 ? pin_number - P0_PIN_NUM : pin_number; - - uint32_t pull_up_down = cfg.grant_cfg.active_high ? - GPIO_PULL_UP : - GPIO_PULL_DOWN; - -#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) - if (use_port_1) { - dev = DEVICE_DT_GET(DT_NODELABEL(gpio1)); - } else { - dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)); - } -#else - dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)); -#endif - __ASSERT_NO_MSG(device_is_ready(dev)); - - gpio_pin_configure(dev, pin_number, GPIO_INPUT | pull_up_down); - - gpio_init_callback(&grant_cb, gpiote_irq_handler, - BIT(pin_number)); - gpio_add_callback(dev, &grant_cb); - - gpio_pin_interrupt_configure(dev, pin_number, - GPIO_INT_EDGE_BOTH); - break; - } - - default: - __ASSERT_NO_MSG(false); - } -} - -void nrf_802154_gpiote_deinit(void) -{ - switch (nrf_802154_wifi_coex_interface_type_id_get()) { - case NRF_802154_WIFI_COEX_IF_NONE: - break; - - case NRF_802154_WIFI_COEX_IF_3WIRE: - gpio_pin_interrupt_configure(dev, pin_number, GPIO_INT_DISABLE); - gpio_remove_callback(dev, &grant_cb); - pin_number = COEX_GPIO_PIN_INVALID; - break; - - default: - __ASSERT_NO_MSG(false); - } -} From 5833593513af1882f70f5f498bd5021e2a58f51a Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 2 Aug 2023 11:10:17 +0200 Subject: [PATCH 487/528] [nrf fromtree] manifest: Update nRF HW models to latest The nRF HW models have been updated to include the following fixes and improvements: * RADIO: Bugfix if DISABLE or STOP during first us of TxStart * File opening: Create folders if missing * TIMER: Completed, including all count functionality Signed-off-by: Alberto Escolar Piedras (cherry picked from commit 71b132ecdc59b53490c799041be3fafe9a7203b3) Signed-off-by: Ilhan Ates --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index ae18171c3d71..f4b5d9fc4c91 100644 --- a/west.yml +++ b/west.yml @@ -284,7 +284,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: cee41373eb0bb720a370586de1ee5eb693e62c95 + revision: 0a7f846b0ad38dd7355e5728e7ba77af91c5f848 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad From ac4dbf7ab791f807f7f5ded262d90e22988e79ff Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Wed, 2 Aug 2023 17:07:41 +0200 Subject: [PATCH 488/528] [nrf fromtree] manifest: Update nRF HW models to latest The nRF HW models have been updated to include the following fixes and improvements: * TIMER: Add missing HAL function override * TIMER: Added notes about minor differences Signed-off-by: Alberto Escolar Piedras (cherry picked from commit a419f9b4732d641f2617ebb195ab125c62404921) Signed-off-by: Ilhan Ates --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index f4b5d9fc4c91..a79382ffb0a1 100644 --- a/west.yml +++ b/west.yml @@ -284,7 +284,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 0a7f846b0ad38dd7355e5728e7ba77af91c5f848 + revision: 23bc852e3e4eaf64caa415b47e365ac1685ed91d path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad From 2119df306f5c9104d479f96c4c8af00857094f83 Mon Sep 17 00:00:00 2001 From: Alberto Escolar Piedras Date: Thu, 10 Aug 2023 14:05:41 +0200 Subject: [PATCH 489/528] [nrf fromtree] manifest: Update nRF HW models to latest The nRF HW models have been updated to include the following fixes and improvements: * TIMER: Fix bogus events/interrupts if shorts where used * PPI: Handle well an event triggering a task twice Signed-off-by: Alberto Escolar Piedras (cherry picked from commit b42331476d3d88a16a3e82c9ac83ea7864fdfc61) Signed-off-by: Ilhan Ates --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index a79382ffb0a1..94af73a2d792 100644 --- a/west.yml +++ b/west.yml @@ -284,7 +284,7 @@ manifest: groups: - tools - name: nrf_hw_models - revision: 23bc852e3e4eaf64caa415b47e365ac1685ed91d + revision: fa1daebb0f6f7ef135f9d2128590adfd88c0af44 path: modules/bsim_hw_models/nrf_hw_models - name: open-amp revision: c904a01d4a882bcbb39987e0e2ce5308f49ac7ad From 78106c74f4ac7936ef78dcddb8c6e1e578fe41dd Mon Sep 17 00:00:00 2001 From: Rubin Gerritsen Date: Fri, 11 Aug 2023 15:37:25 +0200 Subject: [PATCH 490/528] [nrf noup] ci: Only run lwm2m tests when needed There is no need to run those for all PRs. For example: When there are only changes to Bluetooth, we don't want this CI to run. Adding these filters may speedup the time to merge for PRs to sdk-nrf Signed-off-by: Rubin Gerritsen --- .github/test-spec.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 5dd281919bcc..53b811f9ae07 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -21,7 +21,7 @@ - "subsys/testsuite/ztest/**/*" "CI-lwm2m-test": - - "**/*" +# Not necessary to run tests on changes to this repo. "CI-boot-dfu-test": - "subsys/mgmt/mcumgr/**/*" From ff67180ef433b0555c55da5ee1bdbcb5370eb3de Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 30 Jun 2023 01:08:34 +0530 Subject: [PATCH 491/528] [nrf fromtree] net: wifi: Remove obsolete comment Support for legacy types has been added primarily to identify in scan results. Signed-off-by: Chaitanya Tata (cherry picked from commit 8c022fca8766c005ee68f18a650b1a37484c00e0) --- include/zephyr/net/wifi.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 9c65f3197901..a21f7874239e 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -19,9 +19,6 @@ #define WIFI_LISTEN_INTERVAL_MIN 0 #define WIFI_LISTEN_INTERVAL_MAX 65535 -/* Not having support for legacy types is deliberate to enforce - * higher security. - */ enum wifi_security_type { WIFI_SECURITY_TYPE_NONE = 0, WIFI_SECURITY_TYPE_PSK, From 33a29e55b901daed7b95d95bebcdc005f4d7cb37 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 30 Jun 2023 01:32:34 +0530 Subject: [PATCH 492/528] [nrf fromtree] net: wifi: Add doxygen style comments Fix doxygen formatting and add comments. Signed-off-by: Chaitanya Tata (cherry picked from commit 5ec3650d9fa5ed0183aa4c51db62e9cfb72df7a5) --- include/zephyr/net/wifi.h | 167 ++++++++++++++---- include/zephyr/net/wifi_mgmt.h | 306 +++++++++++++++++++++++++++++---- 2 files changed, 412 insertions(+), 61 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index a21f7874239e..0278680cd1db 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -6,7 +6,12 @@ /** * @file - * @brief General WiFi Definitions + * @brief IEEE 802.11 protocol and general Wi-Fi definitions. + */ + +/** + * @addtogroup wifi_mgmt + * @{ */ #ifndef ZEPHYR_INCLUDE_NET_WIFI_H_ @@ -19,14 +24,23 @@ #define WIFI_LISTEN_INTERVAL_MIN 0 #define WIFI_LISTEN_INTERVAL_MAX 65535 +/** IEEE 802.11 security types. */ enum wifi_security_type { + /** No security. */ WIFI_SECURITY_TYPE_NONE = 0, + /** WPA2-PSK security. */ WIFI_SECURITY_TYPE_PSK, + /** WPA2-PSK-SHA256 security. */ WIFI_SECURITY_TYPE_PSK_SHA256, + /** WPA3-SAE security. */ WIFI_SECURITY_TYPE_SAE, + /** GB 15629.11-2003 WAPI security. */ WIFI_SECURITY_TYPE_WAPI, + /** EAP security - Enterprise. */ WIFI_SECURITY_TYPE_EAP, + /** WEP security. */ WIFI_SECURITY_TYPE_WEP, + /** WPA-PSK security. */ WIFI_SECURITY_TYPE_WPA_PSK, __WIFI_SECURITY_TYPE_AFTER_LAST, @@ -34,9 +48,7 @@ enum wifi_security_type { WIFI_SECURITY_TYPE_UNKNOWN }; -/** - * wifi_security_txt - Get the security type as a text string - */ +/** Helper function to get user-friendly security type name. */ static inline const char *wifi_security_txt(enum wifi_security_type security) { switch (security) { @@ -62,10 +74,13 @@ static inline const char *wifi_security_txt(enum wifi_security_type security) } } -/* Management frame protection (IEEE 802.11w) options */ +/** IEEE 802.11w - Management frame protection. */ enum wifi_mfp_options { + /** MFP disabled. */ WIFI_MFP_DISABLE = 0, + /** MFP optional. */ WIFI_MFP_OPTIONAL, + /** MFP required. */ WIFI_MFP_REQUIRED, __WIFI_MFP_AFTER_LAST, @@ -73,9 +88,7 @@ enum wifi_mfp_options { WIFI_MFP_UNKNOWN }; -/** - * wifi_mfp_txt - Get the MFP as a text string - */ +/** Helper function to get user-friendly MFP name.*/ static inline const char *wifi_mfp_txt(enum wifi_mfp_options mfp) { switch (mfp) { @@ -91,9 +104,13 @@ static inline const char *wifi_mfp_txt(enum wifi_mfp_options mfp) } } +/** IEEE 802.11 operational frequency bands (not exhaustive). */ enum wifi_frequency_bands { + /** 2.4GHz band. */ WIFI_FREQ_BAND_2_4_GHZ = 0, + /** 5GHz band. */ WIFI_FREQ_BAND_5_GHZ, + /** 6GHz band (Wi-Fi 6E, also extends to 7GHz). */ WIFI_FREQ_BAND_6_GHZ, __WIFI_FREQ_BAND_AFTER_LAST, @@ -101,9 +118,7 @@ enum wifi_frequency_bands { WIFI_FREQ_BAND_UNKNOWN }; -/** - * wifi_mode_txt - Get the interface mode type as a text string - */ +/** Helper function to get user-friendly frequency band name. */ static inline const char *wifi_band_txt(enum wifi_frequency_bands band) { switch (band) { @@ -126,17 +141,30 @@ static inline const char *wifi_band_txt(enum wifi_frequency_bands band) #define WIFI_CHANNEL_MAX 233 #define WIFI_CHANNEL_ANY 255 -/* Based on https://w1.fi/wpa_supplicant/devel/defs_8h.html#a4aeb27c1e4abd046df3064ea9756f0bc */ +/** Wi-Fi interface states. + * + * Based on https://w1.fi/wpa_supplicant/devel/defs_8h.html#a4aeb27c1e4abd046df3064ea9756f0bc + */ enum wifi_iface_state { + /** Interface is disconnected. */ WIFI_STATE_DISCONNECTED = 0, + /** Interface is disabled (administratively). */ WIFI_STATE_INTERFACE_DISABLED, + /** No enabled networks in the configuration. */ WIFI_STATE_INACTIVE, + /** Interface is scanning for networks. */ WIFI_STATE_SCANNING, + /** Authentication with a network is in progress. */ WIFI_STATE_AUTHENTICATING, + /** Association with a network is in progress. */ WIFI_STATE_ASSOCIATING, + /** Association with a network completed. */ WIFI_STATE_ASSOCIATED, + /** 4-way handshake with a network is in progress. */ WIFI_STATE_4WAY_HANDSHAKE, + /** Group Key exchange with a network is in progress. */ WIFI_STATE_GROUP_HANDSHAKE, + /** All authentication completed, ready to pass data. */ WIFI_STATE_COMPLETED, __WIFI_STATE_AFTER_LAST, @@ -144,9 +172,7 @@ enum wifi_iface_state { WIFI_STATE_UNKNOWN }; -/** - * wifi_state_txt - Get the connection state name as a text string - */ +/** Helper function to get user-friendly interface state name. */ static inline const char *wifi_state_txt(enum wifi_iface_state state) { switch (state) { @@ -176,13 +202,22 @@ static inline const char *wifi_state_txt(enum wifi_iface_state state) } } -/* Based on https://w1.fi/wpa_supplicant/devel/structwpa__ssid.html#a625821e2acfc9014f3b3de6e6593ffb7 */ +/** Wi-Fi interface modes. + * + * Based on https://w1.fi/wpa_supplicant/devel/defs_8h.html#a4aeb27c1e4abd046df3064ea9756f0bc + */ enum wifi_iface_mode { + /** Infrastructure station mode. */ WIFI_MODE_INFRA = 0, + /** IBSS (ad-hoc) station mode. */ WIFI_MODE_IBSS = 1, + /** AP mode. */ WIFI_MODE_AP = 2, + /** P2P group owner mode. */ WIFI_MODE_P2P_GO = 3, + /** P2P group formation mode. */ WIFI_MODE_P2P_GROUP_FORMATION = 4, + /** 802.11s Mesh mode. */ WIFI_MODE_MESH = 5, __WIFI_MODE_AFTER_LAST, @@ -190,9 +225,7 @@ enum wifi_iface_mode { WIFI_MODE_UNKNOWN }; -/** - * wifi_mode_txt - Get the interface mode type as a text string - */ +/** Helper function to get user-friendly interface mode name. */ static inline const char *wifi_mode_txt(enum wifi_iface_mode mode) { switch (mode) { @@ -214,16 +247,28 @@ static inline const char *wifi_mode_txt(enum wifi_iface_mode mode) } } -/* As per https://en.wikipedia.org/wiki/Wi-Fi#Versions_and_generations */ +/** Wi-Fi link operating modes + * + * As per https://en.wikipedia.org/wiki/Wi-Fi#Versions_and_generations. + */ enum wifi_link_mode { + /** 802.11 (legacy). */ WIFI_0 = 0, + /** 802.11b. */ WIFI_1, + /** 802.11a. */ WIFI_2, + /** 802.11g. */ WIFI_3, + /** 802.11n. */ WIFI_4, + /** 802.11ac. */ WIFI_5, + /** 802.11ax. */ WIFI_6, + /** 802.11ax 6GHz. */ WIFI_6E, + /** 802.11be. */ WIFI_7, __WIFI_LINK_MODE_AFTER_LAST, @@ -231,9 +276,7 @@ enum wifi_link_mode { WIFI_LINK_MODE_UNKNOWN }; -/** - * wifi_link_mode_txt - Get the link mode type as a text string - */ +/** Helper function to get user-friendly link mode name. */ static inline const char *wifi_link_mode_txt(enum wifi_link_mode link_mode) { switch (link_mode) { @@ -261,13 +304,19 @@ static inline const char *wifi_link_mode_txt(enum wifi_link_mode link_mode) } } +/** Wi-Fi scanning types. */ enum wifi_scan_type { + /** Active scanning (default). */ WIFI_SCAN_TYPE_ACTIVE = 0, + /** Passive scanning. */ WIFI_SCAN_TYPE_PASSIVE, }; +/** Wi-Fi power save states. */ enum wifi_ps { + /** Power save disabled. */ WIFI_PS_DISABLED = 0, + /** Power save enabled. */ WIFI_PS_ENABLED, }; @@ -276,11 +325,14 @@ static const char * const wifi_ps2str[] = { [WIFI_PS_ENABLED] = "Power save enabled", }; +/** Wi-Fi power save modes. */ enum wifi_ps_mode { + /** Legacy power save mode. */ WIFI_PS_MODE_LEGACY = 0, /* This has to be configured before connecting to the AP, * as support for ADDTS action frames is not available. */ + /** WMM power save mode. */ WIFI_PS_MODE_WMM, }; @@ -289,8 +341,11 @@ static const char * const wifi_ps_mode2str[] = { [WIFI_PS_MODE_WMM] = "WMM power save", }; +/** Wi-Fi Target Wake Time (TWT) operations. */ enum wifi_twt_operation { + /* TWT setup operation */ WIFI_TWT_SETUP = 0, + /* TWT teardown operation */ WIFI_TWT_TEARDOWN, }; @@ -299,9 +354,13 @@ static const char * const wifi_twt_operation2str[] = { [WIFI_TWT_TEARDOWN] = "TWT teardown", }; +/** Wi-Fi Target Wake Time (TWT) negotiation types. */ enum wifi_twt_negotiation_type { + /* TWT individual negotiation */ WIFI_TWT_INDIVIDUAL = 0, + /* TWT broadcast negotiation */ WIFI_TWT_BROADCAST, + /* TWT wake TBTT negotiation */ WIFI_TWT_WAKE_TBTT }; @@ -311,25 +370,32 @@ static const char * const wifi_twt_negotiation_type2str[] = { [WIFI_TWT_WAKE_TBTT] = "TWT wake TBTT negotiation", }; +/** Wi-Fi Target Wake Time (TWT) setup commands. */ enum wifi_twt_setup_cmd { - /* TWT Requests */ + /** TWT Requests */ + /* TWT setup request */ WIFI_TWT_SETUP_CMD_REQUEST = 0, + /* TWT setup suggest (parameters can be changed by AP) */ WIFI_TWT_SETUP_CMD_SUGGEST, + /* TWT setup demand (parameters can not be changed by AP) */ WIFI_TWT_SETUP_CMD_DEMAND, - /* TWT Responses */ + /** TWT Responses */ + /* TWT setup grouping (grouping of TWT flows) */ WIFI_TWT_SETUP_CMD_GROUPING, + /* TWT setup accept (parameters accepted by AP) */ WIFI_TWT_SETUP_CMD_ACCEPT, + /* TWT setup alternate (alternate parameters suggested by AP) */ WIFI_TWT_SETUP_CMD_ALTERNATE, + /* TWT setup dictate (parameters dictated by AP) */ WIFI_TWT_SETUP_CMD_DICTATE, + /* TWT setup reject (parameters rejected by AP) */ WIFI_TWT_SETUP_CMD_REJECT, }; static const char * const wifi_twt_setup_cmd2str[] = { - /* TWT Requests */ [WIFI_TWT_SETUP_CMD_REQUEST] = "TWT request", [WIFI_TWT_SETUP_CMD_SUGGEST] = "TWT suggest", [WIFI_TWT_SETUP_CMD_DEMAND] = "TWT demand", - /* TWT Responses */ [WIFI_TWT_SETUP_CMD_GROUPING] = "TWT grouping", [WIFI_TWT_SETUP_CMD_ACCEPT] = "TWT accept", [WIFI_TWT_SETUP_CMD_ALTERNATE] = "TWT alternate", @@ -337,23 +403,37 @@ static const char * const wifi_twt_setup_cmd2str[] = { [WIFI_TWT_SETUP_CMD_REJECT] = "TWT reject", }; +/** Wi-Fi Target Wake Time (TWT) negotiation status. */ enum wifi_twt_setup_resp_status { - /* TWT Setup response status */ + /** TWT response received for TWT request */ WIFI_TWT_RESP_RECEIVED = 0, + /** TWT response not received for TWT request */ WIFI_TWT_RESP_NOT_RECEIVED, }; +/** Target Wake Time (TWT) error codes. */ enum wifi_twt_fail_reason { + /** Unspecified error */ WIFI_TWT_FAIL_UNSPECIFIED, + /** Command execution failed */ WIFI_TWT_FAIL_CMD_EXEC_FAIL, + /** Operation not supported */ WIFI_TWT_FAIL_OPERATION_NOT_SUPPORTED, + /** Unable to get interface status */ WIFI_TWT_FAIL_UNABLE_TO_GET_IFACE_STATUS, + /** Device not connected to AP */ WIFI_TWT_FAIL_DEVICE_NOT_CONNECTED, + /** Peer not HE (802.11ax/Wi-Fi 6) capable */ WIFI_TWT_FAIL_PEER_NOT_HE_CAPAB, + /** Peer not TWT capable */ WIFI_TWT_FAIL_PEER_NOT_TWT_CAPAB, + /** A TWT flow is already in progress */ WIFI_TWT_FAIL_OPERATION_IN_PROGRESS, + /** Invalid negotiated flow id */ WIFI_TWT_FAIL_INVALID_FLOW_ID, + /** IP address not assigned or configured */ WIFI_TWT_FAIL_IP_NOT_ASSIGNED, + /** Flow already exists */ WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS, }; @@ -378,6 +458,7 @@ static const char * const twt_err_code_tbl[] = { "Flow already exists", }; +/** Helper function to get user-friendly TWT error code name. */ static inline const char *get_twt_err_code_str(int16_t err_no) { if ((err_no) < (int16_t)ARRAY_SIZE(twt_err_code_tbl)) { @@ -387,16 +468,25 @@ static inline const char *get_twt_err_code_str(int16_t err_no) return ""; } +/** Wi-Fi power save parameters. */ enum ps_param_type { + /** Power save state. */ WIFI_PS_PARAM_STATE, + /** Power save listen interval. */ WIFI_PS_PARAM_LISTEN_INTERVAL, + /** Power save wakeup mode. */ WIFI_PS_PARAM_WAKEUP_MODE, + /** Power save mode. */ WIFI_PS_PARAM_MODE, + /** Power save timeout. */ WIFI_PS_PARAM_TIMEOUT, }; +/** Wi-Fi power save modes. */ enum wifi_ps_wakeup_mode { + /** DTIM based wakeup. */ WIFI_PS_WAKEUP_MODE_DTIM = 0, + /** Listen interval based wakeup. */ WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL, }; @@ -405,31 +495,40 @@ static const char * const wifi_ps_wakeup_mode2str[] = { [WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL] = "PS wakeup mode listen interval", }; +/** Wi-Fi power save error codes. */ enum wifi_config_ps_param_fail_reason { + /** Unspecified error */ WIFI_PS_PARAM_FAIL_UNSPECIFIED, + /** Command execution failed */ WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL, + /** Parameter not supported */ WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED, + /** Unable to get interface status */ WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS, + /** Device not connected to AP */ WIFI_PS_PARAM_FAIL_DEVICE_NOT_CONNECTED, + /** Device already connected to AP */ WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED, + /** Listen interval out of range */ WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID, }; static const char * const ps_param_config_err_code_tbl[] = { - [WIFI_PS_PARAM_FAIL_UNSPECIFIED] = "Unspecfied", + [WIFI_PS_PARAM_FAIL_UNSPECIFIED] = "Unspecified", [WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", [WIFI_PS_PARAM_FAIL_OPERATION_NOT_SUPPORTED] = "Operation not supported", [WIFI_PS_PARAM_FAIL_UNABLE_TO_GET_IFACE_STATUS] = "Unable to get iface status", [WIFI_PS_PARAM_FAIL_DEVICE_NOT_CONNECTED] = - "Can not set while device not connected", + "Cannot set parameters while device not connected", [WIFI_PS_PARAM_FAIL_DEVICE_CONNECTED] = - "Can not set while device already connected", + "Cannot set parameters while device connected", [WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID] = - "Can not set due to invalid range", + "Parameter out of range", }; +/** Helper function to get user-friendly power save error code name. */ static inline const char *get_ps_config_err_code_str(int16_t err_no) { if ((err_no) < (int16_t)ARRAY_SIZE(ps_param_config_err_code_tbl)) { @@ -438,4 +537,8 @@ static inline const char *get_ps_config_err_code_str(int16_t err_no) return ""; } + +/** + * @} + */ #endif /* ZEPHYR_INCLUDE_NET_WIFI_H_ */ diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index fdb2814408b1..09d875f1394f 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -21,6 +21,11 @@ extern "C" { #endif +/** + * @addtogroup wifi_mgmt + * @{ + */ + /* Management part definitions */ #define _NET_WIFI_LAYER NET_MGMT_LAYER_L2 @@ -30,18 +35,31 @@ extern "C" { NET_MGMT_LAYER_CODE(_NET_WIFI_CODE)) #define _NET_WIFI_EVENT (_NET_WIFI_BASE | NET_MGMT_EVENT_BIT) +/** Wi-Fi management commands */ enum net_request_wifi_cmd { + /** Scan for Wi-Fi networks */ NET_REQUEST_WIFI_CMD_SCAN = 1, + /** Connect to a Wi-Fi network */ NET_REQUEST_WIFI_CMD_CONNECT, + /** Disconnect from a Wi-Fi network */ NET_REQUEST_WIFI_CMD_DISCONNECT, + /** Enable AP mode */ NET_REQUEST_WIFI_CMD_AP_ENABLE, + /** Disable AP mode */ NET_REQUEST_WIFI_CMD_AP_DISABLE, + /** Get interface status */ NET_REQUEST_WIFI_CMD_IFACE_STATUS, + /** Set power save status */ NET_REQUEST_WIFI_CMD_PS, + /** Set power save mode */ NET_REQUEST_WIFI_CMD_PS_MODE, + /** Setup or teardown TWT flow */ NET_REQUEST_WIFI_CMD_TWT, + /** Get power save config */ NET_REQUEST_WIFI_CMD_PS_CONFIG, + /** Set or get regulatory domain */ NET_REQUEST_WIFI_CMD_REG_DOMAIN, + /** Set power save timeout */ NET_REQUEST_WIFI_CMD_PS_TIMEOUT, NET_REQUEST_WIFI_CMD_MAX }; @@ -105,15 +123,27 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_REG_DOMAIN); NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_PS_TIMEOUT); +/** Wi-Fi management events */ enum net_event_wifi_cmd { + /** Scan results available */ NET_EVENT_WIFI_CMD_SCAN_RESULT = 1, + /** Scan done */ NET_EVENT_WIFI_CMD_SCAN_DONE, + /** Connect result */ NET_EVENT_WIFI_CMD_CONNECT_RESULT, + /** Disconnect result */ NET_EVENT_WIFI_CMD_DISCONNECT_RESULT, + /** Interface status */ NET_EVENT_WIFI_CMD_IFACE_STATUS, + /** TWT events */ NET_EVENT_WIFI_CMD_TWT, + /** TWT sleep status: awake or sleeping, can be used by application + * to determine if it can send data or not. + */ NET_EVENT_WIFI_CMD_TWT_SLEEP_STATE, + /** Raw scan results available */ NET_EVENT_WIFI_CMD_RAW_SCAN_RESULT, + /** Disconnect complete */ NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE, }; @@ -144,8 +174,11 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) +/** Wi-Fi scan parameters */ struct wifi_scan_params { - /* The scan_type is only a hint to the underlying Wi-Fi chip for the + /** Scan type, see enum wifi_scan_type. + * + * The scan_type is only a hint to the underlying Wi-Fi chip for the * preferred mode of scan. The actual mode of scan can depend on factors * such as the Wi-Fi chip implementation support, regulatory domain * restrictions etc. @@ -153,102 +186,155 @@ struct wifi_scan_params { enum wifi_scan_type scan_type; }; -/* Each result is provided to the net_mgmt_event_callback +/** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback * via its info attribute (see net_mgmt.h) */ struct wifi_scan_result { + /** SSID */ uint8_t ssid[WIFI_SSID_MAX_LEN]; + /** SSID length */ uint8_t ssid_length; - + /** Frequency band */ uint8_t band; + /** Channel */ uint8_t channel; + /** Security type */ enum wifi_security_type security; + /** MFP options */ enum wifi_mfp_options mfp; + /** RSSI */ int8_t rssi; - + /** BSSID */ uint8_t mac[WIFI_MAC_ADDR_LEN]; + /** BSSID length */ uint8_t mac_length; }; +/** Wi-Fi connect request parameters */ struct wifi_connect_req_params { + /** SSID */ const uint8_t *ssid; + /** SSID length */ uint8_t ssid_length; /* Max 32 */ - + /** Pre-shared key */ uint8_t *psk; + /** Pre-shared key length */ uint8_t psk_length; /* Min 8 - Max 64 */ - - uint8_t *sae_password; /* Optional with fallback to psk */ + /** SAE password (same as PSK but with no length restrictions), optional */ + uint8_t *sae_password; + /** SAE password length */ uint8_t sae_password_length; /* No length restrictions */ - + /** Frequency band */ uint8_t band; + /** Channel */ uint8_t channel; + /** Security type */ enum wifi_security_type security; + /** MFP options */ enum wifi_mfp_options mfp; - int timeout; /* SYS_FOREVER_MS for no timeout */ + /** Connect timeout in seconds, SYS_FOREVER_MS for no timeout */ + int timeout; }; +/** Generic Wi-Fi status for commands and events */ struct wifi_status { int status; }; +/** Wi-Fi interface status */ struct wifi_iface_status { - int state; /* enum wifi_iface_state */ + /** Interface state, see enum wifi_iface_state */ + int state; + /** SSID length */ unsigned int ssid_len; + /** SSID */ char ssid[WIFI_SSID_MAX_LEN]; + /** BSSID */ char bssid[WIFI_MAC_ADDR_LEN]; + /** Frequency band */ enum wifi_frequency_bands band; + /** Channel */ unsigned int channel; + /** Interface mode, see enum wifi_iface_mode */ enum wifi_iface_mode iface_mode; + /** Link mode, see enum wifi_link_mode */ enum wifi_link_mode link_mode; + /** Security type, see enum wifi_security_type */ enum wifi_security_type security; + /** MFP options, see enum wifi_mfp_options */ enum wifi_mfp_options mfp; + /** RSSI */ int rssi; + /** DTIM period */ unsigned char dtim_period; + /** Beacon interval */ unsigned short beacon_interval; + /** is TWT capable? */ bool twt_capable; }; +/** Wi-Fi power save parameters */ struct wifi_ps_params { + /* Power save state */ enum wifi_ps enabled; + /* Listen interval */ unsigned short listen_interval; + /** Wi-Fi power save wakeup mode */ enum wifi_ps_wakeup_mode wakeup_mode; + /** Wi-Fi power save mode */ enum wifi_ps_mode mode; - /* This is the time out to wait after sending a TX packet + /** Wi-Fi power save timeout + * + * This is the time out to wait after sending a TX packet * before going back to power save (in ms) to receive any replies * from the AP. Zero means this feature is disabled. * * It's a tradeoff between power consumption and latency. */ unsigned int timeout_ms; + /** Wi-Fi power save type */ enum ps_param_type type; + /** Wi-Fi power save fail reason */ enum wifi_config_ps_param_fail_reason fail_reason; }; +/** Wi-Fi TWT parameters */ struct wifi_twt_params { + /** TWT operation, see enum wifi_twt_operation */ enum wifi_twt_operation operation; + /** TWT negotiation type, see enum wifi_twt_negotiation_type */ enum wifi_twt_negotiation_type negotiation_type; + /** TWT setup command, see enum wifi_twt_setup_cmd */ enum wifi_twt_setup_cmd setup_cmd; + /** TWT setup response status, see enum wifi_twt_setup_resp_status */ enum wifi_twt_setup_resp_status resp_status; - /* Map requests to responses */ + /** Dialog token, used to map requests to responses */ uint8_t dialog_token; - /* Map setup with teardown */ + /** Flow ID, used to map setup with teardown */ uint8_t flow_id; union { + /** Setup specific parameters */ struct { - /* Interval = Wake up time + Sleeping time */ + /**Interval = Wake up time + Sleeping time */ uint64_t twt_interval; + /** Requestor or responder */ bool responder; + /** Trigger enabled or disabled */ bool trigger; + /** Implicit or explicit */ bool implicit; + /** Announced or unannounced */ bool announce; - /* Wake up time */ + /** Wake up time */ uint32_t twt_wake_interval; } setup; + /** Teardown specific parameters */ struct { - /* Only for Teardown */ + /** Teardown all flows */ bool teardown_all; } teardown; }; + /** TWT fail reason, see enum wifi_twt_fail_reason */ enum wifi_twt_fail_reason fail_reason; }; @@ -257,87 +343,201 @@ struct wifi_twt_params { #define WIFI_MAX_TWT_INTERVAL_US (LONG_MAX - 1) /* 256 (u8) * 1TU */ #define WIFI_MAX_TWT_WAKE_INTERVAL_US 262144 + +/** Wi-Fi TWT flow information */ struct wifi_twt_flow_info { - /* Interval = Wake up time + Sleeping time */ + /** Interval = Wake up time + Sleeping time */ uint64_t twt_interval; - /* Map requests to responses */ + /** Dialog token, used to map requests to responses */ uint8_t dialog_token; - /* Map setup with teardown */ + /** Flow ID, used to map setup with teardown */ uint8_t flow_id; + /** TWT negotiation type, see enum wifi_twt_negotiation_type */ enum wifi_twt_negotiation_type negotiation_type; + /** Requestor or responder */ bool responder; + /** Trigger enabled or disabled */ bool trigger; + /** Implicit or explicit */ bool implicit; + /** Announced or unannounced */ bool announce; - /* Wake up time */ + /** Wake up time */ uint32_t twt_wake_interval; }; +/** Wi-Fi power save configuration */ struct wifi_ps_config { + /** Number of TWT flows */ char num_twt_flows; + /** TWT flow details */ struct wifi_twt_flow_info twt_flows[WIFI_MAX_TWT_FLOWS]; + /** Power save configuration */ struct wifi_ps_params ps_params; }; -/* Generic get/set operation for any command*/ +/** Generic get/set operation for any command*/ enum wifi_mgmt_op { + /** Get operation */ WIFI_MGMT_GET = 0, + /** Set operation */ WIFI_MGMT_SET = 1, }; +/** Regulatory domain information or configuration */ struct wifi_reg_domain { + /* Regulatory domain operation */ enum wifi_mgmt_op oper; - /* Ignore all other regulatory hints */ + /** Ignore all other regulatory hints over this one */ bool force; + /** Country code: ISO/IEC 3166-1 alpha-2 */ uint8_t country_code[WIFI_COUNTRY_CODE_LEN]; }; +/** Wi-Fi TWT sleep states */ enum wifi_twt_sleep_state { + /** TWT sleep state: sleeping */ WIFI_TWT_STATE_SLEEP = 0, + /** TWT sleep state: awake */ WIFI_TWT_STATE_AWAKE = 1, }; -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS +#if defined(CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS) || defined(__DOXYGEN__) +/** Wi-Fi raw scan result */ struct wifi_raw_scan_result { + /** RSSI */ int8_t rssi; + /** Frame length */ int frame_length; + /** Frequency */ unsigned short frequency; + /** Raw scan data */ uint8_t data[CONFIG_WIFI_MGMT_RAW_SCAN_RESULT_LENGTH]; }; #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ #include +/** Scan result callback + * + * @param iface Network interface + * @param status Scan result status + * @param entry Scan result entry + */ typedef void (*scan_result_cb_t)(struct net_if *iface, int status, struct wifi_scan_result *entry); #ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS +/** Raw scan result callback + * + * @param iface Network interface + * @param status Raw scan result status + * @param entry Raw scan result entry + */ typedef void (*raw_scan_result_cb_t)(struct net_if *iface, int status, struct wifi_raw_scan_result *entry); #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ + +/** Wi-Fi management API */ struct wifi_mgmt_ops { - /* cb parameter is the cb that should be called for each - * result by the driver. The wifi mgmt part will take care of - * raising the necessary event etc... + /** Scan for Wi-Fi networks + * + * @param dev Pointer to the device structure for the driver instance. + * @param params Scan parameters + * @param cb Callback to be called for each result + * cb parameter is the cb that should be called for each + * result by the driver. The wifi mgmt part will take care of + * raising the necessary event etc. + * + * @return 0 if ok, < 0 if error */ int (*scan)(const struct device *dev, struct wifi_scan_params *params, scan_result_cb_t cb); + /** Connect to a Wi-Fi network + * + * @param dev Pointer to the device structure for the driver instance. + * @param params Connect parameters + * + * @return 0 if ok, < 0 if error + */ int (*connect)(const struct device *dev, struct wifi_connect_req_params *params); + /** Disconnect from a Wi-Fi network + * + * @param dev Pointer to the device structure for the driver instance. + * + * @return 0 if ok, < 0 if error + */ int (*disconnect)(const struct device *dev); + /** Enable AP mode + * + * @param dev Pointer to the device structure for the driver instance. + * @param params AP mode parameters + * + * @return 0 if ok, < 0 if error + */ int (*ap_enable)(const struct device *dev, struct wifi_connect_req_params *params); + /** Disable AP mode + * + * @param dev Pointer to the device structure for the driver instance. + * + * @return 0 if ok, < 0 if error + */ int (*ap_disable)(const struct device *dev); + /** Get interface status + * + * @param dev Pointer to the device structure for the driver instance. + * @param status Interface status + * + * @return 0 if ok, < 0 if error + */ int (*iface_status)(const struct device *dev, struct wifi_iface_status *status); -#ifdef CONFIG_NET_STATISTICS_WIFI +#if defined(CONFIG_NET_STATISTICS_WIFI) || defined(__DOXYGEN__) + /** Get Wi-Fi statistics + * + * @param dev Pointer to the device structure for the driver instance. + * @param stats Wi-Fi statistics + * + * @return 0 if ok, < 0 if error + */ int (*get_stats)(const struct device *dev, struct net_stats_wifi *stats); #endif /* CONFIG_NET_STATISTICS_WIFI */ + /** Set power save status + * + * @param dev Pointer to the device structure for the driver instance. + * @param params Power save parameters + * + * @return 0 if ok, < 0 if error + */ int (*set_power_save)(const struct device *dev, struct wifi_ps_params *params); + /** Setup or teardown TWT flow + * + * @param dev Pointer to the device structure for the driver instance. + * @param params TWT parameters + * + * @return 0 if ok, < 0 if error + */ int (*set_twt)(const struct device *dev, struct wifi_twt_params *params); + /** Get power save config + * + * @param dev Pointer to the device structure for the driver instance. + * @param config Power save config + * + * @return 0 if ok, < 0 if error + */ int (*get_power_save_config)(const struct device *dev, struct wifi_ps_config *config); + /** Set or get regulatory domain + * + * @param dev Pointer to the device structure for the driver instance. + * @param reg_domain Regulatory domain + * + * @return 0 if ok, < 0 if error + */ int (*reg_domain)(const struct device *dev, struct wifi_reg_domain *reg_domain); }; +/** Wi-Fi management offload API */ struct net_wifi_mgmt_offload { /** * Mandatory to get in first position. @@ -345,11 +545,14 @@ struct net_wifi_mgmt_offload { * net_if_api structure. So we make current structure pointer * that can be casted to a net_if_api structure pointer. */ -#ifdef CONFIG_WIFI_USE_NATIVE_NETWORKING +#if defined(CONFIG_WIFI_USE_NATIVE_NETWORKING) || defined(__DOXYGEN__) + /** Ethernet API */ struct ethernet_api wifi_iface; #else + /** Offloaded network device API */ struct offloaded_if_api wifi_iface; #endif + /** Wi-Fi management API */ const struct wifi_mgmt_ops *const wifi_mgmt_api; }; @@ -358,18 +561,63 @@ struct net_wifi_mgmt_offload { */ BUILD_ASSERT(offsetof(struct net_wifi_mgmt_offload, wifi_iface) == 0); +/** Wi-Fi management connect result event + * + * @param iface Network interface + * @param status Connect result status + */ void wifi_mgmt_raise_connect_result_event(struct net_if *iface, int status); + +/** Wi-Fi management disconnect result event + * + * @param iface Network interface + * @param status Disconnect result status + */ void wifi_mgmt_raise_disconnect_result_event(struct net_if *iface, int status); + +/** Wi-Fi management interface status event + * + * @param iface Network interface + * @param iface_status Interface status + */ void wifi_mgmt_raise_iface_status_event(struct net_if *iface, struct wifi_iface_status *iface_status); + +/** Wi-Fi management TWT event + * + * @param iface Network interface + * @param twt_params TWT parameters + */ void wifi_mgmt_raise_twt_event(struct net_if *iface, struct wifi_twt_params *twt_params); + +/** Wi-Fi management TWT sleep state event + * + * @param iface Network interface + * @param twt_sleep_state TWT sleep state + */ void wifi_mgmt_raise_twt_sleep_state(struct net_if *iface, int twt_sleep_state); -#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS + +#if defined(CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS) || defined(__DOXYGEN__) +/** Wi-Fi management raw scan result event + * + * @param iface Network interface + * @param raw_scan_info Raw scan result + */ void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface, struct wifi_raw_scan_result *raw_scan_info); #endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ + +/** Wi-Fi management disconnect complete event + * + * @param iface Network interface + * @param status Disconnect complete status + */ void wifi_mgmt_raise_disconnect_complete_event(struct net_if *iface, int status); + +/** + * @} + */ #ifdef __cplusplus } #endif From dfaa444039a377952a86fe9d7ef6e5747a838b57 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Fri, 30 Jun 2023 02:20:49 +0530 Subject: [PATCH 493/528] [nrf fromtree] doc: net: Add Wi-Fi management Add Wi-Fi management docs and APIs. Signed-off-by: Chaitanya Tata (cherry picked from commit 3e1681eaa1f7fd47307028794ff7592396e20b3c) --- doc/connectivity/networking/api/net_tech.rst | 1 + doc/connectivity/networking/api/wifi.rst | 30 ++++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 doc/connectivity/networking/api/wifi.rst diff --git a/doc/connectivity/networking/api/net_tech.rst b/doc/connectivity/networking/api/net_tech.rst index 3575db974b54..910ec4e0cce5 100644 --- a/doc/connectivity/networking/api/net_tech.rst +++ b/doc/connectivity/networking/api/net_tech.rst @@ -10,3 +10,4 @@ Networking Technologies ieee802154.rst thread.rst ppp.rst + wifi.rst diff --git a/doc/connectivity/networking/api/wifi.rst b/doc/connectivity/networking/api/wifi.rst new file mode 100644 index 000000000000..be29d9f8ddaa --- /dev/null +++ b/doc/connectivity/networking/api/wifi.rst @@ -0,0 +1,30 @@ +.. _wifi_mgmt: + +Wi-Fi Management +################ + +Overview +======== + +The Wi-Fi management API is used to manage Wi-Fi networks. It supports below modes: + +* IEEE802.11 Station (STA) +* IEEE802.11 Access Point (AP) + +Only personal mode security is supported with below types: + +* Open +* WPA2-PSK +* WPA3-PSK-256 +* WPA3-SAE + +The Wi-Fi management API is implemented in the `wifi_mgmt` module as a part of the networking L2 stack. +Currently, two types of Wi-Fi drivers are supported: + +* Networking or socket offloaded drivers +* Native L2 Ethernet drivers + +API Reference +************* + +.. doxygengroup:: wifi_mgmt From 2b762391bb0b0f27eb0993c070ac6546dd2d1a09 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Sun, 16 Jul 2023 00:31:06 +0530 Subject: [PATCH 494/528] [nrf fromtree] wifi: Fix doxygen comments Fix TWT comment to conform to doxygen style. Signed-off-by: Chaitanya Tata (cherry picked from commit 94e0e10193ca2ea12984b564068b2478cd113e95) --- include/zephyr/net/wifi.h | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 0278680cd1db..e7388fe6f6fe 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -343,9 +343,9 @@ static const char * const wifi_ps_mode2str[] = { /** Wi-Fi Target Wake Time (TWT) operations. */ enum wifi_twt_operation { - /* TWT setup operation */ + /** TWT setup operation */ WIFI_TWT_SETUP = 0, - /* TWT teardown operation */ + /** TWT teardown operation */ WIFI_TWT_TEARDOWN, }; @@ -356,11 +356,11 @@ static const char * const wifi_twt_operation2str[] = { /** Wi-Fi Target Wake Time (TWT) negotiation types. */ enum wifi_twt_negotiation_type { - /* TWT individual negotiation */ + /** TWT individual negotiation */ WIFI_TWT_INDIVIDUAL = 0, - /* TWT broadcast negotiation */ + /** TWT broadcast negotiation */ WIFI_TWT_BROADCAST, - /* TWT wake TBTT negotiation */ + /** TWT wake TBTT negotiation */ WIFI_TWT_WAKE_TBTT }; @@ -372,23 +372,21 @@ static const char * const wifi_twt_negotiation_type2str[] = { /** Wi-Fi Target Wake Time (TWT) setup commands. */ enum wifi_twt_setup_cmd { - /** TWT Requests */ - /* TWT setup request */ + /** TWT setup request */ WIFI_TWT_SETUP_CMD_REQUEST = 0, - /* TWT setup suggest (parameters can be changed by AP) */ + /** TWT setup suggest (parameters can be changed by AP) */ WIFI_TWT_SETUP_CMD_SUGGEST, - /* TWT setup demand (parameters can not be changed by AP) */ + /** TWT setup demand (parameters can not be changed by AP) */ WIFI_TWT_SETUP_CMD_DEMAND, - /** TWT Responses */ - /* TWT setup grouping (grouping of TWT flows) */ + /** TWT setup grouping (grouping of TWT flows) */ WIFI_TWT_SETUP_CMD_GROUPING, - /* TWT setup accept (parameters accepted by AP) */ + /** TWT setup accept (parameters accepted by AP) */ WIFI_TWT_SETUP_CMD_ACCEPT, - /* TWT setup alternate (alternate parameters suggested by AP) */ + /** TWT setup alternate (alternate parameters suggested by AP) */ WIFI_TWT_SETUP_CMD_ALTERNATE, - /* TWT setup dictate (parameters dictated by AP) */ + /** TWT setup dictate (parameters dictated by AP) */ WIFI_TWT_SETUP_CMD_DICTATE, - /* TWT setup reject (parameters rejected by AP) */ + /** TWT setup reject (parameters rejected by AP) */ WIFI_TWT_SETUP_CMD_REJECT, }; From 1ab2d12e27b7295b2b1f394c28f5b0be9ca7e829 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Thu, 13 Jul 2023 19:44:08 +0530 Subject: [PATCH 495/528] [nrf fromlist] net: wifi: Modify option and argument for scan type Modify the way the scan type option is passed to the wifi scan command. This makes it flexible to add more scan options. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- subsys/net/l2/Kconfig | 2 ++ subsys/net/l2/wifi/wifi_shell.c | 57 ++++++++++++++++++++++----------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/subsys/net/l2/Kconfig b/subsys/net/l2/Kconfig index 468e1729dd78..84be2a4bd8ef 100644 --- a/subsys/net/l2/Kconfig +++ b/subsys/net/l2/Kconfig @@ -116,6 +116,8 @@ endif # NET_L2_WIFI_MGMT config NET_L2_WIFI_SHELL bool "Wi-Fi shell module" select NET_L2_WIFI_MGMT + select SHELL_GETOPT + select GETOPT_LONG help This can be used for controlling Wi-Fi through the console via exposing a shell module named "wifi". diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index a2ef9e6d242c..ec90db926aea 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include #include #include +#include #include "net_private.h" @@ -444,6 +445,40 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, return 0; } + +static int wifi_scan_args_to_params(const struct shell *sh, + size_t argc, + char *argv[], + struct wifi_scan_params *params) +{ + struct getopt_state *state; + int opt; + static struct option long_options[] = {{"type", required_argument, 0, 't'}, + {0, 0, 0, 0}}; + int opt_index = 0; + + while ((opt = getopt_long(argc, argv, "t:", long_options, &opt_index)) != -1) { + state = getopt_state_get(); + switch (opt) { + case 't': + if (!strcmp(optarg, "passive")) { + params->scan_type = WIFI_SCAN_TYPE_PASSIVE; + } else if (!strcmp(optarg, "active")) { + params->scan_type = WIFI_SCAN_TYPE_ACTIVE; + } else { + shell_fprintf(sh, SHELL_ERROR, "Invalid scan type %s\n", optarg); + return -ENOEXEC; + } + break; + case '?': + shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", + long_options[opt_index].name); + return -ENOEXEC; + } + } + return 0; +} + static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); @@ -451,27 +486,13 @@ static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) context.sh = sh; - if (argc > 2) { - shell_fprintf(sh, SHELL_WARNING, "Invalid number of arguments\n"); + if (wifi_scan_args_to_params(sh, argc, argv, ¶ms)) { + shell_help(sh); return -ENOEXEC; } - if (argc == 2) { - if (!strcmp(argv[1], "passive")) { - params.scan_type = WIFI_SCAN_TYPE_PASSIVE; - } else if (!strcmp(argv[1], "active")) { - params.scan_type = WIFI_SCAN_TYPE_ACTIVE; - } else { - shell_fprintf(sh, SHELL_WARNING, "Invalid argument\n"); - shell_fprintf(sh, SHELL_INFO, - "Valid argument : / \n"); - return -ENOEXEC; - } - } - if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, ¶ms, sizeof(params))) { shell_fprintf(sh, SHELL_WARNING, "Scan request failed\n"); - return -ENOEXEC; } @@ -528,7 +549,6 @@ static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) return 0; } - #if defined(CONFIG_NET_STATISTICS_WIFI) && \ defined(CONFIG_NET_STATISTICS_USER_API) static void print_wifi_stats(struct net_if *iface, struct net_stats_wifi *data, @@ -1135,7 +1155,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, 0), SHELL_CMD(scan, NULL, "Scan for Wi-Fi APs\n" - " : >\n", + "OPTIONS:\n" + "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), From 215b968ac9e6f3976da7ee4f626f9f9506c70dbd Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Mon, 17 Jul 2023 20:47:03 +0530 Subject: [PATCH 496/528] [nrf fromlist] net: wifi: Added scan extension support for frequency bands Added scan extension to support scanning individual Wi-Fi bands or combinations thereof. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- include/zephyr/net/wifi.h | 13 ++++-- include/zephyr/net/wifi_mgmt.h | 10 ++++- include/zephyr/net/wifi_utils.h | 69 +++++++++++++++++++++++++++++++ subsys/net/l2/Kconfig | 7 ++++ subsys/net/l2/wifi/CMakeLists.txt | 1 + subsys/net/l2/wifi/Kconfig | 12 ++++++ subsys/net/l2/wifi/wifi_mgmt.c | 12 +++++- subsys/net/l2/wifi/wifi_shell.c | 21 +++++++--- subsys/net/l2/wifi/wifi_utils.c | 65 +++++++++++++++++++++++++++++ 9 files changed, 199 insertions(+), 11 deletions(-) create mode 100644 include/zephyr/net/wifi_utils.h create mode 100644 subsys/net/l2/wifi/wifi_utils.c diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index e7388fe6f6fe..65dcd9e5118f 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -104,17 +104,22 @@ static inline const char *wifi_mfp_txt(enum wifi_mfp_options mfp) } } -/** IEEE 802.11 operational frequency bands (not exhaustive). */ +/** + * @brief IEEE 802.11 operational frequency bands (not exhaustive). + */ enum wifi_frequency_bands { - /** 2.4GHz band. */ + /** 2.4 GHz band. */ WIFI_FREQ_BAND_2_4_GHZ = 0, - /** 5GHz band. */ + /** 5 GHz band. */ WIFI_FREQ_BAND_5_GHZ, - /** 6GHz band (Wi-Fi 6E, also extends to 7GHz). */ + /** 6 GHz band (Wi-Fi 6E, also extends to 7GHz). */ WIFI_FREQ_BAND_6_GHZ, + /** Number of frequency bands available. */ __WIFI_FREQ_BAND_AFTER_LAST, + /** Highest frequency band available. */ WIFI_FREQ_BAND_MAX = __WIFI_FREQ_BAND_AFTER_LAST - 1, + /** Invalid frequency band */ WIFI_FREQ_BAND_UNKNOWN }; diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 09d875f1394f..4ab94d730ad3 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -174,7 +174,11 @@ enum net_event_wifi_cmd { #define NET_EVENT_WIFI_DISCONNECT_COMPLETE \ (_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE) -/** Wi-Fi scan parameters */ +/** + * @brief Wi-Fi scan parameters structure. + * Used to specify parameters which can control how the Wi-Fi scan + * is performed. + */ struct wifi_scan_params { /** Scan type, see enum wifi_scan_type. * @@ -184,6 +188,10 @@ struct wifi_scan_params { * restrictions etc. */ enum wifi_scan_type scan_type; + /** Bitmap of bands to be scanned. + * Refer to ::wifi_frequency_bands for bit position of each band. + */ + uint8_t bands; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h new file mode 100644 index 000000000000..dcbb48c7b2ff --- /dev/null +++ b/include/zephyr/net/wifi_utils.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * + * @brief Utility functions to be used by the Wi-Fi subsystem. + */ + +#ifndef ZEPHYR_INCLUDE_NET_WIFI_UTILS_H_ +#define ZEPHYR_INCLUDE_NET_WIFI_UTILS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @addtogroup wifi_mgmt + * @{ + */ + +/** + * @name Wi-Fi utility functions. + * + * Utility functions for the Wi-Fi subsystem. + * @{ + */ + +#define WIFI_UTILS_MAX_BAND_STR_LEN 3 +#define WIFI_UTILS_MAX_CHAN_STR_LEN 4 + +/** + * @brief Convert a band specification string to a bitmap representing the bands. + * + * @details The function will parse a string which specifies Wi-Fi frequency band + * values as a comma separated string and convert it to a bitmap. The string can + * use the following characters to represent the bands: + * + * - 2: 2.4 GHz + * - 5: 5 GHz + * - 6: 6 GHz + * + * For the bitmap generated refer to ::wifi_frequency_bands + * for bit position of each band. + * + * E.g. a string "2,5,6" will be converted to a bitmap value of 0x7 + * + * @param scan_bands_str String which spe. + * @param band_map Pointer to the bitmap variable to be updated. + * + * @retval 0 on success. + * @retval -errno value in case of failure. + */ +int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map); + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif +#endif /* ZEPHYR_INCLUDE_NET_WIFI_UTILS_H_ */ diff --git a/subsys/net/l2/Kconfig b/subsys/net/l2/Kconfig index 84be2a4bd8ef..36a466c58eee 100644 --- a/subsys/net/l2/Kconfig +++ b/subsys/net/l2/Kconfig @@ -96,11 +96,17 @@ config NET_L2_CUSTOM_IEEE802154_MTU source "subsys/net/l2/canbus/Kconfig" +config NET_L2_WIFI_UTILS + bool + help + This provides utility functions for Wi-Fi subsystem. + config NET_L2_WIFI_MGMT bool "Wi-Fi Management support" select NET_MGMT select NET_MGMT_EVENT select NET_MGMT_EVENT_INFO + select NET_L2_WIFI_UTILS help Add support for Wi-Fi Management interface. @@ -116,6 +122,7 @@ endif # NET_L2_WIFI_MGMT config NET_L2_WIFI_SHELL bool "Wi-Fi shell module" select NET_L2_WIFI_MGMT + select NET_L2_WIFI_UTILS select SHELL_GETOPT select GETOPT_LONG help diff --git a/subsys/net/l2/wifi/CMakeLists.txt b/subsys/net/l2/wifi/CMakeLists.txt index 6935d4e2a45c..445eb56c0a7d 100644 --- a/subsys/net/l2/wifi/CMakeLists.txt +++ b/subsys/net/l2/wifi/CMakeLists.txt @@ -9,6 +9,7 @@ zephyr_library_compile_definitions_ifdef( zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_MGMT wifi_mgmt.c) zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_SHELL wifi_shell.c) zephyr_library_sources_ifdef(CONFIG_WIFI_NM wifi_nm.c) +zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_UTILS wifi_utils.c) # Linker section placement for wifi_nm_instance iterable structure zephyr_linker_sources_ifdef(CONFIG_WIFI_NM DATA_SECTIONS wifi_nm.ld) diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index ea55a499d18c..53ec5db3b818 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -47,6 +47,18 @@ config WIFI_MGMT_FORCED_PASSIVE_SCAN This doesn't guarantee that passive scan will be used, it depends on the underlying chip implementation to support and honour scan type. +config WIFI_MGMT_SCAN_BANDS + string "Frequency bands to scan" + default "" + help + Specifies the frequency bands to scan, as follows: + 2 - 2.4 GHz + 5 - 5 GHz + 6 - 6 GHz + "" - All bands allowed by the regulatory domain. + Multiple bands can be specified as comma separated band values. + Only regulatory domain permitted values are allowed. + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 59e40304d83f..bcd502df4a2f 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -8,6 +8,7 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include +#include #include #include @@ -110,7 +111,16 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, if (data && (len == sizeof(*params))) { #ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN params->scan_type = WIFI_SCAN_TYPE_PASSIVE; -#endif +#endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */ + + if (!params->bands) { + if (wifi_utils_parse_scan_bands(CONFIG_WIFI_MGMT_SCAN_BANDS, + ¶ms->bands)) { + NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_BANDS: %s", + CONFIG_WIFI_MGMT_SCAN_BANDS); + return -EINVAL; + } + } } return wifi_mgmt_api->scan(dev, params, scan_result_cb); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index ec90db926aea..0b7f97a792cd 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -14,13 +14,15 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF); #include #include #include +#include #include #include #include #include -#include #include +#include +#include #include #include "net_private.h" @@ -446,6 +448,7 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, } + static int wifi_scan_args_to_params(const struct shell *sh, size_t argc, char *argv[], @@ -454,10 +457,11 @@ static int wifi_scan_args_to_params(const struct shell *sh, struct getopt_state *state; int opt; static struct option long_options[] = {{"type", required_argument, 0, 't'}, - {0, 0, 0, 0}}; + {"bands", required_argument, 0, 'b'}, + {0, 0, 0, 0}}; int opt_index = 0; - while ((opt = getopt_long(argc, argv, "t:", long_options, &opt_index)) != -1) { + while ((opt = getopt_long(argc, argv, "t:b:", long_options, &opt_index)) != -1) { state = getopt_state_get(); switch (opt) { case 't': @@ -470,9 +474,15 @@ static int wifi_scan_args_to_params(const struct shell *sh, return -ENOEXEC; } break; + case 'b': + if (wifi_utils_parse_scan_bands(optarg, ¶ms->bands)) { + shell_fprintf(sh, SHELL_ERROR, "Invalid band value(s)\n"); + return -ENOEXEC; + } + break; case '?': shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", - long_options[opt_index].name); + argv[opt_index + 1]); return -ENOEXEC; } } @@ -1156,7 +1166,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, SHELL_CMD(scan, NULL, "Scan for Wi-Fi APs\n" "OPTIONS:\n" - "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.", + "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" + "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c new file mode 100644 index 000000000000..056d42889dcd --- /dev/null +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** @file + * @brief Utility functions to be used by the Wi-Fi subsytem. + */ +#include +LOG_MODULE_REGISTER(net_wifi_utils, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); + +#include +#include +#include + +#include +#include +#include + +/* Ensure 'strtok_r' is available even with -std=c99. */ +char *strtok_r(char *str, const char *delim, char **saveptr); + +static enum wifi_frequency_bands wifi_utils_map_band_str_to_idx(char *band_str) +{ + if (!strcmp(band_str, "2")) { + return WIFI_FREQ_BAND_2_4_GHZ; + } else if (!strcmp(band_str, "5")) { + return WIFI_FREQ_BAND_5_GHZ; + } else if (!strcmp(band_str, "6")) { + return WIFI_FREQ_BAND_6_GHZ; + } else { + NET_ERR("Unknown band value: %s", band_str); + return WIFI_FREQ_BAND_UNKNOWN; + } +} + + +int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) +{ + char *band_str = NULL; + char *ctx = NULL; + enum wifi_frequency_bands band = WIFI_FREQ_BAND_UNKNOWN; + + if (!scan_bands_str) { + return -EINVAL; + } + + band_str = strtok_r(scan_bands_str, ",", &ctx); + + while (band_str) { + band = wifi_utils_map_band_str_to_idx(band_str); + + if (band == WIFI_FREQ_BAND_UNKNOWN) { + NET_ERR("Invalid band value: %s", band_str); + return -EINVAL; + } + + *band_map |= (1 << band); + + band_str = strtok_r(NULL, ",", &ctx); + } + + return 0; +} From a232237675ee80f716e69e5de1b8bbf095249e5d Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Wed, 19 Jul 2023 20:11:08 +0530 Subject: [PATCH 497/528] [nrf fromlist] net: wifi: Add scan extension for active channel dwell times Add scan extension to control time spent on active scan channels. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- include/zephyr/net/wifi_mgmt.h | 3 +++ subsys/net/l2/wifi/Kconfig | 7 +++++++ subsys/net/l2/wifi/wifi_mgmt.c | 4 ++++ subsys/net/l2/wifi/wifi_shell.c | 17 +++++++++++++++-- 4 files changed, 29 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 4ab94d730ad3..41da27472983 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -192,6 +192,9 @@ struct wifi_scan_params { * Refer to ::wifi_frequency_bands for bit position of each band. */ uint8_t bands; + /** Active scan dwell time (in ms) on a channel. + */ + uint16_t dwell_time_active; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 53ec5db3b818..dbee3d7045ff 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -59,6 +59,13 @@ config WIFI_MGMT_SCAN_BANDS Multiple bands can be specified as comma separated band values. Only regulatory domain permitted values are allowed. +config WIFI_MGMT_SCAN_DWELL_TIME_ACTIVE + int "Active scan dwell time" + default 50 + range 5 1000 + help + Active scan dwell time (in ms) per channel. + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index bcd502df4a2f..7e0fb189da64 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -121,6 +121,10 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, return -EINVAL; } } + + if (!params->dwell_time_active) { + params->dwell_time_active = CONFIG_WIFI_MGMT_SCAN_DWELL_TIME_ACTIVE; + } } return wifi_mgmt_api->scan(dev, params, scan_result_cb); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 0b7f97a792cd..ca32c8603e25 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -458,10 +458,12 @@ static int wifi_scan_args_to_params(const struct shell *sh, int opt; static struct option long_options[] = {{"type", required_argument, 0, 't'}, {"bands", required_argument, 0, 'b'}, + {"dwell_time_active", required_argument, 0, 'a'}, {0, 0, 0, 0}}; int opt_index = 0; + int val; - while ((opt = getopt_long(argc, argv, "t:b:", long_options, &opt_index)) != -1) { + while ((opt = getopt_long(argc, argv, "t:b:a:", long_options, &opt_index)) != -1) { state = getopt_state_get(); switch (opt) { case 't': @@ -480,6 +482,16 @@ static int wifi_scan_args_to_params(const struct shell *sh, return -ENOEXEC; } break; + case 'a': + val = atoi(optarg); + + if ((val < 5) || (val > 1000)) { + shell_fprintf(sh, SHELL_ERROR, "Invalid dwell_time_active val\n"); + return -ENOEXEC; + } + + params->dwell_time_active = val; + break; case '?': shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", argv[opt_index + 1]); @@ -1167,7 +1179,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "Scan for Wi-Fi APs\n" "OPTIONS:\n" "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" - "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.", + "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" + "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), From 3d48380d7bfede06a87614d0f6c074151a8705dc Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Wed, 19 Jul 2023 20:45:13 +0530 Subject: [PATCH 498/528] [nrf fromlist] net: wifi: Add scan extension for passive channel dwell times Add scan extension to control scanning time spent on channels where passive scanning is used. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- include/zephyr/net/wifi_mgmt.h | 3 +++ subsys/net/l2/wifi/Kconfig | 7 +++++++ subsys/net/l2/wifi/wifi_mgmt.c | 4 ++++ subsys/net/l2/wifi/wifi_shell.c | 16 ++++++++++++++-- 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 41da27472983..ba2730cc9379 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -195,6 +195,9 @@ struct wifi_scan_params { /** Active scan dwell time (in ms) on a channel. */ uint16_t dwell_time_active; + /** Passive scan dwell time (in ms) on a channel. + */ + uint16_t dwell_time_passive; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index dbee3d7045ff..7fbde46d01f4 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -66,6 +66,13 @@ config WIFI_MGMT_SCAN_DWELL_TIME_ACTIVE help Active scan dwell time (in ms) per channel. +config WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE + int "Passive scan dwell time" + default 130 + range 10 1000 + help + Passive scan dwell time (in ms) per channel. + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 7e0fb189da64..cda55fadaafa 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -125,6 +125,10 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, if (!params->dwell_time_active) { params->dwell_time_active = CONFIG_WIFI_MGMT_SCAN_DWELL_TIME_ACTIVE; } + + if (!params->dwell_time_passive) { + params->dwell_time_passive = CONFIG_WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE; + } } return wifi_mgmt_api->scan(dev, params, scan_result_cb); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index ca32c8603e25..a6d17fdd5abd 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -459,11 +459,12 @@ static int wifi_scan_args_to_params(const struct shell *sh, static struct option long_options[] = {{"type", required_argument, 0, 't'}, {"bands", required_argument, 0, 'b'}, {"dwell_time_active", required_argument, 0, 'a'}, + {"dwell_time_passive", required_argument, 0, 'p'}, {0, 0, 0, 0}}; int opt_index = 0; int val; - while ((opt = getopt_long(argc, argv, "t:b:a:", long_options, &opt_index)) != -1) { + while ((opt = getopt_long(argc, argv, "t:b:a:p:", long_options, &opt_index)) != -1) { state = getopt_state_get(); switch (opt) { case 't': @@ -492,6 +493,16 @@ static int wifi_scan_args_to_params(const struct shell *sh, params->dwell_time_active = val; break; + case 'p': + val = atoi(optarg); + + if ((val < 10) || (val > 1000)) { + shell_fprintf(sh, SHELL_ERROR, "Invalid dwell_time_passive val\n"); + return -ENOEXEC; + } + + params->dwell_time_passive = val; + break; case '?': shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", argv[opt_index + 1]); @@ -1180,7 +1191,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "OPTIONS:\n" "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" - "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.", + "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" + "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), From 17a5e8b066e06c19bbe137987efe7832130bcca8 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Fri, 21 Jul 2023 19:03:20 +0530 Subject: [PATCH 499/528] [nrf fromlist] net: wifi: Add scan extension for filtering SSIDs Add scan extension to scan only for specific SSIDs. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- include/zephyr/net/wifi_mgmt.h | 9 ++++++ include/zephyr/net/wifi_utils.h | 16 ++++++++++ samples/subsys/mgmt/updatehub/src/main.c | 3 ++ subsys/net/ip/net_private.h | 2 ++ subsys/net/l2/wifi/Kconfig | 15 ++++++++++ subsys/net/l2/wifi/wifi_mgmt.c | 10 +++++++ subsys/net/l2/wifi/wifi_shell.c | 12 ++++++-- subsys/net/l2/wifi/wifi_utils.c | 38 ++++++++++++++++++++++++ 8 files changed, 103 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index ba2730cc9379..a31d9557f2da 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -35,6 +35,12 @@ extern "C" { NET_MGMT_LAYER_CODE(_NET_WIFI_CODE)) #define _NET_WIFI_EVENT (_NET_WIFI_BASE | NET_MGMT_EVENT_BIT) +#ifdef CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX +#define WIFI_MGMT_SCAN_SSID_FILT_MAX CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX +#else +#define WIFI_MGMT_SCAN_SSID_FILT_MAX 0 +#endif /* CONFIG_WIFI_MGMT_SCAN_SSID_FILT_MAX */ + /** Wi-Fi management commands */ enum net_request_wifi_cmd { /** Scan for Wi-Fi networks */ @@ -198,6 +204,9 @@ struct wifi_scan_params { /** Passive scan dwell time (in ms) on a channel. */ uint16_t dwell_time_passive; + /** Array of SSID strings to scan. + */ + char ssids[WIFI_MGMT_SCAN_SSID_FILT_MAX][WIFI_SSID_MAX_LEN + 1]; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index dcbb48c7b2ff..c4fe5944dfcc 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -55,6 +55,22 @@ extern "C" { */ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map); + +/** + * @brief Convert a string containing a list of SSIDs to an array of SSID strings. + * + * @details The function will parse a string which specifies Wi-Fi SSIDs. + * as a comma separated string and convert it to an array. + * + * @param scan_ssids_str List of SSIDs expressed as a comma separated list. + * @param ssids Pointer to an array where the parsed SSIDs are to be stored. + * + * @retval 0 on success. + * @retval -errno value in case of failure. + */ +int wifi_utils_parse_scan_ssids(char *scan_ssids_str, + char ssids[][WIFI_SSID_MAX_LEN + 1]); + /** * @} */ diff --git a/samples/subsys/mgmt/updatehub/src/main.c b/samples/subsys/mgmt/updatehub/src/main.c index 9e51c7e7b2dc..022fbd4b2ae8 100644 --- a/samples/subsys/mgmt/updatehub/src/main.c +++ b/samples/subsys/mgmt/updatehub/src/main.c @@ -9,7 +9,10 @@ #include #include #include + +#ifdef CONFIG_NET_L2_WIFI_MGMT #include +#endif /* CONFIG_NET_L2_WIFI_MGMT */ #if defined(CONFIG_UPDATEHUB_DTLS) #include diff --git a/subsys/net/ip/net_private.h b/subsys/net/ip/net_private.h index 351c87c61466..1fce0ab3aae5 100644 --- a/subsys/net/ip/net_private.h +++ b/subsys/net/ip/net_private.h @@ -19,8 +19,10 @@ #include +#ifdef CONFIG_NET_L2_WIFI_MGMT /* For struct wifi_scan_result */ #include +#endif /* CONFIG_NET_L2_WIFI_MGMT */ #define DEFAULT_NET_EVENT_INFO_SIZE 32 /* NOTE: Update this union with all *big* event info structs */ diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 7fbde46d01f4..0ad961c46f1d 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -73,6 +73,21 @@ config WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE help Passive scan dwell time (in ms) per channel. +config WIFI_MGMT_SCAN_SSID_FILT_MAX + int "Maximum number of SSIDs that can be specified for SSID filtering" + default 1 + help + Maximum number of SSIDs that can be specified for SSID filtering. + This can be set based on the underlying chipsets limitations. + +config WIFI_MGMT_SCAN_SSID_FILT + string "Scan for specific SSIDs" + default "" + help + String of comma separated SSID values to scan for. The number of SSID’s + that can be specified depends on WIFI_MGMT_SCAN_MAX_SSIDS. + Use "" to disable SSID filtering. + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index cda55fadaafa..459b960e7d43 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -13,6 +13,7 @@ LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include +#include #ifdef CONFIG_WIFI_NM #include #endif /* CONFIG_WIFI_NM */ @@ -129,6 +130,15 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, if (!params->dwell_time_passive) { params->dwell_time_passive = CONFIG_WIFI_MGMT_SCAN_DWELL_TIME_PASSIVE; } + + if (!strlen(params->ssids[0])) { + if (wifi_utils_parse_scan_ssids(CONFIG_WIFI_MGMT_SCAN_SSID_FILT, + params->ssids)) { + NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_SSID_FILT: %s", + CONFIG_WIFI_MGMT_SCAN_SSID_FILT); + return -EINVAL; + } + } } return wifi_mgmt_api->scan(dev, params, scan_result_cb); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index a6d17fdd5abd..abd8bbc29a1a 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -460,11 +460,12 @@ static int wifi_scan_args_to_params(const struct shell *sh, {"bands", required_argument, 0, 'b'}, {"dwell_time_active", required_argument, 0, 'a'}, {"dwell_time_passive", required_argument, 0, 'p'}, + {"ssids", required_argument, 0, 's'}, {0, 0, 0, 0}}; int opt_index = 0; int val; - while ((opt = getopt_long(argc, argv, "t:b:a:p:", long_options, &opt_index)) != -1) { + while ((opt = getopt_long(argc, argv, "t:b:a:p:s:", long_options, &opt_index)) != -1) { state = getopt_state_get(); switch (opt) { case 't': @@ -503,6 +504,12 @@ static int wifi_scan_args_to_params(const struct shell *sh, params->dwell_time_passive = val; break; + case 's': + if (wifi_utils_parse_scan_ssids(optarg, params->ssids)) { + shell_fprintf(sh, SHELL_ERROR, "Invalid SSID(s)\n"); + return -ENOEXEC; + } + break; case '?': shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", argv[opt_index + 1]); @@ -1192,7 +1199,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" - "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.", + "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" + "[-s, --ssids ] : SSID list to scan for.", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 056d42889dcd..9c50ea1c2bc1 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -17,6 +17,7 @@ LOG_MODULE_REGISTER(net_wifi_utils, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include +#include /* Ensure 'strtok_r' is available even with -std=c99. */ char *strtok_r(char *str, const char *delim, char **saveptr); @@ -63,3 +64,40 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map) return 0; } + +int wifi_utils_parse_scan_ssids(char *scan_ssids_str, + char ssids[][WIFI_SSID_MAX_LEN + 1]) +{ + char *ssid = NULL; + char *ctx = NULL; + uint8_t i = 0; + + if (!scan_ssids_str) { + return -EINVAL; + } + + ssid = strtok_r(scan_ssids_str, ",", &ctx); + + while (ssid) { + if (strlen(ssid) > WIFI_SSID_MAX_LEN) { + NET_ERR("SSID length (%zu) exceeds maximum value (%d) for SSID %s", + strlen(ssid), + WIFI_SSID_MAX_LEN, + ssid); + return -EINVAL; + } + + if (i >= WIFI_MGMT_SCAN_SSID_FILT_MAX) { + NET_WARN("Exceeded maximum allowed (%d) SSIDs. Ignoring SSIDs %s onwards", + WIFI_MGMT_SCAN_SSID_FILT_MAX, + ssid); + break; + } + + strcpy(&ssids[i++][0], ssid); + + ssid = strtok_r(NULL, ",", &ctx); + } + + return 0; +} From 3e9d1d1c3f022427ed2aeaa65fadb56232cc8a50 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Mon, 24 Jul 2023 17:48:01 +0530 Subject: [PATCH 500/528] [nrf fromlist] net: wifi: Add scan extension for limiting scan results Add scan extension to allow limiting the scan results to a user defined maximum number. This parameter is intended to return results with the best RSSI. It cannot be counted upon to limit the scan times since the Wi-Fi chips might have to scan all the channels to find APs with the best RSSI values across all channels. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- include/zephyr/net/wifi_mgmt.h | 8 ++++++++ subsys/net/l2/wifi/Kconfig | 7 +++++++ subsys/net/l2/wifi/wifi_mgmt.c | 5 +++++ subsys/net/l2/wifi/wifi_shell.c | 16 ++++++++++++++-- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index a31d9557f2da..377f2b30f300 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -207,6 +207,14 @@ struct wifi_scan_params { /** Array of SSID strings to scan. */ char ssids[WIFI_MGMT_SCAN_SSID_FILT_MAX][WIFI_SSID_MAX_LEN + 1]; + /** Specifies the maximum number of scan results to return. These results would be the + * BSSIDS with the best RSSI values, in all the scanned channels. This should only be + * used to limit the number of returned scan results, and cannot be counted upon to limit + * the scan time, since the underlying Wi-Fi chip might have to scan all the channels to + * find the max_bss_cnt number of APs with the best signal strengths. A value of 0 + * signifies that there is no restriction on the number of scan results to be returned. + */ + uint16_t max_bss_cnt; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 0ad961c46f1d..9d1477e2b057 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -88,6 +88,13 @@ config WIFI_MGMT_SCAN_SSID_FILT that can be specified depends on WIFI_MGMT_SCAN_MAX_SSIDS. Use "" to disable SSID filtering. +config WIFI_MGMT_SCAN_MAX_BSS_CNT + int "Maximum number of scan results to return." + default 0 + range 0 65535 + help + Maximum number of scan results to return. 0 represents unlimited number of BSSes. + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 459b960e7d43..2ce5b9c5f9df 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -139,6 +139,11 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, return -EINVAL; } } + + if (!params->max_bss_cnt) { + params->max_bss_cnt = CONFIG_WIFI_MGMT_SCAN_MAX_BSS_CNT; + } + } return wifi_mgmt_api->scan(dev, params, scan_result_cb); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index abd8bbc29a1a..e38f45998d13 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -461,11 +461,12 @@ static int wifi_scan_args_to_params(const struct shell *sh, {"dwell_time_active", required_argument, 0, 'a'}, {"dwell_time_passive", required_argument, 0, 'p'}, {"ssids", required_argument, 0, 's'}, + {"max_bss", required_argument, 0, 'm'}, {0, 0, 0, 0}}; int opt_index = 0; int val; - while ((opt = getopt_long(argc, argv, "t:b:a:p:s:", long_options, &opt_index)) != -1) { + while ((opt = getopt_long(argc, argv, "t:b:a:p:s:m:", long_options, &opt_index)) != -1) { state = getopt_state_get(); switch (opt) { case 't': @@ -510,6 +511,16 @@ static int wifi_scan_args_to_params(const struct shell *sh, return -ENOEXEC; } break; + case 'm': + val = atoi(optarg); + + if ((val < 0) || (val > 65535)) { + shell_fprintf(sh, SHELL_ERROR, "Invalid max_bss val\n"); + return -ENOEXEC; + } + + params->max_bss_cnt = val; + break; case '?': shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", argv[opt_index + 1]); @@ -1200,7 +1211,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" - "[-s, --ssids ] : SSID list to scan for.", + "[-s, --ssids ] : SSID list to scan for.\n" + "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), From 4141db23f2b7f4347db63ddf74f7a4880bea0e29 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Mon, 31 Jul 2023 17:46:45 +0530 Subject: [PATCH 501/528] [nrf fromlist] net: wifi: Add scan extension for specifying channels Add scan extension to allow limiting the scanning to specific channels. Only 20 MHz channel specifications are allowed presently. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- include/zephyr/net/wifi_mgmt.h | 15 ++ include/zephyr/net/wifi_utils.h | 33 +++- subsys/net/l2/wifi/Kconfig | 18 ++ subsys/net/l2/wifi/wifi_mgmt.c | 17 ++ subsys/net/l2/wifi/wifi_shell.c | 14 +- subsys/net/l2/wifi/wifi_utils.c | 311 +++++++++++++++++++++++++++++++- 6 files changed, 399 insertions(+), 9 deletions(-) diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index 377f2b30f300..456f93116e65 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -215,6 +215,21 @@ struct wifi_scan_params { * signifies that there is no restriction on the number of scan results to be returned. */ uint16_t max_bss_cnt; + /** Channel information array indexed on Wi-Fi frequency bands and channels within that + * band. + * E.g. to scan channel 6 and 11 on the 2.4 GHz band, channel 36 on the 5 GHz band: + * @code{.c} + * chan[WIFI_FREQ_BAND_2_4_GHZ][0] = 6; + * chan[WIFI_FREQ_BAND_2_4_GHZ][1] = 11; + * chan[WIFI_FREQ_BAND_5_GHZ][0] = 36; + * @endcode + * + * This list specifies the channels to be __considered for scan__. The underlying + * Wi-Fi chip can silently omit some channels due to various reasons such as channels + * not conforming to regulatory restrictions etc. The invoker of the API should + * ensure that the channels specified follow regulatory rules. + */ + uint16_t chan[WIFI_FREQ_BAND_MAX + 1][WIFI_CHANNEL_MAX]; }; /** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback diff --git a/include/zephyr/net/wifi_utils.h b/include/zephyr/net/wifi_utils.h index c4fe5944dfcc..86b39ff46601 100644 --- a/include/zephyr/net/wifi_utils.h +++ b/include/zephyr/net/wifi_utils.h @@ -59,7 +59,7 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map); /** * @brief Convert a string containing a list of SSIDs to an array of SSID strings. * - * @details The function will parse a string which specifies Wi-Fi SSIDs. + * @details The function will parse a string which specifies Wi-Fi SSIDs * as a comma separated string and convert it to an array. * * @param scan_ssids_str List of SSIDs expressed as a comma separated list. @@ -71,6 +71,37 @@ int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map); int wifi_utils_parse_scan_ssids(char *scan_ssids_str, char ssids[][WIFI_SSID_MAX_LEN + 1]); + +/** + * @brief Convert a string containing a specification of scan channels to an array. + * + * @details The function will parse a string which specifies channels to be scanned + * as a string and convert it to an array. + * + * The channel string has to be formatted using the colon (:), comma(,), hyphen (-) and + * underscore (_) delimiters as follows: + * - A colon identifies the value preceding it as a band. A band value + * (2: 2.4 GHz, 5: 5 GHz 6: 6 GHz) has to precede the channels in that band (e.g. 2: etc) + * - Hyphens (-) are used to identify channel ranges (e.g. 2-7, 32-48 etc) + * - Commas are used to separate channel values within a band. Channels can be specified + * as individual values (2,6,48 etc) or channel ranges using hyphens (1-14, 32-48 etc) + * - Underscores (_) are used to specify multiple band-channel sets (e.g. 2:1,2_5:36,40 etc) + * - No spaces should be used anywhere, i.e. before/after commas, + * before/after hyphens etc. + * + * An example channel specification specifying channels in the 2.4 GHz and 5 GHz bands is + * as below: + * 2:1,5,7,9-11_5:36-48,100,163-167 + * + * @param scan_chan_str List of channels expressed in the format described above. + * @param chan Pointer to an array where the parsed channels are to be stored. + * + * @retval 0 on success. + * @retval -errno value in case of failure. + */ +int wifi_utils_parse_scan_chan(char *scan_chan_str, + uint16_t chan[][WIFI_CHANNEL_MAX]); + /** * @} */ diff --git a/subsys/net/l2/wifi/Kconfig b/subsys/net/l2/wifi/Kconfig index 9d1477e2b057..e034a745b5e3 100644 --- a/subsys/net/l2/wifi/Kconfig +++ b/subsys/net/l2/wifi/Kconfig @@ -95,6 +95,24 @@ config WIFI_MGMT_SCAN_MAX_BSS_CNT help Maximum number of scan results to return. 0 represents unlimited number of BSSes. +config WIFI_MGMT_SCAN_CHAN + string "Scan on specific channels" + default "" + help + Formatted string which specifies channels to be scanned. The channel string has to be formatted + using the colon (:), comma(,), hyphen (-) and space ( ) delimiters as follows: + - A colon identifies the value preceding it as a band. A band value + (2: 2.4 GHz, 5: 5 GHz 6: 6 GHz) has to precede the channels in that band (e.g. 2: etc) + - Hyphens are used to identify channel ranges (e.g. 2-7, 32-48 etc) + - Commas are used to separate channel values within a band. Channels can be specified + as individual values (2,6,48 etc) or channel ranges using hyphens (1-14, 32-48 etc) + - Spaces are used to specify multiple band-channel sets (e.g. 2:1,2 5:36,40 etc) + - No spaces should be used anywhere else, i.e. before/after commas, + before/after hyphens. + An example channel specification specifying channels in the 2.4 GHz and 5 GHz bands is + as below: + 2:1,5,7,9-11_5:36-48,100,163-167 + config WIFI_NM bool "Wi-Fi Network manager support" help diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index 2ce5b9c5f9df..22d54b926ab6 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -104,6 +104,8 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); struct wifi_scan_params *params = data; const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + bool chan_specified = false; + uint8_t i = 0; if (wifi_mgmt_api == NULL || wifi_mgmt_api->scan == NULL) { return -ENOTSUP; @@ -144,6 +146,21 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface, params->max_bss_cnt = CONFIG_WIFI_MGMT_SCAN_MAX_BSS_CNT; } + for (i = 0; i <= WIFI_FREQ_BAND_MAX; i++) { + if (params->chan[i][0]) { + chan_specified = true; + break; + } + } + + if ((!chan_specified) && strlen(CONFIG_WIFI_MGMT_SCAN_CHAN)) { + if (wifi_utils_parse_scan_chan(CONFIG_WIFI_MGMT_SCAN_CHAN, + params->chan)) { + NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_CHAN: %s", + CONFIG_WIFI_MGMT_SCAN_CHAN); + return -EINVAL; + } + } } return wifi_mgmt_api->scan(dev, params, scan_result_cb); diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index e38f45998d13..571d76761ad0 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -462,11 +462,12 @@ static int wifi_scan_args_to_params(const struct shell *sh, {"dwell_time_passive", required_argument, 0, 'p'}, {"ssids", required_argument, 0, 's'}, {"max_bss", required_argument, 0, 'm'}, + {"chans", required_argument, 0, 'c'}, {0, 0, 0, 0}}; int opt_index = 0; int val; - while ((opt = getopt_long(argc, argv, "t:b:a:p:s:m:", long_options, &opt_index)) != -1) { + while ((opt = getopt_long(argc, argv, "t:b:a:p:s:m:c:", long_options, &opt_index)) != -1) { state = getopt_state_get(); switch (opt) { case 't': @@ -521,6 +522,14 @@ static int wifi_scan_args_to_params(const struct shell *sh, params->max_bss_cnt = val; break; + case 'c': + if (wifi_utils_parse_scan_chan(optarg, params->chan)) { + shell_fprintf(sh, + SHELL_ERROR, + "Invalid band or channel value(s)\n"); + return -ENOEXEC; + } + break; case '?': shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", argv[opt_index + 1]); @@ -1212,7 +1221,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" "[-s, --ssids ] : SSID list to scan for.\n" - "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.", + "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" + "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), diff --git a/subsys/net/l2/wifi/wifi_utils.c b/subsys/net/l2/wifi/wifi_utils.c index 9c50ea1c2bc1..00585480f349 100644 --- a/subsys/net/l2/wifi/wifi_utils.c +++ b/subsys/net/l2/wifi/wifi_utils.c @@ -13,27 +13,202 @@ LOG_MODULE_REGISTER(net_wifi_utils, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL); #include #include #include +#include #include #include #include #include +#include /* Ensure 'strtok_r' is available even with -std=c99. */ char *strtok_r(char *str, const char *delim, char **saveptr); +static const uint16_t valid_5g_chans_20mhz[] = {32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 96, 100, + 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 159, 161, + 163, 165, 167, 169, 171, 173, 175, 177}; + static enum wifi_frequency_bands wifi_utils_map_band_str_to_idx(char *band_str) { + enum wifi_frequency_bands band = WIFI_FREQ_BAND_UNKNOWN; + if (!strcmp(band_str, "2")) { - return WIFI_FREQ_BAND_2_4_GHZ; + band = WIFI_FREQ_BAND_2_4_GHZ; } else if (!strcmp(band_str, "5")) { - return WIFI_FREQ_BAND_5_GHZ; + band = WIFI_FREQ_BAND_5_GHZ; } else if (!strcmp(band_str, "6")) { - return WIFI_FREQ_BAND_6_GHZ; - } else { - NET_ERR("Unknown band value: %s", band_str); - return WIFI_FREQ_BAND_UNKNOWN; + band = WIFI_FREQ_BAND_6_GHZ; + } + + return band; +} + + +static bool wifi_utils_validate_chan_2g(uint16_t chan) +{ + if ((chan >= 1) && (chan <= 14)) { + return true; + } + + return false; +} + + +static bool wifi_utils_validate_chan_5g(uint16_t chan) +{ + uint16_t i; + + for (i = 0; i < ARRAY_SIZE(valid_5g_chans_20mhz); i++) { + if (chan == valid_5g_chans_20mhz[i]) { + return true; + } + } + + return false; +} + + +static bool wifi_utils_validate_chan_6g(uint16_t chan) +{ + if (((chan >= 1) && (chan <= 233) && (!((chan - 1)%4))) || + (chan == 2)) { + return true; + } + + return false; +} + + +static bool wifi_utils_validate_chan(uint8_t band, + uint16_t chan) +{ + bool result = false; + + switch (band) { + case WIFI_FREQ_BAND_2_4_GHZ: + result = wifi_utils_validate_chan_2g(chan); + break; + case WIFI_FREQ_BAND_5_GHZ: + result = wifi_utils_validate_chan_5g(chan); + break; + case WIFI_FREQ_BAND_6_GHZ: + result = wifi_utils_validate_chan_6g(chan); + break; + default: + NET_ERR("Unknown band: %d", band); + break; + } + + return result; +} + + +static int wifi_utils_get_all_chans_in_range(uint16_t chan_start, + uint16_t chan_end, + uint16_t chan[][WIFI_CHANNEL_MAX], + uint8_t band_idx, + uint8_t *chan_idx) +{ + uint16_t i; + bool start = false; + bool end = false; + uint8_t idx; + + if (!wifi_utils_validate_chan(band_idx, chan_start)) { + NET_ERR("Invalid channel value %d in band %d", chan_start, band_idx); + return -EINVAL; + } + + if (!wifi_utils_validate_chan(band_idx, chan_end)) { + NET_ERR("Invalid channel value %d in band %d", chan_end, band_idx); + return -EINVAL; + } + + if (chan_end < chan_start) { + NET_ERR("Channel range end (%d) cannot be less than start (%d)", + chan_end, + chan_start); + return -EINVAL; + } + + switch (band_idx) { + case WIFI_FREQ_BAND_2_4_GHZ: + idx = *chan_idx; + + for (i = chan_start; i <= chan_end; i++) { + chan[band_idx][idx++] = i; + } + + *chan_idx = idx; + + break; + case WIFI_FREQ_BAND_5_GHZ: + idx = *chan_idx; + + for (i = 0; i < ARRAY_SIZE(valid_5g_chans_20mhz); i++) { + if (valid_5g_chans_20mhz[i] == chan_start) { + start = true; + } + + if (valid_5g_chans_20mhz[i] == chan_end) { + end = true; + } + + if (start) { + chan[band_idx][idx++] = valid_5g_chans_20mhz[i]; + } + + if (end) { + *chan_idx = idx; + break; + } + } + + break; + case WIFI_FREQ_BAND_6_GHZ: + idx = *chan_idx; + + i = chan_start; + + while (i <= chan_end) { + chan[band_idx][idx++] = i; + + if (i == 1) { + i++; + } else if (i == 2) { + i += 3; + } else { + i += 4; + } + } + + *chan_idx = idx; + default: + NET_ERR("Unknown band value: %d", band_idx); + return -EINVAL; } + + return 0; +} + + +static int wifi_utils_validate_chan_str(char *chan_str) +{ + uint8_t i; + + if ((!chan_str) || (!strlen(chan_str))) { + NET_ERR("Null or empty channel string\n"); + return -EINVAL; + } + + for (i = 0; i < strlen(chan_str); i++) { + if (!isdigit((int)chan_str[i])) { + NET_ERR("Invalid character in channel string %c\n", chan_str[i]); + return -EINVAL; + } + } + + return 0; } @@ -101,3 +276,127 @@ int wifi_utils_parse_scan_ssids(char *scan_ssids_str, return 0; } + + +int wifi_utils_parse_scan_chan(char *scan_chan_str, + uint16_t chan[][WIFI_CHANNEL_MAX]) +{ + char band_str[WIFI_UTILS_MAX_BAND_STR_LEN] = {0}; + char chan_str[WIFI_UTILS_MAX_CHAN_STR_LEN] = {0}; + enum wifi_frequency_bands band = WIFI_FREQ_BAND_UNKNOWN; + uint16_t band_str_start_idx = 0; + uint16_t chan_str_start_idx = 0; + uint8_t chan_idx = 0; + uint16_t chan_start = 0; + uint16_t chan_val = 0; + uint16_t i = 0; + bool valid_band = false; + bool valid_chan = false; + + while (scan_chan_str[i] != '\0') { + if (scan_chan_str[i] != ':') { + i++; + continue; + } + + if (((i - band_str_start_idx) <= 0) || + ((i - band_str_start_idx) > WIFI_UTILS_MAX_BAND_STR_LEN)) { + NET_ERR("Invalid band value %s", + &scan_chan_str[band_str_start_idx]); + return -EINVAL; + } + + strncpy(band_str, + &scan_chan_str[band_str_start_idx], + (i - band_str_start_idx)); + + band = wifi_utils_map_band_str_to_idx(band_str); + + if (band == WIFI_FREQ_BAND_UNKNOWN) { + NET_ERR("Unsupported band value: %s", band_str); + return -EINVAL; + } + + i++; + chan_idx = 0; + chan_str_start_idx = i; + valid_band = true; + + while (1) { + if ((scan_chan_str[i] != ',') && + (scan_chan_str[i] != '_') && + (scan_chan_str[i] != '-') && + (scan_chan_str[i] != '\0')) { + i++; + continue; + } + + if ((i - chan_str_start_idx) > + WIFI_UTILS_MAX_CHAN_STR_LEN) { + NET_ERR("Invalid chan value %s", + &scan_chan_str[chan_str_start_idx]); + return -EINVAL; + } + + strncpy(chan_str, + &scan_chan_str[chan_str_start_idx], + (i - chan_str_start_idx)); + + if (wifi_utils_validate_chan_str(chan_str)) { + NET_ERR("Channel string validation failed"); + return -EINVAL; + } + + chan_val = atoi(chan_str); + + memset(chan_str, 0, sizeof(chan_str)); + + if (chan_start) { + if (wifi_utils_get_all_chans_in_range(chan_start, + chan_val, + chan, + band, + &chan_idx)) { + NET_ERR("Channel range invalid"); + return -EINVAL; + } + + chan_start = 0; + } else { + if (!wifi_utils_validate_chan(band, + chan_val)) { + NET_ERR("Invalid channel %d", chan_val); + return -EINVAL; + } + + chan[band][chan_idx++] = chan_val; + } + + valid_chan = true; + + if (scan_chan_str[i] == '_') { + band_str_start_idx = ++i; + break; + } else if (scan_chan_str[i] == ',') { + chan_str_start_idx = ++i; + } else if (scan_chan_str[i] == '-') { + chan_start = chan_val; + chan_str_start_idx = ++i; + } else if (scan_chan_str[i] == '\0') { + break; + } + } + } + + if (!valid_band) { + NET_ERR("No valid band found"); + return -EINVAL; + } + + if (!valid_chan) { + NET_ERR("No valid channel found"); + return -EINVAL; + } + + return 0; +} From ed83e6c46305f97acc2de018f8b4958ea5ef9db0 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Tue, 1 Aug 2023 17:52:42 +0530 Subject: [PATCH 502/528] [nrf fromlist] net: wifi: Add scan command option to print help Add a scan command option to print the help text for the scan command. This is to facilitate ease of using the command (since now there are many different options added to the scan command). Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- subsys/net/l2/wifi/wifi_shell.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index 571d76761ad0..b709fb56e2bf 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -452,7 +452,8 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc, static int wifi_scan_args_to_params(const struct shell *sh, size_t argc, char *argv[], - struct wifi_scan_params *params) + struct wifi_scan_params *params, + bool *do_scan) { struct getopt_state *state; int opt; @@ -463,11 +464,14 @@ static int wifi_scan_args_to_params(const struct shell *sh, {"ssids", required_argument, 0, 's'}, {"max_bss", required_argument, 0, 'm'}, {"chans", required_argument, 0, 'c'}, + {"help", no_argument, 0, 'h'}, {0, 0, 0, 0}}; int opt_index = 0; int val; - while ((opt = getopt_long(argc, argv, "t:b:a:p:s:m:c:", long_options, &opt_index)) != -1) { + *do_scan = true; + + while ((opt = getopt_long(argc, argv, "t:b:a:p:s:m:c:h", long_options, &opt_index)) != -1) { state = getopt_state_get(); switch (opt) { case 't': @@ -530,12 +534,18 @@ static int wifi_scan_args_to_params(const struct shell *sh, return -ENOEXEC; } break; + case 'h': + shell_help(sh); + *do_scan = false; + break; case '?': + default: shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n", argv[opt_index + 1]); return -ENOEXEC; } } + return 0; } @@ -543,17 +553,20 @@ static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); struct wifi_scan_params params = { 0 }; + bool do_scan = false; context.sh = sh; - if (wifi_scan_args_to_params(sh, argc, argv, ¶ms)) { + if (wifi_scan_args_to_params(sh, argc, argv, ¶ms, &do_scan)) { shell_help(sh); return -ENOEXEC; } - if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, ¶ms, sizeof(params))) { - shell_fprintf(sh, SHELL_WARNING, "Scan request failed\n"); - return -ENOEXEC; + if (do_scan) { + if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, ¶ms, sizeof(params))) { + shell_fprintf(sh, SHELL_WARNING, "Scan request failed\n"); + return -ENOEXEC; + } } shell_fprintf(sh, SHELL_NORMAL, "Scan requested\n"); @@ -1215,14 +1228,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands, 0), SHELL_CMD(scan, NULL, "Scan for Wi-Fi APs\n" - "OPTIONS:\n" + "OPTIONAL PARAMETERS:\n" "[-t, --type ] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n" "[-b, --bands ] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.\n" "[-a, --dwell_time_active ] : Active scan dwell time (in ms) on a channel. Range 5 ms to 1000 ms.\n" "[-p, --dwell_time_passive ] : Passive scan dwell time (in ms) on a channel. Range 10 ms to 1000 ms.\n" "[-s, --ssids ] : SSID list to scan for.\n" "[-m, --max_bss ] : Maximum BSSes to scan for. Range 1 - 65535.\n" - "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44", + "[-c, --chans ] : Channels to be scanned. The channels must be specified in the form band1:chan1,chan2_band2:chan3,..etc. band1, band2 must be valid band values and chan1, chan2, chan3 must be specified as a list of comma separated values where each value is either a single channel or a channel range specified as chan_start-chan_end. Each band channel set has to be separated by a _. For example, a valid channel specification can be 2:1,6-11,14_5:36,149-165,44\n" + "[-h, --help] : Print out the help for the scan command.", cmd_wifi_scan), SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats), SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status), From 1e2596a3584ad0c61bd2257aaec785c84949d2c9 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Thu, 3 Aug 2023 14:13:53 +0530 Subject: [PATCH 503/528] [nrf fromlist] net: wifi: Validate scan parameters Add defensive check to validate scan command parameters. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- subsys/net/l2/wifi/wifi_shell.c | 40 ++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/subsys/net/l2/wifi/wifi_shell.c b/subsys/net/l2/wifi/wifi_shell.c index b709fb56e2bf..52d611d8fd65 100644 --- a/subsys/net/l2/wifi/wifi_shell.c +++ b/subsys/net/l2/wifi/wifi_shell.c @@ -468,6 +468,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, {0, 0, 0, 0}}; int opt_index = 0; int val; + int opt_num = 0; *do_scan = true; @@ -483,12 +484,16 @@ static int wifi_scan_args_to_params(const struct shell *sh, shell_fprintf(sh, SHELL_ERROR, "Invalid scan type %s\n", optarg); return -ENOEXEC; } + + opt_num++; break; case 'b': if (wifi_utils_parse_scan_bands(optarg, ¶ms->bands)) { shell_fprintf(sh, SHELL_ERROR, "Invalid band value(s)\n"); return -ENOEXEC; } + + opt_num++; break; case 'a': val = atoi(optarg); @@ -499,6 +504,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, } params->dwell_time_active = val; + opt_num++; break; case 'p': val = atoi(optarg); @@ -509,12 +515,15 @@ static int wifi_scan_args_to_params(const struct shell *sh, } params->dwell_time_passive = val; + opt_num++; break; case 's': if (wifi_utils_parse_scan_ssids(optarg, params->ssids)) { shell_fprintf(sh, SHELL_ERROR, "Invalid SSID(s)\n"); return -ENOEXEC; } + + opt_num++; break; case 'm': val = atoi(optarg); @@ -525,6 +534,7 @@ static int wifi_scan_args_to_params(const struct shell *sh, } params->max_bss_cnt = val; + opt_num++; break; case 'c': if (wifi_utils_parse_scan_chan(optarg, params->chan)) { @@ -533,10 +543,13 @@ static int wifi_scan_args_to_params(const struct shell *sh, "Invalid band or channel value(s)\n"); return -ENOEXEC; } + + opt_num++; break; case 'h': shell_help(sh); *do_scan = false; + opt_num++; break; case '?': default: @@ -546,20 +559,28 @@ static int wifi_scan_args_to_params(const struct shell *sh, } } - return 0; + return opt_num; } static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) { struct net_if *iface = net_if_get_first_wifi(); struct wifi_scan_params params = { 0 }; - bool do_scan = false; + bool do_scan = true; + int opt_num; context.sh = sh; - if (wifi_scan_args_to_params(sh, argc, argv, ¶ms, &do_scan)) { - shell_help(sh); - return -ENOEXEC; + if (argc > 1) { + opt_num = wifi_scan_args_to_params(sh, argc, argv, ¶ms, &do_scan); + + if (opt_num < 0) { + shell_help(sh); + return -ENOEXEC; + } else if (!opt_num) { + shell_fprintf(sh, SHELL_WARNING, "No valid option(s) found\n"); + do_scan = false; + } } if (do_scan) { @@ -567,11 +588,14 @@ static int cmd_wifi_scan(const struct shell *sh, size_t argc, char *argv[]) shell_fprintf(sh, SHELL_WARNING, "Scan request failed\n"); return -ENOEXEC; } - } - shell_fprintf(sh, SHELL_NORMAL, "Scan requested\n"); + shell_fprintf(sh, SHELL_NORMAL, "Scan requested\n"); - return 0; + return 0; + } + + shell_fprintf(sh, SHELL_WARNING, "Scan not initiated\n"); + return -ENOEXEC; } static int cmd_wifi_status(const struct shell *sh, size_t argc, char *argv[]) From 894454c776f536135baacb1bb606f1150d4a5209 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Wed, 9 Aug 2023 20:07:26 +0530 Subject: [PATCH 504/528] [nrf fromlist] net: wifi: Enhance help text for NET_L2_WIFI_MGMT Changed Add to Enable in help text to convey the intended use of the Kconfig NET_L2_WIFI_MGMT. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- subsys/net/l2/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/net/l2/Kconfig b/subsys/net/l2/Kconfig index 36a466c58eee..9c274a5737a8 100644 --- a/subsys/net/l2/Kconfig +++ b/subsys/net/l2/Kconfig @@ -108,7 +108,7 @@ config NET_L2_WIFI_MGMT select NET_MGMT_EVENT_INFO select NET_L2_WIFI_UTILS help - Add support for Wi-Fi Management interface. + Enable support for Wi-Fi Management interface. if NET_L2_WIFI_MGMT module = NET_L2_WIFI_MGMT From 48f1f1f6b223742dc1c7bdca3974bb53a090544a Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Wed, 9 Aug 2023 20:07:28 +0530 Subject: [PATCH 505/528] [nrf fromlist] scripts: coccinelle: Remove strtok_r symbol from checklist strtok_r is part of GNU99, but default Zephyr is built with C99, so, the GNU headers are not pulled in, even if we add "--std=gnu99" it won't override the C99 standard. As a workaround for build we redefine the prototype, but this causes a coding guideline warning, so, for now disable this warning for strtok_r. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- scripts/coccinelle/symbols.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/coccinelle/symbols.txt b/scripts/coccinelle/symbols.txt index 3b32b3800cd8..02bd93e0dcc2 100644 --- a/scripts/coccinelle/symbols.txt +++ b/scripts/coccinelle/symbols.txt @@ -207,7 +207,6 @@ strtod64 strtod128 strtof strtok -strtok_r strtol strtold strtoul From 582837b2010d033344cb524f0e95f8de86c62d03 Mon Sep 17 00:00:00 2001 From: Sachin D Kulkarni Date: Wed, 16 Aug 2023 19:55:59 +0530 Subject: [PATCH 506/528] [nrf fromlist] net: wifi: Enhance wifi_mgmt documentation Enhance wifi_mgmt group documentation by : - Hiding some internal entities i.e. the human-readable strings defined in the various static const char * const arrays, by marking them as @cond INTERNAL_HIDDEN blocks. - Moving the Wi-Fi management API page under the networking group and adding a human readable name. Upstream PR: https://github.com/zephyrproject-rtos/zephyr/pull/60686 Signed-off-by: Sachin D Kulkarni --- include/zephyr/net/wifi.h | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/include/zephyr/net/wifi.h b/include/zephyr/net/wifi.h index 65dcd9e5118f..d70bd06846c5 100644 --- a/include/zephyr/net/wifi.h +++ b/include/zephyr/net/wifi.h @@ -10,7 +10,9 @@ */ /** - * @addtogroup wifi_mgmt + * @defgroup wifi_mgmt Wi-Fi Management + * Wi-Fi Management API. + * @ingroup networking * @{ */ @@ -325,10 +327,12 @@ enum wifi_ps { WIFI_PS_ENABLED, }; +/** @cond INTERNAL_HIDDEN */ static const char * const wifi_ps2str[] = { [WIFI_PS_DISABLED] = "Power save disabled", [WIFI_PS_ENABLED] = "Power save enabled", }; +/** @endcond */ /** Wi-Fi power save modes. */ enum wifi_ps_mode { @@ -341,10 +345,12 @@ enum wifi_ps_mode { WIFI_PS_MODE_WMM, }; +/** @cond INTERNAL_HIDDEN */ static const char * const wifi_ps_mode2str[] = { [WIFI_PS_MODE_LEGACY] = "Legacy power save", [WIFI_PS_MODE_WMM] = "WMM power save", }; +/** @endcond */ /** Wi-Fi Target Wake Time (TWT) operations. */ enum wifi_twt_operation { @@ -354,10 +360,12 @@ enum wifi_twt_operation { WIFI_TWT_TEARDOWN, }; +/** @cond INTERNAL_HIDDEN */ static const char * const wifi_twt_operation2str[] = { [WIFI_TWT_SETUP] = "TWT setup", [WIFI_TWT_TEARDOWN] = "TWT teardown", }; +/** @endcond */ /** Wi-Fi Target Wake Time (TWT) negotiation types. */ enum wifi_twt_negotiation_type { @@ -369,11 +377,13 @@ enum wifi_twt_negotiation_type { WIFI_TWT_WAKE_TBTT }; +/** @cond INTERNAL_HIDDEN */ static const char * const wifi_twt_negotiation_type2str[] = { [WIFI_TWT_INDIVIDUAL] = "TWT individual negotiation", [WIFI_TWT_BROADCAST] = "TWT broadcast negotiation", [WIFI_TWT_WAKE_TBTT] = "TWT wake TBTT negotiation", }; +/** @endcond */ /** Wi-Fi Target Wake Time (TWT) setup commands. */ enum wifi_twt_setup_cmd { @@ -395,6 +405,7 @@ enum wifi_twt_setup_cmd { WIFI_TWT_SETUP_CMD_REJECT, }; +/** @cond INTERNAL_HIDDEN */ static const char * const wifi_twt_setup_cmd2str[] = { [WIFI_TWT_SETUP_CMD_REQUEST] = "TWT request", [WIFI_TWT_SETUP_CMD_SUGGEST] = "TWT suggest", @@ -405,6 +416,7 @@ static const char * const wifi_twt_setup_cmd2str[] = { [WIFI_TWT_SETUP_CMD_DICTATE] = "TWT dictate", [WIFI_TWT_SETUP_CMD_REJECT] = "TWT reject", }; +/** @endcond */ /** Wi-Fi Target Wake Time (TWT) negotiation status. */ enum wifi_twt_setup_resp_status { @@ -440,6 +452,7 @@ enum wifi_twt_fail_reason { WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS, }; +/** @cond INTERNAL_HIDDEN */ static const char * const twt_err_code_tbl[] = { [WIFI_TWT_FAIL_UNSPECIFIED] = "Unspecified", [WIFI_TWT_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", @@ -460,6 +473,7 @@ static const char * const twt_err_code_tbl[] = { [WIFI_TWT_FAIL_FLOW_ALREADY_EXISTS] = "Flow already exists", }; +/** @endcond */ /** Helper function to get user-friendly TWT error code name. */ static inline const char *get_twt_err_code_str(int16_t err_no) @@ -493,10 +507,12 @@ enum wifi_ps_wakeup_mode { WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL, }; +/** @cond INTERNAL_HIDDEN */ static const char * const wifi_ps_wakeup_mode2str[] = { [WIFI_PS_WAKEUP_MODE_DTIM] = "PS wakeup mode DTIM", [WIFI_PS_WAKEUP_MODE_LISTEN_INTERVAL] = "PS wakeup mode listen interval", }; +/** @endcond */ /** Wi-Fi power save error codes. */ enum wifi_config_ps_param_fail_reason { @@ -516,6 +532,7 @@ enum wifi_config_ps_param_fail_reason { WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID, }; +/** @cond INTERNAL_HIDDEN */ static const char * const ps_param_config_err_code_tbl[] = { [WIFI_PS_PARAM_FAIL_UNSPECIFIED] = "Unspecified", [WIFI_PS_PARAM_FAIL_CMD_EXEC_FAIL] = "Command Execution failed", @@ -530,6 +547,7 @@ static const char * const ps_param_config_err_code_tbl[] = { [WIFI_PS_PARAM_LISTEN_INTERVAL_RANGE_INVALID] = "Parameter out of range", }; +/** @endcond */ /** Helper function to get user-friendly power save error code name. */ static inline const char *get_ps_config_err_code_str(int16_t err_no) From 6a0df6f20645130ef3bf90b8c2ec605510d9b125 Mon Sep 17 00:00:00 2001 From: Jorgen Kvalvaag Date: Thu, 24 Aug 2023 10:03:43 +0200 Subject: [PATCH 507/528] [nrf noup] ci: Update Thingy91 test-spec entry MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thingy91 CI tests dependencies added. Signed-off-by: Jørgen Kvalvaag --- .github/test-spec.yml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 53b811f9ae07..ce1d40b330e0 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -52,7 +52,37 @@ - "include/dfu/**/*" "CI-thingy91-test": - - "**/*" + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "arch/x86/core/**/*" + - "arch/x86/include/**/*" + - "drivers/console/**/*" + - "drivers/ethernet/**/*" + - "drivers/flash/**/*" + - "drivers/hwinfo/**/*" + - "drivers/interrupt_controller/**/*" + - "drivers/net/**/*" + - "drivers/serial/**/*" + - "drivers/timer/**/*" + - "include/**/*" + - "kernel/**/*" + - "lib/libc/common/source/stdlib/**/*" + - "lib/libc/newlib/**/*" + - "lib/libc/picolibc/**/*" + - "lib/os/**/*" + - "lib/posix/**/*" + - "misc/**/*" + - "modules/mbedtls/**/*" + - "soc/x86/ia32/**/*" + - "subsys/fs/fcb/**/*" + - "subsys/logging/**/*" + - "subsys/net/**/*" + - "subsys/random/**/*" + - "subsys/settings/include/**/*" + - "subsys/settings/src/**/*" + - "subsys/stats/**/*" + - "subsys/storage/flash_map/**/*" + - "subsys/storage/stream/**/*" + - "subsys/tracing/**/*" "CI-desktop-test": - "**/*" From 00c27fe11656f31fbed5873bb4bd2ce6f0cc477a Mon Sep 17 00:00:00 2001 From: Juha Heiskanen Date: Wed, 23 Aug 2023 15:09:21 +0300 Subject: [PATCH 508/528] [nrf fromtree] mcumgr: img_mgmt_client: Fix Image upload max len MCUmgr client upload max data payload length was missing Transport layer CRC + 16bit lenght. Full net buf packet was possible to send but receiver side it was blocked because there was not space for calculate CRC and length. Signed-off-by: Juha Heiskanen (cherry picked from commit ea84ef55dad978a026ee928c6b272098b657c9bf) --- .../mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c index 2bb9743160db..b0e38640e8c8 100644 --- a/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c +++ b/subsys/mgmt/mcumgr/grp/img_mgmt_client/src/img_mgmt_client.c @@ -345,9 +345,11 @@ int img_mgmt_client_upload(struct img_mgmt_client *client, const uint8_t *data, request_length = length; wrote_length = 0; - /* Calculate max data length based on net_buf size - (SMP header + CBOR message_len) */ + /* Calculate max data length based on + * net_buf size - (SMP header + CBOR message_len + 16-bit CRC + 16-bit length) + */ max_data_length = CONFIG_MCUMGR_TRANSPORT_NETBUF_SIZE - - (active_client->upload.upload_header_size + MGMT_HDR_SIZE); + (active_client->upload.upload_header_size + MGMT_HDR_SIZE + 2U + 2U); /* Trim length based on CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE */ if (max_data_length % CONFIG_MCUMGR_GRP_IMG_UPLOAD_DATA_ALIGNMENT_SIZE) { max_data_length -= From c0d21ea8df1bce0d1bc2774a8e7348f3fc90271f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magne=20V=C3=A6rnes?= Date: Wed, 23 Aug 2023 16:10:42 +0200 Subject: [PATCH 509/528] [nrf noup] ci: Only run crypto and tf-m tests when needed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extended the github CI filter for crypto and TF-M tests to reduce the CI load and possibly speed up PRs. Signed-off-by: Magne Værnes --- .github/test-spec.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index ce1d40b330e0..102642d42163 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -31,7 +31,13 @@ - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" "CI-tfm-test": - - "**/*" + - "boards/arm/nrf5340dk_nrf5340/**/*" + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "drivers/entropy/*" + - "dts/arm/nordic/nrf5340*" + - "dts/arm/nordic/nrf9160*" + - "modules/trusted-firmware-m/**/*" + - "samples/tfm_integration/**/*" "CI-ble-test": - "**/*" @@ -88,7 +94,16 @@ - "**/*" "CI-crypto-test": - - "**/*" + - "boards/arm/nrf52840dk_nrf52840/**/*" + - "boards/arm/nrf5340dk_nrf5340/**/*" + - "boards/arm/nrf9160dk_nrf9160/**/*" + - "drivers/entropy/*" + - "drivers/serial/**/*" + - "dts/arm/nordic/nrf52840*" + - "dts/arm/nordic/nrf5340*" + - "dts/arm/nordic/nrf9160*" + - "include/drivers/serial/**/*" + - "modules/mbedtls/**/*" "CI-fem-test": - "**/*" From 9769ef83d7027855f18a1f968cc6ec9b98ab5e22 Mon Sep 17 00:00:00 2001 From: Georgios Vasilakis Date: Mon, 17 Jul 2023 11:46:55 +0200 Subject: [PATCH 510/528] [nrf noup] modules: mbedtls: Rename PSA SRP fixup! [nrf noup] modules: mbedtls: Add symbols for PAKE Rename the SRP config: PSA_WANT_ALG_SRP -> PSA_WANT_ALG_SRP_6 since the Oberon PSA core uses this name. Noup since this symbol is not available upstream but only available in the Oberon PSA core. Signed-off-by: Georgios Vasilakis --- modules/mbedtls/Kconfig.psa | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index 9b256ead81a2..df046f5cbabb 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -453,8 +453,7 @@ config PSA_WANT_ALG_SPAKE2P prompt "PSA SPAKE2+ support" if !PSA_PROMPTLESS select EXPERIMENTAL -config PSA_WANT_ALG_SRP +config PSA_WANT_ALG_SRP_6 bool - prompt "PSA SRP support" if !PSA_PROMPTLESS - default n + prompt "PSA SRP-6 support" if !PSA_PROMPTLESS select EXPERIMENTAL From 55b533d626971b459f6598352888a2096e6bc9d9 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Wed, 23 Aug 2023 14:05:07 +0200 Subject: [PATCH 511/528] [nrf noup] modules: mbedtls: Add missing PSA configurations fixup! [nrf noup] modules: mbedtls: add PSA configurations Add missing PSA configurations for: CCM* (no tag) HKDF expand HKDF extract Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index df046f5cbabb..fdeaec7b1d4e 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -116,6 +116,7 @@ config PSA_HAS_AEAD_SUPPORT bool default y depends on PSA_WANT_ALG_CCM || \ + PSA_WANT_ALG_CCM_STAR_NO_TAG || \ PSA_WANT_ALG_GCM || \ PSA_WANT_ALG_CHACHA20_POLY1305 help @@ -125,6 +126,10 @@ config PSA_WANT_ALG_CCM bool prompt "PSA CCM support" if !PSA_PROMPTLESS +config PSA_WANT_ALG_CCM_STAR_NO_TAG + bool + prompt "PSA AES CCM star with no tag support" if !PSA_PROMPTLESS + config PSA_WANT_ALG_GCM bool prompt "PSA GCM support" if !PSA_PROMPTLESS @@ -272,6 +277,8 @@ config PSA_HAS_KEY_DERIVATION bool default y depends on PSA_WANT_ALG_HKDF || \ + PSA_WANT_ALG_HKDF_EXPAND || \ + PSA_WANT_ALG_HKDF_EXTRACT || \ PSA_WANT_ALG_PBKDF2_HMAC || \ PSA_WANT_ALG_PBKDF2_AES_CMAC_PRF_128 || \ PSA_WANT_ALG_TLS12_PRF || \ @@ -285,6 +292,14 @@ config PSA_WANT_ALG_HKDF prompt "PSA HKDF support" if !PSA_PROMPTLESS depends on PSA_WANT_ALG_HMAC +config PSA_WANT_ALG_HKDF_EXTRACT + bool + prompt "PSA HKDF extract support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_HKDF_EXPAND + bool + prompt "PSA HKDF expand support" if !PSA_PROMPTLESS + config PSA_WANT_ALG_PBKDF2_HMAC bool prompt "PSA PBKDF2 HMAC support" if !PSA_PROMPTLESS From 0b32fd2743f574aaa293122545caeadd3b01fd41 Mon Sep 17 00:00:00 2001 From: Joakim Andersson Date: Thu, 24 Aug 2023 13:01:25 +0200 Subject: [PATCH 512/528] [nrf noup] modules: mbedtls: Add symbols of EDDSA squash! [nrf noup] modules: mbedtls: Add symbols for PAKE Squash with new commit message: modules: mbedtls: Add PSA symbols for Oberon PSA extension Add PSA symbols for Oberon extension to the PSA specification. Noup commit until we can decide a better way to include PSA extension options, or these are accepted to be included in PSA specification with naming for the configurations that are compatible with Mbed TLS project. Signed-off-by: Joakim Andersson --- modules/mbedtls/Kconfig.psa | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/modules/mbedtls/Kconfig.psa b/modules/mbedtls/Kconfig.psa index fdeaec7b1d4e..a91bc76a6845 100644 --- a/modules/mbedtls/Kconfig.psa +++ b/modules/mbedtls/Kconfig.psa @@ -472,3 +472,15 @@ config PSA_WANT_ALG_SRP_6 bool prompt "PSA SRP-6 support" if !PSA_PROMPTLESS select EXPERIMENTAL + +config PSA_WANT_ALG_PURE_EDDSA + bool + prompt "PSA PURE_EDDSA support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_ED25519PH + bool + prompt "PSA ED25519PH support" if !PSA_PROMPTLESS + +config PSA_WANT_ALG_ED448PH + bool + prompt "PSA ED448PH support" if !PSA_PROMPTLESS From cd4e36f63fd444d1e850894ca743ee8e9654fc1a Mon Sep 17 00:00:00 2001 From: Tomasz Tyzenhauz Date: Fri, 25 Aug 2023 13:27:53 +0200 Subject: [PATCH 513/528] [nrf noup] ci: Add Sidewalk to test-spec Add Sidewalk to be trigger on changes in this repo. Correct entry path for hci_rpmsg samples for Matter and Homekit. Signed-off-by: Tomasz Tyzenhauz --- .github/test-spec.yml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/test-spec.yml b/.github/test-spec.yml index 102642d42163..7c4d93cd0381 100644 --- a/.github/test-spec.yml +++ b/.github/test-spec.yml @@ -119,7 +119,7 @@ - "subsys/settings/**/*" - "subsys/net/lib/openthread/**/*" - "subsys/mgmt/mcumgr/**/*" - - "samples/hci_rpmsg/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" - "samples/subsys/mgmt/mcumgr/smp_svr/**/*" - any: - "subsys/bluetooth/**/*" @@ -140,7 +140,7 @@ - "subsys/net/**/*" - "subsys/mgmt/mcumgr/**/*" - "drivers/net/**/*" - - "samples/hci_rpmsg/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" - any: - "subsys/bluetooth/**/*" - "!subsys/bluetooth/mesh/**/*" @@ -193,3 +193,16 @@ "CI-wifi": - "subsys/net/l2/wifi/**/*" - "subsys/net/l2/ethernet/**/*" + +"CI-sidewalk-test": + - "include/dfu/**/*" + - "include/mgmt/mcumgr/**/*" + - "soc/arm/nordic_nrf/**/*" + - "subsys/dfu/**/*" + - "subsys/settings/**/*" + - "subsys/mgmt/mcumgr/**/*" + - "samples/bluetooth/hci_rpmsg/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" + - "!subsys/bluetooth/audio/**/*" From 5410e25ea0981cba654faa713d5f2276918a4e79 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 18 Jul 2023 10:23:18 +0200 Subject: [PATCH 514/528] [nrf fromtree] pm: drop HAS_NO_PM Remove HAS_NO_PM option, in preparation for a new HAS_PM option (inverted logic). Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 26bf349ab12933d52384d41b647e552559738710) --- soc/arm/nordic_nrf/Kconfig.defconfig | 2 +- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 1 - subsys/pm/Kconfig | 10 +--------- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/soc/arm/nordic_nrf/Kconfig.defconfig b/soc/arm/nordic_nrf/Kconfig.defconfig index 183ec475fde9..bf4264c734bc 100644 --- a/soc/arm/nordic_nrf/Kconfig.defconfig +++ b/soc/arm/nordic_nrf/Kconfig.defconfig @@ -29,7 +29,7 @@ config ARCH_HAS_CUSTOM_BUSY_WAIT default y if !QEMU_TARGET config PM - default y if SYS_CLOCK_EXISTS && !HAS_NO_PM && MULTITHREADING + default y if SYS_CLOCK_EXISTS && MULTITHREADING config BUILD_OUTPUT_HEX default y diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 67cb8a08a6f7..521964b5ac62 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -12,7 +12,6 @@ config SOC_NRF5340_CPUAPP config SOC_NRF5340_CPUNET bool - select HAS_NO_PM select ARM_ON_EXIT_CPU_IDLE imply SOC_NRF53_ANOMALY_160_WORKAROUND_NEEDED diff --git a/subsys/pm/Kconfig b/subsys/pm/Kconfig index 4395e7718598..9de95fe7a82b 100644 --- a/subsys/pm/Kconfig +++ b/subsys/pm/Kconfig @@ -6,7 +6,7 @@ menu "Power Management" menuconfig PM bool "System Power Management" - depends on SYS_CLOCK_EXISTS && !HAS_NO_PM + depends on SYS_CLOCK_EXISTS help This option enables the board to implement extra power management policies whenever the kernel becomes idle. The kernel informs the @@ -54,14 +54,6 @@ endchoice endif # PM -config HAS_NO_PM - bool - help - This option blocks selection of PM. It can be selected in SOC - targets where system power management is not supported, for example - on support core of a multi-core device where SoC power management is - the responsibility of a different core. - config PM_DEVICE bool "Device Power Management" help From 489f92c651da5daa0cceed885514f84016d94216 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 18 Jul 2023 10:40:27 +0200 Subject: [PATCH 515/528] [nrf fromtree] pm: introduce HAS_PM Add a new Kconfig option that has to be selected by SoCs providing PM hooks. This option will be now required to enable CONFIG_PM. Before this change, CONFIG_PM could always be enabled, regardless of SoC providing any kind of low-power support. NOTE: commit adjusted to fix conflicts due to some missing previous commits. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 3d2194f11e465adb2b99dfe85f88fef41ace7500) --- soc/arm/microchip_mec/mec1501/Kconfig.series | 1 + soc/arm/microchip_mec/mec172x/Kconfig.series | 1 + soc/arm/nordic_nrf/Kconfig.defconfig | 2 +- soc/arm/nordic_nrf/nrf51/Kconfig.series | 1 + soc/arm/nordic_nrf/nrf52/Kconfig.series | 1 + soc/arm/nordic_nrf/nrf53/Kconfig.soc | 1 + soc/arm/nordic_nrf/nrf91/Kconfig.series | 1 + soc/arm/nuvoton_npcx/npcx7/Kconfig.series | 1 + soc/arm/nuvoton_npcx/npcx9/Kconfig.series | 1 + soc/arm/nxp_imx/rt/Kconfig.series | 1 + soc/arm/nxp_imx/rt5xx/Kconfig.series | 1 + soc/arm/nxp_imx/rt6xx/Kconfig.series | 1 + soc/arm/nxp_kinetis/ke1xf/Kconfig.series | 1 + soc/arm/silabs_exx32/efm32hg/Kconfig.series | 1 + soc/arm/silabs_exx32/efm32jg12b/Kconfig.series | 1 + soc/arm/silabs_exx32/efm32pg12b/Kconfig.series | 1 + soc/arm/silabs_exx32/efm32pg1b/Kconfig.series | 1 + soc/arm/silabs_exx32/efm32wg/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32bg13p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32bg22/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32bg27/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32fg13p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32fg1p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32mg12p/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32mg21/Kconfig.series | 1 + soc/arm/silabs_exx32/efr32mg24/Kconfig.series | 1 + soc/arm/st_stm32/stm32g0/Kconfig.series | 1 + soc/arm/st_stm32/stm32g4/Kconfig.series | 1 + soc/arm/st_stm32/stm32l0/Kconfig.series | 1 + soc/arm/st_stm32/stm32l4/Kconfig.series | 1 + soc/arm/st_stm32/stm32l5/Kconfig.series | 1 + soc/arm/st_stm32/stm32u5/Kconfig.series | 1 + soc/arm/st_stm32/stm32wb/Kconfig.series | 1 + soc/arm/st_stm32/stm32wl/Kconfig.series | 1 + soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series | 1 + soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.series | 1 + soc/riscv/esp32c3/Kconfig.soc | 1 + soc/riscv/riscv-ite/it8xxx2/Kconfig.series | 1 + soc/xtensa/esp32/Kconfig.soc | 1 + soc/xtensa/esp32s2/Kconfig.soc | 1 + soc/xtensa/intel_adsp/ace/Kconfig.series | 1 + soc/xtensa/intel_adsp/cavs/Kconfig.series | 1 + subsys/pm/Kconfig | 10 ++++++++-- 43 files changed, 50 insertions(+), 3 deletions(-) diff --git a/soc/arm/microchip_mec/mec1501/Kconfig.series b/soc/arm/microchip_mec/mec1501/Kconfig.series index 83683877bf6a..d3b679bb557d 100644 --- a/soc/arm/microchip_mec/mec1501/Kconfig.series +++ b/soc/arm/microchip_mec/mec1501/Kconfig.series @@ -9,5 +9,6 @@ config SOC_SERIES_MEC1501X select CPU_CORTEX_M4 select CPU_CORTEX_M_HAS_DWT select SOC_FAMILY_MEC + select HAS_PM help Enable support for Microchip MEC Cortex-M4 MCU series diff --git a/soc/arm/microchip_mec/mec172x/Kconfig.series b/soc/arm/microchip_mec/mec172x/Kconfig.series index 77f7d4023c10..cb62a2bbfa91 100644 --- a/soc/arm/microchip_mec/mec172x/Kconfig.series +++ b/soc/arm/microchip_mec/mec172x/Kconfig.series @@ -12,5 +12,6 @@ config SOC_SERIES_MEC172X select CPU_HAS_ARM_MPU select SOC_FAMILY_MEC select HAS_SWO + select HAS_PM help Enable support for Microchip MEC Cortex-M4F MCU series diff --git a/soc/arm/nordic_nrf/Kconfig.defconfig b/soc/arm/nordic_nrf/Kconfig.defconfig index bf4264c734bc..18ffeafe020d 100644 --- a/soc/arm/nordic_nrf/Kconfig.defconfig +++ b/soc/arm/nordic_nrf/Kconfig.defconfig @@ -29,7 +29,7 @@ config ARCH_HAS_CUSTOM_BUSY_WAIT default y if !QEMU_TARGET config PM - default y if SYS_CLOCK_EXISTS && MULTITHREADING + default y if SYS_CLOCK_EXISTS && MULTITHREADING && HAS_PM config BUILD_OUTPUT_HEX default y diff --git a/soc/arm/nordic_nrf/nrf51/Kconfig.series b/soc/arm/nordic_nrf/nrf51/Kconfig.series index 33f62dc43273..632ec5792fca 100644 --- a/soc/arm/nordic_nrf/nrf51/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf51/Kconfig.series @@ -12,5 +12,6 @@ config SOC_SERIES_NRF51X select XIP select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + select HAS_PM help Enable support for NRF51 MCU series diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.series b/soc/arm/nordic_nrf/nrf52/Kconfig.series index 6ff33c5da4c2..fc02e76a41b3 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.series @@ -15,5 +15,6 @@ config SOC_SERIES_NRF52X select HAS_NORDIC_DRIVERS select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_SWO + select HAS_PM help Enable support for NRF52 MCU series diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 521964b5ac62..b72528e3aa31 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -9,6 +9,7 @@ config SOC_NRF5340_CPUAPP select CPU_HAS_NRF_IDAU select CPU_HAS_FPU select ARMV8_M_DSP + select HAS_PM config SOC_NRF5340_CPUNET bool diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index 54884ec13d2f..971855ef932e 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -16,5 +16,6 @@ config SOC_SERIES_NRF91X select XIP select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE + select HAS_PM help Enable support for NRF91 MCU series diff --git a/soc/arm/nuvoton_npcx/npcx7/Kconfig.series b/soc/arm/nuvoton_npcx/npcx7/Kconfig.series index 3fb6921fc094..8f8898388cf2 100644 --- a/soc/arm/nuvoton_npcx/npcx7/Kconfig.series +++ b/soc/arm/nuvoton_npcx/npcx7/Kconfig.series @@ -12,5 +12,6 @@ config SOC_SERIES_NPCX7 select CPU_HAS_ARM_MPU select SOC_FAMILY_NPCX select CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS + select HAS_PM help Enable support for Nuvoton NPCX7 series diff --git a/soc/arm/nuvoton_npcx/npcx9/Kconfig.series b/soc/arm/nuvoton_npcx/npcx9/Kconfig.series index 61f258171fbb..82423b370598 100644 --- a/soc/arm/nuvoton_npcx/npcx9/Kconfig.series +++ b/soc/arm/nuvoton_npcx/npcx9/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_NPCX9 select CPU_HAS_FPU select CPU_HAS_ARM_MPU select SOC_FAMILY_NPCX + select HAS_PM help Enable support for Nuvoton NPCX9 series diff --git a/soc/arm/nxp_imx/rt/Kconfig.series b/soc/arm/nxp_imx/rt/Kconfig.series index d1adff602513..0a94b3963b1d 100644 --- a/soc/arm/nxp_imx/rt/Kconfig.series +++ b/soc/arm/nxp_imx/rt/Kconfig.series @@ -8,5 +8,6 @@ config SOC_SERIES_IMX_RT select ARM select SOC_FAMILY_IMX select CLOCK_CONTROL + select HAS_PM help Enable support for i.MX RT MCU series diff --git a/soc/arm/nxp_imx/rt5xx/Kconfig.series b/soc/arm/nxp_imx/rt5xx/Kconfig.series index 057e03115be8..0acc80909516 100644 --- a/soc/arm/nxp_imx/rt5xx/Kconfig.series +++ b/soc/arm/nxp_imx/rt5xx/Kconfig.series @@ -10,5 +10,6 @@ config SOC_SERIES_IMX_RT5XX select CPU_CORTEX_M_HAS_DWT select SOC_FAMILY_IMX select CLOCK_CONTROL + select HAS_PM help Enable support for i.MX RT5XX Series MCU series diff --git a/soc/arm/nxp_imx/rt6xx/Kconfig.series b/soc/arm/nxp_imx/rt6xx/Kconfig.series index b028afbfa343..bcbf86ff6bfb 100644 --- a/soc/arm/nxp_imx/rt6xx/Kconfig.series +++ b/soc/arm/nxp_imx/rt6xx/Kconfig.series @@ -12,5 +12,6 @@ config SOC_SERIES_IMX_RT6XX select CLOCK_CONTROL select CODE_DATA_RELOCATION_SRAM if FLASH_MCUX_FLEXSPI_XIP select PLATFORM_SPECIFIC_INIT + select HAS_PM help Enable support for i.MX RT6XX Series MCU series diff --git a/soc/arm/nxp_kinetis/ke1xf/Kconfig.series b/soc/arm/nxp_kinetis/ke1xf/Kconfig.series index 259e95e8a6d4..640bc4ec8fdf 100644 --- a/soc/arm/nxp_kinetis/ke1xf/Kconfig.series +++ b/soc/arm/nxp_kinetis/ke1xf/Kconfig.series @@ -32,5 +32,6 @@ config SOC_SERIES_KINETIS_KE1XF select HAS_MCUX_PWT select HAS_MCUX_RCM select PLATFORM_SPECIFIC_INIT + select HAS_PM help Enable support for Kinetis KE1xF MCU series diff --git a/soc/arm/silabs_exx32/efm32hg/Kconfig.series b/soc/arm/silabs_exx32/efm32hg/Kconfig.series index 13c74edb2e6c..4acdfa793ccd 100644 --- a/soc/arm/silabs_exx32/efm32hg/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32hg/Kconfig.series @@ -12,5 +12,6 @@ config SOC_SERIES_EFM32HG select HAS_SILABS_GECKO select SOC_GECKO_CMU select SOC_GECKO_GPIO + select HAS_PM help Enable support for EFM32 Happy Gecko MCU series diff --git a/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series b/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series index f454316dad44..2d9675430bef 100644 --- a/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series @@ -17,5 +17,6 @@ config SOC_SERIES_EFM32JG12B select SOC_GECKO_EMU select SOC_GECKO_GPIO select SOC_GECKO_TRNG + select HAS_PM help Enable support for EFM32 JadeGecko MCU series diff --git a/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series b/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series index 7f99d6d64b8b..ccb7e8178b91 100644 --- a/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series @@ -19,5 +19,6 @@ config SOC_SERIES_EFM32PG12B select SOC_GECKO_EMU select SOC_GECKO_GPIO select SOC_GECKO_TRNG + select HAS_PM help Enable support for EFM32 PearlGecko MCU series diff --git a/soc/arm/silabs_exx32/efm32pg1b/Kconfig.series b/soc/arm/silabs_exx32/efm32pg1b/Kconfig.series index 9bbf4def7629..caeae082a3bf 100644 --- a/soc/arm/silabs_exx32/efm32pg1b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32pg1b/Kconfig.series @@ -18,5 +18,6 @@ config SOC_SERIES_EFM32PG1B select SOC_GECKO_CMU select SOC_GECKO_EMU select SOC_GECKO_GPIO + select HAS_PM help Enable support for EFM32 PearlGecko MCU series diff --git a/soc/arm/silabs_exx32/efm32wg/Kconfig.series b/soc/arm/silabs_exx32/efm32wg/Kconfig.series index 5d6e4f21e444..f339c755e050 100644 --- a/soc/arm/silabs_exx32/efm32wg/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32wg/Kconfig.series @@ -14,5 +14,6 @@ config SOC_SERIES_EFM32WG select HAS_SILABS_GECKO select SOC_GECKO_CMU select SOC_GECKO_GPIO + select HAS_PM help Enable support for EFM32 WonderGecko MCU series diff --git a/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series b/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series index 3fea9b454df3..e7f524a026f7 100644 --- a/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg13p/Kconfig.series @@ -17,5 +17,6 @@ config SOC_SERIES_EFR32BG13P select SOC_GECKO_CMU select SOC_GECKO_EMU select SOC_GECKO_GPIO + select HAS_PM help Enable support for EFR32BG13P Blue Gecko MCU series diff --git a/soc/arm/silabs_exx32/efr32bg22/Kconfig.series b/soc/arm/silabs_exx32/efr32bg22/Kconfig.series index 776175de925e..266d63917257 100644 --- a/soc/arm/silabs_exx32/efr32bg22/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg22/Kconfig.series @@ -20,5 +20,6 @@ config SOC_SERIES_EFR32BG22 select SOC_GECKO_CORE select SOC_GECKO_DEV_INIT select SOC_GECKO_SE + select HAS_PM help Enable support for EFR32BG22 Blue Gecko MCU series diff --git a/soc/arm/silabs_exx32/efr32bg27/Kconfig.series b/soc/arm/silabs_exx32/efr32bg27/Kconfig.series index 6118e1886294..572e6107f4e2 100644 --- a/soc/arm/silabs_exx32/efr32bg27/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32bg27/Kconfig.series @@ -20,5 +20,6 @@ config SOC_SERIES_EFR32BG27 select SOC_GECKO_CORE select SOC_GECKO_DEV_INIT select SOC_GECKO_SE + select HAS_PM help Enable support for EFR32BG27 Blue Gecko MCU series diff --git a/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series b/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series index 1913377b3e70..6f5573775795 100644 --- a/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32fg13p/Kconfig.series @@ -18,5 +18,6 @@ config SOC_SERIES_EFR32FG13P select SOC_GECKO_CMU select SOC_GECKO_GPIO select SOC_GECKO_HAS_ERRATA_RTCC_E201 + select HAS_PM help Enable support for EFR32 FlexGecko MCU series diff --git a/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series b/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series index b2d1ff287447..f8e509faa6db 100644 --- a/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32fg1p/Kconfig.series @@ -18,5 +18,6 @@ config SOC_SERIES_EFR32FG1P select SOC_GECKO_CMU select SOC_GECKO_GPIO select SOC_GECKO_HAS_ERRATA_RTCC_E201 + select HAS_PM help Enable support for EFR32 FlexGecko MCU series diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series index 510889568f03..7c636daec862 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series @@ -19,5 +19,6 @@ config SOC_SERIES_EFR32MG12P select SOC_GECKO_EMU select SOC_GECKO_GPIO select SOC_GECKO_TRNG + select HAS_PM help Enable support for EFR32 Mighty Gecko MCU series diff --git a/soc/arm/silabs_exx32/efr32mg21/Kconfig.series b/soc/arm/silabs_exx32/efr32mg21/Kconfig.series index ab64bea46d1f..c22cb8376ee2 100644 --- a/soc/arm/silabs_exx32/efr32mg21/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg21/Kconfig.series @@ -19,5 +19,6 @@ config SOC_SERIES_EFR32MG21 select SOC_GECKO_EMU select SOC_GECKO_GPIO select SOC_GECKO_SE + select HAS_PM help Enable support for EFR32MG21 Mighty Gecko MCU series diff --git a/soc/arm/silabs_exx32/efr32mg24/Kconfig.series b/soc/arm/silabs_exx32/efr32mg24/Kconfig.series index 7c6d49d2eaed..064db296cd8e 100644 --- a/soc/arm/silabs_exx32/efr32mg24/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg24/Kconfig.series @@ -22,5 +22,6 @@ config SOC_SERIES_EFR32MG24 select SOC_GECKO_GPIO select SOC_GECKO_DEV_INIT select SOC_GECKO_SE + select HAS_PM help Enable support for EFR32MG24 Mighty Gecko MCU series diff --git a/soc/arm/st_stm32/stm32g0/Kconfig.series b/soc/arm/st_stm32/stm32g0/Kconfig.series index 43353332745f..acdb926ef61d 100644 --- a/soc/arm/st_stm32/stm32g0/Kconfig.series +++ b/soc/arm/st_stm32/stm32g0/Kconfig.series @@ -13,5 +13,6 @@ config SOC_SERIES_STM32G0X select SOC_FAMILY_STM32 select HAS_STM32CUBE select CPU_CORTEX_M_HAS_SYSTICK + select HAS_PM help Enable support for STM32G0 MCU series diff --git a/soc/arm/st_stm32/stm32g4/Kconfig.series b/soc/arm/st_stm32/stm32g4/Kconfig.series index 93fda8ba9a05..6d81e3f1fc14 100644 --- a/soc/arm/st_stm32/stm32g4/Kconfig.series +++ b/soc/arm/st_stm32/stm32g4/Kconfig.series @@ -13,5 +13,6 @@ config SOC_SERIES_STM32G4X select HAS_STM32CUBE select CPU_HAS_ARM_MPU select CLOCK_CONTROL_STM32_CUBE if CLOCK_CONTROL + select HAS_PM help Enable support for STM32G4 MCU series diff --git a/soc/arm/st_stm32/stm32l0/Kconfig.series b/soc/arm/st_stm32/stm32l0/Kconfig.series index c465a922848a..950c72d4aa78 100644 --- a/soc/arm/st_stm32/stm32l0/Kconfig.series +++ b/soc/arm/st_stm32/stm32l0/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_STM32L0X select SOC_FAMILY_STM32 select HAS_STM32CUBE select CPU_CORTEX_M_HAS_SYSTICK + select HAS_PM help Enable support for STM32L0 MCU series diff --git a/soc/arm/st_stm32/stm32l4/Kconfig.series b/soc/arm/st_stm32/stm32l4/Kconfig.series index 084082188b2f..33758aadefd7 100644 --- a/soc/arm/st_stm32/stm32l4/Kconfig.series +++ b/soc/arm/st_stm32/stm32l4/Kconfig.series @@ -14,5 +14,6 @@ config SOC_SERIES_STM32L4X select HAS_STM32CUBE select CPU_HAS_ARM_MPU select HAS_SWO + select HAS_PM help Enable support for STM32L4 MCU series diff --git a/soc/arm/st_stm32/stm32l5/Kconfig.series b/soc/arm/st_stm32/stm32l5/Kconfig.series index f9447205a539..ffee96473c32 100644 --- a/soc/arm/st_stm32/stm32l5/Kconfig.series +++ b/soc/arm/st_stm32/stm32l5/Kconfig.series @@ -15,5 +15,6 @@ config SOC_SERIES_STM32L5X select ARMV8_M_DSP select CPU_CORTEX_M_HAS_DWT select HAS_STM32CUBE + select HAS_PM help Enable support for STM32L5 MCU series diff --git a/soc/arm/st_stm32/stm32u5/Kconfig.series b/soc/arm/st_stm32/stm32u5/Kconfig.series index 69082b70e1cf..99835997a6a2 100644 --- a/soc/arm/st_stm32/stm32u5/Kconfig.series +++ b/soc/arm/st_stm32/stm32u5/Kconfig.series @@ -15,5 +15,6 @@ config SOC_SERIES_STM32U5X select ARMV8_M_DSP select CPU_CORTEX_M_HAS_DWT select HAS_STM32CUBE + select HAS_PM help Enable support for STM32U5 MCU series diff --git a/soc/arm/st_stm32/stm32wb/Kconfig.series b/soc/arm/st_stm32/stm32wb/Kconfig.series index 8ba570edfe6e..03c9bf957235 100644 --- a/soc/arm/st_stm32/stm32wb/Kconfig.series +++ b/soc/arm/st_stm32/stm32wb/Kconfig.series @@ -13,5 +13,6 @@ config SOC_SERIES_STM32WBX select HAS_STM32CUBE select CPU_HAS_ARM_MPU select HAS_SWO + select HAS_PM help Enable support for STM32WB MCU series diff --git a/soc/arm/st_stm32/stm32wl/Kconfig.series b/soc/arm/st_stm32/stm32wl/Kconfig.series index 3b2645dd6cdd..58dcae421bad 100644 --- a/soc/arm/st_stm32/stm32wl/Kconfig.series +++ b/soc/arm/st_stm32/stm32wl/Kconfig.series @@ -12,5 +12,6 @@ config SOC_SERIES_STM32WLX select HAS_STM32CUBE select CPU_HAS_ARM_MPU select CLOCK_CONTROL_STM32_CUBE if CLOCK_CONTROL + select HAS_PM help Enable support for STM32WL MCU series diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series b/soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series index ea9154b262f3..a7c8710bb2b7 100644 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series +++ b/soc/arm/ti_simplelink/cc13x2_cc26x2/Kconfig.series @@ -14,5 +14,6 @@ config SOC_SERIES_CC13X2_CC26X2 select SOC_FAMILY_TISIMPLELINK select HAS_CC13X2_CC26X2_SDK select HAS_TI_CCFG + select HAS_PM help Enable support for TI SimpleLink CC13x2 / CC26x2 SoCs diff --git a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.series b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.series index a937b6c521c1..147dd6821e27 100644 --- a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.series +++ b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/Kconfig.series @@ -14,5 +14,6 @@ config SOC_SERIES_CC13X2X7_CC26X2X7 select SOC_FAMILY_TISIMPLELINK select HAS_CC13X2X7_CC26X2X7_SDK select HAS_TI_CCFG if !BOOTLOADER_MCUBOOT + select HAS_PM help Enable support for TI SimpleLink CC13x2x7 / CC26x2x7 SoCs diff --git a/soc/riscv/esp32c3/Kconfig.soc b/soc/riscv/esp32c3/Kconfig.soc index 63321375841f..56d2a64a63ce 100644 --- a/soc/riscv/esp32c3/Kconfig.soc +++ b/soc/riscv/esp32c3/Kconfig.soc @@ -14,6 +14,7 @@ config SOC_ESP32C3 select RISCV_ISA_EXT_M select RISCV_ISA_EXT_C select RISCV_ISA_EXT_ZICSR + select HAS_PM if SOC_ESP32C3 diff --git a/soc/riscv/riscv-ite/it8xxx2/Kconfig.series b/soc/riscv/riscv-ite/it8xxx2/Kconfig.series index a30d1e554385..ebed0fcd120e 100644 --- a/soc/riscv/riscv-ite/it8xxx2/Kconfig.series +++ b/soc/riscv/riscv-ite/it8xxx2/Kconfig.series @@ -8,5 +8,6 @@ config SOC_SERIES_RISCV32_IT8XXX2 # default in most toolchains, causing link-time errors. select CPU_HAS_FPU if "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "zephyr" || RISCV_ISA_EXT_M select SOC_FAMILY_RISCV_ITE + select HAS_PM help Enable support for ITE IT8XXX2 diff --git a/soc/xtensa/esp32/Kconfig.soc b/soc/xtensa/esp32/Kconfig.soc index 56949f965992..97020542b00f 100644 --- a/soc/xtensa/esp32/Kconfig.soc +++ b/soc/xtensa/esp32/Kconfig.soc @@ -12,6 +12,7 @@ config SOC_ESP32 select XIP if !MCUBOOT select HAS_ESPRESSIF_HAL select CPU_HAS_FPU + select HAS_PM if SOC_ESP32 diff --git a/soc/xtensa/esp32s2/Kconfig.soc b/soc/xtensa/esp32s2/Kconfig.soc index f9d77cc1f5d5..1aea6e8beb3a 100644 --- a/soc/xtensa/esp32s2/Kconfig.soc +++ b/soc/xtensa/esp32s2/Kconfig.soc @@ -10,6 +10,7 @@ config SOC_ESP32S2 select PINCTRL select XIP if !MCUBOOT select HAS_ESPRESSIF_HAL + select HAS_PM if SOC_ESP32S2 diff --git a/soc/xtensa/intel_adsp/ace/Kconfig.series b/soc/xtensa/intel_adsp/ace/Kconfig.series index 8b4f8e61436f..963c33bdf615 100644 --- a/soc/xtensa/intel_adsp/ace/Kconfig.series +++ b/soc/xtensa/intel_adsp/ace/Kconfig.series @@ -11,5 +11,6 @@ config SOC_SERIES_INTEL_ACE select SCHED_IPI_SUPPORTED select DW_ICTL_ACE select SOC_HAS_RUNTIME_NUM_CPUS + select HAS_PM help Intel ADSP ACE diff --git a/soc/xtensa/intel_adsp/cavs/Kconfig.series b/soc/xtensa/intel_adsp/cavs/Kconfig.series index 1f398025eb4b..adbc1f39e1d4 100644 --- a/soc/xtensa/intel_adsp/cavs/Kconfig.series +++ b/soc/xtensa/intel_adsp/cavs/Kconfig.series @@ -10,5 +10,6 @@ config SOC_SERIES_INTEL_ADSP_CAVS select XTENSA_USE_CORE_CRT1 select ATOMIC_OPERATIONS_BUILTIN if "$(ZEPHYR_TOOLCHAIN_VARIANT)" != "xcc" select ARCH_HAS_COHERENCE + select HAS_PM help Intel ADSP CAVS diff --git a/subsys/pm/Kconfig b/subsys/pm/Kconfig index 9de95fe7a82b..3240f936a7d5 100644 --- a/subsys/pm/Kconfig +++ b/subsys/pm/Kconfig @@ -4,9 +4,15 @@ menu "Power Management" -menuconfig PM +config HAS_PM + bool + help + This option must be selected by SoCs that provide PM hooks, that is, + calls to configure low-power states. + +config PM bool "System Power Management" - depends on SYS_CLOCK_EXISTS + depends on SYS_CLOCK_EXISTS && HAS_PM help This option enables the board to implement extra power management policies whenever the kernel becomes idle. The kernel informs the From 9d68d7e687fe387f072e7be9a4d8de088f5652e7 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 18 Jul 2023 11:21:35 +0200 Subject: [PATCH 516/528] [nrf fromtree] tests: pm: select HAS_PM Some tests provide their own PM hooks, adapted for testing purposes. Add a new option to select HAS_PM, so that CONFIG_PM can be enabled. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit bddf2d9dc0721d15e828b7acd7de6dd25a3a736a) --- samples/subsys/pm/latency/Kconfig | 6 ++++++ tests/subsys/pm/device_wakeup_api/Kconfig | 11 +++++++++++ tests/subsys/pm/policy_api/Kconfig | 11 +++++++++++ tests/subsys/pm/policy_api/src/main.c | 14 ++++++++++++++ tests/subsys/pm/power_mgmt/Kconfig | 11 +++++++++++ tests/subsys/pm/power_mgmt_multicore/Kconfig | 11 +++++++++++ 6 files changed, 64 insertions(+) create mode 100644 tests/subsys/pm/device_wakeup_api/Kconfig create mode 100644 tests/subsys/pm/policy_api/Kconfig create mode 100644 tests/subsys/pm/power_mgmt/Kconfig create mode 100644 tests/subsys/pm/power_mgmt_multicore/Kconfig diff --git a/samples/subsys/pm/latency/Kconfig b/samples/subsys/pm/latency/Kconfig index 0e08794c13a8..e3578670ddfb 100644 --- a/samples/subsys/pm/latency/Kconfig +++ b/samples/subsys/pm/latency/Kconfig @@ -8,3 +8,9 @@ endmenu module = APP module-str = Application source "subsys/logging/Kconfig.template.log_config" + + +config APP_PROVIDE_PM_HOOKS + bool "Application provides PM hooks" + default y + select HAS_PM diff --git a/tests/subsys/pm/device_wakeup_api/Kconfig b/tests/subsys/pm/device_wakeup_api/Kconfig new file mode 100644 index 000000000000..6a021dcd9449 --- /dev/null +++ b/tests/subsys/pm/device_wakeup_api/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "Zephyr" +source "Kconfig.zephyr" +endmenu + +config TEST_PROVIDE_PM_HOOKS + bool "Provide PM hooks for test purposes" + default y + select HAS_PM diff --git a/tests/subsys/pm/policy_api/Kconfig b/tests/subsys/pm/policy_api/Kconfig new file mode 100644 index 000000000000..6a021dcd9449 --- /dev/null +++ b/tests/subsys/pm/policy_api/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "Zephyr" +source "Kconfig.zephyr" +endmenu + +config TEST_PROVIDE_PM_HOOKS + bool "Provide PM hooks for test purposes" + default y + select HAS_PM diff --git a/tests/subsys/pm/policy_api/src/main.c b/tests/subsys/pm/policy_api/src/main.c index c29c7eb86d0c..8ea72d7e3f03 100644 --- a/tests/subsys/pm/policy_api/src/main.c +++ b/tests/subsys/pm/policy_api/src/main.c @@ -9,6 +9,20 @@ #include #include +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + ARG_UNUSED(state); +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(state); + ARG_UNUSED(substate_id); + + irq_unlock(0); +} + #ifdef CONFIG_PM_POLICY_DEFAULT /** * @brief Test the behavior of pm_policy_next_state() when diff --git a/tests/subsys/pm/power_mgmt/Kconfig b/tests/subsys/pm/power_mgmt/Kconfig new file mode 100644 index 000000000000..6a021dcd9449 --- /dev/null +++ b/tests/subsys/pm/power_mgmt/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "Zephyr" +source "Kconfig.zephyr" +endmenu + +config TEST_PROVIDE_PM_HOOKS + bool "Provide PM hooks for test purposes" + default y + select HAS_PM diff --git a/tests/subsys/pm/power_mgmt_multicore/Kconfig b/tests/subsys/pm/power_mgmt_multicore/Kconfig new file mode 100644 index 000000000000..6a021dcd9449 --- /dev/null +++ b/tests/subsys/pm/power_mgmt_multicore/Kconfig @@ -0,0 +1,11 @@ +# Copyright (c) 2023 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +menu "Zephyr" +source "Kconfig.zephyr" +endmenu + +config TEST_PROVIDE_PM_HOOKS + bool "Provide PM hooks for test purposes" + default y + select HAS_PM From f88f67babf4df5bf08104bf3ca3946a1bd0c29f5 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 17 Jul 2023 16:49:31 +0200 Subject: [PATCH 517/528] [nrf fromtree] pm: remove dummy pm_state_set/pm_state_exit_post_ops Dummy inline functions are useful to avoid ifdeffery in code when a certain option is not available. pm_state_set/pm_state_exit_post_ops, are only called from the PM subsystem, so never called if CONFIG_PM=n, that is, never surrounded with ifdeffery. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit b3fa2eec45178e26bcf7bce4ad13463af8dadcea) --- include/zephyr/pm/pm.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/include/zephyr/pm/pm.h b/include/zephyr/pm/pm.h index 9d6b69ad21a3..03062eefd12e 100644 --- a/include/zephyr/pm/pm.h +++ b/include/zephyr/pm/pm.h @@ -167,19 +167,6 @@ static inline int pm_notifier_unregister(struct pm_notifier *notifier) return -ENOSYS; } -static inline void pm_state_set(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(state); - ARG_UNUSED(substate_id); -} - -static inline void pm_state_exit_post_ops(enum pm_state state, - uint8_t substate_id) -{ - ARG_UNUSED(state); - ARG_UNUSED(substate_id); -} - static inline const struct pm_state_info *pm_state_next_get(uint8_t cpu) { ARG_UNUSED(cpu); From a56be313e3a7d729190056737c0160daa95c6251 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 17 Jul 2023 16:59:26 +0200 Subject: [PATCH 518/528] [nrf fromtree] pm: require pm_state_set/pm_exit_post_ops Any system supporting PM must now implement pm_state_set/pm_exit_post_ops. Before this change any platform could enable CONFIG_PM=y, even though it did nothing, ie, no power savings at all. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit e1eedd1a9f714e7c40d8f4591fd4c2360a355d64) --- subsys/pm/pm.c | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/subsys/pm/pm.c b/subsys/pm/pm.c index c9eb15e0d351..ae6e8505d891 100644 --- a/subsys/pm/pm.c +++ b/subsys/pm/pm.c @@ -107,35 +107,6 @@ static void pm_resume_devices(void) #endif /* !CONFIG_PM_DEVICE_RUNTIME_EXCLUSIVE */ #endif /* CONFIG_PM_DEVICE */ -static inline void pm_exit_pos_ops(struct pm_state_info *info) -{ - extern __weak void - pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id); - - if (pm_state_exit_post_ops != NULL) { - pm_state_exit_post_ops(info->state, info->substate_id); - } else { - /* - * This function is supposed to be overridden to do SoC or - * architecture specific post ops after sleep state exits. - * - * The kernel expects that irqs are unlocked after this. - */ - - irq_unlock(0); - } -} - -static inline void state_set(struct pm_state_info *info) -{ - extern __weak void - pm_state_set(enum pm_state state, uint8_t substate_id); - - if (pm_state_set != NULL) { - pm_state_set(info->state, info->substate_id); - } -} - /* * Function called to notify when the system is entering / exiting a * power state @@ -178,7 +149,7 @@ void pm_system_resume(void) * and it may schedule another thread. */ if (atomic_test_and_clear_bit(z_post_ops_required, id)) { - pm_exit_pos_ops(&z_cpus_pm_state[id]); + pm_state_exit_post_ops(z_cpus_pm_state[id].state, z_cpus_pm_state[id].substate_id); pm_state_notify(false); z_cpus_pm_state[id] = (struct pm_state_info){PM_STATE_ACTIVE, 0, 0}; @@ -266,7 +237,7 @@ bool pm_system_suspend(int32_t ticks) /* Enter power state */ pm_state_notify(true); atomic_set_bit(z_post_ops_required, id); - state_set(&z_cpus_pm_state[id]); + pm_state_set(z_cpus_pm_state[id].state, z_cpus_pm_state[id].substate_id); pm_stats_stop(); /* Wake up sequence starts here */ From 3cd256ddb5f46173a203c62bf76d9a6ba827bf20 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Mon, 17 Jul 2023 17:03:00 +0200 Subject: [PATCH 519/528] [nrf fromtree] pm: remove unnecessary __weak from pm_state_set/pm_exit_post_ops Remove unnecessary __weak attribute from power management functions. These functions are now defined once, globally, and mandatory for systems that support CONFIG_PM. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 55f5a75c58e8e693ca95bd6d6f14510061bb5055) --- soc/arm/microchip_mec/mec1501/power.c | 4 ++-- soc/arm/microchip_mec/mec172x/power.c | 4 ++-- soc/arm/nordic_nrf/nrf51/power.c | 4 ++-- soc/arm/nordic_nrf/nrf52/power.c | 4 ++-- soc/arm/nordic_nrf/nrf53/power.c | 4 ++-- soc/arm/nordic_nrf/nrf91/power.c | 4 ++-- soc/arm/nuvoton_npcx/common/power.c | 4 ++-- soc/arm/nxp_imx/rt/power_rt10xx.c | 4 ++-- soc/arm/nxp_imx/rt/power_rt11xx.c | 4 ++-- soc/arm/nxp_imx/rt5xx/power.c | 4 ++-- soc/arm/nxp_imx/rt6xx/power.c | 4 ++-- soc/arm/nxp_kinetis/ke1xf/power.c | 4 ++-- soc/arm/silabs_exx32/common/soc_power.c | 4 ++-- soc/arm/silabs_exx32/common/soc_power_pmgr.c | 2 +- soc/arm/st_stm32/stm32g0/power.c | 4 ++-- soc/arm/st_stm32/stm32g4/power.c | 4 ++-- soc/arm/st_stm32/stm32l0/power.c | 4 ++-- soc/arm/st_stm32/stm32l4/power.c | 4 ++-- soc/arm/st_stm32/stm32l5/power.c | 4 ++-- soc/arm/st_stm32/stm32u5/power.c | 4 ++-- soc/arm/st_stm32/stm32wb/power.c | 4 ++-- soc/arm/st_stm32/stm32wl/power.c | 4 ++-- soc/arm/ti_simplelink/cc13x2_cc26x2/power.c | 4 ++-- soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/power.c | 4 ++-- soc/riscv/esp32c3/power.c | 4 ++-- soc/riscv/riscv-ite/common/power.c | 4 ++-- soc/xtensa/esp32/power.c | 4 ++-- soc/xtensa/esp32s2/power.c | 4 ++-- soc/xtensa/intel_adsp/ace/power.c | 4 ++-- soc/xtensa/intel_adsp/cavs/power.c | 4 ++-- 30 files changed, 59 insertions(+), 59 deletions(-) diff --git a/soc/arm/microchip_mec/mec1501/power.c b/soc/arm/microchip_mec/mec1501/power.c index 53cc7bc9717d..de6e2fd6fbfb 100644 --- a/soc/arm/microchip_mec/mec1501/power.c +++ b/soc/arm/microchip_mec/mec1501/power.c @@ -102,7 +102,7 @@ static void z_power_soc_sleep(void) * For deep sleep pm_system_suspend has executed all the driver * power management call backs. */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -126,7 +126,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) * an ISR on wake except for faults. We re-enable interrupts by setting PRIMASK * to 0. */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/microchip_mec/mec172x/power.c b/soc/arm/microchip_mec/mec172x/power.c index ec0034589ef3..0f31cca31288 100644 --- a/soc/arm/microchip_mec/mec172x/power.c +++ b/soc/arm/microchip_mec/mec172x/power.c @@ -144,7 +144,7 @@ static void z_power_soc_sleep(void) * For deep sleep pm_system_suspend has executed all the driver * power management call backs. */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -168,7 +168,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) * ISR on wake except for faults. We re-enable interrupts by undoing global disable * and alling irq_unlock with the same value, 0 zephyr core uses. */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { __enable_irq(); irq_unlock(0); diff --git a/soc/arm/nordic_nrf/nrf51/power.c b/soc/arm/nordic_nrf/nrf51/power.c index 8291d10700d2..1f86bca17b8c 100644 --- a/soc/arm/nordic_nrf/nrf51/power.c +++ b/soc/arm/nordic_nrf/nrf51/power.c @@ -11,7 +11,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -26,7 +26,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/nordic_nrf/nrf52/power.c b/soc/arm/nordic_nrf/nrf52/power.c index 8291d10700d2..1f86bca17b8c 100644 --- a/soc/arm/nordic_nrf/nrf52/power.c +++ b/soc/arm/nordic_nrf/nrf52/power.c @@ -11,7 +11,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -26,7 +26,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/nordic_nrf/nrf53/power.c b/soc/arm/nordic_nrf/nrf53/power.c index ccd658be6ebc..5e4f6080dd41 100644 --- a/soc/arm/nordic_nrf/nrf53/power.c +++ b/soc/arm/nordic_nrf/nrf53/power.c @@ -13,7 +13,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -28,7 +28,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/nordic_nrf/nrf91/power.c b/soc/arm/nordic_nrf/nrf91/power.c index 20834906069d..44bcefbf1593 100644 --- a/soc/arm/nordic_nrf/nrf91/power.c +++ b/soc/arm/nordic_nrf/nrf91/power.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -27,7 +27,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/nuvoton_npcx/common/power.c b/soc/arm/nuvoton_npcx/common/power.c index 379784231d2c..e7fe036f7669 100644 --- a/soc/arm/nuvoton_npcx/common/power.c +++ b/soc/arm/nuvoton_npcx/common/power.c @@ -199,7 +199,7 @@ static void npcx_power_enter_system_sleep(int slp_mode, int wk_mode) } /* Invoke when enter "Suspend/Low Power" mode. */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { if (state != PM_STATE_SUSPEND_TO_IDLE) { LOG_DBG("Unsupported power state %u", state); @@ -228,7 +228,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle soc specific activity after exiting "Suspend/Low Power" mode. */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { if (state != PM_STATE_SUSPEND_TO_IDLE) { LOG_DBG("Unsupported power state %u", state); diff --git a/soc/arm/nxp_imx/rt/power_rt10xx.c b/soc/arm/nxp_imx/rt/power_rt10xx.c index dea33f3ce8f6..ca10fdecf4dc 100644 --- a/soc/arm/nxp_imx/rt/power_rt10xx.c +++ b/soc/arm/nxp_imx/rt/power_rt10xx.c @@ -183,7 +183,7 @@ static void lpm_raise_voltage(void) /* Sets device into low power mode */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -213,7 +213,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/nxp_imx/rt/power_rt11xx.c b/soc/arm/nxp_imx/rt/power_rt11xx.c index 559e61ce5bcc..871a7d809a3c 100644 --- a/soc/arm/nxp_imx/rt/power_rt11xx.c +++ b/soc/arm/nxp_imx/rt/power_rt11xx.c @@ -283,7 +283,7 @@ void cpu_mode_transition(gpc_cpu_mode_t mode, bool enable_standby) * SOC specific low power mode implementation * Drop to lowest power state possible given system's request */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(state); @@ -306,7 +306,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } } -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(state); ARG_UNUSED(substate_id); diff --git a/soc/arm/nxp_imx/rt5xx/power.c b/soc/arm/nxp_imx/rt5xx/power.c index 9c95fc3a424f..b4137827c605 100644 --- a/soc/arm/nxp_imx/rt5xx/power.c +++ b/soc/arm/nxp_imx/rt5xx/power.c @@ -45,7 +45,7 @@ __ramfunc void restore_deepsleep_pin_config(void) } /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -82,7 +82,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(state); ARG_UNUSED(substate_id); diff --git a/soc/arm/nxp_imx/rt6xx/power.c b/soc/arm/nxp_imx/rt6xx/power.c index 6709f7b2c9dc..04494737af60 100644 --- a/soc/arm/nxp_imx/rt6xx/power.c +++ b/soc/arm/nxp_imx/rt6xx/power.c @@ -22,7 +22,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); APP_DEEPSLEEP_RAM_APD, APP_DEEPSLEEP_RAM_PPD})) /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -52,7 +52,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(state); ARG_UNUSED(substate_id); diff --git a/soc/arm/nxp_kinetis/ke1xf/power.c b/soc/arm/nxp_kinetis/ke1xf/power.c index 8d2cdfbe4383..6340df6ff5b9 100644 --- a/soc/arm/nxp_kinetis/ke1xf/power.c +++ b/soc/arm/nxp_kinetis/ke1xf/power.c @@ -25,7 +25,7 @@ __ramfunc static void wait_for_flash_prefetch_and_idle(void) } #endif /* CONFIG_XIP */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { switch (state) { case PM_STATE_RUNTIME_IDLE: @@ -51,7 +51,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } } -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/silabs_exx32/common/soc_power.c b/soc/arm/silabs_exx32/common/soc_power.c index e1702a100833..cdb279c848fe 100644 --- a/soc/arm/silabs_exx32/common/soc_power.c +++ b/soc/arm/silabs_exx32/common/soc_power.c @@ -20,7 +20,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); */ /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -63,7 +63,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(state); ARG_UNUSED(substate_id); diff --git a/soc/arm/silabs_exx32/common/soc_power_pmgr.c b/soc/arm/silabs_exx32/common/soc_power_pmgr.c index aa303874ddec..0286e99e77f5 100644 --- a/soc/arm/silabs_exx32/common/soc_power_pmgr.c +++ b/soc/arm/silabs_exx32/common/soc_power_pmgr.c @@ -21,7 +21,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); sl_power_manager_em_t energy_mode = SL_POWER_MANAGER_EM0; diff --git a/soc/arm/st_stm32/stm32g0/power.c b/soc/arm/st_stm32/stm32g0/power.c index bc9ca8f2a312..d13ec265679e 100644 --- a/soc/arm/st_stm32/stm32g0/power.c +++ b/soc/arm/st_stm32/stm32g0/power.c @@ -20,7 +20,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { if (state != PM_STATE_SUSPEND_TO_IDLE) { LOG_DBG("Unsupported power state %u", state); @@ -50,7 +50,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { if (state != PM_STATE_SUSPEND_TO_IDLE) { LOG_DBG("Unsupported power substate %u", state); diff --git a/soc/arm/st_stm32/stm32g4/power.c b/soc/arm/st_stm32/stm32g4/power.c index 7d55a3c42094..dadb07114681 100644 --- a/soc/arm/st_stm32/stm32g4/power.c +++ b/soc/arm/st_stm32/stm32g4/power.c @@ -20,7 +20,7 @@ LOG_MODULE_REGISTER(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { if (state != PM_STATE_SUSPEND_TO_IDLE) { LOG_DBG("Unsupported power state %u", state); @@ -49,7 +49,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { if (state != PM_STATE_SUSPEND_TO_IDLE) { LOG_DBG("Unsupported power substate %u", state); diff --git a/soc/arm/st_stm32/stm32l0/power.c b/soc/arm/st_stm32/stm32l0/power.c index 585aaf69293f..a2a11f824aad 100644 --- a/soc/arm/st_stm32/stm32l0/power.c +++ b/soc/arm/st_stm32/stm32l0/power.c @@ -28,7 +28,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); #endif /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -54,7 +54,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/st_stm32/stm32l4/power.c b/soc/arm/st_stm32/stm32l4/power.c index b8445a7165cd..8b1a68fc767e 100644 --- a/soc/arm/st_stm32/stm32l4/power.c +++ b/soc/arm/st_stm32/stm32l4/power.c @@ -82,7 +82,7 @@ void set_mode_shutdown(void) } /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { switch (state) { case PM_STATE_SUSPEND_TO_IDLE: @@ -106,7 +106,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { switch (state) { case PM_STATE_SUSPEND_TO_IDLE: diff --git a/soc/arm/st_stm32/stm32l5/power.c b/soc/arm/st_stm32/stm32l5/power.c index e799b88c86ef..1d5316c69635 100644 --- a/soc/arm/st_stm32/stm32l5/power.c +++ b/soc/arm/st_stm32/stm32l5/power.c @@ -28,7 +28,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); #endif /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { if (state != PM_STATE_SUSPEND_TO_IDLE) { LOG_DBG("Unsupported power state %u", state); @@ -66,7 +66,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { if (state != PM_STATE_SUSPEND_TO_IDLE) { LOG_DBG("Unsupported power substate-id %u", state); diff --git a/soc/arm/st_stm32/stm32u5/power.c b/soc/arm/st_stm32/stm32u5/power.c index 32e8e7334e29..4cd5834cf8be 100644 --- a/soc/arm/st_stm32/stm32u5/power.c +++ b/soc/arm/st_stm32/stm32u5/power.c @@ -62,7 +62,7 @@ void set_mode_shutdown(uint8_t substate_id) } /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { switch (state) { case PM_STATE_SUSPEND_TO_IDLE: @@ -88,7 +88,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { switch (state) { case PM_STATE_SUSPEND_TO_IDLE: diff --git a/soc/arm/st_stm32/stm32wb/power.c b/soc/arm/st_stm32/stm32wb/power.c index fba9c06aad2d..cf368503c364 100644 --- a/soc/arm/st_stm32/stm32wb/power.c +++ b/soc/arm/st_stm32/stm32wb/power.c @@ -56,7 +56,7 @@ static void lpm_hsem_lock(void) } /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { if (state == PM_STATE_SOFT_OFF) { lpm_hsem_lock(); @@ -108,7 +108,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { /* Implementation of STM32 AN5289 algorithm to enter/exit lowpower */ /* Release ENTRY_STOP_MODE semaphore */ diff --git a/soc/arm/st_stm32/stm32wl/power.c b/soc/arm/st_stm32/stm32wl/power.c index e85f55ea39a3..5517ec1ff470 100644 --- a/soc/arm/st_stm32/stm32wl/power.c +++ b/soc/arm/st_stm32/stm32wl/power.c @@ -28,7 +28,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); #endif /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { switch (state) { case PM_STATE_SUSPEND_TO_IDLE: @@ -74,7 +74,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/arm/ti_simplelink/cc13x2_cc26x2/power.c b/soc/arm/ti_simplelink/cc13x2_cc26x2/power.c index a22ecee538f3..88a519336654 100644 --- a/soc/arm/ti_simplelink/cc13x2_cc26x2/power.c +++ b/soc/arm/ti_simplelink/cc13x2_cc26x2/power.c @@ -58,7 +58,7 @@ extern PowerCC26X2_ModuleState PowerCC26X2_module; */ /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -122,7 +122,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(state); ARG_UNUSED(substate_id); diff --git a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/power.c b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/power.c index 07057129e258..f0e1407ef45a 100644 --- a/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/power.c +++ b/soc/arm/ti_simplelink/cc13x2x7_cc26x2x7/power.c @@ -58,7 +58,7 @@ extern PowerCC26X2_ModuleState PowerCC26X2_module; */ /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -122,7 +122,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(state); ARG_UNUSED(substate_id); diff --git a/soc/riscv/esp32c3/power.c b/soc/riscv/esp32c3/power.c index f7dd0e8ec508..aa63c6925f0a 100644 --- a/soc/riscv/esp32c3/power.c +++ b/soc/riscv/esp32c3/power.c @@ -12,7 +12,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -32,7 +32,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/riscv/riscv-ite/common/power.c b/soc/riscv/riscv-ite/common/power.c index 882101b94346..120c80c68524 100644 --- a/soc/riscv/riscv-ite/common/power.c +++ b/soc/riscv/riscv-ite/common/power.c @@ -16,7 +16,7 @@ static void ite_power_soc_deep_doze(void) } /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -31,7 +31,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(state); ARG_UNUSED(substate_id); diff --git a/soc/xtensa/esp32/power.c b/soc/xtensa/esp32/power.c index 440d232d4b3c..ddbf77c42fcc 100644 --- a/soc/xtensa/esp32/power.c +++ b/soc/xtensa/esp32/power.c @@ -16,7 +16,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); static uint32_t intenable; /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -43,7 +43,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/xtensa/esp32s2/power.c b/soc/xtensa/esp32s2/power.c index 907784d5cd4c..42e7121438ea 100644 --- a/soc/xtensa/esp32s2/power.c +++ b/soc/xtensa/esp32s2/power.c @@ -14,7 +14,7 @@ LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); static uint32_t intenable; /* Invoke Low Power/System Off specific Tasks */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); @@ -35,7 +35,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); diff --git a/soc/xtensa/intel_adsp/ace/power.c b/soc/xtensa/intel_adsp/ace/power.c index ea3ea2e6d63f..bd921e3f16b0 100644 --- a/soc/xtensa/intel_adsp/ace/power.c +++ b/soc/xtensa/intel_adsp/ace/power.c @@ -213,7 +213,7 @@ __imr void pm_state_imr_restore(void) } #endif /* CONFIG_ADSP_IMR_CONTEXT_SAVE */ -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); uint32_t cpu = arch_proc_id(); @@ -298,7 +298,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); uint32_t cpu = arch_proc_id(); diff --git a/soc/xtensa/intel_adsp/cavs/power.c b/soc/xtensa/intel_adsp/cavs/power.c index e05df97c6e72..34ddb726afdb 100644 --- a/soc/xtensa/intel_adsp/cavs/power.c +++ b/soc/xtensa/intel_adsp/cavs/power.c @@ -76,7 +76,7 @@ static inline void __sparse_cache *uncache_to_cache(void *address) return (void __sparse_cache *)((uintptr_t)(address) | SRAM_ALIAS_OFFSET); } -__weak void pm_state_set(enum pm_state state, uint8_t substate_id) +void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); uint32_t cpu = arch_proc_id(); @@ -112,7 +112,7 @@ __weak void pm_state_set(enum pm_state state, uint8_t substate_id) } /* Handle SOC specific activity after Low Power Mode Exit */ -__weak void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); uint32_t cpu = arch_proc_id(); From 8811ec6710c31e1d13a50b295b2c6bfefe667da1 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 19 Jul 2023 09:40:09 +0200 Subject: [PATCH 520/528] [nrf fromtree] soc: xtensa: intel_adsp: cavs: fix PM hooks guards The PM hooks were guarded with CONFIG_PM_POLICY_CUSTOM, however, they need to be guarded (if file is always compiled) with CONFIG_PM. In fact, CONFIG_PM_POLICY_CUSTOM requires to implement a custom policy hook, something this module did not provide. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit f60306193844208f4f9ac373f8cae1fd3a207d12) --- soc/xtensa/intel_adsp/cavs/power.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/soc/xtensa/intel_adsp/cavs/power.c b/soc/xtensa/intel_adsp/cavs/power.c index 34ddb726afdb..42598e9b56fd 100644 --- a/soc/xtensa/intel_adsp/cavs/power.c +++ b/soc/xtensa/intel_adsp/cavs/power.c @@ -35,7 +35,7 @@ LOG_MODULE_REGISTER(soc); # define SHIM_GPDMA_CLKCTL(x) (SHIM_GPDMA_BASE(x) + 0x4) # define SHIM_CLKCTL_LPGPDMAFDCGB BIT(0) -#ifdef CONFIG_PM_POLICY_CUSTOM +#ifdef CONFIG_PM #define SRAM_ALIAS_BASE 0x9E000000 #define SRAM_ALIAS_MASK 0xFF000000 #define SRAM_ALIAS_OFFSET 0x20000000 @@ -125,7 +125,7 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) __ASSERT(false, "invalid argument - unsupported power state"); } } -#endif /* CONFIG_PM_POLICY_CUSTOM */ +#endif /* CONFIG_PM */ __imr void power_init(void) { From 4e22e52585c49758a43e3167ea7e99ffd86a13a4 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 20 Jul 2023 11:46:41 +0200 Subject: [PATCH 521/528] [nrf fromtree] lib: os: add support for system power off Add a new API to perform an immediate system power off: `sys_poweroff()`. Until now, this functionality has been implemented via the system power management module, but in a clunky fashion. The way system PM works is by defining some idle states in devicetree, that, given some properties (e.g. minimal residency, exit latency, etc.) are automatically selected when system goes to idle based on the expected next wake-up. However, system off is a power state that one typically wants to control manually from the application because it implies state loss, and in most cases, configuring some sort of wake-up source. So in general, it is not desired to let the system enter this state automatically. This led to the following stuff in-tree: from `boards/arm/mimxrt595_evk/mimxrt595_evk_cm33.dts`: ```c /* * Deep power-down mode is supported in this SoC through * 'PM_STATE_SOFT_OFF' state. There is no entry for this in device tree, * user can call pm_state_force to enter this state. */ ``` That is, state not being defined in devicetree so that PM subsystem doesn't pick it automatically, but still implemented in in the PM hooks: from `soc/arm/nxp_imx/rt5xx/power.c`, `pm_state_set()`: ```c case PM_STATE_SOFT_OFF: set_deepsleep_pin_config(); POWER_EnterDeepPowerDown(EXCLUDE_FROM_DEEP_POWERDOWN); break; ``` And to actually make use of this state, users had to do this kind of abominations: ```c pm_state_force(0u, &(struct pm_state_info){ PM_STATE_SOFT_OFF, 0, 0 }); /* Now we need to go sleep. This will let the idle thread runs and * the pm subsystem will use the forced state. To confirm that the * forced state is used, lets set the same timeout used previously. */ k_sleep(K_SECONDS(SLEEP_S)); printk("ERROR: System off failed\n"); while (true) { /* spin to avoid fall-off behavior */ } ``` Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 90b247b90b1a8f8b545a325a303ff5f52bceae80) --- doc/services/index.rst | 1 + doc/services/poweroff.rst | 6 ++++ include/zephyr/sys/poweroff.h | 54 +++++++++++++++++++++++++++++++++++ lib/os/CMakeLists.txt | 2 ++ lib/os/Kconfig | 11 +++++++ lib/os/poweroff.c | 14 +++++++++ 6 files changed, 88 insertions(+) create mode 100644 doc/services/poweroff.rst create mode 100644 include/zephyr/sys/poweroff.h create mode 100644 lib/os/poweroff.c diff --git a/doc/services/index.rst b/doc/services/index.rst index 8b9e94092b24..6ba8af68a673 100644 --- a/doc/services/index.rst +++ b/doc/services/index.rst @@ -22,6 +22,7 @@ OS Services notify.rst pm/index.rst portability/index.rst + poweroff.rst shell/index.rst settings/index.rst smf/index.rst diff --git a/doc/services/poweroff.rst b/doc/services/poweroff.rst new file mode 100644 index 000000000000..a37c4a23b1b8 --- /dev/null +++ b/doc/services/poweroff.rst @@ -0,0 +1,6 @@ +.. _poweroff: + +Power off +######### + +.. doxygengroup:: sys_poweroff diff --git a/include/zephyr/sys/poweroff.h b/include/zephyr/sys/poweroff.h new file mode 100644 index 000000000000..e9a3dc052153 --- /dev/null +++ b/include/zephyr/sys/poweroff.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_SYS_POWEROFF_H_ +#define ZEPHYR_INCLUDE_SYS_POWEROFF_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @defgroup sys_poweroff System power off + * @ingroup os_services + * @{ + */ + +/** @cond INTERNAL_HIDDEN */ + +/** + * @brief System power off hook. + * + * This function needs to be implemented in platform code. It must only + * perform an immediate power off of the system. + */ +FUNC_NORETURN void z_sys_poweroff(void); + +/** @} */ + +/** @endcond */ + +/** + * @brief Perform a system power off. + * + * This function will perform an immediate power off of the system. It is the + * responsability of the caller to ensure that the system is in a safe state to + * be powered off. Any required wake up sources must be enabled before calling + * this function. + * + * @kconfig{CONFIG_POWEROFF} needs to be enabled to use this API. + */ +FUNC_NORETURN void sys_poweroff(void); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* ZEPHYR_INCLUDE_SYS_POWEROFF_H_ */ diff --git a/lib/os/CMakeLists.txt b/lib/os/CMakeLists.txt index ac542223b934..f92b0d6e98e9 100644 --- a/lib/os/CMakeLists.txt +++ b/lib/os/CMakeLists.txt @@ -68,6 +68,8 @@ zephyr_sources_ifdef(CONFIG_SYS_MEM_BLOCKS mem_blocks.c) zephyr_sources_ifdef(CONFIG_WINSTREAM winstream.c) +zephyr_sources_ifdef(CONFIG_POWEROFF poweroff.c) + zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/${ARCH}/include diff --git a/lib/os/Kconfig b/lib/os/Kconfig index adb67a510701..5f84c6781b82 100644 --- a/lib/os/Kconfig +++ b/lib/os/Kconfig @@ -166,6 +166,17 @@ config REBOOT needed to perform a "safe" reboot (e.g. to stop the system clock before issuing a reset). +config HAS_POWEROFF + bool + help + Option to signal that power off functionality is implemented. + +config POWEROFF + bool "Power off functionality" + depends on HAS_POWEROFF + help + Enable support for system power off. + config UTF8 bool "UTF-8 string operation supported" help diff --git a/lib/os/poweroff.c b/lib/os/poweroff.c new file mode 100644 index 000000000000..f4e90e477caa --- /dev/null +++ b/lib/os/poweroff.c @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +void sys_poweroff(void) +{ + (void)irq_lock(); + + z_sys_poweroff(); +} From f195f480d0408559512e80830ed356d5a155dce8 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 20 Jul 2023 12:05:26 +0200 Subject: [PATCH 522/528] [nrf fromtree] soc: arm: nordic_nrf: add support for poweroff Implement the z_sys_poweroff() hook and select HAS_POWEROFF. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 526a7bb20d9da75aa6819a40d0de88ef9e47c4da) --- soc/arm/nordic_nrf/common/CMakeLists.txt | 1 + soc/arm/nordic_nrf/common/poweroff.c | 16 ++++++++++++++++ soc/arm/nordic_nrf/nrf51/Kconfig.series | 1 + soc/arm/nordic_nrf/nrf52/Kconfig.series | 1 + soc/arm/nordic_nrf/nrf53/Kconfig.soc | 1 + soc/arm/nordic_nrf/nrf91/Kconfig.series | 1 + 6 files changed, 21 insertions(+) create mode 100644 soc/arm/nordic_nrf/common/poweroff.c diff --git a/soc/arm/nordic_nrf/common/CMakeLists.txt b/soc/arm/nordic_nrf/common/CMakeLists.txt index 941ccaea039d..eb074dd05481 100644 --- a/soc/arm/nordic_nrf/common/CMakeLists.txt +++ b/soc/arm/nordic_nrf/common/CMakeLists.txt @@ -2,6 +2,7 @@ # SPDX-License-Identifier: Apache-2.0 zephyr_library_sources_ifdef(CONFIG_SOC_FAMILY_NRF soc_nrf_common.S) +zephyr_library_sources_ifdef(CONFIG_POWEROFF poweroff.c) zephyr_include_directories(.) if (CONFIG_TFM_PARTITION_PLATFORM) diff --git a/soc/arm/nordic_nrf/common/poweroff.c b/soc/arm/nordic_nrf/common/poweroff.c new file mode 100644 index 000000000000..7474c94a74a1 --- /dev/null +++ b/soc/arm/nordic_nrf/common/poweroff.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#include + +void z_sys_poweroff(void) +{ + nrf_power_system_off(NRF_POWER); + + CODE_UNREACHABLE; +} diff --git a/soc/arm/nordic_nrf/nrf51/Kconfig.series b/soc/arm/nordic_nrf/nrf51/Kconfig.series index 632ec5792fca..ac972be24a43 100644 --- a/soc/arm/nordic_nrf/nrf51/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf51/Kconfig.series @@ -13,5 +13,6 @@ config SOC_SERIES_NRF51X select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_PM + select HAS_POWEROFF help Enable support for NRF51 MCU series diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.series b/soc/arm/nordic_nrf/nrf52/Kconfig.series index fc02e76a41b3..184d9d87d93f 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.series @@ -16,5 +16,6 @@ config SOC_SERIES_NRF52X select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_SWO select HAS_PM + select HAS_POWEROFF help Enable support for NRF52 MCU series diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index b72528e3aa31..33044a424f06 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -10,6 +10,7 @@ config SOC_NRF5340_CPUAPP select CPU_HAS_FPU select ARMV8_M_DSP select HAS_PM + select HAS_POWEROFF config SOC_NRF5340_CPUNET bool diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index 971855ef932e..37312832bdb1 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -17,5 +17,6 @@ config SOC_SERIES_NRF91X select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_PM + select HAS_POWEROFF help Enable support for NRF91 MCU series From 5bb00175b3794d3c0c72ae90df61379404f75f9d Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 20 Jul 2023 12:09:51 +0200 Subject: [PATCH 523/528] [nrf fromtree] samples: boards: nrf: system_off: use sys_poweroff Make use of the new sys_poweroff API to actually power off the system. This lets us remove many hacks present in the sample. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 37b26f40a6f671499c192a1ac30e32b633b3378f) --- samples/boards/nrf/system_off/prj.conf | 2 +- samples/boards/nrf/system_off/src/main.c | 35 ++---------------------- 2 files changed, 3 insertions(+), 34 deletions(-) diff --git a/samples/boards/nrf/system_off/prj.conf b/samples/boards/nrf/system_off/prj.conf index f32cffde85b6..a57c6919a1ec 100644 --- a/samples/boards/nrf/system_off/prj.conf +++ b/samples/boards/nrf/system_off/prj.conf @@ -1,7 +1,7 @@ -CONFIG_PM=y # Required to disable default behavior of deep sleep on timeout CONFIG_PM_DEVICE=y CONFIG_GPIO=y # Optional select RAM retention (nRF52 only) #CONFIG_APP_RETENTION=y CONFIG_CRC=y +CONFIG_POWEROFF=y diff --git a/samples/boards/nrf/system_off/src/main.c b/samples/boards/nrf/system_off/src/main.c index 31b41e69fcb9..6a2a34916021 100644 --- a/samples/boards/nrf/system_off/src/main.c +++ b/samples/boards/nrf/system_off/src/main.c @@ -7,10 +7,8 @@ #include #include #include -#include -#include #include -#include +#include #include #include "retained.h" #include @@ -18,21 +16,6 @@ #define BUSY_WAIT_S 2U #define SLEEP_S 2U -/* Prevent deep sleep (system off) from being entered on long timeouts - * or `K_FOREVER` due to the default residency policy. - * - * This has to be done before anything tries to sleep, which means - * before the threading system starts up. - */ -static int disable_ds_1(void) -{ - - pm_policy_state_lock_get(PM_STATE_SOFT_OFF, PM_ALL_SUBSTATES); - return 0; -} - -SYS_INIT(disable_ds_1, PRE_KERNEL_1, 99); - int main(void) { int rc; @@ -90,21 +73,7 @@ int main(void) retained_update(); } - /* Above we disabled entry to deep sleep based on duration of - * controlled delay. Here we need to override that, then - * force entry to deep sleep on any delay. - */ - pm_state_force(0u, &(struct pm_state_info){PM_STATE_SOFT_OFF, 0, 0}); + sys_poweroff(); - /* Now we need to go sleep. This will let the idle thread runs and - * the pm subsystem will use the forced state. To confirm that the - * forced state is used, lets set the same timeout used previously. - */ - k_sleep(K_SECONDS(SLEEP_S)); - - printk("ERROR: System off failed\n"); - while (true) { - /* spin to avoid fall-off behavior */ - } return 0; } From 15f47a61c5f5a136eb3e0ffd3a7769647cf9c9db Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 20 Jul 2023 12:35:59 +0200 Subject: [PATCH 524/528] [nrf fromtree] soc: arm: nordic_nrf: drop PM hooks Nordic SoCs do all power management automagically when going to idle (ie k_cpu_idle()). The only extra state, system off, is now handled via sys_shutdown(), so there's no need to support the PM subsystem. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit 96b38273138f05dd06cf7a58fa361f401e773e5e) --- soc/arm/nordic_nrf/Kconfig.defconfig | 3 -- soc/arm/nordic_nrf/nrf51/CMakeLists.txt | 4 -- soc/arm/nordic_nrf/nrf51/Kconfig.series | 1 - soc/arm/nordic_nrf/nrf51/power.c | 47 ------------------------ soc/arm/nordic_nrf/nrf52/CMakeLists.txt | 4 -- soc/arm/nordic_nrf/nrf52/Kconfig.series | 1 - soc/arm/nordic_nrf/nrf52/power.c | 47 ------------------------ soc/arm/nordic_nrf/nrf53/CMakeLists.txt | 4 -- soc/arm/nordic_nrf/nrf53/Kconfig.soc | 1 - soc/arm/nordic_nrf/nrf53/power.c | 49 ------------------------- soc/arm/nordic_nrf/nrf91/CMakeLists.txt | 4 -- soc/arm/nordic_nrf/nrf91/Kconfig.series | 1 - soc/arm/nordic_nrf/nrf91/power.c | 48 ------------------------ 13 files changed, 214 deletions(-) delete mode 100644 soc/arm/nordic_nrf/nrf51/power.c delete mode 100644 soc/arm/nordic_nrf/nrf52/power.c delete mode 100644 soc/arm/nordic_nrf/nrf53/power.c delete mode 100644 soc/arm/nordic_nrf/nrf91/power.c diff --git a/soc/arm/nordic_nrf/Kconfig.defconfig b/soc/arm/nordic_nrf/Kconfig.defconfig index 18ffeafe020d..3eedcf350c6c 100644 --- a/soc/arm/nordic_nrf/Kconfig.defconfig +++ b/soc/arm/nordic_nrf/Kconfig.defconfig @@ -28,9 +28,6 @@ config SYS_CLOCK_TICKS_PER_SEC config ARCH_HAS_CUSTOM_BUSY_WAIT default y if !QEMU_TARGET -config PM - default y if SYS_CLOCK_EXISTS && MULTITHREADING && HAS_PM - config BUILD_OUTPUT_HEX default y diff --git a/soc/arm/nordic_nrf/nrf51/CMakeLists.txt b/soc/arm/nordic_nrf/nrf51/CMakeLists.txt index 0f11eefca2e1..1a8b943ad5b3 100644 --- a/soc/arm/nordic_nrf/nrf51/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf51/CMakeLists.txt @@ -6,10 +6,6 @@ zephyr_library_sources( soc.c ) -zephyr_library_sources_ifdef(CONFIG_PM - power.c - ) - zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/arm/include diff --git a/soc/arm/nordic_nrf/nrf51/Kconfig.series b/soc/arm/nordic_nrf/nrf51/Kconfig.series index ac972be24a43..e7028b021909 100644 --- a/soc/arm/nordic_nrf/nrf51/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf51/Kconfig.series @@ -12,7 +12,6 @@ config SOC_SERIES_NRF51X select XIP select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE - select HAS_PM select HAS_POWEROFF help Enable support for NRF51 MCU series diff --git a/soc/arm/nordic_nrf/nrf51/power.c b/soc/arm/nordic_nrf/nrf51/power.c deleted file mode 100644 index 1f86bca17b8c..000000000000 --- a/soc/arm/nordic_nrf/nrf51/power.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include - -#include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); - -/* Invoke Low Power/System Off specific Tasks */ -void pm_state_set(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(substate_id); - - switch (state) { - case PM_STATE_SOFT_OFF: - nrf_power_system_off(NRF_POWER); - break; - default: - LOG_DBG("Unsupported power state %u", state); - break; - } -} - -/* Handle SOC specific activity after Low Power Mode Exit */ -void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(substate_id); - - switch (state) { - case PM_STATE_SOFT_OFF: - /* Nothing to do. */ - break; - default: - LOG_DBG("Unsupported power state %u", state); - break; - } - - /* - * System is now in active mode. Reenable interrupts which were disabled - * when OS started idling code. - */ - irq_unlock(0); -} diff --git a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt index c795df3947b3..559ce6a39797 100644 --- a/soc/arm/nordic_nrf/nrf52/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf52/CMakeLists.txt @@ -6,10 +6,6 @@ zephyr_library_sources( soc.c ) -zephyr_library_sources_ifdef(CONFIG_PM - power.c - ) - zephyr_library_include_directories( ${ZEPHYR_BASE}/kernel/include ${ZEPHYR_BASE}/arch/arm/include diff --git a/soc/arm/nordic_nrf/nrf52/Kconfig.series b/soc/arm/nordic_nrf/nrf52/Kconfig.series index 184d9d87d93f..f11bd5cd59f5 100644 --- a/soc/arm/nordic_nrf/nrf52/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf52/Kconfig.series @@ -15,7 +15,6 @@ config SOC_SERIES_NRF52X select HAS_NORDIC_DRIVERS select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE select HAS_SWO - select HAS_PM select HAS_POWEROFF help Enable support for NRF52 MCU series diff --git a/soc/arm/nordic_nrf/nrf52/power.c b/soc/arm/nordic_nrf/nrf52/power.c deleted file mode 100644 index 1f86bca17b8c..000000000000 --- a/soc/arm/nordic_nrf/nrf52/power.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation. - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include - -#include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); - -/* Invoke Low Power/System Off specific Tasks */ -void pm_state_set(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(substate_id); - - switch (state) { - case PM_STATE_SOFT_OFF: - nrf_power_system_off(NRF_POWER); - break; - default: - LOG_DBG("Unsupported power state %u", state); - break; - } -} - -/* Handle SOC specific activity after Low Power Mode Exit */ -void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(substate_id); - - switch (state) { - case PM_STATE_SOFT_OFF: - /* Nothing to do. */ - break; - default: - LOG_DBG("Unsupported power state %u", state); - break; - } - - /* - * System is now in active mode. Reenable interrupts which were disabled - * when OS started idling code. - */ - irq_unlock(0); -} diff --git a/soc/arm/nordic_nrf/nrf53/CMakeLists.txt b/soc/arm/nordic_nrf/nrf53/CMakeLists.txt index bb398c987a9c..af4fe549a635 100644 --- a/soc/arm/nordic_nrf/nrf53/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf53/CMakeLists.txt @@ -4,10 +4,6 @@ zephyr_sources( soc.c ) -zephyr_library_sources_ifdef(CONFIG_PM - power.c - ) - zephyr_library_sources_ifdef(CONFIG_NRF53_SYNC_RTC sync_rtc.c ) diff --git a/soc/arm/nordic_nrf/nrf53/Kconfig.soc b/soc/arm/nordic_nrf/nrf53/Kconfig.soc index 33044a424f06..122c36988e5d 100644 --- a/soc/arm/nordic_nrf/nrf53/Kconfig.soc +++ b/soc/arm/nordic_nrf/nrf53/Kconfig.soc @@ -9,7 +9,6 @@ config SOC_NRF5340_CPUAPP select CPU_HAS_NRF_IDAU select CPU_HAS_FPU select ARMV8_M_DSP - select HAS_PM select HAS_POWEROFF config SOC_NRF5340_CPUNET diff --git a/soc/arm/nordic_nrf/nrf53/power.c b/soc/arm/nordic_nrf/nrf53/power.c deleted file mode 100644 index 5e4f6080dd41..000000000000 --- a/soc/arm/nordic_nrf/nrf53/power.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation. - * Copyright (c) 2019 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include - -#include - -#include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); - -/* Invoke Low Power/System Off specific Tasks */ -void pm_state_set(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(substate_id); - - switch (state) { - case PM_STATE_SOFT_OFF: - nrf_regulators_system_off(NRF_REGULATORS); - break; - default: - LOG_DBG("Unsupported power state %u", state); - break; - } -} - -/* Handle SOC specific activity after Low Power Mode Exit */ -void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(substate_id); - - switch (state) { - case PM_STATE_SOFT_OFF: - /* Nothing to do. */ - break; - default: - LOG_DBG("Unsupported power state %u", state); - break; - } - - /* - * System is now in active mode. Reenable interrupts which were disabled - * when OS started idling code. - */ - irq_unlock(0); -} diff --git a/soc/arm/nordic_nrf/nrf91/CMakeLists.txt b/soc/arm/nordic_nrf/nrf91/CMakeLists.txt index c9799cf9ae6e..332416ba43b0 100644 --- a/soc/arm/nordic_nrf/nrf91/CMakeLists.txt +++ b/soc/arm/nordic_nrf/nrf91/CMakeLists.txt @@ -3,7 +3,3 @@ zephyr_sources( soc.c ) - -zephyr_library_sources_ifdef(CONFIG_PM - power.c - ) diff --git a/soc/arm/nordic_nrf/nrf91/Kconfig.series b/soc/arm/nordic_nrf/nrf91/Kconfig.series index 37312832bdb1..fd8f5b04d7ad 100644 --- a/soc/arm/nordic_nrf/nrf91/Kconfig.series +++ b/soc/arm/nordic_nrf/nrf91/Kconfig.series @@ -16,7 +16,6 @@ config SOC_SERIES_NRF91X select XIP select HAS_NRFX select HAS_SEGGER_RTT if ZEPHYR_SEGGER_MODULE - select HAS_PM select HAS_POWEROFF help Enable support for NRF91 MCU series diff --git a/soc/arm/nordic_nrf/nrf91/power.c b/soc/arm/nordic_nrf/nrf91/power.c deleted file mode 100644 index 44bcefbf1593..000000000000 --- a/soc/arm/nordic_nrf/nrf91/power.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation. - * Copyright (c) 2019 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: Apache-2.0 - */ -#include -#include -#include - -#include -LOG_MODULE_DECLARE(soc, CONFIG_SOC_LOG_LEVEL); - -/* Invoke Low Power/System Off specific Tasks */ -void pm_state_set(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(substate_id); - - switch (state) { - case PM_STATE_SOFT_OFF: - nrf_regulators_system_off(NRF_REGULATORS); - break; - default: - LOG_DBG("Unsupported power state %u", state); - break; - } -} - -/* Handle SOC specific activity after Low Power Mode Exit */ -void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) -{ - ARG_UNUSED(substate_id); - - switch (state) { - case PM_STATE_SOFT_OFF: - /* Nothing to do. */ - break; - default: - LOG_DBG("Unsupported power state %u", state); - break; - } - - /* - * System is now in active mode. Reenable interrupts which were disabled - * when OS started idling code. - */ - irq_unlock(0); -} From c7094146b5b47fd4da05ed773e0128e2e6a634e1 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 8 Aug 2023 15:17:45 +0200 Subject: [PATCH 525/528] [nrf fromtree] soc: arm: nordic_nrf: fix poweroff for nrf53/91 nRF53/91 require usage of nrf_regulators_system_off, so the API is not common with nRF51/52. This was an oversight during the conversion. Signed-off-by: Gerard Marull-Paretas (cherry picked from commit b990082befd3a4890c11465262eb897bd383c1e6) --- soc/arm/nordic_nrf/common/poweroff.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/soc/arm/nordic_nrf/common/poweroff.c b/soc/arm/nordic_nrf/common/poweroff.c index 7474c94a74a1..1c43da3e9eae 100644 --- a/soc/arm/nordic_nrf/common/poweroff.c +++ b/soc/arm/nordic_nrf/common/poweroff.c @@ -6,11 +6,19 @@ #include #include +#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) #include +#else +#include +#endif void z_sys_poweroff(void) { +#if defined(CONFIG_SOC_SERIES_NRF51X) || defined(CONFIG_SOC_SERIES_NRF52X) nrf_power_system_off(NRF_POWER); +#else + nrf_regulators_system_off(NRF_REGULATORS); +#endif CODE_UNREACHABLE; } From 72190c0624b754f2e01d94eaa2c60d6abea8e608 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Thu, 3 Aug 2023 01:10:37 +0530 Subject: [PATCH 526/528] libc: common: Add support for malloc stats If malloc is enabled in common libc, add support for malloc stats using the mallinfo API. Signed-off-by: Chaitanya Tata --- lib/libc/common/source/stdlib/malloc.c | 42 ++++++++++++++++++++++++++ lib/libc/minimal/include/malloc.h | 35 +++++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 lib/libc/minimal/include/malloc.h diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index 02354cd194dc..df2d425c0b7a 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -229,6 +230,38 @@ void free(void *ptr) (void) sys_mutex_unlock(&z_malloc_heap_mutex); } +#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 33) +struct mallinfo mallinfo(void) +#else +struct mallinfo2 mallinfo2(void) +#endif /* __GLIBC__ < 2 && (__GLIBC__ == 2 && __GLIBC_MINOR__ < 33) */ +{ +#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 33) + struct mallinfo info = { 0 }; +#else + struct mallinfo2 info = { 0 }; +#endif /* __GLIBC__ < 2 && (__GLIBC__ == 2 && __GLIBC_MINOR__ < 33) */ +#ifdef CONFIG_SYS_HEAP_RUNTIME_STATS + struct sys_memory_stats stats; + int ret = sys_heap_runtime_stats_get(&z_malloc_heap, &stats); + + if (ret != 0) { + LOG_ERR("Failed to get heap stats"); + return info; + } + + info.arena = stats.free_bytes + stats.allocated_bytes; + info.fordblks = stats.free_bytes; + info.uordblks = stats.allocated_bytes; + info.usmblks = stats.max_allocated_bytes; +#else + ARG_UNUSED(info); + LOG_ERR("CONFIG_SYS_HEAP_RUNTIME_STATS is not enabled"); +#endif + + return info; +} + SYS_INIT(malloc_prepare, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #else /* No malloc arena */ void *malloc(size_t size) @@ -251,6 +284,15 @@ void *realloc(void *ptr, size_t size) ARG_UNUSED(ptr); return malloc(size); } + +struct mallinfo2 mallinfo2(void) +{ + struct mallinfo2 info = { 0 }; + + LOG_ERR("CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE is 0"); + + return info; +} #endif /* else no malloc arena */ #endif /* CONFIG_COMMON_LIBC_MALLOC */ diff --git a/lib/libc/minimal/include/malloc.h b/lib/libc/minimal/include/malloc.h new file mode 100644 index 000000000000..7556d2fd19c3 --- /dev/null +++ b/lib/libc/minimal/include/malloc.h @@ -0,0 +1,35 @@ +/* malloc.h */ + +/* + * Copyright (c) 2023 - Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_MALLOC_H_ +#define ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_MALLOC_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct mallinfo2 { + size_t arena; /* total space allocated from system */ + size_t ordblks; /* number of non-inuse chunks */ + size_t smblks; /* unused -- always zero */ + size_t hblks; /* number of mmapped regions */ + size_t hblkhd; /* total space in mmapped regions */ + size_t usmblks; /* unused -- always zero */ + size_t fsmblks; /* unused -- always zero */ + size_t uordblks; /* total allocated space */ + size_t fordblks; /* total non-inuse space */ + size_t keepcost; /* top-most, releasable (via malloc_trim) space */ +}; + +struct mallinfo2 mallinfo2(void); + +#ifdef __cplusplus +} +#endif +#endif /* ZEPHYR_LIB_LIBC_MINIMAL_INCLUDE_MALLOC_H_ */ From 24bb6b9628abad02ea15dbbb66b6e4d0561a832c Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Wed, 12 Jul 2023 00:23:50 +0530 Subject: [PATCH 527/528] libc: Add shell support This is useful as a placeholder for all commands common to applications. For now we start with malloc stats, useful in debugging HEAP issues. Signed-off-by: Chaitanya Tata --- doc/releases/release-notes-3.5.rst | 52 +++++++++++++++++++++++++++++ subsys/shell/modules/CMakeLists.txt | 4 +++ subsys/shell/modules/Kconfig | 6 ++++ subsys/shell/modules/app_service.c | 44 ++++++++++++++++++++++++ 4 files changed, 106 insertions(+) create mode 100644 subsys/shell/modules/app_service.c diff --git a/doc/releases/release-notes-3.5.rst b/doc/releases/release-notes-3.5.rst index c532ff873e5c..900908b533d8 100644 --- a/doc/releases/release-notes-3.5.rst +++ b/doc/releases/release-notes-3.5.rst @@ -232,6 +232,58 @@ Devicetree Libraries / Subsystems ********************** +* Management + + * Introduced MCUmgr client support with handlers for img_mgmt and os_mgmt. + + * Added response checking to MCUmgr's :c:enumerator:`MGMT_EVT_OP_CMD_RECV` + notification callback to allow applications to reject MCUmgr commands. + + * MCUmgr SMP version 2 error translation (to legacy MCUmgr error code) is now + supported in function handlers by setting ``mg_translate_error`` of + :c:struct:`mgmt_group` when registering a transport. See + :c:type:`smp_translate_error_fn` for function details. +* shell + + * Added an application shell module with helpers common to all applications. + + * Fixed an issue with MCUmgr img_mgmt group whereby the size of the upload in + the initial packet was not checked. + + * Fixed an issue with MCUmgr fs_mgmt group whereby some status codes were not + checked properly, this meant that the error returned might not be the + correct error, but would only occur in situations where an error was + already present. + + * Fixed an issue whereby the SMP response function did not check to see if + the initial zcbor map was created successfully. + + * Fixes an issue with MCUmgr shell_mgmt group whereby the length of a + received command was not properly checked. + + * Added optional mutex locking support to MCUmgr img_mgmt group, which can + be enabled with :kconfig:option:`CONFIG_MCUMGR_GRP_IMG_MUTEX`. + + * Added MCUmgr settings management group, which allows for manipulation of + zephyr settings from a remote device, see :ref:`mcumgr_smp_group_3` for + details. + + * Added :kconfig:option:`CONFIG_MCUMGR_GRP_IMG_ALLOW_CONFIRM_NON_ACTIVE_IMAGE_SECONDARY` + and :kconfig:option:`CONFIG_MCUMGR_GRP_IMG_ALLOW_CONFIRM_NON_ACTIVE_IMAGE_ANY` + that allow to control whether MCUmgr client will be allowed to confirm + non-active images. + + * Added :kconfig:option:`CONFIG_MCUMGR_GRP_IMG_ALLOW_ERASE_PENDING` that allows + to erase slots pending for next boot, that are not revert slots. + +* File systems + + * Added support for ext2 file system. + * Added support of mounting littlefs on the block device from the shell/fs. + * Added alignment parameter to FS_LITTLEFS_DECLARE_CUSTOM_CONFIG macro, it can speed up read/write + operation for SDMMC devices in case when we align buffers on CONFIG_SDHC_BUFFER_ALIGNMENT, + because we can avoid extra copy of data from card bffer to read/prog buffer. + HALs **** diff --git a/subsys/shell/modules/CMakeLists.txt b/subsys/shell/modules/CMakeLists.txt index d002604c6ae0..e5d025956d53 100644 --- a/subsys/shell/modules/CMakeLists.txt +++ b/subsys/shell/modules/CMakeLists.txt @@ -16,3 +16,7 @@ zephyr_sources_ifdef( CONFIG_DEVMEM_SHELL devmem_service.c ) +zephyr_sources_ifdef( + CONFIG_APP_SHELL + app_service.c + ) diff --git a/subsys/shell/modules/Kconfig b/subsys/shell/modules/Kconfig index cb7aedaa79e5..7bb28d80f141 100644 --- a/subsys/shell/modules/Kconfig +++ b/subsys/shell/modules/Kconfig @@ -45,3 +45,9 @@ config DEVMEM_SHELL select GETOPT help This shell command provides read/write access to physical memory. + +config APP_SHELL + bool "application shell (common to all applications)" + default y if !SHELL_MINIMAL + help + This shell module provides access to common helpers. diff --git a/subsys/shell/modules/app_service.c b/subsys/shell/modules/app_service.c new file mode 100644 index 000000000000..8938ff5a944e --- /dev/null +++ b/subsys/shell/modules/app_service.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#if defined(CONFIG_LOG_RUNTIME_FILTERING) +#include +#endif + +#include + +static int cmd_app_heap(const struct shell *sh, size_t argc, char **argv) +{ +#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 33) + /* mallinfo() was deprecated in glibc 2.33 and removed in 2.34. */ + struct mallinfo mi = mallinfo(); +#else + struct mallinfo2 mi = mallinfo2(); +#endif /* __GLIBC__ < 2 && (__GLIBC__ == 2 && __GLIBC_MINOR__ < 33) */ + + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + shell_print(sh, "Heap size: %d bytes", mi.arena); + shell_print(sh, " used: %d bytes", mi.uordblks); + shell_print(sh, " free: %d bytes", mi.fordblks); + shell_print(sh, " max used: %d bytes", mi.usmblks); + shell_print(sh, " free fastbin: %d bytes", mi.fsmblks); + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_app, + SHELL_CMD(heap, NULL, "app heap", cmd_app_heap), + SHELL_SUBCMD_SET_END /* Array terminated. */ +); + +SHELL_CMD_REGISTER(app, &sub_app, "application commands", NULL); From d0f31a49c1f6fae30f846ff34f2129a0c818d871 Mon Sep 17 00:00:00 2001 From: Chaitanya Tata Date: Mon, 4 Sep 2023 00:09:00 +0530 Subject: [PATCH 528/528] tests: c_lib: Add tests for mallinfo2 This adds basic tests in a single testcase to verify the functionality of mallinfo2. Signed-off-by: Chaitanya Tata --- tests/lib/c_lib/src/main.c | 55 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/lib/c_lib/src/main.c b/tests/lib/c_lib/src/main.c index f5365d493ea8..d824ed657875 100644 --- a/tests/lib/c_lib/src/main.c +++ b/tests/lib/c_lib/src/main.c @@ -1194,6 +1194,61 @@ ZTEST(test_c_lib, test_rand_reproducibility) #endif } +/** + * @brief Test mallinfo2 function + * +*/ +ZTEST(test_c_lib, test_mallinfo2) +{ +#ifdef CONFIG_MINIMAL_LIBC + struct mallinfo2 info; + + info = mallinfo2(); + zassert_equal(info.arena, 0, "mallinfo2 failed"); + zassert_equal(info.ordblks, 0, "mallinfo2 failed"); + zassert_equal(info.smblks, 0, "mallinfo2 failed"); + zassert_equal(info.hblks, 0, "mallinfo2 failed"); + zassert_equal(info.hblkhd, 0, "mallinfo2 failed"); + zassert_equal(info.usmblks, 0, "mallinfo2 failed"); + zassert_equal(info.fsmblks, 0, "mallinfo2 failed"); + zassert_equal(info.uordblks, 0, "mallinfo2 failed"); + zassert_equal(info.fordblks, 0, "mallinfo2 failed"); + zassert_equal(info.keepcost, 0, "mallinfo2 failed"); + + /* Allocate and verify */ + char *ptr = malloc(10); + zassert_not_null(ptr, "malloc failed"); + info = mallinfo2(); + zassert_equal(info.arena, 4096, "mallinfo2 failed"); + zassert_equal(info.ordblks, 1, "mallinfo2 failed"); + zassert_equal(info.smblks, 0, "mallinfo2 failed"); + zassert_equal(info.hblks, 0, "mallinfo2 failed"); + zassert_equal(info.hblkhd, 4096, "mallinfo2 failed"); + zassert_equal(info.usmblks, 0, "mallinfo2 failed"); + zassert_equal(info.fsmblks, 0, "mallinfo2 failed"); + zassert_equal(info.uordblks, 0, "mallinfo2 failed"); + zassert_equal(info.fordblks, 4086, "mallinfo2 failed"); + zassert_equal(info.keepcost, 10, "mallinfo2 failed"); + + /* Free and verify */ + free(ptr); + info = mallinfo2(); + zassert_equal(info.arena, 4096, "mallinfo2 failed"); + zassert_equal(info.ordblks, 0, "mallinfo2 failed"); + zassert_equal(info.smblks, 0, "mallinfo2 failed"); + zassert_equal(info.hblks, 0, "mallinfo2 failed"); + zassert_equal(info.hblkhd, 4096, "mallinfo2 failed"); + zassert_equal(info.usmblks, 0, "mallinfo2 failed"); + zassert_equal(info.fsmblks, 0, "mallinfo2 failed"); + zassert_equal(info.uordblks, 0, "mallinfo2 failed"); + zassert_equal(info.fordblks, 4096, "mallinfo2 failed"); + zassert_equal(info.keepcost, 0, "mallinfo2 failed"); +#else + ztest_test_skip(); +#endif /* CONFIG_MINIMAL_LIBC */ +} + + /** * * @brief test abort functions