Skip to content

Commit

Permalink
Anjay-zephyr 3.8.0
Browse files Browse the repository at this point in the history
Bugfixes:
- On nRF91 platforms, initialization of Anjay is now delayed until the Connectivity Monitoring object can be properly populated
  • Loading branch information
Kucmasz committed May 28, 2024
1 parent a385f3b commit 7875939
Show file tree
Hide file tree
Showing 12 changed files with 130 additions and 24 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Changelog

## 3.8.0 (May 28th, 2024)

### Bugfixes
- On nRF91 platforms, initialization of Anjay is now delayed until the Connectivity Monitoring object can be properly populated

## 3.7.0 (February 16th, 2024)

### Improvements
Expand Down
14 changes: 14 additions & 0 deletions Kconfig.anjay
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ choice ANJAY_COMPAT_SECURITY
default y
depends on ANJAY_COMPAT_ZEPHYR_TLS

config ANJAY_COMPAT_ZEPHYR_TLS_SESSION_CACHE_PURGE_ON_START
bool "Purge modem when Anjay security config is not restored from persistence."
default y
depends on ANJAY_COMPAT_ZEPHYR_TLS
depends on ANJAY_COMPAT_ZEPHYR_TLS_SESSION_CACHE
depends on NRF_MODEM_LIB
depends on MODEM_KEY_MGMT
help
When reconfiguring Anjay Client, modem can store in cache DTLS Session ID
valid for a given LwM2M Server, but not for a specific Endpoint, which
results in hard to debug successful Handshake and rejected registration
attempts. For production configuration it is advised to disable it for
data transmitted optimization.

config ANJAY_COMPAT_ZEPHYR_TLS_EPHEMERAL_SEC_TAG_BASE
int "Lowest security tag number to use for Anjay's ephemeral credentials"
default 2652900
Expand Down
8 changes: 4 additions & 4 deletions Kconfig.anjay_zephyr
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ config ANJAY_ZEPHYR_MODEL_NUMBER

config ANJAY_ZEPHYR_VERSION
string "Client Version"
default "3.7.0"
default "3.8.0"

config ANJAY_ZEPHYR_AUTOGENERATE_ENDPOINT_NAME
bool "Autogenerate endpoint name"
Expand Down Expand Up @@ -237,7 +237,7 @@ menu "GPS on nRF9160-based devices"

config ANJAY_ZEPHYR_GPS_NRF_A_GPS
bool "Enable A-GPS using Nordic Location Services over LwM2M"
depends on ANJAY_ZEPHYR_GPS_NRF
depends on ANJAY_ZEPHYR_GPS_NRF && ANJAY_ZEPHYR_NRF_LC_INFO
select NRF_CLOUD_AGNSS
select NRF_CLOUD_AGPS
help
Expand Down Expand Up @@ -339,8 +339,6 @@ config ANJAY_ZEPHYR_OTA_MCUBOOT

config ANJAY_ZEPHYR_PERSISTENCE
bool "Enable persistence"
select ANJAY_WITH_ACCESS_CONTROL
select ANJAY_WITH_MODULE_ACCESS_CONTROL
help
Enables persistence of Access Control Object, Security Object
and Server Object.
Expand Down Expand Up @@ -368,6 +366,8 @@ config ANJAY_ZEPHYR_FACTORY_PROVISIONING_INITIAL_FLASH
depends on ANJAY_ZEPHYR_FACTORY_PROVISIONING
select ANJAY_WITH_CBOR
select ANJAY_WITH_MODULE_FACTORY_PROVISIONING
select ANJAY_WITH_ACCESS_CONTROL
select ANJAY_WITH_MODULE_ACCESS_CONTROL
select FILE_SYSTEM
select MCUMGR
select MCUMGR_CMD_FS_MGMT
Expand Down
14 changes: 13 additions & 1 deletion config/avsystem/coap/avs_coap_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,23 @@
# define WITH_AVS_COAP_OBSERVE
#endif // CONFIG_ANJAY_WITH_OBSERVE

/**
* Turn on cancelling observation on a timeout.
*
* Only meaningful if <c>WITH_AVS_COAP_OBSERVE</c> is enabled.
*
* NOTE: LwM2M specification requires LwM2M server to send Cancel Observation
* request. Meanwhile CoAP RFC 7641 states that timeout on notification should
* cancel it. This setting is to enable both of these behaviors with default
* focused on keeping observations in case of bad connectivity.
*/
/* #undef WITH_AVS_COAP_OBSERVE_CANCEL_ON_TIMEOUT */

/**
* Enable support for observation persistence (<c>avs_coap_observe_persist()</c>
* and <c>avs_coap_observe_restore()</c> calls).
*
* Only meaningful <c>WITH_AVS_COAP_OBSERVE</c> is enabled.
* Only meaningful if <c>WITH_AVS_COAP_OBSERVE</c> is enabled.
*/
#ifdef CONFIG_ANJAY_WITH_OBSERVE_PERSISTENCE
# define WITH_AVS_COAP_OBSERVE_PERSISTENCE
Expand Down
2 changes: 1 addition & 1 deletion deps/anjay
Submodule anjay updated 59 files
+28 −0 CHANGELOG.md
+3 −1 CMakeLists.txt
+15 −1 demo/advanced_firmware_update.c
+7 −0 demo/advanced_firmware_update.h
+10 −1 demo/advanced_firmware_update_addimg.c
+2 −14 demo/advanced_firmware_update_app.c
+21 −0 demo/demo.c
+8 −0 demo/demo_args.c
+1 −0 demo/demo_args.h
+24 −0 demo/demo_cmds.c
+24 −0 demo/demo_utils.c
+5 −0 demo/demo_utils.h
+1 −0 deps/avs_coap/CMakeLists.txt
+1 −0 deps/avs_coap/doc/CMakeLists.txt
+13 −1 deps/avs_coap/include_public/avsystem/coap/avs_coap_config.h.in
+4 −5 deps/avs_coap/src/async/avs_coap_async_server.c
+1 −1 deps/avs_commons
+3 −3 doc/sphinx/snippet_sources.md5
+52 −20 doc/sphinx/source/AdvancedTopics/AT-NetworkErrorHandling.rst
+1 −0 doc/sphinx/source/Migrating.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay214.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay215.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay225.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay24.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay26.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay27.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay28.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay30.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay32.rst
+1 −2 doc/sphinx/source/Migrating/MigratingFromAnjay33.rst
+3 −2 doc/sphinx/source/Migrating/MigratingFromAnjay34.rst
+28 −0 doc/sphinx/source/Migrating/MigratingFromAnjay37.rst
+7 −0 example_configs/embedded_lwm2m10/anjay/anjay_config.h
+13 −1 example_configs/embedded_lwm2m10/avsystem/coap/avs_coap_config.h
+7 −0 example_configs/embedded_lwm2m11/anjay/anjay_config.h
+13 −1 example_configs/embedded_lwm2m11/avsystem/coap/avs_coap_config.h
+7 −0 example_configs/linux_lwm2m10/anjay/anjay_config.h
+13 −1 example_configs/linux_lwm2m10/avsystem/coap/avs_coap_config.h
+7 −0 example_configs/linux_lwm2m11/anjay/anjay_config.h
+13 −1 example_configs/linux_lwm2m11/avsystem/coap/avs_coap_config.h
+7 −0 include_public/anjay/anjay_config.h.in
+171 −0 include_public/anjay/core.h
+10 −0 src/anjay_config_log.h
+9 −0 src/anjay_modules/anjay_servers.h
+33 −0 src/core/anjay_bootstrap_core.c
+12 −1 src/core/anjay_core.c
+6 −0 src/core/anjay_core.h
+8 −0 src/core/anjay_dm_core.c
+18 −0 src/core/anjay_servers_private.h
+2 −6 src/core/io/anjay_base64_out.c
+2 −1 src/core/io/anjay_json_encoder.c
+28 −25 src/core/observe/anjay_observe_core.c
+107 −0 src/core/servers/anjay_activate.c
+98 −0 src/core/servers/anjay_connections.c
+38 −1 src/core/servers/anjay_register.c
+4 −0 src/core/servers/anjay_reload.c
+31 −3 src/core/servers/anjay_servers_internal.h
+54 −0 tests/integration/suites/default/notifications.py
+240 −96 tests/integration/suites/default/retransmissions.py
15 changes: 12 additions & 3 deletions src/lwm2m.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
#include <zephyr/net/sntp.h>
#include <zephyr/posix/time.h>

#include <anjay/access_control.h>
#ifdef CONFIG_ANJAY_WITH_MODULE_ACCESS_CONTROL
# include <anjay/access_control.h>
#endif // CONFIG_ANJAY_WITH_MODULE_ACCESS_CONTROL
#include <anjay/anjay.h>
#include <anjay/factory_provisioning.h>
#include <anjay/security.h>
Expand Down Expand Up @@ -478,11 +480,11 @@ static anjay_t *initialize_anjay(void) {

if (anjay_security_object_install(anjay)
|| anjay_server_object_install(anjay)
#ifdef CONFIG_ANJAY_ZEPHYR_PERSISTENCE
#ifdef CONFIG_ANJAY_WITH_MODULE_ACCESS_CONTROL
// Access Control object is necessary if Server Object with many
// servers is loaded
|| anjay_access_control_install(anjay)
#endif // CONFIG_ANJAY_ZEPHYR_PERSISTENCE
#endif // CONFIG_ANJAY_WITH_MODULE_ACCESS_CONTROL
) {
LOG_ERR("Failed to install necessary modules");
goto error;
Expand Down Expand Up @@ -555,6 +557,13 @@ static anjay_t *initialize_anjay(void) {
return anjay;
}
#endif // CONFIG_ANJAY_ZEPHYR_PERSISTENCE

#if defined(CONFIG_ANJAY_COMPAT_ZEPHYR_TLS_SESSION_CACHE_PURGE_ON_START)
// Modem caching might be pretty aggresive. We clear it on startup unless
// Anjay security config is restored from presistence
(void) _anjay_zephyr_tls_session_cache_purge();
#endif // defined(CONFIG_ANJAY_COMPAT_ZEPHYR_TLS_SESSION_CACHE_PURGE_ON_START)

#ifdef CONFIG_ANJAY_ZEPHYR_FACTORY_PROVISIONING
if (!_anjay_zephyr_restore_anjay_from_factory_provisioning(anjay)) {
return anjay;
Expand Down
66 changes: 55 additions & 11 deletions src/network/network_nrf91.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#include "../gps.h"
#include "../utils.h"

#ifdef CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO
# include "../nrf_lc_info.h"
#endif // CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO

#if __has_include("ncs_version.h")
# include "ncs_version.h"
#endif // __has_include("ncs_version.h")
Expand All @@ -37,14 +41,46 @@ LOG_MODULE_REGISTER(anjay_zephyr_network_nrf91);

static volatile atomic_int lte_nw_reg_status; // enum lte_lc_nw_reg_status
static volatile atomic_int lte_mode; // enum lte_lc_lte_mode
#ifdef CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO
static volatile atomic_uint_least32_t lte_cell_id;
#endif // CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO

static bool is_network_connected(void) {
if (atomic_load(&lte_mode) == LTE_LC_LTE_MODE_NONE) {
return false;
}

int nw_reg_status = atomic_load(&lte_nw_reg_status);
return nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME
|| nw_reg_status == LTE_LC_NW_REG_REGISTERED_ROAMING;
}

static void lte_evt_handler(const struct lte_lc_evt *const evt) {
if (evt) {
if (evt->type == LTE_LC_EVT_NW_REG_STATUS) {
atomic_store(&lte_nw_reg_status, (int) evt->nw_reg_status);
} else if (evt->type == LTE_LC_EVT_LTE_MODE_UPDATE) {
atomic_store(&lte_mode, (int) evt->lte_mode);
#ifdef CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO
if (evt->type == LTE_LC_EVT_NEIGHBOR_CELL_MEAS) {
atomic_store(&lte_cell_id, evt->cells_info.current_cell.id);
} else {
// NOTE: This may look suspicious, as we are carelessly reading
// atomic variables without even trying to consider that they might
// change in between calls. However, please note that
// lte_nw_reg_status and lte_mode are only ever modified from this
// function, so this is actually safe. Those variables are atomic
// to allow safely reading them from other threads, but this code
// does not cause a race condition.
bool was_connected = is_network_connected();
#endif // CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO
if (evt->type == LTE_LC_EVT_NW_REG_STATUS) {
atomic_store(&lte_nw_reg_status, (int) evt->nw_reg_status);
} else if (evt->type == LTE_LC_EVT_LTE_MODE_UPDATE) {
atomic_store(&lte_mode, (int) evt->lte_mode);
}
#ifdef CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO
if (!was_connected && is_network_connected()) {
_anjay_zephyr_nrf_lc_info_schedule_refresh_now();
}
}
#endif // CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO
}
_anjay_zephyr_network_internal_connection_state_changed();
}
Expand Down Expand Up @@ -81,6 +117,10 @@ int _anjay_zephyr_network_internal_platform_initialize(void) {

lte_lc_register_handler(lte_evt_handler);

#ifdef CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO
atomic_store(&lte_cell_id, LTE_LC_CELL_EUTRAN_ID_INVALID);
#endif // CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO

return 0;
}

Expand Down Expand Up @@ -109,18 +149,22 @@ enum anjay_zephyr_network_bearer_t _anjay_zephyr_network_current_bearer(void) {
}
#endif // CONFIG_ANJAY_ZEPHYR_GPS_NRF

if (atomic_load(&lte_mode) == LTE_LC_LTE_MODE_NONE) {
if (!is_network_connected()) {
return ANJAY_ZEPHYR_NETWORK_BEARER_LIMIT;
}

int status = atomic_load(&lte_nw_reg_status);

if (status == LTE_LC_NW_REG_REGISTERED_HOME
|| status == LTE_LC_NW_REG_REGISTERED_ROAMING) {
return ANJAY_ZEPHYR_NETWORK_BEARER_CELLULAR;
} else {
#ifdef CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO
// When CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO is enabled, the Connectivity
// Monitoring object is present in the data model. That object is only
// filled with data if the cell ID is available. For this reason, we only
// treat the connection as valid and connected if the cell ID is available,
// to avoid populating the object with null data.
if (atomic_load(&lte_cell_id) == LTE_LC_CELL_EUTRAN_ID_INVALID) {
return ANJAY_ZEPHYR_NETWORK_BEARER_LIMIT;
}
#endif // CONFIG_ANJAY_ZEPHYR_NRF_LC_INFO

return ANJAY_ZEPHYR_NETWORK_BEARER_CELLULAR;
}

void _anjay_zephyr_network_disconnect(void) {
Expand Down
10 changes: 8 additions & 2 deletions src/nrf_lc_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@

LOG_MODULE_REGISTER(anjay_zephyr_nrf_lc_info);

static struct k_work_delayable periodic_search_dwork;
static void periodic_search_work_handler(struct k_work *work);

static K_WORK_DELAYABLE_DEFINE(periodic_search_dwork,
periodic_search_work_handler);
static struct anjay_zephyr_nrf_lc_info nrf_lc_info = {
.cells = {
.current_cell.id = LTE_LC_CELL_EUTRAN_ID_INVALID,
Expand Down Expand Up @@ -134,7 +137,6 @@ int _anjay_zephyr_initialize_nrf_lc_info_listener(void) {
}

lte_lc_register_handler(lte_lc_evt_handler);
k_work_init_delayable(&periodic_search_dwork, periodic_search_work_handler);

res = _anjay_zephyr_k_work_schedule(&periodic_search_dwork, K_NO_WAIT);
if (res < 0) {
Expand Down Expand Up @@ -166,3 +168,7 @@ void _anjay_zephyr_nrf_lc_info_get(struct anjay_zephyr_nrf_lc_info *out) {
out->cells.neighbor_cells = out->storage.neighbor_cells;
}
}

int _anjay_zephyr_nrf_lc_info_schedule_refresh_now(void) {
return _anjay_zephyr_k_work_reschedule(&periodic_search_dwork, K_NO_WAIT);
}
1 change: 1 addition & 0 deletions src/nrf_lc_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,4 @@ int _anjay_zephyr_initialize_nrf_lc_info_listener(void);
void _anjay_zephyr_nrf_lc_info_get(struct anjay_zephyr_nrf_lc_info *out);
bool _anjay_zephyr_nrf_lc_info_get_if_changed(
struct anjay_zephyr_nrf_lc_info *out);
int _anjay_zephyr_nrf_lc_info_schedule_refresh_now(void);
6 changes: 5 additions & 1 deletion src/persistence.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
#include <zephyr/logging/log.h>
#include <zephyr/settings/settings.h>

#include <anjay/access_control.h>
#ifdef CONFIG_ANJAY_WITH_MODULE_ACCESS_CONTROL
# include <anjay/access_control.h>
#endif // CONFIG_ANJAY_WITH_MODULE_ACCESS_CONTROL
#ifdef CONFIG_ANJAY_ZEPHYR_PERSISTENCE_ATTR_STORAGE
# include <anjay/attr_storage.h>
#endif // CONFIG_ANJAY_ZEPHYR_PERSISTENCE_ATTR_STORAGE
Expand Down Expand Up @@ -71,7 +73,9 @@ static bool previous_attempt_failed;
static const struct persistence_target targets[] = {
DECL_TARGET(security_object),
DECL_TARGET(server_object),
#ifdef CONFIG_ANJAY_WITH_MODULE_ACCESS_CONTROL
DECL_TARGET(access_control),
#endif // CONFIG_ANJAY_WITH_MODULE_ACCESS_CONTROL
#ifdef CONFIG_ANJAY_ZEPHYR_PERSISTENCE_ATTR_STORAGE
DECL_TARGET(attr_storage),
#endif // CONFIG_ANJAY_ZEPHYR_PERSISTENCE_ATTR_STORAGE
Expand Down
9 changes: 9 additions & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,3 +240,12 @@ int _anjay_zephyr_k_work_schedule(struct k_work_delayable *dwork,
return k_work_schedule(dwork, delay);
#endif // CONFIG_ANJAY_ZEPHYR_WORKQUEUE_ENABLE
}

int _anjay_zephyr_k_work_reschedule(struct k_work_delayable *dwork,
k_timeout_t delay) {
#ifdef CONFIG_ANJAY_ZEPHYR_WORKQUEUE_ENABLE
return k_work_reschedule_for_queue(&anjay_zephyr_workqueue, dwork, delay);
#else
return k_work_reschedule(dwork, delay);
#endif // CONFIG_ANJAY_ZEPHYR_WORKQUEUE_ENABLE
}
4 changes: 3 additions & 1 deletion src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ void _anjay_zephyr_init_workqueue(void);

/**
* These functions should be used in place of basic Zephyr functions
* k_work_submit and k_work_schedule.
* k_work_submit, k_work_schedule and k_work_reschedule.
* Their purpose is to avoid using the system workqueue in order to prevent
* blocking other works from different modules.
*/
int _anjay_zephyr_k_work_submit(struct k_work *work);
int _anjay_zephyr_k_work_schedule(struct k_work_delayable *dwork,
k_timeout_t delay);
int _anjay_zephyr_k_work_reschedule(struct k_work_delayable *dwork,
k_timeout_t delay);

0 comments on commit 7875939

Please # to comment.