From fc267441825e37233d62342ef715257ef674746c Mon Sep 17 00:00:00 2001 From: Jakub Zimnol Date: Fri, 16 Feb 2024 11:40:49 +0100 Subject: [PATCH] Anjay 3.7.0 Features - Added support for LwM2M 1.2 server object requirement for infinite lifetime (lifetime == 0). - Introduced @experimental and @deprecated Doxygen tags. - Added experimental IPSO objects v2 API. - Added experimental Software Management object API. Improvements - Improved integration tests compability and framework stability - Added support for wget2 for validating links in documentation (for HTTP/2 support) Bugfixes - Refactored generation of blockwise Confirmable notifications to avoid a possible assertion failure; requests for subsequent blocks of such notifications are now sent as Piggybacked responses - Fixed a bug in the documentation of an object definition struct - (commercial version only) Fixed problems with running some tests on systems with Mbed TLS 3.x - Fixed a few assertion and pointer punning issues regarding calls to IPSO objects APIs in erroneous cases - Prevent from trying to store empty cert/keys on HSM --- .github/workflows/anjay-tests.yml | 2 +- .github/workflows/coverity.yml | 2 +- CHANGELOG.md | 30 + CMakeLists.txt | 21 +- CONTRIBUTING.rst | 2 +- Dockerfile | 2 +- Doxyfile.in | 2 +- NOTICE | 2 +- cmake/anjay-config.cmake.in | 2 +- cmake/anjay-version.cmake.in | 2 +- cmake/sphinx.cmake | 2 +- cmake/toolchain/afl-gcc.cmake | 2 +- covconfig | 2 +- demo/CMakeLists.txt | 10 +- demo/advanced_firmware_update.c | 22 +- demo/advanced_firmware_update.h | 2 +- demo/advanced_firmware_update_addimg.c | 2 +- demo/advanced_firmware_update_app.c | 2 +- demo/demo.c | 35 +- demo/demo.h | 10 +- demo/demo_args.c | 280 +- demo/demo_args.h | 36 +- demo/demo_cmds.c | 81 +- demo/demo_cmds.h | 2 +- demo/demo_time.c | 2 +- demo/demo_utils.c | 2 +- demo/demo_utils.h | 2 +- demo/firmware_update.c | 22 +- demo/firmware_update.h | 2 +- demo/objects.h | 4 +- demo/objects/apn_conn_profile.c | 2 +- demo/objects/binary_app_data_container.c | 2 +- demo/objects/cell_connectivity.c | 2 +- demo/objects/conn_monitoring.c | 2 +- demo/objects/conn_statistics.c | 2 +- demo/objects/device.c | 2 +- demo/objects/download_diagnostics.c | 2 +- demo/objects/event_log.c | 2 +- demo/objects/ext_dev_info.c | 2 +- demo/objects/geopoints.c | 2 +- demo/objects/ip_ping.c | 2 +- demo/objects/ipso_objects.c | 94 +- demo/objects/location.c | 2 +- demo/objects/portfolio.c | 2 +- demo/objects/test.c | 5 +- demo/software_mgmt.c | 939 ++++++ demo/software_mgmt.h | 68 + deps/avs_coap/CMakeLists.txt | 2 +- deps/avs_coap/NOTICE | 2 +- .../cmake/AddHeaderSelfSufficiencyTests.cmake | 2 +- deps/avs_coap/cmake/avs_coap-config.cmake.in | 2 +- deps/avs_coap/cmake/fill-placeholders.cmake | 4 +- deps/avs_coap/devconfig | 2 +- deps/avs_coap/doc/CMakeLists.txt | 2 +- .../doc/sphinx/source/ErrorHandling.rst | 2 +- deps/avs_coap/doc/sphinx/source/Fuzzing.rst | 2 +- deps/avs_coap/doc/sphinx/source/Overview.rst | 2 +- .../sphinx/source/_static/theme_overrides.css | 2 +- deps/avs_coap/doc/sphinx/source/conf.py.in | 2 +- deps/avs_coap/doc/sphinx/source/index.rst | 2 +- deps/avs_coap/examples/CMakeLists.txt | 2 +- .../examples/async-client/CMakeLists.txt | 2 +- .../avs_coap/examples/async-client/src/main.c | 2 +- .../include_public/avsystem/coap/async.h | 2 +- .../avsystem/coap/async_client.h | 2 +- .../avsystem/coap/async_exchange.h | 2 +- .../avsystem/coap/async_server.h | 2 +- .../avsystem/coap/avs_coap_config.h.in | 2 +- .../include_public/avsystem/coap/coap.h | 2 +- .../include_public/avsystem/coap/code.h | 2 +- .../include_public/avsystem/coap/ctx.h | 2 +- .../include_public/avsystem/coap/observe.h | 2 +- .../include_public/avsystem/coap/option.h | 2 +- .../include_public/avsystem/coap/streaming.h | 2 +- .../include_public/avsystem/coap/tcp.h | 2 +- .../include_public/avsystem/coap/token.h | 2 +- .../include_public/avsystem/coap/udp.h | 2 +- .../include_public/avsystem/coap/writer.h | 2 +- .../src/async/avs_coap_async_client.c | 2 +- .../src/async/avs_coap_async_client.h | 2 +- .../src/async/avs_coap_async_server.c | 47 +- .../src/async/avs_coap_async_server.h | 8 +- deps/avs_coap/src/async/avs_coap_exchange.c | 2 +- deps/avs_coap/src/async/avs_coap_exchange.h | 2 +- deps/avs_coap/src/avs_coap_code_utils.c | 2 +- deps/avs_coap/src/avs_coap_code_utils.h | 2 +- deps/avs_coap/src/avs_coap_common_utils.c | 8 +- deps/avs_coap/src/avs_coap_common_utils.h | 2 +- deps/avs_coap/src/avs_coap_ctx.c | 2 +- deps/avs_coap/src/avs_coap_ctx.h | 2 +- deps/avs_coap/src/avs_coap_ctx_vtable.h | 2 +- deps/avs_coap/src/avs_coap_init.h | 2 +- deps/avs_coap/src/avs_coap_observe.c | 6 +- deps/avs_coap/src/avs_coap_observe.h | 2 +- deps/avs_coap/src/avs_coap_parse_utils.h | 2 +- deps/avs_coap/src/avs_coap_poison.h | 2 +- deps/avs_coap/src/avs_coap_x_log_config.h | 5 +- deps/avs_coap/src/options/avs_coap_iterator.c | 2 +- deps/avs_coap/src/options/avs_coap_iterator.h | 2 +- deps/avs_coap/src/options/avs_coap_option.c | 2 +- deps/avs_coap/src/options/avs_coap_option.h | 2 +- deps/avs_coap/src/options/avs_coap_options.c | 4 +- deps/avs_coap/src/options/avs_coap_options.h | 2 +- .../src/streaming/avs_coap_streaming_client.c | 4 +- .../src/streaming/avs_coap_streaming_client.h | 2 +- .../src/streaming/avs_coap_streaming_server.c | 2 +- .../src/streaming/avs_coap_streaming_server.h | 2 +- deps/avs_coap/src/tcp/avs_coap_tcp_ctx.c | 2 +- deps/avs_coap/src/tcp/avs_coap_tcp_ctx.h | 2 +- deps/avs_coap/src/tcp/avs_coap_tcp_header.c | 2 +- deps/avs_coap/src/tcp/avs_coap_tcp_header.h | 2 +- deps/avs_coap/src/tcp/avs_coap_tcp_msg.c | 2 +- deps/avs_coap/src/tcp/avs_coap_tcp_msg.h | 2 +- .../src/tcp/avs_coap_tcp_pending_requests.c | 4 +- .../src/tcp/avs_coap_tcp_pending_requests.h | 2 +- .../avs_coap/src/tcp/avs_coap_tcp_signaling.c | 2 +- .../avs_coap/src/tcp/avs_coap_tcp_signaling.h | 2 +- deps/avs_coap/src/tcp/avs_coap_tcp_utils.c | 2 +- deps/avs_coap/src/tcp/avs_coap_tcp_utils.h | 2 +- deps/avs_coap/src/udp/avs_coap_udp_ctx.c | 2 +- deps/avs_coap/src/udp/avs_coap_udp_ctx.h | 2 +- deps/avs_coap/src/udp/avs_coap_udp_header.h | 2 +- deps/avs_coap/src/udp/avs_coap_udp_msg.c | 2 +- deps/avs_coap/src/udp/avs_coap_udp_msg.h | 2 +- .../avs_coap/src/udp/avs_coap_udp_msg_cache.c | 4 +- .../avs_coap/src/udp/avs_coap_udp_msg_cache.h | 2 +- .../avs_coap/src/udp/avs_coap_udp_tx_params.c | 2 +- .../avs_coap/src/udp/avs_coap_udp_tx_params.h | 2 +- deps/avs_coap/tests/fuzz/CMakeLists.txt | 2 +- deps/avs_coap/tests/fuzz/coap_async_api_tcp.c | 2 +- deps/avs_coap/tests/fuzz/coap_async_api_udp.c | 2 +- deps/avs_coap/tests/fuzz/coap_parse.c | 2 +- deps/avs_coap/tests/mock_clock.c | 2 +- deps/avs_coap/tests/mock_clock.h | 2 +- deps/avs_coap/tests/options/option.c | 2 +- deps/avs_coap/tests/options/options.c | 2 +- deps/avs_coap/tests/socket.c | 2 +- deps/avs_coap/tests/socket.h | 2 +- deps/avs_coap/tests/tcp/async_client.c | 2 +- deps/avs_coap/tests/tcp/async_server.c | 2 +- deps/avs_coap/tests/tcp/csm.c | 2 +- deps/avs_coap/tests/tcp/ctx.c | 2 +- deps/avs_coap/tests/tcp/env.h | 2 +- deps/avs_coap/tests/tcp/header.c | 2 +- deps/avs_coap/tests/tcp/helper_functions.h | 2 +- deps/avs_coap/tests/tcp/payload_escaper.c | 2 +- deps/avs_coap/tests/tcp/requesting.c | 2 +- deps/avs_coap/tests/tcp/responding.c | 2 +- deps/avs_coap/tests/tcp/setsock.c | 2 +- deps/avs_coap/tests/tcp/utils.h | 2 +- deps/avs_coap/tests/udp/async_client.c | 2 +- .../tests/udp/async_client_with_big_data.c | 2 +- deps/avs_coap/tests/udp/async_observe.c | 2 +- deps/avs_coap/tests/udp/async_server.c | 2 +- deps/avs_coap/tests/udp/big_data.h | 2 +- deps/avs_coap/tests/udp/fuzzer_cases.c | 2 +- deps/avs_coap/tests/udp/msg.c | 2 +- deps/avs_coap/tests/udp/msg_cache.c | 2 +- deps/avs_coap/tests/udp/setsock.c | 2 +- deps/avs_coap/tests/udp/streaming_client.c | 2 +- deps/avs_coap/tests/udp/streaming_observe.c | 103 +- deps/avs_coap/tests/udp/streaming_server.c | 2 +- deps/avs_coap/tests/udp/tx_params_mock.h | 2 +- deps/avs_coap/tests/udp/udp_tx_params.c | 2 +- deps/avs_coap/tests/udp/utils.h | 2 +- deps/avs_coap/tests/utils.c | 2 +- deps/avs_coap/tests/utils.h | 2 +- deps/avs_coap/tools/avs_common.py | 2 +- deps/avs_coap/tools/license_headers.py | 4 +- deps/avs_commons | 2 +- devconfig | 3 +- doc/CMakeLists.txt | 2 +- doc/sphinx/extensions/builders/__init__.py | 2 +- doc/sphinx/extensions/builders/dummy.py | 2 +- .../builders/snippet_source_linter.py | 2 +- .../snippet_source_list_references.py | 2 +- .../extensions/file_dirtiness_checker.py | 2 +- doc/sphinx/extensions/snippet_source.py | 2 +- doc/sphinx/snippet_sources.md5 | 50 +- doc/sphinx/source/AdvancedTopics.rst | 2 +- .../AdvancedTopics/AT-AccessControl.rst | 2 +- .../AdvancedTopics/AT-AttributeStorage.rst | 2 +- .../source/AdvancedTopics/AT-Certificates.rst | 2 +- .../AdvancedTopics/AT-CustomEventLoop.rst | 2 +- .../AdvancedTopics/AT-CustomObjects.rst | 7 +- .../AT_CO1_SingleInstanceReadOnly.rst | 2 +- ...O2_SingleInstanceExecutableAndReadOnly.rst | 2 +- .../AT_CO3_MultiInstanceReadOnlyFixed.rst | 2 +- .../AT_CO4_FixedInstanceWritable.rst | 2 +- .../AT_CO5_MultiInstanceDynamic.rst | 2 +- .../AT_CO6_MultipleResourceInstances.rst | 2 +- .../AT_CO7_BootstrapAwareness.rst | 2 +- .../AT_CO_BootstrapAwareness.rst | 2 +- .../AT_CO_FixedInstanceWritable.rst | 2 +- .../AT_CO_MultiInstanceDynamic.rst | 2 +- .../AT_CO_MultiInstanceReadOnlyFixed.rst | 2 +- .../AT_CO_MultipleResourceInstances.rst | 2 +- ...CO_SingleInstanceExecutableAndReadOnly.rst | 2 +- .../AT_CO_SingleInstanceReadOnly.rst | 2 +- .../AT-CustomObjects/Anjay_codegen_note.rst | 2 +- .../AdvancedTopics/AT-EventLoopNotes.rst | 2 +- .../source/AdvancedTopics/AT-IpsoObjects.rst | 648 ++-- .../AT-NetworkErrorHandling.rst | 2 +- .../AdvancedTopics/AT-OtherFeatures.rst | 2 +- .../source/AdvancedTopics/AT-Persistence.rst | 2 +- .../AT-RetransmissionsTimeoutsCaching.rst | 2 +- doc/sphinx/source/BasicClient.rst | 2 +- .../source/BasicClient/BC-Initialization.rst | 2 +- .../BasicClient/BC-MandatoryObjects.rst | 2 +- .../source/BasicClient/BC-Notifications.rst | 2 +- .../BasicClient/BC-ObjectImplementation.rst | 2 +- doc/sphinx/source/BasicClient/BC-Security.rst | 2 +- doc/sphinx/source/BasicClient/BC-Send.rst | 2 +- .../source/BasicClient/BC-ThreadSafety.rst | 2 +- doc/sphinx/source/BasicClient/BC1.rst | 2 +- doc/sphinx/source/BasicClient/BC2.rst | 2 +- doc/sphinx/source/BasicClient/BC3.rst | 2 +- doc/sphinx/source/BasicClient/BC4.rst | 2 +- doc/sphinx/source/BasicClient/BC5.rst | 2 +- doc/sphinx/source/BasicClient/BC6.rst | 2 +- doc/sphinx/source/BasicClient/BC7.rst | 2 +- doc/sphinx/source/BasicClient/BC8.rst | 2 +- doc/sphinx/source/CommercialFeatures.rst | 2 +- .../CommercialFeatures/CF-CorePersistence.rst | 2 +- .../CF-CustomHardwareSupport.rst | 2 +- .../source/CommercialFeatures/CF-EST.rst | 8 +- .../source/CommercialFeatures/CF-FSDM.rst | 2 +- .../source/CommercialFeatures/CF-HSM.rst | 2 +- .../source/CommercialFeatures/CF-IoTSAFE.rst | 2 +- .../source/CommercialFeatures/CF-NIDD.rst | 2 +- .../source/CommercialFeatures/CF-OSCORE.rst | 2 +- .../CommercialFeatures/CF-SMSBinding.rst | 2 +- .../CF-SmartCardBootstrap.rst | 2 +- .../source/Compiling_client_applications.rst | 2 +- doc/sphinx/source/FirmwareUpdateTutorial.rst | 2 +- .../FU-AdvancedFirmwareUpdate.rst | 2 +- .../FU-AFU-BasicImplementation.rst | 2 +- .../FU-AFU-Examples.rst | 2 +- .../FU-AFU-ResourceDefinitions.rst | 2 +- .../FU-AFU-StateDiagram.rst | 2 +- .../_files/33629.xml | 2 +- .../FU-BasicImplementation.rst | 2 +- .../FU-DownloadResumption.rst | 2 +- .../FU-Introduction.rst | 4 +- .../FU-ModesAndProtocols.rst | 2 +- .../FU-PoorConnectivity.rst | 2 +- .../FU-SecureDownloads.rst | 4 +- .../source/FirmwareUpdateTutorial/FU1.rst | 2 +- .../source/FirmwareUpdateTutorial/FU2.rst | 2 +- .../source/FirmwareUpdateTutorial/FU3.rst | 2 +- .../source/FirmwareUpdateTutorial/FU4.rst | 2 +- .../source/FirmwareUpdateTutorial/FU5.rst | 2 +- .../source/FirmwareUpdateTutorial/FU6.rst | 2 +- doc/sphinx/source/Introduction.rst | 13 +- doc/sphinx/source/LwM2M.rst | 2 +- doc/sphinx/source/Migrating.rst | 2 +- .../Migrating/MigratingCustomEntropy.rst | 2 +- .../Migrating/MigratingFromAnjay214.rst | 2 +- .../Migrating/MigratingFromAnjay215.rst | 2 +- .../Migrating/MigratingFromAnjay225.rst | 2 +- .../source/Migrating/MigratingFromAnjay24.rst | 2 +- .../source/Migrating/MigratingFromAnjay26.rst | 2 +- .../source/Migrating/MigratingFromAnjay27.rst | 2 +- .../source/Migrating/MigratingFromAnjay28.rst | 2 +- .../source/Migrating/MigratingFromAnjay30.rst | 2 +- .../source/Migrating/MigratingFromAnjay32.rst | 2 +- .../source/Migrating/MigratingFromAnjay33.rst | 2 +- .../source/Migrating/MigratingFromAnjay34.rst | 2 +- .../PortingGuideForNonPOSIXPlatforms.rst | 2 +- .../CustomTLS.rst | 2 +- .../CustomTLS-CertificatesAdvanced.rst | 2 +- .../CustomTLS/CustomTLS-CertificatesBasic.rst | 2 +- .../CustomTLS/CustomTLS-ConfigFeatures.rst | 2 +- .../CustomTLS/CustomTLS-Minimal.rst | 2 +- .../CustomTLS/CustomTLS-Resumption.rst | 2 +- .../CustomTLS/CustomTLS-Stub.rst | 2 +- .../CustomTLS/CustomTLS-TCPSupport.rst | 2 +- .../NetworkingAPI.rst | 2 +- .../NetworkingAPI/NetworkingAPI-Bind.rst | 2 +- .../NetworkingAPI-EventLoopSupport.rst | 2 +- .../NetworkingAPI-IpStickiness.rst | 2 +- .../NetworkingAPI/NetworkingAPI-Minimal.rst | 2 +- .../NetworkingAPI-OtherFeatures.rst | 2 +- .../NetworkingAPI-RemoteHostPort.rst | 2 +- .../NetworkingAPI-ShutdownRemoteHostname.rst | 2 +- .../NetworkingAPI/NetworkingAPI-Stats.rst | 2 +- .../NetworkingAPI/NetworkingAPI1.rst | 2 +- .../NetworkingAPI/NetworkingAPI2.rst | 2 +- .../NetworkingAPI/NetworkingAPI3.rst | 2 +- .../NetworkingAPI/NetworkingAPI4.rst | 2 +- .../NetworkingAPI/NetworkingAPI5.rst | 2 +- .../NetworkingAPI/NetworkingAPI6.rst | 2 +- .../NetworkingAPI/NetworkingAPI7.rst | 2 +- .../ThreadingAPI.rst | 2 +- .../TimeAPI.rst | 2 +- doc/sphinx/source/Tools.rst | 2 +- doc/sphinx/source/Tools/CliLwM2MServer.rst | 2 +- .../source/Tools/FactoryProvisioning.rst | 2 +- doc/sphinx/source/Tools/StandaloneObjects.rst | 2 +- doc/sphinx/source/Tools/StubGenerator.rst | 2 +- doc/sphinx/source/_static/theme_overrides.css | 2 +- doc/sphinx/source/conf.py.in | 2 +- doc/sphinx/source/index.rst | 2 +- .../embedded_lwm2m10/anjay/anjay_config.h | 17 +- .../avsystem/coap/avs_coap_config.h | 2 +- .../avsystem/commons/avs_commons_config.h | 2 +- .../avsystem/commons/lwip-posix-compat.h | 2 +- .../embedded_lwm2m11/anjay/anjay_config.h | 17 +- .../avsystem/coap/avs_coap_config.h | 2 +- .../avsystem/commons/avs_commons_config.h | 2 +- .../avsystem/commons/lwip-posix-compat.h | 2 +- .../linux_lwm2m10/anjay/anjay_config.h | 17 +- .../avsystem/coap/avs_coap_config.h | 2 +- .../avsystem/commons/avs_commons_config.h | 2 +- .../linux_lwm2m11/anjay/anjay_config.h | 17 +- .../avsystem/coap/avs_coap_config.h | 2 +- .../avsystem/commons/avs_commons_config.h | 2 +- examples/CMakeLists.txt | 2 +- .../CF-EST-PKCS11/CMakeLists.txt | 15 +- .../CF-PKCS11/CMakeLists.txt | 15 +- .../tutorial/AT-IpsoObjects/CMakeLists.txt | 10 + examples/tutorial/AT-IpsoObjects/src/main.c | 212 ++ examples/tutorial/CMakeLists.txt | 1 + include_public/anjay/access_control.h | 2 +- include_public/anjay/advanced_fw_update.h | 19 +- include_public/anjay/anjay.h | 2 +- include_public/anjay/anjay_config.h.in | 17 +- include_public/anjay/attr_storage.h | 2 +- include_public/anjay/core.h | 62 +- include_public/anjay/dm.h | 7 +- include_public/anjay/download.h | 4 +- include_public/anjay/factory_provisioning.h | 2 +- include_public/anjay/fw_update.h | 7 +- include_public/anjay/io.h | 2 +- include_public/anjay/ipso_objects.h | 2 +- include_public/anjay/ipso_objects_v2.h | 316 ++ include_public/anjay/lwm2m_send.h | 2 +- include_public/anjay/security.h | 2 +- include_public/anjay/server.h | 2 +- include_public/anjay/stats.h | 2 +- include_public/anjay/sw_mgmt.h | 1122 +++++++ ltoconfig | 2 +- requirements.txt | 3 +- src/anjay_config_log.h | 12 +- src/anjay_init.h | 2 +- src/anjay_modules/anjay_access_utils.h | 2 +- src/anjay_modules/anjay_bootstrap.h | 2 +- src/anjay_modules/anjay_dm_utils.h | 2 +- src/anjay_modules/anjay_io_utils.h | 2 +- src/anjay_modules/anjay_notify.h | 2 +- src/anjay_modules/anjay_raw_buffer.h | 2 +- src/anjay_modules/anjay_sched.h | 2 +- src/anjay_modules/anjay_servers.h | 2 +- src/anjay_modules/anjay_time_defs.h | 2 +- src/anjay_modules/anjay_utils_core.h | 2 +- src/anjay_modules/dm/anjay_execute.h | 2 +- src/anjay_modules/dm/anjay_modules.h | 18 +- src/core/anjay_access_utils.c | 2 +- src/core/anjay_access_utils_private.h | 2 +- src/core/anjay_bootstrap_core.c | 2 +- src/core/anjay_bootstrap_core.h | 2 +- src/core/anjay_core.c | 4 +- src/core/anjay_core.h | 2 +- src/core/anjay_dm_core.c | 2 +- src/core/anjay_dm_core.h | 2 +- src/core/anjay_downloader.h | 2 +- src/core/anjay_event_loop.c | 2 +- src/core/anjay_io_core.c | 2 +- src/core/anjay_io_core.h | 2 +- src/core/anjay_io_utils.c | 2 +- src/core/anjay_lwm2m_send.c | 2 +- src/core/anjay_lwm2m_send.h | 2 +- src/core/anjay_notify.c | 2 +- src/core/anjay_raw_buffer.c | 2 +- src/core/anjay_servers_inactive.h | 2 +- src/core/anjay_servers_private.h | 2 +- src/core/anjay_servers_reload.h | 2 +- src/core/anjay_servers_utils.c | 33 +- src/core/anjay_servers_utils.h | 12 +- src/core/anjay_stats.c | 2 +- src/core/anjay_stats.h | 2 +- src/core/anjay_utils_core.c | 6 +- src/core/anjay_utils_private.h | 2 +- src/core/attr_storage/anjay_attr_storage.c | 2 +- src/core/attr_storage/anjay_attr_storage.h | 2 +- .../anjay_attr_storage_persistence.c | 2 +- .../attr_storage/anjay_attr_storage_private.h | 2 +- src/core/coap/anjay_content_format.h | 2 +- src/core/coap/anjay_msg_details.h | 2 +- src/core/dm/anjay_discover.c | 2 +- src/core/dm/anjay_discover.h | 2 +- src/core/dm/anjay_dm_attributes.c | 2 +- src/core/dm/anjay_dm_attributes.h | 2 +- src/core/dm/anjay_dm_create.c | 2 +- src/core/dm/anjay_dm_create.h | 2 +- src/core/dm/anjay_dm_execute.c | 2 +- src/core/dm/anjay_dm_execute.h | 2 +- src/core/dm/anjay_dm_handlers.c | 2 +- src/core/dm/anjay_dm_read.c | 2 +- src/core/dm/anjay_dm_read.h | 2 +- src/core/dm/anjay_dm_write.c | 2 +- src/core/dm/anjay_dm_write.h | 2 +- src/core/dm/anjay_dm_write_attrs.c | 2 +- src/core/dm/anjay_dm_write_attrs.h | 2 +- src/core/dm/anjay_modules.c | 2 +- src/core/dm/anjay_query.c | 2 +- src/core/dm/anjay_query.h | 2 +- src/core/downloader/anjay_coap.c | 2 +- src/core/downloader/anjay_downloader.c | 2 +- src/core/downloader/anjay_http.c | 2 +- src/core/downloader/anjay_private.h | 2 +- src/core/io/anjay_base64_out.c | 2 +- src/core/io/anjay_base64_out.h | 2 +- src/core/io/anjay_batch_builder.c | 2 +- src/core/io/anjay_batch_builder.h | 2 +- src/core/io/anjay_cbor_in.c | 2 +- src/core/io/anjay_cbor_out.c | 2 +- src/core/io/anjay_common.c | 2 +- src/core/io/anjay_common.h | 2 +- src/core/io/anjay_dynamic.c | 2 +- src/core/io/anjay_input_buf.c | 2 +- src/core/io/anjay_json_encoder.c | 2 +- src/core/io/anjay_json_like_decoder.c | 2 +- src/core/io/anjay_json_like_decoder.h | 2 +- src/core/io/anjay_json_like_decoder_vtable.h | 2 +- src/core/io/anjay_opaque.c | 2 +- src/core/io/anjay_output_buf.c | 2 +- src/core/io/anjay_senml_in.c | 2 +- src/core/io/anjay_senml_like_encoder.c | 2 +- src/core/io/anjay_senml_like_encoder.h | 2 +- src/core/io/anjay_senml_like_encoder_vtable.h | 2 +- src/core/io/anjay_senml_like_out.c | 2 +- src/core/io/anjay_text.c | 2 +- src/core/io/anjay_tlv.h | 2 +- src/core/io/anjay_tlv_in.c | 2 +- src/core/io/anjay_tlv_out.c | 2 +- src/core/io/anjay_vtable.h | 2 +- src/core/io/cbor/anjay_cbor_encoder_ll.c | 2 +- src/core/io/cbor/anjay_cbor_encoder_ll.h | 2 +- src/core/io/cbor/anjay_cbor_types.h | 2 +- .../io/cbor/anjay_json_like_cbor_decoder.c | 2 +- .../io/cbor/anjay_json_like_cbor_decoder.h | 2 +- src/core/io/cbor/anjay_senml_cbor_encoder.c | 2 +- src/core/io/json/anjay_json_decoder.c | 2 +- src/core/io/json/anjay_json_decoder.h | 2 +- src/core/observe/anjay_observe_core.c | 2 +- src/core/observe/anjay_observe_core.h | 2 +- src/core/observe/anjay_observe_internal.h | 2 +- src/core/observe/anjay_observe_planning.c | 2 +- src/core/servers/anjay_activate.c | 3 +- src/core/servers/anjay_activate.h | 2 +- src/core/servers/anjay_connection_ip.c | 2 +- src/core/servers/anjay_connections.c | 2 +- src/core/servers/anjay_connections.h | 2 +- src/core/servers/anjay_connections_internal.h | 2 +- src/core/servers/anjay_register.c | 37 +- src/core/servers/anjay_register.h | 2 +- src/core/servers/anjay_reload.c | 2 +- src/core/servers/anjay_security.h | 2 +- src/core/servers/anjay_security_generic.c | 2 +- src/core/servers/anjay_server_connections.c | 2 +- src/core/servers/anjay_server_connections.h | 2 +- src/core/servers/anjay_servers_internal.c | 2 +- src/core/servers/anjay_servers_internal.h | 2 +- .../anjay_access_control_handlers.c | 6 +- .../anjay_access_control_persistence.c | 2 +- .../access_control/anjay_mod_access_control.c | 2 +- .../access_control/anjay_mod_access_control.h | 2 +- .../anjay_advanced_fw_update.c | 6 +- .../factory_provisioning/anjay_provisioning.c | 2 +- src/modules/fw_update/anjay_fw_update.c | 5 +- src/modules/ipso/anjay_ipso_3d_sensor.c | 20 +- src/modules/ipso/anjay_ipso_basic_sensor.c | 20 +- src/modules/ipso/anjay_ipso_button.c | 20 +- src/modules/ipso_v2/anjay_ipso_v2_3d_sensor.c | 671 ++++ .../ipso_v2/anjay_ipso_v2_basic_sensor.c | 485 +++ src/modules/security/anjay_mod_security.c | 5 +- src/modules/security/anjay_mod_security.h | 2 +- .../security/anjay_security_persistence.c | 2 +- .../security/anjay_security_transaction.c | 2 +- .../security/anjay_security_transaction.h | 2 +- src/modules/security/anjay_security_utils.c | 2 +- src/modules/security/anjay_security_utils.h | 2 +- src/modules/server/anjay_mod_server.c | 6 +- src/modules/server/anjay_mod_server.h | 2 +- src/modules/server/anjay_server_persistence.c | 2 +- src/modules/server/anjay_server_transaction.c | 8 +- src/modules/server/anjay_server_transaction.h | 2 +- src/modules/server/anjay_server_utils.c | 2 +- src/modules/server/anjay_server_utils.h | 2 +- src/modules/sw_mgmt/anjay_sw_mgmt.c | 1644 ++++++++++ standalone/security/standalone_mod_security.c | 1 - .../standalone_security_transaction.c | 3 +- standalone/server/standalone_mod_server.c | 1 - .../server/standalone_server_transaction.c | 6 +- tests/codegen/CMakeLists.txt | 2 +- tests/codegen/check_with_object_registry.sh | 2 +- tests/codegen/input/execute.xml | 2 +- tests/codegen/input/multiple-object.xml | 2 +- tests/codegen/input/read.xml | 2 +- tests/codegen/input/sanitization.xml | 2 +- tests/codegen/input/write.xml | 2 +- tests/core/anjay.c | 2 +- tests/core/attr_storage/attr_storage.c | 2 +- tests/core/attr_storage/attr_storage_test.h | 2 +- tests/core/attr_storage/persistence.c | 2 +- tests/core/bootstrap.c | 2 +- tests/core/bootstrap_mock.h | 2 +- tests/core/coap/utils.c | 2 +- tests/core/coap/utils.h | 2 +- tests/core/dm.c | 2 +- tests/core/downloader/downloader.c | 2 +- tests/core/io.c | 2 +- tests/core/io/batch_builder.c | 2 +- tests/core/io/bigdata.h | 2 +- tests/core/io/cbor/cbor_decoder.c | 2 +- tests/core/io/cbor/cbor_encoder.c | 2 +- tests/core/io/cbor_in.c | 2 +- tests/core/io/dm_batch.c | 2 +- tests/core/io/dynamic.c | 2 +- tests/core/io/json/json_decoder.c | 2 +- tests/core/io/json_in.c | 2 +- tests/core/io/raw_cbor_in.c | 2 +- tests/core/io/senml_cbor_encoder.c | 2 +- tests/core/io/senml_in_common.h | 2 +- tests/core/io/senml_json_encoder.c | 2 +- tests/core/io/text.c | 2 +- tests/core/io/tlv_in.c | 2 +- tests/core/io/tlv_out.c | 2 +- tests/core/lwm2m_send.c | 2 +- tests/core/observe/observe.c | 2 +- tests/core/observe/observe_mock.h | 2 +- tests/core/socket_mock.c | 2 +- tests/core/socket_mock.h | 2 +- tests/core/utils.c | 8 +- tests/doc/runtest.py | 122 +- tests/fuzz/CMakeLists.txt | 2 +- tests/fuzz/cbor/decoder.c | 2 +- tests/integration/CMakeLists.txt | 2 +- tests/integration/framework/__init__.py | 2 +- tests/integration/framework/asserts.py | 2 +- .../integration/framework/coap_file_server.py | 2 +- .../framework/create_xlsx_test_report.py | 2 +- .../integration/framework/firmware_package.py | 8 +- tests/integration/framework/lwm2m/__init__.py | 2 +- .../framework/lwm2m/coap/__init__.py | 2 +- .../integration/framework/lwm2m/coap/code.py | 2 +- .../framework/lwm2m/coap/content_format.py | 2 +- .../framework/lwm2m/coap/option.py | 2 +- .../framework/lwm2m/coap/packet.py | 2 +- .../framework/lwm2m/coap/server.py | 2 +- .../framework/lwm2m/coap/transport.py | 2 +- .../integration/framework/lwm2m/coap/type.py | 2 +- .../integration/framework/lwm2m/coap/utils.py | 2 +- tests/integration/framework/lwm2m/messages.py | 2 +- tests/integration/framework/lwm2m/path.py | 2 +- .../integration/framework/lwm2m/senml_cbor.py | 2 +- tests/integration/framework/lwm2m/server.py | 2 +- tests/integration/framework/lwm2m/tlv.py | 2 +- tests/integration/framework/lwm2m_test.py | 2 +- .../framework/nsh-lwm2m/cbor_shell.py | 2 +- .../framework/nsh-lwm2m/nsh_lwm2m.py | 2 +- .../framework/nsh-lwm2m/pymbedtls/setup.py | 2 +- .../nsh-lwm2m/pymbedtls/src/common.cpp | 2 +- .../nsh-lwm2m/pymbedtls/src/common.hpp | 2 +- .../nsh-lwm2m/pymbedtls/src/context.cpp | 2 +- .../nsh-lwm2m/pymbedtls/src/context.hpp | 2 +- .../pymbedtls/src/pybind11_interop.hpp | 2 +- .../nsh-lwm2m/pymbedtls/src/pymbedtls.cpp | 2 +- .../nsh-lwm2m/pymbedtls/src/security.cpp | 2 +- .../nsh-lwm2m/pymbedtls/src/security.hpp | 2 +- .../nsh-lwm2m/pymbedtls/src/socket.cpp | 2 +- .../nsh-lwm2m/pymbedtls/src/socket.hpp | 2 +- .../framework/nsh-lwm2m/tlv_shell.py | 2 +- .../framework/pretty_test_runner.py | 2 +- .../framework/serialize_senml_cbor.py | 2 +- tests/integration/framework/test_suite.py | 5 +- tests/integration/framework/test_utils.py | 25 +- tests/integration/run_tests.sh.in | 2 +- tests/integration/runtest.py | 2 +- tests/integration/suites/__init__.py | 2 +- tests/integration/suites/default/__init__.py | 2 +- .../suites/default/access_control.py | 26 +- .../default/advanced_firmware_update.py | 27 +- tests/integration/suites/default/async.py | 2 +- .../suites/default/block_response.py | 2 +- .../integration/suites/default/block_write.py | 8 +- .../suites/default/bootstrap_client.py | 2 +- .../suites/default/bootstrap_discover.py | 2 +- .../suites/default/bootstrap_factory.py | 2 +- .../suites/default/bootstrap_server.py | 2 +- .../suites/default/bootstrap_sync.py | 2 +- .../suites/default/bootstrap_transaction.py | 2 +- .../suites/default/buffer_sizes.py | 2 +- .../suites/default/cbor_encoding.py | 2 +- .../suites/default/cbor_requests.py | 2 +- .../suites/default/client_block_request.py | 2 +- tests/integration/suites/default/coap.py | 2 +- tests/integration/suites/default/con_attr.py | 2 +- .../suites/default/connection_id.py | 2 +- tests/integration/suites/default/crash.py | 34 +- tests/integration/suites/default/create.py | 2 +- .../suites/default/critical_opts.py | 2 +- .../suites/default/disable_server.py | 2 +- .../integration/suites/default/downloader.py | 2 +- .../suites/default/factory_provisioning.py | 2 +- .../suites/default/firmware_update.py | 480 +-- .../suites/default/forbidden_on_register.py | 2 +- tests/integration/suites/default/formats.py | 2 +- .../default/hierarchical_cbor_encoding.py | 2 +- .../suites/default/ipso_objects.py | 14 +- .../suites/default/json_encoding.py | 4 +- .../suites/default/json_requests.py | 2 +- .../suites/default/modify_servers.py | 2 +- tests/integration/suites/default/msg_cache.py | 2 +- .../suites/default/notification_timestamps.py | 2 +- .../suites/default/notifications.py | 2 +- .../suites/default/observe_attributes.py | 2 +- tests/integration/suites/default/offline.py | 2 +- .../suites/default/plaintext_base64.py | 8 +- .../integration/suites/default/port_rebind.py | 37 +- .../integration/suites/default/queue_mode.py | 2 +- .../suites/default/read_composite.py | 2 +- tests/integration/suites/default/reboot.py | 2 +- tests/integration/suites/default/register.py | 7 +- .../suites/default/request_too_large.py | 2 +- .../suites/default/retransmissions.py | 2 +- tests/integration/suites/default/security.py | 2 +- tests/integration/suites/default/send.py | 2 +- .../suites/default/senml_json_encoding.py | 2 +- .../suites/default/separate_response.py | 2 +- .../suites/default/software_mgmt.py | 2733 +++++++++++++++++ tests/integration/suites/default/stats.py | 2 +- .../integration/suites/default/test_object.py | 2 +- tests/integration/suites/default/time_api.py | 7 +- .../integration/suites/default/unregister.py | 2 +- tests/integration/suites/default/update.py | 2 +- .../suites/default/uri_change_reregister.py | 2 +- .../suites/default/write_composite.py | 2 +- .../integration/suites/sensitive/__init__.py | 2 +- .../sensitive/advanced_firmware_update.py | 2 +- .../suites/sensitive/bootstrap_client.py | 2 +- .../suites/sensitive/firmware_update.py | 7 +- tests/integration/suites/sensitive/update.py | 2 +- tests/integration/suites/testfest/__init__.py | 2 +- .../integration/suites/testfest/bootstrap.py | 2 +- .../suites/testfest/dm/__init__.py | 2 +- .../testfest/dm/advanced_firmware_update.py | 2 +- .../testfest/dm/connectivity_management.py | 2 +- .../testfest/dm/connectivity_monitoring.py | 2 +- .../testfest/dm/connectivity_statistics.py | 2 +- .../integration/suites/testfest/dm/device.py | 2 +- .../suites/testfest/dm/firmware_update.py | 2 +- .../suites/testfest/dm/location.py | 2 +- .../suites/testfest/dm/portfolio.py | 2 +- tests/integration/suites/testfest/dm/utils.py | 2 +- .../integration/suites/testfest/management.py | 2 +- .../suites/testfest/multi_servers.py | 2 +- tests/integration/suites/testfest/register.py | 2 +- .../integration/suites/testfest/reporting.py | 2 +- tests/integration/suites/testfest/security.py | 2 +- tests/modules/access_control/access_control.c | 2 +- tests/modules/access_control/persistence.c | 2 +- .../factory_provisioning/provisioning.c | 2 +- tests/modules/security/api.c | 2 +- tests/modules/security/persistence.c | 2 +- tests/modules/server/api.c | 19 +- tests/modules/server/persistence.c | 2 +- tests/utils/coap/socket.c | 2 +- tests/utils/coap/socket.h | 2 +- tests/utils/dm.c | 2 +- tests/utils/dm.h | 2 +- tests/utils/mock_clock.c | 2 +- tests/utils/mock_clock.h | 2 +- tests/utils/mock_dm.c | 2 +- tests/utils/mock_dm.h | 2 +- tests/utils/utils.h | 2 +- tools/analyze | 4 +- tools/anjay_codegen.py | 2 +- tools/anjay_config_log_tool.py | 2 +- tools/avs_common.py | 2 +- tools/ci-psa/Dockerfile | 2 +- tools/ci/build-docker-images.sh | 2 +- tools/ci/rockylinux-9/Dockerfile | 2 +- tools/ci/ubuntu-18.04/Dockerfile | 2 +- tools/ci/ubuntu-20.04/Dockerfile | 2 +- tools/ci/ubuntu-22.04/Dockerfile | 2 +- tools/coverage | 2 +- tools/find_unused_code.py | 4 +- tools/generate-certs.sh | 2 +- tools/license_headers.py | 4 +- tools/lwm2m_object_registry.py | 2 +- tools/markdown-toc.py | 2 +- .../factory_prov/__init__.py | 2 +- .../factory_prov/cert_gen.py | 2 +- .../factory_prov/factory_prov.py | 2 +- tools/provisioning-tool/ptool.py | 2 +- tools/symlink-check.sh | 2 +- tools/test_duplicates.py | 2 +- tools/test_ghactions.py | 2 +- tools/utils.sh | 2 +- 701 files changed, 10707 insertions(+), 1593 deletions(-) create mode 100644 demo/software_mgmt.c create mode 100644 demo/software_mgmt.h create mode 100644 examples/tutorial/AT-IpsoObjects/CMakeLists.txt create mode 100644 examples/tutorial/AT-IpsoObjects/src/main.c create mode 100644 include_public/anjay/ipso_objects_v2.h create mode 100644 include_public/anjay/sw_mgmt.h create mode 100644 src/modules/ipso_v2/anjay_ipso_v2_3d_sensor.c create mode 100644 src/modules/ipso_v2/anjay_ipso_v2_basic_sensor.c create mode 100644 src/modules/sw_mgmt/anjay_sw_mgmt.c create mode 100644 tests/integration/suites/default/software_mgmt.py diff --git a/.github/workflows/anjay-tests.yml b/.github/workflows/anjay-tests.yml index 1019624b..d9ebbb9c 100644 --- a/.github/workflows/anjay-tests.yml +++ b/.github/workflows/anjay-tests.yml @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/.github/workflows/coverity.yml b/.github/workflows/coverity.yml index 94722dc7..bc19e748 100644 --- a/.github/workflows/coverity.yml +++ b/.github/workflows/coverity.yml @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ab2169a..83e8b130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,33 @@ # Changelog +## 3.7.0 (February 16th, 2024) + +### Features + +- Added support for LwM2M 1.2 server object requirement for infinite lifetime + (lifetime == 0). +- Introduced @experimental and @deprecated Doxygen tags. +- Added experimental IPSO objects v2 API. +- Added experimental Software Management object API. + +### Improvements + +- Improved integration tests compability and framework stability +- Added support for wget2 for validating links in documentation (for HTTP/2 + support) + +### Bugfixes + +- Refactored generation of blockwise Confirmable notifications to avoid a + possible assertion failure; requests for subsequent blocks of such + notifications are now sent as Piggybacked responses +- Fixed a bug in the documentation of an object definition struct +- (commercial version only) Fixed problems with running some tests on systems + with Mbed TLS 3.x +- Fixed a few assertion and pointer punning issues regarding calls to IPSO + objects APIs in erroneous cases +- Prevent from trying to store empty cert/keys on HSM + ## 3.6.1 (November 21st, 2023) ### Improvements @@ -9,6 +37,8 @@ contents depend on the Access Control object state - Added a public define for MSISDN string size - Optimized "Out of memory" logs in favor of a smaller flash memory footprint +- (commercial feature only) Added API for querying Anjay for SSID associated + with given MSISDN and SMS Trigger resource value ### Bugfixes diff --git a/CMakeLists.txt b/CMakeLists.txt index 018a44d2..9b66190f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # @@ -8,7 +8,7 @@ cmake_minimum_required(VERSION 3.6.0) project(anjay C) -set(ANJAY_VERSION "3.6.1" CACHE STRING "Anjay library version") +set(ANJAY_VERSION "3.7.0" CACHE STRING "Anjay library version") set(ANJAY_BINARY_VERSION 1.0.0) set(ANJAY_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") @@ -325,6 +325,7 @@ endif() cmake_dependent_option(WITH_MODULE_access_control "Access control object implementation module" ON WITH_ACCESS_CONTROL OFF) option(WITH_MODULE_ipso_objects "Generic implementation of certain kinds of IPSO objects" ON) +option(WITH_MODULE_ipso_objects_v2 "Experimental generic implementation of certain kinds of IPSO objects" ON) option(WITH_MODULE_security "Security object module" ON) option(WITH_MODULE_server "Server object module" ON) option(WITH_MODULE_fw_update "Firmware Update object module" ON) @@ -333,6 +334,7 @@ cmake_dependent_option(WITHOUT_MODULE_fw_update_PUSH_MODE OFF "WITH_MODULE_fw_update;WITH_DOWNLOADER" OFF) cmake_dependent_option(WITH_MODULE_factory_provisioning "Factory provisioning module" ON "WITH_BOOTSTRAP;WITH_CBOR" OFF) option(WITH_MODULE_advanced_fw_update "Advanced Firmware Update object module" OFF) +option(WITH_MODULE_sw_mgmt "Software Management object module" OFF) ################# CODE ######################################################### @@ -348,10 +350,12 @@ add_library(anjay include_public/anjay/fw_update.h include_public/anjay/io.h include_public/anjay/ipso_objects.h + include_public/anjay/ipso_objects_v2.h include_public/anjay/lwm2m_send.h include_public/anjay/security.h include_public/anjay/server.h include_public/anjay/stats.h + include_public/anjay/sw_mgmt.h src/anjay_config_log.h src/anjay_init.h src/anjay_modules/anjay_access_utils.h @@ -483,6 +487,8 @@ add_library(anjay src/modules/ipso/anjay_ipso_3d_sensor.c src/modules/ipso/anjay_ipso_basic_sensor.c src/modules/ipso/anjay_ipso_button.c + src/modules/ipso_v2/anjay_ipso_v2_3d_sensor.c + src/modules/ipso_v2/anjay_ipso_v2_basic_sensor.c src/modules/security/anjay_mod_security.c src/modules/security/anjay_mod_security.h src/modules/security/anjay_security_persistence.c @@ -497,6 +503,7 @@ add_library(anjay src/modules/server/anjay_server_transaction.h src/modules/server/anjay_server_utils.c src/modules/server/anjay_server_utils.h + src/modules/sw_mgmt/anjay_sw_mgmt.c ) target_include_directories(anjay PUBLIC @@ -528,11 +535,13 @@ set(ANJAY_WITHOUT_IP_STICKINESS "${WITHOUT_IP_STICKINESS}") set(ANJAY_WITHOUT_COMPOSITE_OPERATIONS "${WITHOUT_COMPOSITE_OPERATIONS}") set(ANJAY_WITH_MODULE_ACCESS_CONTROL "${WITH_MODULE_access_control}") set(ANJAY_WITH_MODULE_IPSO_OBJECTS "${WITH_MODULE_ipso_objects}") +set(ANJAY_WITH_MODULE_IPSO_OBJECTS_V2 "${WITH_MODULE_ipso_objects_v2}") set(ANJAY_WITH_MODULE_FW_UPDATE "${WITH_MODULE_fw_update}") set(ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE "${WITH_MODULE_advanced_fw_update}") set(ANJAY_WITHOUT_MODULE_FW_UPDATE_PUSH_MODE "${WITHOUT_MODULE_fw_update_PUSH_MODE}") set(ANJAY_WITH_MODULE_SECURITY "${WITH_MODULE_security}") set(ANJAY_WITH_MODULE_SERVER "${WITH_MODULE_server}") +set(ANJAY_WITH_MODULE_SW_MGMT "${WITH_MODULE_sw_mgmt}") set(ANJAY_WITH_NET_STATS "${WITH_NET_STATS}") set(ANJAY_WITH_COMMUNICATION_TIMESTAMP_API "${WITH_COMMUNICATION_TIMESTAMP_API}") set(ANJAY_WITH_EVENT_LOOP "${WITH_EVENT_LOOP}") @@ -865,6 +874,10 @@ if(WITH_MODULE_ipso_objects) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include_public/anjay/ipso_objects.h" DESTINATION include/anjay) endif() +if(WITH_MODULE_ipso_objects_v2) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include_public/anjay/ipso_objects_v2.h" + DESTINATION include/anjay) +endif() if(WITH_MODULE_fw_update) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include_public/anjay/fw_update.h" DESTINATION include/anjay) @@ -885,6 +898,10 @@ if(WITH_MODULE_factory_provisioning) install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include_public/anjay/factory_provisioning.h" DESTINATION include/anjay) endif() +if(WITH_MODULE_sw_mgmt) + install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/include_public/anjay/sw_mgmt.h" + DESTINATION include/anjay) +endif() # install CMake package configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/anjay-config.cmake.in diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 2f541a49..d0f80e50 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/Dockerfile b/Dockerfile index d2bb4ea6..1a93fcf0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/Doxyfile.in b/Doxyfile.in index db30881b..df8e5318 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -203,7 +203,7 @@ TAB_SIZE = 8 # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES += "experimental=\xrefitem experimentals \"Experimental\" \"Experimental List\"" # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding diff --git a/NOTICE b/NOTICE index 61dfccd5..2fec434f 100644 --- a/NOTICE +++ b/NOTICE @@ -1,5 +1,5 @@ Anjay -Copyright 2017-2023 AVSystem +Copyright 2017-2024 AVSystem This product includes software developed at AVSystem (www.avsystem.com). diff --git a/cmake/anjay-config.cmake.in b/cmake/anjay-config.cmake.in index a097c679..006e2c28 100644 --- a/cmake/anjay-config.cmake.in +++ b/cmake/anjay-config.cmake.in @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/cmake/anjay-version.cmake.in b/cmake/anjay-version.cmake.in index 2ead2783..a058a321 100644 --- a/cmake/anjay-version.cmake.in +++ b/cmake/anjay-version.cmake.in @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/cmake/sphinx.cmake b/cmake/sphinx.cmake index f6f96eab..29bf736b 100644 --- a/cmake/sphinx.cmake +++ b/cmake/sphinx.cmake @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/cmake/toolchain/afl-gcc.cmake b/cmake/toolchain/afl-gcc.cmake index 3d1476df..b83bb479 100644 --- a/cmake/toolchain/afl-gcc.cmake +++ b/cmake/toolchain/afl-gcc.cmake @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/covconfig b/covconfig index 93d1ae0a..079a2928 100755 --- a/covconfig +++ b/covconfig @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt index 64e072c6..d83e6871 100644 --- a/demo/CMakeLists.txt +++ b/demo/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # @@ -48,6 +48,10 @@ if (${ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE}) endif() +if (${ANJAY_WITH_MODULE_SW_MGMT}) + set(SOURCES ${SOURCES} software_mgmt.c) +endif() + if(NOT WIN32) set(SOURCES ${SOURCES} objects/ip_ping.c) endif() @@ -72,6 +76,10 @@ if (${ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE}) set(HEADERS ${HEADERS} advanced_firmware_update.h) endif() +if (${ANJAY_WITH_MODULE_SW_MGMT}) + set(HEADERS ${HEADERS} software_mgmt.h) +endif() + set(ALL_SOURCES ${SOURCES} ${HEADERS}) if(NOT TARGET anjay) diff --git a/demo/advanced_firmware_update.c b/demo/advanced_firmware_update.c index 1c1db95e..714754e8 100644 --- a/demo/advanced_firmware_update.c +++ b/demo/advanced_firmware_update.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -1021,18 +1021,18 @@ int fw_update_common_perform_upgrade( int fw_update_common_maybe_create_firmware_file( advanced_fw_update_logic_t *fw) { + if (fw->next_target_path) { + return 0; + } + if (fw->administratively_set_target_path) { + fw->next_target_path = avs_strdup(fw->administratively_set_target_path); + } else { + fw->next_target_path = generate_random_target_filepath(); + } if (!fw->next_target_path) { - if (fw->administratively_set_target_path) { - fw->next_target_path = - avs_strdup(fw->administratively_set_target_path); - } else { - fw->next_target_path = generate_random_target_filepath(); - } - if (!fw->next_target_path) { - return -1; - } - demo_log(INFO, "Created %s", fw->next_target_path); + return -1; } + demo_log(INFO, "Created %s", fw->next_target_path); return 0; } diff --git a/demo/advanced_firmware_update.h b/demo/advanced_firmware_update.h index a39147f2..88bbf898 100644 --- a/demo/advanced_firmware_update.h +++ b/demo/advanced_firmware_update.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/advanced_firmware_update_addimg.c b/demo/advanced_firmware_update_addimg.c index 1959df7d..1d742892 100644 --- a/demo/advanced_firmware_update_addimg.c +++ b/demo/advanced_firmware_update_addimg.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/advanced_firmware_update_app.c b/demo/advanced_firmware_update_app.c index 296d98af..48bbe259 100644 --- a/demo/advanced_firmware_update_app.c +++ b/demo/advanced_firmware_update_app.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/demo.c b/demo/demo.c index 59aee5d5..14b22c91 100644 --- a/demo/demo.c +++ b/demo/demo.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -292,6 +292,9 @@ static void demo_delete(anjay_demo_t *demo) { #ifdef ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE advanced_firmware_update_uninstall(demo->advanced_fw_update_logic_table); #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + sw_mgmt_update_destroy(demo->sw_mgmt_table); +#endif // ANJAY_WITH_MODULE_SW_MGMT #ifdef WITH_DEMO_USE_STANDALONE_OBJECTS standalone_server_object_cleanup(demo->server_obj_ptr); standalone_security_object_cleanup(demo->security_obj_ptr); @@ -585,6 +588,14 @@ static int demo_init(anjay_demo_t *demo, cmdline_args_t *cmdline_args) { } #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#if defined(ANJAY_WITH_MODULE_SW_MGMT) && defined(ANJAY_WITH_DOWNLOADER) + avs_net_security_info_t *sw_mgmt_security_info_ptr = NULL; + if (cmdline_args->sw_mgmt_security_info.mode + != (avs_net_security_mode_t) -1) { + sw_mgmt_security_info_ptr = &cmdline_args->sw_mgmt_security_info; + } +#endif // defined(ANJAY_WITH_MODULE_SW_MGMT) && defined(ANJAY_WITH_DOWNLOADER) + demo->connection_args = &cmdline_args->connection_args; #ifdef AVS_COMMONS_STREAM_WITH_FILE # ifdef ANJAY_WITH_ATTR_STORAGE @@ -777,6 +788,28 @@ static int demo_init(anjay_demo_t *demo, cmdline_args_t *cmdline_args) { } #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + if (sw_mgmt_install( + demo->anjay, &demo->sw_mgmt_common, demo->sw_mgmt_table, + cmdline_args->sw_mgmt_persistence_file, + cmdline_args->prefer_same_socket_downloads, + cmdline_args->sw_mgmt_delayed_first_instance_install_result, + cmdline_args->sw_mgmt_terminate_after_downloading, + cmdline_args->sw_mgmt_disable_repeated_activation_deactivation +# ifdef ANJAY_WITH_DOWNLOADER + , + sw_mgmt_security_info_ptr, + cmdline_args->sw_mgmt_tx_params_modified + ? &cmdline_args->sw_mgmt_tx_params + : NULL, + &cmdline_args->sw_mgmt_tcp_request_timeout, + cmdline_args->sw_mgmt_auto_suspend +# endif // ANJAY_WITH_DOWNLOADER + )) { + return -1; + } +#endif // ANJAY_WITH_MODULE_SW_MGMT + #ifdef ANJAY_WITH_MODULE_ACCESS_CONTROL if (!dm_persistence_restored && (add_default_access_entries(demo) diff --git a/demo/demo.h b/demo/demo.h index 5a3acc64..eba34152 100644 --- a/demo/demo.h +++ b/demo/demo.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -27,6 +27,10 @@ #ifdef ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE # include "advanced_firmware_update.h" #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE + +#ifdef ANJAY_WITH_MODULE_SW_MGMT +# include "software_mgmt.h" +#endif // ANJAY_WITH_MODULE_SW_MGMT #include "objects.h" typedef int anjay_demo_object_get_instances_t(const anjay_dm_object_def_t **, @@ -66,6 +70,10 @@ struct anjay_demo_struct { advanced_fw_update_logic_t advanced_fw_update_logic_table[FW_UPDATE_IID_IMAGE_SLOTS]; #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + sw_mgmt_common_logic_t sw_mgmt_common; + sw_mgmt_logic_t sw_mgmt_table[SW_MGMT_PACKAGE_COUNT]; +#endif // ANJAY_WITH_MODULE_SW_MGMT #ifdef WITH_DEMO_USE_STANDALONE_OBJECTS const anjay_dm_object_def_t **security_obj_ptr; diff --git a/demo/demo_args.c b/demo/demo_args.c index 5da38b7c..81b1a8d1 100644 --- a/demo/demo_args.c +++ b/demo/demo_args.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -74,6 +74,21 @@ static const cmdline_args_t DEFAULT_CMDLINE_ARGS = { }, #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + .sw_mgmt_delayed_first_instance_install_result = UINT8_MAX, +# if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) + .sw_mgmt_persistence_file = "/tmp/anjay-sw-mgmt", + .sw_mgmt_terminate_after_downloading = false, +# endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) +# ifdef ANJAY_WITH_DOWNLOADER + .sw_mgmt_security_info = { + .mode = (avs_net_security_mode_t) -1 + }, +# endif // ANJAY_WITH_DOWNLOADER +#endif // ANJAY_WITH_MODULE_SW_MGMT + #ifdef AVS_COMMONS_STREAM_WITH_FILE # ifdef ANJAY_WITH_ATTR_STORAGE .attr_storage_file = NULL, @@ -101,6 +116,12 @@ static const cmdline_args_t DEFAULT_CMDLINE_ARGS = { .advanced_fwu_tx_params = ANJAY_COAP_DEFAULT_UDP_TX_PARAMS, .advanced_fwu_tcp_request_timeout = { 0, -1 }, #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + .sw_mgmt_tx_params_modified = false, + .sw_mgmt_tx_params = ANJAY_COAP_DEFAULT_UDP_TX_PARAMS, + .sw_mgmt_tcp_request_timeout = { 0, -1 }, +// AVS_TIME_DURATION_INVALID +#endif // ANJAY_WITH_MODULE_SW_MGMT #ifdef ANJAY_WITH_LWM2M11 .lwm2m_version_config = { .minimum_version = ANJAY_LWM2M_VERSION_1_0, @@ -266,8 +287,9 @@ static void print_help(const struct option *options) { "daemon." }, #endif // _WIN32 { 'l', "SECONDS", "86400", - "set registration lifetime. If SECONDS <= 0, use default value and " - "don't send lifetime in Register/Update messages." }, + "set registration lifetime. If SECONDS == 0, the lifetime is " + "infinite and register updates are not being sent automatically. " + "Negative values are not allowed." }, { 'L', "MAX_NOTIFICATIONS", "0", "set limit of queued notifications in queue/offline mode. 0: " "unlimited; >0: keep that much newest ones" }, @@ -406,7 +428,7 @@ static void print_help(const struct option *options) { #endif // ANJAY_WITH_LWM2M11 { 283, NULL, NULL, "Configures preference of re-using existing LwM2M CoAP contexts for " - "firmware download" }, + "firmware and software download" }, { 284, "NSTART", "1", "Configures NSTART (defined in RFC7252)" }, #if defined(ANJAY_WITH_SEND) && defined(ANJAY_WITH_MODULE_FW_UPDATE) { 287, NULL, NULL, @@ -518,6 +540,60 @@ static void print_help(const struct option *options) { "Request timeout (in seconds) to use for Advanced Firmware Update " "downloads performed over CoAP+TCP and HTTP" }, #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + { 335, "RESULT", NULL, + "If specified, initializes first Software Management " + "object in DELIVERED state, and sets the result to given value after " + "a short " + "while" }, + { 336, NULL, NULL, + "Terminate the program after downloading package for instance 0. " + "Useful for testing purposes only." }, + { 337, NULL, NULL, + "Do not execute code related to activation/deactivation and return " + "an error from the activation/deactivation handler when the package " + "is already activated/deactivated." }, +# if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) + { 338, "PATH", DEFAULT_CMDLINE_ARGS.sw_mgmt_persistence_file, + "Persistence file path" }, +# endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) +# ifdef ANJAY_WITH_DOWNLOADER + { 339, "CERT_FILE", NULL, + "Require certificate validation against specified file when " + "downloading software over encrypted channels" }, + { 340, "CERT_DIR", NULL, + "Require certificate validation against files in specified path when " + "downloading software over encrypted channels; note that the TLS " + "backend may impose specific requirements for file names and " + "formats" }, + { 341, "PSK identity", NULL, + "Download software over encrypted channels using PSK-mode encryption " + "with the specified identity (provided as hexlified string); must be " + "used together with --sw-mgmt-psk-key" }, + { 342, "PSK key", NULL, + "Download software over encrypted channels using PSK-mode encryption " + "with the specified key (provided as hexlified string); must be used " + "together with --sw-mgmt-psk-identity" }, + { 343, "ACK_RANDOM_FACTOR", "1.5", + "Configures ACK_RANDOM_FACTOR (defined in RFC7252) for software " + "update" }, + { 344, "ACK_TIMEOUT", "2.0", + "Configures ACK_TIMEOUT (defined in RFC7252) in seconds for software " + "update" }, + { 345, "MAX_RETRANSMIT", "4", + "Configures MAX_RETRANSMIT (defined in RFC7252) for software " + "update" }, + { 346, NULL, NULL, + "Start the software downloads in suspended mode and resume " + "them just when they are requested. Useful for testing purposes " + "only." }, + { 347, "TIMEOUT", NULL, + "Request timeout (in seconds) to use for software download performed " + "over CoAP+TCP and HTTP" }, +# endif // ANJAY_WITH_DOWNLOADER +#endif // ANJAY_WITH_MODULE_SW_MGMT }; const size_t screen_width = get_screen_width(); @@ -899,6 +975,25 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) { #ifdef ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE { "afu-tcp-request-timeout", required_argument, 0, 334 }, #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + { "delayed-sw-mgmt-result", required_argument, 0, 335 }, + { "sw-mgmt-terminate-after-downloading", no_argument, 0, 336 }, + { "sw-mgmt-disable-repeated-activation-deactivation", no_argument, 0, 337 }, +# if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && defined(AVS_COMMONS_STREAM_WITH_FILE) + { "sw-mgmt-persistence-file", required_argument, 0, 338 }, +# endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && defined(AVS_COMMONS_STREAM_WITH_FILE) +# ifdef ANJAY_WITH_DOWNLOADER + { "sw-mgmt-cert-file", required_argument, 0, 339 }, + { "sw-mgmt-cert-path", required_argument, 0, 340 }, + { "sw-mgmt-psk-identity", required_argument, 0, 341 }, + { "sw-mgmt-psk-key", required_argument, 0, 342 }, + { "sw-mgmt-ack-random-factor", required_argument, 0, 343 }, + { "sw-mgmt-ack-timeout", required_argument, 0, 344 }, + { "sw-mgmt-max-retransmit", required_argument, 0, 345 }, + { "sw-mgmt-auto-suspend", no_argument, 0, 346 }, + { "sw-mgmt-tcp-request-timeout", required_argument, 0, 347 }, +# endif // ANJAY_WITH_DOWNLOADER +#endif // ANJAY_WITH_MODULE_SW_MGMT { 0, 0, 0, 0 } // clang-format on }; @@ -1330,8 +1425,8 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) { break; } case 269: { - int32_t max_retransmit; - if (parse_i32(optarg, &max_retransmit) || max_retransmit < 0) { + uint32_t max_retransmit; + if (parse_u32(optarg, &max_retransmit)) { demo_log(ERROR, "Expected MAX_RETRANSMIT to be an unsigned " "integer"); goto finish; @@ -1382,8 +1477,8 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) { break; } case 274: { - int32_t max_retransmit; - if (parse_i32(optarg, &max_retransmit) || max_retransmit < 0) { + uint32_t max_retransmit; + if (parse_u32(optarg, &max_retransmit)) { demo_log(ERROR, "Expected MAX_RETRANSMIT to be an unsigned " "integer"); goto finish; @@ -1737,6 +1832,175 @@ int demo_parse_argv(cmdline_args_t *parsed_args, int argc, char *argv[]) { break; } #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + case 335: { + uint16_t result; + if (parse_u16(optarg, &result) || (result != 0 && result != 1)) { + demo_log(ERROR, "invalid install result value: %s", optarg); + goto finish; + } + parsed_args->sw_mgmt_delayed_first_instance_install_result = + (uint8_t) result; + break; + } + case 336: { + parsed_args->sw_mgmt_terminate_after_downloading = true; + break; + } + case 337: { + parsed_args->sw_mgmt_disable_repeated_activation_deactivation = + true; + break; + } +# if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) + case 338: { + parsed_args->sw_mgmt_persistence_file = optarg; + break; + } +# endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) +# ifdef ANJAY_WITH_DOWNLOADER + case 339: { + if (parsed_args->sw_mgmt_security_info.mode + != (avs_net_security_mode_t) -1) { + demo_log(ERROR, "Multiple incompatible security information " + "specified for software managment"); + goto finish; + } + + const avs_net_certificate_info_t cert_info = { + .server_cert_validation = true, + .trusted_certs = + avs_crypto_certificate_chain_info_from_file(optarg) + }; + parsed_args->sw_mgmt_security_info = + avs_net_security_info_from_certificates(cert_info); + break; + } + case 340: { + if (parsed_args->sw_mgmt_security_info.mode + != (avs_net_security_mode_t) -1) { + demo_log(ERROR, "Multiple incompatible security information " + "specified for software managment"); + goto finish; + } + const avs_net_certificate_info_t cert_info = { + .server_cert_validation = true, + .trusted_certs = + avs_crypto_certificate_chain_info_from_path(optarg) + }; + parsed_args->sw_mgmt_security_info = + avs_net_security_info_from_certificates(cert_info); + break; + } + case 341: { + if (parsed_args->sw_mgmt_security_info.mode != AVS_NET_SECURITY_PSK + && parsed_args->sw_mgmt_security_info.mode + != (avs_net_security_mode_t) -1) { + demo_log(ERROR, "Multiple incompatible security information " + "specified for software managment"); + goto finish; + } + if (parsed_args->sw_mgmt_security_info.mode == AVS_NET_SECURITY_PSK + && parsed_args->sw_mgmt_security_info.data.psk.identity.desc + .source + != AVS_CRYPTO_DATA_SOURCE_EMPTY) { + demo_log(ERROR, + "--sw-mgmt-psk-identity specified more than once"); + goto finish; + } + uint8_t *identity_buf = NULL; + size_t identity_size = 0; + if (parse_hexstring(parsed_args, optarg, &identity_buf, + &identity_size)) { + demo_log(ERROR, "Invalid PSK identity for software managment"); + goto finish; + } + parsed_args->sw_mgmt_security_info.mode = AVS_NET_SECURITY_PSK; + parsed_args->sw_mgmt_security_info.data.psk.identity = + avs_crypto_psk_identity_info_from_buffer(identity_buf, + identity_size); + break; + } + case 342: { + if (parsed_args->sw_mgmt_security_info.mode != AVS_NET_SECURITY_PSK + && parsed_args->sw_mgmt_security_info.mode + != (avs_net_security_mode_t) -1) { + demo_log(ERROR, "Multiple incompatible security information " + "specified for software managment"); + goto finish; + } + if (parsed_args->sw_mgmt_security_info.mode == AVS_NET_SECURITY_PSK + && parsed_args->sw_mgmt_security_info.data.psk.key.desc + .source + != AVS_CRYPTO_DATA_SOURCE_EMPTY) { + demo_log(ERROR, "--sw-mgmt-psk-key specified more than once"); + goto finish; + } + uint8_t *psk_buf = NULL; + size_t psk_size = 0; + if (parse_hexstring(parsed_args, optarg, &psk_buf, &psk_size)) { + demo_log(ERROR, + "Invalid pre-shared key for software managment"); + goto finish; + } + parsed_args->sw_mgmt_security_info.mode = AVS_NET_SECURITY_PSK; + parsed_args->sw_mgmt_security_info.data.psk.key = + avs_crypto_psk_key_info_from_buffer(psk_buf, psk_size); + break; + } + case 343: + if (parse_double( + optarg, + &parsed_args->sw_mgmt_tx_params.ack_random_factor)) { + demo_log(ERROR, "Expected ACK_RANDOM_FACTOR to be a floating " + "point number"); + goto finish; + } + parsed_args->sw_mgmt_tx_params_modified = true; + break; + case 344: { + double ack_timeout_s; + if (parse_double(optarg, &ack_timeout_s)) { + demo_log(ERROR, + "Expected ACK_TIMEOUT to be a floating point number"); + goto finish; + } + parsed_args->sw_mgmt_tx_params.ack_timeout = + avs_time_duration_from_fscalar(ack_timeout_s, AVS_TIME_S); + parsed_args->sw_mgmt_tx_params_modified = true; + break; + } + case 345: { + uint32_t max_retransmit; + if (parse_u32(optarg, &max_retransmit)) { + demo_log(ERROR, "Expected MAX_RETRANSMIT to be an unsigned " + "integer"); + goto finish; + } + parsed_args->sw_mgmt_tx_params.max_retransmit = + (unsigned) max_retransmit; + parsed_args->sw_mgmt_tx_params_modified = true; + break; + } + case 346: + parsed_args->sw_mgmt_auto_suspend = true; + break; + case 347: { + double timeout_s; + if (parse_double(optarg, &timeout_s) || !isfinite(timeout_s) + || timeout_s <= 0.0) { + demo_log(ERROR, "Expected TCP request timeout to be a positive " + "floating point number"); + goto finish; + } + parsed_args->sw_mgmt_tcp_request_timeout = + avs_time_duration_from_fscalar(timeout_s, AVS_TIME_S); + break; + } +# endif // ANJAY_WITH_DOWNLOADER +#endif // ANJAY_WITH_MODULE_SW_MGMT case 0: goto process; } diff --git a/demo/demo_args.h b/demo/demo_args.h index ce051b4c..ceedfa3e 100644 --- a/demo/demo_args.h +++ b/demo/demo_args.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -22,6 +22,10 @@ # include #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT +# include "software_mgmt.h" +#endif // ANJAY_WITH_MODULE_SW_MGMT + #include "demo_utils.h" #include "objects.h" @@ -86,6 +90,25 @@ typedef struct cmdline_args { */ const char *original_img_file_path; #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + const char *sw_mgmt_persistence_file; + bool sw_mgmt_terminate_after_downloading; + bool sw_mgmt_disable_repeated_activation_deactivation; +# ifdef ANJAY_WITH_DOWNLOADER + avs_net_security_info_t sw_mgmt_security_info; +# endif // ANJAY_WITH_DOWNLOADER + /** + * If delayed-sw-mgmt-result is passed, first (iid=0) Software Management + * object will be initialized in + * @ref ANJAY_SW_MGMT_INITIAL_STATE_DELIVERED state. In that case, @ref + * anjay_sw_mgmt_finish_pkg_install will be used after a while to make + * transition to Installed state or report installation error. This + * simulates a installation procedure during which the client is restarted + * while the procedure is still in progress. + */ + uint8_t sw_mgmt_delayed_first_instance_install_result; + bool sw_mgmt_auto_suspend; +#endif // ANJAY_WITH_MODULE_SW_MGMT #ifdef AVS_COMMONS_STREAM_WITH_FILE # ifdef ANJAY_WITH_ATTR_STORAGE const char *attr_storage_file; @@ -126,6 +149,17 @@ typedef struct cmdline_args { avs_coap_udp_tx_params_t advanced_fwu_tx_params; avs_time_duration_t advanced_fwu_tcp_request_timeout; #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + /** + * This flag allows to enable callback providing tx_params for software + * management only if some of parameters were changed by passing proper + * command line argument to demo. Otherwise tx_params should be inherited + * from Anjay. + */ + bool sw_mgmt_tx_params_modified; + avs_coap_udp_tx_params_t sw_mgmt_tx_params; + avs_time_duration_t sw_mgmt_tcp_request_timeout; +#endif // ANJAY_WITH_MODULE_SW_MGMT #ifdef ANJAY_WITH_LWM2M11 anjay_lwm2m_version_config_t lwm2m_version_config; #endif // ANJAY_WITH_LWM2M11 diff --git a/demo/demo_cmds.c b/demo/demo_cmds.c index d047014a..8ea2bb7e 100644 --- a/demo/demo_cmds.c +++ b/demo/demo_cmds.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -18,7 +18,12 @@ # include "advanced_firmware_update.h" #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT +# include "software_mgmt.h" +#endif // ANJAY_WITH_MODULE_SW_MGMT + #include +#include #include #include @@ -205,6 +210,57 @@ static void cmd_afu_reconnect(anjay_demo_t *demo, const char *args_string) { } #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT +static void cmd_set_sw_mgmt_package_path(anjay_demo_t *demo, + const char *args_string) { + anjay_iid_t iid; + + char *path = (char *) avs_malloc(strlen(args_string) + 1); + if (!path) { + demo_log(ERROR, "Out of memory"); + return; + } + path[0] = '\0'; + + if (sscanf(args_string, "%" SCNu16 "%s", &iid, path) != 2 + || iid >= SW_MGMT_PACKAGE_COUNT) { + demo_log(ERROR, "invalid parameters"); + avs_free(path); + return; + } + + sw_mgmt_set_package_path(&demo->sw_mgmt_table[iid], path); + avs_free(path); +} + +static void cmd_set_sw_mgmt_install_result(anjay_demo_t *demo, + const char *args_string) { + anjay_iid_t iid; + uint8_t result; + + if (sscanf(args_string, "%" SCNu16 "%" SCNu8, &iid, &result) != 2 + || (result != 0 && result != 1)) { + demo_log(ERROR, "invalid parameters"); + return; + } + + anjay_sw_mgmt_finish_pkg_install( + demo->anjay, iid, + result == 1 ? ANJAY_SW_MGMT_FINISH_PKG_INSTALL_SUCCESS_INACTIVE + : ANJAY_SW_MGMT_FINISH_PKG_INSTALL_FAILURE); +} + +static void cmd_sw_mgmt_suspend(anjay_demo_t *demo, const char *args_string) { + (void) args_string; + anjay_sw_mgmt_pull_suspend(demo->anjay); +} + +static void cmd_sw_mgmt_reconnect(anjay_demo_t *demo, const char *args_string) { + (void) args_string; + anjay_sw_mgmt_pull_reconnect(demo->anjay); +} +#endif // ANJAY_WITH_MODULE_SW_MGMT + static void cmd_open_location_csv(anjay_demo_t *demo, const char *args_string) { const anjay_dm_object_def_t **location_obj = demo_find_object(demo, DEMO_OID_LOCATION); @@ -1088,7 +1144,8 @@ static void cmd_registration_expiration_time(anjay_demo_t *demo, demo_log(INFO, "REGISTRATION_EXPIRATION_TIME=%s", AVS_TIME_DURATION_AS_STRING( - anjay_registration_expiration_time(demo->anjay, ssid) + anjay_registration_expiration_time_with_status(demo->anjay, + ssid, NULL) .since_real_epoch)); } @@ -1165,7 +1222,6 @@ static void cmd_has_unsent_notifications(anjay_demo_t *demo, demo_log(INFO, "HAS_UNSENT_NOTIFICATIONS=%s", result ? "true" : "false"); } -#ifdef ANJAY_WITH_MODULE_IPSO_OBJECTS static void cmd_temperature_add_instance(anjay_demo_t *demo, const char *args_string) { anjay_iid_t iid; @@ -1253,7 +1309,6 @@ static void cmd_push_button_release(anjay_demo_t *demo, anjay_ipso_button_update(demo->anjay, iid, false); } -#endif // ANJAY_WITH_MODULE_IPSO_OBJECTS static void cmd_set_tx_params(anjay_demo_t *demo, const char *args_string) { avs_coap_udp_tx_params_t tx_params; @@ -1398,12 +1453,12 @@ static const struct cmd_handler_def COMMAND_HANDLERS[] = { CMD_HANDLER("reconnect", "[transports...]", cmd_reconnect, "Reconnects to LwM2M servers and sends Update messages"), #ifdef ANJAY_WITH_MODULE_FW_UPDATE - CMD_HANDLER("set-fw-package-path", "", cmd_set_fw_package_path, + CMD_HANDLER("set-fw-package-path", "PATH", cmd_set_fw_package_path, "Sets the path where the firmware package will be saved when " "Write /5/0/0 is performed"), #endif // ANJAY_WITH_MODULE_FW_UPDATE #ifdef ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE - CMD_HANDLER("set-afu-package-path", "", cmd_set_afu_package_path, + CMD_HANDLER("set-afu-package-path", "PATH", cmd_set_afu_package_path, "Sets the path where the firmware package will be saved when " "Write /" AVS_QUOTE_MACRO(ANJAY_ADVANCED_FW_UPDATE_OID) "/0/0 is performed. Only applied to instance 0."), CMD_HANDLER("get-afu-deadline", "", cmd_get_afu_deadline, @@ -1420,6 +1475,18 @@ static const struct cmd_handler_def COMMAND_HANDLERS[] = { "Firmware Update module and if PULL-mode downloads are " "suspended, resumes normal operation"), #endif // ANJAY_WITH_MODULE_ADVANCED_FW_UPDATE +#ifdef ANJAY_WITH_MODULE_SW_MGMT + CMD_HANDLER("set-sw-mgmt-package-path", "IID PATH", cmd_set_sw_mgmt_package_path, + "Sets the path where the software package will be saved when " + "Write to /9/x/2 or /9/x/3 is performed"), + CMD_HANDLER("set-sw-mgmt-install-result", "IID RESULT", cmd_set_sw_mgmt_install_result, + "Attempts to set Software Install Result at runtime"), + CMD_HANDLER("sw-mgmt-suspend", "", cmd_sw_mgmt_suspend, + "Suspends the operation of PULL-mode downloads in the Software Management module"), + CMD_HANDLER("sw-mgmt-reconnect", "", cmd_sw_mgmt_reconnect, + "Reconnects any ongoing PULL-mode downloads in the Software Management module" + "and if PULL-mode downloads are suspended, resumes normal operation"), +#endif // ANJAY_WITH_MODULE_SW_MGMT CMD_HANDLER("open-location-csv", "filename frequency=1", cmd_open_location_csv, "Opens a CSV file and starts using it for location information"), @@ -1516,7 +1583,6 @@ static const struct cmd_handler_def COMMAND_HANDLERS[] = { CMD_HANDLER("ongoing-registration-exists", "", cmd_ongoing_registration_exists, "Display information about ongoing registrations"), -#ifdef ANJAY_WITH_MODULE_IPSO_OBJECTS CMD_HANDLER("temperature-add-instance", "IID", cmd_temperature_add_instance, "Adds a new instance of the fake Temperature object. Maximal " @@ -1545,7 +1611,6 @@ static const struct cmd_handler_def COMMAND_HANDLERS[] = { CMD_HANDLER("push-button-release", "IID", cmd_push_button_release, "Releases the selected instance of the fake Push Button object."), -#endif // ANJAY_WITH_MODULE_IPSO_OBJECTS CMD_HANDLER("registration-expiration-time", "SSID", cmd_registration_expiration_time, "Displays time when registration with a given server expires"), diff --git a/demo/demo_cmds.h b/demo/demo_cmds.h index 94c26d06..c39969d1 100644 --- a/demo/demo_cmds.h +++ b/demo/demo_cmds.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/demo_time.c b/demo/demo_time.c index c3584188..21ddcd7a 100644 --- a/demo/demo_time.c +++ b/demo/demo_time.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/demo_utils.c b/demo/demo_utils.c index 1e87a671..16c164f3 100644 --- a/demo/demo_utils.c +++ b/demo/demo_utils.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/demo_utils.h b/demo/demo_utils.h index 6d9488c6..ce1d90ed 100644 --- a/demo/demo_utils.h +++ b/demo/demo_utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/firmware_update.c b/demo/firmware_update.c index ea27fad4..b6aba921 100644 --- a/demo/firmware_update.c +++ b/demo/firmware_update.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -35,18 +35,18 @@ #define FORCE_DO_NOTHING 7 static int maybe_create_firmware_file(fw_update_logic_t *fw) { + if (fw->next_target_path) { + return 0; + } + if (fw->administratively_set_target_path) { + fw->next_target_path = avs_strdup(fw->administratively_set_target_path); + } else { + fw->next_target_path = generate_random_target_filepath(); + } if (!fw->next_target_path) { - if (fw->administratively_set_target_path) { - fw->next_target_path = - avs_strdup(fw->administratively_set_target_path); - } else { - fw->next_target_path = generate_random_target_filepath(); - } - if (!fw->next_target_path) { - return -1; - } - demo_log(INFO, "Created %s", fw->next_target_path); + return -1; } + demo_log(INFO, "Created %s", fw->next_target_path); return 0; } diff --git a/demo/firmware_update.h b/demo/firmware_update.h index 8b7d4293..a262476f 100644 --- a/demo/firmware_update.h +++ b/demo/firmware_update.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects.h b/demo/objects.h index 8023a67c..7c784889 100644 --- a/demo/objects.h +++ b/demo/objects.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -179,7 +179,6 @@ int event_log_write_data(anjay_t *anjay, const void *data, size_t data_size); -#ifdef ANJAY_WITH_MODULE_IPSO_OBJECTS int install_temperature_object(anjay_t *anjay); void temperature_update_handler(anjay_t *anjay); void temperature_add_instance(anjay_t *anjay, anjay_iid_t iid); @@ -191,6 +190,5 @@ void accelerometer_add_instance(anjay_t *anjay, anjay_iid_t iid); void accelerometer_remove_instance(anjay_t *anjay, anjay_iid_t iid); int install_push_button_object(anjay_t *anjay); -#endif // ANJAY_WITH_MODULE_IPSO_OBJECTS #endif // DEMO_OBJECTS_H diff --git a/demo/objects/apn_conn_profile.c b/demo/objects/apn_conn_profile.c index 0d4dd200..267c088e 100644 --- a/demo/objects/apn_conn_profile.c +++ b/demo/objects/apn_conn_profile.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/binary_app_data_container.c b/demo/objects/binary_app_data_container.c index c3e043b1..6e800e3e 100644 --- a/demo/objects/binary_app_data_container.c +++ b/demo/objects/binary_app_data_container.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/cell_connectivity.c b/demo/objects/cell_connectivity.c index d76aa6da..d67b61c3 100644 --- a/demo/objects/cell_connectivity.c +++ b/demo/objects/cell_connectivity.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/conn_monitoring.c b/demo/objects/conn_monitoring.c index 91a8a943..951be0c0 100644 --- a/demo/objects/conn_monitoring.c +++ b/demo/objects/conn_monitoring.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/conn_statistics.c b/demo/objects/conn_statistics.c index 64530cdb..c3402aa2 100644 --- a/demo/objects/conn_statistics.c +++ b/demo/objects/conn_statistics.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/device.c b/demo/objects/device.c index 5065b00a..fbef3173 100644 --- a/demo/objects/device.c +++ b/demo/objects/device.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/download_diagnostics.c b/demo/objects/download_diagnostics.c index 11430fba..bfffde65 100644 --- a/demo/objects/download_diagnostics.c +++ b/demo/objects/download_diagnostics.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/event_log.c b/demo/objects/event_log.c index 20135a65..b8721b8a 100644 --- a/demo/objects/event_log.c +++ b/demo/objects/event_log.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/ext_dev_info.c b/demo/objects/ext_dev_info.c index b1b4ff94..6aadf9e9 100644 --- a/demo/objects/ext_dev_info.c +++ b/demo/objects/ext_dev_info.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/geopoints.c b/demo/objects/geopoints.c index b9e0c84b..88a81d25 100644 --- a/demo/objects/geopoints.c +++ b/demo/objects/geopoints.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/ip_ping.c b/demo/objects/ip_ping.c index 6a42ec4c..03f8acd7 100644 --- a/demo/objects/ip_ping.c +++ b/demo/objects/ip_ping.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/ipso_objects.c b/demo/objects/ipso_objects.c index 0178bade..3c812a02 100644 --- a/demo/objects/ipso_objects.c +++ b/demo/objects/ipso_objects.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -8,6 +8,7 @@ */ #include +#include #include @@ -32,19 +33,11 @@ static double get_temperature(thermometer_t *thermometer) { return (double) (thermometer->value); } -static int -temperature_get_value(anjay_iid_t iid, void *thermometer, double *value) { - (void) iid; - - *value = get_temperature((thermometer_t *) thermometer); - - return 0; -} - int install_temperature_object(anjay_t *anjay) { - if (anjay_ipso_basic_sensor_install( + if (anjay_ipso_v2_basic_sensor_install( anjay, ANJAY_DEMO_TEMPERATURE_OID, + NULL, ANJAY_DEMO_TEMPERATURE_MAX_INSTANCE_NUM)) { avs_log(ipso, ERROR, "Could not install Temperature object"); return -1; @@ -56,25 +49,29 @@ int install_temperature_object(anjay_t *anjay) { } void temperature_update_handler(anjay_t *anjay) { - (void) anjay_ipso_basic_sensor_update(anjay, ANJAY_DEMO_TEMPERATURE_OID, 0); + (void) anjay_ipso_v2_basic_sensor_value_update(anjay, + ANJAY_DEMO_TEMPERATURE_OID, + 0, + get_temperature( + &THERMOMETER)); } void temperature_add_instance(anjay_t *anjay, anjay_iid_t iid) { - (void) anjay_ipso_basic_sensor_instance_add( + (void) anjay_ipso_v2_basic_sensor_instance_add( anjay, ANJAY_DEMO_TEMPERATURE_OID, iid, - (anjay_ipso_basic_sensor_impl_t) { + get_temperature(&THERMOMETER), + &(anjay_ipso_v2_basic_sensor_meta_t) { .unit = ANJAY_DEMO_TEMPERATURE_UNIT, - .get_value = temperature_get_value, - .user_context = (void *) &THERMOMETER, + .min_max_measured_value_present = true, .min_range_value = 0, .max_range_value = (double) ANJAY_DEMO_TEMPERATURE_MAX_VALUE }); } void temperature_remove_instance(anjay_t *anjay, anjay_iid_t iid) { - (void) anjay_ipso_basic_sensor_instance_remove( + (void) anjay_ipso_v2_basic_sensor_instance_remove( anjay, ANJAY_DEMO_TEMPERATURE_OID, iid); } @@ -85,43 +82,44 @@ void temperature_remove_instance(anjay_t *anjay, anjay_iid_t iid) { #define ANJAY_DEMO_ACCELEROMETER_MAX_INSTANCE_NUM 16 -static int accelerometer_get_values(anjay_iid_t iid, - void *ctx, - double *x_value, - double *y_value, - double *z_value) { - (void) iid; - (void) ctx; - +static anjay_ipso_v2_3d_sensor_value_t get_accelerometer_value(void) { static int counter = 1; - *x_value = (double) counter; + double x_value = (double) counter; counter = (counter + ANJAY_DEMO_ACCELEROMETER_CHANGE) % (ANJAY_DEMO_ACCELEROMETER_MAX + 1); - *y_value = (double) counter; + double y_value = (double) counter; counter = (counter + ANJAY_DEMO_ACCELEROMETER_CHANGE) % (ANJAY_DEMO_ACCELEROMETER_MAX + 1); - *z_value = (double) counter; + double z_value = (double) counter; counter = (counter + ANJAY_DEMO_ACCELEROMETER_CHANGE) % (ANJAY_DEMO_ACCELEROMETER_MAX + 1); - return 0; + return (anjay_ipso_v2_3d_sensor_value_t) { + .x = x_value, + .y = y_value, + .z = z_value + }; } int install_accelerometer_object(anjay_t *anjay) { - if (anjay_ipso_3d_sensor_install(anjay, - ANJAY_DEMO_ACCELEROMETER_OID, - ANJAY_DEMO_ACCELEROMETER_MAX_INSTANCE_NUM) - || anjay_ipso_3d_sensor_instance_add( + anjay_ipso_v2_3d_sensor_value_t value = get_accelerometer_value(); + if (anjay_ipso_v2_3d_sensor_install( + anjay, + ANJAY_DEMO_ACCELEROMETER_OID, + NULL, + ANJAY_DEMO_ACCELEROMETER_MAX_INSTANCE_NUM) + || anjay_ipso_v2_3d_sensor_instance_add( anjay, ANJAY_DEMO_ACCELEROMETER_OID, 0, - (anjay_ipso_3d_sensor_impl_t) { + &value, + &(anjay_ipso_v2_3d_sensor_meta_t) { .unit = ANJAY_DEMO_ACCELEROMETER_UNIT, - .get_values = accelerometer_get_values, - .use_y_value = true, - .use_z_value = true, .min_range_value = 0.0, .max_range_value = - (double) ANJAY_DEMO_ACCELEROMETER_MAX + (double) ANJAY_DEMO_ACCELEROMETER_MAX, + .y_axis_present = true, + .z_axis_present = true + })) { avs_log(ipso, ERROR, "Could not install Accelerometer object"); return -1; @@ -131,27 +129,29 @@ int install_accelerometer_object(anjay_t *anjay) { } void accelerometer_update_handler(anjay_t *anjay) { - (void) anjay_ipso_3d_sensor_update(anjay, ANJAY_DEMO_ACCELEROMETER_OID, 0); + anjay_ipso_v2_3d_sensor_value_t value = get_accelerometer_value(); + (void) anjay_ipso_v2_3d_sensor_value_update( + anjay, ANJAY_DEMO_ACCELEROMETER_OID, 0, &value); } void accelerometer_add_instance(anjay_t *anjay, anjay_iid_t iid) { - - (void) anjay_ipso_3d_sensor_instance_add( + anjay_ipso_v2_3d_sensor_value_t value = get_accelerometer_value(); + (void) anjay_ipso_v2_3d_sensor_instance_add( anjay, ANJAY_DEMO_ACCELEROMETER_OID, iid, - (anjay_ipso_3d_sensor_impl_t) { + &value, + &(anjay_ipso_v2_3d_sensor_meta_t) { .unit = ANJAY_DEMO_ACCELEROMETER_UNIT, - .get_values = accelerometer_get_values, - .use_y_value = true, - .use_z_value = true, .min_range_value = 0.0, - .max_range_value = (double) ANJAY_DEMO_ACCELEROMETER_MAX + .max_range_value = (double) ANJAY_DEMO_ACCELEROMETER_MAX, + .y_axis_present = true, + .z_axis_present = true }); } void accelerometer_remove_instance(anjay_t *anjay, anjay_iid_t iid) { - (void) anjay_ipso_3d_sensor_instance_remove( + (void) anjay_ipso_v2_3d_sensor_instance_remove( anjay, ANJAY_DEMO_ACCELEROMETER_OID, iid); } diff --git a/demo/objects/location.c b/demo/objects/location.c index 9c54197f..8cf4a369 100644 --- a/demo/objects/location.c +++ b/demo/objects/location.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/portfolio.c b/demo/objects/portfolio.c index a97db523..59c66b76 100644 --- a/demo/objects/portfolio.c +++ b/demo/objects/portfolio.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * diff --git a/demo/objects/test.c b/demo/objects/test.c index fda8a64c..d59e86af 100644 --- a/demo/objects/test.c +++ b/demo/objects/test.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem Anjay LwM2M SDK * All rights reserved. * @@ -508,7 +508,8 @@ static int test_resource_write(anjay_t *anjay, return ANJAY_ERR_BAD_REQUEST; } inst->bytes_size = value; - return 0; + return anjay_notify_changed(anjay, (*obj_ptr)->oid, iid, + TEST_RES_BYTES); } case TEST_RES_BYTES_BURST: { assert(riid == ANJAY_ID_INVALID); diff --git a/demo/software_mgmt.c b/demo/software_mgmt.c new file mode 100644 index 00000000..fdcc15aa --- /dev/null +++ b/demo/software_mgmt.c @@ -0,0 +1,939 @@ +/* + * Copyright 2017-2024 AVSystem + * AVSystem Anjay LwM2M SDK + * All rights reserved. + * + * Licensed under the AVSystem-5-clause License. + * See the attached LICENSE file for details. + */ + +#include "software_mgmt.h" +#include "demo.h" +#include "demo_utils.h" + +#include +#include +#include + +#include + +#include +#include + +#define FORCE_ERROR_FAILED_INSTALL 1 +#define FORCE_DELAYED_SUCCESS_INSTALL 2 +#define FORCE_DELAYED_ERROR_FAILED_INSTALL 3 +#define FORCE_SET_SUCCESS_FROM_PERFORM_INSTALL 4 +#define FORCE_SET_SUCCESS_FROM_PERFORM_INSTALL_ACTIVATE 5 +#define FORCE_SET_FAILURE_FROM_PERFORM_INSTALL 6 +#define FORCE_SET_FAILURE_FROM_PERFORM_UNINSTALL 7 +#define FORCE_SET_FAILURE_FROM_PERFORM_ACTIVATION 8 +#define FORCE_SET_FAILURE_FROM_PERFORM_DEACTIVATION 9 +#define FORCE_SET_FAILURE_FROM_PREPARE_FOR_UPDATE 10 +#define FORCE_DO_NOTHING_SW 11 + +#define DEFAULT_INSTANCE_COUNT 2 + +static const char *SW_NAME[SW_MGMT_PACKAGE_COUNT] = { + [0] = "Cute software 0", + [1] = "Cute software 1", + [2] = "Secret software" +}; + +void sw_mgmt_set_package_path(sw_mgmt_logic_t *sw_mgmt, const char *path) { + if (sw_mgmt->stream) { + demo_log(ERROR, + "cannot set software package path while a download is in " + "progress"); + return; + } + char *new_target_path = avs_strdup(path); + if (!new_target_path) { + demo_log(ERROR, "out of memory"); + return; + } + avs_free(sw_mgmt->administratively_set_target_path); + + sw_mgmt->administratively_set_target_path = new_target_path; + demo_log(INFO, "software package path set to %s", + sw_mgmt->administratively_set_target_path); +} + +static int maybe_create_software_file(sw_mgmt_logic_t *sw_mgmt) { + if (sw_mgmt->next_target_path) { + return 0; + } + if (sw_mgmt->administratively_set_target_path) { + sw_mgmt->next_target_path = + avs_strdup(sw_mgmt->administratively_set_target_path); + } else { + sw_mgmt->next_target_path = generate_random_target_filepath(); + } + if (!sw_mgmt->next_target_path) { + return -1; + } + demo_log(INFO, "Created %s", sw_mgmt->next_target_path); + return 0; +} + +static void maybe_delete_software_file(sw_mgmt_logic_t *sw_mgmt) { + if (sw_mgmt->next_target_path) { + unlink(sw_mgmt->next_target_path); + demo_log(INFO, "Deleted %s", sw_mgmt->next_target_path); + avs_free(sw_mgmt->next_target_path); + sw_mgmt->next_target_path = NULL; + } +} + +static void fix_sw_meta_endianness(sw_metadata_t *meta) { + meta->version = avs_convert_be16(meta->version); + meta->force_error_case = avs_convert_be16(meta->force_error_case); + meta->crc = avs_convert_be32(meta->crc); +} + +static int read_sw_meta_from_file(FILE *f, sw_metadata_t *out_metadata) { + sw_metadata_t m; + memset(&m, 0, sizeof(m)); + + if (fread(m.magic, sizeof(m.magic), 1, f) != 1 + || fread(&m.version, sizeof(m.version), 1, f) != 1 + || fread(&m.force_error_case, sizeof(m.force_error_case), 1, f) != 1 + || fread(&m.crc, sizeof(m.crc), 1, f) != 1) { + demo_log(ERROR, "could not read software metadata"); + return -1; + } + + fix_sw_meta_endianness(&m); + *out_metadata = m; + return 0; +} + +static int unpack_sw_to_file(const char *sw_pkg_path, + const char *target_path, + sw_metadata_t *out_metadata) { + int result = -1; + FILE *sw = fopen(sw_pkg_path, "rb"); + FILE *tmp = NULL; + + if (!sw) { + demo_log(ERROR, "could not open file: %s", sw_pkg_path); + goto cleanup; + } + + tmp = fopen(target_path, "wb"); + if (!tmp) { + demo_log(ERROR, "could not open file: %s", target_path); + goto cleanup; + } + + result = read_sw_meta_from_file(sw, out_metadata); + if (result) { + demo_log(ERROR, "could not read metadata from file: %s", sw_pkg_path); + goto cleanup; + } + result = copy_file_contents(tmp, sw); + if (result) { + demo_log(ERROR, "could not copy software from %s to %s", sw_pkg_path, + target_path); + goto cleanup; + } + + result = 0; + +cleanup: + if (sw) { + fclose(sw); + } + if (tmp) { + fclose(tmp); + } + return result; +} + +static int unpack_software_in_place(sw_mgmt_logic_t *sw_mgmt) { + char *tmp_path = generate_random_target_filepath(); + if (!tmp_path) { + return -1; + } + + int result = unpack_sw_to_file(sw_mgmt->next_target_path, tmp_path, + &sw_mgmt->metadata); + if (result) { + goto cleanup; + } + + if ((result = rename(tmp_path, sw_mgmt->next_target_path)) == -1) { + demo_log(ERROR, "could not rename %s to %s: %s", tmp_path, + sw_mgmt->next_target_path, strerror(errno)); + goto cleanup; + } + + if ((result = chmod(sw_mgmt->next_target_path, 0700)) == -1) { + demo_log(ERROR, "could not set permissions for %s: %s", + sw_mgmt->next_target_path, strerror(errno)); + goto cleanup; + } + +cleanup: + unlink(tmp_path); + avs_free(tmp_path); + if (result) { + maybe_delete_software_file(sw_mgmt); + } + + return result; +} + +static bool sw_magic_valid(const sw_metadata_t *meta) { + if (memcmp(meta->magic, "ANJAY_SW", sizeof(meta->magic))) { + demo_log(ERROR, "invalid software magic"); + return false; + } + + return true; +} + +static bool sw_version_supported(const sw_metadata_t *meta) { + if (meta->version != 1) { + demo_log(ERROR, "unsupported software version: %" PRIu16, + meta->version); + return false; + } + + return true; +} + +static int validate_software(sw_mgmt_logic_t *sw_mgmt) { + if (!sw_magic_valid(&sw_mgmt->metadata) + || !sw_version_supported(&sw_mgmt->metadata)) { + return ANJAY_SW_MGMT_ERR_UNSUPPORTED_PACKAGE_TYPE; + } + + uint32_t actual_crc; + int result = calc_file_crc32(sw_mgmt->next_target_path, &actual_crc); + + if (result) { + demo_log(WARNING, "unable to check software CRC"); + return ANJAY_SW_MGMT_ERR_INTEGRITY_FAILURE; + } + + if (sw_mgmt->metadata.crc != actual_crc) { + demo_log(WARNING, "CRC mismatch: expected %08x != %08x actual", + sw_mgmt->metadata.crc, actual_crc); + return ANJAY_SW_MGMT_ERR_INTEGRITY_FAILURE; + } + + return 0; +} + +static void sw_mgmt_destroy_inst(sw_mgmt_logic_t *sw_mgmt) { + if (sw_mgmt->stream) { + fclose(sw_mgmt->stream); + } + avs_free(sw_mgmt->administratively_set_target_path); + avs_free(sw_mgmt->next_target_path); +} + +void sw_mgmt_update_destroy(sw_mgmt_logic_t *sw_mgmt_table) { + assert(sw_mgmt_table); + + for (size_t iid = 0; iid < SW_MGMT_PACKAGE_COUNT; iid++) { + sw_mgmt_destroy_inst(&sw_mgmt_table[iid]); + } +} + +typedef struct { + anjay_sw_mgmt_initial_state_t result[SW_MGMT_PACKAGE_COUNT]; + char *download_file[SW_MGMT_PACKAGE_COUNT]; + bool filename_administratively_set[SW_MGMT_PACKAGE_COUNT]; + bool exists[SW_MGMT_PACKAGE_COUNT]; +} persistence_file_data_t; + +#if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) +static bool is_valid_result(uint8_t result) { + switch (result) { + case ANJAY_SW_MGMT_INITIAL_STATE_IDLE: + case ANJAY_SW_MGMT_INITIAL_STATE_DOWNLOADED: + case ANJAY_SW_MGMT_INITIAL_STATE_DELIVERED: + case ANJAY_SW_MGMT_INITIAL_STATE_INSTALLING: + case ANJAY_SW_MGMT_INITIAL_STATE_INSTALLED_DEACTIVATED: + case ANJAY_SW_MGMT_INITIAL_STATE_INSTALLED_ACTIVATED: + return true; + default: + return false; + } +} + +static int write_persistence_file(const char *path, + persistence_file_data_t *data) { + avs_stream_t *stream = avs_stream_file_create(path, AVS_STREAM_FILE_WRITE); + avs_persistence_context_t ctx = + avs_persistence_store_context_create(stream); + int retval = 0; + + for (size_t iid = 0; iid < SW_MGMT_PACKAGE_COUNT; iid++) { + uint8_t result8 = (uint8_t) data->result[iid]; + if (!stream || avs_is_err(avs_persistence_bytes(&ctx, &result8, 1)) + || avs_is_err(avs_persistence_string(&ctx, + &data->download_file[iid])) + || avs_is_err(avs_persistence_bool( + &ctx, &data->filename_administratively_set[iid])) + || avs_is_err(avs_persistence_bool(&ctx, &data->exists[iid]))) { + demo_log(ERROR, "Could not write software state persistence file"); + retval = -1; + break; + } + } + if (stream) { + avs_stream_cleanup(&stream); + } + if (retval) { + unlink(path); + } + return retval; +} +#endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) + +static int read_persistence_file(const char *path, + persistence_file_data_t *data) { +#if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) + int ret = 0; + memset(data, 0, sizeof(*data)); + avs_stream_t *stream = NULL; + uint8_t result8 = (uint8_t) ANJAY_SW_MGMT_INITIAL_STATE_IDLE; + uint8_t result8_first = (uint8_t) ANJAY_SW_MGMT_INITIAL_STATE_IDLE; + + if ((stream = avs_stream_file_create(path, AVS_STREAM_FILE_READ))) { + // invalid or empty but existing file still signifies success but only + // for first instance + result8_first = (uint8_t) ANJAY_SW_MGMT_INITIAL_STATE_INSTALLING; + } + avs_persistence_context_t ctx = + avs_persistence_restore_context_create(stream); + + for (size_t iid = 0; iid < SW_MGMT_PACKAGE_COUNT; iid++) { + if (!stream || avs_is_err(avs_persistence_bytes(&ctx, &result8, 1)) + || !is_valid_result(result8) + || avs_is_err(avs_persistence_string(&ctx, + &data->download_file[iid])) + || avs_is_err(avs_persistence_bool( + &ctx, &data->filename_administratively_set[iid])) + || avs_is_err(avs_persistence_bool(&ctx, &data->exists[iid]))) { + demo_log(WARNING, + "Invalid data in the software state persistence file %s", + path); + for (size_t i = 0; i < SW_MGMT_PACKAGE_COUNT; i++) { + avs_free(data->download_file[i]); + } + memset(data, 0, sizeof(*data)); + data->result[0] = (anjay_sw_mgmt_initial_state_t) result8_first; + ret = -1; + break; + } + data->result[iid] = (anjay_sw_mgmt_initial_state_t) result8; + } + if (stream) { + avs_stream_cleanup(&stream); + } + return ret; +#else // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) + (void) path; + (void) data; + demo_log(WARNING, "Persistence not compiled in"); + return 0; +#endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) +} + +static void delete_persistence_file(const sw_mgmt_common_logic_t *sw) { +#if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) + unlink(sw->persistence_file); +#else // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) + (void) sw; + demo_log(WARNING, "Persistence not compiled in"); +#endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) +} + +static int update_persistence_file(const char *path, + sw_mgmt_logic_t *sw, + anjay_sw_mgmt_initial_state_t result, + anjay_iid_t iid) { +#if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) + int res = 0; + persistence_file_data_t data; + read_persistence_file(path, &data); + avs_free(data.download_file[iid]); + data.result[iid] = result; + data.download_file[iid] = sw->next_target_path; + data.filename_administratively_set[iid] = + sw->administratively_set_target_path; + data.exists[iid] = true; + res = write_persistence_file(path, &data); + for (size_t i = 0; i < SW_MGMT_PACKAGE_COUNT; i++) { + if (i != iid) { + avs_free(data.download_file[i]); + } + } + return res; +#else // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) + (void) path; + (void) sw; + (void) result; + (void) iid; + return 0; +#endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) +} + +static int update_persisted_instance_existence(const char *path, + bool exists, + anjay_iid_t iid) { +#if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) + int res = 0; + persistence_file_data_t data; + read_persistence_file(path, &data); + data.exists[iid] = exists; + res = write_persistence_file(path, &data); + for (size_t i = 0; i < SW_MGMT_PACKAGE_COUNT; i++) { + avs_free(data.download_file[i]); + } + return res; +#else // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) + (void) path; + (void) exists; + (void) iid; + return 0; +#endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) +} + +static int sw_mgmt_stream_open(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + (void) obj_ctx; + (void) iid; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + assert(!sw->stream); + + if (maybe_create_software_file(sw)) { + return -1; + } + + if (!(sw->stream = fopen(sw->next_target_path, "wb"))) { + demo_log(ERROR, "could not open file: %s", sw->next_target_path); + return -1; + } + + return 0; +} + +static int sw_mgmt_stream_write(void *obj_ctx, + anjay_iid_t iid, + void *inst_ctx, + const void *data, + size_t length) { + (void) obj_ctx; + (void) iid; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + + if (!sw->stream) { + demo_log(ERROR, "stream not open"); + return -1; + } + + if (length + && (fwrite(data, length, 1, sw->stream) != 1 + // Software management integration tests measure download + // progress by checking file size, so avoiding buffering + // is required. + || fflush(sw->stream) != 0)) { + demo_log(ERROR, "fwrite or fflush failed: %s", strerror(errno)); + return ANJAY_SW_MGMT_ERR_NOT_ENOUGH_SPACE; + } + + return 0; +} + +static int +sw_mgmt_stream_finish(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + if (sw_common->auto_suspend) { + anjay_sw_mgmt_pull_suspend(sw_common->anjay); + } + if (!sw->stream) { + demo_log(ERROR, "stream not open"); + return -1; + } + fclose(sw->stream); + sw->stream = NULL; + + (void) update_persistence_file(sw_common->persistence_file, sw, + ANJAY_SW_MGMT_INITIAL_STATE_DOWNLOADED, iid); + + if (sw_common->terminate_after_downloading && iid == 0) { + anjay_event_loop_interrupt(sw_common->anjay); + } + + return 0; +} + +static int +sw_mgmt_check_integrity(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + int result = 0; + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + if (!(sw_common->terminate_after_downloading && iid == 0)) { + + if (unpack_software_in_place(sw)) { + return ANJAY_SW_MGMT_ERR_UNSUPPORTED_PACKAGE_TYPE; + } + + result = validate_software(sw); + if (!result) { + demo_log(INFO, "software downloaded successfully"); + (void) update_persistence_file( + sw_common->persistence_file, sw, + ANJAY_SW_MGMT_INITIAL_STATE_DELIVERED, iid); + } + } + return result; +} + +static void sw_mgmt_reset(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + (void) iid; + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + + if (sw->stream) { + fclose(sw->stream); + sw->stream = NULL; + } + + maybe_delete_software_file(sw); + delete_persistence_file(sw_common); + if (sw_common->auto_suspend) { + anjay_sw_mgmt_pull_suspend(sw_common->anjay); + } +} + +static const char * +sw_mgmt_get_name(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + (void) obj_ctx; + (void) inst_ctx; + return SW_NAME[iid]; +} + +static const char * +sw_mgmt_get_version(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + (void) obj_ctx; + (void) iid; + (void) inst_ctx; + return "1.0"; +} + +static int sw_mgmt_pkg_install(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + + demo_log(INFO, "*** SOFTWARE INSTALL: %s ***", sw->next_target_path); + switch (sw->metadata.force_error_case) { + case FORCE_ERROR_FAILED_INSTALL: + demo_log(ERROR, "install failed"); + delete_persistence_file(sw_common); + return -1; + case FORCE_DELAYED_SUCCESS_INSTALL: + if (argv_append("--delayed-sw-mgmt-result") || argv_append("1")) { + demo_log(ERROR, "could not append delayed result to argv"); + return -1; + } + break; + case FORCE_DELAYED_ERROR_FAILED_INSTALL: + if (argv_append("--delayed-sw-mgmt-result") || argv_append("0")) { + demo_log(ERROR, "could not append delayed result to argv"); + return -1; + } + break; + case FORCE_SET_SUCCESS_FROM_PERFORM_INSTALL: + if (anjay_sw_mgmt_finish_pkg_install( + sw_common->anjay, iid, + ANJAY_SW_MGMT_FINISH_PKG_INSTALL_SUCCESS_INACTIVE)) { + demo_log(ERROR, "anjay_sw_mgmt_finish_pkg_install failed"); + return -1; + } + return 0; + case FORCE_SET_SUCCESS_FROM_PERFORM_INSTALL_ACTIVATE: + if (anjay_sw_mgmt_finish_pkg_install( + sw_common->anjay, iid, + ANJAY_SW_MGMT_FINISH_PKG_INSTALL_SUCCESS_ACTIVE)) { + demo_log(ERROR, "anjay_sw_mgmt_finish_pkg_install failed"); + return -1; + } + return 0; + case FORCE_SET_FAILURE_FROM_PERFORM_INSTALL: + if (anjay_sw_mgmt_finish_pkg_install( + sw_common->anjay, iid, + ANJAY_SW_MGMT_FINISH_PKG_INSTALL_FAILURE)) { + demo_log(ERROR, "anjay_sw_mgmt_finish_pkg_install failed"); + return -1; + } + return 0; + case FORCE_DO_NOTHING_SW: + return 0; + default: + break; + } + + if (sw->metadata.force_error_case == FORCE_DELAYED_SUCCESS_INSTALL + || sw->metadata.force_error_case + == FORCE_DELAYED_ERROR_FAILED_INSTALL) { + execv(sw->next_target_path, argv_get()); + demo_log(ERROR, "execv failed (%s)", strerror(errno)); + delete_persistence_file(sw_common); + return -1; + } else { + if (system(sw->next_target_path)) { + demo_log(ERROR, "execution of shell command failed"); + return -1; + } + anjay_sw_mgmt_finish_pkg_install( + sw_common->anjay, iid, + ANJAY_SW_MGMT_FINISH_PKG_INSTALL_SUCCESS_INACTIVE); + (void) update_persistence_file( + sw_common->persistence_file, sw, + ANJAY_SW_MGMT_INITIAL_STATE_INSTALLED_DEACTIVATED, iid); + return 0; + } +} + +static int +sw_mgmt_pkg_uninstall(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + + if (sw->metadata.force_error_case + == FORCE_SET_FAILURE_FROM_PERFORM_UNINSTALL) { + return -1; + } else { + (void) update_persistence_file(sw_common->persistence_file, sw, + ANJAY_SW_MGMT_INITIAL_STATE_IDLE, iid); + } + + return 0; +} + +static int +sw_mgmt_prepare_for_update(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + + if (sw->metadata.force_error_case + == FORCE_SET_FAILURE_FROM_PREPARE_FOR_UPDATE) { + return -1; + } else { + (void) update_persistence_file(sw_common->persistence_file, sw, + ANJAY_SW_MGMT_INITIAL_STATE_IDLE, iid); + } + + return 0; +} + +static int sw_mgmt_activate(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + bool activate; + + if ((sw_common->disable_repeated_activation_deactivation + && (anjay_sw_mgmt_get_activation_state(sw_common->anjay, iid, + &activate) + || activate)) + || sw->metadata.force_error_case + == FORCE_SET_FAILURE_FROM_PERFORM_ACTIVATION) { + return -1; + } else { + (void) update_persistence_file( + sw_common->persistence_file, sw, + ANJAY_SW_MGMT_INITIAL_STATE_INSTALLED_ACTIVATED, iid); + } + + return 0; +} + +static int sw_mgmt_deactivate(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + bool activate; + + if ((sw_common->disable_repeated_activation_deactivation + && (anjay_sw_mgmt_get_activation_state(sw_common->anjay, iid, + &activate) + || !activate)) + || sw->metadata.force_error_case + == FORCE_SET_FAILURE_FROM_PERFORM_DEACTIVATION) { + return -1; + } else { + (void) update_persistence_file( + sw_common->persistence_file, sw, + ANJAY_SW_MGMT_INITIAL_STATE_INSTALLED_DEACTIVATED, iid); + } + + return 0; +} + +#ifdef ANJAY_WITH_DOWNLOADER +static int +sw_mgmt_get_security_config(void *obj_ctx, + anjay_iid_t iid, + void *inst_ctx, + const char *download_uri, + anjay_security_config_t *out_security_info) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + (void) download_uri; + (void) iid; + (void) inst_ctx; + memset(out_security_info, 0, sizeof(*out_security_info)); + out_security_info->security_info = *sw_common->security_info; + return 0; +} + +static avs_time_duration_t +sw_mgmt_get_tcp_request_timeout(void *obj_ctx, + anjay_iid_t iid, + void *inst_ctx, + const char *download_uri) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + (void) download_uri; + (void) iid; + (void) inst_ctx; + return *sw_common->tcp_request_timeout; +} +# ifdef ANJAY_WITH_COAP_DOWNLOAD +static avs_coap_udp_tx_params_t +sw_mgmt_get_coap_tx_params(void *obj_ctx, + anjay_iid_t iid, + void *inst_ctx, + const char *download_uri) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + (void) download_uri; + (void) iid; + (void) inst_ctx; + if (sw_common->auto_suspend) { + anjay_sw_mgmt_pull_reconnect(sw_common->anjay); + } + return sw_common->coap_tx_params != NULL ? *sw_common->coap_tx_params + : AVS_COAP_DEFAULT_UDP_TX_PARAMS; +} +# endif // ANJAY_WITH_COAP_DOWNLOAD +#endif // ANJAY_WITH_DOWNLOADER + +static int +sw_mgmt_add_handler(void *obj_ctx, anjay_iid_t iid, void **out_inst_ctx) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + + if (iid < SW_MGMT_PACKAGE_COUNT + && !update_persisted_instance_existence(sw_common->persistence_file, + true, iid)) { + *out_inst_ctx = (void *) &sw_common->sw_mgmt_table[iid]; + } else { + return -1; + } + + return 0; +} + +static int +sw_mgmt_remove_handler(void *obj_ctx, anjay_iid_t iid, void *inst_ctx) { + sw_mgmt_common_logic_t *sw_common = (sw_mgmt_common_logic_t *) obj_ctx; + sw_mgmt_logic_t *sw = (sw_mgmt_logic_t *) inst_ctx; + + if (iid < SW_MGMT_PACKAGE_COUNT + && !update_persisted_instance_existence(sw_common->persistence_file, + false, iid)) { + sw_mgmt_destroy_inst(sw); + } else { + return -1; + } + + return 0; +} + +static anjay_sw_mgmt_handlers_t g_handlers = { + .stream_open = sw_mgmt_stream_open, + .stream_write = sw_mgmt_stream_write, + .stream_finish = sw_mgmt_stream_finish, + .check_integrity = sw_mgmt_check_integrity, + .reset = sw_mgmt_reset, + .get_name = sw_mgmt_get_name, + .get_version = sw_mgmt_get_version, + .pkg_install = sw_mgmt_pkg_install, + .pkg_uninstall = sw_mgmt_pkg_uninstall, + .prepare_for_update = sw_mgmt_prepare_for_update, + .activate = sw_mgmt_activate, + .deactivate = sw_mgmt_deactivate, + .add_handler = sw_mgmt_add_handler, + .remove_handler = sw_mgmt_remove_handler +}; + +typedef struct { + anjay_t *anjay; + bool delayed_result; +} set_delayed_sw_mgmt_update_result_args_t; + +static void set_delayed_sw_mgmt_update_result(avs_sched_t *sched, + const void *arg) { + (void) sched; + const set_delayed_sw_mgmt_update_result_args_t *args = + (const set_delayed_sw_mgmt_update_result_args_t *) arg; + anjay_sw_mgmt_finish_pkg_install( + args->anjay, 0, + args->delayed_result + ? ANJAY_SW_MGMT_FINISH_PKG_INSTALL_SUCCESS_INACTIVE + : ANJAY_SW_MGMT_FINISH_PKG_INSTALL_FAILURE); +} + +int sw_mgmt_install(anjay_t *anjay, + sw_mgmt_common_logic_t *sw_mgmt_common, + sw_mgmt_logic_t *sw_mgmt_table, + const char *persistence_file, + bool prefer_same_socket_downloads, + uint8_t delayed_first_instance_install_result, + bool terminate_after_downloading, + bool disable_repeated_activation_deactivation +#ifdef ANJAY_WITH_DOWNLOADER + , + avs_net_security_info_t *security_info, + avs_coap_udp_tx_params_t *tx_params, + avs_time_duration_t *tcp_request_timeout, + bool auto_suspend +#endif // ANJAY_WITH_DOWNLOADER +) { + int ret = 0; + sw_mgmt_logic_t *sw_logic = NULL; + sw_mgmt_common->anjay = anjay; + sw_mgmt_common->sw_mgmt_table = sw_mgmt_table; + sw_mgmt_common->persistence_file = persistence_file; + sw_mgmt_common->terminate_after_downloading = terminate_after_downloading; + sw_mgmt_common->disable_repeated_activation_deactivation = + disable_repeated_activation_deactivation; +#ifdef ANJAY_WITH_DOWNLOADER + if (security_info) { + sw_mgmt_common->security_info = security_info; + g_handlers.get_security_config = sw_mgmt_get_security_config; + } else { + g_handlers.get_security_config = NULL; + } + + if (tx_params || auto_suspend) { + sw_mgmt_common->auto_suspend = auto_suspend; + sw_mgmt_common->coap_tx_params = tx_params; + g_handlers.get_coap_tx_params = sw_mgmt_get_coap_tx_params; + } else { + g_handlers.get_coap_tx_params = NULL; + } + + if (tcp_request_timeout && avs_time_duration_valid(*tcp_request_timeout)) { + sw_mgmt_common->tcp_request_timeout = tcp_request_timeout; + g_handlers.get_tcp_request_timeout = sw_mgmt_get_tcp_request_timeout; + } else { + g_handlers.get_tcp_request_timeout = NULL; + } +#endif // ANJAY_WITH_DOWNLOADER + + const anjay_sw_mgmt_settings_t settings = { + .handlers = &g_handlers, + .obj_ctx = sw_mgmt_common, +#ifdef ANJAY_WITH_DOWNLOADER + .prefer_same_socket_downloads = prefer_same_socket_downloads +#endif // ANJAY_WITH_DOWNLOADER + }; + + persistence_file_data_t data; + if (read_persistence_file(persistence_file, &data)) { + for (size_t i = 0; i < DEFAULT_INSTANCE_COUNT; i++) { + data.exists[i] = true; + } + } + delete_persistence_file(sw_mgmt_common); + + if (anjay_sw_mgmt_install(anjay, &settings)) { + ret = -1; + goto exit; + } + + for (anjay_iid_t iid = 0; iid < SW_MGMT_PACKAGE_COUNT; iid++) { +#if defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) \ + && defined(AVS_COMMONS_STREAM_WITH_FILE) + if (data.exists[iid]) +#endif // defined(AVS_COMMONS_WITH_AVS_PERSISTENCE) && + // defined(AVS_COMMONS_STREAM_WITH_FILE) + { + sw_logic = &sw_mgmt_table[iid]; + + if ((sw_logic->next_target_path = data.download_file[iid]) + && data.filename_administratively_set[iid] + && !(sw_logic->administratively_set_target_path = + avs_strdup(data.download_file[iid]))) { + demo_log(WARNING, + "Could not administratively set firmware path for %d", + iid); + } + + anjay_sw_mgmt_instance_initializer_t inst_settings = { + .iid = iid, + .initial_state = data.result[iid], + .inst_ctx = sw_logic + }; + + if (iid == 0 + && (delayed_first_instance_install_result == 0 + || delayed_first_instance_install_result == 1)) { + demo_log(INFO, + "delayed_result == %d; initializing Software " + "Management " + "in DELIVERED state", + (int) delayed_first_instance_install_result); + inst_settings.initial_state = + ANJAY_SW_MGMT_INITIAL_STATE_INSTALLING; + + // Simulate installing process that finishes after the LwM2M + // client starts by changing the Update Result later at runtime + set_delayed_sw_mgmt_update_result_args_t args = { + .anjay = anjay, + .delayed_result = delayed_first_instance_install_result == 1 + }; + + if (AVS_SCHED_DELAYED(anjay_get_scheduler(anjay), NULL, + avs_time_duration_from_scalar(1, + AVS_TIME_S), + set_delayed_sw_mgmt_update_result, &args, + sizeof(args))) { + ret = -1; + goto exit; + } + } + + if (anjay_sw_mgmt_add_instance(anjay, &inst_settings)) { + ret = -1; + goto exit; + } + + if (auto_suspend) { + anjay_sw_mgmt_pull_suspend(anjay); + } + } + } +exit: + if (ret) { + sw_mgmt_update_destroy(sw_mgmt_table); + } + return ret; +} diff --git a/demo/software_mgmt.h b/demo/software_mgmt.h new file mode 100644 index 00000000..5437b532 --- /dev/null +++ b/demo/software_mgmt.h @@ -0,0 +1,68 @@ +/* + * Copyright 2017-2024 AVSystem + * AVSystem Anjay LwM2M SDK + * All rights reserved. + * + * Licensed under the AVSystem-5-clause License. + * See the attached LICENSE file for details. + */ + +#ifndef SOFTWARE_MGMT_H +#define SOFTWARE_MGMT_H + +#include +#include + +#include +#include + +#define SW_MGMT_PACKAGE_COUNT 3 + +typedef struct software_metadata { + uint8_t magic[8]; + uint16_t version; + uint16_t force_error_case; + uint32_t crc; +} sw_metadata_t; + +typedef struct { + FILE *stream; + char *administratively_set_target_path; + char *next_target_path; + sw_metadata_t metadata; +} sw_mgmt_logic_t; + +typedef struct { + anjay_t *anjay; + const char *persistence_file; + avs_net_security_info_t *security_info; + avs_coap_udp_tx_params_t *coap_tx_params; + avs_time_duration_t *tcp_request_timeout; + bool auto_suspend; + bool terminate_after_downloading; + bool disable_repeated_activation_deactivation; + sw_mgmt_logic_t *sw_mgmt_table; +} sw_mgmt_common_logic_t; + +int sw_mgmt_install(anjay_t *anjay, + sw_mgmt_common_logic_t *sw_mgmt_common, + sw_mgmt_logic_t *sw_table, + const char *persistence_file, + bool prefer_same_socket_downloads, + uint8_t delayed_first_instance_install_result, + bool terminate_after_downloading, + bool disable_repeated_activation_deactivation +#ifdef ANJAY_WITH_DOWNLOADER + , + avs_net_security_info_t *security_info, + avs_coap_udp_tx_params_t *tx_params, + avs_time_duration_t *tcp_request_timeout, + bool auto_suspend +#endif // ANJAY_WITH_DOWNLOADER +); + +void sw_mgmt_update_destroy(sw_mgmt_logic_t *sw_mgmt_table); + +void sw_mgmt_set_package_path(sw_mgmt_logic_t *sw_mgmt, const char *path); + +#endif // SOFTWARE_MGMT_H diff --git a/deps/avs_coap/CMakeLists.txt b/deps/avs_coap/CMakeLists.txt index 60b58f20..4d323b65 100644 --- a/deps/avs_coap/CMakeLists.txt +++ b/deps/avs_coap/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/NOTICE b/deps/avs_coap/NOTICE index 238dcba7..b869bc8d 100644 --- a/deps/avs_coap/NOTICE +++ b/deps/avs_coap/NOTICE @@ -1,5 +1,5 @@ AVSystem CoAP Library -Copyright 2017-2023 AVSystem +Copyright 2017-2024 AVSystem This product includes software developed at AVSystem (www.avsystem.com). diff --git a/deps/avs_coap/cmake/AddHeaderSelfSufficiencyTests.cmake b/deps/avs_coap/cmake/AddHeaderSelfSufficiencyTests.cmake index 422dabfa..6fb773c8 100644 --- a/deps/avs_coap/cmake/AddHeaderSelfSufficiencyTests.cmake +++ b/deps/avs_coap/cmake/AddHeaderSelfSufficiencyTests.cmake @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/cmake/avs_coap-config.cmake.in b/deps/avs_coap/cmake/avs_coap-config.cmake.in index 1ee0be7b..bd1649db 100644 --- a/deps/avs_coap/cmake/avs_coap-config.cmake.in +++ b/deps/avs_coap/cmake/avs_coap-config.cmake.in @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/cmake/fill-placeholders.cmake b/deps/avs_coap/cmake/fill-placeholders.cmake index b0659f8b..56979aac 100644 --- a/deps/avs_coap/cmake/fill-placeholders.cmake +++ b/deps/avs_coap/cmake/fill-placeholders.cmake @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # @@ -10,7 +10,7 @@ string(TIMESTAMP current_year "%Y") foreach(file IN LISTS CMAKE_INSTALL_MANIFEST_FILES) if(file MATCHES ".(h|hpp|c|cpp|cmake|py|sh)$") file(READ ${file} file_contents) - string(REPLACE "2017-2023" "${current_year}" file_contents_replaced "${file_contents}") + string(REPLACE "2017-2024" "${current_year}" file_contents_replaced "${file_contents}") file(WRITE ${file} "${file_contents_replaced}") endif() endforeach() diff --git a/deps/avs_coap/devconfig b/deps/avs_coap/devconfig index a53e8934..ee7b9bc7 100755 --- a/deps/avs_coap/devconfig +++ b/deps/avs_coap/devconfig @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/doc/CMakeLists.txt b/deps/avs_coap/doc/CMakeLists.txt index f7abfb9d..5aaa2a67 100644 --- a/deps/avs_coap/doc/CMakeLists.txt +++ b/deps/avs_coap/doc/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/doc/sphinx/source/ErrorHandling.rst b/deps/avs_coap/doc/sphinx/source/ErrorHandling.rst index e8dcd7fa..270f5f10 100644 --- a/deps/avs_coap/doc/sphinx/source/ErrorHandling.rst +++ b/deps/avs_coap/doc/sphinx/source/ErrorHandling.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem CoAP library All rights reserved. diff --git a/deps/avs_coap/doc/sphinx/source/Fuzzing.rst b/deps/avs_coap/doc/sphinx/source/Fuzzing.rst index 584a27d3..3f3ecd29 100644 --- a/deps/avs_coap/doc/sphinx/source/Fuzzing.rst +++ b/deps/avs_coap/doc/sphinx/source/Fuzzing.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem CoAP library All rights reserved. diff --git a/deps/avs_coap/doc/sphinx/source/Overview.rst b/deps/avs_coap/doc/sphinx/source/Overview.rst index 0e3dc719..1a6a459e 100644 --- a/deps/avs_coap/doc/sphinx/source/Overview.rst +++ b/deps/avs_coap/doc/sphinx/source/Overview.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem CoAP library All rights reserved. diff --git a/deps/avs_coap/doc/sphinx/source/_static/theme_overrides.css b/deps/avs_coap/doc/sphinx/source/_static/theme_overrides.css index 1b442baa..bbb4efaa 100644 --- a/deps/avs_coap/doc/sphinx/source/_static/theme_overrides.css +++ b/deps/avs_coap/doc/sphinx/source/_static/theme_overrides.css @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/doc/sphinx/source/conf.py.in b/deps/avs_coap/doc/sphinx/source/conf.py.in index 13b6cb98..e3bdfa37 100644 --- a/deps/avs_coap/doc/sphinx/source/conf.py.in +++ b/deps/avs_coap/doc/sphinx/source/conf.py.in @@ -18,7 +18,7 @@ # -- Project information ----------------------------------------------------- project = 'avs_coap' -copyright = '2017-2023, AVSystem' +copyright = '2017-2024, AVSystem' author = 'AVSystem' version = '@AVS_COAP_VERSION@' release = version diff --git a/deps/avs_coap/doc/sphinx/source/index.rst b/deps/avs_coap/doc/sphinx/source/index.rst index 1c6d1560..88544355 100644 --- a/deps/avs_coap/doc/sphinx/source/index.rst +++ b/deps/avs_coap/doc/sphinx/source/index.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem CoAP library All rights reserved. diff --git a/deps/avs_coap/examples/CMakeLists.txt b/deps/avs_coap/examples/CMakeLists.txt index 059f9802..22c46fe1 100644 --- a/deps/avs_coap/examples/CMakeLists.txt +++ b/deps/avs_coap/examples/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/examples/async-client/CMakeLists.txt b/deps/avs_coap/examples/async-client/CMakeLists.txt index 4760f484..cc42691b 100644 --- a/deps/avs_coap/examples/async-client/CMakeLists.txt +++ b/deps/avs_coap/examples/async-client/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/examples/async-client/src/main.c b/deps/avs_coap/examples/async-client/src/main.c index 6e7ab5b5..76bd56a2 100644 --- a/deps/avs_coap/examples/async-client/src/main.c +++ b/deps/avs_coap/examples/async-client/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/async.h b/deps/avs_coap/include_public/avsystem/coap/async.h index 43b864aa..802deb93 100644 --- a/deps/avs_coap/include_public/avsystem/coap/async.h +++ b/deps/avs_coap/include_public/avsystem/coap/async.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/async_client.h b/deps/avs_coap/include_public/avsystem/coap/async_client.h index 422fdb4a..3aa16164 100644 --- a/deps/avs_coap/include_public/avsystem/coap/async_client.h +++ b/deps/avs_coap/include_public/avsystem/coap/async_client.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/async_exchange.h b/deps/avs_coap/include_public/avsystem/coap/async_exchange.h index 6ebf65c1..37166ee7 100644 --- a/deps/avs_coap/include_public/avsystem/coap/async_exchange.h +++ b/deps/avs_coap/include_public/avsystem/coap/async_exchange.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/async_server.h b/deps/avs_coap/include_public/avsystem/coap/async_server.h index 87ed0b97..05470bef 100644 --- a/deps/avs_coap/include_public/avsystem/coap/async_server.h +++ b/deps/avs_coap/include_public/avsystem/coap/async_server.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/avs_coap_config.h.in b/deps/avs_coap/include_public/avsystem/coap/avs_coap_config.h.in index a40d73a7..edba0df2 100644 --- a/deps/avs_coap/include_public/avsystem/coap/avs_coap_config.h.in +++ b/deps/avs_coap/include_public/avsystem/coap/avs_coap_config.h.in @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/coap.h b/deps/avs_coap/include_public/avsystem/coap/coap.h index 079c99f6..ce07bc4a 100644 --- a/deps/avs_coap/include_public/avsystem/coap/coap.h +++ b/deps/avs_coap/include_public/avsystem/coap/coap.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/code.h b/deps/avs_coap/include_public/avsystem/coap/code.h index a9a4a871..3b90db9a 100644 --- a/deps/avs_coap/include_public/avsystem/coap/code.h +++ b/deps/avs_coap/include_public/avsystem/coap/code.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/ctx.h b/deps/avs_coap/include_public/avsystem/coap/ctx.h index 267273bb..ceb42e4d 100644 --- a/deps/avs_coap/include_public/avsystem/coap/ctx.h +++ b/deps/avs_coap/include_public/avsystem/coap/ctx.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/observe.h b/deps/avs_coap/include_public/avsystem/coap/observe.h index 488d7b58..5cc560ea 100644 --- a/deps/avs_coap/include_public/avsystem/coap/observe.h +++ b/deps/avs_coap/include_public/avsystem/coap/observe.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/option.h b/deps/avs_coap/include_public/avsystem/coap/option.h index a199b06c..af94915f 100644 --- a/deps/avs_coap/include_public/avsystem/coap/option.h +++ b/deps/avs_coap/include_public/avsystem/coap/option.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/streaming.h b/deps/avs_coap/include_public/avsystem/coap/streaming.h index e5b050a5..78395430 100644 --- a/deps/avs_coap/include_public/avsystem/coap/streaming.h +++ b/deps/avs_coap/include_public/avsystem/coap/streaming.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/tcp.h b/deps/avs_coap/include_public/avsystem/coap/tcp.h index 7310d45d..3bd10e43 100644 --- a/deps/avs_coap/include_public/avsystem/coap/tcp.h +++ b/deps/avs_coap/include_public/avsystem/coap/tcp.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/token.h b/deps/avs_coap/include_public/avsystem/coap/token.h index c186771e..44e3ea5c 100644 --- a/deps/avs_coap/include_public/avsystem/coap/token.h +++ b/deps/avs_coap/include_public/avsystem/coap/token.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/udp.h b/deps/avs_coap/include_public/avsystem/coap/udp.h index 8a085f29..0f3a0f28 100644 --- a/deps/avs_coap/include_public/avsystem/coap/udp.h +++ b/deps/avs_coap/include_public/avsystem/coap/udp.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/include_public/avsystem/coap/writer.h b/deps/avs_coap/include_public/avsystem/coap/writer.h index e01d5f55..446cb892 100644 --- a/deps/avs_coap/include_public/avsystem/coap/writer.h +++ b/deps/avs_coap/include_public/avsystem/coap/writer.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/async/avs_coap_async_client.c b/deps/avs_coap/src/async/avs_coap_async_client.c index 23181542..70240fb7 100644 --- a/deps/avs_coap/src/async/avs_coap_async_client.c +++ b/deps/avs_coap/src/async/avs_coap_async_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/async/avs_coap_async_client.h b/deps/avs_coap/src/async/avs_coap_async_client.h index 604c7e65..86981043 100644 --- a/deps/avs_coap/src/async/avs_coap_async_client.h +++ b/deps/avs_coap/src/async/avs_coap_async_client.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/async/avs_coap_async_server.c b/deps/avs_coap/src/async/avs_coap_async_server.c index 7165b52d..68d692ff 100644 --- a/deps/avs_coap/src/async/avs_coap_async_server.c +++ b/deps/avs_coap/src/async/avs_coap_async_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -221,9 +221,12 @@ static bool is_last_response_block_sent(const avs_coap_exchange_t *exchange) { static bool is_exchange_done(const avs_coap_exchange_t *exchange) { switch (exchange->by_type.server.reliability_hint) { case AVS_COAP_NOTIFY_PREFER_CONFIRMABLE: - // CON response? we're not done until the delivery handler is called. - // send_result_handler will take care of cleanup - return false; + // CON response? we're not done until the initial CON request has been + // ACKed, which is handled in send_result_handler + if (!exchange->by_type.server.con_block_acked) { + return false; + } + break; case AVS_COAP_NOTIFY_PREFER_NON_CONFIRMABLE: break; } @@ -285,13 +288,16 @@ send_result_handler(avs_coap_ctx_t *ctx, break; } + avs_coap_server_exchange_data_t *server = &exchange->by_type.server; + if (avs_is_ok(fail_err)) { + server->con_block_acked = true; #ifdef WITH_AVS_COAP_BLOCK - if (avs_is_ok(fail_err) && !is_last_response_block_sent(exchange)) { - return AVS_COAP_RESPONSE_ACCEPTED; - } + if (!is_last_response_block_sent(exchange)) { + return AVS_COAP_RESPONSE_ACCEPTED; + } #endif // WITH_AVS_COAP_BLOCK + } - avs_coap_server_exchange_data_t *server = &exchange->by_type.server; AVS_ASSERT(server->delivery_handler, "send_result_handler called for an exchange without " "user-defined delivery handler; this should not happen"); @@ -349,9 +355,10 @@ static avs_error_t send_ise(avs_coap_ctx_t *ctx, result_handler_arg); } -static avs_error_t -server_exchange_send_next_chunk(avs_coap_ctx_t *ctx, - AVS_LIST(avs_coap_exchange_t) *exchange_ptr) { +static avs_error_t server_exchange_send_next_chunk( + avs_coap_ctx_t *ctx, + AVS_LIST(avs_coap_exchange_t) *exchange_ptr, + avs_coap_notify_reliability_hint_t reliability_hint) { AVS_ASSERT(AVS_LIST_FIND_PTR(&_avs_coap_get_base(ctx)->server_exchanges, *exchange_ptr) != NULL, @@ -359,8 +366,7 @@ server_exchange_send_next_chunk(avs_coap_ctx_t *ctx, avs_coap_exchange_id_t id = (*exchange_ptr)->id; avs_coap_send_result_handler_t *handler = NULL; - if ((*exchange_ptr)->by_type.server.reliability_hint - == AVS_COAP_NOTIFY_PREFER_CONFIRMABLE) { + if (reliability_hint == AVS_COAP_NOTIFY_PREFER_CONFIRMABLE) { handler = send_result_handler; } @@ -931,7 +937,9 @@ static avs_error_t continue_request_exchange(avs_coap_ctx_t *ctx) { update_exchange_block2_option(*exchange_ptr, &coap_base->request_ctx.request); #endif // WITH_AVS_COAP_BLOCK - return server_exchange_send_next_chunk(ctx, exchange_ptr); + return server_exchange_send_next_chunk( + ctx, exchange_ptr, + (*exchange_ptr)->by_type.server.reliability_hint); } static void cleanup_exchange_by_id(avs_coap_ctx_t *ctx, @@ -1093,7 +1101,12 @@ static avs_error_t handle_request(avs_coap_ctx_t *ctx, // Figure 12: "Observe Sequence with Block-Wise Response" avs_coap_options_remove_by_number(&(*existing_exchange_ptr)->options, AVS_COAP_OPTION_OBSERVE); - return server_exchange_send_next_chunk(ctx, existing_exchange_ptr); + // Also, subsequent blocks in a blockwise notification are just regular + // responses; don't send them as Confirmable because we don't support + // acknowledging Separate Responses properly + return server_exchange_send_next_chunk( + ctx, existing_exchange_ptr, + AVS_COAP_NOTIFY_PREFER_NON_CONFIRMABLE); } #else // WITH_AVS_COAP_BLOCK *out_exchange = *existing_exchange_ptr; @@ -1369,7 +1382,9 @@ avs_coap_notify_async(avs_coap_ctx_t *ctx, # ifdef WITH_AVS_COAP_BLOCK update_exchange_block2_option(exchange, exchange_create_args.request); # endif // WITH_AVS_COAP_BLOCK - err = server_exchange_send_next_chunk(ctx, &coap_base->server_exchanges); + err = server_exchange_send_next_chunk( + ctx, &coap_base->server_exchanges, + coap_base->server_exchanges->by_type.server.reliability_hint); AVS_LIST(avs_coap_exchange_t) *exchange_ptr = _avs_coap_find_server_exchange_ptr_by_id( ctx, exchange_create_args.exchange_id); diff --git a/deps/avs_coap/src/async/avs_coap_async_server.h b/deps/avs_coap/src/async/avs_coap_async_server.h index 60911f5a..520096da 100644 --- a/deps/avs_coap/src/async/avs_coap_async_server.h +++ b/deps/avs_coap/src/async/avs_coap_async_server.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -30,6 +30,12 @@ typedef struct avs_coap_server_exchange_data { /** Flag indicating whether NON messages may be used if supported. */ avs_coap_notify_reliability_hint_t reliability_hint; + /** + * Flag indicating whether the initial CON block of a Confirmable + * notification has been ACKed by the remote endpoint. + */ + bool con_block_acked; + /** * User-defined response delivery handler. May be non-NULL for Observe * notifications. diff --git a/deps/avs_coap/src/async/avs_coap_exchange.c b/deps/avs_coap/src/async/avs_coap_exchange.c index 9a78c36e..8fd8a74c 100644 --- a/deps/avs_coap/src/async/avs_coap_exchange.c +++ b/deps/avs_coap/src/async/avs_coap_exchange.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/async/avs_coap_exchange.h b/deps/avs_coap/src/async/avs_coap_exchange.h index 41c0a271..5f3395dc 100644 --- a/deps/avs_coap/src/async/avs_coap_exchange.h +++ b/deps/avs_coap/src/async/avs_coap_exchange.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_code_utils.c b/deps/avs_coap/src/avs_coap_code_utils.c index 6ceb18be..59bbb87f 100644 --- a/deps/avs_coap/src/avs_coap_code_utils.c +++ b/deps/avs_coap/src/avs_coap_code_utils.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_code_utils.h b/deps/avs_coap/src/avs_coap_code_utils.h index 4bff1ec4..9cf7ce63 100644 --- a/deps/avs_coap/src/avs_coap_code_utils.h +++ b/deps/avs_coap/src/avs_coap_code_utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_common_utils.c b/deps/avs_coap/src/avs_coap_common_utils.c index 7bae80c2..bb19d7ce 100644 --- a/deps/avs_coap/src/avs_coap_common_utils.c +++ b/deps/avs_coap/src/avs_coap_common_utils.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -72,3 +72,9 @@ avs_error_t _avs_coap_parse_token(avs_coap_token_t *out_token, return AVS_OK; } + +#ifdef WITH_AVS_COAP_LOGS +void _avs_coap_log_oom__(void) { + LOG(ERROR, _("out of memory")); +} +#endif // WITH_AVS_COAP_LOGS diff --git a/deps/avs_coap/src/avs_coap_common_utils.h b/deps/avs_coap/src/avs_coap_common_utils.h index f9a80006..c239c752 100644 --- a/deps/avs_coap/src/avs_coap_common_utils.h +++ b/deps/avs_coap/src/avs_coap_common_utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_ctx.c b/deps/avs_coap/src/avs_coap_ctx.c index 47ce25a1..bb843454 100644 --- a/deps/avs_coap/src/avs_coap_ctx.c +++ b/deps/avs_coap/src/avs_coap_ctx.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_ctx.h b/deps/avs_coap/src/avs_coap_ctx.h index f1ec7e9f..96732be7 100644 --- a/deps/avs_coap/src/avs_coap_ctx.h +++ b/deps/avs_coap/src/avs_coap_ctx.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_ctx_vtable.h b/deps/avs_coap/src/avs_coap_ctx_vtable.h index 71bcc030..704d5984 100644 --- a/deps/avs_coap/src/avs_coap_ctx_vtable.h +++ b/deps/avs_coap/src/avs_coap_ctx_vtable.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_init.h b/deps/avs_coap/src/avs_coap_init.h index 3be30b34..b14069f5 100644 --- a/deps/avs_coap/src/avs_coap_init.h +++ b/deps/avs_coap/src/avs_coap_init.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_observe.c b/deps/avs_coap/src/avs_coap_observe.c index c9b0f462..e16fb56c 100644 --- a/deps/avs_coap/src/avs_coap_observe.c +++ b/deps/avs_coap/src/avs_coap_observe.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -38,7 +38,7 @@ create_observe(avs_coap_observe_id_t id, (AVS_LIST(avs_coap_observe_t)) AVS_LIST_NEW_BUFFER( sizeof(avs_coap_observe_t) + options_capacity); if (!observe) { - LOG(ERROR, _("out of memory")); + LOG_OOM(); return NULL; } @@ -251,7 +251,7 @@ avs_error_t avs_coap_observe_restore_with_id( observe = (AVS_LIST(avs_coap_observe_t)) AVS_LIST_NEW_BUFFER( sizeof(avs_coap_observe_t) + options_size); if (!observe) { - LOG(ERROR, _("Out of memory")); + LOG_OOM(); return avs_errno(AVS_ENOMEM); } *observe = (avs_coap_observe_t) { diff --git a/deps/avs_coap/src/avs_coap_observe.h b/deps/avs_coap/src/avs_coap_observe.h index 86e7fb24..b06af411 100644 --- a/deps/avs_coap/src/avs_coap_observe.h +++ b/deps/avs_coap/src/avs_coap_observe.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_parse_utils.h b/deps/avs_coap/src/avs_coap_parse_utils.h index fbad8369..75147555 100644 --- a/deps/avs_coap/src/avs_coap_parse_utils.h +++ b/deps/avs_coap/src/avs_coap_parse_utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_poison.h b/deps/avs_coap/src/avs_coap_poison.h index f3703b3f..05f8e87b 100644 --- a/deps/avs_coap/src/avs_coap_poison.h +++ b/deps/avs_coap/src/avs_coap_poison.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/avs_coap_x_log_config.h b/deps/avs_coap/src/avs_coap_x_log_config.h index 7f44fa46..d9979097 100644 --- a/deps/avs_coap/src/avs_coap_x_log_config.h +++ b/deps/avs_coap/src/avs_coap_x_log_config.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -38,8 +38,11 @@ # endif # include # define LOG(...) avs_log(MODULE_NAME, __VA_ARGS__) +void _avs_coap_log_oom__(void); +# define LOG_OOM() _avs_coap_log_oom__() #else // WITH_AVS_COAP_LOGS # define LOG(...) ((void) 0) +# define LOG_OOM() ((void) 0) // used by tcp_ctx # define avs_log_internal_l__(...) ((void) 0) #endif // WITH_AVS_COAP_LOG diff --git a/deps/avs_coap/src/options/avs_coap_iterator.c b/deps/avs_coap/src/options/avs_coap_iterator.c index b3e7da27..31364de5 100644 --- a/deps/avs_coap/src/options/avs_coap_iterator.c +++ b/deps/avs_coap/src/options/avs_coap_iterator.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/options/avs_coap_iterator.h b/deps/avs_coap/src/options/avs_coap_iterator.h index 99a51d30..80ce364c 100644 --- a/deps/avs_coap/src/options/avs_coap_iterator.h +++ b/deps/avs_coap/src/options/avs_coap_iterator.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/options/avs_coap_option.c b/deps/avs_coap/src/options/avs_coap_option.c index b32f8d2f..032ae1cc 100644 --- a/deps/avs_coap/src/options/avs_coap_option.c +++ b/deps/avs_coap/src/options/avs_coap_option.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/options/avs_coap_option.h b/deps/avs_coap/src/options/avs_coap_option.h index 8bd700fa..6cbc6fe3 100644 --- a/deps/avs_coap/src/options/avs_coap_option.h +++ b/deps/avs_coap/src/options/avs_coap_option.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/options/avs_coap_options.c b/deps/avs_coap/src/options/avs_coap_options.c index f824bf21..af95b4bb 100644 --- a/deps/avs_coap/src/options/avs_coap_options.c +++ b/deps/avs_coap/src/options/avs_coap_options.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -620,7 +620,7 @@ avs_error_t avs_coap_options_add_string_fv(avs_coap_options_t *opts, uint16_t size = (uint16_t) result; char *buf = (char *) avs_malloc(size + 1u); // +1 for nullbyte if (!buf) { - LOG(ERROR, _("out of memory")); + LOG_OOM(); return avs_errno(AVS_ENOMEM); } diff --git a/deps/avs_coap/src/options/avs_coap_options.h b/deps/avs_coap/src/options/avs_coap_options.h index ef9070e9..e8fb62c1 100644 --- a/deps/avs_coap/src/options/avs_coap_options.h +++ b/deps/avs_coap/src/options/avs_coap_options.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/streaming/avs_coap_streaming_client.c b/deps/avs_coap/src/streaming/avs_coap_streaming_client.c index a5c4d8a6..83dc5843 100644 --- a/deps/avs_coap/src/streaming/avs_coap_streaming_client.c +++ b/deps/avs_coap/src/streaming/avs_coap_streaming_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -522,7 +522,7 @@ static avs_error_t perform_request(coap_stream_t *coap_stream, buffer_size = in_buffer_capacity; } if (avs_buffer_create(&coap_stream->chunk_buffer, buffer_size)) { - LOG(ERROR, _("out of memory")); + LOG_OOM(); return avs_errno(AVS_ENOMEM); } diff --git a/deps/avs_coap/src/streaming/avs_coap_streaming_client.h b/deps/avs_coap/src/streaming/avs_coap_streaming_client.h index abb6559e..9090239c 100644 --- a/deps/avs_coap/src/streaming/avs_coap_streaming_client.h +++ b/deps/avs_coap/src/streaming/avs_coap_streaming_client.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/streaming/avs_coap_streaming_server.c b/deps/avs_coap/src/streaming/avs_coap_streaming_server.c index 9db85c55..b43962bb 100644 --- a/deps/avs_coap/src/streaming/avs_coap_streaming_server.c +++ b/deps/avs_coap/src/streaming/avs_coap_streaming_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/streaming/avs_coap_streaming_server.h b/deps/avs_coap/src/streaming/avs_coap_streaming_server.h index d8655ffe..a169c862 100644 --- a/deps/avs_coap/src/streaming/avs_coap_streaming_server.h +++ b/deps/avs_coap/src/streaming/avs_coap_streaming_server.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_ctx.c b/deps/avs_coap/src/tcp/avs_coap_tcp_ctx.c index 61bad138..938467e1 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_ctx.c +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_ctx.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_ctx.h b/deps/avs_coap/src/tcp/avs_coap_tcp_ctx.h index 4ad2743f..1cd52677 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_ctx.h +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_ctx.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_header.c b/deps/avs_coap/src/tcp/avs_coap_tcp_header.c index a05ff602..958d146f 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_header.c +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_header.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_header.h b/deps/avs_coap/src/tcp/avs_coap_tcp_header.h index 997a79c0..1474b16e 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_header.h +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_header.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_msg.c b/deps/avs_coap/src/tcp/avs_coap_tcp_msg.c index 6394d9a7..d6a45043 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_msg.c +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_msg.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_msg.h b/deps/avs_coap/src/tcp/avs_coap_tcp_msg.h index 414c50ab..ce66bc8a 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_msg.h +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_msg.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_pending_requests.c b/deps/avs_coap/src/tcp/avs_coap_tcp_pending_requests.c index ca8883a7..2b8fa79f 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_pending_requests.c +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_pending_requests.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -234,7 +234,7 @@ avs_error_t _avs_coap_tcp_create_pending_request( AVS_LIST(avs_coap_tcp_pending_request_t) req = AVS_LIST_NEW_ELEMENT(avs_coap_tcp_pending_request_t); if (!req) { - LOG(DEBUG, _("failed to create pending request - out of memory")); + LOG_OOM(); return avs_errno(AVS_ENOMEM); } diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_pending_requests.h b/deps/avs_coap/src/tcp/avs_coap_tcp_pending_requests.h index b70fc170..0a536d87 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_pending_requests.h +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_pending_requests.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_signaling.c b/deps/avs_coap/src/tcp/avs_coap_tcp_signaling.c index b0bc1d7c..ef6a39da 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_signaling.c +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_signaling.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_signaling.h b/deps/avs_coap/src/tcp/avs_coap_tcp_signaling.h index a976d252..10570f46 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_signaling.h +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_signaling.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_utils.c b/deps/avs_coap/src/tcp/avs_coap_tcp_utils.c index 2faef3ea..18746495 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_utils.c +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_utils.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/tcp/avs_coap_tcp_utils.h b/deps/avs_coap/src/tcp/avs_coap_tcp_utils.h index ddfa0d63..8b13b536 100644 --- a/deps/avs_coap/src/tcp/avs_coap_tcp_utils.h +++ b/deps/avs_coap/src/tcp/avs_coap_tcp_utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/udp/avs_coap_udp_ctx.c b/deps/avs_coap/src/udp/avs_coap_udp_ctx.c index e9e53bbc..3050b4ae 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_ctx.c +++ b/deps/avs_coap/src/udp/avs_coap_udp_ctx.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/udp/avs_coap_udp_ctx.h b/deps/avs_coap/src/udp/avs_coap_udp_ctx.h index e6e04242..a63cce9b 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_ctx.h +++ b/deps/avs_coap/src/udp/avs_coap_udp_ctx.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/udp/avs_coap_udp_header.h b/deps/avs_coap/src/udp/avs_coap_udp_header.h index a6454472..3d60fd83 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_header.h +++ b/deps/avs_coap/src/udp/avs_coap_udp_header.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/udp/avs_coap_udp_msg.c b/deps/avs_coap/src/udp/avs_coap_udp_msg.c index d7e8c726..a99c7e5c 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_msg.c +++ b/deps/avs_coap/src/udp/avs_coap_udp_msg.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/udp/avs_coap_udp_msg.h b/deps/avs_coap/src/udp/avs_coap_udp_msg.h index 5dc2b92f..2fedfbbf 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_msg.h +++ b/deps/avs_coap/src/udp/avs_coap_udp_msg.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/udp/avs_coap_udp_msg_cache.c b/deps/avs_coap/src/udp/avs_coap_udp_msg_cache.c index 4e56e040..9f1b30b8 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_msg_cache.c +++ b/deps/avs_coap/src/udp/avs_coap_udp_msg_cache.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -104,7 +104,7 @@ static endpoint_t *cache_endpoint_add_ref(avs_coap_udp_response_cache_t *cache, AVS_LIST(endpoint_t) new_ep = AVS_LIST_NEW_ELEMENT(endpoint_t); if (!new_ep) { - LOG(DEBUG, _("out of memory")); + LOG_OOM(); return NULL; } diff --git a/deps/avs_coap/src/udp/avs_coap_udp_msg_cache.h b/deps/avs_coap/src/udp/avs_coap_udp_msg_cache.h index c27d1e7b..9225d495 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_msg_cache.h +++ b/deps/avs_coap/src/udp/avs_coap_udp_msg_cache.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/udp/avs_coap_udp_tx_params.c b/deps/avs_coap/src/udp/avs_coap_udp_tx_params.c index 215b98e8..bc30ab29 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_tx_params.c +++ b/deps/avs_coap/src/udp/avs_coap_udp_tx_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/src/udp/avs_coap_udp_tx_params.h b/deps/avs_coap/src/udp/avs_coap_udp_tx_params.h index 7e403021..e4589815 100644 --- a/deps/avs_coap/src/udp/avs_coap_udp_tx_params.h +++ b/deps/avs_coap/src/udp/avs_coap_udp_tx_params.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/fuzz/CMakeLists.txt b/deps/avs_coap/tests/fuzz/CMakeLists.txt index 33e5c279..72f4d61c 100644 --- a/deps/avs_coap/tests/fuzz/CMakeLists.txt +++ b/deps/avs_coap/tests/fuzz/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/tests/fuzz/coap_async_api_tcp.c b/deps/avs_coap/tests/fuzz/coap_async_api_tcp.c index cb98e484..1907575b 100644 --- a/deps/avs_coap/tests/fuzz/coap_async_api_tcp.c +++ b/deps/avs_coap/tests/fuzz/coap_async_api_tcp.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/fuzz/coap_async_api_udp.c b/deps/avs_coap/tests/fuzz/coap_async_api_udp.c index 8ce8493e..b4c7ea67 100644 --- a/deps/avs_coap/tests/fuzz/coap_async_api_udp.c +++ b/deps/avs_coap/tests/fuzz/coap_async_api_udp.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/fuzz/coap_parse.c b/deps/avs_coap/tests/fuzz/coap_parse.c index 0161c014..89d7a309 100644 --- a/deps/avs_coap/tests/fuzz/coap_parse.c +++ b/deps/avs_coap/tests/fuzz/coap_parse.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/mock_clock.c b/deps/avs_coap/tests/mock_clock.c index 77bcfd17..5aa60395 100644 --- a/deps/avs_coap/tests/mock_clock.c +++ b/deps/avs_coap/tests/mock_clock.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/mock_clock.h b/deps/avs_coap/tests/mock_clock.h index 72c47262..a9f8ea92 100644 --- a/deps/avs_coap/tests/mock_clock.h +++ b/deps/avs_coap/tests/mock_clock.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/options/option.c b/deps/avs_coap/tests/options/option.c index e8fd13ca..a18af724 100644 --- a/deps/avs_coap/tests/options/option.c +++ b/deps/avs_coap/tests/options/option.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/options/options.c b/deps/avs_coap/tests/options/options.c index c7443fc8..478d7228 100644 --- a/deps/avs_coap/tests/options/options.c +++ b/deps/avs_coap/tests/options/options.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/socket.c b/deps/avs_coap/tests/socket.c index 15fb990d..5bbd004e 100644 --- a/deps/avs_coap/tests/socket.c +++ b/deps/avs_coap/tests/socket.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/socket.h b/deps/avs_coap/tests/socket.h index 3a840a32..50b7973c 100644 --- a/deps/avs_coap/tests/socket.h +++ b/deps/avs_coap/tests/socket.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/async_client.c b/deps/avs_coap/tests/tcp/async_client.c index 4382e5bb..056db54c 100644 --- a/deps/avs_coap/tests/tcp/async_client.c +++ b/deps/avs_coap/tests/tcp/async_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/async_server.c b/deps/avs_coap/tests/tcp/async_server.c index 2894129b..e2187aed 100644 --- a/deps/avs_coap/tests/tcp/async_server.c +++ b/deps/avs_coap/tests/tcp/async_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/csm.c b/deps/avs_coap/tests/tcp/csm.c index a351f704..a775ca21 100644 --- a/deps/avs_coap/tests/tcp/csm.c +++ b/deps/avs_coap/tests/tcp/csm.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/ctx.c b/deps/avs_coap/tests/tcp/ctx.c index ae0e1577..5f484911 100644 --- a/deps/avs_coap/tests/tcp/ctx.c +++ b/deps/avs_coap/tests/tcp/ctx.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/env.h b/deps/avs_coap/tests/tcp/env.h index 6d671150..1d8d74fb 100644 --- a/deps/avs_coap/tests/tcp/env.h +++ b/deps/avs_coap/tests/tcp/env.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/header.c b/deps/avs_coap/tests/tcp/header.c index 1ddf90f6..a5974165 100644 --- a/deps/avs_coap/tests/tcp/header.c +++ b/deps/avs_coap/tests/tcp/header.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/helper_functions.h b/deps/avs_coap/tests/tcp/helper_functions.h index 298cd9a6..e89cc884 100644 --- a/deps/avs_coap/tests/tcp/helper_functions.h +++ b/deps/avs_coap/tests/tcp/helper_functions.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/payload_escaper.c b/deps/avs_coap/tests/tcp/payload_escaper.c index a0fdeca4..73f974dd 100644 --- a/deps/avs_coap/tests/tcp/payload_escaper.c +++ b/deps/avs_coap/tests/tcp/payload_escaper.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/requesting.c b/deps/avs_coap/tests/tcp/requesting.c index 56168992..df630e13 100644 --- a/deps/avs_coap/tests/tcp/requesting.c +++ b/deps/avs_coap/tests/tcp/requesting.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/responding.c b/deps/avs_coap/tests/tcp/responding.c index dda01583..d18c3d22 100644 --- a/deps/avs_coap/tests/tcp/responding.c +++ b/deps/avs_coap/tests/tcp/responding.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/setsock.c b/deps/avs_coap/tests/tcp/setsock.c index 7bffcb58..6aa6910d 100644 --- a/deps/avs_coap/tests/tcp/setsock.c +++ b/deps/avs_coap/tests/tcp/setsock.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/tcp/utils.h b/deps/avs_coap/tests/tcp/utils.h index 387ec57e..b32c57af 100644 --- a/deps/avs_coap/tests/tcp/utils.h +++ b/deps/avs_coap/tests/tcp/utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/async_client.c b/deps/avs_coap/tests/udp/async_client.c index 404fa01a..a7bc0c9c 100644 --- a/deps/avs_coap/tests/udp/async_client.c +++ b/deps/avs_coap/tests/udp/async_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/async_client_with_big_data.c b/deps/avs_coap/tests/udp/async_client_with_big_data.c index 708da542..b0832bf8 100644 --- a/deps/avs_coap/tests/udp/async_client_with_big_data.c +++ b/deps/avs_coap/tests/udp/async_client_with_big_data.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/async_observe.c b/deps/avs_coap/tests/udp/async_observe.c index a3bac06d..6db3290b 100644 --- a/deps/avs_coap/tests/udp/async_observe.c +++ b/deps/avs_coap/tests/udp/async_observe.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/async_server.c b/deps/avs_coap/tests/udp/async_server.c index a9d45b16..aed16b8c 100644 --- a/deps/avs_coap/tests/udp/async_server.c +++ b/deps/avs_coap/tests/udp/async_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/big_data.h b/deps/avs_coap/tests/udp/big_data.h index b5688d7b..bed8802b 100644 --- a/deps/avs_coap/tests/udp/big_data.h +++ b/deps/avs_coap/tests/udp/big_data.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/fuzzer_cases.c b/deps/avs_coap/tests/udp/fuzzer_cases.c index 98291c1d..b839bb97 100644 --- a/deps/avs_coap/tests/udp/fuzzer_cases.c +++ b/deps/avs_coap/tests/udp/fuzzer_cases.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/msg.c b/deps/avs_coap/tests/udp/msg.c index 39d1d563..267ae177 100644 --- a/deps/avs_coap/tests/udp/msg.c +++ b/deps/avs_coap/tests/udp/msg.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/msg_cache.c b/deps/avs_coap/tests/udp/msg_cache.c index c9d09b96..6fe02ef5 100644 --- a/deps/avs_coap/tests/udp/msg_cache.c +++ b/deps/avs_coap/tests/udp/msg_cache.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/setsock.c b/deps/avs_coap/tests/udp/setsock.c index c916994b..5ad4ac45 100644 --- a/deps/avs_coap/tests/udp/setsock.c +++ b/deps/avs_coap/tests/udp/setsock.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/streaming_client.c b/deps/avs_coap/tests/udp/streaming_client.c index 0e14422c..c737f14a 100644 --- a/deps/avs_coap/tests/udp/streaming_client.c +++ b/deps/avs_coap/tests/udp/streaming_client.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/streaming_observe.c b/deps/avs_coap/tests/udp/streaming_observe.c index 3b8e5c67..09074c11 100644 --- a/deps/avs_coap/tests/udp/streaming_observe.c +++ b/deps/avs_coap/tests/udp/streaming_observe.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * @@ -641,8 +641,6 @@ AVS_UNIT_TEST(udp_streaming_observe, notify_block_confirmable) { // request for second block of Notify COAP_MSG(CON, GET, ID(101), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_REQ(1, 1024)), - // separate response ack - COAP_MSG(ACK, EMPTY, ID(1), NO_PAYLOAD), }; const test_msg_t *responses[] = { COAP_MSG(ACK, CONTENT, ID(100), TOKEN(MAKE_TOKEN("Obserw")), OBSERVE(0), @@ -653,7 +651,7 @@ AVS_UNIT_TEST(udp_streaming_observe, notify_block_confirmable) { BLOCK2_RES(0, 1024, NOTIFY_PAYLOAD)), // Note: further blocks should not contain the Observe option // see RFC 7959, Figure 12: "Observe Sequence with Block-Wise Response" - COAP_MSG(CON, CONTENT, ID(1), TOKEN(MAKE_TOKEN("Notifaj")), + COAP_MSG(ACK, CONTENT, ID(101), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_RES(1, 1024, NOTIFY_PAYLOAD)), }; @@ -687,7 +685,78 @@ AVS_UNIT_TEST(udp_streaming_observe, notify_block_confirmable) { expect_recv(&env, requests[1]); expect_recv(&env, requests[2]); expect_send(&env, responses[2]); - expect_recv(&env, requests[3]); + expect_has_buffered_data_check(&env, false); + + ASSERT_OK(avs_coap_notify_streaming( + env.coap_ctx, observe_id, + &(avs_coap_response_header_t) { + .code = responses[1]->response_header.code + }, + AVS_COAP_NOTIFY_PREFER_CONFIRMABLE, test_streaming_writer, + &test_payload)); + + // should be canceled by cleanup + expect_observe_cancel(&env, requests[0]->msg.token); +# undef NOTIFY_PAYLOAD +} + +AVS_UNIT_TEST(udp_streaming_observe, notify_block_confirmable_late_ack) { +# define NOTIFY_PAYLOAD DATA_1KB "Notifaj" + test_env_t env __attribute__((cleanup(test_teardown_late_expects_check))) = + test_setup_default(); + + const test_msg_t *requests[] = { + COAP_MSG(CON, GET, ID(100), TOKEN(MAKE_TOKEN("Obserw")), OBSERVE(0), + NO_PAYLOAD), + // request for second block of Notify + COAP_MSG(CON, GET, ID(101), TOKEN(MAKE_TOKEN("Notifaj")), + BLOCK2_REQ(1, 1024)), + // late ACK for the first block + COAP_MSG(ACK, EMPTY, ID(0), NO_PAYLOAD), + }; + const test_msg_t *responses[] = { + COAP_MSG(ACK, CONTENT, ID(100), TOKEN(MAKE_TOKEN("Obserw")), OBSERVE(0), + NO_PAYLOAD), + + // BLOCK Notify + COAP_MSG(CON, CONTENT, ID(0), TOKEN(MAKE_TOKEN("Obserw")), OBSERVE(1), + BLOCK2_RES(0, 1024, NOTIFY_PAYLOAD)), + // Note: further blocks should not contain the Observe option + // see RFC 7959, Figure 12: "Observe Sequence with Block-Wise Response" + COAP_MSG(ACK, CONTENT, ID(101), TOKEN(MAKE_TOKEN("Notifaj")), + BLOCK2_RES(1, 1024, NOTIFY_PAYLOAD)), + }; + + streaming_handle_request_args_t args = { + .env = &env, + .expected_request_header = requests[0]->request_header, + .response_header = { + .code = responses[0]->response_header.code + } + }; + + avs_unit_mocksock_enable_recv_timeout_getsetopt( + env.mocksock, avs_time_duration_from_scalar(1, AVS_TIME_S)); + + expect_recv(&env, requests[0]); + expect_send(&env, responses[0]); + expect_has_buffered_data_check(&env, false); + + ASSERT_OK(avs_coap_streaming_handle_incoming_packet( + env.coap_ctx, streaming_handle_request, &args)); + + avs_coap_observe_id_t observe_id = { + .token = requests[0]->msg.token + }; + test_streaming_payload_t test_payload = { + .data = NOTIFY_PAYLOAD, + .size = sizeof(NOTIFY_PAYLOAD) - 1 + }; + + expect_send(&env, responses[1]); + expect_recv(&env, requests[1]); + expect_send(&env, responses[2]); + expect_recv(&env, requests[2]); expect_has_buffered_data_check(&env, false); ASSERT_OK(avs_coap_notify_streaming( @@ -794,25 +863,18 @@ AVS_UNIT_TEST(udp_streaming_observe, increasing_block_size_confirmable) { // requests and separate response ACKs for further blocks of Notify COAP_MSG(CON, GET, ID(101), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_REQ(1, 16)), - COAP_MSG(ACK, EMPTY, ID(1), NO_PAYLOAD), COAP_MSG(CON, GET, ID(102), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_REQ(1, 32)), - COAP_MSG(ACK, EMPTY, ID(2), NO_PAYLOAD), COAP_MSG(CON, GET, ID(103), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_REQ(1, 64)), - COAP_MSG(ACK, EMPTY, ID(3), NO_PAYLOAD), COAP_MSG(CON, GET, ID(104), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_REQ(1, 128)), - COAP_MSG(ACK, EMPTY, ID(4), NO_PAYLOAD), COAP_MSG(CON, GET, ID(105), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_REQ(1, 256)), - COAP_MSG(ACK, EMPTY, ID(5), NO_PAYLOAD), COAP_MSG(CON, GET, ID(106), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_REQ(1, 512)), - COAP_MSG(ACK, EMPTY, ID(6), NO_PAYLOAD), COAP_MSG(CON, GET, ID(107), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_REQ(1, 1024)), - COAP_MSG(ACK, EMPTY, ID(7), NO_PAYLOAD), }; const test_msg_t *responses[] = { COAP_MSG(ACK, CONTENT, ID(100), TOKEN(MAKE_TOKEN("Obserw")), OBSERVE(0), @@ -823,19 +885,19 @@ AVS_UNIT_TEST(udp_streaming_observe, increasing_block_size_confirmable) { BLOCK2_RES(0, 16, NOTIFY_PAYLOAD)), // Note: further blocks should not contain the Observe option // see RFC 7959, Figure 12: "Observe Sequence with Block-Wise Response" - COAP_MSG(CON, CONTENT, ID(1), TOKEN(MAKE_TOKEN("Notifaj")), + COAP_MSG(ACK, CONTENT, ID(101), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_RES(1, 16, NOTIFY_PAYLOAD)), - COAP_MSG(CON, CONTENT, ID(2), TOKEN(MAKE_TOKEN("Notifaj")), + COAP_MSG(ACK, CONTENT, ID(102), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_RES(1, 32, NOTIFY_PAYLOAD)), - COAP_MSG(CON, CONTENT, ID(3), TOKEN(MAKE_TOKEN("Notifaj")), + COAP_MSG(ACK, CONTENT, ID(103), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_RES(1, 64, NOTIFY_PAYLOAD)), - COAP_MSG(CON, CONTENT, ID(4), TOKEN(MAKE_TOKEN("Notifaj")), + COAP_MSG(ACK, CONTENT, ID(104), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_RES(1, 128, NOTIFY_PAYLOAD)), - COAP_MSG(CON, CONTENT, ID(5), TOKEN(MAKE_TOKEN("Notifaj")), + COAP_MSG(ACK, CONTENT, ID(105), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_RES(1, 256, NOTIFY_PAYLOAD)), - COAP_MSG(CON, CONTENT, ID(6), TOKEN(MAKE_TOKEN("Notifaj")), + COAP_MSG(ACK, CONTENT, ID(106), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_RES(1, 512, NOTIFY_PAYLOAD)), - COAP_MSG(CON, CONTENT, ID(7), TOKEN(MAKE_TOKEN("Notifaj")), + COAP_MSG(ACK, CONTENT, ID(107), TOKEN(MAKE_TOKEN("Notifaj")), BLOCK2_RES(1, 1024, NOTIFY_PAYLOAD)), }; @@ -868,9 +930,8 @@ AVS_UNIT_TEST(udp_streaming_observe, increasing_block_size_confirmable) { expect_send(&env, responses[1]); expect_recv(&env, requests[1]); for (size_t i = 2; i < AVS_ARRAY_SIZE(responses); ++i) { - expect_recv(&env, requests[2 * i - 2]); + expect_recv(&env, requests[i]); expect_send(&env, responses[i]); - expect_recv(&env, requests[2 * i - 1]); } expect_has_buffered_data_check(&env, false); diff --git a/deps/avs_coap/tests/udp/streaming_server.c b/deps/avs_coap/tests/udp/streaming_server.c index 2e5714c9..5072a6e7 100644 --- a/deps/avs_coap/tests/udp/streaming_server.c +++ b/deps/avs_coap/tests/udp/streaming_server.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/tx_params_mock.h b/deps/avs_coap/tests/udp/tx_params_mock.h index 7e3eaf54..39598e44 100644 --- a/deps/avs_coap/tests/udp/tx_params_mock.h +++ b/deps/avs_coap/tests/udp/tx_params_mock.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/udp_tx_params.c b/deps/avs_coap/tests/udp/udp_tx_params.c index a308dd8b..4da8d7f3 100644 --- a/deps/avs_coap/tests/udp/udp_tx_params.c +++ b/deps/avs_coap/tests/udp/udp_tx_params.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/udp/utils.h b/deps/avs_coap/tests/udp/utils.h index e76a444a..ad9b11a1 100644 --- a/deps/avs_coap/tests/udp/utils.h +++ b/deps/avs_coap/tests/udp/utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/utils.c b/deps/avs_coap/tests/utils.c index 992c0569..fd419111 100644 --- a/deps/avs_coap/tests/utils.c +++ b/deps/avs_coap/tests/utils.c @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tests/utils.h b/deps/avs_coap/tests/utils.h index 57f41f78..c0632279 100644 --- a/deps/avs_coap/tests/utils.h +++ b/deps/avs_coap/tests/utils.h @@ -1,5 +1,5 @@ /* - * Copyright 2017-2023 AVSystem + * Copyright 2017-2024 AVSystem * AVSystem CoAP library * All rights reserved. * diff --git a/deps/avs_coap/tools/avs_common.py b/deps/avs_coap/tools/avs_common.py index b2ea0b0d..c32d57d7 100644 --- a/deps/avs_coap/tools/avs_common.py +++ b/deps/avs_coap/tools/avs_common.py @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # diff --git a/deps/avs_coap/tools/license_headers.py b/deps/avs_coap/tools/license_headers.py index 0b93be7e..eb809421 100755 --- a/deps/avs_coap/tools/license_headers.py +++ b/deps/avs_coap/tools/license_headers.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem CoAP library # All rights reserved. # @@ -17,7 +17,7 @@ import avs_common -EXPECTED_COPYRIGHT_HEADER = 'Copyright 2017-2023 AVSystem ' +EXPECTED_COPYRIGHT_HEADER = 'Copyright 2017-2024 AVSystem ' LICENSE = ( 'AVSystem CoAP library', diff --git a/deps/avs_commons b/deps/avs_commons index ebcc5a7a..683a8cb3 160000 --- a/deps/avs_commons +++ b/deps/avs_commons @@ -1 +1 @@ -Subproject commit ebcc5a7a49fde3566d83c2453c15bd273b3c2d00 +Subproject commit 683a8cb3d92efd094ff7dafc8322c8fce4666dbe diff --git a/devconfig b/devconfig index b3a0759a..b23ad8d3 100755 --- a/devconfig +++ b/devconfig @@ -1,6 +1,6 @@ #!/usr/bin/env bash # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # @@ -148,6 +148,7 @@ ${CMAKE_COMMAND} \ -D WITH_URL_CHECK=ON \ -D WITH_STATIC_ANALYSIS=${WITH_STATIC_ANALYSIS} \ -D WITH_MODULE_advanced_fw_update=ON \ + -D WITH_MODULE_sw_mgmt=ON \ -D DTLS_BACKEND="${DTLS_BACKEND}" \ -D AVS_LOG_WITH_TRACE=ON \ -D WITH_EXAMPLES=${WITH_EXAMPLES} \ diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 0e7aa4d3..dca9f2fa 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/doc/sphinx/extensions/builders/__init__.py b/doc/sphinx/extensions/builders/__init__.py index 62bebd6f..9317eb23 100644 --- a/doc/sphinx/extensions/builders/__init__.py +++ b/doc/sphinx/extensions/builders/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/doc/sphinx/extensions/builders/dummy.py b/doc/sphinx/extensions/builders/dummy.py index f6818920..71cf2064 100644 --- a/doc/sphinx/extensions/builders/dummy.py +++ b/doc/sphinx/extensions/builders/dummy.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/doc/sphinx/extensions/builders/snippet_source_linter.py b/doc/sphinx/extensions/builders/snippet_source_linter.py index 71135d2f..d2ab7b3e 100644 --- a/doc/sphinx/extensions/builders/snippet_source_linter.py +++ b/doc/sphinx/extensions/builders/snippet_source_linter.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/doc/sphinx/extensions/builders/snippet_source_list_references.py b/doc/sphinx/extensions/builders/snippet_source_list_references.py index c56bf073..b9611875 100644 --- a/doc/sphinx/extensions/builders/snippet_source_list_references.py +++ b/doc/sphinx/extensions/builders/snippet_source_list_references.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/doc/sphinx/extensions/file_dirtiness_checker.py b/doc/sphinx/extensions/file_dirtiness_checker.py index fa8478fa..f3967e2c 100644 --- a/doc/sphinx/extensions/file_dirtiness_checker.py +++ b/doc/sphinx/extensions/file_dirtiness_checker.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/doc/sphinx/extensions/snippet_source.py b/doc/sphinx/extensions/snippet_source.py index aef1fa3b..e34d3a20 100644 --- a/doc/sphinx/extensions/snippet_source.py +++ b/doc/sphinx/extensions/snippet_source.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- # -# Copyright 2017-2023 AVSystem +# Copyright 2017-2024 AVSystem # AVSystem Anjay LwM2M SDK # All rights reserved. # diff --git a/doc/sphinx/snippet_sources.md5 b/doc/sphinx/snippet_sources.md5 index dad3df16..c17470e4 100644 --- a/doc/sphinx/snippet_sources.md5 +++ b/doc/sphinx/snippet_sources.md5 @@ -1,18 +1,16 @@ -8a6d05a275ef8e8c871bf395154b5164 demo/demo_cmds.c -cd5ba3adb34a01fdd2ceceb6a35d5be2 demo/objects/ipso_objects.c -90e172b4b00a21b7290510a21498e0b8 deps/avs_coap/include_public/avsystem/coap/tcp.h -4670a0997896b4ab2b973fb833c4a039 deps/avs_coap/include_public/avsystem/coap/udp.h -632ec469b37df582ff65792fc01d81ce deps/avs_commons/include_public/avsystem/commons/avs_addrinfo.h -b02b7236e89497c73496ab2e5503ed14 deps/avs_commons/include_public/avsystem/commons/avs_base64.h -045968e7cbf1891b418ed417b6b8d189 deps/avs_commons/include_public/avsystem/commons/avs_crypto_common.h -477cd70c144b9fba0f1be35f0c049f76 deps/avs_commons/include_public/avsystem/commons/avs_crypto_pki.h -75bb517f8386fd9c77e5982835eef537 deps/avs_commons/include_public/avsystem/commons/avs_crypto_psk.h -77120c9f2f2b754019b81cb8cfbd6646 deps/avs_commons/include_public/avsystem/commons/avs_socket.h -0691a3c8a2dbb7f8f22c74e09db381ce deps/avs_commons/include_public/avsystem/commons/avs_socket_v_table.h -1dc558d1f1b72af3da021cf9c1fca4f4 deps/avs_commons/include_public/avsystem/commons/avs_utils.h -6805fe6ea07bc0eabd90a52923abfc77 deps/avs_commons/src/net/avs_net_global.h -ca82847266e70bd9728611eda7b1a19e deps/avs_commons/src/net/avs_net_impl.h -646826b1669c1dfa639d3c1899f26ba3 deps/avs_commons/src/utils/compat/posix/avs_compat_time.c +563b9fc06ed0c55bae149f839ab80f11 deps/avs_coap/include_public/avsystem/coap/tcp.h +8d609e7d1e46df8b37f8d694f6d78e7f deps/avs_coap/include_public/avsystem/coap/udp.h +6979acbbeda62d10befc6f7aa7e0865e deps/avs_commons/include_public/avsystem/commons/avs_addrinfo.h +65c5f1a934166ea7ffe0b427f87e0d2d deps/avs_commons/include_public/avsystem/commons/avs_base64.h +e9bc875ab314a3d88787889cfe282f8f deps/avs_commons/include_public/avsystem/commons/avs_crypto_common.h +9f284929ca4c327e8955e3e01fe8f007 deps/avs_commons/include_public/avsystem/commons/avs_crypto_pki.h +e23cc205e18c2bc699b7805ff2f04fe3 deps/avs_commons/include_public/avsystem/commons/avs_crypto_psk.h +a9cad6508cf9c61d88f0dc809848bc9d deps/avs_commons/include_public/avsystem/commons/avs_socket.h +99c2b66c9d05b8af9138472a43014197 deps/avs_commons/include_public/avsystem/commons/avs_socket_v_table.h +3edd418e701f23417f0732fd410d5c04 deps/avs_commons/include_public/avsystem/commons/avs_utils.h +1457c2516170e096c0e10c46a8490eb8 deps/avs_commons/src/net/avs_net_global.h +203ca6c6b3e3559571ab24e2055cce24 deps/avs_commons/src/net/avs_net_impl.h +3298bc32ba08dd4885215066acfd44f1 deps/avs_commons/src/utils/compat/posix/avs_compat_time.c 9bba955ab235e4c315b28aa83589e010 examples/commercial-features/CF-CorePersistence/src/main.c 4613be67a0c66ba130fe5601e75ef5f0 examples/commercial-features/CF-EST-PKCS11/src/main.c bcefabd7777e025ed9b0503b81365a59 examples/commercial-features/CF-EST/src/main.c @@ -58,6 +56,7 @@ bc7422f705aa8a760391867aefa708ba examples/tutorial/AT-CustomObjects/read-only-m a1fc955b8941a2f8814aa7e842b80628 examples/tutorial/AT-CustomObjects/read-only-with-executable/src/main.c 2131cbb07e912a50b4ee37d14b6cefba examples/tutorial/AT-CustomObjects/writable-multiple-fixed/src/main.c 9a194ea46051b2a5a8f5e801b33f5651 examples/tutorial/AT-CustomObjects/writable-multiple-fixed-transactional/src/main.c +5f3d0ee04c3ecdf78ec187731e30ced0 examples/tutorial/AT-IpsoObjects/src/main.c b0e29570c700dcb88514ee8bbf6415d4 examples/tutorial/AT-Persistence/src/main.c b95986a7fc990c24cec0c1674ef32c6e examples/tutorial/BC-Initialization/CMakeLists.txt 19350ae71ff9e7c3db83a14d2d915247 examples/tutorial/BC-Initialization/src/main.c @@ -83,14 +82,13 @@ f971df7872a8f052bb72ae64610a8031 examples/tutorial/firmware-update/basic-implem 1d85bb08f511fcc7b321f0be56ddb119 examples/tutorial/firmware-update/basic-implementation/src/main.c 844cd7d9d0ebe80007dc5ae8d6a719b0 examples/tutorial/firmware-update/download-resumption/src/firmware_update.c 077f6b89dad59ef3b9b58e2abe93aff6 examples/tutorial/firmware-update/secure-downloads/src/firmware_update.c -5838371e4081a02d1b91133088262fd5 include_public/anjay/advanced_fw_update.h -af2f0e0ac0de25dc04713f05a378d469 include_public/anjay/attr_storage.h -cb32a2854acf33cce16d04b6bdcec940 include_public/anjay/core.h -c88697977b9c8e8a34d0229137ae793a include_public/anjay/dm.h -774ecfbac5a3a686790469b90092c3f6 include_public/anjay/fw_update.h -7ef9abee6d8d8e689ddf467cce116347 include_public/anjay/io.h -33c77736e874a89e7dec6a4654eab3c9 include_public/anjay/ipso_objects.h -e449359975f3fb404a50078630be399b include_public/anjay/security.h -f5479c311353f8f7f441494cbc97774f tests/integration/framework/test_utils.py -78596279ba96afc13d9cac52ebe8c707 tools/provisioning-tool/factory_prov/factory_prov.py -bec6f7f8f8a559fa52ff0a6a224a01e7 tools/provisioning-tool/ptool.py +99ef6e1d741fbfefab9ddf0db97c61e7 include_public/anjay/advanced_fw_update.h +be8a4c22a41c2ab79bf3a68f1f74f301 include_public/anjay/attr_storage.h +6434100b9f5206dd350885fdab853504 include_public/anjay/core.h +9771c6bc4940d778a12ab93cb400a11c include_public/anjay/dm.h +56b500ecbd5ffc8d468327c650883cbd include_public/anjay/fw_update.h +b49ca67d9f4f04bf20261c261ad41822 include_public/anjay/io.h +e7c2357db51f9896d2b82245699e0a42 include_public/anjay/security.h +b95279360cd728e0b137ae6318b2c4a7 tests/integration/framework/test_utils.py +d867c4d479f49fc39254f70bdda67fb5 tools/provisioning-tool/factory_prov/factory_prov.py +82ad6e92a83128ffac51b9c369d5275d tools/provisioning-tool/ptool.py diff --git a/doc/sphinx/source/AdvancedTopics.rst b/doc/sphinx/source/AdvancedTopics.rst index ed480ff7..a6c1702b 100644 --- a/doc/sphinx/source/AdvancedTopics.rst +++ b/doc/sphinx/source/AdvancedTopics.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-AccessControl.rst b/doc/sphinx/source/AdvancedTopics/AT-AccessControl.rst index e0ee5d6b..1c57f0d5 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-AccessControl.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-AccessControl.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-AttributeStorage.rst b/doc/sphinx/source/AdvancedTopics/AT-AttributeStorage.rst index 5465c0db..33cd7200 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-AttributeStorage.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-AttributeStorage.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-Certificates.rst b/doc/sphinx/source/AdvancedTopics/AT-Certificates.rst index 58038448..3b163e97 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-Certificates.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-Certificates.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomEventLoop.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomEventLoop.rst index d064c2ab..84c0c6e4 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomEventLoop.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomEventLoop.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects.rst index c0dbc261..7f67f2d9 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. @@ -265,7 +265,10 @@ which holds: * Object version: a string with static lifetime, containing two digits * separated by a dot (for example: "1.1"). * If left NULL, client will not include the "ver=" attribute in Register - * and Discover messages, which implies version 1.0. + * and Discover messages. This implies: + * 1. Version 1.0 for Non-Core Objects. + * 2. The version corresponding to the version in the LwM2M Enabler for Core + * Objects. */ const char *version; diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO1_SingleInstanceReadOnly.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO1_SingleInstanceReadOnly.rst index 061c967c..acc788ae 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO1_SingleInstanceReadOnly.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO1_SingleInstanceReadOnly.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO2_SingleInstanceExecutableAndReadOnly.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO2_SingleInstanceExecutableAndReadOnly.rst index 038f909a..e36f22a5 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO2_SingleInstanceExecutableAndReadOnly.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO2_SingleInstanceExecutableAndReadOnly.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO3_MultiInstanceReadOnlyFixed.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO3_MultiInstanceReadOnlyFixed.rst index a7bab56d..b474a07c 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO3_MultiInstanceReadOnlyFixed.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO3_MultiInstanceReadOnlyFixed.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO4_FixedInstanceWritable.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO4_FixedInstanceWritable.rst index a5a8b781..ee0fad54 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO4_FixedInstanceWritable.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO4_FixedInstanceWritable.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO5_MultiInstanceDynamic.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO5_MultiInstanceDynamic.rst index 1a89fac2..9b2771f7 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO5_MultiInstanceDynamic.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO5_MultiInstanceDynamic.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO6_MultipleResourceInstances.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO6_MultipleResourceInstances.rst index f42347b5..ee7aef3f 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO6_MultipleResourceInstances.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO6_MultipleResourceInstances.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO7_BootstrapAwareness.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO7_BootstrapAwareness.rst index fa21ee66..8418a8ee 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO7_BootstrapAwareness.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO7_BootstrapAwareness.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_BootstrapAwareness.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_BootstrapAwareness.rst index c2cd0156..853b4588 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_BootstrapAwareness.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_BootstrapAwareness.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_FixedInstanceWritable.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_FixedInstanceWritable.rst index 5f9125cf..52521363 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_FixedInstanceWritable.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_FixedInstanceWritable.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultiInstanceDynamic.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultiInstanceDynamic.rst index 31a8b5fe..32162407 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultiInstanceDynamic.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultiInstanceDynamic.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultiInstanceReadOnlyFixed.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultiInstanceReadOnlyFixed.rst index b31a595a..668b760f 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultiInstanceReadOnlyFixed.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultiInstanceReadOnlyFixed.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultipleResourceInstances.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultipleResourceInstances.rst index b229d237..54433220 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultipleResourceInstances.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_MultipleResourceInstances.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_SingleInstanceExecutableAndReadOnly.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_SingleInstanceExecutableAndReadOnly.rst index 57ffb0ba..5ac148f6 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_SingleInstanceExecutableAndReadOnly.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_SingleInstanceExecutableAndReadOnly.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_SingleInstanceReadOnly.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_SingleInstanceReadOnly.rst index 47773275..5fd1fabc 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_SingleInstanceReadOnly.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/AT_CO_SingleInstanceReadOnly.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/Anjay_codegen_note.rst b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/Anjay_codegen_note.rst index 58773f6e..e1b66d87 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/Anjay_codegen_note.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-CustomObjects/Anjay_codegen_note.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-EventLoopNotes.rst b/doc/sphinx/source/AdvancedTopics/AT-EventLoopNotes.rst index c56e6add..16af7211 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-EventLoopNotes.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-EventLoopNotes.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-IpsoObjects.rst b/doc/sphinx/source/AdvancedTopics/AT-IpsoObjects.rst index d04cf644..7296bf78 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-IpsoObjects.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-IpsoObjects.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. @@ -8,264 +8,446 @@ .. highlight:: c -Anjay IPSO Objects implementation +IPSO objects implementation ================================= -Among many Objects defined in -`OMA LightweightM2M (LwM2M) Object and Resource Registry -`_ -there are some which are used quite frequently. -Anjay provides an easy to use API for implementing some of them, i.e. for a few -kinds of IPSO objects: +.. contents:: :local: - * basic sensors (like Temperature or Humidity Objects), - * three axis sensors (like Accelerometer or Gyrometer Objects) and - * Push Button Object. +Introduction +------------ -The API is declared in `anjay/ipso_objects.h <../api/ipso__objects_8h.html>`_ header. +IPSO (Internet Protocol for Smart Objects) objects are a collection of LwM2M +objects that can be used to expose some common features of many IoT devices, +like sensors, buttons, actuators or control switches. Using predefined objects +for these purposes enables higher interoperability of applications, i.e. all +devices that have a temperature sensor can report the readings in a standardized +way, making it possible to easily process such measurements from different, +nonhomogeneous devices on the cloud. -Object installation -------------------- +In practice, IPSO objects are most importantly a convenient way to report sensor +data over LwM2M. All IPSO objects of aforementioned certain kinds share +common set of resources, and thanks to that these objects in a large part can be +easily preimplemented. -To install an Anjay IPSO Object we can use one of the following functions, each -of them corresponding to a specific class of objects: +Anjay provides a ready-to-use implementation of: - * `anjay_ipso_basic_sensor_install <../api/ipso__objects_8h.html#a8a95f45e84db077652f65d272ccbf730>`_, - * `anjay_ipso_3d_sensor_install <../api/ipso__objects_8h.html#a9911f0f48d8cdebcbd8bfd9859f43358>`_, - * `anjay_ipso_button_install <../api/ipso__objects_8h.html#a11e68bd571d70da7d17ee5c73cff6e0d>`_. +- basic (i.e. scalar) sensor objects (e.g. Temperature Object or Pressure + Object), +- three-axis sensor objects (e.g. Accelerometer Object or Magnetometer Object), +- Push Button Object. -As you can see, it needs only the maximum number of -instances which will be used and, in case of sensor objects, OID of the -installed objects (in the case of the Push Button Object it is always the same -and equals 3347). +User's only responsibility is to retrieve those values from actual sensors +and supply them to Anjay, making it very easy to implement LwM2M devices with +sensor support. -For example, if we wanted to create a Temperature Object (which has OID equal to -3303) that could have up to 2 instances, we would call -``anjay_ipso_basic_sensor_install`` function like we did in our demo: +The API is declared in ``include_public/anjay/ipso_objects.h`` and +``include_public/anjay/ipso_objects_v2.h`` headers. To use them, enable them +first by either defining ``ANJAY_WITH_MODULE_IPSO_OBJECTS`` and/or +``ANJAY_WITH_MODULE_IPSO_OBJECTS_V2`` in the Anjay's configuration files, or, if +using CMake, enabling ``WITH_MODULE_ipso_objects`` and/or +``WITH_MODULE_ipso_objects_v2`` options. -.. snippet-source:: demo/objects/ipso_objects.c +.. important:: - if (anjay_ipso_basic_sensor_install( - anjay, - ANJAY_DEMO_TEMPERATURE_OID, - ANJAY_DEMO_TEMPERATURE_MAX_INSTANCE_NUM)) { - avs_log(ipso, ERROR, "Could not install Temperature object"); - return -1; - } + The APIs for basic and 3D IPSO sensors objects explained in this tutorial + are new, experimental variants declared in + ``include_public/anjay/ipso_objects_v2.h``. -Instance addition +Supported objects ----------------- -To add an instance of an existing Anjay IPSO Object we can use one of the following functions, -each of them corresponding to a specific class of objects: +Implementation of IPSO objects in Anjay supports objects that have the following +set of resources: + +.. flat-table:: + :header-rows: 2 + + * - :cspan:`3` **Basic (scalar) sensor objects** + * - **Resource ID** + - **Resource Name** + - **Must be supported by object** + * - 5601 + - Min Measured Value + - no + * - 5602 + - Max Measured Value + - no + * - 5603 + - Min Range Value + - no + * - 5604 + - Max Range Value + - no + * - 5605 + - Reset Min and Max Measured Values + - no + * - 5700 + - Sensor Value + - **yes** + * - 5701 + - Sensor Units + - no + +.. flat-table:: + :header-rows: 2 + + * - :cspan:`3` **Three-axis sensor objects** + * - **Resource ID** + - **Resource Name** + - **Must be supported by object** + * - 5508 + - Min X Value + - no + * - 5509 + - Max X Value + - no + * - 5510 + - Min Y Value + - no + * - 5511 + - Max Y Value + - no + * - 5512 + - Min Z Value + - no + * - 5513 + - Max Z Value + - no + * - 5603 + - Min Range Value + - no + * - 5604 + - Max Range Value + - no + * - 5605 + - Reset Min and Max Measured Values + - no + * - 5701 + - Sensor Units + - no + * - 5702 + - X Value + - **yes** + * - 5703 + - Y Value + - no + * - 5704 + - Z Value + - no + +As of December 13th, 2023, objects registered by IPSO Alliance that meet these +requirements are: +3300 (Generic Sensor), +3301 (Illuminance), +3303 (Temperature), +3304 (Humidity), +3313 (Accelerometer), +3314 (Magnetometer), +3315 (Barometer), +3316 (Voltage), +3317 (Current), +3318 (Frequency), +3319 (Depth), +3320 (Percentage), +3321 (Altitude), +3322 (Load), +3323 (Pressure), +3324 (Loudness), +3325 (Concentration), +3326 (Acidity), +3327 (Conductivity), +3328 (Power), +3329 (Power Factor), +3330 (Distance), +3334 (Gyrometer), +3345 (Multiple Axis Joystick), +3346 (Rate). + +Additionally, object 3347 (Push Button) is supported with a separate API. + +Usage example +------------- + +This tutorial builds up on the :doc:`../../BasicClient/BC-MandatoryObjects` +tutorial which contains an implementation of a minimal, but complete LwM2M +client. + +.. note:: + + Complete code of this example can be found in + `examples/tutorial/AT-IpsoObjects` subdirectory of main Anjay project + repository. + +In this example we'll implement a simple application that simulates a few +thermometers, accelerometers and buttons. + +Installing objects and instances +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +To setup an IPSO object, you must install it first using one of the following +methods: + + * `anjay_ipso_v2_basic_sensor_install <../api/ipso__objects__v2_8h.html#ac3200c3c61ea62f76eb4e606adfcd90f>`_, + * `anjay_ipso_v2_3d_sensor_install <../api/ipso__objects__v2_8h.html#a154a62e2adafe9890cbd66c91bb8f20a>`_, + * `anjay_ipso_button_install <../api/ipso__objects_8h.html#a11e68bd571d70da7d17ee5c73cff6e0d>`_. + +For sensors, the API accepts Object ID, object version and maximum number of +instances that'll be installed later. For button, the Object ID and version is +defined upfront. + +.. important:: - * `anjay_ipso_basic_sensor_instance_add <../api/ipso__objects_8h.html#adc74272152c265197c86eff505bde54a>`_, - * `anjay_ipso_3d_sensor_instance_add <../api/ipso__objects_8h.html#a822eca024f1b55d83ca6828b56b02bef>`_, + It's important to set appropriate object version number. Without configuring + it a LwM2M server may fail to interpret resources that were added in newer + versions of an object. Such an example is Gyrometer Object, which has the + "Reset Min and Max Measured Values" resource available only since version + 1.1. + + In this example all enabled resources are available in version 1.0 of these + objects, to which passing ``NULL`` defaults to. + +After installing objects, instances of these objects can be added using +following APIs: + + * `anjay_ipso_v2_basic_sensor_instance_add <../api/ipso__objects__v2_8h.html#ae92a38b4eba14909b00233088e6256b5>`_, + * `anjay_ipso_v2_3d_sensor_instance_add <../api/ipso__objects__v2_8h.html#a760f33f44690447409e77066b4c86295>`_, * `anjay_ipso_button_instance_add <../api/ipso__objects_8h.html#ae981fe67ce9c2e9032284f26fa5fb3c3>`_. -As you can see, in case of basic or three-axis sensors we need to provide the -OID, IID and the implementation. Let's have a look at -``anjay_ipso_basic_sensor_impl_t`` structure: - - -.. snippet-source:: include_public/anjay/ipso_objects.h - - typedef struct anjay_ipso_basic_sensor_impl_struct { - /** - * Unit of the measured values. - * - * The pointed string won't be copied, so user code must assure that the - * pointer will remain valid for the lifetime of the object. - */ - const char *unit; - - /** - * User context which will be passed to @ref get_value callback. - */ - void *user_context; - - /** - * The minimum value that can be measured by the sensor. - * - * If the value is NaN the resource won't be created. - */ - double min_range_value; - - /** - * The maximum value that can be measured by the sensor. - * - * If the value is NaN the resource won't be created. - */ - double max_range_value; - - /** - * User provided callback for reading the sensor value. - */ - anjay_ipso_basic_sensor_value_reader_t *get_value; - } anjay_ipso_basic_sensor_impl_t; - -The most important field of the structure is ``get_value`` which is a callback -called whenever the sensor value needs to be read (so either when it is -updated explicitly by the client or when the value is read by the server). -User might pass some additional context to the callback using the ``user_ctx`` -field. - -Let's assume that we want to add an instance of the installed Temperature -Object and let ``get_temperature`` be a given system -function (which takes as an argument some thermometer instance of type -``thermometer_t *``) for reading the temperature. We fake such situation for our -demo client and in this scenario we can use the following simple function: - -.. snippet-source:: demo/objects/ipso_objects.c - - static int - temperature_get_value(anjay_iid_t iid, void *thermometer, double *value) { - (void) iid; - - *value = get_temperature((thermometer_t *) thermometer); +For basic and 3D sensors, these methods accept an initial value of the sensor +and a structure that provides metadata about each instance: +`anjay_ipso_v2_basic_sensor_meta_t <../api/ipso__objects__v2_8h.html#a2e0cd9b35002025a91edb96842cd29cf>`_ +and +`anjay_ipso_v2_3d_sensor_meta_t <../api/ipso__objects__v2_8h.html#a34fe615fc03fa7313a2dffabd326058f>`_, +respectively. + +These structs are used to configure unit, reported minimum and maximum values +that can be measured by a sensor, and presence of optional Y and Z axis in case +of 3D objects. + +In our example, let's define some macros and necessary metadata structs first: + +.. snippet-source:: examples/tutorial/AT-IpsoObjects/src/main.c + + #define TEMPERATURE_OBJ_OID 3303 + #define ACCELEROMETER_OBJ_OID 3313 + + #define THERMOMETER_COUNT 3 + #define ACCELEROMETER_COUNT 2 + #define BUTTON_COUNT 4 + + static const anjay_ipso_v2_basic_sensor_meta_t thermometer_meta = { + .unit = "Cel", + .min_max_measured_value_present = true, + .min_range_value = -20.0, + .max_range_value = 120.0 + }; + + static const anjay_ipso_v2_3d_sensor_meta_t accelerometer_meta = { + .unit = "m/s2", + .min_range_value = -20.0, + .max_range_value = 20.0, + .y_axis_present = true, + .z_axis_present = true + }; + +.. note:: + + It's a good practice to report values using units defined in + `SenML Units Registry `_, + the up to date list can be + `found here `_. + +Then, let's introduce some helper methods that will install our sensor objects +and add all instances upfront: + +.. snippet-source:: examples/tutorial/AT-IpsoObjects/src/main.c + + static int setup_temperature_object(anjay_t *anjay) { + if (anjay_ipso_v2_basic_sensor_install(anjay, TEMPERATURE_OBJ_OID, NULL, + THERMOMETER_COUNT)) { + return -1; + } + + for (anjay_iid_t iid = 0; iid < THERMOMETER_COUNT; iid++) { + if (anjay_ipso_v2_basic_sensor_instance_add( + anjay, TEMPERATURE_OBJ_OID, iid, 20.0, &thermometer_meta)) { + return -1; + } + } return 0; } -The proper temperature unit are degrees Celsius (as defined in -`SenML RFC `_). -Let assume that our thermometer measures temperatures between 0 and 100 degrees -Celsius. Knowing this we can prepare an instance of -``anjay_ipso_basic_sensor_impl_t`` and pass it to -``anjay_ipso_basic_sensor_add_instance`` function, as we did in our demo: - -.. snippet-source:: demo/objects/ipso_objects.c - - (void) anjay_ipso_basic_sensor_instance_add( - anjay, - ANJAY_DEMO_TEMPERATURE_OID, - iid, - (anjay_ipso_basic_sensor_impl_t) { - .unit = ANJAY_DEMO_TEMPERATURE_UNIT, - .get_value = temperature_get_value, - .user_context = (void *) &THERMOMETER, - .min_range_value = 0, - .max_range_value = (double) ANJAY_DEMO_TEMPERATURE_MAX_VALUE - }); - -The implementation struct for the three axis objects is quite similar to this -for basic objects - there are three major differences: - - * there are additional ``use_y_value`` and ``use_z_value`` fields for enabling - optional Y and Z axes, - - * callback needs to take three output pointers, one for each of the axes. - -Let's have a look on the whole structure: - -.. snippet-source:: include_public/anjay/ipso_objects.h - - typedef struct anjay_ipso_3d_sensor_impl_struct { - /** - * Unit of the measured values. - * - * The pointed string won't be copied, so user code must assure that the - * pointer will remain valid for the lifetime of the object. - */ - const char *unit; - /** - * Enables usage of the optional Y axis. - */ - bool use_y_value; - /** - * Enables usage of the optional Z axis. - */ - bool use_z_value; - - /** - * User context which will be passed to @ref get_values callback. - */ - void *user_context; - - /** - * The minimum value that can be measured by the sensor. - * - * If the value is NaN the resource won't be created. - */ - double min_range_value; - - /** - * The maximum value that can be measured by the sensor. - * - * If the value is NaN the resource won't be created. - */ - double max_range_value; - - /** - * User provided callback for reading the sensor value. - */ - anjay_ipso_3d_sensor_value_reader_t *get_values; - } anjay_ipso_3d_sensor_impl_t; - -In case of the Push Button Object, neither implementation nor OID is required. -Instead, we need to provide the initial string for the "Application Type" field. - -In both cases it is allowed to overwrite an existing instance of an object -(but in the case of the Push Button Object it can change only "Application Type" -field). - -Instance update ---------------- - -To update an instance of an existing Anjay IPSO Object we can use one of the following functions, -each of them corresponding to a specific class of objects: - - * `anjay_ipso_basic_sensor_instance_update <../api/ipso__objects_8h.html#adb1d4d64c728ad7e77f35c8c28eb74bf>`_, - * `anjay_ipso_3d_sensor_instance_update <../api/ipso__objects_8h.html#a254fafed91f3ef3613ae29de05a67449>`_, - * `anjay_ipso_button_instance_update <../api/ipso__objects_8h.html#a84a9bf58b9cff7e1bd5fe9083576cfa2>`_. - -In case of the sensor objects they just force an update of the sensor value -for the proper instance of the sensor object instance. To keep the value of -the sensor object current, it is usually a good practice to call it frequently. - -In the case of the Push Button Object the update function is a bit more -significant - it is meant to be called every time the button is pressed or -released and it is the only way to update the state of the Object Instance. -In addition to IID it passes a new state of the button. Thus, when an instance -of the fake button in our demo is pressed, we call: - -.. snippet-source:: demo/demo_cmds.c - - anjay_ipso_button_update(demo->anjay, iid, true); - -and when it is released: - -.. snippet-source:: demo/demo_cmds.c - - anjay_ipso_button_update(demo->anjay, iid, false); - -.. note: - - It is not safe to call update functions for the IPSO objects (as all of the - Anjay API functions) from an ISR context. + static int setup_accelerometer_object(anjay_t *anjay) { + if (anjay_ipso_v2_3d_sensor_install(anjay, ACCELEROMETER_OBJ_OID, NULL, + ACCELEROMETER_COUNT)) { + return -1; + } + + for (anjay_iid_t iid = 0; iid < ACCELEROMETER_COUNT; iid++) { + anjay_ipso_v2_3d_sensor_value_t initial_value = { + .x = 0.0, + .y = 0.0, + .z = 0.0 + }; + + if (anjay_ipso_v2_3d_sensor_instance_add(anjay, ACCELEROMETER_OBJ_OID, + iid, &initial_value, + &accelerometer_meta)) { + return -1; + } + } -Instance removal ----------------- + return 0; + } -To remove an instance of an existing Anjay IPSO Object we can use one of the following functions, -each of them corresponding to a specific class of objects: + static int setup_button_object(anjay_t *anjay) { + if (anjay_ipso_button_install(anjay, BUTTON_COUNT)) { + return -1; + } - * `anjay_ipso_basic_sensor_instance_remove <../api/ipso__objects_8h.html#a50e8c38ac2271e9d702d305349ea79c3>`_, - * `anjay_ipso_3d_sensor_instance_remove <../api/ipso__objects_8h.html#a2bd255f62cf4817ea567b65ddae6644c>`_, - * `anjay_ipso_button_instance_remove <../api/ipso__objects_8h.html#af53a1881ef4ed8de52cb000700a0dbb9>`_. + for (anjay_iid_t iid = 0; iid < BUTTON_COUNT; iid++) { + if (anjay_ipso_button_instance_add(anjay, iid, "")) { + return -1; + } + } + + return 0; + } + +Finally, let's call these methods in initialization code, in ``main()`` method: + +.. snippet-source:: examples/tutorial/AT-IpsoObjects/src/main.c + :emphasize-lines: 5-7 + + int main(int argc, char *argv[]) { + // ... + + if (setup_security_object(anjay) || setup_server_object(anjay) + || setup_temperature_object(anjay) + || setup_accelerometer_object(anjay) + || setup_button_object(anjay)) { + result = -1; + } + + // ... + } -For example, we can look how the fake temperature object instance is removed in -our demo: +Updating values +^^^^^^^^^^^^^^^ -.. snippet-source:: demo/objects/ipso_objects.c +To update reported value of a sensor, use one of following methods: - (void) anjay_ipso_basic_sensor_instance_remove( - anjay, ANJAY_DEMO_TEMPERATURE_OID, iid); + * `anjay_ipso_v2_basic_sensor_value_update <../api/ipso__objects__v2_8h.html#ab9ee3d855e885a2dc25ae73f466dd228>`_, + * `anjay_ipso_v2_3d_sensor_value_update <../api/ipso__objects__v2_8h.html#a2166bd5daae8fb235f96064d8b97c740>`_, + * `anjay_ipso_button_update <../api/ipso__objects_8h.html#a84a9bf58b9cff7e1bd5fe9083576cfa2>`_. -Further reading ---------------- +.. important:: + + Keep in mind that a LwM2M Server is allowed to configure resource + observations with attributes that require the client to report the data very + frequently or when some threshold value is exceeded, even for a very short + moment. If you want to ensure that server is notified of every change of + resource value that could meet such conditions, **you must update the value + very frequently**. + +.. important:: + + These methods (as all methods in Anjay's public API) cannot be called from + an interrupt. In case ``ANJAY_WITH_THREAD_SAFETY`` is disabled Anjay APIs + are not safe to call from other contexts than method which runs event loop + and ``avs_sched`` tasks, while if ``ANJAY_WITH_THREAD_SAFETY`` is enabled + calling such methods will attempt to lock a mutex from an interrupt which + also is wrong. + + If your application retrieves new sensor values and/or button state changes + in an interrupt, you must find a way to pass these values to a non-interrupt + execution context. + +In our example we're simulating values of these sensors, so let's add some +utility methods first: + +.. snippet-source:: examples/tutorial/AT-IpsoObjects/src/main.c + + static double get_random_in_range(double min, double max) { + return min + (max - min) * rand() / RAND_MAX; + } + + static double get_thermometer_value(void) { + return get_random_in_range(thermometer_meta.min_range_value, + thermometer_meta.max_range_value); + } + + static anjay_ipso_v2_3d_sensor_value_t get_accelerometer_value(void) { + return (anjay_ipso_v2_3d_sensor_value_t) { + .x = get_random_in_range(accelerometer_meta.min_range_value, + accelerometer_meta.max_range_value), + .y = get_random_in_range(accelerometer_meta.min_range_value, + accelerometer_meta.max_range_value), + .z = get_random_in_range(accelerometer_meta.min_range_value, + accelerometer_meta.max_range_value) + }; + } + + static bool get_button_state(void) { + return rand() % 2 == 0; + } + +Then, let's implement a scheduler task that will update all sensors. The task +schedules itself to run every second: + +.. snippet-source:: examples/tutorial/AT-IpsoObjects/src/main.c + + static void update_sensor_values(avs_sched_t *sched, const void *anjay_ptr) { + anjay_t *anjay = *(anjay_t *const *) anjay_ptr; + + for (anjay_iid_t iid = 0; iid < THERMOMETER_COUNT; iid++) { + (void) anjay_ipso_v2_basic_sensor_value_update( + anjay, TEMPERATURE_OBJ_OID, iid, get_thermometer_value()); + } + + for (anjay_iid_t iid = 0; iid < ACCELEROMETER_COUNT; iid++) { + anjay_ipso_v2_3d_sensor_value_t value = get_accelerometer_value(); + + (void) anjay_ipso_v2_3d_sensor_value_update( + anjay, ACCELEROMETER_OBJ_OID, iid, &value); + } + + for (anjay_iid_t iid = 0; iid < BUTTON_COUNT; iid++) { + (void) anjay_ipso_button_update(anjay, iid, get_button_state()); + } + + AVS_SCHED_DELAYED(sched, NULL, avs_time_duration_from_scalar(1, AVS_TIME_S), + update_sensor_values, &anjay, sizeof(anjay)); + } + +Lastly, let's call this method once before entering event loop. From that moment +the task will keep running infinitely. + +.. snippet-source:: examples/tutorial/AT-IpsoObjects/src/main.c + :emphasize-lines: 5 + + int main(int argc, char *argv[]) { + // ... + + if (!result) { + update_sensor_values(anjay_get_scheduler(anjay), &anjay); + result = anjay_event_loop_run( + anjay, avs_time_duration_from_scalar(1, AVS_TIME_S)); + } + + // ... + } + +Removing instances +^^^^^^^^^^^^^^^^^^ + +In case you need to change the set of instances of installed IPSO objects, those +instances can be removed using following methods: + + * `anjay_ipso_v2_basic_sensor_instance_remove <../api/ipso__objects__v2_8h.html#af53a1881ef4ed8de52cb000700a0dbb9>`_, + * `anjay_ipso_v2_3d_sensor_instance_remove <../api/ipso__objects__v2_8h.html#a2bd255f62cf4817ea567b65ddae6644c>`_, + * `anjay_ipso_button_instance_remove <../api/ipso__objects_8h.html#af53a1881ef4ed8de52cb000700a0dbb9>`_. -To learn more about Anjay IPSO Objects API you can look how they are used in -our demo `demo/objects/ipso_objects.c <../../../../../demo/objects/ipso_objects.c>`_ -and our integrations: `Anjay Zephyr Client `_ -and `Anjay FreeRTOS Client `_. +In our example instance set doesn't change. All objects and instances are +automatically deleted when ``anjay_delete()`` is called. diff --git a/doc/sphinx/source/AdvancedTopics/AT-NetworkErrorHandling.rst b/doc/sphinx/source/AdvancedTopics/AT-NetworkErrorHandling.rst index dfd54ec3..4d7f13bf 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-NetworkErrorHandling.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-NetworkErrorHandling.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-OtherFeatures.rst b/doc/sphinx/source/AdvancedTopics/AT-OtherFeatures.rst index ac414bf3..a0d1082f 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-OtherFeatures.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-OtherFeatures.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-Persistence.rst b/doc/sphinx/source/AdvancedTopics/AT-Persistence.rst index 95bb7252..2b471e0d 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-Persistence.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-Persistence.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/AdvancedTopics/AT-RetransmissionsTimeoutsCaching.rst b/doc/sphinx/source/AdvancedTopics/AT-RetransmissionsTimeoutsCaching.rst index f540bb1d..b22cdb28 100644 --- a/doc/sphinx/source/AdvancedTopics/AT-RetransmissionsTimeoutsCaching.rst +++ b/doc/sphinx/source/AdvancedTopics/AT-RetransmissionsTimeoutsCaching.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient.rst b/doc/sphinx/source/BasicClient.rst index 4f92b9ad..5fd9fb1d 100644 --- a/doc/sphinx/source/BasicClient.rst +++ b/doc/sphinx/source/BasicClient.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC-Initialization.rst b/doc/sphinx/source/BasicClient/BC-Initialization.rst index 4bcdbb81..1dd8059e 100644 --- a/doc/sphinx/source/BasicClient/BC-Initialization.rst +++ b/doc/sphinx/source/BasicClient/BC-Initialization.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC-MandatoryObjects.rst b/doc/sphinx/source/BasicClient/BC-MandatoryObjects.rst index ce8a6258..7ab7f720 100644 --- a/doc/sphinx/source/BasicClient/BC-MandatoryObjects.rst +++ b/doc/sphinx/source/BasicClient/BC-MandatoryObjects.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC-Notifications.rst b/doc/sphinx/source/BasicClient/BC-Notifications.rst index c1d0aace..f695da81 100644 --- a/doc/sphinx/source/BasicClient/BC-Notifications.rst +++ b/doc/sphinx/source/BasicClient/BC-Notifications.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC-ObjectImplementation.rst b/doc/sphinx/source/BasicClient/BC-ObjectImplementation.rst index e67db749..70e8fb87 100644 --- a/doc/sphinx/source/BasicClient/BC-ObjectImplementation.rst +++ b/doc/sphinx/source/BasicClient/BC-ObjectImplementation.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC-Security.rst b/doc/sphinx/source/BasicClient/BC-Security.rst index b8e77087..990ff129 100644 --- a/doc/sphinx/source/BasicClient/BC-Security.rst +++ b/doc/sphinx/source/BasicClient/BC-Security.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC-Send.rst b/doc/sphinx/source/BasicClient/BC-Send.rst index 6cd87d44..d7cd9394 100644 --- a/doc/sphinx/source/BasicClient/BC-Send.rst +++ b/doc/sphinx/source/BasicClient/BC-Send.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC-ThreadSafety.rst b/doc/sphinx/source/BasicClient/BC-ThreadSafety.rst index 5ac66033..babe9ec6 100644 --- a/doc/sphinx/source/BasicClient/BC-ThreadSafety.rst +++ b/doc/sphinx/source/BasicClient/BC-ThreadSafety.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC1.rst b/doc/sphinx/source/BasicClient/BC1.rst index 9d528f4c..b75c5d8b 100644 --- a/doc/sphinx/source/BasicClient/BC1.rst +++ b/doc/sphinx/source/BasicClient/BC1.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC2.rst b/doc/sphinx/source/BasicClient/BC2.rst index 782614e5..d326fb70 100644 --- a/doc/sphinx/source/BasicClient/BC2.rst +++ b/doc/sphinx/source/BasicClient/BC2.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC3.rst b/doc/sphinx/source/BasicClient/BC3.rst index 97842c14..1f4d8157 100644 --- a/doc/sphinx/source/BasicClient/BC3.rst +++ b/doc/sphinx/source/BasicClient/BC3.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC4.rst b/doc/sphinx/source/BasicClient/BC4.rst index 60fa175c..aaeb07af 100644 --- a/doc/sphinx/source/BasicClient/BC4.rst +++ b/doc/sphinx/source/BasicClient/BC4.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC5.rst b/doc/sphinx/source/BasicClient/BC5.rst index 952e02af..9a6a6f67 100644 --- a/doc/sphinx/source/BasicClient/BC5.rst +++ b/doc/sphinx/source/BasicClient/BC5.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC6.rst b/doc/sphinx/source/BasicClient/BC6.rst index b5d163f9..4ccabc20 100644 --- a/doc/sphinx/source/BasicClient/BC6.rst +++ b/doc/sphinx/source/BasicClient/BC6.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC7.rst b/doc/sphinx/source/BasicClient/BC7.rst index 3d225e70..be13978e 100644 --- a/doc/sphinx/source/BasicClient/BC7.rst +++ b/doc/sphinx/source/BasicClient/BC7.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/BasicClient/BC8.rst b/doc/sphinx/source/BasicClient/BC8.rst index 483b1871..0166cc09 100644 --- a/doc/sphinx/source/BasicClient/BC8.rst +++ b/doc/sphinx/source/BasicClient/BC8.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures.rst b/doc/sphinx/source/CommercialFeatures.rst index 3245ff58..fcd43513 100644 --- a/doc/sphinx/source/CommercialFeatures.rst +++ b/doc/sphinx/source/CommercialFeatures.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-CorePersistence.rst b/doc/sphinx/source/CommercialFeatures/CF-CorePersistence.rst index d96ecd68..135f6074 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-CorePersistence.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-CorePersistence.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-CustomHardwareSupport.rst b/doc/sphinx/source/CommercialFeatures/CF-CustomHardwareSupport.rst index 36b1d74d..dde52aef 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-CustomHardwareSupport.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-CustomHardwareSupport.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-EST.rst b/doc/sphinx/source/CommercialFeatures/CF-EST.rst index 8ab82cc8..dc179216 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-EST.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-EST.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. @@ -23,9 +23,9 @@ key pairs as well as key pairs generated by the CA. **EST-coaps** (`draft-ietf-ace-coap-est-18 `_, also -referenced in the LwM2M Core TS) that uses CoAP instead of HTTP for message -exchanges, which allows constrained, low-resource devices to use existing EST -functionality for provisioning certificates. +referenced in the LwM2M Core TS) is a protocol that uses CoAP instead of HTTP +for message exchanges, which allows constrained, low-resource devices to use +existing EST functionality for provisioning certificates. An implementation of the **EST-coaps client** is provided as a commercial feature in Anjay. This enhances security provided by the (D)TLS Certificate diff --git a/doc/sphinx/source/CommercialFeatures/CF-FSDM.rst b/doc/sphinx/source/CommercialFeatures/CF-FSDM.rst index a114b942..f1da29b1 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-FSDM.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-FSDM.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-HSM.rst b/doc/sphinx/source/CommercialFeatures/CF-HSM.rst index 9ef932f3..c935115c 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-HSM.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-HSM.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-IoTSAFE.rst b/doc/sphinx/source/CommercialFeatures/CF-IoTSAFE.rst index 4ac22962..084e41e2 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-IoTSAFE.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-IoTSAFE.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-NIDD.rst b/doc/sphinx/source/CommercialFeatures/CF-NIDD.rst index 4d063a1c..b9b458fc 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-NIDD.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-NIDD.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-OSCORE.rst b/doc/sphinx/source/CommercialFeatures/CF-OSCORE.rst index f88e8428..44d3ddc8 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-OSCORE.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-OSCORE.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-SMSBinding.rst b/doc/sphinx/source/CommercialFeatures/CF-SMSBinding.rst index 6f89ccca..cd4ae570 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-SMSBinding.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-SMSBinding.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/CommercialFeatures/CF-SmartCardBootstrap.rst b/doc/sphinx/source/CommercialFeatures/CF-SmartCardBootstrap.rst index 97861828..9ced1426 100644 --- a/doc/sphinx/source/CommercialFeatures/CF-SmartCardBootstrap.rst +++ b/doc/sphinx/source/CommercialFeatures/CF-SmartCardBootstrap.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/Compiling_client_applications.rst b/doc/sphinx/source/Compiling_client_applications.rst index 26a6cfba..bfd700c2 100644 --- a/doc/sphinx/source/Compiling_client_applications.rst +++ b/doc/sphinx/source/Compiling_client_applications.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/FirmwareUpdateTutorial.rst b/doc/sphinx/source/FirmwareUpdateTutorial.rst index b2608389..36129fb1 100644 --- a/doc/sphinx/source/FirmwareUpdateTutorial.rst +++ b/doc/sphinx/source/FirmwareUpdateTutorial.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate.rst b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate.rst index ff14bbc4..31695d82 100644 --- a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate.rst +++ b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-BasicImplementation.rst b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-BasicImplementation.rst index a8ac57ab..89d208c6 100644 --- a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-BasicImplementation.rst +++ b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-BasicImplementation.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-Examples.rst b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-Examples.rst index a3252c2e..fb45fffb 100644 --- a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-Examples.rst +++ b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-Examples.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-ResourceDefinitions.rst b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-ResourceDefinitions.rst index ab1fba23..63c556df 100644 --- a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-ResourceDefinitions.rst +++ b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-ResourceDefinitions.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-StateDiagram.rst b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-StateDiagram.rst index 6cf3897d..a9196edb 100644 --- a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-StateDiagram.rst +++ b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/FU-AFU-StateDiagram.rst @@ -1,5 +1,5 @@ .. - Copyright 2017-2023 AVSystem + Copyright 2017-2024 AVSystem AVSystem Anjay LwM2M SDK All rights reserved. diff --git a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/_files/33629.xml b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/_files/33629.xml index 53d32977..ef3502ca 100644 --- a/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/_files/33629.xml +++ b/doc/sphinx/source/FirmwareUpdateTutorial/FU-AdvancedFirmwareUpdate/_files/33629.xml @@ -1,7 +1,7 @@