From 15df23050d6857d06507296137475970e6bac077 Mon Sep 17 00:00:00 2001 From: jenia81 Date: Mon, 21 Nov 2022 18:38:57 +0200 Subject: [PATCH] mbed-cloud-client-example 4.13.0 --- CHANGELOG.md | 27 ++- CONTRIBUTING.md | 4 +- Makefile | 164 ------------- README.md | 175 +------------- define-rpi3-yocto.txt | 2 + define.txt | 3 + define_linux_psa.txt | 6 +- define_lwm2m_compliant.txt | 1 - main.cpp | 3 +- mbed-cloud-client.lib | 2 +- mbed_app_lwm2m_compliant.json | 28 ++- mbed_cloud_client_user_config.h | 17 ++ pal-platform/SDK/ZephyrOS/CMakeLists.txt | 6 +- pal-platform/SDK/ZephyrOS/Kconfig | 10 +- pal-platform/SDK/ZephyrOS/README.txt | 48 ++-- .../SDK/ZephyrOS/boards/frdm_k64f.overlay | 4 +- pal-platform/SDK/ZephyrOS/prj.conf | 26 +- pal-platform/pal-platform.json | 28 +-- pal_config_MbedOS.h | 2 +- pal_config_MbedOS_LWM2M_Compliant.h | 2 +- pal_config_Renesas_RA.h | 1 + pal_config_Renesas_RX65N-CK.h | 1 + pal_config_non_trng_MbedOS.h | 1 + ...ction-to-standard-lwm2m-server-tutorial.md | 167 +++++++++++++ pdmc-migration-tutorial.md | 44 ++++ psa_storage_user_config.h | 1 + requirements.txt | 4 +- sotp_fs_config_ARIA_linux.h | 30 --- sotp_fs_config_MbedOS.h | 2 + sotp_fs_config_linux.h | 2 + sotp_fs_config_linux_lwm2m_compliant.h | 6 +- source/application_init.cpp | 19 +- source/migrate_kvstore.cpp | 226 ++++++++++++++++++ source/migrate_kvstore.h | 43 ++++ ...o_l496ag-internal_kvstore-qspif-v4.1.3.bin | Bin 0 -> 35492 bytes update_ui_example.cpp | 1 + update_ui_example.h | 1 + utils/LICENSE | 201 ++++++++++++++++ utils/cert_convert.py | 7 - utils/cnvfile2hex.py | 162 +++++++++++++ utils/dev_init.py | 2 +- utils/gen_update_image.py | 66 +++++ west.yml | 10 +- 43 files changed, 1099 insertions(+), 456 deletions(-) delete mode 100644 Makefile create mode 100644 pdmc-connection-to-standard-lwm2m-server-tutorial.md create mode 100644 pdmc-migration-tutorial.md delete mode 100644 sotp_fs_config_ARIA_linux.h create mode 100644 source/migrate_kvstore.cpp create mode 100644 source/migrate_kvstore.h create mode 100755 tools/mbed-bootloader-disco_l496ag-internal_kvstore-qspif-v4.1.3.bin create mode 100644 utils/LICENSE create mode 100755 utils/cnvfile2hex.py create mode 100755 utils/gen_update_image.py diff --git a/CHANGELOG.md b/CHANGELOG.md index d3a6188..a618085 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,27 @@ -# Changelog for Pelion Device Management Client example application +# Changelog for Izuma Device Management Client example application + +## Release 4.13.0 (21.11.2022) + +- [Mbed OS] Add DISCO_L496AG board. The cellular settings are for example use only. +- Enable EST flow for `LWM2M_COMPLIANT` mode. +- Enable server certificate verification in `LWM2M_COMPLIANT` mode. +- [Mbed OS] New feature for migrating the boostrap server URI to another URI. + * This allows moving a device from one Device Management region to another, for example from US to EU. + * Works only with KVStore based storage. + * More details in [PDMC Migration Tutorial](pdmc-migration-tutorial.md) document. +- Updated `libcurl` from 7.76.0 to 7.85.0 for Linux targets. +- Updated `mbedTLS` from 2.27.0 to 2.28.1 for Linux targets. +- Branding changes to Izuma. +- Add following files to `.gitignore`: + * `mbed_cloud_client_user_config.h` + * `mbed_cloud_dev_credentials.c` and + * `update_default_resources.c` to minimize risk of leaking credentials/private configs. + * You can still update these files if you wish, but you have to use `git add -f`. +- Zephyr OS updated to 2.7.3. +- Alternating port fallback config example for `MBED_CLOUD_CLIENT_CUSTOM_URI_PORT` added to `mbed_cloud_client_user_config.h`. + * If a socket error is encountered, next try will be done with original CoaP port `5684`. + * After 2nd fail we alternate back to custom port. + * NOTE! Only port 443 can be used as a alternative customer port with Izuma Networks. ## Release 4.12.0 (01.03.2022) @@ -258,7 +281,7 @@ No changes. * Change the target offsets to match the `block_device` bootloader. * Change the update storage to point to the external storage. * Change the KVstore configuration to match the external storage configuration. - * See the [porting guide](https://www.pelion.com/docs/device-management/current/porting/index.html) for reference. + * See the [porting guide](https://developer.izumanetworks.com/docs/device-management/current/porting/index.html) for reference. * K66F default configuration now provides the full Client feature. This target enables all the RAM/ROM intensive features by default. * Enabled certificate enrollment client features. * Increased the main stack size to reflect higher RAM requirements for features. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 49a221b..3b0a13a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ -# Contributions to Pelion Device Management Client Example +# Contributions to Izuma Device Management Client Example -Pelion Device Management Client is Apache 2.0 licensed open source software. We accept contributions from 3rd parties, if they agree to submit their changes with Apache 2.0 licensing. Arm will review all contributions and possibly make some modifications before merging them. +Izuma Device Management Client is Apache 2.0 licensed open source software. We accept contributions from 3rd parties, if they agree to submit their changes with Apache 2.0 licensing. Izuma will review all contributions and possibly make some modifications before merging them. Due to the release process, all new releases are squashed code drops. Therefore, we cannot provide the full Git commit history in the releases. diff --git a/Makefile b/Makefile deleted file mode 100644 index 8a397a7..0000000 --- a/Makefile +++ /dev/null @@ -1,164 +0,0 @@ -## ---------------------------------------------------------------------------- -## Copyright 2016-2018 ARM Ltd. -## -## SPDX-License-Identifier: Apache-2.0 -## -## Licensed under the Apache License, Version 2.0 (the "License"); -## you may not use this file except in compliance with the License. -## You may obtain a copy of the License at -## -## http://www.apache.org/licenses/LICENSE-2.0 -## -## Unless required by applicable law or agreed to in writing, software -## distributed under the License is distributed on an "AS IS" BASIS, -## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -## See the License for the specific language governing permissions and -## limitations under the License. -## ---------------------------------------------------------------------------- - -## This makefile is only for SX OS platform - -## ----------------------------------------------------------- ## -## Don't touch the next line unless you know what you're doing.## -## ----------------------------------------------------------- ## -include ${SOFT_WORKDIR}/env/compilation/compilevars.mk - -export MBED_CLOUD_SERVICE = ${EXTERNAL_APP_FOLDER} - -# Name of the module -LOCAL_NAME := ${MBED_CLOUD_SERVICE} - -# list all modules APIs that are necessary to compile this module -LOCAL_API_DEPENDS := \ - ${LOCAL_NAME}/mbed-cloud-client \ - platform/service/posix \ - ${API_PLATFORM_DEPENDS} \ - -LOCAL_ADD_INCLUDE += . \ - ${LOCAL_NAME} \ - ${LOCAL_NAME}/source \ - ${LOCAL_NAME}/source/include \ - ${LOCAL_NAME}/source/platform/include \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/key-config-manager/source/include \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/key-config-manager/key-config-manager \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/factory-configurator-client/factory-configurator-client \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/fcc-output-info-handler/fcc-output-info-handler \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/fcc-bundle-handler/fcc-bundle-handler \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/storage/storage \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/mbed-client-esfs/source/include \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/crypto-service/crypto-service \ - ${LOCAL_NAME}/mbed-cloud-client/factory-configurator-client/mbed-trace-helper/mbed-trace-helper \ - ${LOCAL_NAME}/mbed-cloud-client \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-client \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-client/mbed-client \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-trace \ - ${LOCAL_NAME}/mbed-cloud-client/source \ - ${LOCAL_NAME}/mbed-cloud-client/ns-hal-pal \ - ${LOCAL_NAME}/mbed-cloud-client/nanostack-libservice/mbed-client-libservice \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-client-pal/Source \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-client-pal/Source/PAL-Impl/Services-API \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-client-pal/Configs/pal_config \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-client-pal/Configs/pal_config/SXOS \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-client/mbed-client-c \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-coap/mbed-coap \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-client-randlib \ - ${LOCAL_NAME}/mbed-cloud-client/nanostack-libservice \ - ${LOCAL_NAME}/mbed-cloud-client/sal-stack-nanostack-eventloop \ - ${LOCAL_NAME}/mbed-cloud-client/sal-stack-nanostack-eventloop/nanostack-event-loop \ - ${LOCAL_NAME}/mbed-cloud-client/certificate-enrollment-client/certificate-enrollment-client \ - ${LOCAL_NAME}/mbed-cloud-client/update-client-hub \ - ${LOCAL_NAME}/mbed-cloud-client/update-client-hub/modules/common \ - ${LOCAL_NAME}/mbed-cloud-client/mbed-cloud-client \ - ${LOCAL_NAME}/mbed-cloud-client/fota \ - -LOCAL_EXPORT_FLAG += __SXOS__ - -LOCAL_EXPORT_FLAG += "'PAL_USER_DEFINED_CONFIGURATION=\"SXOS/sxos_sotp.h\"'" -LOCAL_EXPORT_FLAG += "'MBED_CLOUD_CLIENT_USER_CONFIG_FILE=\"mbed_cloud_client_user_config.h\"'" - -LOCAL_EXPORT_FLAG += "'MBED_CONF_MBED_CLIENT_EVENT_LOOP_SIZE=12000'" -LOCAL_EXPORT_FLAG += "PAL_SIMULATOR_FLASH_OVER_FILE_SYSTEM=1" -LOCAL_EXPORT_FLAG += "MBED_CONF_APP_CLOUD_MODE=1" -LOCAL_EXPORT_FLAG += "MBED_CONF_APP_DEVELOPER_MODE=1" -LOCAL_EXPORT_FLAG += "MBED_CLOUD_CLIENT_SUPPORT_UPDATE" -LOCAL_EXPORT_FLAG += "MBED_CLOUD_CLIENT_UPDATE_BUFFER=2048" -LOCAL_EXPORT_FLAG += "MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP_QUEUE" - -# not yet -LOCAL_EXPORT_FLAG += "MBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT=1" - -# Disable code using STL as it not available on SDK -LOCAL_EXPORT_FLAG += "MBED_CLOUD_CLIENT_STL_API=0" -LOCAL_EXPORT_FLAG += "MBED_CLOUD_CLIENT_STD_NAMESPACE_POLLUTION=0" - -# Compile the sub-modules, except when the "service" must be used as a library. -# list all the modules that need to be compiled prior to using this module - -LOCAL_MODULE_DEPENDS += \ - ${LOCAL_NAME}/mbed-cloud-client \ - -# One can compile and run the PAL unit tests instead of example-app -# by "PAL_UNIT_TESTING=1 ctmake CT_PRODUCT=20180930 dbmerge -j" command. -# -# By default, the example app itself is built. By having the PAL tests in -# same makefile, one can easily be sure the configuration is the same and -# the changes in PAL during porting can be tested by its own unit tests and -# then running the example itself. -ifndef PAL_UNIT_TESTING - -# this enables the mbed_cloud_application_entrypoint(void) from main.cpp -LOCAL_EXPORT_FLAG += MBED_CLOUD_APPLICATION_NONSTANDARD_ENTRYPOINT - -else -# the PAL tests have mbed_cloud_application_entrypoint(void) too, which is enabled -# from pal_tests_nonstandard_entrypoint.c by PAL_UNIT_TESTING_NONSTANDARD_ENTRYPOINT. -LOCAL_EXPORT_FLAG += "PAL_UNIT_TESTING_NONSTANDARD_ENTRYPOINT" - -# the PAL tests can be run one suite at a time by defining PAL_UNIT_TEST_ flag -# or all suites by omitting said flags and only giving PAL_UNIT_TESTING flag. -# here, export all PAL_UNIT_TEST_* -flags to enable the singe suite testing feature -$(foreach v, $(filter PAL_UNIT_TEST_%,$(.VARIABLES)), $(eval LOCAL_EXPORT_FLAG += "$(v)=$($(v))")) - -# build the tests -LOCAL_MODULE_DEPENDS += ${LOCAL_NAME}/mbed-cloud-client/mbed-client-pal/Test - -# These are needed for building PAL SOTP tests. Note: the flag is renamed on yet-to-be-merged -# version of esfs without backwards compatibility, so we need to have both here for some time. -LOCAL_EXPORT_FLAG += "SOTP_TESTING" -LOCAL_EXPORT_FLAG += "RBP_TESTING" -endif - -ifdef RESET_STORAGE -LOCAL_EXPORT_FLAG += "RESET_STORAGE=1" -endif - -# Generate the revision (version) file automatically during the make process. -AUTO_GEN_REVISION_HEADER := no - -# This is a top-level module -IS_TOP_LEVEL := yes - -# Generates the CoolWatcher headers automatically. -AUTO_XMD2H ?= no - -# code is not in one "src/" directory as SDK expects by default -USE_DIFFERENT_SOURCE_LAYOUT := yes -USE_DIFFERENT_SOURCE_LAYOUT_ARM := yes - -C_SRC := ${wildcard *.c} -C++_SRC := ${wildcard *.cpp} - -C_SRC += ${wildcard source/*.c} -C++_SRC += ${wildcard source/*.cpp} - -C_SRC += ${wildcard source/platform/SXOS/*.c} -C++_SRC += ${wildcard source/platform/SXOS/*.cpp} - -C_SRC += ${wildcard mbed-cloud-client/mbed-trace/source/*.c} -C_SRC += ${wildcard mbed-cloud-client/nanostack-libservice/source/libip6string/*.c} - - -## ------------------------------------- ## -## Do Not touch below this line ## -## ------------------------------------- ## -include ${SOFT_WORKDIR}/env/compilation/compilerules.mk diff --git a/README.md b/README.md index 5f7b4cb..bf3507e 100644 --- a/README.md +++ b/README.md @@ -1,177 +1,12 @@ # Device Management Client reference application for connectivity -The [`mbed-cloud-client-example`](https://github.com/PelionIoT/mbed-cloud-client-example) is a reference application that uses [Pelion Device Management Client library](https://github.com/PelionIoT/mbed-cloud-client) and demonstrates how to build a connectivity application. +The [`mbed-cloud-client-example`](https://github.com/PelionIoT/mbed-cloud-client-example) is a reference application that uses [Izuma Device Management Client library](https://github.com/PelionIoT/mbed-cloud-client) and demonstrates how to build a connectivity application. -## Device Management Client connection tutorial +This readme offers tutorial for: +1. [Device Management Client connection to a standard OMA LwM2M server tutorial.](pdmc-connection-to-standard-lwm2m-server-tutorial.md) +2. [Device Management Client migration tutorial.](pdmc-migration-tutorial.md) -This tutorial builds and flashes a Device Management Client application using either Linux (running on a PC) or Mbed OS. -The application can then connect to a standard OMA Lightweight M2M server. -The application uses developer mode that relies on a developer certificate, which you add to your software binary to allow test devices to connect to the server. -In the production, you should use the factory flow. - -### Linux - -#### Requirements - -This requires a Linux PC (64-bit Ubuntu/XUbuntu OS desktop environment). -See also the [Mbed CLI instructions](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html). - -#### Connecting the device - -1. Open a terminal, and clone the example repository to a convenient location on your development environment: - - ``` - git clone https://github.com/PelionIoT/mbed-cloud-client-example - cd mbed-cloud-client-example - ``` - - **Note:** If you want to speed up `mbed deploy`, you can remove components that are unnecessary for Linux, such as `mbed-os.lib` and the `drivers/` folder. - -2. Deploy the example repository: - - ``` - mbed deploy - ``` - -3. [Create a developer certificate](#create-developer-cert). - -4. Copy the `mbed_cloud_dev_credentials.c` file to the root folder of the example. - -5. Deploy Linux dependencies: - - ``` - python pal-platform/pal-platform.py deploy --target=x86_x64_NativeLinux_mbedtls generate - cd __x86_x64_NativeLinux_mbedtls - ``` - **Note: python2 is needed for the above command** - -6. Generate `cmake` files based on your configuration and build profile (**Release** or **Debug**): - - - For the **Release** profile: - ``` - cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./../pal-platform/Toolchain/GCC/GCC.cmake -DEXTERNAL_DEFINE_FILE=./../define_lwm2m_compliant.txt - ``` - - - For the **Debug** profile: - ``` - cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=./../pal-platform/Toolchain/GCC/GCC.cmake -DEXTERNAL_DEFINE_FILE=./../define_lwm2m_compliant.txt - ``` - - If you want your application to bypass the Bootstrap server and work directly with LwM2M server, please add `DISABLE_BOOTSTRAP` cmake flag: - ``` - cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DDISABLE_BOOTSTRAP=ON -DCMAKE_TOOLCHAIN_FILE=./../pal-platform/Toolchain/GCC/GCC.cmake -DEXTERNAL_DEFINE_FILE=./../define_lwm2m_compliant.txt - ``` - -7. Compile the application: - - ``` - make mbedCloudClientExample.elf - ``` - -8. The build creates binaries under `mbed-cloud-client-example/__x86_x64_NativeLinux_mbedtls`. In both cases, there are subdirectories `Debug` and `Release` respectively created for the two profiles. - -9. Run the application (at the respective path, see above): - - ``` - ./mbedCloudClientExample.elf - ``` - - You should see a message when the device connects to LwM2M server: - - ``` - Client registered - Endpoint Name: - Device Id: - ``` -10. If you want to run the application with a clean storage, you can remove the `pal` folder that is created in the location where you run your application. - - -### Mbed OS - -#### Prerequisites - -To work with the Device Management Client example application, you need: - -* A supported board with a network connection and an SD card attached. Currently FRDM K64F and NUCLEO F429ZI boards are supported. -* [Serial connection](https://os.mbed.com/docs/latest/tutorials/serial-comm.html) to your device with open terminal connection (baud rate 115200, 8N1). -* [Arm Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/tools/index.html) installed. See [installation instructions](https://os.mbed.com/docs/latest/tools/installation-and-setup.html). - * Make sure that all the Python components are in par with the `pip` package [requirements.txt](https://github.com/PelionIoT/mbed-os/blob/master/requirements.txt) list from Mbed OS. -* Updated [DAPLink](https://github.com/ARMmbed/DAPLink/releases) software (version 250 or later), if your board uses DAPLink. - -#### Connecting the device - -1. Clone the embedded application's GitHub repository to your local computer and navigate to the new folder: - - ``` - mbed import https://github.com/PelionIoT/mbed-cloud-client-example - cd mbed-cloud-client-example - ``` - -2. Configure Mbed CLI to use your board: - - ``` - mbed target - mbed toolchain GCC_ARM - ``` - -3. [Create a developer certificate](#create-developer-cert). - -4. Copy the `mbed_cloud_dev_credentials.c` file to the root folder of the example application. - -5. Configure the example application: - 1. If you want your application to bypass the Bootstrap server and work directly with LwM2M server, - please set the `disable-bootstrap-feature` feature to `true` in [mbed_app_lwm2m_compliant.json](https://github.com/PelionIoT/mbed-cloud-client-example/blob/master/mbed_app_lwm2m_compliant.json#L21). - - ``` - mbed-client.disable-bootstrap-feature: true - ``` - - 2. Currently, the application will always start with a clean storage. - If you want to avoid this, remove the `RESET_STORAGE` from the `"target.macros_add"` line in the `mbed_app_lwm2m_compliant.json`: - - ``` - "target.macros_add" : ["LWM2M_COMPLIANT","DISABLE_SERVER_CERT_VERIFY"], - ``` - -7. Compile the example application: - - ``` - mbed compile --app-config mbed_app_lwm2m_compliant.json - ``` - For more information about Mbed CLI parameters, please see the [Mbed OS documentation site](https://os.mbed.com/docs/mbed-os/latest/build-tools/mbed-cli-1.html). - -8. Flash the binary to the device - 1. Connect the device to your computer over USB. It's listed as a mass storage device. - 2. Drag and drop `mbed-cloud-client-example.bin` to the device, or alternatively add the `-f` flag to the build command (if your device is connected to the build machine). This flashes the binary to the device. You should see the LED blink rapidly; wait for it to stop. - -9. Press the **Reset** button to restart the device and reset the terminal. -10. When the client has successfully connected, the terminal shows: - - ``` - Client registered - Endpoint Name: - Device ID: - ``` - -

Create a developer certificate

- -1. Download the server CA certificate from the LwM2M service you want to connect to and copy it to the scripts' folder: - - ``` - cp utils/server_ca_cert.der - ``` - -2. Run the python script `cert_convert.py` to generate a `mbed_cloud_dev_credentials.c` file. - - ``` - cd utils - python cert_convert.py --endpoint --uri --use-ca - ``` - - The script will do the following steps: - 1. Generate a root CA key and certificate on the first time the script is running. All CA outputs are stored in `CA` folder. - 1. Generate a private key and a certificate signed by this CA. - 1. Convert the private key, certificate and the server certificate to a C file. - 1. All non CA outputs are stored in a folder named `YOUR_ENDPOINT_NAME`. +More documentation in: https://developer.izumanetworks.com diff --git a/define-rpi3-yocto.txt b/define-rpi3-yocto.txt index 4641119..b100b75 100644 --- a/define-rpi3-yocto.txt +++ b/define-rpi3-yocto.txt @@ -11,4 +11,6 @@ add_definitions(-DMBED_CLOUD_CLIENT_FOTA_LINUX_UPDATE_STORAGE_FILENAME="\\"/mnt/ add_definitions(-DMBED_CLOUD_CLIENT_FOTA_LINUX_CANDIDATE_FILENAME="\\"/mnt/cache/fota_raw_candidate\\"") add_definitions(-DMBED_CLOUD_CLIENT_FOTA_LINUX_HEADER_FILENAME="\\"/mnt/cache/fota_fw_metadata\\"") +# curl fix - https://github.com/curl/curl/issues/7988 +set (CURL_USE_OPENSSL OFF CACHE BOOL "disable openssl" FORCE) diff --git a/define.txt b/define.txt index 57d767c..979d150 100644 --- a/define.txt +++ b/define.txt @@ -59,3 +59,6 @@ add_definitions(-DFOTA_DEFAULT_APP_IFS=1) add_definitions(-DTARGET_LIKE_LINUX=1) add_definitions(-DFOTA_CUSTOM_PLATFORM=1) add_definitions(-DMBED_CLOUD_CLIENT_FOTA_SUB_COMPONENT_SUPPORT=1) + +# curl fix - https://github.com/curl/curl/issues/7988 +set (CURL_USE_OPENSSL OFF CACHE BOOL "disable openssl" FORCE) diff --git a/define_linux_psa.txt b/define_linux_psa.txt index f3751ee..17455e1 100644 --- a/define_linux_psa.txt +++ b/define_linux_psa.txt @@ -20,4 +20,8 @@ if(PARSEC_TPM_SE_SUPPORT) -DMBED_CONF_APP_SECURE_ELEMENT_PARSEC_TPM_SUPPORT -DMBED_CONF_MBED_CLOUD_CLIENT_NON_PROVISIONED_SECURE_ELEMENT ) -endif() \ No newline at end of file +endif() + +# curl fix - https://github.com/curl/curl/issues/7988 +set (CURL_USE_OPENSSL OFF CACHE BOOL "disable openssl" FORCE) + diff --git a/define_lwm2m_compliant.txt b/define_lwm2m_compliant.txt index 3e5d7ea..c2e40d4 100644 --- a/define_lwm2m_compliant.txt +++ b/define_lwm2m_compliant.txt @@ -29,7 +29,6 @@ add_definitions(-DPLATFORM_ENABLE_LED=1) add_definitions(-DMBED_CONF_MBED_CLOUD_CLIENT_DISABLE_CERTIFICATE_ENROLLMENT) add_definitions(-DLWM2M_COMPLIANT) -add_definitions(-DDISABLE_SERVER_CERT_VERIFY) add_definitions(-DFOTA_DEFAULT_APP_IFS=1) add_definitions(-DTARGET_LIKE_LINUX=1) diff --git a/main.cpp b/main.cpp index ad48fec..518f5df 100755 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,6 @@ // ---------------------------------------------------------------------------- -// Copyright 2016-2021 Pelion. +// Copyright 2022-2021 Pelion. +// Copyright 2022 Izuma Networks. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/mbed-cloud-client.lib b/mbed-cloud-client.lib index 777d48f..30e96df 100644 --- a/mbed-cloud-client.lib +++ b/mbed-cloud-client.lib @@ -1 +1 @@ -https://github.com/PelionIoT/mbed-cloud-client/#54282bc27ed9c404524e15a0de93dc9a59516f79 +https://github.com/PelionIoT/mbed-cloud-client/#bed292c4a7778cbc55ac01fc832e2469d439c7f1 diff --git a/mbed_app_lwm2m_compliant.json b/mbed_app_lwm2m_compliant.json index aeadccf..d81dffe 100644 --- a/mbed_app_lwm2m_compliant.json +++ b/mbed_app_lwm2m_compliant.json @@ -15,10 +15,11 @@ "nsapi.default-wifi-security" : "WPA_WPA2", "nsapi.default-wifi-ssid" : "\"SSID\"", "nsapi.default-wifi-password" : "\"Password\"", - "target.macros_add" : ["LWM2M_COMPLIANT","DISABLE_SERVER_CERT_VERIFY","RESET_STORAGE"], + "target.macros_add" : ["LWM2M_COMPLIANT"], "client_app.pal-user-defined-configuration" : "\"pal_config_MbedOS_LWM2M_Compliant.h\"", "lwip.mem-size" : 18432, "mbed-client.disable-bootstrap-feature" : null, + "mbed-cloud-client.disable-certificate-enrollment": null, "mbed-client.max-certificate-size" : 2048 }, "K64F": { @@ -40,6 +41,31 @@ "storage_filesystem.filesystem" : "LITTLE", "storage_filesystem.blockdevice" : "SD" }, + "DISCO_L496AG": { + "target.network-default-interface-type" : "CELLULAR", + "target.bootloader_img" : "tools/mbed-bootloader-disco_l496ag-internal_kvstore-qspif-v4.1.3.bin", + "target.header_offset" : "0x11000", + "target.app_offset" : "0x11400", + "target.components_add": [ + "STMOD_CELLULAR", + "FLASHIAP", + "QSPIF" + ], + "cellular.radio-access-technology" : "CellularNetwork::RadioAccessTechnology::RAT_GSM", + "nsapi.default-cellular-apn" : "\"pp.vodafone.co.uk\"", + "nsapi.default-cellular-username" : "\"wap\"", + "nsapi.default-cellular-password" : "\"wap\"", + "platform.stdio-baud-rate" : 115200, + "platform.stdio-convert-newlines" : 1, + "stmod_cellular.provide-default" : "true", + "target.macros_add": [ + "CELLULAR_DEVICE=STModCellular" + ], + "target.features_add" : ["STORAGE"], + "storage.storage_type" : "TDB_INTERNAL", + "storage_tdb_internal.internal_base_address": "(MBED_ROM_START + (36 * 1024))", + "storage_tdb_internal.internal_size" : "(32 * 1024)" + }, "NUCLEO_F429ZI": { "target.network-default-interface-type" : "ETHERNET", "target.bootloader_img" : "tools/mbed-bootloader-nucleo_f429zi-internal_flash-no_rot-v4.1.0.bin", diff --git a/mbed_cloud_client_user_config.h b/mbed_cloud_client_user_config.h index 152d898..2fbbdc2 100644 --- a/mbed_cloud_client_user_config.h +++ b/mbed_cloud_client_user_config.h @@ -26,6 +26,16 @@ #define MBED_CLOUD_CLIENT_LIFETIME (3*60) +// Option to migrate the bootstrap server to another URI. +// You must specify both, activate feature via +// #define MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP and +// new address via +// #define MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP_TO "coaps://new-bootstrap-server-uri.com:port" +/* +#define MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP +#define MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP_TO "coaps://new-bootstrap-server-uri.com:port" +*/ + #ifdef LWM2M_COMPLIANT #define MBED_CLOUD_CLIENT_TRANSPORT_MODE_UDP #define MBED_CONF_MBED_CLIENT_MAX_CERTIFICATE_SIZE 2048 @@ -37,6 +47,8 @@ #ifdef MBED_CONF_MBED_CLIENT_SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE #define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE MBED_CONF_MBED_CLIENT_SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE +#elif defined LWM2M_COMPLIANT + #define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 1024 #else #define SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE 512 #endif @@ -47,5 +59,10 @@ #define MBED_CLOUD_DEV_UPDATE_ID #endif /* MBED_CONF_APP_DEVELOPER_MODE */ +/* +// Try port 443 instead of default CoAP port, will fallback to CoAP port 5684 if 443 fails. +// NOTE! Only port 443 is supported as alternative port in the cloud service. +*/ +//#define MBED_CLOUD_CLIENT_CUSTOM_URI_PORT 443 #endif /* MBED_CLOUD_CLIENT_USER_CONFIG_H */ diff --git a/pal-platform/SDK/ZephyrOS/CMakeLists.txt b/pal-platform/SDK/ZephyrOS/CMakeLists.txt index aea7f87..09cd1f3 100644 --- a/pal-platform/SDK/ZephyrOS/CMakeLists.txt +++ b/pal-platform/SDK/ZephyrOS/CMakeLists.txt @@ -11,11 +11,11 @@ endif() configure_file(${CMAKE_SOURCE_DIR}/pal-platform/SDK/ZephyrOS/Kconfig ${CMAKE_SOURCE_DIR} COPYONLY) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project("Pelion Client") +project("Izuma Client") ################################################################################ -add_definitions(-DMBED_CONF_APP_DEVELOPER_MODE=$) +add_definitions(-DMBED_CONF_APP_DEVELOPER_MODE=$) add_definitions(-DMBED_CLOUD_APPLICATION_NONSTANDARD_ENTRYPOINT=1) add_definitions(-DPAL_USER_DEFINED_CONFIGURATION="pal_config_zephyr.h") @@ -42,7 +42,7 @@ SET(APP_SRCS target_sources(app PRIVATE ${CMAKE_SOURCE_DIR}/pal-platform/SDK/ZephyrOS/src/main.cpp ${APP_SRCS}) -if(CONFIG_PELION_SOURCES) +if(CONFIG_IZUMA_SOURCES) target_include_directories(app PRIVATE ${ZEPHYR_BASE}/subsys/storage/flash_map) # Copy configuration file to include directory visible for all libraries. # Needed for the file to be visible by Zephyr's mbedtls library. diff --git a/pal-platform/SDK/ZephyrOS/Kconfig b/pal-platform/SDK/ZephyrOS/Kconfig index 9cea162..c3f8b4b 100644 --- a/pal-platform/SDK/ZephyrOS/Kconfig +++ b/pal-platform/SDK/ZephyrOS/Kconfig @@ -1,18 +1,18 @@ -# Copyright (c) 2021 Pelion +# Copyright (c) 2022 Izuma Networks # SPDX-License-Identifier: Apache-2.0 -menu "Pelion Device Management Client Example" +menu "Izuma Device Management Client Example" comment " Example application configuration " -config PELION_EXAMPLE_DEVELOPER_MODE +config IZUMA_EXAMPLE_DEVELOPER_MODE bool "Enable developer mode to skip Factory enrollment" default y help - Connect to Pelion DM using developer credentials. + Connect to Izuma DM using developer credentials. comment " Library configuration can be found under: " -comment " Modules -> Pelion Device Management Client Library " +comment " Modules -> Izuma Device Management Client Library " endmenu diff --git a/pal-platform/SDK/ZephyrOS/README.txt b/pal-platform/SDK/ZephyrOS/README.txt index 594fb3b..ac07f76 100644 --- a/pal-platform/SDK/ZephyrOS/README.txt +++ b/pal-platform/SDK/ZephyrOS/README.txt @@ -7,17 +7,17 @@ underlying storage medium. The bootloader, MCUboot, is stored in the partition labeled "mcuboot". The active application is executed from "image_0", and the candidate firmware is -stored in "image_1". Pelion Device Management Client uses the partition "pelion_storage" -for storing configuration and credentials. If "pelion_storage" doesn't exist, -Pelion Device Management Client uses "storage" partition unless Zephyr is already using it +stored in "image_1". Pelion Device Management Client uses the partition "izuma_storage" +for storing configuration and credentials. If "izuma_storage" doesn't exist, +Izuma Device Management Client uses "storage" partition unless Zephyr is already using it (CONFIG_SETTINGS=n). Depending on the architecture, you can put "image_0" and "image_1" on external -storage, but for better security, keep "pelion_storage" in internal +storage, but for better security, keep "izuma_storage" in internal storage. For more information about Zephyr's storage partitions, see: -https://docs.zephyrproject.org/2.5.0/reference/storage/flash_map/flash_map.html#relationship-with-devicetree +https://docs.zephyrproject.org/2.7.3/reference/storage/flash_map/flash_map.html#relationship-with-devicetree As a reference, we've provided a partition overlay for the target "frdm_k64f" in the "boards" folder, using the following flash layout: @@ -25,7 +25,7 @@ in the "boards" folder, using the following flash layout: +--------------------------+ | | -| TDBStore | <-+ "pelion_storage" +| TDBStore | <-+ "izuma_storage" | | +--------------------------+ | | @@ -60,29 +60,29 @@ Bootloader Zephyr OS uses MCUboot (https://mcuboot.com/) as a bootloader. The example application installs new firmware as "permanent" by default. -To use MCUboot's rollback feature, use Kconfig to set PELION_UPDATE_PERMANENT=n +To use MCUboot's rollback feature, use Kconfig to set IZUMA_UPDATE_PERMANENT=n and Zephyr's DFU commands for interacting with MCUboot: -https://docs.zephyrproject.org/2.5.0/guides/device_mgmt/dfu.html +https://docs.zephyrproject.org/2.7.3/guides/device_mgmt/dfu.html Note that the build instructions below use the default developer keys in MCUboot. For production devices, use secure credentials, instead: -https://docs.zephyrproject.org/2.5.0/guides/west/sign.html +https://docs.zephyrproject.org/2.7.3/guides/west/sign.html Building ======== Ensure a working build environment has been set up: -https://docs.zephyrproject.org/2.5.0/getting_started/index.html +https://docs.zephyrproject.org/2.7.3/getting_started/index.html The example below creates a new Zephyr workspace with the structure: - pelion-workspace + zephyrworkspace ├── bootloader ├── modules │ └── lib - │ └── pelion-dm (middleware library) - ├── pelion-dm-example (example application) + │ └── izuma-dm (middleware library) + ├── izuma-dm-example (example application) │ ├── pal-platform │ │ └── SDK │ │ └── ZephyrOS (Zephyr project) @@ -97,11 +97,11 @@ and uses the "frdm_k64f" target as an example. Create workspace ---------------- -> west init -m https://github.com/PelionIoT/mbed-cloud-client-example pelion-workspace -> cd pelion-workspace +> west init -m https://github.com/PelionIoT/mbed-cloud-client-example zephyr-workspace +> cd zephyr-workspace > west update -Add developer credentials for connecting (https://developer.pelion.com/docs/device-management/current/provisioning-process/provisioning-development-devices.html) +Add developer credentials for connecting (https://developer.izumanetworks.com/docs/device-management/current/provisioning-process/provisioning-development-devices.html) and updating devices (https://github.com/PelionIoT/manifest-tool#manifest-dev-tool-init). Note that V1 manifests are used for Zephyr builds. @@ -109,7 +109,7 @@ Note that V1 manifests are used for Zephyr builds. Build and flash without bootloader and update support --------------------------------------------------- -> west build -b frdm_k64f -d build/pdmc -s pelion-dm-example -- -DCONFIG_PELION_UPDATE=n +> west build -b frdm_k64f -d build/pdmc -s izuma-dm-example -- -DCONFIG_IZUMA_UPDATE=n > west flash -d build/pdmc @@ -117,29 +117,29 @@ Build and flash with bootloader and update support --------------------------------------------------- > west build -b frdm_k64f -d build/mcuboot -s bootloader/mcuboot/boot/zephyr -- \ - -DDTC_OVERLAY_FILE=`pwd`/pelion-dm-example/pal-platform/SDK/ZephyrOS/boards/frdm_k64f.overlay \ + -DDTC_OVERLAY_FILE=`pwd`/izuma-dm-example/pal-platform/SDK/ZephyrOS/boards/frdm_k64f.overlay \ -DCONFIG_MCUBOOT_CLEANUP_ARM_CORE=y > west flash -d build/mcuboot -> west build -b frdm_k64f -d build/pdmc -s pelion-dm-example -- \ +> west build -b frdm_k64f -d build/dmc -s izuma-dm-example -- \ -DCONFIG_MCUBOOT_SIGNATURE_KEY_FILE=\"bootloader/mcuboot/root-rsa-2048.pem\" -> west flash -d build/pdmc +> west flash -d build/dmc Advanced options ================ -To add Pelion Device Management to an existing project, add the following repository and module +To add Izuma Device Management to an existing project, add the following repository and module to the West manifest: remotes: - name: PelionIoT url-base: https://github.com/PelionIoT projects: - - name: pelion-dm + - name: izuma-dm repo-path: mbed-cloud-client remote: PelionIoT revision: master - path: modules/lib/pelion-dm + path: modules/lib/izuma-dm -You can find further configuration options using the Kconfig menu under "modules -> pelion-dm". +You can find further configuration options using the Kconfig menu under "modules -> izuma-dm". diff --git a/pal-platform/SDK/ZephyrOS/boards/frdm_k64f.overlay b/pal-platform/SDK/ZephyrOS/boards/frdm_k64f.overlay index 1c36548..d8912eb 100644 --- a/pal-platform/SDK/ZephyrOS/boards/frdm_k64f.overlay +++ b/pal-platform/SDK/ZephyrOS/boards/frdm_k64f.overlay @@ -12,8 +12,8 @@ }; &flash0 { partitions { - pelion_partition: partition@0x000FA000 { - label = "pelion_storage"; + izuma_partition: partition@0x000FA000 { + label = "izuma_storage"; reg = <0x000FA000 0x00006000>; }; }; diff --git a/pal-platform/SDK/ZephyrOS/prj.conf b/pal-platform/SDK/ZephyrOS/prj.conf index 7cc6f7d..c940b35 100644 --- a/pal-platform/SDK/ZephyrOS/prj.conf +++ b/pal-platform/SDK/ZephyrOS/prj.conf @@ -1,35 +1,35 @@ # Use developer credentials -CONFIG_PELION_EXAMPLE_DEVELOPER_MODE=y -CONFIG_PELION_UPDATE_DEVELOPER=y +CONFIG_IZUMA_EXAMPLE_DEVELOPER_MODE=y +CONFIG_IZUMA_UPDATE_DEVELOPER=y # Enable Pelion Client library -CONFIG_PELION_CLIENT=y +CONFIG_IZUMA_CLIENT=y # Endpoint type -CONFIG_PELION_ENDPOINT_TYPE="default" +CONFIG_IZUMA_ENDPOINT_TYPE="default" # Device registration lifetime -CONFIG_PELION_LIFETIME=86400 +CONFIG_IZUMA_LIFETIME=86400 # Transport mode -CONFIG_PELION_TRANSPORT_MODE_TCP=y -#CONFIG_PELION_TRANSPORT_MODE_UDP=y -#CONFIG_PELION_TRANSPORT_MODE_UDP_QUEUE=y +CONFIG_IZUMA_TRANSPORT_MODE_TCP=y +#CONFIG_IZUMA_TRANSPORT_MODE_UDP=y +#CONFIG_IZUMA_TRANSPORT_MODE_UDP_QUEUE=y # CoAP block size -CONFIG_PELION_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE=512 +CONFIG_IZUMA_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE=512 # Debug tracing -CONFIG_PELION_DEBUG_TRACE=n +CONFIG_IZUMA_DEBUG_TRACE=n # Enable firmware update -CONFIG_PELION_UPDATE=y +CONFIG_IZUMA_UPDATE=y # Firmware update buffer -CONFIG_PELION_UPDATE_BUFFER=1024 +CONFIG_IZUMA_UPDATE_BUFFER=1024 # Make new firmware permanent -CONFIG_PELION_UPDATE_PERMANENT=y +CONFIG_IZUMA_UPDATE_PERMANENT=y ################################################################################ ## Common Zephyr configuration diff --git a/pal-platform/pal-platform.json b/pal-platform/pal-platform.json index 2e85620..6ab3a9c 100644 --- a/pal-platform/pal-platform.json +++ b/pal-platform/pal-platform.json @@ -34,11 +34,11 @@ }, "middleware": { "mbedtls": { - "version": "2.27.0", + "version": "2.28.1", "from": { "protocol": "git", "location": "https://github.com/ARMmbed/mbedtls.git", - "tag": "mbedtls-2.27.0" + "tag": "mbedtls-2.28.1" }, "to": "Middleware/mbedtls/mbedtls" }, @@ -61,11 +61,11 @@ "to": "Middleware/parsec_se_driver/parsec_se_driver" }, "curl": { - "version": "7.76.0", + "version": "7.85.0", "from": { "protocol": "git", "location": "https://github.com/curl/curl.git", - "tag": "curl-7_76_0" + "tag": "curl-7_85_0" }, "to": "Middleware/curl/curl" } @@ -81,20 +81,20 @@ }, "middleware": { "mbedtls": { - "version": "2.27.0", + "version": "2.28.1", "from": { "protocol": "git", "location": "https://github.com/ARMmbed/mbedtls.git", - "tag": "mbedtls-2.27.0" + "tag": "mbedtls-2.28.1" }, "to": "Middleware/mbedtls/mbedtls" }, "curl": { - "version": "7.76.0", + "version": "7.85.0", "from": { "protocol": "git", "location": "https://github.com/curl/curl.git", - "tag": "curl-7_76_0" + "tag": "curl-7_85_0" }, "to": "Middleware/curl/curl" } @@ -109,20 +109,20 @@ }, "middleware": { "mbedtls": { - "version": "2.27.0", + "version": "2.28.1", "from": { "protocol": "git", "location": "https://github.com/ARMmbed/mbedtls.git", - "tag": "mbedtls-2.27.0" + "tag": "mbedtls-2.28.1" }, "to": "Middleware/mbedtls/mbedtls" }, "curl": { - "version": "7.76.0", + "version": "7.85.0", "from": { "protocol": "git", "location": "https://github.com/curl/curl.git", - "tag": "curl-7_76_0" + "tag": "curl-7_85_0" }, "to": "Middleware/curl/curl" } @@ -201,11 +201,11 @@ }, "middleware": { "mbedtls": { - "version": "2.27.0", + "version": "2.28.1", "from": { "protocol": "git", "location": "https://github.com/ARMmbed/mbedtls.git", - "tag": "mbedtls-2.27.0" + "tag": "mbedtls-2.28.1" }, "to": "Middleware/mbedtls/mbedtls" }, diff --git a/pal_config_MbedOS.h b/pal_config_MbedOS.h index c1fc906..d85abc1 100644 --- a/pal_config_MbedOS.h +++ b/pal_config_MbedOS.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019 ARM Limited. All rights reserved. + * Copyright (c) 2022 Izuma Networks. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. diff --git a/pal_config_MbedOS_LWM2M_Compliant.h b/pal_config_MbedOS_LWM2M_Compliant.h index b6d324e..161e7ad 100644 --- a/pal_config_MbedOS_LWM2M_Compliant.h +++ b/pal_config_MbedOS_LWM2M_Compliant.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2022 ARM Limited. All rights reserved. + * Copyright (c) 2022 Izuma Networks. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. diff --git a/pal_config_Renesas_RA.h b/pal_config_Renesas_RA.h index 3fad6f0..6dde598 100644 --- a/pal_config_Renesas_RA.h +++ b/pal_config_Renesas_RA.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2020 ARM Limited. All rights reserved. + * Copyright (c) 2022 Izuma Networks. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. diff --git a/pal_config_Renesas_RX65N-CK.h b/pal_config_Renesas_RX65N-CK.h index 41e0b20..e5449ed 100644 --- a/pal_config_Renesas_RX65N-CK.h +++ b/pal_config_Renesas_RX65N-CK.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2019 ARM Limited. All rights reserved. + * Copyright (c) 2022 Izuma Networks. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. diff --git a/pal_config_non_trng_MbedOS.h b/pal_config_non_trng_MbedOS.h index 0061839..9c1a661 100644 --- a/pal_config_non_trng_MbedOS.h +++ b/pal_config_non_trng_MbedOS.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2018-2019 ARM Limited. All rights reserved. + * Copyright (c) 2022 Izuma Networks. All rights reserved. * SPDX-License-Identifier: Apache-2.0 * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. diff --git a/pdmc-connection-to-standard-lwm2m-server-tutorial.md b/pdmc-connection-to-standard-lwm2m-server-tutorial.md new file mode 100644 index 0000000..ea34545 --- /dev/null +++ b/pdmc-connection-to-standard-lwm2m-server-tutorial.md @@ -0,0 +1,167 @@ +# Device Management Client connection to a standard OMA LwM2M server tutorial + +This tutorial builds and flashes a Device Management Client application using either Linux (running on a PC) or Mbed OS. +The application can then connect to a standard OMA Lightweight M2M server. +In this tutorial, the application uses developer mode that relies on a developer certificate, which should be added to your software binary to allow test devices to connect to the server. +In production, the factory flow should be used instead. + +## Linux + +### Requirements + +This requires a Linux PC (64-bit Ubuntu/XUbuntu OS desktop environment). +See also the [Mbed CLI instructions](https://os.mbed.com/docs/mbed-os/latest/tools/developing-mbed-cli.html). + +### Connecting the device + +1. Open a terminal, and clone the example repository to a convenient location in your development environment: + + ``` + git clone https://github.com/PelionIoT/mbed-cloud-client-example + cd mbed-cloud-client-example + ``` + + **Note:** If you want to speed up `mbed deploy`, you can remove components that are unnecessary for Linux, such as `mbed-os.lib` and the `drivers/` folder. + +2. Deploy the example repository: + + ``` + mbed deploy + ``` + +3. [Create a developer certificate](#create-a-developer-certificate). + +4. Copy the `mbed_cloud_dev_credentials.c` file to the root folder of the example. + +5. Deploy Linux dependencies: + + ``` + python pal-platform/pal-platform.py deploy --target=x86_x64_NativeLinux_mbedtls generate + cd __x86_x64_NativeLinux_mbedtls + ``` + **Note: Python 2 is needed for the above command** + +6. Generate `cmake` files based on your configuration and build profile (**Release** or **Debug**): + + - For the **Release** profile: + ``` + cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=./../pal-platform/Toolchain/GCC/GCC.cmake -DEXTERNAL_DEFINE_FILE=./../define_lwm2m_compliant.txt + ``` + + - For the **Debug** profile: + ``` + cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=./../pal-platform/Toolchain/GCC/GCC.cmake -DEXTERNAL_DEFINE_FILE=./../define_lwm2m_compliant.txt + ``` + + - If you want your application to bypass the Bootstrap server and work directly with the LwM2M server, add `DISABLE_BOOTSTRAP` cmake flag: + ``` + cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DDISABLE_BOOTSTRAP=ON -DCMAKE_TOOLCHAIN_FILE=./../pal-platform/Toolchain/GCC/GCC.cmake -DEXTERNAL_DEFINE_FILE=./../define_lwm2m_compliant.txt + ``` + +7. Compile the application: + + ``` + make mbedCloudClientExample.elf + ``` + +8. The build creates binaries under `mbed-cloud-client-example/__x86_x64_NativeLinux_mbedtls`. In both cases, there are subdirectories `Debug` and `Release` respectively created for the two profiles. + +9. Run the application (at the respective path, see above): + + ``` + ./mbedCloudClientExample.elf + ``` + + You should see a message when the device connects to the LwM2M server: + + ``` + Client registered + Endpoint Name: + Device Id: + ``` + +10. If you want to run the application with clean storage, you can remove the `pal` folder that is created in the location where you run your application. + + +## Mbed OS + +### Prerequisites + +To work with the Device Management Client example application, you need: + +* A supported board with a network connection and an SD card is attached. FRDM K64F board is supported. +* [Serial connection](https://os.mbed.com/docs/latest/tutorials/serial-comm.html) to your device with open terminal connection (baud rate 115200, 8N1). +* [Arm Mbed CLI](https://os.mbed.com/docs/mbed-os/latest/tools/index.html) installed. See [installation instructions](https://os.mbed.com/docs/latest/tools/installation-and-setup.html). + * Make sure that all the Python components are on par with the `pip` package [requirements.txt](https://github.com/PelionIoT/mbed-os/blob/master/requirements.txt) list from Mbed OS. +* Updated [DAPLink](https://github.com/ARMmbed/DAPLink/releases) software (version 250 or later), if your board uses DAPLink. + +### Connecting the device + +1. Clone the embedded application's GitHub repository to your local computer and navigate to the new folder: + + ``` + mbed import https://github.com/PelionIoT/mbed-cloud-client-example + cd mbed-cloud-client-example + ``` + +2. Configure Mbed CLI to use your board: + + ``` + mbed target K64F + mbed toolchain GCC_ARM + ``` + +3. [Create a developer certificate](#create-a-developer-certificate). + +4. Copy the `mbed_cloud_dev_credentials.c` file to the root folder of the example application. + +5. Configure the example application: + + 1. If you want your application to bypass the Bootstrap server and work directly with the LwM2M server, + please set the `disable-bootstrap-feature` feature to `true` in [mbed_app_lwm2m_compliant.json](https://github.com/PelionIoT/mbed-cloud-client-example/blob/master/mbed_app_lwm2m_compliant.json#L21). + + ``` + mbed-client.disable-bootstrap-feature: true + ``` + +7. Compile the example application: + + ``` + mbed compile --app-config mbed_app_lwm2m_compliant.json + ``` + For more information about Mbed CLI parameters, please see the [Mbed OS documentation site](https://os.mbed.com/docs/mbed-os/latest/build-tools/mbed-cli-1.html). + +8. Flash the binary to the device: + 1. Connect the device to your computer over USB. It's listed as a mass storage device. + 2. Drag and drop `mbed-cloud-client-example.bin` to the device, or alternatively add the `-f` flag to the build command (if your device is connected to the build machine). This flashes the binary to the device. You should see the LED blink rapidly; wait for it to stop. + +9. Press the **Reset** button to restart the device and reset the terminal. + +10. When the client has successfully connected, the terminal shows: + + ``` + Client registered + Endpoint Name: + Device ID: + ``` + +## Create a developer certificate + +1. Download the server CA certificate from the LwM2M service you want to connect to and copy it to the scripts' folder: + + ``` + cp utils/server_ca_cert.der + ``` + +2. Run the python script `cert_convert.py` to generate a `mbed_cloud_dev_credentials.c` file. + + ``` + cd utils + python cert_convert.py --endpoint --uri --use-ca + ``` + + The script will do the following steps: + 1. Generate a root CA key and certificate the first time the script is running. All CA outputs are stored in `CA` folder. + 1. Generate a private key and a certificate signed by this CA. + 1. Convert the private key, certificate, and server certificate to a C file. + 1. All non-CA outputs are stored in a folder named `YOUR_ENDPOINT_NAME`. diff --git a/pdmc-migration-tutorial.md b/pdmc-migration-tutorial.md new file mode 100644 index 0000000..bd77077 --- /dev/null +++ b/pdmc-migration-tutorial.md @@ -0,0 +1,44 @@ +# Device Management Client migration tutorial + +Starting with release 4.13.0 PDMC supports migration from one bootstrap server to another. +This is available now only for Mbed OS-based devices that use KVStore as the storage solution. + +Valid use-cases: +* Transferring devices from a US-based server to an EU-based server due to GDPR requirements. +* Transferring devices from one standard OMA LwM2M server to another. + +Follow the next steps to compile an image with the migration feature enabled. +1. Enable the migration feature by modifying `mbed_cloud_client_user_config.h` file as follows: + ``` + #define MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP + #define MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP_TO "coaps://new-bootstrap-server-uri.com:port" + ``` +2. Generate a .C-based file for the Bootstrap server certificate. + ``` + python utils/cnvfile2hex.py --server-cert server_ca_cert.der --output migrate_server_cert.c + ``` + `server_car_cert.der` - the Bootstrap server certificate in DER format of the new server. +3. Compile the image with the relevant `*.json` configuration file. + For transferring the device from one standard OMA LwM2M server to another, use `mbed_app_lwm2m_compliant.json` file. + ``` + mbed compile --app-config mbed_app_lwm2m_compliant.json + ``` + **Note**: the image must be compiled in production mode, i.e. following modifications in the `*.json` file are needed: + ``` + "*": { + ... + "target.OUTPUT_EXT" : "hex" + }, + ... + "developer-mode": { + ... + "value" : null + }, + ``` + +Update the device with the compiled image via the firmware update (FOTA) campaign. + +**Notes:** + * As part of the migration, the LwM2M credentials are wiped from the device, thus forcing a new bootstrap operation with the new server URI. + * The migration state is tracked via a new KVStore entry `pelion_wMIGR`. + If you need to migrate the device a 2nd time you should either remove that KVStore entry via another FOTA or modify the code to use a different entry for the 2nd migration (for example `pelion_wMIGR2`). diff --git a/psa_storage_user_config.h b/psa_storage_user_config.h index 742f5d7..fda2c59 100644 --- a/psa_storage_user_config.h +++ b/psa_storage_user_config.h @@ -1,5 +1,6 @@ // ---------------------------------------------------------------------------- // Copyright 2019 ARM Ltd. +// Copyright (c) 2022 Izuma Networks. All rights reserved. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/requirements.txt b/requirements.txt index 21716b6..cec8741 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # ---------------------------------------------------------------------------- -# Copyright 2021 Pelion +# Copyright (c) 2022 Izuma Networks # # SPDX-License-Identifier: Apache-2.0 # @@ -17,7 +17,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# This file lists Pelion device management client requirements. +# This file lists Izuma Device Management client requirements. # Install the requirements by calling # pip install -r requirements.txt diff --git a/sotp_fs_config_ARIA_linux.h b/sotp_fs_config_ARIA_linux.h deleted file mode 100644 index 6b9ccbb..0000000 --- a/sotp_fs_config_ARIA_linux.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2018-2019 ARM Limited. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - * Licensed under the Apache License, Version 2.0 (the License); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an AS IS BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef PAL_HEADER_SOTP_FS_ARIA_LINUX -#define PAL_HEADER_SOTP_FS_ARIA_LINUX - -#define PAL_USE_HW_ROT 0 -#define PAL_USE_HW_RTC 0 -#define PAL_USE_HW_TRNG 1 -#define PAL_SIMULATOR_FLASH_OVER_FILE_SYSTEM 1 -#define PAL_USE_SECURE_TIME 1 - -#define PAL_TLS_CIPHER_SUITE PAL_TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256_SUITE - -#include "Linux_default.h" - -#endif //PAL_HEADER_SOTP_FS_ARIA_LINUX diff --git a/sotp_fs_config_MbedOS.h b/sotp_fs_config_MbedOS.h index fe4646f..2d908d2 100644 --- a/sotp_fs_config_MbedOS.h +++ b/sotp_fs_config_MbedOS.h @@ -1,5 +1,7 @@ /* * Copyright (c) 2018-2019 ARM Limited. All rights reserved. + * Copyright (c) 2022 Izuma Networks. All rights reserved. + * * SPDX-License-Identifier: Apache-2.0 * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. diff --git a/sotp_fs_config_linux.h b/sotp_fs_config_linux.h index 10f539f..997ff36 100644 --- a/sotp_fs_config_linux.h +++ b/sotp_fs_config_linux.h @@ -1,5 +1,7 @@ /* * Copyright (c) 2018-2019 ARM Limited. All rights reserved. + * Copyright (c) 2022 Izuma Networks Limited. All rights reserved. + * * SPDX-License-Identifier: Apache-2.0 * Licensed under the Apache License, Version 2.0 (the License); you may * not use this file except in compliance with the License. diff --git a/sotp_fs_config_linux_lwm2m_compliant.h b/sotp_fs_config_linux_lwm2m_compliant.h index 9e12672..e1b8160 100644 --- a/sotp_fs_config_linux_lwm2m_compliant.h +++ b/sotp_fs_config_linux_lwm2m_compliant.h @@ -1,5 +1,5 @@ -#ifndef PAL_HEADER_SOTP_FS_LINUX_COIOTE -#define PAL_HEADER_SOTP_FS_LINUX_COIOTE +#ifndef PAL_HEADER_SOTP_FS_LINUX_LWM2M_COMPLIANT +#define PAL_HEADER_SOTP_FS_LINUX_LWM2M_COMPLIANT #define PAL_USE_HW_ROT 0 #define PAL_USE_HW_RTC 0 @@ -9,4 +9,4 @@ #include "Linux_default.h" -#endif //PAL_HEADER_SOTP_FS_LINUX_COIOTE +#endif //PAL_HEADER_SOTP_FS_LINUX_LWM2M_COMPLIANT diff --git a/source/application_init.cpp b/source/application_init.cpp index 95ef4d3..81e3c79 100644 --- a/source/application_init.cpp +++ b/source/application_init.cpp @@ -1,5 +1,5 @@ // ---------------------------------------------------------------------------- -// Copyright 2016-2021 Pelion. +// Copyright 2016-2022 Pelion. // // SPDX-License-Identifier: Apache-2.0 // @@ -26,6 +26,7 @@ #include "mcc_common_setup.h" #include "mcc_common_button_and_led.h" #include "application_init.h" +#include "migrate_kvstore.h" #if defined (MEMORY_TESTS_HEAP) #include "memory_tests.h" @@ -223,7 +224,7 @@ bool application_init_mbed_trace(void) static bool verify_cloud_configuration() { - int status; + int status = 0; bool result = 0; #if MBED_CONF_APP_DEVELOPER_MODE == 1 @@ -308,6 +309,20 @@ static bool initialize_fcc(void) bool application_init(void) { +#if defined MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP + #if (defined MBED_CONF_APP_DEVELOPER_MODE && MBED_CONF_APP_DEVELOPER_MODE == 1) + #error "Migration can only be used with factory flow." + #endif + int ret; + + printf("Migration mode on.\n"); + ret = migrate_kvstore(MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP_TO); + if (ret != 0) { + printf("ERROR - migrate_kvstore failed with %d\n", ret); + return false; + } +#endif // MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP_TO + // The function always returns 0. (void) mcc_platform_init_button_and_led(); diff --git a/source/migrate_kvstore.cpp b/source/migrate_kvstore.cpp new file mode 100644 index 0000000..803e7fa --- /dev/null +++ b/source/migrate_kvstore.cpp @@ -0,0 +1,226 @@ +// ---------------------------------------------------------------------------- +// Copyright 2022 Pelion. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------- + +// Only compile in Mbed OS +#if defined __MBED__ + +#ifdef MBED_CLOUD_CLIENT_USER_CONFIG_FILE +#include MBED_CLOUD_CLIENT_USER_CONFIG_FILE +#endif + +#include "mbed.h" +#include "mbed-trace/mbed_trace.h" +#include "KVStore.h" +#include "kvstore_global_api.h" + +using namespace mbed; + +#define TRACE_GROUP "MIGR" +#define MAX_CONTENT_LEN 1024 // Max certificate length +#define backupBootstrapURI "pelion_bCfgParam_mbed.BootstrapServerURI" +#define workingBootstrapURI "pelion_wCfgParam_mbed.BootstrapServerURI" +#define backupBootstrapCA "pelion_bCrtae_mbed.BootstrapServerCACert" +#define workingBootstrapCA "pelion_wCrtae_mbed.BootstrapServerCACert" +#define migrationKey "pelion_wMIGR" + +// Please note that migration state is NOT reset after a sucesfull migration. +// If you have a need to do multiple migrations, you should make a special SW +// update at some stage to disable migration and also remove the migrationKey +// at that stage OR alternatively change the name of the key (say pelion_wMIGR2) +// for 2nd migration etc. so that a unique state per migration is retained. +typedef struct rep_key_info { + const char *key; // KVSStore key name + const uint8_t *value; // New value to replace + size_t size; // New value length/size + bool printable; // Is entry printable string? +} rep_key_info; + +/* Definitions for bootstrap cert info via the migrate_server_cert.h */ + +extern const uint8_t MIGRATE_BOOTSTRAP_CA_CERT[]; +extern const uint32_t MIGRATE_BOOTSTRAP_CA_CERT_SIZE; + +/* Internal function prototypes */ +static int kvstore_locate_and_replace(rep_key_info *); +static int kvstore_clear_LwM2M_info(void); + +/* migrate_kvstore Change the bootstrap server address. + NOTE! Supports only Mbed OS / KVStore and production mode. + + There are two sets of keys that need to be updated. + Working set and backup set. They both need to be deleted and re-recreated with the new value. + +*/ +int migrate_kvstore(const char *new_BS_server) { + int status; + kv_info_t info; + rep_key_info bURI = { backupBootstrapURI, + (const uint8_t *) new_BS_server, + strlen(backupBootstrapURI), + true, // Printable + }; + rep_key_info wURI = { workingBootstrapURI, + (const uint8_t *) new_BS_server, + strlen(backupBootstrapURI), + true, // Printable + }; + rep_key_info bCert = { backupBootstrapCA, + MIGRATE_BOOTSTRAP_CA_CERT, + MIGRATE_BOOTSTRAP_CA_CERT_SIZE, + false, // Printable + }; + rep_key_info wCert = { workingBootstrapCA, + MIGRATE_BOOTSTRAP_CA_CERT, + MIGRATE_BOOTSTRAP_CA_CERT_SIZE, + false, // Printable + }; + + // Check migration status, skip if key is found. + status = kv_get_info(migrationKey, &info); + if (status == MBED_SUCCESS) { + tr_info("Migration done already, %s exists.", migrationKey); + return status; + } + // Migration NOT done, let's do it. + // Always do locate and replace, it will only change the value if it's not + // already what it should be. We get value back via bool changed if the value + // is what it should be. + status = kvstore_locate_and_replace(&bURI); + status = status + kvstore_locate_and_replace(&wURI); + status = status + kvstore_locate_and_replace(&bCert); + status = status + kvstore_locate_and_replace(&wCert); + status = status + kvstore_clear_LwM2M_info(); + if (status != MBED_SUCCESS) { + // Failure to update any of the keys is pretty fatal, as + // either connection or RFS will fail + tr_error("ERROR - Migration failed, %d", status); + return status; + } + // Create migration key to mark "all done". + status = kv_set(migrationKey, &status, 1, 0); + if (status != MBED_SUCCESS) { + // Not failing whole operation, because the actual relevant keys + // managed to be changed. Flag write failing is not fatal, it will + // just cause unnecessary further LwM2M cert wiping. + tr_error("ERROR - Can't write migration key %s - error, %d", migrationKey, status); + } + else { + printf("Migration done.\n"); + } + return status; +} + +/* + locate_and_replace find the given key (with name), + verify if the names is matching migration value + and if not, set the new value to it. + + remove() did not work for some reason. +*/ +static int kvstore_locate_and_replace(rep_key_info *repKey) { + + size_t actual_size = 0; + kv_info_t info; + int res; + char kv_value[MAX_CONTENT_LEN + 1]; + + res = kv_get_info(repKey->key, &info); + if (res != MBED_SUCCESS) { + // Can't get key info - key likely not existing? + tr_warn("WARNING - kv_get_info failed %d for %s", res, repKey->key); + } + else { + // Does the value already match new value (i.e. our 2nd or n+ run here) + if (MAX_CONTENT_LEN < info.size) { + tr_error("ERROR - migrate - buffer len < info.size %d", info.size); + return MBED_ERROR_INVALID_SIZE; + } + memset(kv_value, 0, sizeof(kv_value)); + res = kv_get(repKey->key, kv_value, info.size, &actual_size); + if (res != MBED_SUCCESS) { + tr_error("ERROR - kv_get failed with %d for %s", res, repKey->key); + return res; + } + if (actual_size == info.size && + repKey->size == actual_size && + 0 == memcmp(kv_value, repKey->value, repKey->size) ) { + // We have a match, same string in both - just return with success + tr_info("Migration for %s already done.", repKey->key); + return MBED_SUCCESS; + } + } + + res = kv_set(repKey->key, repKey->value, repKey->size, info.flags); + if (res != MBED_SUCCESS) { + tr_error("ERROR - kv_set failed %d for %s", res, repKey->key); + return res; + } + else { + if (repKey->printable) { + tr_info("kv_set %s succeeded, written new value %s", repKey->key, repKey->value); + } + else { + tr_info("kv_set %s succeeded, written len %d bytes", repKey->key, repKey->size); + } + } + return res; +} + +static int kvstore_clear_LwM2M_info() { + + const char *keys[] = {"pelion_wCfgParam_mbed.LwM2MServerURI", + "pelion_wCrtae_mbed.LwM2MDeviceCert", + "pelion_wCrtae_mbed.LwM2MServerCACert", + "pelion_wPrvKey_mbed.LwM2MDevicePrivateKey", + }; + kv_info_t info; + int index = 0; + int failed = MBED_SUCCESS; + int rounds = (sizeof(keys)/sizeof(char*)); // Nbr of keys to remove + int res; + + while (index < rounds) { + res = kv_get_info(keys[index], &info); + if (res == MBED_ERROR_ITEM_NOT_FOUND) { + // No such key. + tr_info("Key %s does not exist (OK).", keys[index]); + res = MBED_SUCCESS; + index++; + continue; + } + res = kv_remove(keys[index]); + if (res != MBED_SUCCESS) { + tr_error("ERROR - failed to remove %s, code %d", keys[index], res); + failed = res; + } + else { + tr_info("Removed %s as part of migration.", keys[index]); + } + index++; + } + + if (failed != MBED_SUCCESS) { + res = failed; + } + else { + tr_warn("LwM2M credentials wiped to ensure bootstrap."); + } + return res; +} + +#endif // __MBED__ diff --git a/source/migrate_kvstore.h b/source/migrate_kvstore.h new file mode 100644 index 0000000..c44890b --- /dev/null +++ b/source/migrate_kvstore.h @@ -0,0 +1,43 @@ +// ---------------------------------------------------------------------------- +// Copyright 2016-2022 Pelion. +// +// SPDX-License-Identifier: Apache-2.0 +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// ---------------------------------------------------------------------------- + +#ifndef MIGRATE_KVSTORE_H +#define MIGRATE_KVSTORE_H + +/* migrate_kvstore Change the bootstrap server address. + NOTE! Supports only Mbed OS / KVStore and production mode. + + There are two sets of keys that need to be updated. + Working set and backup set. They both need to be deleted and re-recreated with the new value. + +*/ +#if defined __MBED__ +int migrate_kvstore(const char *new_value); +#else + #if defined MBED_CLOUD_CLIENT_MIGRATE_BOOTSTRAP + #error "No migration_kvstore implementation for other than Mbed OS using KVStore." + #endif +// Dummy implementation for other OSes +int migrate_kvstore(const char *new_value) { + (void) new_value; + return 0; +} +#endif + +#endif //MIGRATE_KVSTORE_H + diff --git a/tools/mbed-bootloader-disco_l496ag-internal_kvstore-qspif-v4.1.3.bin b/tools/mbed-bootloader-disco_l496ag-internal_kvstore-qspif-v4.1.3.bin new file mode 100755 index 0000000000000000000000000000000000000000..116b31b268ddcb72f7cea3a6b8a72da4b7d164ab GIT binary patch literal 35492 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

A)}9m@Z8V0Pc0^c)wGlZA%Bw@Rg*yd5iU7(s9$n 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 O>KMG2@;roly8bU)9Y=Hk literal 0 HcmV?d00001 diff --git a/update_ui_example.cpp b/update_ui_example.cpp index d3ffe0b..0e81936 100644 --- a/update_ui_example.cpp +++ b/update_ui_example.cpp @@ -1,5 +1,6 @@ // ---------------------------------------------------------------------------- // Copyright 2016-2020 ARM Ltd. +// Copyright (c) 2022 Izuma Networks. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/update_ui_example.h b/update_ui_example.h index 10b2294..266e398 100644 --- a/update_ui_example.h +++ b/update_ui_example.h @@ -1,5 +1,6 @@ // ---------------------------------------------------------------------------- // Copyright 2016-2017 ARM Ltd. +// Copyright (c) 2022 Izuma Networks. // // SPDX-License-Identifier: Apache-2.0 // diff --git a/utils/LICENSE b/utils/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/utils/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/utils/cert_convert.py b/utils/cert_convert.py index 0fde4d2..c1a9c11 100755 --- a/utils/cert_convert.py +++ b/utils/cert_convert.py @@ -28,7 +28,6 @@ from helpers import ExecuteHelper from helpers import _str_to_resolved_path -dummy_accountID = "123456" bs_public_cert_file = "bs_cert.der" bs_private_key_file = "bs_key.der" csr_file = "csr.pem" @@ -486,17 +485,11 @@ def main(): prefix, args.endpoint ) ) - output_data.write( - 'const char {}ACCOUNT_ID[] = "{}";\n'.format( - prefix, dummy_accountID - ) - ) output_data.write( 'const char {}BOOTSTRAP_SERVER_URI[] = "{}";\n\n'.format( prefix, args.uri ) ) - _process_data( private_key_file, output_data, diff --git a/utils/cnvfile2hex.py b/utils/cnvfile2hex.py new file mode 100755 index 0000000..8c010ba --- /dev/null +++ b/utils/cnvfile2hex.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# +# ---------------------------------------------------------------------------- +# Copyright 2022 Pelion +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ---------------------------------------------------------------------------- + +"""Convert a single file into C-compatible .h-file with an hex array.""" + +import argparse +import binascii +import pathlib +import sys + +from helpers import _str_to_resolved_path + +server_cert_file = "server_cert.der" +output_file = "migrate_server_cert.c" +array_name = "MIGRATE_BOOTSTRAP_CA_CERT" + + +def _parse_args(): + # Parse command line + parser = argparse.ArgumentParser( + description="Convert a file into C-compatible .c file " + "with contents as array. For example\n" + "./cnvfile2hex.py " + "--server-cert server_ca_cert.der " + "--output migrate_server_cert.c", + add_help=False, + ) + + required = parser.add_argument_group("required arguments") + optional = parser.add_argument_group("optional arguments") + + optional.add_argument( + "--server-cert", + help="Server CA cert, defaults to {}".format(server_cert_file), + default=server_cert_file, + ) + optional.add_argument( + "--output", + help="Output file (.c), defaults to {}".format(output_file), + default=output_file, + ) + optional.add_argument( + "--name", + help="Name for the array in the output file, defaults to {}.".format( + array_name + ), + default=array_name, + ) + optional.add_argument( + "-v", + "--verbose", + action="store_true", + help="Print verbose output", + default=False, + required=False, + ) + optional.add_argument( + "-h", "--help", action="help", help="Show this help message and exit." + ) + args = parser.parse_args() + + return args + + +def _sanity_check_files(args): + # Sanity check files exist or not. + status = True + + # Expect the server_certificate to exist. + if not pathlib.Path(server_cert_file).is_file(): + print("ERROR - file {} not found.".format(args.server_cert)) + status = False + + return status + + +def _process_data(infile, outfile, name, verbose): + # Process data + if verbose: + print("\tAdding {} into the credentials file.".format(infile)) + outfile.write("const uint8_t {}[] =\n".format(name)) + outfile.write("{\n") + with open(infile, "rb") as dataFile: + while True: + hexdata = dataFile.read(16).hex() + if len(hexdata) == 0: + break + hexlist = map("".join, zip(hexdata[::2], hexdata[1::2])) + outfile.write(" ") + for item in hexlist: + outfile.write("0x{}, ".format(item)) + outfile.write("\n") + outfile.write("};\n") + + outfile.write("const uint32_t {0}_SIZE = sizeof({0});\n\n".format(name)) + + +def _resolve_file_paths(args): + + # Convert all the file names to full paths. + global server_cert_file + global output_file + + output_file = _str_to_resolved_path(args.output) + server_cert_file = _str_to_resolved_path(args.server_cert) + + +def main(): + """Perform the main execution.""" + args = _parse_args() + + if args.name: + array_name = args.name + + _resolve_file_paths(args) + + if _sanity_check_files(args) is False: + sys.exit(2) + + if args.verbose: + print("\n\tGenerating {}.".format(output_file)) + print("\tInput file {}".format(server_cert_file)) + print("\tArray name {}".format(array_name)) + + with open(output_file, "w") as output_data: + output_data.write("#ifndef __{}_H\n".format(array_name)) + output_data.write("#define __{}_H\n".format(array_name)) + output_data.write("\n") + output_data.write("#include \n\n") + output_data.write("\n") + + _process_data( + server_cert_file, + output_data, + array_name, + args.verbose, + ) + output_data.write("\n") + output_data.write("#endif //__{}_H\n".format(array_name)) + print("File converted to {}".format(output_file)) + + +if __name__ == "__main__": + + sys.exit(main()) diff --git a/utils/dev_init.py b/utils/dev_init.py index ec330ff..3212ad8 100755 --- a/utils/dev_init.py +++ b/utils/dev_init.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # ---------------------------------------------------------------------------- -# Copyright 2020 ARM Limited or its affiliates +# Copyright 2022 Pelion Limited or its affiliates # # SPDX-License-Identifier: Apache-2.0 # diff --git a/utils/gen_update_image.py b/utils/gen_update_image.py new file mode 100755 index 0000000..d7b6449 --- /dev/null +++ b/utils/gen_update_image.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2019-2022 Pelion Ltd. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Generate the binary image to be used by FOTA.""" + +import struct +from time import time +import hashlib + + +def make_firmware_package(binary: bytes, + version: int): + """Given version and binary, Generate the FOTA binary image.""" + # Big endian. Fields: Magic, header size, version, FW size, FW hash + st_map = '>IIQI32s' + magic = 0x464F5441 # "FOTA" + header_size = struct.calcsize(st_map) + fw_size = len(binary) + hash = hashlib.sha256() + hash.update(binary) + meta = struct.pack( + st_map, + magic, + header_size, + version, + fw_size, + hash.digest()) + return meta + binary + + +if __name__ == '__main__': + import argparse + + parser = argparse.ArgumentParser( + description='Create firmware package from binary application image') + parser.add_argument('-i', '--in-file', + help='Raw binary application file name', + required=True) + parser.add_argument('-o', '--out-file', + help='Generated FOTA binary file name', + required=True) + parser.add_argument( + '-v', '--version', + type=int, + help='Firmware version (64 bit integer). Default: current epoch', + default=int(time())) + + args = parser.parse_args() + + with open(args.in_file, 'rb') as in_file, \ + open(args.out_file, 'wb') as out_file: + out_file.write(make_firmware_package(in_file.read(), + version=args.version)) diff --git a/west.yml b/west.yml index 0db8bff..1a5da68 100644 --- a/west.yml +++ b/west.yml @@ -1,18 +1,18 @@ manifest: self: - path: pelion-dm-example + path: izuma-dm-example remotes: - name: PelionIoT url-base: https://github.com/PelionIoT - name: zephyrproject-rtos url-base: https://github.com/zephyrproject-rtos projects: - - name: pelion-dm + - name: izuma-dm repo-path: mbed-cloud-client remote: PelionIoT - revision: 54282bc27ed9c404524e15a0de93dc9a59516f79 - path: modules/lib/pelion-dm + revision: bed292c4a7778cbc55ac01fc832e2469d439c7f1 + path: modules/lib/izuma-dm - name: zephyr remote: zephyrproject-rtos - revision: v2.6.0-rc1 + revision: zephyr-v2.7.3 import: true