From b5eae78f3cafe6941978b08b9779af1614bdb336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Mi=C5=9B?= Date: Thu, 15 Jul 2021 11:18:03 +0200 Subject: [PATCH 001/126] mpsl: Generic coex implementation according to Thread Recommendations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This implementation is presenting how to implement PTA client aligned with given PTA interface. It is disabled in Kconfig by default. It can be easily replaced with other implementations added by Nordic to NCS or created by an application developer. Signed-off-by: Hubert Miś --- include/mpsl/mpsl_cx_config_thread.h | 48 +++++ subsys/mpsl/CMakeLists.txt | 2 + subsys/mpsl/Kconfig | 1 + subsys/mpsl/Kconfig.cx | 65 +++++++ subsys/mpsl/cx/thread/mpsl_cx_thread.c | 252 +++++++++++++++++++++++++ subsys/mpsl/mpsl_cx.c | 36 ++++ subsys/mpsl/mpsl_cx_internal.h | 25 +++ subsys/mpsl/mpsl_init.c | 13 ++ 8 files changed, 442 insertions(+) create mode 100644 include/mpsl/mpsl_cx_config_thread.h create mode 100644 subsys/mpsl/Kconfig.cx create mode 100644 subsys/mpsl/cx/thread/mpsl_cx_thread.c create mode 100644 subsys/mpsl/mpsl_cx.c create mode 100644 subsys/mpsl/mpsl_cx_internal.h diff --git a/include/mpsl/mpsl_cx_config_thread.h b/include/mpsl/mpsl_cx_config_thread.h new file mode 100644 index 000000000000..297debd98d3f --- /dev/null +++ b/include/mpsl/mpsl_cx_config_thread.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/** + * @file mpsl_cx_config_thread.h + * + * @defgroup mpsl_cx_thread MPSL Coexistence configuration according to Thread Radio Coexistence + * @ingroup mpsl_cx + * + * @{ + */ + +#ifndef MPSL_CX_CONFIG_THREAD_H__ +#define MPSL_CX_CONFIG_THREAD_H__ + +#include +#include + +/** @brief Configuration parameters for the Thread Radio Coexistence variant. */ +struct mpsl_cx_thread_interface_config { + /** GPIO pin number of REQUEST pin. */ + uint8_t request_pin; + /** GPIO pin number of PRIORITY pin. */ + uint8_t priority_pin; + /** GPIO pin number of GRANTED pin. */ + uint8_t granted_pin; +}; + +/** @brief Configures the Thread Radio Coexistence interface. + * + * This function sets device interface parameters for the Coexistence module. + * The module is used to control PTA interface through the given pins and resources. + * + * @param[in] config Pointer to the interface parameters. + * + * @retval 0 Coexistence interface successfully configured. + * @retval -NRF_EPERM Coexistence interface is not available. + * + */ +int32_t mpsl_cx_thread_interface_config_set( + struct mpsl_cx_thread_interface_config const * const config); + +#endif // MPSL_CX_CONFIG_THREAD_H__ + +/**@} */ diff --git a/subsys/mpsl/CMakeLists.txt b/subsys/mpsl/CMakeLists.txt index a4b5217415bb..50a30c523b3f 100644 --- a/subsys/mpsl/CMakeLists.txt +++ b/subsys/mpsl/CMakeLists.txt @@ -10,4 +10,6 @@ zephyr_library_sources( mpsl_init.c ) +zephyr_library_sources_ifdef(CONFIG_MPSL_CX mpsl_cx.c) +zephyr_library_sources_ifdef(CONFIG_MPSL_CX_THREAD cx/thread/mpsl_cx_thread.c) zephyr_library_sources_ifdef(CONFIG_MPSL_FEM mpsl_fem.c) diff --git a/subsys/mpsl/Kconfig b/subsys/mpsl/Kconfig index f23afc03033a..5b8f3945b97d 100644 --- a/subsys/mpsl/Kconfig +++ b/subsys/mpsl/Kconfig @@ -34,6 +34,7 @@ config MPSL_ASSERT_HANDLER MPSL code encounters an unrecoverable error. rsource "Kconfig.fem" +rsource "Kconfig.cx" module=MPSL module-str=MPSL diff --git a/subsys/mpsl/Kconfig.cx b/subsys/mpsl/Kconfig.cx new file mode 100644 index 000000000000..e0952adc82e0 --- /dev/null +++ b/subsys/mpsl/Kconfig.cx @@ -0,0 +1,65 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +config MPSL_CX + bool "Radio Coexistence interface support [EXPERIMENTAL]" +# Generic coexistence is not yet supported by Bluetooth + depends on !BT + help + Controls if Radio Coexistence interface is to be configured and enabled + when MPSL is initialized. + + Radio Coexistence interface connects nRF5 radio protocols with external + Packet Traffic Arbiter (PTA) which denies or grants access to RF. + +if MPSL_CX + +choice MPSL_CX_CHOICE + prompt "Radio Coexistence interface implementation" + +config MPSL_CX_THREAD + select NRFX_GPIOTE + select GPIO + bool "Thread Radio Coexistence" + help + Radio Coexistence interface implementation according to Thread Radio + Coexistence Practical recommendations for using a 3-wire PTA + implementation for co-located 2.4 GHz radios. + +endchoice # MPSL_CX_CHOICE + +if MPSL_CX_THREAD + +config MPSL_CX_THREAD_PIN_REQUEST + int "GPIO pin id used as coexistence Request signal" + default 13 + help + For port 0 simply use pin number. For port 1 add value 32 to pin number: + P0.04 is 4; P1.04 is 36. + + Note: This configuration will be moved to device tree. + +config MPSL_CX_THREAD_PIN_PRIORITY + int "GPIO pin id used as coexistence Priority signal" + default 14 + help + For port 0 simply use pin number. For port 1 add value 32 to pin number: + P0.04 is 4; P1.04 is 36. + + Note: This configuration will be moved to device tree. + +config MPSL_CX_THREAD_PIN_GRANT + int "GPIO pin id used as coexistence Grant signal" + default 12 + help + For port 0 simply use pin number. For port 1 add value 32 to pin number: + P0.04 is 4; P1.04 is 36. + + Note: This configuration will be moved to device tree. + +endif + +endif # MPSL_CX diff --git a/subsys/mpsl/cx/thread/mpsl_cx_thread.c b/subsys/mpsl/cx/thread/mpsl_cx_thread.c new file mode 100644 index 000000000000..6a7ba4c7f945 --- /dev/null +++ b/subsys/mpsl/cx/thread/mpsl_cx_thread.c @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/** + * @file + * This file implements generic Coexistence interface according to + * Thread Radio Coexistence whitepaper. + * + */ + +#include +#include + +#include +#include + +#include +#include + +#include "hal/nrf_gpio.h" + +/* Value from chapter 7. Logic Timing from Thread Radio Coexistence */ +#define REQUEST_TO_GRANT_US 50U + +static struct mpsl_cx_thread_interface_config config; +static mpsl_cx_cb_t callback; + +static const struct device *req_dev; +static const struct device *pri_dev; +static const struct device *gra_dev; +static gpio_port_value_t req_pin_mask; +static gpio_port_value_t pri_pin_mask; +static gpio_port_value_t gra_pin_mask; +static struct gpio_callback grant_cb; + +static int32_t grant_pin_is_asserted(bool *is_asserted) +{ + int ret; + gpio_port_value_t port_val; + + ret = gpio_port_get_raw(gra_dev, &port_val); + + if (ret != 0) { + return -NRF_EPERM; + } + + *is_asserted = (port_val & gra_pin_mask) ? true : false; + return 0; +} + +static mpsl_cx_op_map_t granted_ops_map(bool grant_is_asserted) +{ + mpsl_cx_op_map_t granted_ops = MPSL_CX_OP_IDLE_LISTEN | MPSL_CX_OP_RX; + + if (grant_is_asserted) { + granted_ops |= MPSL_CX_OP_TX; + } + + return granted_ops; +} + +static int32_t granted_ops_get(mpsl_cx_op_map_t *granted_ops) +{ + int ret; + bool grant_is_asserted; + + ret = grant_pin_is_asserted(&grant_is_asserted); + if (ret < 0) { + return ret; + } + + *granted_ops = granted_ops_map(grant_is_asserted); + return 0; +} + +static void gpiote_irq_handler(const struct device *gpiob, struct gpio_callback *cb, uint32_t pins) +{ + (void)gpiob; + (void)cb; + (void)pins; + + static mpsl_cx_op_map_t last_notified; + int32_t ret; + mpsl_cx_op_map_t granted_ops; + + if (callback != NULL) { + ret = granted_ops_get(&granted_ops); + + __ASSERT(ret == 0, "Getting grant pin state returned unexpected result: %d", ret); + if (ret != 0) { + /* nrfx gpio implementation cannot return failure for this call + * This condition is handled for fail-safe approach. It is assumed + * GRANT is not given, if cannot read its value + */ + granted_ops = granted_ops_map(false); + } + + if (granted_ops != last_notified) { + last_notified = granted_ops; + callback(granted_ops); + } + } +} + +static int32_t gpio_init(uint8_t pin_no, bool input, const struct device **port, + gpio_port_value_t *pin_mask) +{ + gpio_flags_t flags; + bool use_port_1 = (pin_no > P0_PIN_NUM); + + pin_no = use_port_1 ? pin_no - P0_PIN_NUM : pin_no; + *port = device_get_binding(use_port_1 ? "GPIO_1" : "GPIO_0"); + + if (*port == NULL) { + return -NRF_EINVAL; + } + + *pin_mask = 1U << pin_no; + + if (input) { + flags = GPIO_INPUT | GPIO_PULL_UP; + } else { + flags = GPIO_OUTPUT_LOW; + } + + gpio_pin_configure(*port, pin_no, flags); + + return 0; +} + +static int32_t gpiote_init(void) +{ + int32_t ret; + gpio_flags_t flags = GPIO_INT_ENABLE | GPIO_INT_EDGE | GPIO_INT_EDGE_BOTH; + + ret = gpio_init(config.granted_pin, true, &gra_dev, &gra_pin_mask); + if (ret < 0) { + return ret; + } + + ret = gpio_pin_interrupt_configure(gra_dev, config.granted_pin, flags); + if (ret < 0) { + return ret; + } + + gpio_init_callback(&grant_cb, gpiote_irq_handler, gra_pin_mask); + gpio_add_callback(gra_dev, &grant_cb); + + return 0; +} + +static int32_t request(const mpsl_cx_request_t *req_params) +{ + int ret; + + if (req_params == NULL) { + return -NRF_EINVAL; + } + + if (req_params->prio > (UINT8_MAX / 2)) { + ret = gpio_port_set_clr_bits_raw(pri_dev, pri_pin_mask, 0); + } else { + ret = gpio_port_set_clr_bits_raw(pri_dev, 0, pri_pin_mask); + } + + if (ret < 0) { + return -NRF_EPERM; + } + + if (req_params->ops & (MPSL_CX_OP_RX | MPSL_CX_OP_TX)) { + ret = gpio_port_set_clr_bits_raw(req_dev, req_pin_mask, 0); + } else { + ret = gpio_port_set_clr_bits_raw(req_dev, 0, req_pin_mask); + } + + if (ret < 0) { + return -NRF_EPERM; + } + + return 0; +} + +static int32_t release(void) +{ + int ret; + + ret = gpio_port_set_clr_bits_raw(req_dev, 0, req_pin_mask); + if (ret < 0) { + return -NRF_EPERM; + } + + ret = gpio_port_set_clr_bits_raw(pri_dev, 0, pri_pin_mask); + if (ret < 0) { + return -NRF_EPERM; + } + + return 0; +} + +static uint32_t req_grant_delay_get(void) +{ + return REQUEST_TO_GRANT_US; +} + +static int32_t register_callback(mpsl_cx_cb_t cb) +{ + callback = cb; + + return 0; +} + +static const mpsl_cx_interface_t m_mpsl_cx_methods = { + .p_request = request, + .p_release = release, + .p_granted_ops_get = granted_ops_get, + .p_req_grant_delay_get = req_grant_delay_get, + .p_register_callback = register_callback, +}; + +int32_t mpsl_cx_thread_interface_config_set( + struct mpsl_cx_thread_interface_config const * const new_config) +{ + int32_t ret_code; + + config = *new_config; + callback = NULL; + + ret_code = mpsl_cx_interface_set(&m_mpsl_cx_methods); + if (ret_code != 0) { + return ret_code; + } + + ret_code = gpio_init(config.request_pin, false, &req_dev, &req_pin_mask); + if (ret_code != 0) { + return ret_code; + } + + ret_code = gpio_init(config.priority_pin, false, &pri_dev, &pri_pin_mask); + if (ret_code != 0) { + return ret_code; + } + + ret_code = gpiote_init(); + if (ret_code != 0) { + return ret_code; + } + + return 0; +} diff --git a/subsys/mpsl/mpsl_cx.c b/subsys/mpsl/mpsl_cx.c new file mode 100644 index 000000000000..f3bd41b212c0 --- /dev/null +++ b/subsys/mpsl/mpsl_cx.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "mpsl_cx_internal.h" + +#include +#include + +#if IS_ENABLED(CONFIG_MPSL_CX_THREAD) +static int cx_thread_configure(void) +{ + struct mpsl_cx_thread_interface_config cfg = { + .request_pin = CONFIG_MPSL_CX_THREAD_PIN_REQUEST, + .priority_pin = CONFIG_MPSL_CX_THREAD_PIN_PRIORITY, + .granted_pin = CONFIG_MPSL_CX_THREAD_PIN_GRANT, + }; + + return mpsl_cx_thread_interface_config_set(&cfg); +} +#endif + +int mpsl_cx_configure(void) +{ + int err = 0; + +#if IS_ENABLED(CONFIG_MPSL_CX_THREAD) + err = cx_thread_configure(); +#else +#error Incomplete CONFIG_MPSL_CX configuration. No supported coexistence protocol found. +#endif + + return err; +} diff --git a/subsys/mpsl/mpsl_cx_internal.h b/subsys/mpsl/mpsl_cx_internal.h new file mode 100644 index 000000000000..81fecc96f995 --- /dev/null +++ b/subsys/mpsl/mpsl_cx_internal.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/** + * @file + * @brief Internal MPSL Coexistence initialization + */ + +#ifndef MPSL_CX_INTERNAL__ +#define MPSL_CX_INTERNAL__ + +#ifdef __cplusplus +extern "C" { +#endif + +int mpsl_cx_configure(void); + +#ifdef __cplusplus +} +#endif + +#endif /* MPSL_CX_INTERNAL__ */ diff --git a/subsys/mpsl/mpsl_init.c b/subsys/mpsl/mpsl_init.c index 49dc3775dec0..57c157180dfc 100644 --- a/subsys/mpsl/mpsl_init.c +++ b/subsys/mpsl/mpsl_init.c @@ -12,6 +12,7 @@ #include #include #include +#include "mpsl_cx_internal.h" #include "mpsl_fem_config_common.h" #include "mpsl_fem_internal.h" #include "multithreading_lock.h" @@ -224,7 +225,19 @@ static int mpsl_fem_init(const struct device *dev) #endif } +static int mpsl_cx_init(const struct device *dev) +{ + ARG_UNUSED(dev); + +#if IS_ENABLED(CONFIG_MPSL_CX) + return mpsl_cx_configure(); +#else + return 0; +#endif +} + SYS_INIT(mpsl_lib_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); SYS_INIT(mpsl_signal_thread_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); SYS_INIT(mpsl_fem_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); +SYS_INIT(mpsl_cx_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); From 8711032238e147725630fd3a8a45fe96ebaacdfa Mon Sep 17 00:00:00 2001 From: Jun Qing Zou Date: Wed, 4 Aug 2021 16:03:19 +0900 Subject: [PATCH 002/126] lib: ftp_client: Add IPv6 support to FTP client Try IPv6 parsing first, if fails try IPv4 parsing next. Adjust control and data socket based on address family. Update QUIT command as some server does not reply. Update KEEPALIVE to avoid unnecessary NOOP. Signed-off-by: Jun Qing Zou --- subsys/net/lib/ftp_client/src/ftp_client.c | 221 ++++++++++++--------- 1 file changed, 132 insertions(+), 89 deletions(-) diff --git a/subsys/net/lib/ftp_client/src/ftp_client.c b/subsys/net/lib/ftp_client/src/ftp_client.c index 95ac1912f3d9..97f7c59260ed 100644 --- a/subsys/net/lib/ftp_client/src/ftp_client.c +++ b/subsys/net/lib/ftp_client/src/ftp_client.c @@ -5,6 +5,7 @@ */ #include #include +#include #include #include #include @@ -17,9 +18,6 @@ LOG_MODULE_REGISTER(ftp_client, CONFIG_FTP_CLIENT_LOG_LEVEL); #define INVALID_SOCKET -1 #define INVALID_SEC_TAG -1 -#define FTP_MAX_HOSTNAME 64 -#define FTP_MAX_USERNAME 32 -#define FTP_MAX_PASSWORD 32 #define FTP_MAX_BUFFER_SIZE 708 /* align with MSS on modem side */ #define FTP_DATA_TIMEOUT_SEC 60 /* time in seconds to wait for "Transfer complete" */ @@ -30,13 +28,17 @@ LOG_MODULE_REGISTER(ftp_client, CONFIG_FTP_CLIENT_LOG_LEVEL); static K_THREAD_STACK_DEFINE(ftp_stack_area, FTP_STACK_SIZE); static struct ftp_client { + int family; /* Socket address family */ + bool connected; /* Server connected flag */ int cmd_sock; int data_sock; - bool connected; /* Server connected flag */ - struct sockaddr_in remote; /* Server */ int sec_tag; ftp_client_callback_t ctrl_callback; ftp_client_callback_t data_callback; + union { + struct sockaddr_in remote; /* IPv4 server */ + struct sockaddr_in6 remote6; /* IPv6 server */ + }; } client; static struct k_work_q ftp_work_q; @@ -55,17 +57,19 @@ static struct data_task { uint16_t length; /* TX length */ } data_task_param; +static bool ftp_inactivity; + static int parse_return_code(const uint8_t *message, int success_code) { - char code_str[6]; /* max 1xxxx*/ + char success_code_str[6]; /* max 1xxxx*/ int ret = FTP_CODE_500; if (success_code == FTP_CODE_ANY) { return success_code; } - sprintf(code_str, "%d ", success_code); - if (strstr(message, code_str)) { + sprintf(success_code_str, "%d ", success_code); + if (strstr(message, success_code_str)) { ret = success_code; } @@ -75,46 +79,50 @@ static int parse_return_code(const uint8_t *message, int success_code) static int establish_data_channel(const char *pasv_msg) { int ret; - char tmp[16]; + char tmp[8]; char *tmp1, *tmp2; uint16_t data_port; /* Parse Server port from passive message - * e.g. "227 Entering Passive Mode (90,130,70,73,86,111)" + * e.g. "227 Entering Passive Mode (90,130,70,73,86,111)" in case of IPv4 + * e.g. "227 Entering Passive Mode (0,0,0,0,97,78)" in case of IPv6 + * NOTE assume no IP address change from the Control channel */ - tmp1 = strstr(pasv_msg, "("); - tmp1++; - tmp2 = strstr(tmp1, ","); - tmp2++; - tmp1 = strstr(tmp2, ","); - tmp1++; - tmp2 = strstr(tmp1, ","); - tmp2++; - tmp1 = strstr(tmp2, ","); - tmp1++; - tmp2 = strstr(tmp1, ","); - memset(tmp, 0x00, 16); - strncpy(tmp, (const char *)tmp1, (size_t)(tmp2 - tmp1)); - data_port = atoi(tmp) << 8; - tmp2++; - tmp1 = strstr(tmp2, ")"); - memset(tmp, 0x00, 16); - strncpy(tmp, (const char *)tmp2, (size_t)(tmp1 - tmp2)); - data_port += atoi(tmp); - - /* Establish the second connect for data */ + tmp1 = strrchr(pasv_msg, ')'); + if (tmp1 == NULL) { + return -EINVAL; + } + tmp2 = strrchr(pasv_msg, ','); + if (tmp2 == NULL) { + return -EINVAL; + } + memset(tmp, 0x00, sizeof(tmp)); + strncpy(tmp, (const char *)(tmp2 + 1), (size_t)(tmp1 - tmp2 - 1)); + data_port = atoi(tmp); + tmp1 = tmp2 - 1; + while (isdigit((int)(*tmp1))) { + tmp1--; + } + if (*tmp1 != ',') { + return -EINVAL; + } + memset(tmp, 0x00, sizeof(tmp)); + strncpy(tmp, (const char *)(tmp1 + 1), (size_t)(tmp2 - tmp1 - 1)); + data_port += atoi(tmp) << 8; + LOG_DBG("data port: %d", data_port); + + /* open data socket */ if (client.sec_tag <= 0) { - client.data_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + client.data_sock = socket(client.family, SOCK_STREAM, IPPROTO_TCP); } else { - client.data_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2); + client.data_sock = socket(client.family, SOCK_STREAM, IPPROTO_TLS_1_2); } if (client.data_sock < 0) { LOG_ERR("socket(data) failed: %d", -errno); - ret = -errno; + return -errno; } - - if (client.sec_tag > 0) { - sec_tag_t sec_tag_list[1] = { client.sec_tag }; + if (client.sec_tag != INVALID_SEC_TAG) { + sec_tag_t sec_tag_list[] = { client.sec_tag }; ret = setsockopt(client.data_sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list, sizeof(sec_tag_t)); @@ -125,16 +133,24 @@ static int establish_data_channel(const char *pasv_msg) } } - client.remote.sin_port = htons(data_port); - ret = connect(client.data_sock, (struct sockaddr *)&client.remote, - sizeof(struct sockaddr_in)); + + /* Connect to remote host */ + if (client.family == AF_INET) { + client.remote.sin_port = htons(data_port); + ret = connect(client.data_sock, (struct sockaddr *)&client.remote, + sizeof(struct sockaddr_in)); + } else { + client.remote6.sin6_port = htons(data_port); + ret = connect(client.data_sock, (struct sockaddr *)&client.remote6, + sizeof(struct sockaddr_in6)); + } if (ret < 0) { LOG_ERR("connect(data) failed: %d", -errno); close(client.data_sock); return -errno; } - return ret; + return 0; } static void close_connection(int code, int error) @@ -166,11 +182,13 @@ static void close_connection(int code, int error) if (client.data_sock != INVALID_SOCKET) { close(client.data_sock); } - close(client.cmd_sock); - client.cmd_sock = INVALID_SOCKET; - client.data_sock = INVALID_SOCKET; - client.connected = false; - client.sec_tag = INVALID_SEC_TAG; + if (client.cmd_sock != INVALID_SOCKET) { + close(client.cmd_sock); + client.cmd_sock = INVALID_SOCKET; + client.data_sock = INVALID_SOCKET; + client.connected = false; + client.sec_tag = INVALID_SEC_TAG; + } } /**@brief Send FTP message via socket @@ -180,8 +198,7 @@ static int do_ftp_send_ctrl(const uint8_t *message, int length) int ret = 0; uint32_t offset = 0; - LOG_HEXDUMP_DBG(message, length, "TXC"); - + LOG_DBG("%s", log_strdup(message)); while (offset < length) { ret = send(client.cmd_sock, message + offset, length - offset, 0); if (ret < 0) { @@ -198,6 +215,7 @@ static int do_ftp_send_ctrl(const uint8_t *message, int length) } else { LOG_DBG("CMD sent"); } + ftp_inactivity = false; return ret; } @@ -210,12 +228,10 @@ static int do_ftp_send_data(const char *pasv_msg, uint8_t *message, uint16_t len /* Establish data channel */ ret = establish_data_channel(pasv_msg); - if (ret < 0) { + if (ret) { return ret; } - LOG_HEXDUMP_DBG(message, length, "TXD"); - while (offset < length) { ret = send(client.data_sock, message + offset, length - offset, 0); if (ret < 0) { @@ -223,12 +239,13 @@ static int do_ftp_send_data(const char *pasv_msg, uint8_t *message, uint16_t len ret = -errno; break; } + LOG_DBG("DATA sent %d", ret); offset += ret; ret = 0; } - LOG_DBG("DATA sent"); close(client.data_sock); + ftp_inactivity = false; return ret; } @@ -274,13 +291,12 @@ static int do_ftp_recv_ctrl(bool post_result, int success_code) } ctrl_buf[ret] = 0x00; - LOG_HEXDUMP_DBG(ctrl_buf, ret, "RXC"); - if (post_result) { client.ctrl_callback(ctrl_buf, ret); } - LOG_DBG("CTRL received"); + LOG_DBG("%s", log_strdup(ctrl_buf)); + ftp_inactivity = false; return parse_return_code(ctrl_buf, success_code); } @@ -294,7 +310,7 @@ static void do_ftp_recv_data(const char *pasv_msg) /* Establish data channel */ ret = establish_data_channel(pasv_msg); - if (ret < 0) { + if (ret) { return; } @@ -308,7 +324,7 @@ static void do_ftp_recv_data(const char *pasv_msg) break; } if ((fds[0].revents & POLLIN) != POLLIN) { - LOG_INF("No more data"); + LOG_DBG("No more data"); break; } ret = recv(client.data_sock, data_buf, sizeof(data_buf), 0); @@ -320,13 +336,12 @@ static void do_ftp_recv_data(const char *pasv_msg) /* Server close connection */ break; } - - LOG_HEXDUMP_DBG(data_buf, ret, "RXD"); client.data_callback(data_buf, ret); + LOG_DBG("DATA received %d", ret); } while (true); close(client.data_sock); - LOG_DBG("DATA received"); + ftp_inactivity = false; } static int poll_data_task_done(void) @@ -371,9 +386,13 @@ static void keepalive_handler(struct k_work *work) { int ret; - ret = do_ftp_send_ctrl(CMD_NOOP, sizeof(CMD_NOOP) - 1); - if (ret == 0) { - (void)do_ftp_recv_ctrl(false, FTP_CODE_200); + if (ftp_inactivity) { + ret = do_ftp_send_ctrl(CMD_NOOP, sizeof(CMD_NOOP) - 1); + if (ret == 0) { + (void)do_ftp_recv_ctrl(false, FTP_CODE_200); + } + } else { + ftp_inactivity = true; } } @@ -390,31 +409,58 @@ static void keepalive_timeout(struct k_timer *dummy) } } -int ftp_open(const char *hostname, uint16_t port, int sec_tag) +static int host_lookup(const char *hostname, int family, struct sockaddr *sa) { - int ret; - struct addrinfo *result; + int err; + struct addrinfo *ai; struct addrinfo hints = { - .ai_family = AF_INET + .ai_family = family, + .ai_socktype = SOCK_STREAM }; + err = getaddrinfo(hostname, NULL, &hints, &ai); + if (err) { + LOG_DBG("getaddrinfo(%d) error: %d", family, err); + return -EHOSTUNREACH; + } + + *sa = *(ai->ai_addr); + client.family = family; + freeaddrinfo(ai); + return 0; +} + +int ftp_open(const char *hostname, uint16_t port, int sec_tag) +{ + int ret; + if (client.connected) { LOG_ERR("FTP already connected"); return -EINVAL; } + + /* Attempt IPv6 resolution, fallback to IPv4 if failed */ + ret = host_lookup(hostname, AF_INET6, (struct sockaddr *)(&client.remote6)); + if (ret) { + ret = host_lookup(hostname, AF_INET, (struct sockaddr *)(&client.remote)); + if (ret) { + LOG_ERR("Failed to parse remote host"); + return -EHOSTUNREACH; + } + } + /* open control socket */ - if (sec_tag <= 0) { - client.cmd_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sec_tag == INVALID_SEC_TAG) { + client.cmd_sock = socket(client.family, SOCK_STREAM, IPPROTO_TCP); } else { - client.cmd_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TLS_1_2); + client.cmd_sock = socket(client.family, SOCK_STREAM, IPPROTO_TLS_1_2); } if (client.cmd_sock < 0) { LOG_ERR("socket(ctrl) failed: %d", -errno); ret = -errno; } - - if (sec_tag > 0) { - sec_tag_t sec_tag_list[1] = { sec_tag }; + if (sec_tag != INVALID_SEC_TAG) { + sec_tag_t sec_tag_list[] = { sec_tag }; ret = setsockopt(client.cmd_sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list, sizeof(sec_tag_t)); @@ -427,27 +473,21 @@ int ftp_open(const char *hostname, uint16_t port, int sec_tag) } /* Connect to remote host */ - ret = getaddrinfo(hostname, NULL, &hints, &result); - if (ret || result == NULL) { - LOG_ERR("ERROR: getaddrinfo(ctrl) failed %d", ret); - close(client.cmd_sock); - return ret; + if (client.family == AF_INET) { + client.remote.sin_port = htons(port); + ret = connect(client.cmd_sock, (struct sockaddr *)&client.remote, + sizeof(struct sockaddr_in)); + } else { + client.remote6.sin6_port = htons(port); + ret = connect(client.cmd_sock, (struct sockaddr *)&client.remote6, + sizeof(struct sockaddr_in6)); } - client.remote.sin_family = AF_INET; - client.remote.sin_port = htons(port); - client.remote.sin_addr.s_addr = - ((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr; - ret = connect(client.cmd_sock, (struct sockaddr *)&client.remote, - sizeof(struct sockaddr_in)); if (ret < 0) { LOG_ERR("connect(ctrl) failed: %d", -errno); close(client.cmd_sock); - freeaddrinfo(result); return -errno; } - freeaddrinfo(result); - /* Receive server greeting */ ret = do_ftp_recv_ctrl(true, FTP_CODE_220); if (ret != FTP_CODE_220) { @@ -509,11 +549,14 @@ int ftp_close(void) if (client.connected) { ret = do_ftp_send_ctrl(CMD_QUIT, sizeof(CMD_QUIT) - 1); if (ret == 0) { - ret = do_ftp_recv_ctrl(true, FTP_CODE_221); + /* Some FTP servers do not reply QUIT */ + (void)do_ftp_recv_ctrl(true, FTP_CODE_221); + } else { + return ret; } } close_connection(FTP_CODE_200, 0); - return ret; + return FTP_CODE_221; } int ftp_status(void) From 3eef36295b144869fdbd099b3dc54488fa129f10 Mon Sep 17 00:00:00 2001 From: Jun Qing Zou Date: Wed, 4 Aug 2021 16:06:07 +0900 Subject: [PATCH 003/126] application: serial_lte_modem: Add IPv6 support to FTP client Code clean-up after adding IPv6 to lib_ftp_client. Signed-off-by: Jun Qing Zou --- .../serial_lte_modem/doc/FTP_AT_commands.rst | 1 + .../serial_lte_modem/doc/slm_description.rst | 12 ------ .../serial_lte_modem/src/ftp_c/Kconfig | 20 ---------- .../serial_lte_modem/src/ftp_c/slm_at_ftp.c | 37 ++++++++++--------- 4 files changed, 21 insertions(+), 49 deletions(-) diff --git a/applications/serial_lte_modem/doc/FTP_AT_commands.rst b/applications/serial_lte_modem/doc/FTP_AT_commands.rst index 2ed81f4fab51..a0c55a1ac85d 100644 --- a/applications/serial_lte_modem/doc/FTP_AT_commands.rst +++ b/applications/serial_lte_modem/doc/FTP_AT_commands.rst @@ -47,6 +47,7 @@ The ```` command is a string, and can be used as follows: * ``AT#XFTP="mput",[,]`` The values of the parameters depend on the command string used. +When using the ``put``,``uput`` and ``mput`` commands, if the ```` attribute is not specified, SLM enters ``slm_data_mode``. Response syntax ~~~~~~~~~~~~~~~ diff --git a/applications/serial_lte_modem/doc/slm_description.rst b/applications/serial_lte_modem/doc/slm_description.rst index f77746cbeb0c..3bd42c4c6af6 100644 --- a/applications/serial_lte_modem/doc/slm_description.rst +++ b/applications/serial_lte_modem/doc/slm_description.rst @@ -195,18 +195,6 @@ Check and configure the following configuration options for the sample: This option enables additional AT commands for using the FTP client service. -.. option:: CONFIG_SLM_FTP_SERVER_PORT - FTP service port on remote host - - This option specifies the port to use when connecting to an FTP server. - -.. option:: CONFIG_SLM_FTP_USER_ANONYMOUS - FTP client anonymous login user - - This option specifies the user name to use for anonymous login on an FTP server. - -.. option:: CONFIG_SLM_FTP_PASSWORD_ANONYMOUS - FTP client anonymous login password - - This option specifies the password to use for anonymous login on an FTP server. - .. option:: CONFIG_SLM_MQTTC - MQTT client support in SLM This option enables additional AT commands for using the MQTT client service. diff --git a/applications/serial_lte_modem/src/ftp_c/Kconfig b/applications/serial_lte_modem/src/ftp_c/Kconfig index 177d5b77bf70..5777b0ed53d0 100644 --- a/applications/serial_lte_modem/src/ftp_c/Kconfig +++ b/applications/serial_lte_modem/src/ftp_c/Kconfig @@ -7,23 +7,3 @@ config SLM_FTPC bool "FTP client support in SLM" default y select FTP_CLIENT - -if SLM_FTPC - -config SLM_FTP_SERVER_PORT - int "FTP service port on remote host" - default 21 - -config SLM_FTP_USER_ANONYMOUS - string "FTP client anonymous login user" - default "anonymous" - help - Define the user name for anonymous login. - -config SLM_FTP_PASSWORD_ANONYMOUS - string "FTP client anonymous login password" - default "anonymous@example.com" - help - Define the password for anonymous login. - -endif diff --git a/applications/serial_lte_modem/src/ftp_c/slm_at_ftp.c b/applications/serial_lte_modem/src/ftp_c/slm_at_ftp.c index 09a970b121e8..6297868ba1f6 100644 --- a/applications/serial_lte_modem/src/ftp_c/slm_at_ftp.c +++ b/applications/serial_lte_modem/src/ftp_c/slm_at_ftp.c @@ -17,13 +17,13 @@ LOG_MODULE_REGISTER(slm_ftp, CONFIG_SLM_LOG_LEVEL); -#define INVALID_SEC_TAG -1 -#define FTP_MAX_HOSTNAME 64 -#define FTP_MAX_USERNAME 32 -#define FTP_MAX_PASSWORD 32 #define FTP_MAX_OPTION 32 #define FTP_MAX_FILEPATH 128 +#define FTP_USER_ANONYMOUS "anonymous" +#define FTP_PASSWORD_ANONYMOUS "anonymous@example.com" +#define FTP_DEFAULT_PORT 21 + /**@brief Socketopt operations. */ enum slm_ftp_operation { /* FTP Session Management */ @@ -139,10 +139,13 @@ void ftp_ctrl_callback(const uint8_t *msg, uint16_t len) sprintf(rsp_buf, "\r\n#XFTP: %d,\"disconnected\"\r\n", -ENOEXEC); break; } - rsp_send(rsp_buf, strlen(rsp_buf)); if (ftp_data_mode_handler && exit_datamode(false)) { ftp_data_mode_handler = NULL; } + if (ftp_verbose_on) { + rsp_send(rsp_buf, strlen(rsp_buf)); + } + return; } if (ftp_verbose_on) { @@ -153,7 +156,7 @@ void ftp_ctrl_callback(const uint8_t *msg, uint16_t len) static int ftp_data_save(uint8_t *data, uint32_t length) { if (ring_buf_space_get(&ftp_data_buf) < length) { - LOG_WRN("RX overrun"); + LOG_WRN("FTP buffer overflow"); return -1; /* RX overrun */ } @@ -166,7 +169,7 @@ static int ftp_data_send(void) if (ring_buf_is_empty(&ftp_data_buf) == 0) { sz_send = ring_buf_get(&ftp_data_buf, rsp_buf, sizeof(rsp_buf)); - rsp_send(rsp_buf, sz_send); + datamode_send(rsp_buf, sz_send); } return sz_send; @@ -182,21 +185,21 @@ void ftp_data_callback(const uint8_t *msg, uint16_t len) static int do_ftp_open(void) { int ret = 0; - char username[FTP_MAX_USERNAME] = ""; /* DO initialize, in case of login error */ - int sz_username = FTP_MAX_USERNAME; - char password[FTP_MAX_PASSWORD] = ""; /* DO initialize, in case of login error */ - int sz_password = FTP_MAX_PASSWORD; - char hostname[FTP_MAX_HOSTNAME]; - int sz_hostname = FTP_MAX_HOSTNAME; - uint16_t port = CONFIG_SLM_FTP_SERVER_PORT; + char username[SLM_MAX_USERNAME] = ""; /* DO initialize, in case of login error */ + int sz_username = sizeof(username); + char password[SLM_MAX_PASSWORD] = ""; /* DO initialize, in case of login error */ + int sz_password = sizeof(password); + char hostname[SLM_MAX_URL]; + int sz_hostname = sizeof(hostname); + uint16_t port = FTP_DEFAULT_PORT; sec_tag_t sec_tag = INVALID_SEC_TAG; int param_count = at_params_valid_count_get(&at_param_list); /* Parse AT command */ ret = util_string_get(&at_param_list, 2, username, &sz_username); if (ret || strlen(username) == 0) { - strcpy(username, CONFIG_SLM_FTP_USER_ANONYMOUS); - strcpy(password, CONFIG_SLM_FTP_PASSWORD_ANONYMOUS); + strcpy(username, FTP_USER_ANONYMOUS); + strcpy(password, FTP_PASSWORD_ANONYMOUS); } else { ret = util_string_get(&at_param_list, 3, password, &sz_password); if (ret) { @@ -221,7 +224,7 @@ static int do_ftp_open(void) } /* FTP open */ - ret = ftp_open(hostname, (uint16_t)port, sec_tag); + ret = ftp_open(hostname, port, sec_tag); if (ret != FTP_CODE_200) { return -ENETUNREACH; } From b0c72f123ae746cf49a5ca4c1889a229aef9fcba Mon Sep 17 00:00:00 2001 From: Trond Einar Snekvik Date: Mon, 9 Aug 2021 17:02:09 +0200 Subject: [PATCH 004/126] actions: labeler: Exclude Bluetooth Mesh from CI-find-my-test Adds filter for excluding find-my CI label from pure Bluetooth Mesh changes, just like the other high level protocols that do not depend on Bluetooth Mesh. Signed-off-by: Trond Einar Snekvik --- .github/labeler.yml | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 01c4557c5fc5..c95b80b2baba 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -181,19 +181,24 @@ - "samples/matter/**/*" "CI-find-my-test": - - "include/bluetooth/**/*" - - "include/dfu/**/*" - - "include/nfc/**/*" - - "include/dk_buttons_and_leds.h" - - "include/event_manager.h" - - "lib/dk_buttons_and_leds/**/*" - - "subsys/bootloader/**/*" - - "subsys/bluetooth/**/*" - - "subsys/dfu/dfu_target/**/*" - - "subsys/event_manager/**/*" - - "subsys/nfc/**/*" - - "subsys/partition_manager/**/*" - - "modules/mcuboot/**/*" + - any: + - "include/dfu/**/*" + - "include/nfc/**/*" + - "include/dk_buttons_and_leds.h" + - "include/event_manager.h" + - "lib/dk_buttons_and_leds/**/*" + - "subsys/bootloader/**/*" + - "subsys/dfu/dfu_target/**/*" + - "subsys/event_manager/**/*" + - "subsys/nfc/**/*" + - "subsys/partition_manager/**/*" + - "modules/mcuboot/**/*" + - any: + - "include/bluetooth/**/*" + - "!include/bluetooth/mesh/**/*" + - any: + - "subsys/bluetooth/**/*" + - "!subsys/bluetooth/mesh/**/*" "no-changelog": - "!doc/nrf/releases/release-notes-latest.rst" From 08c651f6de7c56524400c67b32641e9d6d52812a Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc Date: Wed, 11 Aug 2021 13:23:33 +0200 Subject: [PATCH 005/126] doc: zigbee: expand default signal handler docs Added new images to Zigbee default signal handler docs. Applied minor style edits. KRKNWK-10712. Signed-off-by: Grzegorz Ferenc --- .../zigbee_signal_handler_10_rejoin.svg | 124 +++++++++++++++++ .../zigbee_signal_handler_10_rejoin.vsdx | Bin 0 -> 160126 bytes .../zigbee_signal_handler_10_rejoin_stop.svg | 51 +++++++ .../zigbee_signal_handler_10_rejoin_stop.vsdx | Bin 0 -> 155143 bytes ...ee_signal_handler_10_rejoin_user_input.svg | 103 ++++++++++++++ ...e_signal_handler_10_rejoin_user_input.vsdx | Bin 0 -> 160658 bytes .../images/zigbee_signal_handler_overview.svg | 126 ++++++++++++++++++ .../zigbee_signal_handler_overview.vsdx | Bin 0 -> 266984 bytes include/zigbee/zigbee_app_utils.rst | 58 +++++--- 9 files changed, 442 insertions(+), 20 deletions(-) create mode 100644 doc/nrf/images/zigbee_signal_handler_10_rejoin.svg create mode 100644 doc/nrf/images/zigbee_signal_handler_10_rejoin.vsdx create mode 100644 doc/nrf/images/zigbee_signal_handler_10_rejoin_stop.svg create mode 100644 doc/nrf/images/zigbee_signal_handler_10_rejoin_stop.vsdx create mode 100644 doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.svg create mode 100644 doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.vsdx create mode 100644 doc/nrf/images/zigbee_signal_handler_overview.svg create mode 100644 doc/nrf/images/zigbee_signal_handler_overview.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin.svg b/doc/nrf/images/zigbee_signal_handler_10_rejoin.svg new file mode 100644 index 000000000000..1b29afaa9780 --- /dev/null +++ b/doc/nrf/images/zigbee_signal_handler_10_rejoin.svg @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + Drawing + + Nordic Blue.1368 + start_network_rejoin() + + start_network_rejoin() + + Dynamic connector.1421 + + + + Nordic Blue.1422 + Schedule stop_network_rejoin(ZB_TRUE) after ZB_DEV_REJOIN_TIM... + + Schedule stop_network_rejoin(ZB_TRUE) after ZB_DEV_REJOIN_TIMEOUT_MS + + Hexagon.1423 + role == end device + + role == end device + + Dynamic connector.1424 + yes + + yes + + Nordic Blue.1425 + Schedule network steering after 2^n sec + + Schedule network steering after 2^n sec + + Dynamic connector.1426 + + + + Diamond.1428 + + + + Circle.1430 + + + + Dynamic connector.1431 + + + + Dynamic connector.1432 + no + + no + + Nordic Blue.1505 + n++ + + n++ + + Dynamic connector.1506 + + + + Dynamic connector + + + + Hexagon.1474 + wait_for_user_input + + wait_for_user_input + + Dynamic connector.1511 + false + + false + + Diamond.1513 + + + + Dynamic connector.1514 + true + + true + + Dynamic connector.1518 + + + + diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin.vsdx b/doc/nrf/images/zigbee_signal_handler_10_rejoin.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..d5cc111d245813a3b125475bb5a2d4d5b6e4c95a GIT binary patch literal 160126 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�t)0!HxEh%Cutnm@|iYZf)UXMKq1Dnis?W!RM^h#Tv?4k}LnBI4p?9Z+F?eT6s7Wi;vCGTS+ZWBvE%TSx;66fUgk!O+y(Ydo?Iq3~I8uw3 z#4hJ&6C(xDdMw2xY>I7Y-B)gO7aNbg(P#t+!+`C7O8Wn4!up{s6!EKUdTXB~;r#~{ z5gR=#izLB^3HIvT2fvaqH|*Mjd}4URd=NbKstogw=9UabaCtl9i6$n(H4MT)Af=Kl zp^Y$2^s?*m48s+;^{Q9Lt|!`jP&VBmDqPc*Kn?Yv=JwA*DcmQ-bRN)&>)a zk+|d{bJXQkBnCT+iE;Shtq9K{%P_Ig0=z7NxNfd>W5kC2h9)GwSdG5){;o(e+oFf9 zx?Sin!mGr*-EP4zZPc{ERl&rsq5`85W0O$~BtI`Vu7pMR!w1&STC7(>q zy?ttp1t2-|_^aENO-3ULIoBmD88W;ZGP4IHvu5dG3ps`*x>^x9eJYG?EO_jtV0Qq4sfmmj$6ncoQbTnEhhh;3V`}zfiAsSRRuoc$aP_DwC8;1)& z3@WOb++ldGo9rna4!m&hd>O9H3ozY_w>q+vY@5g~ATzi8=tx`F<4Uz`l@BCsB-8|I zpMI^=(coh$ZHmqXMS6ob4>$Q(vMGqQ7o#adI*tM9toWcMtu9NgoCu>9LRzZ#b<}4= zqrhQDnj;thjy&ENBjVBgi6$B!FR^<0o)O|6mWLM4E}92jIt@K1|1xk6>Ingro(ifc#4@nhqT{-{~Hds67qW=(GzI0aRk}KlukS!(>*^Bca!mueU5ojGo14NfB^EdciRP z6@i2eGb4$eVb!T_m^zZ-3A-S_GL{wFQgrb3kk!c2j-e;kHcG?hT7Gj7wLU#cC$XMp z#f&>+Cekc3H_9G|W2IcoMtUXj4>hB+^TK=uz3*U0A+2!7WHa|Q?cv5FpKJ+3Z6Jta zzjpU`Ip?PYb}^z#*IP%9l8?{$!xQ`9)k2tcH_0Vg z6IzcL$?d#-GFll`gR(J-pG$CTfLgLqtmVbd#YG>A%BThQa%QzJ)tlFsIB=DbwT(8) z78-9|XW^UKmw}(7chAes{N47gI@>i=Z~eaq{B&5)cZF~zSQJ~u8k^Q_5z>?LtpyrY(7a|O#)ZJ>Gg>DdL#`>p zC4)5^GUg-~NgA-feUEGpQ?&9MKiS!MHa0_gnv!xW?pqBf2i>$0b(BNrOx7oq1ij}-y%xW zh+CowB`SNg&-_5@fk6|fZ!+Rse6~IJQ^fDv9F?}x*`St?VP+i$|Q*TBls$3r1kk1z}UxAA7RYCw( zRN~h#&C}sqrEMY}N3vYzi^gAGee>^O()_!L>mBQVTL%{#FH&oNanbuP_Z9QECG2Y9 zWMM~VW8ma$;^_20Bg=oC*0+9f(IP#%kJtepy8A!=c=mH2%}~)zo8%S6l&Z@d`LV4L z!U!TR8mwO2(RL20P<=p%`d_yow}(5o*k0W3UMQft(P$)0jk!5^VD|ennur$EEs{(( zA@ChMK0jAxH;=&eG*O6HMA%@hA(}HX3GcGYtp|rQM;c<>!Yo_F>B4+jHmm~!A30(B zZQ;=JFxm+H6R$DM9p;gQ@XmZ{XQUd1mT4jBvQ{V&O$6X4mrx)!gk#6tA#G8vqxwq& zs1azVsb_Rty!9R|qnsbG#t0BEc=q2o*1uZt+VS9<<39MRobXwH@ymL!y;GC)M#YS< zf%OggNg`I@s}!?DzYO49M6&?|gZA^F`jbIUoyu0D?R?i?Gqy;5ZMU(U!^(`D#eA07 z#0pd9PSdQvh}qaeLj$H{cbOI3^jlOM1-cs?i;9m43#AG5$0fl^QIkx%1T^J%#7}av zMXY1wYt57;R9>oT!oJDoS^FB)i$Zx|#Iy3()n}Z_S5ngwZ{20>vQfhJNdn^o$UhL3JBxPxm9&5wn?VxRD8mzXA8ucC=OHBHP-RMTTm;pns3MjJ z^!80W<07ruYhN|Az$lgSH zhkDkOCf@7{4_V{i1M^JqGc-vCSq`KMroV{8O!^@u$RZ)AC^!jx(|HQcf)v#d_e^Tb zNuvUWDU0J$hS4bV5fz&{hhFTK%{~4Nt%j%>5{@559Uw7HP+`3yZ>!zXPbFcngv*uu zVwBJ{MkUV-w`PFzAU212=|3L&;9h;s+8wvFIaTbQSOKmsWglc7g6Ir`@keFG(aGp& z&O5(cX|ery)VlOM8nL;&kI1BV)3Q1F%U9}kHCI(qvc{9XVF+3+il}m9WtoXvE55Uo z+*{iehq@?uUdrp;OYQi3tAg3+PKe_C6W+s}(X}f5twbD2%hu!~)A3*?Zxc1~D4Jo) zqP#VKj7@@jb`a*T`vc(g`8%2azdVo2WsQZ@U&==d{{Jz}|7%0KrDEGr(rWQK4~|}Zs|WYX+5LQ$vY{n5NJi=Q zR4tgOfY#Y)xDINlRO`BN9y_PdlA1J)m5At`yr?iwqh)`7^JbQ0mqG`-fe#clrWsGp zUHRx(U(cwWBOdLX4jU>aE9i1B5x&1YIsl9Y!VhtYaONuK*>X&(7NsXuxX=M zq@&7NygpBxvuYHZeEHE|xe1|y9@bK+yQm(;RnoiX(kv=GxxmV~qi2~uyuB~7e<@b; z>CiR$@svo8_|q_9K6Dp z-f6c7>z6THu$Ip&dmA>K?I<4{U7T+Fz@BNY?1TzuwN3lmHadO$^Sy^IzcOWND=qrg zZcuOv%IUc`%Z%E(vR%*kgkLo1ymQOzK3zTXp1RnRZqK_Wv#bp-h}fc9z<`Fmfdl&E zyXat#We?^o$ST2FvI zNN+ARUZ~F(w+^me+#maG`?johtEO|&NQs60d)lu8H7`i?&1;?e7qNdOp*Pb-V~^d< zS?bx$fRjKDt#{;=&F6O9zFaIVNzx=jW+qD#O3#AXVZWz-6nWUAt~h z2-~9bIgYKUhR6>@9&mjv(-u$^F89aRq%`$MnhC2@es6AWT(P)=8ka<7YUFC(#m0!x zhOJV5-Ei0SnGOQYK8rVS5O-Pq*KLv6MG-(7;t&$+iK7?OERh~*o!jsRHLd8v68Fvn z^6ecQy^2!5&COf*c=-TtloP%u8X>}+4S_@`u^^*E3WNqg_Q1C^t%`-S;X=($ji@fg zD(5SE`$P28Yp?bZjE=2MDcx#2p4l6%d2{9HlQVYI_`|8zDmE(B70R z8;md2MrO72o)$ecm!r+nt_NSu*)g?seA+ng|6F}YSU4rCC7RxjkXWzG314Mz6w!XE zJeDN#81^A`jdl-DhZG4}>QLw#i61 zG3ECK_wGkXMkWC#slkcP&j&G?d*d$^b|(bB3uX@8=MD%J#!tbI)}5J=#b~9)sm5qw zc=mAwjinC_7egkS`!nJIr5!*YZ~T`LG(au^4F|QG*_2U&96|V>`T%BF1ZFQHb-OV< z9>b_&;!`V-Z>GMyFgY3UFfpopzyHjQ0qXr+Tm@d4!xnkdMaD?$xwZ~KOpETG1~NT) z)*paqDR}^|)h03_5s(amJS^zw!yMc3&@ps)Vw7Y30qHLlpf(PiC}4*@>R51+9LgWL znuzFJqltY`?AAp7Yg2qlTBPj^jS1G1Rsu2n3Seo$u6QeG`O&OA@jrNNrcFKg*rpVS z3BvRg!R9WYs?0(9z5@p7Xpk!y@$CL91T^}Q_{n1{>U-$J$l`F?f5Fcw9}susS;A%N z?oju&9-0YP7SPrc{ygtHcdr`zSDU(_Np+xq@oFH7#DC#`L76M~0|Io}rl}tZ-A54! zB0G2cHygnDt1SuqVM9b8L#c=LN_zol29Q%UDEef>jv$f*L6V>32b3}XFqT7)BwoTg zK{v@&Al9_UQWp#@WiW_W$V&|BH>}KOKZF>JCojtLB`}eXAR>fE7O9Z*?}>MZ-c6I# z7Z-zugiW{4HPZ!5sy@DTi;Wb%_6}Bqec; zjtV)wC1k9CblhUW;KwJd$T)!!2hJxgfEC|^cDMasmQc2z@A~@$Q=}mr7|!w%w2DAL zRH|;>O0vFLTGgDWM>DwK%M=66_mw-qxnlcaqQK7i_ zTjD=#JMIS3#XgZjqarvg(elv+W<|PLn^0+b+tRZaE1p{RuBX zQx4uL7{lED{4u=@m-JSakfZ_ZNe(uQq3IzC9WFsm8q>?6(BF zYNR+%D^MpDj=Ksl)s`z8Fog!qn<*B{moo8l3R0=&FvNIZ{f@dTG%9H7XcScFt))8f z8zKSE{aU1%N$iVrw#!u=7L2+dm(Hq`2sCEWMsISLL>hE!o&cAOwO^PXmofvw6_9N% z+$V8%bzT$9k>^4A%W!Xsos8{6>?Oar7iNWbg8z?-+e)@N_Z6faVy*d^m%+u`fon55Q9u0n(bcRy#(SLa?8_F}%qv}M(6}{yE>AQm z34too)>F5OeS{u)^Ej6G@h!ZBp{L@p94_|HIjbNQvVesCso;0OcH@{+i;>L*c4`@9jwqrQVgIs`cB+vFg3Sri(cmL4r&aP#`zj`(L(AY-~{`( zqz69Q%Sx4m-JY9gFcMjf;}hF0JeV+&ilWC@?5Dc8Lbqc{he=PhP(6gF>O_9Epd4qp zNDjBBtLghreZ}f+>&`ix{vxZ765|z1ltpXhJb5TV2t2x_y%5Javjimm2f$`9w7pE_;Z(8R538`(roRd6HHU@yhotOO z$cz0c-`$$%FoP?b6S24+g$&iE-BZxiYFQbq|3#FVur#h!@TXOHGZWr2>LOhUz6ybk! z0i#KdwHW#^B8%Xbn4KyQ|BzFHQKdQ}y|Wk~fG!#>GdJ8cUJxzRk3g>y?bfYctZ+7i zll03JUBqkw3t}3iKl2;Wu##ueU#HjXHdrpx)BH)|L&w9wbA!VeDtNUdpceS!x_4&7 zXgIWq%rp;PG7LITzmk}r#?3@{HHghOygLs1`DQx6n3=KIQH(LI+Gv^v!#lD*X1tQw zoT3ndkquMoLAO#J7n*|eV&{J1@ssQVME(TEbbYWFpGpx90A=n70klZCi84}^gA|W( z^{--ER37)Y+lDcr)lIogKCsI+ra^i2E%@ndAG1d)by8y4xxpNb3di8IxD(>YW-?m3 zCCr@=O0#0##(W_~JA8CQMXx{@YmxJI<#%6{Q$oOv^WYuafPOp<4!7a;Y(cd$f z=#6HSzFY!Pa-EOIv0i2`4uvM1-k*rUSBPO6PI4@x8mOrLcQWIHELpZ{vPh~@P?Z~^ zhoK8&xKcfT7F);r$xMZ)G6zGLu)xa#P1qcY6Z@0}()vU}rQLfc^|4A-LP5i>U?Ork zv#d&~%o0)gsYM~ojznfZ6T)RqBgMUh745?Fgc74H%S^x{*0YRu5RhN9WZoAmN}Wz) z<0=#P79SSsm?N^7pr7z7We9gp8$nK|-^zrE_#@9n*+{7%A$Y&yO!X$F}QOL zM__-aCBIW>uF1&U(6u+WRAg>U(T_b)nBOHf-$Y^#{e5FkPV51}n~*=2j_Rz*Ua@oJ zHUE8ck3xdRl6rKIkai>u#p#K=`Xky+oJ@qqjP_nnjN-HaLSn-CP$J#4rJL1hu%Z4K zmFCSKYInfNHGfVII-T_$5;xQFTK{>V_rGq)xmOLLG{3clx7j~`ewiizQ%1BmFf(zY z`_J|NWt8YxIU$WNf9F(uf|E0 zaDI`VJ>Q%fOVLmlri3szeSdt)I@SId=i}9p@x+UIGvv;+efbJly+v7^zq01;Uc1?) zp2ai!+TqLjexj4xfu@T*Z9H#CqebKKX4bKOp-Y{-%x!H!Eu1{CY(v+M5qnrSbnU^8 zHdWJVe0aDkTYG00UDOIV1=CU+ylbNC`SP&!=INv@F@N!9?Zu=;3tImyur_pK?Pv$o zU_KzxdN5?vE@+IJyn704eSSFbWT$NTSbZ>5nBqhIDwT_+4O<;9`25-Fzj5V*eD6M- zU3I@6_I7pJzU{`Aiz+-mh46*==>EDhR{Xhadu>Yk@q9n>U`T(|wRzc%E+zZgsWrET zKk~>J);RjeNj=r@lk&K1@}`njnw2}4l2Y6)z5Vp^Zs|IrEB^hGg~XAG#Bh#$(&tva z$cIsrCU3eaqB(e_3MV1HNo0@Rsf`I&TI}M4d@w;3>)1h?H%@_mFQD~r>1WpLV}nZ% ziV`7yq?~zvtxVl%$X#lxpVa2$e7!WNhd(G`jZ9KfKOGoxy#GL6UD)v+ zj!%vNC2x-Z{qh{BYka9rJ_&O5o%WAA9>mGYOfSd7O2A(?AaN9e&Y{f$SjageA2_!y-zS4$wW5Gf~|m5W>B3<>_b?O zSzW_!f_DkjvpP~Q6V7{>VBfBXMV({(?2S5oht*Es(Rqb=(d}G!ZTs~7#_!Bbg7I-< z#qw(V$H~s-%#t>~!NK|6C&#Gb>5rJgg-yP_CZc1JX!Z`T*?nkvot_Sxx10Mp;5kk_ zpDO;49yYzX^Se>7E)PBQZ^g4r3&uZTc`Wgo)M0!Rg{8LTq5f;Mc!~jl;p= zk?aVW_^MaZoeVZI=x$`f`eh;;9xN+anAoQQi1U%g=IFtm4$dQ9-JU15Htu?Xk!||G z`PB|Bzjt(poaFMZb0Rhos7jETE|$Nltw$L-SA9>PC9NGiAKn$D>7Y!$nfcil*vofB zUAoC8ySa`&NIusMd$3$y1Bq`*hdMLdA=*rSBMLzrt*z;8v}?@hBJ(r#0x~Ng+MP63 zS`jq7(JJuSrHxtY`xs5=POsh3OLS+{+bFvx|A|*?ESy}wUD+)a!pC#gSU0OR{lveS z2}64lYRRul3TuoTzLS0&C-aJ$aiPFEqgHN=){P)Yovw#fn+6eede%{B*cmywtR6>S zUnDEMbVO~ajg)m)I(u7z^8kK;WAw7qG(78Q~3p?U!o zvJL0?>VN1UScDCN;P1Hd`TJEqlZm4_F^hNM zM->dg3G&4$=QcaLnF4hoiy0t#0DNxv%Gyw9@9s&WJb0E$Ld{&^)!1eCvBkc;WYu2MptbJF!oHQHv)sKg_9(%r(>L{ygiQ zW5Lgu9)Mch4b#UVFSr+m6?O`5U~vM zfQi8JOeSU@;!B>A`heBw)Y*vT4tR{!m>DJYP@D>))ayPL^%ifJbNFU&iSa&T$elGI zVYjXQ%%iVE)u3_2>s2*HvyO3kIQjwhG*fo1JM>qbs8l5@a-{vVR9c<2X)IMTH}4s{ zL#9W@uE2mpn>y^__`{<9(}(rvpRewx8*2`)ySm5d8YIix&?otyQ)-g&o6~dnJDu)? zxmmLZfiL&YTTjbmO7QnHV&%1bF774=Lkgn>#x)8FK)$B|{vMUkXbGlZqE3a$v1 z19=RP0^cN3aEeNCEikD8O=$)jOA2V@HGWQJ+L=K+k8JqDZR--}JPON3yH*}=bG z;DKR00gLt!9_a+1VGJQeC-beurQtM*I`A2?pC+JlKw$jcy9L8NP#=LT<}1@m$gR(Q z+d`emzZi=oc?JhJa<%|QEk|_a$d!@2gEV8Zf(f^n3XB5x;zd9oYGQ)=-cM;jaWCHgedLhw!bFTk0+reyZS?=6G_QEAA4^ zO9E}EmcM{89HKoLyqt6_f5NZVGky5EmL5Sn-e~&6q!e?DN=E!5N8xi=N4hkgq}7O5 z974GybHgu0OGOFp4RK|!iXcw!e~p^R=wF$`10>4RUNac6MIhWKq#waLti?NrZ1>%X zLdb!9YYz_$FP?r2CXsUNA$=DDEV7RuDKs=;=9|F;qhkQWQV9d9J4G}e#2%^0=SsDs z0Z#^h3jv>k_iiCvu9y>f6@YKB(S=tefL>aiHi9M03k`uT1ujJicw8MnGS^wDa@%*p zYRS>^$y0XBmxD$voOS~Yrlj5LxMSPod@{qBIjXAkb6%R&UFJ6<*BbO3$;2H;XnfPy>x4r;B>}3}$EIn0-G! z&oUUUtrF0v1|TQ4ItzJ3rWrjgw#s!%Kbe85fuctR{jff5tf<~W>KlfU)+#DeP`#p8o(X|?j z^yhZ{cKM3+MLw=Ij0YdWTOBuglZV+rI7Pef#cXu<*jC z#hAub2LA`K>_^cXQ+KLlDnsLY%pLk`8g_2q*Abmzka#L>6^gWQ2zIVe;EKfHN+cpR z#G}HRVYnvWvrDmtS!GYHS*q;2azU}!V#!*o62X{OEnWo23{MHIzTqVcJe#BjAFeb$ z!eoqIMhqv0AixybASMC3nHb%JKd-8GsK)Vea^_|SNbqHT(k-kL?Bj!&BZ}u36w}yr z*%kebs<1M{U~Nx}XmjmlCiMoNFT@rqvGJgQIuGF4 zEE#vf!r+f6{ZGWs3yXwp#?x$AY-!RQfHnb`RyEb?ZEZh(ScxjFp368Lg8>eaPsULA zpD~3u&Nb}1`Q9K)(kVUfJAplXTb{*6txbI0wb+&&mZt-95e09ta*>b z5Ixb5afw502DU{K)NPV=-ZD`Xs(!h~6vWimE%xAhR6L8oiWR zTxd@lmDoRi;&8%4Y*RJ&SOpn;)H@PaHd6iai;-w5wvz87W>o$%#tbs186aus%O^L1dTAQ6q%C2 z@{M_#NzZfhfDV)OmYBNZx=ekVh#=xV0ya5pmq|!6Qb_ezjiga>JtLNm!>IQ(My_r{ z7o|t_F3H$}eUB?|t49soaOuY%hqLP=9hds0 z0`i(}X4IX=Q9u@WIn<30dXsw88)+_|6MEKcy-tBwsuvIip9^eR@+cM5*kYCk-gr1I z-~O^ql_A}?$7jS#ufbJtgK`mklx%5Tk&%5Cmf3`e3TPznVZ4Z42r zuphd~qrpRm)%>&#k^W7IhLVpYR3(~_@)vd-HYCDng0S=@pvTOSqc>PWP;9f9cIk~9 zGqHM7eb3`bVh*L0&C=tH?SEEc{pi zQx1_|SP(QYr95_t5!Sx}GJv*H?*7FNAt6TJMO=r@g!GTQ>JY_s%?}oUX*OX40z_tT z4p=H&)I^IVr|@m-Y*BvONF=H>irP~|4IWYmABH|8;FK?PUc##h@8SlzL`?5uxS`zj zi-deS{UcdvfaSm+8~~0(0OU<<06Pt6rcSksqz(7Sm5xP?xCy*Y%g zrLbWt7Yl!f?o5?ui&6RcXQUwRhEF8xcJ7EF*H~Fcuc>xj12lYrC|iE`Uv=wCF~9Kp zTJyt8)o+_9J92aBO0?+m-_7su(zi{FMqBgmaQ*kiMaQOak1CnbMu56W`xmeduq1_I zxKO^*pkVc?6Sok=WyXM7#SYC_dNbqdPM4Tb_Z5C3l!?DhM}`E(ztfsvLL<2|_X#mn zO28vS69P*I{niMO3A5G95vBX#oDyC&pxuQ0e;}MJtre^*t{9|2bb%iL6?2o(R7@`l zzYD<@JixK6ZD);F*eP~|V7A!#HK352XKc7L9Txa_U5TN?3aCLLUdw>k%?V|eu(<-u zGC#e-amtySN@ViY?>7z+4R%-AXc7RDdGV{~V7w|5=${DPFhXS4*y)QBV}i@S8a~J^ z@#qpfTTkY*Q!CdqyyT=rA{N#=R!s_oZ4|`hzq6#JHS9LvVOTB}yyoS*S5hvp6u@Cs zDo$ocALfBW*pBSTV`Tgs!ErfDsUUHIVZ^2yqK6EX8^)Hx1t{HvS75+2K^+3bg-iD= zJQYy53Hgxkd^jqc^T5(oV*h1QRyZwRCwd|A5KG2q`c+EvjZkWmMCVkDV-n3rqIdqv1Pi|RF0-$aX7p_>}589pI4(X}H{Rp*-&50g<*H4#B9X54lCSu?oN&56RTU4z#S*?>_s)N;<|s~quaV;M8_uXdsOW%{ z04Q8kBR^kvNUfI55No04VAgo*%9(<4Jd%nsBSkte#@69wm1H#$a!hd<8?&*-Mrl~F zl5x_;N$!UCoAgca8EMl@JXR-kNL`1?MSNb8iUlTfcyyG9*Sa!)xxHSNlEj7bY$Qpd=gbt_|!x9G@?DeHPdq-Af)veSHh zc>#X~Zf0p=DIbd`#phwMDKtA_H#LKvOAcj;Lvjp~O?t!1gSK6!wh9UApo{s*Z1A>r zQ)(br4L^Tfsvv`uQYa~nOm38p4@Dw^DmhSvb7L+hLS8$m6ZA?iT)j`o#0RFTJht1p z8j9i>)Cq2K>WE6eLGL{6Wi(TJ66BxoE2>k-Wp=j<6bMfrkN*N+LOLwr*ywLYP|jj^ z))(wBcZT1ofTd27#l9Z5II}<4d#+**>ZXd+_mO~Sn||xtII9|sNNm@p*U4s2i; zr4cQ`8YcZuk~>^M8w|G$9ptJnJ%IGm8&&24a~zLRSjev+%sf6XQOhLVnN)aBGK0_= zbsaAp)WD(58Z-K?OurHqWF8=c7dIZEYx8lxI(f!(E)vPgS(wV2l`|hj*=%6DZ>QA2f6wz0`OT={@i?<~k~O(VkI)v0YR2S^xt$Xu zr6X1Z2AI~+tFX7Es*p1eq-4x!%z$p@4`WWN==G4M)ObmXNjg09ak5W0s^|`-dkJoT zE)Y`V6xzv89LX-1=@_U%e%zJE9x<*=Dd6AqmN&lIZVvo$daq4AN|v~uV9Bs^yxOLI9( zck&!lkq=Xru-?`zG4|!E3Ae8o08lVXU+(|aW!Aax4&QpR8Js2KHjScorpDlrg zC>=YalP{iG@$#e{f|%VM(lnqj6#61lqA5vVN~9JA|&=pmFP(G!Rr_^LzK4^+y@? z3c^0<6R)gfP?NmoSrBdaLoLyS^+cu+2XQo*EhxFk2dNx= zbfO7VaU8^?@n97IN)*MQA|p+6XqL5w8*`8|2mGtXRs$op&j?5Srb4%@%1osGygpO6 zVIdW2o}W(u-I-_eF03!v#{?60>OjbGHw18_^5~N9g9J5yeTk2PX!I-zx0Z1g*G7X@ zMBjs_`lB3HA(^kTu*3*d9OXj??Srg32oqyb(&k4@Zsp=G5GIMR11X2-k0ajL#uIcL?hNM?dS^W+TgxQsBR`!4-V`MWEOC4_2P%<4`7z|LoiRyOk)Qp3 z#O%o5x!K;uxu^lwWJMmeg0bP^>=9r@su4Vx-Vly;LeIKgjak=-gJKh9)n<#7E7Zot zXP`G|qc*aTC@ZN@O2_IU7RadzUF(A;af&unwL`h?+~Hri)1A_m^C9dE1HkJiDlEpM zi5$mr9fcB~LeVnbV_B;3Q9->w)^;IBnAtJH)2Dx{fAV+$kEajv%%%yU=NGk| zVFGs#u~mEr;B;I(ABiLznC0x>P$tgw=hOtl2V977P_0R;@P^hS;Q+i3Tx;JshNe;F z>+m6yt@&>Fy5Rs;FiawIMH(J#pnj-gT9YHllM>N|x~fv9V*B@!fvw#9dsHH2oTzs? zwLKiOn3?s|Y&yO-m&F7bt=X%jsP1&OPcHeOX(z1AvL z-)b3tA5tN9EmXNWRCoHxi%qwC$XW8j7G?PD%iZ0h!78@*N>UT>)qm1aiQAc5bJkHP z!2&tC*cT?uH}1d8Eaq+nXcZBbvBR3($a=@@dD9d|6Wh5Z=7T-7MEF8vh$|Z&uVT&J zdcWBp1KcP&cHij$=5JFr)He9(O6g5(N<58hs69^8t^J;;G(9O|%}p^-{VVycKMiYJ z;2!e;TNRC1bASBXZ+*|gxds`znXvJ9iL7H8(s{^03e=%b@r!#4KPuB;(lF#dv-ePT zP~|8)hD&xfmws8L^%kEMAw--IW0RXxzjPulM8HYR%-_h1*(YXX-mnG-J1BOpt4&yXuq_(=+S3OCVa` zjPaG}JtB*q3p?48w+XWqhnf}KPLJH>%81_hp*~elMDTg=9n%(HtT1_-nd+ljgFl26 z)N*-EE16Twz8vDfFyN0I5k{oTW$Zv?lGncg2K*2k36I|({?g1y z;X-%peJ(*g8l=b=K-(h`g4qfd^NJKz8)_LqR%EC|J#Q4$ewpDx6q-OC){ufr)^xzi zk!TsK1k1ou{!7a>tzR_Elux*2Vx<-w10=+`E}qsfTT%b4uv8VrpPU>+q61ptykkOL zj@gk~Tp)aIts;DDl1{Eb>DfW2U}07SqX6WXx)ar2ySj0q61ZWIO#Yl_nsXDQJWD*T zE-k+51(HA&W358>VsC~a#Y@!LX}I2;1<)6=id%tzOn>GP9@K8q!}hnV8(*w|qY8O0 zR|?44Z4sO^5M9pvRep&Ow=}4iu;AlD{Xc)8x_DBsojw#54o!o`$kSP})gyugR78Zqisb2K zU3}fT{gCLUQ+VZI@rInd+@Jbj4n#qPG){wM!i;OO_^7EuC}VIi`h_u{OMsO?Bi6UQ zO&{MK&f%dlH%%Y%l)}mG^M9=p4yvWc2nyYnf^GE&z;RLuMYRkbVdyB)CDfT>m?$0B zSuryC99qpOd&W@S`GK6serx=;fL4~F=wiSX2fW(A6@PVAhv0z5J?X04)D2R9%~1y`j2D!%cXM*Pa0l5m?x66>Ct4#zLs!`xP)O8 zgV@XO>KNR9d&|EWe;P4ymL$}=wH>wJk)#;2_Ku&JaSw{b$Vh3}tn`s46aXQG=9 zJlnX(gm0-Rq}B%pCwWbeNddcJ*l4h~2J6sh3A94Z5wr{u?h2J>hr%1X0mNy3{+;n7 z5Pw|OUMPYRzrrR14h%DBO{?qEd;WFnmdj-hMB|y2T#G{$pFnoqez)uXdb_$fYambA z^eMqU(35_mX2IvDeTGT_i|b#CGdr%FmUZ=b@yWIX@eGuElc>@Mq}(VL}{-87cGm|5o*$n#6n8Q2|FzlJ?qk}EeJ%P z3YD!A-V6(~f3uSBQXDF?c&_pdn?3sD6Qd#GcE2Ek~1#aUCR|>n(yWHKpYNZH24lw2)I{Ld`?l#JH=|&+qHF8JRI@ zW;T^08d`RtXk|sbI;e}s2j{;QmH&%=VRaCMk^PtO2l#&w{{E}p{tw~rf7IK1mUz;v z5qA20mGLP1e}y5fQMn+xoR8B0s?g)CGPO0IdS9lZW6bo$f4^6ej`3`}_o?rQnV#Ni z!hQ4t^^k)Y3yYA7JocUkIvv*qsa{r#%JJn}ZEsf0C$*Rb+$cxngET-3`(;@rw_MMe zCu-H)#%z-ddJ+3zls42q&Cw_kbo?(4;QbDhw3MFbL3NWZy#*fItUUB1TKkUY2kF7{ z2Kf2Wep47rf$;eyCFD1bzG+p1zX}$54MTA9Vls+J`HvXor)D=3a`LL5l&fE{mX#B0 zdWD^_7oy)x3w>wYk3=f%GoG2$qn8Iu#?H5Y14@;Ly`=cbREj9s45GI_X#&~y>J89E zmJ`EtAFdbQG~h%M7;nm24Y*a3KVmJ-{cYA1tkBFMZezjjygiGwDro0sAU8VJ?K4Cd z9kC~yti#NyG|YlsS_a?YXC74gwH#QeH=Q+;R=;@fELjR3lK|M?w>e2?nVz|WPKj`* zP#{w)vm%sH?9a@H@OJn7nPebS4d11&POOc+L(+@24Y3znrFLRc5eo37r)@E4N;O(D zXiDd4r!G9V>xVNP1~SK}a77Iig$-X^B0_^W1TZ2wVD`Gqus9G*o8WA+ml zlHJhl+=9daF}a5}obicvlSAjA^TeFDZuYNXNq2``I>>}?qq`N_W9aRvN!r|>(G|iF zO327ve2xd<@oblv2Pm4uUTKTV)y+r^9wQcqC?mGuE#|Ye_jF-PTOyx0gUcfI`6uuV zo^+q^CF@7mLJKCeg&{$Y@m1lZj0K_v$f)9H<>=h|DbSOoY!mvwfK8f02@fcv%v$I$ zVU=8~%XHcbUGqQLzlmV3!ux2wP6jxtJ)i+71L=d& zw~N=3hh*R{HGt#?$DvUs(VCT~zB53h%6Ezh&~Vt#^mB>>2t~x(R7%V9i$QRF|C-B? zr#2PgL^39W>>^Y4@QCi?VJU-X)=a>Bg2Q~_kD8oM1nUT6xl)4@Fx>`Zf@B!1Y<}hr zip9vk*ejpC-9`w%zMVl(F!X1pT~U816k2{A^#Sxd;j8m>$%ZR?ROMadv@xRf#W#L@ zy3oU|$0Nhm$|t$ALjXmd@&4x2#Py(7t@Qd>u2q-F`|xCS324!nUO!8egNQ*^3A&gl z-)Kp~l|sm#>lXde^H`xL(kO-{nO9%c>$oKg=x4u19V737ciHIW&SnHZ+3p{hlc1v` zBb8@Im4k)>K|G!r_Tg8igp`@Xv>WUTF5P3%t4d(Dqgeg9+~hwdnKf7DFrZ~&2J?O} zO0NY5{YOjYZ(uG%eGI;Q9@p7Ty|pKp!aENxxeOwV>VQgb6A_4ZO8*HH3DXSSrIz!- z84SP~B9g8Ih9DCA{=}OHI`QpJc!EEu)HmI@wsk_6{UfCyQ5881?5=Z6Y);k&P{i(! z<>{w80{Q%;->=`Yis~uGsCKP1NR#2MoyZ<((u(=zh|y$J$1OWARU7?3+`UtDqjy1HhvD5fHuB#RXaDkj{-0T10esf8ixK%u@4<8JsdHitH4*p^~@CUHrPkh zmTmP=ZnuooR~yZxo9KvF;c5NukVN6Eyk6ddP&g?{zuxGYzb3nXEpA7eL*1Wh$)eQ<^ z6Xb*X3aI9nwV!DwCaQN%X_hf7(1?rWol6eIw~cXce(jrW1$`*a^8%7hSE+^s9kUDg zJp~DLTNCSAGL|tuwql{1oKCM%+BJ_xw4+5tNtBsHYVG2~B)ch&OZG}8#6E`O(iVX- z-%zRh1@uSzH;tNyorL{05z2q;o51JzMQ>o+G8U+sdAbW@wu3s4PM?<36m;0uR z)E(xq2@ywnt-Pd-Uvy(D2_ZRd%T9Cz?6tj?D~rmi+!a$MPjpol#LIBeRGN*Knk}2N zI387ld5#)o_>?o@e7jsy5LAY~7V<&!n*i!S;+rkGE{#!NDWo&cr*{bk4fFY+f3Z<$ zJP6>&m;It+P#+Ja^QgA@WvZWtWMw1CmdJdjslUwJ^i0@~k*hZ6M+Ao5^JSkuqJ%+| z3;>TLD;oJd6>Wlq4|m)fC5BAc_^N3jKYowm>04NVQO1nzcAi&KuGs3zKCcvo746s% zI7@lDnG2CX)n~S!q*EOl8|DE}=cAkb0@V2`^JTiLb8;aiSv2l$qkYywFX#X2e5_Cd zSs(q-hPrR@z8}c{R_Ck5hQ+V|#;yJT61V>hNBHk?YgdfhKB&%Ihp36l2&-hEEQ988 zJkA2H!9uvmv0SA3={+^Eh zg-5R%jOcg@6lRfOpz*F6`y1`GM*AAV3$*fO#Extci=I7xBU3Wt`}9M-1uwPbKd17)b~kVVW;ngRU{ z@X0?%U80Xz?KqLPsya$B%;Foqw{AgD00yDpYQFwsXrShr@;Wli5alpOkdLv^xjUzT z?Fl~Sx?W*;oyC8j7- zj=Wwv5;LZN!YiLouF$Zdv&|X!Ea}vDr2H|n>+3+->XqOCuuJ7l6)s=6{##rrN z(Sr-rp^=@NMEu;SH|%chLZQ$=XIS6@dVk=G7^d1HIcfuj{^2D^trz_kGf3g&p8fAtHwYn`D-l|4RI!j)=3s5n$qXJq<$sWT6V0A6QM7NEwNY=#uI*1+jHO@r)xe z+Na=(*!$D*O*zYRS#Lo!-u7nbjQR6IDX+hyHJ+LU_Elb|6rB%3_V`%9`wKmI^CwK& zB6YMm7m^R{t$;*NdtA)@c{I*3#xi>T48o}k;L+6}#~LcH^SkSeIHMe) z@yHZfu0sf3C)EJj_T+t=9HZK_^tJi$$6L64vZ)iYZmV{<-=o4cS}iX{+AWRK{_BA1!&u2L&ZtVnr0W+j)^hG51ciL-QbE z+8&NtC={5FC}`k)B=|?R*SvwVzlYArFqrL%MFd`7O%5-h{F8FTUysFabfZmYGAYxW zC;fIX$?npz;DE9{-B&+gYY2+;N@f-0ejWLc)(cgdToqlBbce{yKeGMT$YPDc(;mj| zdu-jpqa4V;vi&h(#59(RCA~Ms(nMiBP_}QmD^UMOwx`YbE89OR%u|%%m)bVTuG+1v zaiX8(HIQD**fQST_p7ohP)r5gWZfx zZ6+>7Q7jHRt6ym?+YJd=WdB)8ws0|7NaL8m^FcO@oEo?EM+l7C47$nrHkX*6un!qt z!YD>24SRq>h`7)HqlDrAk^&lo>R9&s8A z#tCCd+SDR=sd1N7(VsqTU0jd5K6OXfS7UewtUmaQ%PDd#Ea?Y#Og_E~L$wFkpZ|7v z5vHmh9Um~BLI0O{{%2-Kr-r6Ia0IL$)AVPa5z(HFQFgNp(+)j8kz~MNW>eOn-?2!7 zrFH~;MPgQ=*r#`R5z=f)l93`?uN|qQ*^^_eeHhRCOFQhp61x3A5<19YUbSVpenTy# z)*RUX=Cun<=$C&bbeWi?x~{qAn;0;mV>o~b4fZ#o%`)ORdGr{;|0XofKM5TJOz64y z#4}4^LL0dMNQ(KJ&}wZzKp$H0maw96VsrAQ0U&nmNIS_|uZhDsaqU)Fc^DK^68yZb zi+a(sZ!J#jM-{TFU%c^L7FCxO{X+VzvdhO+S2jz&Z0to*qMugS9q|{U4~>w>eWSTb zs*u?GpIf#h3e9J|sAv&pQ%-rU0UnHP{-|0X zT0maLhR+ze{XH0u{&v>vSgx}zG;Jgpu}NphRL(}9e~vv7ts7lvvnw{$wC&hd(0zP0 z(W*?4Jw@o9xm;lJ%xO5}<|Dc`U_`ye3#_3X%;tQ%VSi{Vl-yR5$sKEJ`^wt&mL96R zgWbGY5*F$&w|i z8D=MO^G%#!q)~IhWSFL#cg&E@EZ)lIt$Lrw;gU0+K3N3z{tfttDcU3BLA~wcoPUgR zWE?JRis!}{my8T(GA87nXSDEk#svtGqO6F6qHrmbZT);ilpPX{=!kYiuHfYvISZk* ze<58XRqDJu z9z)CxQ7X#p|K0W_<6VV>rHgd=28>@vg7||(yeL9>IFkIN8Omk(Oap0;#{r@aBG*=Ei7YEmwJ|T@-2_K3+yrFM-HW^Pi{9EjW$?=0 zPN!K`y4>L)YZe*FaLCORaJa`v>ZWjXCe!+9#xij0b(ph}+ZlhgHdAmnoNj^{2K2Zt zlOBWuV!%20K3Lgo8SMA!5`*NU>+g_}q+HI0bAwTNzWvSKXm{k$3)~ve6nXb(zv{+*RzvOxv$p2S6$$Sy79i z1Hb%NnU2X%mnRj{*<@3H)`SQFBL4hHN)Nn*F&jZE7i}hiIw6fup}H3jbo9y_4dHoy zM^nZC66?q1QwP*ul%~wiH0tP5V5GLY5ETioiOb(EW^M|wXE2DDbqmC92B?kELz#_J z6(11MFkdZ?%d)7_`eqGs<M%o| z&Yq~B!#2&hwgX{M(-EnLLNyQJu1V2w4F+G8X5zJJrl6 zcU=)O@F`@Gq8pS79Q6A6tIz<>;xzIn)0ocC{!Vz4;$UkCPEA(MWr7Y<99u%8?UGqw zuNx+SsO^UbDYACOjDzK$H2mE0^_IeKp zFKP{*iJ#~r2;-`+$4C7sAzkw_;!lA9l;oxJ>I3_E(=%oJl=vbzeB&RTKEu7YUzzFtghX17D|j}|2!7TH!APTn(L@LUlljO#7iUk zsCok9@%`XII<2E_dW;CxP-zCg@5;dFJ*qZftig|D5mTy4@pn4ia|v~&p~Kjdyjt&N zkfR?$=ZQbv>FP9y3F3#382om*w$742c|5J*h>`VE+|>D5N6D*CRY_%`qYSRz3p?c= zwIU26W!I%D)^e30^R+^lK!piy>W>*%Ep|;}V1>(p%3)r31}nW)s{o#-)3@*e$Ex%S8ujo za5eQDEO3?B>XVnmMO~2#jwPmXe9r%)zpX6!0NCHw+BNoAQ19mXy7{GG#U^ z_A>m@Kb#5HStZO&L@*V_f`X^Cz-Fp~Cdt0iywop?6YCv8KtxnOY-*lId-j+OYCY>C z?6R-@iQx4NxF_k~6rdA|kn%<#K|rd2^F#lqj`M%!=VYmCJ7;oX_-+1tN49whn4{F# zk)x6u`E_kNEY}c5{#!ZRXvi!W6`V`f&HVF~5Haa!pVYJ6Esy*PTo~ zUxB3jFkB);5K3$n>(;RHH1ZFLk; z+>2%dETQ=2NeO(6ExYa?vss0{6LZAm{M?fga`on<`g$Ij#1x+Q>KRDh^(4}ZeW_~? zCQMpX!t~N}K6L>2_Ucqe8V4UDCo<^|YdAHoM*7Ku5RV~i1iDoEm;$bi&zmvn>xa`D zBcUCQ_KPu2#rovpj+|(Wf!?KIobrtF3JFfoe5yG6*C@kMXR!t1r#@LVz+8tl??%iALD|QJ8USl@dcVblCOuaBG~}Pzji)bFY#s0XG;}gP)$)?3IB?!F|cr z$)QAFtR@S95L?;qCW%C+U8??J=uvVYcGbAjV}Af8q1J^R2nkM z%NP%(DK|vROxY-XFnh5MOJT&Mv0mpSTy-IdSZ|2o^EeGBo4wjJw^*-)5M1 zdoZA#o;yhv)&-=cvA7AbaxX*YeXrzKZ(v{C`t!g%|2v1jZl)&9wcICqC7 zGICs^={wAWG9KRzKS|<Nb>vbqkXA1m31VwNSN`Adq4k@KFJ_< z?Kdu4%ikeutL`w6axmyqN*s=dcAf!D!|DVsP;9;>q_>TVeCfx2sWbLfVqD*XMYuk1 z-&y4|EZWuh>zfvNV*y6^=6$qaIgUwN)-r1N#RL0H1qVXj1&nI{|&CbL2v zlfsb~v$)r-U72|S(iA$d)~?7fgx|AtQ!AFkJJy2yjNwV4d#!xSY2!LxzEd#&n9dU1 zf)=)dUDIe+(w%}}R@*7GAx}NZhk9Z}CkRy_{1#6!ssd~Hy|nQ6q1ebRwx0imTc_mb zu&Ioq^WgFF*x2zhxz;>}OBgQVBXAEDDFFm5Z_R^eZIWlwjICDULr@XswiNyC#1Nwj zSa&69-@aBE7K%QK2ur1xY+4n`gX+ui^wo3Q=@bu@yD%1{WFPyLq_f|~3tmkQ;_O!j zmT+kC<+yAj^mYod2RQkl)YZl07|1E*;F%@O4E(W8_Ir-IRYN^Pe%M*#Q~!&CE6a4q zQ>&!;w+tyV4~X-f0LY=0&C4<87a1R|_K464wRfhlO*?mh()O^a6_mV^<`7&;sA6FS zbeV>wAW8_Om8Rmaa_g`PD~>6Z4s{J=UA+*?l${IHXSm=r)0VXpCrZO}RsQw%Nvgwr z|9^Y;hgR2arv*NkoCO}b{-?V?2cw6rO_8du{R%UNZ*Jo!iYsy$YXmx2F=qZwL$%5@ zTq7M*Ql~-Cyn%RZ{&~s!<1<+@#L){gp@_|<_wTO54ING$A14G<8 z?)-e@1tUc}kkk76XJzLIv_Q`^#lUh2`s45DMD(E%Og6l*sUD$;w^hr&P(KL!zbG~g)z=rHgJ{ibBdCqv>zuTe{04H4*?xeEjP#jc** zv0#QV5eIS!nq>s`01rWHatv*VOY*ZiGY8qKH=}!aR*DGpG*y8QwKid`9L!p%z@jB% z2m89&ioJs?vMK?&8}$XI3Yw@_s``KnaU{^L>7sqQQW}B?gNG}bvREKn5X%;OiF3M^fPej6ucEmqmTl_d^wcK{-vjo;@^KkEElHwho% zUheaKwYiS-wrKWjWDj+*Sp1aex!Y#ft0k|Bv=#49QDEitWE?bg-P9`L1e;Hou((jh zM#8|KyL!xv!DfXsWk|jq2GR#q-Ok7mp-@G@oo{DhIBT95HFBE+do7tVv#LhC#c4z6 zVh_F{g$sxYlG&JqYx+-eDWbz|PIGhI%v(2AWWlg5y-N06t)9-G>Rnc8hfP@!>gCe|A!zC&#K$=E;+ z0gEbsS1#RRglwuM(b=Uk22sP}`sOb68bQTgsQ^wrVh$^MQqqheua?UD9Bf*(y4hfQ zvN9Lu71nS50A7JA#Lip!r|beNuf`1FtO|=3O7bG=#K&6OSQ}sOa?&E~tn8k2ZGX^z zhgX@sQ_tJLpB_5!M@9^M{nr@Mf6WijcQUp4Z&L&q|NhySIB7M&j1X`c+!Z|I>$b+G z{l(P_?~Z2$n)ydY`jDVTNtL}I0guM`C<7G4fe``f zcWGQ20Sqn2om(U*;#&OHw1D8bpksY#xP{9P2xYJ@IMR}rQi_}fE#$`iz1h+e8(4C; zd5P!UX8~5qs~jgq`A1MlV-a9}rPj_HbIgLIbm~ zNpLK1r44D9I9UcyF@?`nPP*087K#qNuYNuw41 zmUMjfJ@8E!7silhtVEG#lSoGws(>9O60KAj-`uiQ&;ur_j|tlUV@|wNow1)B!@y7L zZ2P?r*bC-8V8{}<+WHjFFo2OWSuG%%{HPBYLAADDajfJ8#@~qzXLJ-^0ZBf ze0{!^Cme0mo0AIJ#`5EqMHp{kI?d(G)G-wscndN2qC+1g&E52HWL(?!@F$*`GVr)^ zjCiyPXgwQ%yi*>S2bt3@4ws*EnRL+d!60UQbr}5y#R_~2B2U>X>u*~`hDgIs53Yjv z+UiRLDIA;$S`lUyXEt>sOXPZ`oCl|OI^exG7g#EU*|`xcj`V!m3;b~7s82fa+;&Wz6U(U2okEXlzG zyRQaJJ1vD|ovtpa471QBTg41q_b_l|Ic+vLKWVmJxC6226EU zcmGifzgIGiWK1o=luVq>W)&n1Bp45(H|1n05S(aH#X8K+?(q1oY3;6Y=!^^nS2x&> zUy8=2?>juRjXRq#D`2+1p@(;axUa{|6NDIoZP+v!ZhwF^Ya8|n5qV@rmJl@o#BYMH z+)g%fgP|UmnlvsoZc9?6uRee(rax3ZiaDDolpQf!GWU1( z-0z}a4u0t=Q5L|_uJMopIzx*6fzFKhX`#+HFeCV_WP5si&=)tOUw%30rOK1hXNBo= zOU&#mLOmT};^8iJ(gWByQx#=ZCXtfX0mJp^uBUTw6Iien-70v9Cj2GW_DA5 z2|Ix7Hm0e6O>K&`vd7?2wPZ{fFL|8jJH_BxzX>#11}POhb0mzz%@? zwrmN)IW|#2XpIM@@S2nkW9^#X{hGWFW)Y%=k->->g1@pJKp08RzBk*BW}x@oC-fl{ zzt)ll%L7+!F#Y9g1ZbO`6`7po`e6ALW`=^oPfz9pZbWN-4 zIm3)+NNzIj;UNv0Tr|u418XD@DrsA%wA#A@#dDuTfs*k@ut#Qco&0q5rMfWYg#!HL zmHr*q5hyYao{6$_Q>4N6-m$AWhw0yGNT$YnzU>=z_DUbQkNtuE9mSJA32*ola~gQ` z+nw8(Ry&>NEF&G9H2`~D)LW7ga@-`O*j|{d@xPzqSTsWN`nys-S$SwqgKl(keMpasr zCt??cRGVz<`@YLY$vjwvX41iQHQ?9+P*Gx$NEi`m2OYn^+-~9NN6gcFNiwu(0tmcd zIky03WRh0CqR@11R3g~(@wV^a8GW{H)!|bqA2+M=w}G~W#r7Y>AYDd;p1E&(uQGwM zJ+cQ#Yb24P26g=4(dpqcx(I1sP`rDXX;Cnjw%uq%KZ({IMdCW8Z71SQ=iOw|1ItDr zXgb`yL*7awELYO|c~skQ{8$Es^maVj2V+AZvRSwS{K81vS#?B_79eK?_Ae!b5E%uL z&0wXC!1YH3g^&`-x?*$m(xJ*a4Y782jZG)WogeW@{GZjVktc5tnEZ%BWAUTr>MZ>F zEk3er6!3D++h@Rf^$4acbelv1JK$HRD|2nS*rOnAhwVks#q*gL6ut%?R+bvsD%d%x zyo(Pf3IzZ{&lNNFB$&MeuMLoS)8+YHzJc?}tKD^o{lXS(8c|GHbxW5+)`Or=*_Nvd zx>z(ZCiM;_+D5(a6SCMnf@As_@Y!d_{fSKwNG@&yj{u7+9K%ihh-JU<}u(cVn zL)1y8ju88Mja_Cz4NiA{S=e!#mMwpLcz7euTEdmrk2}W>5KO}kJ#WZ`j8f$?h`bbt zTDARsFSb~}U{ZOKOM{vIfH(U~*Cx@y*%95ehx-O9^~BSZ-eLcflqW|E(WGkR)z;0$ z{v@Z*UADKcHAQ8ORVzbK&tHbrvjbg<)$QYHCk@VfcEc)C#hIMRV51IB6C?Nt7o;WOVfjyz@1*4T)P-&`bbfc3MQBXGW zqu#}F9Mw6BL$%imGwjmmc81Q<$QP5?8*1M6y6G@mECiie6h+z{uC5+J(I@+net1=X zY8D6NMC{vxg&OoB*wK?Ny>fFYM9 zlD*7lXF-wRn2oM%R&*9?7Ur+1fBo=D`H5_7CZN-FYv}=5{BUSJ;e+$_cDo|Gc79&W zzq@ZDoaHM~&C2uq=_Mv8KR;XIG5-<Jz>}X z3U-`-PnG|G-RL#H&`01juXrc2@foDN_SbHMWpplk+aHOo2l?^IBO3;Sq@#xr&zZoH zP)h5vO2F-e#`Kp6tPdc&W)1BZH5D}_f*($~l>NFY$&NYa$a~1MLJ{?n0x=EGA6qA^ z7}bFaYSftp1lu_rPy{Py@knqK)d{jhwf26G{+xfPLGZC!Fd&q03nb zq!Pl=JMD9RA_2Z$_Ca&JCGkGNqJ(n3TnST$>w3aYlm2K}C2TCht5`I!7dG>B8iZ_d zWnfFm_<}{-UKBA8bd(}y)tRQA3xu8h!>G{_9Mdg z>8yN+kQXQGaeL^fI6SxHqq$+tRVAYIN9 z5^@1p^9^u8zT_P@sP!%JKI5&=^UO;P(zx$`de-L>Z}G zyF5Q16@ecWs=5)H!Xy2jD(xPSa%mes@L9oDr(c5AE(%~#lqd)eWlTwR|S_xNYREOQ&_)O z&E3&@QTO_V6nyiHYGjd${$Z-DY)6~$xAEawbm-l!wte6%1+p6-55JM2_`Yopl?2xm z9pTfMrh9PK-ZK7KKz;SW2P+)UL3i|A+2E>5>!@?%HV;+* zqPwgE+bMMRDR(h(PG3b3IOC4jJcvk`(V72 zggdww^}S(K!mjCrawAi+$E0+d&|Czo@yV0{)Lpw}47sswl1ab1g-G8R{)z&6;~G)2 zf3R?SRzGznI;0DO=yevb^5Yk z^1@S-s=i?w7N75!hDEd3`U`oMcZSR|3PriO z+{-t zGvL}$!S0wJpxeJoigHIJ!mw%=jt%dbtd}eT;ZFG={=eWZGSV(w;a_k^4TL+$$l9?~ z@O9(a87LjS98(nOn**y*y}xjmskisWuEj`bQC|P^lxS60dv=KE7lgGNnUIUIT@UR~ zVZ4{s6SRe5hp;WXg4jPyQ|Y|hHHa8pzIP03%Szgu=OMht*zMqB?O_*(NM;AG`_fxU z+l8@jnb)8@vt*^o>R2zQRxkXO!XW-U&dhMyrPGg9%`L}GqODYCrKE`<-iw*t<>C1y zWd+r}4Amt|^+y(l#N#yumZ`=43^khOoKCA!ui&*kdnT9umSVz}_WCn(Ajt?(K8~2c zJ}bcDH|6>*4(tm%F?C0s85b~41(Qi9di(5&^18nFI9faH4v0q|M}Ba|Dnxj@O7K;% zQ>dJyCp&7XRM`3xTAlfDYe!D2G|rR`cX9dgmcz!H*56&SpzZk<6>#-{64+caj|#+= zM+29mImt+4?|QRlIE(QVC#r+t`6DLccE6szOzq|T8U^2iUaSsZSES| zfs1&2^v;pcgv!;DGP*E(>Iy@z8Z~d^KijC>2p1BbT_P{76hbOXv(~x2+EF%eRG=0V zeWj{mO@uMKn_KavTlRIMeITE9hwTe}R>!+FaS!($R5WAk6j#@|8EAsYwi@*@hIqHW zbbRHHg1`F($tXhoE}NqeZ@yNWW&qhfFf?w{lW-o}YE4Fst<%b9gjKI<&aaxq1XVudLU=w(#Q|ILhFp*nOia8Y%2lv7J(c<90p^1YeGZSyI`m%L}FANIx&P#kP zu`N7+wGZ}^seJwLO3?(89Y0^wsiYTV;lrZ!gcr`&)9rFyd4bP^8qV~4X0wF><&GRb zEqTG{-<0yX1(St#Z=>Zqoadt1ckHQT1kmLmVAf%*b30 zm7r}-pz9MuEJiS0kzc%Ed)!o}JelP@Y03KqqHW0iSp6f7yWPqe`-v3vVOJvI9P9pe8~vE%wru>1c> z#ZJxoTv5utQQ z9CW81Ib6nsxDfdE$^?w>Zt-Gz6hw7Ez;07qczVk$pdx>zaJj)}PMnaemK+i4+4i!0_3=Vhrknz+$8mZ5K88R9F=|rd=k&X|Fk%tRARL zKxP|D43(J|Cq08h?CP@;UI^8*5rUnNyL1;6{ASbteOK`F!<^k6 z{VEZX&k}>tM=Rv`jk?P6Nan@mBFl|3CiHfoO6ME;2V6M))iy0~30Ic$b}M~Wk~r5v zF9FHp4!1*^`0t3&+j`*g5*BJ#5tb*WZAn)bQISZeC-O_p=48ll+~(sX zJf};SPb4|p@ubkT>yAT`$=$D}l*yg1rnm{4@4#Z6+1D!fp0%P@+u1hno{9DyN`RR) zf%-l9Tzy_x3%~pyzD-Pm^*gaKW;UiP0_lYHmMT{j@51TwaXo5#iFqiB| z{%&0RdS0%K6JfW|Jf5djmS*9>K-h5xbz==g~ zi{h@s!Ip!qNaD zzw=75{b)rUTAK}oR!*TA)+tQ1!UTz}Z;Q0n05R-N44;L{St4c9vwTEMLdZq_#Nx|eWAy6w?@#kv|^g4#42uu@>u)st`=Q_%{O)(M#2ge)2|DH z&B4tfQG!Nr31?x!M=xuBYOKK=cP;xARgwuXee2%{YV-+N+(mRxsl8s0w96WbIqX+p zU56P>ptD>t*W(B#vM;fj0_DPDS8nZJps%FkRA_2t?iQEtyj8%VKV0?f+U#W|W9O>s`I6|H+{J^#_MoKLkc zVy=F#kvUL#CK7uMmFYRP+TD~HiIAmj4sLYqk-L#4!8%2w8T%R=Jn8Ba1+PRY>m2UF zk3Mev;7CB6ldDXy4RlMO;_1eVNHhhjZHE)T@5@+^S=*O=-ry@NUB>ePK8@eOedGW= z3M(k5y<*Iy?2O$i=g8U!p3Rr1qKQ2p%UFiXlT?q)F3U6#JoIc1(E>{|O;2j^m(UX# z{RAacB${!WXdxVM)>#c(C*h{lh=V6nZ;@40N7z(Q8MxD_ZYCTZ5Y+rKIT{tPX{jLWiW?_>T=5>^gwlAyU0QETwtYI{etc0^QqfX7Hwu1>-l_a8)IM9uDUo7U_ps?GstPDf zYfA_byLFZPmV;FKUqDCxFQDT*Kk7r`uBJh{wE+U1&tISm$ih|JQ*{Ui&|YBfnazuV zH&bb5?f<`1tIPR!wK}H${}0yc@cx%to$3Ent0O7;WpWAh@k!u7Kv4hlA*{Qlor%4> z^Iw|#^I!5ue2Wb-fQlTHqFif9qlpydctJH%rL7Oex-Zt|cE-QwG{nTEnzm?0%3JtJ zXLa##&Dp-cVZCCSBOSiqqG&a&*gDAmABY?^x&&Q<|MW*_k< z0RQ0;pG!ehpGEV4bryVTfxR^)Qevu@{w}?z(gX`1?d4rfPK@Qr)uzAnxw&jx1i>U{qNip@oMrU{o z_UN@vyXS@Yhx$)LvPHC1UX*9HTV$%n;vXh*XP0y6zEyJ3P_2bZQ0Bom^CEYIO6&W# z*nOUwb3!P4vUT>in)xR1j?-6u34(CR-^~rKpcJv^(|j7L38+-JOBL5A{-G7_Iu6l( zKPcS-{v0lt#I7Ed>8YX;e|IdQWi|~N=Qu^@!^gDFGN2K*Lv??f_JIh26*I+q@M$T{ z@sCjD6}TiX8Sf%>AV^5m1&0G2I&!^EgYPaZ(?b?g#+B_^OjGe_L z)_Ec}|8sm);f!ZHqQUjcYDG3{C{1lC%MJ@nn&+1Z`Zv{t4zE3jkIrbBUD&J@ z=d>c2yEA0i#+GGaovC&(QaJe>Gu|yK-Yqx!E9Yyy|1Ztr;6zpCNif;3QA9$trl$L< zo+?sA{_T?J+dQ=6TvNjZH^Nw<)S3IYT-vciw+#yQV)<1L93zrBV#e1Tv_rXWpD$@~ z9;I4hmgK!}Rcn35j;gAs*)wHXeawu4d#BXF=24vzj*u-wPC(RB@6DtnQ%#*zjNFyM zV9f$svCOJTl325yDS&V=SCxb^lVqWgD1>^TW;(b&yR4{MBEpy~N;*)717(QXFV4m2 zXO|l;kn!KKc-)1#WCM|84}n*N>4B;NP1i36_i48~Dp}nw{QI#e7Hh&X@T~_2xLcSt zp#Jo!EYLLI1VCb^*-XEA(f9SK33Rdqk6PliPdN{_M<5{0RMvT)kPotAI|kHeix{$; z-vdr%AQRjJ&?sAqEFY*QnWc-EXFBl5r?_t;kp9Lb7ybgr%c5yiv+SsZhng;kuqH$n zHEzhiEVZgFqf|055<_wkOuXK7AW>!yA~kkTVR2o5XgzLm9*Onw*$8#2V8#_86HZ1~QQW1n_j`d^biFJOmh8ZEw424H4;qMUdaV z9m?NCvp#`wAcbbtuWT%=^kXFgoa^{2IWKNK!JbsfZhCKgG&vJOAl;;^2)18NF*|~; z9z(;ka@!Y+sI!9qegtaP3INziqmxJRReIrNIYQBVa5IU35C_24?8ubaEzW>V^;$l0 z{a}hphk>XA9)bAT=%7VS7!*WNYlVNjUd*VN2z}hX3Vy!VZl1KQ2AI=t8CKeD&(V&j zzAB1}+Rv7vKbCP?(q^6Q&(r2yt1lS`K5|HAIc=>eFB)&Jkq*N`+Yxz|Zi2ZtU&?84 zmj3NSqyLXot%;<+$1`6eol>Kcv z66h)@Zq?&w+tyR~pU*jCU1025Z_IwACge@x0yl<;9$yv`rclBDrtOTbFGG7%RoPQl z9L#?*Vm;P zYHKHc=;I5vs?X4X=N2JRL%guxeyv0ML7yCz_$&QcQRnzA1U!}J5V#=Ug?;=0pLP(T zgIjHTkBox+y16563h)F}>KXYpRyAAx!HaxdbKbL4#}@8)GQZ1O!{)JVeJ`pQl0e5{ z(6c@}iF8$hM9Xg6`pWj(eBUkY=t6lge(->C6ls2w?B_F}% zoe=5bP3Hc*GdtL-UhCD*&Qw*ihA-?FwdP~WeagR9sUO@$K_{9n-h*Mdb%kmsN= z&vFm}$fkdAb${T~fqkyN$g?isCdxeVU=fIh()xrg8vhzSa7d{+H2yV_+B8a}@Ck^p z)J;|m0H{`*Sw+R@Qhs3xYLRKO!dvL56B7&DmG>HkIx%^uxnLVWwqIYYkG~YUgU5*& z#%wBR+LcdWpE&PGw)hochIwj|j#}@1stqIVTDJXHRfz5-W(?b=q||4W6fzTAi0iS1 zseCs)cP9E$dWp}DPo&09I&ySYfUU-WV;9#$1d|H@oBJk0eRE>(*pyLog^NUviOZI1 zIur9t9lR%TW0M7M-)gcq(@bH!)nQP-ik5VO{n7HG?4DOgNVIV?qe z#ARCCDYmk1#2<(n$z8M_^B`&cU;{ zxK$oqGko}K<2Fd^8y}!IZO`_!(yrnCvN~Ki)0UUp%VM?5$VrC0W1sj%phYf%%>qim z9(M%U9g8KdS;2zyj=Afj8RwnyhhHGhdr$$??Qtf68H|O@<#ZP3qf3-+dTjcd5N|c( zk)I>T^lsoGGb&~pfe?!AxI1kBXYrW~gef z${z`h#RA2QPsiCd&13phqOM6Fu;S_gi6jYAHCE4ohS2RMV;qfV`NB+|6{nJ^QG7+T z?dK~Wx>5>XqwM@t+&U0o)~}ZDWj*Nn8n;s*_LlN=_oVH%LKAJYdn-Zhb1b$AI<&t` zBTqgCsC9!ND9^JadZ^RGZ*X6;L+j0e6c0F7RrN;+McTQ7StRA$X#SCPDoY~O7ZnSt zq@^A0&?Ao_@xF!jV6!^Pb2Z4$K=uhf?#S8gy@=O^uNn!an{uEZQ<&^kVV}F<@A^eJ zdQgZve+y$DA4}u{uYl@y>gsM#?T`g?4^d7|d&IJ-E4!@w^C!7Px;(6d?n`qnd>|)hO4iqHnn5o*&0gS z6`e@VsJ<74n7FLO1f7=*68Hx@=^0VhQ<8O6Z}Cv~oPcHapq){A>ti_tsHWZC~8?A*8!YKpN?8M5I%?5s>cgmIgsUkrJdEq>&Dhk{0Q1kdl^qHhBH% z={6n3JCU3qtGB-F3H!Lo`oC> zq*0$NJx%q@Qo6DUUdtmr^V0G@Wpn%qd6H`st4!(oh_|R2ZJcjMr@DUq>ooXE;pm^a zT~+@#;pk1%EI?miKM91P*)CusXYlQw@!M_NLRe8(E$+q0{T%Y6lv?1xeUnL4_wEe+ zowr<$&+ywzQB+V2nFvkQ^HZwfF;q@CVxnYZ6R3-$w{`SytQX6q!aRL48x_P9ljXzA zV)~E8)!s&bkI2mbe2SGLO1u-by=Z>WQ}^g{o?)f{*A7SegJ8+g?xm^1XivjlO=2^9 z@eEcEcd$!&`WIW|sAW%nhCSToq^#$%3Wat-v7Qvm+)xz{8k-oOd$PHYl8Mpk^>2pB z$PE4PfBzELL+GQ%MWFSSml`YreFlUmEN0H4*9Zz+>AesF}7*uSta(eJ_3aLU=PQf8k$kY+l{eULR z7Fvs;`2*h|bXQ@g#kQxz3~5^vjuA8Swkv_a&O#uX?FF`q7P6=p$fON{EEt_gY zFYG%^7)>l??%n`j1K#2P1f+%*To6oWzSKpnS;yhrsU)9~k*Cs+O=f7T*MxcbXf{My z(RXYIUK2dL-{gO;5j1iS*ZrCH) z03ta`j>lN=4SWC^#9YgWM`U-n=*N7~vU6M4R)`?iH>vHX!oK@$W^0E$wc5)Ldo!zQ zUNsI8HlkXvgkt`x(r{v-a7MNv+z_oe^kdW>BsnKZi_+}}HA6W@m2MKY*NCGrtme}3iL!}}3^p8rVD z`#aFeK=woPxFWQNoum6$ut2_b7+L#}hC+C=yxm?j_IxaQ9w8E*vxXXZ6YlKJ77K@BZs{LtO;d=JCEf{QOKMH$ z8*k6>zZE>QR+?g5pK5rvUAMs5vpve&NK8|;D8#V?<7Ww-#^jNGzdOtb|1p+(WcE)c zjm@>~_XGNYOa*qPX~P!=HdujljwjbD(n26I-P;JLNMqO=a(9MnXhC!#Wy5e(T~ex1 zPX9!v8(edD8Vx^!2-0u@v!x*)1UqxR4^F3H_*hX49iM~VKOh*r$iXlIDgRt7!b;E| z@6~2D=TLn~68qamAxwma4yI3JckO+YFR)?8?GZ9OL99Nr@FwPN5P$_Zq{tl#Qg1}ly88DR1V2UcwwAA znZ(|g(eM+MHX>-;}fD9T_I~7Z5 zMMHVlD#~thA7hw?@{Q<4PNuFl{Vv8&ori~h`}y$3`%;=X*p9Uc7M^2-weIC-Fe(A+ z1TuQwTO&FP{2FiKi_17r5kdu82iS5he#X%Uz3DU}9|$9IvSE|c3ow8%+tf&@hyygF zT7ZVMGd4Ts5H+NT8oogEmxk05mfi7MLkbOONTba@6ajH*Gob1;30Hgi8xiea#oM~s(LbDa))O2^_%4ylw0}`|R zc~`j)C@T>fj>j2glgo^2a$l_VS^_JVo2@wP?+-8{7&0BqqfC|hsVM~){50*|7Tf-j z?uojyW_BsYxIFKka@9UlQAC$!XM^c$W)@TowUckvwhHIB-MS?}bN{Df*vdyg^RaiJ z3CFC7&|1kO2UQ&DTuNJ=4$4!MkR{51bCNmiL-hL{2Aidj{VqD(_rpwH9G)=$kR6Sa z?L}aat^VH3MX>3|&!62s7a71Mkr`EooC{ZXQA_>d8*8dCC8&tvq$0m?G$VY;=IN5z z5+S`N-m9i*qLTY$aSyh$D{N*2YGNn8Lvvm#?NCHMAx!-4IrjPdDI#k3#qscNe@*P? zMyAPj2tY~Nu`T4f&H)>ch3|E?I)!H8hQ!Jh^8qg{uaky({)o2XJ!P7EEm3^*LSE#~ zhU!_?{f4mz)f^*_H45YSLTzHJ2GOIn$itHFak(1Wm5{|2UJFUXDrlM}D%?e|n?64g z9ks5kd$|S34RB{&wYD0Zo|E~Otj~=&k(r>D}Nu|DwN%D!2@v*UQ7rDmYMmL3SB}= zxa@<*cuGM(_%w`EJ;~NX`43Abh#3>E836D(i}xm}E)KsVJJCJfc_GOc&wAis7Q+eXMrYFz=Qgq~*4?mG4<93trm4 z{nTm|kE;;3eWN6W8JBQ7(MLc@8V)bBxbUP3NeNJr{(yeF8{Z#1OymPqFUfzcB&Fh(f)x(K6xv)o+vNYm z1t>{b!XP{}aSRPGR-gNG7N*IUdlJZArc0EG;>y?>IF4`(e72(%5CgcpiwI3eF;SoLLflM0|SR2fE z-HL8m0ctzq#-u2xXGm!4t?`GxN?eBUMH|3-tMKskagS{f^&C4tk@%>ahzR6~-Ks1H z2d%r3A=gt8Vur^ruO+1e5T`p$mwTx`SLK>@@UG+kQX%N!c=5W(C5S$sKWC=H9Smq{ z)5krr#TJK$?fYmu#rQ{sKzpr1$VFU5?+*(c-X(;kt>riHmEW<8;IU=oHM$WYJh~Af z;63aJ_f+{|2q;PeAP)8(3ZM?(gI!%!nq9Yd{3x}0-oR8`do4ovQT2}qA@oLsz@nVe z!OgJ8FVm*Di=&@19q=G{p(F#H{9C1y*UMWX1P?%jU?s+Rttbt5(>_~6L=1f##{Z;F zq$A?5a-k{g6Bb5XezJ~dO!bV{A_V8(A_R**#zxlvi4aC(8ISt8nKB4(6s3iT>n2%KgYdhdXH?Z|9mMP+$LaQ_3t+Eb4P&(ZbsxL3WofH^b=3&gs7T~*q?x|yBF;(q&dPU9* zk0Ah|(;r&B6ZYK>x0NS1ipk*6hKm^8AD&UZ%xqc1aMwy6aP^1)S8qwK8F^gS$S2JVkBvSNAdU^V#u)U61~)kLZ97~YpF^A4pS0@T$KNw z@PQEObD#GXBi~-3EN};Oev>Fu;L!n`Ctve#nLGz;_Pi5i`Lv0du<7ZO5Qc75jG8GV zA(2}i5_=ru_U}Dp_$GXNdWNt(CBID-C|7gO&Q2Cv+g%bd;vTEym*H=c@IKaRZQm&k zkZ^8${6Vlf_05;}$QNF2lB1at0dvG;L7S`MU*0_(zy6;!?WX(f)a$OX82M=(vqHad1MJ(56BwMTaU1XZ#jHkbx@+(FSeOt08w8#$(;Y-xr zu%97u&l?Z%QWhsTlTo@@THLkqKGs@=)f$`xr4wYYnpYkQ5fcv?*owDqQVw-&!6*l8 zd2eB=TcpUPVfd~(1G8kq*I^zUk`-0QxV7mLwM{X~=lAmJ zE8pJYKoFG{NfirFGL&I|bpezNZD%Ua)&b2Du4M?@Lh9=yu$fY9wMYFmY5B{8JyQ~` z*SbL#T@44wYurcIX#YF_YZ=DYef~US=1-n&gZc{YMCW?s*S-+(D@vx@l zIrcFEtA^8{@0KKv$>|H(0&3+w3w~wCUZBU!*woMqkHeSMBQsiDRFJL`uuQ7(>)))W z@9UyvxHqOhgQcr1a0;&6s$4hQjgS6=MAoJ-|aPmPwg3&HP2Ch&9|q@KP4Qm9c)L0jrc== zUlJ{k1mdZbuh7uJ-~oyzCX}Bcd2fw5A&2}D-q*#4bvq?$e1I#bfhxb{PN4fZ@8VF? zL?D9iT3C8hGSo1rfx6h|?rJ`&mikQ%`ru$d;#yf6vUII1rD!iglk^81h}^lkJj!(1 z=$|t6m1wE@&`Y);C;<(QnDvG+tc3!N1-AIPhkN*OpLDK}q`gbgp7mlpGwC%5l;}4xaN-Rg4YF!EG+m| z_y>$uB>8}&hk2KychmU~aP$-xyAK6aPGR57a>P}J6Vzm3^FtxEv(o;EF}EE5CK^uO zg+$@>i0n{MRj`UG8J=N7WKqYksCFDD%X3jau2DxDqRH(Th5ZEr6_3=v9@^V* z7gFuwsqBOqCAZaSC>ZAkP1*}4$E_jG^$w-w)2uK*kraGo{~BTfBrx@wrS?8iMMxXg zhgGLQ5+I-lnQ;@))42$IMZG&bi5`^SeflyrZs@+$F)YFYy&vt8ZR4G!b(- zeioqYYID@oV#3;W=My*~&Et7tI`${!ZQ`H-L&%r|GY5WFp@Xt0LWhaHZqT4~QHO(R zfO{@yJ+sh(;!ew%v);W2u=2h%^@A^9$!jCqTQErxY>wt$b{-4Ad_gS~&faC?F%YJ2 zewpjH4J2pWDWF}D1j;n^HF8fH1&hrih>J5-627Be7HfvBn5R&|nsdiEG1wXc8+?x= zy=xwNLOJAgT;0-gR_7jd;=qpr=!*(GQc@^m%W}gsF02&|+YC6RsrGgm{qEoM7E}!W zsz4b=^96|IHM1l2`o0uR{<&*T1d{KD^Jae*+rmJ0E*-t~RBf(X+49j4R-2NK#aD=! zT}awUoC&$LZXm--`U<047t2pMaZ`lx+%@hS93V06&tZC#ZNl)G>#uqFxtKxQTP}OT~2_D@HwXgb6!rh}~ zK4GC~%(bZ`8bWd(PaUdrSIazo=*x%Du%FYcL;UeMP9IaZnSbW+NjS*N)$J2Rs^EJp z___Ms*O)5~2|_>7K*YLUb2atquM0FYd!odtiS&F`Pc@R6pt&EVz%bGcEvAFLm|%=F zF~*J=pj=3bmAU6d$m0*3IZ3hoF>0A)c`tU^P(y{n$;9iBqIfun(^X!wqIXLlFU6~z zu;k;CQ85+wd*Lt^ZeZkgm^}y_uE`g%5PbK{;k$Q0Cn@JY3RCijn@g$z`(qaep@B$Y zT0VYdS#U=Np6;JoBMTKJ4Uul#nt7)B7=4E1i zjR=$rd3Kgo9OV}nHmbkzrwpE_?(<NcU2g-%CY5HQ$85r5}mKYdgBhGQ&&MvTO z={K}5SAE(F>znQ{;>4;};hfxbO)OEbLVj1jcviLzoARANm6R?!?@VECVx!ZeS6AGD zlkon;@j@SrJJF@uzSKOy{YI~570xZZ5c~3y3e<86S*DF(c58xWgtG7K{=u%4R*kiO z5C@ms)Q}9s8+A+?jK1P)qWW_&LfsFBk>gWoqw2L|q2YMe=lJr! z>V?=%tYTM&aPfp5o1l>A!fS4$<~Oy9RwcKp2vQ@=F${OhepD~7QjNV}=V0i`M|oQL zJ_IgWtlBK{x?G53kun+nPq~o%O}S8-)9IGkcI%E_$1Wd5O7DVX?>7Dlys__$aA8Ix zm8W#v)g#D7ib17;ULtW1Rimh2v=%WhPjnlfoR=Z5WS)8{%9t7AKeqIc8cTT_Vn~}u zzwwCjaKXSYj(LY58jrgq(U7ww(@3EuGb!kEM@Cu($5*bJ)-N%Jko}_y(=9Er&Y|lM zwR+yqO_9q8IItGjjHj!Y>T+Tf(L81Q#2u&~d9Sc2^+#bPJlLYwx39OLQgyK9NRr)f2-UI_`2%)(e-^+w{h{+ z1jVa>Tg@|g=<2&^HNh;Tv~N-Z}g=#4zG)?C*WOH z7#(3__O8o?R=SRR-ZoRWiDRB}Ekb?DDsiM`qCXfNInYvl0lIWu(Zi~eOS91c^raTp z`cipO3J5@73e^)rrZZwF9;l?L<0MvAAfCqmLs_TV3R%vsh^j7nSe2K=_4EO?$E7qK zg1h&be*&N{RmTc1(Dc?D^JCNsL%z|MdgO0*#Syxv@eWyy9*uS-BM{D9FcvGOYnf)PI))SP-bv8=MZ{cbS!M-f*g*^|N*6}DOo z-eb;tc-i?D1f7Cq^e03uqeMVOct%^YoPtgV$+~KeZ_=40m|tQM=G4 zh*l?f<11KKQ3Da`(lHO2*+U{&=imj+IRRpAx1i@;LFO>o`3Z45>o1Rm?i0rv+lqH@ zVh?rPhe&UY)OCTK(OgklgVuWuovQNY@aG2EDIvSt!^_Jsc9;{Js$07ZI8g)Y&KM5d`37) zMAo&$;4hk%y05F3-}lew9dE}(Gd4)uusaK2UJ-SW~T)eZzZaZeSPHu*Z8q;-oi~d6Fy9(A=Z?#m7#rH zHaT0evN^SF5i9en+33<&`bRknV7)f=6)mV+YymvZ0q6sH0!pYc{{d z9w3Nqm5e4F+V&O(*I75rIO1L$Qk4@I1MiF$<)nU7f^l~?i@iV^?0CZi=0*a`ITF4%_(+dE#yg#pNgg$+C^s>Mhh;R z&cWx?#?#>J7gt~#Az`SSH0#b0zfVD}eTF)iohe+QwM%7gy z@_9iFSs@X7o{ef1pZLi9g9~XnnE;kQUl6ed0}K6irdEYR>{q7tMN>gsI-s8G@*{{e z)IlT~S4EQMd_w)<;AyDi^o7^%{DoD6xFruU?91rcZvu4vF_Id}?Sikc1?8Pwd6!pwTyx_f@JMF(W@=o5*|7V+UgQa};imw8a0?+SY_Mj^cDrEZg8L zIvX$Lrw2L8T!4v$UB!U2uo~z64(OoQPmj{!YKF9_?dLnnD}vHCliUQoXt@Ne=9RuC z1HFF6Ul0ih(-O6)A~JuMV-;hi`;o{unvB~yP$G&C0S6WY3ekb`F(bb{##|li%Cg}b=dZf#~_kLw-9s0GS0v&pwvmk5Q2KYP>rrOi^jDa0J zl%pLne6UH8nNWD633nf|`9)6@(VNw9dzEm*)AikWD5Qahk6!Kv zf>v{4n~ivC)vt54CU5Dd@P(_>i!PAK;nk$!ghS!7eDLg*Q?hAF2KoCIHGkmRX-s`8 z^<5~~i^trYs4d3mdJ_7S4EMQBxFj(Ze(tia2&rjOZ0{a!7o8&d=;M>XU=dQ$=ro-G z@nk&Ifqbz9xaB|(&rb;Fa3hH5(W`1Ef{3`PPVjYq9K2K=yCrYPep1!5y}=Qd@C!`9 z!4nJE@4Prq031BRUk;w9r+p{j;3ZupDf4TOr5CL|nGxy%^70#`7VR|dQj-!EUj|4E2c zwu~iqnhfVVDg$(CHjtgrlsOvyR6$?BD>ULyMwY~0ChI`&B9)kj&y*%Zx=!LTYopd4 zmvO-E+%#Op^p(+vzgK7Melp%=z^8Hz{=9Lvwl8{+Yvd=q<`%8hhS%Xcl$-EfX|;*y zQ4JzG(bo>#y`L_cQE)BLBOUFp-Q&U z@SGy#)x6Hs#;ar8WNPn!=QsN&QyY1msipP;GPPmYJvW(Jj&gizW|>moibHyN%^p&e zg(7|lk1-&pn|A*U>%6vrLzZhev>Lw;nDaNyUXTT zT0`KSAeU8hY7a3Su_f#LLG+~Rf;2{ldiM#(fOr++uYz#z=+!ytup_BJ-MO2B@VRpi zUB+#*Ke0QYAY2-V-R=I4-C4Q8TPSk>%GB=v%G8SPTxV({e`RW?er0Me##+93Ho3w( zvO2P-_zXYtedhjN%1uALsV{proq&6{gB+IpgA<%rxVcA?Dqny{t2Yf9#0QrKe04Fb z^?WM6hf_lv`D`&d0tm~|IUBWB7C`KdWANov)zD>g4-?P$*|S82fnT9J$|vdZIwL=z z+E5(F6)kIe1M9TLm2~8*rUnp4qOI$ynow3=kMC}a8&&t{wDPgkHNxY5%SNsqNqY{I z*FSTHVv50@gw#bwF5bwv>Go6bW4bAW`joKob?~O!C9cPC z+K*!`|4!A;YmxgW!*ID~+Lg4%R{WEyC9%{58q7aie2{KYJu&_HTO9FJflYnU(M&B1 zPV*C9*HS5!DWkW{!@05Tvz3y~+b{fKL| zS=@Dz!|ZuDCrYl#q!^DN-v@x;bJiEv?^jU4VDyPiuvigR%Aeq|KTn)K{$DA$mV7H6 zO=Xj=$+xz6AfPwx-jK)mb5qt>AR^&#_bcGyH7P;5yPHx1E*`Cj=NmF0__H7v!u^f=eVfzuh zf4USEC(+CvC?EhqmkF#;1W1)HU$0PT^U%=yXmPu%?GDk&hQmU0_dFxySUq;0+%n#A zKH9M=F=Q&AOqe}4UMX)%c=z$$tS%zl0~PKdK^yWiM;gB-n??zV3%UR-xm1o9uOQ3p zI3F+x>H01@5lP!-KEfVIfSxumOvVr$I$e7Gw(|}3^UmNU9ah|qv(5yuxLA2f9t{zx zuGJTbJM%WP^m%v+Win!_w2{L0X6m8JGWc>x9ZGqxNf}$*AR`|VwdeBPC&|z8jS!c5 zjTo)q-O5pyT8Oh2HXYAnMAka^1h(wqQrd3Ig-3Y~o1UOYEhXyS*H^@k+{e66>ou*t zyGyE`O?;e=O|>*vcH($cqI(p0{jQIVV7-xpsCQYO!pAS>aiwa41Y4d}r*qrghes0+ zaw^-Q8h_?3I?GeMZ73KVXl`y!Pl z)vKKVIsDO?L_X(ev|n)7To}(w2kP^YX|pVbgYY*CVm$`@j$*B1(zFNnjRi;S>&=I` z5MVMSgA-8Mzp4~!SYs)s?J$=!?3ecxu6_EFX|XDkG{$)9GB=)3M7JTGt?yN;_%U?P z^M^?DKzF6#e8;4~8?FqsL>w86(Z}>5T>Y?w$2$y0k64sP+V@RtOR3`bvKq1{!u@&M zqGylhLkX<{Ex5wJq?Lr1Qq9Os@p=xFlw;(kDeSpH*kw!y_}9FNh{HJC2|C?`b&jW_ zn{Gm3OUl5O{`f_;FsG@|!sMc=Ed7*d?9{AG;2W!oiRrGK_4HMw+_H7!SeVta5w^3p zV@_7DJX$&&|L}@bPsb%b)mq;!xb>b|U98kise9u<;_k zp~v=C5I6zrt^v}xkI`OF+KLI`P&~zCiSU9)vk5v2sywb#E`+FVV3*!YSU^48nzR#M8ZE1@X#BQ5aIrU*9Dif zw){yU`ZEf13^eba1m*#YG?E+vx(vA`*1bUDF4}TK84q&uPNe+>7#aD__~NsVxv8?$ z9!Z%a;#*SUuQZS)l~VXt{5qz6oIMNJ0-n%0nG0|AA@_B=GcXmX*DY%#?g>Xs!2FG4q;c?4`0)`_O8+{Bg27u;$k!LOE~mn4e}?%T>7Nr`R4V7EyW1C8SQ7 zH|etNYxA&R6|2g+4h%{>=ttk5MXjwnVqgx)f4V)!34j0fn<=vW)>8-UvjmGCoM#p% zKUybB5nvo79hH`YSVb{Szt$OHGIo60@Ktks`jAaeLJt)FYTh2>i23-1Oku{lHV@_z z3k%6GuHkb*&WNXsR38ONU?u50g~e-Yk9H7QBtE=J9Ea8|XX!|;T%>s5j>Gj1T8{=& zQ-CW2o-f?BArEVo;KyjNyOxV|vm%9C!|4R7%{pvjy`AR*`|<3fe#1A%yN7AY`QrIX zVe!Us=I=#_4|kdC$V9X*5a44l7_vBN>2kg((kVjsYWM_q>l=T2lxGC%R^xmr zgXx~4Y`89?kKNxs;3{|*>#6Yi5ml{qh96l=o*LGwfZ1r%+_svdc*+=lE&{XEkehJ} zo!aY=<_O|FS$I55Dp7uTeIKMQ!%P}t9?m6U*`5sk*AEWn!c+IZU_ots0p`G=xXpK` zwg$#T%GR}bxL$G(3i@hBQ{pzEG zqks?Cg;iQfHqJ92iX$R36E-7}14CJlza)7jyDXNSPqF2kP-&_~b{%LmbJ-=$rqvi$ zW^O%)s;XRoO0VN+FZd9Bx;`z}H5z9od4VxllrS<1qX~UJCtQRW(Y;KpegZp>{2kF= zKWYx`pqZzW6opCuOUDB`hGQf?Tho7{S3P zE;L!8L`DgOLtFl59O4qZ1%V$6>k(UW6nEo}4BBP#c)6Tn)Ro(8e0JZo8Bn6&u0Cv{ zGg{@F%57hHk@#cAxG zAzj&vv?|4hBlNK$PKsC(IU-|#{Dd*VA&fNAn{slCDnq(b|NG2;$zqNCFwBlN71GAA5o zOW#iGjVO|;Zp3BCDcIEq@BQM@yTsDYBL&FZTileR2D)lU1G5$e1Lep9)8=*asmDPj zVFtZ?LV1)@-Y_fPRAsoCs%%54!bu=aKz|Gs9{n~vrpX*#7`T#eHQSk4xw$JN}VheX!Amo+!7tWD#6IKHu`j?NAF); zkp6Ig!9mv&#fUP$Qk}tvaw#h$P9o)HxnE!BJr;LP72>#RmtX;pV6MC&7+~X@vBALm zy*_AMZXX4)2un3X^V8v}7oc;8A4mm!4%BBC?L|)*lA26j8`{X|I(`=O&f(#fhu5b= z@ESlS4tJa|z?7L0K_Ilh%~{{p_WxP)pF22NwZ(dp8?Axq!6RwI~D>1l>!kR;)ZqTFQ;lou@HIby@Emoybm8W{`s0=0!+!S>>djCQ7pW5cZiv zM+=onP=8q;d^&q^OgtDA_S&9SZ%O5S11g|)6H%gccpBtKMf2dGQ;RV68H}IYw^s^V z_>YcV>19#p`k7X+!TC2xY!H+Ls%!z+#f#_YqY}P`^4@tnVJ2 z=T3YQ=U`4s{EU&9-P$EuSQys@k}B+t(9flCWm@S@B-S{IXq?b!^HL`jCaEBFcd5ta zZwA77C@emubPu3jC?>t7S)&&r*-tJHAc!#a?7^U{)F$|0dM{m%B*GYenORJHk#d}T5Zy#Kza-;EgngOw_No5bjJCr;hv!s!3GaHa39cM& zw#i0p+pBjkITN-=jr0p(JvS%Xu!zruuseKIF1BD)B2KRTl>LVm!Xqo( z>$*5qn54(*ZzFSNsP*IXI@OYxNM0&@_s~a~t+qx~YG=)V_ybj$FQ1Lz>tL?*a^0;l3z858Tl_H>K@WXSdTW;TK|<(D@6J_wgSxV+3m)wV<0_fVF%zr3 zX<^3~@1hoH>;tXP5U$vFvfb-HEBiar?a}F-Rd!@UM7AON_&%G?wi->>8{PN}er0_4 zd;`-C_^h=Co?)1OKfj(kIXK!_{l7=ppGR0>th|jsGv4PN>7)A+I})^H!k`TQ&@SUI zpZUKVpoMX!F_?uXX&gaPpd-v@#F`^`QxbO6f=H|jVO8rT= zdP6n`IHWv#)fEmCZb(@A7MjK;#JB!j>NNgYX_WC1&2o8EALuo{Gxr+FMs$@39Giin;l%WMc6_{o%e6?h>pDV=uKJtuGT9;_LOU2o=Vw(FL=Mf&ZN@hf} z_<~&Qr@-P+MIZBtft2{hMGq<>;SefQ-u;esYUad6R!EqhyvRmfhSe_j^H*8&;dXJ1 zpQF~xab^qNThC--*qQ1y@vS}DlM7C*$YjK2nAT&#=2olWZK^?Jo79voPTx2u{xuFnOxN$YqgWGZ&N)KC)GD+!`Kh@J}WuaGwLFVmv6S) z;mEX}g_)tUawBPT3GE&lE|u9?edbMBIL-L<44CsPK#BEK8Um65gav{D!2$0)0HG&$ zEE@pbV5;t4+v@F?))O0RM^!C^K{dCQ%EvF8Hwf&GU8{4}Be8}n-emz%HP5M{`A zuLOZ9AcFycfNA{e#VbUyMC?%uS!k+Zakht}5bdI|gR!dOxc_FLihD7#?uf?+GQAC=-Br zN&o@@|NnXw`Gd!>FoWYnP;W4N2hQp>a9023V1?hox#=cz`?OwZ@Vj9FD17w{Zb zu=cF=-Xw+(cr@AobNz3Q>fjw5u=Z^Fo^?PF;HdqF)AjWZ4p@5@sV|A+2RN4h;XE3< zg9Fx{y}c2;=oInZJVr)}AZh zRek`^X;`|01J<6)7E7S|!H%bO^$reLdv-YL9v%nF>Dsu11J<5#9Uc)4gXK(Yf#En2ez;h@`?%;s6=PLZlP&u&U$tSym z1J<6GY@axS=P*;L1UYk~130fMxDKgX(Q@8E#7Xa4GlnCs`5?SJMum*EZ$ zSbLtwRJW7{J3quM;5qDI?O7)~w_6S1RQ+c>Y3z4!z}mBiRMrgm>(0!52M4S@ho?u| zNda>V!FhY0EBWr=fVJmF{pIg5z_ajm+j@q{Ma!2xT}X+I)E27vKw0}JDSk0;^X9UQRs zJY2r^nGM?U}vR2}2WD7Z~H-UN)(f zfaidn=G5 z0vMbBV5(=pW58Y~Y!zKPegFgUAB^e>cnsLf6rG9kzT+MUR0x>gzgMMQTi`KZuhQ+! zn*S_IJNCh2z&> + + + + + + + + + + + + + + + Drawing + + Nordic Blue.1497 + stop_network_rejoin(was_scheduled) + + stop_network_rejoin(was_scheduled) + + Nordic Blue.1498 + wait_for_user_input=was_scheduled + + wait_for_user_input=was_scheduled + + Dynamic connector.1499 + + + + Circle.1500 + + + + Dynamic connector.1501 + + + + diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin_stop.vsdx b/doc/nrf/images/zigbee_signal_handler_10_rejoin_stop.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..9fd7371e1c33a4ce3c0d1d0a94231426da397e14 GIT binary patch literal 155143 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­Yk8a#oYNO9Nc;kK@G&3&2_r8 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 literal 0 HcmV?d00001 diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.svg b/doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.svg new file mode 100644 index 000000000000..708beed93a35 --- /dev/null +++ b/doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + Drawing + + Nordic Blue.1375 + user_input_indicate() + + user_input_indicate() + + Circle.1470 + User action (e.g. button press) + + User action (e.g. button press) + + Hexagon.1474 + wait_for_user_input + + wait_for_user_input + + Dynamic connector.1475 + true + + true + + Dynamic connector.1476 + + + + Dynamic connector.1477 + + + + Dynamic connector.1479 + false + + false + + Nordic Blue.1502 + wait_for_user_input=false + + wait_for_user_input=false + + Diamond.1428 + + + + Circle.1430 + + + + Dynamic connector.1431 + + + + Dynamic connector + + + + Nordic Blue.1508 + start_network_rejoin() + + start_network_rejoin() + + Dynamic connector.1509 + + + + diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.vsdx b/doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..f54fc86c280da050ab9cdcd6f2f86322d643bae4 GIT binary patch literal 160658 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

e=^0c$gdwXoK~EQ0L5!sSfYZ7}_8v9Ymu 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 Ee{`kV@&Et; literal 0 HcmV?d00001 diff --git a/doc/nrf/images/zigbee_signal_handler_overview.svg b/doc/nrf/images/zigbee_signal_handler_overview.svg new file mode 100644 index 000000000000..a71b3b3dc89a --- /dev/null +++ b/doc/nrf/images/zigbee_signal_handler_overview.svg @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + Drawing + + Nordic Blueslate.1724 + Stack start + + Stack start + + Nordic Blueslate.1728 + BDB initialization (two scenarios) + + BDB initialization (two scenarios) + + Nordic Blueslate.1729 + Network formation + + Network formation + + Nordic Blueslate.1730 + Network joining + + Network joining + + Dynamic connector.1733 + + + + Dynamic connector.1734 + + + + Dynamic connector.1735 + + + + Dynamic connector.1737 + + + + Nordic Blueslate.1739 + Zigbee stack sleep routines + + Zigbee stack sleep routines + + Nordic Blueslate.1742 + Network leaving + + Network leaving + + Dynamic connector.1743 + + + + Dynamic connector.1744 + + + + Dynamic connector.1745 + + + + Dynamic connector.1746 + + + + Sheet.1747 + Device in network + + Device in network + + Dynamic connector.1748 + + + + Dynamic connector.1749 + + + + Dynamic connector.1776 + + + + Dynamic connector.1777 + + + + Dynamic connector.1778 + + + + diff --git a/doc/nrf/images/zigbee_signal_handler_overview.vsdx b/doc/nrf/images/zigbee_signal_handler_overview.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..70e93ed173a81358aca1f47e78ffbe0bd63372bd GIT binary patch literal 266984 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

Oze zcVTIZmaqNmzU{?{KT>+%i4q&Yh8rtBv_0}7aPNJ6%<0RE`{>KJS~&fUn=`|#)mymI zQ_dY*Q5I@^UXf2Vte0ErgNMXedlaofO~lj9-RtA$z#Mh#SCoZ5q=v4!B%_+*BE6JZ zF2HIjwXH8cU2|j26sf%2aP%vcPP?UeBGT~mCDf05m4~0DL8r0^Ver5aNNLw6*p&Z zqc!+xVea~+*q0zS^uF`$$LTg()cDo<3W`tu)~zW=k12I{V2mLfSEhVP^bfcFh1(b8 znQ@U}$+uU|`(w@rvH_7%7u^{bk>^o2Kc22XIe0QURb=Z=nqcoQF^B<(f2`Y`kX}PZS?;pUpee4<`r$p4m-}^g2305VKh3T~4Sl9Y zIzJm9b;J!^#TR`!>b?%ndZx5&5zOXgQ-w(!z3gaXu#xFzrUk0UZMLba?Vjy zXm{h23b!f!d`ZtwOz=+KMLEW2=`eG$A4~;GK(x(GxxQsl(8I^&zF-~~&PnuF(e7>G z=EK0w(>aG%95s6c42%y7a%|2|BqT{s3k0_39(@B8qQ;UM9QFb+PcX%1sc}$Yo^&hC zdFhUPrU8G7}qE85AmEhLD&J<#(ojZvXX z=UcR6u>alglDo@F>Db$^>~QFYZzKR35lRA5d8jx_jJ2jfDl|kjT5gySAD4V}tNp7n zVQ{H{VQ?j+xh$^GgN=7wPDv7~9q58MRcOCN4ib>Kl^yFAc%=;#X))V@s1Zo2xz$6( zuF%sQE_In&HO=cI#;EEY3cJ+XO%i16H&`E$2=gf!S~;tKfHxR1sgsKLwg7{m@rq{i z2Nk28gc#df>24eg-_}|;5E6gl#DNnQ0ZJO2>)HpHpGW3{EB&%)DDq;6h9fixF$}ZB zK8ZzryAqhvQ1C;j-G#u`wzNANaE{kD2LI`fLY4o>oJ~ljvOqH~H$oIguweB{%kz}C zzb*@KLmm+I0$o>%L%n8{0(j_*4|Yiiv|H=%6Un{$oI zX%xvrA-$8wh5hAly^31;d6t*O^7t;VrTwei`GGV$7q|fk`=DvySjp5tiv{Dkb4h$) z)TL`CGMdg43KhWPg5O?|#bO%5|5_8U+npr`lfkuQFl*_LF(%1|vRCSjY;owSkhcGH zxobB_%bxn=er+`4+U-I3LE(et4uj2;*g7w#`+MC{Z3-`17ZM%TX@J&@zl}T-l$Ei| zNExj1Im1l9a%7&h%3RK%vGWt?6c`}&F!>HZ1eNwd#ErFs!NYDDt_xUzz$-I6`4PD% zRZ=ODXbX{lklsRXQI~?9x(C^ET@`=;uj`=^24>oOK`OWa<z4v6>78^ z3(5oS(FR=!`hy#~&c3eo56K=IKiM_eotFn^TU6-_gJ1gQQ|uS9U&g>pi0}R6Tz_u# z$O$Nz(HPvYJYD2Xsv^QP-;pzaI^*t=s4v?g;v_rSWA*Owe953g5N!+`$sV-ozKAW^ zBut%ozP0l;KT;l+(79P5jgZ*c9 z=^us@qzo^3zm(e8P)d=WF&D#1975Fu*}Bfc1vtMH_l3_=HrGr&Oebc2W@f8g`#D&{zo z%}V=8E_x2o4{V%C+uT2zdmMWR%gKU2p@eo*Qkktj*qgSDB-zl<1e0jwdY9*KMn%CX zFiQ+{Cf*sWtUoD5@-DkiDF!fyrdSucCgGz|7}s@OR$*LOfq>%z211JPlo`1M1wzWC zgClkj)`wzYA654Xor&bcjLAWSGVX-5lsEmYlJaHr+cLJ4POKdU zNq@S{CNa6jWFJXJKze}H@+E<`J|VaU3zG?+wlRuv>#%{UdXjdeRBn!pY+LlrKu=SBHCU zMWa?>S_omSAkP+S`3f?0wf*Xx8v4Cq0=v!qr zcc0haVa|Vk)34ccwSuiF9uj-=@`~%}+w)G$!{LoW>%^^BYW4=NsH3E%f+8ni5>M&U z12O<63ObTo*f~}jn0NE>+Qa~hxHqf#ElbN|1yf$K{Qb(7SeS=-UOy< z;z6n?e05~qtzlkUb~O&5*x*k4JgiKc!vxj#ZVoFG!`68IT$7YGT7_~eF=HF<=356} z(8j@yIFCq1QUUPJ2$UG1DL))_di{;1#E+|z!~KmxV_~?|pcpfooFRCpuJqaAG}T=R z#C$w1T0lnLBKB9FWfQQ^TY>o6i9C330wKnfgSY3~phHpXI=#3sEgwMYMS}S%>7ht)>5*48L^wUCo%zQWaZv3Xw_m~}%!_j@_9&q-ELsEa(lU~f zFk>vRSZIj@UrQ)0bY$m{7Tnr>ebbec=Q_Z?dE>1j?ePNd8<@Hc*j?OXg>%(40Xn-;LUfjIs3Z!F_f^P@kLHYR!zZ}& zJuq!)^LUR@EwAP%L2qr`c1TS@J)q)?V{s{GL6=dX!6@huhYEUpIxAYhdKT!*%58aEfO)TECBjhUvg<&jk%jFR!ciAH(PS5&ea?rJNJp z5g9d)4u=Rv^|i;Sy*i2}?E%98)C}A`rnh*-aLz?j>wcL7iQm@lG(e2*emZ_w#HX)H z50bO{0<&5IT>C*J6R|t|wdATkR|InVXPpi2NhwKH4mvuH5)5`-D_DoBwLx%1G%lH4 zrhq}6=etoXuBtvtKOVMn;%d>v79A|VPUoRM=T%S8c^j}WW=-j00f$`rYCx^~=}lZqS1R=mA2`wmDD zK4qIT2){$`s}`(@8Vium&|f)m%-w>?KY|Gq18i#Dc++!rJ>16lfoI_l3sbKKv4fJP zp(as&^r$*OiGVBen)lJ@UfdC})U(kVTgiO!9}LNYDVxZu=rGS9FFz9YYLd49_FGXF zAQza8MS%4h5j%;k(U*YkrOro|%P^-<&xhUi!(VKvkXv5n4R1&}LJ;+K&+pT0p|EG& zR`=Hm#QL>eK>PJ|KiWFEj^%5g%xoB^P58Y%p+dl3lDYD8A8V678Upd3x3mH3E#&8{ zb@#pABGN!G?fuO!2{tp9y5^Cp*qVvj)5(z+d2-^@Rm^Nwt}lnGy>F=4QkFb+ZP3IB z%&SQ*2_Og}3XiL;ec1#6F@kQaeStMdgaM>}BqI)C)StaxdOD-3wzo}4HPj>-73U76 zC~~@0ox6SlGt0v*Y#2u=IZYw?7r!&~pDNoD7 zh{MHmGtui;MwrjiC)fyMVX!gLJ6D2;{y4wJ(>tyl%!yfJ$LcC$>T)#ZrN{jxsofWp zN;yF^WBI6cCYUB1OxRKf7(H<%%Pc8WIqIzAN1r{yPt84-v407-k|-FMjdz+ zR7#iciB{)5QB~D7#u9NBOk~z#)EWfJ9IB-vS>zR38$ZkIT#{xo0J@;gszU1DCiXbF zdPBD#|9rXow+y~9-W3GhbX{K_6ZusGVfoka7N6xle&0fK>=VJs)CrxSVuYsgoJI@f zTkM|TNJHz@b@PpHXX%-=^RpfE6+XIkSGNWmstH_r4@dKnDE1i=EAvk`w+i0n!@fuJ z`K>6hBHA~ndHQx(ImlR%(^2!cf@JYTyf9P(D@GG4f^x}t>DJ|JDj$c}sqvL`fwnI~ zWA!k&cH4hH{=oQvw?4ER5nZS$IP>N}*Oe5P^3`|hy7Om$H4Dlfx>n6Pdut2!i=%>q z!s@cn5OUKgOvXz! z{7Rsnz$z#~&?D=Mt6h@WY=^+MBN#J5LeyX)c{243@ia)9dpyfQL%b?pp}=6tJ>q|l zpk_E;%xlHUTg*t?ioh}7ANS`7WaZGa(y$R6`-3_T=sW@UUxTMEH+LV+V%D-!#37Rx z$X0hc1I0hvh5Bi|#hBye;{CF=Ea&t9tikFKgoQ4tUmaHhA z<0WI-x!KJ)Os)->cwwJBdxCeb8sVC^*i2IY!|{WRgL%LH-x9mRZ*0o9N!Gipy1YxZeH7n=D`ZEq zlVo3=w{>@ZUT`Qs8S3}*EI#?VE0Y(=M0&Tzr2(mz7IJwXaVlaf>eh|*SRznf8l z^fR&B0L_)Pr_B(Ty}IIC2mQvu4Jeya{w2?pbMh=m;qlFYI6habOh*&MK(REf-mfXP z827Zzyjz@WiKLAb|NIDR?Qo$5O*#}H8#giJh=_@z32EM_aCj@!vC761=@>Nq0W_P4 z>~oNW1bjusYHaln;L!U26*}rwnn!=$aCi4$H@{Az9@p5GAckayxC<;5WZ_e*f-sUC zHX`%MJvaGVj{+sP0{cgy5eoU}r0AOni@6CXqINi-{#V4i2bE#*S4#*6yad@`V4RMZ zMrs%dRBHZ)O3i?(3eh2DeBKNUsfd!y)RWH81Hz$VWq?Z^I-7Bb(yTOC53+`kK?qhf z293B)dP47<*COMiYgYnL{OIo3u1335G+wma&oFN%S;Q4`Ss-(hs_29mY$X3Ag8si- zv?sx3FRe6GIr{%6_)z1o544bMHbqU? z4(6pozHbwmq(2ro*1pzlWS=edgK)y->^$fI)aXzrE_s`y!CGjkWKTo{)Rv0%Scjh^J(X4jq`;Q)2)ow#KQbuQJEBQCF_Mc65`)9AF=`YCW8v zT=~2}mvi;`aWr_)5(X=`6V@nSO5&3{m+G_OOB9W1pB`EZ?uBeJMY%BcC~GuobcNO{ z=Q(HMiJ%XC1P&5wA0j#PaF9*faQqT_ZYJ@BkWtUn5%bRBj6Tl}|8t~-lF1d`%Q=Xi zwhX&MQ>bxx57QM2%I=L0^kOQ^eKGTkjaOhblQ6r`jN^wod-4LE4k^Fh(2B!MZZvRV zji2IA`fC(UqHPfs1bvfBU2C*0-mIvr&&-oG>{EQFAlj0;3wtuc*aJPdS1`*37LB9* zXsQKyg&uS2lneB)hLJpMmTL0f(%Wgx4Lne$@Z~cz$(33qtZe7bB8iwK+)}Erzew|> z-l(d0kG$CydZWCJUP=*Kw%P8Q3JWaByg*^AWFHh4Pzw}t^-2~#Bs`kS07LLvP>0n>)5vwv~Y!L^%nd$z0{ z3a%>eWIC-WuBf$+o>;2$>`as3a#H330};R8=$Zk`d1?fo5^fG1JCS{Bs-Gg9B)Wrn z&eoow#?Lx=QdV!u6wRT#ubIJ-O~#2O`x||vk}O08R|T?6MapC6lEb312R{Q~1q<*{ zgtcUU#CMI(fzrZ~PHCJSkxY^g$OKw<-7kv&p%Vs;3dhNUq<;cuQwv(eWo}cXxM4a0%`NPvfq^ zJ-EADaF+nV9fCUqcXxM}X_9l!+&go>S>K=C3wlx1E_te++THsVio*b9X**d+#T<++ zEr!W(jImhCM$*MlIe#LKmt9vNJ*D$Fv17~)_(F}6i0UIn8(N}w3%geiRm^3Hiq*W{ zk-f;-d(xN{djp>jN8}KfES1$TvE$d;$sJom`Ss!I!$-MV*@Uf`(5e_k%+XKqfH{#8 ze%MncM&t9Rs3}_qoOo(|JAU90oj58L3FhZ_=eTN{pBu*HMXAku7}JSo zoqIWXzE*I;l}ZwdbUtGGrEYkaEEj!FMD&i+G`FCDDl0p+d!X zy`(|tV6GYR>AFJ$Ii1EcHP^EpcGMmL)%kY z!f$<(gmgE|i!IjgGP6Z%twstz&{vf)gAaykqzS6f&vStfsKUd6i`k*_c#DMOSQOyL zq=gjHht=u@rsHgUk=7XLDe}U|R!2iPoHYsSoqSO=TqbND zD=*Q8hAYIpJU`j}W|uy?yq^p25SSPGPFn`SYs^wZDso189h}FxnM=VkRAQH&A^-pj7|S-dr7;vw1EWX)H6B zcnq)@TP_jYEM(r-p?;mXgp#sX(a7mzyERJceB(E5dgUCAIM|IIp;?E9d zm~O7$<|p0Qe!xyD&v|XR7>jXh>Z?MqY7)kOwL<&ZVyfP zAzto*J2`7Qy3cBrI{upCI5yMWDjX(a`W+m6BihN&4$+zoPF*uH*6A^CtYr9?Hs0#P zyrq<1+NH!;hoNBUkhBbgrQ{flxoR<^h0`ixRA4htg5pq=bQD3N zxUqW`a<}@Aa2tud8dcO#QflLq_Oh}U@Lc2I(-Sdv^~Szn)WZ|4ma`B&(O(KoY1PAc zR6Fvj6pQon;e5fwf2MxQDH1H4BE3E>l2PUa&BtYB`OFcQfI#xudYUy8%R-7a!t(6J?c{uD%|3h7JmT-W7FF}8AN~Z~^V{!e30y#g1( z3tmwEiuNOta0$tx(x3Obw}9csIahOepQvhw;C)2 z^8Nmk%3X=kC>92ucTSlPNJ-727zkh@2pdJIdXQ5oWgpiPq<~PWJOtk)d)rM&x8DbK zih#u*L2wQPj>}tI6r{v@D3!4Q^elO`H?FmWk8>4kg75H$J0o%yM+8kLhbDNnd83RQK2xR0nB2Z9&GQk23 z|Hu(B{pVWj=IcKC!=J#qLhL=0mrZK~BTL3iD+Z#{n;i+0CDv>O(Lp;|o(vTY&c;k8 z^Lkk4XHHkXAzin55Nl4OS!5QtDc+O}g**u|JhysOOC1hUHbsXYH?JA*F;XL9#t?65 z#yqp+@n&^mL5n~+6&gDga@VS8^Ysh!6`pUs&c`siko#RA-csBJz_~86LL*0R7?tkY zU{g+RTk2s6r#@)7LX}FEcLxhRx_+G1*mrOc2#_bfA0QWPMssz!V7~9`c9K89GuFx= zC1Cr=d4`UA^EzeW>S+il{wfZpQeQ4bH8^v|`o23s5&w*xTHDxP_px2dpXMsl$rN-= zVmH4$+A2$` zl`nCEZC@#L<6yz=!`^UI@#>a(5$1aWrSP>M)cc&u!gRkli6J00_Dh7d{WX&g&cTGq zv(K)j$bhfcYto8dc`7vS9nunW_rAp4zb6ZB>V&FV?VriMHj6!OPdFaN!+UR%q;fUG~h;eC;0l)8yJDiK;w-WM8BL? zGE+Q%CKkP*oq!=ZTgjA@@(3QgJrDhMWP;P|?s_=j;2YmQ6dIr_wjeHI>Ww6hRr31(~7OZ=~m`_j=56B1!hWp^5IZ z#fSYSKY08gVK+;b{gWQhmavy^4o}=QLmjr%lD83SKbbVz^;^%mcP6ZcNfH?Mb(ZEo z)#(Gv;Fo5GF*w2+lZa2*lgcj9xJZ#fySup!i{T&XjuVd%taU%I8)Z8e_c9(Kbgn4K zjgy1)41uHXYF?j)6CT-=e&5AiQM9OukE@h(?fw6=F&h{nZ>`(Azor4#A|_}IZ;ESgA_Xt1Wp*0N4a%6y3bq!lx_cEdAqensa0E5B(j$PJr!ynZ{ZA zp|++S7P{PvaoKMvWOHM*AQod&Ar?1x+$#GN@ZRy7uNAA~Bm=+UMW*TG1?jjLW16&9 zAC6KEOPW@*=9eY7AoT})BF`jaPIlUZTH2Uc5M(ex7?ATS(C*HXmytci`|^dRO5KU_ zUyNA<2k~s>uP1V1KWL!eUR6R7S-~0Hknj=6(Ab@xb{EgJa2#g@_TDtnyTM$;h zO_YAqQ-?03u_4@F87VQL!WWZxD1)12?4na4br2+$%i-$qVoAg@;%YHNVk{JW$^gk( z2YEYiZgmBt@8h!^)7Rme$UCdYB+_NcT;Kn~3@hh2Z9$o*4M`+;gWe(8Hd zbjy)EEj3_D0mpThOdCtU3B|9`Y!CmdJ>XPK|7cDkaZGfvMXv=1o&CNz@RE&ENkSeQV)%o zGz#d3srPdJ0CIyW#c_yT^9GclPR|QXe*p1S!dV|$_>$!a6fC^rozPv^{ycDsb+feZ zV7F-Pp)S@(0_(r4^EPA4<7y9e=YmOam(|)_(Z{SV;K^IbT)Hv#Vt|@-nE_wF-tus< z?L!JJg?KX)dLhUzN?c0v(X~=ye0q{NThAYkR!W0k zNwUe9*fkYbsvy!_2^60v#(3l05*uLd5ZAM2rD$0xozzMB3wKkIRT6zl{-^KH9?Res z6xf;~aela zr(U$KlGHlOSz|L-qv9l^q6*oZ<<>V1nV(xKn;goWEdzh;B&Doi@eyUGEl`!)taF}C zE858S8)T6vm+E~_tOZ$2Ry4=8Bo?}}vDSR5QxVl>kfR-Xgae~GRWJd8$q9@pWqHz6 zh!w?D88Wx2nO;J!Ex$apo+^3^b-~Dl+}1AjLZjV6IJBdDo)mVjheH*)i9BvxSVUBy zjdIT8ckJd^X;Zh}{L)j0DP3~xg0HWk{0dbS;| z8+X}g9}D!Fj9W=}Rym<_k4mfb^nO_N2+o5W5`2gJrg|3E5*5E$M`BTwFs!c?my^)f z*8=wUhqcC#I)b~^`jrV0M!m7IYu3gk;r3ENhRwiei#lhUe*$=yAMZz?TkP?lh1euN zZrHdL>Uum6xP&uuOT!*M#3{OIPOs6HXO2Q&e)M(Z_P>Ap!uj+;irX$WL&nGV0Ba5G z-b23sJ%7BGzoPy3!p)zu>3t+ajea<+C;pb2uDnle8yoy`(3=yES1e)@xQU1>VNygh zS#Kh=akz`YyU1k9|61wH*)4+jA zhJ}fo$>dyHyo?^0J)kcWVngl zDeyY*bIvO<;8A>LQ8sa`beK;?oeRyE_K{ra%?@d*fI@A>&CY(GeUg2YcI}cSy&_)c z+^4FdB_gTWmB-7;0i)sv=$ul)HtzmRU^9kNz^H!VUwp`^TdnTt?_}^!nP^~GnUiQ* z!(A1&K3n#;?&op+?v)~I~}a?o=a1B#{tC8QrSDs+8WV93SQ*l8vZR?pz) zVRFR3>5|VG?T6;jB|;tLo2SDa!^~0WCME0P|N3NR-L^`(NHl_VUahz(#iFB{; zx>vCQBf2)T>6Ouj=$j~q#Mdg^73r!`s5hec0$bo1(vu{DQLddzXXX>(+g}A8<+N&- zH!f6dQJR4jV4>az5AYd-pD&dIelRk!Bxdu@;VW0DhPo3wene<%)VbHry*4O)(Pew! z?qzAW4wJSBiT*Oun>dPIpUQ za+2lLy#;$4uS+zN+&B@dh{4Ji38+dn@vbO|zE*ZLrH6 z%Jp)_*>j+%*(PX%JYrUeZ4EG0D8z?5NSQT42ecJJ^Pn7WFFvVv5nIlY_gZ)PhyX8T zps*U-iO4i{1JC7PVH<~dvQlc6PjtLr1T@>Y;*BIC`=ddSy#J6LohOKl7;0i|+*j=W z38OdjW(ne2d$=4@Sr<2`RtEwvC%QmyU)H#w%3Ue+%glaY3ntO2bu3yaO#2AwlQyz% zR=xSlX>7(;0%wk(i(4xO($_Yw<8_8s(Z=RDMaw~-!}ez7jgd%)XrIl$j@ewWp5O1^ z*_tN#09&7v*m!d@FEqr@ub-Qs8_~ppEgA(~Z#KE(v@v+j&b9_g@XYYAAhITg5WXBV zoBv>4PhmcGj*mGWweJB>a)z|MkS10;0pECzf+IVeR2;=}h{Hh4caZH;gw;A^{nLXS z4~_{X7OLP<`gCtWl-!>hm>F^%#i?IYvd})(Lx!cHxu(J66kh8z^Wmb=3OMlzZ# zkE@S|$nXUam$ck&GS;@kUubHF{q8dJQtpTD@Al1Jyj37WX+at$CR|mgAWY+kD-@%p zBYg(y?O&=RXNeDZwhZcTxG|lbdRp^rP7by;vV$p#QxiyQ$Jf~-`@XpMry`FCGVo^2 zp?*4(VIalQX_rPMnVSibUBN9s*j<#uCiM4 z3_*!9?IHAnD@o^*2d6)v*ZB!76wphh=)oO0g)5L!`N#!?WK$h*e;E_I!KT-Q;O@ux zRI-#*g4jd;_jyhe1v@mB1YTjhL0ZXUcL+MP^lD#+DYN0|XQc3>&5t6dq)Hn+O74 zsupD81H!6Alg`1h0@Sq>Vtb=?`UT!>dy!ftP0$g1+5g#vdge9;=~R8~aoe;V&RGr;dgmS*LG2!y^To%AXu#tnhq(flZ=4JI( z;dD&rozs$iW`=??gcr*wZO1%U{8D+VgX4($O+j{f#Wxz=({y=jUgC ztmIhygTV4;7!BBi`wIurt)uG|#IdnWmaq@+35TOqGmL)~Q+5L{5}SMcTs0fY0h&>g z&-K`e9G!-sFkKy!Rf&Fv&I=`hdPVU3a9T8+zhhJRt?WprBR`k!a)1w+8*V*Yq8(+a zgX%=5GDXCBrF6cUN1){-P`Cah7~_h`=IA7Sl(G*EgE+n3rr}rT$=aH1<^cvtp9}AS ztQT$u(UEM_Xaq&04Mw3#U#SGd#Ey}|^qIvvVjWXKN$KC@fF=Z>O+lLR`(FDXXqqUe^xoc*gLSMJ&R zC#}~P4pXf`^d@H)y(cMq&i0ZSDi}b%b$S->Ut1a|zMKYkUFYbLR5j9nk3k)XDp5{W z8f&eDpXcL&mUyZ`eY{C5p3LCT;u6Hv_=z(O&p%RUV>zibc!X0sLx0}#TdG^g4-4D` zYv8?^8DWt+u~W*j2&c?H)mDdM7Gap~(j7e_+!jByNdxf4vZrL4sBp?dZe0>~9?9n8 zo`~U$CIv6#wOab#@pvX$hq5=0pIf+}IlJf8DZ%nhe_*FW3jU$>Ui3S}m{cFr0I_5O zkLJpzip-?*A2Z!Dra-dG)^@@)w(zA~xl=dC`bh{5%qm>V{^IQl^Z$zV0NA^A|F~Dn zFVswc{Gnu#n?vz0ZO5eAnFe@@Fl}F^on2IX5ZbGKD^P8;x|}7!zl*sU4t!vx2ucm& zatZUe^^*u)t2CKUM1{kA_N{DPwZx^fyn~@Nx z6Z=kqLI122S6f66yk*sS`W#_vapvMIR42ti{n|ku@zdPC3N+}WkAXzS?tN_TT@$8x zWd2~)_=WJ$I|im2k1$STw;CfLUl#BIPND42r7x~Y@=8YJqEMFxaT%|FO9Qap-De!o z1Y${1>eFR!8?{U~J5hfmIUpUN4nn5}3bJUeoOx&AnKt1DmRj<5Zl$x*!;b~LCm=He zPVFvn-bJ>0V7KkE*(2R!QFG<+jL~Mkpwt{nd(%;7_z;tFXBlSnT6+zz02j(<8!oK% zk8-O8s5%)N7I-1oi@(offZ|vPA#3Z+U8fMV#fN75>%VUov#*tuc-Q45Q}4ltwVpJ` zmJjrM8xW_oU%wuuFWTYv#RQ&WWIJ~dFqWYnddv}HDE4s}fPfL( zo3%d~BS|97kCf~airZ8+qrt5!^n;e561NSM4GY8>QL1B#3PR%NJz>e+Uo7>kN?e zh`9LX9P_fL{?(M9YkLT0kjg9!wOo0W$+y3g;~Y2M{v%42`mR1J)amxQ_RCOPlK7xJ zNf$nS^2PIFT|;x7mu6;qm$OB-hsbWZgCc7HWifxiu?uafuxbMx+bw$C%BsQRtkOdSMGKVS+boHF>Vy_Y0#E0stsf(A z@LAWpAn&Xh;%)YpLz-3yoRwty=e&A7tOtRxinKiBE|fhwsz}{Ztzclouyw-0K4UA? z2rB80M^Un{(aPIns4+_70sx1z$2*~(>fcHT~s?U)M**E|n|kVSBv z5wyu!thMG^g|=+>+3hVl9Cz!oZ&{(2IG2qy0tGrNFeQx}A;6rz1?QY{&psh+Om_R;nLm5%L&0%>H^DC@RO;ay!agoZ#eEJu zp`zgp$zI{6sEkAWBPY6n?`)cv#nTh?cO?9g!;z%iI|VWO(d1o1bv+0(sOb#>`!C}EmdNaosH|vcB+ab3hS8vhc*=OfK0*r?E9s7 zA~qGmz+O6YeD+@~$Q^Ms#;6cAWA9E=j;n5HSdQ|#o_qf+d5aQR*vyDU?2E zu?l!SuGn>Me|b8-zn)$WtL_`J{tRG<7BJ*NTaB1G@zi@>r`9fnkh*3T%Mf1&xghl+ zjD+6ju@Q}qH?tzYAh?h85N}ia(!jT+f^XY>0p?MU*~azhw286tw($Y98ZUPbaej2< z*4E9L<{;-iY@^^4AtZR4$T5JOz4I(pH>(u!w*<0Px+hJLTv{FheOF*e!LC|~oXVYC zpFj;;v-cBKrKg>GbTfF!XwISID^dtKw|KvEp{^Y2&fh3P^}+B%+dIP~v{^sLY!mA` zCaKs7**|=Dwyb%#qRSV4yAMK1Y*`fC1Ttxk4MW*OmNN1IO%{GXu-viDN5}M`K3lg(UBHHdq*4=yU(Y}Uj zdMdKg81umrLiJ07(sE~{iPG<_8}7xM1n5N&^qygNk*!;-rGV4bo^p5+ICCwV5E1^k zT-JnHRcMHF4`?Q-!Q(rJj@YGa!Hvle%HTfmjVCt2()Hy9A8~{BGY!`5g*$B6{sg>7 zXr*(Lfw%XJ=;iEog;c~HG39Li%`u%^Q^#A{%hn)PD|xBH+#$=<}Kk505_gSQMHrH>m)GoWPuHTTy-==6` zptWR~nErHUB+@$I6mLxSjwNoV%uewFto{_9)VWxgm@@(Kl2@THKJcqc_&Q5qA2y-E z9b5;dVDUd8d>5FLzC^cx04wnEr~uFS@_f>#5mvx>5Z`b!ZWE=`*<4gj8cD;=gnC`$ zV`hRhJK5i2aFObvTT`hDDwsN)El4~>M#|Hem4_yrORkAT9t#O-c@9kqy9&YiHXC72 z#h1Fok!z|Kj8GwEq7p{C{2Pf0!o$Zpam)a$+~SzOjWl~#3nKLo9IoTJIaOtw%&M$M zPI@;;m+YUPHOlQ1{aroI3v&8x)AMZ-n??nxy4n#`D z>1+4J4PrCU+3d$nus>?)J+W4!s657idPJolkCDO$Gl-$|vik{YV{b%+lbeaBz$BV| z$`_aAnW_%VGJ_@;>oC2uYn zOojCM%7b7yGm7R8H-)OXeEgu4A!K$-ucq6dcxi*Ggj6W0yWT%sYb5xo5; za7}@ZDM-(-Lt5p^NINsw>1vknE65TfV)MgZ5gEe28h}LoCjS|C)1~A8R)dWq@K4lV zuB(LLqVJK|C80KLyTo_H^+`xY77UXFI-~#5pbxvPv+G!>Vk4L=@vSl9P~bwLk4iUo)U9Nz!IEAupQCJ%4m zH00(%Yx`(J=7*hfsp>Cu(nZ#N=6Z^PphyZn6yv5G{}bbFIv_w$`q4sB;7r zo@Iqv`>Y_gCbBjgUapNknP4^gz}Q&QaV(^Zt5Gr3WKcd{u`t$fnz90ck19N$YDHAu zVpRN}7)98?t8!{0vDnQ@vF6)ja2`RNuEloUw>I7PgICsSo=wO-`CZ zIobg-!UX|_Lf=gWyJLB0CJp%b-WE^D;Kf|+9u#qUAdZv@d5Fx(arqxNNk5(IJ$1NQ z_ebHNol0{_jB;m)g6(%In@tFe?RGGg=83Kl=Iq~Xv z-K4u!^Wtp#x7Fu|%lh3}HD{(#LZ*QIv9GTURwtF$ywO3L?_ow(C1;gfNH~Y&22_>t z!m?-`*o->oyLv9Kj;@F%xDWl2{l%ddxN-!^iO81v3gaWbP+V+=bnp=paNoTiAm(2X<_F^*EtDOx7J~W{EMrgnsz^- zhQgs2^)0%zMD#7*;kILf6fevaR@j_YzI{JzS?+ZD_`w@1kaO!8QELq0o&~OMzWOK> zQqc`~3j*r`MCMlnbC4JR*V@H?{w2`=$lkNWRRP4XNe0WV?#2 zTZ7#DTrWivk?E&}RrNkd@ET-Dr069dl|zjUl_@KJgvG~t+Y;H91&kI*(LZ5zfe^vd zI@@q)kakPEomTvialGVBl&gn_KLjP#<+m4+Ks&+>Dhc+ z-a46`zpaDWQ61QsK2NuV0D=@%iaAZho`H96AZl6b9OD{YV~^Xx$mS=+j=o~Ac-ax> z9p)x8W$;(3`7(eg{{?_*es_O_To*IM8zMwBqwLrle2tH`(wl(Z3mr=lI>c8=4&#H5kgoYO07d+zJE9B(~%B7Tu2;jKQ2eb z%07jY%zub2c8NV=z#jF>BSQb3po-Pu@)C?+wFZIXs}^PU2vNv9cpwZ2;**&Yx?p$1K!jy z+7+jN3*Mg|BDbUL4yVK>0u*LIb_TSr+fIVB3?=mS^+#xlg-IDplyAXBrkJtfvWo45 zxvt?mEU6Vj|L&srQyIX0Bo7TG`LTcjKiAGka9-;*zP=L%tTYtv0dEj$O9$9_=U}qZ zKtL`#;vX*yS%Mb*gF?exHK#Jtk8)wKaP>=w!@IpL1U~mlIb%NWa(sRAT5A(s_Sw#9 z`})(9py-Y>$#zgKgYR+C>c!jsZe@P**7We*pX|pGjS>~&Ds-@^ z%0>6BznNH|z$QbIu688#Y)h9i{c@b^l*DX|dvZw=mcbEw8e11C| znD1(W0vzk=7k6gvm9L%%0p&4^S(M}>F8Y64>&@wZwlxLE&w~q;0yK^BU`q~*f-J?S zg?G~Ah0Na=MJ`(;#Patb#^7^Z|6^7attvqit{Tqvt)-&|G2>QP3%M1K&%4z3a zms0&_)P4vr|7w%(3*xF@q7hGEJjf@k8r5fxh zflwLC7Hii(M)11!fg}pyj^)4^R&%>%>We2)cDc42nh-H`?BdhN@JE9g`@+OS9n) zjwnpJT_AIJ(rGjdN(jkZ!?##sD_AT+v;K+iey(_+l>721ApgkXG34P|>!Y4i#{Mt_ zKb#WKXdlx*=Qz+D8+<(@Y0?t3_`6K^0qgZ09AbT6%U^bx0dq;FRhw?HcOPj6tz_L(eZo3 z!oRo-5Lfq>8(UYFy%&|LVFRx9fn%bbzM@$yKv^|?9DcKg1Fv7s_nJ^aI)Egm`8oT{ z%w}|IVX$kr2g3iv!QC4-XYk>7?>4PUgt^Ip>FW7Z}R}XSHE9qQLFN5W57Lg;&1~>IY=j-)%ck%y_Fk!ZJ_) zyu9SXn*_@jG;mJR`>(m&-v1YE9!00$$qP!e>Z19McV8c zj(Hd;sh8|{-puL*vEvBEf=|Suhd+3n&+yG&W!K65w|1nWbWI5DGheD2@}pev@9@Z&METXS@!1GPh&jqgHV-ki z0YdnW!X71@a{@d3Ek=P!6A|*?<^(nm<-UEU07xXI1t5Z}LY}g{*>gDFH3NT|IWW=% zk)kbF=UHeM z_owWRnnCb_5rRe;Ib&Q|MY;Y{G0z;gdBko9oxx4HaJP}(3c;ysEb~Rc)9a? zV_NZctqB7-7O+VgC^Xz;qn-F4PO{ASB^c9xf^r1Ai1L!Yad6$glUWnF0$0=7vci!o z?=|I=C!KXZ6QH%-!_SI_M4SWax zL@SW3oy=+PT6?>!?1jC}u{N$@x}hm^5`GHb^9Go^QDTH=_?f%eh{~-P;^2>FcKsoJ z77+i=JtKJPW*hL7+@*3dZo_xQo|5P7p-Auc!YMV~_kzbHQHO-;`PK6SYD=)Ym_y$R z5wIfB2`&*{|2>odQqKn`faJ1!?E}e1p~LVwa8v^%!On~WStOA`qMp7W+HSPLOfw>l z=~11E#mb_vT5r^|kGf6lU#wz|45WPqK-veo(GxG~2^<)8N2R z?rd!iyG^AUsd0+cN00hLq=D0s>wkLSa|8g-%y=!Da_SC{&6BM}HH2~fQr!H+k?0RhNsTA+am|;i#Mb2$|Sz$R^qJG z=k|-Kl2V7>c4CYsE+VJJ8bF;+WC?RVcfpE!TXaA-Zi@cl2fueDxU&Fg*}MK(i?Yi0 z#+wRy``~9!NeoG4eTvUN;i485ke^5ADzLzQ!+pj7i0SWovT#~pg+j^E}W-7;J z{?N}t?A#L=^qJ!12f%w3DNGa4O7O_unb&pG;)cj8I-cFq>o*dR5~4%}SAhPD5}4hG zflUN9MT-L~*KT;{z=$px*h_12O1_>{2~QTHj}nVQKNycTX{G#*y+YOBjMZ9 z2G)J7`1j0a`j0AeD!F%miAg~j+k@$@{#+$Jh<1p5)nlKj8($_x&bIH5A_o`W_Otn} zP{##bN88;+vYv3|WF@LOV7Zj2S^oa0>%Gh`@R%;gzcF!zK z9f-`|Q%GQJ9yqmRTNf5w_587(**R|_wFj%{VENK026eqMRPT5&e8SCq8o5FTCffCX zG+!T3h`CfF;7?FuF-15IVgxUfc>|;@f*H^$2R{g{J<#9v4#FM$wcs$WQ33}vvmq66Uvekx z8OVRTps)E34gom_qc8k-D-7(_ngCpU1x{EMZWsO-%e!Mc?G(MLYp&ieqKu z{DO5Eq3CAlsko`Xg8>LWzGXo0sk$Ufe50CgK6u+tiJH)?*xNi5m}Xc+;2cZT!5bol ziZ*EB**@faA;n*;eO_twbAEdfxLCYp{J$icW3#p3XNJ&O<-y~(RQo#Baz`zkM-rV! zKO9zw`LNyKTg=YhMT}cmHHi2ps)6|~{Fd+kQxUg+F|6K)7G&D!Zz4W+&7XrO=TQwp zHc4AXzDCH)P9)RD@UmACh5MJ*amX?3ECdMDo zdTYer%E3RqCeSPCrbUbU+K_Wxez^^D;xGt3ql7Os0ARW+NK4S zIfT>43d@Mo$0cvbQ{tZa6!JEfc#DmY)~4m5Qk|1>Cb_5Q=i{`=xLu_4`k+4Gfwal_ zssNgclV<$`#KHc{(e=Rb$ma3D=627(^88_#P1CKl+*kL8Ifm9Y0e5#hr^|z_k?rZt zo`If`(jc@-{`S_!Ms6?O#@1Dh)&P*hn~{O8iuUwnog?_Kjh>FzN%hV0{GT&`H#NS~ z3V?2Hd3fxx27h@txR$NoH!1v51EkSoOkIo4L?WFzY|r~A)AO4=o0-<-U!RXRT-}@= zkjyP}%8oMLhsR9Y%KbnUVjok&41q^McVst&`GyqgCrr)TjD54zh4|I$`e3?eq*~eK zHmEwNFYHmEwbgG#eP?*zSzgCGS6f^AGjE26m!tjp#rZLZ2cpc-^!4>it^nZabW=d! z;UqKofbdC2t%8tAUjF6j=#$4g(pL0HBXXlb3F@Z1{rP<)fp7fxS19f64Q`(I+z%v7 zOggRiT{^^16H3w7L4p`t0QF>4?~#dfGm>Yw6|ovRev$S1_v3>t0J>-S%k^D zU!H0G_GX^OWq&wo`%>mSltjFch{Ikyb z$n;3*C|UjO>bF;?R}dR*z;c&PQ0Zct&1jQ=auSwFMHADD;ceLDbMyU)*{%FjbGk88 z(Sz|T?*mc0!+BPE>e+dP8(2@DSGIH1(?r`+A@)mUGrJ4e=E@zGUk}wTKcX7slh4=l z=3TY1inf;$_ve@PAugi4^r-9gpk;!`yOmAMv+Y2Ep!Kn=x{LY~G_O-_8g6d??MBb3L@k?KG4#Gwx@(>@ z&Q@yX&+y!E+Ezy{7Bp$1y^_vEu!Kj7K6*hvL$t1&Z->2Mm3cxwnGrqc2dsa4O}XU3 zvO8aI?2jN==P)wzw?rfJi>J|=v_s1lGc+M#<(K*Tw7$VOAH4u_SQR<08ho%+b>JW! zn#cJr)lRiqCYgqgKGBGsVkXkJU|VRTpYgdT)|--v~mOLx(?}9O7?MtCqBeV|2vW_cAM3&kkFPJ zAVF=Xt{IyP%i9|aB%KWf6d^s@2ViIKM=p~JFFaN!3`-1|$n00fqeHDtT7w*6!m z5v}le%1^oH-r?I|uk}2XR`I(pex}S)cbb?ZXa?;S!giS>gd}8NP(%dmzm(!V$Cce+ zD1wT2l_EL1zoTbR{btSSFTEiRmLOk9Z-O6MPd>lBqFx)|t!?fO&s#RS9q^R1G$BsA z!CJiVIVhVV&?52W2e}I3@*+h>s4xU75B_vxOkvIwq(Z$og6Fc;&$I{($ z#h{E5vpUI-`nq2>T1({UXOT7HEiTHgo>9Uf!&UrGHcK;KE{vJ|s&(B0f9!T5^_r|F z1g$d>1x+@Fi6@P&3cUJySv^BF>KNfj_Ox#=pPvOPt0wAp-^HZN*xIYMk=0DZndWvA zBk;)AZSoy)&j%ez@?%`fyOdY7_J>q zInYCV;8=Cq#i+Zh*U(9lxReX$GA0O31}$C}#x|kQO^SkG`Nbty?1Z@RLxY9T_pTFe z2KlKMvMir`uROBC!@HVHG1-SnpG2n;eq@SenuOUnt@AwmtzSy<*D+aJodSk4eh*XQ z9L4Qi6cGo_@ioKlQmJC{l04JYt+DfI!QYgFKP;`L#Ux%ghu5^Yi=~Q3P?}xruA=pOq1K%Nq0s$fTC)fWx`u$%YQvLfe@GbGn=6=lR-lx#+&;!rmKfWJ} z8QAn@)#tihm9T;=F{GMvcR2ClQP^Ht z0-$*H!`)poyWh3o-3&GZ^#`~hPT*Io9{}vbUGn9L-@~#(ozSOO>Y1>4wBPl7w$#jC zmo_WYCluCNPdt}bh5be;8F*}j5Pxefw&+XR%;4S5Qz!V+UPmK6&{MjuBV{V!-9gv_ zfo@obnvtV?m-e}vIP|Qt%d%TY(mH}IKdMpDg-I`1kV3MZ#Ur|j85;P2%MfI{_rCbp z`wUiNB8dCJT?tn8m19`4nZk2k5`kG;oYeR{NQL*jhm1bW9R8zX#gw)mHP-$- zQ8;~F$H#B8D%ZDc{Lt1cM?~cHvfp*uTz|~)GI{Oj)m9F+?XoOWQNMUUd;Rcm)x=|2 zfmC>Tg8h22?eN~x=6rM8$a96?bGhwk=6$}A=RH^N)g7Y!^}Z_`fS+&INYnG>YvlMV zsK8MsW8vZc(DC}dgSywEIFwJx6`>({<`ToiU) zz!W{HX=0cL8%nh?9@_gQ^D!qH(F|!@SH|=Gr@K)=Q`kHmO0^oEJuypA7!64TUL~iw z(1JwIO$^+G1gM35dW`CXrMo2CgbeTpD-w5s7iAS`PTCyHi@`+X3ze!PI?;KWbk?&O61@ zPDlZTewSb?Ua(Gu1*8Eoz+)!#5*&!l5Yq}V$$xn}7M4Ovasc-buAo#G9*@E>qAE=% z>^p6z`;od*6Y4WE*k}4z2AF4t#AounEYQO?OjsJTj)fvfnv&4(C2&eJ-j0n<{%*}i zE0M@H^)011lI*(6`{rUw2@vnHbb9BX$uNlRO~d#ENP#3R%XdCnohh7E^R0)X2@4Z@nIkZR2e8 zhHw~rZ$-f5$o@2gYs+o!=(v(3smu5@kleF?cY>JV@r0%k7u$h?z zjiUjZ8)UdTS5^p1`8pDjlm!Ax(K3WFg#Mb1+x+2;iBpDzXht~oS@B{0xzm7@p8QoU zRtxF&T1%K;Ttk=O=bw7ho4Gn0q!R5DQi|yxi|N^vHQLw`SmLCv~s!uyrV&(;a z&zuvZPKt|49lYk~5sP%4v32=EOzY>8vUrM$wmoB}YBW50@>JJc@kkpR?QqHxb<}onbkZoEFRlPT6-Qf*K&Xk?-D)m zq$NNxrfRSqIIukT_jaTYo{Q!rtybTZZFt<^6mmswIBFP91Bt9)!^X_XU~p4u;H zYQRzGAyF#n!%c76CARQaowlzo0UvpPM9V7*&DIbzFRhMXDsfs&C$OOCOn zK)xwlVsbVNrlk9k<#D?WI5CBH6Ze3s`89Ev;bzvaJ$_F?Aen2DOu+ga4?EyiQcj}s zQ$r?EvhJXGYtY5l{Xt;VZLL05)(>EH$fbg8XShP_Io z94o%64b2jZicx&t{)xGdPU-RV^fpLgG3#M*{eSWGPSKS%TDNXkNh-E&qf&7ywo|cf z+qP}nwr$(Cor=$_Z>_b@KIcbkv$b5!n_SHId3%4x7-CMLYCeFz;<&Kso*g@C8ai;7^ml#1Nti7XVnu|f|H0XrO z_KveRX#>NW3%aq~iIXqDrca+O`@iOWH$tCAyqd%rpC!R?3dOWU$~@b%ggUr~4evO+ z2**K1zuctvtSzX!goXN^GNs7DPww}v9n4ojWd!kJ5>N=Gq`4-O{v@ihHCggA^`vzL z@Evb2&Dd7ta<=e}FzrI;LetkEyxYaFVx*3I8oVE0fWD?iBR{dbxb@jC2C;gs`qO~s zd(!uS1Dk<4I%1g+()&%;5fTV##e7m45L5Zm*M4&- z;VQ+^h4}Xsr3>F(5u)9Y-VM|$Fao73x;vAV0#%|klE16)+GM`2r#)~xclW+odv! zr*9#nH96O&+=he!{2G^^#%vC+4kpK3?lP-~vqU5x9klL6X8Mb|0>1`6c^V;iD80=y zgfPg&mxbY-FAWLIrJ3KVS-M|>S2{lVS_EcUoOy_1(7cAbGMve-D#SD_P|$A0G3CAr zeJ2k_z8hk2T>rt1+#0jzIFuDIkGJMSG_Bf3?5O~*HgM@DbX(-TtqS%W-hOJsc*>if ztCf|xj{ohvWQPA_($XLl6jt+-K{AXLs%U>S511>Mlqq^mhY1;L;_mz z<-~9{$BBmXyFDnou{=#q!K)Bo*L_7o0a0QxvHXr=lSNOdJUdL(R4k07$hI)*iL>nX zW#1lVx0V0+AHBv;&w4t+Ni zCfPg?7q*}&VC}p1C|L1}-+|Z!o~P89c0X_Uayq`3pFJp;#L5cr=(f*;nPO+Be2=WM zRod?eCITVp??oIxg--h^ePF2)Uvp{~C`=$h;LlRC5YG4^27i!mpTgGefa4Chj}vYo zWLVT;wuOv*o7n`k^cAI~BMU4u_bBy;*+ zx+Nv}BRvOM`n4IDG$82v)Rg!8?S)4i4R(=l0O~9r7PISgUW5}POXR~&6G3{0{R__V z&vqtoalZB%?Cf`_g-|y;#4J8-1dQUHz ztJb=Aiin5j#Pu?wx18rs6W~e-EH~ke^pvfny$!@grn*=mX&=Zf^l-#HcJu)zL-%ri*{9oQzU>6%hN*pq z`?)UXeC`abK-#l(QAHu_Y51Lb^*d|iP9tjN6PFm}n87E&{>)#^G&YH6-+ASD!<4*D*xaFx%Q6Guf&>N-&psd?2Zt9MxdRk~+Y7LLdg( z8{~st0tU;LkMlB{JQ_OMIT+8qp5(Nu`xrcq0%OaR?<+hDWldS)1C%`TOzYhT9Me5- z`yIbcx%~WHa}#<=(>aM<`paWDkCgV2oR@twub_$sp`Q|^miy+)6)13%BTx@Y>c|A% z3w`jDn8M0i&&lMpY_tYQE=$^i6u^t2>mueAMLg-U>9`bM zF3*a+HMazXLhtd!Br=i$LHg(N@~g&~-WIIT!+&lG1~!GFvr~@zE~OnQlFG{31GnlP z0NP@Sv1(wI%P8}>DE6>s9<}-2B15t*XqX%8p~&|zy5|Zy4+3eo#x9+Qv_ZRMtHjVC zBZNk4BQj~HvGe|K0I-q!sE&BUT~tb3RsW{cpTT8ZW`|qMMzf9NqE|LXARV{ajOj(& zyj?}-&L);1Cej%>-&(fes8FC9bxO1@l(m17WR+s3&g5P)5p%5?RQVQVOgztOIePU= zE9rb}hE+oXf&>5w(+s$X)&cvAZ51%hDs=o+$7gxFKUHxY<$@z|928iNMG98m_M_e; zA?(Q0h}%!8dN+O`+QbZ~qLv=*o1xv_qM+Yq{|TajC-`_{*YeO;w?#i>Tz6*4Bn0tr zefPJbb>9u8cOxNm6^%!Zo+tG(M2oUakAbNvs@9!(jb3!dDZhTAL#UJd<2w_Gt^(<0 zAG3^|GV*Eh{(M3Fn)q)52(N>(eyxKr{Vx2bSeG`|4jW_Nvls<(O zv`QK-SNw^qeR+M~Yr%mB=Wj~w;_JnQ4`eFg3RM2i*)Ir^ypa-f{s&xH;oIbAR9#F> z@3LGQ*7K@;hL#8HYEi^|qe=gYnRu4O))jlmf)3xJ?9UzxKjkgcLQ@RE6jEDN;b_JF zeL~ZTpYF7Qa29V>{xkaQ%YVAK>O4oN7P#}bq) zkuy9QV!FB(OOy6@na4FGWVv@v)iEc%Rv4Qs)%ZHU|f^QV!&abJBs40On?V>Lo&n+ZRPX>cGZXKc zhaj?s#45K^alat`qp}Qkm!3g{G3o2<3f9O?lhy+PB^fc$52xdumk+t-AHo={nu4s6 z9tlxNKd;1=9<-UBgBsP=3~ZQ~CNnj~KRBLNMW89v5R4_YRZCHr8B?vu+&wu; zM!kAZIYkv_w3ejSsEfa2+$eOX1uP~EO%Z0+JY>(t{N25wQn27>$t0L+pQ_3VRPJP9 zGl$5{Oq5F5}_uUlm1eV(~`&C^_Ym_DHh~GioW03)pvl#sTdm(7sh+d>adz zR}#kd2$SpFmAt1^X0rPD4TMmIpqucLbrLvgBg)C)72g?JVxhX5U(Q+dnQw*t@#cFR6q#k~g*f_+B+kWalzOoF~8) z0yV&kuUtwd?R}OqnBe}!cuHzhPn58jyspy+zFk0SOD08K+kZ_7nyQ!Xw}X3+u+Xc` z`?VhCca)RU0*9j;eHH=0gZ2VF5UGouYllE*N1|n&w*74Ekyyu+89A&nJd-^If!*UG z+Q&;3F`M_V8Ck5zooq9TnyavjVz!raDT8W5ps~{`!rOS+whrKH4@9|%&MkYOKyCmg zT;_^09(8qu>wQ6f2elFpi`S$JcnhcS?f${shI{R16RX|ay$Sk4kEHwsXyE>9UQde6 z+JpxQNDu($_Wq}fd+dKPp+QyMey;_|i%0PdpQ|07tbSm``3Gv&LM^Uw%h7r`1q$6BMO_X)Om+>lZ$tD`5a12SvWdhM+ zrNX(m2NA8fhk>@30F1z*3t)t+;tLa&)jbrOY|$pDa1G+svVfC#lV)E-U@-Pd7;;_U zv!ipD^dAi}FDwx@BAZ5R!>d1(s;iIAZNl&GnwhSg71R~UcE4>qE|_MpByK7x4!K$< zqZ|B=I@j2X08$ZA^joH__%Q*Q>4jYEqSZmh@GpMoSNG8l`&fTegeMPW(j9?Td|8u= zHBxUgb#uaY9r26*jVW{xq$Y@-g{93I!3JlNUc>bKS0oX6d)b40ZG z3l9{#8sh>*R_thZT;t3dayLPOI%)NSj;O7DkgI#nql ztfG6Cr9z%98iF`kyIh~p+i{0b1$bhjEX7ly!>35yHH|pyEWMb#88r^rP=H6=mNOr*Bd1-!yFRE@ z%xq_w=me2{=ar|-PdMx}=I>w*+{l=s5b!Aa1aNnG1q)6shwEckSv0{gsz`Ykel@+Z z#^Hg;(Z?EL23e^|uh%-P+s1?lD7F}2yTt$*faEtBV?Jr&7So#49p8q&Y@p@vO=4vH z*vNqRB>_Z~3*RL2QAI*}_eSvZWNYGsxHas?dbAT2_)qPR;a`Y$lxGc`=91)m`dvdU zGaK-v`lf!fXm0llH~wCPlw;9(8V3ihAJE~l(}_>Ju2F{US?9L&hhb~@Pa+Zmm`obT z>~SKX$nDaDZnA#CDDtFt3sR|B7~<05HkpGuLx4E z!NlWk1!JE=V=#^EEtUaJDqTbm5~M^13wSs25PxBo`3?g4bveM*{IKOXFlW=&eN8ph zdx&31jY&-`DA%c*ki`_fY{mA}e)ISZou#o9A&l`0Ssso$^c@%>b4Lkk*5JM5uV)rxtT3(zm z*tA&JKbgM-yR1f^Jt&GxguZhgzO8oxpV z=93hg6kIqE#WxdmFM?WMSL^n0;T?LvH(MTzp9HJ&k928&nPY;v?Yb?BzadE0bQGS4 zsR#RIf0v>JC_RzNk%8R~yXwIOr*cE6GXzBRS35~#5%%5h$tp-XbZZ99h&4aw`UEcG zc0csi4Mv<<;~g4P*a?GobS*t`u-u=w%rrT+K6Usj#I88~+11J0$LDo+u_F-auVgDK zeTCa@x=5SRElPRv#2FT#b&3Dkz|wF?7}r9wffEfIu*FQ$J|b`Ed1N_DqT(_)Eeo>ZP~ zYw5}h+DNbMV*HW{__-=rgV&J%2&qTMxyZ6ljyQ7=Ajy^#myy^{==ZWt)&E9N<2^Vi zGa1%Na3I(BH5m{7&Q~Ekz-EKQ=Z?ULM$q4|^EmD@^9Ll9BxSO_*-QV|nY8EFTUajo zWVUygNz|SpDo~o}-kCrk8K->8T!B-~TNm5ph|zc`WB)qSTCI3e*@|DhPxc`p-=Zg5 zB_SEMhC#KgIz5Fo+~ZY%?6IzdSVqn$6?bl5z{LycDa^hpq^8AYDp^1y%mP&ANnDtn>trAlLqdEtlylbLe7w?EV4L0 zI;QAV`m+@!s&3OTT9tbH;0lQr;tZMp&p)KoB~*sUGUlNI{xa4epRWEgmnw?tZ&Xsu zp)(;XXnq-UEV#q<4*BAF6@raC7sRdO#N1}{;b5cKa8TF5)!$&|8F!L;1)5G9cFXt{ zB&TFVl+hiG$(ZZ- z@Q`(az3TVQc1wOh(Swn}hQ2Id9%u+V(@0VI&!^kt7@X&N{Ytf#6k)Cjq5BE@$uqNuUsf>Y-4Fgg%R8#}N8z&& zrYB!j>!PFq)1OtmIBM)wdItwLHAr<1b4^`rCH%u>b>ck8~Led@{tkD7Uej(QC#P zUiRlx$5;coMgrw1XPYU3X8%jX#JtDsEPi=#Jnym>=i9Znbah-^pHTDx>QuSBzpm@* zY_ekG=ZaNwJ*gIHVXe3^IOV8-;lxOp6dv9jrWH>i&{k87X``}O+PTNYu%0oq>OPJQ zzG$s@*&M+jKkving)KNBe7IW!pNjjwL7RNq_P2d-Wa`KD)Z9Trmr>#2%%q9`NjGSH znYTTwsfkTW?J+;QU+``gkXxmh&^cU3M18w)fCd4hw8qsS7%Dg@*}y$b)#a_~YrWwpy+ za=DrIfGr71OTwu6v_p-FldYxa&SM)!a@s-TcN53(sh%nn+cs2;B}bOOUr#NqHcJOd zz5iz`T18EMJ?6Imef$0s=f!O1>B&a$QIA#E2!s6ui{!9_z_`67DDwRatM(S+|#FToyY+=*j@w< zNP=*F-CQUS-&pK;RK4*#MezTyoigMFLvWR+-89+h@MhygICTP{lav70TsY>aXa;ad zBuuvhg5uke8pDGx?xOl?8oF*0p)r$z3YyiE`wx8Psa0qvly-wV7K5|y1E?9T^hF6y z$#PanQomX#RKJ(+y*ufG4ETS%VsyH2U6P`?5JURYuUfXvJo}(^_8?YDPvzD*;*{Z0 zN(5G!qz+!1kX1(DEe0qFh&SW{+R6Hol13N==xt(g*M5P(Z0p7j5n|Eze-`cq3$7y@ zuq7F;MWMU#B2No2!8z^*(4I&G%brH`_0(=ea%xey*6BWG-FndX_zxM4;90Cz0$H5G zs)7sh(zI_YRv36$SAN?Z7i-X0M*jTSzKr67&k21|1jOmVx4db4?uOD#CJ{m1?@f*& zF(1j;81>BERUd^S@*)=^_LQ~W%>WgtVTjAO!ybkH2RK^(s^rbezCmFu=5T%FcVmz+ zJcORHLUehwg3*xSonJV0N84~92BGOvh(oWDvMZVTIZdYk)c%%XJ1(~H%bxtp*n6~4JZwwBmwD_6<7E?;1mPiSP-SE1E&R##k+=> zq9842lyNG>jU-~G+(zW^Y>v?RsGmV0-{E^&0wwK5!tVo{b}F#KCt)SLire$Lo_7&uw+GK)^rxK~CO0MqK3Mh8VQt{zT6O zZ`o(Kky?sDv6WW)1q?^3B2QHwm;|3z)G{UMwNzvoOj&{*gRZ;@Ws`<9dQ^W*7JAi3X=GUp+!Bl#xCf840^`$w{fk94Y)ps{pXRK*VVLT6N0WZk zsQI|vK5O3sH{Ov$zq+g7@H&1Zg;x36D^LrB67ON;75qRrVJzJm3nOh!adXv#TfRc9 zSDaj6zD;(yp0AKBExMJkI`wL#M)ZhMR3U-<88hp;Dibg?Caf<{y7=v!r7|f`-0bQ= z3QB1vXCY+$g-q5Rq}zm;CaRZ6yeR8hbH0j+nQI^8E?rt&xEUlNx!{Ztc+uPeRO6bJe@{Vp31g*y3X8(8Uv)9(SHPRJS*d0} zo!ci@NVG8kn9=y=XS{$uJ2$VUw|+J6?u&2nEX1j)te#FK1*cewXp0NRPTIgtZzEYQ z4ZsY?ZOep>WASKyx5^yBewJO&XCYrhceD+5u#v{j87A*OAz!FuRI&^O%(1ObK~aQOaLc#(6MC+1?^qDiN+zpRpbBshI}2Vkvi> zIwu+2ady+3b^M>ip5U!xYKgJuqA0UIc`jGBGB*5`2vYeNsr9N-Q=Qj(y$J_d<)5a- zZ`U(^4Xt9EY8vt3Zl))O$$};?Hn?!1jTx8OzI`cS7ru13x>d zu!l&^lc|c&J3Ap%pc71)vkSKAuXLJ|pnuIsPY<~sa2jiRwa%^o@4ey(a)62ms5lY; z703UG8I1qxI5e%-TL75R^9f=3%qPtnTWVbzQg37V0xG(pu`ZQS97yz|si}@a)GqB} z@Z;K9RGfu!SlZcl(9xGUDJZyqH{*xE(Oq-0R36uUM~K*(oFi=McWL5(I*!dG8T72O zcc;hsZaV9}yaCtf0#fO5eqUYFS-EAyR8OTqDwS!a2D4RF- zZ#PZ84*8u>`wEBpJckhZVnM%qJc(Y&XrLnx%D?By?Pa+-{JX{ZGf? zF%M3%S>rj)LNjaiua3j{|8yLoQEev}H6u}DNADrbZ#EmY*{8f$g7yZinxrZ2WFT;H zY~@6Y9vYKGzq0m-K9RR$4zWeQwuWX|n^2u~@#;N|=P`+Tl81Rtmg>;6{^W@u#Z8;o z?b)^s&`_80eCh}YqM zfG1p5mW=|-u9Wr@fmH9w473fO4;E0hH0b1^(2Xiw{f1nkSWB-qr`gv}Sl?)IK`MA= z{~1EFe?TLS>2(}b`4>F^`>d};%kI* zPlL96-)>g8f~#LoCEJM=f@IeKJUCai(NX^W zmas`#b#J0<#?NPD9w9OL+4|i#1!6*J3T&OlV)$EbWkD5Qr#261^A#a_Y7#9JL(@P1<^+(m7vp;D1EkHqU{Ae%-d81O{7W2r){Rbck3EQeB&dj& zcd4hWZ;lX;6(zxXQ(~-;s^_Ky%+n6Q7`%OM?-(PxYJKPAgGbS>2jtyA2{Vsx%@m~| zEP`qOcrvEQ4EO6YSb|T>`k{l)n3^8zj(QuXl&r>KBirHf?2C8ibZyJ+A}V>|7M0s( za}S>mE@Rr;XH*Gclga+Bqje2DCWtZtj)buUN|Czh3omDe^-nPr(@5IYSKN0I#j>B& z7SBCd>pCZZW~aN0xjfN`H|p)+%>L$&W|?glhk}(jtS&#$5dF9901VV>wWHlhZa#S~ z2Tgn+a$V+zQcz`qhf;effSV0oW&jL`c9Ti}!FNF05v?X`Tax~-wqv3Z6XlewE+%h1LYP42E52U)(y_m2$z}PXqZV)+g}ADa>hbrhaI9+tb~{#>t>g(GlBC}Oc5g} zyo`bj_h77ZC5RALEH)t(da2@3C-fPbKNp|R8N|WwuLRLkqkY}BTnS%MFDAjl|7AlK z2)?rTx9}*gS@<=Vy;P2^%xQ{(*?bORvQctK~A;H?SZzKXp-eW*TbaNb5?SV&BNHOPMu&5F%% z%uCC2*fr?+hAQs(N5u@q;hPk`O?nm<)tmr2GwJpzXzV+`b;C~i5*&%(&20b!q!P63 zw7w2A^mYOvBMSV_9yusCWPW!9J~W;Fj-5nnE)&nxCZqe)3U}lNqx>sN-o{*|!1{Z5 z{HZCC+d4E{Q5D3?T;cd<8c9>W{czMtYx}yClD{CbdqZ{QB4eB z+OiKU`kfZ?3nax}swP-prd^EDMunB{xoZD+y}|JBdP8-0yZZms8~p3rDuV&CZcGTF z;thX_tOM-%ox}+S@w18vaf!tXyzKsRBigXfAyGXZ$ zw;`N_!R-}&Uxgn&)3gTfT=`XjN~I|rX@--B*WlWhG+NJlyJJ~s#qekulpgnT#xz!j z04h!PzI9Z+F1a|c4(TSS*Nm9BCFfm^4Y6j}b9B)y7ct+A7^TlqbmcnZ(L)OYViV%D zX||+UUamg!q_KP(v;U^2Q7DkOuU2H$_RWsQ&61Gsa;)g^JjoJpDm`70q;|eW3K!uI zc&L>Mll*1ErQdpxA$!p=0VOJUqji?`PSQb&dP8~@Po93{R$r~=xIm*nkJnE64+P2$#b({8H5ZV+v_kMk(jF{}ud7ba>CBtgW+|_#k6@mu&vsK5p1D+O91~RF72l z870hBHgt}&XU@MK#6>~pGsq)Ix(XH^T<{NLxYTiNt)|+$hWVPMD(&AD2ioO)+0fogFl`gZ zdCiz3hEooIRbq+pC@a*bpG|z6cM(6iJ|x zM;p&OpL1NRg~%>@fFyl>V<6rjP&*}1f1T_Aq~i2^!}>!P7H1gC;T63mn(RGzCh%PS zuL7}-pY~UQaD77jm>7n7y8tvBHGpPgZi}yzL}%dvL<1owNLI-jl=c9?2WetgC1cDh zd)1nbH)&w9QQ|7DIjJ#6@g3dc&~>zt4pyJa6}~uSAbRuS;0v+eA-kZ!7ktgQ23`!e44 z0~Xj<+N&2g76+m17R0pC?m%crSgHMG#92J5Nn*sH&41Ecr3Xj6S~Du41+uwDw+rREjGgYO=8DA4Gu zC0cBl$#UG$QRKQsUWl<`E|-a;$#NwMRuaZRDp}qacTb>P+gT0*01u2XQbBXo-+qV7 zZqSD&n0`wVSS3@fDm*U&pX@oJS+Mc1TwCPsx3?%KCi`-{39HBM@EpJlM$wiQqmNn| zHSRN&wgVZ_3AsIEgzN_J!k+Lg-1W6wIN zfgCGJbe++!Nru=VQr4ma4!0rFT)yG%d<~MCW5<{Za?mFna&+zEiAk|KL`yXK!7f(* zPK*&=+-X~fg7cB02k@62dbjXY9t*kH_*k}Oitx=it~@gVHA0d7H}P{EOtL{nDRowd z@UhV6orYkJ98rm+D^Yw!VBu~}hK=;Cy2hL2@V8MNMk_w;oPTV{w{(K}qZ#q@5fH=P zF~@&cU?n?ZDE#{kPSOZhng3{mA;B^VPhLJMzb12!J)Ha^xS;f_O|n*)fbNo$d;uLH zd`S>?987gQszgw>2{*B9Lk)IK2X;2{nZ-kE;MDGRY6Ao#xQripFDf> z5a_C3mJh01{!vHWl6SC=J8M2dNyU~L`6Zu`Mi`l&2Z<*kHwayoG>UShl@K5*BHuNV z0K6pmtrnAz$QRvDK90E0&wjbx%2S7mnsNp5!yku0xU`do8Z<{j56$fJ=6fhL4@`dR zY6Pz4GzGL0qD^S_Oym7#JnzX-hdDE`knBb6RleSDD%2GzDA>8{bXgRp)Sh-Pgy84> zBfLo43_4M)Kma`?d~rNC+SGsClC!1o=0UZtke^b^8kep=|BD{ZQVJf#lHwvx)uiOy zY$kO4?FzX@E117?KtMsE2u2f-vicUK#a=)7j>!4V?OmQh&O`mmI->72f$A7fat8}9 znw6_VA-*L5!XX{|M~4gYHN;Q|J_L=cCIfJ)So)i)nt(n^59_iCQ)*xOip^sXP9JI`rsT z$m{5DYs|gTkWfw6-vGn7Q_y#9`PnwfCe^W$GfeALD_4j6*xb>P0}IA-d=shH;aRK8 z<}_>`DmyaW)rFI1Fb zG5qUq!E#dqc0C-+Yk7MOQui34WIbhN!4Uk{r+JCbYU;EBgoTGc=>Dzo0Z0}8t1Cg*#qRPqZwUF{SmMY3ElX^d z-Txy?{0NP`eo`1g0}YZ*WT1(Ga$U2F0NG+hGfbDPE1vS+PBQQ}h#y~CJtTxuI{#fx zukFlv-2KZE=@8M_RdOz>%v@B_1}oMuql)9K%7yJ-;cz+p>)pW%_XvE-jfB=l?clqG z#C=p7UD)NZ6KC|23-Zw#Srk)Td@z4FK&ZsS+k?2whZK5K4C0VoFQ32wU=Ij?!@o9VE*gAr_wC{oi1mew@Q?^ebi{baH92qH{S6lIs#OkWsG(Z(GMEkuPJ1GtbpUB$rhlmB+PPPx3t-IOWY^Q75*IzkShR|6d8^lnfM$8Pi z6qduUuvGiwXas!Fofd)_>h^dzJWXRH4fG~L~r4@-SN>U$lK(9 z*j!wC4zPnR~gRN4KrI9S`Ku4AL28w<^kJgr(rLYkzg*LF(`H2`zA5 z)5&u+33q@6mq1!+d(uAPL28yMXB?G6;18!e+6#qojn|HJhtF{W{Br%?n-BNw(G?CxDDGElzp^6_WO0|UdcL{E{t z87QxHn0PNm2(wOHO42_Wv45C*`%mhS#}s#fRX7ecs*g1qm&m3;JkC9Q%f0RapFuVc z2NVWoGLElxSlu4J#HBJ}E%NbV2yF(Zczv+&xuPDN%Hq$Yxh$t6P=J~AuA5ZklH6fx46%{APO93;jLJsWYGG!$POEPt*-UzfL=0Ob{t`6sWJPWQQw^2q6p z1a#(El(!jy$Pw#Exm8ju{(_X0CdON>V;9+=RbwKp7%P_rCmgi!7aib@LVWqJ6rshW zVS0%~zRtcngsA?CcHBJ;LaS!|>m3C4SDeC0?B$Ocsa4?XZc2g@>gC0j+y~JnQcQD1 zz#s*G`xMKeI6ERuV_R)7K#B0p^JDIixv6t?J$qvfEGmG6)(G7k8f?3WJL|QJ_eYt) zO+4A{z^pcK=%NS(<|w9o;lmFBBYgO+7;AbLfzVE0A572ybObOWq!_R~MOwuh4mAS_ z9Eg!*aD`^B1S7yl7-(J0e_=Ir@e`)X7;m2E{A|CF1{otp_0P!oe7_$(HSDN>JVO!F zuv5+*^+hRaD8aqxvX=f)w`wPzy=OT(R1sfD)zpi8Q}2K@5f5Pv%ecBj5fOaUB;!B~5Iy zC09L4oP}JKM^{1-j8NwR)*oejf<&pvJ+cKyO3^6(nqUB{fGowNv-+&$M_MK$EQ>=BL zI?&M4;*n>eFXAAp<8%}5biCiLZ1gtwXL{Qq=M1%46s)(ZUF(a;koTq&ExfP!Nh3{i zv+-NIsQ$SG>HQbx7b$41QjK@^1Ck3Y!NAM17{ih0SPLoXuSoD#wdJ$o3FOJW&oZ{k z2XD|1+)X}3=mR8$-+Lnyk9xXp_U97T3X+TigIekAf;(I}OLljD4fLzLE=xLnVMbWh z<0WMx$Q64yRI=b%C7L`_;<8EBOs9$&aQsA5wz(f3px0d352}QY&fu7OTA2kW88~A@ zv6s~ek$4XCx?r@1roC>rCXzHFE^;>`?Pao+W$)^WC$dgOY_9otA-^g;8oNy~RekQ< zN@Kb1q*3bSYNB##L^eW)9c!^D;v!q=tn*f`0qVn}PhR8Y9@knD=5m)$UjbLI`zwof zDHZt_EPWp~{8&R^;T^pp5aHyRvPdB^p+~;zjNB>)keEoeWM9Qe$uAUT`LMY#$(9{o zs1tY0*NpJ6Smx{~aR)3LuxW0P+U;|4n^h{+Igj{}U?z!w5(6|6v5) z|F2M48$dX!aQO=dFOI;uS*`N3>&l7F+kIeNv_VUwEg|I?|0&M zmDlU^p;XEt+hq*NuvivlPLctwW9IR?%%oA1%Dz;JX}U>lTm;wAnx945!7ZcO&e3nM zp>#mra6}e?lz8qXZoXy^j$HF5IwzH4j3uTV7)qyl!BRtu!3Vf{Xq)2SzRIy?G_h7} zflX&4v022{e~PSB4VcHb39sL4X1ZtsIF-Txr?P2b2g<^<4ORr(C{r^jUg}oxn2B77 zfWM5%eYH>PBjKXypEx3|d!R9jM08#!9k+gv%gkq{hqYi z&9;G7kIYIuIh=Oz5Nax~`vz9ku3gk)iI7pOm|63dL3Pi#sb0T7X<~TYbOzv9azrgU za-#psvFwAU0rTcN;NV7H&5r!a@)Yd0th9zx-n6bkrt z%nwC`6Sjg?5ZtF0mei*esb?o0hyk6!8%gIMl-N;PC4IJDkGIOd#jFMj?dC5yGM3tx zghAxZku==oYtn!7p@PKI#Kw{0~fQ#=_N$JR*AHLErGged~HqkCM!q0;7r%iSdwv3i zj`OW^Sb0pDAFQh1;O9l1V}{0t^r~0C0qrR7unl>VenEQHpIi7s)k!^JfM@xD-ZN$s zu}aVa#TG94nvMPMc}P1lelQi>6n>!!h^#|XMRJ%^hC-^}@nI%~P8$~&?C5DBagH>@ zGqJ}fLQdc6pDd6buo?;_#WGA2CWlGFDdq~)501=84zPl()vnwpOqrJn@ESpMKMomG3Mde_yc*-%{Nvr5gC;W_(w`mK?EnmkR`G1dJ{Mcol56&! zTPNYBSwHSqEJJTeP|Mmak3Zl;P$aH1gzM-z>3P4mynpioMl;8Dg->G~B;=RaO~dAb znzASj#TmV6e%?+n6MZmi2s1c>iTy#?H~hF@X0ZM)C5m_CuI?*oAc}Cxc;86fd*;^M@*%Y zzH&4ag{+}O(RTZ}h;r3}oq^0ny$09Zpfp^n1?rEg29jj;qU9q1DY!g+m)xXne>b)h z^T!8UlIr@Ql^=va6W0wVAN;5wCyZza9%Ux7&^syGEprjAHWN(1gE?zwD~OthNoxcQ zSp@tuWI;DZ89;;IivTWAB8UgBsc1_PG50$`I5J*X%EVK{fB@rgV0`Pia3iob5J5CVgnCd=#y!+*t+*Q8%Vw>acBtR5x$$~V@H&uvz>a3vNdtNdU8QN9 zGgaPM=AcTS@Ss0HhZmoMR6y~1>m#k_Mx%vtosT1eyNNVVkxu5$JmR^VY=(B8g=X2m z7V^8RZOMmjfo%(w82ZhJ=^h5&nqQ(892x5Cd6qb%OT7bgmGa z=@aDg%Y_nr)#%g8w6o%`pxE7tp1T-^?6Ku5zQ`g&P4SJFQj5Q@sZ=z;oWPLijF<^R z{8$4Tv5b=f9zG{%S3}!0ib^0CtrF0LF)Iw+Xjbt91UZKTpW+elQ=_39o!L+IwT25E zu$94&LWnc&q`^)w^uKI;8n7%O5#zZ&yu(&z<2HQ72sC)<)ekmwb*rTOzjy;v< z0;|Pe!G^6B91+0{ovvln3b0gMJ0m1gZ>6b?Dlysg0%^rey?4SD>xl+a-tLM}-?)`h zcKfURpI`w4E|$G=lhhQiV?W-93rDjPG@-s=zvfD4Q3N5P!@3jjVt~xy)TlCzcCig} zlE%I{=TNpW!OeFRzRtA7@FzHN20$xqh;6&hI?`1U!LHA1Mn; zZ(M?Yw)B@fIuIrB0;w2h=3Q@6$YAiGo^!Y6$=>s_V_wJ3Ujah#-vUI)yrJ@D!t^mf zfcSi=_HJ!~3P(Ejj7wspg$6Gw6jIhqG<+(Zr_4ju3Jz?F%FjSKXk8$xyNWqJX6wsL z#^~V$z{V6u#P7uEkA&+71P!@9)G~Sr`QCp;>9IM)}dcRyx zsyc=~&7b48zW3-AUR{t%x4mY+_D; zNTPAW>&;_!SS(Mn{Y*3CSIL;CvJhZMFzb3X%lsVDwJ6t#q;^;w<|WH;rR~~aD!IH4WP`sIvNfwb+;5qLqcE50tjuB*KIikZ zW1nh1R3r3gLaR-ZVHvRGfz(zBv+Si!O~`}0U+A5@i!dBi)O&qkmemRA8Q?$Y8;^@U zb$PyWa;viJgpPQ|#c<_xg_56wbTdH>H%Z-qugoXwth^Tgw81god74H9jClIbw6ZoJ zc-X}(G~&(@T=i~Wlm=8RbF+r6HzSM z#qvHa^KWJjuu&kAH_b_9V559Z&m%b(7d_tNA%-2zg(GOHK;f-I;k}W9BtXx*M*cwaS0gX{|{^L6rXvweS5~XRZ+#Zjf!nM6`K{?wkx(( zv2EKG+fMqa+NZlupZ~k}zUj;7^SgR3zH5vz*PL^4mnvLxVO@+Y^ms{LC^tA7)l+Ot zg`%;j8)#cR*sc>R-WWN?sDsW{ad>=3oT)#uuP=;)cwV=c9$JtY671HRJ$qr%7IxL{ zyMgO_#B27u+oEvz(z){nQJrHqd5>IMT#(W~b{BtTOqK>D}(Q6AJbfP)_@1aziYDP zu4Z=QIpVuYswHrZBdW%zU#w7Jh=F4JwVeZN_L8slGVxpqG?}ST0d_aU?pG?nkmo6q z+mxWi>+x_heidNIljF{yH5E>@7*y|>YEe&IES|KmyEuEm0^z{z5*g+lY7_;EoMB)h zRtfdhZL7_u!-!Nyvkv>Ejd_Fy?Szgd_jj;=3pUJl2W92-3KR+`kbhmu;csqSMv@`Z z(IELJkaU*s<@Y>@O89QGZaEdqt=nuK;`t4B_;Gmja|4}uPFFWtymudIyyJv>+pR&X zCD!WVtL$0!PFp<|*E-s#9s6zGV6?F6sURoG3yaRhmAFk{l80eGhuG};f!1{JurcSk zsDL-1(7COIvmN!H9-dpeO+M`Ok4mB<<_i7E8;*teXI!LX(RjW!tI_|N=4b;>tLK+1 zdjXt+W1q(BMqB*@hwl9RT=HD6Q4|@0RqAYAFzr|P_5Ij-$p`P?`fwW!B_WlwZi()# zli2NO0S;P1z(6EL(386izFFNmD?@{VQO$PpwGw^=_oj)r1mRpD7Dmq$$TStGr0E(FUo0?F0?n1f4xitdy9fZi5@jff(ei)i(MtG~;Hl#x>QsC|eLW8!}R++#t9bgs}5v|v;`V~#~jXZg! zg+YcYhd!@@iLu+b_Yi^LqNbg8GfZ$v20M&RRX|=*O3qT3Bl83!^5LVV|CpN*78}AL z?i?rBTF`dNO~YnIe=Pa?Yq9~SJoVSo9~Mmy7 zFsRgeh#JWV&MhW_jOTa?V}4`oh?3SvPdpnaeVT;i$p}Hr>^POV6<8|Kyu|6+r))HX z%^K{fv+!}+o5W)wjpr{8$k%KB=Qp$CUxR#?mtb|p^whG+%e=}gzrXKnQy!Dssgd`u zoNw5TwuPHZQ4N`?5AUnzizGYpJNM}!ZP7o-=6(JIES$K7p9f_p{`t5AvlF5eqvKI` zx~KQE{0r$9^KYhVDe}Rm(OYb>UtI}71X(r3hH=_m(cZr4V{K;jEknyb@iRyVFn*}P zfxcGNeZrAFdl7|Mu`hIoyX?F^*a6ca|I^k8T0r4m0&Gp_f3h`f|FSjKwrd@+wG-f3Ljh%*{ukaEQWcw*rmv$WJ z;@0+0b{v^$--A1!?wwI3=sCvvNG?Xp{EeZ91nZ#oRMa*x#+trLb?JV*+hR6*>uy)% z^n*u7X#1PnZze5?#(5t*-RMWLdskWY5=z||YfuQ*9g~ciU~NxIL2ZA5FV+0M7g9TZ z;63tSN=_LK?3!kb+clg-qLqXcK(cJ3uK^^eO5PWz_vfxf+A;irRPG(fb)Th=b5gg) z(|xD%9qn-cbJln|Nk${RtB}w+i*!vn*`^oEV?Ybc)=2{=NTK1CZKzuG{rn~`CSN?= zW&f4IJFzgNDiRIW9D%3G&uUEdi_!&@p z;30cuC3dF}Ox!)YMmouEoY8N?E>=mH?Gpa^IIT4URnls2foOs{Z0ElQjfv-SIqNa2 ziO13Q?y*D-G*?TXTeX9Hc>CO+xI1MqAY(sj;R7!32=U)&3W{Y@=G=VS4t?SS3PJsM zUL+EY@$F@J!Z4qbB-M*b1E{;RJAd>o5)5|NMfz>nel8`(nKS3^T9?RFGE?#^xQ>)u#y{2*jj@m2s9yzEtg-3}M(F&OL6;}nxq*38b$drl8=cbwNe*nc6uLH|jZM)>M#cF{ z-W(JB0uw7j0L_+Z85C6}jCeps3>uNDJU9B~_%cmCi|inwL@Tw2WhCstTOm`JsYdI; zuk=FBbRrS{f!&IHE{p=eW{(LrJeP5Fb!&n?XTnmhvWw-aSffyC`Nq{~5YAN>xP>6N z3X38(tMao7DwZP6HB~2Ab&!={826kodqz3D`gMv}u(MtT+ADt4_PA$xa5d`hy$)AX zwaW0?SplurTXrrH>{A>@p>NwP$D%t_os#M=s8FEs{ZM-Y^#q>9s6n)PVp`gVDh6OQ z+*7@P=~RSS5WI2Qm_N42i}#N$>RyQXDt_!A&>j7mVD9+?b3T=feFv5f^$QvZB8f1x zX_#69uvg69gIY`(XV_9Z+=Owxu~v1^4 zf>!$N`cKO9XF{72$v=7nlX9UgPly8@MoEaui6K=3%fxrkNO?~)%3N7NEpNm!L{VJ` zBg0dlBgWQQWA&C<;XaT26KcKFEf*7alE+_Tu^G)r~HTf+lBL zObL6)j0Y7m+)f7&y(?paEdkF`@#}kml;8}ulxZHu?t;rR#X#~l`F({bakV$jR5~pI zb7B)YtAW?x^51FOXBq-Gq7@to78zK{#JnWQ&cD*r^6X!+WTe0P%5x);+va1_IIq&c z+bwrr(_EDq>nb0w;Zi(lru9C~4O7hCf9Fa!2Q?`@_~MP`iTlSMDR9ZnGW--qH2BD1 zSN6X@NQs%YBkpl~C-DNkpnk1=$pG^&bJA+;Qsf_*CCP`6AeP`YBRDS5rUDcjdu`(b z=bR7dg|;UQq}2nT`E^zTAVA{zkNKrkeSiE&ej}uJbJ;FCyO~ac7=k);&*bC?-~(w> z%n(TD?N@^|58qk=+|jj!P@E9@-}D>t_`|9AH(DnsoZ2kj957eAa$C9YZNA6ai4EX< zKP2GG%!=s~6_q?RRCFtw?l-zOQoO9`xQW>M9$SlbI%TJc!gy{Isth>^{E;jM)(pR{ z0gNsrA`sOtYk4ECxL<`z%uAqykjdmZDdaul%4y)@1&%G(xb6tAL5w_Y#^0WY3$3Tk^vHs+|kIvs*?0T7cf=|;p`sU=-ue?X{ znuSr@W}U_G#wyG9Yk2eLigl`IdThI(VBov}%*a#sid+I0IW&gv<2BJu2H9PwAy6A7 zE2%M)49Rxd1lvs*w)pmB+l}>&{~@%J!hZX%KV==+>goS#EtUTnrO@@fW z0E8NMf`XJT42hjyq)}A_i_pI`5p50{YNOR!xDtJgH$SSXGNA%Ltyv#bF~ z+ZT{S$KTG!uI;PEHc)1^oNm!C$m?(p3NEhvnRUs=t0*U|C}@TqizU^fKL}-?P z(LuYd{yE+EN;wM36sNl*RtIs*2ob24OGUNbf#f6G_V&*<$&4O@${w)t83yh@RDb^N z_>5FtbI9jF`n%)Pqt$h2JlD4zsGi{Yl-Ou->g>@-r@nDWg z{meob=ZHB!9AgcK($i9c?qR7$sAsU^C(1cbyyK^1=x2E!K{Rc4KZBFF5JQzG-FQ^n z%(V*iTOH3VTXNw=}4(UHy{hA)Z|wv zsRy4)D`r1kR0cN4=fiDFM`^=z6V8QOXVsDzVft=TV7Kb}s!z*_;Dk*W-nuSaI0xq|QGY_a@3pGh|e%fhsjT;P|cNl<%m`xuwD6?8xY@@dVO@Ry9Pe|Kz=&Y3p86MQYeD( zOwi944C)}+J>+(Y-+^_9HxvCnR!YN%g8W*JVv3h1k|@!HqtzVkWk??XylexlbjP2$ zCxfg>RYLfj<&U=(reEYjp#iDw#D!TWpuW$sdRYO3opc9_EY7&mTv35>I0k6s)>++y zXd46zDIE;-4pHjAPzu7^$y_Sar6$NXS2+g!-?oN_h3cWX46X8D%j)%zmEkP5b)dSl z^va7AgKgxATu}~L1r(O)aoPL5R5)9UDKe#IAS?7zya1I2>j&zs7J)IjoDh8tc+vw0jM%0wRyvj$F(aM5SDQcUzdg{sHKl=S9TCkHh730+CP8 zB3d+{6{pYyUe3FqKKdXWoY8i(qfw*;Fw{*qR?%8B;oq{Q@sI0KWC3(F=y}$j0b8<; zxaWI}ff-^`J{XEAU&wb5>e#$mZ_ls4zYl_JRjW{smu~EbP&<5{(PDJR z5R#2-n7;5$^EatX_Z8q%U=u+;J98bXhRx!6n9F#OTE5M!lo?k@FIKb*ggcF9!&?qp zBd2xxYih07HEbQ)gC?`mr0q)=w&R=1lA@bm6`qYUN<}_8%U#UcmcR{-aJ6}CJjQAz zPU}xiRvZ_zwFfSJX_~HVmS&>VmQ8$K7EMKFN=~B~CF15fKUJdn?hIYVB)`F?UqD5p zT=S^+lH|a^>?IbKC`BJ{WqQBVQJpgQark4el#f~sgljW(bxSkzDDTVGapNu()O5@G z>d7hPpVp?#SNd!beY%UZTX&97HFl4t@)5h{4xxNswSzpt>k`0>K!c|oa2@E8KrNmm zQlA75d?rU?72;sf2w36k;mK-`=i{HfvTtiu0tIIgy3yZa5vyL$f9;PRzrq_K8MA2iHPmXaT(K)~Ei{G!xh9HnAacZ^MY z_T=MnvTCVjkSy$?fQl#9EiEhU{UF13Xk$vwz?Y3h!V6<%c^c{)%gu6c48C>yWHR}e zNWPrUHzn7zB5au-G^1vTg-}hRrBP}c7&*s3PAbigiZqWrpruxr=6EnptXl4P%WOUE zs@OwkriGVc>^dK5O3zFgqq;BSNpmv_ais7IBlvC?i2}jN3ku0u?3l&bb)N01+OrC4 zPZe;7pk>VKa-Z4(PoFT#?CY_dtS$GN?FQd14zkaWtsgP|#EP2TX1(96yW-G$AKQw&V+>bD z(7!+G;7aMXrsqFHqE|r5=y<5)5!nQ)K7^-XJuhvandMGnj`erpF0$HYejlkj50-m3 z2gIB8o4L%(MZeDjOD-?B;6y^+Mx5ryw0RNueAVpBNMH;Y8n`%LkDw|JUf~y9v}9vRj!KwHL?!4JvD*qn5eb?+q{7^eEw308{eO=T zB>Ldt0zXUzN3Zp=Zx;eve07^@~UVrG0LU z8JBva>U+`!vQ!0DDkZvB(Apb~Kr@JfTQMcBr znYUa+pxJrq`l{+ts;!7IOXFTu_8NFy>hAiAKFVnD7GI&2Q@OmfdOsYs|6(wa#bD3= zi28W_vvPi&aZNsCA6xC7EeDWyHjgb!alqZtQP2i{2Ts!KV~6E5get3)T`E6t;dEfN ztln&4uDF#8;P?M5YMYt0;<+s0X?z^qR9J3Em zBG#K7&>sn5enu!y+3J}3=M8D@7a1ycfWr&pKOJ6wSEP-rtvRf*A$bAr*nlMn^o!A< zb)9ZQCplV|(`%Jk3+UZXrqM|3g-~cDC|#J}AL#@XL1ac23({oo2s5THvNr}+Kx-a9 z7~!Ua$x5e)VJ%^LLcif>yw1$_o?6Wu>EC_49p?N%WuGvc{jTsWpGI^WqYy*aM8mVF zth6~VH-jqol9a|ILi$?0q;8=1v845y=vNu4jM|^G>%t>>zFkB5YiOIk#F1%fZ@dYz zVRySTR1H#K!+aow4a9K~HNUKALp_TNuf+~WE~N|`TF&EH67F2XQ^X)BEIVU*D^W*n z&HK`-48^y-hAvrV42&^No0?D8BlvHVN^lg!EZ>&AMb6JCebGVl;|Rdo$V2!{*NSg- zb0C1zHQf%x9~zIrTEG(T-NW*V{dZ1?j4Vm;zioN zZd9d+5T(z=@w?xCN3iSdom{YEYVY{P=iYYf@rtY9I zK*d~%y-~#Uo*C)k!gpXPE4~mXyouxd8XMLO2q#>Wmf8?7<+S%h6xY@U#pN=olZ|ScR*l?JzCni&UxEmG_3Si&vX$Zk7=b=b`?+eH_hEl;W zoZgD!fX0^8Fmb4{gnq$z&3-ywl>2NT&>qkVvh`-nIJd~;i^z#T7q`lp4s#9vrJ5^I zYEm*4pGqp^h!#kvpB!Wq4%3oG?cgPZf5vh3Nb)p{dl-V-X+nRV56jjF{&C2oZySmo@8MsF{NoD7oD=rk0V z>z7}6!a=cDIsz&Tuhi`Jyo6@JJe`MqEuaksgEz+Ll`78-15kY;?I7J?K0o_GdTJRm z*)x?q;dvoxz<*YWI!JZt1VDJl3!8;6&amX+(&~_#YOzZ_C#b^@dL({t8~bU<5V)Y5 z!tGo;xlBqs^ii|H$UTHzTWp=)AZH>284VYmBlW|ip;H(aSLE15x}(%tD~pV=_1k2` z3FE!dqeAt4txJ5sdZzOuWo-S}_0ZoC%jj~!V<=)cNhJ-@A$>@`xVg&(4GG)Em*%+f~94>(YnQV*T zE*;`31{13R?nzC1cB{xfJAZ6Q773u;Es1k9rVb?RF;}Dv@j9Y_izfJ{U<}n0sf7=6 zEBGxhg$E3hneh~rQcY?7*o1Sm?R_gQgZ^s@$x`C$DAwf);FKaaczL_%)$5(~(ACz) zd)oi1r#OHfrRNx)BGUNc;PFBKk45v9xt?EdfOEka%9nL&s6+Gedm6Azr&A3VB&I{D`q(?JVy*LF>~`U z-;SSUdwN2F?%FOlaRo0+#F|$L`44@z2IBUySlzx(v$tBo4!*ZmJcVULFKEN z=+bYJJTO$3`67k)qZAE=KbNv&j3g(RsiW;HU-Bh1R*FhNiNjHxIE_@}rxjOx@)r!cw-yw5q~ z9bDrSZ9!_#s$jo=iEFv$j)(gYhPmI>dML;Awmxyq7xhi6kJYYG^I`ZskpoUbCoh^Y zwx9iWgDyL=2J*rmE zaHPwTpl-=mwWJG=W%|%jsGep>p0>{})_}r7Yuu_FnU!H$9Cbhyt-zwFjCe!wG;ktc zH^h2Oh}ltk&4s4k1w7Rti!-S!qbKCv^aD+==E1a2{Cw_XN9qFAJ%3R<~Bngxbg-=l`3~Apu z=_Z3wqB&k{GS8^_fvHZlxRChT6C)HEU97yA(-dTWPlbp3l}+W-1(ZY?pM6FPtP8m= zL?&D$*J)_fZp&TXfM`zT-cjFuVp?Zta{HW5)lW&Rk^P2YW0eoD$x+I^-y8$fX zULi|!G+7cTl#36Cb&O*~Cj{G}x^g=bC@~z|5OS9Hb8^)@sbb>lR{=Rs&LCllWKM>l zT{H#)Z1f(D5xymz2mwtrio)rEc(Mg&a>ixKCLJT2_})ME3KueUakXT3K33T5pWPI- zDK*xds-|BtmRrh&8uL08lHD1!sf$4EP^%#Nd1$z4C9)_PNz0O(VEGKS#0R8u+nkrd zmGd3F=+&wGEs-s$g~U3)`&-|Bcxr-m6ZFLZ^^1QCcoeaDYZZ>9SAzu+?+6>qExFj> zOWg1oc%y8ZjPjQ0=(1LKdr|sF!tn4u4J;<^Y3>6K9WPM2XJ!yGW|fxdfENPf(m1T@ zKx8!wg6b6I_9Cx`6#ca)hgTx5EyAP{M`67?vP8J)Eq^iB1yBrHg3&32u(WU{X$*MW z4fAvA!H_>d8^Ddyb0}9Ai=|#Foq2C|9lRc|n2XK|=H=Q4WLIuT81o*N3xkGe9c^KA zu0PaBx-R{Ts?;$C2Df>kwuwohm_8QKuY$GpsILp#CBNW2Z?_$G!A5_p*|0(24lt6;K=4-hvHpdXlCRO+mBGdAH1GQG ziupZ$D5=Q~4Q%_=+U>Al93coTe~u2eK;9oGe^VDyQ#qo<6kDi!QHXvypx8w5%!kx3 zZ4b9dVYLK`Ib;9K)IM)HKL6nxqX$yWx-(P#XVILtMbW3xhW!@|u2os{=|ROFs!1g; z%~=zHYvo>R4ejWn{E_o#PdA1fZ9EpU$C4Sl=%XEjv<5*6wZzgfKs#xifiVYEnjs%X z5s1hb2k;Ez^HG6*Gw*K>??+%^=Zql+J*m%L>HX zBe&>scYG*pb?1*~d1ySVY^)pl64V3nS3&7?i$VerFBruJgU3nAsIkaq_mPK(s(Yrh z4c^W0%;pDXIUBJ1QymYf=zW?t)6(8Lj-NwFQX61tU$lQ2BLJSKG9Yr)yr1>H;AE66 z7S%n57?6JtnOznvJ$vC+7*!LPG(nU!{ShVQ7$PNF$_aSNN%K;0#J8Eed)@p!I|r>T zT1;8-N7JndH)>5^o5Z95I-}B4A`p`+bd%>1LQX83jCCHbLiZi#stf%D7G9ZF|h_U_5OnGfs?v zfXQGZfU0F&c=wK?mM~^N{SdGk#o2+2aB=85$0xE%qf}7FxQb}0Fv!3iJ6`#8cfDzh zBPcSdBXUSGnQ5j&-Ly#>1wX)R3VGe7bZ-@VkF(ThYC*SwhEQx>q%88dj(nlWFLl%{ z!$1=(*RN85Ar!i`O`hz!s385v1=^>$OQMC z7tD*Py~jJ@FH5b(8u0=Zt~;-NY}{zl(Xy{Ju|lvG(XBtQ%@%0$GE88g*I+sfUE`8P z9T&2|Of_v&zd`2%O@KAkXY@%8EaI`Ujjd$)-ghRXU8!XyD>A?HFRE3|eWPuogkROB zTK?@^<|=_wO=&~Wp1g3la({O7Fz4{2p}n2M!RxcX@B^Bc&nAHl>O36J5zC<3o)xQB zMzKge5%24zrBb}~ENC5l=r`UYpI7m5#ka_w9 zdFi+89tHrpE_hh;gQHkp$%)pDFMdIh4vTP>ZGy1ROUXl@(zWx4gpL8_u{46(V;<@w z>B)1gQ=qu{jkG6{ISOzK0`i&qjxBnwlPv-rK~Ax3UAFnmAl(e z^|Q726tr2IqvNSGx6WUdt3<3#8{9`%H+&%X^!_m%h_qKH^8l!``cKsT9bNuEgf5;< zT^~*sB0=I8NgAbexCDJncwB8!-F}=X-TB>CTiph6fa4DE*}}z2eK{{mK>bjl)}!)) zbOE15GeeyjPB^;M65ndc(X#O3%GG;YPvr0L(KvB*85J8r_4HQ?RVwbrbDl_Zp&Qj+ zAxa12QdJ5REfHkcQm-kX^^0wnAz3IX1#Azh$2`$*O5IU`(xIbTLRHkEwNUKP1>i{Q z^`!eEz#BZK8oEET4zQt1W0)iysV*sT5d2e(S*pD&PiteejVC08Y`q$OQXA_W=F3!x zD6XvTTl5h-foqHv!(GA38+(~j!q1~Z!qUiKAFef%dMPhtfUc19^_n}!)hhjUbJ~_&Y;U)9>T2H>LPKH4#=KEYp*3`J z{*fd4M56<@Cr?&W#77m1x07sHMBSHDnvbE2vKGZJx0IP|C9_QVU1OnF$1!P)h2Ct^ zdnQetl`sknlW7`Ns(KFHi^kzzd&v*lFV7}mr04SD*V1Y9Yraur8-k~S=b20^R`!o& zT$wLtx=tT>_&YHsnYAGa6nVL;L9VjWE?Dw=cN6ZaOlNlkANsMn;xT~KvWI%1O6~* zafgB|K2V;)%#jGc;`Flhq!Pq=EP_fbu%3HF`pnQKd?4Knw(-)H%=ekPveKpc;TRL8 zRb#O>A#!erFp)+{hQvyr8*f>K(yq$dvehqsG2Zx^nN`P%qZs_iGIJ2T7*kP4F;1Q| zXZva0d|mr!@v_-~?hcQ2B|x2rWmQQLzI^3p%Tt}f&J<%}EBq|?uX!=HoG_18G}6kZ z+8lWDV0+EPBpU^m1s{qm-o(|aF64oBP)Ry?ilAdsx(!}B*1}|MT~Yfje?_26S>Mk2 z-~fhlmoL#J<8Do3CT&QK*)u06ji)}?!T+pu-rg`?qky-W*#5)yEYsgnzy{SBn^guh zubc*-&<04Ugl|G>W~ERnka@y+4WO&eF@r5cs;Jy`@Yav_^{7~r;>+_vSH7M`IgXdt z&YrC)^b%(kg5slTG3oG#oZV1}6k0E4g}riz!!2hWK1&@vihf6qMZT2BM<&uQ6pBBo_;=8mv~ak#yVgy6Fv`u>rAqOs&( zt@t~VG9c|ol(PsXZ-IR~?!=DhJN|vESE$kV-F)s*{J2|vj9)=VG4DsNI3*OYIqaGb zchv$Zaig0o84nSRHY=$ zJHe0`vv8qto1ymAg^NOR&-K`(4!ldeKwmK&zHCrE`0lB6wre2m$X=05h)%D*n)PPo zZa%0)MiEy*YzVVusD*1!AHsL*F}Q1cooaDjLdH0r_M>H?_-6xz$1F%V4!sR4n?`k{O!``Tbyhex43v z#~hr9af%U2Yd_F;;u0(H+(BsSG!}={tJ{B9CWUPbJ8bDj_Vg4dqc%^DyT@?GW|6FH zLVc#hZKg+L%ZHWq&yUh#Sm|MV>JV+iT52OFCRKk^kS)-Ldl5P&`m?`^p}oec|HK>!K`t#V))=nRp< zD)4!$*xou)xdh%yaMSC{3N)M;iPed}n?OtLRLkSb`qN#N?%wb!5N0ANz5^~o9U;+p z@yMvKCAQ}=;c40DweTedEVO4g3UnA+@@g^^Vvu4{N)xR(6eC7dD#|1ntZ_iivZYYCj_ST?8ZDn%@IVJb=mg>8#P&f4C>w~ z(Xhc50%MT_E6wN(;oCP%Hn#TUhn1i~w@7y@A6Xo}mn z%kZXMF25>v$n!s#ov*dMxo!6w@50Ll-*Qi-CC2I#-MY{y)P)K zc&Z5lyWvkzC%zt_*{Yl*Gq*~e3Dq~D$PB_{HEC|xl=H2mMxqM^HF>D+9c4tKOTuSf zw9N5Js8JV$Cs{-JCorg*E!bb7VIU41_FuB>I~a2CCz`+(9wjBLfSde0Vp z_hFVzW0MX+FdA(DtUj9(eo(}bv(v=*>@522K74KQsi+kd6k>|BQ3p?>o}J9uPI@rN zz~-S9mw%+}N^u}?Kml(15JPeB7l9!MM#$p2yso^|KKZbC_hO!u4v@2P9%|es<{6in zw@06UtT0T7WS>s_Hw6B+GXD<*K)yEodj!4%5DKGx~%k81>`qmbg6 zx8fM~4`j$8qeiSWxjM$vNO^y}{K2j+z73izE?!VG-z4Hjk;v3hV=X8YT5HyyXh)__ zh#NS-1`8tDy(tfF)0}BK7R@Ll-}&fIaArzL0>iG)GpNXdrDshP99dx`S}u?oJweo~ zSV%3D9u81}f>hrSMFfy12>C8{M0*&+*DV}G-rvNQ*Xd;{OPQ5Q#xiCgj?Xxyp;SLa z^36V*d@-M2E4Oe3&@_|~H)eh#Yaspz&_A;g`l@ zgsO-OVTz0auk)OVmZKlN4ll2YR{;y*j3Q1?M*G>vEs|e_4fTR*lWI#i;diunYPw#o zTK;Wnx!yZsz%-WyXpcmns`YdkGa0p6n_e8yyK_zl#Gl6BbAjJ63Tm~|1>Q* zSjDHT;4&q-Qzl($Z6RW+QoD+IeP$d-)m)VvE16M{Y}<#!iuvNAazd?8iQCG6$c7Iq z^n!7PyoE;?G^Y#z0i0htTfFc_L8<}1C3;s0PWKhs<)0o#%l|h3@Bjex;#j@s{{aAP z9Jv}MBcC5-l&?)izs>(ZpzyySsQLc`f`82XjaiK~{}qD2jcN_5I=26ELZ3+Hh{3j^^HwrMr?tH)aZtK zq||aZ%Yw-HG2DvP>BIhOkO`b|mj*mpQp(zBR@fk&?68Se0*WyipaVUmh_etowG#op zC^hWLerqyA)~k#~aQhxp13fm`KuW)WF&Sk|0wMr9Fh25E2acCPh%?KaOvF*say(52NY_3~=N zfhCBh!Hl?}_~2XN(a}RE;)D0CONk%8-mZFv?Jop#XJM!5h((!LV2l02*n>kL8l7fC z#hCkU11c$2=sgCq387@9;73;oGbNS?@gISf7r5fEgsu0j*sf&@WiyT+6_og+xlg;e~pgp^7$Rt`vD~s_kLjX z964*#9X@P$GnMlg_FBxlSeK4g*dG!EOAp3*p^bv%?X^B-d)0I22?;GeBGZV72ezj>L<7xT&bJr;z9r$?<@UYq-CGe5re7r zT3H>SZ)B>_J~#>cbxvvGshO2j&d5*gHDuL-hL(d%xujUH|)m#!5|ASX0D-&p&Sl zsoSdto%(M|@V5!7{r`*uP~fwwf6S1|{~HGqIQ~Cz;M(8ePaL>!0VqK`KnWoJD8X-* z^nWRV6k?_E)iIg|=07R{Z}UGXfvyrj3DRZ%ml9-Np8xMkU_%H{0z-fjr0Zk|2Np`I z1+t)HueOLY0wWgUfnBlw^tQ#=Me9GWAMS*EIE-y|8wS_D1*+p>VT> zi_+Zz5Qd=5nfERN4vitI(U{Qf&0r@%+)VgOm8>L|sq&U^uZ%ZHjhl8dz z^#9F4FtvMPraoXWJ& z9RHOGq|h9PsT7#DgN2~-2n`$6Ia%EdUk#K*Z~kI1b>H!H zN2j+py!ITan3a6 zq@nw%c*L0_P6OdZ#A0nolw{lai2*>J!1I?AsvO|8@2ob#d?$oPAIYQtazv5lAoXXo z@yL{a9T8i|(%F<&7rQS76B%D?@dzpt{sP1;;ma+@O8~?Q6{1H}bmtrH^gh*C*K*T` z!FcF5{YcM5BTqg;YK-%z`8<$Iy9JfH$Zd{d1(7)vV5)ZEc_$gcKdAr&-W)4#Mb&59c1E=d%*j`J9Kf@_GIojf1&}+nDfZ_g z)1;;O9GcXdmE|;;2FFczM&jBJtlHz;xJBkOl)Y|}I(HZ(ysBvOU<>0i63ua0gC#E! zGZM|;MbLF~p~a!*V!gtcKqw8W%~RO`cWD!(jYRKQb>`V!$e*FTRH63Ste#olJey@a zuYR)BXEc6;$7Yusy*slVgjNbZUN(?Uty3|%UJ36=97Ls=Sl-IE=B6lt~sbyO`V{1cLAA}2Og(I}`EzJ&9|f{*&KzsjL`0f2DWR%$s4P%1sjp?G0X z&ilPtI&889Y-*ET2)~wQc02v=5(1_pKi=Gb0fPB&-^TwiM@TRQm4C`a+XW}5&{Zuo!Wo}(X)Uc>%eghTso*_bhQ zkGE`oXb~xhlUsz@QM&(6Tf06$NQMwe(Z$@;P0~dFF`9j^M6>9)0BV;7CN0{G?$JF% zwRM3OZa1Wnc_1p^_&6P?@zwdP9O^WD8O8}wgFu(kA(!tG=p%e&PVru37g4>xq3HdL zAAAK-;}IWcJ=(VTpr<3iG4y#3xXJXPJj%L)`vOP@NK?n!DJ8JPfVW$%o+qGM#rsER zHJVEd(N#ev64!L_A|uq=e&FwU*ZZG~^Euxn0FLNHDspPw2+3s(nj2W7Tf#cx*52X|9}NF?uHV%n@9HVzWn@utG+$45y%v$rpxR)urbDy- zV%j&azEHkw{W__@(z@UA(v_p^;aE>S)X=tD?K?pDOkGz+(D=7rR0RL0Uc_Mir(P7x zn=*)6F}|Gh7X=D;8~_R(^8gfbDMi?=;2o2TO%MPmF#fAv#097qamI2=_GG+&4d*mY zqQJh&)gJFDRlZY0bHoBj#bx4Q-6;?^^VDdtwM>H!%jf$)-%_yJw{FeA!wlJV7l(Komgn1aR}V2TpRodn0x?Sq4GNtmxrArc zsec7ge;&GGZ<@aMEHTY|+NBc6OR}V0hjpqoZ$FFB%BrJxL;3)cgm%s~5_#UhlLaKB zp)snYCbXeCR|pU}lTK|>t@zBOXe9J6iUUGlTVVK?Th?g7vrRzftEf%^t*#O0X?VR% zWCL`Res((q6LAFo93h7%?KbK2JL?f55mZBI#D&=%pg!CvKriBh4`6{_qu8K$VM6W` z!l_Yq7I|(QQ5tIm*~|#D5Gx1Pc%^_hCp~co{kzV$a-e8O97q;AN`auq(3VzH!Xw;u z2Ko>d$UM#JbbER&T3lYEsS|3nwV-(*Z85%t8LuIHyPA>Y3_!)m9%E1g)%a3}#bj08 z=9R3w>}x9+uaN4Ws_Fl#7&XMFhqe>Jrj{LZyvljM5T0*}_N|Sa({$NiZsQqzIQdVA z=d3Q1N!pVidCD&=d~=lu<*6Wlf&+aFO%#=x7{6{DbDd(a${6O?cn{2S5Q6m}b4n-V zp(baEl!YAoRDVYYfY5=TI&I@WO-0^7J9M%j_T z15Ohd*hPH)qL7x|H^E^t%J79dl2WOujD}CI{&3bUu<%bvXyY(=pij+&mUMzo>O;uAt3*@HHG=_J^5MIrP3M)&d}D@_&cJF zttq^R&R$Nf5)`+UZ}JMt51G|jHEwgHezl=Vjw0IEr5vlFXm~-V)x)BzE3f(uFbx-D z2?E|azQxH)z3*`k8U+yyfIAYC)K;=x2?vZpOx|}U?oZn3#x2*+=a{U$YhqM${xD|b z@31oX81z40SjG;fnwu~ZN>igS2Wc`3Mu<75A|;sCBqyi(!j@m~M#r12=IWYF_ZSw( zjB<+Eqh$|>lb^H6kF7FkBS`>P?6o=4bl-0pm{9BMlfun1N5*ud`=0ZL&z}wXvO}}^ zD1B{IP6Z%yJ+Nv}8Oj?S=dP z$K7x-c@UOd%J7v%Z~ml zgZg7Ko4$t=qUg8Caj;M)^7fH2)AjKe^2rzV)R9bz4|p`aj&txc(Auwa{l}l1Ny65= zOq%kqf9P^k$?B{x->bdbrW%QRkiVQ0iVBbF#Tk2t-6U6wH<4H`Tuv_D7&l#>YKZ$S z&}eCTjT>%QY%VzO9oKPtHxEB8jErPk>sWUrO>C9K@tS)w-VoxMRJxHPjUO5>v|@Lg ztLU7VJAg6u+;C-iC(p}U9oE-kj;6bkxh9)fT|Bp(SXo@RoLF1rTubY&1X)ve*2roH zIORJ1wg5E$rrs|3c6dlS#?9T`{&pE%UyGeo(FUf>Fn}id@*^7M+S)pJ0*{1%V7J~@ z{k73htDSm`>xpI|?oj4F{@4z6&v+#3!QEQr^Bo_Cy2b;STI^NS{7pRE)wG~;bb8og z0mGoj0!;R_i?2ixyvX;HjDX$PnQ2K!?fmxRYDV(Wxb2nPDtr0|%k`s$Z80iq7SPGk z1}rsJ(aE=m$_ENMl2qx3^y*sF3(5^%;_ld%O<=P)Bbjz7**c=0?<$~=*2G$Hrs3_H z-p}tlmIlNR0>n(Qg?0JdoD-ra{Y!^rzTd~tzd>xbv44Trzg)^$Ty=sMrW@oX1A3M zC)v7v%dL*{GJRcDcJ5ZbJDCWD)_5pP*yuEB@fx~*t1@}XT4Ldv5U6MyDsyjV6%exC zI*yoL+u}*R{kY8BmhOYqR}|7EyTC`il&BP-OSu4TrcYLLE;X<}#t zhI|o0Ahzq>A$u>d9YWt9e<41;fbWL3m@-Pm>n0E=e3Ifu+Ph||zx zrJJb>!dGZ=mk)J zhS~87U&*}d=W_?ycFGjDFQSyH_+nj%6{+5+hXGT1-ap$_FUIvUo*9wScb;sf-nHbz zLzU^igVrf8Z+v$c0}-7-Fj*KNaFeRn3GZuDPI*l&%MrAQF5e2X?L6wbHzKeE@w_lp zRql;=079fM@RDD7bJqYzuiNmaRvnYp1&>Z_(^^fXCJb6$;G~%w+nQL#&QQWG!9FFvj3h>A!&VMR$UF-&d}}nkFB^EsymSJXP{@QmVTi}rS6oNp zS+8h1e1#=BzWuKPz+nXVzb^z&&@>r}um26pA6a&R=AJ3`;T`{fUPm?P@9QiplKF+$ zUA1GC*RPHR@W-}=`4K+G64Jwb{uz3c172G$Q$K_+BzR7~Fo#!D(Z#m>?LzWb1tvJl zBXxz4(DHfBirUIKZS90iy%_;I&>+2W1kB)Y=7BO@I=L~Hgzt;G^O~lgA`eU8g;%wu zbMmqi*~%h(2!K91(I9}nPs)v_l(c@5CQEvC<{pFcVqxNr8S7VIgC6w32-{wC`onAb zL87DsvnG+hj$QYB9z$RVQY|W8;YNr6FhFN20vhyThz?;GsN$LE3e$x~?@wX)`soQb z;UIkZFJ>$jKL%ZBgF)cWZ*D`-1uahJEDpd2YYd?^whEz4zhFj#V-6U9jZ_ScY*rQ6 zySC`Kf0HTfgeXRoIbazXlCvaeZ}7Ujx{SiDZI<0r`fY4)gf3ALVo(=sM@#!E=sKj+ z6R{ZaPe>vMN`MS}&};+n<}b`LB!A^&wDh;{RuKdb4`vw>^q>)XW{U(B&5{uK#jG2&;GEet`+YsI#dpBV{aFi`qq*~S3+e|lsvSb{9|X?bT5UEexe zq_^Ske}6nvb^Ei;%{*_vRHw{!8VPh8H)3Y4)3C^OP4?Z)c$`GuUAc(7yZui1dIuIq z9I=dR@gmN18)p_Y_cI?|XdNz;(ZlteP)4k&Iij7=MdbJP#5^Wc@V<3;;tUr5Xh$&p zeN|iNJ$8{oT|b5p1C=*QxIuXHcVb9Vc%T7#kqC)iV0|BSs}O>wSF=AJ{*K-6ckG{G zRy@s-r~Dlz2-06+s@@jM)BhbNB_y5Yr#AiO3f!g<8 zREF%imuwA73gzf|$Wt1lRw*ILQ{d!#9ddOAdiM);p9j)-BR_q^kJ7^)`g6W5bTfO9 z>MfZ(y)Qa`5QDzbpRjBMp=%HRgA4ujl*&{52`iG}Z;L(*5g7Rjf5O5t2x0NY{1YuY z)1R#ALNg5l|JMex{mv~iWRV%L?@|JNVPC!t{YH{Yh$X$bHx%rlpaVS*dx{PH8SA)y zc%9GkZLtkKK&luPew-fmNC~kNA80IevsjSo9a+q8SBl7ey%@VC`acQz`L34tEGubx znx%S^6SmB(VQhwpIIbAWWBSfI$T`*5=SHW}pV>d4y-q;xttPh|sSpB8& zsXIKbRMkDIpG0my>F|LLZN*8}NbmE;jhD?{gBykjdqYAY#Q+$(2#OTy0W$hPvkk+S zzawLk;sXu;42l@-2R8hIVHHE*^hUw`8CJ{=3`SxI#3vH1;|o&1D2Al?K;!pgF;XJ^ zHqyc$wER#^&j5hI7sO_$METnYy}wkl>SM9oKMvCVK4{|)U3(?Fr|;yKbLNb_b>-G{ z<;u9K(2@eHDRmzFRFg!nF||lz-4u2(fzy&=!*J$!OPxgT92)42iG~#88%`ma!)nmt z%1HV7iJ!QiCXN90U0m}|S$;nB;eS8$=Pz?DfBeJvGw_dps=tbD|G2_rsPsQw`T6O} z@7PU-OEmuk35ub=lRfz3ckGif@~wZ2z%UN<@kWOKjy;1Q-|mkQEW?n$Tmmp;7Zf@8 zV}xl~m9+L+mdK#(&s1xBHEZDl*v`>UV6cI}Kwxm6$ly7KfxzGX544&(QnDbATf+8e_e*56`ng4e)4=Fj&gdHi2#At|7AI5WXL5sIJ z@YEb=^8QptN&=(=0HbC3Ak~**21b4ixgaJZB@t3`pwXIq=-Nlwd_zCR9B7l#l7!zz z^h7cAud@e7fQ|StCKKd2{uqg39602SO!#d(gCalfj}aWBkOgl{iaG7e2s5|evr#2C zWQ8IS3M2(mJPIbC1PF@w)C4nx@(*SOQgVOQAbaXRCk`;K>!)(dpleMC%i_rl+2@*9 z_o+hHmy3BBi0j?bN8}9-#r{gG{8|OM=ZKz-+I|oxmiqfS`n*pRzn>$Ox6|M}MV822 z7LB4gM~}HXAe~dP@{!B~p`b$Ri%W}6@vigB;SbaNtSsk)e4(W%8TYp0YDOCO?-<$@ zH!cKmsl&5WW9&3HC!Zb14Usgnygg^(A{DJ*eh@>&t7;1X#BF5m;$4{P*b#$4kQka4 z{3Ek}qNl>A&xNjimL)R!J7<5s{++Y?Y?0Bwb0+?eoSps$Is1J-*cC-c{utpJh5su@ zK%+KA5fXolI3*CMe3%tT**A(Ccezy)P0TFhweKi}jQ`A5 zUR9j_L^<@`aaRv{viwKHQdbo!Eo+w-5$ev?E<1-t{9LaIg2@YBz8A90R~p%bM+CBJ zIM96mxtW*z-a+HrdAfe4Sh^tV0AKl@5u6i zsaB*O{YH|W)9`<+2%T)uIDPz6-K;rTv5N}iFJA_o{^Pf-nEq@&Ki9gj$7I9&@M3!8 zwK*9FfEZkT++dxAX{z1B=$Vh1f1gdK(O%PJ7^7ylysYldF7S+1y{OY&aR=q|bXxIcQUcpwQ$nzQkeTUss9hB}P@>Bia3Q^H$e^|0=Cp@aAS-u&q4-3pnP zZ_@>NSZ)NPdwanDX4Rkl+uC){A|+88Fk?t=`ms%$l{!p259tpe7}7{zjhiM3vLtkxrXr(S(-_ z<&B6vk0xIOokz$2*8eh-*$tj_{joF|1$U~_$@<>bQ!+>Hp*nBgdBTle*){p|N6C^* zQN7wjv+d6#%D1)PN6}sj6)f!e;JGKG&WF^jc$0Qi2JU`>0b87U?H32RtH-mK*=;IT zRcoX<28THYM}5@+#fUc}x6U>LfAKYY>5bXhCzO0%(7CmCW$yKx5F@j+aGBFIfZI(?`wPHni*5U@0Rpwzv^>VFdc_7uZ15A+&MZ-$%C1H zSl;)EyFnLNy0sN)V2naEAwx8kHWyeP^gi{*G+nB-85n8k4%=HS0dU=}sr5WkPdYQE z)Behgxu3cw+&v1{<#@B6hO0(ldV8hMe4V7tR2Ya~t#1auN>Z6z2b^Ik7 z=u5U;3E5BXarcvx!Zf+(bcM0d+2LV6(VoKM$FZk-=b_cE7aFnRjs9 zk#%ngkWN)&+;^Kb&2FVl9P*l!XG_gm=xO^T`LcYtwm*x{iHBEuo{M%XdV;V{9=gxv z$K6URstXW%i`kY$$6PP z4tvgyqbcjDsFh#3U5{o1vR+=IN4UPJx`A@-KH9(*QQ<$~p4lX(Qmuxe{ifc}ea|xS zxYxQ<*XfO19X7eTb#IH5K1c(-h_rstLtdd#1;GgG;+=_y8*`UxDz!7lNdJNgxP^E2v@Gce>~paiO5Qhm#o83JHT7V7ZA?oJtLg@fNa8 zTZnH-^3C4*JB-l94p-kLTd*hE%o6tPKJBcmuhfhx0V=*SHQy(S7K<0DuaKL_*Uaz0)!M_c(XV01*9j$lZ)0w)Lh*MR1Fe$d}G zs}l`c!+Qmcr!utW=jq9G1|J=DS{fI>55;yvTJ@V^QbWa{Z3H47UV^+k!aL^1EB%52 z+Z)W`ItX*pqmoeLnwap1Bx1H+FnA{3TpF~XV+-r8Z%-~ zWxQTf@U+kwfvk;4BBtVR6}+6Me`4=o$79_T!(TX1#^cnLp!lIfv9vQ!TtW2ZykYcd zVuF!e6-rw#^tPbUF|b)B@ypP=1FK(g{-#knN0^O-;~a68S>NzMTJ$Oket{#NZMt$W zKeKPAofp&H&P>^GVne8)gXof0wA|K|y_T&f={4f(V{qp6khZf8=le1{Oy7$xis!)T~EZcd3j!C=hC_Tr@H(JS~3kf82i@kPhF=yAn zA_b5b1ii@;HECc5vZa5(wpG;4G0`k{NSP~$a>CCkY%XhVHvL15eMidxm@NoNmD}vu z;Hly)Ugax!P{&OS{IRWO`ZjS-P?A+@h^#MEG*`qs=iX#aZ*#|#twonn_A#8BVC&n% zf_58D`HDi+ilj5(QdwKbB{iB{ADYr8n#G{8>FxdF3ZZf#C_9*KhYwffci&uJ8$LGX z$%7Tu&@9DA<{6uF0T5^m4AYFJz$t4MK>Y8)2VY9ImYXV*3}z6{ct5_|O`i@eJboaF zBny)rv^AOdnpj5n)F%gQ9Uq0;dR)v`Tfdien}a()mv4GN{gAsie3^4a*FwqBQ!Uct zLu_w~+y+E(zf*D#3?7{v{!VhYr;cH;lD?wH`;bK3OmV1(kM1txr%a$b(eDnAXY@TB zlh4TQEUZ;JMX1$U$f|U{7*uJ6IC)41p{r;zzod4T2*LV50zJevo(efwQ~%L|_Jp%K zK_~k4$!wQPVzW_K1xFa5Vj|5YpftMVt0%kFJMe>}$Gb_ggAN9eaqci4A{nek=o|SU zQ5=d>PG`|)Z`T9HFwP^(UVmgD5=0cHv(O<3cyFYSoyA!jDZ2Rf?a@7)T?cC-Z~jPp ziOsVich>H&sUnh>lf`$$?7-;LP*xJ&-C_nLWe_FSJkZIRSnJn2{T85tN_iW0uSoXg zS^XaH3R6s3l6)@k3fU_6o(^d5yb+BK2Y5-rzLDtj$>V zvoNPP$f0H&>Qf|&#W#J9GNF|ALYB2sN43@J_W{_24`+we3u;Xa>Ao#Nl%76%7Uuh4 z*9H)YwA5(ZQBSiph0QBTwOa}B>O~}}AdN2*L)j8%AyD23{NYO_ipo!Rh{^^#rjfJ2 z^L{iQeTZ8{%*lkgs8`LwY@2JIR8In9-Tqx-oi(qurUYjf{U=Y;&S=2RZXt%_w-p=YA=Q8te#$a0Taa$_{#$fS?q#5#Pp!6LznJYUu2EoMYxrczV zx6}a~Qe%zO>FFzpAg#l|B<6(;*7&?3=s_^XYnc(S=C;aHLXig0Z4une@2zKA^)yQ*NSf zssYCOdlZq!RD>d7xg=og`LHmX3UrcfZg`pG{#R;0rY06B8IllxUt3<UnF&m6TrqgCZz2JMhujhpn>H}y=DXgQ#9>;LqLkz5v$zB{&eUL!QkC?@ zv%=}vSHx0Dq5PEeP^H;163l9#bhU6~%A;SS#KEaSg}5vt%V+HbJaK+?E7YOV_zF>& zvQA|ClWC0ysC?2? zDhSC`@AVDUbCah-fwU3Wo<~n%$amt9P`@bEl+I=hS+@2^_#BC)bLN?nM@UYy!x~06 z0v6zkJlfu87Iu$RY zxT+-}Y4a-#31;Bf@*YdRD*Ap4LpV|>$U~=?#f-s~!x~`P9`CIbBtQLO<5oDnOP&&l zzwHYQSjSRjfNoq`+Eky*hig^_pv{b|u#n4vdoGE7Lkb17+ZVoa*odD^9|JlT#Jb!Q z9b8+nw~be9F)C$r+E@)mlSoL3s19Pqd#jU69qSy(bud$~#nu@9ZM3K=Od7#lM5kEL z0!BEhW^GigQ*}D&Y0Yhtep#eC*H5)KU(OO74WBxM9hh*b0raAgDC;K~A#j#SFQkxn zRuE>;P^{BRueoiZ+~JUw!?KO;$vCtL!(ENh_Z1gcK#Z?kf7gyu2G zA*vUWrGTO4Gz0Z00PoO;5`H@aVh7ZH3nf+zA(sRP)dZ9yin0gVwx#$z1&QogQSqwj z?qt6#@{!gB)FG95jzOZ!@w5T+(TFjOIJE6DxwnWpx1!0z_!e*~(gze{&0%J+!l*H1 zQ^cL`?^+qx+bIv?EijbmmQw2G>GO4sx=8%n^=;Dkj-RNJ>jjl;?<{U41b$tCe3AsiNo;0%j1d zky(u{pA1v!I?8GTew|}piUkhj2np(UBl#!=3a<_V(k3my`E}7h0E;J&w(q z*oJS{SgauZd=}=`%gE5Li(54m-WU2q--x5Kp4GzpiphwPlzv9lfnhip*O6xY$dhD@ zk(;1%K$E|mIOpTGBXAI*TG}b9ZHNM|d!uY`RzM>_m{LVZEExXQxi-7W4B_jLMYEWA zvkwBEz^Z&iA7fGxB7q7+(ZjzYK~qU1C2uRA>tAoWz%3rmhq4qa5nac*8ey+1j@Fzj zk)BXg*7ABulV6+mDOF`nPI<7S^&(ifF{o9P{*b!D>v#9ONu11`>R;0HVG^Ga1qy(i zSLgh$sV)|?;9oqL*tR643`=_)Q#VP}FrPmTVXFeySdc_Uo2F(gykY-T6n>+OR1C<& z>mmho4b|Zr_=`4LW~lHAt4UoGUb~CAI-J-N%kmmnRy7B5Q}`bI@qtoh!@8Z74JhF} zgZ<Q+o^@Lh0)i~8h8==&IL5wC`%`P}0S_OJa0d)@L$Nfb8X zCgAFlu~^7W$R2ZiKV6v)TO{jJvmRh+yWyq5(8;j<8)TOPY=2Pxe*VnLiyccPYpfkP zsm3*2i9SJGMpv<5-*8QJt6xIgN+{{0nk0kj-S*1k%BJ0ma=ItW4M&PaM+v^=RH^%u zs<*NL))Y^pKSPSw$YJJU@`!C4SCM`y8wn{43dA7<+D{AifWlpdK-%>CS{PT1E)!=2 zsuoB>3lYhq?&c7S4H(CBdI366)+eF!cq5ztP|LmjWJ+SN559|-8PNt;Y;dD zels4NKEVZJc4ZwKe%z{}3lPYMa=Hnzs=_=oMK-jr4{gZc_aW?V=68o`zTG z1?2k8&yH!D&>zJ~dTQUiz2c&jjFJadCDwl4#$!vwbEACg)ZFs$3SOIkJIHk|{TQ37 zbHvg03bW3`l}peQZ_rSKOWE2|arAZliE|2c8-FfGmXf`nUV?@U6&D|_;0Sco>}*yF zlabn7jeBx7zGrO)``G6p6aB89dIpKRDYl|^P zio|TLK3ueG@6?ciUDgG`&ZEoOT)DC5ZlhE0hs+gvt`#QB%%|YOMHG9W;-*baFXkph z_BRQdr-#YBFFH{P)+%~p{?VzlZ9HKBJ|GIZ! z3XF^|7#sU3ys#dgd*`RmOhvw8Qg~6qCSA65i?{!Qei8i7mG~H&qRj+9-v9-J_)pe2 z|9;tD!+MPs*$c1cBS#+&7*uLk%TTw~6sLe{8dxi%awETJI*DE!nV8e^`OMkDoP2E} z2p~}pJa6)8@?uZ4QroL)bi21fOYaOg7CygcKDCqX)YA{v>M>lPckDizx1wrpGS$hz z+~oTb$hL|z#Av2DZC=TkonoPuDvFvpSG&EQaryA2ldy4KFklZ+7(`@QL&?ms`%IS0 z+TgrTd%b018*RgdmtRZ6O0Hkc7eAx9kZ}mdX>U7u{*M#)-K> zhdCY>_f&jezxE-}ip_?H>6~pX`SeP6YP~>uWK9&K6Q0e~sml}F&efDUXe-3Kt`gq7 z?P%Z~czXi!qcHg*5>!T!nZC=Zl_-WPa6{VKFpx#4cDNs%V@F4 zM2`-fhL2+myZ2!{1g6)diZBo`lwwHqVyr&(G#jjVJ1DO+E&7T}Crj{lpfQJ{Gv3(A z>pvfT-Ji$Ct`cBZsm9%KkN|-Q!e(aV1=d$UO9r@#)^WiaJh}4Sjb9|*TJ4LGF)Pf^ ztw8CwjHXrwT4cIIR~k?l#fL-t0fw!YvkcVBDaENrynG~Y;tv7QE%&f48{XaH5t-As zsYMTgF(#vIy2sE^YGUjn*cU&DLW4&9b7v#cIaNRwhCv}a+QzM!tYIvTRi|Yd-d-=n zR8CfxY)(17X*szZBSH5oWJ4Hjxvlc0MyjfQ{LYF_h9<@;&w$9E2n{g6 z4yYYiYedjh%R`;Do_$A)&8=?^PMujdTzyX$a)#bIO(*XoCyQQ?mxvDLqvkKVm***{ z*RyHDs?lg@s=e9vyuz~LgnXLSS-LOlCaP|b?w};d^eipF!@A@A=Wgjox+@Up`nm>o zCi1Mo-P-AN_HM7hV8I`?r>;TOgOfpF2BV>b44{y9joTwYvh@D$GVt%x`@gjGRC|AIIi(98S+I2C=Z`c~`!F)4gZ{eeEAot3Ag+OkhLJFiaUb=`Dp4j=mt=DZ-z5N#|6jh^(*PEz46W)p-JL*Y;r z+f%LCdBwyC_*LIzYdkNRsCfc;{1G8jFf{=U=@0RpIw$OF&Vij6Y8YDU$hUj0G z-rwB~{#|aU?=cNIKlrj!ufYk1&!zgF=Q{cYhGQCk^#fq zDmfOjRa03J>5Nb=p7yrrVI?-99B`%RsP4`F35ql)r}|I_&Vb#FtM#tuu!S*eqn(YD zq6ujfqFsai6H1n5*T(3X-pluxVfR+AXG6!-1{F3eMK!IJMWE)gNO@yRPgG#bv=c_N zH%3{kxwOoCMMY5K<}pQ_^@A_Ca#E&pq^^OWTlK~}mfy7iE+?6d^fk7aUl4ZJ3xW~* z0KsAXMbJV69oDF;*KjW?D&v)gN~|2p)43uS%Po`U+iIg%q7QS=c+$WvC{ zm{u4DNqolzsfm0S#xD)L%P?^B`5qVI0Kb?7`3koL0y3W+34Lq? zL=oh2_GWK1o%bv z1}Md5Fg!FX#8U`xkf!JjhJ+o`0FYWs>7{wKa|gqaD4aBPb0PNGE z&C}!5DqG_K;STr%t)(0ISa*Q`f-`+ccLmUiwT7TI{uA_$mY!b{aCNqIKX_GmCVnnV ztLfNDal{h$LH5ft?TwtxkotY{&22Jl#<(d9R$g1aGl~rG1aWpRW5>+sPrfNEBt-nl zHy4?nYX9)fFIW+ueDf}idt--6x0U`QL+#_A_EJ1-k)8gRp!cVdLxak{LGS-k&=ayp z{y#F+%K(S@_f+q{J=Ieakudp}p!aw4i2oMo^>gTCj(yXqb$hC$?%>*JXf4$j@`&Kp zDm-MZeqi8S-oQh2rCXBCuAq%yJT*3;ET>v?gI8%}7_F$B^2?EC(ju+YIW#j+udny| zKH78cpg6gjXS6AqIc)wR!;^d12sQbV{n7X}5c?VmFV_ZXw zh-=cGJjbmqSve^ET9x#MiG(5a#z8#FZ#|94rs$Oj91`RKLxdofZac*{sEIItFSAe) zQiSKsqu-Bp^>`I*qv=zVBhzbG^VxpaU(sMdyt5ql#|g z0;0ew0?(wgH?}}ie^71y(MUWH-u0V!=?CB-F)InIRA(@bgb z2aUriXyZgfQF_aMu18*vpRKf%UKMdoD64OmY-J3z=qLbz^`(-)8 zM5{5bGH)^JVfqkqv1vw504;yC`N-3Ni#}#Ioef+dYsXaxvto1W28u?@OFbeFKwBV? zOysLk2XIevC);YNKg6r2i(Uv}N@zpNd6?VTk#hd|cZen-slM*wR)^T72tf?8hb3EG#* zvw+RkIlEGH^YHb5`<&@9_kR;K@f`V_>BWIlL5ogAkX4IjgKO(b`DWV;i+#Oac^v?# zEVdz(Bi;Fxy5RWrnLYvq0Uq3he`uBD-8&V?f_@gGXx9A3A-LM7Q16|i{{5e} zZP6+!8U6N2H=F*G2ExpLx>Q7{Y+0vsB71euzJoRJv~0|O@r5rDD553SDquYoShb9% zOsS+n^jR>$gU8sa(m=y^njhXqCzQtRTsLo)oHTLefr(zjaWJ!$V z<;L0ylMn1tB$M5I7rA+TT7twCz8#CzCykp{4LA;(wjOSQie0b|@;!5FLTT~E`Q-_g zic^0jn&L@f9?Rm??|TLI)^!2ah2&DT^x3l8Fg}zBx?1%nPQU<_aN=q66lN8;aZ87U zs$0FkY7b;%Uk=KAZ^BN2)peD}N^EsVvSe7c#rO5|Tzjr^_Cj%<*ln5B)MAmu=8%*I;Gy-fZfD zGn;^MpR--fu@Tt_HrlpNoB}qK)yQElb|qkQq&HHkH)xOXMH2R_NUE>%&}0hBnY*GG z*+7SZZeD!3*T;^It1E58?ybAGSX?UF#3&O@Pi|RxJ2H61`==aq-$u|u=Cd4w{U zfUP&ifT$>o4od^YhFEBPq49CarGn^(+*jeCq4IZP> z7LRxyPTlic|8Y#EC*>hHS%GOyMG|(nTnz)eC1@2>??LPPgOBJa%`UFY1eDB%r7)uN zRXvVu;q}xvg#n)P7JWnE9faeN;fAyGmKB$-?ZP8&>_Cu8C^U4oF#CQStRIo{_M`uZ}qAVe1F_iMGg;og1R-Hc}MbJUzoO33s=&Fgey3Fl(5hYV$gHaQ z)@o>6c+_@o&B^a@H=AbST^fHLjZCZ8C;~NLBSf?gxsiIS?8x_1ygZq677dx^o=oDi ztG@ERbKde*p!yg9vi)6JlCG?zd5t-Zb>7{UzrK$%7hm_WNPmSz87z^q`jnODMH)_y zdxI-Q`-L~D2=70wLQZ&IwBK45|5;ak=KrN-Ap-A7H|>od6WkcDsu`LfhLz{1iZ;YY z+>*Cm5N-aQoVINraV*iG`MBFT$&gAx-{Oovc_o#}gw~|=y0}K6>u2b_+07Z<9tjn5N$EJVVOtG7H5Fi-X{OGK69P$0U0(8y*oeSj8`{Wx zlI=KA4IYQz8qg};JRvA!bu+4LRC=8h-tR|r2`a=? zIO0Xwuo^JH2nuozuCLUfUY{NLsqC2(Y79ZG3U%O%PlcXj#hQK_U4xXlMmOgL`#=@E z`E3S~7lcGbHMhSUFI2g6=(f7T=-S{4#_2)C&5!q zPTUKm_Je!T=HxYpm%(Pv(zlM>D=h5Or!2`AB7HsIF{8ORsGnMSTbCcoBD{r?wm4+LP6S%0ybJViCUd*ox_%nq|&n6N7ScY7Ld z)#fef1u&4bq-158)NQyhw%V~y3OJ2Cngy@bRQSj0x`*fd#W5-phh{T_;#QwxdIjz! zt>0o67;BCcF4Z{S+xp|2!VX4czqf5d0g!yQ)i);jY^%TFBgJ2C((yGKvpKHlzSvS# zyk1o6fj*X(^8%whxp5^Y@zruFpVvh7lwerO#-PfgHX*tu7Nye5APa|0WUr}&k|zhf z>?0RiMowMPn@HjoL(cYuk3yQx)>gKqAwk{t6Z?LlCLsQD0U8&yWQ@9TJ9QC0h`e%g zv`EflrKmnmBiZ6IRFKXJ# z-NBz=5s}MIYRPKVd#f?N61Jv^J3)8LeX=$CsN@Fd%e5og`bGu;zAfq;^@`Xwg=0=jTDlKo3sisC~OueOetM{EY-!|^c|kDNQZig z0<2$hS}oDi8}0w$CZBC6;xIH=L%tXG!8ZgWdj{iVnlnCBc!@ zn3@`D$%!C7#q>jHN}FZzzN^Q%ul$94>bKxp@((C#YzTIoo&3kHU1tH>$3gtf!RJXU z&1fl}xm2kvPX1o-0UK3V0sM4#JX--TLdT@>bo3qDCyJ1jW&zAcT*Y&25Z}8$BviZ_ zgS3X2nnuKF#s|_58!T=b+}C4LhM*K?viIYvVeunfCx!FU;>VZ6*3D_Vx32h^e9F!Y z?e50HJ-5Qa_K=3I-F^<)%J_vI^~7HRe*)i$_xbx*ucMCYw}?N$H~I;Dre*%VdVhcq z{WtIx{{?&uYI~Nn$-h`*J1itN2<0~10!bq1p>t08;c`A#$ zVM{0zz%UMSbfU}`Oy}Jhg{xWnya|y`SKXTp-D_k6)amkQ(X1^Cr^de!qckK03oYk3 zF*l^ksWWKti(&bWo%1qyt{-yDG7scu+J z;ZVfDm{F`W#;`}ae0J!hW(8~xPP{Xa%O zwc&M_zse;Y6pu{opI+LpbD&tX&!cmp6n$t=<{vO zCZJ1K%V{CV!;@s|m0uED(K@(3%+aH@UBG4*w{A|h<1nF73`twBL8OIyH!;7k`O4{J zIDjNGsKYxE;f^TG*Ljp@fuTk;YMzSe$TiGolW*`Os4Q%S>UX34o&}E2n5*~k&{XzT zHFku~y2FJ5e9i*j@~~j)>q<{hW2=9S5s>i1h*T@4j~BtyCF5690_8T{#FG3IbX$SJ0P3?HBiV!02Y z(&&I1;znYl8|eC@@j$<|BnSm?Clez@PBQw7{$EEHDD z&rAS`68C}RmmtIi$Ary8Mk}!JZVZ?A(JYX*6|n-m^QRxgb5C-OXb5N2OpG(RAgZ^8 zoK6S_iEK0l@leJ)MwmUE0x>LC#J`9;B#xVcrv7OvfT6K9F%oZaWr2?(pl^wpW1i+M zx@zeYk>$DWj6KEtEVFg~k`#FtwHEE%vN01VrO|D$^!Sow^z6BH=^jCMfkIonF1cbCtPST9@vJ)CYGSy$6DGcVPm+)Y;pb1g5foYB7wuq4r+<-D#*%t3ZaoS6X9k$?6d z8hVUic7|zQMvdjJs95ev|ZmQ77bMHI|gAG@*n-m8t3~~E(Lk!V9*x000EkyrK@j!rGdha z-2Mk)=fIw6yL9Q;w$-t1+qP}n9VZ>zwr!go+qOD(GU@lj%p9|4f4|{*>aKOIs&!Vi zXDBxnhDW%e0CZbK5S(==a2E}z>uP(k6}bh4eO$Nv{AoCYVqo`>g|d?;$s*=1X51d; zUbvxrDvfTDMF$D>7KweNq& zh_8+PyY3+vM@5NZ9ftXVHX>M=cmA2M&Ll+9bdTyE@(ev564QK$ERjfCh_~p>j&JR` zrH=uUcMThu#~0bo^Q}F7JNquMH6}XiuCa#X2pV_0fmV-hVMEloy(IFO zBI0)64_sbZ1umbo#@1?&NCl9fS<=>GFtv_Oa;U3#8kRiHIPz)lUszM{<)4Y?&36pB5u-t70ZzyEs#a1^HES1RQ73Kq{Vbxl6`*N#S{$by1DHjx_&5fmK9ed zwtX%haPzf0?U&L2XwNs?h8>E5zuHst51$+HTUx1nPL?yM8iOWK*AaZ}-apo7+<#b~ zX5ZE)U*Z*@WW|}CaNRa^Q}Pe;qZ1OEKL6w;{bfyEk<%W~A%JT)Ki}CXF^yGaov8m; zdw%`P({4ZTB!Q&A*RfB&=M(?G%h}BTEWsRToZIb*B7EtVeFb_YS&E0mjPKpBgJ({DxQ6F<ev?{QBLWaW0Tv5{nA5#Ad+jZ34cm>mv&%`fo48lMuUlFa|TtR z^)jp=ZpAe07~60?mPM?=c(tA;OXz(_ub4`(Y9*YgBE77<-nNYUOltb4dQsC@&5YrX zHfqdhYYa&bal$D3EyOwuF@7Pcc)Mwr)gGRdiuN9CUJyJq)#BA`aNop&wkGMR{4%@F z!LI@AJd)7)dk&un-?NdTS?g4O#sdx zo@<459gYK`2KaBu=-C^xf36H#^DTJ!UL&?0=*@n6lJh&@aWEPU#8XRwvWyZ$QO~wu z1s%sSS;d;nMQt!Y=DXH#;Uev zz)JYz@Aj1+rQV=b%PbUMSxQ>Qo8Va%> z>bRULf^FUge_flvc72I17B~U`R3!@P{uC^p(TcvoCtV46dGe z@y3a4hf&k)Xt;G`fG|+E9;$_}Vu)6QiicOd#Ofqz;I>QTl0vi&sWY~_3aCn3fMt9> zRY*a4i0Ml7A-_Y=nyb3JOHJ;X7RX|2KmhO}lJq)N>LX>J=qIC`3%3$gyunzqk!86B z2dBO`bb4E)Ft-R7UN+ka=tD~Ay_%uglV z`}HY{V~&{bv*o2|tOuJ!A`xYng?# z!w(Y(_xRV42}Bo=(=C$qkVJjWfN%V}7;a5%qHNpdFVeT>&osc9XkK>Ie8N~VQVNuAtpfAOGY$R;toHrXQ9b-*{( z05DXT>7A{>Hzb)3NHi#dYttR2^{1QN7k+6?m{mhs@jz%9=F@50q`6 zhynWqQHOQ^vnb;oTqMX>aOjdQRuB1HWShiY1N{14qSx{7t#15;f>UY0iXe)v_BIg) z$h^1IeCU`2^-^j7j!FikDFeYrj8+m?jesKpp>1I(V-zVDX{}{xnP!v$<1@PgWxHa0 zC3vvL*hVN&Wz=O8M!q3yS*8rNw2#S^n-AN=;VU4p?7_=&UsituWnExmk%rSA9C-|5 zYg(NRU?}?*9rwt3z(H4k%mQn{Uag$U8MZ6W6VXl=?z5ATE1{Qo_8ABs52eJ3K_@)c zr=*16m2Y(6Q4Sk#%m%hJl6U46^Sd6%T92!}R8-S9AXuuez6}vR9*4m*qqS7b>(#~K z%2PsVdFQ@EjYqShR@s6{e@1KGiJ>nQO2=JGh}I7wQ3#EUxH}td+9_5>+f4}BsB6edi;~;#(IBi?`WM8nfJ&ETN+@Xy#+^$l2f085dXW#@@{4mnv1cHs$P+4!Z zNu@mrshmhQS-R8q(w%WlqIeu@(yrV*_M( zW-V^Wf*Z;CJ^;c8$~wx8W8{zww{|@VILwjQ;4B}_jbdVvWAHdabgVozCm_)6wV=uU zJwtDO9Ee4>%&Hz0?JAwD>~@$!KHCnI>|&7odhL@|p5yp^l-DOMxS~(Z*?sMBIT}of zJ;C~^38duv4xQ7resTN?|MUAO#@BZQLtY9P1O)&L;QQ$bKnS24{&D$t{d)}i-}K;r zw&4afZ0y$Akv@HUKfrC?1Z1ry7CMxPb=Z9+V2EX>T;~tw1>-EV&^7KQB-1YpzusUa zR`FhG*12$GK^3)dcyZv&j?(hve){MXu0c;m1eut%TOjBZX#6IXVC9<6nXvdV)1=q) z`C(VGte`O0IawcXYLeI2Sjj$rY|{2VXN`7~Nt@rVPV6uR#Yz*EN|SEQDPy?iEdkJJ zfjDnTn@>D{xIyB*@ zhL#jY5xkuOnsK`JYy(-LcW~iRW~C+}Dt4#^WoNB(PGZsi!dhH&_`1G4&nly2Lx9${ z+|3$#WZhLkIp(E3IioywOeq=V}+cGw<=Ug4~kry*%lkrH*l zuZvkjRnxksTD7kxv{Br*WZAkNylhf2Ii_`f&X+Z>#*pUw*;=;PqR{dfI)B4mvfqLo z#LoIoScvG13zWl+)ab?PFkQtb#~U~8h{suS?Xm!wS!zvcp*F<$oi0m;<1i^Tddr^CLdSr)|-v!QMZpSe|cT%fj>f>-?N&ybZ}` zv0STBFmS4K!z|&+`1#LkH<`Zt7`UycW$q~f*uB|0NVAfOf(tx;EL!PAwR1TpF^WIv zv>DydM$s^hFO7lB5fpF~743f3GyXdCXhsc6HUmXlfe9|`6#T2gNuCI zO)?nkxxr8o1tif+3pCF}D3VrO(qEP2WWe!^?p|A7KVNYYb+qh!BkuGoY?5BTiaE{X zSejHWn4aLwD^V7&;8{Xix!F68ciyF2LA1BtDECmK2?v4d;u^ zh#HhQER@6#z`cmTxVd*m)}sg|d#*MWWC0NXwR;}_tV zyoYm?nz2#dk;{2E>(y3F&lA`F1QtE^@@?UjujO>X1_of3-47}XWX9@S2IF!4+EVoh}fK)#)Im-WcW6rVSAMN66G@C$dKl`=sku z-5;@1e~=AvuGI4f5q+QHV#y=@xBC!#QI>VajQ93+&dVPK7Qi$pOjGe?Q5x(^*Gq%u z@S&bA#Q}~d-Af2WA(r@w$5g*J^$dS2a$^IzG8IZAhl|Mz4@h=l#kqG-As^X_98qT#w# zh!vVu6L0p*yWNBeG!#COk$$?Cb^2+L8T^d%{ln=%cYXPXv0?~o1-y41L{F( z?%2#-TcmmQx$PhjNLc;|GOjy40yj@dgoEz*G{?MyN#Eb#uE-QoJpBQj_cKGAwiul3 z1$Of;)@wlLG*uKq_87``?t)wZXrZqz4KBi^l<$r}Eo}mBpFfujQZb88?wf>Y)bV=H zJkF{qxv6Jl5T~9!F2=D9Ux==G%xya=9MU4$p+5xjN3XPJ@Ao>C0j5^)X_(cO2fcjL zg^-|t5!xn#(++m9s*u6hnCFPTSMQ#iCwL?Z@$@in_YVlZ2STpIuT0S- z=dw4l5O4#qHC`iZjMZjZt;Fj=bQV0}+B_qje-L7D=<0NYcg;4Z#IvHdNdxVhm9UQdF#kmwl&9;{h&V^i>|SpnR1{T9(K8h5V}gXTa2cz=3@q4@`Dvdg-yVhy#{XYGvHZv7J&kRrHBkiL zZzB=B$Ol2Tmi;4{u@4srh{*^UihWoP7jr6C^aMkK-IeQOyTgsFFAJoZ%f`cgr}1rb zYwN0|W4uH!o3-vXY@V7(LTizwkdj>^)+DiV?Tq#(`;+ovN(BDTXJ=ef4%rUkF^70F zs8SLQEuG_+N27`)nk9E+(=}4fLgF9rZOsH3XddoiXsr(zfbJ9g?Xzn^3i*zkF%~iz z)($|e@Wh)z9>sCaD*X4OhAsX!fFK-IC?f`NN2cfI84QgvtE}2P&FwM{A@gFDy58y4 z12j|NKa&hKr4Hf%I~fGkR_H^9Cl$KU9$S z&A)Smpem`nD&XMzPX1Bq{&Kk~i`ZAkWH@Lm_qM4JZ=l&^=2;iRbA(-2)rw!xAv7U^ zei?OfUj7qjpqam7)A)N?8t!V631@kcXLFWD3%!Wep;7Y~G&7JpwhnOgG4>EEe+N~= z&rCM0N?5Z!@ju|hJp?)D`E;6d&Fn&vatt9 znUrC?tcCfWLH(edHQo2ACkW8mGgB<)&qmK^qlb+v4#8x|p9q{!K+t_`_9`uQL~ji@ z%d1}Z{^yV>DBRpTBD%qBKC_(SDIh^-s(z3_%J}tXCb?vzdV))>v4dm{ z!z?@__Hjm97o^~9SrRp~&yi{fJ@^5}9DG)oX8ECnwG$AFHq$ILt+t!XI-^}!{kS5n z6+}4kuomst?yQVH^CF`U+OuKfLOpIItAxb+9COl}O*rs`)A!QYNNV)K>Go4_&SZe2 z65-y{j2B%T(R2hC2@hesPoU}qTtYLvg_VW0N7R#qR~`%J;);e)_=T@o6&CUdR8FrX zZ7K1YdYmP3SS5-x4rX&0F{V+cSo_*e+o&88&|$3086(Np_e^85zVJhMVsw{$D?uSu z&M?zX)DZB?M}*_BP1~2(N%5$R+Q=M?88b7x{1?1ZUALk`jjd2Q4xUkLPwX_zAgWk# zvN%=o(?Q53%E|=iZy0pf14C@ZL`J9c-U){HnX0b`%h z0b-?(cf2$0&hYk(3bP3ttbUV6Jl2fS>ON$}4o~eJsvS&$(a1z44zm|Md2KHrRvFcQB7d38mXCU8PO5 zVc!dmpQJ_NW#f1fWZb2=p`ax{kq!9;i>BKRI$OJpTjv_2aO}*Cv1wKcY7`#VnP zCp&TsIQiotb?SY<+9}$%Kj=U~Tn^haRT60>T8K@25{k)jPZrV?i&6Fm6)QNsVnZe% z$SKA9zkkZ}&=R+=@|mCmgJ`L`b#gs)8bua$TgKRcxB?WO3%1}Zq}!ZmG*AZqb!Nit z(*SVPql!qIcSv{a93*BO@olaA#=wqGnV6THBw<5M-Gt5m)K(R?mJCsH81{!< zPzcv!E+rroFIdt?L1dtNTC`H)%~fC_7Qs6`(ZZGOG6$I2Jfw5)VeXQi1^jY^Ae<1R zC-VrQf@J~C!h4tZn^Q{69hQ(s*2G809Ca*=bHh(@L=VC6P~F@#JSFZ1_LB{l`y-OC zpcPJ$#flsXnH~N56CQFTYrrqYZ zNWjPZHzMJmq{X1dy6rwYl8>JLmjKfpK?zxMS;s;cll}TFsQ8A)#HK?wSorUiwPXz^I%QR7hPKJhB-6_TLECMIe+YAT;~^A!6mTf#-n5_P(Hz~&yz|$|3j8aM##Y)RCz+X9R`e^*I^Az@2Dm%7q zvbXVhKGb*Q!#XT<_P-*~D|PjP&&fwjK6)52omI3{if6%oo|YTbkLTYjO57+dR*QFt ztDZ}$keYn8RgMBQ40A6lu2q#vFn*PJI`rHAaEwy(v7@GK0(UTcI@y+xb-m}j$5!g0%? zu5jU*VT0KQCZ2bsUT1)D*uc0uWE$Y2Mkic$A{k&K<~`15yeR*D1YWqB56F9+I9*Fa zAICMDxjLaraU_KR7-|u}9A~*zT@}`1)++tk+wxa4$SEoYF?-w)Ywf9-PSn{Xcs-E7 zXnxg$MH|6x_+k@I1i=Tb>FN_cPYCG#G$(pXxVesiKT+eATPfQ)g&a{q-ntjL&dp`S za6SQTCE$n6yP5)?JQNvK{k+K>+*Tj=i3$%=f!8Wegvi1Fl2A(J`BQo`faU1Q!t6dl zRO(8y^;(lA4^$#~@-Zt2%Fv()+NKEF$CekMP5$@;^#Ci{_AL9jBl@(TFWIDku4^@S z@ijItQspM}4$();L&O$PTa*oDj6&pBmpya1FL-rgQ(E|M?DBavDx{%(f zx#$7PuM7*KKnYvvF`3%{D>R_VKS^^@{55O}&FL^JKABBDLBA&@n$bq+HPhpc!=GH> zhz>#RIc(mnrT;*M=Uapb1bL(@tK6%*vEs#tRJ~X=SvA>co?Qf32Pazx;OI*r{r0-k zptn|#QH^a}Ag9`jW6awVhaw9_z8$7_S!d!wZcA2Kc5+9P^)d$vXEr;Hb}oY|t?b}% zx@&GRp9~y&_hn3t(V8hLO+in24E^M!Y(&s>Le|LV7fPWEk+>P|GiJ`V1Ee$f^}B#H zRXPalR{91Bcaw-&1Y#ovH8R@zbdR=6b;Js{IKrBo6!&1fi@ZD5)^qPL;#7<&VhlA| zwTA%Zh2h?koD5>fruWpF^>slorF~xyYqTxa5Rhb%3hFk?tf&yBj1xB=sHXl9Ept3` zf9C{gtk?NbN4akopzz}+Qje}D^n9&RImKC_fJl?H7f3+VD!|KcFi8pc8ZJGKvfNeu zNusIR1jL;>Bq|^zA1Xh6?vU6a;`fa`YF|K;X_|I-|jq?~%<26Hw2l~1MxkVG1!xIey4b#)P zhi1TN<(O63^Fn*I2vFfXT>(i#Xi>JdzP}ttOgPkUFv1d7hCSAbBs@`%o1+_<7J|Eh zt{!Agn6cNaCPB(Wt@&s9O?xIBYy$a47?MYL_K-rS|MIGnEQ`sQ$Eq|A&^!d8v<{xh zuOE55zvEiE?tLx~yM2H>H&T4>Yv*zDM?FkyilkrNDR&1B-c}zK#_)f@(GQ%`t9qBwIckXcP(w+(CT9uI; z0*vHSP~hd}pUf)!P)1Ym{crdR&4p#T&7l~rFqjiWiStmdFAhVecc+{5+m5E_^M ztQv?Hvf>q*epTA@&;d$`tZ(_IpAa zb);EG8t}CDtY5K$nXW@9WWHEOv)rbna698Pw_c~$MwD7WcfCXia}i=QCa;d$O$xLM zly0Fu(Bd^5S-vcj*Y^???AP^!;=D>3LRI^qcwIz583Af`IX7AIe@MfA zs|{n48wJ0)C;kJ{rK5!?FqIXR3W3jE{DHEC1flZyLYwM%%4#El^19s3nnytm6%I^D zbmyV;vy+J%gyEKKMnhwkgKOrr5zk_{DsxI^1L&Y$Q59VFebNF>)5+4 zh}W@xx;w(~3j%7r)08*sGX0&0@7;CwB)c=BKL&W+wY`V%Yuw@Ed%fXbOkT*UNRD5> zMFHHu69xYSzXmn_Hv+^J-mzW1_(~Dc%--e&h}hP&H=E^CHtd3Y~Do6hY~*{yZqhpWgi}W z*+5~hQ)&*W#3Zk`vC+JuqW(8;v!+O6|9S1ql0#xb0C%#c@Dk1KGlp2}0}k*%&VgpA zL-}nR{$1B9@c_jRZ@f2daTdq49_GVZc@^cpeN<25qD80lz=8JI{$aUwa$(xeh@y(9$Ws~lSbO|j z+q>JZz(Zw|$8>+Vz)WtFa!1q>cg=26dc$%_KH2!q7EE7?mTg+Pc6NzG2d%DO^KIoD z%_@Z&(WgY~BH8;V$<^sCb#R^;|7>y>?4HAQf;cZfcL z^%8~v3uz_9d5fkZ#7=>FYMXG@S=&_giUs!NDvsGzr!QF%>!qIq<>#TPL2_^oT;53Q z`7nQG`SA1IdGt$w#>B8wp8qMPvjh*46foC=mKX3l1HP68o;;8lt$2S$5z|YX*bMRb zy)w{j8D{0}`<&HI@3lLN{)Xe&jC0miOjxV)i}ls2*dbHUP6`^va6%Hskp!%d&0l~v z_5&c$SghIS$Rv>NANwFEg}*5$(3#;M`vA7LPmZe`!aKuXS+AlFv9Bs}9-CfKl zOK4^>LmOElP|3M5=;iyoz{yiJF-BTteCe@$y(3R^A`ksX7zNI3I@ggT0FjGZhG{xt$VhJ4-9TD3JuS-{E}PW+ zvi0%}?!W?1;hVIiK1m?AA#p}%EbP{lbbf~dnLZYwj4NtjJ9iEgD$n6}R-L}R9Abz~I0>>q6nDtGHwuzay%)U05ux<2M_ zuoQFHwHq*V*Y%ok^<)>1EgnBvF=4^_3K6-5+H;-=Ev0+`I^Nml2S-WE7)aG_n5y%U z7m!+*VIaZ1QHv)OVxsmNUrfdqaEhoDLV_zGJt#f8j|mh*f-&SK07;QM|0q+@3=kA+ zAf=c*%bRf9#;<8Mq$rB_HD7a%3P!`S_?hr0^=gx*x|k;9Zs!(h%Ek*8^xcM_FjS=x zTRApntv@H5w02vqCf9Je4uvMzuleB0NBSmTiN}=l-?%UtS?anSMQPCIY({xD7y!qk zFWz2ke9q_ux3LCC>WC!+735984-~o&=rdzXvHBg?iWDp0O2ftc)dz^En*l9u63hqdu()4XQT}Dr_;{IsLpMJp zDyAvC=#mM;%QD09o{*H^VAqeN32%;bc7M>RLDMaxmNYjvzQ7vDtv!e!6_CgnVMS0T zhwiRqE;wGhVYoST7)~?E96!@b(hU_&S(n*;9wOn)wy`~iK(-ob>@cXiIXq-H&mWB zFU3&lax>Fo?VR}|u?6FrB-FiT#bz7^AP<&}!U>o|TPJ8rFAWsHc`=tC zNuP*%prFYLiaVVOIlaF`E!yednBbXK{HTDJ_yn)OaOL8yO93Rc(mtx0;aPBHAWh7K z5hg;KTssAHiXLNy6Mqc7VGhd1=@+xfd=TMTk$H&coJ=K0s9utj5TE34qqnM9KERxY zP*XsM(TNk_UdXzZn&d#4TxY7{Kc!{O9p*K!B2IkmyH+4Q_3wL;x1h!?w8Toc^zs*_y3Mk8SPoMKMQk2$g zlULsQLfB<&CUQjtMrU9=y@0i1t%*?ZGx+(S44AQ>gIGhXE)#CCM$f#txMzSntOG1@ z*QuP^1~2VF#6h0=nwP90Vu_PzEuIqV<%@*T-+o28@*e44)aWS{YQ&kXU9uaGY3u+r z9tG#1s5AtObE_lE?2ufOMy2C55Ah~QH4ccTPdDUn=MFYoVXDNY)5KfzcAmUD*u>fjat!f-b{a6WG<<(3YIE7 zLBDJSIS`M&LJJk3AHP)QR!n|D%6@v}uSh}rIdU?I6N=}OwfH7!f3JM%`f~X7hsfrs zdy&USwb9z;uWSeQ`<;I}GbY?v`8=29C(pW@25tkfQrNN)e3d%9u>DKL0JJ%0Jqii{ zFbDTPWj)szU}f4_>14boJP5A1IoV>6*`s65>OduODF=W>IKq)r1xwu ze{RqFt>vbrt?l*&T{(60F4w>>=jgQ%K1C)l6DVY)fDAgZ-;ObcE!p^{R8>o7zj@!i z*)1c}P1?_qD1;PHAM(>kuD_E`?8)V)zG8PiC>mftLrRQMB74`Pj#;8Ut9!!%XeY)I zM`+Q7Jqtc5ITp(p;s9QS6Kl~)fyP%#h2h<}X|aEs2ehQ@_l)#xn;;J91wN8S(<3&# zvi9K#X1}+!xv=SmEnZTvAJ#gDos{e%uGc$}D}T^gJDd&!gVJtY%=bPC(!vp4k&Lq9 zjIpxs&S^&;i(0s)m>PdKeb6boKK??Fsm&36CtLFAs6Ys=Ro)=fz~ff|jO;D#_jKHC z+v*N>m^O=y9_W0IX&;+A@fl_bMiR)eaM}s+MZmmC_$#gk-2#V*WrF9~=;XU%ayE~; zfZ9<+;=VcQ#Y7q*CTf)i=8U7Rkh)xq2+m=l+TW}sqq6`)sw&0|5cl^L{qfn<%%q>wLqA%cfP*dqJP~2op)`sqt;C$1my-Gq zn1W;*;T+=NhOHOQm8VWa1++<{;?CTLqkTx#)PZ3=eh;*5z?AfDy9*|V7NlLE?b6DW z*P!o&>r1p33H6gqHWEwadzcAZtZj|jsGR9jHE=#YvZw7_{*axrIf;)YhBJZX4o`k& zNtt1h@uvlKyTX)<%JK~O|}7C0GiQ~~)q9ldx&E!-UcV&%(?3C443?9w#g zs~Dg{JIA8e01-U?9(BMd<3n7(@!Kx`I-^jUgY*}*mDtT26nuJAz~4VCIOaRNnz%S3 z*f5YpIOd8~WrJKgXRPEWMyR#B>*m6S1$(SC-~(2gdXq;^3J*~J#BZXD`KiNdBstv2 z1cuK|;FG&slQ^H+8`Wjbb9Q*n-rnx!$Rsu!k~G$4C+eyp-~$>qCCQ&m&UD21XeEHM zXr%wND@-)g9&cDLM{FE{hCkmqe}zckW6AU z0$3(RNZB!&O}ksqJ-25($U%&zx7Re41V0tC)31iR1R^rf@v+rHrT$GWH%aEt{L`7DJ zpA@z64W)3DmX|=6_j+nVUpN@>F82zcPv~XdpzH!V6~^o!n6~xnOV3Mq6<_v~hhpuo zdIdv4RWw#D><3O(7)((Lo!M0W#L|T*;BxN}O30+K9;ARZ!urCBaMFqJG^s@^zop^H zCj1mcG`ny+mgi5D2pR@62u;>Q@ND%D`mPuFfAwPYk}TT#pF%4v|CN|_%J`4a3h+EH z`Kc@nMx?`VYXTP6gY@1Q7MTq`Ds^Nr0fV4y!shB%w_3m^#JbF0D2CKiw$l|E=1*U0 z=yU(DbVoG8mScj5+C)3@by0J&h6V(U9J1@}s2T^FU#X6ykO@toww2NHv?eaL>n`aD zNXuRE#R1FQ30;XPtkaC?NN@f?t($He-8zQj^7~%2aGf3^7(1rgiRw!{w9Pc%*a98M zZ)^cbGXdx~wqVLa#j5eHz5g3qKq4+P2rQ7`5WgS3aM{un_Jf&!2`S}(Rgh0y;g8;^ z=EA%VjmIipM^xXmc=5;M;qs`a;4%okj`wKf7+2Bce^xhfeYAN$FJ+`4h;pCZ*SM-X#~ z=-R~P9Ag1CqXkD$V8HO{fXbVs4GBFT>=5tn>^x35+kt%1PH0o!;MqWAnNvJwe~P}Q zPsxsBhNnyCsVBrKpLVIaDjIs~h4e26?2liP)I z+aJKBFbpvG7yU`U30f%bLI%U8Fx%+HPUim*v`|yjKVu%E#yhi;eI$cfj{~eVgdS$^ zI)B5vXe{ZOEjN6JR#d$6@&7Bd@)uh$@Euwy_60QsJ5K)_T0yUi4y|oi7gnNHueL@a zhqeADXwBn5XA1i2>#Dt{G(A_x-*YFH3t}0ELwnMdO5};0PQW#60fhdN&eh47&&GD< z6*BJgY}atBnr1qEBQ%?nzFQ7M%VkJW-uY;tE zM3JrkH?%UQ@;9_{Q2rfSA!}Qk`VOreKn~d0Wk71)^0_g8U<#E^%a#Y6LsW@7On$>G z*y^$KCwa}*L6zT{uQ$+OCP5Qn_!m^GtwPYO~RpTRXb12@gT(IJ1(P+&W^ z0nbF(FiTXlTrkSU-J3J4w5|ab3ofNruRfU=UeNzl5pp|uIsK1C_@9C4{}Ef@glwgn z%v~>N;P$#r_5V_{7Cb-{5T^_e+_(<_CZ5AJE=@((l%HNszXip3yy+^k%7VKGtu_0|efuKop; zoWV%snV7$Z;Tjq_-Uc+`B*zHbINY;{&c~&Y0v;)TT$xHokL*@6Q={ zFa?ZN`y4-O#}~K(tL(1gnY7_i`)tpwY#I5t?;?DxV7cJbt%nWPOpRhID*O+2$jS(G z>F7`U0X6X0;Y`Q4v!ftPt-gfaaL+D&mOw?96xrx6_ylsOgu9!x<6!^S|DYC>m5iRp zl=v^dt$g@8o_*-NX}ElI_+!U(p1-LDO27k&v)xc6eF5p^ZJxO1t8n>~@x54fW!ih8 z%D43tE)o20=QPQdL5l!qaE+@Ehe^Fu`KH$We}ID*yW_6@utlM18@@oFGsSr@(R3tY z*^Gl)tIIs71*!3Z6jM*gC1i{(ZXObGu*N*4ERTpisU!R@EHk%vb~HR+)_1k<_VI{X zHBC-+_sjYRTHt7tP(D{GlW*pfY2?q8gwOKL4w+2znU(Owl++;vW*koBhA>pZP&ld| zvS#h|CHfw$eX~PiG;^E|O8*m@6lnX_fphXqF104G8Vs_TasP6vh9BX7xhH z?rGR8W(`iZ(N6nf9cj00=G`$buY0r@9dVnqp4xB;IDJkh8-I~f{ueZh-|qPbwFk{a z%bACMpZY{m^gXDE)W@&6O(6@Fk1X;>ue>EkfFYc&Vv>#dIjjrKi45|tr(BGkO}H7l z_E~zWjPi;&$||##Zr4e;?+{66;^reCa>2j$PPtnm1)B8*0HGSoGcK{)Sa~aNlx~hQ^XeYj11~cMkSYRS9)T)t>chuZ19jWh~VKV@F)h{ zp6Y6^_)WA)@hn=%>j)qZLddjYE}Y$236?r$C(s8#Czwm?q?w618|bOWxRETfbXQ!_ zgb^AlQSbQ2q(jZ=oSy`vrG}?8h|c|q%;8VBv6fWulyoIdllBq+mV}7Fo%(adW zcSujP);CW)44YiQ)GfhN9FhC|dWa+2IS2Pg(@u9Fe6+J_U0%!xR30V>YPug~k?Te} zZxAz|IL+y>wVNrLYMU>yF=4NVz@+utVB0wmEwb|rP!Z2B{!eaJXT zHTo>4{te}uQ->;h_qN=nTQ8?p#7CBwjKU4HR zo9%Nynz=GLemb>!EskV*w8siTI1zF`-Y^c8l$<$D1y!WaH6?Ey@n3o%I@2IUsLz_Q zay_?7Q+?BuiiN*rnJ=|T6z0t|ee`yyUI{69E{5ztt>thX5B-uTNm`Kp8hGt@QHDIF zH;HCVfNGXVJ6jB~6$~FivYmJxaAwHb?$nc!RlS=?fWz&)bk1zKzh5BE`jLu?dV5>9 z>~4C%i6bUm2LLT-$I z@f01YU3a-|U%9snpFI1F6p6JS7xuCog?s&xMaM`&YiRC-k45Jy$PehALN*~_{zusn zfziwvApA_=FpbI9>pm;B39p!pD_=Yx)+J;`$fEU(qVL+x&Kro-Cio#&>*FZYpx{=Y zW^&`&urF&S#;}EgYP;B2*{8@UPTqp+M;iGNuDqiKKZSIRgF{T~LZYUl2U5`+P9o5= zJCKWRzKlb~CiXF_WfFkL!osz{$7#{1+1otz5HsuJ5X|`*&6MpP}h> z$2EF{zoF?qrti=+sk*-Hm_8$9i!muZ1*yzyX)4Q-ax-_mc!KNewa%(--9OlZCa=c} z%NXJ73ksyAAEk*CDXierM%9HXm7oXq7D)1z z#>#9;d?65}tPr1)q)l?Ix+ASIK{mkO;(oMl=01erGT!WM?7%33K_ zL51brFC!LAHGW3=P&QS-ix;SUYu1Z`>k9TVl^j z7NGO55&ZD|vO4Vq zreN=qAl*t}iHYLHPZIyMee7a|wNePCjKd34hy0cJf=5vXFNE3+7siIK;(2Y$;%^** z11=ipnykgluwozOl#-9;oC*Jpa=(p+c64#U*yW42JAIBe4zu}F>8yS9$*w_KqX4;D zV%fxi?tYwsF*`(>Aun3wT;@d1(qdPc=MVn*+sbi3Vy8jAlDoKCwW$Pf04R$?%G znxu>zi)j83d3>z8Z#viL+XBmEab%ve34J)-^_Yq}plLfJ?W^PTHG&|u36h4Z-D(VH zNQrMi=%o2D=X=G$AXy@!dkQur{}DR3B2aem%B3)_#y@2OFKOx-CFK+CqjF9zui&4NfhX`3wW`3wc1d@ zgA~{>5~TH{d?a1SYuQ3yZ;lm?Dz(hJR(i4`w6yx?qoXhKAbdPd992feRzN-dja-$I ztLc(E(n9c7wO^3J5wT2_97#(U5xUH08erpU$8|&&LP`PCi}ER7L{zCaDo8qPTuZQ; zDy$BI4f2~5ve7_tC=9sCZK|Q0n{|Wb6g-(Ev&e@c4#?3Zua@6^>RJ0c6YBxZfI+T+9gzTap55?iaR_4d3YyTrkM``pc;Bb1ul zo|S2{hFojp?D8{5P&CD?rmlT94wBTh2_jmRX@N(^&jg z(Mc1`bmmjOvuWxq1W_R9j5EkmHS?%G)Q%6@%l?r5`L=;$eb-m5%jeN=1xAq_aNY*q z7c%V_*`6!dGPoDI&Yw7VyD=u2b)gC5`FU%>ZnDy@x%nuWj~W1=z?M*d;gA}1`PnAY zKk9caC9Z%->Mg&lAnysb5kT9)RL*vp8_tKMBvfI7*d)eqm&;dO<_5mX=LO00KaG5h zD64}Of>=@GtLGUPL&+U^(6bG+lGPGc4{jg58FCK%8@hZ=++s~?iT)z99SWpAknDl@5xobC4zyG7pX)M(xM9z;8 zBvLEM5L@eW;jE}o*jL+Fwfo2aFZSLlst#>g*TsXo2X_b_+=2wR;O-FI-3jjQ?(XjH z1a}4mcXx*~lDXF2x3x9T-1qHDJMZIVj8Rqnuj*g@eIeHH@-wTJ1xFDi&>V6Q5@-&o zB_H#RJZs}&)pS+!VBx$;kNyUab=gmqhh;@U9-(YGyXB!)Z*!6FjgG^ z2EdOTc>d`YAJeL_LNV)6%1X6!#J6?o_mBdnpjrnwoq(?1(A|m!PDTC z%U;^@@_HQs0UrgEnjk&4tf!e76nS*uOJae27X8kNK~`+vG=RM?j9+Xx%7unF!B2r%qvXU)2-*Ur6MFFD}_g$yt4m zMz7BU()ZOD&Z{hX1+XW_jELHNXBvDn#xH_NZoFkeOeTB8{(bj4AMWhp*xGCQOdNuU z)!BOOPK!Ke&ge34L2@h=q4i6SBuy$}<6VX1I7jQJ zQ#ziD*XE&L9l$O_zGg9Q^88NaivH)Bw^`cd48U8*LmLe`Ora3_si+$*`Vkhxaa#dA zDv8zgC!CWzYNV@eyTdXiiuXZ%5h#I#s-}TR{UCIumrQVfaNT zf1}Qqm!mxqcZ=^W?!?IA-6-<+yDV73QHf5#z^?;RDgQe^4z@qLEOSbd)<9RPPL(5X zoB2M8grg5oXvh?${P{6pX5f}1)653$O724|T4D!P=T8_5tY1UzN*NOOFUQ$sWh=94 z=Qu#H&{JgbW+|Ymk)7iQ_?E{Gt}&P@i_X`j6MsZ^8xNB)Qp4{K`pcqHU)LCgF#e!L z{w^XE2}Wufn5>2^%mQ)DkI_6|mywwO86Pw1{FD1vGPpuB$`x&N?^l9FWPAAg6xcF; zi^;8MDEVm&m~r6{HcVGw$lD=;J%A27)XMnceSKxK+ULVTHn9JhFpn_gDHF~;s!JDD z63ao)gvlb^Fp0o3GQ013{2>?X&t?uy>yR^jcql~vd4x*{ebm*mKWZA0S~*@AyI?vIC27AKMYFI z?YZ*w#yz*u@gt0*?>n#^1-eCXxNW-Yy7yd5q^JJ%M=xd;_YF&HLPfiBb}h-GU1*Y8 zQM1%13kL`_P+0n`aXZO?umJ959upX~Tb@#pgrYLnGD2mQskdvH_rKj-kIp+^WCKbg zaO8i8)<017i3;#F2}WeEtorvKW=M$?2o_%CC4!~YN^KIBbF9k?d?Z^CEZxxDrfpqb z9|HBkN?IFI>r30eUOt|+aeI3N4T(C7ms^@nkS4kXA7GoZAS^LUEE22)&leHTL{b3f z;S3)1CVWOE*(Dpe%>}DMImpX7dKX0bA(OXcuy%vX5(l7?@IaIbl(i8Bf?Y~Viu5uM zU3|T-eS4faRd5w!3{A%-WA~V*p9zi)rdtsC1eY_y6ZG(kanuFpG}_pUpErIte%3>B z+K>n7HT>#Gg`4{>+OK}V6RJ(dzHubliJ-uN{>(s?7;{D@mqYoD{vgBTO=eI5cWC9O zP?DTmME$vN*)TK`o?*QOd&0Qwc;caGJ-VLhXU7vn+FdzPkDO^P^j*GkZVH04W#gOFpg4#pC_4}hF2xWp(7HlHgHE6a$zKCviH|%&EY zpqQRA^&Yn0=oyUJrHS6T5XjRw?DOB@B1+NWO%#=CuxnYw4XQOZJ5{Q8Y`+3AoXQqVjUl0=2;qTYf;|bMF)^{lX{%nX%&h!!k zW}6f0KV;h=2&1Po#yhrc=IZ_tt@*|J?vr%SKj#nf_p zJnGw^ehUoajb%z_D)rG2@kD1zJU78bAWer-l-{l;ikC{kja4L_HO14nL;-L9eiT?z zAdpUc)}~P3E*|;0J0q3^0b5C&sf_qeoI{qF*5{y7d4o(hnm%GHUD<@21xfHEue}=` z3obm+&lY_rdBJ(tWL*?do?;Bo2_MrilXRD3;v$(2tr{Cs9&w8d#Y^UbRpT8G@y;fe zij**8a2Zmb?{QceKVSTgAz@9?vJZp7c5(k9R(PIGmc_gKl2)J9VjY!1Vbxhmkht^o zj!tM1U*QARqMzu69L7dOraEZOoQrm9z z0Qk;UJrtSSOQd$%OOD>;k_lynqe>QJ&qZ>~G0Iw@)p1gstpyDn(x-(OGUF7H3vKBB zn9M+HO-KHC*Yc{l{d zq1ASy_0BT;*Rz?hSYOTen1L|jmCKDPenhVeAhFFM4V{N9aGL_y)o4)3Te{FY=W=L$ zJ1Y-!mqo8AoV3YSdd+X?>tDg9ac6CDljR&{Nd?``=&FjGSdpLMz!S&4K{!tgCjMIo^xAHEo4M0nG{qo_zabA?u%)~{ zKjtOf*c~Wm@mi9Ce){+qujDm<`5&qmQUZnfKde&V#mW`=8fb9_q6257)X185xQ#@3 z8Xl~MNU9^@d+35zA`=2>NfXW$Z`xfEakkEy#e~SE>F-$kIinD%XGoy&)xcuE=`}Nd zZ=szoWJV%|7Nh6)z}tUC6ts|b|@FXzYz zuNP&1hO!_mn~6;A6mo1u{KXoT34SfLXiwn;ekjA((a`#2Hs>R$+v#fCp_a;fxbvp(MF;XpD+?j(nUrfSrVVEmNXs@0e#=fD%o#T~zrF*c zSlcu;eIR9*ub&p}94T(HT2`IyZ;{FpO>kDrLfm-m zUOf2-0XZa{em}hf%2QYYtL^He3wttS!=;o?e08H5OYN6U%UBNY@7G;_8|-2S8+}8- zU|0XAVE+R;)GGsk!47;A<#(`GBNx}VF4xrHg$m8^>(4A%W{46;RTRW3pHyb#>#R># zs0&M&z}$vSo%~E0%jCQ|Ibo6xCxsqy!9)h+_xsRpX(XP4+kI=3E$Zh;>+)uAgDC*3 z*+}t~5(n>N#)(!f@i0?k4kbn?NU0UG8F3yBcQLzMixk$y$MMxbY{377pe9nfRB|AE zjmO--W*ZYIk*axO9&As5FE15F4HEon9oQS9e1ZE4`kWXVk53$w@ zS7jgcGNi_9boyBSLP#duJh4ZDm)xXAOJB2^Y+8HqqIhNT(E?OlpBCJ1tQLW(^Fu$Y zB^Re7fUt&3`@R9|R`wMJpR?2J&CgOvlWU{@&@lhip^2gUu7>8d_>fyscCn{zZ#t`& zXZAKdWR1TS?SziVXb_F(zXN{1l&G|nDP{k88|Bsvn+#N6aW`FemwrBGbFo58S(A8?bmRlu%_<4Pn#oz9~HQ4NP_t8RZ z`@$_512%A46M}hKI>7(BoYMuYgf6SDl)h*bZ`5H4}@qi@2=9f87zNqRwCFw?Gg}UB~Xa}M+r3IE;o+e}`zOtIIqmLFv zL2F4pY%0b_@9ATn_LZGiW)X=49ZSWFl9B5wtJ7|B4wbB-Q*n=7GJ9Ro<(sLNR@!(* z$M#i@hV$VWljZWXX_Q_n&w*!z{*Tsw8~#r-J?FpOq5n~9{Xq;)RR0X1e!D|6wp(bF zboM9p|MvjO(_x&V(ac@zoFdxGb4Z(exdH(jREgnXVDw}nd1x z88`YXX`LFnt|bm=^TKRIX5xcfX!E(uuL}ws8Bk}DtA1le^2c`HCCVO>AJrha-0G1A zSpuyr;mqo}r&B+Xs)K6r6w(=(a1khTvh>u~67qmpj#x@1^O9q7oN!?LHq`)HV`z_l zvKVLZmg)oNz@o*qJRz(u{;#{YZifW=jK|x;1e_vc23o4ymwK^xMo(LHlPj@7@V{n~$N5~)Z z)c&!?&yX)y_FU_460vS z5BkyY(1pa9(D3wQbrY+6n$5Jg9Dv?U_W=ML*qZ*xKNn}c+9Ur2;@nrpV`Ubn0zljfr+mf(K963g zJW$*G!{Jyym$y0Hgm!x%S z#u8@fUY1(x8Y{lVMrl;unfn+Td8a7&;$Sidwx$WRXmB+21ut7iv>Wi%Ac9-*gGi=8 zP2Nd_5PzGR{^(^8=$?LO&v0JoZ8w_Xr~x(u5}oqY$-4UZd7Km@{&A0yqZ=fr9&7ac z%LX~a@~!lasHsE{&h@#X=hjVEU;_K zM^-o^%1ytbl$Y#TOGHGp^mfpnF12V-Eh-3F&ymMh4Y9ndLryv}5lM|(AKcSV(YVj1*FkG9naJX{uYd_d)M0`Ajx@rDF5ZAjnhQ*;;KzK zWRcc1C>n@VjJr&v9wA~o;uFKqibl0>(cLx6Rl0C{N-ZyPzq!t6_cPY<+o{88UFzJK zUR{=lHU$kxzAZP0PLYq%KhU*pG1F;?o9Bv3#$aKYgLd25@|!B0%B7=(4hE!9o#CO| zPCeUQicqOr8qy=>MsrdjEd=nP4jdiSX{rj!KFKDly8Bg!jj-bRmx0Z=W*ZE}o148Z z7mTrLNdZz6_!z$q1pPALgu9e^cedEH|ZVw3bmeJX=*BReXaAvr$#y} z|92C)TlDjTE^S#tRE6EhdFET@Ir{rL&9+Kvz$@yf;R+kEPkVWnLtES*biAoI*1olH zCW_wjD{y&w*JL7FNK629J);`OkMnl9Pad<=O#&4qN0jTIb*J7fYhTd*4vd&6mJ$bn z00D{rr+V=Rj969GvIelB197DHY$v2uD5+dNG4UU}`eKQd{00uTtp!o3f*OM4atR0Z z%T?Zd&>#qE;LrSEtq(sYeO+*r&H|vQfHACO2B3_pOiNNtQH0Tt`_np z(2~L5R5si#+=y>qh@g3o;-)h6Puy>L*vU|P2T+Baz=@(mi2PM%UkG}>;91-Joy5qZ&X>MQ?a~SrVT{3Be$WQB|@<%&k6MvVBRYP7S znrxVZQDV9j9A&B*@wqxp!fpGbFF#1$@~D^44bb#7} zsk8~T%dGyY@_xG8&3H&w%<^KtUqNYqsZ`oxl~hNYar0da$C8?J?k+xt*0Ui5zY1+y znhmoX(70#9(kXhmwrCIUspGd_!D!v;I;q{+R>QX*>iKuMVEA1wYUwmg&G#Y`N!Ibp zAwk9lf@d1JvN_PuBj7}Hn}@O;;5w?XtbKD&BTjY&(Cy$y{hkF0L-cQN)ac7)WCLYw z%7wDSoF`aU;ZzXvNwW=t;?1pImJ8t0;#W3JpmzF5ET?V2_0XQ_FN@LctmoT(f)awZ zlQ-x?5YV{m-)cTa52i&ybP5Tv=ld^phO%h;U5r5nxdTr9?g1JNHIx9S6Q7%NAw)b6 z>-}PPESX{!vAD{Al?+gHz{iYZ_#ATqC0EyvR6y_t)@J53&UX=@OoDi6q&0a(Q3xp}JF@D~-&KwIWr z5dBpi@-0vD%*TVTNX-wCB9BKu6zLo&3eE>im_ELyJ^1U}$F5_3JhKI~^ED@Irz4Gq zMn>CHABT2EfxcEH>}LI~&<~)Hvwj2W4BLOI8-M7I-#P;T)ERt0Uzk%qn~#hkZh86L zc1&cFD%nh}9BVVcx&ipFx)Bm@h#HFqIiei`5*XFKKfK+yKcUwCB)>CASCJN;z*H+8 z4zFH#Lh-4IY2|txiI`cNuItUrHijjAp{RVPekTId$_OnFe}6v2i1jcMQyf?~)awE* zn^S6g^?`Lm{=e#mxH8G1yL?o;ny_T|T6L?Ki$Sd$Kp?%wL5E)zq^G~sG}C6us&1@Q zBs+seDRu^1iPh4?Q*zp_<`+4JWvlG=xLUY}q2`)W^^xQF9R~BS@8nw7ZFsbeVd2-b zlL=KSH*jA(wCH6_Ge4GLcZ`ji8@}L@PTs^6EPsJ+GjL;*3u--TIte`QuN7l`m#RCB zbgs@RLlo7zPb`q|i1M$Ds5#fQAx6O?79r`rU%DaLg4DxyCA%PX4re-bQl<3#Ah_p#*=@#gvct_!w-WBh{E8=aeyOiA$h`)GYuPa5vIdFI#(`i>-~Qfn-6 z`vsub|4U}r0ATEnX+ z^?1}O>o-qrlokV^wHKCWw|9bzXbnLN-A|KNsfO{=$A4OIB2>7$jr7c{PlCCjt>&!o zuUukyrhRo$rUdlukUv{!4jjbpVVxvuGquoZEH8YGNF-sPUjXyj-SU~SY7n&*p~A)b zp4)8ytzY0A5XLSzZAW^4MHKqw!){M|v}mp>zGotw_KYd2P}@Ff!;!)>bv93tb-c2Q?smB>M=FC_}z~WIWZ6)Pvfik z6QreK)YrI;S=SQTd%amo+(Jd4s<7sQ<`i2DSfx7<8)kWn0It$2XN#%=Rslll%!CnN zl-D^Qp7MN}a_sEOqmF(Q`aiuH@)9q_XEyabkyxfJiq1N#UJGze!&fAxRs`SoWWTQ) zKK^}o($mPfg#uI?5&u**{_rXPsWv*PsH-*MM`kcg!s%t2ZsZh9G>XYeQ8U<{Z`(+2 z1!U~D$`7lhp^^P}c<*C*xbCUKu(Co|n+qJ{YM4bDLt+HR;@1p!*+kqsABn#XhV3ru z(9y>R&OXH_q$jpB5tUo$*KfCT)s$1LO_P}ZB#|@+dKj`RD63l3jmVp=eFw4PTyiQW z8Id3}kUbJ-DKmj-{-}%vV=bj@%^mzX@eEE3jwo4`bsPsU*Ey71YuohvLR>bKlb?kHdG6dXJ*&o}o<>I*(4+2$Fu-<|yQ6cXi4k5$An z8KD&Z%W#*K*()N(_-S}%a6QC!=*A+K@2GUW_G2g77>VP9ajKzyZR%fshcGPPFa4owLv|?kMye4S4;@Jr|+m% zw}%YvyukKE-s)-cDUUA^%Iw6Y|LC&hWiMiDeXpK=w`RwdJpDUYTe zPRs8M45))tYlc%l%=9mhC~(A=lNEg8|@xHWbkNT0dT*4^61BF*YR1RoI#7CjuuyuKF4n zEet=>(9N({?*?hE^QMqkr+xrzS6YAtTg>0J{*v|qjv1ZOPuQTseM+&eP>tH{ zzdP+2PLTPXmeDHh2zY_1%$`h1?{Epq*HGs z)`1M9V`-!g<|Z2wE7XzEQ0Jjlim=Qc7{-46nnnpynbN9frk1=@e7Q!m*lr4Zi7sP` z8IDuIlv9iUWX2>>Kow-VMmd&cCz?Ji&UfBKqa2zPH9MCqJl@_Hc&Cep=}-47!EX(O zQ;f5Neq+u{+!#_GF)ls)(GeE2PjFN_wy<|d!EQi>Fvt%-ws4e+e@NUbGF}$6R_TLj z?5m_DyVBY~YlTLl=@ZnTD$gxv%Z9DzPpol5G3E$Y%c0U^_fE^ygir1HL_sX5TY#lH zcr9nCwL039J`6C$4=#CSjZv11;6x`}o#caNjH#M*^8=N}`m?i^Lw#(OOsN(i{k9f; zx3u`jiI(mp!)+d^v0OS@EawH{(~8F9s}S)&DgDX645M@)M=t=NI3s$)(;-b@lY~b> z0Vzx}bpg{R1kStxoqS$nWh7Asg3U)3^#h4+5C~>r=8v7HxFYkJM@m>tw^|r#wAsT^ zw_<@VH_8*iond0Jby8#x-=XJXtVrt$js@4S9wQ)ZlORHTyoQLQ#?#d7`eG;xVZA_< zE<~II+Dc|bVq4eZXvTn7xLsc{rfLV4sC+0G)vRzS@S`9@=Y)>rAPjGL9SQkS?t%Bc zq~cm<;xR^KBai0=Vr54O4}Cj6kRKM%kez31j#FINyxz^OQ@z7Nf%m<;Cl_owDse7S zxn>9@jlQ0OpL@s5b?01t9G1SQ@1RsvFBaH+Eql!y>K#bNLLb1Lri|jj6!B2aMt=RoeBS{mX%6)95E_x=(0ems`6Cq zjpS+OAc0)20e`hF+V}TOK?IgVvK25Z&;BVZ|Kgf}!-QEzbWhQ(FNW?+L^1u+Cu9l= z{%mX%mKf!bg9gK^6eJ-+TW5YclhQNwY~vETCR+yXC1%f=?w+1blX5`}m9t;l425y7 ze~PNI#|+j+>+~-KDm~vmWs#qH!6rCA->}6qv{JT5GX0K zRlNZE@Dg0jZPcmZF>fr{QtqzMd2hS{hqnJc$tJZ4J7)1*`9LJ;DXb%faWBQ%m_=rF ztGq%Wuhdri;mn|2oTM6`fzeAs#uXfl>GdPk%%H&NuSb(ers|vKRh@X>qA}rB3+L0` z=eM__DuO;x34t&Q6azs@Zp)?w#2&bY(*b%4%ob91&Mak_`muATI|PSo{5n=z<(UbIOjE?6^|F& zWK;f7#!1-lj^@wy2D&SPyXwNOvAJ+Hl5fp{pEdePx}zE= z$iciFhs-|tjf!-~gO)*ve6Z;CS-Q>kW_P_cych96yk^L{nNPQM&Qk7k@9iC(QheJA zzKjpqf^u;>BSlM>3gg+sxGP+Wblo*f!YJJH0&SfL-v31P#Wd{Mr=>QlP}FD0^f@1 zMiLpwWpL=$U@Z?)tt<&6^2ok78d(%1y*_z%vf7=*M~3%ET%*!@I^$=c89Ur0_pk6y zhKc3#k#LFN$_g=s%>+a#+j(t}oSM8`_8pK=kxfPk)40;WA*{~yib_(~3H4F+lFRxE z%H}d+1td%IqK6RgT~qB0dP4Ldgu<}K5=qFNx+mYa3lAy;b7Q%p4hv#E=EB&L^eTaw z5<@peq!0b@|NS5qhEjbW37p_r9_>ElBs*xCX zlssR8EK@l$nrV?7-lwR=7r9Epp*#bEp_P77Abl8CPsqpYhz3|W89J)0 zA&E3%vOqau9Lm8jOEaNJO2C<~8BgA4lA>nX%!7I!%^Q$cc2ae&7NxUT!L;uQ=PKQ7 zfzBGs!SwDeWxdfcke$ADmMSp-FnD4R*!8Dowro0=Z~CU zX-wFNb1OAgQ;fT5-x}E2_rJ(cYqId`zozN%Azn&@UA-_eJibX&lk!x@SER zx{tduUKK2L?Dv>CfKZ#wjyDzpqdW)Ds~nqnDNvTRw38MTH-7z2i6B?~^t z2Ved~x7&a)|FIXCY>#77_|YY04iqDQJ_XsYYU5K+4%7rti?fBDh(WUbO-kr*JR^Ps zD~A$1CX0Nn$oDVmbF3%@h04SW>hmzmGy%DS^PQl2LwOWVYMvj{?)2{yoHEKj-+!4f zI!iBOIFrazveo$5;5H(Flm+Q+63k6zpb^`kO8RuVAXjO51`KYfn(Y`lrlO~|@iko| zmtPb&te>p0+v~0t)+5OU)mdF<)z|HQ(U+HBl;NH+M_*_|ShIFd;?G%M*;^~zmRlWg zTe8Pq$N+ZJHs8F(0IZ&U?#^S|473jKa@g-serQ(4$IiQ=%L2qe3TguNpH_DmY2hc(h?Gg1C%)_)>-W5 zY6R&#+mSa7bPE4xS5YL0aJY{o=cWFH4=Q--G zi@Oo@XPDQ+=gu@xuM}NnW@5{Et%)j)&(ce3VPmsQaz(s_mMbgmo7+XpV4St54b2e^ zldpr7$AXZf6~r!B>PsBM(?Gal)#`7j!6_Tt<`_M?w4_^v;T~IT5B9p2WKtlp%qokh z7mvOmXZu$Rtu`E1i@sxyEH?yw1tO zQIjNRFv*IO?ZfEO+u?U@=DA3!GSq^^U+SFEVn6CGQ1HZ-!aYGV^W=VZ>IkmJdwSRO z7^!Qg-5r1Z4Hb4{C7?(f98w-beqHMG>vn~nUKgnRo!oo5&W92<`wtjZ{&SLhk=O5F zCCZc%jxAbfz{V+OiA8I)*pGL%w!|$)@;D|~SX=J9Gvlr@h#O?;>?Jj%Ijvo%nDP7` zWq60~UV>hcj~4Q?5O-t2J805my~rM-g?sJd~;8V`xjQ2zLcsY^z;mKLoT zX-8=iZ4>h;&pP}1*5ksr(zYs3?fX^O6^yZ?Kn5JL50Gz`O;~g{6 z(;FCwwIo2(f{(+xq&uwZz0Y2PzZf}??HnJUCfgEX_UIiWPx*(<1(k~%j3#4^D#2i~ zzFr7`&#k7cQLtKDmS$p@5@5H<`GFhsv2X52MlVRrdHc<$wJG5L@~bi53q(3g?7au3 zuLSnn->yKSS!rqfreXfEOZ@|b{YRJje~*T_`WFo&{{Jx=#wC5rywMd8;ob)ClL1nO z$RQ9tb{&?t{EZ$LbQGxvl4@^NPEM10C_y?3q}CBe1>H$%Qph6Hb6P z0n6Ae{614l`z_x>K8l1W?Y#aSB=qK7IEE|MVHBUbHj<3jf znxXvUFDoZ;(V7h_3WSB2Vlt@HOpndMzShqzU)E_eV?G%j<$T7=iYCuQ&HUYp=FYT_ zBz-6Y?KWu^pq8(Yb3;H6fy0;kNl&#K_A4=Lo(RBA*6AVugp^6hq zphwEW%D0uV<$2Fhfx-oN?1z3(a0+Sd?!B*VrW)qs4+D>C8U6B3X$}aB2#7~Ge(i-^;g2DCPO$Nkx(H}zc#Y=iLaX; zLh3WmvW<;09Tgu<0sBsU{cYIQsnnDfT72s>Ylv?;bL);7KUxHRk{o}%G{gj}&`{uS z7R~?E^jB>mj(E>`>|V%Zio~_j?p8X~F+{H~+S;@o>NDPqkzRbw41jv<#m9we42JYE zFniht^9e_9zRS+_jQAt+sP)-8hk>J~6Ds4!Z&kjoiZhsu> zjuG&SBvQ8r)55Y-G(ySfpwAWWOSXoF3@c1{ql%^+#CLkr3bI97!-RRonYTvsG>9G$ z868pXv;`?ILFH@LUZ&cnDh8{vvDzOF34z$sKHELvs|Qu?VYeQMTe|f!+^T9-9 zz#{4RCyBcqXvC7Ka~{k_53EZ0eXjL?a!{_}dl7s;azTK=>-(wD95~Pwk&-$Wro>pt zG%ks2j;R{#p^C--82I9a@vJXsUn_xCa1mG8_SQ?M_#K3ONp_&MnTUm$XC3V3j3>WO zztlj+bTel>O+npo){zhHP-x#(eRolJj{3DR(pP7{rE3LeZRUf~S&n%tu|17lue=Pa z&iS2apV2rVpm|VRt_sRZv~Sco#`6?l@@Q4nu2n9wu7fw`;YeF!RIoMbkBDj90M;ww zrrxd<;jRbr%yMku%HD~8su(9H2gYk?wP<;@kf z>*E-|y#Tix;LhcLPG}`w%Ci2)v+oax_J7X4|2Lg|AO6qT_y3QxPlU|`S@eGrpMS`% z|42X`ee@4X->6W(#``DowSGs_Xy~W}S^;!*Zfn$Pd}IVG)xHSZUC#Kty}ZpC2k%@J zr>ee{E<$!2O;IM+Ysycb=Wvz-nbv_%Wa@l#HE_{i1i$Z2X2fBn2-XzuMrB9~kVD7y z=eR6M|0*CumBPeH6e9S&j;ec<8O%mlg;h)Zg-SR92x4FTH;7H~*dF+A5PL=9A3^N( z0w9R3CYJhd5Ig^0Aa*W}7+3ICvipBaPszWeXDl%N;_33CfzneeNqT&b!E15fF= zP|bWrm1&^_g4hthLF|Z9tSumj4TXm-%fIS4Mw8N9rRA^% zgBZ$`pA3u0B+fXd(p?OPRKn=ZGHf8P+f-mD75WIg1%Vk+D&oD>GyAavfr1|w6-M>Y znDu-;zJ=2gTS&mwcL}4mMO`v8(_GJ`*lKpQ+d~7wh->vN6u9-)5kO*-Lm4{#p}=Dr zV8^6EC1_cydG@vDDSK57>p7E3LON^u8}+leeNajRQ~aHslVg@$v?&WX6rWeOk9Zx8 zu6yoUeMQ6fm#vp_84v1b=~i5+Cg9fFzd-D{uc)mOvaaf)sJ}t%nK@(6Qm=9q8p`NR zwJcrD!@M`%o01u7nQAMhU~j?*ufN^#hJtx4{~yo4KY-MKq~HJP{r;cp{USiCuY=F% zs7S?)SRU*EH0j6NgsyTs;=xP`rxmSBS|LPFR-v?*-*$qU(?ps3E1K*?ZYoH`CzxY4 z#*m9iI}p}^3D|$)b-3_G(iKA#Eiw=Qa^QSaSMB^+(rW3dU(uF;AH%q;qxV#?gjBp} zEr#a!-}jKAG&oZbTw~JX`9^BlV$1mi!u)LOrthHWhwEV^j%0`N-13I_;&yND)beF+ z#BWoay4^o6A^JOvHH_@Jv)a8II`r3lPo7mA*SMhoRbetbJpxRD=n6f=6foZ(VX+-I ziShTMa9yQfPYM+y#hJY8mnn%`%o>XLr0Am4$#M;@Y*8TB@9e!h)p$r%M(2c#IrxYr zdB}O_gv82(3tZzEkd(oFrfvM>^VRciaH&wSxN?)VzKvpa&|#JRAej%`x1$VQgWR2H z<+%SkP4g5UsJ<+F#Qn3pA*Vj6uIxG9PpSfk@gf8qN-DM8XFSAdws9f#GVHpJE2Q9r z?GTr7?XBc$hmSvV)qO+(U;Ky$f7kT)*InNknaa8ic~{-1p^W(}0dwE*Z$ggaiBy}g zcee}a$Nm>lP-VG1-^pd;R_MMNou`KnTqT~Qsu zC$h<3PRwSVl_6;hO(Z?9otQ*5wEoz+Z9lg0L@hmx=x;a-e#A*9;Un6t?}0W| zq3+$DyW{q7H?E5-0jck=391rn!cGs4`zhg8OGSh!KgU5H6DGb{S;oI4?3gvIdyPr@ z?1^sDc{bWs{oziy@8jou?6@N1Um~*+cDyilA23Iibia{Pp*fTkT9)wj(T!5{{r-ypQ?QY$uZBw$B(_k?~U?Sg>BE>{_Lp>^E_nNPG;s7(C+m36#bP)5vH)G0!n#;j&)yirv90 zXsSt#&)ia_1W>;~7yF30wu)NsntZ}2ELi>oQZ(u4SvIpj_nv)2A$g6>&$;GI8CMQx zPu-Vreki4L6jxYltg@|tzSLP@H~#2tT5RSt-XFy%5aVq5TDnIyry(HQXiYg)9smQo zbfM(+;AKg`7~OIv+!6RwxfxVSAf&_UrxCw~+q+`wXBPNzrj(qJy?9T8?QL;xhV3$h zDfljHwHtTZ-tnG80>TlJY=zYxu&`vFPlaYY(ywDy4ON;EC7hMGGwE%qP8?J%(l;1Q z>l;>Qb$-fp=iU|bUKIKeC>mg=fr2cD4(OnOmQa~lU zmqwdOBviewE&MmF)c9r$U`)-%iVOoGeOz zeM$m%lx`)~AvvvW@r7cTE33ovbH_w82wPEukGhRy>pYKe0P=Xs_C>o7&9;-Uoe1X| zEO$|YP?JWipFI)k>ZRrhr;>=-+*4*v47+7^Vzb6*sgzAxt=0!yfoo6lJ_%%YJM8$B z=))^t7R|hjONudKVFYl*6A%+NAiV+J{;ZyaMGYI%;AN3NZ!B_;P+KX6@aa-j0_HBJ zfyl`8rE*gM&)ayGGrpifYFb5po#a?F)Wdy?Qrou!nG^grLpi7sYa8NO&xiE3zi?i* z7A1f!>||Kc1GM&&{{jTt-5S|t7QyUU=$;74FT<@(GDNM{;U9GJ`9dBxr@GAIsCcg8 zwCjf9)8CJmt-5BUQ+mWOg;FW{c1`t3i*!dcC34 zf9OWVS~XGI?M}}OY03vMQoP5OTF8v3Kz4kgu4;RMGOx*Bzax8h?5SOwJ`DV&ag44t z3tn!ThQ?-hlq4hFo|dg<*X1FxCM$7>55t}2v_$hv0Qjg^hISmxcW_fS{koVJ6(yX9 zneo3Ed+UcP_itNR8bn&8K}w{%yBnmtyQLfH?o_(FyFL7DWFRI;(WWS(LdVEkG|6sYsv(%h3nkE-LWh;*;Nuc|zvTAG4 zbyl7J{Kr3Lx=JVXdf;>4`?t^icS@vI3FJS&^#c577m)u6aK{V}S%{oQ+WW)OYI(zsV+#T`#644;niQ*#N`VaIipF)mo|hPiKl85RP*guqKhuIL)lmMC$FY^{i>EuPmX0%r?y1~==)jQUYE7+w z7LtI}`G5@pBO)UvAjPGNG#`b)>FuBSDrW!=8hmYD-6+Bz$y4Ey*a&FR<3fgPX3|}0 z9yRp8ZQU-~fD9q>?d}vDo$O8S&#bZy%)}Aa3-&~Xet_@CEGyW>42-lDoA9oENlk;H zyW%FZTlsiJ%)od5$=ZI=&C++=Ub&84pd(fz4B~=2;RvQ}(*nXwlZ!w#EH_g}|GjB( zW&7&Df((VWgW>Y))SbiEx4kx*zxdA&BSX3vauoSbwKC56iyRZ0T?qTycbiH0wDMtw zwDM7KO_6YnEZ?LwdA7MqZI8|KxzEd48Ilp3L+KzKIMDqnQ+TK<4RYnTcTtfOKWm1EpKf&$VL^EQ;y&rHq}LTIsy#MK?&IoQn? zowLOhg)5`J44EIpV;x3a8~XiuFkEQe9e|!=`o!RWjdVtJza_9zUYm( zcd4$)V)C?pZOs|UL5W#$%%f4M>3!(%0?vJH*mFPsF{ub|Tlj4P_}aPtg@&;GPFvI} z|Kn@_`ghub{P?xie6pnlkhbX2uQwtgwYohdTf=sBg3pnn?GxSg*u6;{E-}TcH!x{WkDMF;^F`L;%k0?@f?o0pf5gGt5WgvV8f7% z>&Dq}V%{`69m0ujaHRrCDP-Ak5vJN@Xd<@ruyD*rGyAH;_hYWjw6z)t;GUurTyh+m z->M{7Obevfq~6F6#Y<7@;#;0)vAdtpH?U*9e|pJ z8n)kblqQ%tcjVES;A%*uzZ)9j)O{|LL>HR4=0o$Y@Z}zA%cXN5dQl0HSdCm z5uVIj!e1`n3dit9EmF*G<Oc3 zhzMHJ!=z-X1#p}P!cY06o+JW?YKWuy%%|XjYxFl?z61=98^$q{a>GbKM`FMKJ^bBkOtAPSS@PwfXS{LeF~T#xM}+K2ACb6byo;)GAc zep#xynrjks63x+g(JeFh+>PWgy7V;~MS(Yy8LSyGnf%sIUFSBf_!JL;GsAJ-@rs)T zU+=K)VlJQa0sHe&hG&z_HM4fPNV>Eo?aqFL$D!<=1+#}A?S*eey4gUxdsVb(nmaLJ z!DflIVGZnK!HZoaRJV@zJ;5IfL)Y?2?mqw=2>u%m{<;G5PaG6dE&NU${ogpa0pXxY z20mwmwhM%V>{E}it*4@aGCcIya|UQkBHc-bZAxWp{Ys_7DP+~%sVIUE4Izq(BQ8az zMY(z15?FpxMF%7GM#+;zF_pSS>#-H+Qm%TJ*U5R)tMmxgoUoiuF_oybRVMmxM=90K zmzgnyvq`q}r}#C`95nW7u_5p4GhMSCnivccEGNbc6LOiL6Eb5%@t~##i6ki~T67K{ zh@c@=hduM!$|2X3JDc@LwF*7Uspp|)NkKRe&zRnDu%P3Qb9VFdDVzyp_N};z^9HWjZ&nTyN}tBf}X2ZC=) zS4Xf{nBeBL->_GTit*d12cTaPDF<^~+lI)op+nOHd}~iz&6i=V51u!KLI%IfafKm@Z7dn-+C~TUMo8 zi@ydz$!S#@3d^j;4|r8-Hy?7D9hYD1NslL*1_8|2RxIl?B5iVZ&xD@JD+Yodq6`-j z)#(=ZR{2aShoLh=-+I(tXCr5_Y6J66_W2dEvg^xuS^}h1u+qVKtCXwBj;3`-R zl(CFM`y%t~Ww^}?(YT!ML|u5}0qF`xxzJ^&SU9dz&~vEHf@%qH)(Z804`Q`8<|ndpG5#2(1#-RZ9&+$k3M3&D4(H~Zx@FeR(eD~ z`deonLo0U-sK3R-bc6n3`e9y0sy<-CsT}Vy1|u*X=kb9*e}j26W9ssVL5Qtigv9a)t(ZqNxl8fUD zjh%rYXe&Tru`--s*oIdI?gT3jPa$LNZjNV&fM$c#@7VyRmlrOVujpv3#xQCcBUS^N z4YUd0F24U9CY3Cz(*w$2EI=7dkJQ{?yytzgN-g9vDKHyy2YZYC8rS!my=!0Tqe%iB ziBHA2G!|hIcyKnpuMkyHzADRF$zO-pN&J^ZK)dd(<$AL0b%rWXX(#j40Y~-B5rm)n}LwT5Ar}eW# z#hPVSHDWj<$_E?S%ofiA%Y>r7aTY<=&mL?06Pnqat7lgc=>{T%aGx<<m;>dU_65UJO2o~9 z)r0%o)@;8^%e++d(2euc&8po}V-ET$0EVLCj+JYfuV<-YBF#EhOR~P(GK1@%lRnP- zSN0!JXA;a(ZpFekQ(!zIT@Q%tGk&77tahu?l+*r1s?FDqL|?5JaGjgq3XQLwPhPQq zQZvr*Qah*pq4LiAW{f%Ig1{p2r3rb^+}&k7BiuFI`aW>Xbr{Yf^+8foGB>4aHROe1 zuK)Stp*_5Ae-2`c@tOfAgr#M>PRNobr`E4s&66N|goa9GQ^6D6tkw7I9=1^|=MaNW z5QA=IdY2ozlnp#l>cYwes+dMKG>@zvWQzCfV#H%r2qPO-CJX98ic*F^n}sV>py zN#+XCEP7~9)tQbV$*9Rth z^m9#EY{uGF7b%Z!nD{?2X<8%&pysM8xLIhTD5DN$BygOfc~5&CuMn* z5}8E794jTQ>4xqcJti7=(7H4)z^qh>T72`?s3(@3-SLk|eZZP|y;nX#)s&&+xx5z7 z(|`^d6oCrz>(`Gup;pk+o%t^5Rn_G9UNqL+$v-us zkC2wn>U@|C6NoHOcF%|fz)`pNHxp8ibAP&0eu((K?=EdHht7PJ(vnT|@k-r}BJd!V zTH%$EJ3;b=L5qr=w3^B(JzU|T0++R0@kS{l&vcu~vpSMexbrOarLm9BDdkk7?Itc#o&2Yb+*Z@g!_isa zFKbm>w*kQoe=XBQ4&AqvKc%I5f{SqE`~(=ctrbfSBa04JCo8AK!?c9g^jaV+^>63W zY-%Md245ED_D0(Sac0G85l?!B`XP27EZkE4(1bnw7*C;0v?@>@PkQC?9Zw>{Q|k?w z6RsJKRv#!i-d_Del=|}l@r7UT+w%Yz%>NAxzs==Z<^OX)9PqX%fQJy@C=$-Z7i;CQ z9Dr0M6kBj?UBll8#7(?NWW-fad=YEhx1p=nbnQ<(9qk`u>MD5Y^mO35qt{Gh28`aGC4B;&Giw#^{< zwPx_uZ#WQ*Nlf>ohiNlasKPZ$(uAstr-UiN+YZJ#f|-FqDu`BcDf6l1tC3pN+N<@# zg?%FZYN+2m;ld=j89I1lwW299AUOL}2VP;(HHThpT@yPxZGrfXfp1nRakpYr$&n3Q3qS0S=`wlXp7aU{umu88iW$?v9CnHBSy&OI`}kzxNqDLTcHB zhbZDz3N1C$tRz4|rILHQ^kdMa+1Yh_#%*ic?)wPi#a$ z)eyp|cD^C;E2X%(rHu8v|E}irkLU0zj7P~Dy~Pb4N~MF?2fiNfRE#CCt@Sm<#kxr`(^tQ9%x&na8J=fXl~FVokH zzivKSJ>y(rJ^H1G`3rbN{QnLc4!4SXPyfHT(r>T#pTmJ)ul~0$!-XY*!OY>(^p}vKy&7eV$$oiM9z^6)X5Kpd@ zrk*Ips7~_Zx2<4dl;2u;=Qb*DevIj@!SbPAiKJA>>Zk})7!X;#TXwR=;+dM}9gugq zR^IW!zn^b_97TiL9|~8h=I2cKeS*eUg2L&oG+7u`QQ=WKaAr81%aAIA;;i|thX&zh za)Luvx?LqQ3>F5}c-N%^gZjfk4uKd=iT|oY;1418-#IwYF%EDaxaAo@V?i3 zwN?29+8?@Iz>8qA2vCk5<=(n*sK8I|L`ok8>LH^pb&rCRzY<9qgUj^=V>yE$3;%BV zX@1TwZi+<@?}^AnX^HD;ahd*LM}uO4v2BAA!OWwWhhayY|4X0PgyKC5L;02^B|0q! zqZuCJX*c~%v1#U7*=x%{nJXeVWavUfxB3BKhqx^|=4FB54q`mSkqJI+D#u%wQS@6+ z>O;z2L!JDZyocwdq3ZTolskBK#wqv6ZyS-+sq$xc!V9a?wR1~4EMvO;$AsYP{l1bC`F$;jZWY{$c0P^>3n->TDk&TB`h;D6OEdd&sO={^T5JB{poE4R&>| zO>oa}FC!{Zpu#m`M0h0g5CP<+U!7O9f83_iwfb^q0W9$U%WPo(%T4~L(E62n;k>Me zoS0NA3jw4q<=Donj?{Y3&WEl&`}!t%jXT*566m2T&gCsOF|}jl#TfB zzSF5t6DY$2?zr{!)L(o>FRbFmfUwa10seVTbE_)$14hcbpRr_1xXa+MH&pyJs{D-% zMtP-^V@6nHOagfzomDvQoG3z)VyVE^6N?Z7Yj_v67SLG}2O9ODv8q2Cnv=MeA_kvgn1bxtV^~6USbl{Y!9&ub(seF^H%gYk&P?vtBM>!glB6GzMQn; zsYeA2&lve)sapjF56hd^hzN&b3`9OAkNEg?h6h*;M!eNtVf;!RkLB)$t|>~*wuj9o zWeQf&%x@ObEkwZ%pT6%5{$@&IGouc5aQR%DKsGWh>{{u~68MMJS=wSp`b}T!P$kcM zEQ5aQKs_)I|7%67Fv=nO;vUB6OCABt8~I)PF-rf9!V%Z)i+GQii~hKa?1&0h4f_{^ z;aJ`zqE+1Rle?U%@CoX*Nm3hqB6X>iU~}qeg%gpw<`WL36#xfV4f9G@c=g~UcF(z4XEr4*l&9PQR2lG z4e7NU7Lx$P*3+#dk)pWHkCzy6Q!Do4E8H9=9yglrW&>Xjx+J{UH!z%}*o0RuLj|-Y zT9oRs4+Om7HVQ?BY`Y2B39;||l^FP&|H*hMvYUepjLn-{fW9T zS6>i#Wo39Oc?eKjbw~z8XP@$*D=53>n5(T-g-s6fUcsM7I}V0^zhf^LH-EHe;3*K+ zlSXssFNQIEo-TWBa0Ernd$9<^&Z!**%!Yn#w$M#E%s4*Y{5jhCPp&ZUt`H+sOq)G( zEE7ulkd|UFn%hr*(ooXl*|^+DjMr^`gcZ+?>qhJOq~{A*4}8EH{dFC*MiU6sE_aQR z+441`rhFhRG_wD>$mZmEBzhj~@`AWlF;kpLt%debt?RhN@ie=7oM} z5u%x;B_D|SeT^yXVjQW*=j6|;8RKU4ezCu)niGO}wwB&I@2T*8rRKepd03MwZ}gb4 zcw*pQun9bC>ESMv-H8CfWu6D#i`AvIwkAXn7mc-ouxj~atM;u+>%dR_x3Z)WfnVnG zCGVHC((~x-<9aHFCKHG(Wd!~vOEgNAPAs);Elj?M96=JQFVq+HNQU@?dJ6%NOFm=+qnmK7`6rxBH9X zD4N4CtHYRvOwanXjy`pab)PZW!*FTTquhZ#j4s(GqDIYW)e0C()mnMCRe4(ZFMFEP zm8L+P`H!`P&Xp6BfUsl*2upZ>2}>xCe+f%~-1=X_k`YK)f{**NuvD)ghYoV21^x{Z ze>>9u<3v5>AvRUe&uFITuPjbWTXF*i7Dc(}Ef%{M*IFw-l}KPD3bp-BOvX~baWh_A z9np`6bARSnLm|}HH{^?{WTvi1SsWZqdWB_D6Gf2ES{2>7TN?dIOs}v~Kg#|OJ+7!cI;^#N1Ig?uVQ-*EV3qs4J_uA%Pn1qVbmV=AJnw0F(}cS?0bNasEF%ep_f1`b?T=CmWt zWCd6&A@p0CyKR~i&B8YC3D33hb(|le9a4rCktlQF5W(m6Qyu#)5?ks19uYFC+}eeq zVV}~@g{p2KXi4TTzfYXXnZL(g>>-If4U*|E^)a1KWivMAbXs>s?E4DI5mC|0;ulzM z-9BKt;DFGW5huG9FFmO}~DwY;5zmQMbw9}c|CEB(e5n+JW17t#V;bGDWQ4X|zN^`{ltYq1k_ z%#%33>PxTISsZEA=N4nCMTcjg0{bcPe+#WR2j=J_YJDz@F>WOXIjUvw%op`upN_-e z`}8zQ54*=PTdF#WG!rGF&3Tm$f1;`)#`2Oo0$X%R@AS52C9p+P!Yk+D*3c^4(3#V! zd$p0PR}ye0Ke6wg-yk~-OLmRrQ#83*Ok61*J%4q*Nb2YMPeP?A zqW;6uqNq@+E&^S38tCwCSEs&^d{J>9{7=pH%QVWk;a#GJ8%43cVN5_z3QHu{sjglQz9gb_(R75*-y7C!Mc4e)pyIW2DcLS;OM zJM?;FSjgd9I7+!qcS7jZ)@;&s>&B0$q*gTb)SxI5ls^>aSc}5#YRGgWCdtjt)A>l37S z+f{+4Y_9@On@~c;U}cfRrIK}qtYnxaEkk$NOOoXgdZb&^@6th5^f{m<9qDIr z(4#UbL3Y>v6-TPI`=Odj@2%{tklD4y1=V~aJ?gk|$R9chgpw9sg34do>iNf;-J*z( zTqhK#c2z&ue5I8R-(L|T$v-S2XV6;o=FaFcMUdzErv4>)E00;H;(^%G|qUKY!f&HCpiHkMX;L-0hoT;Isd?AO`z??C1YK z@w<9Z{4R_OWGi57=GeENE^iNR+sA0Q1KWYo8#)eD&_>ex5a%Mn7(9@ z657D^yovE682Kk-HMx~_cB$4ghkBTD~&gh z(&!?Ps;qYPae&o^+kj2>)?wi>(zJ7J8AW<$sdNtAc`=uoQ3Cyn=L(%|l?GP-$h}k~> zB*fJ-6A*A-#Y24Ak+uB3Ie7~0)@HJObR z?-d3pkbz+p5elWYB~k6nVH|z+SUvy)YyG@$sUZS20+jIIU!!L!9$rk_D#liGDLaj! zk;kiAaH2F3&swC@ne>DGWhU%End{4LzgLeheYIQ{?OK{Zy_FxphB3$jqyDPPhgj{M zg_ufSt0MDa5e4XFgm@|XCIeFrwOrdl#mD;cF=C;ZIuDAjL-|mvkWvfn$^fsSP5~}M zturb{o}?o=-Y+s_jEP3GTmm|-wn3!?C>NF)f&O<6N6bieZrZnH7>I4}Ga(;IyiE+< zp0_B|X03Y=Mf8q8vEwy*>UqQ+EFvu#*lfuk{7ht~J1-ZmmaVwJjk4X{gH{SbDJJLD zTS5{%xF@E)DvIhR6pMR?V-xVni5$Ir!pC@(ejR z=K6u{G_;J3c_+dI=H)6*vUY7ADU~YlUQH9fK9pE@mekRqeTyE|O-?J0(pSZ!dntGQ zbQ}p!xR9?p6GT8C*i>lZ2^Q+FrBoIv`N1xK8?Eq?MgTKWv7a3S{rhLto$PFn!FI9U z?y#He(F#@(`*W+|IGtUFRW6v7P#6oWESxF>$;mCD@YH6)GRTS7vs6tuvmh>XunY!7 zRC~*-e-DI>AAa?U;3xw; z1yjll&y$GIROPDAzdeOB4GyNOUvH&;{ZTgpL&|dp#ga_^4HSR-&Hn%e1v;JXZ#rZS z(4pr4PKQ0(brF-&Ce*ga?TWK=MwHZe#^uPo0wAIi`Ag$q)r#FEqc6c8Pwz1C z_1zzB2JKr>p`+Vte^mcy#-~aMvJ}$Q5~bvm`+tn65dqn3qYqpScgEeQ=Eqpx8j%rr zlu>Fv$@7f#!8@eXz^XLRaS&FF4e;O5^V*D6<>q0 z*-R-kQ;oURo;Y(DC`1FQZSm`lq=3WLhd{X}-)5-WMZ-X&mT1NcVnkkJ`S!_1eMADz zr7nDZQLs(Md(bl8c)q2p=LVifDf6V|VPt5WpG!n<9|mVB%2q1(Wd)81@K=D0-jd>s zS3OoES`c!9u)XKXc_7&rSEY1*UFS$dA24l^LK#>66m3k@xs=8%Q7%qgU#273u1RA4 ze!M+*W{K`S$jFdGWY$->0#B8qJCaqSrh@809V4m>4r5+c)^;}|w~EzkSBVwOxf^1h zhEzXOy`rKsL%w5*X%FAaP^33FExX{_dJj5h7j~^thZf%xnnABhwH-V&VVZj@dL^P+Cjo5`7B(L3(!hsUP{ z`OGczGaO$p!^6~@Gptg2;v!ZnhBj!FDUco>G;YzuQ@wEoTLu+DyXr!e}^(s0_O_$7Ay`gGpm#Cl(8NoTGy0X>quG77eM7P zNFYgg8~M6K2;7eR(0&eGO=d{3GuAj2u0Dp&Aa9rjCmF?A7QOM1c-(n7Ub(X;{gR)l zL_F^^Yj{%8+vsyEz+sO0#_br>(e`af+$_ga6u&Zk5?k22JX+f7T+vbks|x5Y$vq28)*Hl?Tem~ul!yK zqgYQqxUf<^reOHWAqx+P%1vtgn^!S?gx{zUF|l85dw{F3kQjUtcU zvtx!G|0-^xpaxn0t;poZ3y8I-ewLwKa}DIUYO8dNS{6?ryc$?#(oXFA@}a@fiV%U; z0WwusJ@yoCog^;3V6~#xl8l5>qs4?vhON;3lq9QbjVdJnnx4gTZgfssW5-`CnAd^z zvnDNUG5BZ9hs~RxQvEIK^_Q?W**a5l_BvX%SvN;x9p%)Vph3~`cDeE(XJ!$VQ||0s z0A#jRStoXdqlc#y)pF)V$=A_MPdwi6*U;~T$63|Q1`(iq-*=g6q)K={6KMXf4_%Km z=1DE&k_SwzEI-n|3)_FAluA|5b)XQ4te-5QDC`Djv&bUpES zF!Wn07iEF9NLhkj((-6=-5aL765z$^cP)eM-8V4v-4V{~2WCL{!k5(^A*ocUQ0Bxi zYr|X9Qyj_tRt#;8FHknxQT=lLc~BYO1HUwMS-EN|q{Lb8wxm5%Q1Dkp=M``(=MNT} znalA9kdP|%Z)o`2a{ljeBvAh1k8vcxV#|2SRxFOI2I3bVKyjogP#ozhi=qtAICX*p zY9O%lyQ7Rs?rN?s&bsx)HzlsGUlS&y^>4WPl!Py#4`OXQ zP#>i#BWhKMN2cM$tVhDf94cZJ@e{az7n!W>s_W5GP&V>iinoFeW=yuB6sP3Z-J{bq z7RVol|8a(R?9ZwesW3q|LcgR3RChv4yF6Spl1#{9z3V(IbLXIPmY`Kta{J(co*Mjx zx1-FE{9|(u($9OKy92~lM-_nBYD4G4H}LTrKS)B};Io+Y5RvgFlJHTT=0(4-5ov`EzqTidacc6lO;2EChb!xSQw5 zRfI_*;TJ~iC518$u|S$^S(qQ`b_Kyd+f>VMuFwQvQIj9`%iG8~#}D=r2CdB?EsomC zV69GD?rxa`9VtiFrtrRU9TYAgal>K%$wH|g;@7q-3MYN~f#G~Jh z+raqOa`xwT()&}!M5}Z^>%F!*sV?S~4bo$K0d*O3F%7UczB7`_-HZ4oGIhI={%JDM zM=b6E$B~sWR^?pmeeN`Z2ERtO+rC+}8r2E3Y(>61h#J_YJ!q%Pp*3F@rF^a!^d&Zw zuo!6Pc1sxNaaI=|%T!$$vc@WIcp}Ba8R>wW;{78eWXOvwK?B0*-yrb^*ZIF7VMtk< z^*<7N9hVw8(=vMT_hEzkCrzTx<7tfSU#RR1ewW!$=;;|uzg;kc9zQ7>-34N+Q@5ud z=KibF@Tb_SO*|;J3RaHpSm%Hm1MIZ0Rc^(dhb8MRud!50b0x3i{Q}qqzSeNfd6n8O+Iurj6DMwBTe zqMsnbgac}|dCk8`>%8H@X)ukf;M6|9`lfP>71-!p%Wb;OB_cf}JMWM)V87fMqB-6> ziJWT`CB0@}dB|fQh8>-VoC(SQHoyteL(DrQ@*;0}r#7!N1rU-Jn>UhnXaGdy#Xe`v zd6W?%;2aPe0GqUEIIv0k#9}7>wMnPd;*;TKp0<%-pRr12(|AtTwH&)@-5ZG%F|;9h z!t`B(rx9k^!0%2hie>;kXgy0q-1B7&WVMjInfYcNncZw^T3xqEYKh6HJfDgjy5u@q2N)oC(t zc`&RQpi4yo6pnrj@;$61mog-Wbs{4zad}*K%NDHF9K8aRDMkw&8)%$NxW81szWgzR zLHszrGX6JR0=Di~PG92hdo@1CZF2}opUNqOeNtm#rsl%(~_J7~!vzCo;UaodC0>6l<_l7%I z?$X7_e4Pu7V~fm`QUdIP`0b+)l0lpz{EzA&mMi+mQ6+)bCx zd&xR#G06qU42)XqLuj4Qmf-xmMA(O*f@}Q%JVcJe*J`o8@mLFM?qeqY=Dm8~bOCWXw=-~M zE!bilqLV=lR2sO?yx2c)mPQ$K;#TFr5y)P3NGo;Bj?#av@;!H=9F;IrDn<-ccNMsGy+g^ygL5SH)A){hF1~K+gw$)}QNx&d$+B zVe7#iLZU@i`>E;8qi+GI&){CE4A-dVUae0}Hn%=~T4>8K691@WHSJk|-IfCoCBzoJ zH3N5IAi==dgFQ0O+b>`f$;?wNlAXLfDD*7%`I?k_d4*WmL$GpPsM2dz^YO%x9MonI zkzuVWPI!2CV{;9K2OszaD*w;=D!(pXXE%TYWMC@%?>P8Rzxlu80O#ix!n!s?Qnl6(nz=CcuO7R8zM?Af1IpD6=MLgc5Q| zM9={kK=9Y>Q%F(}EmqjtqZ1Qg9VWf5EoWa+8EDKSRU1sgC7BoQ^WAB>Y56dIamSf5 zCZ3KnjOm%P4Z+~m_mS?Hu5*&)JHLJO%#@p=dV7c`*=x&+ndCk7jy(}$351kM%1D8! znRe9X;oKkg(!8~PAr(46n`@@XUh^`*XE(^&6BpJEg;?0Z$vWkQn$am9LHi$QKA)oyP+4$G@F?EKtWa2aGX|%U$&Fxr_K`jGrlq;kr0~`c1 z)sa_N!@2Ky^?SrAs!j*;M1oDV!oq?-IwUC_lC-iJ9AXogicF7>MG%sSGMP8kn&tbGC2#HFVv~U3V5Q zN!EP{9e>8tp3r=&a7XsBx&8Z2_h2oaBYquQX+39_rFny+jtfGN?@JBOBmAG11U6g! z{mH+Vg#Z29|5MvJnEKD%{@><8geGTzT>jtY!tp*RdIb9Pg(0KieE38CtxT)JI<>9I z!02d<33#P!3<%*eY6M~hUJHIhCju`5-flDsAt8088cF>C?8^zp-|fPz8kh)YeJDP| z3;LIF~9LpM8~_XF6Mb-*_R-x-o-Fp~1K(7j_CuAO6cjqRUXaFD4U zQ59Lop+50BX9Q1&gFp)K3U1wbRZ?(0VGcEaskH=98s+}UIjo9ZtG@~?9kl(JH}+S>R^ZT-yLtgCwc1;r=%!V+A14hg)UAFL{idbg?aLU3blr7w@mk*gPSXp zdy(AOhp@}l5Nb7jWV!d#qkFa{SMOWYW)k^5ZOG>rYJ1CDPb<$~xi?-!YPR7&n$SG1 zXm(SVK&f*&Gkh}PD{n8P4RfXnIel*rtjoYvna8*yt^+Pp6g8{N^-{`>Cg#NvF6b zZa1o1zbytVVvxnafKI7xtq-yokkw3TZcp=BLw-o51Bc4xDdCqT&~u~?4*-iHxr#{6 zsY~Iv#eg0FvKSctV=)kIkeYkSZVzZEmO=s+gK##;V(@E3-miZJS`LWS(oJDij9TRp z7K@5w<9iEZe_ISJT884iinsOUH2PbF7WaxiGZ^Ic=+)(}gYO>5gU|$G90xC#@0tvw z+BsmW}zMK)*um<%}G|)ivnTlSrH2TG+JEv z_?BA*pJPVRDuzDa>QrzEvM^2U)t+Wj2RC8XDYO?E7J#~i0~-j|K%C^=F?2g}t$ z$uUGI#{3FnkQ$PVMghG*86Fi#N-o=39;pfoNCK4wken(8*J#lfCIpNJX<$73umUOz zJvY=c7ee4#F_RM0rn}h^@~AnXph8>bpi2xXItmaxY7dVI3g2!Aub>>OM`y4$6@O=! z0cv@Eodnipn!y^br_}HQlJN-F@DtN}Z(v=%kmkIyeJeC?gKv1SOjljDkg#~J>%7H!*b=Y%?eWGDAXouB98}$_TigApoGtmb zU2D!^3S^Ji-FMuH_6Y2Tm9c+(uKk_S_UZ|aQ`9G5a;MJMAXJ-NwB5A*4)%5;BnSFS z1KV_JcG6f$Rml!5gFx=Sr+MJ3wke!faTbTHqHI@boeiQ9wVBw|jaJVkdkwj{qO3(# z>33GH`(0KC+O_3Pn@R*_${1LtN2*=@fQVFlK+~uWuaL;7EqPmGA@ZJK9@|}j!0k-6Ubl@2rgP>7L%xnU(8Fr+q*nyh> zNBf0sQo6Tb$E(aKHK!WMFYQ}{JD**~(?NOdg-9y3ZlLGcELr*%*br?LoWIT3vPw7t zo3r7vKIIKwJ!2=nb+2H#_S|0=0lI}t(beNP)%HxIae10SwYI@lv_TF~%hQk&>37Ss z1Za7-QMIsoSOx{YbOin{`BYs-e^t;~43Mn)zcZ%)c+vmOWynNUyRZRjp0$71JUy8r zQNtDzW8!O9ba)r4ahhaa19vfin&)W?=Zfdx)zP18p5lrH#{^sN_QPLTbdn&&s~ zSJ@vsZ810bcsuc3xE-|rYI#n10pZlAb6*eHN@3O}5nq`3r;%mPYR*Xjxv(a#0UPL4J-E$1O%_f42*u zVqu}`hV5tONe4m1yQh^LAKk4!T2GY~o0R$ixR{AwxfQSY*DSr88_KIio*i;a3B6jg~o-F*Jmg?IgaF}1NfW;KZ7f)DcMB5SU4uKpEl6-XxO;%$?(XjH?h@QN0TSFbK!5=MLvGcr z>aJV&_IO8s=98{*3((@ik5@(y)TE^k!<_e^1iC#{Q$`VHnA;uLpD$3PBvDe}5HzPN3%!f!1k4D1oQ6 zSA-lb%Z*Ch{>Q^yrLmL|@fsz^_4^b9hIKU6@jARxS)F}7*JP3#rHTdi{x~L`DH#tb z#;%@O{YHo_`g~U&w8EE8_n;YA^dK64Bsk^|lruB#H6kt0%(s>}2$ z7HI}ec;#D^yn%XZZbQ3rzKJioCqxo`=)s08*Zb@;Hq^Hp$`TGGYt=rq$B8@1neHXJ zddu&`3xGoGJ`j!JMiIxr1LG3!BtDf3Ufp#L#J&augmdU-sH{Y|HQZFzvvl1qLEH9B z-fCbtpd!)``7```e9XL3Xwu5B*GHM}xsnH+RfdBcaYZz%a#AM^5>;2tQ_2DmFQK6B zU#NRlMy~*O6j_kan$OLHza0vRV^Lsl7*UWb9B`U!UlzYSIUBR_o<1>$B4NMLpS|{? z$Qe9Ysc2ME4L#5?W>H6jNVhC-by@2T$FBQ?o%8}#)Byw3$_Nh*U*Lv+fMYrxDnmvkA-a8f z>Fj|P>1NmNxLkzVby!~nP9&}I&QLt^b{F%dPx?-e{f&L^>F}o_^x&%RcqZ*MV=AKu zIKA^p+ScWfAPTAkwe;%Sa;$=!kNniv0`c}a3iBKFuOrq}8u(=FZgTj5*r&+U?(`rG zG2`yYPGlFk2TrP>cHa6QHVfEdQHjo=lV1lS;{E%R|8vwlrz&H!B81YZe&Ay}-zS}L z00WJVLRl)59|K_l2^g7XG4xRN7+TSh+^agh!(3n&4Ye<2Ox!&m=TuOr%&MK^0>j2g zQ6QM5gsw($i60PH9^1RbWUhQRhg(qEg4d|8TEoLx>uBF5yb)FCI!As$ZB#U8d_-@ z6K-5AgagYB#ZSQ=3F15Wuw$*fAA#rthxM)iE{dVUr-XULAusuG-cfz}sFGMN24*Za zxrRwZzL8nbmcKt6yP5#V0h@>;=(UlO_h`H2I*DAPrG{LPVA<;B!Zqd8wI@$mV4ok> z1rdR+IeNd70Cab3<3-5g{w9|&*GomQMWyX!PC(NaDn5B+Da&u8(W*-Nbamgmfgw%Q zh}0x$u4}x8s?Myn;eqlEna-|=)Jb~-)ezI@tdEL7c)xhL4YRHzI(goph=r?4-OEx- zOSr40K#qG6&X)}a45VD zlbEi&0dI>iW-+3g_R_43TKO3ScfXZ7jiC4dB^4@|b;I|@MGIPu!_*Y$6BmR=nP)F1q?u)1kjS`{hURg)HI9ukyF_V17D zZ)|Jze^`YqKxkb=D{qPt;ZkbVHfg{d`|^SS*#;C_H|)>#W0*h#h?3TZ)cVqP(evAr zHeMgkpdkqtsd9k%#H&R2;5{63HpC?s=|!TI;Q1obnMlgh^$12!1~UQUlI)T%c+CZ$ zMRHJqC#=X%F4bv&%=;f?`z*2XGs;K*=ds6mP~BcIEq_QhTg?doQ$UVp=73$N)Q3-_n8>pj=%Ci|`pVlqyiokC}V-+rPax9J5c8 zxOOE{qH)|6y2eA2r6-suD%IxHv5FhiY;1O})auxLz|jkZEbX9hJk%%Njy}*PZAw=) z_<-{bV^zCcn)0)rjZel?w5+WOrky<=tikE7a+Xex%E&DCR8;55sDo3M2=z^N*StcW z3gW8406O)R?`L~&_V`i>A!e>ZI+K<;_p1U%IRON09F#(f*M(znWBWWhiG#>EypQ^- zRw?E8(R2gfQ`T#q-Ke=JwkOQ9-Q^{tMx!)zPwj089vxR@II&u=Ud z8){At9)z0~Ot3U{IIR#`ecyA(S@z=p;X!ALtTxV;t9J@8s@oN(9xndQgNt8)Qktc~ zl&2c<@w~&vC<(32&?j!mOV9fS@4?7fX^}I%3m`=)_vbvB$6bK)mK#6&HGn^moNVokI4Evl|RG;H(BoEkp|IXHt-b^rZ!`#EPm z(f}x=3!yx&HR-!O&kd*YP+gvPsykM|SoL|z21MbN5 zhR09%SU(ATV*PA(Pa_vk!C)rKLX2A)iIM(si)>;?K&yHgNUGF0#Hbe@2{CG0Bf=8M zDvoJ8Rvbk(ctJ0h_da0Ox6~XIP92M@ED~#B#1SS^PHzadD7(tkz!uEf@6{BV$T?yM z-OQ?#51vOuy~Ezm0EbNtT31+|hfjw>m?=<9pM?j6?Ys&0ipNggFbJ7;WsC45n7ykc zIJz5tGrI4D)OP){b~wf!$JBMS61^G+OX+%p9MwB>gSPRJo9OrpxgwQug!m!-F0Wjvk6;R-SkcsHa)yi58-D)j@GlunM&G-^Z{q`W& zjWNVQHzP3x1{7?aJScdE+JXX#a@Zj=M$7;HNx}iW*;U8|6e3pNi0j#4h$??|j@(Xn z&eoe;G9j*f(8-44wMcCQapb#-Tv5l*2`$O;ObxCB& zyh35vEnXxIqcz#zk{mvRk{nj|eoJzgc}{YmiQRfma%h#1OCT_V@Y*iaov8tZh*>B` zkr5x>IG%xpBAkfDP=Z3l_^E3{e};&evvtIKgF?jCx@{q5ta+U0KZAV9dVp9ryq)!~ z(y}$?&z?HY8`MZ+r1|M^*UVDPw3QzecLiqN-@Wo{wnillEWas zUAHfH9CkJTWF>Gxn$_FRTaBtF{$b}GWM})MirWPdiNYEvL@WdpB9?hk|NQ6vEksOk zzU8-6YnE42ZzuE475-42Z4C6KHGtF^_n)=s%)bq`RhKP*LKq;H9I?tB z6G}1L%F&Vr(g3MB2{YiRaUw6esv;*={8KpS$?<3q%aeqQf7=1Ox}Dx;>3khcIfxoy z#P>27pkyF~bxuEa4bEM>nxt%yJ}&5;yc(eNLE}vJO=12A>l6gZautCFI^2Qiz!_Oh z^5!jGV{yKQ@768dVwYwqVZk#kricrWgT(kFcMup<5b`uACw8cB#rP48zL{!VtrP_( zZIy(BO(#`9$<9}N?I55n6pJ(F>uI_ih|>kJk;;*g-g+!j9yzZA5PMMe5tfLoI`pZl z2$g{>=gJ7Lm*BjIwjwT@iA?PjacV_cV~@&&yp&yZpmc`ZmuG77jSr_P&TBl3++Rv_ zjm&dUMNyrT+_`;p745)-4gzB?wUuWwvN@WKIeB0QQoVgq8pep0sJ@-cIKUpq(D`B{ z^Gl!&d%icZM88HL^$&z#UrBBv=E|)N5=;fl8Xa7O!RS#@;dTp9Z%V=0P zVKlyX0DF}|Z9{S@BH&aMrgmB77%JZV<@?<_ytd%Z9%uKZ2iiq@C(3U>Axl@tWr=3E zpUXnr`R#vr2@nH8pK1L+`Ft!-VF!M0*BV{eksli_rE(Ui8`WNFKW|#bc6@re?E1sg zF1h!mZwPeSwf^+9|7~OXKdpzhF4xo$go@07LT8r%84{#X6$P za93edN1sy0GPy5~j+o`bU%`&JVxa)@`+ey)v=fgZ?ccU36!mkZb@_0%!4*K%d`a<> zm4fVJ!Hw1^@wCun2_;1=NU4>y9dQ{AceOZQjTF--#P!ogY9ORV)D$mWD%lgeBw*=Z zwTlUqPJMS|8SFqrs3aRk;%EdXDg1GJGzV-sWdbq&o!@jkDL!eUR`&U98U-|SU- z$f{5)`Vl>e@gO?iKTiB^DM@K5bIR`hChC<14mr4i%67W`$l6lTEB-r&Mult|6;3^J zx~f63th7Vf)>|a<`xl&^Wu#Z9cB0|N$-Pa!u)*>ERqFP3(V;~R%asIyljpVgMDbHL zJKz(c?so(6dB2@_6+;Q)4u$qolL>j=&5ho{j4$qMlev1E@^&(-bB&qbodouK##Ile zc}4=;h>jX%%6kHX@E>f_Eu354KA-s4A@?y#f&`~Lgn4~{; z;8zj;+WaT@+t60k;bDq1jCfb!3(&DwtWM2MYzI53nu*2UMp{;9_Q9z)B^@P5TwU&< zcyiaDo^(Jx0rr99UOA+FUsUyus$8R*a$Rplv?EEH>H=FXUlWS6Kv_)~2BHcls@L=P}zB55s^61u~fV$6S=PbdD>mkv64M>D(<#Rey1zC{A((}T9?51(4or7 zXg)k+vRsKSjmlg7KJbJ%;MV33&%Y{o^|!xNTg*R4*uT`){~WdT@|W8BzoE8VOM>^m zgSs7C)IaHVn12q=KWhMN@;Oi*bxWQ;w0YZVm+0$Sk!W43P>f&Yj~%3rH?%~>ySgZX zE9*NX-CuDob+7oz1;=*gN|q6NWa35PC zKTt?E=PwScu(0h`s}JI_5ouFbz?yO+rz*`y(Z@>T2*);8KF#KDu&=Y3^g4vuaG3X& z12MYkVStedL*^gyPo>x|b|`2;8%bq+))sNRRAQ))t|+UlFd2dhvoWc}#IAKxqy&eoOO6}NfI*raAGVU_M=X|}Gi6Iy*K zjmkUm7(=J%lz?0uOy?u`;abS1SH$sG8Oe-beyz_zA8dKnD1 zr{BdZoF8`6on|;{fWweXuRL|Ku0DPqH^o?J+;imM8*AGaPWYMcE3aA9>?YPE%w&Ai zZ4PF=R?ph&mhGJkP_3_S8Qba4-G?*`W3jzTc4vgH_~SL`vqq7en!=6Bv`>x04}fAb z=}ve(9yuryyb+(dY{fPk7(W*xUvSPq&g>OOgWawTj8AaO$G*~jG$@^-di$|6x$=xn z^-gjHFquD!BIWQXsQ7|MQz8M)45HOuR)#VWGZZ$&J@MMkRpEi^ZNCqO80cr|C-aA& zfA&-<|8yU42(#^b4jqVYc8qi$(A=T-^zB%tb3E>1a((;_uV2!7gLJ!z6mLL1Ymeoi z!-9%Sckv$};3`V8)E zNW%pt%qv9LG=?jkNz$Aj$`aVg`fX**eN$J$LrEG)330*cRe{a{axmz^)rRN>_mLcd zM6D$38BE=Mo3d15eN)7lLUPiILdhNjqN{{a1TtfToeB^K`gj5HrTV30t%b)u592A- zU-B_51&JO*P|K1kuPX$%ajOEVJt4bT4Se!4&^U@qOW@wndhE6v05`>(>k!*;!5^F<-epsg*`(xe}?xkb!6R2Rs|7pSaX)O4x zp<@H&!0;lje#&-6{tPXfD1Dpgp!ms~M!tA4-g6q8z$oSX_N z)(a0BLGL2dLyCxy$m9G#IR?L}+?qvKe3*loMI+@bt^BjN*`l>KZ1lOs?Uj01ShKmN z*XUSc0>Ds6YgzO)0C><}n@Vmh_BmNBajyMq+Jda>`}1*1nPjIl@aAoOU`;3&ZOkYB z5~}5P1CaO9Ri__dc;OBdNk2DI7t#dlnJd*KYMQc+Gf{mtC7((ouMtq1%3j`SY}TSt zWH*rdIP2fZec~0pS;_rwM-{Bi> z=u761(vb@1cHb<06F#_ogW^6%mBTx*baUWlElC~_MiF=fEd)#1d1!d_26s{UjW=Br zH~NDCyJx0p!siSr4XnA|r1BAgx|iO0Byv#^WQLg7M_vJq7{j-P+^g*LjCaZO5~k2! zRkEJC+vs(R!W$^vn60jA*xot}(W^Bn7zgoatJThz+^~p`AJdwT@I-uRc^jNpAuj*f z;kjVU>|j3^jFr8Tp9KSOKtMV2f!c>zbq~E*Snt#68J}vP^olvLRDu@;{q2(|X7h-9 zsfrN#RDy^W3v2mXQOUWwcf^|x2ZA5S9`jzasLaUUN`@YRe$$gqD1wW-%ay;qZwI&o zgnF9@AF1`}qM+A(tW8+{-KC2|6=BcVDG!BiT|O&m29@i$YtPCZ5{?rgDZ+`NknTB> zhr42>>#o4g#$miqdPEYlE0&pjo3Q$iB%Q<`c4|XFyR%pywn{R`k&Bn!W0lQTV`?j@ zEqMjQVg3zZ`Ykw$t!gkBrhd70UnMbaa4>47?%mHRU$3kU>k^5Q4rTK-Gk%MCt)`H* z-HYbV;^}8d2tme>ZrO}oi61P!fn{^U-5 zkZo;ta@$1F+7Y`#t{)Xv1_fFd!e0y4CO&>?uJp9M`zTMLqO+HtxZV|_@S20_R;T7G zQPcRLzc%;8ZFcz{EO%0E<=#Ec)RUH`_aA;%Wgty)d;rxAyFaZPKb;rPLIVgA8Up%H zZ;l0Q@tH#1^YXjxnaO3;vzc4DR%bwU1NeL02#GgBi$#Aiq8kDh7}dTzyxF%qq1k>H zZ#qa{22v8JwM=iIY0qJk;0@5?JA4uKBV)t~DGTE2q|gz04X{i(#Ry*~sa}yq!BNItWxZ(9}9A zzjulb0_*h;cNieUwn;Ym##w&W4T4Sv>>|1`5UXdcV1S*)J0d!a-^k(`x!2loG56rD z`a|Lx8*dGr%D7;iW1A(8L38f;3byqu%q{*tIPiC&ApjB@GQSIriGL9qH2)+t3V#zC7j~{ikLa&A z1VhQZ$d40Em5hS(xu0C9XBNLTe)G2%@_-zNi+2V(eEbhW<2?JhY-l}~4S?`U<`?!& zZp%_${W+%qSVv<1i_oT}P2rXezzwsp-s$%tDGyYUNr<#r>3` z1OwDTbOtOU79UE{DM;YK6T|)J4z$KvSeY6x)d*sdtRaLp!fA}8;C=09j&s)st3oaY zk#mko@8lv7HHsv4?In^zzC_k}`eKff4VGH9M@7o9db{_SY&xKj`&AEeSA?{uvMj(W-CI4Yd6#X=44Gd%#r6Z}T!KMXU?7wb!v)dGg+ zm}ksT>&ohv0?ih!GH)e4Iz7M5ZqSwDYZ2Dv=7=drTTC_>6hdNQKeFBwC3Q=_-fmV%7^7E&L~uLYunLSLQKpw zsbYxn+EnJ64)uAh;RblQwYlsSmDHfBA*C|YdSB7O2Nx4oAC?BH8pTVMqAO+f*@run z{;0F!E9R-jGg;W*3|Svr-Vw~w&8m^QXJ92sdf<~uxWwdyckON_o+OKUZ>gTnlu>>i zgK+zfoN66c=zj&ct=V#_(xBUR3ARbYX~POcLF>j6?nmbvXhlaEx_sy+&BR|)4$n~= zs)1A&TGG%DwgBrNs5JG!;f)@2Hi}*k1&F(KXb=gE&nTr&7-^8J1WuY~c;}iPNeidy z;=fs;8Qo7q0eF$@j@`McbJCp-$};n^!ZqEUVXqOL^W@Y|uMRyZ5=%pJJM$Ubem8O+ zE)%0v)^(>f+*)FYLo1(wU3(eAHEP}8`+*j|il2z1D~4DS`E_2NFv6AxA$v$e7P&{F zr)g=lO*Xt6pHJ_l%04S~lNX6G>R-94dYHBMnr8COtahus`79_)^<%F&~^ zD!1?Yd-d%p#`v#=WQO|jb?W?HeL`QLr#)k8)_i=`C%FNWn3T4UG)mEnf8~L%RTILm zfUyN5x|~iIc*gvq)6+A+@ZfOSvOZhIZ`%e|u|N79+z)H{GWF`~Z9x;T-+{^|Momw<2&Kpt1IpKuIGE|k{Y zUaFkc{B`S^oUgankaPMG2Xwe^DfR`Lal3Mx0PU<2vc+Np!N$ws8gb>uYEdFYkmY_oet zv7(}BRA7}Ut?w-~ledb`S7{d8&EME}XH2oY-oY=>-wre-re90&Uj^fq~UgAmIyb%Q0bvZCm=O}wmqLDhz)H6xKxLr<089SM|aeR384bxnpf5s1z3b6IpXQ0 z7_?wYeMdhJsv-unvw)#Kj!NcKE3ke$tG+8b!ox&>2ib6&XKE~uo(|h-fz-5$>G)?T z(4;qjLU0(h10{L^2+bYQ8=n5c3_eM06dVY0BiDVLHY0N3|JW(uJyu2*WhmTyU{ybm z=njQw5oUSYd5kAMpLw8)-E;*C!KKR{j=GWzbp56_5!@Lj8Cxey{@nz2F2?#*UBRL7 zD)wyzlwA^3h_Ck$Y1DX{rhQ)wRUy1LnCh9h%g45o8S&WG)i|25zek4;EWP%nWYV<8 zqa=)a5jrPwpa^Aj#qUHcgnFZkVg5===R_*Tn0(~+v_P`#AmMx8mhTIg1#}db*_y)? zR}Swdi#YkZ;_r{DIul4Xmrm>+o8oXU?hVc^2CUy;XQO{B%yEUa2x(S})mAkS z!2yoob$2sWBwhs7(>g%% zOF}9hv?nu?BDpq8f?!C=bFVefU|%6VfcJ|3X`mH#|=Cj>mX?;O@|@c`{ZM|9+2rVj}vwN21Z% zgJ`gywZ_~~nwlkEIqN_fa+SQlfnR;?0VgZ0c+J^qvW_kc#qAz3Y&WL(ro>ut%uyER ztV~csz@=ZL1yA~2C?S_QaITVJE01TI6`iJ_zb0f8B~2?0MXn@Ko?zCI*_jZSk3>*T zl4=0v|JG^-obYu)=cgUGGFo=yr9SeBGzI`2XG{FHvf7~F60=|uD9|m63_y^7)Dg9V z11Ynfcps*8=GYRPc3i3By58nr}aZ3^UZQIbO>q%2vo#M&;uxO z5+w8u3o4g)HDXOZnx!&vqDE?s5&2)bPvB~8vUJ>6;Q zjpMr9n6tN2(Ul{}Z8Pe!X0j;0gP5G~H1dlxj~Qz3UBdt}SEb7?-jQ#t^DNeZ{XoVj z8a_+z((eD770{~t5yzLOA|=!$HZMg6dLy;kkNY&oyER3#oQf+gn5c*=C{SxZ|96zB z`*!>j*#%MALW^xT-i+zHUfIF(*OyPTNquglD;Cs>@CJ>d|26O7Rn7*u1L&HD{h0%i z`EQn}=Tu!BFHnYb^K*vu-%@qySD%-OtO1}@U2>B~W2=IshdZxMcKf6F$nYNNOEfw! z7s3p5Q^#+~{VV*FVUqa*WIW<{3L?y5GasYW?7hE`9h?0)@7p7LO+FbVM&m~F67lm) zuY?SBok-v7UJ3<2VTD{K?2pMZ{1_pmJD0Dw2ECwq5JTbEV@aeHk3Eua+QkNygL$#t z(1wMvZ*$@7$a+;F%t>JzBhrUH1lWfe$78D2_mRC6KFOooeKC2;jTcooMzSe(S&@

mJk~d08AVGn-90lFHNRfaxYVn6+CGk+6A<@uEzXZsE7*i-;d@ED5*JX zxKvBfTdiO@^n~-2erWL?z$-PVb!TZh*00 zHe^mv5#KzHvDu7He-=+=^u)bGZ8B@=Q7kxlTmUn^nS zDpqx^T$`tTf~lHcAv)R14EA|l^A6t z@E4u9cHyct@FaBVtpNK5&sHQ-U!b26 zn$9?**>DSI$e65ZCGg_ApHQOv)yJ@au^({Ro`llwlodoZ$EWTbsfnN$ zXA3)#f)x6jR52d;M*Ig>_NDpE76n>SZhmOZv7;6gs*x^e&BHCze9RS|?*xB8lt<~T z>4l$mZE%y|oKePlBRFAvl3vDmBAusdr;Xp>KJo@R>xGY5FfX~Gc5H*jtGnX`#Y(^l z=x{^VY{n=u7u~guuj(7Su2Fttr?tUpue(@SkE9URVt1R>TDMx#QTsMo|B7xdy=gagD^O_85xHAm7@e11x2($sD0D^&<3-`XPtve?!oO7-P zN`cnU8Q%Pd0NYln5GkuPE~G{P@cE{8*5dOH1_H)AoKyDsjVZ~)`{dqUn!L#;}Q&n(OwIS(~arSVzslUg`907-60 zSFnm@rG0bT=ow724s@Y85}@5+cqMEoMLJ=ef~CI1F#>JG3wE9Ub{gEWu}!YggL44= zA{_77VtcUnr3|w&86c}HqFyTcj95Sm1^SGiQM^nzG+&ea%6XlE;78X0)H`BvoiHuR zPl?RpWp;8&=`yQ47N+amY+N--iiVTyxY@o;uDu=pmlj@&uhfTHkcCQJGFlu)J>C@D zais80(9GO_5s&hJo#cj)gVyf592M{8qE*W0|tXeVC4$`FCCgxM_^>z(x#>KAW?9}hdEr82KEeZGmw)8hZ zR!bI~p!_i)2_$4vC}7fhsDGPx^t{9*l9TkPw-_uj&5Ok61TPPccHZ3!_u z3{H{9Lc^BAYQ+u4ld;B?5O7(dXKx_qKBufwvfBVkGcnDHaM~38Ar1RDzwSmxFG$b% z_|K=cDHE>w*I4cZBA+Do-hl3}G|uB6ekX75pc8sF#QbTa%JS0?_W#Kc16#*CiBN}p z`Dyiknf;hZ;T%(2Fj9h-ODaAjDsuCPfI7?5s0?X_{61;ay0r0YXj1c`gJ(~!MH*GA z;1^e-8a!vSkR<98Uh*82b?2bO98hGOf7oFU?e}8%GjVmmWCKiJj%gd@P~8en**gI6 zf&l6LK7qd}BuV56LivYEAj)8^ShUMBUyo{MtJ#{&M!I^D@eVk}C0yY-vZp8mRQ`2M zi)0EEwZP@{=jsm`Fpj2gaHTBsdXn1IzP=-V8XhB4com*3r-vtS4i>e}=b+Zm^8c|V4( zJm3YU`Z?kR-bJ|}ggnDpp|qS#YT^k^RcOqjbV~?*kB*Z)F4Fh|nQELn2DqkAkw45^ zBU{E$wwQcnP&2CfTQiz>Q1D%3*B2aS@Mkkxw&Tp<1!_h=fwV5D8NG`9x^q~Iu3)DT zNxH349VHd2X@?lja}$GfDdEpYO5vFDdm1%b~$Gr|}A88{RN$zedA$&(-jHTZ-L5kKOi> zY(8)o^r>qWW_zNw`9^fw;x1f5YhEFh_fvU9POW-f*-gB^Y#uJtSqLPwY-+pjaftJ3 zquTE+Dd#>O)6bTaUnsL3)RLl09Xz+Bn7_BAAx|2+G*mHPHM8{J?dLu6e+xN`C(&ra z+3JcK6#T>c_kE6XMg(;KLP1={e{26|`OT1~{(DY=Py>ui97M9VFs71R$&9K+UL`2` z5*3vy8(e%zD(&Hpkco{lx>&VHdNwr)HtU|7c)h2uZirlsgWMEVjz2(^keVEEk4##f zNbAzr#y7rhdI-7CGRrPD%6wF6GzG$h`tt3tn{%l-9jw#_D|?7vI!o)8g%ElKLz1FU zy&Tj8yU0*r;&;W+fMfHu+Cp5Zp3~T!kjWJ3OV#a-bm&8aicbuCK@7Ufl*}PupVM;l7{mvUfWn#izamKx<)h>zGQmgetLY0&(Q4L*k_{hGsU? z`7TyB&A2G-%4PW-(Fu}_er@q zaG)z9C3P-Lm8p<? z2^%TjI>fgVzWhFeQbT$3uQ}ss%34OVP699YMRwh^wios1s2>_5{q%NQx>j&kXJCv^ zax7a(9cb)(mE_s=POl~UjK_f=n+J6jtDvnV`bJ%1ypDlpx7JndI_2W)dIV#hPINWK z1skIQNLZ!~5WV8=TJ1U!9`C{Kg?#apH9B~gYBMG}R6eSaqKm7sr2cS&y6@~sJo8Ma zzrk2rR?^*jLe`dUS69}41I{TBbO_;j1Zl(ZwskU%KF3P4Q|#1HOYw>~Ba~O;0aIr! zG;@5>=1q~G+Se7$%flG|osaI{K&zMk+GlPvt_1w`+xOFq_UrBYpY!(F{(AfVZ@hi` z+qf?!|5AJY^mhHrkfgr}XW$JcMko|2#ng<%qLo2ey;5}KsRi$dkx*R@1pSzS8^#~+`MVdv%fvb;Nr4*wdi z_~J9mL0)i;r_8Jw&R4c<3%sBgIYxtX(fN2FLn(^o7*2P?2Wy1-zu0}7{x9sliT}aw z8|Ba4w?7u2B^*D+r@&kKK2%1##oh0IV)GmdY(CxRdDC{Q6W?3$MV{f5mzrzTSVM8e0FA?O+`e9_nyJFXsK~4M{}mOVX)RF8%2*CW)V`w?j%c_%%*sj9`0@A`z$WE-=q z+GoQ#CZ?rI4b=+8luGf3`j&So-+*J-o&M+DHx4T0*4(v}Rl^{y52 zOSVs4KC0>+hRwIFNBznKiH4Hgm`8@O25Rph^CrCV`+iK5C`g8^CXT{U??y4)vymlb zT+{iMyoikxbrcq0*f;}PqkdWpquNs9zM6)Uj~qtJLd#4f&7aSiX&+ICDFg3ztrw?O z2E2u)#|U}JulPye^?cY`V%WTJj76VA3;Mu`zrCqWx<{@VyVu~WiUX=~LX(BTx65VA z^B$vb3a1fpzW0MeQp)LeUyHU`YtxQ@AGp=b=vTTjC_q^8n&N@FMR`__4$;i2F0T zRP?q8JjNu6Ws2jl&M%vVt|r0ep0*AffQxwtx4Dsve0HZb6>qPj#GXp$} zply`=M5JQ9%6Nef2Vp+<4)%lh5O~<9=SgHDRbl8oSZOo&-jj(qk2>`4iiN*H<6ClupMwsS=SigVOR-YK$!&RzBIMBwC%e;--1%>~ zQT3%+Y%a-~_#(ztChDiuFe&1!`d`pt5R%#4z=7z;t$+%)P3&D$Cp4L5n;CZf)(7S7 z5f5KJx0~1^%Gfzo_tDwsz1*&mxE#Sl^rxB$Re7?$I)R?%8HopvJ@iHDH`Uh6!#>0j zK7TmqfL&`#_)8`Z%fB#jB&{1OR3`L!St3jGrCw2}S?~hfrOubi;ptZYgo#7Bg4di) z_cFL3P1K*xz#)|$vNksC#w(XFO1BG7_oFa`;QN#SS$M=g7Sw2s(I3N1q8K80@cad+ zrhfGKL^X5zVJ{-OHIxJJ8_k!+@n*tRY9v5R9Q)zuHhn(Cf+<|RgjA2 z+`mfCG;d8Fv{M}pvPu!stSU*JL`zlwor&}CLfz^o69*kYP-u%D4ZFXX6AsAL364vM zrmI-jNSMrHXzpX|x)p0HV)mWu@RtMLBn05KSvIXmt5TP`B#bEOWT`~qX`5O=aZ-F- z4<^eUw4fQPu*SnXO?bch@-|4RhsEN})@yW(2}72B*9yt}xi4X#f^;q)x}t-9rdF4& zL#$ZXo!t~dtXSFop7cVj0-c$GcJ^OxKNcZRSOXno2G(Q+JGr;)@U{iJ4uR)0yq?;g zy2`bC?)NS$ zbR_7Kl}mUgyGi=FFZoj@4$Chl&Mzj;e-{%6OYs*I2LlWm z41@&%BL({}F>zRbF>!t|asGe9#9{r##QDX<`M=4;@pRY&{-xSt{l&!jAEvhc7c+5w zsVzvTf2b`8TY@)#$;4s(uQPG5Rk|^jK5u(JAaYbU>c>U=3loQo(^_-Ys6G5A6Nlw1 zr)EpURORYFF>z*V@8Xl_X@P@aO|>C!R~qL-jM=3|Lz|hy=t|uBI4e@lK$(+riA;wa zkhWtzjfR+ZYGnH!N($|61Jd2AXRX1&!L6&tAg;}kO5bWQzY^6tK5Nod%JEY1>nOpZ`q$d)dE(ot3Q+p zM7BO7F24T_abcT7N9kR(v(>sQRzB;ki8B!Y>+^bpS) z3xUZxX*E-WL~!;?3d`C_5ccJ@mt22^qsvf;g$^}f25BE-}K1!8Fo$;Y1w7kfthsx;Yf zd!wZEDVl1p$;b~hSB4(>ud;+tpA<20$;_KP$;AdGQ!jmz$V3!QwFFVQmyET$SH==a!hmR#`ai20Yl5iagP zo9dRW$?%Ot!G7%pzI#1DmzZwddlF__RN^-#&dr}NacogtMgEeB!}^Pf^NWe| z-^;|QmH)-W`QOaMnWz8S|CdZ0*8egS=N~Ms-7GQj!OVB zaaR6`iNi@>rr@?*TMIz2rA>n^0BC0wyp+YQF)fWHS1cw1-U_PN(NjjastgY%4vT`!r+ zeEIt;dXcdKo(S57Z&`zBb+B&3&8=nn^M|RYG)C>?(v8-q_SG6lEE9En>YchZ3dfI! z_I9HepEbnxbkuZTZ7#yLEQu7FJdqr6IMbIRInCQF%cX@H=U6kI}&f-sax$}hqqT*3jOzNc``A_sSGP+I41giS-4Pv)I6rs7bLVsPv^!8TAQT|9-~ z!EQE#*n8U?rUqT2>{+{-6m_i3W4@`kvFyvH&OJ65`TGruM&%oR9Z^#YF#ix5Bg-jL zKZORv07z(Hc`yd5{1h5l2JBuSp)t=ATfp$oLPMA|(iyMCb}MwyQm=WOc*`aq#wzdc zLcZR8Xr%lmG)9LWGwu|!gP&f9f<%e7KrGp_DCv@k$tiRxAdZJz z!8eo7t_Nn){s*BEDRB&|>%B;Qo=TyEK63?Ch0Ca+y$+sN`ARhV9w%D8y)P4M6!Ww- ziu;~to7nW&7=iz#l|1b~3yq8aAT&NF7Fbypip#`cV_QOW+t*0!H}YgJp<_h6l*r{8 z$`1BlYr=N%%iR_~*?xm@iW3iWDNGzQ8||TzgZI7#f$7!h1`F=w?w*~ zn&#uYZ(l89w&*Yl4p>;iM0^pfA9NRK=>dZ8X=Cr{-gr$GU-UC4P6|RcK=O> z?@9nPX#q_#O$busyXI~~EjmAdbiE$(lV}vXnflGqv)sr5$qnR)pK{|xsg;HF)c)^s zLuy``Z^ox1TOhx1l(5Vk&#^d-h--D+a>lu95Z<1aU?%p~>_^ERk$;sSyemEpXVG0T zk(qq)slo!f-}t^8w$7B7Zc|f6X(B~ ziK8O*i;44piHW1>cuMk@Oq~D6-dhFL*>20iAqm0VHNk_sOMqa(-66QUySo$IgS)#2 zCy?Miad(0T2;qMx$y$5uwZHxCQ}v%Zbxu{T=Ec12F-DK>e#gW7=O)gdn>ha`ZsOEN z{JDt(_Ig`(k;VSUn>fsWZsPp8iSvK>CQf6>#Gjiu|BPh(FWtmp{&N%O&rO^^H*x-- zxQWB^=O)gdn>c@N;{4xu6DMKR!TNvvERyBVO`JbBasGGR#Hj^y-9I;Re#ejhmu}*) z{JDwq=O)gdn>hcwZ{mE>@+7`9o1N_{l7x=l)`cDRpQC1z!wy*<9 zz5Is-iE(rE)aWS1#1P$T`2JT&oYHKk^Q$TLm;I zW*Rc_*03v4zxHVmR4QkNUl=0=93<+h-_D#qO*r)mLu|4Qc^cE&JwEeJ4?*-mQRroB zD{T=Zk;vQVm=n?`?8`2?lKGxtZwG`4SR-U3a*Xq|(?NI?LbkUmIG5aJT1w<2m`jd| zAm_~3hOXG_XJ2eRlyLgmwbEBD#dVk_6yjIul~US+KBkl?B;e8WJDu(KAbz*pz47Wu z%}z4tY~eT|T2Ubo}pF3 zQpKXA#%?UsLS7K|z3S2+PmAZ69J87(YcXZgzB_PGrb3}LmejwIIUrG^pL2saV5+>w zbv=;k7Ak>la^%^Lwyts?VhP*x&z?rQk#A*c?&T<`6kA4^;Tz(AqU1c2p~`azYmHiI zvg@w9f3xmXka2#A-nWdz(myPTs^5@ONQ5&4wXs^-hMT(K{ z^o{A+}Rvr2BC5zTEg04LCy8?q5GmJ?K#gDRZf-o=Xr&a^) z#*Aap_|Ko#L!nP0iH>lpic)?&MX9;Zz(gMt5svCCQ)Uz=g{gv&ufB|OSPhf13?ysvZpKe=9@v}*hLi%DmYrmpwCyQ(2< zGl)Z^>HEQJ_3OZC8a=kN#|`4EM5mmqI94Ex1L$uJ!uRUAo_C~B9#h*BIYh-wI%dXJ`Q z%B72@`R$4X>beZ9F#nAs6m3G3Y44prMJUg^(J#dzcQOhH%G8_Wr>5OR@OcA8CVC)) z36Wf#Q0y|1cJ1=X5(i@>aql#dN!$h~f94*BUGIK1b6IAcc?R`%-RYwD>JRa6uwUZ5 zbVkDI&G~LdL?iITX?53b=nbJ}x zTk>(fD%Tn%Bk=Xl4;sv*)hEgY;$$Ecy3)^-M+YSmTwA+ryFMg1K6`x$#eB5B8k0mB z0s&`Y2lH%_7=+PZmWdXFbNH=fNko=#PRb8wNTZ!<>2>!C`=A=t;ZMOI4mOdi5tvAf_LIwjcI<`&g^NNwu|c#mCQU5+5_El=$J7jR#8IZ1H;3M5d6@-7JOt++ z0X5iLpP`W!+^_VuH9b!Z7+C`Sx*=n=Ct;LzD&~$of}i^f%aqhM+7j=kxcB99reK^= z^IPG3P08GFkB%J}NIdYRzNLsag0L9wxpE( zn{{?xUlk zzCuoHz}lzV#UR&=N+QWqwdEruBAZhU+2vdlbtaaYw$-tzJQD-TF8uD?>^9NyIx-XZ zpT{<@NnK(1VzUQRFdfu6N|ra>$A2E5VUS_5CT*_ACT~i@ak&xBK8UoFCXisUVBJ=e zV%SeWk{NQH7f5z2YNxmAE~s9FCwuS*S+8?(kMA+O_?rGRFnXlrd-ad?zkU;QyDqG< z5;$LX1PtZ>_Ch(!V{ETZ3H%xlFp>}7xPV{dp}9$o=P=C6qps66uPOIr8F@!zq#+_d zF1`CxUhgqwd%+*X-jF*L9VP0Z}#TU z{HKf?fqsJTBw8_;1dHXjQY?o_19=iTj6+vHSffk3Se<_jBGWlZdC^E9NWdMf=8L<+ z%=m4a3?0|GN0^X0w0W)p8H;CrD^=M)<`ZU2pLj5}g7OgVkz}InQxqylF=TiC$(FH&wJqc-6rT^B0V+IQ2R zyjQ6H`Z07AeUw?5jf}`U46h{fJ0_`n5MBpcOi(*)Onr#`cT6IP&>X^=icJd&j8P3n zOZcb*$G5H8vt!oBtbM*%itQCcZITe^S8p7)j#=f{3#4$lgC}M#k2o6*XCm3m+0vtl zbSrZ!MQ7j{clP>CHh! zzwq77y=L{jGtG@F(fU!>Ug8_oQs|{`yk#zEXsmks4PzWHjE0ujl=mwX5|(GGCf|i? z39smKKRZ0OAi#Eeb~y`w{DuksBsW%(U?TjT>of8DVQ$S)5=i%FDGyK8*j3P1+EqXK ze{GMAU6L-e((nYeH2$1MfV}sMAOHz z5acdQrjKHCL71)3M_X4cLj5;~_pN(UG^F1+sY%i0v4_f#QN;6UMkN(UDL1P>aY}KZ zSy0<{+r?QnvOt{kV>Fp+^s=2NV-{8OZagzr7R{D2CC20{FrL5yDs?rSNXOEhn8rD1W!hB_Q*VVP&BH z-lmGzb}{pec}$DSygZN>1WRx<*{)f;>5R_SkRi*-h>21%E<bI{-=OY26-xj2OHv6zc zqu*vV5}k-4gF5C~PPf=Ee?(vJIdyoYTJ*xZi{mitYm5tbaHB;+*e(E)_E*x|c%EHX#@AD6B6}5ZKw2G_T{p$?gU$NZSc5N)lxegFUItEzH zLClnehMF)s>X%r;WfWLxQah>)iCa_6&DZr+b z$$dVN{6RUjNtTb#o-@U7s)xNf?ZsYDyReJv-yV{-td|dhOl-Qe2vl zDY&X@_N38^-GBI>I7pg#1^GF4`CcXA;N_%JgPg>EkqqL~nIsI3P zh-JdS2j^OFYNYDAMC`P^&0>v^O_0c_Eg!Z*gKU)gsg-gwN~qqcMNoZ4kK+z1h!aj! zl&qK8+2;`<*`&#$8f%Hy(;(VOO|r<&vWt;@$%(}?T0TnVK6N*`XV8DPm@=@7M}HD? z&MX2E^)&iB%Bk394@?YbvZb;<3g(KE0Fvc!B((fGywYK&8*;-Z;_XC9lx2Nogf)}a z0Sb>90dC>;T-YqJC*oL7=F3RYJl=T0D8>?ALI_yjxpoF<6QNvfNdyrzzP@bdb%Cu< zH8AUg15@E9Chqt0R(3N&#^LmK+N|}&^nD0!G9JU|4?R}BLxQ+$j6x$klylM8?-I@E z`9~5`EfX+>se@>~g4W!39Ypx;JC3!U(4Xwmj{X+?-sE;f=IdAX ztST^N(Af5)blLMLSb{ZD%_a12dcK$Y4;In*L{-Io32QRQ(NX7vU_a3l(!p`$+v$D< zPhm(W$r8L7F3E!*pJeILj*}XGqLKNNFX^+9wF5O_x?zM>ZxpRC8d|;HKKT^#N6YLC zJNDx3mV@|aX9y=Q(`u;;f(G_ah~I{%8?L8I@7~;d}@1zNP z1lNvJk8oAUd0d-OUUOY5i&zb-ni#gjwNm_G4)*&w>U|3|{Qvs;LvwGZ@Gt;#rkM%9b*Z{oeF}Xp&DgH9)`66jxS(1*0qGqh1|oRX@HZvYs@`qVbd0{fKKeB8(VX zYG)qj3h(vRV*cdh0FV8ZBo$p4w47v2Pnb}dE126@M+t7GkMMaVYY&Jsb7BP=1u7#Z zV^9ee&uoPrl#m*_mf4J;QO3`iq=zhGq#?*8x9&VSb_;N`B0PUO-9S-eOe?PZ=KQYg4fvX-QTQ0=_<9=R+{|5!Z*I73lMPk1oxt zzp4^s(DIGCsLh78q0jCToYE@%Kx)M_hbvy`eZm>eVf==eR4s?srCsqnV}jVaHzxmv z)dMNR>Yc1WXWH|EezfrCL82(?1req^KQA=RxjlDf;&`tzTeaeH^%vvuxC}Kqg_AqX z&C)ugh(S%ZOVwVV%e-d%=NAl!dti_#ZdW*_5o>TBng;{QLhf*0m~I3+wMTSImFezv z4f*+=#P?W)+Y`+UT`lO<&ZWOG^5X(%P<+DG`mq!y2cnWyB7&R~BUZ$we3n+}%M$Qqf0D^|=-m zAmvndEFI&?7a*Y(J$GJ>U(CWFFU;&M3V;Hnb^Cya4_ZB@IRmdMI(<~AvqyGV`5wr zp@*3x&+xg|H+$Y8L5M8wsMFRFg%}Ixpb)hTVE0LbP10};@-jGLA(0WnsfG&&sk|i{ z2Nqn$YDP3~FUV+*V@`R6GWXYY6EklPt@4nq%0TSdi`L>^FXuc5{29p{j(4UZglD`hHpvbN!LiJ^-w+Q#!rk@H9P-o#j`YW}o zz~~P-ykT*K%GX9TQC2Zd6C~qZycjxn@1Vat=8XROB_?*)!#ka1snPI|^PuNa<3sM} z%N-M%&eOJ^pk0S>jq9IHM`3G7NssMBO$XTq9(a$U$(`n;2Wk9tq!qTI&(3OD+);jtU~xXbg%kIhG8~KK%y++Ixa0E$jXz3co$&)*SKfJ!g=! z!fwD}Bjl~X!zAAw zisKCwE!ZmDwRv^>_>xheri@LRLT z4!4TTXjaV>N0q!?Y;Z_2HV#d6U(ik~^3n7a3;%D{Pl`dkL##rhGV!EQGw8Kk2}dmr z4h2nkUdm|`y1YdKPWTs85N&jdigS_e4|YjTdy~P9dVGowZt+tW}W%M zqJ_@3{Rx-qw0i+`IF4^xi9b}sJzQBcf_tO zNv_f_*KTP)k8j@Evm~y#Xg^pwwDgtFc+$zs&79w$Y?z=jw@W5;S>~+{c7^&uo+M}OtbRO-;Ii7ByfdU;i|dvnIqMy;MMWB7#%{niF5Duc69?tg1B) z*Q!3L0&2lZ(fufj(QW$Y0rpjAKQ^H{^0%XaoI3ODXyv$3JiX@1-hJ}$ zXhcq zK>X;Q^cOD`Zy96|P_jdlqV{-zY^G=wXSFz@le#NP2&(ZCS6#>C2`_FX+s< zbDWyVyPZ-ERowKNSWiv_{xxd#b{`utcRMFcs4biOoski{fztcc#QP@ySqcyRLq4hy224@r8MlgcTE#Dk&c+fQ9u=rl}Vd2oH z!B)TNL)hW>fD3yFz^gtciqzOa(?{9)#!8HedZZVjV%DLczF9tJ1}Hz(omvOxyDE*# zIUNTo<(2#Gk`OGH%Z`pO9niR^$fdL_0#95jw%A8MHJ7vJK07)67y$!S?&<1sJ3_nm zsr8MVKYDb*jB01{(rMXG(4qsiI_;IFf#6IJr)0H!U(=7KPggoTws-Ua0budx1SgyV zEdJngwy{m0z4sdw7^XJI`G~x3<2A3KFP) zNbR~24LZ#}BvT5$u#i6vL4EKEW_HWdseE;wNp!G1l;b>#`Ax@uWq8n{5Dlcf(r_H< z-BGRc9qzwDeF~Fk;sAhpg1?;tkFlG7p8_;18K{L3@eYA(4pI&E(fx9Ij3A~DAHZ91 z2kqG*W&=|vcGmE9Mr+}YjH?lT5m@A`VGwvhi`t>vMmrKp7XmUERwm@jS_+)TY}$&bpB%d)pVH$rNoEkbW?VPI=LuS!+)` zwQ1Dctp1Sv$b;g*JV?+(VT?u@;6ZAX;2F>l6Ddnsl()`54wimC3|(1jY6%U#?Z0h) zUMkUbO~zEACZMv<`7Ctnm3~)^)v} zA!xfmW8AEI2ar4oN1_9I;{x_;RdE*kVMlQANmRGAF-o|rR{f5_LeO=Yu`47q%uZ1Y zVp9B$VyH3p*c~)V(_1ZB32g|ZS;NnzCjFbG@o%Dr!m%r`0+uxL$R28pKS#r%oJ0+A z|1>Ehap*yE_?nhXLt9`aRbQK(RID)zZv7K!Pq@<>=9GX{nD^5$;$m#J%0Z`*&Cgg} zmv{Af`!U**Lj-{#qeyvKSh4p{}B0&0P(XtcBif?;im7qX2*F(DFs$E zPyjw~Lt)VKbAm6>VL)SgSlR81UhuKDjGlK!c6e|w9{sQ|f#^YY)ItIBl*84gVL;o* zmRAqMwWJy1@P$smfBx;+$326TezFh%|L;Wr{O_w$l~Rvfkuh1BKuEZL ziSKoaVJuWD@T^#s%j7GJ!!byy4jIEzFN;0p6{I82BtQmBpPuD)HrQNNs~QzYvob|# z_aE_6W}FboNd}H|Jzlg(7>2K-P&?F#iZ<(hM#J$7MSDTj;~HRgfrNSGFSi;Pg|VQm zgG9icQ?Y>>93v+&Rmq5p3M(Xx6jJH#P345ca^Y~wlWVAeeIR3t_YP~t_haX3q9se7 z?f`m{aC%Q8w5?d)4)KQimn*@VHVjZ?mutJ3`Rpm~?KDAS^~tT$Kq(cy!jsT;XRUg7 zUPaHnAqi<_StP;Ho8m9LCu=V7&#rK9&jxo#EI(y7@`<*ikN#@%H;+v|P3`DB!Z2dC zXI=(q@@6~J%c!1+rTJORh^=}G)GHdwJmMdj)JkF%L<<&fsC78SycEwHqhj(aB(Ute zr~=m5XjJ>Q(>+pZf@{xmwq`Z5An#fVKaWZfo=8hO9|BE&H<3W64_CUOzZfKVgt<%U z3{ov_l~!_7=#r+Ob?WQrAqNzGvkc;klKWYdbngfss2w?pk^*p(f0cK8nh~{=;@3`` zd@WgJRbkQQ)!;*s=1xmen;|{jaNFQ$ec6Ktd+U9?XZ@FI=Nw%sW<7xNzh8GBPubKd zsR57GBYV+byeYcS&6ZtC^52rhPk(_L*Kd`^1M6x*n^33ce1zZGkxQ+uB>oX$I(!U& z#lzmr?KZ}E;Zfgzd})bT7f=0=xF!iSN;EEQe6k`{sYm2Hsz#I@BlxyaP>3|4hKCV8 zHZNvCaMZLrMMtBUf`)z0Ndk=l5xolmRA)gFZ3=K3G`?>}U~U5j`54YhJ+d*){0=sz zfaJ<*OdsmrFMS^c(D#KN_5H!$`u+^v2=O|K<-KaoG^g?12a}{ap9GIDvU;3C8e=pH ze6!zPML%*INez+BR7~KdB@`5u#z$^*5${|-G1W6>`)tL5w$n>+`jBF2u&%-0!F|1n zH=>f?x!6LE2Lw;BB_~Ixb|%?BV+l~39$_J~3z>rBM~R>LvB^6LX${m9fHLcZ?s0R8 zd|zSnR(Vd}NdWSGc3~J64sBX@vUeCrtmONP=bnDl4RSF-1aIkvIf746)?&nv-q81Y z(31{pR8Iq}zPem%z_$e*4lp3(x`saK9NxyX-9N2f&!-KtqP9j0BR-n z@~g#Fpr>EHX8_R7T%pK&fbxD#avh^2s++S4pVYe-qCGMsbf=J{-T>p9jaFir-lMkf z1!(&&bumuXor#B_O!CeVmo{!H>$&!Zs6hE-EILvObum!(ll zbb40%h^BFqk>qAbTWEOxXkq_}0tlRyo>zch^~Hq7UiR(MfKa!lKK}%ix%u? zmCv$3*oy*=)+4RKEDGh_@izfGTC=|#Eh#wL&mSx+OfaBNr4ZF=_FV{Y2CA@s7xYVc^1>Dqqt66oxSf6^FgfC(vUgzRxa(F;{KoMzcF^(ObG- zVUS6mFuSs@Nwhy2xbJpV_US5S-kxtt+V5x#??!-Mu+YnGz-uBw^1vRkK{N_v?*-BF z4ruH1xF3D@J}gyjvf|)@q_K-&jR8_K3XmG0ts}zF(pLrfO67>#48UrxmkO4w2Hk(@ z&W(xCY{k23o--KRoMs&b3@rj8?^KYs!&m25yKsv&N>HY+6QUzr(|fMLjr{~@?2?T@ zV`tU)>f7U$Uzpeuj|GNt@p!)ABYWYF`RIu zFQ%$+b5CvWg}GL%x&u^^%6ivC>Lf)ex8}5W8eaQ{X<`|*eiz>K_7~F?ssz~ zG&*!q5xGOLlVYI>;MPve!&dq<+-X*NqVmKhJewnSp{VWEw%xX!QPAgk{X|^%n6Pjj zQcS~MA0ABeOzXEblW8&#j3Wg=Yp)>57Z?$$AetTGZ`2GV9dF@amBOHi5e_rrNfZo? zET|rote*dd{e@T5X3{9p(gG6cA`DmZB%udJ6Ijc z(1g1QhF>xw!BJ)$>{4J7Kw0qAv|44ITf#bOYn}3J2``~s6*lb&tAJNkKlAG2R|v&t zA=M#F-!V~Ps;|DC%YSte4=+Q}sPD4nJ)4);66j1Z3wI-_%xgIuV}cl)x*uz379~VI z<9R}er?$Md$H{JKRJX&M9(Bm{(Q9hZ+{{K1<8BZv(U|AGrL^qfvHOZJfeN zCM15~Lhv(N!|J-~B*jMSc`m`J4E;>Ow9`YDLnt90deM(D`HCaT!axEj>)&mKqpBp5Z zt0M?{Xz*iF6a3m&6@YzJs0jU)z#+uff?*aqfd=b?eI7x=8fBUMh8A=W72<uOHj=sgsmq>E%$HfdmI~9jKgdhwZ~13=7}s-rMg7qBXJtMzhs%C-*wm%C z*z3JaA4^FOAXoAq>-CVd5qrAN-J-Y97`ncjtT)OF!!zJ;r)a@!@{|S8XsFYuVw2W` zaws|=KWDB5RU+i+-gy|%uH$zIi}B|?#ZptT>xc{6DNkm5vEjC~QE|_D@uo3LC)lN{ zH)A(ZNlCrn39zrGilZ%>=UGXou{(LJHNCu@((OhPU4menGx-W0@ zv`ad$2-thn^{7T|G~YKu>|fO{oND;?WWos|x zXYzWwl}On93hBIB20}V%laC=C&2Y%d9Gp0Mg`W(MAsx8dUm+d3zX<8fRGWE%1ev$2 zXnzSc=Km1vGl;I%f(XRiARo*>dMtFulWsxhLqLL-#JgF zsZt@^YrlRSUstC=L=sP>l)2C#DL<$mYM%&AcO$YEu*0@uq5AYH)6@n;G*$gesKEe) z8o_K^_FqDcC7kU@oK}S?EA*))gj$(H6O&Od0u06L5jf^9W^75iq&@ne8!WU1}XI+W3<%Av6r-hh=|W-$ui$| zzq@Q2JXYhaQ=YQz`B*=0R50z_ploU>QYBG*5bSHb|CmZ+{Vt_gd+A%@s@E(0Ec!Xc zRAm;wF=lq^-e8aP?quizXErk@j8w^s?9iL!)tKi~&JKNb)@Xg>jD4Bzs4h`^SH*Ki zW6w>(=$Vw+l)zC1VHppo5BC9&v9zP}Sa2*27l@_7UVv4aJiw(Y09-2V>n3w=g!|DW zia8=}23v|2L#2d7N}ulK;DU+g*SN)LliQI5SxuJa`#&$zLGqp72nphdC|D)#cg7hr zG)6KTIc4b42&BgFUmh_eZn#)ISo*YhmN$5eFw^Z*-tP{W!?u%^!CUF)Tc>qMx>dRd z7DaVKVpY-3Y=}?R67J^{N_(c2DA+#2|1xh`G-Nk-3bK9`p!L?6ZDD{&FL|?3)E06{ zIjMWiX4chtsCu@c*$eVNi+ZE}uQ9c&`qapVfo*g)G$lFQP5P*Bri*#ndS^52%gZ_^ee4Q#Pswqr9LoDiex?uqakvBdAA z7;-(S<=VI%`Dw{jMSUyGSmnv>Oj)%6mD0VQtCg|Q$QKtkAhH8=|Gf0R5FIGBPx2iF z7I?WC3-~fIj%;AHGENLqZzSbuL0FY-^QaTf=rcJy+1?@SH+HA@> z_Y!|l#aqo*vDa@SPl~Z!&QX)2TGw*K;(IkMK*&2hOBlGyP_}{^{F$#aD!!Od9+(u? zNXm!EQS$rEJxi5JQj_E-#$Vh5fETfU57(69C zI~H8QJdK!)w}SHoH5~(kJ()YA*)JvAwgsF<_d6Qw7;W$0Z90f#nqK->C@H6L&QbIt zQOM~4MX+R4!V10kHU@T#rEPmJs|`9TMfFm>r7Nts$2^8I~W-?BJcIY(pX=YpZzgbAl@2&}b6KXesG7Jj%rwttp;SGo_sGn&|s8O=B}M!Wr)>YR@J zvGgQx`yWuuZ*&COf25Y-N}p3O0RF=#6XxIF`@2{}b@}_7#w#0N>Y4sTp61BmC2tA! z=2rdoRFz%p`AYj-50KK7i(MKiBLCI?5rFn@{om}gI~2Kx;Lr}^-(vr_TMGi*Ddb=7 zRF&+YcxfpbP4IdQOH4A06KGRzP~W^b4`ZP|?&5&EWx7-hh9%z(C3QFjlrnyC!6*^Q z8~*_y`Vs2?B>D0u_0_R?YD5aujX#QkkS*g_C}D(S)UB3+pFl z?lbDqXSl}ik^<>9qzLm+M4r3@yS1BuKV^tX`A)dml4wMzZJ2?^Pqjl$5SLO?g}g0> zbs>}{2U}1+{#EwkvlOYMcZxn1EB#w)Vmx|fnXq*&ulp)q^<#|c7H7)GGX!Jr@JQAF z6Z-2+4R=8>`7T-=Fg(Vt(M7qDW$TV@WDm5>f zhO7GNHfWCN!gAufLvPUzAyj6$=+AU(1rw&Jz8y;XR5rEIKB-6SKS0jvl@lTC1P9XO zz;^`Z1*l5J6eR)NN8F%1nHAtZ_;&0MxVKq5)^eb;rvr{QMgaCsq1WfGmG4)zh{5?h<(kx zoHDiB@#q=&+b^R2X<}=(J(B_9OXfn37$d?kAP?S(DPD7V`q*@r^b!qQ2;yf-d_)Q- zf_iI8`ybRpU|pKn;pFnU$={Q&>ndi7x(qWMEsN0h&Jsj>XC{naeQd)(>Zc-|)kC5l z-|VeR2Zm15_=qZnVq;@M3!Y&gV)t4j~LE!;yqo9u#LwL3jHBJUgt?5^gRJYSIx4TydL#4Tw6W4CNMy%`zT*C8C0ul?IZ|)HOiu;dr zq6&b$s=x35za3f)Ah?F^l~wl;V~Ug*V{^Eenp0pxFM32 zz10*Eq^abAM5_JG$QJjGf!!^@{t^F${r80dvW}T2!2TU>PkT1G0QMj8uk4@VU)jGh znElV11MFY_U)g`}FZR#+i~Uaurk@(59aP~4Ja6!!QRdQ0sR2?u6g3fOA+q5950NU3 zX{zaGku|fW765SQETI1reQyw&!JyX3&Sav^rmGoIOT?*^a8bOQ-7|QhX7rWhA`)Q# zEs-(dqWW1}$8$(ax50;*)1H=FI{PkbA$4pO=IZwb)Cn_2&)wtQ1USy5?p1Ws6zgAf z)It@nrv$0+xQ>MD4O}n!xUdv?5l!a{7a=-s>a7PZ&*4S4#eA@V9w+q#HUJS88;9XK z>$rY^2z6Xt5KJCPRDb^Xc?>l1X$^L# z%;MskaV4A)%hLBQFVoQ`%R}FNRqo{FF0jX|-LXWR8Wu#toa1Oy+gSVO2#7HLJp%e} z(HBLE*r%syId+}`T92|9;yOm4+ZLwV)x}Yq*`w{AZHT5s9 z315kBh_{fSwuIB(TkCHBxJxAK1p3uH_tG~gbDV7R4u3LhyBt6*;!>V!L{B}RC^yVM zPA<7<2+ELFKcu=t1mWnNM9=YwRjzpx^m=+D^Kc}Km^vy~CT=6-;)>P{2(h1@AZ>S| z{#pT!)|R)Ii@+;DoJv;9adBr5fd5)P@M9JKRoB!|jZYf?A7{WnyxM=oKl$2Ra~-8w zSOGCMs$zr_JYnudU3Fq_>=EW%WtM#|klWN(e?O6K-*K`iQ$P`|W_BbX)_;x+#5N&a zzs%CC1ep}Fi9*y!8@+rZSxH>X|HZZ9mCD3K)vv@(gC!0i_MjTmU}~O4b~BDzbj(*_ zAM#FaHoPs;H%1wji{!=RWubpH+lEJ1Blhk~Uqd#>)+ybj6)OzR{L=}sJsZPrShZ?` zVd5|%p};3FdPpX0TI6yNHLmJdg+ynu^=?#k)6J``Pt}rWg7e+P>jPQ_x%5rV+5oeP zKpWTr@`~%B$61F@VjS^^v7#yX92Y}hHccbV6O`T!4RuYO`Z1bXXwKH%ex9K!{sMjV z`ckB8j{S1Q#}aKC`}>G*-i0x)_Stt%x-fzjd(qz9+%qiM4D}EymG_#GZJ*Ly;;OM^ zQ7KSo0%4kkz8YcWNZ_k6b#s;-Rf(C_Zp2BGgmOP#6>g|$d-<~KQwqpbKCbgqR} zA{2N%hzzO=;rxJ(^-+Z+tf2!Fpi$iFk-8u3WwTONckksM>>t4Rcj8sKE-Ra0f{>ki zP*h1>m8NiXPHn3`Ura4|!$tjUG5!|P%|=>M^(Zbi-^<-e(q^O9pABl?FvlNe#)sV= zf8?kWLAJGOD|OU$NSHN0OLRO{(Al-F%Q5f5cCv7`jswRY#-?mTn z6h|w#Qjho=f9#FRoN7fz@k{{1n{A}WCtv-N)(}4@!FXfG@5FW(avhF{(0;!r2=~qi zGjW$)1_}Wqhq@yeqf$RdMDnO3v3C4ou1u)4F~7yqu(*-+$YQ}JX}ob!I_u763sIVD z>!&%z@mJFX9;l{IramUfbzF&=pU}_zg2=29j#dyIWjyjNwNZk{Y6BcH+FtT>jj3@XT(ysop0P|GHc zH`5|)tq=$H;XwOLvFu*;4WZ2n)k@c=$5D7TNhm{$Jll|F7SUUu)Z=Bb7wcnO%P=tQ zfKd=?kcQXzBH(#N0L=`!X2O~Lw8=op<0ugDU4%%L!U9Ht*~$ob6ae9U@mxouz6PNY z40@gHEGCj{lFjsUn%XD{m#MoA3pZG`?Jp!330Tg9&5<#|DJSmw{p2h~naIt&<#+1g zxmuV;PCR#USS)KQ|P@qoP6>| z=;;nVIUe1(SMWXC&LQJMo8`u{KCmRszO=$)UFim6T0oLIJPkax!GE`D=yq{ybfr#(Xa$&zRQ@Y9OuFsmizk zHY-ngP|IkMR}K`K1-$mxQyZ&?NdBc>WqU6wCL;61tJ<;(y;?Xck|}-1diasR0I6yq zzyIPiOpwHEC(wU2Ek8wUtq zG(A9Pn>#5H?C!aEr>it14zx~H=u(nXVa0d@C6|_PM^VoDYFf@2CC6INey0}L@bpd^ z=a%19u6iFCTsTpKF3#o)IpyEIw;SJk-fu>;5|ng3=BXHQh&W? zQY$F(N~wg$Rx2fsC7SGu8Zod6L!xE2derK|I9^Now?5Zh-)5xdw{$0Vn`z4n>|e5p z9S|3!Ye4A5k#TBvDix4jg-!kabs~`9PqY;zk%gryo>O1|=hgCR9uxfEd~4n4>SqF1 zTTwYw%05b5rklbLLhJyaCtfz^$n1aPOdByxeSO(a_~9SHmomb z+^wh%y0;fE*o4Q7PU8S9h04Dj>zRY=&$iC;&bLS_5$U3ULiRVL);`^o(S!~{L&{c8 z(^t#zV5S|Y6{|t%GHPWv_`${WxJENU{(({2?xGX zoN*MS@2d}w`kp9$6|Q|=A2?;L^CVq3eewhanMF=t>Wc*D%DcXEkuqjh>zNd|7v(g~h!GnO( z8$TYaTH6R11VXgm8wn)5GDBV5Ioh_ON2s38ddR4>MZst=)}Na-0fV4Ih`VvS$ughQ znH5N{>7?yySWFD?l{NdvNjE<%eBQm6*0Ii4FIEDJqO;d#mh;jS3$ZSp%numGw5<$n z-t|FH8Bo+DjcY|#+Vyat!k_Q2AeUY~9J2rAAW&5c-0lD>0rhVy;jh2Z;SSy zJHYWj?0{dYC{JNv`J*bD0dkI_00-E>lqekhB@3i*_iWjm2tbJniE2g)0sqTN51>RY z*&k&mCaeM@WJ`b`KZxlaQ8d}eV;uydWrDzUFy~&-Wf?3xFru&gvHw~UzReZpcOB@_ zHPH4#0(F2`DiC4~H>j6CnLtTx80kbl49@R7B@N;ImERe>veW|S*Jk#cr<9ZYPQ(qg zYM&-RX)~%=Ws1U)TXI zBM^DrObC^(XWaCD^%Kq+bmZgD(nX7+90hH}-t9u_kK){s1S1Nh*2&Zp!4#eB7MSjk z$Hpmy@jB!GLlxaL3EKhe0Fl@?zgOZr7(fnsg+Q@OVh%($X@PBkbw;uMLv03l8>nOC zsF>A1#+H5CnF8^gyBAL6SWKpTe}V~8cJ6MhzJ*<(w@O$sa$jVZtbP#X~IH88bl1yeEA5w}FJe{L!jD!OCVE+j3UtSqR{IUZM#7xO|h-YbLhn@ny?`y#Kt+&Jg!u#kWE;NCt z8jntwRrx-CqhE?1Q-M2f8E_um}W$7XjM=2%PBDfx6ofb}nEMaH4d) zw_Q!SrH?p4UBY%5LCNa{fG_j|0KULpt2AERrzcoMC3>F3E|Q<;;K(zXPel=r{HIK_ ze89lxpZwG;y*UZfm&yI;gQcIyEAN<8G1GSt^dlm;+Hwj)`Va@PjjusG@u zP`t48C>pY{QkSwBaF3xZ&>*N~9-W=n=VE8%Ue*$Kgd?D-asqTvUcL#b!b>e*>631gIb?3zCDdQ%@uFZk zIOLO-S)6(pYEvh>gj@kP>3gzuTiHxeo3F2qfE}Q37KrSp51TkEE{BPl6XclN>X^&z z2t}qZc+xhHf0;Xc+yMxH9RLClgC2e0!f4Mn`+-*(fEW}r-U-#!o@N%WYzPRVR&PpN zji45;f^?SQy40NjFF+3|8t?*yoqFW3wH@I=>^~Up{EoA{|Jn_URK<+|7XaGd7Qk;C z_+JBUL@^1vpGl+NDCsD*j&-i=G3W7`;Hely*x!#+QZTX6-uzOIXjv=aHK{E zf$I#uikj#sx>H1$=%K2odT6ob+ApI+9oak|tn9#XeR6PIAM+n^eaq5+#`Visfw+G7 zWh#Zv35Or3qDPbacU=G5V_YBeS6p8mi0fO}!-v0;){z+0i`*-TPbv}N29CP`kv16E zO~gTm8nF#j#k+=z5t4N@^BcvS>3nq12i4g&pFpo6*=~{EmQ}zGqg#_ZdGnatWQ`ug z(q2S4;O>^ge4!e@QT@?PP!F(y&8d@^X7PeYT&DO6rja@(Of9!%qZ#S3gFA{J;638@ zXFfS!zrsi~b)o&R;!41c%>e-x>W@wK3Mge_}JzNgql; z^AMMdJq4eDdEcEP`y|yWD@^MDBkY~RE9)9=!PvHKJE_>VZC7ko#kOtRPAax-+crA& zzWsNf^PI20zF9ZxcJDdH8k%4-aYfHWdnR*~M};krGss(hyHj?=s$jEr0f4oK_HbK7 zM1(Wsc(qmYR^<)DT8uwo;LhwPaX~GQe;4@(=?uY(;kndZ&Jux6&wouftmbwa?E0*> zm0~*;l&1Qt7=&{jH7(G0z$*?o{WN5%U-(@VeX>4y?w+3Ep>f;;B=efnmx~3z^p^u& zST&w7$3kk{h2tUkU0)#ul zL;PKf!+)To_S(@N=8Yc4c*TYV``_kGR5vp?-Z+oNXCEi^b)jPD-_oa~q*XHP41X(zBnS*y%#k-qI< zo|G@inkb!!&Cb=n&VT#>2b6yhAd;{DJGX3>{rUYf|39@L(Hzt-r|&o9|LqUJ^6%w@ zDr;fiCEkDi00N5nD90@XGfK!6IxE3;iM8{5`@yD?O2)Xjjr%j|7r_Kh$b>@rhwz)@ z@gMoE?p|+kg~srLO#8eK8EB;4LhDR;Z%)N|(L$0o6eq@gZ*v&Er` zFT>6zDg0>SV*2CD6zuhRdE_R&5c8P*_mXntQ9d!ij z`?b`&Qi5+)9tX7O492dzh+`#`AyhUs-z>Lc&oCU$k; zM2>2jxIzthH0A7lHj6(0m2*!fRSv@cqtn$az5?2jwy*K(MOyDHzNpSjZO`&*xhwHD z^zLg`{^2|=G}|yN4@ZVeZa^WY*)P@Vt-B)d2UN&Q6NeXmDmaXBp{GJMVLj?40JHpV z4z}aoT+$|A;~^5PkfU^xImy(D8YFLa;~iC3JfP<85-#-bNnr&1OuU=a3h%aVo{HLt zk$S_jp}F}#r>bwG4=HJTZG;o8Do`<*kC1o@li? z9cInBmFzQ(I9-C}t^(zkEK@7m());a#yZ25uPW$u>i!Q}UnJ>4bALYe|1(RMj_b_n z`Tsku+5gA5{a*u_z?M=`^cIN47>W(l(_sI^c6JzQ8P=Ho5|)R2+eqzV&_#pqL}u(! z%q}6%5AR{-pWur23c>*^3F`mqHNt=O8nVTc`;YdKzj{q71q+I%28L=$NP%WDc~pMf zcW`Irhg^ZYVdaJJe$-#RW-^MnWl!;t(|sIzwm)lFpn)Qn{~x_3k#@f*kOO&yO-vIc z*O!)$mUZX!K*d#MV12s7~fZupWRzgNi6xx2RVPVMy8O^$*+g|`%4 zz8A^jM(jqO!H#da=J4eoxdyJQ9lW$gdWbrf`@mV)8XvN+cw8GjJX~Dn@g!s=3p>CF zP5u=0(=Futw5Bk^s_P!m>f0uZr&@iA653+z<3&%0Nh6WDa~~W#EIM{{6q;e)^4a~f zqgeq{U;qtlII)M*B_=GG7p;(%Y}uspU9L)Hg$tgloyr9HKCF`f8g)*;^_l?da+|+; z&Dz(rHtS;#4G#AFqIJ7mr$xaWv`zJ^#=Sr(%#YNO=QgkL?WB5iYs*vjTySVBAl=Fv zJL@kQ{*7_fcwXexm`2Gr6;&}t8{mxNtg>=vyYIAGn2Pr^V~85eX{lDuquqz{+BT3d zoF;D`f-SM2{gqROqXHq!kRe@}72FDXX$znEUz!fgjK0;x{o+ivH^F->x~?@Aq8*M) zBNC6y>~K2xPiRMpenVY#NT;~W5&Zw5>A}lyJWb>$I?sCX5u37x@GeCPnwbmXh3-PC zM&XZ~GnC(vg->YX%(fKow_V&z@5_j=4AuPQ4vz(A+jl}Z*blz9d-(tOeTs!z^75Cb z{MVTg_WxwthBQ#0?ShTvl6>!CJD;S#C zgdEFd*tiSHp%t|qC6#)%&qy!6=SlM&&+p-e&GNjFtY-o!yR6;rnLuXi$!<1YOQ9t4yit&Tqo65>X$elzuv$pzyf=-xE@ zgPw1-(gxP^CEP!ssKU1yONfo$Fc`dMhi&TG!l(M#Q7IR#0vx7*g}U3(!4xu^AxuSt z(ErjD<;||AANM+c{i?|viP>+zs>6y?MDHKJik9LNyJ}#TA1jK1V3B5W$5WVuBu#E+UgWU9abMMLNbn#!TELOEA|OxpK#*@lZG23Cadnz1Z@n=}R=%=4ZJMA8Kk0tK7F7 z87J`De|np2(QW6NcgN)kOCdAJkWPG?3|X?xqhQ|3NTL}$cfk#28RV!pBNi`O$_(!EOfZWn3_?`v8a5T<3M#40t{ zqOz}IrU#s|H7mO2SKPz({;i%QerI;zYF&$M&|G+VMcp`Y(ss80DaQ}E#!ASrU$Kz-`OQ(Ni2lpC z6#GA(?Y^d#<1PoqLqHU*RLLNYlgT!dITMWs}v}rcwG-hK<=FmW?5H#w%>A_H4}ce zX(OZ1gj1;_fsP@A>Sd@jM6#B&&CEMDZqA-LHxl!wd@(Xhkpkt6b|-vQ{vn@|dh7@| zVuC+Mc3@izp#lS|>9lLHt@U1RFJob;th5+9h=(-3L)qqv*=ejlu{r{O5Kg1@q}se= zqsvo=5h?!}8MSGJ5$RIAKp1s8%2Ut2@Uo%&oOuf!tvwXYj&{BzVMU?x$vD zpNQXX{}eJE+_NjzrGEMJ22iO0;M+F{n(Yrf-o0Wa-~BGyeC^E0WVV-{zEi>C1!77s zT2rx&xIFvCbg_8Lwg;#K>Ao=K*tWX7b{m38S`tw;zgCvJz$MdI>dM)c^c?5Ni~8HQ zDTCt%bgfj;mL(mxGapm5eP&S$vkj8eXonebzyb`*`zWOB#*@eherC?@fB_BKf4<+} z)@IB3{L1NvJ|V)%G&hFi6z#rPT5XYc8S%WE4`e^{_4l44R{mwyLsM<{LWNKmbqgeucm#3{3s zMg!x6H{4Rh&HIP(lLskkJE=m!`=O<_UYX9^aG+^y?Mjn#geDZxYm2HXFL1obhi|0M z>mL^H7(Y+9)9T=m>nbaYRBxpNRemi4e_7}d`+1-5a*&q_4swRYmZ|f@ur>7ZK|w_2 zcvBFFPRmqK*k!5P4Ew7I+qCEsb3uiNAO(o*!!`P7+Q6OW5)<+Oox}j03qmvX@eM;i zzn1kF%?j7-mr!ZulkRVlaK-gIc|Tzi9p@1S-|OoMg=ObqS=DX(u2v$p!>|2FF%rpicVP1vosLpJBIjsw4- zgg4qKC%UCTA*zlyr#ER-pn=fj5t5T^4=KviKd~aefO4utH-|Huh~XFddpVc*0{>ce z0D&L<27b(B$?burw&)6hzp*8(JNH3d_K>Xs=Milk^h6emUffc40ZB54GD+0VVY59+ zKZYa|c%Y8dLs?KMr^j4Tgp?60!6cD2g|$$ZIKo4v$IPI1B&oir%jE=px ztLvEEW@_P$7e{*HZYL#lB~99m$oRQWUz(e}S_PGHT3mpdl^DgC9raCj6%U6euet=~ zYyewqxd>(x8r2NpFXjcPk;tXADZkG}C>rcbJ;V26?v%dPL`<2P2)3^i`8}chlt28@ zkMuh;+>R{(M4-w0h&JTN`xhsI#_J*tWci8reW6XW)r*r~;s>qEhG9Q~CxZ`5oc!}J zHM2=N97L%990iNuB~hc(WXex=vKM@JZg4H^T}j4Ss8l)?)N(^7Qxv;~wUjh^%O1{C z-H~BAV|!%$$not}d@88NMo+@E3&6GuTuMz>4g_JUY3u&vtDGZGssWRe9K}Y&VlwPZ zI%dx~4&t?Lj&To6d-|sXTzPZKh*uFmVP55bF4{AzGFMK_uQCckpBUqdEMxbm;HwP7 zPuL@TL}7FhFG!3A$jh~4Oc+V7DKP zK;8Z)!N{&%c-91MfT9P?4PF50NGhwfS~6x3y26l>-!3BQ$c>{ZgA-{rzXOw|9+H~B zZZy+gTxPf8HuFh+Wb>~( zxySX?EM2d=;=s)ZZ7WAY5_3SFM|bk)&)qv4C<0-9-tK#Q`mayQ-25UMtObiQgDZi) zPq;LWK@A4E{81i^1I^i$r+_^CcD^ry3F=W&5&yA9k<0mjb0gzvCVaKgV-n;;AgdyP z!z>d}uU#2H=ybJR;#MAXy))-$bL$ZXY<$kZyw;C4=jZ@+mbo#t+-h>Z?yUAgqYyU_ zMN%`N)_5Q_ZpBX+r%3H&3(VlJb!fp!H_QZ&5x1cgsYuaVjrtzDQ`J0*nh13-NcGin zzc>Pmv4O!@#~E-3>5`f8to83o*<8I$?w0*|=UG2fBVVlMzZk>rfNC|d9rqrQd0 ziy>>URuuhe%X>C-yc70!`#iGGoxRilyal+_2g=0p-4z7-o=f}xT3-K$qW@i9-xWpq zRXzW;ZHX_<7HX^CT^@tF6DJI1g~kQh;dGD!Sb-7!GhJKr;m^}}M5LL%_^P*gfsXOi z_ZrTxK{GwQrP$kuS(<)(F;-R~6?vR(cMN*2Q!>4bCY6J;m+C(mk?%BO7Vtwq!tSI2 zn>fx&%DLsbjy=#SrdOvLoG}VG`oguLuQi9lMKB0Het_(>nWQ9jJ@%=abm-0U*kt5j z?9E(8ozx-B4E318S_*{B%qyY1{OF!gHHcHN(5vf*mlu;!Ovt^*EIl&29F>z- zeWzObh_WmnUDnHQk2)3oWS;Fl=DsIZX`S>)rx`lioi}#6it{a29`KanCs!$;VmF9b zf2Z|h->x;l5Lt*1*1fx!d(nUwiDkMhX*S?iNqmd4H21MyR``i-4tW&?e&gj)pjAdU zJqfkiwqlniI_H2h)?gKEPOV`U;M~;riZFSn(xYY1O0(vqnXvT1dt=F(cb@>r@w&lD zHpTqN?SDj!H;xLGT%HlCjB0mm-jBbv?ZYesm2CJbeST=l?=sBMTd*DSRenT(i6 zAU$D&Nn5PZoJLzbLpOfvu~9paZr__eOpPaMpeStk+@`pqlQNML5Spt@r|(M}4OEDWB=ljgOaWo+rr;4^!fkPQsid^=3N zZ8b^j+hh8CSRx4-xzqO%e|(;eB6D9wbGUPDak-jFslEfG!a!xDCj7Zv_SUWr9BE6G zLnjDXzP`iGL%u})h-w(Y*p^^qm|?yO+@xVYbYB@&f{ZMk+usTdq)8h@K2P9d zrqIH@%BWKoI?UKb7wR(YHbNKt4|XpiSStv{=9p6!#(bDTS1~X?&mL<2GuyXSTqjFp z$>^+m{Z^dhNi*C?hSDV3+}1DnTE70L316d~rKypFp%yH1(#2gv&Sysq_WHW(@h)S& z4r+JkfXcx7;0&$e)f9ng1oL&ExdGAWR0(uurOB_1Flh4aVgj^3>?V6S#Q}vvW30=i z<@v=Re|$En8&f1V6ySz2C4z3DP<8Q$?%-o9gKAcd!oEYmeh>_qoQwwO2xGg@KoBxt z`KE)W87!{7XZMLk%0JmDAHQ6M3O~ObLsByKq^F$IyeZ^ce(ZMx_Bax#^K{6DD7#nW zoMyE!p?AmBzr8y%z^}xhz*Wm9xN$%NhaK~d|7wZuLaSK(<88TIStRexlhGldMQeKT zC{YS322~;GY@&RrB?(^)DSM(@@V%4H1~ZyMIUvch^sHXPEt$tK^)ciSb_=q_&LDR@ zDfrHQd&iOh6A>1sJT;{3KL7;k{>Zq4usANH%o40!XP0;87KKq!1iKN==ELPG|2D>= zxj2mpBMaM?^MzS_A<*YDR5Wu5dluwv@Zo*G!eQ#AJ<1%?zI(=H5NcEdTznOeNW58m zEley-+kcZ>$_H=I3vY--w&)j#MDpt^#@x@5Z)?;8;!dTu;nJn09j4@(jFMDUWY4d& z#v#5jQ5#SZrzeW1hkhUQ{heW_cKv5~S0QGlOSwUc3~%*l=3s+Xf{sF9( zOpBXRn?;zO>TovoczcX8XN#y^JgKA7Mrkul{)7@DMQ@S?i#FB+ zY4Vf9)5Sll>YA^ASJib32({13yaEbj%8diY4td%q9ICpW#xT+Z=@0$HJ%=!;Yt$;( zW99sM^2irfv|cF3$18WwC|6L+kO&Ip9E*;`c8suYYY$Af{XP{IxW*Dp*2o9=>@)Lt z-1%^ITHmR~x9mV!NW7m9qBRF~;hwhEgUgew`+l z_wv%BgzWYdqVW;KGxx_mlKm6_rIDyr{iG~FK9f9|t&(Sx^RoqM=BP!HJ01{1zdA5k zqG&gRj14)~ZQ&wnz|@H<#{*@%D>>EXwbk-iDK99ga8*d0IMq>J6f40(Qf@L@Zn9{~ zV0%*W=R9tZ=2l9F^6qp>gi#(~&gTZ_F&?V{h-tFmxH3X~Bb7?OnBK$fH^}7%uVo=s zf8@o9DXFEVRT~YYcB{0iHPOp~v$T?6iDNj|&|6_>e8KBQ$yS~Fg%5=O2lId@q=;6C zcnlg&Mkq`)32B^=8*9`PA(B|Y=(@2lH)fyoSvV-qFm1+qC&wc`TV!qZfJ>6pl4@iC zn6Wg))Cr%r;w$r)ghLGy3+mzbt~&KB=J&38d9HLU4++q;MKz4U3Dg~ zzKqXaa08w981K*jtcf8bS2Mih001nH0sx?Xt7iXRbYf>eXvKJk`_+hJvd7~Sz1nw<-l{8Qzy2cktY(KGJ@T%8e5H6VsROynnE0(Per6P^2wS4B=N#(_$ISEOMtuCAqB( z9PE1#YQDMK^I(~+^_{sl4IgIL?cAA(CFh@6DZIO0d!Q2=@dmlPKVY$Ur5)i{2m7_LHE zFLrTakF9hs=}kJQ<23`=r{>_izAuBQ*$yx1uBxkoU*qc94@7wJ^f`RZ%izncg+8EWBCK z(Y3wnj1N4GCZZ?XG~fCngV0FuB#{yB&xAi_wZ*2Ch|$+U4-d(C*4M`mX^nasnyeP7 z^SX~_b1!5SC@NM;)xLTuME~-3eLqILx-C8by!mqHyV;UExGH}BVALTbk{i`5xivx# zkbUU^>%(>)8BmzZ49*g$rkMqbWSa>Uvq1Gt|?>XxqBy{kZ0&PO3Jcruj zcZZFq-M)cyY3|!*#~b3sW-C@_HvRj81&nsq9LNo+N9r zux0b$o7nF!Z=WkWW&o}USZC<$z?l%+Bc0#AGrPK-@?Rof6AJpBEZEq!v?+Kum2HhX z(v@pHBDG(i`d;Z4Zq%Xv!M;~mkTMiy9p5o}TWy(o`jI7W>d&{wGy`C#InJt8V zQh;|EyyTe!cV?hprh)cN28TW-(&&%H(H_(9M8K7IxDI0VoBH zs{sDH*9w6C%e7Uuu+%hb1%3c7txSZzbt7ysK0ZKY>ufPOif4_Rq%rzNBSDWFmMeMG zT1<;3BYv!!Ox_sg*vn*qgDWZ%JmlBN*=^MKXG`K;#Xpv5lEF50gTK za{X``F5)KrY)9$?+>X>v^pmy0`J|IMw-g09BhT2IpD|k5qz9C)j$P{+^ua+Z@1{pm zcgGN`g5!Cbzvw$9ehg~dysQ{=yD@&G&~7VC z;WW3cx+&CJ+loQ!cV6Tky##btdQFdqZiKkU;)Aaj;{*X7$WR5FpFaCuiSbGyZAHdU z7rTaH#&EM}&s}?Y(m>1&!wN1OhdW~`2pW=sd7lfNsdOmr}wGC)u6IhG1YD2e?!KfmN5`rviHTU*;$dVA|v z>aRwVZ6J4ETF~RUFMp(2d_2BAcO1B-E_uto`qFV{==b$yV5Wcbj7WK&IXc`ZM~_}c zevf{Yv=yxnUurj;sau)bih8bSZsD|)Y6+VX*W_;%K=~4>6~MvIIv{Y+z$&mw;}?AC zO`4Qt1==Na4~H_BB9nP$quIo8{Bw#Z5jL z&=9NNY)fPZIoM(LCK&}zs&F!n9^s2hr6h}RUu*h zX}nPEAv~E7y4j)pNj2dR@8xPf9v0b@^AM5GdMmN}t>M#vK2tgkdH%^hACbe&H)1xtXTYODfCw@eb-Aq@*!gH^>3i5O*x1?G zqxvIr(4G4S`zUrFB!IdkToSR2%GF+mMz`w}rI3cr#v>dKng9ZWz$4(7Q*a~YLM2=d zAllreeBauFFOgdlhS)PM*!~GS6zT?(xH@!gH!iK`$1Ymqu^+k8$Igwd?=?HVO zwTy(AOJOu<)l~2Y?YSya!vCSLe^kPk#=Za+2?5)FHwbdOlLSk0Ae6=*U|kHOSR6^d z1;zT4Lux`hgE0V$Hj)uYe;^v&g9BQ=Q$m^ znnb|Ms=e~Sf^ed#sl&3d(OFaik#boe^r5~n6q%HgFQVsH9fhizz0uDvD_tw2pX^OZ zV(V&U)iOgHokUhOI6rF}=UFIds2RZ~j-K9l1lZ=<0EuJB($);*iwdnjT%+zT&hz@} zPJQnS-Gv9$GE)_QM0gF!yn`TMxf@Wn$en=9iHi&RiVi14bd%ZDAO|1~nY%76BC){Z z+;Q}Ya{ocJp(I>mN(}Yv8QcE>u$Ky~fZEC5w6xK7bR;Ib_K})6)RJ z*v$qOM2*VfpdjPQ`R>zQPj^QCfD+S($Qu*o?F_ob7EL799ZHC(*C z1e7_%@s6l7;dK_Hi^R3DAdhB;vWE<#eTK>yx%s=G#m`iDfQpE82&3(=yg9IB$yFtv z($e;^_E|!e3zS1aR^-9~3v>S$!?Z&=i!-a^S?x;94h?z+zf*?MZM< zUG|>iJRNo;#$BRFJ+`JVkcy(!gitbnBCP=LW;EA{!O7v!j*i~y7iyH59%?1})fXTZ z0}+L;0~Q4{X*08>1H^GZLX873?{OUju!t5#KXGr3fMZ@o22!kJA#BHKMiwvO1XA3n z3c6`1Rc@Q}<)8PGzc=+Z+# z(}L@q!P^@_R(-vW*@DX|PGGxRhB2d3gUGJUI!|cbr)8=Gt?vWGUR|wkyh%U=dEmrl z)6YzktMo%ql|TRJsDW9r3iv7QOjKW4ki>}qBO1b@RRMyyP?SmQg}RI%IJr+7-wm~s zWI&-!kYpnvAzhS0Ah0GP&lFvNWn6)-sNEK2l%MCrgT~NiJBVUnpZHzwRuoH8VXC9V z8x$_*lt|JVS;!|6+A?~HZ%-QFJxXRiAx+Xju!Qnq^rDoqvGbEhWgf*+y^#L`Ca?l1 zgDVVk8ZcP43DHuraL1|J_g4W>7v{oZd-elBdJbgLeNjoNQVE z9Q5{(V5{sQu^>ME&sbhRMkHZ1KW3mm2Y~|9J!uT&kqSO2_mbOyqyzxT`XDxAoa?$i zn!MX`{Y3cueIgLm##huavwc^n1b~FF#OVA`<^z`t`Nu%sL^Yw{1#JXt*ZMn;GXRhR z=)TCeYA9JkEq0`}HYtV^o*I3s?Zr^q0dU%G3d8mWKKxb6RcX9=1gaYG zZTJ^qyhK2B+gj2XOa!>uZi@5AnM8qbJKF8ib^?$EnMzN~?h7aPD2de0q<8{DD9zN$ARa*4YO;0L z5?amaBIuO#0^AA0Ugc;Vb4?`B!nG{{29B$8fLqfVjLi8?sQCv zpX7iMZgr#)R8#`ry{eu0vB-vl_7Qo&IN?gr#-aVRN&9I;pa3hL4Iq_yTWI{qMqjA= z%ZID`R{VUB+}QtQzqeViz0RisBlv9AXwEs;bhDTlidUCLdAP2z+_736Hu z?3Nu;aCw|=3w}KeO{V|u@VHyU`_h+3{P+a1Rr|b)p1JSa;pUn;d`{6Q%9x~jWVXMC z%tO(@1X$*<6F1wX#nOe|Si#v$wbr4mg^@d<6dZWL`Rz)*$1!R_cyh>quq%9B^KHZIvr z6A6I8TqShEX1e!{%SAJSs+~=qL+cMjVm(;F`$0(T<>bJS6xeh3BTPLh8Bu!6&Y6@O z$sJG#>6RCWp~?4V)HT1lz_YBwNXB=JVjXdLDM$<=+Q zy|h9-hXPqxo~xMld2?Lzz!a2pJ8Oy1NPf|R!cB}}b>U$ErlRQ>Evo3MLeg-!3jT-{ zidL;=Hz&7r^`|N8+RIx4%SoF+Vj9S3vMr<9UgHVd*t)o~?l8-C#y53`UEG3f!A7w>DzK0ZYTvQ=Mu?+^$j@llo#62-2CS7sK3B2+-c zYXr)J=dpaDi8K7@3(I5Dvi9m`5vnTY=cK-BfVr%mF_N?0j7c199u=dsjWmrU`ic zk~}D22l97c<|T?NW}<^Qf3lS1Pm;M*9J$%7PI*l08=VU1xm2X;<(nfIdk~hcD@6!r zlG&+Qk7z26jfmCMI<%8#L<2q*IMA$?ZcNGN+S@>ifTP zDr~Wfr_Wc?X}Iceypoy;!am5P!`wGW$Z~{_TCNFIO`wRB@~AHJflTMW2)QGY+eKDvtm8Lqalu`^&L*@czV7bbQ6skhdA6FyuSD7-y#p~p3`%>qm^&Wx(;EK_Z1A|Fg zrq3EKe4Tl8=qO`bsK^$6^6FRyeQ55bqy~||WU01ZwwUuElY9xAe1kuoG5IwCc1zKT zCkkbW?i$<{aAm({sjAu!{0GUqPQgp(Px+_BUsfh~Wd>LDnXt$AUAZ}tyzR(riFv}t zU<<&js`x$nqwsgN8rO441^aJU9t#e~%ccXbRdZ^9tJ47*jOn*%4;xZ?%Q9w14>BMi zc1X+RRgp1M?V5Zw=St%79QlCGPFulj9{YhkZz_fyH(6=G_%p_-zM5YNN2+A=}^^cDG{4N|3xb z=jv9b(PO=JD}+BR+(ZX<;Y*&M*kO7J!LR@as8zt|S;Zv?)IY$3^kZ;^#KG!m!!Zz& zdd!p7tJd&1`{7{pR5m^*fBLh>!jK0>QYGgzz}^15aL}dgBGs}c`w4w8Qac@=28(>O zGbo#b@8JkjV`8nJ+p-RTX6FoAgTRR>8Qa$fTH-VHYuOtdN}bYF4MnBLIxPHj z*x4WuV*pWpfl^o%%QE$@Q_)@H5`v1v0Hzth(!vi#-`6<@ges+8d_KVP7!f_pHh{nb zd_i5YFu~fSXkzg>#CdzC{2?c#UZg#bORFSTEC&>ygjddAGS$I!X>p25KDRn|sQu|R z1fpo0Og^_gEso-nc!%t5KP;47peYiM0 z);cP}(Rf87uqv~aB8uOcBq0z`$~R(%=uNxb^MW6!4cinBQr$}LXH(f4N#2F1&YWHP}q-tK-n*D@ReUU)jL3OzY&pXcu@o7 zvI#W{N*cB8!E|C%v;48H*Tzhgu0ZHp z<6jYvt%q$mH2KJ!Y*hn5L^5x&!6`^?R3e6goI%kqa8C zn#qBXy;`!jGefUCWif<3`HKdvV^|0-!gP^EL9wXo@th5n#Q1*tQca8uVkujIaD70; z6lLZS+M_n+#4uR416Q@=)L!eYEn17wx*6|LQ+D+{Ab63oF%pIprCDH11xM-F`7LxYnPv+rY#Y*O}(qd+9eM3RJ?tQOv(|?Ud5Ztq_KO6UrGvfUQ8I z?v^wvP_v35iiLMrBZ!gjwy@7&mcf>H`;dYZ5OWIo1%cK?S8S_({jA}es*a+ow+g-1 z@@fJsgZ#Zs;o=G53^_6Rn-6E=#W`a!>h9H4Hg*42RUWtHfg_n6YFp7sgln5dV!^`# z`s^_mz5Gx_t?nW(SAzFjj-FmIp{I+V8FCPh{Ah>*Y7qJnu+VN#$~fmJT;q;ofr?yo zAEZ$YPTJQpE|AMEtE1f67zO=F$e5mliNdT!W4?2GaarMA+rnOEU~cF)wwbmMB(#@P zfTgKst2?*s@kj>IQr4U3k=F5>M3Q>h^Q{r;rF(Ol-V?8p@P-ptn5YW1ggFqnd-KmVf+Ylq6$Cf0-aROr2$ zLTn_Ed;Vmbae)HS+hfzLFxzSx_JhmZ#G;bu^-Vdd@&2NalE)c_WU*~Qin-bYt0d1yfxF**5T69D!N5PQi&Z%LymFGKzqLo8JyO|FboO3o<}B%HrduYjEt!%42zkj=ZUpAKYO4eLw&=H3nhN4l-A& zA7bqAXhsqCX|xOt{1wXlId<`v+?c`VONfN1M3dA>g`q~~k$U8E%jO%@ceFZ!C;mC} z9x8oG?_};PS-a-z_ZhVvxLCu&rnUD8e{|jrGV?$rbKi5_66TOA z8py?;3G%uW9^wtvcRN;`ZEaZ6)WAqlF9>l$cAOwDp3A26E3T+;d(?{T^uu$3!24H^ zAgVe4#GRfqvV?BGrXiqcg1;|#iqJA#zzYeGFo&8>ef6its-LNu&Ag|+e@%9NTuU|T zR*B>ZUa>6_$tq{{uxvU8&Za2Hg}3)xoQX5-oeJ7%lo;ga9j^l4>siooU9Fa`rlS^} za9U*@vnvynMSx6}BmLT|tJTE4ZC~2>%;}{p-&l`)%ipOHOjPELq1K$mFKg^0J`+Oy z6(BkLFK4$AD@$k*>`q%)-blTZb>vgMBi05^R>Brj1!m~p^)QQh&1|7nZPI<#%#`_Q&! z$t1%c!i)Nrm-m0pe@c`-tAM)bYGI;>H_rA+L?E{T{0y57Jcwl~lI(h;W7TDly5xYV zi+GL~M3n#R@?Y?+%I|+OqL%_18K)@?dD|++nwBB(&W;&>5u!qW1XjNqQIytYN5bjl z@})oJ$k6XoKUT|NrAKVtYu1#H0?B5W~f?m(43^$cr`a4aQ+H1%X-q& zNDe@AYnY>pqH|C6!>IA$)KMov8z`;$b>9(kPBuj8md?LY1LMCzq~1xjLDI9uHmpTO zQ=JQavW?XvlQb^lvSx!N8Xm0PVsRzdnjUucv@XmY8%(=k-okP!Ri!Yx;o2=6%2DLL zQ~xy*?~xUB{XMNj+z?(ME$UX=X=Xc_QGV4)6jUT{u8nXapQ#Uec;SNXL4rZ!p_thj zncPjYLX9^u0z)h1lYlUhnuQJ)Ezv!clnzV%%B9UX9A?Oh)%eb5Z;)fX!-1>g254BE zb^`H-tTJ&86FxT`Ot)d^dsK=ER`7oJRRY1xGtLIdjgWq4FnlqecOfLNp6dzsw+>;4 zh{i3H?E`pLn*MBO6zuo&&G_gN?00;Y*xQNNtxkl=OgdRg)5Nb`RO0&-G$`TJ9%|-a zqRit6Qmg3|pa(T11Ddbo$+8vH1yb#TGu)6}j2+Bjh3ffdf9Sd%&~@^Uvp|K3@;p!Q zLZ;E2ENDDYmdEq!TD>-#@AK3o6f|t}sL~eFODdk^7f4HRime-E)@)YS*^y6k>WOZo zt?BL`dR3U@NvHg7Gw$Vuf(9&`Y1N0f28kY}lGxsIhqyxe1l?r~?Mc)Nw&IqlLZ{=6yF9}XDN^`n#BMGXc z0%*xmrzD|NuhveEr#-KlWAy70>_a9moTZgS*=EL+!+Ux!@5O=YL-eoj9^e02#70%o zrRM&IXTbjg&;LyFb*O9D?y-GetTX+UV~D?RWtiDyMZZgfgD>IJpWc|!|La6B)EN;VjnJ?EB6Nv}g_@3;#=FQjLPxTFBQ(%ogf>l!X6MwU1OAK982=!2Gwk329$C@V~P9bYEB zWw;z`lTWoI5U_qu8^FF@t$+};Fo)7B(Y{h+oo~{BJ7kqYo350JyzmlrDpWJP*lJT~qG8>>Bd_!HW~^Br zD{}_ZJ#)3l=$=)7^n)A!MxPGx4%@eisy~zc{g(ByHD6*!Q9661wUwEv^F1X{XBWL` ztICaDGcY7;Y(9-Pf5F~r%)%M#LN*+)oc$t__7j8r9q}bn>>ICRm%VjzcJyWCvED;% zuKlcSuBpaaNj6w)4H4`0T`IdmRCX8TIC zPNdjzf6n&jb~{k68B#M3gd(OA+5|!&gRI9g&4#=l8hi+{nVffSqFgPD&)f z50GLZhTo#ruW293gp8d;E4M&A+TsMCgkm**s2vcNOhns{E2v-S{qp)Nv@UMHWAG#i zkP5>{PMg4-R?gMo_Bri9YCy8B`Im_^a#R{}Vn2*Abc2ln`dvMKbYSYPKalya?(cS( zW~9g-^)qD<6AlL4PGw7e3?*#|M5NPioTaUpXQTu<8oHeGRBF-tcR}gInxcS@>d@5MO>V}M5eyc99z+-Ph z=R^4OY30lgu^XW=y(5_-qWBw9+nn$V_}0bb?v~QGcv;hE#Y(z(qqclhM`*xIN68Bh z@&7OG-Z46|w%z`XZFX!s9e0e5t&VNmX2(uCw$-uGaVoZL+c@<+@B80-pK+dde?8-z zFSS;!8Z~Nts{6O*J+C=wn6H*cWm!~deKPyG@@8|2srk|hOAX8Sf;NSBje2jWk%H)N z2_r26u%Eg@x+KlM?sVe;*Hp>A(n5)QZ+iAZ8|L>Pacr$3N)S_GI}Bh)SAF3FbuRo37iu3ma7ylY*jN?Dj(J9XJ+gypj-V3uFz62u-Er7gr(v+M z1KJsj^`;FgRiOqv9o>P7PMh zWrB8-FE)gR+r={>j+~ePqSl}8q{v$3)Akl~srWgg>&*qCAzVco|7Z2JFRQpgP2ea? zK&?)HJYxj3zHHDLn!`a1LdJ8U-$BRRbT)NiDsxh1I!R#zKkFTe0C6*T^su6LWSqk7FvEE%F25M78-4 zdBRkV(buWm>*~!02UkPa-W*qntuARvT*L)A|5#$`i}$%bHMs{Ye|%nP(t)!kS4-!} zV}6~h$M-Usaq?DoV#?&1%$UotN53#8SSOWGQ(=J=6mtrml6>pQa+*ZD3bPX5OirwK z1b$%=z0k>d9<7;UHmLQ?kI>8BwkLwuGopVSs*f*3${hmcVpSsj=XssKvp+M{wVX1z zFnl+Ey(3${_|H=Q*pZ`>8~S~1GALIcNuUD-N(dVc>B>~^Yj1d* zdATMaiJha{^!rYxjyGRYeh@B!A|corlj1bHgN|_0M&rf#`PB~lmY7L`BUe%=fizW+ zVZ`gEn0h95-ImaHm}5BE2E&xCBsK(X#wL}Y|2xSszc|Q-DymxhDzVg_(xZ`UuB>tb z$OYMWlTbVzo0d9?2<}CbK9*qI^0)*(#+Gf@&zZ~upRrkDaz5^H3As8mQaxSw3}On8 zd-ZfAuR0Rx#om;)2V*8pDj|C5S?^i^d|OqD1C6~mkt3P(hZUR}R|EZcez5z16#`uf zeRMw8#^=q5^!3B(jiKPqkG6{uPQ|*UqW0`4jJ}?w!7pX$W#tl_pm|iWcCV2JB~D@s z#817lYJk~lPg*xT7-W19OJB!DJo(A>^b1T(~397I0`qP5M(xH_^E6V@IK zM{6DSjWw151*ueIl$Q}6N)v8~=IPqa+OH7>4YcXR>?f1FkAl^AP~VTLkis0{6U6-z zxpn4?LrzkTtFRe?#2Ood-h(d{+>RU7x z9X_!_;lI98b#TJJgdq#>BcQIx5j%BBRwG7}SW4X=){_}Ba+`L@30O@bJNo%uT!`i~ zcIB|fkHBp=eInlsj0Hk)Rxr~oYBsokJkXer;Kn5(bJKHe+@cQEgzJ&vsG7R027*Nl zwiM0iJL7IwlIS$^ZZ`(BQ!G7zh2Gj6m-D36cT=yW0O^}8EAAm2*&JTFc+?}FB<=L5 zDVBN9g0phHjLthG?|xo%ilIE^5+I>g&+0(^LcMj6KB=pPAXE#sN4kGJ7nQQ%? z)i^L4Qn9`-8RccaVuDbbMssmC`m$v2Cj#k1iTM%cr zF7}K)srqO9A=b@)iHsbVXzC90pp?gF!&j0xyvW1nJ`Rda+G4NjDwEZZS*%SuKKzbIbEHR!o)DiBNP zI@E;-GvkBO_uMs>cbdRM^ z8EtI)%XbRqpHrCvThKz5uxmfslyoK`nALU)tjSZ3@}Qm=(FsBn2u0&4hE-q4w}d)I`tnfkBl5IlWWdnIEUgQKGuq(lM+C{eye`)s7drloVL+S zcnB=S+?Jxh9UEX&0qd$D?cLWb#X`|T5oW3IlufN9c~E^hp1OK&J)PvCaudRWlYb;}1EovI!itc#-keYzq$=Q+sC$-L!QBC~Xg# zSVGAwX$-(6hbR`5Lzn)r5I_m0wA4`iU1k+pZpksJ(ysmkSw}b6B6;V++9 zM7{Ks3F;f*)^g|NAukvz+JcL>N3=Nt8wW zSprx#*h}1t%M0vA-;|r``BpED8B(Z-a_tom@{Hg9` zrB>)v#VB;}{`bwGn<^x{bs@|Jo{O9v8hV^=Ya(-+$L)&4XBg^a&#%7vDX*1DOVC){ zxfcAeeXQ|Qj`-!E^E#w4VB9795cu_Grw57?w9j1x`kxw%T82&Ou2R%tr!miP^_W<1 znE3WFX(uCn*#s=Ae4ROTi{Y{<7DQ*4${0lTi|d=a)N2IgdnNo|>JYP8(GwG=4Zdlr zywAd>R;iozrzI(KVP0WP@cDn^uSD#)m4C|0xAbgC7s@O*Z>A(Kq)vFOv5B$v@hT%N z#Lmp>PSf%O{U=2OYDS{~00ggJz)y*R$NxE>rRQj3{XeF(82@_P5H}tH#)9B~`KL={ z#3us>)eZIA21HFHzuzKeY%;hpOroX4 zzBD1IAez6^Uw^Gu(^P|aTiy7m?|gr0+&#-%|Hqw|@nnISDWK@X_P=H9asIn4c zSy#K{kB%drTu>N~M)y~Glc>A38YI?vbylI?=C&GBfQn`LO<>wzr8@?m4@pG}gny;1 z!WJO?CXO9QKU|GFyE||f{&(q`ghiZFywz}H-4ug5iDUz#oQ>81tZ{rkPHd5aVSxob ztClqfFO=6L>Y6LT!HPz|lhSMUXm&F-vG`haoJJugrsJw$W~6(n!4C)rZ!KY53mJ8a z4h77WGTOg7cO(>u9|cWkP0%oN)05Uug#;uCZmLIFa_ekB-uAbg!V%n$)^0xh3;`+(^^s&?-yC z6p7#~#{<>ht!tZV+%T(GI|xg+rnS3PVCm+Mzl(R;fWLaTT%jn#p6nFJR+gW)EJAn-Q>o5pCJrgsz*W=ClMa2DG-uP@ zfpKly-H&*BQs4c`A^g$OzvZkC@=m#L9%NRlC`^9VdE8#p8-tkf)qYqMiWPVYB2U>P z>t|C)hDgIs53Yjv+Tue5DHN0eS{`Z{YdU!&OXPB;oC~LW+UK=58&D#M*|8BMj`V!m z1H8C#)GM8EZZjnkfaQ?1@sQ^ta=(Y`1mfJ<96lUZHSZ~h7VVI}izHV*p>a>d6@Zdi;{@zUHvy#u3%*I@< zd}AI-FyP1#OSE^#?yUyXN=+tNr>jjY#Vl}6K0`*(QNKS}*q$GTPB$J=0mCCfrBC&h z%nxCMWkejg0aKmP*?-i;?~zO;8BvQjAroh_UIhsS3BrTuNj_N$04G{hu?n@dJv_c^ zT)S%+I3q*B)d{lYlcKTi{SMD;?Zzg=3Ye*@@BX$y+}myH0YVJHHfWLrx8KK_xefb- zh&(hcONbf|;ycD$W-A-9!BB@wO&Xh$J4klu%&RZ>@mk~ecDVUjd0-2sTjx&|{U<~| zk~xbggdH(UGG`)dcB1gNy>D7_r1>Ac?Knt&?E%F<0ZxqgsUc1`Fhlq)WP7^2&=)sA zj_iaZ&8W~d&w#Pq%*^wS;aP#XAQ{w&g0y&D)|80f336XmecYf`;rUJYM*J^JriS{UXN%c}U5JEOOGk$g{N= z9b#!_%?87HPo8Wi;Vw2hi}71K;dJqU`1S$v*nEh&n;tThhV}UI5$xV^L&8P=mzj`$ zVzKNzo&4RHFUZ&B{jkXUMNW=maBp8y;R)k+PvK)jM8tmeofu@on&VN$*j+JAI4_|BcqRo__F;huTe#{6rhx z9=Y^kE_9}?>SHSEN$D%A)Sp0Wp2Rvi!w$>3Gu zAIs+=OhtD1f$a||x@-Z$IWksGXoUx*@S2zgW95?9^_sK~W*)4Gkz55@bd9U)*@KK{NUkz&VZrqpTr|skeQP8TDydtiv|79TMYEqo0g`b?ut%nH z9ei|kB|0!>1^j$v6@Km4;V3fp9tpB^lcYg*UNNiLhiTtwNG3lc4&x4g~Bpysv0glZ9<;CU+gy9jk&~f|AZRQ@n z#5_%xBm;}afPf2@b8~P;CTZm>3Js?QC4xO~FS~Z0;b*HBZC;hKQPWC4YiJu-Y`=aC z(q%;G>HF6AN@FOSBRhcfk3>?`!1kX!+TFZ{7r|`{igypw%?f7HHX9A-Cs8`XNL;71 zZA9PFzHKt;f@L8PG#+l=A#bG;mMQ7}I;yEZegr!9-j0WRVXO&+Hw#vPH;lBMSxXdQ z4su3d_fkvbM(IC*=( zP1FjHNE#&-nAeS-7m z^XKoU+3|%QwlpEOi#W>E5@LU^w#~?|{?e6K8hYHSX~P#67S`}(E&j^$=bb}42&O^1 zt{3D&dWmu=L~b%fjoSXcCtHkf5UD)LrT+9E|2Ml!mqwBPnIWCjhx>Xe^@P*poZ4I2HkuS!vH`KiBbkbn9SO_{aDGIgP zU0mD+qfYiCeDNyhsuu_rnl9U>O_%w;Z5nJBmo-b9X7?{!HxHJ#EzVV3IZ2E!@Ipv7 z9RYaAw~8-+HpS3S&migu#q58fEO#3IhH$B!ay7`SQ|KBY){1Ti%uEO#k^M5H_?x(< zKM^AS1r?+S0)||cNcJ+1odrdLV{jx7+1eHS_ageqFs|VJu&Xs#l)pPcJb+`S{opj`@}_NV%o9SwSTo=tL8UXVEEW zxmqlLnoAY(qi<@3GckkJar*~kSK^M`5n97tkJDd6%Gf7Afl2R7_ytgOYlhpI{;X-- z!-m;D4{nj|Xh4XcjY_;Adj{G+3i? z1b~$(xDn}!Vs+;PL}I93{TK_I1@nRIuwYdoANf*DJpm;gsw8+?5SBqI+#D1HtdY z=RuYsPFU8-mk8gxqv9c4UYxAk^`X7|@Z5rz=7u##m59=VXUweL9S!l)a7lIRw2qbB z3(^(sdWTr6=oMUKQML0IPY3REPvV|?^}c2s457u&C;2oS8|?Q`V~;%AJB1^VSgiyk>63st1Qp6&s&b2+4+IFrNZ$o=_9vHb#@a z5#*PqZ@6T?_BH00H?z#+^7U>>Ay5#~b7?1nPYiIzryzDh!xEl~!&zi|V$(RCEtMXM znc0~|QJH$9#3zp3d;H%X^*)~_yFVot{|$G&K)9pMAQEFo&Jz0@?(+YFJM~ESKPC3V zU_{jkT>CxT*fD@V++tB^NNb8){|$G#GDhT?-+^!!1SmkdItG_Qfu2B=`}W71#!!L; zzo)N4o`7*E(opr<`T6;%5d5e>)s@f$9%*8-q^nQLxpnlwdj(saehpICjTZ=ai4YYO z@j0Wfw3*f$Yl5 z!)It9zHgIFCBZdGNBA_N;TDv+w~T-0UsrYT!3xK7&=oaX+P|vOGOV2B&~akvykuZ; zuBv|R{hO9c8Y!qg<}-#U0Ve{+F?=OUA#-rqOWRaw#7mnJ=b4YOd&s2ek7q1E_U9^A zR(mYKn%cJ9`l0e)beDNxGl|YV=_V%5>7&SsFb?lCq-6ZaFv(Ni=`q!7hWC_bmU$80 z;s414opo^ys=j>JFPN0U@93R2Ajw)ym{7_Ok`iZ9LL#%1e8;=Mfv|NJ>qI(rBJA@> z0f4-MF;g^e>yLAka0BR7bMh{`G-0K9nzUWWMa1JeW9{y9*B3cfc#2t6~mqIpsV~#K4%sC<{G26}3aK=D-!-k<^r%IFJdW?^ z--BF5>{b(*7a*>t(&5@r!S0wJpxeGnig1S~z_4l+j12A>uNN-@;ZFG=?!VzKBEmLI z;a_k^4TL+$h?2LwE0uU6YZ}ysYlmDbcEs*31CW zZwM<_GC^k}+iu!lLU=E$Cuj>r_Muz0`7v`$lWE_!s}V6eeeM|6mX)+P&x5}iVYh*g zw1r+ABAFh%?n`eaZWqM7Wn6>q%#f8NsbjsITE6gA2!Z(VI5ER%l}tTWHZ>nNinLIj zm5?TYcr9jhm4)RMm*!XXFjN&U)g74|5RX>pTci~IVW`$H<8)k=dIhiP-ZQ@Rvk()y zw9}iO1xZ4P^mf3Uy>$UBiYnJ_abREAim5wjPdkHgDj1JD(%WT?mDTpX$I{wrwL?65 zJMe)sRwBaNR)DX9okC?FJ=s!ArNGvm&}z?zSvhc8rgA2?yNSz>HXk-rw@h@(g0|(E zm&4ToieYoe+{+Q0AN8G&W+fwxyy{Gw;LJyp9jOim=O;blnYQTz%4un@+yq+~d(S>W zY9yk}DGt11x4Elr`Yz(|(L07h;wx5*OX))GsLKsJtJS=a=eAL~5iTS=I)z_aCO2|#h%V|K0JWbRYijw>D{;{>6^h89fPuoi@L|w z+DkU>MUh>o!-nD&*iGltU~wO%{DzCHs3T(O7Cg?t*TPBFaemgB%&gX9#Npm3Y2WNh z=i(lab+R7{B)k5a|026iuFU}Z*}2ssX89fKCaqo7bu%>8C-y>9D_sz=zsL^bZ?Yr& zkza(@hQ^g*lqRGjvO)56P#4H_02|LkoiZ<%kBQujQpBm4(7zAnhZYMjiY5+{#7w-! z>ciFW1e5Wo^F@v$n$?5 zRCA`?Gn+2-DYs|)YRaSDolTh+KN>3ke4-5jKwu11p*aM|*d~SVY?YbhbCcdDUv&Zr zj;bdE9OCG>d|Kvmpcrj)3|)^HVlkZQiu~dQ+x?~@`N=fq0s_-2d01iSgrePZI@bx7&9q9wO4fg+ZCB~Z= z80G*KJH-E_*!|rN_WvivPSUwOKWxIB@nUKiM759Kc2itvYRlBWJa467 zx!!wLoSgwdfqm}fityQai$(#m=5Z@tedIpEyMK0M8M;R~uf0Vj(fvrM7oN>i)T|60X zlMRRn8rnKBNVUok68=+5vF2B2r*HBlHT%US45mZ@Q%AVYr;1Vr@En@{2JNx12^uLW zSvu?2ps*k80B{hJTo%Rx6>6fCZ3OuqEqAUM+nexkh%2K5Nf#@nJKOkqK~#?h2zEm5 zl3h^nn@zv>U4hRJGj=!hs{}}13k*hY&EVrV>Pm|vnHT4aOjpY2klVgWZBg_OxG?&w zZQ2+#q)eyn7W&LYajt_N0+PoaZu?a6iSUryI&WNqZML^jp$NuUo}Ln9u0eb*>@3%` z=LB&SE-rsyZxWA64EA&R-pI}Ev?TP@P{kdu3^smdj=WFU{*hzy#Iu#2_HTRaFPqmX z4;)btRVgTeq=ZtJFfOIMu@0I$9%-RPTMU1A+Yv>O1{Mnx#Vf5&+hQQF#kGHG$E-0> zdSFoGra%)0&W#zY~=gb3BXZG*zFScHzShwvjwd! zHZQW4{;_Io3XjsM>aM&7w$}y@s z(MaFOtEx_D)0xz`%|=OhPM0p9NV2!%NTF-i9R?(mx?W8vlR92aaN{@MfnuHM*GjkU zwZaygnO3jvv9=vbfTAR#% zaATXorq8G&D4Q??TvZB;Fw(iL;Gt*&uA_wxEHe{Xm+-4_%whuuJTD@hq0Bo@zrQwT zBWg*d?T*S5ToqO6Sl%;RFW_D1n)3@efF^2&8&gpIE8-?5rq#@XVO=&=v59UHKO+_< zX`2MYDi?)gjl^Ftm*hbHZdCJnUcOY9oIP~mrumS(a&9YcgzXCbt+-v}&oX^x(pk2_ z1qxWX^p#6;l|#ugxx^iW^H-`3ph7;&7+kNIlRY=zz3wgwL)pSRQk-lS-`mVL zWHad`Q;-yAwy&4($fCPNao28q0)8k)Fm@19I|g^;tX_R>VP{@(e}boiYG}b6@M=|K zi+-q~`tzDr1bi!xxqwLnN1Q|RIC|%_{LhNfmZ;9VD&L>$Et2$@G;G`0W>wWh~_Dwl3SrH#;&Wg zS%+Zrja{3Ouw2FD>w-X2P*ZTEfFWG`S!mGF%bKqmYY@j>^FBqTWIRmox+p=l9wCdH zu+Ay9=j)MHX?+og-3qMBAfqvKrVHkJEWudTB{oxlTxiV7t=$Xsm2|8MO^wXm;_{uB z3OMwK^PWCL6H?x#q7Cqd!|dgjkj2mBS_UbFrvTL-uDAN-lOIqz+>DnT8BZ`Bx3y0J9 ze{ArisgLEq5+$#5xCuRayYhh}0dY>QBHkvzHJ*y63oksu1gxeFPW-+%eLZ?@U-o%} zx1eMh&l_k!*};9}06hxLFQdI;%%JRu*(&46+z6V~qpy4P7VUru-2LPo~~1tEi5!si4w#r(M-V zINT?q3FJBVPSKYZ9sh`0otjQCtMOSH6|gC(Ky` zLmF)~MOTBS56B3-H6 zzcyiw?Ti#0?d+X^JFqS`hPDP4){G`Lre~RY3V1^VLyPZU??p=PMTlOGhWI)9M9#fR zkAV?|7S?W*Hu$@)J9Fn0zXtEgxlBX3l8YsWjSZnO-PX`N0!#5gcY`5tzX`%M%_+bb z^f0rA!ob7B8+rA-p)SD)&0QY%o0vToYB7Y-YqC|$+W9@M`sJ*@uU|0qQ3?+`c&qad zpfpv9UcHWw2d_QTl4!YIyugxVNSxaWqlAbKH(&c;>7DPsLCyF?#|=63)l@{C4iM;3 zr5eG{OZOr(;8^$2|n;7zXchUm_S{~Qgg0-&xf#ayb*bQ%Wg9mX(` z>5cvrB`y14sNU>Tx7z)!)7FtNNqMtg7+t*iv=;;NV!B%|%&}#iK$&maQ%eA&b@gdVgJ_+BGzzy)oEA=28b=D7wXEkV8&F;^Pj^PDT)+qhW-u{!rU!C~hEMyaA_ z*KA?_auxLX_8Pd2&TJdRZt3?E%|cq|n>2#5wlwBWG(@TC6N7@~)}Aowv&3U-RtFoin4n z6?jIA?i4djYZ*j{$grWUM{LT**0zNuF~*pI*l@=(jyyuBw0)7hDQS{t<18XSWP3wvC`!*I~Q#(?P^*VRLC_iXlJwFw7%yPByJT?<$p) z3|vy*hZ!7yZ&*2$vwR>;-oR$+cJ5y~(EoaW7og|*baG7$KOY|eu#|8DtIjqxDHl0D zwl{c*btBgi9VMaWbAj1w4H9@7n1qYI8V*{;Jv}{A>q#{fi3rt3L?RLNhf>!m15C|I zx_i*LUarM9-Eq&^KXsHyWIa&(blv(8s*A**IGN|=N%XGs=fJxGs|9V3J+)uG%S!|a zJ}b`;qG90Xr7PcuR=WjSF6-r2U7CDj+gBEM9$N$81M5qj*=U%pr{U#dS1)NGMb^2J znahNrw^JrKI8Pzyv1hBkc!VCa{jl}X>{vZiWX}d_QWDnzy76#0Dn3X9;6>n`vf$a- zq_Q=1c=(LGuUMvI@`ElIDe5ZpbUAT&O=*`Y%KQXMngU;W$Xj@~2*3yfe;7@*;;@#! zBo;Ubcz_^*f}>3s`1R`A6nm|u-4qx=*k~?KxaP)~TZJOoNcztQUO*o~*6#E4GByFO zA-4uZa>P@Gb{W>tY%7Lv`}{{>c(hv7s196OAf50_9p=5kGEYYF_28S>zAG;$R59@P zf&>oGrnC^4$b)J^6}H@8=Y`dFhi^tR4t+fj=~W}I#BKsl4k0zLydndqA?v>!-#zBw zp7T1_Gh)W-l5T2#cPe7IlaHLZm$ z(|4cuUHN^zOqU1UcM|XlG20B?F>~S*sB3*9`)BMNPx^OA#x5#E8-EJxsz@`_lNIMgGwwmcx_r z&i7-vLtY@ej0|{EtB@*M?k>p^uvbtEG)}PY_*?16hV-{Zg+I zxI?6-+9J-a2KpIqZag7BfZ4>PvVOyRhYV9HQ)EqSQRo2;mlnhAm^JZu3XwFAme(ZU zZuHi~#5U=2j+aRJtF8r4%7S@yUghu+dl%A7`dV%B18lMNF9*7HSIRsK zjVM{QY4&m|WoU~g(vK7xX`ToJ(@O~esFsYuTXOgsQA?YA>xTP%EE}Wqth^hBgd0{C zCYgFRZ$N5hloAhI?MxLG6Nb^{5`0+yxrH<@|J5N~0~G59J}a(PezA$7ggx1f27c)RQ0YN#Va3I37||wN&#KBS0xovwn3cE4s2l=auDk>^QgT z3vJXD=o%RH^47B_`j3#0fUZ`D-V}!}RJ&eY>7QPS_IRzpw}LH(-c&!Ri3W69)i&mj zeOpuD=XR*DVm6tb^VdpWzS7qhd-zjVMlhJap2VQkmks=#aZoLk+rabV8%lldbI24* z8yU;R;s<}m9+2q3;tIaFx?V0Okw1=zU4xsE@lm?|2#B^gC<_vC|GEcu%U4Y^fPX?b z?yaHZYr$>i%-Lsc`R~=Y?_YcQ~$qE<18K5D?V=^3u6k*c#ipIWfB1 zSkI~H*k%07w%&uc+V=zlApxOcG1EA&$qu*NCMl6DovDw=T$dI5@v3v%Xk1k+Ax(8p z@#hd%FUM)JvsYks|5sga6uKtF-y_12!Hg2W;pQ5D_}-}O(|dnTbW;rk+P1Pzz%cgn zX@p}utZoR})1(XbL-JF{YCDzJvXvPP2)_&fpG9rP}Iob-Jnr$ zDM*KMo8nc5BI50PqLucv9B=?Tux5kv7~<@DC5S;wEm~5nGIS?x!8zSwjf;54R~v$h zAlFV^Dik)4niVRhdi*nuG+}ZhHL_eI)PAV$F_E8^jdBJyD+aQ*&e2yu4GN;wUj|rO zWm_QQ_qm*RowKi=9wB>ZjN2nlI#{n>^hOH{NFBR2P2`T{9iMtt&^nF`ld@TMcvdTT zq&kI8%Wn)m#JzN~Yiu!kYSfg&#L?N4RxlS8qUbD`wfOz2atICq8SyZ0@A3tCQVbYn zJZo7H)b%5(aMeD8U@Q#sFkik8whJ)Zw;$?!nOWO`f+Jl_SDHtjp z3kMk~!7#V<(fb6yy>DBB4n3h)Q0EA2ry#eIox&+!e9mv0u_IEGV{LcYCC3}pHnZ~C zyYG!w?l1RETBjLD7^p_qWo=^=QC@H%;)0RZRhsTZMDvVSOa17cvh?Cn80vE$J&MTF zewN7%9SzGm^p3Jy)yQ8{bt2DJq}_R0cHXfpr-o(2DMil+H5oW8IP!e6udw0T%o1$g zh;I|RROLN z4Zo%o!Q7l6LpQc83TjQXf{?<->Ie6a^)yGLM7FevKp&q%|?w zSM^YlBJyjKMBnD29p#!F%)b%B3Zc%}zXjId4&2r&)QRO)+H(v^W{VkJbI=atxPHE* z#=4hiidm5Nyj8CC8ab${o@Py#X7(~O3hbRy2bo27NH{$rPGxeSfN;1`yam9#T z84T7;uoa8U>O_e(o9TQAdoxu@C{sxm3W)-!2WqB+>$A)9$|WL<@xsIdbvRIl$o--m zj6dvhgZVOkJLZqOFqdo~lI+3oiZIs zS^?@#pGpHv{7(QRwi-?Jn-{%bpBh2Oi}9!>PJ5Meal85bQ%z)@_6d0*%eSLJy|;)V z%lO>kRQfW&-2n}`X{7O?QThmJ<10paa7s15qO!^XJ_8?MX_7oP^^#;~s7w3`KkIm88ntXK-qxhoD z#B>iLPx|QP#h(pPC-bLW5HjFobQHy%D|)`?n?}{i@?gpKO+~qyUwWf~$VTiy>Nj+e z1KObcj5X@w8T*oHR((rHLQ6hY!hywnU&+7W))DMU74N3?#6^)aAq3Eky9i_ZW*4y| z=;$)kKP$K5m`9%F|4%8qNz)%-D~(Pb$y?!xm+1gS^TEv|3_|P=TfHMwYP&cMHrZqG z#PyRYG7Scz7AR%&vC%<`7&9n{pw zU5)^HP8GN6@Uv{{DE!W6ovlo(x%!f8I~DF&g&vv8a=pp8`-FtK3E9nB;u0kdjqFE5s!kb3Ig2I=F{Qu=yMXg3Pum z-mkWH;s!o&uvNVW`aHG>iR$BoeD`bY+YWl=sKj6C&k8$6Zz15RJO;o8crWbY`gpYh z3GH2L+PY;F z!-!cfuSb9kwZ|iXjkNo9A80@|{c-8rDr?_fc>Da$dK$5cpHbz^JD$q08mhE$?IZaJ zF7Jp)7iT;>_s(n&Osv(do0+bxVhvl^FKo%fl>3x_tyDj_i-b-vS-c0swDq*Rt_@E# z)?BAlRDMfFF*+ncNbqoBSRlX>T$d*$t(*(rmpb1UAbwTH-CV*NTaS?#g=(LY){tR9~?5A=|Al*2P^4-obwf zAH;0TZ`_rSXCFInPcr`zopk8vEFW8q;frl-HxWz@0BlxNnEK|#&Y>~A`U)4AtBcE) zV$!!-hq2%R8y(J*a`l76)3nsG%8_mf-4HKKvHFVF(!I7_aUpuGH8sG7$wHurqGC{r z`iRSvVj$dXk0U`Y_&5Jnz?6dbd9 z#4U5_n&87;8@54O-gp5$se3l36}I*7msMdx88+XzJaA>XmZ#0kP#U@g+K_!cJkH2EbTj>n1<-b_b(^ql-#rpJ1+Bz6KVZex{S!#yC#x-=0}P_-^;qw^)_rLL+mZ(>g-9|ZiOURYxPus+GU$>6SQmL zOd*dy`m1$;ASlnXBf6{8!*6h3vqS4ngB0~SR960p6pXNS0W(j`zR{SIbu3LJ)e{j5 zte~YGZr3G`Ch@w3c4xCZ%5~AtN=Nn%I&RP2?YW54fv+42qMNj*A5j?ZQDL9G;p_ZO zIDAlmJAVsf7Z*e146lIddg|h)UuB;OO!O`zr#)iX)REoQ%T-Ys@p5hGApUIs-Q^no zBeW$0Jn&$dv!-wsQ_qQ_(HHf+C{3xKVRr+Kh`mlg$>gwqBR}F8kb!UH3EI2atgjoAKO=GJvPvyZb;(m|cDqcb;3aN9x4HCxc)R9q^~TJs`fAS5;wPU) z((O1!ur97ZAQ50FxUUb{wfAK>#k!A8WpAb0B9HR9bMQ*e9x}&iN(@&|S8Z~~*rO$c zx-%+)oKbx*5;0*}i3vJ42_#?+JMkG&)20a|8k7 zZao<0{ZS6qew-Tgf`{UZtPPh+;NV!8l_~$4%dJJe9zY)eL-_k6mQIvvhZNGTsr=zfUFl7#K*7!LV1S<3Q$Gb@R(=P0&jQG_@%lG-K z^9$HhsY#*=g}VSxRS(MYw@aPoj^nxYe|~6*e<>Yl`rihC{;o#_+6f$2fdfEa-=SkR za2)h_9WLxaZK#@duM^~6W&$XrcG$6#3-Q~tUQx4r62}D>!c#Q{R+Djzbj?RM_43GK8mZS#-BwMmJdE-l!y^t#$N1N z-T~SLKDHS)DzF`}q-*(W9Bk!-Ci=^La^#8B+-a0JG=8gMaLRvZ{rBOn zdRD`3-Rj?Yk`_U}%=%I1G|=WuR)e?F%smsoEjRfdss+o$tdmbxZ))Gc#2DwK6{O!C zjU*k-`$`4MefP}ETVz2N+J?bVh*^8M*duL{n!s20N*#*{W!q0S~sW9pd213^2M#R)TwWzgtZ{pBdXfPgU)>@TicvQaYOb=2Y>6OxQ zAsmQfn-41Ud){`VYD#uHIc?U%2FsFLfSZFT%M)ZwcSak=_eW( z_O@z5NZ!I?DU75baVuV^B)*YFGZIBRt++ql=1)B}L>^RVyLhk^Titu%KIHcNHmeO!$4Q#TT4GaVzzEdr9HX>%%9R2bfg&Jp+MN?{0VB}3 zM`JeQ;Qg>QlrZL4hMetQ;cC*o{~3WytoRW)j(wR58eZ>*3#3xFT)sS>vHx(ArF>aZ zNSOJX3>V&}T`#Jb_G<-3-|yX`wKz*J&{Zzk1-FU&V2v-NKmHPo8Rn39e}(5Ktwb0* zj^OlwN3t;eiuq)M)J=>-53Rat0ZHeurOga^y zyx=HVUQ8tb|08gH+{<~R7(d+&8RRErf+NYEF(hAyssm4|-I?1O@$Ws7iSZL#G#GThZ=Z0>ZJ=&p8JDI~_=v4MIP>ik z`iM6p@-{3rtS)b)^%@0o|6U%tWX=@pBf<7FE} zRDB@()LQHb>9f^rzW%CrNj&j25(F669L=Saw;X)bPl-@Q956CHRW8+8WiKSD6){?~ zF)rB~>&9tN&RW*v_9?)0D;7L(6#alp(+j zq=MxmIXl9d^5v9!An7Xdd$}#=&qD#WD?4X$_wngb5Gzv%Y^O*@8rh}oZc`gJtxj2s z(jpV+rxM;>)KTBEjlXfz!L>cV@44t^-xYOVM$rh+zH;ln_xhm0tccEwmxaZ=I2fU#4ZYlNPLJYPgI=_m()ET>INNfo+z&8D zuvpbeDTxETKze`|s4X@-W)CN%fC)WM=9d@f5h{-p)C+_Rc!8oV-WLG%1r}J*1usnU z94c+j>kE_}m-~pEN;D>Vv6`QnbUD$r?dacid2%C0lppIE@s-@Uo9FcfTDRu~4`MQ^ zb&W^_rzXeDNCbT%8j__Lx}Z_v-Osw~?(^pa>e zc&&Q_bc-rEs}#-C6keFlh5ZZ4!s*?kfos0phJB4+`;rd5xAB+P`ubddDxX2TSFUSx za1)$5^POH9tn(A65Ohb>3+^4xDJ!=qeNe$f5kz|hf;ya(ZY>*~zEYf5&sLEBF?Wp& zFGk}YH&$!k4Dql{26?r$>8an+J%=BgK031X8@8#?a#2zI<~2(f+(Z@gwzAneYxePp zj+({8;`OW47P&L7D(|rupXxa6XBLkwurI58wz*#)Sh`SW&Fetf%Z_2fu{(o3UgW2B zH#qOeylX>tV<*ECXLH%&r!4!zjC;yi^JGcE^>lk%0$&S@phBe0TgH5@7t&ac7s-K8RcJp*(0Ka@z)ThfiXrE3incfd^rAjhD3g{0? za`T5X!{=>p&s)rsv+9yQtDT^DM@buZbtAjPc2cw=c61Gy@8{i3`ba7A#5K>aEho1z zaXL=-2ex`DVq0oB#+nfTM^NjAgzE|~YQSqUuj8e0Tq`#$F8-MJr0H+lm~YJdU@1vs zNO!NKco{wWHgfZu=J9LF>aSPJc?WOm~RNv2%&)~lT#(E7exnI5@zbz-#OQzNFax~kT0=l$0% zr5o>EyoMuyiDu*wo4j1P+JNgjP4|zAQq5-ZyYFbbuU;NT!=)c_$Vq(WJ7z@liP6EN zwdB@ix5$ShIqg?%IXxY98cDu8#kR0$?x|G0Kr1JFIBcKDIQYa9Ulm{a8&EciPZP~^ zYVM9&5E?CA9PRRXRCb*}5T)y->3-v$yRGO`51>v|PqpznvvbAdazU`Yt*D6eYD9J= zX<@nhs?oR}j_QQ_k3(U)`)R>INexMoB)t}kBqI&WMu0rNiF>B>B~(>PJnK*%lUWbU zZFE@)Y}6Y!o@rc9s1H}ZTJw@Y%nv;sKlQ#s!=CE<`G=U>&8*uW<4%yTRwd(>hsN_Y zDA*>SP$M6Ysq`)Co>7N{t=^l-y&m9mMfztmP18%nXn@K*F?)&1P`8O2K z<+V~E(j$adIC_56^#4!cXg0^C2c2a$B^5Er3cBM_%twMUXW1O5;Z%3RWx~6;>}^n9 z&0kH=X>9zk{YYKxr$c;GgY`=iwYZIQM-bY80$)V`xg!V{a0ERUcr`1a)OcF&rHutR zg662jW~&|W7}FuE1I9R;IK-wO0Y^|c`mMQHsWPm)fFo!JIezP9Pw)VR4^owa2-Fe8 zD4>Wc8Ac$nI(NJ((!>uqf;htvJamaojPaKqJmJevSN-65Mfqoje6bA4En5>r&H3+E z9NmF>6q`8e8kc#jZioN}OMCE2=>M2OB&<`ttc7&T_BoZ9@&Iq6#kLyM1b&r(tj&B| z4I+{Nxqe#B&|V~}-ss|+YeZd6pO8Jg_2rk}yK&nzi|YVdJi0f{prAn+`k&)_-b)?pc5|Kbr6L!6GD7Z~eOkWR*1uZwBHW z1_p=)W%dLS)B8l1`!b(5;5{mVH2x4Ep#Q+imeAN$@dWuSaRI>>x0f_t?b`GGPP-tc zX&w;@xnVbHX~YBjC1qY-7Wca*{I{j4*ltEZtwFsAhnuxOw^M!2KInczcOAJ}g~REik; zs&3jp6|`d)GCeOQ6+bT~CB4=f?y0e30yu*L5O%k(iQ)`gLS0(AJGJ8A^igr?q?)6! z5?V~UQ}$mmY3O+|DW`f$s{q@!$gRdZTf{~w69HF)XWwPw(G8V4dqwzl zsc8VI^F3Jw?Pm|J>6@Ud2x>a>3Yp03>J4h}+{<_9j*)U|0g6e*eif5;Rm{>WPMtb1 z{Z&l5ah`%xupi5E-1q*t8kWTRNpH0xmnk9c((9^qw~WQZ!sX>`4#nFxu6~=^VQV#J z1(~Ddf!Hk8ZK@h`@9B;Zy*UH1^~9dBe##}yv5Q6R2-YENo!b$^UPXNG%Pf5PeoTJ; zx1us5NU3;e=z9{(y+x%s%rrbpwdD$FTnF>VNLQHe+|4QX6p1>(Smzcr9Js@}#giYx zxyOWy`_ zmbEGn>QMlp-n`D?n;iY8B(CVE>+^({IF!rI*DBQM(){<`gS4(%aWLdnvpSvVB%KBuA4#~61nanzs)=1kmhkqc+|JEv!BpYVQ4&0yv@{Y2cuA`2k zp!6${TJ}&M8!H*TI!^FI3h%OS^{VpJ7k`Pn>V2Biahi7@={S`@LW}dv6HVXRgS>C~%dpt(6%L6eDmKOUIwsKgxV3on5W0!>axI80IpwL{XO(rZ~ zCvu^{->sRo@>p%e+L6Sm_2Dr0bi?TT>9Q*$#O5S!8FQcfm~|MpavSB)E#I3xrhDwB zQNs^}dp}TWsca4GBRrBIPEvj9M6U751Y&Yq>f|H?0({5sz6 z@39wAJ~*kz&xq(MkIJEmzA|JpL1~Da>0Xm@5A}L!o^x>N`X`$b9haVN@<-!5doJyt zGX;|7hO~)}Z&hQ62Y-3gCH2fCye3}?(dH<{e6?>ENiYyI(Q9`Sx^A_o3)hVW>gq-1=SJr-L)s?e1zhtd%;Xg}l4lD-U%D zh0H@8LiEiAxC&2z03v64`Yl5SOZ3sLs#4rkBjkBI2$HA{Z_G;dSHjsmomuXe)7Q4i z;+hQ3u#~)uaPM{D-?MD*!EIPYw@-4lpiACuX+OKE?vunas=xYk|F+BNb$#ce!nWur(~i{0udR1%#l zANEIdtIih0lwNO-R(q}K#7 zX4k?|giB(#IEvhHbh`u6r&Q4DXdd96!&h}fV)xEw{jtmaOIJ}fsOGfxJNrdyX+j{hd8Cm|!@!J44XWZ$LA7hCY>l*3g9Mp&vT0W&J%+g3$ z!}(dL8@6bf!iZ`q5aY~dXQIc+I)e48u3w6w-+8~hzW(@=d(?rW2sThBp68L0!Vp`W z6Q*-&bH}97m`{mudyCzV@{+gMo!~EO3}MWlfm~i44_23NgiP|$mL&y5wFAwY=U!|* z8|{fw^!jbB=??Wr;{Ak;cYUnBAjE7TvP2S(sw{T^JFGO%@H-3%{nQgzrP)thf;0AZjKI%Cs_jr;SdW~w8h>g1dEOd5=XcYDnqa7iYo2rdAeDhQF2Ta z_kA@Fb&@%d1;kTO*su33TuTkNNWE8Nw}dtkDt}C_f?pW-ECe4<@r-%CLPSZ;Fw-r$ zwRE0iwzwkV0YdBW9OoOT?VBkk7(ZQ>y>$|>eJgU^==2Y{`JV4hQfyC*Ru=7B|1EBu zP>FC_xldS8g1l528WCK09ZLK2FEtK0b4h3!ISPBch}rYM;penkTn!wk$d$Gddv(uo z%{!othVMV85Z$%adCh?DUr%>K1F^#NeEf=Eqx~@UbZ=^i%p1#)k9N}hLc0~KdV(Uz zvLpBvVL`9!)Q!SnvF28BMZ=i75C_+DOu+W-*;Z8YBR9{aM*GDRhTs{dZXXV+ezGuh z!1k@r+#Pem#?JkAo{c^B=?QWC)GU{tQFZe|Src&O=|rn3A7Qx$-`J{a;ydlK%de{D zj*B-?Q`W9%(p=Aed#pA+`mN2Q%TUgdkDPLJf3_RNo#Lm~cg2}2lr>&;8hq=dAr2qj zmEe4!SLXN@%wuz<4x@OD=Si?DgLO@%AHwcW0VYH?s&Ah-bl836mSv2lVAHBIuuLW0RtNA2SwVe5sxtHlfKLdiGlbS)&_piquC9TzY;m4k zy2y^YLAmv175f6lPtgOKLe#E@SD8G1DqY8L_db4-0QiKo3B&Vrz3+eZW7iA2eC`wS z$X#uZBX>_1>bD;LG2EVvK|XnwGwV{S2eZEVi*|}C%+Qf=k4=Cz~DS(rGG8>as z)C^jwS2W-Fmg&EBF}Be^O@7gg?~blMY#&;S(BO=2c82OIV=T>7^ws0m)E)(@OYp4j zv?!InThN2{AWM|&+=RHzm56-_N~%~hJGqWkqW)G&gp7tr!^fzTx{G(0k?%i8PStp^ zcl3?+ketWu+RvY1JSYdY`%lZUHI=9z4~+6}QoZJ}WcG_X`|`ZW&Ac(j0Bg*3vb-VF z{p^(Wg!|5&m3`AsUuncMkCw^M-c_6V_j38~`LJX4Ma#W&XuK3oMH)tNgpw?FiSa4D zY$4;ZY*q!`m?O`J)BZ?`wdsMxZ|_+(J73M0D+n)#Y`w+1sS-;*-e09P6YLa*Vtk&* z6Do0+Bmwex>ccUkltxyaSQ~@rwyV|U_$?R*iI)u@;foYZC{h~Uf8$=04n%j`d3yn+ zNuO+<>bP)pKc*SS-g99AqPwy6A$KAl)r_!;pf8jYIO%P1{?Q1RDu@n>9|V*=BF|0_ zDqK(0{QBkDW3-x&`7>5-l3D0s8r8Ap3=M3}Bg)Cy3Z-?ajdO_6O?VInEcuFC)T*0C zJe<$$c>4_piqt%U%Wpa=L+#%YIyl3h-78jyVs|lQ*WV2%?AdkY2Y<4uo^&EP-DCVf zRS5iKxZq9d&|MUF7jxbLkD|BIp3i9s5yNIxLMtQ~nG~h%?S?t~%H+MS)|BI?&LF!w z`a(nvN)v(TPJK4dZI(L#_sTX|3cdarma2CV{=F`Od*9l7ZUYyD+9$cU(@^xZY@gli ztzD<%(tmK~mQ!&^6j_OQ@WxL=R}1&Ftr)+agxg@Z<*?>3INSdW^bA*gZOhtsKy-%# zFSZKE*S=v)|!9zYZ0Z}lvt-st{m5+)cgB? zn0b^ob>K$pPIhK` zeB439yBiU?kDIx=XD0HQxz!sV2vVyk?GkO7t=!fibbOgkPc1Ll0kQVoc-KiffhG1k zyklataEt6~xxA~OrV@+p_iFO#4QY+;cc&%KZPY5oZ@2Z_KbSeiUFU^ZOazBF{NAel zv9(f}o@5go1<7)zW-pQC<`MQphA1=E$@tht%A$l|A6NK8Lagn%C7g2h%zv!cVKf90 z13%uQ5@Bv~X2ni{sJUjM+9s5(!<5<5;6t{f;nC1hm zDB%;~ASxX;PFCnntp=~`ubo=|+Pt_7pn9&|?@FYJ0Vc(WCYBPP6w~|N+o4Vqr(Rn# zr`FYSj|8buBci8+B6dQ3SF~qvMCe>LWl2gBxa*&-y##_DoU879= z#$_q)(YOAc_7EOFC&}i>M`WKH8fythu$?c-W*Z+zXOpHJdC*}`2RxLwFX?rW)Z(LT zMGks?`$q;^MZZ3i!%XXklA!d}BsVcH7JgCdnY&+-fioLN{3%2wSt#l?F>kD?aLICA z-$@i6P9|yVeJ4YPfQF*1_G=7>KVVx50y6vd0Ba0iWWlf#v*mq=K>*Tf^f2SS$K#MYS#R%%1{Y9Ge4j+052 zXB3=XrbE|KLX!+dd+kH&pq`S={H{-=dro(U#9n8-smOOWZ~G;|>S$#le!EoYZCa8C zw&4m?jAS_rhSD_VNwHnqB<+>2#`xA#p%tJO+Z@+^zdxLI6)i4 z#EV|idMJiTqUntO=}&-{YG6O_jo3q@dA!{>$Qgc000ell0pHtBPZEFtkNj7F=jrLt z1_XFX&;U;t2=L~5P7nmycYy5O0yKL^;qa|S9tiMS)rGDD0bc$$2hY0blCs>+UjZKK z%)@T)p3MPhfVVZ8d>shzx;VJg=esy!Lrxasr%t$%jH(Y8_?p*ax+jiJhlt8``1Jk@ z@HD^!JY6|Q_dskmPm2gCj8_{ZUYX4L>5cI?0`}QNNO(3sBo1#V_3u{IsLo|W@@YC$ z=w3Emw-6oT#Y+3p%8B=57C5&t=D%|r+0X+h`X_uRLo-U|V}NrTQ{+Tsj&A{8aCJ(DQT^^U(fijLS>^>r0245+Y zNq+`3eb5nkJHp-g`99(@-GPv$RYSQ6G<}DCp1vz8e<<^#0uztoODoCt(PP~xw0h*h z*5>E#ad-!1Zz|T^Lgk;wbY%Qgy2H^;Vvc@Vh`0UsPVHMO&v9}gUFc5jOKtq~om$E@ z5sUwJY9paLwM<^XPHh-b=lM=8?*}rb8@GylOZHe*bvtRWXA4B+)#nw+XZE6?PVkY8 zb0_%Ia-=IlP$&2kzzJU0y8`6yGI)a8h7^l61a*Gp?y?2vmobD!>6Epcn?p;9_CqnyaQggUpXn1`L-q}eKe;>LU>_wQcenLB zcW3Q}ZgofC*G}#CUpuujo6w!w$X`3P!q>+8zvXhr7>Hsl zM8Ek~X>A4M?s)qm#>@JD)^&0SjvU`hRO|hfx?_;acxf=WgVc!aG;-%rMOWY_y^*^H zs%7K7fbq@dQ&}zc;`5QM4LQ^DPJ;$v&QCSyBtzMk%LmgR0LLWVb3x*WAsRz8ynMOv zTju$xjd?p0wV6zZl2DDTwLxSFZOGK%PV#Ne9c)X~;GI)2@hqvV_ z2hr1%wQ^tOkUtcEV_F0l!Uvu8XE%N944<^0AsFIO_t~?SQ4Ks6ZS@;SuOQZrLZt(W z>_+}BvTJ;B=RZSu&X{k=`>}T(h*oUhe;LA6b35Ecg;b%3H#SchMmIpt))!sZ?-%Xb z^S}1`zR~wewo3(S2v?bf8p6AStv~OVZsm-h30yvVD*W~eOP-6pgtzQ=pD?bWdly2w z1&Y;KGI<7Dl;L6!0kP-}Lc!h36iKa9%bItV8C|hl28!(hm9gEzr;|Fb)I4WO;!!EeeLPzrUGZArQ{({8TjGPe zuE{j`;)rPh5cD@Ib1Rf3j41fsvZI{Vr9z!*%A;TEmA!jW2Wi!#I342>#fDo_tE~2};IRg;lu}FKqpaqgYvnnA1HyQaArR}!9;Pu7H zdok9OLlbxh=Lx*hzY=)3&;%Yd#Dh)XDbP{u{}h4dH)&@CUXIrcfghO$IUoa~cHr zEB|+YJ&l>N8oPnpI)!=) zxVDOFsY3dL5eM>=DoyCUi(b#sUPZO`5%S8JC~_D)P7Ac!&mNyN6<$(L*>{K^(*i9$ zIHXeI2?eh8!lHseaQ_yxk)7TD)AOG(oSbmac2)qlZc4Rs^ZxcYBKlQ{7saDx<)3iY ztxJ1TRC3kb2#|=cwvRHh?XUD)l~6JZIx18}|Ng*CBt<+sQmnf0jwZ%y(-ecUDwpzR zY2u~O&x`Q|!7K6KjlwM&KLosSV`SGOPuELrsXZf}$g9HbkWWw0h+gR&YIr%DG0?Xy znO|X}XK%*vLBF7)=$++c`$KNB@FWq#chY7;-sR*jO?h}av@zdj)81=XRWWy+X(Z0u zFQj@W+hDA22_%MTL_5&643nthjI!^u;BopKrG%0*DAjk5q<&O1`OIj{FejokRMb8= zFsX6ML$uvcBN}fwW)(kLCHu<1d)ZMfi)*o^#mftzuNaltum3#5;fcjz)Md|JWATr~gHPD?7_?#@wy@_ne2ZUq z)HTm++4p33`chPUB0sR#h${2$K>?u)6 zPj#hNaydE0Cy%aO&vA{}xszPf%wiOZVU^V5Jxrdllcd~Yt;?PCb%gKD?QdPxWlJ;R zdHkt6_8h0Z?PbH5Y9t$`E-gcst|d8COJDMNUY3v+Q&36o({65Y&1`Xeeo3*Lgz5RC zW+JWaoU+j5haxgE;sJ(l7M~VHMXal7c|835%BhHIOjBGn^yH*;5rf1)iRkXsXv@OW zmB7%3b!SGj-Cc0E}rqs?WM3$h(fsJ(V|D`FhMC!DA2UN7ZWJaOqKVYSyn zF@F|I`5D;f@wY0+dq^h7FgPP`+kAGvkrK9zItHQQ{xeK)nk zP*|gQ?A$?goKG0-Hb%UA(~(nfa{F7HgUdMIXo@Ir`sBuTX5{S|SNAphHx2n;l0S!& z>p`e(hD_YJtZJ?mMqv{Ne^eS4)95Gv@Dx+;rTw*V4;$j@o49FeR!_vJ3K)mTaX&%o zdZ|B>wakruS@JMoa<2B4z}n7kF~r5EM1EGCzG+@PytjJy-gmT1PDeFSOWZWoHa&fn zyc=c{)R&snvMeU3gG5^+D6o)D4v?L&D-p!dA!J8>54?B%#U{1=x@p$tc%$Q5o9Bd$ zT~{F1uA~TyGkR!(A_31Dk86D)l$_^O5E$=?2v9i^pbA$Po68g6nQ-K_^D$E z3HKI<6Y#wpFQ=!k)-SWh?}2_$q}vULr=4iFT=%Q#T8~HtTbijZ^`bxT(Xyc{N5`it z4~?cH@%_?f{Y0$B*cXqkyuFW(2`Hy10od1pg z{;0)95&i}pzj>gkZ5Dw>Lqz!*GnFr1^T7P_ECRibh%Y_hl~Uh^#IRCH#55zx7rQ3X z8=U|2naQ?9%(dS?g(wjBh;&6V;@BHrBK6)vAQhWJkWJRQ8r<`sO>mT#8e zS%TWWFp$FA8|b?Wu6UzwO9-cPA!pzNzTCY~;UCQqqO+BUe zDVqeT93ofID2MT8S6|9|FfdQoZbaI=zOsM&vB(E4D@zJzY}Mhz-06`PZztEv7bADX z2?tKHEA7V(b}4;Gm2-W9nSRLHbNC$79GPt%s9V0!AHfvQtJwB-9UR6yo^p>~(~!97 z%zdbRZzHn${Y0tH7-swFL$#&#E00e&KtH}@JSX1S1HqOJ5RVc3{qgm{+0n_?`u}}` z{rLpTk5#pOa)Y#GQ|Sk#{H8n$tt2G#Noc#-=N6GQW85&lbT*6dB%L1AbRhe)*qG7#t&|KtwD1eB{TF+cliy8lf zUz_>K>vV>fPwQ0PGQMZkS-a6?sv4D$qORYozjEgho1sQl9Xf|@SVA#w08*a$>)9`l z*d3Tt&^KoiERoj487xHIog}@vS!YMkwP+r z(Ol?z>k8A2#5pcRl+L%2HHK_U?d~VfUaN-N$Fa9Wt$ZM!%1g7E%)+-fH>ed}7T;D0 zPA$n|Ct;ho&q*YpRUy)-AYPU}Ozn#8P#t?|0=fH;o5Kgd0EhLcG-!qvnwzqB( zN|`;(Y`XV9r6M4*K?orz5a22+$W=)E>$10>0iBZGf@<~OFFh$+8z)m6r+eydcBYO7 zQ03lMx(Ilq-B8K^h}{r?U|x9rB@_tc*DYb^mxKNL!UMkd%>}d&NID$?1pmSd^?-Es zudBv@m5j4B@b82D!w;@2Xr|tUKsEy|o!|cV2O+@v`}NjFj!vcyjvW7e2g9Tf3G00X z+P(yw!a($g0sIcz_czAQ=%MMayUxzfW%#!z#h2}$i2;v*7U(eL1;mm6Z^W+$@ppef z9}3doR`*wA2*h6%I2Ymq$}#Xa>UXDpA^++cC^4!rVXXonVFC@Lxj>8v`%V1Szdtv+ zo%a%y)`(WF)()IAJ4yQM%EdoG|M1_m-|hSL{ruj5f1j9KBqzldfa!$A#DZhaPpSPE z!$8hoMg`R|aQh?l0?0pKxk=y{K`;qOF%Zgd0GQiXAQ0gHzrM~g!7-fYSH1n)oTp6R z*w%nvJqLPqkzvua}MHb_P}7n!1}j6W>auDplX)ke~cUma7uCh<>1W2;eg87Z6is; z4&V^Oa6T`?;ehISWT3v{1mGA0H?&>Uq0>4zhYM8CdT9@1gn_Bi7I@YdIXOFUIG}nq zPvhzp12|eR9P%G20l+`X!4h9k&4yc|>UzNTG=is2g;ehJ7csSx5on0u_jxE{@Y35jY%B zJ=4iI&x3QUCE##C^*kc+j1HW$ECq)Hs^`0GP7ablztCX%^*{~|2UO3C6{@}9?U_)7 z!vWQ^j;!KC@b+k{z~O-E*&sWoLks9v8O%J^uLjQH0oC)oos^RbzzKrk7-_)afa+NY zSDXYoKf}(eOWJTapn9Gm(0-%@+8zUaI2=$tmywl*g7<6s9vlv+p5cG)m_2~Q0o8LD zk^g4}pkMc4p7XdF91f_SS>psvmBF8nB^(Z@p6RF*5pMx;-7@vR<9*f|4hK}vhGD1c z(6QAH6Gxdj!{LDH+2yV;$2!m+YnV7Q+Z&w23##XL^2xRn0EZfgX*;BY|o3_q^Blm~|cs%Inb0JVDH^F15p z^TMqV4hK}vBr;KPE&%5PprMO8bSMJn@PX?2S?1<2AMl)!aR24dl)&MD>N)0Rinlz# zaRFkEi|vUlhrsPHQS#+ zd+cF2bD!aGK=oW-COC@+v?l_FL)Hg}1FGk#!4^V8pgpcI`Y|2^=lr_L{@?X-1c}p2 zXij?rhI8;04hK}vbm_AQjsPbdW?ZCRFc099IssUx6ENIG}n) zK|jog)1DnT98f(E_o1&k0P_YD%)Ak}2ZsZy=k%R#2ju`~5oUhoH~{AefX>f1-n$T$ z0i0zR4%IOn4yc|n?Q;@(0gebvzp#G7;ehIS?@qi&KfsZK;SeGqg60zhK=s_n>Ddll zcPqkhsF2}sK=r)MuYo=ZaA4O39H?+OpnA@dSn&0o8Mcgc{x;z>$aH zs9%P|0oC)!8Ro)QfMW^6F~Wtz0o8M7m4Yucp8(r0djdEdP(7y@v}6teoSQK1@gfH2 z2!iT)e{myY4B(iFI4#%Va6t8J;kwQUecx}vaK5m^;ehH{h2`xdXnRayI7^&xIG}o_JMNi)<`1F$ z0+yD4eeLmpb2x8+3i{@K%DP4XgbM>Y<%b6XRkVP;@k-x+Pv~Nc4u#->KqdVp@-qi? z>X3tJ5t0}@5U8fP>$*~*b1O8rez8S_H{pRmMSY(;KpXm@0e$l?g04%$1A(f#4f{#s z@72>q5T6`85U8yGUOrs}-B5%F0@d~3>!*vLsax}7h5D^01pJJ zY_ji8A<%;cpsT2hAZsIdAW&tqUrlg21whbc)J4#1Q+OayWmguHtKt5)j=BgMvw#Nz zRkj^UIgY`90rf=?y$w7NsInPsG4y_~q%MLg?csqymHqcp>LSR<86F5!*?+I4E`lz* z!2yA98dg=aO8j1QTm*G_!UKUS`|s7%MUb*DJP@d|7dS=(z+2Sr4-W*Y?3D#FOlTek zx=y^3xuOTym01LA(@#@odY zqs?(R7#>hvQ;G%m0lI@=!z>_%r{IA=b?tx};Lreoprv9LTl9Gr9tc#|ADe1rpzD2T zz0gHa>jE4Q_=aLQ58VzR7YMYN?jopj86F5!*Zc83SkMd>FAS)A6&?sw*GdPrOVt4A z1m<0v+<*rH)pY`wTpTc@Ae1mI`mzlV1gh%=4#B4d0O&hRi@xl_1A*%LD|;d_Fr$Jz z?8<$3AkZ0ma(K?F2mnD#7cahRIY;n7pvq3_!KC{LfG)#4qnJ~8AW&r&UgyaKW>g3c z3@8AC1U_VWL6yDPz$pP0EsgB3~SMAW&sX3z|8%03bY=u7%;l1A!`= z>3|Fo+9EC(P$&^R5U8@XbpjV_01!S5C>HSUf=>N>pvp$%GstNJK-@5(FmiYxP-RDG zUwH}z5x{`Lso;S?l`We_bmjzrpnE$P2kq0Va6mku&*)Z6bsBU@1KT1&dN?3{P-R~s z$~lB~4ff-Rn+YBWRM|Kq7D`q?x31Ct+clnR@Iau-9&WtEB>+rnh%lf0U%9|RpzR?b zcz5H30s{Hk@vmb+PUtu0k7EJ!*}Nk`Co~6IVhhs}7oac=Oo*TzBGNFtE&^Z>U@%1Y zz%if$H98ABtre)V$p`9eE|&3!n1N$JhbgL-UM28`K>C3eUBm=E0>^*~5T#!yvlGZ! zC%_mcmTZ4x{xwXTKV(qDMAr-Pe&}8b56rmOvinWDSR>2{zWKguixc-6C~P75?;NK; zS@lC;Fa6hB=45VaZ3^515Bv(+HP2$IYH&us7YGA%>WMZrGEN2BaT%r^dBGqI&{^l- z3+(^ }a^1tH?E?j5-Z!yBZx2OJL$Rz!4$6t4;{`>NOZ+IC=xZ03FQ#p0fXkF<%7203C+^9^m?i(e(+00Xhc%JtpiABd-~R0XhILoRI>;LQJ|D6Hw@2fAGF8_Wt)yQA3{$s(stpqiwK_E@Q Pe;E7_NZS}NcR>C>E^fW7 literal 0 HcmV?d00001 diff --git a/include/zigbee/zigbee_app_utils.rst b/include/zigbee/zigbee_app_utils.rst index bcbab4a1c436..62d4abb2bca2 100644 --- a/include/zigbee/zigbee_app_utils.rst +++ b/include/zigbee/zigbee_app_utils.rst @@ -135,7 +135,12 @@ Complete zigbee_default_signal_handler implementation In its complete implementation, the `zboss_signal_handler()`_ allows the application to control a broader set of basic functionalities, including joining, commissioning, and network formation. -The following sections describe the logic implemented inside :c:func:`zigbee_default_signal_handler`. +.. figure:: /images/zigbee_signal_handler_overview.svg + :alt: Zigbee default signal handler logic (simplified) + + Zigbee default signal handler logic (simplified) + +The following sections describe the logic implemented inside :c:func:`zigbee_default_signal_handler` and correspond to the shapes in the figure. .. _zarco_signal_handler_startup: @@ -149,14 +154,14 @@ When the stack is started through :c:func:`zigbee_enable`, the stack generates t The reception of these signals determines the behavior of the default signal handler: -* Upon reception of `ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY`_, the default signal handler prints out a log with the signal status and exit. +* Upon reception of `ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY`_, the default signal handler prints out a log with the signal status, and then exits. .. figure:: /images/zigbee_signal_handler_01_production_config.svg :alt: ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY signal handler ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY signal handler -* Upon reception of `ZB_ZDO_SIGNAL_SKIP_STARTUP`_ signal, the default signal handler performs the BDB initialization procedure, and then exit. +* Upon reception of `ZB_ZDO_SIGNAL_SKIP_STARTUP`_ signal, the default signal handler performs the BDB initialization procedure, and then exits. .. figure:: /images/zigbee_signal_handler_02_startup.svg :alt: ZB_ZDO_SIGNAL_SKIP_STARTUP signal handler @@ -207,16 +212,16 @@ Commissioned device scenario For devices that have been already commissioned, the default handler performs the following actions: -* Not perform additional actions if the device implements a coordinator role. +* For devices that implement the coordinator role, the handler does not perform additional actions. * This keeps the network closed for new Zigbee devices even if the coordinator is reset. -* Not perform additional actions if the device successfully rejoins Zigbee network. +* For devices that successfully rejoin the Zigbee network, the handler does not perform additional actions. * This does not open the network for new devices if one of existing devices is reset. * If :ref:`zarco_network_rejoin` is running, it is cancelled. -* For routers and end devices, if they did not join the Zigbee network successfully, :ref:`zarco_network_rejoin` is started by calling :c:func:`start_network_rejoin`. +* For routers and end devices, if they did not join the Zigbee network successfully, the handler starts :ref:`zarco_network_rejoin` by calling :c:func:`start_network_rejoin`. Once finished, the stack generates the `ZB_BDB_SIGNAL_STEERING`_ signal, and continues to :ref:`zarco_signal_handler_network`. @@ -228,7 +233,7 @@ Once finished, the stack generates the `ZB_BDB_SIGNAL_STEERING`_ signal, and con .. _zarco_signal_handler_network: Zigbee network formation and commissioning -++++++++++++++++++++++++++++++++++++++++++ +------------------------------------------ According to the logic implemented inside the default signal handler, the devices can either form a network or join an existing network: @@ -277,29 +282,42 @@ It is used in :c:func:`zigbee_default_signal_handler` by default. If the network is left by a router or an end device, the device tries to join any open network. -* The router uses the default signal handler to try to join or rejoin the network until it succeeds. -* The end device uses the default signal handler to try to join or rejoin the network for a finite period of time, because the end devices are often powered by batteries. +The Zigbee rejoin procedure retries to join a network with each try after ``2^n`` seconds, where ``n`` is the number of retries. +The period is limited to the time specified in ``REJOIN_INTERVAL_MAX_S``, which by default equals 15 minutes. - * The procedure to join or rejoin the network is restarted after the device reset or power cycle. - * The procedure to join or rejoin the network can be restarted by calling :c:func:`user_input_indicate`, but it needs to be implemented in the application (for example, by calling :c:func:`user_input_indicate` when a button is pressed). - The procedure is restarted only if the device does not join and the procedure is not running. +When :c:func:`start_network_rejoin` is called, the rejoin procedure is started. -The Zigbee rejoin procedure retries to join a network with each try after a specified amount of time: ``2^n`` seconds, where ``n`` is the number of retries. +.. figure:: /images/zigbee_signal_handler_10_rejoin.svg + :alt: Starting the rejoin procedure -The period is limited to 15 minutes if the result is higher than that. + Starting the rejoin procedure -* When :c:func:`start_network_rejoin` is called, the rejoin procedure is started, and depending on the device role: +When ``stop_network_rejoin(was_scheduled)`` is called, the network rejoin is canceled and the alarms scheduled by :c:func:`start_network_rejoin` are canceled. - * For the end device, the application alarm is scheduled with ``stop_network_rejoin(ZB_TRUE)``, to be called after the amount of time specified in ``ZB_DEV_REJOIN_TIMEOUT_MS``. - Once called, the alarm stops the rejoin. +.. figure:: /images/zigbee_signal_handler_10_rejoin_stop.svg + :alt: Stopping the rejoin procedure -* When ``stop_network_rejoin(was_scheduled)`` is called, the network rejoin is canceled and the alarms scheduled by :c:func:`start_network_rejoin` are canceled. + Stopping the rejoin procedure - * Additionally for the end device, if :c:func:`stop_network_rejoin` is called with ``was_scheduled`` set to ``ZB_TRUE``, :c:func:`user_input_indicate` can restart the rejoin procedure. +The rejoin procedure is different for routers and end devices in the following aspects: -* For end devices only, :c:func:`user_input_indicate` restarts the rejoin procedure if the device did not join the network and is not trying to join a network. +* The router uses the default signal handler to try to join or rejoin the network until it succeeds. +* The end device uses the default signal handler to try to join or rejoin the network for a finite period of time, because the end devices are often powered by batteries. + + * The procedure to join or rejoin the network is restarted after the device resets or power cycles. + * The procedure to join or rejoin the network can be restarted by calling :c:func:`user_input_indicate`, but it needs to be implemented in the application (for example, by calling :c:func:`user_input_indicate` when a button is pressed). + The procedure is restarted only if the device was unable to join and the procedure is not running. + + For the end device, the application alarm is scheduled with ``stop_network_rejoin(ZB_TRUE)``, to be called after the amount of time specified in ``ZB_DEV_REJOIN_TIMEOUT_MS``. + + If :c:func:`stop_network_rejoin` is called with ``was_scheduled`` set to ``ZB_TRUE``, :c:func:`user_input_indicate` can restart the rejoin procedure. + :c:func:`user_input_indicate` restarts the rejoin procedure if the device did not join the network and is not trying to join a network. It is safe to call this function from an interrupt and to call it multiple times. + .. figure:: /images/zigbee_signal_handler_10_rejoin_user_input.svg + :alt: User input restarting the the rejoin procedure + + User input restarting the the rejoin procedure .. note:: The Zigbee network rejoin procedure is managed from multiple signals in :c:func:`zigbee_default_signal_handler`. From 6a5daf2034a2caa47bdc3d9df3e013999c91b37f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20R=C3=B8nningstad?= Date: Wed, 23 Jun 2021 10:53:23 +0200 Subject: [PATCH 006/126] .github: manifest.yml: Bring in support for filtered labels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the action-manifest version. Signed-off-by: Øyvind Rønningstad --- .github/workflows/manifest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 32e1e1366991..399504d30285 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -22,7 +22,7 @@ jobs: fetch-depth: 0 - name: Manifest - uses: zephyrproject-rtos/action-manifest@v1.1.0 + uses: oyvindronningstad/action-manifest@module-labels with: github-token: ${{ secrets.GITHUB_TOKEN }} manifest-path: 'west.yml' From 58f26120d4572ba5b1788acb78797682530238ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20R=C3=B8nningstad?= Date: Sun, 13 Jun 2021 14:26:01 +0200 Subject: [PATCH 007/126] .github: manifest.yml: Add CI labels based on modules in west.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add CI labels only when relevant modules are changed. This allows more granularity on the testing when west.yml is changed, allowing different test suites to run depending on the module, instead of running the entire test suite whenever west.yml is updated. Signed-off-by: Øyvind Rønningstad --- .github/workflows/manifest.yml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/manifest.yml b/.github/workflows/manifest.yml index 399504d30285..e2ed904ee8d5 100644 --- a/.github/workflows/manifest.yml +++ b/.github/workflows/manifest.yml @@ -29,5 +29,19 @@ jobs: checkout-path: 'ncs/nrf' label-prefix: 'manifest-' verbosity-level: '1' - labels: 'manifest' + + # Add one label per line. 'manifest' always adds the label 'manifest'. + # 'CI-all-test:zephyr;nrfxlib,' adds the 'CI-all-test' label when the + # zephyr module or the nrfxlib module is changed. Each line is comma- + # separated. + labels: > + manifest, + CI-all-test:zephyr;nrfxlib, + CI-tfm-test:trusted-firmware-m;tfm-mcuboot, + CI-boot-dfu-test:mcuboot;mcumgr, + CI-matter-test:matter, + CI-find-my-test:find-my, + CI-homekit-test:homekit, + CI-thread-test:openthread, + CI-crypto-test:mbedtls;mbedtls-nrf dnm-labels: 'DNM' From c782d6bc968472485c00d70f20afc85f7ba8e01a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=98yvind=20R=C3=B8nningstad?= Date: Thu, 10 Jun 2021 12:25:08 +0200 Subject: [PATCH 008/126] labeler.yml: Don't apply CI-all-test for west.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit action-manifest now allows adding CI labels based on which module was changed. Signed-off-by: Øyvind Rønningstad --- .github/labeler.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index c95b80b2baba..dd8361c5a559 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -46,7 +46,6 @@ - "tests/subsys/net/**/*" "CI-all-test": - - "west.yml" - "**/*partition_manager*/**/*" - "**/*partition_manager*" From 322a86e6530e40adc813ffbb72bfa9ed54ac48e5 Mon Sep 17 00:00:00 2001 From: Tommi Kangas Date: Wed, 11 Aug 2021 15:12:59 +0300 Subject: [PATCH 009/126] net: lib: nrf_cloud: add GNSS API support for nRFCloud A-GPS and P-GPS Added support for writing assistance data to GNSS using the new GNSS API. If GPS driver is not enabled and no GNSS socket descriptor has been given, it's assumed that the GNSS API is used. Removed Kconfig dependency to the GPS driver from both A-GPS and P-GPS. It's should not be mandatory for the application to enable the GPS driver. The library does use gps.h, but that's always present regardless of the NRF9160_GPS configuration option. Signed-off-by: Tommi Kangas --- subsys/net/lib/nrf_cloud/Kconfig | 2 -- subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c | 27 ++++++++++--------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/subsys/net/lib/nrf_cloud/Kconfig b/subsys/net/lib/nrf_cloud/Kconfig index 7e0d3c7a6357..5d84a0e09085 100644 --- a/subsys/net/lib/nrf_cloud/Kconfig +++ b/subsys/net/lib/nrf_cloud/Kconfig @@ -200,7 +200,6 @@ menu "nRF Cloud A-GPS" config NRF_CLOUD_AGPS bool "Enable nRF Cloud Assisted GPS" - depends on NRF9160_GPS depends on MODEM_INFO depends on MODEM_INFO_ADD_NETWORK @@ -230,7 +229,6 @@ menu "nRF Cloud P-GPS" config NRF_CLOUD_PGPS bool "Enable nRF Cloud Predicted GPS" - depends on NRF9160_GPS depends on MODEM_INFO depends on MODEM_INFO_ADD_NETWORK select STREAM_FLASH_ERASE diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c index 4fb69e2f436b..fd877aaa771f 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -339,22 +340,22 @@ static int send_to_modem(void *data, size_t data_len, agps_print(type, data); } - /* At this point, GPS driver or app-provided socket is assumed. */ if (gps_dev) { - return gps_agps_write(gps_dev, type_socket2gps(type), data, - data_len); - } - - err = nrf_sendto(fd, data, data_len, 0, &type, sizeof(type)); - if (err < 0) { - LOG_ERR("Failed to send AGPS data to modem, errno: %d", errno); - err = -errno; + /* GPS driver */ + err = gps_agps_write(gps_dev, type_socket2gps(type), data, data_len); + } else if (fd != -1) { + /* GNSS socket */ + err = nrf_sendto(fd, data, data_len, 0, &type, sizeof(type)); + if (err < 0) { + err = -errno; + } else { + err = 0; + } } else { - err = 0; + /* GNSS API */ + err = nrf_modem_gnss_agps_write(data, data_len, type); } - LOG_DBG("A-GSP data sent to modem"); - return err; } @@ -725,7 +726,7 @@ int nrf_cloud_agps_process(const char *buf, size_t buf_len, const int *socket) parsed_len += element_size; - LOG_DBG("Parsed_len: %d\n", parsed_len); + LOG_DBG("Parsed_len: %d", parsed_len); if (element.type == NRF_CLOUD_AGPS_GPS_TOWS) { memcpy(&sys_time.sv_tow[element.tow->sv_id - 1], From 6bf2f13432257565ef791e32fd22ac8278776cf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20S=C5=82aw=C4=99cki?= Date: Mon, 16 Aug 2021 10:20:24 +0200 Subject: [PATCH 010/126] samples: peripheral: Introduce IEEE 802.15.4 PHY Test Tool to NCS MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit IEEE 802.15.4 PHY Test Tool introduction as a peripheral sample Signed-off-by: Piotr Sławęcki --- CODEOWNERS | 1 + .../peripheral/802154_phy_test/CMakeLists.txt | 39 + samples/peripheral/802154_phy_test/Kconfig | 80 + samples/peripheral/802154_phy_test/README.rst | 986 ++++++ .../802154_phy_test/include/comm_proc.h | 53 + .../include/internal/ctrl/ptt_ctrl.h | 96 + .../include/internal/ctrl/ptt_events.h | 18 + .../include/internal/ctrl/ptt_timers.h | 34 + .../include/internal/ctrl/ptt_trace.h | 29 + .../include/internal/ctrl/ptt_uart.h | 239 ++ .../include/internal/ptt_errors.h | 25 + .../include/internal/ptt_proto.h | 99 + .../include/internal/ptt_utils.h | 24 + .../include/internal/rf/ptt_rf.h | 293 ++ .../802154_phy_test/include/periph_proc.h | 24 + .../peripheral/802154_phy_test/include/ptt.h | 85 + .../802154_phy_test/include/ptt_config.h | 52 + .../802154_phy_test/include/ptt_rf_api.h | 127 + .../802154_phy_test/include/ptt_types.h | 37 + .../802154_phy_test/include/ptt_uart_api.h | 38 + .../802154_phy_test/include/rf_proc.h | 61 + .../802154_phy_test/include/timer_proc.h | 32 + .../802154_phy_test/include/uart_proc.h | 29 + samples/peripheral/802154_phy_test/prj.conf | 45 + .../peripheral/802154_phy_test/sample.yaml | 11 + .../802154_phy_test/src/comm_proc.c | 156 + .../802154_phy_test/src/ctrl/ptt_ctrl.c | 250 ++ .../src/ctrl/ptt_ctrl_internal.h | 149 + .../802154_phy_test/src/ctrl/ptt_events.c | 275 ++ .../src/ctrl/ptt_events_internal.h | 186 ++ .../src/ctrl/ptt_mode_manager.c | 110 + .../802154_phy_test/src/ctrl/ptt_modes.h | 79 + .../802154_phy_test/src/ctrl/ptt_parser.c | 183 ++ .../src/ctrl/ptt_parser_internal.h | 120 + .../802154_phy_test/src/ctrl/ptt_proto.c | 140 + .../802154_phy_test/src/ctrl/ptt_rf_proc.c | 184 ++ .../802154_phy_test/src/ctrl/ptt_timers.c | 303 ++ .../src/ctrl/ptt_timers_internal.h | 64 + .../802154_phy_test/src/ctrl/ptt_uart_proc.c | 353 +++ .../src/ctrl/ptt_zb_perf_cmd_mode.c | 46 + .../src/ctrl/ptt_zb_perf_cmd_mode.h | 358 +++ .../src/ctrl/ptt_zb_perf_cmd_mode_ota.c | 820 +++++ .../src/ctrl/ptt_zb_perf_cmd_mode_response.c | 475 +++ .../src/ctrl/ptt_zb_perf_cmd_mode_uart.c | 2736 +++++++++++++++++ .../src/ctrl/ptt_zb_perf_dut_mode.c | 614 ++++ .../src/ctrl/ptt_zb_perf_dut_mode.h | 34 + samples/peripheral/802154_phy_test/src/main.c | 53 + .../802154_phy_test/src/periph_proc.c | 345 +++ .../peripheral/802154_phy_test/src/ptt_conf.c | 98 + .../802154_phy_test/src/rf/ptt_rf.c | 631 ++++ .../802154_phy_test/src/rf/ptt_rf_internal.h | 37 + .../peripheral/802154_phy_test/src/rf_proc.c | 429 +++ .../802154_phy_test/src/timer_proc.c | 55 + .../802154_phy_test/src/uart_proc.c | 88 + 54 files changed, 11928 insertions(+) create mode 100644 samples/peripheral/802154_phy_test/CMakeLists.txt create mode 100644 samples/peripheral/802154_phy_test/Kconfig create mode 100644 samples/peripheral/802154_phy_test/README.rst create mode 100644 samples/peripheral/802154_phy_test/include/comm_proc.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_ctrl.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_events.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_timers.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_trace.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_uart.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/ptt_errors.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/ptt_proto.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/ptt_utils.h create mode 100644 samples/peripheral/802154_phy_test/include/internal/rf/ptt_rf.h create mode 100644 samples/peripheral/802154_phy_test/include/periph_proc.h create mode 100644 samples/peripheral/802154_phy_test/include/ptt.h create mode 100644 samples/peripheral/802154_phy_test/include/ptt_config.h create mode 100644 samples/peripheral/802154_phy_test/include/ptt_rf_api.h create mode 100644 samples/peripheral/802154_phy_test/include/ptt_types.h create mode 100644 samples/peripheral/802154_phy_test/include/ptt_uart_api.h create mode 100644 samples/peripheral/802154_phy_test/include/rf_proc.h create mode 100644 samples/peripheral/802154_phy_test/include/timer_proc.h create mode 100644 samples/peripheral/802154_phy_test/include/uart_proc.h create mode 100644 samples/peripheral/802154_phy_test/prj.conf create mode 100644 samples/peripheral/802154_phy_test/sample.yaml create mode 100644 samples/peripheral/802154_phy_test/src/comm_proc.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_ctrl.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_ctrl_internal.h create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_events.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_events_internal.h create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_mode_manager.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_modes.h create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_parser.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_parser_internal.h create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_proto.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_rf_proc.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_timers.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_timers_internal.h create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_uart_proc.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode.h create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_ota.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_response.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_uart.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_dut_mode.c create mode 100644 samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_dut_mode.h create mode 100644 samples/peripheral/802154_phy_test/src/main.c create mode 100644 samples/peripheral/802154_phy_test/src/periph_proc.c create mode 100644 samples/peripheral/802154_phy_test/src/ptt_conf.c create mode 100644 samples/peripheral/802154_phy_test/src/rf/ptt_rf.c create mode 100644 samples/peripheral/802154_phy_test/src/rf/ptt_rf_internal.h create mode 100644 samples/peripheral/802154_phy_test/src/rf_proc.c create mode 100644 samples/peripheral/802154_phy_test/src/timer_proc.c create mode 100644 samples/peripheral/802154_phy_test/src/uart_proc.c diff --git a/CODEOWNERS b/CODEOWNERS index 881f3d0d39d0..621fd30a3ee4 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -115,6 +115,7 @@ Kconfig* @tejlmand /samples/profiler/ @pdunaj @pizi-nordic /samples/peripheral/radio_test/ @kapi-no /samples/peripheral/lpuart/ @nordic-krch +/samples/peripheral/802154_phy_test/ @czeslawmakarski /samples/tfm/tfm_hello_world/ @oyvindronningstad /samples/zigbee/ @tomchy @sebastiandraus /samples/CMakeLists.txt @tejlmand diff --git a/samples/peripheral/802154_phy_test/CMakeLists.txt b/samples/peripheral/802154_phy_test/CMakeLists.txt new file mode 100644 index 000000000000..d16065786db4 --- /dev/null +++ b/samples/peripheral/802154_phy_test/CMakeLists.txt @@ -0,0 +1,39 @@ +# +# Copyright (c) 2021 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.10) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(phy_tt LANGUAGES NONE) + +target_include_directories(app PRIVATE + include + include/internal + include/internal/ctrl + include/internal/rf) + +target_sources(app PRIVATE + src/main.c + src/comm_proc.c + src/uart_proc.c + src/rf_proc.c + src/ptt_conf.c + src/periph_proc.c + src/timer_proc.c + src/ctrl/ptt_ctrl.c + src/ctrl/ptt_events.c + src/ctrl/ptt_mode_manager.c + src/ctrl/ptt_parser.c + src/ctrl/ptt_proto.c + src/ctrl/ptt_rf_proc.c + src/ctrl/ptt_timers.c + src/ctrl/ptt_uart_proc.c + src/ctrl/ptt_zb_perf_cmd_mode_ota.c + src/ctrl/ptt_zb_perf_cmd_mode_response.c + src/ctrl/ptt_zb_perf_cmd_mode_uart.c + src/ctrl/ptt_zb_perf_cmd_mode.c + src/ctrl/ptt_zb_perf_dut_mode.c + src/rf/ptt_rf.c) diff --git a/samples/peripheral/802154_phy_test/Kconfig b/samples/peripheral/802154_phy_test/Kconfig new file mode 100644 index 000000000000..61a310b04abf --- /dev/null +++ b/samples/peripheral/802154_phy_test/Kconfig @@ -0,0 +1,80 @@ +# +# Copyright (c) 2021 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +source "Kconfig.zephyr" + +menu "PHY Test Tool configuration" + +choice + prompt "Device Mode" + default PTT_BOTH + help + Select the device mode + +config PTT_DUT_MODE + bool "Configure device as a DUT" + help + DUT (Device Under Test) - serial communication is not initialized + +config PTT_CMD_MODE + bool "Configure device as a CMD" + help + CMD - serial communication is available with 115200 8N1 settings + +config PTT_BOTH + bool "Supports both CMD and DUT modes" + help + Device can be switched between modes using "custom changemode 0/1" command. + +endchoice + +config PTT_POWER + int "Transmit Power (dBm)" + default 0 + range -20 8 + +config PTT_CHANNEL_MASK + hex "Channel page and channel number mask" + default 0x00000800 + +config PTT_SW_VERSION + int "Software Version" + default 1 + range 0 255 + +config PTT_HW_VERSION + int "Hardware Version" + default 1 + range 0 255 + +config PTT_ANTENNA_DIVERSITY + bool "Enable Antenna Diversity (Not Yet Supported)" + default n + +if PTT_ANTENNA_DIVERSITY + +choice + prompt "Antenna Mode" + default PTT_ANT_MODE_AUTO + help + Select the antenna diversity mode + +config PTT_ANT_MODE_AUTO + bool "Automatic" + +config PTT_ANT_MODE_MANUAL + bool "Manual" + +endchoice + +config PTT_ANTENNA_NUMBER + int "Antenna Number" + range 0 2 + default 0 + +endif #PTT_ANTENNA_DIVERSITY + +endmenu diff --git a/samples/peripheral/802154_phy_test/README.rst b/samples/peripheral/802154_phy_test/README.rst new file mode 100644 index 000000000000..dbcf36fd71e7 --- /dev/null +++ b/samples/peripheral/802154_phy_test/README.rst @@ -0,0 +1,986 @@ +.. _802154_phy_test: + +IEEE 802.15.4 PHY Test Tool +########################### + +.. contents:: + :local: + :depth: 2 + +The IEEE 802.15.4 PHY Test Tool provides a solution for performing Zigbee RF Performance and PHY Certification tests, as well as a general evaluation of the integrated radio with IEEE 802.15.4 standard. + +Overview +******** + +You can perform the testing by connecting to the development kit through the serial port and sending supported commands. + +See the :ref:`802154_phy_test_ui` for the list of the available commands. + +Requirements +************ + +The sample supports the following development kits: + +.. table-from-rows:: /includes/sample_board_rows.txt + :header: heading + :rows: nrf5340dk_nrf5340_cpunet, nrf52840dk_nrf52840 + +Conducting tests using the sample also requires a testing device, like another development kit running the same sample, set into DUT mode. +For more information, see :ref:`802154_phy_test_testing`. + +.. note:: + You can perform the testing using other equipment, like spectrum analyzers, oscilloscopes, or RF power meters, but these methods are not covered by this documentation. + +.. _802154_phy_test_ui: + +Serial commands list +******************** + +This section lists the serial commands that are supported by the sample. + +changemode - Change the device mode +=================================== + +It changes the device mode if BOTH modes are available. + + .. parsed-literal:: + :class: highlight + + custom changemode ** + +The ```` argument can assume one of the following values: + +* ``0`` - DUT +* ``1`` - CMD + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom changemode *1* + +indication - LED indication +=========================== + +It makes the CMD device control the LED indicating packet reception. + + .. parsed-literal:: + :class: highlight + + custom indication ** + +The ```` argument can assume one of the following values: + +* ``0`` - none +* ``1`` - LED packet reception indication + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom indication *1* + +rping - Ping the DUT +==================== + +It makes the CMD device send a PING to the DUT device and wait for the reply. + + .. parsed-literal:: + :class: highlight + + custom rping + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rping + +lpingtimeout - Set the ping timeout +=================================== + +It makes the CMD device set the timeout in milliseconds for receiving the *pong* responses from the DUT device. + + .. parsed-literal:: + :class: highlight + + custom lpingtimeout ** ** + +* The ```` value indicates the higher byte of the timeout. +* The ```` value indicates the lower byte of the timeout. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lpingtimeout *0* *255* + +setchannel - Set the common radio channel for the DUT and CMD +============================================================= + +It sets a common radio channel for the DUT and CMD devices, sends a PING, and waits for the response. + + .. parsed-literal:: + :class: highlight + + custom setchannel ** ** ** **. + +The four ```` arguments are four octets defining the channel page and number. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom setchannel *0* *0* *8* *0* + +lsetchannel - Set the CMD radio channel +======================================= + +It sets radio channel of the CMD device. + + .. parsed-literal:: + :class: highlight + + custom lsetchannel ** ** ** **. + +The four ```` arguments are four bytes defining the channel page and number. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsetchannel *0* *0* *16* *0* + +rsetchannel - Set the DUT radio channel +======================================= + +It sets the radio channel of the DUT device. + + .. parsed-literal:: + :class: highlight + + custom rsetchannel ** + +The ```` argument indicates the selected channel’s number. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rsetchannel *13* + +lgetchannel - Get the CMD radio channel +======================================= + +It gets the current configured channel of the CMD device. + + .. parsed-literal:: + :class: highlight + + custom lgetchannel + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgetchannel + +lsetpower - Set the CMD radio power +=================================== + +It sets the CMD device's TX power. + + .. parsed-literal:: + :class: highlight + + custom lsetpower ** ** ** + +* The ```` and ```` arguments are currently unsupported. + Use ``0`` for both. +* The ```` argument indicates the TX power as a signed integer in dBm. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rsetpower *0* *0* *-17* + +lgetpower - Get the CMD radio power +=================================== + +It gets the current configured power of the CMD device. + + .. parsed-literal:: + :class: highlight + + custom lgetpower + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgetpower + +rgetpower - Get the DUT radio power +=================================== + +It gets the current configured power of the DUT device. + + .. parsed-literal:: + :class: highlight + + custom rgetpower + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rgetpower + +rstream - DUT modulated waveform transmission +============================================= + +It commands the DUT device to start a modulated waveform transmission of a certain duration in milliseconds. + + .. parsed-literal:: + :class: highlight + + custom rstream ** ** + +* The ```` argument indicates the higher byte of the duration value. +* The ```` argument indicates the lower byte of the duration value. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rstream *255* *255* + +rstart - Start the RX Test +========================== + +It makes the DUT device start the RX test routine, clearing previous statistics. + + .. parsed-literal:: + :class: highlight + + custom rstart + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rstart + +rend - End the RX Test +====================== + +It makes the DUT device terminate the RX test routine. +The DUT device also sends the test results to the CMD device + + .. parsed-literal:: + :class: highlight + + custom rend + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rend + +find - Find the DUT +=================== + +It makes the CMD device cycle all the channels (11-26) trying to PING the DUT device. +It stops upon receiving a reply. + + .. parsed-literal:: + :class: highlight + + custom find + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom find + +lgetcca - Clear Channel Assessment +================================== + +It makes the CMD device perform a Clear Channel Assessment (CCA) with the requested mode and print the result. + + .. parsed-literal:: + :class: highlight + + custom lgetcca ** + +The ```` argument indicates the IEEE 802.15.4 CCA mode (1-3). + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgetcca *1* + +lgeted - Perform Energy Detection +================================= + +It starts the energy detection and reports the result as 2 hexadecimal bytes. + + .. parsed-literal:: + :class: highlight + + custom lgeted + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgeted + +lgetlqi - Get Link Quality Indicator +==================================== + +It puts the CMD device in receive mode and makes it wait for a packet. +It then outputs the result as 2 hexadecimal bytes. + + .. parsed-literal:: + :class: highlight + + custom lgetlqi + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgetlqi + +lgetrssi - Measure RSSI +======================= + +It gets the RSSI in dBm. + + .. parsed-literal:: + :class: highlight + + custom lgetrssi + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgetrssi + +lsetshort - Set short address +============================= + +It sets the CMD device's short address. +It is used for frame filtering and acknowledgment transmission. + + .. parsed-literal:: + :class: highlight + + custom lsetshort *0x* + +The ```` argument indicates the IEEE 802.15.4 short, two-byte address. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsetshort *0x00FF* + +lsetextended - Set extended address +=================================== + +It sets the CMD device's extended address. +It is used for frame filtering and acknowledgment transmission. + + .. parsed-literal:: + :class: highlight + + custom lsetextended *0x* + +The ```` argument indicates the IEEE 802.15.4 long, 8-byte address. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsetextended *0x000000000000FFFF* + +lsetpanid - Set PAN id +====================== + +It sets the PAN id. +It is used for frame filtering and acknowledgment transmission. + + .. parsed-literal:: + :class: highlight + + custom lsetpanid *0x* + +The ```` argument indicates the two-bytes of the IEEE 802.15.4 PAN ID. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsetpanid *0x000A* + +lsetpayload - Set payload for burst transmission +================================================ + +It sets an arbitrary payload of a raw IEEE 802.15.4 packet. + + .. parsed-literal:: + :class: highlight + + custom lsetpayload ** ** + +* The ```` argument indicates the length of the payload in bytes. +* The ```` argument indicates the bytes of the packet payload. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsetpayload *5* *FFFFFFFFFF* + +ltx - Burst transmission of packets +=================================== + +It starts the transmission of packets with a random (or previously defined) payload. + + .. parsed-literal:: + :class: highlight + + custom ltx ** ** + +* The ```` argument indicates the number of packets to be sent. + Set to ``0`` for an infinite transmission. +* The ```` argument indicates the delay in milliseconds between the transmissions. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom ltx *10* *1000* + +ltxend - Stop the burst transmission of packets +=============================================== + +It makes the CMD device stop current burst transmission. + + .. parsed-literal:: + :class: highlight + + custom ltxend + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom ltxend + +lstart - Start the continuous receive mode +========================================== + +It makes the sample enter the continuous receive mode and print the received packet information over a serial connection. +The sample does not accept any other command until it receives ``custom lend``. + + .. parsed-literal:: + :class: highlight + + custom lstart + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lstart + +lend - End the continuous receive mode +====================================== + +It makes the sample leave the continuous receive mode and print statistics + + .. parsed-literal:: + :class: highlight + + custom lend + +The statistics are shown in the following format: + + .. parsed-literal:: + :class: highlight + + [total]0x%x%x%x%x [protocol]0x%x%x%x%x [totalLqi]0x%x%x%x%x [totalRssiMgnitude]0x%x%x%x%x + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lend + +lsetantenna - Set CMD antenna number +==================================== + +It sets the antenna used by the CMD device. + + .. parsed-literal:: + :class: highlight + + custom lsetantenna ** + +The ```` argument indicates the antenna number, in the range between ``0`` and ``225``. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsetantenna *1* + +lgetantenna - Get CMD antenna number +==================================== + +It gets the antenna used by the CMD device. + + .. parsed-literal:: + :class: highlight + + custom lgetantenna + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgetantenna + +rsetantenna - Set DUT antenna number +==================================== + +It sets the antenna used by the DUT device. + + .. parsed-literal:: + :class: highlight + + custom rsetantenna ** + +The ```` argument indicates the antenna number, in the range between ``0`` and ``225``. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rsetantenna *1* + +rgetantenna - Get DUT antenna number +==================================== + +It gets the antenna used by the DUT device. + + .. parsed-literal:: + :class: highlight + + custom rgetantenna + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom rgetantenna + +lcarrier - Unmodulated waveform (carrier) transmission +====================================================== + +It starts the transmission of the unmodulated carrier. + + .. parsed-literal:: + :class: highlight + + custom lcarrier ** ** ** + +* The ```` argument indicates the duration of the continuous signal transmission. + It ranges between ``1`` and ``32767`` milliseconds. +* The ```` argument indicates the duration of the interval between the pulses. + It ranges between ``0`` and ``32767`` milliseconds. +* The ```` argument indicates the upper limit for the command’s execution. + It ranges between ``0`` and ``32767`` milliseconds. + Set to ``0`` for infinite transmission. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lcarrier ``10`` ``200`` ``2000`` + +lstream - Modulated waveform transmission +========================================= + +It starts a modulated waveform transmission. + + .. parsed-literal:: + :class: highlight + + custom lstream ** ** ** + +* The ```` argument indicates the duration of the continuous packet transmission. + It ranges between ``1`` and ``32767`` milliseconds. +* The ```` argument indicates the duration of the interval between the pulses. + It ranges between ``0`` and ``32767`` milliseconds. +* The ```` argument indicates the upper limit for the command’s execution. + It ranges between ``0`` and ``32767`` milliseconds. + Set to ``0`` for infinite transmission. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lstream *100* *200* *20000* + +rhardwareversion - Get the DUT hardware version +=============================================== + +It gets the hardware version of the DUT device. + + .. parsed-literal:: + :class: highlight + + custom rhardwareversion + + .. parsed-literal:: + :class: highlight + + custom rhardwareversion + +rsoftwareversion - Get the DUT software version +=============================================== + +It gets the software version of the DUT device. + + .. parsed-literal:: + :class: highlight + + custom rsoftwareversion + + .. parsed-literal:: + :class: highlight + + custom rsoftwareversion + +lclk - High-frequency clock output on a selected pin +==================================================== + +It makes the CMD device disable or enable the high-frequency clock output on a selected pin. +The actual clock frequency depends on the SoC used. +It is the highest possible considering the GPIO and CLOCK modules possibilities. + + .. parsed-literal:: + :class: highlight + + custom lclk ** ** + +* The ```` argument indicates the GPIO pin number. + It ranges between ``0`` and the number of GPIO pins supported by the SoC. +* The ```` argument can assume one of the following values: + + * ``0`` - disabled + * ``1`` - enabled + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lclk *10* *1* + +lsetgpio - Set GPIO pin value +============================= + +It makes the CMD device set the value of the selected GPIO out pin. + + .. parsed-literal:: + :class: highlight + + custom lsetgpio ** ** + +* The ```` argument indicates the GPIO pin number. + It ranges between ``0`` and the number of GPIO pins supported by the SoC. +* The ```` argument can assume one of the following values: + + * ``0`` - low + * ``1`` - high + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsetgpio *29* *0* + +lgetgpio - Get GPIO pin value +============================= + +It makes CMD reconfigure the selected GPIO pin to INPUT mode and read its value. + + .. parsed-literal:: + :class: highlight + + custom lgetgpio ** + +* The ```` argument indicates the GPIO pin number. + It ranges between ``0`` and the number of GPIO pins supported by the SoC. + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgetgpio *29* + +lsetdcdc - Set DC/DC mode +========================= + +It makes the CMD device disable or enable the DC/DC mode. +It has no effects on unsupported boards. + + .. parsed-literal:: + :class: highlight + + custom lsetdcdc ** + +* The ```` argument can assume one of the following values: + + * ``0`` - disabled + * ``1`` - enabled + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsetdcdc *1* + +lgetdcdc - Get DC/DC mode +========================= + +It gets the DC/DC mode of the CMD device. +It is always ``0`` for unsupported boards. + + .. parsed-literal:: + :class: highlight + + custom lgetdcdc + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgetdcdc + +lseticache - Set ICACHE configuration +===================================== + +It makes the CMD device disable or enable the ICACHE + + .. parsed-literal:: + :class: highlight + + custom lseticache ** + +* The ```` argument can assume one of the following values: + + * ``0`` - disabled + * ``1`` - enabled + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lseticache *1* + +lgettemp - Read SoC temperature +=============================== + +It makes the CMD device print the SoC temperature in the format ``<.%02>``. + + .. parsed-literal:: + :class: highlight + + custom lgettemp + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lgettemp + +lsleep - Transition radio to sleep mode +======================================= + +It makes the CMD device put the radio in sleep mode. + + .. parsed-literal:: + :class: highlight + + custom lsleep + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lsleep + +lreceive - Transition radio to receive mode +=========================================== + +It makes the CMD device put the radio in receive mode. + + .. parsed-literal:: + :class: highlight + + custom lreceive + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lreceive + +lreboot - Reboots the device +============================ + +It reboots the device + + .. parsed-literal:: + :class: highlight + + custom lreboot + +See the following example: + + .. parsed-literal:: + :class: highlight + + custom lreboot + +Building and running +******************** + +.. |sample path| replace:: :file:`samples/peripheral/802154_phy_test` + +.. include:: /includes/build_and_run.txt + +.. note:: + On the |nRF5340DKnoref|, the IEEE 802.15.4 PHY Test Tool is a standalone network sample that does not require any counterpart application sample. + However, you must still program the application core to boot up the network core, and forward the UART pins to the network core of the CMD device. + The :ref:`nrf5340_empty_app_core` sample, which does both, is built and programmed automatically by default. + +.. _802154_phy_test_testing: + +Testing the sample +================== + +After programming the sample to your development kit, test it by performing the following steps: + +1. Connect the development kit to the computer using a USB cable. + Use the development kit's programmer USB port (J2). + The kits are assigned a COM port (in Windows) or a ttyACM device (in Linux), visible in the Device Manager or in the :file:`/dev` directory. +#. |connect_terminal| +#. If the sample is configured to support BOTH modes (the default setting), switch the development kit into CMD mode by sending the following command: + + .. parsed-literal:: + :class: highlight + + custom changemode *1* + +#. On the bottom side of your development kit, locate the table describing the GPIO pin assignment to the LEDs. + Read the numbers of the GPIO pins assigned to LED 1, 2, 3 or 4. + For example, on the nRF52840DK, the LEDs are controlled by the pins ranging between P0.13 and P0.16. +#. The LEDs on nRF5340DK and nRF52840DK are in the ``sink`` configuration. + To turn them on, you must set the respective pin's state to low to let the current flow through the LED, using the ``custom lsetgpio 0`` command, where ```` is the number of the pin assigned for selected LED. + See the following example for how to light up LED 1 on the nRF5340DK: + + .. parsed-literal:: + :class: highlight + + custom lsetgpio *28* 0 + +If the selected LED lights up, the sample works as expected and is ready for use. + +.. _802154_phy_test_testing_board: + +.. note:: + The serial communication does not utilize echo, and the timeout for receiving the entire command after receiving its first character is very short. + To let the device properly receive the commands, use a terminal application that supports *line mode*, or send the entire command using commands like ``echo`` or ``printf``. + +Performing radio tests without the serial interface +=================================================== + +1. Make sure that at least one of the development kits can be set into CMD mode and the other one to the DUT mode. + The DUT device will not initialize the serial interface. + The easiest way to achieve this is to flash both devices with the sample configured to support BOTH modes (default setting). +#. Connect both development kits to the computer using a USB cable. + The kits are assigned a COM port (in Windows) or a ttyACM device (in Linux), visible in the Device Manager or the :file:`/dev` directory. +#. |connect_terminal| +#. If the samples are configured to support BOTH modes (the default setting), switch one of the development kits into CMD mode by sending the following command: + + .. parsed-literal:: + :class: highlight + + custom changemode *1* + +#. Run the following command on the development kit running in CMD mode: + + .. parsed-literal:: + :class: highlight + + custom find + +#. The development kit running in CMD mode should respond with one of the following 2 responses: + + * ``channel find `` - if the CMD device successfully communicates with the DUT device. + * ``DUT NOT FOUND`` - if it could not exchange packets with the DUT device. + +Refer to the :ref:`802154_phy_test_ui` for the complete list of the available commands. diff --git a/samples/peripheral/802154_phy_test/include/comm_proc.h b/samples/peripheral/802154_phy_test/include/comm_proc.h new file mode 100644 index 000000000000..9d9ca579dc2f --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/comm_proc.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: communication interfaces */ + +#ifndef COMM_PROC_H__ +#define COMM_PROC_H__ + +#include + +#include + +/**< Maximum expected size of received packet */ +#define COMM_MAX_TEXT_DATA_SIZE (320u) + +/**< Time to wait for a mark of end of a packet (new line) */ +#define COMM_PER_COMMAND_TIMEOUT (500u) + +/**< Maximum size of transmitted packet */ +#define COMM_TX_BUFFER_SIZE (320u) + +/**< Additional symbols in the end of transmitted packet */ +#define COMM_APPENDIX "\r\n" +#define COMM_APPENDIX_SIZE sizeof(COMM_APPENDIX) + +/**< Stated of COMM packet parser */ +enum input_state { + INPUT_STATE_IDLE = 0, /**< Wait for the first symbol */ + INPUT_STATE_WAITING_FOR_NEWLINE, /**< Wait for new line symbol or timeout */ + INPUT_STATE_TEXT_PROCESSING, /**< Passes received string to the library */ +}; + +struct text_proc_s { + struct k_timer timer; + struct k_work work; + char buf[COMM_MAX_TEXT_DATA_SIZE]; + uint16_t len; + enum input_state state; +}; + +void comm_init(void); + +void comm_input_process(struct text_proc_s *text_proc, const uint8_t *buf, uint32_t len); + +void comm_text_processor_fn(struct k_work *work); + +void comm_proc(void); + +void comm_input_timeout_handler(struct k_timer *timer); + +#endif /* COMM_PROC_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_ctrl.h b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_ctrl.h new file mode 100644 index 000000000000..44a3feb693c3 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_ctrl.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: control module interface intended for internal usage on library + * level + */ + +#ifndef PTT_CTRL_H__ +#define PTT_CTRL_H__ + +#include "ptt_events.h" +#include "ptt_types.h" + +/** @brief Push a received packet from rf to ctrl module + * + * Provides the control module with a packet received over the air + * + * @param pkt - packet received over the air + * @param len - length of the packet + * @param rssi - RSSI of the packet + * @param lqi - LQI of the packet + * + * @return none + */ +void ptt_ctrl_rf_push_packet(const uint8_t *pkt, ptt_pkt_len_t len, int8_t rssi, uint8_t lqi); + +/** @brief Pass an event "Transmission started" + * + * Pass to the control module external event about starting transmission + * + * @param evt_id - id of currently processed event + */ +void ptt_ctrl_rf_tx_started(ptt_evt_id_t evt_id); + +/** @brief Pass an event "Transmission finished" + * + * Pass to the control module external event about finished transmission + * + * @param evt_id - id of currently processed event + */ +void ptt_ctrl_rf_tx_finished(ptt_evt_id_t evt_id); + +/** @brief Pass an event "Transmission failed" + * + * Pass to the control module external event about failed transmission + * + * @param evt_id - id of currently processed event + * @param tx_error - a reason of transmission fail + */ +void ptt_ctrl_rf_tx_failed(ptt_evt_id_t evt_id, ptt_rf_tx_error_t tx_error); + +/** @brief Pass an event "Reception failed" + * + * Pass to the control module information about failed reception + * + * @param rx_error - a reason of reception fail + */ +void ptt_ctrl_rf_rx_failed(ptt_rf_rx_error_t rx_error); + +/** @brief Pass an event "ED detected" and a result + * + * Pass to the control module external event about finished ED procedure and its result + * + * @param evt_id - id of currently processed event + * @param result - result of "ED detected" procedure + */ +void ptt_ctrl_rf_ed_detected(ptt_evt_id_t evt_id, ptt_ed_t result); + +/** @brief Pass an event "ED failed" + * + * Pass to the control module external event about failed ED procedure + * + * @param evt_id - id of currently processed event + */ +void ptt_ctrl_rf_ed_failed(ptt_evt_id_t evt_id); + +/** @brief Pass an event "CCA done" and a result + * + * Pass to the control module external event about finished CCA procedure and its result + * + * @param evt_id - id of currently processed event + * @param result - result of CCA procedure + */ +void ptt_ctrl_rf_cca_done(ptt_evt_id_t evt_id, bool result); + +/** @brief Pass an event "CCA failed" and a result + * + * Pass to the control module external event about finished CCA procedure and its result + * + * @param evt_id - id of currently processed event + */ +void ptt_ctrl_rf_cca_failed(ptt_evt_id_t evt_id); + +#endif /* PTT_CTRL_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_events.h b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_events.h new file mode 100644 index 000000000000..1e400358cc9a --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_events.h @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: events interface intended for internal usage on library level */ + +#ifndef PTT_EVENTS_H__ +#define PTT_EVENTS_H__ + +#include + +#define PTT_EVENT_UNASSIGNED (0xFFu) + +/** type definition of event id */ +typedef uint8_t ptt_evt_id_t; + +#endif /* PTT_EVENTS_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_timers.h b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_timers.h new file mode 100644 index 000000000000..af391e82437e --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_timers.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: timers interface intended for internal usage on library level */ + +#ifndef PTT_TIMERS_H__ +#define PTT_TIMERS_H__ + +#include "ptt_errors.h" +#include "ptt_events.h" +#include "ptt_types.h" + +/** type definition of function to be call when timer is expired */ +typedef void (*ptt_timer_cb)(ptt_evt_id_t evt_id); + +/** @brief Add a timer to the timer pool + * + * @param timeout - timeout for the timer in ms + * @param cb - function to be called when timeout expired + * @param evt_id - event id to identify timer also will be passed as parameter to user cb + * + * @return zero on success, or error code + */ +enum ptt_ret ptt_timer_add(ptt_time_t timeout, ptt_timer_cb cb, ptt_evt_id_t evt_id); + +/** @brief Free timer for evt_id + * + * @param evt_id - event, corresponding to removing timer + */ +void ptt_timer_remove(ptt_evt_id_t evt_id); + +#endif /* PTT_TIMERS_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_trace.h b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_trace.h new file mode 100644 index 000000000000..9c4a5823c6d3 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_trace.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: trace interface intended for internal usage on library level */ + +#ifndef PTT_TRACE_H__ +#define PTT_TRACE_H__ + +#ifdef TESTS + +#include "stdio.h" +#define PTT_TRACE printf + +#else +#include +LOG_MODULE_DECLARE(phy_tt); + +#define PTT_TRACE(...) LOG_DBG(__VA_ARGS__) + +#endif + +#define PTT_TRACE_FUNC_ENTER() PTT_TRACE("%s ->\n", __func__) +#define PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id) PTT_TRACE("%s -> evt_id: %d\n", __func__, evt_id) +#define PTT_TRACE_FUNC_EXIT() PTT_TRACE("%s -<\n", __func__) +#define PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret) PTT_TRACE("%s -< ret: %d\n", __func__, ret) + +#endif /* PTT_TRACE_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_uart.h b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_uart.h new file mode 100644 index 000000000000..111d950777e2 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/ctrl/ptt_uart.h @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: uart transport interface intended for internal usage on library + * level + */ + +#ifndef PTT_UART_H__ +#define PTT_UART_H__ + +#include "ptt_errors.h" +#include "ptt_uart_api.h" + +#define PTT_VALUE_ON (1u) +#define PTT_VALUE_OFF (0u) + +/* commands text */ +#define UART_CMD_R_PING_TEXT "custom rping" +#define UART_CMD_L_PING_TIMEOUT_TEXT "custom lpingtimeout" +#define UART_CMD_SETCHANNEL_TEXT "custom setchannel" +#define UART_CMD_L_SETCHANNEL_TEXT "custom lsetchannel" +#define UART_CMD_R_SETCHANNEL_TEXT "custom rsetchannel" +#define UART_CMD_L_GET_CHANNEL_TEXT "custom lgetchannel" +#define UART_CMD_L_SET_POWER_TEXT "custom lsetpower" +#define UART_CMD_R_SET_POWER_TEXT "custom rsetpower" +#define UART_CMD_L_GET_POWER_TEXT "custom lgetpower" +#define UART_CMD_R_GET_POWER_TEXT "custom rgetpower" +#define UART_CMD_R_STREAM_TEXT "custom rstream" +#define UART_CMD_R_START_TEXT "custom rstart" +#define UART_CMD_R_END_TEXT "custom rend" +#define UART_CMD_L_REBOOT_TEXT "custom lreboot" +#define UART_CMD_FIND_TEXT "custom find" +#define UART_CMD_R_HW_VERSION_TEXT "custom rhardwareversion" +#define UART_CMD_R_SW_VERSION_TEXT "custom rsoftwareversion" +#define UART_CMD_CHANGE_MODE_TEXT "custom changemode" +#define UART_CMD_L_GET_CCA_TEXT "custom lgetcca" +#define UART_CMD_L_GET_ED_TEXT "custom lgeted" +#define UART_CMD_L_GET_LQI_TEXT "custom lgetlqi" +#define UART_CMD_L_GET_RSSI_TEXT "custom lgetrssi" +#define UART_CMD_L_SET_SHORT_TEXT "custom lsetshort" +#define UART_CMD_L_SET_EXTENDED_TEXT "custom lsetextended" +#define UART_CMD_L_SET_PAN_ID_TEXT "custom lsetpanid" +#define UART_CMD_L_SET_PAYLOAD_TEXT "custom lsetpayload" +#define UART_CMD_L_START_TEXT "custom lstart" +#define UART_CMD_L_END_TEXT "custom lend" +#define UART_CMD_L_SET_ANTENNA_TEXT "custom lsetantenna" +#define UART_CMD_L_GET_ANTENNA_TEXT "custom lgetantenna" +#define UART_CMD_R_SET_ANTENNA_TEXT "custom rsetantenna" +#define UART_CMD_R_GET_ANTENNA_TEXT "custom rgetantenna" +#define UART_CMD_L_TX_TEXT "custom ltx" +#define UART_CMD_L_CLK_TEXT "custom lclk" +#define UART_CMD_L_SET_GPIO_TEXT "custom lsetgpio" +#define UART_CMD_L_GET_GPIO_TEXT "custom lgetgpio" +#define UART_CMD_L_TX_END_TEXT "custom ltxend" +#define UART_CMD_L_CARRIER_TEXT "custom lcarrier" +#define UART_CMD_L_STREAM_TEXT "custom lstream" +#define UART_CMD_L_SET_DCDC_TEXT "custom lsetdcdc" +#define UART_CMD_L_GET_DCDC_TEXT "custom lgetdcdc" +#define UART_CMD_L_SET_ICACHE_TEXT "custom lseticache" +#define UART_CMD_L_GET_ICACHE_TEXT "custom lgeticache" +#define UART_CMD_L_GET_TEMP_TEXT "custom lgettemp" +#define UART_CMD_L_INDICATION_TEXT "custom lindication" +#define UART_CMD_L_SLEEP_TEXT "custom lsleep" +#define UART_CMD_L_RECEIVE_TEXT "custom lreceive" + +/* commands payload in space separated words */ +#define UART_CMD_R_PING_PAYLOAD_L 0 +#define UART_CMD_L_PING_TIMEOUT_PAYLOAD_L 2 +#define UART_CMD_SETCHANNEL_PAYLOAD_L 4 +#define UART_CMD_L_SETCHANNEL_PAYLOAD_L 4 +#define UART_CMD_R_SETCHANNEL_PAYLOAD_L 1 +#define UART_CMD_L_GET_CHANNEL_PAYLOAD_L 0 +#define UART_CMD_L_SET_POWER_PAYLOAD_L 3 +#define UART_CMD_R_SET_POWER_PAYLOAD_L 3 +#define UART_CMD_L_GET_POWER_PAYLOAD_L 0 +#define UART_CMD_R_GET_POWER_PAYLOAD_L 0 +#define UART_CMD_R_STREAM_PAYLOAD_L 2 +#define UART_CMD_R_START_PAYLOAD_L 0 +#define UART_CMD_R_END_PAYLOAD_L 0 +#define UART_CMD_L_REBOOT_PAYLOAD_L 0 +#define UART_CMD_FIND_PAYLOAD_L 0 +#define UART_CMD_R_HW_VERSION_PAYLOAD_L 0 +#define UART_CMD_R_SW_VERSION_PAYLOAD_L 0 +#define UART_CMD_CHANGE_MODE_PAYLOAD_L 1 +#define UART_CMD_L_GET_CCA_PAYLOAD_L 1 +#define UART_CMD_L_GET_ED_PAYLOAD_L 0 +#define UART_CMD_L_GET_LQI_PAYLOAD_L 0 +#define UART_CMD_L_GET_RSSI_PAYLOAD_L 0 +#define UART_CMD_L_SET_SHORT_PAYLOAD_L 1 +#define UART_CMD_L_SET_EXTENDED_PAYLOAD_L 1 +#define UART_CMD_L_SET_PAN_ID_PAYLOAD_L 1 +#define UART_CMD_L_SET_PAYLOAD_PAYLOAD_L 2 +#define UART_CMD_L_START_PAYLOAD_L 0 +#define UART_CMD_L_END_PAYLOAD_L 0 +#define UART_CMD_L_SET_ANTENNA_PAYLOAD_L 1 +#define UART_CMD_L_GET_ANTENNA_PAYLOAD_L 0 +#define UART_CMD_R_SET_ANTENNA_PAYLOAD_L 1 +#define UART_CMD_R_GET_ANTENNA_PAYLOAD_L 0 +#define UART_CMD_L_TX_PAYLOAD_L 2 +#define UART_CMD_L_CLK_PAYLOAD_L 2 +#define UART_CMD_L_SET_GPIO_PAYLOAD_L 2 +#define UART_CMD_L_GET_GPIO_PAYLOAD_L 1 +#define UART_CMD_L_TX_END_PAYLOAD_L 0 +#define UART_CMD_L_CARRIER_PAYLOAD_L 3 +#define UART_CMD_L_STREAM_PAYLOAD_L 3 +#define UART_CMD_L_SET_DCDC_PAYLOAD_L 1 +#define UART_CMD_L_GET_DCDC_PAYLOAD_L 0 +#define UART_CMD_L_SET_ICACHE_PAYLOAD_L 1 +#define UART_CMD_L_GET_ICACHE_PAYLOAD_L 0 +#define UART_CMD_L_GET_TEMP_PAYLOAD_L 0 +#define UART_CMD_L_INDICATION_PAYLOAD_L 1 +#define UART_CMD_L_SLEEP_PAYLOAD_L 0 +#define UART_CMD_L_RECEIVE_PAYLOAD_L 0 + +#define UART_TEXT_PAYLOAD_DELIMETERS " " + +#define UART_CMD_SET_POWER_VALUE_PLACE 2 + +#define UART_SET_PAN_ID_SYM_NUM 6 +#define UART_SET_SHORT_SYM_NUM 6 +#define UART_SET_EXTENDED_SYM_NUM 18 + +/** UART commands */ +enum ptt_uart_cmd { + PTT_UART_CMD_R_PING = 0x00, /**< send ping to DUT */ + PTT_UART_CMD_L_PING_TIMEOUT, /**< set ping timeout to CMD */ + PTT_UART_CMD_SETCHANNEL, /**< set channel to CMD and DUT */ + PTT_UART_CMD_L_SETCHANNEL, /**< set channel to CMD */ + PTT_UART_CMD_R_SETCHANNEL, /**< set channel to DUT */ + PTT_UART_CMD_L_GET_CHANNEL, /**< get channel from CMD */ + PTT_UART_CMD_L_SET_POWER, /**< set power to CMD */ + PTT_UART_CMD_R_SET_POWER, /**< set power to DUT */ + PTT_UART_CMD_L_GET_POWER, /**< get power from CMD */ + PTT_UART_CMD_R_GET_POWER, /**< get power from DUT */ + PTT_UART_CMD_R_STREAM, /**< DUT transmits a stream */ + PTT_UART_CMD_R_START, /**< DUT starts RX test */ + PTT_UART_CMD_R_END, /**< DUT ends RX test and sends a report */ + PTT_UART_CMD_L_REBOOT, /**< CMD reboot local device */ + PTT_UART_CMD_FIND, /**< CMD starts find procedure */ + PTT_UART_CMD_R_HW_VERSION, /**< get HW version from DUT */ + PTT_UART_CMD_R_SW_VERSION, /**< get SW version from DUT */ + PTT_UART_CMD_CHANGE_MODE, /**< change device mode */ + PTT_UART_CMD_L_GET_CCA, /**< CMD will perform CCA with selected mode and print result*/ + PTT_UART_CMD_L_GET_ED, /**< CMD will perform ED and print out the result */ + PTT_UART_CMD_L_GET_LQI, + /**< CMD will put the device into receive mode and wait for reception of a single packet */ + PTT_UART_CMD_L_GET_RSSI, /**< CMD will measure RSSI and print result */ + PTT_UART_CMD_L_SET_SHORT, /**< CMD will set its short address */ + PTT_UART_CMD_L_SET_EXTENDED, /**< CMD will set its extended address */ + PTT_UART_CMD_L_SET_PAN_ID, /**< CMD will set its PAN Id */ + PTT_UART_CMD_L_SET_PAYLOAD, /**< CMD will set payload for next ltx commands */ + PTT_UART_CMD_L_START, + /**< CMD will put the DUT in a continuous receive mode, where each packet received */ + /** is displayed in turn */ + PTT_UART_CMD_L_END, + /**< CMD will stop the continuous receive mode, if active. If continuous receive mode */ + /** is not active, the command is ignored. */ + PTT_UART_CMD_L_SET_ANTENNA, /**< CMD will set antenna device is sending frames with. */ + PTT_UART_CMD_L_GET_ANTENNA, /**< CMD will print out the antenna used by the device */ + PTT_UART_CMD_R_SET_ANTENNA, /**< CMD will set antenna DUT device is sending frames with. */ + PTT_UART_CMD_R_GET_ANTENNA, /**< CMD will print out the antenna used by the DUT device */ + PTT_UART_CMD_L_TX, + /**< CMD will transmit a number of raw 802.15.4 frames with */ + /** payload previously set by “custom lsetpayload” */ + PTT_UART_CMD_L_CLK, /**< CMD will output HFCLK to GPIO pin */ + PTT_UART_CMD_L_SET_GPIO, /**< CMD will set value to GPIO pin */ + PTT_UART_CMD_L_GET_GPIO, /**< CMD will get value from GPIO pin */ + PTT_UART_CMD_L_TX_END, + /**< CMD will stop ltx command processing if ltx started with infinite number of packets */ + PTT_UART_CMD_L_CARRIER, /**< CMD will emit carrier signal without modulation */ + PTT_UART_CMD_L_STREAM, + /**< CMD will emit modulated signal with payload set by “custom lsetpayload”*/ + PTT_UART_CMD_L_SET_DCDC, /**< CMD will disable/enable DC/DC mode */ + PTT_UART_CMD_L_GET_DCDC, /**< CMD will print current DC/DC mode */ + PTT_UART_CMD_L_SET_ICACHE, /**< CMD will disable/enable ICACHE */ + PTT_UART_CMD_L_GET_ICACHE, /**< CMD will print current state of ICACHE */ + PTT_UART_CMD_L_GET_TEMP, /**< CMD will print out the SoC temperature */ + PTT_UART_CMD_L_INDICATION, /**< CMD will control LED indicating received packet */ + PTT_UART_CMD_L_SLEEP, /**< CMD will put radio into sleep mode */ + PTT_UART_CMD_L_RECEIVE, /**< CMD will put radio into receive mode*/ + PTT_UART_CMD_N, /**< command count */ +}; + +/** Actions to perform with payload before sending it to command handler */ +enum ptt_uart_payload { + /**< payload will be parsed as bytes separated by @ref UART_TEXT_PAYLOAD_DELIMETERS*/ + /** will be send to command handler */ + PTT_UART_PAYLOAD_PARSED_AS_BYTES, + /**< payload will be written as raw ASCII and command handlerwill be */ + /** responsible for parsing actions types count */ + PTT_UART_PAYLOAD_RAW, + PTT_UART_PAYLOAD_N, +}; + +/** command name and additional info for text command parsing */ +struct uart_text_cmd_s { + const char *name; /**< string containing command name */ + enum ptt_uart_cmd code; /**< command code */ + uint8_t payload_len; /**< payload length in space separated words */ + enum ptt_uart_payload payload_type; + /**< action to perform with payload before sending it to command handler\ */ +}; + +/** @brief Send a packet over UART + * + * @param pkt - data to send + * @param len - length of pkt + * + * @return PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_uart_send_packet(const uint8_t *pkt, ptt_pkt_len_t len); + +/** @brief Send @ref PTT_UART_PROMPT_STR over UART + * + * @param - none + * + * @return - none + */ +void ptt_uart_print_prompt(void); + +/** @brief Notify UART module a handler is busy + * + * @param - none + * + * @return - none + */ +void ptt_handler_busy(void); + +/** @brief Notify UART module a handler is free + * + * @param - none + * + * @return - none + */ +void ptt_handler_free(void); + +#endif /* PTT_UART_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/ptt_errors.h b/samples/peripheral/802154_phy_test/include/internal/ptt_errors.h new file mode 100644 index 000000000000..6208e47e7005 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/ptt_errors.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: PHY Test Tool library errors declaration */ + +#ifndef PTT_ERRORS_H__ +#define PTT_ERRORS_H__ + +#include + +/** error codes */ +enum ptt_ret { + PTT_RET_SUCCESS = 0, /**< success */ + PTT_RET_NULL_PTR, /**< pointer is NULL */ + PTT_RET_INVALID_VALUE, /**< invalid input value */ + PTT_RET_INVALID_STATE, /**< invalid state */ + PTT_RET_INVALID_MODE, /**< invalid mode of device */ + PTT_RET_INVALID_COMMAND, /**< invalid command*/ + PTT_RET_NO_FREE_SLOT, /**< no free slots in a pool */ + PTT_RET_BUSY, /**< resource is busy */ +}; + +#endif /* PTT_ERRORS_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/ptt_proto.h b/samples/peripheral/802154_phy_test/include/internal/ptt_proto.h new file mode 100644 index 000000000000..18758fdf9cb1 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/ptt_proto.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: Protocol related definitions */ + +#ifndef PTT_PROTO_H__ +#define PTT_PROTO_H__ + +#include +#include + +#include "ptt_types.h" + +/* first byte of a packet preamble */ +#define PTT_PREAMBLE_1ST (0xDEu) +/* second byte of a packet preamble */ +#define PTT_PREAMBLE_2ND (0xDEu) +/* third byte of a packet preamble */ +#define PTT_PREAMBLE_3D (0x00u) +/* length of a packet preamble */ +#define PTT_PREAMBLE_LEN (3u) + +/* length of command id field */ +#define PTT_CMD_CODE_LEN (1u) + +/* index in a packet where command id is placed */ +#define PTT_CMD_CODE_START (PTT_PREAMBLE_LEN) +/* index in a packet where payload started */ +#define PTT_PAYLOAD_START (PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN) + +#define PTT_PAYLOAD_LEN_SET_CHANNEL 4 +#define PTT_PAYLOAD_LEN_SET_POWER 1 +#define PTT_PAYLOAD_LEN_STREAM 2 +#define PTT_PAYLOAD_LEN_GET_POWER 1 +#define PTT_PAYLOAD_LEN_REPORT 16 +#define PTT_PAYLOAD_LEN_GET_HARDWARE 1 +#define PTT_PAYLOAD_LEN_GET_SOFTWARE 1 +#define PTT_PAYLOAD_LEN_SET_ANTENNA 1 +#define PTT_PAYLOAD_LEN_GET_ANTENNA 1 + +/** OTA commands codes */ +enum ptt_cmd { + PTT_CMD_PING = 0x00, /**< ping command */ + PTT_CMD_ACK = 0x01, /**< ack command */ + PTT_CMD_SET_CHANNEL = 0x02, /**< set DUT radio channel command */ + PTT_CMD_SET_POWER = 0x05, /**< set DUT radio power command */ + PTT_CMD_GET_POWER = 0x06, /**< send get power request to DUT command */ + PTT_CMD_GET_POWER_RESPONSE = 0x07, /**< get power command response */ + PTT_CMD_STREAM = 0x09, /**< start modulated waveform stream */ + PTT_CMD_START_RX_TEST = 0x0A, /**< start statistics incrementing */ + PTT_CMD_END_RX_TEST = 0x0B, /**< send report request to DUT command */ + PTT_CMD_REPORT = 0x0C, /**< test statistic report */ + PTT_CMD_GET_HARDWARE_VERSION = 0x11, /**< send hardware version request to DUT */ + PTT_CMD_GET_HARDWARE_VERSION_RESPONSE = 0x12, /**< get hardware version response */ + PTT_CMD_GET_SOFTWARE_VERSION = 0x13, /**< send software version request to DUT */ + PTT_CMD_GET_SOFTWARE_VERSION_RESPONSE = 0x14, /**< get software version response */ + PTT_CMD_GET_ANTENNA = 0x20, /**< send antenna request to DUT command */ + PTT_CMD_GET_ANTENNA_RESPONSE = 0x21, /**< get antenna command response */ + PTT_CMD_SET_ANTENNA = 0x22, /**< set DUT antenna command */ + PTT_CMD_CHANGE_MODE = 0xF0, /**< change device mode command */ +}; + +/** @brief Check a packet for valid protocol header + * + * @param pkt - pointer to packet data + * @param len - length of packet + * + * @return true - packet header is valid + * @return false - packet header isn't valid + */ +bool ptt_proto_check_packet(const uint8_t *pkt, ptt_pkt_len_t len); + +/** @brief Fill a packet with protocol header and provided command + * + * @param pkt - pointer to packet data, must have enough space to reside the header and command + * @param cmd - command id + * @param pkt_max_size - available space in the packet + * + * @return ptt_pkt_len_t - length of header with command + */ +ptt_pkt_len_t ptt_proto_construct_header(uint8_t *pkt, enum ptt_cmd cmd, + ptt_pkt_len_t pkt_max_size); + +/* helper functions to convert between protocol big-endian format and host endianness */ +void ptt_htobe16(uint8_t *src, uint8_t *dst); +void ptt_htobe32(uint8_t *src, uint8_t *dst); +void ptt_betoh16(uint8_t *src, uint8_t *dst); +void ptt_betoh32(uint8_t *src, uint8_t *dst); + +uint16_t ptt_htobe16_val(uint8_t *src); +uint32_t ptt_htobe32_val(uint8_t *src); +uint16_t ptt_betoh16_val(uint8_t *src); +uint32_t ptt_betoh32_val(uint8_t *src); + +void ptt_htole16(uint8_t *src, uint8_t *dst); + +#endif /* PTT_PROTO_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/ptt_utils.h b/samples/peripheral/802154_phy_test/include/internal/ptt_utils.h new file mode 100644 index 000000000000..5b53b39a98d8 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/ptt_utils.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: miscellaneous helpful things */ + +#ifndef PTT_UTILS_H__ +#define PTT_UTILS_H__ + +#include + +#define PTT_COMPILE_TIME_ASSERT_CAT_(a, b) a##b +#define PTT_COMPILE_TIME_ASSERT_CAT(a, b) PTT_COMPILE_TIME_ASSERT_CAT_(a, b) + +#define PTT_COMPILE_TIME_ASSERT(cond) \ + typedef char PTT_COMPILE_TIME_ASSERT_CAT(assertion_failed_, __LINE__)[(cond) ? 1 : -1] + +#define PTT_UNUSED(x) ((void)(x)) + +#define PTT_CAST_TO_UINT8_P(x) ((uint8_t *)(x)) +#define PTT_CAST_TO_STR(x) ((char *)(x)) + +#endif /* PTT_UTILS_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/internal/rf/ptt_rf.h b/samples/peripheral/802154_phy_test/include/internal/rf/ptt_rf.h new file mode 100644 index 000000000000..d123c2893d4c --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/internal/rf/ptt_rf.h @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: radio module interface intended for internal usage on library + * level + */ + +#ifndef PTT_RF_H__ +#define PTT_RF_H__ + +#include + +#include "ptt_config.h" +#include "ctrl/ptt_events.h" +#include "ptt_errors.h" +#include "ptt_types.h" + +#define PTT_CHANNEL_MIN (11u) +#define PTT_CHANNEL_MAX (26u) + +#define PTT_PANID_ADDRESS_SIZE (2u) +#define PTT_SHORT_ADDRESS_SIZE (2u) +#define PTT_EXTENDED_ADDRESS_SIZE (8u) + +/* received packets statistic */ +struct ptt_rf_stat_s { + uint32_t total_pkts; /**< total received packets */ + uint32_t total_lqi; /**< sum of lqi of received packets */ + uint32_t total_rssi; /**< sum of rssi of received packets */ +}; + +/** payload for `custom ltx` command */ +struct ptt_ltx_payload_s { + uint8_t arr[PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE]; /**< raw PHY packet */ + uint8_t len; /**< length of used part of arr */ +}; + +/* information that came with the packet */ +struct ptt_rf_packet_info_s { + uint8_t lqi; + int8_t rssi; +}; + +/** @brief RF module context initialization + * + * @param none + * + * @return none + */ +void ptt_rf_init(void); + +/** @brief RF module context unitialization + * + * @param none + * + * @return none + */ +void ptt_rf_uninit(void); + +/** @brief RF module reset to default + * + * @param none + * + * @return none + */ +void ptt_rf_reset(void); + +/** @brief Send a packet to a transmitter + * + * @param evt_id - event id locking this transmission + * @param pkt - data to be transmitted + * @param len - length of the data + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_send_packet(ptt_evt_id_t evt_id, const uint8_t *pkt, ptt_pkt_len_t len); + +/** @brief Set channel mask to radio driver + * + * @param evt_id - event id locking setting mask + * @param mask - channel bit mask, if more than one bit enabled, least significant will be used + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_set_channel_mask(ptt_evt_id_t evt_id, uint32_t mask); + +/** @brief Set channel to radio driver + * + * @param evt_id - event id locking setting channel + * @param channel - channel number (11-26) + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_set_channel(ptt_evt_id_t evt_id, uint8_t channel); + +/** @brief Set short address to radio driver + * + * @param evt_id - event id locking setting address + * @param short_address Pointer to the short address (2 bytes, little-endian) + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_set_short_address(ptt_evt_id_t evt_id, const uint8_t *short_addr); + +/** @brief Set extended address to radio driver + * + * @param evt_id - event id locking setting address + * @param extended_address Pointer to the extended address (8 bytes, little-endian) + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_set_extended_address(ptt_evt_id_t evt_id, const uint8_t *extended_addr); + +/** @brief Set pan id to radio driver + * + * @param evt_id - event id locking setting PAN id + * @param pan_id Pointer to the PAN ID (2 bytes, little-endian) + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_set_pan_id(ptt_evt_id_t evt_id, const uint8_t *pan_id); + +/** @brief Returns number of current channel + * + * @param none + * + * @return uint8_t - current channel number + */ +uint8_t ptt_rf_get_channel(void); + +/** @brief Set power to radio driver + * + * @param evt_id - event id locking setting power + * @param power - power in dbm + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_set_power(ptt_evt_id_t evt_id, int8_t power); + +/** @brief Returns current power + * + * @param none + * + * @return int8_t - current power + */ +int8_t ptt_rf_get_power(void); + +/** @brief Set antenna to radio driver + * + * @param evt_id - event id locking setting antenna + * @param antenna - is value in range [0-255] + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_set_antenna(ptt_evt_id_t evt_id, uint8_t antenna); + +/** @brief Returns current antenna + * + * @param none + * + * @return uint8_t - current antenna + */ +uint8_t ptt_rf_get_antenna(void); + +/** @brief Calls radio driver to verify if the channel is clear + * + * @param evt_id - event id locking radio module + * @param mode - CCA mode + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_cca(ptt_evt_id_t evt_id, uint8_t mode); + +/** @brief Calls radio driver to detect the maximum energy for a given time + * + * @param evt_id - event id locking radio module + * @param time_us - duration of energy detection procedure. + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_ed(ptt_evt_id_t evt_id, uint32_t time_us); + +/** @brief Calls radio driver to begin the RSSI measurement + * + * @param evt_id - event id locking static module + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_rssi_measure_begin(ptt_evt_id_t evt_id); + +/** @brief Calls radio driver to get the result of the last RSSI measurement + * + * @param[IN] evt_id - event id locking static module + * @param[OUT] rssi - RSSI measurement result in dBm, unchanged if error code returned + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_rssi_last_get(ptt_evt_id_t evt_id, ptt_rssi_t *rssi); + +/** @brief Convert channel bitmask into a channel number + * + * @param mask - channel bit mask, if more than one bit enabled, least significant will be used + * + * @return uint8_t - channel number or 0, if there is no valid channels inside mask + */ +uint8_t ptt_rf_convert_channel_mask_to_num(uint32_t mask); + +/** @brief Clear statistic and enable statistic gathering in RF module + * + * @param evt_id - event id locking statistic control + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_start_statistic(ptt_evt_id_t evt_id); + +/** @brief Disable statistic gathering in RF module + * + * @param evt_id - event id locking statistic control + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_end_statistic(ptt_evt_id_t evt_id); + +/** @brief Get gathered statistic from RF module + * + * @param none + * + * @return struct ptt_rf_stat_s - structure with gathered statistic + */ +struct ptt_rf_stat_s ptt_rf_get_stat_report(void); + +/** @brief Start modulated stream transmission + * + * @param evt_id - event id locking this transmission + * @param pkt - payload to modulate carrier with + * @param len - length of payload to modulate carrier with + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_start_modulated_stream(ptt_evt_id_t evt_id, const uint8_t *pkt, + ptt_pkt_len_t len); + +/** @brief Stop modulated stream transmission + * + * @param evt_id - event id locking this transmission + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_stop_modulated_stream(ptt_evt_id_t evt_id); + +/** @brief Start continuous carrier transmission + * + * @param evt_id - event id locking this transmission + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_start_continuous_carrier(ptt_evt_id_t evt_id); + +/** @brief Stop continuous carrier transmission + * + * @param evt_id - event id locking this transmission + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_stop_continuous_carrier(ptt_evt_id_t evt_id); + +/** @brief Getter for payload of custom ltx command + * + * @param none + * + * @return struct ptt_ltx_payload_s * pointer to payload + */ +struct ptt_ltx_payload_s *ptt_rf_get_custom_ltx_payload(void); + +/** @brief Change radio state to receiving + * + * @param evt_id - event id locking this operation + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_receive(void); + +/** @brief Change radio state to sleeping + * + * @param evt_id - event id locking this operation + * + * @return enum ptt_ret - PTT_RET_SUCCESS or error + */ +enum ptt_ret ptt_rf_sleep(void); + +#endif /* PTT_RF_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/periph_proc.h b/samples/peripheral/802154_phy_test/include/periph_proc.h new file mode 100644 index 000000000000..4f859ef93ba0 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/periph_proc.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: Periphery interfaces */ + +#ifndef PERIPH_PROC_H__ +#define PERIPH_PROC_H__ + +#include + +#include "ptt.h" + +/** @brief Initialize various periphery + * + * @param none + * + * @return none + * + */ +void periph_init(void); + +#endif /* PERIPH_PROC_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/ptt.h b/samples/peripheral/802154_phy_test/include/ptt.h new file mode 100644 index 000000000000..970fc09c6e6e --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/ptt.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: PHY Test Tool library interface for external usage */ + +#ifndef PTT_H__ +#define PTT_H__ + +#include "ptt_types.h" + +/** @brief PTT library initialization + * + * @param call_me_cb - callback to be called from the library to schedule a timer + * @param max_time - maximum supported time by a current timer implementation + * + * @return none + */ +void ptt_init(ptt_call_me_cb_t call_me_cb, ptt_time_t max_time); + +/** @brief PTT library uninitialization + * + * @param none + * + * @return none + */ +void ptt_uninit(void); + +/** @brief Notify the library about expired timeout + * + * @param current_time - current time in milliseconds + * + * @return none + */ +void ptt_process(ptt_time_t current_time); + +/* external provided function to get current time */ +extern ptt_time_t ptt_get_current_time(void); +/* external provided function to get mode mask from application */ +extern bool ptt_get_mode_mask_ext(uint32_t *mode); +/* external provided function to get channel_mask from application */ +extern bool ptt_get_channel_mask_ext(uint32_t *channel_mask); +/* external provided function to get power from application */ +extern bool ptt_get_power_ext(int8_t *power); +/* external provided function to get antenna from application */ +extern bool ptt_get_antenna_ext(uint8_t *antenna); +/* external provided function to get SW version from application */ +extern bool ptt_get_sw_version_ext(uint8_t *sw_version); +/* external provided function to get HW version from application */ +extern bool ptt_get_hw_version_ext(uint8_t *hw_version); +/* external provided function to get ANT mode from application */ +extern bool ptt_get_ant_mode_ext(uint8_t *ant_mode); +/* external provided function to get ANT number from application */ +extern bool ptt_get_ant_num_ext(uint8_t *ant_num); +/* external provided function to reset board */ +extern void ptt_do_reset_ext(void); +/** @brief external provided function to get random value + * + * must be able to get at least @ref PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE bytes every + * (@ref PTT_L_STREAM_INTERVAL_MIN + @ref PTT_L_STREAM_PULSE_MIN) ms + */ +extern uint32_t ptt_random_get_ext(void); +/* external provided function to control HFLCK output */ +extern bool ptt_clk_out_ext(uint8_t pin, bool mode); +/* external provided function to set GPIO pin value */ +extern bool ptt_set_gpio_ext(uint8_t pin, uint8_t value); +/* external provided function to get GPIO pin value */ +extern bool ptt_get_gpio_ext(uint8_t pin, uint8_t *value); +/* external provided function to disable/enable DC/DC mode */ +extern void ptt_set_dcdc_ext(bool enable); +/* external provided function to get current DC/DC mode */ +extern bool ptt_get_dcdc_ext(void); +/* external provided function to disable/enable ICACHE */ +extern void ptt_set_icache_ext(bool enable); +/* external provided function to get current state of ICACHE */ +extern bool ptt_get_icache_ext(void); +/* external provided function to get SoC temperature */ +extern bool ptt_get_temp_ext(int32_t *temp); +/* external provided function to set LED indicating received packet state to ON */ +extern void ptt_ctrl_led_indication_on_ext(void); +/* external provided function to set LED indicating received packet state to OFF*/ +extern void ptt_ctrl_led_indication_off_ext(void); + +#endif /* PTT_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/ptt_config.h b/samples/peripheral/802154_phy_test/include/ptt_config.h new file mode 100644 index 000000000000..df5e5ecc7817 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/ptt_config.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: settings intended for external configuration */ + +#ifndef PTT_CONFIG_H__ +#define PTT_CONFIG_H__ + +#define PTT_EVENT_POOL_N 8u +#define PTT_EVENT_DATA_SIZE 320u /* necessary to keep aligned to 4 */ +#define PTT_EVENT_CTX_SIZE 32u /* necessary to keep aligned to 4 */ + +#define PTT_TIMER_POOL_N 8u + +/* will be rounded up to multiplication of 8 symbols (128 us) */ +#define PTT_ED_TIME_US 128u + +/* timeout for the measurement process to finish */ +#define PTT_RSSI_TIME_MS 1u + +/* if this value returned by RSSI measurement procedure, error will be printed */ +#define PTT_RSSI_ERROR_VALUE INT8_MAX + +/* time to wait for packet for `lgetlqi` command */ +#define PTT_LQI_DELAY_MS 5000u + +#define PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE 125u +#define PTT_CUSTOM_LTX_DEFAULT_REPEATS 1 +#define PTT_CUSTOM_LTX_DEFAULT_TIMEOUT_MS 0 +#define PTT_CUSTOM_LTX_TIMEOUT_MAX_VALUE INT16_MAX + +#define PTT_L_CARRIER_PULSE_MIN 1 /* must fit in int32_t */ +#define PTT_L_CARRIER_PULSE_MAX INT16_MAX /* must fit in int32_t */ +#define PTT_L_CARRIER_INTERVAL_MIN 0 /* must fit in int32_t */ +#define PTT_L_CARRIER_INTERVAL_MAX INT16_MAX /* must fit in int32_t */ +#define PTT_L_CARRIER_DURATION_MIN 0 /* must fit in int32_t */ +#define PTT_L_CARRIER_DURATION_MAX INT16_MAX /* must fit in int32_t */ + +#define PTT_L_STREAM_PULSE_MIN 1 /* must fit in int32_t */ +#define PTT_L_STREAM_PULSE_MAX INT16_MAX /* must fit in int32_t */ +#define PTT_L_STREAM_INTERVAL_MIN 0 /* must fit in int32_t */ +#define PTT_L_STREAM_INTERVAL_MAX INT16_MAX /* must fit in int32_t */ +#define PTT_L_STREAM_DURATION_MIN 0 /* must fit in int32_t */ +#define PTT_L_STREAM_DURATION_MAX INT16_MAX /* must fit in int32_t */ + +#define PTT_UART_PROMPT_STR ">" + +#define PTT_LED_INDICATION_BLINK_TIMEOUT_MS 200 + +#endif /* PTT_CONFIG_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/ptt_rf_api.h b/samples/peripheral/802154_phy_test/include/ptt_rf_api.h new file mode 100644 index 000000000000..ba91f11629df --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/ptt_rf_api.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: radio module interface intended for external usage */ + +#ifndef PTT_RF_API_H__ +#define PTT_RF_API_H__ + +#include + +#include "ptt_types.h" + +/** @brief Provides library RF module with a received packet + * + * @param pkt - pointer to a packet data + * @param len - length of a received data + * @param rssi - RSSI + * @param lqi - LQI + * + * @return none + */ +void ptt_rf_push_packet(const uint8_t *pkt, ptt_pkt_len_t len, int8_t rssi, uint8_t lqi); + +/** @brief Provides library RF module with "Transmission started" event + * + * @param none + * + * @return none + */ +void ptt_rf_tx_started(void); + +/** @brief Provides library RF module with "Transmission finished" event + * + * @param none + * + * @return none + */ +void ptt_rf_tx_finished(void); + +/** @brief Provides library RF module with "Transmission failed" event + * + * @param tx_error - reason of transmission fail + * + * @return none + */ +void ptt_rf_tx_failed(ptt_rf_tx_error_t tx_error); + +/** @brief Provides library RF module with "Reception failed" event + * + * @param rx_error - reason of reception fail + * + * @return none + */ +void ptt_rf_rx_failed(ptt_rf_rx_error_t rx_error); + +/** @brief Provides library RF module with "CCA done" and a result + * + * @param result - result of CCA procedure + * + * @return none + */ +void ptt_rf_cca_done(bool result); + +/** @brief Provides library RF module with "CCA failed" + * + * @param none + * + * @return none + */ +void ptt_rf_cca_failed(void); + +/** @brief Provides library RF module with "ED detected" and a result + * + * @param result - result of ED procedure + * + * @return none + */ +void ptt_rf_ed_detected(ptt_ed_t result); + +/** @brief Provides library RF module with "ED failed" + * + * @param none + * + * @return none + */ +void ptt_rf_ed_failed(void); + +/* external provided function to set channel on current radio */ +extern void ptt_rf_set_channel_ext(uint8_t channel); +/* external provided function to set power on current radio */ +extern void ptt_rf_set_power_ext(int8_t power); +/* external provided function to get current power from current radio */ +extern int8_t ptt_rf_get_power_ext(void); +/* external provided function to set promiscuous mode on current radio */ +extern void ptt_rf_promiscuous_set_ext(bool value); +/* external provided function to start receive on current radio */ +extern bool ptt_rf_receive_ext(void); +/* external provided function to put current radio on sleep */ +extern bool ptt_rf_sleep_ext(void); +/* external provided function to start sending continuous carrier on current radio */ +extern bool ptt_rf_continuous_carrier_ext(void); +/* external provided function to start sending modulated carrier on current radio */ +extern bool ptt_rf_modulated_stream_ext(const uint8_t *pkt, ptt_pkt_len_t len); +/* external provided function to send a packet on current radio */ +extern bool ptt_rf_send_packet_ext(const uint8_t *pkt, ptt_pkt_len_t len, bool cca); +/* external provided function to verify if the channel is clear */ +extern bool ptt_rf_cca_ext(uint8_t mode); +/* external provided function to detects the maximum energy for a given time */ +extern bool ptt_rf_ed_ext(uint32_t time_us); +/* external provided function to begin the RSSI measurement */ +extern bool ptt_rf_rssi_measure_begin_ext(void); +/* external provided function to get the result of the last RSSI measurement */ +extern ptt_rssi_t ptt_rf_rssi_last_get_ext(void); +/* external provided function to set PAN ID used by the device */ +extern void ptt_rf_set_pan_id_ext(const uint8_t *pan_id); +/* external provided function to set extended address of the device */ +extern void ptt_rf_set_extended_address_ext(const uint8_t *extended_address); +/* external provided function to set short address of the device */ +extern void ptt_rf_set_short_address_ext(const uint8_t *short_address); +/* external provided function to set antenna on current radio */ +extern void ptt_rf_set_antenna_ext(uint8_t antenna); +/* external provided function to get current antenna from current radio */ +extern uint8_t ptt_rf_get_antenna_ext(void); + +#endif /* PTT_RF_API_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/ptt_types.h b/samples/peripheral/802154_phy_test/include/ptt_types.h new file mode 100644 index 000000000000..1859df36eeee --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/ptt_types.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: PHY Test Tool types */ + +#ifndef PTT_TYPES_H__ +#define PTT_TYPES_H__ + +#include +#include + +typedef uint16_t ptt_pkt_len_t; + +typedef int32_t (*ptt_uart_send_cb)(const uint8_t *pkt, ptt_pkt_len_t len, bool add_crlf); + +typedef uint32_t ptt_time_t; +typedef void (*ptt_call_me_cb_t)(ptt_time_t timeout); + +typedef uint16_t ptt_ed_t; +typedef int8_t ptt_rssi_t; + +typedef uint8_t ptt_rf_rx_error_t; + +#define PTT_RF_RX_ERROR_NONE 0x00 /**< there is no error */ +#define PTT_RF_RX_ERROR_INVALID_FCS 0x01 /**< received a frame with an invalid checksum */ +#define PTT_RF_RX_ERROR_OPERATION_FAILED 0x02 /**< reception failed */ + +typedef uint8_t ptt_rf_tx_error_t; + +#define PTT_RF_TX_ERROR_NONE 0x00 /**< there is no error */ +#define PTT_RF_TX_ERROR_INVALID_ACK_FCS 0x01 /**< received ACK frame is valid, but has wrong FCS */ +#define PTT_RF_TX_ERROR_NO_ACK 0x02 /**< ACK was not received during the timeout period */ +#define PTT_RF_TX_ERROR_OPERATION_FAILED 0x03 /**< transmission failed */ + +#endif /* PTT_TYPES_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/ptt_uart_api.h b/samples/peripheral/802154_phy_test/include/ptt_uart_api.h new file mode 100644 index 000000000000..a3a12daea5f7 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/ptt_uart_api.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: UART interface intended for external usage */ + +#ifndef PTT_UART_API_H__ +#define PTT_UART_API_H__ + +#include "ptt_types.h" + +/** @brief Initialize library UART processing module + * + * @param send_cb - callback provided by application to send packets via UART + * + * @return none + */ +void ptt_uart_init(ptt_uart_send_cb send_cb); + +/** @brief Uninitialize library UART processing module + * + * @param none + * + * @return none + */ +void ptt_uart_uninit(void); + +/** @brief Push received packet to library for further processing + * + * @param pkt - received packet + * @param len - length of the packet + * + * @return none + */ +void ptt_uart_push_packet(const uint8_t *pkt, ptt_pkt_len_t len); + +#endif /* PTT_UART_API_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/rf_proc.h b/samples/peripheral/802154_phy_test/include/rf_proc.h new file mode 100644 index 000000000000..85e1dc89d9ee --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/rf_proc.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: RF interfaces */ + +#ifndef RF_PROC_H__ +#define RF_PROC_H__ + +#include + +#include "ptt_rf_api.h" + +/**< Size of PHY header */ +#define RF_PHR_SIZE (1u) + +/**< Size of frame check sequence */ +#define RF_FCS_SIZE (2u) + +/**< Maximum size of PSDU */ +#define RF_PSDU_MAX_SIZE (127u) + +/**< Start of PSDU payload */ +#define RF_PSDU_START (1u) + +/** @brief NRF radio driver initialization + * + * @param none + * + * @return none + */ +void rf_init(void); + +/** @brief NRF radio driver deinitialization + * + * @param none + * + * @return none + */ +void rf_uninit(void); + +/** @brief Thread function for Radio handling + * + * @param none + * + * @return none + * + */ +void rf_thread(void); + +/**< element of received packets array */ +struct rf_rx_pkt_s { + uint8_t *rf_buf; /**< pointer to buffer inside radio driver with a received packet */ + uint8_t *data; /**< pointer to payload */ + ptt_pkt_len_t length; /**< size of payload of received packet */ + int8_t rssi; /**< RSSI */ + uint8_t lqi; /**< LQI */ +}; + +#endif /* RF_PROC_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/timer_proc.h b/samples/peripheral/802154_phy_test/include/timer_proc.h new file mode 100644 index 000000000000..2ec1d411e56b --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/timer_proc.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: timer interfaces */ + +#ifndef TIMER_PROC_H__ +#define TIMER_PROC_H__ + +#include + +#include "ptt.h" + +/** @brief Callback provided by application to be called from the library + * to schedule a timer with a given timeout + * + * @param timeout - timeout in milliseconds + * + * @return none + */ +void launch_ptt_process_timer(ptt_time_t timeout); + +/** @brief Return maximum time supported by current timer implementation + * + * @param none + * + * @return ptt_time_t - maximum time in milliseconds + */ +ptt_time_t ptt_get_max_time(void); + +#endif /* TIMER_PROC_H__ */ diff --git a/samples/peripheral/802154_phy_test/include/uart_proc.h b/samples/peripheral/802154_phy_test/include/uart_proc.h new file mode 100644 index 000000000000..473ac397da67 --- /dev/null +++ b/samples/peripheral/802154_phy_test/include/uart_proc.h @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: uart interfaces */ + +#ifndef UART_PROC_H__ +#define UART_PROC_H__ + +#include + +#include "ptt.h" + +/**< Amount of bytes requested from driver */ +#define UART_BYTES_TO_READ (1u) + +/** @brief Initialize UARTE driver and UART module inside PTT library + * + * @param none + * + * @return none + * + */ +void uart_init(void); + +int32_t uart_send(const uint8_t *pkt, ptt_pkt_len_t len, bool add_crlf); + +#endif /* UART_PROC_H__ */ diff --git a/samples/peripheral/802154_phy_test/prj.conf b/samples/peripheral/802154_phy_test/prj.conf new file mode 100644 index 000000000000..ea3c4ecacbe6 --- /dev/null +++ b/samples/peripheral/802154_phy_test/prj.conf @@ -0,0 +1,45 @@ +# Enabling assert +CONFIG_ASSERT=y + +# Logger configuration +CONFIG_LOG=y +CONFIG_LOG_DEFAULT_LEVEL=3 +CONFIG_USE_SEGGER_RTT=y +CONFIG_LOG_BACKEND_RTT=y +CONFIG_LOG_BACKEND_UART=n +CONFIG_LOG_STRDUP_BUF_COUNT=10 + +# Enable UART +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_NRFX_UARTE=y +CONFIG_NRFX_UARTE0=y +CONFIG_UART_0_NRF_TX_BUFFER_SIZE=3072 + +# Enable temperature sensor +CONFIG_NRFX_TEMP=y + +# Enable DC/DC Support +CONFIG_NRFX_POWER=y + +# Enable RNG +CONFIG_NRFX_RNG=y +# Use XOROSHIRO PRNG +CONFIG_XOROSHIRO_RANDOM_GENERATOR=y + +# Enable Timer +CONFIG_NRFX_TIMER2=y + +# Enabling radio driver +CONFIG_NRF_802154_RADIO_DRIVER=y + +# Allow sharing the RTC between IEEE 802.15.4 and Zephyr +CONFIG_NRF_RTC_TIMER_USER_CHAN_COUNT=2 + +# Workaround for a bug in the MPSL Glue Layer (not required for nRF52840) +CONFIG_BT=y + +# Include empty image in the APP core (not used for nRF52840) +CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE=y + +# Enable ring buffers +CONFIG_RING_BUFFER=y diff --git a/samples/peripheral/802154_phy_test/sample.yaml b/samples/peripheral/802154_phy_test/sample.yaml new file mode 100644 index 000000000000..0f0f9a87602f --- /dev/null +++ b/samples/peripheral/802154_phy_test/sample.yaml @@ -0,0 +1,11 @@ +sample: + name: IEEE 802.15.4 PHY Test Tool + description: IEEE 802.15.4 PHY Test Tool sample +tests: + samples.peripheral.802154_phy_test: + build_only: true + platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpunet + integration_platforms: + - nrf52840dk_nrf52840 + - nrf5340dk_nrf5340_cpunet + tags: ci_build diff --git a/samples/peripheral/802154_phy_test/src/comm_proc.c b/samples/peripheral/802154_phy_test/src/comm_proc.c new file mode 100644 index 000000000000..c9ada89a0339 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/comm_proc.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: Communication interface for library */ + +#include +#include + +#include "uart_proc.h" +#ifdef USE_USB +#include "usb_proc.h" +#endif +#include "comm_proc.h" + +#include +LOG_MODULE_REGISTER(comm); + +#include "ptt_uart_api.h" + +static int32_t comm_send_cb(const uint8_t *pkt, ptt_pkt_len_t len, bool add_crlf); + +static void comm_symbols_process(struct text_proc_s *text_proc, const uint8_t *buf, uint32_t len); +static inline void text_process(struct text_proc_s *text_proc); +static inline void input_state_reset(struct text_proc_s *text_proc); + +void comm_input_process(struct text_proc_s *text_proc, const uint8_t *buf, uint32_t len) +{ + switch (text_proc->state) { + case INPUT_STATE_IDLE: + if (text_proc->len != 0) { + LOG_WRN("text_proc->len is not 0 when input state is idle"); + text_proc->len = 0; + } + + /* start the timer after first received symbol */ + k_timer_start(&text_proc->timer, K_MSEC(COMM_PER_COMMAND_TIMEOUT), K_MSEC(0)); + + text_proc->state = INPUT_STATE_WAITING_FOR_NEWLINE; + + comm_symbols_process(text_proc, buf, len); + break; + + case INPUT_STATE_WAITING_FOR_NEWLINE: + comm_symbols_process(text_proc, buf, len); + break; + + case INPUT_STATE_TEXT_PROCESSING: + LOG_WRN("received a command when processing previous one, discarded"); + break; + + default: + LOG_ERR("incorrect input state"); + break; + } +} + +K_FIFO_DEFINE(text_processing_fifo); + +void comm_text_processor_fn(struct k_work *work) +{ + LOG_DBG("Called work queue function"); + struct text_proc_s *text_proc = CONTAINER_OF(work, struct text_proc_s, work); + + /* force string termination for further processing */ + text_proc->buf[text_proc->len] = '\0'; + LOG_DBG("received packet to lib: len %d, %s", text_proc->len, log_strdup(text_proc->buf)); + text_process(text_proc); +} + +void comm_input_timeout_handler(struct k_timer *timer) +{ + LOG_DBG("push packet to lib via timer"); + struct text_proc_s *text_proc = CONTAINER_OF(timer, struct text_proc_s, timer); + + k_work_submit(&text_proc->work); +} + +static void comm_symbols_process(struct text_proc_s *text_proc, const uint8_t *buf, uint32_t len) +{ + for (uint32_t cnt = 0; cnt < len; cnt++) { + if (('\n' != buf[cnt]) && ('\r' != buf[cnt])) { + text_proc->buf[text_proc->len] = buf[cnt]; + ++text_proc->len; + + if (text_proc->len >= COMM_MAX_TEXT_DATA_SIZE) { + LOG_ERR("cannot parse %d bytes received, freeing input buffer", + COMM_MAX_TEXT_DATA_SIZE); + + /* Stop the timeout timer */ + k_timer_stop(&text_proc->timer); + input_state_reset(text_proc); + } + } else { + LOG_DBG("push packet to lib via newline"); + /* Stop the timeout timer */ + k_timer_stop(&text_proc->timer); + k_work_submit(&text_proc->work); + + text_proc->state = INPUT_STATE_TEXT_PROCESSING; + break; + } + } +} + +static inline void input_state_reset(struct text_proc_s *text_proc) +{ + text_proc->len = 0; + text_proc->state = INPUT_STATE_IDLE; +} + +static inline void text_process(struct text_proc_s *text_proc) +{ + ptt_uart_push_packet((uint8_t *)text_proc->buf, text_proc->len); + input_state_reset(text_proc); +} + +void comm_init(void) +{ + /* won't initialize UART if the device has DUT mode only */ +#if CONFIG_PTT_DUT_MODE + LOG_INF("Device is in DUT mode only."); +#else + LOG_INF("Init"); + uart_init(); +#ifdef USE_USB + usb_init(); +#endif + ptt_uart_init(comm_send_cb); +#endif +} + +static int32_t comm_send_cb(const uint8_t *pkt, ptt_pkt_len_t len, bool add_crlf) +{ + if ((add_crlf && (len >= (COMM_TX_BUFFER_SIZE - COMM_APPENDIX_SIZE))) || + (!add_crlf && (len >= COMM_TX_BUFFER_SIZE))) { + LOG_WRN("%s: not enough of tx buffer size", __func__); + return -1; + } + + uart_send(pkt, len, add_crlf); + +#ifdef USE_USB + usb_send(pkt, len, add_crlf); +#endif + + return len; +} + +void comm_proc(void) +{ +#ifdef USE_USB + usb_task(); +#endif +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_ctrl.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_ctrl.c new file mode 100644 index 000000000000..17ee2200a943 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_ctrl.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: PTT interface part */ + +#include +#include + +#include "ptt.h" + +#include "ctrl/ptt_trace.h" +#include "rf/ptt_rf.h" + +#include "ptt_ctrl_internal.h" +#include "ptt_events_internal.h" +#include "ptt_modes.h" +#include "ptt_timers_internal.h" + +#ifdef TESTS +#include "test_ctrl_conf.h" +#endif /* TESTS */ + +/** default timeout for waiting for any response */ +#define PTT_DEFAULT_TIMEOUT (500u) + +static struct ptt_ctrl_s ptt_ctrl_ctx; + +void ptt_init(ptt_call_me_cb_t call_me_cb, ptt_time_t max_time) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + assert(call_me_cb != NULL); + + ptt_ctrl_handlers_reset_all(); + ptt_ctrl_ctx.call_me_cb = call_me_cb; + ptt_ctrl_ctx.rsp_timeout = PTT_DEFAULT_TIMEOUT; + ptt_ctrl_ctx.max_time = max_time; + + ptt_events_init(); + ptt_timers_init(); + ptt_rf_init(); + + ret = ptt_mode_default_init(); + + assert(ret == PTT_RET_SUCCESS); + + PTT_UNUSED(ret); +} + +void ptt_uninit(void) +{ + ptt_mode_uninit(); + ptt_events_uninit(); + ptt_timers_uninit(); + ptt_rf_uninit(); +} + +void ptt_process(ptt_time_t current_time) +{ + ptt_timers_process(current_time); +} + +struct ptt_timer_ctx_s *ptt_ctrl_get_timer_ctx(void) +{ + return &ptt_ctrl_ctx.timer_ctx; +} + +void ptt_ctrl_call_me_cb(ptt_time_t timeout) +{ + if (ptt_ctrl_ctx.call_me_cb != NULL) { + ptt_ctrl_ctx.call_me_cb(timeout); + } +} + +struct ptt_evt_ctx_s *ptt_ctrl_get_evt_ctx(void) +{ + return &ptt_ctrl_ctx.evt_ctx; +} + +ptt_time_t ptt_ctrl_get_rsp_timeout(void) +{ + return ptt_ctrl_ctx.rsp_timeout; +} + +void ptt_ctrl_set_rsp_timeout(ptt_time_t timeout) +{ + ptt_ctrl_ctx.rsp_timeout = timeout; +} + +ptt_time_t ptt_ctrl_get_max_time(void) +{ + return ptt_ctrl_ctx.max_time; +} + +enum ptt_mode_t ptt_ctrl_get_current_mode(void) +{ + return ptt_ctrl_ctx.current_mode; +} + +void ptt_ctrl_set_current_mode(enum ptt_mode_t mode) +{ + ptt_ctrl_ctx.current_mode = mode; +} + +enum ptt_mode_t ptt_ctrl_get_default_mode(void) +{ + uint32_t mode_mask; + enum ptt_mode_t mode = PTT_MODE_ZB_PERF_DUT; + + if (ptt_get_mode_mask_ext(&mode_mask)) { + for (uint8_t i = 0; i <= sizeof(mode_mask) * 8; i++) { + if (((mode_mask >> i) & 1u) == 1u) { + mode = i; + break; + } + } + } + + return mode; +} + +uint8_t ptt_ctrl_get_hw_version(void) +{ + uint8_t hw_version = 0xFF; + + ptt_get_hw_version_ext(&hw_version); + return hw_version; +} + +uint8_t ptt_ctrl_get_sw_version(void) +{ + uint8_t sw_version = 0xFF; + + ptt_get_sw_version_ext(&sw_version); + return sw_version; +} + +void ptt_ctrl_set_dcdc(bool activate) +{ + ptt_set_dcdc_ext(activate); +} + +bool ptt_ctrl_get_dcdc(void) +{ + return ptt_get_dcdc_ext(); +} + +enum ptt_ret ptt_ctrl_get_temp(int32_t *temp) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (!ptt_get_temp_ext(temp)) { + ret = PTT_RET_INVALID_VALUE; + } + + return ret; +} + +struct ptt_ext_evts_handlers_s *ptt_ctrl_get_handlers(void) +{ + return &ptt_ctrl_ctx.mode_handlers; +} + +void ptt_random_vector_generate(uint8_t *buff, uint8_t requested_size) +{ + for (int i = 0; i < requested_size; ++i) { + buff[i] = ptt_random_get_ext() % UINT8_MAX; + } +} + +void ptt_ctrl_set_icache(bool enable) +{ + ptt_set_icache_ext(enable); +} + +bool ptt_ctrl_get_icache(void) +{ + return ptt_get_icache_ext(); +} + +void ptt_ctrl_led_indication_on(void) +{ + ptt_ctrl_led_indication_on_ext(); +} + +void ptt_ctrl_led_indication_off(void) +{ + ptt_ctrl_led_indication_off_ext(); +} + +void ptt_ctrl_handlers_reset_all(void) +{ + ptt_ctrl_ctx.mode_handlers = (struct ptt_ext_evts_handlers_s){ 0 }; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_uart_pkt_received(void) +{ + return ptt_ctrl_ctx.mode_handlers.uart_pkt_received; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_tx_finished(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_tx_finished; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_tx_failed(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_tx_failed; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_rx_failed(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_rx_failed; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_tx_started(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_tx_started; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_rx_done(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_rx_done; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_ed_detected(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_ed_detected; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_ed_failed(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_ed_failed; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_cca_done(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_cca_done; +} + +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_cca_failed(void) +{ + return ptt_ctrl_ctx.mode_handlers.rf_cca_failed; +} + +#ifdef TESTS +#include "test_ctrl_wrappers.c" +#endif /* TESTS */ diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_ctrl_internal.h b/samples/peripheral/802154_phy_test/src/ctrl/ptt_ctrl_internal.h new file mode 100644 index 000000000000..747f8f781d21 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_ctrl_internal.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: control module interface intended for internal usage on library + * level + */ + +#ifndef PTT_CTRL_INTERNAL_H__ +#define PTT_CTRL_INTERNAL_H__ + +#include "ctrl/ptt_ctrl.h" + +#include "ptt_modes.h" +#include "ptt_events_internal.h" +#include "ptt_timers_internal.h" + +/** type definition of function to handle event */ +typedef void (*ptt_ext_evt_handler)(ptt_evt_id_t evt_id); + +/** handlers for each event + * NULL if unsupported by current mode + */ +struct ptt_ext_evts_handlers_s { + ptt_ext_evt_handler rf_tx_finished; /**< packet transmission finished */ + ptt_ext_evt_handler rf_tx_failed; /**< packet transmission failed */ + ptt_ext_evt_handler rf_tx_started; /**< packet transmission started */ + ptt_ext_evt_handler rf_rx_done; /**< packet received over radio */ + ptt_ext_evt_handler rf_rx_failed; /**< packet reception failed */ + ptt_ext_evt_handler rf_cca_done; /**< CCA procedure finished */ + ptt_ext_evt_handler rf_cca_failed; /**< CCA procedure failed */ + ptt_ext_evt_handler rf_ed_detected; /**< ED procedure finished */ + ptt_ext_evt_handler rf_ed_failed; /**< ED procedure failed */ + ptt_ext_evt_handler uart_pkt_received; /**< packet received over UART */ +}; + +/** control module context */ +struct ptt_ctrl_s { + ptt_call_me_cb_t call_me_cb; + /**< callback from application to be call when need to update nearest timeout */ + enum ptt_mode_t current_mode; /**< current device mode */ + struct ptt_ext_evts_handlers_s mode_handlers; /**< event handlers */ + struct ptt_timer_ctx_s timer_ctx; /**< timers context */ + struct ptt_evt_ctx_s evt_ctx; /**< events context */ + ptt_time_t rsp_timeout; /**< common timeout for all responses */ + ptt_time_t max_time; /**< maximum time supported by application timer */ +}; + +/* Get timer context */ +struct ptt_timer_ctx_s *ptt_ctrl_get_timer_ctx(void); + +/* Get event context */ +struct ptt_evt_ctx_s *ptt_ctrl_get_evt_ctx(void); + +/* Call call_me_cb - an application callback with given timeout */ +void ptt_ctrl_call_me_cb(ptt_time_t timeout); + +/* Get response timeout */ +ptt_time_t ptt_ctrl_get_rsp_timeout(void); + +/* Set response timeout */ +void ptt_ctrl_set_rsp_timeout(ptt_time_t timeout); + +/* Get max time */ +ptt_time_t ptt_ctrl_get_max_time(void); + +/* Get SoC temperature */ +enum ptt_ret ptt_ctrl_get_temp(int32_t *temp); + +/* Get current mode */ +enum ptt_mode_t ptt_ctrl_get_current_mode(void); + +/* Set current mode */ +void ptt_ctrl_set_current_mode(enum ptt_mode_t mode); + +/* Get default mode */ +enum ptt_mode_t ptt_ctrl_get_default_mode(void); + +/* Get HW version */ +uint8_t ptt_ctrl_get_hw_version(void); + +/* Get SW version */ +uint8_t ptt_ctrl_get_sw_version(void); + +/* Get external events handlers structure */ +struct ptt_ext_evts_handlers_s *ptt_ctrl_get_handlers(void); + +/* Disable/enable DC/DC mode */ +void ptt_ctrl_set_dcdc(bool activate); + +/* Get current DC/DC mode */ +bool ptt_ctrl_get_dcdc(void); + +/* Enable/Disable ICACHE */ +void ptt_ctrl_set_icache(bool enable); + +/* Get current state of ICACHE */ +bool ptt_ctrl_get_icache(void); + +/* Reset external events structure */ +void ptt_ctrl_handlers_reset_all(void); + +/* Get current handler for a packet received through UART */ +ptt_ext_evt_handler ptt_ctrl_get_handler_uart_pkt_received(void); + +/* Get current handler for Transmission finished event */ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_tx_finished(void); + +/* Get current handler for Transmission failed event */ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_tx_failed(void); + +/* Get current handler for Reception failed event */ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_rx_failed(void); + +/* Get current handler for Transmission started event */ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_tx_started(void); + +/* Get current handler for a packet received through RF */ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_rx_done(void); + +/* Get current handler for CCA done procedure */ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_cca_done(void); + +/* Get current handler for CCA failed procedure */ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_cca_failed(void); + +/* Get current handler for ED done procedure*/ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_ed_detected(void); + +/* Get current handler for ED failed procedure */ +ptt_ext_evt_handler ptt_ctrl_get_handler_rf_ed_failed(void); + +/** Get vector of random values + * + * @param buff - buffer to store vector, must be at least requested_size long + * @param requested_size - number of random bytes to store in buff + * + * @return - None + */ +void ptt_random_vector_generate(uint8_t *buff, uint8_t requested_size); + +/* Change state of LED indicating received packet to ON */ +void ptt_ctrl_led_indication_on(void); + +/* Change state of LED indicating received packet to OFF */ +void ptt_ctrl_led_indication_off(void); + +#endif /* PTT_CTRL_INTERNAL_H__ */ diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_events.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_events.c new file mode 100644 index 000000000000..d66b87f21d50 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_events.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: events implementation */ + +#include +#include +#include + +#include "ctrl/ptt_trace.h" + +#include "ptt_events_internal.h" + +#ifdef TESTS +#include "test_events_conf.h" +#else +#include "ptt_ctrl_internal.h" +#endif + +void ptt_events_init(void) +{ + PTT_TRACE("%s ->\n", __func__); + + struct ptt_evt_ctx_s *evt_ctx = ptt_ctrl_get_evt_ctx(); + + *evt_ctx = (struct ptt_evt_ctx_s){ 0 }; + + PTT_TRACE("%s -<\n", __func__); +} + +void ptt_events_uninit(void) +{ + PTT_TRACE("%s\n", __func__); +} + +void ptt_events_reset_all(void) +{ + PTT_TRACE("%s ->\n", __func__); + + ptt_events_uninit(); + ptt_events_init(); + + PTT_TRACE("%s -<\n", __func__); +} + +enum ptt_ret ptt_event_alloc(ptt_evt_id_t *evt_id) +{ + PTT_TRACE("%s -> evt %p\n", __func__, evt_id); + + uint8_t i; + struct ptt_evt_ctx_s *evt_ctx = ptt_ctrl_get_evt_ctx(); + enum ptt_ret ret = PTT_RET_SUCCESS; + + assert(evt_ctx != NULL); + + if (evt_id == NULL) { + ret = PTT_RET_NULL_PTR; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + for (i = 0; i < PTT_EVENT_POOL_N; ++i) { + if (false == evt_ctx->evt_pool[i].use) { + *evt_id = i; + evt_ctx->evt_pool[i].use = true; + + ret = PTT_RET_SUCCESS; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + } + + ret = PTT_RET_NO_FREE_SLOT; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; +} + +enum ptt_ret ptt_event_free(ptt_evt_id_t evt_id) +{ + PTT_TRACE("%s -> evt_id %d\n", __func__, evt_id); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (evt_id >= PTT_EVENT_POOL_N) { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + struct ptt_evt_ctx_s *evt_ctx = ptt_ctrl_get_evt_ctx(); + + assert(evt_ctx != NULL); + + if (false == evt_ctx->evt_pool[evt_id].use) { + /* evt already inactive */ + ret = PTT_RET_SUCCESS; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + evt_ctx->evt_pool[evt_id] = (struct ptt_event_s){ 0 }; + + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; +} + +enum ptt_ret ptt_event_alloc_and_fill(ptt_evt_id_t *evt_id, const uint8_t *pkt, ptt_pkt_len_t len) +{ + PTT_TRACE("%s -> evt %p pkt %p len %d\n", __func__, evt_id, pkt, len); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (pkt == NULL) { + ret = PTT_RET_NULL_PTR; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + if (len > PTT_EVENT_DATA_SIZE) { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + if (len == 0) { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + ret = ptt_event_alloc(evt_id); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + struct ptt_event_s *event = ptt_get_event_by_id(*evt_id); + + assert(event != NULL); + + event->data.len = len; + memcpy(event->data.arr, pkt, event->data.len); + + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; +} + +struct ptt_event_s *ptt_get_event_by_id(ptt_evt_id_t evt_id) +{ + PTT_TRACE("%s -> evt_id %d\n", __func__, evt_id); + + if (evt_id >= PTT_EVENT_POOL_N) { + return NULL; + } + + struct ptt_evt_ctx_s *evt_ctx = ptt_ctrl_get_evt_ctx(); + + assert(evt_ctx != NULL); + + if (false == evt_ctx->evt_pool[evt_id].use) { + /* event inactive */ + return NULL; + } + + return &evt_ctx->evt_pool[evt_id]; +} + +void ptt_event_set_cmd(ptt_evt_id_t evt_id, ptt_evt_cmd_t cmd) +{ + PTT_TRACE("%s -> evt_id %d cmd %d\n", __func__, evt_id, cmd); + + struct ptt_event_s *event = ptt_get_event_by_id(evt_id); + + assert(event != NULL); + + event->cmd = cmd; + + PTT_TRACE("%s -<\n", __func__); +} + +ptt_evt_cmd_t ptt_event_get_cmd(ptt_evt_id_t evt_id) +{ + PTT_TRACE("%s -> evt_id %d\n", __func__, evt_id); + + struct ptt_event_s *event = ptt_get_event_by_id(evt_id); + + assert(event != NULL); + + PTT_TRACE("%s -< cmd %d\n", __func__, event->cmd); + return event->cmd; +} + +void ptt_event_set_state(ptt_evt_id_t evt_id, ptt_evt_state_t state) +{ + PTT_TRACE("%s -> evt_id %d state %d\n", __func__, evt_id, state); + + struct ptt_event_s *event = ptt_get_event_by_id(evt_id); + + assert(event != NULL); + + event->state = state; + + PTT_TRACE("%s -<\n", __func__); +} + +ptt_evt_state_t ptt_event_get_state(ptt_evt_id_t evt_id) +{ + PTT_TRACE("%s -> evt_id %d\n", __func__, evt_id); + + struct ptt_event_s *event = ptt_get_event_by_id(evt_id); + + assert(event != NULL); + + PTT_TRACE("%s -< state %d\n", __func__, event->state); + return event->state; +} + +void ptt_event_set_ctx_data(ptt_evt_id_t evt_id, const uint8_t *data, uint16_t len) +{ + PTT_TRACE("%s -> evt_id %d data %p len %d\n", __func__, evt_id, data, len); + + struct ptt_event_s *event = ptt_get_event_by_id(evt_id); + + assert(event != NULL); + + assert(data != NULL); + assert(len <= PTT_EVENT_CTX_SIZE); + + event->ctx.len = len; + memcpy(event->ctx.arr, data, event->ctx.len); + + PTT_TRACE("%s -<\n", __func__); +} + +struct ptt_evt_ctx_data_s *ptt_event_get_ctx_data(ptt_evt_id_t evt_id) +{ + PTT_TRACE("%s -> evt_id %d\n", __func__, evt_id); + + struct ptt_event_s *event = ptt_get_event_by_id(evt_id); + + assert(event != NULL); + + PTT_TRACE("%s -< ctx %p\n", __func__, &event->ctx); + return &event->ctx; +} + +void ptt_event_set_data(ptt_evt_id_t evt_id, const uint8_t *data, uint16_t len) +{ + PTT_TRACE("%s -> evt_id %d data %p len %d\n", __func__, evt_id, data, len); + + struct ptt_event_s *event = ptt_get_event_by_id(evt_id); + + assert(event != NULL); + + assert(data != NULL); + assert(len <= PTT_EVENT_DATA_SIZE); + + event->data.len = len; + memcpy(event->data.arr, data, event->data.len); + + PTT_TRACE("%s -<\n", __func__); +} + +struct ptt_evt_data_s *ptt_event_get_data(ptt_evt_id_t evt_id) +{ + PTT_TRACE("%s -> evt_id %d\n", __func__, evt_id); + + struct ptt_event_s *event = ptt_get_event_by_id(evt_id); + + assert(event != NULL); + + PTT_TRACE("%s -< ctx %p\n", __func__, &event->data); + return &event->data; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_events_internal.h b/samples/peripheral/802154_phy_test/src/ctrl/ptt_events_internal.h new file mode 100644 index 000000000000..ab6ba25b702a --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_events_internal.h @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: events interface intended for usage inside control module */ + +#ifndef PTT_EVENTS_INTERNAL_H__ +#define PTT_EVENTS_INTERNAL_H__ + +#include "ctrl/ptt_events.h" + +#include "ptt_config.h" +#include "ptt_errors.h" +#include "ptt_types.h" +#include "ptt_utils.h" + +/** events command type definition */ +typedef uint32_t ptt_evt_cmd_t; + +/** events state type definition */ +typedef uint8_t ptt_evt_state_t; + +PTT_COMPILE_TIME_ASSERT((PTT_EVENT_DATA_SIZE % sizeof(int32_t)) == 0u); + +/** struct to hold packet data and length */ +struct ptt_evt_data_s { + uint8_t arr[PTT_EVENT_DATA_SIZE]; /**< packet */ + uint16_t len; /**< packet used lengths */ +}; + +PTT_COMPILE_TIME_ASSERT((PTT_EVENT_CTX_SIZE % sizeof(int32_t)) == 0u); + +/** struct to hold context data and length */ +struct ptt_evt_ctx_data_s { + uint8_t arr[PTT_EVENT_CTX_SIZE]; /**< context */ + uint16_t len; /**< context used lengths */ +}; + +/** event data */ +struct ptt_event_s { + struct ptt_evt_data_s data; /**< packet payload */ + struct ptt_evt_ctx_data_s ctx; /**< command's context */ + ptt_evt_cmd_t cmd; /**< command */ + ptt_evt_state_t state; /**< command processing state */ + bool use; /**< flag to determine is this event currently in use */ +}; + +/** events context */ +struct ptt_evt_ctx_s { + struct ptt_event_s evt_pool[PTT_EVENT_POOL_N]; /**< array of events */ +}; + +/** @brief Initialize events context + * + * @param none + * + * @return none + */ +void ptt_events_init(void); + +/** @brief Uninitialize events context and free resources + * + * @param none + * + * @return none + */ +void ptt_events_uninit(void); + +/** @brief Reset events context to default values as after initialization + * + * @param none + * + * @return none + */ +void ptt_events_reset_all(void); + +/** @brief Allocate event entry in the event pool + * + * @param[out] evt_id - pointer to event index in event pool + * + * @return PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_event_alloc(ptt_evt_id_t *evt_id); + +/** @brief Free event in the event pool + * + * If event pointed by evt_id is free already returns PTT_RET_SUCCESS + * + * @param evt_id - index of event in event pool + * + * @return PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_event_free(ptt_evt_id_t evt_id); + +/** @brief Allocate an event and fill the event content with data provided by pkt and its length + * + * Makes copy from pkt to the event content + * + * @param[out] evt_id - index of event in event pool + * @param pkt - pointer to data + * @param len - length of data + * + * @return PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_event_alloc_and_fill(ptt_evt_id_t *evt_id, const uint8_t *pkt, ptt_pkt_len_t len); + +/** @brief Return pointer to an event by its index in the event pool + * + * @param evt_id - index of event in event pool + * + * @return pointer to the event, or NULL if the event is not found + */ +struct ptt_event_s *ptt_get_event_by_id(ptt_evt_id_t evt_id); + +/** @brief Assign given command to the event + * + * @param evt_id - the event + * @param cmd - command + * + * @return none + */ +void ptt_event_set_cmd(ptt_evt_id_t evt_id, ptt_evt_cmd_t cmd); + +/** @brief Get a command assigned to the event + * + * @param evt_id - the even + * + * @return ptt_evt_cmd_t Command + */ +ptt_evt_cmd_t ptt_event_get_cmd(ptt_evt_id_t evt_id); + +/** @brief Assign given state to the event + * + * @param evt_id - the event + * @param state - state + * + * @return none + */ +void ptt_event_set_state(ptt_evt_id_t evt_id, ptt_evt_state_t state); + +/** @brief Get a state assigned to the event + * + * @param evt_id - the event + * + * @return ptt_evt_state_t State + */ +ptt_evt_state_t ptt_event_get_state(ptt_evt_id_t evt_id); + +/** @brief Copy data to event context + * + * @param evt_id - the event + * @param data - pointer to data, mustn't be NULL + * @param len - length of the data, len <= PTT_EVENT_CTX_SIZE + * + * @return none + */ +void ptt_event_set_ctx_data(ptt_evt_id_t evt_id, const uint8_t *data, uint16_t len); + +/** @brief Returns a pointer to context data of the event + * + * @param none + * + * @return none + */ +struct ptt_evt_ctx_data_s *ptt_event_get_ctx_data(ptt_evt_id_t evt_id); + +/** @brief Copy data to event data + * + * @param evt_id - the event + * @param data - pointer to data, mustn't be NULL + * @param len - length of the data, len <= PTT_EVENT_DATA_SIZE + * + * @return none + */ +void ptt_event_set_data(ptt_evt_id_t evt_id, const uint8_t *data, uint16_t len); + +/** @brief Returns a pointer to data of the event + * + * @param none + * + * @return none + */ +struct ptt_evt_data_s *ptt_event_get_data(ptt_evt_id_t evt_id); + +#endif /* PTT_EVENTS_INTERNAL_H__ */ diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_mode_manager.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_mode_manager.c new file mode 100644 index 000000000000..47447ce9c369 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_mode_manager.c @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: mode manager implementation. */ + +#include "ptt.h" + +#include "ctrl/ptt_trace.h" +#include "rf/ptt_rf.h" + +#include "ptt_ctrl_internal.h" +#include "ptt_modes.h" + +static enum ptt_ret ptt_mode_init(enum ptt_mode_t mode); + +/* caller should take care about freeing shared resources */ +enum ptt_ret ptt_mode_default_init(void) +{ + enum ptt_mode_t mode = ptt_ctrl_get_default_mode(); + + return ptt_mode_init(mode); +} + +enum ptt_ret ptt_mode_switch(enum ptt_mode_t new_mode) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + uint32_t mode_mask; + + if (new_mode >= PTT_MODE_N) { + PTT_TRACE("%s: invalid new_mode %d\n", __func__, new_mode); + ret = PTT_RET_INVALID_VALUE; + } else { + if (ptt_get_mode_mask_ext(&mode_mask)) { + /* if new_mode isn't allowed */ + if ((mode_mask & (1u << new_mode)) == 0) { + PTT_TRACE("%s: new_mode isn't allowed %d\n", __func__, new_mode); + ret = PTT_RET_INVALID_VALUE; + } + } + } + + if (ret == PTT_RET_SUCCESS) { + ret = ptt_mode_uninit(); + if (ret == PTT_RET_SUCCESS) { + ret = ptt_mode_init(new_mode); + } + } + + return ret; +} + +enum ptt_ret ptt_mode_uninit(void) +{ + enum ptt_mode_t current_mode = ptt_ctrl_get_current_mode(); + enum ptt_ret ret = PTT_RET_SUCCESS; + + switch (current_mode) { + case PTT_MODE_ZB_PERF_DUT: + ret = ptt_zb_perf_dut_mode_uninit(); + break; + + case PTT_MODE_ZB_PERF_CMD: + ret = ptt_zb_perf_cmd_mode_uninit(); + break; + + default: + PTT_TRACE("%s: invalid current_mode %d\n", __func__, current_mode); + ret = PTT_RET_INVALID_MODE; + break; + } + + if (ret == PTT_RET_SUCCESS) { + ptt_timers_reset_all(); + ptt_events_reset_all(); + ptt_ctrl_handlers_reset_all(); + ptt_rf_reset(); + ptt_ctrl_set_current_mode(PTT_MODE_N); + } + + return ret; +} + +/* caller should take care about freeing shared resources */ +static enum ptt_ret ptt_mode_init(enum ptt_mode_t mode) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + switch (mode) { + case PTT_MODE_ZB_PERF_DUT: + ret = ptt_zb_perf_dut_mode_init(); + break; + + case PTT_MODE_ZB_PERF_CMD: + ret = ptt_zb_perf_cmd_mode_init(); + break; + + default: + PTT_TRACE("%s: invalid mode %d\n", __func__, mode); + ret = PTT_RET_INVALID_MODE; + break; + } + + if (ret == PTT_RET_SUCCESS) { + ptt_ctrl_set_current_mode(mode); + } + + return ret; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_modes.h b/samples/peripheral/802154_phy_test/src/ctrl/ptt_modes.h new file mode 100644 index 000000000000..43040e88bc62 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_modes.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: modes declaration intended for usage inside control module */ + +#ifndef PTT_MODES_H__ +#define PTT_MODES_H__ + +#include "ptt_config.h" +#include "ptt_errors.h" +#include "ptt_utils.h" + +/** device modes */ +enum ptt_mode_t { + PTT_MODE_ZB_PERF_DUT = 0, /**< device under test mode */ + PTT_MODE_ZB_PERF_CMD, /**< command mode */ + PTT_MODE_N /**< mode count */ +}; + +/** @brief Switch current mode to a given + * + * Uninitialize current mode, reset shared resources and initialize a new mode. + * If a given mode matches with current mode, current mode resets to state as after initialization. + * + * @param new_mode - a new mode to switch + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_mode_switch(enum ptt_mode_t new_mode); + +/** @brief Initialize default mode + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_mode_default_init(void); + +/** @brief Uninitialize current mode + * + * @param none + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_mode_uninit(void); + +/** @brief Initialize Zigbee RF Performance Test Plan CMD mode + * + * @param none + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_zb_perf_cmd_mode_init(void); + +/** @brief Uninitialize Zigbee RF Performance Test Plan CMD mode + * + * @param none + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_zb_perf_cmd_mode_uninit(void); + +/** @brief Initialize Zigbee RF Performance Test Plan DUT mode + * + * @param none + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_zb_perf_dut_mode_init(void); + +/** @brief Uninitialize Zigbee RF Performance Test Plan DUT mode + * + * @param none + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_zb_perf_dut_mode_uninit(void); + +#endif /* PTT_MODES_H__ */ diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_parser.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_parser.c new file mode 100644 index 000000000000..38883988f270 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_parser.c @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: converting string of ASCII codes to integers */ + +#include "ptt_parser_internal.h" + +#include +#include +#include +#include + +#define PARSER_DECIMAL_BASE 10 +#define PARSER_HEXADECIMAL_BASE 16 +#define PARSER_BASE_NOT_FOUND 0xffu + +static enum ptt_ret ptt_parser_hex_string_next_byte(const char *hex_str, uint8_t *out_num_p); + +enum ptt_ret ptt_parser_string_to_int(const char *str, int32_t *out_value_p, uint8_t base, + int32_t min, int32_t max) +{ + if (str == NULL) { + return PTT_RET_NULL_PTR; + } + + if (out_value_p == NULL) { + return PTT_RET_NULL_PTR; + } + + enum ptt_ret ret = PTT_RET_SUCCESS; + char *end_p; + long out_num = strtol(str, &end_p, base); + + /* "In particular, if *nptr is not '\0' but **endptr is '\0' on return, the entire string + * is valid." <- from man strtol + */ + /* also lets discard LONG_MIN/LONG_MAX values which show strtol failed */ + if (('\0' != *end_p) || (out_num < min) || (out_num > max) || (out_num == LONG_MIN) || + (out_num == LONG_MAX)) { + ret = PTT_RET_INVALID_VALUE; + } else { + *out_value_p = out_num; + } + + return ret; +} + +inline enum ptt_ret ptt_parser_string_to_int32(const char *str, int32_t *out_value, uint8_t base) +{ + return ptt_parser_string_to_int(str, out_value, base, INT32_MIN, INT32_MAX); +} + +inline enum ptt_ret ptt_parser_string_to_byte(const char *str, uint8_t *out_value_p, uint8_t base) +{ + int32_t out_value; + enum ptt_ret ret = ptt_parser_string_to_int(str, &out_value, base, INT8_MIN, UINT8_MAX); + + if (ret == PTT_RET_SUCCESS) { + *out_value_p = out_value; + } + + return ret; +} + +inline enum ptt_ret ptt_parser_string_to_int8(const char *str, int8_t *out_value_p, uint8_t base) +{ + int32_t out_value; + enum ptt_ret ret = ptt_parser_string_to_int(str, &out_value, base, INT8_MIN, INT8_MAX); + + if (ret == PTT_RET_SUCCESS) { + *out_value_p = out_value; + } + + return ret; +} + +inline enum ptt_ret ptt_parser_string_to_uint8(const char *str, uint8_t *out_value_p, uint8_t base) +{ + int32_t out_value; + enum ptt_ret ret = ptt_parser_string_to_int(str, &out_value, base, 0, UINT8_MAX); + + if (ret == PTT_RET_SUCCESS) { + *out_value_p = out_value; + } + + return ret; +} + +inline enum ptt_ret ptt_parser_string_to_int16(const char *str, int16_t *out_value_p, uint8_t base) +{ + int32_t out_value; + enum ptt_ret ret = ptt_parser_string_to_int(str, &out_value, base, INT16_MIN, INT16_MAX); + + if (ret == PTT_RET_SUCCESS) { + *out_value_p = out_value; + } + + return ret; +} + +inline enum ptt_ret ptt_parser_string_to_uint16(const char *str, uint16_t *out_value_p, + uint8_t base) +{ + int32_t out_value; + enum ptt_ret ret = ptt_parser_string_to_int(str, &out_value, base, 0, UINT16_MAX); + + if (ret == PTT_RET_SUCCESS) { + *out_value_p = out_value; + } + + return ret; +} + +enum ptt_ret ptt_parser_hex_string_to_uint8_array(const char *hex_str, uint8_t *out_value_p, + uint8_t max_len, uint8_t *written_len) +{ + if (hex_str == NULL) { + return PTT_RET_NULL_PTR; + } + + if (out_value_p == NULL) { + return PTT_RET_NULL_PTR; + } + + if (max_len == 0) { + return PTT_RET_NO_FREE_SLOT; + } + + /* cut away prefix, if present */ + if ((hex_str[0] == '0') && ((hex_str[1] == 'X') || (hex_str[1] == 'x'))) { + hex_str += 2; + } + + /* one byte is represented by 2 ASCII symbols => we expect even number of elements */ + if ((strlen(hex_str) % 2) || (!strlen(hex_str))) { + return PTT_RET_INVALID_VALUE; + } + + enum ptt_ret ret = PTT_RET_SUCCESS; + uint8_t byte_cnt = 0; + + while ((ret == PTT_RET_SUCCESS) && strlen(hex_str)) { + if (byte_cnt < max_len) { + ret = ptt_parser_hex_string_next_byte(hex_str, &(out_value_p[byte_cnt])); + hex_str += 2; + ++byte_cnt; + } else { + ret = PTT_RET_NO_FREE_SLOT; + } + } + + if (written_len != NULL) { + *written_len = byte_cnt; + } + + return ret; +} + +static enum ptt_ret ptt_parser_hex_string_next_byte(const char *hex_str, uint8_t *out_num_p) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + char hex_byte[3] = { 0 }; + + hex_byte[0] = hex_str[0]; + hex_byte[1] = hex_str[1]; + hex_byte[2] = '\0'; + + char *end_p; + long out_num = strtol(hex_byte, &end_p, PARSER_HEXADECIMAL_BASE); + + /* "In particular, if *nptr is not '\0' but **endptr is '\0' on return, the entire string + * is valid." <- from man strtol + */ + if ((*end_p != '\0') || (out_num < INT8_MIN) || (out_num > UINT8_MAX)) { + ret = PTT_RET_INVALID_VALUE; + } else { + *out_num_p = (uint8_t)out_num; + } + + return ret; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_parser_internal.h b/samples/peripheral/802154_phy_test/src/ctrl/ptt_parser_internal.h new file mode 100644 index 000000000000..2bd621e2c7b1 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_parser_internal.h @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: parser interface intended for usage inside control module */ + +#ifndef PTT_PARSER_INTERNAL_H__ +#define PTT_PARSER_INTERNAL_H__ + +#include "ptt_types.h" +#include "ptt_errors.h" + +/** @brief Converts string to integer and checks upper and lower boundaries + * + * Works with decimal values and hexadecimal values with '0x' or 0X' prefix. + * Will return error if converted value fails boundary check or can not be + * stored in long type. + * + * @param[IN] str - pointer to NULL terminated string + * @param[OUT] out_value - pointer to store out value of procedure + * @param[IN] base - base used in conversion. Zero for auto selection + * @param[IN] min - lower boundary of expected integer + * @param[IN] max - higher boundary of expected integer + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_parser_string_to_int(const char *str, int32_t *out_value, uint8_t base, + int32_t min, int32_t max); + +/** @brief Converts string to uint8_t, will be successful for all value that fit in one byte + * + * This is a wrapper for @ref ptt_parser_string_to_int with min = INT8_MIN and max = UINT8_MAX. + * Used to get one byte from input regardless of it sign. + * + * @param[IN] str - pointer to NULL terminated string + * @param[OUT] out_value - pointer to store out value of procedure + * @param[IN] base - base used in conversion. Zero for auto selection + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_parser_string_to_byte(const char *str, uint8_t *out_value, uint8_t base); + +/** @brief Converts string to int32_t + * + * This is a wrapper for @ref ptt_parser_string_to_int with min = INT32_MIN and max = INT32_MAX. + * + * @param[IN] str - pointer to NULL terminated string + * @param[OUT] out_value - pointer to store out value of procedure + * @param[IN] base - base used in conversion. Zero for auto selection + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_parser_string_to_int32(const char *str, int32_t *out_value, uint8_t base); + +/** @brief Converts string to int8_t + * + * This is a wrapper for @ref ptt_parser_string_to_int with min = INT8_MIN and max = INT8_MAX. + * + * @param[IN] str - pointer to NULL terminated string + * @param[OUT] out_value - pointer to store out value of procedure + * @param[IN] base - base used in conversion. Zero for auto selection + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_parser_string_to_int8(const char *str, int8_t *out_value, uint8_t base); + +/** @brief Converts string to uint8_t + * + * This is a wrapper for @ref ptt_parser_string_to_int with min = 0 and max = UINT8_MAX. + * + * @param[IN] str - pointer to NULL terminated string + * @param[OUT] out_value - pointer to store out value of procedure + * @param[IN] base - base used in conversion. Zero for auto selection + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_parser_string_to_uint8(const char *str, uint8_t *out_value, uint8_t base); + +/** @brief Converts string to int16_t + * + * This is a wrapper for @ref ptt_parser_string_to_int with min = INT16_MIN and max = INT16_MAX. + * + * @param[IN] str - pointer to NULL terminated string + * @param[OUT] out_value - pointer to store out value of procedure + * @param[IN] base - base used in conversion. Zero for auto selection + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_parser_string_to_int16(const char *str, int16_t *out_value, uint8_t base); + +/** @brief Converts string to uint16_t + * + * This is a wrapper for @ref ptt_parser_string_to_int with min = 0 and max = UINT16_MAX. + * + * @param[IN] str - pointer to NULL terminated string + * @param[OUT] out_value - pointer to store out value of procedure + * @param[IN] base - base used in conversion. Zero for auto selection + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_parser_string_to_uint16(const char *str, uint16_t *out_value, uint8_t base); + +/** @brief Converts string of hexadecimal values to array of uint8_t + * + * Detects and cut out prefix '0x' or '0X'. Returns error if string can not be + * stored fully in provided array, has invalid symbols or is empty. + * + * @param[IN] hex_str - pointer to NULL terminated string of hexadecimal values + * @param[OUT] out_value - pointer to allocated array long enough to store max_len values + * @param[IN] max_len - maximum available space in array out_value + * @param[OUT] written_len - pointer to length of converted array, can be NULL, + * contains incorrect value on error + * + * @return enum ptt_ret returns PTT_RET_SUCCESS, or error code + */ +enum ptt_ret ptt_parser_hex_string_to_uint8_array(const char *hex_str, uint8_t *out_value, + uint8_t max_len, uint8_t *written_len); + +#endif /* PTT_PARSER_INTERNAL_H__ */ diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_proto.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_proto.c new file mode 100644 index 000000000000..7dc9c2fd688f --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_proto.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: Protocol processing */ + +#include +#include +#include +#include + +#include "ctrl/ptt_trace.h" + +#include "ptt_proto.h" + +#include "ptt_types.h" + +bool ptt_proto_check_packet(const uint8_t *pkt, ptt_pkt_len_t len) +{ + bool ret = false; + + if ((pkt != NULL) && (len > PTT_PREAMBLE_LEN)) { + if ((pkt[0] == PTT_PREAMBLE_1ST) && (pkt[1] == PTT_PREAMBLE_2ND) && + (pkt[2] == PTT_PREAMBLE_3D)) { + ret = true; + } + } + + return ret; +} + +ptt_pkt_len_t ptt_proto_construct_header(uint8_t *pkt, enum ptt_cmd cmd, ptt_pkt_len_t pkt_max_size) +{ + ptt_pkt_len_t len = 0; + + assert(pkt_max_size >= (PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN)); + + pkt[len] = PTT_PREAMBLE_1ST; + len++; + pkt[len] = PTT_PREAMBLE_2ND; + len++; + pkt[len] = PTT_PREAMBLE_3D; + len++; + pkt[len] = cmd; + len++; + + assert((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN) == len); + + return len; +} + +void ptt_htobe16(uint8_t *src, uint8_t *dst) +{ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + dst[0] = src[1]; + dst[1] = src[0]; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + dst[0] = src[0]; + dst[1] = src[1]; +#else +#error "Unsupported endianness" +#endif +} + +void ptt_htole16(uint8_t *src, uint8_t *dst) +{ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + dst[0] = src[0]; + dst[1] = src[1]; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + dst[0] = src[1]; + dst[1] = src[0]; +#else +#error "Unsupported endianness" +#endif +} + +void ptt_htobe32(uint8_t *src, uint8_t *dst) +{ +#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; +#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + dst[0] = src[0]; + dst[1] = src[1]; + dst[2] = src[2]; + dst[3] = src[3]; +#else +#error "Unsupported endianness" +#endif +} + +void ptt_betoh16(uint8_t *src, uint8_t *dst) +{ + ptt_htobe16(src, dst); +} + +void ptt_betoh32(uint8_t *src, uint8_t *dst) +{ + ptt_htobe32(src, dst); +} + +uint16_t ptt_htobe16_val(uint8_t *src) +{ + uint16_t val = 0; + + ptt_htobe16(src, (uint8_t *)(&val)); + + return val; +} + +uint32_t ptt_htobe32_val(uint8_t *src) +{ + uint32_t val = 0; + + ptt_htobe32(src, (uint8_t *)(&val)); + + return val; +} + +uint16_t ptt_betoh16_val(uint8_t *src) +{ + uint16_t val = 0; + + ptt_betoh16(src, (uint8_t *)(&val)); + + return val; +} + +uint32_t ptt_betoh32_val(uint8_t *src) +{ + uint32_t val = 0; + + ptt_betoh32(src, (uint8_t *)(&val)); + + return val; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_rf_proc.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_rf_proc.c new file mode 100644 index 000000000000..7d71cd99f240 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_rf_proc.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: processing external events from RF */ + +#include + +#include "ptt_ctrl_internal.h" +#include "ptt_events_internal.h" +#include "rf/ptt_rf.h" + +#include "ptt_proto.h" + +#include "ctrl/ptt_trace.h" + +#ifdef TESTS +#include "test_rf_proc_conf.h" +#endif /* TESTS */ + +void ptt_ctrl_rf_tx_started(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_tx_started(); + + if (handler != NULL) { + handler(evt_id); + } else { + ptt_event_free(evt_id); + } + + PTT_TRACE_FUNC_EXIT(); +} + +void ptt_ctrl_rf_tx_finished(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_tx_finished(); + + if (handler != NULL) { + handler(evt_id); + } else { + ptt_event_free(evt_id); + } + + PTT_TRACE_FUNC_EXIT(); +} + +void ptt_ctrl_rf_tx_failed(ptt_evt_id_t evt_id, ptt_rf_tx_error_t tx_error) +{ + PTT_TRACE("%s -> evt %d res %d\n", __func__, evt_id, tx_error); + + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_tx_failed(); + + ptt_event_set_ctx_data(evt_id, PTT_CAST_TO_UINT8_P(&tx_error), sizeof(tx_error)); + + if (handler != NULL) { + handler(evt_id); + } else { + ptt_event_free(evt_id); + } + + PTT_TRACE_FUNC_EXIT(); +} + +void ptt_ctrl_rf_cca_done(ptt_evt_id_t evt_id, bool result) +{ + PTT_TRACE("%s -> evt %d res %d\n", __func__, evt_id, result); + + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_cca_done(); + + ptt_event_set_ctx_data(evt_id, PTT_CAST_TO_UINT8_P(&result), sizeof(result)); + + if (handler != NULL) { + handler(evt_id); + } else { + ptt_event_free(evt_id); + } + + PTT_TRACE_FUNC_EXIT(); +} + +void ptt_ctrl_rf_cca_failed(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_cca_failed(); + + if (handler != NULL) { + handler(evt_id); + } else { + ptt_event_free(evt_id); + } + + PTT_TRACE_FUNC_EXIT(); +} + +void ptt_ctrl_rf_ed_detected(ptt_evt_id_t evt_id, ptt_ed_t result) +{ + PTT_TRACE("%s -> evt %d res %d\n", __func__, evt_id, result); + + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_ed_detected(); + + ptt_event_set_ctx_data(evt_id, PTT_CAST_TO_UINT8_P(&result), sizeof(result)); + + if (handler != NULL) { + handler(evt_id); + } else { + ptt_event_free(evt_id); + } + + PTT_TRACE_FUNC_EXIT(); +} + +void ptt_ctrl_rf_ed_failed(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_ed_failed(); + + if (handler != NULL) { + handler(evt_id); + } else { + ptt_event_free(evt_id); + } + + PTT_TRACE_FUNC_EXIT(); +} + +void ptt_ctrl_rf_push_packet(const uint8_t *pkt, ptt_pkt_len_t len, int8_t rssi, uint8_t lqi) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret; + ptt_evt_id_t evt_id; + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_rx_done(); + + ret = ptt_event_alloc_and_fill(&evt_id, pkt, len); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ptt_event_alloc_and_fill returned error code: %d", __func__, ret); + } else { + struct ptt_rf_packet_info_s pkt_info = { .rssi = rssi, .lqi = lqi }; + + ptt_event_set_ctx_data(evt_id, (uint8_t *)(&pkt_info), sizeof(pkt_info)); + + if (handler != NULL) { + handler(evt_id); + } else { + ptt_event_free(evt_id); + } + } +} + +void ptt_ctrl_rf_rx_failed(ptt_rf_rx_error_t rx_error) +{ + PTT_TRACE("%s -> res %d\n", __func__, rx_error); + + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_rf_rx_failed(); + + if (handler != NULL) { + enum ptt_ret ret; + ptt_evt_id_t evt_id; + + ret = ptt_event_alloc(&evt_id); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ptt_event_alloc returned error code: %d", __func__, ret); + } else { + ptt_event_set_ctx_data(evt_id, PTT_CAST_TO_UINT8_P(&rx_error), + sizeof(rx_error)); + handler(evt_id); + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +#ifdef TESTS +#include "test_rf_proc_wrappers.c" +#endif /* TESTS */ diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_timers.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_timers.c new file mode 100644 index 000000000000..088058a2442e --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_timers.c @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: timers implementation */ + +#include + +#include "ptt.h" + +#include "ctrl/ptt_trace.h" + +#include "ptt_timers_internal.h" + +#ifdef TESTS +#include "test_timers_conf.h" +#else +#include "ptt_ctrl_internal.h" +#endif + +/* Main idea is to keep timeouts bounded to current time and refresh them every + * time when a new timer added or any timer is ended. The nearest timeout is + * selected from all timeouts in the pool and the application timer is called + * with this timeout. It helps to charge the application timer actually only + * when a timer which is closer than already charged one is added and allows + * to keep a pool of timers based on a single application timer. + */ + +static void charge_app_timer(void); +static ptt_time_t get_min_timeout(void); +static void update_timers(ptt_time_t current_time); + +static inline void app_timer_update(ptt_time_t timeout); +static inline ptt_time_t update_timeout(ptt_time_t timeout, ptt_time_t value); +static inline ptt_time_t time_diff(ptt_time_t prev_time, ptt_time_t new_time); + +void ptt_timers_init(void) +{ + PTT_TRACE("%s ->\n", __func__); + + struct ptt_timer_ctx_s *timer_ctx = ptt_ctrl_get_timer_ctx(); + + *timer_ctx = (struct ptt_timer_ctx_s){ 0 }; + timer_ctx->free_slots = PTT_TIMER_POOL_N; + timer_ctx->last_timeout = ptt_ctrl_get_max_time(); + timer_ctx->last_update_time = ptt_ctrl_get_max_time(); + + PTT_TRACE("%s -<\n", __func__); +} + +void ptt_timers_uninit(void) +{ + PTT_TRACE("%s\n", __func__); +} + +void ptt_timers_reset_all(void) +{ + PTT_TRACE("%s ->\n", __func__); + ptt_timers_uninit(); + ptt_timers_init(); + PTT_TRACE("%s -<\n", __func__); +} + +static inline ptt_time_t time_diff(ptt_time_t prev_time, ptt_time_t new_time) +{ + if (prev_time <= new_time) { + return (new_time - prev_time); + } else { + return ((ptt_ctrl_get_max_time() - prev_time) + new_time); + } +} + +static inline void app_timer_update(ptt_time_t timeout) +{ + PTT_TRACE("%s -> %d\n", __func__, timeout); + + struct ptt_timer_ctx_s *timer_ctx = ptt_ctrl_get_timer_ctx(); + + timer_ctx->last_timeout = timeout; + ptt_ctrl_call_me_cb(timeout); + + PTT_TRACE("%s -<\n", __func__); +} + +static inline ptt_time_t update_timeout(ptt_time_t timeout, ptt_time_t value) +{ + if (value > timeout) { + return 0; + } else { + return (timeout - value); + } +} + +void ptt_timers_process(ptt_time_t current_time) +{ + PTT_TRACE("%s -> %d\n", __func__, current_time); + + uint8_t i; + struct ptt_timer_ctx_s *timer_ctx; + + update_timers(current_time); + + timer_ctx = ptt_ctrl_get_timer_ctx(); + + for (i = 0; i < PTT_TIMER_POOL_N; ++i) { + if ((true == timer_ctx->timer_pool[i].use) && + (timer_ctx->timer_pool[i].timeout == 0)) { + if (timer_ctx->timer_pool[i].cb != NULL) { + timer_ctx->timer_pool[i].cb(timer_ctx->timer_pool[i].evt_id); + } + timer_ctx->timer_pool[i] = (struct ptt_timer_s){ 0 }; + timer_ctx->free_slots++; + } + } + + charge_app_timer(); + + PTT_TRACE("%s -<\n", __func__); +} + +enum ptt_ret ptt_timer_add(ptt_time_t timeout, ptt_timer_cb cb, ptt_evt_id_t evt_id) +{ + PTT_TRACE("%s -> tm %d cb %p evt %d\n", __func__, timeout, cb, evt_id); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_timer_s timer = { 0 }; + + if (timeout > ptt_ctrl_get_max_time()) { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + if (cb != NULL) { + timer.cb = cb; + } else { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + if (evt_id < PTT_EVENT_POOL_N) { + timer.evt_id = evt_id; + } else { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + timer.timeout = timeout; + timer.use = true; + + struct ptt_timer_ctx_s *timer_ctx = ptt_ctrl_get_timer_ctx(); + + if (timer_ctx->free_slots == 0) { + ret = PTT_RET_NO_FREE_SLOT; + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; + } + + ptt_time_t current_time = ptt_get_current_time(); + + /* refresh last update time each time when the first timer is added to empty pool + * to have actual time after large delay of update_timers calls + */ + if (timer_ctx->free_slots == PTT_TIMER_POOL_N) { + timer_ctx->last_update_time = current_time; + + /* as pool is empty */ + timer_ctx->timer_pool[0] = timer; + timer_ctx->free_slots--; + + app_timer_update(timer.timeout); + } else { + /* need to bind all previously placed timers to current time to align them with + * timer of adding new timer + */ + /* legend: + * o - time of last binding timers to absolute time (last_update_time) + * c - current time (time of adding the new timer) + * a - time when the application timer will shoot + * t0, t1 - previously added timers + * t2 - new timer + * x0, x1, x2 - timeouts + */ + /* o----c-----a + * |-------------x0 t0 + * |----------x1 t1 + * .....|.......... t2(new) + */ + update_timers(current_time); + /* o----c-----a + * .....|--------x0 t0 + * .....|-----x1 t1 + * .....|.......... t2(new) + */ + + /* add timer to pool */ + for (uint8_t i = 0; i < PTT_TIMER_POOL_N; ++i) { + if (false == timer_ctx->timer_pool[i].use) { + timer_ctx->timer_pool[i] = timer; + timer_ctx->free_slots--; + break; + } + } + /* o----c-----a + * .....|--------x0 t0 + * .....|-----x1 t1 + * .....|----------x2 t2(new) + */ + + /* check is new timer closer than already charged in the application timer */ + /* note: timer.timeout = x2 - c */ + /* note: timer_ctx->last_timeout = x1 - c */ + if (timer_ctx->last_timeout > timer.timeout) { + app_timer_update(timer.timeout); + } + } + + PTT_TRACE("%s -< ret %d\n", __func__, ret); + return ret; +} + +/* if removing timer was going to expire then one of next calls from an application + * will be ptt_timers_process, where timer pool will be updated and new application + * timer will be charged if any timers are running + */ +void ptt_timer_remove(ptt_evt_id_t evt_id) +{ + PTT_TRACE("%s -> evt %d\n", __func__, evt_id); + + uint8_t i; + struct ptt_timer_ctx_s *timer_ctx = ptt_ctrl_get_timer_ctx(); + + for (i = 0; i < PTT_TIMER_POOL_N; ++i) { + if (evt_id == timer_ctx->timer_pool[i].evt_id) { + timer_ctx->timer_pool[i] = (struct ptt_timer_s){ 0 }; + timer_ctx->free_slots += 1; + } + } + + PTT_TRACE("%s -<\n", __func__); +} + +static void charge_app_timer(void) +{ + PTT_TRACE("%s ->\n", __func__); + + ptt_time_t current_time = ptt_get_current_time(); + + update_timers(current_time); + ptt_time_t nearest_timeout = get_min_timeout(); + + app_timer_update(nearest_timeout); + + PTT_TRACE("%s -<\n", __func__); +} + +static ptt_time_t get_min_timeout(void) +{ + PTT_TRACE("%s ->\n", __func__); + + /* @fixme: division by 4 is workaround to update application timer variables + * min_timeout = ptt_ctrl_get_max_time() should be after bug is fixed + */ + ptt_time_t min_timeout = ptt_ctrl_get_max_time() / 4; + struct ptt_timer_ctx_s *timer_ctx = ptt_ctrl_get_timer_ctx(); + uint8_t i; + + for (i = 0; i < PTT_TIMER_POOL_N; ++i) { + if ((true == timer_ctx->timer_pool[i].use) && + (min_timeout > timer_ctx->timer_pool[i].timeout)) { + min_timeout = timer_ctx->timer_pool[i].timeout; + } + } + + PTT_TRACE("%s -< tm %d\n", __func__, min_timeout); + return min_timeout; +} + +static void update_timers(ptt_time_t current_time) +{ + PTT_TRACE("%s -> ct %d\n", __func__, current_time); + + uint8_t i; + struct ptt_timer_ctx_s *timer_ctx = ptt_ctrl_get_timer_ctx(); + + /* calculate time difference */ + ptt_time_t diff = time_diff(timer_ctx->last_update_time, current_time); + + for (i = 0; i < PTT_TIMER_POOL_N; ++i) { + if (true == timer_ctx->timer_pool[i].use) { + timer_ctx->timer_pool[i].timeout = + update_timeout(timer_ctx->timer_pool[i].timeout, diff); + } + } + + timer_ctx->last_timeout = update_timeout(timer_ctx->last_timeout, diff); + timer_ctx->last_update_time = current_time; + + PTT_TRACE("%s -<\n", __func__); +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_timers_internal.h b/samples/peripheral/802154_phy_test/src/ctrl/ptt_timers_internal.h new file mode 100644 index 000000000000..615b3c5dd42a --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_timers_internal.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: timer interface intended for usage inside control module */ + +#ifndef PTT_TIMERS_INTERNAL_H__ +#define PTT_TIMERS_INTERNAL_H__ + +#include "ctrl/ptt_timers.h" + +#include "ptt_config.h" +#include "ptt_types.h" + +/** timer */ +struct ptt_timer_s { + ptt_time_t timeout; /**< timeout, when expires user function will be called */ + ptt_timer_cb cb; /**< function to be called when timer is expired */ + ptt_evt_id_t evt_id; /**< event id which will be passed to user function */ + bool use; /**< flag to determine that timer currently at use */ +}; + +/** context for timer */ +struct ptt_timer_ctx_s { + struct ptt_timer_s timer_pool[PTT_TIMER_POOL_N]; /**< array of timers */ + ptt_time_t last_update_time; /**< time of last update of used timers in the pool */ + ptt_time_t last_timeout; /**< timeout with which call_me_cb was called last time */ + uint8_t free_slots; /**< counter of free slots at timer_pool */ +}; + +/** @brief Initialize timers context + * + * @param none + * + * @return none + */ +void ptt_timers_init(void); + +/** @brief Uninitialize timers context + * + * @param none + * + * @return none + */ +void ptt_timers_uninit(void); + +/** @brief Reset timers context to default values as after initialization + * + * @param none + * + * @return none + */ +void ptt_timers_reset_all(void); + +/** @brief Find expired timers and calls their callbacks from `cb` field + * + * @param current_time - current time, provided by an application, should be no more than max_time + * + * @return none + */ +void ptt_timers_process(ptt_time_t current_time); + +#endif /* PTT_TIMERS_INTERNAL_H__ */ diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_uart_proc.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_uart_proc.c new file mode 100644 index 000000000000..bc0e2175d3b3 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_uart_proc.c @@ -0,0 +1,353 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + *//* Purpose: processing external UART messages */ + +/* We expects a command string looks like "custom ". + * Each whitespace-separated value fits into one byte and payload has big-endian byte order. + * For example: "custom setchannel 0x00 0x00 0x08 0x00" to set 11 channel. + */ + +#include +#include +#include +#include + +#include "ctrl/ptt_ctrl.h" +#include "ctrl/ptt_events.h" +#include "ctrl/ptt_trace.h" +#include "ctrl/ptt_uart.h" + +#include "ptt_proto.h" + +#include "ptt_ctrl_internal.h" +#include "ptt_errors.h" +#include "ptt_events_internal.h" +#include "ptt_modes.h" +#include "ptt_uart_api.h" +#include "ptt_parser_internal.h" + +#ifdef TESTS +#include "test_uart_conf.h" +#endif + +/** array to parse text command */ +static struct uart_text_cmd_s text_cmds[PTT_UART_CMD_N] = { + { UART_CMD_R_PING_TEXT, PTT_UART_CMD_R_PING, UART_CMD_R_PING_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_PING_TIMEOUT_TEXT, PTT_UART_CMD_L_PING_TIMEOUT, + UART_CMD_L_PING_TIMEOUT_PAYLOAD_L, PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_SETCHANNEL_TEXT, PTT_UART_CMD_SETCHANNEL, UART_CMD_SETCHANNEL_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_SETCHANNEL_TEXT, PTT_UART_CMD_L_SETCHANNEL, UART_CMD_L_SETCHANNEL_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_SETCHANNEL_TEXT, PTT_UART_CMD_R_SETCHANNEL, UART_CMD_R_SETCHANNEL_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_CHANNEL_TEXT, PTT_UART_CMD_L_GET_CHANNEL, UART_CMD_L_GET_CHANNEL_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_SET_POWER_TEXT, PTT_UART_CMD_L_SET_POWER, UART_CMD_L_SET_POWER_PAYLOAD_L, + PTT_UART_PAYLOAD_RAW }, + { UART_CMD_R_SET_POWER_TEXT, PTT_UART_CMD_R_SET_POWER, UART_CMD_R_SET_POWER_PAYLOAD_L, + PTT_UART_PAYLOAD_RAW }, + { UART_CMD_L_GET_POWER_TEXT, PTT_UART_CMD_L_GET_POWER, UART_CMD_L_GET_POWER_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_GET_POWER_TEXT, PTT_UART_CMD_R_GET_POWER, UART_CMD_R_GET_POWER_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_STREAM_TEXT, PTT_UART_CMD_R_STREAM, UART_CMD_R_STREAM_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_START_TEXT, PTT_UART_CMD_R_START, UART_CMD_R_START_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_END_TEXT, PTT_UART_CMD_R_END, UART_CMD_R_END_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_REBOOT_TEXT, PTT_UART_CMD_L_REBOOT, UART_CMD_L_REBOOT_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_FIND_TEXT, PTT_UART_CMD_FIND, UART_CMD_FIND_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_HW_VERSION_TEXT, PTT_UART_CMD_R_HW_VERSION, UART_CMD_R_HW_VERSION_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_SW_VERSION_TEXT, PTT_UART_CMD_R_SW_VERSION, UART_CMD_R_SW_VERSION_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_CHANGE_MODE_TEXT, PTT_UART_CMD_CHANGE_MODE, UART_CMD_CHANGE_MODE_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_CCA_TEXT, PTT_UART_CMD_L_GET_CCA, UART_CMD_L_GET_CCA_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_ED_TEXT, PTT_UART_CMD_L_GET_ED, UART_CMD_L_GET_ED_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_LQI_TEXT, PTT_UART_CMD_L_GET_LQI, UART_CMD_L_GET_LQI_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_RSSI_TEXT, PTT_UART_CMD_L_GET_RSSI, UART_CMD_L_GET_RSSI_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_SET_SHORT_TEXT, PTT_UART_CMD_L_SET_SHORT, UART_CMD_L_SET_SHORT_PAYLOAD_L, + PTT_UART_PAYLOAD_RAW }, + { UART_CMD_L_SET_EXTENDED_TEXT, PTT_UART_CMD_L_SET_EXTENDED, + UART_CMD_L_SET_EXTENDED_PAYLOAD_L, PTT_UART_PAYLOAD_RAW }, + { UART_CMD_L_SET_PAN_ID_TEXT, PTT_UART_CMD_L_SET_PAN_ID, UART_CMD_L_SET_PAN_ID_PAYLOAD_L, + PTT_UART_PAYLOAD_RAW }, + { UART_CMD_L_SET_PAYLOAD_TEXT, PTT_UART_CMD_L_SET_PAYLOAD, UART_CMD_L_SET_PAYLOAD_PAYLOAD_L, + PTT_UART_PAYLOAD_RAW }, + { UART_CMD_L_START_TEXT, PTT_UART_CMD_L_START, UART_CMD_L_START_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_END_TEXT, PTT_UART_CMD_L_END, UART_CMD_L_END_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_SET_ANTENNA_TEXT, PTT_UART_CMD_L_SET_ANTENNA, UART_CMD_L_SET_ANTENNA_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_ANTENNA_TEXT, PTT_UART_CMD_L_GET_ANTENNA, UART_CMD_L_GET_ANTENNA_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_SET_ANTENNA_TEXT, PTT_UART_CMD_R_SET_ANTENNA, UART_CMD_R_SET_ANTENNA_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_R_GET_ANTENNA_TEXT, PTT_UART_CMD_R_GET_ANTENNA, UART_CMD_R_GET_ANTENNA_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_TX_END_TEXT, PTT_UART_CMD_L_TX_END, UART_CMD_L_TX_END_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_TX_TEXT, PTT_UART_CMD_L_TX, UART_CMD_L_TX_PAYLOAD_L, PTT_UART_PAYLOAD_RAW }, + { UART_CMD_L_CLK_TEXT, PTT_UART_CMD_L_CLK, UART_CMD_L_CLK_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_SET_GPIO_TEXT, PTT_UART_CMD_L_SET_GPIO, UART_CMD_L_SET_GPIO_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_GPIO_TEXT, PTT_UART_CMD_L_GET_GPIO, UART_CMD_L_GET_GPIO_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_CARRIER_TEXT, PTT_UART_CMD_L_CARRIER, UART_CMD_L_CARRIER_PAYLOAD_L, + PTT_UART_PAYLOAD_RAW }, + { UART_CMD_L_STREAM_TEXT, PTT_UART_CMD_L_STREAM, UART_CMD_L_STREAM_PAYLOAD_L, + PTT_UART_PAYLOAD_RAW }, + { UART_CMD_L_SET_DCDC_TEXT, PTT_UART_CMD_L_SET_DCDC, UART_CMD_L_SET_DCDC_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_DCDC_TEXT, PTT_UART_CMD_L_GET_DCDC, UART_CMD_L_GET_DCDC_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_SET_ICACHE_TEXT, PTT_UART_CMD_L_SET_ICACHE, UART_CMD_L_SET_ICACHE_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_ICACHE_TEXT, PTT_UART_CMD_L_GET_ICACHE, UART_CMD_L_GET_ICACHE_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_GET_TEMP_TEXT, PTT_UART_CMD_L_GET_TEMP, UART_CMD_L_GET_TEMP_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_INDICATION_TEXT, PTT_UART_CMD_L_INDICATION, UART_CMD_L_INDICATION_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_SLEEP_TEXT, PTT_UART_CMD_L_SLEEP, UART_CMD_L_SLEEP_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, + { UART_CMD_L_RECEIVE_TEXT, PTT_UART_CMD_L_RECEIVE, UART_CMD_L_RECEIVE_PAYLOAD_L, + PTT_UART_PAYLOAD_PARSED_AS_BYTES }, +}; + +static ptt_uart_send_cb uart_send_cb; + +static bool handler_busy; + +static enum ptt_ret packet_parser(ptt_evt_id_t evt_id); +static enum ptt_ret text_cmd_parser(ptt_evt_id_t evt_id); +static enum ptt_ret payload_fill(struct ptt_evt_ctx_data_s *ctx_data, char *payload, uint8_t len); + +void ptt_uart_init(ptt_uart_send_cb send_cb) +{ + uart_send_cb = send_cb; + ptt_uart_print_prompt(); +} + +void ptt_uart_uninit(void) +{ + uart_send_cb = NULL; +} + +inline void ptt_uart_print_prompt(void) +{ + if (uart_send_cb != NULL) { + uart_send_cb(PTT_CAST_TO_UINT8_P(PTT_UART_PROMPT_STR), + sizeof(PTT_UART_PROMPT_STR) - 1, false); + } +} + +enum ptt_ret ptt_uart_send_packet(const uint8_t *pkt, ptt_pkt_len_t len) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if ((pkt == NULL) || (len == 0)) { + ret = PTT_RET_INVALID_VALUE; + } + + if (ret == PTT_RET_SUCCESS) { + if (uart_send_cb == NULL) { + ret = PTT_RET_NULL_PTR; + } else { + int32_t size = uart_send_cb(pkt, len, true); + + if (size != len) { + ret = PTT_RET_BUSY; + } + } + } + + PTT_TRACE("%s: ret %d", __func__, ret); + return ret; +} + +void ptt_uart_push_packet(const uint8_t *pkt, ptt_pkt_len_t len) +{ + ptt_evt_id_t evt_id; + enum ptt_ret ret; + + if ((pkt == NULL) || (len == 0)) { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s: invalid input value", __func__); + } else { + ret = ptt_event_alloc_and_fill(&evt_id, pkt, len); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ptt_event_alloc_and_fill return error code: %d", __func__, + ret); + } else { + ret = packet_parser(evt_id); + } + } + + /* to prevent sending prompt on invalid command + * when handler is busy processing previous command + */ + if ((ret != PTT_RET_SUCCESS) && !handler_busy) { + ptt_uart_print_prompt(); + } +} + +/* @todo: refactor to let handler return result being busy */ +void ptt_handler_busy(void) +{ + handler_busy = true; +} + +void ptt_handler_free(void) +{ + handler_busy = false; +} + +static enum ptt_ret packet_parser(ptt_evt_id_t evt_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + ptt_ext_evt_handler handler = ptt_ctrl_get_handler_uart_pkt_received(); + + ret = text_cmd_parser(evt_id); + + if (ret == PTT_RET_SUCCESS) { + if (ptt_event_get_cmd(evt_id) == PTT_UART_CMD_CHANGE_MODE) { + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + ret = ptt_mode_switch(ctx_data->arr[0]); + + ptt_uart_print_prompt(); + + ptt_event_free(evt_id); + } else if (handler == NULL) { + ret = PTT_RET_INVALID_MODE; + ptt_event_free(evt_id); + } else { + handler(evt_id); + } + } else { + ptt_event_free(evt_id); + } + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("packet parser ended with error code: %u", ret); + } + + return ret; +} + +/* fills evt_id with command and its parameters or return error */ +static enum ptt_ret text_cmd_parser(ptt_evt_id_t evt_id) +{ + uint8_t str; + uint8_t i; + size_t cmd_name_len; + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_data_s *data = ptt_event_get_data(evt_id); + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(data != NULL); + assert(ctx_data != NULL); + + for (i = 0; i < PTT_UART_CMD_N; ++i) { + cmd_name_len = strlen(text_cmds[i].name); + + /* compare without '\0' symbol */ + str = strncmp(PTT_CAST_TO_STR(data->arr), text_cmds[i].name, cmd_name_len); + + if (str != 0) { + ret = PTT_RET_INVALID_VALUE; + } else { + if (text_cmds[i].payload_type == PTT_UART_PAYLOAD_RAW) { + /* raw payload already written in data, just pass */ + ret = PTT_RET_SUCCESS; + } else if (text_cmds[i].payload_type == PTT_UART_PAYLOAD_PARSED_AS_BYTES) { + /* after a command should be only whitespace + * in case of payload or \0 + */ + if ((data->arr[cmd_name_len] == '\0') || + (data->arr[cmd_name_len] == ' ')) { + char *payload = PTT_CAST_TO_STR(data->arr + cmd_name_len); + + ret = payload_fill(ctx_data, payload, + text_cmds[i].payload_len); + } else { + ret = PTT_RET_INVALID_VALUE; + } + } else { + ret = PTT_RET_INVALID_VALUE; + } + + if (ret == PTT_RET_SUCCESS) { + ptt_event_set_cmd(evt_id, text_cmds[i].code); + } + + /* we found command name, time to quit */ + break; + } + } + + return ret; +} + +/* payload points to payload of text cmd */ +static enum ptt_ret payload_fill(struct ptt_evt_ctx_data_s *ctx_data, char *payload, uint8_t len) +{ + if ((payload == NULL) || (ctx_data == NULL)) { + return PTT_RET_INVALID_VALUE; + } + + enum ptt_ret ret = PTT_RET_SUCCESS; + static char *save; + char *next_word = strtok_r(payload, UART_TEXT_PAYLOAD_DELIMETERS, &save); + + for (uint8_t i = 0; i < len; ++i) { + if (next_word == NULL) { + /* expected more words in payload */ + ret = PTT_RET_INVALID_VALUE; + break; + } + + uint8_t out_num; + + /* signed values are processed in their handlers */ + ret = ptt_parser_string_to_uint8(next_word, &out_num, 0); + + if (ret != PTT_RET_SUCCESS) { + break; + } + + if (ctx_data->len >= PTT_EVENT_CTX_SIZE) { + ret = PTT_RET_INVALID_VALUE; + break; + } + + ctx_data->arr[ctx_data->len] = out_num; + ++(ctx_data->len); + + next_word = strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save); + } + + if (next_word != NULL) { + ret = PTT_RET_INVALID_VALUE; + } + + return ret; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode.c new file mode 100644 index 000000000000..51af8106e6b3 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: implementation of Zigbee RF Performance Test Plan CMD mode */ + +#include "ctrl/ptt_trace.h" + +#include "ptt_ctrl_internal.h" +#include "ptt_modes.h" +#include "ptt_zb_perf_cmd_mode.h" + +enum ptt_ret ptt_zb_perf_cmd_mode_init(void) +{ + PTT_TRACE("%s ->\n", __func__); + + cmd_ota_cmd_init(); + cmd_uart_cmd_init(); + + struct ptt_ext_evts_handlers_s *handlers = ptt_ctrl_get_handlers(); + + handlers->rf_tx_finished = cmd_rf_tx_finished; + handlers->rf_tx_failed = cmd_rf_tx_failed; + handlers->rf_rx_done = cmd_rf_rx_done; + handlers->rf_rx_failed = cmd_rf_rx_failed; + handlers->uart_pkt_received = cmd_uart_pkt_received; + handlers->rf_cca_done = cmd_rf_cca_done; + handlers->rf_cca_failed = cmd_rf_cca_failed; + handlers->rf_ed_detected = cmd_rf_ed_detected; + handlers->rf_ed_failed = cmd_rf_ed_failed; + + PTT_TRACE("%s -<\n", __func__); + return PTT_RET_SUCCESS; +} + +enum ptt_ret ptt_zb_perf_cmd_mode_uninit(void) +{ + PTT_TRACE("%s ->\n", __func__); + + cmd_ota_cmd_uninit(); + cmd_uart_cmd_uninit(); + + PTT_TRACE("%s -<\n", __func__); + return PTT_RET_SUCCESS; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode.h b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode.h new file mode 100644 index 000000000000..7884ce94c125 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode.h @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: implementation of Zigbee RF Performance Test Plan CMD mode */ + +#ifndef PTT_MODE_ZB_PERF_CMD_H__ +#define PTT_MODE_ZB_PERF_CMD_H__ + +#include + +#include "ctrl/ptt_ctrl.h" +#include "ctrl/ptt_events.h" +#include "ctrl/ptt_timers.h" +#include "ctrl/ptt_uart.h" + +#include "ptt_errors.h" +#include "ptt_config.h" +#include "ptt_utils.h" + +#define PTT_PING_ERROR_MES "NO ACK" +#define PTT_PING_SUCCESS_MES "ACK" +#define PTT_GET_POWER_ERROR_MES "NO POWER RESPONSE" +#define PTT_END_RX_TEST_ERROR_MES "NO REPORT" +#define PTT_GET_HARDWARE_ERROR_MES "NO HW VERSION RESPONSE" +#define PTT_GET_SOFTWARE_ERROR_MES "NO SW VERSION RESPONSE" +#define PTT_FIND_ERROR_MES "DUT NOT FOUND" +#define PTT_GET_CCA_SUCCESS_MES "CCA:" /* note: value will be added in response function */ +#define PTT_GET_CCA_ERROR_MES "CCA FAILED" +#define PTT_GET_ED_SUCCESS_MES "ED:" /* note: value will be added in response function */ +#define PTT_GET_ED_ERROR_MES "ED FAILED" +#define PTT_GET_RSSI_SUCCESS_MES "RSSI:" /* note: value will be added in response function */ +#define PTT_GET_RSSI_ERROR_MES "RSSI FAILED" +#define PTT_GET_LQI_SUCCESS_MES "LQI:" /* note: value will be added in response function */ +#define PTT_GET_LQI_ERROR_MES "LQI:ERROR" +#define PTT_GET_ANTENNA_MES "ANTENNA:" /* note: value will be added in response function */ +#define PTT_GET_ANTENNA_ERROR_MES "NO ANTENNA RESPONSE" +#define PTT_L_TX_NO_ACK_MES "NO ACK" +#define PTT_L_TX_CRC_ERROR_MES "CRC ERROR" +#define PTT_L_TX_ERROR_MES "TX ERROR" +#define PTT_L_START_CRC_ERROR_MES "CRC ERROR" +#define PTT_L_START_ERROR_MES "RX ERROR" +#define PTT_GET_DCDC_MES "DCDC:" /* note: value will be added in response function */ +#define PTT_GET_ICACHE_MES "ICACHE:" /* note: value will be added in response function */ + +/** states of OTA commands processing in CMD mode */ +enum cmd_ota_state_t { + CMD_OTA_STATE_IDLE = 0, /**< waiting for next command */ + CMD_OTA_STATE_PING_SENDING, /**< rf module send ping command */ + CMD_OTA_STATE_PING_WAITING_FOR_ACK, /**< ping sent, waiting for ack */ + CMD_OTA_STATE_SET_CHANNEL_SENDING, /**< rf module send set_channel command */ + CMD_OTA_STATE_SET_POWER_SENDING, /**< rf module send set_power command */ + CMD_OTA_STATE_STREAM_SENDING, /**< rf module send stream command */ + CMD_OTA_STATE_START_RX_TEST_SENDING, /**< cmd send start rx test command to dut */ + CMD_OTA_STATE_GET_POWER_SENDING, /**< rf module send get_power command */ + CMD_OTA_STATE_GET_POWER_WAITING_FOR_RSP, /**< get_power sent, waiting for response */ + CMD_OTA_STATE_END_RX_TEST_SENDING, /**< rf module send end_rx_test command */ + CMD_OTA_STATE_END_RX_TEST_WAITING_FOR_REPORT, /**< end_rx_test sent, waiting for report */ + CMD_OTA_STATE_GET_HARDWARE_SENDING, /**< rf module send get hardware command */ + CMD_OTA_STATE_GET_HARDWARE_WAITING_FOR_RSP, /**< get hardware sent, waiting for response*/ + CMD_OTA_STATE_GET_SOFTWARE_SENDING, /**< rf module send get software command */ + CMD_OTA_STATE_GET_SOFTWARE_WAITING_FOR_RSP, /**< get software sent, waiting for response*/ + CMD_OTA_STATE_SET_ANTENNA_SENDING, /**< rf module send set_antenna command */ + CMD_OTA_STATE_GET_ANTENNA_SENDING, /**< rf module send get_antenna command */ + CMD_OTA_STATE_GET_ANTENNA_WAITING_FOR_RSP, /**< get_antenna sent, waiting for response */ + CMD_OTA_STATE_N + /**< Total number of OTA command processing states */ +}; + +/** states of uart command processing in CMD mode */ +enum cmd_uart_state_t { + CMD_UART_STATE_IDLE = 0, + /**< waiting for next command */ + CMD_UART_STATE_SET_CHANNEL, + /**< CMD device set channel on DUT */ + CMD_UART_STATE_STREAM, + /**< CMD device processes enable stream on DUT */ + CMD_UART_STATE_WAIT_DELAY, + /**< CMD is waiting for delay */ + CMD_UART_STATE_PING, + /**< CMD device processes ping command */ + CMD_UART_STATE_WAITING_FOR_LEND, + /**< CMD device in continuous receive mode and will accepts only "custom lend" command */ + CMD_UART_STATE_WAITING_FOR_RF_PACKET, + /**< CMD device in continuous receive mode waiting for reception of any rf packet */ + CMD_UART_STATE_LTX_WAITING_FOR_ACK, + /**< CMD device in continuous receive mode waiting for reception of ACK rf packet */ + CMD_UART_STATE_LTX, + /**< CMD device processes ltx command */ + CMD_UART_STATE_L_CLK_OUT, + /**< CMD device is waiting for disabling CLK output mode */ + CMD_UART_STATE_L_CARRIER_INTERVAL, + /**< CMD device processing lcarrier command and radio is in receiving mode */ + CMD_UART_STATE_L_CARRIER_PULSE, + /**< CMD device processing lcarrier command and sending continuous carrier */ + CMD_UART_STATE_L_STREAM_INTERVAL, + /**< CMD device processing lstream command and radio is in receiving mode */ + CMD_UART_STATE_L_STREAM_PULSE, + /**< CMD device processing lstream command and sending modulated carrier */ + CMD_UART_STATE_N + /**< Total number of UART command processing states */ +}; + +/* information for "custom ltx" command */ +struct cmd_uart_ltx_info_s { + bool is_infinite; + bool is_stop_requested; + uint8_t repeats_cnt; + uint8_t max_repeats_cnt; + uint8_t ack_cnt; + uint16_t timeout; +}; + +PTT_COMPILE_TIME_ASSERT(sizeof(struct cmd_uart_ltx_info_s) <= PTT_EVENT_CTX_SIZE); + +/* information for "custom lcarrier" command */ +struct cmd_uart_waveform_timings_s { + int32_t pulse_duration; + int32_t interval; +}; + +PTT_COMPILE_TIME_ASSERT(sizeof(struct cmd_uart_waveform_timings_s) <= PTT_EVENT_CTX_SIZE); + +/** @brief Initialize OTA commands processing module in CMD mode + * + * @param none + * + * @return none + */ +void cmd_ota_cmd_init(void); + +/** @brief Uninitialize OTA commands processing module in CMD mode + * + * @param none + * + * @return none + */ +void cmd_ota_cmd_uninit(void); + +/** @brief Process new OTA command + * + * @param none + * + * @return none + */ +enum ptt_ret cmd_ota_cmd_process(ptt_evt_id_t new_ota_cmd); + +/** @brief Notify OTA modyle about "RX done" event + * + * @param new_rf_pkt_evt - event containing the received packet. + * + * @return none + */ +void cmd_ota_rf_rx_done(ptt_evt_id_t new_rf_pkt_evt); + +/** @brief Notify OTA mode about "TX finished" event. + * + * @param evt_id - expects to be the same as the event passed to ptt_rf_send_packet() + * + * @return none + */ +void cmd_ota_rf_tx_finished(ptt_evt_id_t evt_id); + +/** @brief Notify OTA mode about "TX failed" event. + * + * @param evt_id - expects to be the same as the event passed to ptt_rf_send_packet() + * + * @return none + */ +void cmd_ota_rf_tx_failed(ptt_evt_id_t evt_id); + +/** @brief Handler for "TX finished" event. + * + * @param evt_id - expects to be the same as the event passed to ptt_rf_send_packet() + * + * @return none + */ +void cmd_rf_tx_finished(ptt_evt_id_t evt_id); + +/** @brief Handler for "TX failed" event. + * + * @param evt_id - expects to be the same as the event passed to ptt_rf_send_packet() + * + * @return none + */ +void cmd_rf_tx_failed(ptt_evt_id_t evt_id); + +/** @brief Handler for new received RF packet + * + * @param new_rf_pkt_evt - new event containing the received packet. + * Handler is responsible for freeing the event. + * + * @return none + */ +void cmd_rf_rx_done(ptt_evt_id_t new_rf_pkt_evt); + +/** @brief Handler for "RX failed" event. + * + * @param evt_id - new event containing the error code of reception fail. + * Handler is responsible for freeing the event. + * + * @return none + */ +void cmd_rf_rx_failed(ptt_evt_id_t evt_id); + +/** @brief Initialize UART commands processing module in CMD mode + * + * @param none + * + * @return none + */ +void cmd_uart_cmd_init(void); + +/** @brief Uninitialize UART commands processing module in CMD mode + * + * @param none + * + * @return none + */ +void cmd_uart_cmd_uninit(void); + +/** @brief Handler for new received UART packet + * + * @param new_uart_cmd - new event containing the received UART packet. + * Handler is responsible for freeing the event. + * + * @return none + */ +void cmd_uart_pkt_received(ptt_evt_id_t new_uart_cmd); + +/** @brief Handler for "CCA done" event + * + * @evt_id - event same as used for uart module locking. + * Contains CCA result in context. + * Handler is responsible for freeing the event. + * + * @return none + */ +void cmd_rf_cca_done(ptt_evt_id_t evt_id); + +/** @brief Handler for "CCA failed" event + * + * @evt_id - event same as used for uart module locking. + * Handler is responsible for freeing the event. + * + * @return none + */ +void cmd_rf_cca_failed(ptt_evt_id_t evt_id); + +/** @brief Handler for "ED detected" event + * + * @evt_id - event same as used for uart module locking. + * Contains ED result in context. + * Handler is responsible for freeing the event. + * + * @return none + */ +void cmd_rf_ed_detected(ptt_evt_id_t evt_id); + +/** @brief Handler for "ED failed" event + * + * @evt_id - event same as used for uart module locking. + * Handler is responsible for freeing the event. + * + * @return none + */ +void cmd_rf_ed_failed(ptt_evt_id_t evt_id); + +/** @brief Handler for OTA command failed result such as timeouts and errors + * + * @param evt_id - expects to be the same as the event passed to cmd_ota_cmd_process() + * + * @return none + */ +void cmt_uart_ota_cmd_timeout_notify(ptt_evt_id_t evt_id); + +/** @brief Handler for OTA command success result with the response in the context if expected + * + * @param evt_id - expects to be the same as the event passed to cmd_ota_cmd_process() + * + * @return none + */ +void cmt_uart_ota_cmd_finish_notify(ptt_evt_id_t evt_id); + +/* Send responses through UART. Responses use passed event as memory + * for storing prepared UART packet. + * If payload is expected in context it will be extracted and processed. + * It depends on UART command. + */ +/* Sends ACK response through UART */ +void cmd_uart_send_rsack(ptt_evt_id_t evt_id); +/* Sends NO ACK response through UART */ +void cmd_uart_send_rsp_no_ack(ptt_evt_id_t evt_id); +/* Sends current CMD channel through UART */ +void cmd_uart_send_rsp_l_channel(ptt_evt_id_t evt_id); +/* Sends NO POWER RESPONSE through UART */ +void cmd_uart_send_rsp_power_error(ptt_evt_id_t evt_id); +/* Sends DUT power through UART */ +void cmd_uart_send_rsp_power(ptt_evt_id_t evt_id); +/* Sends NO REPORT through UART */ +void cmd_uart_send_rsp_rx_test_error(ptt_evt_id_t evt_id); +/* Sends RX test report through UART */ +void cmd_uart_send_rsp_rx_test(ptt_evt_id_t evt_id); +/* Sends NO HW VERSION through UART */ +void cmd_uart_send_rsp_hw_error(ptt_evt_id_t evt_id); +/* Sends HW version through UART */ +void cmd_uart_send_rsp_hw(ptt_evt_id_t evt_id); +/* Sends NO SW VERSION through UART */ +void cmd_uart_send_rsp_sw_error(ptt_evt_id_t evt_id); +/* Sends SW version through UART */ +void cmd_uart_send_rsp_sw(ptt_evt_id_t evt_id); +/* Sends found DUT channel through UART */ +void cmd_uart_send_rsp_find(ptt_evt_id_t evt_id); +/* Sends DUT NOT FOUND through UART */ +void cmd_uart_send_rsp_find_timeout(ptt_evt_id_t evt_id); +/* Sends CCA FAILED through UART */ +void cmd_uart_send_rsp_cca_failed(ptt_evt_id_t evt_id); +/* Sends CCA result through UART */ +void cmd_uart_send_rsp_cca_done(ptt_evt_id_t evt_id); +/* Sends ED FAILED through UART */ +void cmd_uart_send_rsp_ed_failed(ptt_evt_id_t evt_id); +/* Sends ED result through UART */ +void cmd_uart_send_rsp_ed_detected(ptt_evt_id_t evt_id); +/* Sends RSSI FAILED through UART */ +void cmd_uart_send_rsp_rssi_failed(ptt_evt_id_t evt_id); +/* Sends RSSI result through UART */ +void cmd_uart_send_rsp_rssi_done(ptt_evt_id_t evt_id); +/* Sends new packet report through UART */ +void cmd_uart_send_rsp_l_start_new_packet(ptt_evt_id_t new_rf_pkt_evt); +/* Sends report about received packet from previous call to lstart */ +void cmd_uart_send_rsp_l_end(ptt_evt_id_t evt_id, uint32_t proto_pkts); +/* Sends LQI FAILED through UART */ +void cmd_uart_send_rsp_lqi_failed(ptt_evt_id_t evt_id); +/* Sends LQI result through UART */ +void cmd_uart_send_rsp_lqi_done(ptt_evt_id_t evt_id); +/* Sends current antenna through UART */ +void cmd_uart_send_rsp_antenna(ptt_evt_id_t evt_id); +/* Sends NO ANTENNA RESPONSE through UART */ +void cmd_uart_send_rsp_antenna_error(ptt_evt_id_t evt_id); +/* Sends NO ACK through UART */ +void cmd_uart_send_rsp_ltx_failed(ptt_evt_id_t evt_id); +/* Sends ack packet through UART */ +void cmd_uart_send_rsp_ltx_ack(ptt_evt_id_t evt_id, uint32_t packet_n); +/* Sends new packet reception fail report through UART */ +void cmd_uart_send_rsp_l_start_rx_fail(ptt_evt_id_t new_rf_pkt_evt); +/* Sends GPIO pin value through UART */ +void cmd_uart_send_rsp_l_get_gpio(ptt_evt_id_t evt_id); +/* Sends GPIO pin reading error through UART */ +void cmd_uart_send_rsp_l_get_gpio_error(ptt_evt_id_t evt_id); +/* Sends SoC temperature through UART */ +void cmd_uart_send_rsp_get_temp(ptt_evt_id_t evt_id); +/* Sends current DCDC mode through UART */ +void cmd_uart_send_rsp_get_dcdc(ptt_evt_id_t evt_id); +/* Sends current state of ICACHE through UART */ +void cmd_uart_send_rsp_get_icache(ptt_evt_id_t evt_id); + +#endif /* PTT_MODE_ZB_PERF_CMD_H__ */ diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_ota.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_ota.c new file mode 100644 index 000000000000..a673ca00d5b2 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_ota.c @@ -0,0 +1,820 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: OTA commands processing of Zigbee RF Performance Test Plan CMD mode */ + +/* The module processes an event containing OTA command from UART module and + * returns the event with result. The event locks the module as currently processed OTA command + * and the module rejects any other commands while processing the one. + */ + +#include +#include +#include + +#include "ctrl/ptt_trace.h" +#include "rf/ptt_rf.h" + +#include "ptt_proto.h" + +#include "ptt_ctrl_internal.h" +#include "ptt_events_internal.h" +#include "ptt_modes.h" +#include "ptt_zb_perf_cmd_mode.h" + +#ifdef TESTS +#include "test_cmd_ota_conf.h" +#endif + +/** currently processed OTA command */ +static ptt_evt_id_t ota_cmd_evt; + +/* current event handlers */ +static enum ptt_ret cmd_ota_cmd_proc(void); +static enum ptt_ret cmd_set_channel(void); +static enum ptt_ret cmd_set_power(void); +static enum ptt_ret cmd_ping(void); +static void cmd_ping_sent(void); +static enum ptt_ret cmd_get_power(void); +static void cmd_get_power_sent(void); +static enum ptt_ret cmd_end_rx_test(void); +static void cmd_end_rx_test_sent(void); +static enum ptt_ret cmd_get_hardware_version(void); +static void cmd_get_hardware_sent(void); +static enum ptt_ret cmd_get_software_version(void); +static void cmd_get_software_sent(void); +static enum ptt_ret cmd_stream(void); +static enum ptt_ret cmd_start_rx_test(void); +static enum ptt_ret cmd_set_antenna(void); +static enum ptt_ret cmd_get_antenna(void); +static void cmd_get_antenna_sent(void); + +/* timer handlers */ +static void cmd_ping_timeout(ptt_evt_id_t timer_evt_id); +static void cmd_get_power_timeout(ptt_evt_id_t timer_evt_id); +static void cmd_end_rx_test_timeout(ptt_evt_id_t timer_evt_id); +static void cmd_get_hardware_timeout(ptt_evt_id_t timer_evt_id); +static void cmd_get_software_timeout(ptt_evt_id_t timer_evt_id); +static void cmd_get_antenna_timeout(ptt_evt_id_t timer_evt_id); + +/* new rf packets processing */ +static void cmd_ping_ack(ptt_evt_id_t new_rf_pkt_evt); +static void cmd_get_power_response(ptt_evt_id_t new_rf_pkt_evt); +static void cmd_end_rx_test_report(ptt_evt_id_t new_rf_pkt_evt); +static void cmd_get_hardware_response(ptt_evt_id_t new_rf_pkt_evt); +static void cmd_get_software_response(ptt_evt_id_t new_rf_pkt_evt); +static void cmd_get_antenna_response(ptt_evt_id_t new_rf_pkt_evt); + +/* notifications for UART command processing */ +static void cmd_fill_ctx_end_and_reset(const uint8_t *data, ptt_pkt_len_t len); +static void cmd_send_finish_and_reset(void); +static void cmd_send_timeout_and_reset(void); + +static enum ptt_ret cmd_make_and_send_rf_packet(enum ptt_cmd cmd); + +/* OTA command lock routines */ +static inline void cmd_ota_cmd_lock(ptt_evt_id_t new_ota_cmd); +static inline void cmd_change_ota_cmd_state(ptt_evt_state_t state); +static inline ptt_evt_id_t cmd_get_ota_cmd_and_reset(void); +static inline bool cmd_is_ota_cmd_locked(void); +static inline bool cmd_is_ota_cmd_locked_by(ptt_evt_id_t evt_id); +static void cmd_ota_cmd_unlock(void); + +#ifdef TESTS +#include "test_cmd_ota_wrappers.c" +#endif + +void cmd_ota_cmd_init(void) +{ + cmd_ota_cmd_unlock(); +} + +void cmd_ota_cmd_uninit(void) +{ + cmd_ota_cmd_unlock(); +} + +enum ptt_ret cmd_ota_cmd_process(ptt_evt_id_t new_ota_cmd) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (false == cmd_is_ota_cmd_locked()) { + /* store event as currently processed OTA command */ + cmd_ota_cmd_lock(new_ota_cmd); + ret = cmd_ota_cmd_proc(); + if (ret != PTT_RET_SUCCESS) { + cmd_ota_cmd_unlock(); + } + } else { + PTT_TRACE("%s: state isn't idle cmd %d state %d\n", __func__, + ptt_event_get_cmd(ota_cmd_evt), ptt_event_get_state(ota_cmd_evt)); + ret = PTT_RET_BUSY; + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_ota_cmd_proc(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + enum ptt_cmd cmd = ptt_event_get_cmd(ota_cmd_evt); + + PTT_TRACE("%s: cmd %d\n", __func__, cmd); + + switch (ptt_event_get_cmd(ota_cmd_evt)) { + case PTT_CMD_PING: + ret = cmd_ping(); + break; + + case PTT_CMD_SET_CHANNEL: + ret = cmd_set_channel(); + break; + + case PTT_CMD_SET_POWER: + ret = cmd_set_power(); + break; + + case PTT_CMD_GET_POWER: + ret = cmd_get_power(); + break; + + case PTT_CMD_STREAM: + ret = cmd_stream(); + break; + + case PTT_CMD_START_RX_TEST: + ret = cmd_start_rx_test(); + break; + + case PTT_CMD_END_RX_TEST: + ret = cmd_end_rx_test(); + break; + + case PTT_CMD_GET_HARDWARE_VERSION: + ret = cmd_get_hardware_version(); + break; + + case PTT_CMD_GET_SOFTWARE_VERSION: + ret = cmd_get_software_version(); + break; + + case PTT_CMD_SET_ANTENNA: + ret = cmd_set_antenna(); + break; + + case PTT_CMD_GET_ANTENNA: + ret = cmd_get_antenna(); + break; + + default: + PTT_TRACE("%s: unknown command cmd %d\n", __func__, cmd); + ret = PTT_RET_INVALID_COMMAND; + break; + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +void cmd_ota_rf_tx_finished(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + assert(true == cmd_is_ota_cmd_locked_by(evt_id)); + + PTT_TRACE("%s: cmd %d state %d\n", __func__, ptt_event_get_cmd(ota_cmd_evt), + ptt_event_get_state(ota_cmd_evt)); + + switch (ptt_event_get_state(ota_cmd_evt)) { + case CMD_OTA_STATE_PING_SENDING: + cmd_ping_sent(); + break; + + case CMD_OTA_STATE_SET_CHANNEL_SENDING: + case CMD_OTA_STATE_SET_POWER_SENDING: + case CMD_OTA_STATE_STREAM_SENDING: + case CMD_OTA_STATE_START_RX_TEST_SENDING: + case CMD_OTA_STATE_SET_ANTENNA_SENDING: + cmd_send_finish_and_reset(); + break; + + case CMD_OTA_STATE_GET_POWER_SENDING: + cmd_get_power_sent(); + break; + + case CMD_OTA_STATE_END_RX_TEST_SENDING: + cmd_end_rx_test_sent(); + break; + + case CMD_OTA_STATE_GET_HARDWARE_SENDING: + cmd_get_hardware_sent(); + break; + + case CMD_OTA_STATE_GET_SOFTWARE_SENDING: + cmd_get_software_sent(); + break; + + case CMD_OTA_STATE_GET_ANTENNA_SENDING: + cmd_get_antenna_sent(); + break; + + default: + PTT_TRACE("%s: inappropriate state cmd %d state %d\n", __func__, + ptt_event_get_cmd(ota_cmd_evt), ptt_event_get_state(ota_cmd_evt)); + break; + } + + PTT_TRACE_FUNC_EXIT(); +} + +void cmd_ota_rf_tx_failed(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + assert(true == cmd_is_ota_cmd_locked_by(evt_id)); + + PTT_TRACE("%s: cmd %d state %d\n", __func__, ptt_event_get_cmd(ota_cmd_evt), + ptt_event_get_state(ota_cmd_evt)); + + switch (ptt_event_get_state(ota_cmd_evt)) { + case CMD_OTA_STATE_PING_SENDING: + case CMD_OTA_STATE_SET_CHANNEL_SENDING: + case CMD_OTA_STATE_SET_POWER_SENDING: + case CMD_OTA_STATE_GET_POWER_SENDING: + case CMD_OTA_STATE_STREAM_SENDING: + case CMD_OTA_STATE_START_RX_TEST_SENDING: + case CMD_OTA_STATE_END_RX_TEST_SENDING: + case CMD_OTA_STATE_GET_HARDWARE_SENDING: + case CMD_OTA_STATE_GET_SOFTWARE_SENDING: + case CMD_OTA_STATE_SET_ANTENNA_SENDING: + case CMD_OTA_STATE_GET_ANTENNA_SENDING: + cmd_send_timeout_and_reset(); + break; + + default: + PTT_TRACE("%s: inappropriate state cmd %d state %d\n", __func__, + ptt_event_get_cmd(ota_cmd_evt), ptt_event_get_state(ota_cmd_evt)); + break; + } + + PTT_TRACE_FUNC_EXIT(); +} + +void cmd_ota_rf_rx_done(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + if (false == cmd_is_ota_cmd_locked()) { + PTT_TRACE("%s unexpected packet for idle state ignored\n", __func__); + } else { + struct ptt_evt_data_s *evt_data = ptt_event_get_data(new_rf_pkt_evt); + + assert(evt_data != NULL); + + if (!ptt_proto_check_packet(evt_data->arr, evt_data->len)) { + PTT_TRACE("%s not protocol packet received and ignored\n", __func__); + } else { + PTT_TRACE("%s: protocol packet received. Current cmd %d state %d\n", + __func__, ptt_event_get_cmd(ota_cmd_evt), + ptt_event_get_state(ota_cmd_evt)); + + ptt_event_set_cmd(new_rf_pkt_evt, evt_data->arr[PTT_CMD_CODE_START]); + + switch (ptt_event_get_state(ota_cmd_evt)) { + case CMD_OTA_STATE_PING_WAITING_FOR_ACK: + cmd_ping_ack(new_rf_pkt_evt); + break; + + case CMD_OTA_STATE_GET_POWER_WAITING_FOR_RSP: + cmd_get_power_response(new_rf_pkt_evt); + break; + + case CMD_OTA_STATE_END_RX_TEST_WAITING_FOR_REPORT: + cmd_end_rx_test_report(new_rf_pkt_evt); + break; + + case CMD_OTA_STATE_GET_HARDWARE_WAITING_FOR_RSP: + cmd_get_hardware_response(new_rf_pkt_evt); + break; + + case CMD_OTA_STATE_GET_SOFTWARE_WAITING_FOR_RSP: + cmd_get_software_response(new_rf_pkt_evt); + break; + + case CMD_OTA_STATE_GET_ANTENNA_WAITING_FOR_RSP: + cmd_get_antenna_response(new_rf_pkt_evt); + break; + + default: + PTT_TRACE("%s: inappropriate state cmd %d state %d\n", __func__, + ptt_event_get_cmd(ota_cmd_evt), + ptt_event_get_state(ota_cmd_evt)); + break; + } + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_ping(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_PING_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_PING); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_ping_timeout(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_ota_cmd_locked_by(timer_evt_id)); + + cmd_send_timeout_and_reset(); + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_ping_sent(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = ptt_timer_add(ptt_ctrl_get_rsp_timeout(), cmd_ping_timeout, ota_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_ota_cmd_state(CMD_OTA_STATE_PING_WAITING_FOR_ACK); + } else { + PTT_TRACE("%s: add_timer return error code: %d\n", __func__, ret); + cmd_send_timeout_and_reset(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_ping_ack(ptt_evt_id_t new_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_evt_id); + + if (ptt_event_get_cmd(new_evt_id) == PTT_CMD_ACK) { + ptt_timer_remove(ota_cmd_evt); + + uint8_t result = 1; + + cmd_fill_ctx_end_and_reset(&result, sizeof(result)); + } else { + PTT_TRACE("%s: command is not ACK\n", __func__); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_set_channel(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_SET_CHANNEL_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_SET_CHANNEL); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_set_power(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_SET_POWER_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_SET_POWER); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_get_power(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_GET_POWER_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_GET_POWER); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_get_power_timeout(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_ota_cmd_locked_by(timer_evt_id)); + + cmd_send_timeout_and_reset(); + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_get_power_sent(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = + ptt_timer_add(ptt_ctrl_get_rsp_timeout(), cmd_get_power_timeout, ota_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_ota_cmd_state(CMD_OTA_STATE_GET_POWER_WAITING_FOR_RSP); + } else { + PTT_TRACE("%s: add_timer return error code: %d\n", __func__, ret); + cmd_send_timeout_and_reset(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_get_power_response(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(new_rf_pkt_evt); + + assert(evt_data != NULL); + + if ((ptt_event_get_cmd(new_rf_pkt_evt) == PTT_CMD_GET_POWER_RESPONSE) && + ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_GET_POWER) == evt_data->len)) { + ptt_timer_remove(ota_cmd_evt); + + cmd_fill_ctx_end_and_reset(&evt_data->arr[PTT_PAYLOAD_START], + PTT_PAYLOAD_LEN_GET_POWER); + } else { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_set_antenna(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_SET_ANTENNA_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_SET_ANTENNA); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_get_antenna(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_GET_ANTENNA_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_GET_ANTENNA); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_get_antenna_timeout(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_ota_cmd_locked_by(timer_evt_id)); + + cmd_send_timeout_and_reset(); + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_get_antenna_sent(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = + ptt_timer_add(ptt_ctrl_get_rsp_timeout(), cmd_get_antenna_timeout, ota_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_ota_cmd_state(CMD_OTA_STATE_GET_ANTENNA_WAITING_FOR_RSP); + } else { + PTT_TRACE("%s: add_timer return error code: %d\n", __func__, ret); + cmd_send_timeout_and_reset(); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static void cmd_get_antenna_response(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(new_rf_pkt_evt); + + assert(evt_data != NULL); + + if ((ptt_event_get_cmd(new_rf_pkt_evt) == PTT_CMD_GET_ANTENNA_RESPONSE) && + ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_GET_ANTENNA) == + evt_data->len)) { + ptt_timer_remove(ota_cmd_evt); + + cmd_fill_ctx_end_and_reset(&evt_data->arr[PTT_PAYLOAD_START], + PTT_PAYLOAD_LEN_GET_ANTENNA); + } else { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_end_rx_test(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_END_RX_TEST_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_END_RX_TEST); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_end_rx_test_timeout(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_ota_cmd_locked_by(timer_evt_id)); + + cmd_send_timeout_and_reset(); + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_end_rx_test_sent(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = + ptt_timer_add(ptt_ctrl_get_rsp_timeout(), cmd_end_rx_test_timeout, ota_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_ota_cmd_state(CMD_OTA_STATE_END_RX_TEST_WAITING_FOR_REPORT); + } else { + PTT_TRACE("%s: add_timer return error code: %d\n", __func__, ret); + cmd_send_timeout_and_reset(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_end_rx_test_report(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_EXIT_WITH_VALUE(new_rf_pkt_evt); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(new_rf_pkt_evt); + + assert(evt_data != NULL); + + if ((ptt_event_get_cmd(new_rf_pkt_evt) == PTT_CMD_REPORT) && + ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_REPORT) == evt_data->len)) { + ptt_timer_remove(ota_cmd_evt); + + cmd_fill_ctx_end_and_reset(&evt_data->arr[PTT_PAYLOAD_START], + PTT_PAYLOAD_LEN_REPORT); + } else { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_get_hardware_version(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_GET_HARDWARE_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_GET_HARDWARE_VERSION); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_get_hardware_timeout(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER(); + + assert(true == cmd_is_ota_cmd_locked_by(timer_evt_id)); + + cmd_send_timeout_and_reset(); + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_get_hardware_sent(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = + ptt_timer_add(ptt_ctrl_get_rsp_timeout(), cmd_get_hardware_timeout, ota_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_ota_cmd_state(CMD_OTA_STATE_GET_HARDWARE_WAITING_FOR_RSP); + } else { + PTT_TRACE("%s: add_timer return error code: %d\n", __func__, ret); + cmd_send_timeout_and_reset(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_get_hardware_response(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(new_rf_pkt_evt); + + assert(evt_data != NULL); + + if ((ptt_event_get_cmd(new_rf_pkt_evt) == PTT_CMD_GET_HARDWARE_VERSION_RESPONSE) && + ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_GET_HARDWARE) == + evt_data->len)) { + ptt_timer_remove(ota_cmd_evt); + + cmd_fill_ctx_end_and_reset(&evt_data->arr[PTT_PAYLOAD_START], + PTT_PAYLOAD_LEN_GET_HARDWARE); + } else { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_get_software_version(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_GET_SOFTWARE_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_GET_SOFTWARE_VERSION); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_get_software_timeout(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_ota_cmd_locked_by(timer_evt_id)); + + cmd_send_timeout_and_reset(); + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_get_software_sent(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = + ptt_timer_add(ptt_ctrl_get_rsp_timeout(), cmd_get_software_timeout, ota_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_ota_cmd_state(CMD_OTA_STATE_GET_SOFTWARE_WAITING_FOR_RSP); + } else { + PTT_TRACE("%s: add_timer return error code: %d\n", __func__, ret); + cmd_send_timeout_and_reset(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_get_software_response(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(new_rf_pkt_evt); + + assert(evt_data != NULL); + + if ((ptt_event_get_cmd(new_rf_pkt_evt) == PTT_CMD_GET_SOFTWARE_VERSION_RESPONSE) && + ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_GET_SOFTWARE) == + evt_data->len)) { + ptt_timer_remove(ota_cmd_evt); + + cmd_fill_ctx_end_and_reset(&evt_data->arr[PTT_PAYLOAD_START], + PTT_PAYLOAD_LEN_GET_SOFTWARE); + } else { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_stream(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_STREAM_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_STREAM); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_start_rx_test(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_ota_cmd_state(CMD_OTA_STATE_START_RX_TEST_SENDING); + enum ptt_ret ret = cmd_make_and_send_rf_packet(PTT_CMD_START_RX_TEST); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static inline void cmd_ota_cmd_lock(ptt_evt_id_t new_ota_cmd) +{ + assert(ota_cmd_evt == PTT_EVENT_UNASSIGNED); + + ota_cmd_evt = new_ota_cmd; +} + +static inline void cmd_change_ota_cmd_state(ptt_evt_state_t state) +{ + PTT_TRACE("%s: %d", __func__, state); + + ptt_event_set_state(ota_cmd_evt, state); +} + +static inline ptt_evt_id_t cmd_get_ota_cmd_and_reset(void) +{ + ptt_evt_id_t evt_id = ota_cmd_evt; + + cmd_ota_cmd_unlock(); + return evt_id; +} + +static void cmd_ota_cmd_unlock(void) +{ + ota_cmd_evt = PTT_EVENT_UNASSIGNED; +} + +static inline bool cmd_is_ota_cmd_locked(void) +{ + return (ota_cmd_evt == PTT_EVENT_UNASSIGNED) ? false : true; +} + +static inline bool cmd_is_ota_cmd_locked_by(ptt_evt_id_t evt_id) +{ + return (evt_id == ota_cmd_evt) ? true : false; +} + +static void cmd_fill_ctx_end_and_reset(const uint8_t *data, ptt_pkt_len_t len) +{ + ptt_event_set_ctx_data(ota_cmd_evt, data, len); + cmd_send_finish_and_reset(); +} + +static void cmd_send_finish_and_reset(void) +{ + ptt_evt_id_t evt_id = cmd_get_ota_cmd_and_reset(); + + cmt_uart_ota_cmd_finish_notify(evt_id); +} + +static void cmd_send_timeout_and_reset(void) +{ + ptt_evt_id_t evt_id = cmd_get_ota_cmd_and_reset(); + + cmt_uart_ota_cmd_timeout_notify(evt_id); +} + +static enum ptt_ret cmd_make_and_send_rf_packet(enum ptt_cmd cmd) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_data_s *evt_data = ptt_event_get_data(ota_cmd_evt); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(ota_cmd_evt); + + assert(ctx_data != NULL); + + evt_data->len = ptt_proto_construct_header(evt_data->arr, cmd, PTT_EVENT_DATA_SIZE); + + if (evt_data->len != (PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN)) { + ret = PTT_RET_INVALID_VALUE; + } else { + memcpy(&evt_data->arr[evt_data->len], ctx_data->arr, ctx_data->len); + evt_data->len += ctx_data->len; + + ret = ptt_rf_send_packet(ota_cmd_evt, evt_data->arr, evt_data->len); + } + + return ret; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_response.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_response.c new file mode 100644 index 000000000000..ca0d20dee730 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_response.c @@ -0,0 +1,475 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: UART response constructing for Zigbee RF Performance Test Plan CMD mode */ + +#include +#include +#include +#include + +#include "ctrl/ptt_trace.h" +#include "ctrl/ptt_uart.h" +#include "rf/ptt_rf.h" + +#include "ptt_proto.h" + +#include "ptt_ctrl_internal.h" +#include "ptt_events_internal.h" +#include "ptt_zb_perf_cmd_mode.h" + +#if defined(CMD_UART_UNIT_TEST) +#include "test_cmd_uart_conf.h" +#elif defined(CMD_RESPONSE_UNIT_TEST) +#include "test_cmd_response_conf.h" +#endif + +#define CMD_UART_BUF 320 + +static void cmd_uart_send_rf_packet_with_num(ptt_evt_id_t new_rf_pkt_evt, uint32_t packet_n); + +void cmd_uart_send_rsp_get_icache(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), PTT_GET_ICACHE_MES "%d", ctx_data->arr[0]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_get_dcdc(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), PTT_GET_DCDC_MES "%d", ctx_data->arr[0]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_get_temp(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "%d", *(int32_t *)ctx_data->arr); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_antenna_error(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_GET_ANTENNA_ERROR_MES), + sizeof(PTT_GET_ANTENNA_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_antenna(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), PTT_GET_ANTENNA_MES "%d", ctx_data->arr[0]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +static void cmd_uart_send_rf_packet_with_num(ptt_evt_id_t new_rf_pkt_evt, uint32_t packet_n) +{ + struct ptt_evt_data_s *rf_evt_data = ptt_event_get_data(new_rf_pkt_evt); + + assert(rf_evt_data != NULL); + + struct ptt_evt_ctx_data_s *rf_ctx_data = ptt_event_get_ctx_data(new_rf_pkt_evt); + + assert(rf_ctx_data != NULL); + + char out_str[CMD_UART_BUF] = { 0 }; + struct ptt_rf_packet_info_s *pkt_info = (struct ptt_rf_packet_info_s *)(rf_ctx_data->arr); + + sprintf(out_str, "C:%d L:%d Data:", packet_n, rf_evt_data->len); + + uint16_t filled_length = strlen(out_str); + + /* we have each byte coded as two ASCII symbols */ + if ((rf_evt_data->len * 2) < (CMD_UART_BUF - filled_length)) { + for (int i = 0; i < rf_evt_data->len; ++i) { + uint8_t lst = rf_evt_data->arr[i] & 0x0F; + uint8_t mst = (rf_evt_data->arr[i] >> 4) & 0x0F; + + out_str[filled_length + 2 * i] = (mst >= 0xA) ? mst - 0xA + 'A' : mst + '0'; + out_str[filled_length + 2 * i + 1] = + (lst >= 0xA) ? lst - 0xA + 'A' : lst + '0'; + } + + /* let's use rf_evt_data as temporary buffer, as we copied everything from there */ + sprintf(PTT_CAST_TO_STR(rf_evt_data->arr), " CRC:1 LQI:0x%02x RSSI:%d", + pkt_info->lqi, pkt_info->rssi); + + /* concatenate everything together */ + if ((filled_length + rf_evt_data->len * 2 + + strlen(PTT_CAST_TO_STR(rf_evt_data->arr)) + sizeof('\0')) <= CMD_UART_BUF) { + strcat(out_str, PTT_CAST_TO_STR(rf_evt_data->arr)); + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(out_str), strlen(out_str)); + } else { + PTT_TRACE("%s: response string is too long\n", __func__); + } + } else { + PTT_TRACE("%s: there is not enough space to convert the array into ASCII\n", + __func__); + } +} + +void cmd_uart_send_rsp_ltx_ack(ptt_evt_id_t evt_id, uint32_t packet_n) +{ + cmd_uart_send_rf_packet_with_num(evt_id, packet_n); +} + +void cmd_uart_send_rsp_l_start_new_packet(ptt_evt_id_t new_rf_pkt_evt) +{ + struct ptt_rf_stat_s stat = ptt_rf_get_stat_report(); + + cmd_uart_send_rf_packet_with_num(new_rf_pkt_evt, stat.total_pkts); +} + +void cmd_uart_send_rsp_l_start_rx_fail(ptt_evt_id_t new_rf_pkt_evt) +{ + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(new_rf_pkt_evt); + + assert(ctx_data != NULL); + + ptt_rf_rx_error_t rx_error = *(ptt_rf_rx_error_t *)ctx_data->arr; + + if (rx_error == PTT_RF_RX_ERROR_INVALID_FCS) { + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_L_START_CRC_ERROR_MES), + sizeof(PTT_L_START_CRC_ERROR_MES) - 1); + } else { + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_L_START_ERROR_MES), + sizeof(PTT_L_START_ERROR_MES) - 1); + } +} + +void cmd_uart_send_rsp_l_end(ptt_evt_id_t evt_id, uint32_t proto_pkts) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_rf_stat_s stat = ptt_rf_get_stat_report(); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "0x%08x 0x%08x 0x%08x 0x%08x", stat.total_pkts, + proto_pkts, stat.total_lqi, stat.total_rssi); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_lqi_failed(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_GET_LQI_ERROR_MES), + sizeof(PTT_GET_LQI_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_lqi_done(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + struct ptt_rf_packet_info_s *pkt_info = (struct ptt_rf_packet_info_s *)(ctx_data->arr); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), PTT_GET_LQI_SUCCESS_MES "0x%04x", pkt_info->lqi); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_ltx_failed(ptt_evt_id_t evt_id) +{ + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + ptt_rf_tx_error_t tx_error = *(ptt_rf_tx_error_t *)ctx_data->arr; + + switch (tx_error) { + case PTT_RF_TX_ERROR_INVALID_ACK_FCS: + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_L_TX_CRC_ERROR_MES), + sizeof(PTT_L_TX_CRC_ERROR_MES) - 1); + break; + + case PTT_RF_TX_ERROR_NO_ACK: + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_L_TX_NO_ACK_MES), + sizeof(PTT_L_TX_NO_ACK_MES) - 1); + break; + + default: + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_L_TX_ERROR_MES), + sizeof(PTT_L_TX_ERROR_MES) - 1); + break; + } +} + +void cmd_uart_send_rsp_rssi_done(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), PTT_GET_RSSI_SUCCESS_MES "%d", + *(ptt_rssi_t *)ctx_data->arr); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_rssi_failed(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_GET_RSSI_ERROR_MES), + sizeof(PTT_GET_RSSI_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_ed_detected(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), PTT_GET_ED_SUCCESS_MES "0x%04x", + *(ptt_ed_t *)ctx_data->arr); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_ed_failed(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_GET_ED_ERROR_MES), + sizeof(PTT_GET_ED_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_cca_done(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), PTT_GET_CCA_SUCCESS_MES "%d", + *(bool *)ctx_data->arr); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_cca_failed(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_GET_CCA_ERROR_MES), + sizeof(PTT_GET_CCA_ERROR_MES) - 1); +} + +void cmd_uart_send_rsack(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_PING_SUCCESS_MES), + sizeof(PTT_PING_SUCCESS_MES) - 1); +} + +void cmd_uart_send_rsp_no_ack(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_PING_ERROR_MES), + sizeof(PTT_PING_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_l_channel(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "%d", ctx_data->arr[0]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_power_error(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_GET_POWER_ERROR_MES), + sizeof(PTT_GET_POWER_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_power(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + /* @todo: figure out where to find mode */ + uint16_t mode = 0xffff; + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "0x%04x 0x%02x", mode, ctx_data->arr[0]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_rx_test_error(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_END_RX_TEST_ERROR_MES), + sizeof(PTT_END_RX_TEST_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_rx_test(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), + "0x%02x%02x%02x%02x 0x%02x%02x%02x%02x 0x%02x%02x%02x%02x 0x%02x%02x%02x%02x", + ctx_data->arr[0], ctx_data->arr[1], ctx_data->arr[2], ctx_data->arr[3], + ctx_data->arr[4], ctx_data->arr[5], ctx_data->arr[6], ctx_data->arr[7], + ctx_data->arr[8], ctx_data->arr[9], ctx_data->arr[10], ctx_data->arr[11], + ctx_data->arr[12], ctx_data->arr[13], ctx_data->arr[14], ctx_data->arr[15]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_hw_error(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_GET_HARDWARE_ERROR_MES), + sizeof(PTT_GET_HARDWARE_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_hw(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "0x%02x", ctx_data->arr[0]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_sw_error(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_GET_SOFTWARE_ERROR_MES), + sizeof(PTT_GET_SOFTWARE_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_sw(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "0x%02x", ctx_data->arr[0]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_find(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + uint32_t mask = ptt_betoh32_val(ctx_data->arr); + + uint8_t channel = ptt_rf_convert_channel_mask_to_num(mask); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "channel %d find ack", channel); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_find_timeout(ptt_evt_id_t evt_id) +{ + ptt_uart_send_packet(PTT_CAST_TO_UINT8_P(PTT_FIND_ERROR_MES), + sizeof(PTT_FIND_ERROR_MES) - 1); +} + +void cmd_uart_send_rsp_l_get_gpio(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "PIN %d: %d", ctx_data->arr[0], ctx_data->arr[1]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} + +void cmd_uart_send_rsp_l_get_gpio_error(ptt_evt_id_t evt_id) +{ + struct ptt_evt_data_s *evt_data = ptt_event_get_data(evt_id); + + assert(evt_data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(evt_id); + + assert(ctx_data != NULL); + + sprintf(PTT_CAST_TO_STR(evt_data->arr), "PIN %d: ERROR", ctx_data->arr[0]); + + ptt_uart_send_packet(evt_data->arr, strlen(PTT_CAST_TO_STR(evt_data->arr))); +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_uart.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_uart.c new file mode 100644 index 000000000000..39bd9bb32621 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_cmd_mode_uart.c @@ -0,0 +1,2736 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: UART processing of Zigbee RF Performance Test Plan CMD mode */ + +/* The module processes an event containing UART command. The event locks the module as + * currently processed UART command and the module rejects any other UART commands while + * processing the one. + * The module allocates event for OTA cmd, passes it to OTA cmd processing module, + * gets it back with result and then frees the event. + */ + +#include +#include +#include + +#include "ptt.h" + +#include "ctrl/ptt_trace.h" +#include "ctrl/ptt_uart.h" +#include "rf/ptt_rf.h" + +#include "ptt_proto.h" +#include "ptt_config.h" + +#include "ptt_ctrl_internal.h" +#include "ptt_events_internal.h" +#include "ptt_parser_internal.h" +#include "ptt_zb_perf_cmd_mode.h" + +#ifdef TESTS +#include "test_cmd_uart_conf.h" +#endif + +/** currently processed UART command */ +static ptt_evt_id_t uart_cmd_evt; + +/** @brief: Event for "custom lindicate" command + * + * Used as: + * 1. Event to arm timer; + * 2. Command state: validity of it value will tell is led indication currently active; + * 3. Storage: all command related information will be stored in it context. + */ +static ptt_evt_id_t led_indication_evt; + +static void cmd_uart_idle_packet_proc(void); + +static enum ptt_ret cmd_uart_call_ota_cmd(enum ptt_cmd cmd, const struct ptt_evt_ctx_data_s *ctx); + +static enum ptt_ret cmd_uart_parse_waveform_timings(const uint8_t *uart_cmd_payload, + int32_t *pulse_duration, int32_t *interval, + int32_t *duration_p); + +/* "find" command routines */ +static enum ptt_ret cmd_uart_find_idle(void); +static void cmd_uart_find_channel_was_set(void); +static void cmd_uart_find_delay(ptt_evt_id_t timer_evt_id); +static void cmd_uart_find_send_set_channel(void); +static void cmd_uart_find_process_finish(ptt_evt_id_t ota_cmd_evt); +static void cmd_uart_find_process_timeout(ptt_evt_id_t ota_cmd_evt); + +/* "setchannel" command routines */ +static enum ptt_ret cmd_uart_set_channel(void); +static void cmd_uart_set_channel_was_set(void); +static void cmd_uart_set_channel_delay(ptt_evt_id_t timer_evt_id); +static void cmd_uart_set_channel_process_timeout(ptt_evt_id_t ota_cmd_evt); +static void cmd_uart_set_channel_process_finish(ptt_evt_id_t ota_cmd_evt); +static enum ptt_ret cmd_uart_set_channel_payload_check(void); + +/* "lsetchannel" command routine */ +static enum ptt_ret cmd_uart_l_set_channel(void); + +/* "rsetchannel" command routine */ +static enum ptt_ret cmd_uart_r_set_channel(void); + +/* "lgetchannel" command routine */ +static enum ptt_ret cmd_uart_l_get_channel(void); + +/* "lsetpower" command routine */ +static enum ptt_ret cmd_uart_l_set_power(void); +static enum ptt_ret parse_power(const uint8_t *uart_cmd_payload, uint16_t *mode, int8_t *power_p); + +/* "lsetpanid" command routine */ +static enum ptt_ret cmd_uart_l_set_pan_id(void); + +/* "lsetextended" command routine */ +static enum ptt_ret cmd_uart_l_set_extended_address(void); + +/* "lsetshort" command routine */ +static enum ptt_ret cmd_uart_l_set_short_address(void); + +/* "lsetpayload" command routine */ +static enum ptt_ret cmd_uart_l_set_payload(void); + +/* "rsetpower" command routine */ +static enum ptt_ret cmd_uart_r_set_power(void); + +/* "lgetpower" command routine */ +static enum ptt_ret cmd_uart_l_get_power(void); + +/* "lpingtimeout" command routine */ +static enum ptt_ret cmd_uart_l_ping_timeout(void); + +/* "lgetcca" command routine*/ +static enum ptt_ret cmd_uart_l_get_cca(void); + +/* "lgeted" command routine*/ +static enum ptt_ret cmd_uart_l_get_ed(void); + +/* "lgetrssi" command routine */ +static enum ptt_ret cmd_uart_l_get_rssi(void); +static void cmd_uart_l_get_rssi_delay(ptt_evt_id_t timer_evt_id); + +/* "lstart" command routine */ +static enum ptt_ret cmd_uart_l_start(void); +static void cmd_uart_l_start_process_rf_packet(ptt_evt_id_t new_rf_pkt_evt); + +/* "lend" command routine */ +static void cmd_uart_l_end(ptt_evt_id_t new_uart_cmd); + +/* "lgetlqi" command routine */ +static enum ptt_ret cmd_uart_l_get_lqi(void); +static void cmd_uart_l_get_lqi_delay(ptt_evt_id_t timer_evt_id); +static void cmd_uart_l_get_lqi_process_rf_packet(ptt_evt_id_t new_rf_pkt_evt); + +/* "lsetantenna" command routine */ +static enum ptt_ret cmd_uart_l_set_antenna(void); + +/* "lgetantenna" command routine */ +static enum ptt_ret cmd_uart_l_get_antenna(void); + +/* "rsetantenna" command routine */ +static enum ptt_ret cmd_uart_r_set_antenna(void); + +/* "ltx" command routine */ +static enum ptt_ret cmd_uart_l_tx(void); +static void cmd_uart_l_tx_process_next_packet(void); +static void cmd_uart_l_tx_delay(ptt_evt_id_t timer_evt_id); +static void cmd_uart_l_tx_process_ack(ptt_evt_id_t evt_id); +static void cmd_uart_l_tx_finished(ptt_evt_id_t evt_id); +static void cmd_uart_l_tx_failed(ptt_evt_id_t evt_id); +static void cmd_uart_l_tx_end(ptt_evt_id_t new_uart_cmd); + +/* "lclk" command routine */ +static enum ptt_ret cmd_uart_l_clk(void); +static void cmd_uart_l_clk_stop(ptt_evt_id_t new_uart_cmd); + +/* "lsetgpio" command routine */ +static enum ptt_ret cmd_uart_l_set_gpio(void); + +/* "lgetgpio" command routine */ +static enum ptt_ret cmd_uart_l_get_gpio(void); + +/* "lcarrier" command routine */ +static enum ptt_ret cmd_uart_l_carrier(void); +static void cmd_uart_l_carrier_duration_delay(ptt_evt_id_t timer_evt_id); +static void cmd_uart_l_carrier_pulse_delay(ptt_evt_id_t timer_evt_id); +static void cmd_uart_l_carrier_interval_delay(ptt_evt_id_t timer_evt_id); + +/* "lstream" command routine */ +static enum ptt_ret cmd_uart_l_stream(void); +static void cmd_uart_l_stream_duration_delay(ptt_evt_id_t timer_evt_id); +static void cmd_uart_l_stream_pulse_delay(ptt_evt_id_t timer_evt_id); +static void cmd_uart_l_stream_interval_delay(ptt_evt_id_t timer_evt_id); +static enum ptt_ret cmd_uart_l_stream_start(void); + +/* "lsetdcdc" command routine */ +static enum ptt_ret cmd_uart_l_set_dcdc(void); + +/* "lgetdcdc" command routine */ +static enum ptt_ret cmd_uart_l_get_dcdc(void); + +/* "lseticache" command routine */ +static enum ptt_ret cmd_uart_l_set_icache(void); + +/* "lgeticache" command routine */ +static enum ptt_ret cmd_uart_l_get_icache(void); + +/* "lgettemp" command routine */ +static enum ptt_ret cmd_uart_l_get_temp(void); + +/* "lindication" command routine */ +static enum ptt_ret cmd_uart_l_indication(void); +static void cmd_uart_l_indication_off(ptt_evt_id_t evt_id); + +void cmd_uart_l_indication_proc(void); + +/* "lsleep" command routine */ +static enum ptt_ret cmd_uart_l_sleep(void); + +/* "lreceive" command routine */ +static enum ptt_ret cmd_uart_l_receive(void); + +/* UART command lock routines */ +static inline void cmd_uart_cmd_lock(ptt_evt_id_t new_uart_cmd); +static inline void cmd_change_uart_cmd_state(ptt_evt_state_t state); +static inline bool cmd_is_uart_cmd_locked(void); +static inline bool cmd_is_uart_cmd_locked_by(ptt_evt_id_t evt_id); +static void cmd_uart_cmd_unlock(void); + +#ifdef TESTS +#include "test_cmd_uart_wrappers.c" +#endif + +void cmd_uart_cmd_init(void) +{ + uart_cmd_evt = PTT_EVENT_UNASSIGNED; + led_indication_evt = PTT_EVENT_UNASSIGNED; +} + +void cmd_uart_cmd_uninit(void) +{ + cmd_uart_cmd_unlock(); + led_indication_evt = PTT_EVENT_UNASSIGNED; +} + +void cmd_rf_cca_done(ptt_evt_id_t evt_id) +{ + assert(cmd_is_uart_cmd_locked_by(evt_id)); + + cmd_uart_send_rsp_cca_done(evt_id); + cmd_uart_cmd_unlock(); +} + +void cmd_rf_cca_failed(ptt_evt_id_t evt_id) +{ + assert(cmd_is_uart_cmd_locked_by(evt_id)); + + cmd_uart_send_rsp_cca_failed(evt_id); + cmd_uart_cmd_unlock(); +} + +void cmd_rf_ed_detected(ptt_evt_id_t evt_id) +{ + assert(cmd_is_uart_cmd_locked_by(evt_id)); + + cmd_uart_send_rsp_ed_detected(evt_id); + cmd_uart_cmd_unlock(); +} + +void cmd_rf_ed_failed(ptt_evt_id_t evt_id) +{ + assert(cmd_is_uart_cmd_locked_by(evt_id)); + + cmd_uart_send_rsp_ed_failed(evt_id); + cmd_uart_cmd_unlock(); +} + +void cmd_uart_pkt_received(ptt_evt_id_t new_uart_cmd) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_uart_cmd); + + if (false == cmd_is_uart_cmd_locked()) { + /* store UART command as currently processed */ + cmd_uart_cmd_lock(new_uart_cmd); + cmd_uart_idle_packet_proc(); + } else { + switch (ptt_event_get_state(uart_cmd_evt)) { + case CMD_UART_STATE_WAITING_FOR_LEND: + cmd_uart_l_end(new_uart_cmd); + ptt_event_free(new_uart_cmd); + break; + + case CMD_UART_STATE_L_CLK_OUT: + cmd_uart_l_clk_stop(new_uart_cmd); + ptt_event_free(new_uart_cmd); + break; + + case CMD_UART_STATE_LTX_WAITING_FOR_ACK: + case CMD_UART_STATE_LTX: + cmd_uart_l_tx_end(new_uart_cmd); + ptt_event_free(new_uart_cmd); + break; + + default: + PTT_TRACE("%s: state isn't idle cmd %d state %d\n", __func__, + ptt_event_get_cmd(uart_cmd_evt), + ptt_event_get_state(uart_cmd_evt)); + ptt_event_free(new_uart_cmd); + break; + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_idle_packet_proc(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + enum ptt_uart_cmd uart_cmd = ptt_event_get_cmd(uart_cmd_evt); + + PTT_TRACE("%s: cmd %d\n", __func__, uart_cmd); + + /* handlers are responsible for cleaning current event */ + switch (uart_cmd) { + case PTT_UART_CMD_R_PING: + ret = cmd_uart_call_ota_cmd(PTT_CMD_PING, NULL); + break; + + case PTT_UART_CMD_L_PING_TIMEOUT: + ret = cmd_uart_l_ping_timeout(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_SETCHANNEL: + ret = cmd_uart_set_channel(); + break; + + case PTT_UART_CMD_L_SETCHANNEL: + ret = cmd_uart_l_set_channel(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_SETCHANNEL: + ret = cmd_uart_r_set_channel(); + break; + + case PTT_UART_CMD_L_GET_CHANNEL: + ret = cmd_uart_l_get_channel(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_SET_POWER: + ret = cmd_uart_l_set_power(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_SET_POWER: + ret = cmd_uart_r_set_power(); + break; + + case PTT_UART_CMD_L_GET_POWER: + ret = cmd_uart_l_get_power(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_GET_POWER: + ret = cmd_uart_call_ota_cmd(PTT_CMD_GET_POWER, NULL); + break; + + case PTT_UART_CMD_R_STREAM: + ret = cmd_uart_call_ota_cmd(PTT_CMD_STREAM, ptt_event_get_ctx_data(uart_cmd_evt)); + break; + + case PTT_UART_CMD_R_START: + ret = cmd_uart_call_ota_cmd(PTT_CMD_START_RX_TEST, NULL); + break; + + case PTT_UART_CMD_R_END: + ret = cmd_uart_call_ota_cmd(PTT_CMD_END_RX_TEST, NULL); + break; + + case PTT_UART_CMD_L_REBOOT: + ptt_do_reset_ext(); + /* there is no return from function above */ + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_FIND: + ret = cmd_uart_find_idle(); + break; + + case PTT_UART_CMD_R_HW_VERSION: + ret = cmd_uart_call_ota_cmd(PTT_CMD_GET_HARDWARE_VERSION, NULL); + break; + + case PTT_UART_CMD_R_SW_VERSION: + ret = cmd_uart_call_ota_cmd(PTT_CMD_GET_SOFTWARE_VERSION, NULL); + break; + + case PTT_UART_CMD_L_GET_CCA: + ret = cmd_uart_l_get_cca(); + break; + + case PTT_UART_CMD_L_GET_ED: + ret = cmd_uart_l_get_ed(); + break; + + case PTT_UART_CMD_L_GET_RSSI: + ret = cmd_uart_l_get_rssi(); + break; + + case PTT_UART_CMD_L_SET_PAN_ID: + ret = cmd_uart_l_set_pan_id(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_SET_EXTENDED: + ret = cmd_uart_l_set_extended_address(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_SET_SHORT: + ret = cmd_uart_l_set_short_address(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_SET_PAYLOAD: + ret = cmd_uart_l_set_payload(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_START: + ret = cmd_uart_l_start(); + break; + + case PTT_UART_CMD_L_GET_LQI: + ret = cmd_uart_l_get_lqi(); + break; + + case PTT_UART_CMD_L_SET_ANTENNA: + ret = cmd_uart_l_set_antenna(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_GET_ANTENNA: + ret = cmd_uart_l_get_antenna(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_SET_ANTENNA: + ret = cmd_uart_r_set_antenna(); + break; + + case PTT_UART_CMD_R_GET_ANTENNA: + ret = cmd_uart_call_ota_cmd(PTT_CMD_GET_ANTENNA, NULL); + break; + + case PTT_UART_CMD_L_TX: + ret = cmd_uart_l_tx(); + break; + + case PTT_UART_CMD_L_CLK: + ret = cmd_uart_l_clk(); + break; + + case PTT_UART_CMD_L_SET_GPIO: + ret = cmd_uart_l_set_gpio(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_GET_GPIO: + ret = cmd_uart_l_get_gpio(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_CARRIER: + ret = cmd_uart_l_carrier(); + break; + + case PTT_UART_CMD_L_STREAM: + ret = cmd_uart_l_stream(); + break; + + case PTT_UART_CMD_L_SET_DCDC: + ret = cmd_uart_l_set_dcdc(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_GET_DCDC: + ret = cmd_uart_l_get_dcdc(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_SET_ICACHE: + ret = cmd_uart_l_set_icache(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_GET_ICACHE: + ret = cmd_uart_l_get_icache(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_GET_TEMP: + ret = cmd_uart_l_get_temp(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_INDICATION: + ret = cmd_uart_l_indication(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_SLEEP: + ret = cmd_uart_l_sleep(); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_L_RECEIVE: + ret = cmd_uart_l_receive(); + cmd_uart_cmd_unlock(); + break; + + default: + PTT_TRACE("%s: unknown command cmd %d\n ignored", __func__, uart_cmd); + cmd_uart_cmd_unlock(); + break; + } + + if (ret != PTT_RET_SUCCESS) { + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +void cmt_uart_ota_cmd_timeout_notify(ptt_evt_id_t ota_cmd_evt) +{ + PTT_TRACE("%s: cmd %d state %d\n", __func__, ptt_event_get_cmd(uart_cmd_evt), + ptt_event_get_state(uart_cmd_evt)); + + enum ptt_uart_cmd uart_cmd = ptt_event_get_cmd(uart_cmd_evt); + + switch (uart_cmd) { + case PTT_UART_CMD_R_PING: + cmd_uart_send_rsp_no_ack(uart_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_CMD_SET_CHANNEL: + cmd_uart_set_channel_process_timeout(ota_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_SETCHANNEL: + case PTT_UART_CMD_R_SET_POWER: + case PTT_UART_CMD_R_STREAM: + case PTT_UART_CMD_R_START: + case PTT_UART_CMD_R_SET_ANTENNA: + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_GET_POWER: + cmd_uart_send_rsp_power_error(ota_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_END: + cmd_uart_send_rsp_rx_test_error(uart_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_FIND: + cmd_uart_find_process_timeout(ota_cmd_evt); + break; + + case PTT_UART_CMD_R_HW_VERSION: + cmd_uart_send_rsp_hw_error(uart_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_SW_VERSION: + cmd_uart_send_rsp_sw_error(uart_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_GET_ANTENNA: + cmd_uart_send_rsp_antenna_error(ota_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + default: + PTT_TRACE("%s: unexpected notify ignored\n", __func__); + cmd_uart_cmd_unlock(); + break; + } + + /* it's final destination for event allocated inside call_ota_cmd */ + ptt_event_free(ota_cmd_evt); + + PTT_TRACE_FUNC_EXIT(); +} + +/* ota_cmd result inside ota_cmd_evt data context */ +void cmt_uart_ota_cmd_finish_notify(ptt_evt_id_t ota_cmd_evt) +{ + PTT_TRACE("%s: cmd %d state %d\n", __func__, ptt_event_get_cmd(uart_cmd_evt), + ptt_event_get_state(uart_cmd_evt)); + + enum ptt_uart_cmd uart_cmd = ptt_event_get_cmd(uart_cmd_evt); + + switch (uart_cmd) { + case PTT_UART_CMD_R_PING: + cmd_uart_send_rsack(uart_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_SETCHANNEL: + cmd_uart_set_channel_process_finish(ota_cmd_evt); + break; + + case PTT_UART_CMD_R_SETCHANNEL: + case PTT_UART_CMD_R_SET_POWER: + case PTT_UART_CMD_R_STREAM: + case PTT_UART_CMD_R_START: + case PTT_UART_CMD_R_SET_ANTENNA: + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_GET_POWER: + cmd_uart_send_rsp_power(ota_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_END: + cmd_uart_send_rsp_rx_test(ota_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_FIND: + cmd_uart_find_process_finish(ota_cmd_evt); + break; + + case PTT_UART_CMD_R_HW_VERSION: + cmd_uart_send_rsp_hw(ota_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_SW_VERSION: + cmd_uart_send_rsp_sw(ota_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + case PTT_UART_CMD_R_GET_ANTENNA: + cmd_uart_send_rsp_antenna(ota_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + default: + PTT_TRACE("%s: unexpected notify ignored\n", __func__); + cmd_uart_cmd_unlock(); + break; + } + + /* it's final destination for event allocated inside call_ota_cmd */ + ptt_event_free(ota_cmd_evt); + + PTT_TRACE_FUNC_EXIT(); +} + +void cmd_rf_rx_done(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + if (false == cmd_is_uart_cmd_locked()) { + cmd_ota_rf_rx_done(new_rf_pkt_evt); + PTT_TRACE("%s: pass event to OTA module\n", __func__); + } else { + ptt_evt_state_t state = ptt_event_get_state(uart_cmd_evt); + + switch (state) { + case CMD_UART_STATE_LTX_WAITING_FOR_ACK: + cmd_uart_l_tx_process_ack(new_rf_pkt_evt); + break; + + case CMD_UART_STATE_WAITING_FOR_LEND: + cmd_uart_l_start_process_rf_packet(new_rf_pkt_evt); + break; + + case CMD_UART_STATE_WAITING_FOR_RF_PACKET: + cmd_uart_l_get_lqi_process_rf_packet(new_rf_pkt_evt); + break; + + default: + cmd_ota_rf_rx_done(new_rf_pkt_evt); + PTT_TRACE("%s: pass event to OTA module\n", __func__); + } + } + + cmd_uart_l_indication_proc(); + + ptt_event_free(new_rf_pkt_evt); + PTT_TRACE_FUNC_EXIT(); +} + +void cmd_rf_rx_failed(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + if (true == cmd_is_uart_cmd_locked()) { + ptt_evt_state_t state = ptt_event_get_state(uart_cmd_evt); + + switch (state) { + case CMD_UART_STATE_WAITING_FOR_LEND: + cmd_uart_send_rsp_l_start_rx_fail(new_rf_pkt_evt); + break; + + default: + PTT_TRACE("%s: unexpected event for current state\n", __func__); + break; + } + } + + ptt_event_free(new_rf_pkt_evt); + PTT_TRACE_FUNC_EXIT(); +} + +void cmd_rf_tx_finished(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + if (false == cmd_is_uart_cmd_locked()) { + PTT_TRACE("%s: passing evt to ota module\n", __func__); + cmd_ota_rf_tx_finished(evt_id); + } else { + ptt_evt_state_t state = ptt_event_get_state(uart_cmd_evt); + + switch (state) { + case CMD_UART_STATE_LTX_WAITING_FOR_ACK: + cmd_uart_l_tx_finished(evt_id); + break; + + default: + PTT_TRACE("%s: passing evt to ota module\n", __func__); + cmd_ota_rf_tx_finished(evt_id); + break; + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +void cmd_rf_tx_failed(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + if (false == cmd_is_uart_cmd_locked()) { + PTT_TRACE("%s: passing evt to ota module\n", __func__); + cmd_ota_rf_tx_failed(evt_id); + } else { + ptt_evt_state_t state = ptt_event_get_state(uart_cmd_evt); + + switch (state) { + case CMD_UART_STATE_LTX_WAITING_FOR_ACK: + cmd_uart_l_tx_failed(evt_id); + break; + + default: + PTT_TRACE("%s: passing evt to ota module\n", __func__); + cmd_ota_rf_tx_failed(evt_id); + break; + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_uart_l_ping_timeout(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + /* by protocol, timeout consists from two bytes */ + uint16_t timeout = ptt_betoh16_val(ctx_data->arr); + + ptt_ctrl_set_rsp_timeout(timeout); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_set_channel_payload_check(void) +{ + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint32_t mask = ptt_betoh32_val(ctx_data->arr); + enum ptt_ret ret = PTT_RET_SUCCESS; + + if ((mask < (1u << PTT_CHANNEL_MIN)) || (mask > (1u << PTT_CHANNEL_MAX)) || + (!(mask && !(mask & (mask - 1))))) { + /* check that more that one bit is set*/ + ret = PTT_RET_INVALID_VALUE; + } + + return ret; +} + +static enum ptt_ret cmd_uart_set_channel(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = cmd_uart_set_channel_payload_check(); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_SET_CHANNEL); + + ret = cmd_uart_call_ota_cmd(PTT_CMD_SET_CHANNEL, + ptt_event_get_ctx_data(uart_cmd_evt)); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static void cmd_uart_set_channel_was_set(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint32_t mask = ptt_betoh32_val(ctx_data->arr); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + /* set channel to CMD */ + ret = ptt_rf_set_channel_mask(uart_cmd_evt, mask); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_WAIT_DELAY); + ret = ptt_timer_add(ptt_ctrl_get_rsp_timeout(), cmd_uart_set_channel_delay, + uart_cmd_evt); + } + + if (ret != PTT_RET_SUCCESS) { + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static void cmd_uart_set_channel_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_uart_cmd_locked_by(timer_evt_id)); + + cmd_change_uart_cmd_state(CMD_UART_STATE_PING); + enum ptt_ret ret = cmd_uart_call_ota_cmd(PTT_CMD_PING, NULL); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: cmd_uart_call_ota_cmd returns error code: %d\n", __func__, ret); + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_set_channel_process_timeout(ptt_evt_id_t ota_cmd_evt) +{ + PTT_TRACE_FUNC_ENTER(); + + enum cmd_uart_state_t state = ptt_event_get_state(uart_cmd_evt); + + PTT_TRACE("%s: state %d\n", __func__, state); + + switch (state) { + case CMD_UART_STATE_PING: + cmd_uart_send_rsp_no_ack(uart_cmd_evt); + break; + + default: + PTT_TRACE("%s: unexpected timeout\n", __func__); + break; + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_set_channel_process_finish(ptt_evt_id_t ota_cmd_evt) +{ + PTT_TRACE_FUNC_ENTER(); + + enum cmd_uart_state_t state = ptt_event_get_state(uart_cmd_evt); + + PTT_TRACE("%s state %d\n", __func__, state); + + switch (state) { + case CMD_UART_STATE_SET_CHANNEL: + cmd_uart_set_channel_was_set(); + break; + + case CMD_UART_STATE_PING: + /* uart_cmd_evt data ctx has current channel */ + cmd_uart_send_rsack(uart_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + default: + PTT_TRACE("%s: unexpected finish\n", __func__); + cmd_uart_cmd_unlock(); + break; + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_uart_l_set_channel(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = cmd_uart_set_channel_payload_check(); + + if (ret == PTT_RET_SUCCESS) { + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint32_t mask = ptt_betoh32_val(ctx_data->arr); + + /* set channel to CMD */ + ret = ptt_rf_set_channel_mask(uart_cmd_evt, mask); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_r_set_channel(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_uart_cmd_state(CMD_UART_STATE_SET_CHANNEL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t channel = ctx_data->arr[0]; + enum ptt_ret ret = PTT_RET_SUCCESS; + + if ((channel < PTT_CHANNEL_MIN) || (channel > PTT_CHANNEL_MAX)) { + ret = PTT_RET_INVALID_VALUE; + } else { + uint32_t mask = 1u << channel; + + ptt_htobe32((uint8_t *)(&mask), ctx_data->arr); + ctx_data->len = sizeof(mask); + + ret = cmd_uart_call_ota_cmd(PTT_CMD_SET_CHANNEL, + ptt_event_get_ctx_data(uart_cmd_evt)); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_l_get_channel(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + ctx_data->arr[0] = ptt_rf_get_channel(); + ctx_data->len = 1; + + cmd_uart_send_rsp_l_channel(uart_cmd_evt); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret parse_power(const uint8_t *uart_cmd_payload, uint16_t *mode_p, int8_t *power_p) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + uint16_t mode; + uint8_t *p = (uint8_t *)&mode; + int8_t power; + + do { + if ((uart_cmd_payload == NULL) || (mode_p == NULL) || (power_p == NULL)) { + ret = PTT_RET_INVALID_VALUE; + break; + } + static char *save; + char *token_str = strtok_r(PTT_CAST_TO_STR(uart_cmd_payload), + UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if (token_str == NULL) { + ret = PTT_RET_INVALID_VALUE; + break; + } + ret = ptt_parser_string_to_uint8(token_str, &p[0], 0); + + if (ret == PTT_RET_SUCCESS) { + token_str = strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if (token_str == NULL) { + ret = PTT_RET_INVALID_VALUE; + break; + } + ret = ptt_parser_string_to_uint8(token_str, &p[1], 0); + + if (ret == PTT_RET_SUCCESS) { + token_str = strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if ((token_str == NULL) || + (strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save) != NULL)) { + ret = PTT_RET_INVALID_VALUE; + } else { + ret = ptt_parser_string_to_int8(token_str, &power, 10); + } + } + } + } while (false); + + if (ret == PTT_RET_SUCCESS) { + ptt_betoh16(p, (uint8_t *)mode_p); + *power_p = power; + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_l_set_power(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + uint16_t mode; + int8_t power; + + assert(data != NULL); + + uint8_t *uart_cmd_payload = data->arr + sizeof(UART_CMD_L_SET_POWER_TEXT); + + ret = parse_power(uart_cmd_payload, &mode, &power); + + if (ret == PTT_RET_SUCCESS) { + /* @todo: handle mode */ + /* set power to CMD */ + ret = ptt_rf_set_power(uart_cmd_evt, power); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_r_set_power(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + uint16_t mode; + int8_t power; + + assert(ctx_data != NULL); + + assert(data != NULL); + + uint8_t *uart_cmd_payload = data->arr + sizeof(UART_CMD_R_SET_POWER_TEXT); + + ret = parse_power(uart_cmd_payload, &mode, &power); + + if (ret == PTT_RET_SUCCESS) { + /* @todo: handle mode */ + ctx_data->arr[0] = (uint8_t)power; + ctx_data->len = sizeof(power); + + ret = cmd_uart_call_ota_cmd(PTT_CMD_SET_POWER, + ptt_event_get_ctx_data(uart_cmd_evt)); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_l_get_power(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + ctx_data->arr[0] = (uint8_t)ptt_rf_get_power(); + ctx_data->len = 1; + + cmd_uart_send_rsp_power(uart_cmd_evt); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_l_get_cca(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + if (ctx_data->len == 0) { + cmd_uart_send_rsp_cca_failed(uart_cmd_evt); + ret = PTT_RET_INVALID_VALUE; + } else { + ret = ptt_rf_cca(uart_cmd_evt, ctx_data->arr[0]); + } + + if (ret != PTT_RET_SUCCESS) { + cmd_uart_send_rsp_cca_failed(uart_cmd_evt); + } + + PTT_TRACE_FUNC_EXIT(); + return ret; +} + +static enum ptt_ret cmd_uart_l_get_ed(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + ret = ptt_rf_ed(uart_cmd_evt, PTT_ED_TIME_US); + + if (ret != PTT_RET_SUCCESS) { + cmd_uart_send_rsp_ed_failed(uart_cmd_evt); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_get_rssi(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = ptt_rf_rssi_measure_begin(uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_WAIT_DELAY); + ret = ptt_timer_add(PTT_RSSI_TIME_MS, cmd_uart_l_get_rssi_delay, uart_cmd_evt); + } + + if (ret != PTT_RET_SUCCESS) { + cmd_uart_send_rsp_rssi_failed(uart_cmd_evt); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_uart_l_get_rssi_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_uart_cmd_locked_by(timer_evt_id)); + + ptt_rssi_t rssi; + enum ptt_ret ret = ptt_rf_rssi_last_get(timer_evt_id, &rssi); + + if ((ret == PTT_RET_SUCCESS) && (rssi != PTT_RSSI_ERROR_VALUE)) { + ptt_event_set_ctx_data(timer_evt_id, PTT_CAST_TO_UINT8_P(&rssi), sizeof(rssi)); + + cmd_uart_send_rsp_rssi_done(timer_evt_id); + } else { + cmd_uart_send_rsp_rssi_failed(timer_evt_id); + } + + cmd_uart_cmd_unlock(); + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static enum ptt_ret cmd_uart_l_set_pan_id(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + uint8_t pan_id[PTT_PANID_ADDRESS_SIZE]; + uint8_t pan_id_le[PTT_PANID_ADDRESS_SIZE]; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + + assert(data != NULL); + + uint8_t *payload = data->arr + sizeof(UART_CMD_L_SET_PAN_ID_TEXT); + + static char *save; + char *id_str = strtok_r(PTT_CAST_TO_STR(payload), UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if ((id_str == NULL) || (strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save) != NULL)) { + /* lets be sure that there are no extra parameters */ + ret = PTT_RET_INVALID_VALUE; + } else { + /* to pass only 0xYYYY type of values */ + if ((strlen(id_str) == UART_SET_PAN_ID_SYM_NUM) && (id_str[0] == '0') && + (id_str[1] == 'x')) { + ret = ptt_parser_string_to_uint16(id_str, (uint16_t *)pan_id, 16); + + if (ret == PTT_RET_SUCCESS) { + /* parser will return host endian number, + * we need to be sure than it is little endian + */ + ptt_htole16(pan_id, pan_id_le); + + ret = ptt_rf_set_pan_id(uart_cmd_evt, pan_id_le); + } + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_set_extended_address(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + uint8_t extended_addr[PTT_EXTENDED_ADDRESS_SIZE] = { 0 }; + uint8_t extended_addr_le[PTT_EXTENDED_ADDRESS_SIZE] = { 0 }; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + + assert(data != NULL); + + uint8_t *payload = data->arr + sizeof(UART_CMD_L_SET_EXTENDED_TEXT); + + static char *save; + char *addr_str = strtok_r(PTT_CAST_TO_STR(payload), UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if ((addr_str == NULL) || (strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save) != NULL)) { + /* lets be sure that there are no extra parameters */ + ret = PTT_RET_INVALID_VALUE; + } else { + /* to pass only 0xYYYYYYYYYYYYYYYY type of values */ + if ((strlen(addr_str) == UART_SET_EXTENDED_SYM_NUM) && (addr_str[0] == '0') && + (addr_str[1] == 'x')) { + uint8_t written_len = 0; + + ret = ptt_parser_hex_string_to_uint8_array( + addr_str, extended_addr, + ARRAY_SIZE(extended_addr), &written_len); + + if (written_len != PTT_EXTENDED_ADDRESS_SIZE) { + ret = PTT_RET_INVALID_VALUE; + } + if (ret == PTT_RET_SUCCESS) { + /* parser works only with bytes, + * so endianness is unchanged => it is big endian + */ + /* converting big endian address to little endian */ + for (uint8_t i = 0; i < PTT_EXTENDED_ADDRESS_SIZE; i++) { + extended_addr_le[i] = + extended_addr[PTT_EXTENDED_ADDRESS_SIZE - 1 - i]; + } + + ret = ptt_rf_set_extended_address(uart_cmd_evt, extended_addr_le); + } + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_set_short_address(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + uint8_t short_addr[PTT_SHORT_ADDRESS_SIZE]; + uint8_t short_addr_le[PTT_SHORT_ADDRESS_SIZE]; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + + assert(data != NULL); + + uint8_t *payload = data->arr + sizeof(UART_CMD_L_SET_SHORT_TEXT); + + static char *save; + char *addr_str = strtok_r(PTT_CAST_TO_STR(payload), UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if ((addr_str == NULL) || (strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save) != NULL)) { + /* lets be sure that there are no extra parameters */ + ret = PTT_RET_INVALID_VALUE; + } else { + /* to pass only 0xYYYY type of values */ + if ((strlen(addr_str) == UART_SET_SHORT_SYM_NUM) && (addr_str[0] == '0') && + (addr_str[1] == 'x')) { + ret = ptt_parser_string_to_uint16(addr_str, (uint16_t *)short_addr, 16); + + if (ret == PTT_RET_SUCCESS) { + /* parser will return host endian number, + * we need to be sure than it is little endian + */ + ptt_htole16(short_addr, short_addr_le); + + ret = ptt_rf_set_short_address(uart_cmd_evt, short_addr_le); + } + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_set_payload(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + uint8_t payload[PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE] = { 0 }; + + assert(data != NULL); + + uint8_t *uart_cmd_payload = data->arr + sizeof(UART_CMD_L_SET_PAYLOAD_TEXT); + + static char *save; + char *token_str = + strtok_r(PTT_CAST_TO_STR(uart_cmd_payload), UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if (token_str == NULL) { + ret = PTT_RET_INVALID_VALUE; + } else { + uint8_t payload_len; + + ret = ptt_parser_string_to_uint8(token_str, &payload_len, 0); + + if (ret == PTT_RET_SUCCESS) { + struct ptt_ltx_payload_s *ltx_payload; + + ltx_payload = ptt_rf_get_custom_ltx_payload(); + + assert(ltx_payload != NULL); + + token_str = strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if ((token_str == NULL) || + (strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save) != NULL)) { + /* lets be sure that there are no extra parameters */ + ret = PTT_RET_INVALID_VALUE; + } else { + uint8_t actual_len; + + ret = ptt_parser_hex_string_to_uint8_array( + token_str, payload, PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE, + &actual_len); + if (actual_len != payload_len) { + ret = PTT_RET_INVALID_VALUE; + } + + if (ret == PTT_RET_SUCCESS) { + ltx_payload->len = actual_len; + memcpy(ltx_payload->arr, payload, ltx_payload->len); + } + } + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_start(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = ptt_rf_start_statistic(uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + /* we will store counter for protocol packets in context. + * Lets erase it just in case + */ + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint32_t *proto_pkts = (uint32_t *)ctx_data->arr; + + *proto_pkts = 0; + + cmd_change_uart_cmd_state(CMD_UART_STATE_WAITING_FOR_LEND); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_uart_l_start_process_rf_packet(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + struct ptt_evt_data_s *rf_data = ptt_event_get_data(new_rf_pkt_evt); + + assert(rf_data != NULL); + + if (ptt_proto_check_packet(rf_data->arr, rf_data->len)) { + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint32_t *proto_pkts = (uint32_t *)ctx_data->arr; + + ++(*proto_pkts); + } + + cmd_uart_send_rsp_l_start_new_packet(new_rf_pkt_evt); + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_l_end(ptt_evt_id_t new_uart_cmd) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_uart_cmd uart_cmd = ptt_event_get_cmd(new_uart_cmd); + + if (uart_cmd == PTT_UART_CMD_L_END) { + enum ptt_ret ret = ptt_rf_end_statistic(uart_cmd_evt); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ptt_rf_end_statistic returns %d", __func__, ret); + } else { + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint32_t *proto_pkts = (uint32_t *)ctx_data->arr; + + cmd_uart_send_rsp_l_end(new_uart_cmd, *proto_pkts); + } + + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_uart_l_get_lqi(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + ret = ptt_timer_add(PTT_LQI_DELAY_MS, cmd_uart_l_get_lqi_delay, uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_WAITING_FOR_RF_PACKET); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_uart_l_get_lqi_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_uart_cmd_locked_by(timer_evt_id)); + + cmd_uart_send_rsp_lqi_failed(timer_evt_id); + + cmd_uart_cmd_unlock(); + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_l_get_lqi_process_rf_packet(ptt_evt_id_t new_rf_pkt_evt) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_rf_pkt_evt); + + ptt_timer_remove(uart_cmd_evt); + cmd_uart_send_rsp_lqi_done(new_rf_pkt_evt); + + cmd_uart_cmd_unlock(); + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_uart_l_set_antenna(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t antenna = ctx_data->arr[0]; + + enum ptt_ret ret = ptt_rf_set_antenna(uart_cmd_evt, antenna); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_set_dcdc(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + enum ptt_ret ret = PTT_RET_SUCCESS; + uint8_t activate = ctx_data->arr[0]; + + if ((activate == 0) || (activate == 1)) { + ptt_ctrl_set_dcdc(activate); + } else { + ret = PTT_RET_INVALID_VALUE; + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_get_dcdc(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + bool dcdc_active = ptt_ctrl_get_dcdc(); + + ctx_data->arr[0] = dcdc_active; + ctx_data->len = sizeof(dcdc_active); + + cmd_uart_send_rsp_get_dcdc(uart_cmd_evt); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_set_icache(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t enable = ctx_data->arr[0]; + enum ptt_ret ret = PTT_RET_SUCCESS; + + if ((enable == 0) || (enable == 1)) { + ptt_ctrl_set_icache(enable); + } else { + ret = PTT_RET_INVALID_VALUE; + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_get_icache(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + bool icache_active = ptt_ctrl_get_icache(); + + ctx_data->arr[0] = icache_active; + ctx_data->len = sizeof(icache_active); + + cmd_uart_send_rsp_get_icache(uart_cmd_evt); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_indication(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t activate = ctx_data->arr[0]; + enum ptt_ret ret = PTT_RET_SUCCESS; + + if ((activate == 1) && (led_indication_evt == PTT_EVENT_UNASSIGNED)) { + ret = ptt_event_alloc(&led_indication_evt); + + if (ret == PTT_RET_SUCCESS) { + /* setting default value just in case */ + struct ptt_evt_ctx_data_s *ctx_data = + ptt_event_get_ctx_data(led_indication_evt); + + assert(ctx_data != NULL); + + bool *is_timer_active = (bool *)ctx_data->arr; + + *is_timer_active = false; + } + } else if ((activate == 0) && (led_indication_evt != PTT_EVENT_UNASSIGNED)) { + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(led_indication_evt); + + assert(ctx_data != NULL); + + bool is_timer_active = *((bool *)ctx_data->arr); + + if (is_timer_active) { + ptt_timer_remove(led_indication_evt); + cmd_uart_l_indication_off(led_indication_evt); + } + + ptt_event_free(led_indication_evt); + led_indication_evt = PTT_EVENT_UNASSIGNED; + } else { + ret = PTT_RET_INVALID_VALUE; + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +/* this function used as a callback for timer */ +static void cmd_uart_l_indication_off(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER(); + + PTT_UNUSED(evt_id); + + ptt_ctrl_led_indication_off(); + + assert(led_indication_evt != PTT_EVENT_UNASSIGNED); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(led_indication_evt); + + assert(ctx_data != NULL); + + bool *is_timer_active = (bool *)ctx_data->arr; + + if (false == *is_timer_active) { + PTT_TRACE("%s: WARNING: is_timer_active variable is false\n", __func__); + } + + *is_timer_active = false; + + PTT_TRACE_FUNC_EXIT(); +} + +void cmd_uart_l_indication_proc(void) +{ + if (led_indication_evt != PTT_EVENT_UNASSIGNED) { + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(led_indication_evt); + + assert(ctx_data != NULL); + + bool *is_timer_active = (bool *)ctx_data->arr; + + if (false == *is_timer_active) { + enum ptt_ret led_ret = + ptt_timer_add(PTT_LED_INDICATION_BLINK_TIMEOUT_MS, + cmd_uart_l_indication_off, led_indication_evt); + + if (led_ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ptt_timer_add for LED indication returns error: %d", + __func__, led_ret); + } else { + ptt_ctrl_led_indication_on(); + *is_timer_active = true; + } + } + } +} + +static enum ptt_ret cmd_uart_l_tx(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + + assert(data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t *uart_cmd_payload = data->arr + sizeof(UART_CMD_L_TX_TEXT); + static char *save; + char *token_str = + strtok_r(PTT_CAST_TO_STR(uart_cmd_payload), UART_TEXT_PAYLOAD_DELIMETERS, &save); + + struct cmd_uart_ltx_info_s *ltx_info = (struct cmd_uart_ltx_info_s *)ctx_data->arr; + + ltx_info->is_stop_requested = false; + + if (token_str == NULL) { + ltx_info->max_repeats_cnt = PTT_CUSTOM_LTX_DEFAULT_REPEATS; + ltx_info->timeout = PTT_CUSTOM_LTX_DEFAULT_TIMEOUT_MS; + } else { + ret = ptt_parser_string_to_uint8(token_str, &(ltx_info->max_repeats_cnt), 0); + + if (ret == PTT_RET_SUCCESS) { + token_str = strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if ((token_str == NULL) || + (strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save) != NULL)) { + /* lets be sure that there are no extra parameters */ + ret = PTT_RET_INVALID_VALUE; + } else { + ret = ptt_parser_string_to_uint16(token_str, &(ltx_info->timeout), + 0); + + if (ltx_info->timeout > PTT_CUSTOM_LTX_TIMEOUT_MAX_VALUE) { + ret = PTT_RET_INVALID_VALUE; + } + } + } + } + + if (ret == PTT_RET_SUCCESS) { + if (ltx_info->max_repeats_cnt == 0) { + ltx_info->is_infinite = true; + } else { + ltx_info->is_infinite = false; + } + + ltx_info->repeats_cnt = 0; + ltx_info->ack_cnt = 0; + cmd_change_uart_cmd_state(CMD_UART_STATE_LTX); + cmd_uart_l_tx_process_next_packet(); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_uart_l_tx_end(ptt_evt_id_t new_uart_cmd) +{ + PTT_TRACE_FUNC_ENTER(); + + if (ptt_event_get_cmd(new_uart_cmd) == PTT_UART_CMD_L_TX_END) { + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + struct cmd_uart_ltx_info_s *ltx_info = (struct cmd_uart_ltx_info_s *)ctx_data->arr; + + if (ltx_info->is_infinite) { + /* This will cause the ltx routine to stop sending packets + * Requesting it ensures that all replies are received before stopping + */ + ltx_info->is_stop_requested = true; + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_uart_l_get_antenna(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t antenna = ptt_rf_get_antenna(); + + ctx_data->arr[0] = antenna; + ctx_data->len = sizeof(antenna); + + cmd_uart_send_rsp_antenna(uart_cmd_evt); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_get_temp(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + int32_t temp; + enum ptt_ret ret = ptt_ctrl_get_temp(&temp); + + if (ret == PTT_RET_SUCCESS) { + *((int32_t *)ctx_data) = temp; + ctx_data->len = sizeof(temp); + + cmd_uart_send_rsp_get_temp(uart_cmd_evt); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_uart_l_tx_process_next_packet(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + struct cmd_uart_ltx_info_s *ltx_info = (struct cmd_uart_ltx_info_s *)ctx_data->arr; + + if ((!ltx_info->is_infinite && (ltx_info->max_repeats_cnt <= ltx_info->repeats_cnt)) || + ltx_info->is_stop_requested) { + cmd_uart_cmd_unlock(); + } else { + ++(ltx_info->repeats_cnt); + + ret = ptt_timer_add(ltx_info->timeout, cmd_uart_l_tx_delay, uart_cmd_evt); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ptt_timer_add returned %d, aborting ltx\n", __func__, ret); + cmd_uart_cmd_unlock(); + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static void cmd_uart_l_tx_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(cmd_is_uart_cmd_locked_by(timer_evt_id)); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_ltx_payload_s *ltx_payload = ptt_rf_get_custom_ltx_payload(); + /* we will use payload_len instead of ltx_payload->len to be able to generate new random + * payload for every sent packet + */ + uint8_t payload_len = ltx_payload->len; + + if (payload_len == 0) { + ptt_random_vector_generate(&payload_len, sizeof(payload_len)); + + /* make sure that size we get is not bigger that out buffer */ + payload_len %= PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE + 1; + + if (payload_len == 0) { + payload_len = PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE / 2; + } + + ptt_random_vector_generate(ltx_payload->arr, payload_len); + } + + if (ret == PTT_RET_SUCCESS) { + ptt_evt_id_t sender_event_id; + + ret = ptt_event_alloc(&sender_event_id); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_LTX_WAITING_FOR_ACK); + ret = ptt_rf_send_packet(sender_event_id, ltx_payload->arr, payload_len); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ptt_rf_send_packet returns %d, aborting ltx\n", + __func__, ret); + ptt_event_free(sender_event_id); + cmd_uart_cmd_unlock(); + } + } else { + PTT_TRACE("%s: ptt_event_alloc returns %d, aborting ltx\n", __func__, ret); + cmd_uart_cmd_unlock(); + ret = PTT_RET_INVALID_VALUE; + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static void cmd_uart_l_tx_finished(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + if (!cmd_is_uart_cmd_locked()) { + PTT_TRACE("%s: uart module is not locked, aborting ltx\n", __func__); + cmd_uart_cmd_unlock(); + } else { + ptt_evt_state_t state = ptt_event_get_state(uart_cmd_evt); + + if (state != CMD_UART_STATE_LTX_WAITING_FOR_ACK) { + PTT_TRACE("%s: uart module state is unexpected, aborting ltx\n", __func__); + cmd_uart_cmd_unlock(); + } else { + cmd_change_uart_cmd_state(CMD_UART_STATE_LTX); + cmd_uart_l_tx_process_next_packet(); + } + } + + ptt_event_free(evt_id); + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_l_tx_process_ack(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + struct ptt_evt_data_s *data = ptt_event_get_data(evt_id); + + assert(data != NULL); + + /* if ACK is not NULL */ + if ((data->arr != NULL) && (data->len != 0)) { + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + struct cmd_uart_ltx_info_s *ltx_info = (struct cmd_uart_ltx_info_s *)ctx_data->arr; + + cmd_uart_send_rsp_ltx_ack(evt_id, ltx_info->ack_cnt); + + ++(ltx_info->ack_cnt); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_l_tx_failed(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + if (!cmd_is_uart_cmd_locked()) { + PTT_TRACE("%s: uart module is not locked, aborting ltx\n", __func__); + cmd_uart_cmd_unlock(); + } else { + ptt_evt_state_t state = ptt_event_get_state(uart_cmd_evt); + + if (state != CMD_UART_STATE_LTX_WAITING_FOR_ACK) { + PTT_TRACE("%s: uart module state is unexpected, aborting ltx\n", __func__); + cmd_uart_cmd_unlock(); + } else { + cmd_change_uart_cmd_state(CMD_UART_STATE_LTX); + cmd_uart_send_rsp_ltx_failed(evt_id); + cmd_uart_l_tx_process_next_packet(); + } + } + + ptt_event_free(evt_id); + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_uart_find_idle(void) +{ + uint32_t mask = 1u << PTT_CHANNEL_MIN; + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + /* set 0x0B channel as the first channel for find procedure */ + enum ptt_ret ret = ptt_rf_set_channel_mask(uart_cmd_evt, mask); + + if (ret == PTT_RET_SUCCESS) { + ptt_htobe32((uint8_t *)(&mask), ctx_data->arr); + ctx_data->len = sizeof(mask); + + cmd_change_uart_cmd_state(CMD_UART_STATE_SET_CHANNEL); + + ret = cmd_uart_call_ota_cmd(PTT_CMD_SET_CHANNEL, + ptt_event_get_ctx_data(uart_cmd_evt)); + } + + return ret; +} + +static enum ptt_ret cmd_uart_r_set_antenna(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = + cmd_uart_call_ota_cmd(PTT_CMD_SET_ANTENNA, ptt_event_get_ctx_data(uart_cmd_evt)); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_uart_find_channel_was_set(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cmd_change_uart_cmd_state(CMD_UART_STATE_WAIT_DELAY); + enum ptt_ret ret = + ptt_timer_add(ptt_ctrl_get_rsp_timeout(), cmd_uart_find_delay, uart_cmd_evt); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: add_timer returns error code: %d\n", __func__, ret); + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_find_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(true == cmd_is_uart_cmd_locked_by(timer_evt_id)); + + cmd_change_uart_cmd_state(CMD_UART_STATE_PING); + enum ptt_ret ret = cmd_uart_call_ota_cmd(PTT_CMD_PING, NULL); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: cmd_uart_call_ota_cmd returns error code: %d\n", __func__, ret); + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_find_send_set_channel(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint32_t mask = ptt_betoh32_val(ctx_data->arr); + + if (mask >= (1u << PTT_CHANNEL_MAX)) { + /* not found*/ + cmd_uart_send_rsp_find_timeout(uart_cmd_evt); + cmd_uart_cmd_unlock(); + } else { + mask <<= 1u; + + enum ptt_ret ret = ptt_rf_set_channel_mask(uart_cmd_evt, mask); + + if (ret == PTT_RET_SUCCESS) { + ptt_htobe32((uint8_t *)(&mask), ctx_data->arr); + + cmd_change_uart_cmd_state(CMD_UART_STATE_SET_CHANNEL); + + /* first SET_CHANNEL call is from current CMD channel */ + ret = cmd_uart_call_ota_cmd(PTT_CMD_SET_CHANNEL, + ptt_event_get_ctx_data(uart_cmd_evt)); + } + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: failed with error code: %d\n", __func__, ret); + cmd_uart_cmd_unlock(); + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_find_process_finish(ptt_evt_id_t ota_cmd_evt) +{ + PTT_TRACE_FUNC_ENTER(); + + enum cmd_uart_state_t state = ptt_event_get_state(uart_cmd_evt); + + PTT_TRACE("%s: state %d\n", __func__, state); + + switch (state) { + case CMD_UART_STATE_SET_CHANNEL: + cmd_uart_find_channel_was_set(); + break; + + case CMD_UART_STATE_PING: + /* uart_cmd_evt data ctx has current channel */ + cmd_uart_send_rsp_find(uart_cmd_evt); + cmd_uart_cmd_unlock(); + break; + + default: + PTT_TRACE("%s: unexpected finish\n", __func__); + cmd_uart_cmd_unlock(); + break; + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_find_process_timeout(ptt_evt_id_t ota_cmd_evt) +{ + PTT_TRACE_FUNC_ENTER(); + + enum cmd_uart_state_t state = ptt_event_get_state(uart_cmd_evt); + + PTT_TRACE("%s: state %d\n", __func__, state); + + switch (state) { + case CMD_UART_STATE_PING: + cmd_uart_find_send_set_channel(); + break; + + default: + PTT_TRACE("%s: unexpected timeout\n", __func__); + cmd_uart_cmd_unlock(); + break; + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_uart_l_clk(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t pin = ctx_data->arr[0]; + bool mode = (bool)ctx_data->arr[1]; + + /* if mode is false just skip it, output clk is already disabled */ + if (mode == PTT_VALUE_ON) { + if (ptt_clk_out_ext(pin, mode)) { + cmd_change_uart_cmd_state(CMD_UART_STATE_L_CLK_OUT); + } else { + ret = PTT_RET_INVALID_VALUE; + } + } else { + ret = PTT_RET_INVALID_VALUE; + } + + PTT_TRACE_FUNC_EXIT(); + return ret; +} + +static void cmd_uart_l_clk_stop(ptt_evt_id_t new_uart_cmd) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_uart_cmd uart_cmd = ptt_event_get_cmd(new_uart_cmd); + + if (uart_cmd == PTT_UART_CMD_L_CLK) { + struct ptt_evt_ctx_data_s *ctx_data_new = ptt_event_get_ctx_data(new_uart_cmd); + + assert(ctx_data_new != NULL); + + uint8_t pin_new = ctx_data_new->arr[0]; + bool mode_new = (bool)ctx_data_new->arr[1]; + + struct ptt_evt_ctx_data_s *ctx_data_old = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data_old != NULL); + + uint8_t pin_old = ctx_data_old->arr[0]; + bool mode_old = (bool)ctx_data_old->arr[1]; + + if ((pin_old == pin_new) && (mode_old) && (mode_new == PTT_VALUE_OFF)) { + if (ptt_clk_out_ext(pin_new, mode_new)) { + cmd_uart_cmd_unlock(); + } + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret cmd_uart_l_set_gpio(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t pin = ctx_data->arr[0]; + uint8_t value = ctx_data->arr[1]; + + if ((value == PTT_VALUE_OFF) || (value == PTT_VALUE_ON)) { + if (!ptt_set_gpio_ext(pin, value)) { + ret = PTT_RET_INVALID_VALUE; + } + } else { + ret = PTT_RET_INVALID_VALUE; + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_l_get_gpio(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t pin = ctx_data->arr[0]; + uint8_t *value = &ctx_data->arr[1]; + + if (!ptt_get_gpio_ext(pin, value)) { + cmd_uart_send_rsp_l_get_gpio_error(uart_cmd_evt); + ret = PTT_RET_INVALID_VALUE; + } else { + ctx_data->len++; + cmd_uart_send_rsp_l_get_gpio(uart_cmd_evt); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret cmd_uart_parse_waveform_timings(const uint8_t *uart_cmd_payload, + int32_t *pulse_duration, int32_t *interval, + int32_t *duration_p) +{ + if (uart_cmd_payload == NULL) { + return PTT_RET_INVALID_VALUE; + } + + enum ptt_ret ret = PTT_RET_SUCCESS; + static char *save; + char *token_str = + strtok_r(PTT_CAST_TO_STR(uart_cmd_payload), UART_TEXT_PAYLOAD_DELIMETERS, &save); + + /* arguments parsing */ + if (token_str == NULL) { + ret = PTT_RET_INVALID_VALUE; + } else { + ret = ptt_parser_string_to_int32(token_str, pulse_duration, 0); + + if (ret == PTT_RET_SUCCESS) { + token_str = strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if (token_str == NULL) { + ret = PTT_RET_INVALID_VALUE; + } else { + ret = ptt_parser_string_to_int32(token_str, interval, 0); + + if (ret == PTT_RET_SUCCESS) { + token_str = + strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save); + + if ((token_str == NULL) || + /* lets be sure that there are no extra parameters */ + (strtok_r(NULL, UART_TEXT_PAYLOAD_DELIMETERS, &save) != + NULL)) { + ret = PTT_RET_INVALID_VALUE; + } else { + ret = ptt_parser_string_to_int32(token_str, + duration_p, 0); + } + } + } + } + } + + return ret; +} + +static enum ptt_ret cmd_uart_l_carrier(void) +{ + PTT_TRACE_FUNC_ENTER(); + + int32_t transmission_duration; + struct cmd_uart_waveform_timings_s timings_info = { 0 }; + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + + assert(data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t *uart_cmd_payload = data->arr + sizeof(UART_CMD_L_CARRIER_TEXT); + + ret = cmd_uart_parse_waveform_timings(uart_cmd_payload, &(timings_info.pulse_duration), + &(timings_info.interval), &transmission_duration); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: error occurs due payload parsing: %d. Aborting command handling", + __func__, ret); + } else { + /* range checks */ + /* The values are only stored in the ctx_data if the parsing is successful */ + memcpy(ctx_data->arr, &timings_info, sizeof(struct cmd_uart_waveform_timings_s)); + + bool is_pulse_duration_valid = + (timings_info.pulse_duration >= PTT_L_CARRIER_PULSE_MIN) && + (timings_info.pulse_duration <= PTT_L_CARRIER_PULSE_MAX); + bool is_interval_valid = (timings_info.interval >= PTT_L_CARRIER_INTERVAL_MIN) && + (timings_info.interval <= PTT_L_CARRIER_INTERVAL_MAX); + bool is_transmission_duration_valid = + (transmission_duration == 0) || + ((transmission_duration >= PTT_L_CARRIER_DURATION_MIN) && + (transmission_duration <= PTT_L_CARRIER_DURATION_MAX)); + + if (!is_pulse_duration_valid || !is_interval_valid || + !is_transmission_duration_valid) { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s: error during arg range checks: %d. Aborting", __func__, ret); + } else { + /* arm timers */ + /* Transmission duration equal zero means infinite transmission */ + if (transmission_duration != 0) { + ret = ptt_timer_add(transmission_duration, + cmd_uart_l_carrier_duration_delay, + uart_cmd_evt); + } + + if (ret == PTT_RET_SUCCESS) { + ret = ptt_timer_add(timings_info.pulse_duration, + cmd_uart_l_carrier_pulse_delay, uart_cmd_evt); + } + + if (ret != PTT_RET_SUCCESS) { + ptt_timer_remove(uart_cmd_evt); + + PTT_TRACE("%s: error occurs during timers arming: %d. Aborting", + __func__, ret); + } else { + /* start sending carrier */ + ret = ptt_rf_start_continuous_carrier(uart_cmd_evt); + + if (ret != PTT_RET_SUCCESS) { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE( + "%s: rf_start_continuous_carrier is false.Aborting", + __func__); + } else { + cmd_change_uart_cmd_state(CMD_UART_STATE_L_CARRIER_PULSE); + } + } + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_uart_l_carrier_duration_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(cmd_is_uart_cmd_locked_by(timer_evt_id)); + + enum ptt_ret ret = ptt_rf_stop_continuous_carrier(uart_cmd_evt); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: WARNING ptt_rf_stop_continuous_carrier returns error %d\n", __func__, + ret); + } + + ptt_timer_remove(timer_evt_id); + + cmd_uart_cmd_unlock(); + + PTT_TRACE_FUNC_EXIT(); +} + +static void cmd_uart_l_carrier_pulse_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(cmd_is_uart_cmd_locked_by(timer_evt_id)); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + struct cmd_uart_waveform_timings_s *info = + (struct cmd_uart_waveform_timings_s *)(ctx_data->arr); + + enum ptt_ret ret = + ptt_timer_add(info->interval, cmd_uart_l_carrier_interval_delay, uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + ret = ptt_rf_stop_continuous_carrier(uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_L_CARRIER_INTERVAL); + } else { + PTT_TRACE("%s: ptt_rf_stop_continuous_carrier returns error: %d. Aborting", + __func__, ret); + } + } else { + PTT_TRACE("%s: error occurs during timer arming: %d. Aborting command handling", + __func__, ret); + } + + if (ret != PTT_RET_SUCCESS) { + ptt_timer_remove(uart_cmd_evt); + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static void cmd_uart_l_carrier_interval_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(cmd_is_uart_cmd_locked_by(timer_evt_id)); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + struct cmd_uart_waveform_timings_s *info = + (struct cmd_uart_waveform_timings_s *)(ctx_data->arr); + + enum ptt_ret ret = + ptt_timer_add(info->pulse_duration, cmd_uart_l_carrier_pulse_delay, uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + ret = ptt_rf_start_continuous_carrier(uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_L_CARRIER_PULSE); + } else { + PTT_TRACE("%s: ptt_rf_start_continuous_carrier returns error: %d. Aborting", + __func__, ret); + } + } else { + PTT_TRACE("%s: error occurs during timer arming: %d. Aborting command handling", + __func__, ret); + } + + if (ret != PTT_RET_SUCCESS) { + ptt_timer_remove(uart_cmd_evt); + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static enum ptt_ret cmd_uart_l_stream_start(void) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_ltx_payload_s *ltx_payload = ptt_rf_get_custom_ltx_payload(); + /* we will use payload_len instead of ltx_payload->len to be able to generate new random + * payload + */ + uint8_t payload_len = ltx_payload->len; + + if (payload_len == 0) { + ptt_random_vector_generate(&payload_len, sizeof(payload_len)); + + payload_len %= PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE + 1; + + if (payload_len == 0) { + payload_len = PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE / 2; + } + + ptt_random_vector_generate(ltx_payload->arr, payload_len); + } + + ret = ptt_rf_start_modulated_stream(uart_cmd_evt, ltx_payload->arr, payload_len); + + return ret; +} + +static enum ptt_ret cmd_uart_l_stream(void) +{ + PTT_TRACE_FUNC_ENTER(); + + int32_t transmission_duration; + struct cmd_uart_waveform_timings_s timings_info = { 0 }; + enum ptt_ret ret = PTT_RET_SUCCESS; + struct ptt_evt_data_s *data = ptt_event_get_data(uart_cmd_evt); + + assert(data != NULL); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + uint8_t *uart_cmd_payload = data->arr + sizeof(UART_CMD_L_STREAM_TEXT); + + ret = cmd_uart_parse_waveform_timings(uart_cmd_payload, &(timings_info.pulse_duration), + &(timings_info.interval), &transmission_duration); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: error occurs due payload parsing: %d. Aborting command handling", + __func__, ret); + } else { + /* range checks */ + /* The values are only stored in the ctx_data if the parsing is successful */ + memcpy(ctx_data->arr, &timings_info, sizeof(struct cmd_uart_waveform_timings_s)); + + bool is_pulse_duration_valid = + (timings_info.pulse_duration >= PTT_L_CARRIER_PULSE_MIN) && + (timings_info.pulse_duration <= PTT_L_CARRIER_PULSE_MAX); + bool is_interval_valid = (timings_info.interval >= PTT_L_CARRIER_INTERVAL_MIN) && + (timings_info.interval <= PTT_L_CARRIER_INTERVAL_MAX); + bool is_transmission_duration_valid = + (transmission_duration == 0) || + ((transmission_duration >= PTT_L_CARRIER_DURATION_MIN) && + (transmission_duration <= PTT_L_CARRIER_DURATION_MAX)); + + if (!is_pulse_duration_valid || !is_interval_valid || + !is_transmission_duration_valid) { + ret = PTT_RET_INVALID_VALUE; + PTT_TRACE("%s: error occurs during arguments range checks: %d. Aborting", + __func__, ret); + } else { + /* arm timers */ + /* Transmission duration equal zero means infinite transmission */ + if (transmission_duration != 0) { + ret = ptt_timer_add(transmission_duration, + cmd_uart_l_stream_duration_delay, uart_cmd_evt); + } + + if (ret == PTT_RET_SUCCESS) { + ret = ptt_timer_add(timings_info.pulse_duration, + cmd_uart_l_stream_pulse_delay, uart_cmd_evt); + } + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: error occurs during timers arming: %d. Aborting", + __func__, ret); + ptt_timer_remove(uart_cmd_evt); + } else { + /* start sending stream */ + ret = cmd_uart_l_stream_start(); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: cmd_uart_l_stream_start return %d. Aborting", + __func__, ret); + ptt_timer_remove(uart_cmd_evt); + } else { + cmd_change_uart_cmd_state(CMD_UART_STATE_L_STREAM_PULSE); + } + } + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static void cmd_uart_l_stream_duration_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(cmd_is_uart_cmd_locked_by(timer_evt_id)); + + enum ptt_ret ret = ptt_rf_stop_modulated_stream(uart_cmd_evt); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: WARNING ptt_rf_stop_modulated_stream returns error %d\n", __func__, + ret); + } + + ptt_timer_remove(timer_evt_id); + + cmd_uart_cmd_unlock(); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static void cmd_uart_l_stream_pulse_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(cmd_is_uart_cmd_locked_by(timer_evt_id)); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + struct cmd_uart_waveform_timings_s *info = + (struct cmd_uart_waveform_timings_s *)(ctx_data->arr); + + enum ptt_ret ret = + ptt_timer_add(info->interval, cmd_uart_l_stream_interval_delay, uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + ret = ptt_rf_stop_modulated_stream(uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_L_STREAM_INTERVAL); + } else { + PTT_TRACE("%s: ptt_rf_stop_modulated_stream returns error: %d. Aborting", + __func__, ret); + } + } else { + PTT_TRACE("%s: error occurs during timer arming: %d. Aborting command handling", + __func__, ret); + } + + if (ret != PTT_RET_SUCCESS) { + ptt_timer_remove(uart_cmd_evt); + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static void cmd_uart_l_stream_interval_delay(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(timer_evt_id); + + assert(cmd_is_uart_cmd_locked_by(timer_evt_id)); + + struct ptt_evt_ctx_data_s *ctx_data = ptt_event_get_ctx_data(uart_cmd_evt); + + assert(ctx_data != NULL); + + struct cmd_uart_waveform_timings_s *info = + (struct cmd_uart_waveform_timings_s *)(ctx_data->arr); + + enum ptt_ret ret = + ptt_timer_add(info->pulse_duration, cmd_uart_l_stream_pulse_delay, uart_cmd_evt); + + if (ret == PTT_RET_SUCCESS) { + ret = cmd_uart_l_stream_start(); + + if (ret == PTT_RET_SUCCESS) { + cmd_change_uart_cmd_state(CMD_UART_STATE_L_STREAM_PULSE); + } else { + PTT_TRACE("%s: cmd_uart_l_stream_start returns error: %d. Aborting", + __func__, ret); + } + } else { + PTT_TRACE("%s: error occurs during timer arming: %d. Aborting command handling", + __func__, ret); + } + + if (ret != PTT_RET_SUCCESS) { + ptt_timer_remove(uart_cmd_evt); + cmd_uart_cmd_unlock(); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static enum ptt_ret cmd_uart_l_sleep(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = ptt_rf_sleep(); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_l_receive(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = ptt_rf_receive(); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret cmd_uart_call_ota_cmd(enum ptt_cmd cmd, const struct ptt_evt_ctx_data_s *ctx) +{ + PTT_TRACE_FUNC_ENTER(); + + ptt_evt_id_t new_ota_cmd; + + enum ptt_ret ret = ptt_event_alloc(&new_ota_cmd); + + if (ret == PTT_RET_SUCCESS) { + ptt_event_set_cmd(new_ota_cmd, cmd); + + if (ctx != NULL) { + memcpy(ptt_event_get_ctx_data(new_ota_cmd), ctx, + sizeof(struct ptt_evt_ctx_data_s)); + } + + ret = cmd_ota_cmd_process(new_ota_cmd); + + if (ret != PTT_RET_SUCCESS) { + ptt_event_free(new_ota_cmd); + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static inline void cmd_change_uart_cmd_state(ptt_evt_state_t state) +{ + PTT_TRACE("%s: %d", __func__, state); + + ptt_event_set_state(uart_cmd_evt, state); +} + +static inline void cmd_uart_cmd_lock(ptt_evt_id_t new_uart_cmd) +{ + assert(uart_cmd_evt == PTT_EVENT_UNASSIGNED); + + uart_cmd_evt = new_uart_cmd; + ptt_handler_busy(); +} + +static void cmd_uart_cmd_unlock(void) +{ + if (uart_cmd_evt != PTT_EVENT_UNASSIGNED) { + ptt_event_free(uart_cmd_evt); + uart_cmd_evt = PTT_EVENT_UNASSIGNED; + ptt_handler_free(); + ptt_uart_print_prompt(); + } +} + +static inline bool cmd_is_uart_cmd_locked(void) +{ + return (uart_cmd_evt == PTT_EVENT_UNASSIGNED) ? false : true; +} + +static inline bool cmd_is_uart_cmd_locked_by(ptt_evt_id_t evt_id) +{ + return (evt_id == uart_cmd_evt) ? true : false; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_dut_mode.c b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_dut_mode.c new file mode 100644 index 000000000000..c1ef79ce2095 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_dut_mode.c @@ -0,0 +1,614 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: implementation of Zigbee RF Performance Test Plan DUT mode */ + +#include +#include + +#include "ctrl/ptt_trace.h" +#include "rf/ptt_rf.h" + +#include "ptt_proto.h" + +#include "ptt_ctrl_internal.h" +#include "ptt_events_internal.h" +#include "ptt_modes.h" +#include "ptt_zb_perf_dut_mode.h" + +#ifdef TESTS +#include "test_dut_conf.h" +#endif + +/** currently processed event */ +static ptt_evt_id_t cur_evt; + +/* current event handlers */ +static void dut_rf_tx_finished(ptt_evt_id_t evt_id); +static void dut_rf_tx_failed(ptt_evt_id_t evt_id); +static void dut_idle_packet_proc(void); +static enum ptt_ret dut_ping(void); +static enum ptt_ret dut_set_channel(void); +static enum ptt_ret dut_set_power(void); +static enum ptt_ret dut_get_power(void); +static enum ptt_ret dut_stream(void); +static enum ptt_ret dut_start_rx_test(void); +static enum ptt_ret dut_hw_version(void); +static enum ptt_ret dut_sw_version(void); +static enum ptt_ret dut_set_antenna(void); +static enum ptt_ret dut_get_antenna(void); + +/* new event handlers */ +static void dut_rf_rx_done(ptt_evt_id_t new_evt_id); +static void dut_end_rx_test(ptt_evt_id_t new_evt_id); + +static void dut_stream_stop(ptt_evt_id_t timer_evt_id); + +static ptt_pkt_len_t dut_form_stat_report(uint8_t *pkt, ptt_pkt_len_t pkt_max_size); + +static inline void dut_change_cur_state(ptt_evt_state_t state); +static inline void dut_store_cur_evt(ptt_evt_id_t evt_id); +static inline void dut_reset_cur_evt(void); + +#ifdef TESTS +#include "test_dut_wrappers.c" +#endif + +enum ptt_ret ptt_zb_perf_dut_mode_init(void) +{ + PTT_TRACE_FUNC_ENTER(); + + cur_evt = PTT_EVENT_UNASSIGNED; + struct ptt_ext_evts_handlers_s *handlers = ptt_ctrl_get_handlers(); + + handlers->rf_tx_finished = dut_rf_tx_finished; + handlers->rf_tx_failed = dut_rf_tx_failed; + handlers->rf_rx_done = dut_rf_rx_done; + + PTT_TRACE_FUNC_EXIT(); + return PTT_RET_SUCCESS; +} + +enum ptt_ret ptt_zb_perf_dut_mode_uninit(void) +{ + PTT_TRACE_FUNC_ENTER(); + + if (cur_evt != PTT_EVENT_UNASSIGNED) { + dut_reset_cur_evt(); + } + + PTT_TRACE_FUNC_EXIT(); + return PTT_RET_SUCCESS; +} + +static void dut_rf_rx_done(ptt_evt_id_t new_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_evt_id); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(new_evt_id); + + assert(evt_data != NULL); + + if (!ptt_proto_check_packet(evt_data->arr, evt_data->len)) { + PTT_TRACE("%s not protocol packet received and ignored\n", __func__); + ptt_event_free(new_evt_id); + } else { + ptt_event_set_cmd(new_evt_id, evt_data->arr[PTT_CMD_CODE_START]); + + if (cur_evt == PTT_EVENT_UNASSIGNED) { + /* store the event as currently processed */ + dut_store_cur_evt(new_evt_id); + dut_idle_packet_proc(); + } else { + switch (ptt_event_get_state(cur_evt)) { + case DUT_STATE_RX_TEST_WAIT_FOR_END: + dut_end_rx_test(new_evt_id); + break; + + default: + PTT_TRACE("%s: state isn't idle cmd %d state %d\n", __func__, + ptt_event_get_cmd(cur_evt), ptt_event_get_state(cur_evt)); + ptt_event_free(new_evt_id); + break; + } + } + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void dut_idle_packet_proc(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + PTT_TRACE("%s: cmd %d state %d\n", __func__, ptt_event_get_cmd(cur_evt), + ptt_event_get_state(cur_evt)); + + switch (ptt_event_get_cmd(cur_evt)) { + case PTT_CMD_PING: + ret = dut_ping(); + break; + + case PTT_CMD_SET_CHANNEL: + ret = dut_set_channel(); + dut_reset_cur_evt(); + break; + + case PTT_CMD_SET_POWER: + ret = dut_set_power(); + dut_reset_cur_evt(); + break; + + case PTT_CMD_GET_POWER: + ret = dut_get_power(); + break; + + case PTT_CMD_STREAM: + ret = dut_stream(); + break; + + case PTT_CMD_START_RX_TEST: + ret = dut_start_rx_test(); + break; + + case PTT_CMD_GET_HARDWARE_VERSION: + ret = dut_hw_version(); + break; + + case PTT_CMD_GET_SOFTWARE_VERSION: + ret = dut_sw_version(); + break; + + case PTT_CMD_SET_ANTENNA: + ret = dut_set_antenna(); + dut_reset_cur_evt(); + break; + + case PTT_CMD_GET_ANTENNA: + ret = dut_get_antenna(); + break; + + default: + PTT_TRACE("%s: unknown command cmd %d state %d\n", __func__, + ptt_event_get_cmd(cur_evt), ptt_event_get_state(cur_evt)); + dut_reset_cur_evt(); + break; + } + + if (ret != PTT_RET_SUCCESS) { + dut_reset_cur_evt(); + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void dut_rf_tx_finished(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + assert(evt_id == cur_evt); + + PTT_TRACE("%s: cmd %d state %d\n", __func__, ptt_event_get_cmd(cur_evt), + ptt_event_get_state(cur_evt)); + + switch (ptt_event_get_state(cur_evt)) { + case DUT_STATE_ACK_SENDING: + case DUT_STATE_POWER_SENDING: + case DUT_STATE_RX_TEST_REPORT_SENDING: + case DUT_STATE_HW_VERSION_SENDING: + case DUT_STATE_SW_VERSION_SENDING: + case DUT_STATE_ANTENNA_SENDING: + dut_reset_cur_evt(); + break; + + default: + PTT_TRACE("%s: inappropriate state cmd %d state %d\n", __func__, + ptt_event_get_cmd(cur_evt), ptt_event_get_state(cur_evt)); + break; + } + + PTT_TRACE_FUNC_EXIT(); +} + +static void dut_rf_tx_failed(ptt_evt_id_t evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(evt_id); + + assert(evt_id == cur_evt); + + PTT_TRACE("%s: cmd %d state %d\n", __func__, ptt_event_get_cmd(cur_evt), + ptt_event_get_state(cur_evt)); + + switch (ptt_event_get_state(cur_evt)) { + case DUT_STATE_ACK_SENDING: + case DUT_STATE_POWER_SENDING: + case DUT_STATE_RX_TEST_REPORT_SENDING: + case DUT_STATE_HW_VERSION_SENDING: + case DUT_STATE_SW_VERSION_SENDING: + case DUT_STATE_ANTENNA_SENDING: + dut_reset_cur_evt(); + break; + + default: + PTT_TRACE("%s: inappropriate state cmd %d state %d\n", __func__, + ptt_event_get_cmd(cur_evt), ptt_event_get_state(cur_evt)); + break; + } + + PTT_TRACE_FUNC_EXIT(); +} + +static enum ptt_ret dut_ping(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + uint8_t *p = evt_data->arr; + + dut_change_cur_state(DUT_STATE_ACK_SENDING); + + evt_data->len = ptt_proto_construct_header(p, PTT_CMD_ACK, PTT_EVENT_DATA_SIZE); + + enum ptt_ret ret = ptt_rf_send_packet(cur_evt, evt_data->arr, evt_data->len); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret dut_set_channel(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + if ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_SET_CHANNEL) != evt_data->len) { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + ret = PTT_RET_INVALID_COMMAND; + } else { + uint32_t mask = ptt_betoh32_val(&evt_data->arr[PTT_PAYLOAD_START]); + + ret = ptt_rf_set_channel_mask(cur_evt, mask); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret dut_set_power(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + if ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_SET_POWER) != evt_data->len) { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + ret = PTT_RET_INVALID_COMMAND; + } else { + int8_t power = (int8_t)(evt_data->arr[PTT_PAYLOAD_START]); + + ret = ptt_rf_set_power(cur_evt, power); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret dut_get_power(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + uint8_t *p = evt_data->arr; + + dut_change_cur_state(DUT_STATE_POWER_SENDING); + + evt_data->len = + ptt_proto_construct_header(p, PTT_CMD_GET_POWER_RESPONSE, PTT_EVENT_DATA_SIZE); + p[evt_data->len] = ptt_rf_get_power(); + evt_data->len++; + + enum ptt_ret ret = ptt_rf_send_packet(cur_evt, evt_data->arr, evt_data->len); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret dut_set_antenna(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + if ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_SET_ANTENNA) != evt_data->len) { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + ret = PTT_RET_INVALID_COMMAND; + } else { + uint8_t antenna = evt_data->arr[PTT_PAYLOAD_START]; + + ret = ptt_rf_set_antenna(cur_evt, antenna); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret dut_get_antenna(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + uint8_t *p = evt_data->arr; + + dut_change_cur_state(DUT_STATE_ANTENNA_SENDING); + + evt_data->len = + ptt_proto_construct_header(p, PTT_CMD_GET_ANTENNA_RESPONSE, PTT_EVENT_DATA_SIZE); + p[evt_data->len] = ptt_rf_get_antenna(); + evt_data->len++; + + enum ptt_ret ret = ptt_rf_send_packet(cur_evt, evt_data->arr, evt_data->len); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + return ret; +} + +static enum ptt_ret dut_stream(void) +{ + PTT_TRACE_FUNC_ENTER(); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + if ((PTT_PREAMBLE_LEN + PTT_CMD_CODE_LEN + PTT_PAYLOAD_LEN_STREAM) != evt_data->len) { + PTT_TRACE("%s: invalid length %d\n", __func__, evt_data->len); + ret = PTT_RET_INVALID_COMMAND; + } else { + uint16_t duration = ptt_betoh16_val(&evt_data->arr[PTT_PAYLOAD_START]); + + if (duration != 0) { + ret = ptt_timer_add(duration, dut_stream_stop, cur_evt); + + if (ret == PTT_RET_SUCCESS) { + struct ptt_ltx_payload_s *ltx_payload = + ptt_rf_get_custom_ltx_payload(); + + ltx_payload->len = PTT_CUSTOM_LTX_PAYLOAD_MAX_SIZE; + + ptt_random_vector_generate(ltx_payload->arr, ltx_payload->len); + + ret = ptt_rf_start_modulated_stream(cur_evt, ltx_payload->arr, + ltx_payload->len); + + if (ret == PTT_RET_SUCCESS) { + dut_change_cur_state(DUT_STATE_STREAM_EMITTING); + } else { + ptt_timer_remove(cur_evt); + PTT_TRACE("%s: start_modulated_stream returns %d. Aborting", + __func__, ret); + } + } + } else { + dut_reset_cur_evt(); + } + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static void dut_stream_stop(ptt_evt_id_t timer_evt_id) +{ + PTT_TRACE_FUNC_ENTER(); + + assert(timer_evt_id == cur_evt); + + enum ptt_ret ret = ptt_rf_stop_modulated_stream(cur_evt); + + dut_reset_cur_evt(); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static enum ptt_ret dut_start_rx_test(void) +{ + PTT_TRACE_FUNC_ENTER(); + + /* we will store protocol packets counter in context of cur_evt, + * lets erase it just in case + */ + struct ptt_evt_ctx_data_s *cur_ctx_data = ptt_event_get_ctx_data(cur_evt); + + assert(cur_ctx_data != NULL); + + uint32_t *proto_pkts = (uint32_t *)cur_ctx_data; + + *proto_pkts = 0; + + enum ptt_ret ret = ptt_rf_start_statistic(cur_evt); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ret %d\n", __func__, ret); + ret = PTT_RET_INVALID_COMMAND; + } else { + dut_change_cur_state(DUT_STATE_RX_TEST_WAIT_FOR_END); + } + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static void dut_end_rx_test(ptt_evt_id_t new_evt_id) +{ + PTT_TRACE_FUNC_ENTER_WITH_EVT(new_evt_id); + + enum ptt_ret ret = PTT_RET_SUCCESS; + + struct ptt_evt_ctx_data_s *cur_ctx_data = ptt_event_get_ctx_data(cur_evt); + + assert(cur_ctx_data != NULL); + + uint32_t *proto_pkts = (uint32_t *)cur_ctx_data; + + ++(*proto_pkts); + + if (ptt_event_get_cmd(new_evt_id) == PTT_CMD_END_RX_TEST) { + ret = ptt_rf_end_statistic(cur_evt); + + if (ret != PTT_RET_SUCCESS) { + PTT_TRACE("%s: ret %d\n", __func__, ret); + } else { + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + uint8_t *p = evt_data->arr; + + dut_change_cur_state(DUT_STATE_RX_TEST_REPORT_SENDING); + + evt_data->len = + ptt_proto_construct_header(p, PTT_CMD_REPORT, PTT_EVENT_DATA_SIZE); + evt_data->len += dut_form_stat_report(&p[evt_data->len], + PTT_EVENT_DATA_SIZE - evt_data->len); + + ret = ptt_rf_send_packet(cur_evt, evt_data->arr, evt_data->len); + } + } + + ptt_event_free(new_evt_id); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); +} + +static enum ptt_ret dut_hw_version(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + uint8_t *p = evt_data->arr; + + dut_change_cur_state(DUT_STATE_HW_VERSION_SENDING); + + evt_data->len = ptt_proto_construct_header(p, PTT_CMD_GET_HARDWARE_VERSION_RESPONSE, + PTT_EVENT_DATA_SIZE); + p[evt_data->len] = ptt_ctrl_get_hw_version(); + evt_data->len++; + + enum ptt_ret ret = ptt_rf_send_packet(cur_evt, evt_data->arr, evt_data->len); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static enum ptt_ret dut_sw_version(void) +{ + PTT_TRACE_FUNC_ENTER(); + + struct ptt_evt_data_s *evt_data = ptt_event_get_data(cur_evt); + + assert(evt_data != NULL); + + uint8_t *p = evt_data->arr; + + dut_change_cur_state(DUT_STATE_SW_VERSION_SENDING); + + evt_data->len = ptt_proto_construct_header(p, PTT_CMD_GET_SOFTWARE_VERSION_RESPONSE, + PTT_EVENT_DATA_SIZE); + p[evt_data->len] = ptt_ctrl_get_sw_version(); + evt_data->len++; + + enum ptt_ret ret = ptt_rf_send_packet(cur_evt, evt_data->arr, evt_data->len); + + PTT_TRACE_FUNC_EXIT_WITH_VALUE(ret); + + return ret; +} + +static ptt_pkt_len_t dut_form_stat_report(uint8_t *pkt, ptt_pkt_len_t pkt_max_size) +{ + assert(pkt != NULL); + assert(pkt_max_size >= PTT_PAYLOAD_LEN_REPORT); + + ptt_pkt_len_t len = 0; + uint8_t *p = pkt; + struct ptt_rf_stat_s stat = ptt_rf_get_stat_report(); + + struct ptt_evt_ctx_data_s *cur_ctx_data = ptt_event_get_ctx_data(cur_evt); + + assert(cur_ctx_data != NULL); + + uint32_t *proto_pkts = (uint32_t *)cur_ctx_data; + + ptt_htobe32((uint8_t *)&stat.total_pkts, &p[len]); + len += sizeof(stat.total_pkts); + + ptt_htobe32((uint8_t *)proto_pkts, &p[len]); + len += sizeof(*proto_pkts); + + ptt_htobe32((uint8_t *)&stat.total_lqi, &p[len]); + len += sizeof(stat.total_lqi); + + ptt_htobe32((uint8_t *)&stat.total_rssi, &p[len]); + len += sizeof(stat.total_rssi); + + assert(len == PTT_PAYLOAD_LEN_REPORT); + + return len; +} + +static inline void dut_change_cur_state(ptt_evt_state_t state) +{ + PTT_TRACE("%s: state %d", __func__, state); + + ptt_event_set_state(cur_evt, state); +} + +static inline void dut_store_cur_evt(ptt_evt_id_t evt_id) +{ + assert(cur_evt == PTT_EVENT_UNASSIGNED); + + cur_evt = evt_id; +} + +static inline void dut_reset_cur_evt(void) +{ + ptt_event_free(cur_evt); + cur_evt = PTT_EVENT_UNASSIGNED; +} diff --git a/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_dut_mode.h b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_dut_mode.h new file mode 100644 index 000000000000..84d7ca741aa2 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ctrl/ptt_zb_perf_dut_mode.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: implementation of Zigbee RF Performance Test Plan DUT mode */ + +#ifndef PTT_MODE_ZB_PERF_DUT_H__ +#define PTT_MODE_ZB_PERF_DUT_H__ + +#include + +#include "ctrl/ptt_ctrl.h" +#include "ctrl/ptt_events.h" +#include "ctrl/ptt_timers.h" +#include "ctrl/ptt_uart.h" + +#include "ptt_errors.h" + +/** possible states of library in DUT mode */ +enum dut_state_t { + DUT_STATE_IDLE = 0, /**< waiting for next command */ + DUT_STATE_ACK_SENDING, /**< rf module send ack command */ + DUT_STATE_POWER_SENDING, /**< DUT sends power */ + DUT_STATE_STREAM_EMITTING, /**< DUT emits modulated stream */ + DUT_STATE_RX_TEST_WAIT_FOR_END, /**< rf module wait for end_rx_test command */ + DUT_STATE_RX_TEST_REPORT_SENDING, /**< rf module send end_rx_test command */ + DUT_STATE_HW_VERSION_SENDING, /**< DUT sends hardware version */ + DUT_STATE_SW_VERSION_SENDING, /**< DUT sends software version */ + DUT_STATE_ANTENNA_SENDING, /**< DUT sends antenna */ + DUT_STATE_N /**< states count */ +}; + +#endif /* PTT_MODE_ZB_PERF_DUT_H__ */ diff --git a/samples/peripheral/802154_phy_test/src/main.c b/samples/peripheral/802154_phy_test/src/main.c new file mode 100644 index 000000000000..c194a69da489 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/main.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +#include +#include + +#include "rf_proc.h" +#include "timer_proc.h" +#include "comm_proc.h" +#include "periph_proc.h" + +#include + LOG_MODULE_REGISTER(phy_tt); + +/* size of stack area used by each thread */ +#define RF_THREAD_STACKSIZE (1024u) +#define COMM_THREAD_STACKSIZE (1024u) + +/* scheduling priority used by each thread */ +#define RF_THREAD_PRIORITY (7u) +#define COMM_THREAD_PRIORITY (7u) + +void ptt_do_reset_ext(void) +{ + NVIC_SystemReset(); +} + +static int setup(const struct device *dev) +{ + LOG_INF("Setup started"); + + ARG_UNUSED(dev); + + periph_init(); + + rf_init(); + + comm_init(); + + /* initialize ptt library */ + ptt_init(launch_ptt_process_timer, ptt_get_max_time()); + + return 0; +} + +SYS_INIT(setup, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); + +K_THREAD_DEFINE(rf_id, RF_THREAD_STACKSIZE, rf_thread, NULL, NULL, NULL, RF_THREAD_PRIORITY, 0, 0); + +K_THREAD_DEFINE(comm_id, COMM_THREAD_STACKSIZE, comm_proc, NULL, NULL, NULL, COMM_THREAD_PRIORITY, + 0, 0); diff --git a/samples/peripheral/802154_phy_test/src/periph_proc.c b/samples/peripheral/802154_phy_test/src/periph_proc.c new file mode 100644 index 000000000000..f96802c1e5ef --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/periph_proc.c @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: Periphery configuring and processing */ + +#include +#include + +#include + +#include "periph_proc.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if defined(DPPI_PRESENT) +#include +#else +#include +#endif + +#include +LOG_MODULE_REGISTER(periph); + +/* Timer instance used for HFCLK output */ +#define PTT_CLK_TIMER 2 + +static struct onoff_client hfclk_cli; +static nrfx_timer_t clk_timer = NRFX_TIMER_INSTANCE(PTT_CLK_TIMER); + +/* The devicetree node identifier for the "led0" alias. */ +#define LED0_NODE DT_ALIAS(led0) + +#if DT_NODE_HAS_STATUS(LED0_NODE, okay) +#define LED0 DT_GPIO_LABEL(LED0_NODE, gpios) +#define PIN DT_GPIO_PIN(LED0_NODE, gpios) +#define FLAGS DT_GPIO_FLAGS(LED0_NODE, gpios) +#else +/* A build error here means your board isn't set up to blink an LED. */ +#error "Unsupported board: led0 devicetree alias is not defined" +#define LED0 "" +#define PIN 0 +#define FLAGS 0 +#endif + +#define CLOCK_NODE DT_INST(0, nordic_nrf_clock) + +static const struct device *indication_led_dev; +static const struct device *gpio_port0_dev; + +/* Check if the system has GPIO port 1 */ +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) +static const struct device *gpio_port1_dev; + +#endif + +#if defined(DPPI_PRESENT) +uint8_t ppi_channel; + +#else +nrf_ppi_channel_t ppi_channel; + +#endif + +static void hfclk_on_callback(struct onoff_manager *mgr, struct onoff_client *cli, uint32_t state, + int res) +{ + /* do nothing */ +} + +static void clk_timer_handler(nrf_timer_event_t event_type, void *context) +{ + /* do nothing */ +} + +void periph_init(void) +{ + nrfx_err_t err_code; + int ret; + + /* Enable HFCLK */ + struct onoff_manager *mgr = z_nrf_clock_control_get_onoff(CLOCK_CONTROL_NRF_SUBSYS_HF); + + __ASSERT_NO_MSG(mgr != NULL); + + sys_notify_init_callback(&hfclk_cli.notify, hfclk_on_callback); + + ret = onoff_request(mgr, &hfclk_cli); + __ASSERT_NO_MSG(ret >= 0); + + nrfx_timer_config_t clk_timer_cfg = NRFX_TIMER_DEFAULT_CONFIG; + + err_code = nrfx_timer_init(&clk_timer, &clk_timer_cfg, clk_timer_handler); + NRFX_ASSERT(err_code); + + err_code = nrfx_gpiote_init(0); + NRFX_ASSERT(err_code); + + indication_led_dev = device_get_binding(LED0); + assert(indication_led_dev); + + ret = gpio_pin_configure(indication_led_dev, PIN, GPIO_OUTPUT_ACTIVE | FLAGS); + + assert(ret == 0); + gpio_pin_set(indication_led_dev, PIN, false); + + gpio_port0_dev = device_get_binding(DT_LABEL(DT_NODELABEL(gpio0))); + assert(gpio_port0_dev); + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) + gpio_port1_dev = device_get_binding(DT_LABEL(DT_NODELABEL(gpio1))); + assert(gpio_port1_dev); +#endif +} + +uint32_t ptt_random_get_ext(void) +{ + return sys_rand32_get(); +} + +bool ptt_clk_out_ext(uint8_t pin, bool mode) +{ + uint32_t compare_evt_addr; + nrfx_err_t err; + + if (!nrf_gpio_pin_present_check(pin)) { + return false; + } + + if (mode) { + nrfx_timer_extended_compare(&clk_timer, (nrf_timer_cc_channel_t)0, 1, + NRF_TIMER_SHORT_COMPARE0_CLEAR_MASK, false); + + nrfx_gpiote_out_config_t const out_config = { + .action = NRF_GPIOTE_POLARITY_TOGGLE, + .init_state = 0, + .task_pin = true, + }; + + /* Initialize output pin. SET task will turn the LED on, + * CLR will turn it off and OUT will toggle it. + */ + err = nrfx_gpiote_out_init(pin, &out_config); + if (err != NRFX_SUCCESS) { + LOG_ERR("nrfx_gpiote_out_init error: %08x", err); + return false; + } + + compare_evt_addr = + nrfx_timer_event_address_get(&clk_timer, NRF_TIMER_EVENT_COMPARE0); + + nrfx_gpiote_out_task_enable(pin); + + /* Allocate a (D)PPI channel. */ +#if defined(DPPI_PRESENT) + err = nrfx_dppi_channel_alloc(&ppi_channel); +#else + err = nrfx_ppi_channel_alloc(&ppi_channel); +#endif + if (err != NRFX_SUCCESS) { + LOG_ERR("(D)PPI channel allocation error: %08x", err); + return false; + } + + nrfx_gppi_channel_endpoints_setup( + ppi_channel, compare_evt_addr, + nrf_gpiote_task_address_get(NRF_GPIOTE, nrfx_gpiote_in_event_get(pin))); + + /* Enable (D)PPI channel. */ +#if defined(DPPI_PRESENT) + err = nrfx_dppi_channel_enable(ppi_channel); +#else + err = nrfx_ppi_channel_enable(ppi_channel); +#endif + if (err != NRFX_SUCCESS) { + LOG_ERR("Failed to enable (D)PPI channel, error: %08x", err); + return false; + } + + nrfx_timer_enable(&clk_timer); + } else { + nrfx_timer_disable(&clk_timer); + nrfx_gpiote_out_task_disable(pin); +#if defined(DPPI_PRESENT) + err = nrfx_dppi_channel_free(ppi_channel); +#else + err = nrfx_ppi_channel_free(ppi_channel); +#endif + if (err != NRFX_SUCCESS) { + LOG_ERR("Failed to disable (D)PPI channel, error: %08x", err); + return false; + } + nrfx_gpiote_out_uninit(pin); + } + + return true; +} + +static const struct device *get_pin_port(uint32_t *pin) +{ + switch (nrf_gpio_pin_port_number_extract(pin)) { + case 0: + return gpio_port0_dev; + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(gpio1), okay) + case 1: + return gpio_port1_dev; + +#endif + default: + return NULL; + } +} + +bool ptt_set_gpio_ext(uint8_t pin, uint8_t value) +{ + int ret; + const struct device *port; + uint32_t pin_nr = pin; + + if (nrf_gpio_pin_present_check(pin_nr)) { + port = get_pin_port(&pin_nr); + if (port == NULL) { + return false; + } + + ret = gpio_pin_configure(port, pin_nr, GPIO_OUTPUT); + + if (ret == 0) { + ret = gpio_pin_set(port, pin_nr, value); + if (ret == 0) { + return true; + } + } + } + + return false; +} + +bool ptt_get_gpio_ext(uint8_t pin, uint8_t *value) +{ + int ret; + const struct device *port; + uint32_t pin_nr = pin; + + if (nrf_gpio_pin_present_check(pin_nr)) { + port = get_pin_port(&pin_nr); + if (port == NULL) { + return false; + } + + ret = gpio_pin_configure(port, pin_nr, GPIO_INPUT); + + if (ret == 0) { + *value = gpio_pin_get(port, pin_nr); + return true; + } + } + + return false; +} + +void ptt_set_dcdc_ext(bool enable) +{ +#if NRF_POWER_HAS_DCDCEN + nrf_power_dcdcen_set(NRF_POWER, enable); +#endif + +#if NRF_POWER_HAS_DCDCEN_VDDH + nrf_power_dcdcen_vddh_set(NRF_POWER, enable); +#endif + +#if !NRF_POWER_HAS_DCDCEN && !NRF_POWER_HAS_DCDCEN_VDDH +#pragma message "DC-DC related commands have no effect!" +#endif +} + +bool ptt_get_dcdc_ext(void) +{ +#if NRF_POWER_HAS_DCDCEN && NRF_POWER_HAS_DCDCEN_VDDH + return (nrf_power_dcdcen_get(NRF_POWER) || nrf_power_dcdcen_vddh_get(NRF_POWER)); +#elif NRF_POWER_HAS_DCDCEN + return nrf_power_dcdcen_get(NRF_POWER); +#elif NRF_POWER_HAS_DCDCEN_VDDH + return nrf_power_dcdcen_vddh_get(NRF_POWER); +#else + return false; +#endif +} + +void ptt_set_icache_ext(bool enable) +{ +#if defined(NVMC_FEATURE_CACHE_PRESENT) + if (enable) { + nrfx_nvmc_icache_enable(); + } else { + nrfx_nvmc_icache_disable(); + } +#else +#pragma message "ICACHE related command have no effect" +#endif +} + +bool ptt_get_icache_ext(void) +{ +#if defined(NVMC_FEATURE_CACHE_PRESENT) + return nrf_nvmc_icache_enable_check(NRF_NVMC); +#else + return false; +#endif +} + +bool ptt_get_temp_ext(int32_t *temp) +{ + if (temp == NULL) { + return false; + } + + *temp = nrf_802154_temperature_get(); + + return true; +} + +void ptt_ctrl_led_indication_on_ext(void) +{ + gpio_pin_set(indication_led_dev, PIN, true); +} + +void ptt_ctrl_led_indication_off_ext(void) +{ + gpio_pin_set(indication_led_dev, PIN, false); +} diff --git a/samples/peripheral/802154_phy_test/src/ptt_conf.c b/samples/peripheral/802154_phy_test/src/ptt_conf.c new file mode 100644 index 000000000000..500650c0b910 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/ptt_conf.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: Production configuration routines */ + +#include +#include +#include + +bool ptt_get_mode_mask_ext(uint32_t *mode_mask) +{ + assert(mode_mask != NULL); + +#ifdef CONFIG_PTT_DUT_MODE + *mode_mask = 0x00000001; +#elif CONFIG_PTT_CMD_MODE + *mode_mask = 0x00000002; +#else + *mode_mask = 0x00000003; +#endif + return true; +} + +bool ptt_get_channel_mask_ext(uint32_t *channel_mask) +{ + assert(channel_mask != NULL); + + *channel_mask = CONFIG_PTT_CHANNEL_MASK; + return true; +} + +bool ptt_get_power_ext(int8_t *power) +{ + assert(power != NULL); + + *power = CONFIG_PTT_POWER; + return true; +} + +bool ptt_get_antenna_ext(uint8_t *antenna) +{ + assert(antenna != NULL); + +#if CONFIG_PTT_ANTENNA_DIVERSITY + *antenna = CONFIG_PTT_ANTENNA_NUMBER; + return true; +#else + return false; +#endif +} + +bool ptt_get_sw_version_ext(uint8_t *sw_version) +{ + assert(sw_version != NULL); + + *sw_version = CONFIG_PTT_SW_VERSION; + return true; +} + +bool ptt_get_hw_version_ext(uint8_t *hw_version) +{ + assert(hw_version != NULL); + + *hw_version = CONFIG_PTT_HW_VERSION; + return true; +} + +bool ptt_get_ant_mode_ext(uint8_t *ant_mode) +{ + assert(ant_mode != NULL); + +#if CONFIG_PTT_ANTENNA_DIVERSITY +#if CONFIG_PTT_ANT_MODE_AUTO + /* TODO: Implement when antenna diversity is supported in NCS */ +#elif CONFIG_PTT_ANT_MODE_MANUAL + /* TODO: Implement when antenna diversity is supported in NCS */ +#else + /* TODO: Implement when antenna diversity is supported in NCS */ +#endif + return true; +#else + return false; +#endif +} + +bool ptt_get_ant_num_ext(uint8_t *ant_num) +{ + assert(ant_num != NULL); + +#if CONFIG_PTT_ANTENNA_DIVERSITY + *ant_num = CONFIG_PTT_ANTENNA_NUMBER; + return true; +#else + return false; +#endif +} diff --git a/samples/peripheral/802154_phy_test/src/rf/ptt_rf.c b/samples/peripheral/802154_phy_test/src/rf/ptt_rf.c new file mode 100644 index 000000000000..39ec36e8b8b1 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/rf/ptt_rf.c @@ -0,0 +1,631 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: interface part of radio module */ + +#include +#include + +#include "ctrl/ptt_ctrl.h" +#include "ctrl/ptt_trace.h" +#include "rf/ptt_rf.h" +#include "ptt.h" + +#include "ptt_rf_api.h" +#include "ptt_rf_internal.h" + +struct ptt_rf_ctx_s ptt_rf_ctx; + +static enum ptt_ret ptt_rf_try_lock(ptt_evt_id_t evt_id); +static inline bool ptt_rf_is_locked(void); +static inline bool ptt_rf_is_locked_by(ptt_evt_id_t evt_id); +static inline ptt_evt_id_t ptt_rf_unlock(void); + +static enum ptt_ret ptt_rf_promiscuous_set(bool value); + +static void ptt_rf_stat_inc(int8_t rssi, uint8_t lqi); + +static void ptt_rf_set_default_channel(void); +static void ptt_rf_set_default_power(void); +static void ptt_rf_set_default_antenna(void); + +void ptt_rf_init(void) +{ + PTT_TRACE("%s ->\n", __func__); + ptt_rf_ctx = (struct ptt_rf_ctx_s){ 0 }; + ptt_rf_unlock(); + + ptt_rf_set_default_channel(); + ptt_rf_set_default_power(); + ptt_rf_set_default_antenna(); + + /* we need raw PHY packets without any filtering */ + ptt_rf_promiscuous_set(true); + ptt_rf_receive_ext(); + PTT_TRACE("%s -<\n", __func__); +} + +void ptt_rf_uninit(void) +{ + PTT_TRACE("%s\n", __func__); +} + +void ptt_rf_reset(void) +{ + PTT_TRACE("%s ->\n", __func__); + ptt_rf_uninit(); + ptt_rf_init(); + PTT_TRACE("%s -<\n", __func__); +} + +static void ptt_rf_set_default_channel(void) +{ + uint32_t channel_mask; + enum ptt_ret ret = PTT_RET_SUCCESS; + + /* try to set channel from prod config */ + if (ptt_get_channel_mask_ext(&channel_mask)) { + ret = ptt_rf_set_channel_mask(PTT_RF_EVT_UNLOCKED, channel_mask); + if (ret != PTT_RET_SUCCESS) { + /* set default channel */ + ptt_rf_set_channel(PTT_RF_EVT_UNLOCKED, PTT_RF_DEFAULT_CHANNEL); + } + } else { + /* set default channel */ + ptt_rf_set_channel(PTT_RF_EVT_UNLOCKED, PTT_RF_DEFAULT_CHANNEL); + } +} + +static void ptt_rf_set_default_power(void) +{ + int8_t power = PTT_RF_DEFAULT_POWER; + + /* set power from prod config */ + if (ptt_get_power_ext(&power)) { + ptt_rf_set_power(PTT_RF_EVT_UNLOCKED, power); + } else { + ptt_rf_set_power(PTT_RF_EVT_UNLOCKED, PTT_RF_DEFAULT_POWER); + } +} + +static void ptt_rf_set_default_antenna(void) +{ + uint8_t antenna = PTT_RF_DEFAULT_ANTENNA; + + /* set antenna from prod config */ + if (ptt_get_antenna_ext(&antenna)) { + ptt_rf_set_antenna(PTT_RF_EVT_UNLOCKED, antenna); + } else { + ptt_rf_set_antenna(PTT_RF_EVT_UNLOCKED, PTT_RF_DEFAULT_ANTENNA); + } +} + +void ptt_rf_push_packet(const uint8_t *pkt, ptt_pkt_len_t len, int8_t rssi, uint8_t lqi) +{ + ptt_rf_stat_inc(rssi, lqi); + ptt_ctrl_rf_push_packet(pkt, len, rssi, lqi); +} + +void ptt_rf_tx_finished(void) +{ + if (ptt_rf_is_locked()) { + /* have to unlock before passing control out of RF module */ + ptt_evt_id_t evt_id = ptt_rf_unlock(); + + ptt_ctrl_rf_tx_finished(evt_id); + } else { + PTT_TRACE("%s: called, but rf module is not locked\n", __func__); + /* we get event although we didn't send a packet, just pass it */ + } +} + +void ptt_rf_tx_failed(ptt_rf_tx_error_t tx_error) +{ + if (ptt_rf_is_locked()) { + /* have to unlock before passing control out of RF module */ + ptt_evt_id_t evt_id = ptt_rf_unlock(); + + ptt_ctrl_rf_tx_failed(evt_id, tx_error); + } else { + PTT_TRACE("%s: called, but rf module is not locked\n", __func__); + /* we get event although we didn't send a packet, just pass it */ + } +} + +void ptt_rf_rx_failed(ptt_rf_rx_error_t rx_error) +{ + ptt_ctrl_rf_rx_failed(rx_error); +} + +void ptt_rf_cca_done(bool result) +{ + if (ptt_rf_is_locked()) { + /* have to unlock before passing control out of RF module */ + ptt_evt_id_t evt_id = ptt_rf_unlock(); + + ptt_ctrl_rf_cca_done(evt_id, result); + } else { + PTT_TRACE("%s: called, but rf module is not locked\n", __func__); + /* we get event although we didn't send a packet, just pass it */ + } +} + +void ptt_rf_cca_failed(void) +{ + if (ptt_rf_is_locked()) { + /* have to unlock before passing control out of RF module */ + ptt_evt_id_t evt_id = ptt_rf_unlock(); + + ptt_ctrl_rf_cca_failed(evt_id); + } else { + PTT_TRACE("%s: called, but rf module is not locked\n", __func__); + /* we get event although we didn't send a packet, just pass it */ + } +} + +enum ptt_ret ptt_rf_cca(ptt_evt_id_t evt_id, uint8_t mode) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + /* will be unlocked inside ptt_rf_cca_done/ptt_rf_cca_failed functions */ + if (false == ptt_rf_cca_ext(mode)) { + ret = PTT_RET_BUSY; + } + + if (ret != PTT_RET_SUCCESS) { + ptt_rf_unlock(); + } + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +void ptt_rf_ed_detected(ptt_ed_t result) +{ + if (ptt_rf_is_locked()) { + /* have to unlock before passing control out of RF module */ + ptt_evt_id_t evt_id = ptt_rf_unlock(); + + ptt_ctrl_rf_ed_detected(evt_id, result); + } else { + PTT_TRACE("%s: called, but rf module does not locked\n", __func__); + /* we get event although we didn't send a packet, just pass it */ + } +} + +void ptt_rf_ed_failed(void) +{ + if (ptt_rf_is_locked()) { + /* have to unlock before passing control out of RF module */ + ptt_evt_id_t evt_id = ptt_rf_unlock(); + + ptt_ctrl_rf_ed_failed(evt_id); + } else { + PTT_TRACE("%s: called, but rf module does not locked\n", __func__); + /* we get event although we didn't send a packet, just pass it */ + } +} + +enum ptt_ret ptt_rf_ed(ptt_evt_id_t evt_id, uint32_t time_us) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + /* will be unlocked inside ptt_rf_ed_detected/ptt_rf_ed_failed functions */ + if (false == ptt_rf_ed_ext(time_us)) { + ret = PTT_RET_BUSY; + } + + if (ret != PTT_RET_SUCCESS) { + ptt_rf_unlock(); + } + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_rssi_measure_begin(ptt_evt_id_t evt_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + if (false == ptt_rf_rssi_measure_begin_ext()) { + ret = PTT_RET_BUSY; + } + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_rssi_last_get(ptt_evt_id_t evt_id, ptt_rssi_t *rssi) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + *rssi = ptt_rf_rssi_last_get_ext(); + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_send_packet(ptt_evt_id_t evt_id, const uint8_t *pkt, ptt_pkt_len_t len) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + if ((pkt == NULL) || (len == 0)) { + ret = PTT_RET_INVALID_VALUE; + } + + if (ret == PTT_RET_SUCCESS) { + /* will be unlocked inside ptt_rf_tx_finished/ptt_rf_tx_failed functions */ + if (false == ptt_rf_send_packet_ext(pkt, len, ptt_rf_ctx.cca_on_tx)) { + ret = PTT_RET_BUSY; + } + } + + if (ret != PTT_RET_SUCCESS) { + ptt_rf_unlock(); + } + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_set_channel_mask(ptt_evt_id_t evt_id, uint32_t mask) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + uint8_t channel = ptt_rf_convert_channel_mask_to_num(mask); + + if ((channel < PTT_CHANNEL_MIN) || (channel > PTT_CHANNEL_MAX)) { + ret = PTT_RET_INVALID_VALUE; + } else { + ret = ptt_rf_set_channel(evt_id, channel); + } + + return ret; +} + +enum ptt_ret ptt_rf_set_channel(ptt_evt_id_t evt_id, uint8_t channel) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + if ((channel < PTT_CHANNEL_MIN) || (channel > PTT_CHANNEL_MAX)) { + ret = PTT_RET_INVALID_VALUE; + } + + if (ret == PTT_RET_SUCCESS) { + ptt_rf_ctx.channel = channel; + ptt_rf_set_channel_ext(ptt_rf_ctx.channel); + } + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_set_short_address(ptt_evt_id_t evt_id, const uint8_t *short_addr) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + ptt_rf_set_short_address_ext(short_addr); + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_set_extended_address(ptt_evt_id_t evt_id, const uint8_t *extended_addr) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + ptt_rf_set_extended_address_ext(extended_addr); + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_set_pan_id(ptt_evt_id_t evt_id, const uint8_t *pan_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + ptt_rf_set_pan_id_ext(pan_id); + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +uint8_t ptt_rf_convert_channel_mask_to_num(uint32_t mask) +{ + uint8_t channel_num = 0; + + for (uint8_t i = PTT_CHANNEL_MIN; i <= PTT_CHANNEL_MAX; i++) { + if (((mask >> i) & 1u) == 1u) { + channel_num = i; + break; + } + } + + return channel_num; +} + +uint8_t ptt_rf_get_channel(void) +{ + return ptt_rf_ctx.channel; +} + +enum ptt_ret ptt_rf_set_power(ptt_evt_id_t evt_id, int8_t power) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + ptt_rf_set_power_ext(power); + ptt_rf_ctx.power = power; + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +int8_t ptt_rf_get_power(void) +{ + ptt_rf_ctx.power = ptt_rf_get_power_ext(); + return ptt_rf_ctx.power; +} + +enum ptt_ret ptt_rf_set_antenna(ptt_evt_id_t evt_id, uint8_t antenna) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + ptt_rf_set_antenna_ext(antenna); + ptt_rf_ctx.antenna = antenna; + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +uint8_t ptt_rf_get_antenna(void) +{ + ptt_rf_ctx.antenna = ptt_rf_get_antenna_ext(); + return ptt_rf_ctx.antenna; +} + +enum ptt_ret ptt_rf_start_statistic(ptt_evt_id_t evt_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + ptt_rf_ctx.stat = (struct ptt_rf_stat_s){ 0 }; + ptt_rf_ctx.stat_enabled = true; + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_end_statistic(ptt_evt_id_t evt_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_is_locked_by(evt_id)) { + ptt_rf_ctx.stat_enabled = false; + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +struct ptt_rf_stat_s ptt_rf_get_stat_report(void) +{ + return ptt_rf_ctx.stat; +} + +enum ptt_ret ptt_rf_start_modulated_stream(ptt_evt_id_t evt_id, const uint8_t *pkt, + ptt_pkt_len_t len) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + if ((pkt == NULL) || (len == 0)) { + ret = PTT_RET_INVALID_VALUE; + } + + if (ret == PTT_RET_SUCCESS) { + /* will be unlocked inside ptt_rf_stop_modulated_stream */ + if (false == ptt_rf_modulated_stream_ext(pkt, len)) { + ret = PTT_RET_BUSY; + } + } + + if (ret != PTT_RET_SUCCESS) { + ptt_rf_unlock(); + } + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_stop_modulated_stream(ptt_evt_id_t evt_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_is_locked_by(evt_id)) { + if (false == ptt_rf_receive_ext()) { + ret = PTT_RET_BUSY; + } + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_start_continuous_carrier(ptt_evt_id_t evt_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_try_lock(evt_id) == PTT_RET_SUCCESS) { + /* will be unlocked inside ptt_rf_stop_continuous_stream */ + if (false == ptt_rf_continuous_carrier_ext()) { + ret = PTT_RET_BUSY; + + ptt_rf_unlock(); + } + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_stop_continuous_carrier(ptt_evt_id_t evt_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_is_locked_by(evt_id)) { + if (false == ptt_rf_receive_ext()) { + ret = PTT_RET_BUSY; + } + + ptt_rf_unlock(); + } else { + ret = PTT_RET_BUSY; + } + + return ret; +} + +static enum ptt_ret ptt_rf_promiscuous_set(bool value) +{ + ptt_rf_promiscuous_set_ext(value); + + return 0; +} + +enum ptt_ret ptt_rf_receive(void) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_is_locked() || (false == ptt_rf_receive_ext())) { + ret = PTT_RET_BUSY; + } + + return ret; +} + +enum ptt_ret ptt_rf_sleep(void) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_is_locked() || (false == ptt_rf_sleep_ext())) { + ret = PTT_RET_BUSY; + } + + return ret; +} + +static inline ptt_evt_id_t ptt_rf_unlock(void) +{ + ptt_evt_id_t evt_id = ptt_rf_ctx.evt_lock; + + ptt_rf_ctx.evt_lock = PTT_RF_EVT_UNLOCKED; + + return evt_id; +} + +static inline bool ptt_rf_is_locked(void) +{ + return (ptt_rf_ctx.evt_lock == PTT_RF_EVT_UNLOCKED) ? false : true; +} + +static inline bool ptt_rf_is_locked_by(ptt_evt_id_t evt_id) +{ + return (evt_id == ptt_rf_ctx.evt_lock) ? true : false; +} + +static enum ptt_ret ptt_rf_try_lock(ptt_evt_id_t evt_id) +{ + enum ptt_ret ret = PTT_RET_SUCCESS; + + if (ptt_rf_is_locked()) { + ret = PTT_RET_BUSY; + } + + if (ret == PTT_RET_SUCCESS) { + ptt_rf_ctx.evt_lock = evt_id; + } + + return ret; +} + +static void ptt_rf_stat_inc(int8_t rssi, uint8_t lqi) +{ + if (ptt_rf_ctx.stat_enabled) { + ptt_rf_ctx.stat.total_pkts++; + /* according to B.3.10: + * Assumes no RSSI values measured that are greater than zero dBm + */ + if (rssi > 0) { + rssi = 0; + } + ptt_rf_ctx.stat.total_rssi += (rssi * (-1)); + ptt_rf_ctx.stat.total_lqi += lqi; + } +} + +inline struct ptt_ltx_payload_s *ptt_rf_get_custom_ltx_payload(void) +{ + return &(ptt_rf_ctx.ltx_payload); +} diff --git a/samples/peripheral/802154_phy_test/src/rf/ptt_rf_internal.h b/samples/peripheral/802154_phy_test/src/rf/ptt_rf_internal.h new file mode 100644 index 000000000000..2496b39ce712 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/rf/ptt_rf_internal.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: internal RF defines */ + +#ifndef PTT_RF_INTERNAL_H__ +#define PTT_RF_INTERNAL_H__ + +#include + +#include "ptt_types.h" + +#include "ctrl/ptt_events.h" + +#include "rf/ptt_rf.h" + +#define PTT_RF_EVT_UNLOCKED (PTT_EVENT_UNASSIGNED) +#define PTT_RF_DEFAULT_CHANNEL (PTT_CHANNEL_MIN) +/* @todo: arbitrary selected, change PTT_RF_DEFAULT_POWER to appropriate value after testing */ +#define PTT_RF_DEFAULT_POWER (-20) +#define PTT_RF_DEFAULT_ANTENNA 0u + +/** RF module context */ +struct ptt_rf_ctx_s { + uint8_t channel; /**< configured RF channel */ + int8_t power; /**< configured RF power */ + uint8_t antenna; /**< configured RF antenna */ + ptt_evt_id_t evt_lock; /**< current event processing by RF module */ + bool cca_on_tx; /**< perform CCA before transmission or not */ + bool stat_enabled; /**< statistic gathering enabled */ + struct ptt_rf_stat_s stat; /**< received packets statistic */ + struct ptt_ltx_payload_s ltx_payload; /**< raw payload for 'custom ltx' command */ +}; + +#endif /* PTT_RF_INTERNAL_H__ */ diff --git a/samples/peripheral/802154_phy_test/src/rf_proc.c b/samples/peripheral/802154_phy_test/src/rf_proc.c new file mode 100644 index 000000000000..b9a3fc6aa64f --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/rf_proc.c @@ -0,0 +1,429 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: Adaptation layer for RF configuring and processing */ + +#include +#include +#include + +#include + +#include "nrf_802154.h" + +#include "rf_proc.h" + +#include "ptt.h" + +#include +LOG_MODULE_REGISTER(rf_proc); + +/**< Maximum size of RF pool of received packets */ +#define RF_RX_POOL_N 16u + +static struct rf_rx_pkt_s rf_rx_pool[RF_RX_POOL_N]; +static struct rf_rx_pkt_s ack_packet; +static uint8_t temp_tx_pkt[RF_PSDU_MAX_SIZE]; + +static inline void rf_rx_pool_init(void); +static void rf_rx_pool_clear(void); + +static void rf_tx_finished_fn(struct k_work *work) +{ + ptt_rf_tx_finished(); +} + +K_WORK_DEFINE(rf_tx_finished_wq, rf_tx_finished_fn); + +static void rf_tx_ack_received_fn(struct k_work *work) +{ + ptt_rf_push_packet(ack_packet.data, ack_packet.length, ack_packet.rssi, ack_packet.lqi); + nrf_802154_buffer_free_raw(ack_packet.rf_buf); +} + +K_WORK_DEFINE(rf_tx_ack_received_wq, rf_tx_ack_received_fn); + +static void rf_cca_failed_fn(struct k_work *work) +{ + ptt_rf_cca_failed(); +} + +K_WORK_DEFINE(rf_cca_failed_wq, rf_cca_failed_fn); + +static void rf_ed_failed_fn(struct k_work *work) +{ + ptt_rf_ed_failed(); +} + +K_WORK_DEFINE(rf_ed_failed_wq, rf_ed_failed_fn); + +struct rf_rx_failed_info { + struct k_work work; + ptt_rf_tx_error_t rx_error; +} rf_rx_failed_info; +static void rf_rx_failed_fn(struct k_work *work) +{ + ptt_rf_rx_failed(rf_rx_failed_info.rx_error); +} + +struct rf_tx_failed_info { + struct k_work work; + ptt_rf_tx_error_t tx_error; +} rf_tx_failed_info; +static void rf_tx_failed_fn(struct k_work *work) +{ + ptt_rf_tx_failed(rf_tx_failed_info.tx_error); +} + +struct rf_cca_done_info { + struct k_work work; + bool channel_free; +} rf_cca_done_info; +static void rf_cca_done_fn(struct k_work *work) +{ + ptt_rf_cca_done((bool)rf_cca_done_info.channel_free); +} + +struct rf_ed_detected_info { + struct k_work work; + uint8_t result; +} rf_ed_detected_info; +static void rf_ed_detected_fn(struct k_work *work) +{ + ptt_rf_ed_detected((ptt_ed_t)rf_ed_detected_info.result); +} + +#if CONFIG_PTT_ANTENNA_DIVERSITY +#warning "Antenna diversity enabled but not yet supported in NCS" +/* TODO: Implement when antenna diversity is supported in NCS */ +static void configure_antenna_diversity(void); + +#endif /* CONFIG_PTT_ANTENNA_DIVERSITY */ + +void rf_init(void) +{ + k_work_init(&rf_rx_failed_info.work, rf_rx_failed_fn); + k_work_init(&rf_tx_failed_info.work, rf_tx_failed_fn); + k_work_init(&rf_cca_done_info.work, rf_cca_done_fn); + k_work_init(&rf_ed_detected_info.work, rf_ed_detected_fn); + + /* clear a pool for received packets */ + rf_rx_pool_init(); + ack_packet = (struct rf_rx_pkt_s){ 0 }; + + /* nrf radio driver initialization */ + nrf_802154_init(); + +#if CONFIG_PTT_ANTENNA_DIVERSITY + /* TODO: Implement when antenna diversity is supported in NCS */ + configure_antenna_diversity(); +#endif +} + +void rf_uninit(void) +{ + /* free packets and marks them as free */ + rf_rx_pool_clear(); + ack_packet = (struct rf_rx_pkt_s){ 0 }; + nrf_802154_deinit(); +} + +#if CONFIG_PTT_ANTENNA_DIVERSITY +static void configure_antenna_diversity(void) +{ + /* TODO: Implement when antenna diversity is supported in NCS */ +} + +#endif /* CONFIG_PTT_ANTENNA_DIVERSITY */ + +static void rf_process_rx_packets(void) +{ + struct rf_rx_pkt_s *rx_pkt = NULL; + + for (uint8_t i = 0; i < RF_RX_POOL_N; i++) { + rx_pkt = &rf_rx_pool[i]; + if (rx_pkt->data != NULL) { + ptt_rf_push_packet(rx_pkt->data, rx_pkt->length, rx_pkt->rssi, rx_pkt->lqi); + nrf_802154_buffer_free_raw(rx_pkt->rf_buf); + rx_pkt->data = NULL; + } + } +} + +void rf_thread(void) +{ + while (1) { + rf_process_rx_packets(); + k_sleep(K_MSEC(1)); + } +} + +void nrf_802154_received_raw(uint8_t *data, int8_t power, uint8_t lqi) +{ + struct rf_rx_pkt_s *rx_pkt = NULL; + bool pkt_placed = false; + + assert(data != NULL); + + for (uint8_t i = 0; i < RF_RX_POOL_N; i++) { + if (rf_rx_pool[i].data == NULL) { + rx_pkt = &rf_rx_pool[i]; + rx_pkt->rf_buf = data; + rx_pkt->data = &data[1]; + rx_pkt->length = data[0] - RF_FCS_SIZE; + rx_pkt->rssi = power; + rx_pkt->lqi = lqi; + pkt_placed = true; + break; + } + } + if (false == pkt_placed) { + LOG_ERR("Not enough space to store packet. Will drop it."); + nrf_802154_buffer_free_raw(data); + } +} + +void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id) +{ + LOG_INF("rx failed error %d!", error); + + /* mapping nrf_802154 errors into PTT RF errors */ + /* actually only invalid ACK FCS matters at the moment */ + if (error == NRF_802154_RX_ERROR_INVALID_FCS) { + rf_rx_failed_info.rx_error = PTT_RF_RX_ERROR_INVALID_FCS; + } else { + rf_rx_failed_info.rx_error = PTT_RF_RX_ERROR_OPERATION_FAILED; + } + + k_work_submit(&rf_rx_failed_info.work); +} + +void nrf_802154_transmitted_raw(const uint8_t *frame, uint8_t *ack, int8_t power, uint8_t lqi) +{ + ARG_UNUSED(frame); + + if (ack != NULL) { + ack_packet = (struct rf_rx_pkt_s){ 0 }; + + ack_packet.data = &ack[1]; + ack_packet.length = ack[0]; + ack_packet.rssi = power; + ack_packet.lqi = lqi; + ack_packet.rf_buf = ack; + + k_work_submit(&rf_tx_ack_received_wq); + } + + k_work_submit(&rf_tx_finished_wq); +} + +void nrf_802154_transmit_failed(const uint8_t *frame, nrf_802154_tx_error_t error) +{ + ARG_UNUSED(frame); + + LOG_INF("tx failed error %d!", error); + + /* mapping nrf_802154 errors into PTT RF errors */ + if (error == NRF_802154_TX_ERROR_INVALID_ACK) { + rf_tx_failed_info.tx_error = PTT_RF_TX_ERROR_INVALID_ACK_FCS; + } else if (error == NRF_802154_TX_ERROR_NO_ACK) { + rf_tx_failed_info.tx_error = PTT_RF_TX_ERROR_NO_ACK; + } else { + rf_tx_failed_info.tx_error = PTT_RF_TX_ERROR_OPERATION_FAILED; + } + + k_work_submit(&rf_tx_failed_info.work); +} + +void nrf_802154_cca_done(bool channel_free) +{ + LOG_INF("CCA finished with result %d", channel_free); + + rf_cca_done_info.channel_free = channel_free; + k_work_submit(&rf_cca_done_info.work); +} + +void nrf_802154_cca_failed(nrf_802154_cca_error_t error) +{ + ARG_UNUSED(error); + + LOG_INF("CCA failed error %d!", error); + + k_work_submit(&rf_cca_failed_wq); +} + +void nrf_802154_energy_detected(uint8_t result) +{ + LOG_INF("ED finished with result %d", result); + + rf_ed_detected_info.result = result; + k_work_submit(&rf_ed_detected_info.work); +} + +void nrf_802154_energy_detection_failed(nrf_802154_ed_error_t error) +{ + ARG_UNUSED(error); + + LOG_INF("ED failed error %d!", error); + + k_work_submit(&rf_ed_failed_wq); +} + +void ptt_rf_set_channel_ext(uint8_t channel) +{ + nrf_802154_channel_set(channel); +} + +void ptt_rf_set_power_ext(int8_t power) +{ + nrf_802154_tx_power_set(power); +} + +int8_t ptt_rf_get_power_ext(void) +{ + return nrf_802154_tx_power_get(); +} + +void ptt_rf_set_antenna_ext(uint8_t antenna) +{ +#if CONFIG_PTT_ANTENNA_DIVERSITY + /* TODO: Implement when antenna diversity is supported in NCS */ +#endif +} + +uint8_t ptt_rf_get_antenna_ext(void) +{ +#if CONFIG_PTT_ANTENNA_DIVERSITY + /* TODO: Implement when antenna diversity is supported in NCS */ + return 0; +#else + return 0; +#endif +} + +void ptt_rf_promiscuous_set_ext(bool value) +{ + nrf_802154_promiscuous_set(value); +} + +bool ptt_rf_receive_ext(void) +{ + return nrf_802154_receive(); +} + +void ptt_rf_set_pan_id_ext(const uint8_t *pan_id) +{ + nrf_802154_pan_id_set(pan_id); +} + +void ptt_rf_set_extended_address_ext(const uint8_t *extended_address) +{ + nrf_802154_extended_address_set(extended_address); +} + +void ptt_rf_set_short_address_ext(const uint8_t *short_address) +{ + nrf_802154_short_address_set(short_address); +} + +bool ptt_rf_cca_ext(uint8_t mode) +{ + bool ret = false; + + if ((mode >= NRF_RADIO_CCA_MODE_CARRIER) && (mode <= NRF_RADIO_CCA_MODE_CARRIER_OR_ED)) { + nrf_802154_cca_cfg_t cca_cfg; + + nrf_802154_cca_cfg_get(&cca_cfg); + + cca_cfg.mode = mode; + + nrf_802154_cca_cfg_set(&cca_cfg); + + ret = nrf_802154_cca(); + } else { + ret = false; + } + + return ret; +} + +bool ptt_rf_ed_ext(uint32_t time_us) +{ + return nrf_802154_energy_detection(time_us); +} + +bool ptt_rf_rssi_measure_begin_ext(void) +{ + return nrf_802154_rssi_measure_begin(); +} + +int8_t ptt_rf_rssi_last_get_ext(void) +{ + return nrf_802154_rssi_last_get(); +} + +bool ptt_rf_send_packet_ext(const uint8_t *pkt, ptt_pkt_len_t len, bool cca) +{ + bool ret = false; + + if ((pkt == NULL) || (len > RF_PSDU_MAX_SIZE - RF_FCS_SIZE)) { + ret = false; + } else { + /* temp_tx_pkt is protected inside ptt rf by locking mechanism */ + temp_tx_pkt[0] = len + RF_FCS_SIZE; + memcpy(&temp_tx_pkt[RF_PSDU_START], pkt, len); + + ret = nrf_802154_transmit_raw(temp_tx_pkt, cca); + } + + return ret; +} + +bool ptt_rf_modulated_stream_ext(const uint8_t *pkt, ptt_pkt_len_t len) +{ + bool ret = false; + + if ((pkt == NULL) || (len > RF_PSDU_MAX_SIZE - RF_FCS_SIZE)) { + ret = false; + } else { + /* temp_tx_pkt is protected inside ptt rf by locking mechanism */ + temp_tx_pkt[0] = len + RF_FCS_SIZE; + memcpy(&temp_tx_pkt[RF_PSDU_START], pkt, len); + + ret = nrf_802154_modulated_carrier(temp_tx_pkt); + } + + return ret; +} + +bool ptt_rf_sleep_ext(void) +{ + return nrf_802154_sleep(); +} + +bool ptt_rf_continuous_carrier_ext(void) +{ + return nrf_802154_continuous_carrier(); +} + +static inline void rf_rx_pool_init(void) +{ + for (uint8_t i = 0; i < RF_RX_POOL_N; i++) { + rf_rx_pool[i] = (struct rf_rx_pkt_s){ 0 }; + } +} + +static void rf_rx_pool_clear(void) +{ + struct rf_rx_pkt_s *rx_pkt = NULL; + + for (uint8_t i = 0; i < RF_RX_POOL_N; i++) { + rx_pkt = &rf_rx_pool[i]; + if (rx_pkt->data != NULL) { + nrf_802154_buffer_free_raw(rx_pkt->rf_buf); + rx_pkt->data = NULL; + } + } +} diff --git a/samples/peripheral/802154_phy_test/src/timer_proc.c b/samples/peripheral/802154_phy_test/src/timer_proc.c new file mode 100644 index 000000000000..ca1346d306b5 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/timer_proc.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: timer configuring and processing */ + +#include + +#include "timer_proc.h" + +#include "ptt.h" + +#include +LOG_MODULE_REGISTER(timer); + +static void ptt_process_timer_handler(struct k_timer *timer); +static void schedule_ptt_process(struct k_work *work); + +K_TIMER_DEFINE(app_timer, ptt_process_timer_handler, NULL); + +K_WORK_DEFINE(schedule_ptt_processor, schedule_ptt_process); + +static void ptt_process_timer_handler(struct k_timer *timer) +{ + k_work_submit(&schedule_ptt_processor); +} + +ptt_time_t ptt_get_current_time(void) +{ + return k_uptime_get_32(); +} + +ptt_time_t ptt_get_max_time(void) +{ + /* The maximum possible time is the maximum for a uint32_t */ + return UINT32_MAX; +} + +void launch_ptt_process_timer(ptt_time_t timeout) +{ + if (timeout == 0) { + /* schedule immediately */ + k_work_submit(&schedule_ptt_processor); + } else { + /* Schedule a single shot timer to trigger after the timeout */ + k_timer_start(&app_timer, K_MSEC(timeout), K_MSEC(0)); + } +} + +/* scheduler context */ +static void schedule_ptt_process(struct k_work *work) +{ + ptt_process(ptt_get_current_time()); +} diff --git a/samples/peripheral/802154_phy_test/src/uart_proc.c b/samples/peripheral/802154_phy_test/src/uart_proc.c new file mode 100644 index 000000000000..669eeeaa5869 --- /dev/null +++ b/samples/peripheral/802154_phy_test/src/uart_proc.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ +/* Purpose: UART configuring and processing */ + +/* UART handler waits for a string with new line symbol in the end. The handler reads a packet + * from UARTE driver per a byte and looks for a new line symbol or waits until a timer is expired + * to process received sequence without new line symbol. Then the packet is pushed to the library. + */ + +#include +#include + +#include +#include + +#include "comm_proc.h" +#include "uart_proc.h" + +#include +LOG_MODULE_REGISTER(uart); + +static struct text_proc_s text_proc_uart; +static struct k_timer uart_timer; +static const struct device *uart_dev; + +RING_BUF_DECLARE(uart_rb, 10240); + +static void uart_irq_handler(const struct device *dev, void *context) +{ + uint8_t *data_tx; + + uart_irq_update(dev); + if (uart_irq_tx_ready(dev)) { + int nr_bytes_read = + ring_buf_get_claim(&uart_rb, &data_tx, CONFIG_UART_0_NRF_TX_BUFFER_SIZE); + int sent = uart_fifo_fill(dev, data_tx, nr_bytes_read); + + ring_buf_get_finish(&uart_rb, sent); + if (ring_buf_is_empty(&uart_rb)) { + uart_irq_tx_disable(dev); + } + } + + if (uart_irq_rx_ready(dev)) { + uint8_t buf[10]; + int len = uart_fifo_read(dev, buf, sizeof(buf)); + + if (len) { + /* Call this */ + comm_input_process(&text_proc_uart, buf, UART_BYTES_TO_READ); + } + } +} + +void uart_init(void) +{ + LOG_INF("Init"); + + uart_dev = device_get_binding("UART_0"); + __ASSERT(uart_dev, "Failed to get the device"); + uart_irq_callback_user_data_set(uart_dev, uart_irq_handler, NULL); + uart_irq_rx_enable(uart_dev); + + text_proc_uart = (struct text_proc_s){ 0 }; + text_proc_uart.timer = uart_timer; + k_timer_init(&text_proc_uart.timer, comm_input_timeout_handler, NULL); + k_work_init(&text_proc_uart.work, comm_text_processor_fn); +} + +int32_t uart_send(const uint8_t *pkt, ptt_pkt_len_t len, bool add_crlf) +{ + while (ring_buf_space_get(&uart_rb) < len) { + LOG_WRN("queue full, waiting for free space"); + k_sleep(K_MSEC(1)); + } + + uart_irq_tx_disable(uart_dev); + ring_buf_put(&uart_rb, pkt, len); + if (add_crlf) { + ring_buf_put(&uart_rb, COMM_APPENDIX, COMM_APPENDIX_SIZE); + } + uart_irq_tx_enable(uart_dev); + + return len; +} From bf177c70e1789b62c9927cb997e687b5951ff892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jani=20Hirsim=C3=A4ki?= Date: Fri, 25 Jun 2021 18:02:20 +0300 Subject: [PATCH 011/126] samples: nrf9160: modem_shell: a kill button #1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pressing a long press of button #1 to kill/abort running ping/iperf instances, including all th -command threads. Jira: MOSH-143 Signed-off-by: Jani Hirsimäki --- samples/nrf9160/modem_shell/README.rst | 11 +++++++++++ samples/nrf9160/modem_shell/src/main.c | 15 +++++++++++++++ samples/nrf9160/modem_shell/src/mosh_defines.h | 4 ++++ samples/nrf9160/modem_shell/src/ping/icmp_ping.c | 11 +++++++++++ samples/nrf9160/modem_shell/src/shell.c | 4 ++-- samples/nrf9160/modem_shell/src/th/th_ctrl.c | 10 ++++++++++ samples/nrf9160/modem_shell/src/th/th_ctrl.h | 1 + 7 files changed, 54 insertions(+), 2 deletions(-) diff --git a/samples/nrf9160/modem_shell/README.rst b/samples/nrf9160/modem_shell/README.rst index 4df4666e6724..b6fdb4b56504 100644 --- a/samples/nrf9160/modem_shell/README.rst +++ b/samples/nrf9160/modem_shell/README.rst @@ -379,6 +379,17 @@ Building and running .. include:: /includes/build_and_run_nrf9160.txt +DK buttons +========== + +The buttons have the following functions: + +Button 1: + Raises a kill or abort signal. A long press of the button will kill or abort all supported running commands. You can abort commands ``iperf3`` (also with ``th``), ``curl``, ``ping`` and ``sock send``. + +Button 2: + Enables or disables the UARTs for power consumption measurements. Toggles between UARTs enabled and disabled. + Testing ======= diff --git a/samples/nrf9160/modem_shell/src/main.c b/samples/nrf9160/modem_shell/src/main.c index f966b3cbdfa5..25ce978d3f6f 100644 --- a/samples/nrf9160/modem_shell/src/main.c +++ b/samples/nrf9160/modem_shell/src/main.c @@ -47,9 +47,12 @@ #if defined(CONFIG_MOSH_WORKER_THREADS) #include "th/th_ctrl.h" #endif +#include "mosh_defines.h" /* global variables */ struct modem_param_info modem_param; +struct k_poll_signal mosh_signal; + /** * @brief Global shell pointer that can be used for printing. * @@ -87,6 +90,17 @@ static void mosh_print_version_info(void) static void button_handler(uint32_t button_states, uint32_t has_changed) { + if (has_changed & button_states & DK_BTN1_MSK) { + shell_print(shell_global, "Button 1 pressed - raising a kill signal"); + k_poll_signal_raise(&mosh_signal, MOSH_SIGNAL_KILL); +#if defined(CONFIG_MOSH_WORKER_THREADS) + th_ctrl_kill_em_all(); +#endif + } else if (has_changed & ~button_states & DK_BTN1_MSK) { + shell_print(shell_global, "Button 1 released - resetting a kill signal"); + k_poll_signal_reset(&mosh_signal); + } + if (has_changed & button_states & DK_BTN2_MSK) { shell_print(shell_global, "Button 2 pressed, toggling UART power state"); uart_toggle_power_state(shell_global); @@ -182,6 +196,7 @@ void main(void) #if defined(CONFIG_BOOTLOADER_MCUBOOT) boot_write_img_confirmed(); #endif + k_poll_signal_init(&mosh_signal); /* Resize terminal width and height of the shell to have proper command editing. */ shell_execute_cmd(shell_global, "resize"); diff --git a/samples/nrf9160/modem_shell/src/mosh_defines.h b/samples/nrf9160/modem_shell/src/mosh_defines.h index 2ad394ffb9f4..5215e928d16c 100644 --- a/samples/nrf9160/modem_shell/src/mosh_defines.h +++ b/samples/nrf9160/modem_shell/src/mosh_defines.h @@ -17,4 +17,8 @@ #define MOSH_AT_CMD_RESPONSE_MAX_LEN 2700 +enum mosh_signals { + MOSH_SIGNAL_KILL, +}; + #endif /* MOSH_DEFINES_H */ diff --git a/samples/nrf9160/modem_shell/src/ping/icmp_ping.c b/samples/nrf9160/modem_shell/src/ping/icmp_ping.c index 5278590896ab..bc3fc231e370 100644 --- a/samples/nrf9160/modem_shell/src/ping/icmp_ping.c +++ b/samples/nrf9160/modem_shell/src/ping/icmp_ping.c @@ -22,6 +22,7 @@ #include "utils/net_utils.h" #include "link_api.h" +#include "mosh_defines.h" #include "icmp_ping.h" @@ -39,6 +40,8 @@ #define ICMP6_ECHO_REQ 128 #define ICMP6_ECHO_REP 129 +extern struct k_poll_signal mosh_signal; + enum ping_rai { PING_RAI_NONE, PING_RAI_ONGOING, @@ -525,6 +528,7 @@ static void icmp_ping_tasks_execute(const struct shell *shell) uint32_t count = 0; uint32_t rtt_min = 0xFFFFFFFF; uint32_t rtt_max = 0; + int set, res; enum ping_rai rai; uint32_t ping_t; @@ -540,6 +544,13 @@ static void icmp_ping_tasks_execute(const struct shell *shell) } ping_t = send_ping_wait_reply(shell, rai); + k_poll_signal_check(&mosh_signal, &set, &res); + if (set && res == MOSH_SIGNAL_KILL) { + k_poll_signal_reset(&mosh_signal); + shell_error(shell, "KILL signal received - exiting"); + break; + } + if (ping_t > 0) { count++; sum += ping_t; diff --git a/samples/nrf9160/modem_shell/src/shell.c b/samples/nrf9160/modem_shell/src/shell.c index 99f8af72f024..d9d4d4470ead 100644 --- a/samples/nrf9160/modem_shell/src/shell.c +++ b/samples/nrf9160/modem_shell/src/shell.c @@ -44,7 +44,7 @@ extern const struct shell *shell_global; extern struct k_sem nrf_modem_lib_initialized; - +extern struct k_poll_signal mosh_signal; /** * @brief Overriding modem library error handler. */ @@ -162,7 +162,7 @@ int lwm2m_carrier_event_handler(const lwm2m_carrier_event_t *event) #if defined(CONFIG_MOSH_IPERF3) static int cmd_iperf3(const struct shell *shell, size_t argc, char **argv) { - (void)iperf_main(argc, argv, NULL, 0, NULL); + (void)iperf_main(argc, argv, NULL, 0, &mosh_signal); return 0; } #endif diff --git a/samples/nrf9160/modem_shell/src/th/th_ctrl.c b/samples/nrf9160/modem_shell/src/th/th_ctrl.c index b034d934752d..c3e83920a61a 100644 --- a/samples/nrf9160/modem_shell/src/th/th_ctrl.c +++ b/samples/nrf9160/modem_shell/src/th/th_ctrl.c @@ -159,6 +159,16 @@ void th_ctrl_status_print(const struct shell *shell) th_ctrl_data_status_print(shell, &th_work_data_2); } +void th_ctrl_kill_em_all(void) +{ + if (k_work_is_pending(&(th_work_data_1.work))) { + k_poll_signal_raise(&th_work_data_1.kill_signal, 1); + } + if (k_work_is_pending(&(th_work_data_2.work))) { + k_poll_signal_raise(&th_work_data_2.kill_signal, 2); + } +} + void th_ctrl_kill(const struct shell *shell, int nbr) { if (nbr == 1) { diff --git a/samples/nrf9160/modem_shell/src/th/th_ctrl.h b/samples/nrf9160/modem_shell/src/th/th_ctrl.h index 9e000b4b5102..42159650640b 100644 --- a/samples/nrf9160/modem_shell/src/th/th_ctrl.h +++ b/samples/nrf9160/modem_shell/src/th/th_ctrl.h @@ -16,5 +16,6 @@ void th_ctrl_status_print(const struct shell *shell); void th_ctrl_start(const struct shell *shell, size_t argc, char **argv, bool bg_thread); void th_ctrl_kill(const struct shell *shell, int nbr); +void th_ctrl_kill_em_all(void); #endif /* TH_CTRL_H */ From 4b6c3ef355c9c0a129aeb33588df92a8de56c109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jani=20Hirsim=C3=A4ki?= Date: Wed, 30 Jun 2021 14:33:23 +0300 Subject: [PATCH 012/126] ext: curl: possibility to pass abort/kill signal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added a possibility to pass a kill signal pointer, and if that signal is raised; curl will be exiting. Jira: MOSH-143 Signed-off-by: Jani Hirsimäki --- ext/curl/include/curl/easy.h | 6 ++++++ ext/curl/include/curl/nrf_curl.h | 2 +- ext/curl/lib/easy.c | 29 +++++++++++++++++++++++++++++ ext/curl/lib/multihandle.h | 4 ++++ ext/curl/lib/urldata.h | 3 +++ ext/curl/tool/tool_cfgable.h | 1 + ext/curl/tool/tool_main.c | 6 +++++- ext/curl/tool/tool_operate.c | 5 +++++ 8 files changed, 54 insertions(+), 2 deletions(-) diff --git a/ext/curl/include/curl/easy.h b/ext/curl/include/curl/easy.h index 9aef1339620a..0a1813f9f09d 100644 --- a/ext/curl/include/curl/easy.h +++ b/ext/curl/include/curl/easy.h @@ -38,6 +38,12 @@ struct curl_blob { CURL_EXTERN CURL *curl_easy_init(void); CURL_EXTERN CURLcode curl_easy_setopt(CURL *curl, CURLoption option, ...); + +#if defined(CONFIG_NRF_CURL_INTEGRATION) +CURL_EXTERN void curl_easy_nrf_set_kill_signal( + CURL *curl, struct k_poll_signal *kill_signal); +#endif + CURL_EXTERN CURLcode curl_easy_perform(CURL *curl); CURL_EXTERN void curl_easy_cleanup(CURL *curl); diff --git a/ext/curl/include/curl/nrf_curl.h b/ext/curl/include/curl/nrf_curl.h index 0db6e82bf451..248ffc6de4da 100644 --- a/ext/curl/include/curl/nrf_curl.h +++ b/ext/curl/include/curl/nrf_curl.h @@ -6,5 +6,5 @@ #ifndef NRF_CURL_H #define NRF_CURL_H -int curl_tool_main(int argc, char *argv[]); +int curl_tool_main(int argc, char *argv[], struct k_poll_signal *kill_signal); #endif diff --git a/ext/curl/lib/easy.c b/ext/curl/lib/easy.c index 068a277e1560..05e5e3339725 100644 --- a/ext/curl/lib/easy.c +++ b/ext/curl/lib/easy.c @@ -586,6 +586,20 @@ static CURLcode easy_transfer(struct Curl_multi *multi) while(!done && !mcode) { int still_running = 0; +#if defined(CONFIG_NRF_IPERF3_INTEGRATION) + if (multi->kill_signal != NULL) { + int set, res; + + k_poll_signal_check(multi->kill_signal, &set, &res); + if (set) { + k_poll_signal_reset(multi->kill_signal); + printk("\nKill signal received - exiting\n"); + result = CURLE_ABORTED_BY_CALLBACK; + break; + } + } +#endif + mcode = curl_multi_poll(multi, NULL, 0, 1000, NULL); if(!mcode) @@ -678,6 +692,10 @@ static CURLcode easy_perform(struct Curl_easy *data, bool events) sigpipe_ignore(data, &pipe_st); +#if defined(CONFIG_NRF_CURL_INTEGRATION) + multi->kill_signal = data->kill_signal; +#endif + /* run the transfer */ result = events ? easy_events(multi) : easy_transfer(multi); @@ -729,6 +747,17 @@ void curl_easy_cleanup(struct Curl_easy *data) sigpipe_restore(&pipe_st); } +#if defined(CONFIG_NRF_CURL_INTEGRATION) +void curl_easy_nrf_set_kill_signal(struct Curl_easy *data, + struct k_poll_signal *kill_signal) +{ + if (!data) + return; + + data->kill_signal = kill_signal; +} +#endif + /* * curl_easy_getinfo() is an external interface that allows an app to retrieve * information from a performed transfer and similar. diff --git a/ext/curl/lib/multihandle.h b/ext/curl/lib/multihandle.h index c70a1ce09ada..9193b4d4b819 100644 --- a/ext/curl/lib/multihandle.h +++ b/ext/curl/lib/multihandle.h @@ -151,6 +151,10 @@ struct Curl_multi { bool recheckstate; /* see Curl_multi_connchanged */ bool in_callback; /* true while executing a callback */ bool ipv6_works; + +#if defined(CONFIG_NRF_CURL_INTEGRATION) +struct k_poll_signal *kill_signal; +#endif }; #endif /* HEADER_CURL_MULTIHANDLE_H */ diff --git a/ext/curl/lib/urldata.h b/ext/curl/lib/urldata.h index 6b7ae41a2463..9533f9093069 100644 --- a/ext/curl/lib/urldata.h +++ b/ext/curl/lib/urldata.h @@ -1920,6 +1920,9 @@ struct Curl_easy { iconv_t utf8_cd; /* for translating to UTF8 */ #endif /* CURL_DOES_CONVERSIONS && HAVE_ICONV */ unsigned int magic; /* set to a CURLEASY_MAGIC_NUMBER */ +#if defined(CONFIG_NRF_CURL_INTEGRATION) +struct k_poll_signal *kill_signal; +#endif }; #define LIBCURL_NAME "libcurl" diff --git a/ext/curl/tool/tool_cfgable.h b/ext/curl/tool/tool_cfgable.h index a422113fd297..d63051fc2d7e 100644 --- a/ext/curl/tool/tool_cfgable.h +++ b/ext/curl/tool/tool_cfgable.h @@ -319,6 +319,7 @@ struct GlobalConfig { char *help_category; /* The help category, if set */ #if defined(CONFIG_NRF_CURL_INTEGRATION) bool curr_mdm_traces; + struct k_poll_signal *kill_signal; #endif struct OperationConfig *first; struct OperationConfig *current; diff --git a/ext/curl/tool/tool_main.c b/ext/curl/tool/tool_main.c index 1a764ac69e08..704a09bf9644 100644 --- a/ext/curl/tool/tool_main.c +++ b/ext/curl/tool/tool_main.c @@ -301,7 +301,7 @@ static void restore_terminal(void) int wmain(int argc, wchar_t *argv[]) #else #if defined(CONFIG_NRF_CURL_INTEGRATION) -int curl_tool_main(int argc, char *argv[]) +int curl_tool_main(int argc, char *argv[], struct k_poll_signal *kill_signal) #endif #endif { @@ -345,6 +345,10 @@ int curl_tool_main(int argc, char *argv[]) this point */ result = main_init(&global); if(!result) { +#if defined(CONFIG_NRF_CURL_INTEGRATION) + global.kill_signal = kill_signal; +#endif + /* Start our curl operation */ result = operate(&global, argc, argv); diff --git a/ext/curl/tool/tool_operate.c b/ext/curl/tool/tool_operate.c index 83cc9eb63a7d..51f4e55f5e42 100644 --- a/ext/curl/tool/tool_operate.c +++ b/ext/curl/tool/tool_operate.c @@ -343,6 +343,11 @@ static CURLcode pre_transfer(struct GlobalConfig *global, } per->input.fd = per->infd; } + +#if defined(CONFIG_NRF_CURL_INTEGRATION) + curl_easy_nrf_set_kill_signal(per->curl, global->kill_signal); +#endif + return result; } From 53c95fdcf7c0463e4b7f96626ef42c29afe1e04f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jani=20Hirsim=C3=A4ki?= Date: Wed, 30 Jun 2021 14:34:54 +0300 Subject: [PATCH 013/126] samples: nrf9160: modem_shell: passing kill signal to curl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jira: MOSH-143 Signed-off-by: Jani Hirsimäki --- samples/nrf9160/modem_shell/src/shell.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/nrf9160/modem_shell/src/shell.c b/samples/nrf9160/modem_shell/src/shell.c index d9d4d4470ead..d4ad416b7edb 100644 --- a/samples/nrf9160/modem_shell/src/shell.c +++ b/samples/nrf9160/modem_shell/src/shell.c @@ -170,7 +170,7 @@ static int cmd_iperf3(const struct shell *shell, size_t argc, char **argv) #if defined(CONFIG_MOSH_CURL) static int cmd_curl(const struct shell *shell, size_t argc, char **argv) { - (void)curl_tool_main(argc, argv); + (void)curl_tool_main(argc, argv, &mosh_signal); shell_print(shell, "\nDONE"); return 0; } From 8f89e31ad486d4fa41e7fcf2ce3335d4604eb5e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jani=20Hirsim=C3=A4ki?= Date: Fri, 2 Jul 2021 09:46:57 +0300 Subject: [PATCH 014/126] samples: nrf9160: modem_shell: sock send: support for abort MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support to kill/abort sock tool sending by long pressing DK button #1. Jira: MOSH-143 Signed-off-by: Jani Hirsimäki --- samples/nrf9160/modem_shell/src/sock/sock.c | 26 +++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/samples/nrf9160/modem_shell/src/sock/sock.c b/samples/nrf9160/modem_shell/src/sock/sock.c index 0b603439461a..516937300fd8 100644 --- a/samples/nrf9160/modem_shell/src/sock/sock.c +++ b/samples/nrf9160/modem_shell/src/sock/sock.c @@ -28,6 +28,8 @@ #include "net_utils.h" #include "str_utils.h" +extern struct k_poll_signal mosh_signal; + /* Maximum number of sockets takes into account AT command socket */ #define MAX_SOCKETS (CONFIG_POSIX_MAX_FDS - 1) #define SOCK_SEND_BUFFER_SIZE_UDP 1200 @@ -695,6 +697,15 @@ static int sock_send( { int bytes; int dest_addr_len = 0; + int set, res; + + k_poll_signal_check(&mosh_signal, &set, &res); + if (set && res == MOSH_SIGNAL_KILL) { + k_poll_signal_reset(&mosh_signal); + shell_error(shell_global, + "KILL signal received - exiting"); + return -ECANCELED; + } if (log_data) { if (data_hex_format) { @@ -741,6 +752,7 @@ static void data_send_work_handler(struct k_work *item) struct data_transfer_info *data_send_info_ptr = CONTAINER_OF(item, struct data_transfer_info, work); struct sock_info *socket_info = data_send_info_ptr->parent; + int ret; if (!socket_info->in_use) { shell_print( @@ -751,16 +763,17 @@ static void data_send_work_handler(struct k_work *item) return; } - sock_send( + ret = sock_send( socket_info, socket_info->send_buffer, socket_info->send_buffer_size, true, data_send_info_ptr->data_format_hex); - k_work_schedule( - &socket_info->send_info.work, - K_SECONDS(socket_info->send_info.interval)); + if (ret != -ECANCELED) { + k_work_schedule(&socket_info->send_info.work, + K_SECONDS(socket_info->send_info.interval)); + } } static void sock_send_random_data_length(struct sock_info *socket_info) @@ -779,6 +792,11 @@ static void sock_send_random_data_length(struct sock_info *socket_info) bytes = sock_send(socket_info, socket_info->send_buffer, strlen(socket_info->send_buffer), false, false); + if (bytes == -ECANCELED) { + socket_info->send_poll = false; + break; + } + if (bytes < 0) { /* Wait for socket to allow sending again */ socket_info->send_poll = true; From bae2941d86bce4c9dfb8a1ee46571ca854e6f473 Mon Sep 17 00:00:00 2001 From: Tommi Kangas Date: Fri, 13 Aug 2021 13:55:59 +0300 Subject: [PATCH 015/126] lib: agps: add own API for the A-GPS library Removed A-GPS library functions from the GPS driver header, added an own header file for the A-GPS library and renamed functions in the API accordingly. Removed dependency to the GPS driver from the library API, instead a GNSS API structure is used for providing the requested A-GPS data to the library. Signed-off-by: Tommi Kangas --- applications/asset_tracker/src/main.c | 42 +++++++- .../src/modules/cloud_module.c | 41 +++++++- include/drivers/gps.h | 25 ----- include/modem/agps.h | 57 +++++++++++ lib/agps/Kconfig | 2 +- lib/agps/agps.c | 98 ++++++++++--------- samples/nrf9160/agps/src/main.c | 39 +++++++- 7 files changed, 224 insertions(+), 80 deletions(-) create mode 100644 include/modem/agps.h diff --git a/applications/asset_tracker/src/main.c b/applications/asset_tracker/src/main.c index 830cb1c9c979..c074e95b7d0d 100644 --- a/applications/asset_tracker/src/main.c +++ b/applications/asset_tracker/src/main.c @@ -21,6 +21,9 @@ #endif /* CONFIG_NRF_MODEM_LIB */ #include #include +#if defined(CONFIG_AGPS) +#include +#endif #include #if defined(CONFIG_NRF_CLOUD_AGPS) #include @@ -479,6 +482,36 @@ static void send_cell_pos_request(struct k_work *work) } #endif /* CONFIG_NRF_CLOUD_CELL_POS */ +#if defined(CONFIG_AGPS) +/* Converts the A-GPS data request from GPS driver to GNSS API format. */ +static void agps_request_convert( + struct nrf_modem_gnss_agps_data_frame *dest, + const struct gps_agps_request *src) +{ + dest->sv_mask_ephe = src->sv_mask_ephe; + dest->sv_mask_alm = src->sv_mask_alm; + dest->data_flags = 0; + if (src->utc) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST; + } + if (src->klobuchar) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST; + } + if (src->nequick) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST; + } + if (src->system_time_tow) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST; + } + if (src->position) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + } + if (src->integrity) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; + } +} +#endif + static void send_agps_request(struct k_work *work) { ARG_UNUSED(work); @@ -494,8 +527,12 @@ static void send_agps_request(struct k_work *work) (k_uptime_get() - last_request_timestamp) < AGPS_UPDATE_PERIOD) { LOG_WRN("A-GPS request was sent less than 1 hour ago"); } else { + struct nrf_modem_gnss_agps_data_frame request; + + agps_request_convert(&request, &agps_request); + LOG_INF("Sending A-GPS request"); - err = gps_agps_request_send(agps_request, GPS_SOCKET_NOT_PROVIDED); + err = agps_request_send(request, AGPS_SOCKET_NOT_PROVIDED); if (err) { LOG_ERR("Failed to request A-GPS data, error: %d", err); } else { @@ -1569,8 +1606,7 @@ void cloud_event_handler(const struct cloud_backend *const backend, } #if defined(CONFIG_AGPS) - err = gps_process_agps_data(evt->data.msg.buf, - evt->data.msg.len); + err = agps_cloud_data_process(evt->data.msg.buf, evt->data.msg.len); #if defined(CONFIG_NRF_CLOUD_PGPS) if (!err) { LOG_INF("A-GPS data processed"); diff --git a/applications/asset_tracker_v2/src/modules/cloud_module.c b/applications/asset_tracker_v2/src/modules/cloud_module.c index aa1c841b5feb..3e90737b0f6d 100644 --- a/applications/asset_tracker_v2/src/modules/cloud_module.c +++ b/applications/asset_tracker_v2/src/modules/cloud_module.c @@ -10,6 +10,9 @@ #include #include #include +#if defined(CONFIG_AGPS) +#include +#endif #if defined(CONFIG_NRF_CLOUD_AGPS) #include @@ -224,7 +227,7 @@ static void agps_data_handle(const uint8_t *buf, size_t len) int err; #if defined(CONFIG_AGPS) - err = gps_process_agps_data(buf, len); + err = agps_cloud_data_process(buf, len); if (err) { LOG_WRN("Unable to process agps data, error: %d", err); #if defined(CONFIG_NRF_CLOUD_PGPS) @@ -259,6 +262,36 @@ static void agps_data_handle(const uint8_t *buf, size_t len) (void)err; } +#if defined(CONFIG_AGPS) +/* Converts the A-GPS data request from GPS driver to GNSS API format. */ +static void agps_request_convert( + struct nrf_modem_gnss_agps_data_frame *dest, + const struct gps_agps_request *src) +{ + dest->sv_mask_ephe = src->sv_mask_ephe; + dest->sv_mask_alm = src->sv_mask_alm; + dest->data_flags = 0; + if (src->utc) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST; + } + if (src->klobuchar) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST; + } + if (src->nequick) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST; + } + if (src->system_time_tow) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST; + } + if (src->position) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + } + if (src->integrity) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; + } +} +#endif + static void agps_data_request_handle(struct gps_agps_request *incoming_request) { int err; @@ -269,7 +302,11 @@ static void agps_data_request_handle(struct gps_agps_request *incoming_request) memcpy(&agps_request, incoming_request, sizeof(agps_request)); #if defined(CONFIG_AGPS) - err = gps_agps_request_send(agps_request, GPS_SOCKET_NOT_PROVIDED); + struct nrf_modem_gnss_agps_data_frame request; + + agps_request_convert(&request, &agps_request); + + err = agps_request_send(request, AGPS_SOCKET_NOT_PROVIDED); if (err) { LOG_WRN("Failed to request A-GPS data, error: %d", err); LOG_WRN("This is expected to fail if we are not in a connected state"); diff --git a/include/drivers/gps.h b/include/drivers/gps.h index 424c3cc1ca88..6513009ad6fd 100644 --- a/include/drivers/gps.h +++ b/include/drivers/gps.h @@ -27,7 +27,6 @@ extern "C" { #define GPS_NMEA_SENTENCE_MAX_LENGTH 83 #define GPS_PVT_MAX_SV_COUNT 12 -#define GPS_SOCKET_NOT_PROVIDED 0 struct gps_nmea { char buf[GPS_NMEA_SENTENCE_MAX_LENGTH]; @@ -453,30 +452,6 @@ static inline int gps_deinit(const struct device *dev) return api->deinit(dev); } -/** - * @brief Function to send a request for A-GPS data to the configured A-GPS - * data source. See the A-GPS Library Kconfig documentation for alternatives. - * - * @param request Assistance data to request from A-GPS service. - * @param socket GPS socket to which assistance data will be written - * when it's received from the selected A-GPS service. - * If zero the GPS driver will be used to write the data instead - * of directly to the provided socket. - * - * @return Zero on success or (negative) error code otherwise. - */ -int gps_agps_request_send(struct gps_agps_request request, int socket); - -/** - * @brief Processes A-GPS data. - * - * @param buf Pointer to A-GPS data. - * @param len Buffer size of data to be processed. - * - * @return Zero on success or (negative) error code otherwise. - */ -int gps_process_agps_data(const uint8_t *buf, size_t len); - /** @} */ #ifdef __cplusplus diff --git a/include/modem/agps.h b/include/modem/agps.h new file mode 100644 index 000000000000..a0a02a0248c1 --- /dev/null +++ b/include/modem/agps.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/** + * @file agps.h + * @brief Public APIs for the A-GPS library. + * @defgroup agps A-GPS library + * @{ + */ + +#ifndef AGPS_H_ +#define AGPS_H_ + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define AGPS_SOCKET_NOT_PROVIDED 0 + +/** + * @brief Function to send a request for A-GPS data to the configured A-GPS data source. See the + * A-GPS library Kconfig documentation for alternatives. + * + * @param request Assistance data to request from the A-GPS service. + * @param socket GNSS socket to which assistance data will be written when it's received from the + * selected A-GPS service. If socket argument is set to AGPS_SOCKET_NOT_PROVIDED, + * the data will be written using the GPS driver or GNSS API. + * + * @return Zero on success or (negative) error code otherwise. + */ +int agps_request_send(struct nrf_modem_gnss_agps_data_frame request, int socket); + +/** + * @brief Processes A-GPS data from the cloud. + * + * @param buf Pointer to A-GPS data from the cloud. + * @param len Buffer size of data to be processed. + * + * @return Zero on success or (negative) error code otherwise. + */ +int agps_cloud_data_process(const uint8_t *buf, size_t len); + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* AGPS_H_ */ diff --git a/lib/agps/Kconfig b/lib/agps/Kconfig index 10a8162caca6..bdd5e9a769b3 100644 --- a/lib/agps/Kconfig +++ b/lib/agps/Kconfig @@ -6,6 +6,7 @@ config AGPS bool "A-GPS library" + depends on NRF_MODEM_LIB help A library to simplify switching between A-GPS data sources. @@ -28,7 +29,6 @@ config AGPS_SRC_NRF_CLOUD config AGPS_SRC_SUPL bool "Use SUPL as data source" - depends on NRF_MODEM_LIB imply SUPL_CLIENT_LIB help Note that a request for A-GPS data using SUPL service will block until diff --git a/lib/agps/agps.c b/lib/agps/agps.c index 84f11d712b45..bd5de7891d66 100644 --- a/lib/agps/agps.c +++ b/lib/agps/agps.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -30,41 +31,44 @@ static int gnss_fd; static int supl_fd; #endif /* CONFIG_AGPS_SRC_SUPL */ -static enum gps_agps_type type_lookup_socket2gps[] = { - [NRF_GNSS_AGPS_UTC_PARAMETERS] = GPS_AGPS_UTC_PARAMETERS, - [NRF_GNSS_AGPS_EPHEMERIDES] = GPS_AGPS_EPHEMERIDES, - [NRF_GNSS_AGPS_ALMANAC] = GPS_AGPS_ALMANAC, - [NRF_GNSS_AGPS_KLOBUCHAR_IONOSPHERIC_CORRECTION] - = GPS_AGPS_KLOBUCHAR_CORRECTION, - [NRF_GNSS_AGPS_NEQUICK_IONOSPHERIC_CORRECTION] - = GPS_AGPS_NEQUICK_CORRECTION, - [NRF_GNSS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS] - = GPS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS, - [NRF_GNSS_AGPS_LOCATION] = GPS_AGPS_LOCATION, - [NRF_GNSS_AGPS_INTEGRITY] = GPS_AGPS_INTEGRITY, +static enum gps_agps_type type_lookup_api2driver[] = { + [NRF_MODEM_GNSS_AGPS_UTC_PARAMETERS] = + GPS_AGPS_UTC_PARAMETERS, + [NRF_MODEM_GNSS_AGPS_EPHEMERIDES] = + GPS_AGPS_EPHEMERIDES, + [NRF_MODEM_GNSS_AGPS_ALMANAC] = + GPS_AGPS_ALMANAC, + [NRF_MODEM_GNSS_AGPS_KLOBUCHAR_IONOSPHERIC_CORRECTION] = + GPS_AGPS_KLOBUCHAR_CORRECTION, + [NRF_MODEM_GNSS_AGPS_NEQUICK_IONOSPHERIC_CORRECTION] = + GPS_AGPS_NEQUICK_CORRECTION, + [NRF_MODEM_GNSS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS] = + GPS_AGPS_GPS_SYSTEM_CLOCK_AND_TOWS, + [NRF_MODEM_GNSS_AGPS_LOCATION] = + GPS_AGPS_LOCATION, + [NRF_MODEM_GNSS_AGPS_INTEGRITY] = + GPS_AGPS_INTEGRITY }; -/* Convert nrf_socket A-GPS type to GPS API type. */ -static inline enum gps_agps_type type_socket2gps(nrf_gnss_agps_data_type_t type) +/* Convert GNSS API A-GPS type to GPS driver type. */ +static inline enum gps_agps_type type_api2driver(uint16_t type) { - return type_lookup_socket2gps[type]; + return type_lookup_api2driver[type]; } #if defined(CONFIG_AGPS_SRC_SUPL) -static int send_to_modem(void *data, size_t data_len, - nrf_gnss_agps_data_type_t type) +static int send_to_modem(void *data, size_t data_len, uint16_t type) { int err; /* At this point, GPS driver or app-provided socket is assumed. */ if (gps_dev) { - return gps_agps_write(gps_dev, type_socket2gps(type), data, - data_len); + return gps_agps_write(gps_dev, type_api2driver(type), data, data_len); } err = nrf_sendto(gnss_fd, data, data_len, 0, &type, sizeof(type)); if (err < 0) { - LOG_ERR("Failed to send AGPS data to modem, errno: %d", errno); + LOG_ERR("Failed to send A-GPS data to modem, errno: %d", errno); err = -errno; } else { err = 0; @@ -77,7 +81,7 @@ static int send_to_modem(void *data, size_t data_len, static int inject_agps_type(void *agps, size_t agps_size, - nrf_gnss_agps_data_type_t type, + uint16_t type, void *user_data) { ARG_UNUSED(user_data); @@ -85,12 +89,12 @@ static int inject_agps_type(void *agps, err = send_to_modem(agps, agps_size, type); if (err) { - LOG_ERR("Failed to send AGNSS data, type: %d (err: %d)", + LOG_ERR("Failed to send A-GPS data, type: %d (err: %d)", type, err); return err; } - LOG_DBG("Injected AGPS data, type: %d, size: %d", type, agps_size); + LOG_DBG("Injected A-GPS data, type: %d, size: %d", type, agps_size); return 0; } @@ -283,26 +287,9 @@ static int init_supl(int socket) return 0; } -static int supl_start(const struct gps_agps_request request) +static int supl_start(const struct nrf_modem_gnss_agps_data_frame request) { int err; - struct nrf_modem_gnss_agps_data_frame req = { - .sv_mask_ephe = request.sv_mask_ephe, - .sv_mask_alm = request.sv_mask_alm, - .data_flags = - (request.utc ? - BIT(NRF_GNSS_AGPS_GPS_UTC_REQUEST) : 0) | - (request.klobuchar ? - BIT(NRF_GNSS_AGPS_KLOBUCHAR_REQUEST) : 0) | - (request.nequick ? - BIT(NRF_GNSS_AGPS_NEQUICK_REQUEST) : 0) | - (request.system_time_tow ? - BIT(NRF_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) : 0) | - (request.position ? - BIT(NRF_GNSS_AGPS_POSITION_REQUEST) : 0) | - (request.integrity ? - BIT(NRF_GNSS_AGPS_INTEGRITY_REQUEST) : 0), - }; err = open_supl_socket(); if (err) { @@ -312,7 +299,7 @@ static int supl_start(const struct gps_agps_request request) LOG_INF("Starting SUPL session"); - err = supl_session(&req); + err = supl_session(&request); if (err) { LOG_ERR("SUPL session failed, error: %d", err); goto cleanup; @@ -328,7 +315,7 @@ static int supl_start(const struct gps_agps_request request) #endif /* CONFIG_AGPS_SRC_SUPL */ -int gps_agps_request_send(struct gps_agps_request request, int socket) +int agps_request_send(struct nrf_modem_gnss_agps_data_frame request, int socket) { int err; @@ -352,7 +339,25 @@ int gps_agps_request_send(struct gps_agps_request request, int socket) } #elif defined(CONFIG_AGPS_SRC_NRF_CLOUD) - err = nrf_cloud_agps_request(request); + /* Convert GNSS API A-GPS request to GPS driver A-GPS request. */ + struct gps_agps_request agps_request; + + agps_request.sv_mask_ephe = request.sv_mask_ephe; + agps_request.sv_mask_alm = request.sv_mask_alm; + agps_request.utc = + request.data_flags & NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST ? 1 : 0; + agps_request.klobuchar = + request.data_flags & NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST ? 1 : 0; + agps_request.nequick = + request.data_flags & NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST ? 1 : 0; + agps_request.system_time_tow = + request.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST ? 1 : 0; + agps_request.position = + request.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST ? 1 : 0; + agps_request.integrity = + request.data_flags & NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST ? 1 : 0; + + err = nrf_cloud_agps_request(agps_request); if (err) { LOG_ERR("nRF Cloud A-GPS request failed, error: %d", err); return err; @@ -362,15 +367,14 @@ int gps_agps_request_send(struct gps_agps_request request, int socket) return 0; } -int gps_process_agps_data(const uint8_t *buf, size_t len) +int agps_cloud_data_process(const uint8_t *buf, size_t len) { int err = 0; #if defined(CONFIG_AGPS_SRC_NRF_CLOUD) && defined(CONFIG_NRF_CLOUD_AGPS) - err = nrf_cloud_agps_process(buf, len, NULL); if (err) { - LOG_ERR("A-GPS failed, error: %d", err); + LOG_ERR("Processing A-GPS data failed, error: %d", err); } else { LOG_INF("A-GPS data successfully processed"); } diff --git a/samples/nrf9160/agps/src/main.c b/samples/nrf9160/agps/src/main.c index 2395f631ae81..4488540e24b9 100644 --- a/samples/nrf9160/agps/src/main.c +++ b/samples/nrf9160/agps/src/main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #if defined(CONFIG_NRF_CLOUD_PGPS) #include @@ -143,10 +144,44 @@ static void gps_start_work_fn(struct k_work *work) gps_cfg.interval, gps_cfg.timeout); } +#if defined(CONFIG_AGPS) +/* Converts the A-GPS data request from GPS driver to GNSS API format. */ +static void agps_request_convert( + struct nrf_modem_gnss_agps_data_frame *dest, + const struct gps_agps_request *src) +{ + dest->sv_mask_ephe = src->sv_mask_ephe; + dest->sv_mask_alm = src->sv_mask_alm; + dest->data_flags = 0; + if (src->utc) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST; + } + if (src->klobuchar) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST; + } + if (src->nequick) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST; + } + if (src->system_time_tow) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST; + } + if (src->position) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_POSITION_REQUEST; + } + if (src->integrity) { + dest->data_flags |= NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST; + } +} +#endif + static void on_agps_needed(struct gps_agps_request request) { #if defined(CONFIG_AGPS) - int err = gps_agps_request_send(request, GPS_SOCKET_NOT_PROVIDED); + struct nrf_modem_gnss_agps_data_frame agps_request; + + agps_request_convert(&agps_request, &request); + + int err = agps_request_send(agps_request, AGPS_SOCKET_NOT_PROVIDED); if (err) { LOG_ERR("Failed to request A-GPS data, error: %d", err); @@ -237,7 +272,7 @@ static void cloud_event_handler(const struct cloud_backend *const backend, } #if defined(CONFIG_AGPS) - err = gps_process_agps_data(evt->data.msg.buf, evt->data.msg.len); + err = agps_cloud_data_process(evt->data.msg.buf, evt->data.msg.len); if (!err) { LOG_INF("A-GPS data processed"); #if defined(CONFIG_NRF_CLOUD_PGPS) From b2feffae43eecc3484580b92a848d50326b99f8a Mon Sep 17 00:00:00 2001 From: Tommi Kangas Date: Fri, 13 Aug 2021 14:45:13 +0300 Subject: [PATCH 016/126] lib: agps: add support for writing A-GPS data using the GNSS API Added support for writing SUPL A-GPS data using the GNSS API. Signed-off-by: Tommi Kangas --- lib/agps/agps.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/agps/agps.c b/lib/agps/agps.c index bd5de7891d66..e0d4c9048785 100644 --- a/lib/agps/agps.c +++ b/lib/agps/agps.c @@ -27,7 +27,7 @@ LOG_MODULE_REGISTER(agps, CONFIG_AGPS_LOG_LEVEL); #define DNS_ATTEMPT_COUNT 3 static const struct device *gps_dev; -static int gnss_fd; +static int gnss_fd = -1; static int supl_fd; #endif /* CONFIG_AGPS_SRC_SUPL */ @@ -61,21 +61,22 @@ static int send_to_modem(void *data, size_t data_len, uint16_t type) { int err; - /* At this point, GPS driver or app-provided socket is assumed. */ if (gps_dev) { - return gps_agps_write(gps_dev, type_api2driver(type), data, data_len); - } - - err = nrf_sendto(gnss_fd, data, data_len, 0, &type, sizeof(type)); - if (err < 0) { - LOG_ERR("Failed to send A-GPS data to modem, errno: %d", errno); - err = -errno; + /* GPS driver */ + err = gps_agps_write(gps_dev, type_api2driver(type), data, data_len); + } else if (gnss_fd != -1) { + /* GNSS socket */ + err = nrf_sendto(gnss_fd, data, data_len, 0, &type, sizeof(type)); + if (err < 0) { + err = -errno; + } else { + err = 0; + } } else { - err = 0; + /* GNSS API */ + err = nrf_modem_gnss_agps_write(data, data_len, type); } - LOG_DBG("A-GPS data sent to modem"); - return err; } @@ -270,13 +271,11 @@ static int init_supl(int socket) if (socket) { LOG_DBG("Using user-provided socket, fd %d", socket); - gps_dev = NULL; gnss_fd = socket; } else { gps_dev = device_get_binding("NRF9160_GPS"); if (gps_dev == NULL) { - LOG_ERR("Could not get binding to nRF9160 GPS"); - return -ENODEV; + LOG_DBG("Using GNSS API to input assistance data"); } LOG_DBG("Using GPS driver to input assistance data"); From 7ded0c823bc83114569cf539f95b7974138e4fd5 Mon Sep 17 00:00:00 2001 From: Tommi Kangas Date: Mon, 16 Aug 2021 09:12:03 +0300 Subject: [PATCH 017/126] lib: agps: refactor SUPL socket handling Refactored SUPL socked handling and added support for IPv6. Signed-off-by: Tommi Kangas --- lib/agps/agps.c | 108 +++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 62 deletions(-) diff --git a/lib/agps/agps.c b/lib/agps/agps.c index e0d4c9048785..50b093cf2d41 100644 --- a/lib/agps/agps.c +++ b/lib/agps/agps.c @@ -23,12 +23,9 @@ LOG_MODULE_REGISTER(agps, CONFIG_AGPS_LOG_LEVEL); #if defined(CONFIG_AGPS_SRC_SUPL) -/* Number of DNS lookup attempts */ -#define DNS_ATTEMPT_COUNT 3 - static const struct device *gps_dev; static int gnss_fd = -1; -static int supl_fd; +static int supl_fd = -1; #endif /* CONFIG_AGPS_SRC_SUPL */ static enum gps_agps_type type_lookup_api2driver[] = { @@ -103,85 +100,68 @@ static int inject_agps_type(void *agps, static int open_supl_socket(void) { int err; - int proto; - uint16_t port; - struct addrinfo *addr; struct addrinfo *info; - proto = IPPROTO_TCP; - port = htons(CONFIG_AGPS_SUPL_PORT); - struct addrinfo hints = { - .ai_family = AF_INET, - .ai_socktype = SOCK_STREAM, - .ai_protocol = proto, - /* Either a valid, - * NULL-terminated access point name or NULL. - */ - .ai_canonname = NULL, + .ai_family = AF_UNSPEC, /* Both IPv4 and IPv6 addresses accepted. */ + .ai_socktype = SOCK_STREAM }; - err = getaddrinfo(CONFIG_AGPS_SUPL_HOST_NAME, NULL, &hints, - &info); - + err = getaddrinfo(CONFIG_AGPS_SUPL_HOST_NAME, NULL, &hints, &info); if (err) { - LOG_ERR("Failed to resolve IPv4 hostname %s, errno: %d", + LOG_ERR("Failed to resolve hostname %s, error: %d", CONFIG_AGPS_SUPL_HOST_NAME, err); - return -ECHILD; - } - - /* Create socket */ - supl_fd = socket(AF_INET, SOCK_STREAM, proto); - if (supl_fd < 0) { - LOG_ERR("Failed to create socket, errno %d", errno); - err = -errno; - goto cleanup; - } - - struct timeval timeout = { - .tv_sec = 1, - .tv_usec = 0, - }; - err = setsockopt(supl_fd, - SOL_SOCKET, - SO_RCVTIMEO, - &timeout, - sizeof(timeout)); - if (err) { - LOG_ERR("Failed to setup socket timeout, errno %d", errno); - err = -errno; - goto cleanup; + return -1; } /* Not connected */ err = -1; - for (addr = info; addr != NULL; addr = addr->ai_next) { + for (struct addrinfo *addr = info; addr != NULL; addr = addr->ai_next) { + char ip[INET6_ADDRSTRLEN] = { 0 }; struct sockaddr *const sa = addr->ai_addr; switch (sa->sa_family) { case AF_INET6: - continue; + ((struct sockaddr_in6 *)sa)->sin6_port = htons(CONFIG_AGPS_SUPL_PORT); + break; case AF_INET: - ((struct sockaddr_in *)sa)->sin_port = port; - char ip[INET_ADDRSTRLEN]; + ((struct sockaddr_in *)sa)->sin_port = htons(CONFIG_AGPS_SUPL_PORT); + break; + } + + supl_fd = socket(sa->sa_family, SOCK_STREAM, IPPROTO_TCP); + if (supl_fd < 0) { + LOG_ERR("Failed to create socket, errno %d", errno); + goto cleanup; + } - inet_ntop(AF_INET, - &((struct sockaddr_in *)sa)->sin_addr, ip, - sizeof(ip)); + /* The SUPL library expects a 1 second timeout for the read function. */ + struct timeval timeout = { + .tv_sec = 1, + .tv_usec = 0, + }; - LOG_DBG("ip %s (%x) port %d", log_strdup(ip), - ((struct sockaddr_in *)sa)->sin_addr.s_addr, - ntohs(port)); - break; + err = setsockopt(supl_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); + if (err) { + LOG_ERR("Failed to set socket timeout, errno %d", errno); + goto cleanup; } + inet_ntop(sa->sa_family, + (void *)&((struct sockaddr_in *)sa)->sin_addr, + ip, + INET6_ADDRSTRLEN); + LOG_DBG("Connecting to %s port %d", ip, CONFIG_AGPS_SUPL_PORT); + err = connect(supl_fd, sa, addr->ai_addrlen); if (err) { - /* Try next address */ - LOG_ERR("Unable to connect, errno %d", errno); - err = -errno; + close(supl_fd); + supl_fd = -1; + + /* Try the next address */ + LOG_WRN("Connecting to server failed, errno %d", errno); } else { /* Connected */ break; @@ -193,11 +173,15 @@ static int open_supl_socket(void) if (err) { /* Unable to connect, close socket */ - close(supl_fd); - supl_fd = -1; + LOG_ERR("Could not connect to SUPL server"); + if (supl_fd > -1) { + close(supl_fd); + supl_fd = -1; + } + return -1; } - return err; + return 0; } static void close_supl_socket(void) From 6b37ce7199fed76bc3a3036b1340e5ae595e37b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Narajowski?= Date: Fri, 30 Jul 2021 12:09:23 +0200 Subject: [PATCH 018/126] Bluetooth: Mesh: Refactor Light XYL and HSL Server models MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a node implements Light HSL Server and Light xyL Server located on the same element, the Light xyL state and the Light HSL state are bound indirectly via the Light Lightness Actual state. The user has to add Lightness Server model to the composition data separately and pass a pointer to HSL and XYL Server init macros. Signed-off-by: Michał Narajowski --- include/bluetooth/mesh/light_hsl_srv.h | 18 +- include/bluetooth/mesh/light_hsl_srv.rst | 15 +- include/bluetooth/mesh/light_xyl_srv.h | 12 +- subsys/bluetooth/mesh/light_hsl_srv.c | 28 +-- subsys/bluetooth/mesh/light_xyl_srv.c | 30 +-- tests/bluetooth/tester/src/model_handler.c | 246 ++++++++------------- 6 files changed, 146 insertions(+), 203 deletions(-) diff --git a/include/bluetooth/mesh/light_hsl_srv.h b/include/bluetooth/mesh/light_hsl_srv.h index 5b7dfc62e197..561779d53821 100644 --- a/include/bluetooth/mesh/light_hsl_srv.h +++ b/include/bluetooth/mesh/light_hsl_srv.h @@ -30,16 +30,15 @@ struct bt_mesh_light_hsl_srv; * * @brief Initialization parameters for a @ref bt_mesh_light_hsl_srv instance. * + * @param[in] _lightness_srv Pointer to the Lightness Server instance. * @param[in] _hue_handlers Hue Server model handlers. * @param[in] _sat_handlers Saturation Server model handlers. - * @param[in] _light_handlers Lightness Server model handlers. */ -#define BT_MESH_LIGHT_HSL_SRV_INIT(_hue_handlers, _sat_handlers, \ - _light_handlers) \ - { \ - .hue = BT_MESH_LIGHT_HUE_SRV_INIT(_hue_handlers), \ - .sat = BT_MESH_LIGHT_SAT_SRV_INIT(_sat_handlers), \ - .lightness = BT_MESH_LIGHTNESS_SRV_INIT(_light_handlers), \ +#define BT_MESH_LIGHT_HSL_SRV_INIT(_lightness_srv, _hue_handlers, _sat_handlers) \ + { \ + .lightness = _lightness_srv, \ + .hue = BT_MESH_LIGHT_HUE_SRV_INIT(_hue_handlers), \ + .sat = BT_MESH_LIGHT_SAT_SRV_INIT(_sat_handlers), \ } /** @def BT_MESH_MODEL_LIGHT_HSL_SRV @@ -49,7 +48,6 @@ struct bt_mesh_light_hsl_srv; * @param[in] _srv Pointer to a @ref bt_mesh_light_hsl_srv instance. */ #define BT_MESH_MODEL_LIGHT_HSL_SRV(_srv) \ - BT_MESH_MODEL_LIGHTNESS_SRV(&(_srv)->lightness), \ BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_LIGHT_HSL_SRV, \ _bt_mesh_light_hsl_srv_op, &(_srv)->pub, \ BT_MESH_MODEL_USER_DATA(struct bt_mesh_light_hsl_srv, \ @@ -69,8 +67,8 @@ struct bt_mesh_light_hsl_srv { struct bt_mesh_light_hue_srv hue; /** Light Saturation Server instance. */ struct bt_mesh_light_sat_srv sat; - /** Lightness Server instance. */ - struct bt_mesh_lightness_srv lightness; + /** Pointer to Lightness Server instance. */ + struct bt_mesh_lightness_srv *lightness; /** Model entry. */ struct bt_mesh_model *model; diff --git a/include/bluetooth/mesh/light_hsl_srv.rst b/include/bluetooth/mesh/light_hsl_srv.rst index aa874b4c87f3..81a33cbd1e49 100644 --- a/include/bluetooth/mesh/light_hsl_srv.rst +++ b/include/bluetooth/mesh/light_hsl_srv.rst @@ -12,7 +12,7 @@ It should be instantiated in the light fixture node. The Light HSL Server provides functionality for working on the individual hue, saturation and lightness channels in a combined message interface, controlled by a :ref:`bt_mesh_light_hsl_cli_readme`. -The Light HSL Server adds the following new model instances in the composition data, in addition to the extended :ref:`bt_mesh_lightness_srv_readme` model: +The Light HSL Server adds the following new model instances in the composition data: * Light HSL Server * Light HSL Setup Server @@ -24,6 +24,8 @@ This allows for a fine-grained control of the access rights for the Light HSL st * The Light HSL Setup Server provides write access to the corresponding :ref:`bt_mesh_light_hue_srv_readme` and :ref:`bt_mesh_light_sat_srv_readme` models' meta states. This allows the configurator devices to set up the range and the default value for the various HSL states. +The extended :ref:`bt_mesh_lightness_srv_readme` model should be defined and initialized separately, and the pointer to this model should be passed to the Light HSL Server initialization macro. + Model composition ***************** @@ -46,12 +48,17 @@ In the application code, this would look like this: .. code-block:: c + static struct bt_mesh_lightness_srv lightess_srv = + BT_MESH_LIGHTNESS_SRV_INIT(&lightness_cb); + static struct bt_mesh_light_hsl_srv hsl_srv = - BT_MESH_LIGHT_HSL_SRV_INIT(&hue_cb, &sat_cb, &light_cb); + BT_MESH_LIGHT_HSL_SRV_INIT(&lightness_srv, &hue_cb, &sat_cb); static struct bt_mesh_elem elements[] = { BT_MESH_ELEM( - 1, BT_MESH_MODEL_LIST(BT_MESH_MODEL_LIGHT_HSL_SRV(&hsl_srv)), + 1, BT_MESH_MODEL_LIST( + BT_MESH_MODEL_LIGHTNESS_SRV(&lightness_srv), + BT_MESH_MODEL_LIGHT_HSL_SRV(&hsl_srv)), BT_MESH_MODEL_NONE), BT_MESH_ELEM( 2, BT_MESH_MODEL_LIST(BT_MESH_MODEL_LIGHT_HUE_SRV(&hsl_srv.hue)), @@ -64,6 +71,8 @@ In the application code, this would look like this: .. note:: The :c:struct:`bt_mesh_light_hsl_srv` contains the memory for its corresponding Light Hue Server and Light Saturation Server. When instantiating these models in the composition data, the model entries must point to these substructures. + The :c:struct:`bt_mesh_light_hsl_srv` also contains a pointer to the Light Lightness Server model. + Pointer to this model should be passed to the Light HSL Server initialization macro. The Light HSL Server does not contain any states on its own, but instead operates on the underlying Hue, Saturation and Lightness Server model's states. Because of this, the Light HSL Server does not have a message handler structure, but will instead defer its messages to the individual submodels' handler callbacks. diff --git a/include/bluetooth/mesh/light_xyl_srv.h b/include/bluetooth/mesh/light_xyl_srv.h index 00c79fef456f..156a7a33fef7 100644 --- a/include/bluetooth/mesh/light_xyl_srv.h +++ b/include/bluetooth/mesh/light_xyl_srv.h @@ -28,14 +28,13 @@ struct bt_mesh_light_xyl_srv; * * @brief initialization parameters for a @ref bt_mesh_light_xyl_srv instance. * - * @param[in] _lightness_handlers Lightness server callbacks. + * @param[in] _lightness_srv Pointer to Lightness server instance. * @param[in] _light_xyl_handlers Light xyL server callbacks. */ -#define BT_MESH_LIGHT_XYL_SRV_INIT(_lightness_handlers, _light_xyl_handlers) \ +#define BT_MESH_LIGHT_XYL_SRV_INIT(_lightness_srv, _light_xyl_handlers) \ { \ .handlers = _light_xyl_handlers, \ - .lightness_srv = \ - BT_MESH_LIGHTNESS_SRV_INIT(_lightness_handlers), \ + .lightness_srv = _lightness_srv, \ .range = { \ .min = { .x = 0, .y = 0 }, \ .max = { .x = UINT16_MAX, .y = UINT16_MAX } \ @@ -49,7 +48,6 @@ struct bt_mesh_light_xyl_srv; * @param[in] _srv Pointer to a @ref bt_mesh_light_xyl_srv instance. */ #define BT_MESH_MODEL_LIGHT_XYL_SRV(_srv) \ - BT_MESH_MODEL_LIGHTNESS_SRV(&(_srv)->lightness_srv), \ BT_MESH_MODEL_CB(BT_MESH_MODEL_ID_LIGHT_XYL_SRV, \ _bt_mesh_light_xyl_srv_op, &(_srv)->pub, \ BT_MESH_MODEL_USER_DATA( \ @@ -145,8 +143,8 @@ struct bt_mesh_light_xyl_srv_handlers { struct bt_mesh_light_xyl_srv { /** Model entry. */ struct bt_mesh_model *model; - /** Lightness Server instance. */ - struct bt_mesh_lightness_srv lightness_srv; + /** Pointer to Lightness Server instance. */ + struct bt_mesh_lightness_srv *lightness_srv; /** Publish parameters. */ struct bt_mesh_model_pub pub; /* Publication buffer */ diff --git a/subsys/bluetooth/mesh/light_hsl_srv.c b/subsys/bluetooth/mesh/light_hsl_srv.c index e5bfc51ff5ac..5a46cc07ccb2 100644 --- a/subsys/bluetooth/mesh/light_hsl_srv.c +++ b/subsys/bluetooth/mesh/light_hsl_srv.c @@ -55,7 +55,7 @@ static void hsl_get(struct bt_mesh_light_hsl_srv *srv, srv->hue.handlers->get(&srv->hue, ctx, &hue); srv->sat.handlers->get(&srv->sat, ctx, &sat); - srv->lightness.handlers->light_get(&srv->lightness, ctx, &lightness); + srv->lightness->handlers->light_get(srv->lightness, ctx, &lightness); *status = (struct bt_mesh_light_hsl_status)HSL_STATUS_INIT( &hue, &sat, &lightness, current); @@ -128,8 +128,8 @@ static void hsl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, bt_mesh_light_hue_srv_set(&srv->hue, ctx, &set.h, &hue); bt_mesh_light_sat_srv_set(&srv->sat, ctx, &set.s, &sat); - lightness_srv_disable_control(&srv->lightness); - lightness_srv_change_lvl(&srv->lightness, ctx, &set.l, &lightness, true); + lightness_srv_disable_control(srv->lightness); + lightness_srv_change_lvl(srv->lightness, ctx, &set.l, &lightness, true); srv->pub_pending = false; @@ -177,7 +177,7 @@ static void hsl_target_get_handle(struct bt_mesh_model *model, srv->hue.handlers->get(&srv->hue, ctx, &hue); srv->sat.handlers->get(&srv->sat, ctx, &sat); - srv->lightness.handlers->light_get(&srv->lightness, ctx, &lightness); + srv->lightness->handlers->light_get(srv->lightness, ctx, &lightness); struct bt_mesh_light_hsl_status status = HSL_STATUS_INIT(&hue, &sat, &lightness, target); @@ -194,7 +194,7 @@ static void default_rsp(struct bt_mesh_model *model, { struct bt_mesh_light_hsl_srv *srv = model->user_data; const struct bt_mesh_light_hsl hsl = { - .lightness = srv->lightness.default_light, + .lightness = srv->lightness->default_light, .hue = srv->hue.dflt, .saturation = srv->sat.dflt, }; @@ -215,7 +215,7 @@ static void default_set(struct bt_mesh_model *model, light_hsl_buf_pull(buf, &val); - lightness_srv_default_set(&srv->lightness, ctx, val.lightness); + lightness_srv_default_set(srv->lightness, ctx, val.lightness); bt_mesh_light_hue_srv_default_set(&srv->hue, ctx, val.hue); bt_mesh_light_sat_srv_default_set(&srv->sat, ctx, val.saturation); } @@ -413,11 +413,11 @@ static ssize_t scene_store(struct bt_mesh_model *model, uint8_t data[]) struct bt_mesh_light_hsl_srv *srv = model->user_data; struct bt_mesh_lightness_status status = { 0 }; - if (atomic_test_bit(&srv->lightness.flags, LIGHTNESS_SRV_FLAG_EXTENDED_BY_LIGHT_CTRL)) { + if (atomic_test_bit(&srv->lightness->flags, LIGHTNESS_SRV_FLAG_EXTENDED_BY_LIGHT_CTRL)) { return 0; } - srv->lightness.handlers->light_get(&srv->lightness, NULL, &status); + srv->lightness->handlers->light_get(srv->lightness, NULL, &status); sys_put_le16(status.remaining_time ? light_to_repr(status.target, ACTUAL) : status.current, &data[0]); @@ -431,7 +431,7 @@ static void scene_recall(struct bt_mesh_model *model, const uint8_t data[], { struct bt_mesh_light_hsl_srv *srv = model->user_data; - if (atomic_test_bit(&srv->lightness.flags, LIGHTNESS_SRV_FLAG_EXTENDED_BY_LIGHT_CTRL)) { + if (atomic_test_bit(&srv->lightness->flags, LIGHTNESS_SRV_FLAG_EXTENDED_BY_LIGHT_CTRL)) { return; } @@ -441,7 +441,7 @@ static void scene_recall(struct bt_mesh_model *model, const uint8_t data[], .transition = transition, }; - lightness_srv_change_lvl(&srv->lightness, NULL, &light_set, &light_status, false); + lightness_srv_change_lvl(srv->lightness, NULL, &light_set, &light_status, false); } static void scene_recall_complete(struct bt_mesh_model *model) @@ -453,7 +453,7 @@ static void scene_recall_complete(struct bt_mesh_model *model) srv->hue.handlers->get(&srv->hue, NULL, &hue_status); srv->sat.handlers->get(&srv->sat, NULL, &sat_status); - srv->lightness.handlers->light_get(&srv->lightness, NULL, &light_status); + srv->lightness->handlers->light_get(srv->lightness, NULL, &light_status); struct bt_mesh_light_hsl_status hsl = HSL_STATUS_INIT(&hue_status, &sat_status, &light_status, current); @@ -502,7 +502,7 @@ static int bt_mesh_light_hsl_srv_init(struct bt_mesh_model *model) * stack, but it makes it a lot easier to extend this model, as * we won't have to support multiple extenders. */ - bt_mesh_model_extend(model, srv->lightness.lightness_model); + bt_mesh_model_extend(model, srv->lightness->lightness_model); bt_mesh_model_extend( model, bt_mesh_model_find( bt_mesh_model_elem(model), @@ -534,7 +534,7 @@ static int bt_mesh_light_hsl_srv_start(struct bt_mesh_model *model) bt_mesh_dtt_srv_transition_get(model, &transition); - switch (srv->lightness.ponoff.on_power_up) { + switch (srv->lightness->ponoff.on_power_up) { case BT_MESH_ON_POWER_UP_ON: case BT_MESH_ON_POWER_UP_OFF: hue.lvl = srv->hue.dflt; @@ -565,7 +565,7 @@ static int bt_mesh_light_hsl_srv_start(struct bt_mesh_model *model) /* The lightness server updated its "last" value in its * start function, which has already completed: */ - .lightness = srv->lightness.last, + .lightness = srv->lightness->last, }, .remaining_time = 0, }; diff --git a/subsys/bluetooth/mesh/light_xyl_srv.c b/subsys/bluetooth/mesh/light_xyl_srv.c index ed07b78d4676..ad256cf35e92 100644 --- a/subsys/bluetooth/mesh/light_xyl_srv.c +++ b/subsys/bluetooth/mesh/light_xyl_srv.c @@ -54,8 +54,8 @@ static void xyl_get(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_lightness_status lightness = { 0 }; struct bt_mesh_light_xy_status xy = { 0 }; - srv->lightness_srv.handlers->light_get(&srv->lightness_srv, ctx, - &lightness); + srv->lightness_srv->handlers->light_get(srv->lightness_srv, ctx, + &lightness); srv->handlers->xy_get(srv, ctx, &xy); status->params.xy = xy.current; @@ -135,8 +135,8 @@ static void xyl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, set.transition = model_transition_get(srv->model, &transition, buf); light.transition = set.transition; - lightness_srv_disable_control(&srv->lightness_srv); - lightness_srv_change_lvl(&srv->lightness_srv, ctx, &light, &light_rsp, true); + lightness_srv_disable_control(srv->lightness_srv); + lightness_srv_change_lvl(srv->lightness_srv, ctx, &light, &light_rsp, true); srv->handlers->xy_set(srv, ctx, &set, &status); srv->xy_last.x = set.params.x; srv->xy_last.y = set.params.y; @@ -197,8 +197,8 @@ static void target_get_handle(struct bt_mesh_model *model, struct bt_mesh_light_xy_status status = { 0 }; struct bt_mesh_lightness_status light = { 0 }; - srv->lightness_srv.handlers->light_get(&srv->lightness_srv, ctx, - &light); + srv->lightness_srv->handlers->light_get(srv->lightness_srv, ctx, + &light); srv->handlers->xy_get(srv, ctx, &status); struct bt_mesh_light_xyl_status xyl_status = { @@ -214,7 +214,7 @@ static void default_encode_status(struct bt_mesh_light_xyl_srv *srv, struct net_buf_simple *buf) { bt_mesh_model_msg_init(buf, BT_MESH_LIGHT_XYL_OP_DEFAULT_STATUS); - net_buf_simple_add_le16(buf, srv->lightness_srv.default_light); + net_buf_simple_add_le16(buf, srv->lightness_srv->default_light); net_buf_simple_add_le16(buf, srv->xy_default.x); net_buf_simple_add_le16(buf, srv->xy_default.y); } @@ -244,7 +244,7 @@ static void default_set(struct bt_mesh_model *model, srv->xy_default.x = net_buf_simple_pull_le16(buf); srv->xy_default.y = net_buf_simple_pull_le16(buf); - lightness_srv_default_set(&srv->lightness_srv, ctx, light); + lightness_srv_default_set(srv->lightness_srv, ctx, light); store_state(srv); if (srv->handlers->default_update) { @@ -442,7 +442,7 @@ static ssize_t scene_store(struct bt_mesh_model *model, uint8_t data[]) struct bt_mesh_lightness_status light = { 0 }; struct scene_data *scene = (struct scene_data *)&data[0]; - srv->lightness_srv.handlers->light_get(&srv->lightness_srv, NULL, &light); + srv->lightness_srv->handlers->light_get(srv->lightness_srv, NULL, &light); srv->handlers->xy_get(srv, NULL, &xy_rsp); if (xy_rsp.remaining_time) { @@ -480,7 +480,7 @@ static void scene_recall(struct bt_mesh_model *model, const uint8_t data[], srv->xy_last.y = xy_set.params.y; store_state(srv); - if (atomic_test_bit(&srv->lightness_srv.flags, + if (atomic_test_bit(&srv->lightness_srv->flags, LIGHTNESS_SRV_FLAG_EXTENDED_BY_LIGHT_CTRL)) { return; } @@ -491,7 +491,7 @@ static void scene_recall(struct bt_mesh_model *model, const uint8_t data[], .transition = transition, }; - lightness_srv_change_lvl(&srv->lightness_srv, NULL, &light, &light_status, false); + lightness_srv_change_lvl(srv->lightness_srv, NULL, &light, &light_status, false); } static void scene_recall_complete(struct bt_mesh_model *model) @@ -502,7 +502,7 @@ static void scene_recall_complete(struct bt_mesh_model *model) struct bt_mesh_light_xy_status xy_status = { 0 }; srv->handlers->xy_get(srv, NULL, &xy_status); - srv->lightness_srv.handlers->light_get(&srv->lightness_srv, NULL, &light_status); + srv->lightness_srv->handlers->light_get(srv->lightness_srv, NULL, &light_status); xyl_status.params.xy = xy_status.current; xyl_status.params.lightness = light_status.current; @@ -553,7 +553,7 @@ static int bt_mesh_light_xyl_srv_init(struct bt_mesh_model *model) * stack, but it makes it a lot easier to extend this model, as * we won't have to support multiple extenders. */ - bt_mesh_model_extend(model, srv->lightness_srv.lightness_model); + bt_mesh_model_extend(model, srv->lightness_srv->lightness_model); bt_mesh_model_extend( model, bt_mesh_model_find( bt_mesh_model_elem(model), @@ -586,14 +586,14 @@ static int bt_mesh_light_xyl_srv_start(struct bt_mesh_model *model) struct bt_mesh_light_xyl_srv *srv = model->user_data; struct bt_mesh_light_xy_status status; struct bt_mesh_model_transition transition = { - .time = srv->lightness_srv.ponoff.dtt.transition_time, + .time = srv->lightness_srv->ponoff.dtt.transition_time, .delay = 0, }; struct bt_mesh_light_xy_set set = { .transition = &transition, }; - switch (srv->lightness_srv.ponoff.on_power_up) { + switch (srv->lightness_srv->ponoff.on_power_up) { case BT_MESH_ON_POWER_UP_ON: /* Intentional fallthrough */ case BT_MESH_ON_POWER_UP_OFF: diff --git a/tests/bluetooth/tester/src/model_handler.c b/tests/bluetooth/tester/src/model_handler.c index dea540743c5f..41f1ab897ecb 100644 --- a/tests/bluetooth/tester/src/model_handler.c +++ b/tests/bluetooth/tester/src/model_handler.c @@ -695,6 +695,22 @@ struct light_hsl_ctx { struct bt_mesh_light_hsl_srv srv; struct light_hue_ctx light_hue_ctx; struct light_sat_ctx light_sat_ctx; + struct lightness_ctx *lightness_ctx; +}; + +struct light_xy_ctx { + struct bt_mesh_light_xyl_srv srv; + struct k_work_delayable work; + uint32_t remaining; + uint32_t period; + struct bt_mesh_light_xy current; + struct bt_mesh_light_xy target; + struct lightness_ctx *lightness_ctx; +}; + +struct light_xyl_hsl_ctx { + struct light_xy_ctx xyl_ctx; + struct light_hsl_ctx hsl_ctx; struct lightness_ctx lightness_ctx; }; @@ -703,8 +719,8 @@ static void light_hsl_status(struct light_hsl_ctx *ctx, { rsp->params.hue = ctx->light_hue_ctx.current; rsp->params.saturation = ctx->light_sat_ctx.current; - rsp->params.lightness = ctx->lightness_ctx.current; - rsp->remaining_time = MAX(MAX(ctx->lightness_ctx.remaining, + rsp->params.lightness = ctx->lightness_ctx->current; + rsp->remaining_time = MAX(MAX(ctx->lightness_ctx->remaining, ctx->light_hue_ctx.remaining), ctx->light_sat_ctx.remaining); } @@ -733,7 +749,7 @@ static void periodic_light_hue_work(struct k_work *work) struct light_hsl_ctx *hsl_ctx = CONTAINER_OF(ctx, struct light_hsl_ctx, light_hue_ctx); struct light_sat_ctx *sat_ctx = &hsl_ctx->light_sat_ctx; - struct lightness_ctx *lightness_ctx = &hsl_ctx->lightness_ctx; + struct lightness_ctx *lightness_ctx = hsl_ctx->lightness_ctx; ctx->remaining -= ctx->period; @@ -832,7 +848,7 @@ static void periodic_light_sat_work(struct k_work *work) struct light_hsl_ctx *hsl_ctx = CONTAINER_OF(ctx, struct light_hsl_ctx, light_sat_ctx); struct light_hue_ctx *hue_ctx = &hsl_ctx->light_hue_ctx; - struct lightness_ctx *lightness_ctx = &hsl_ctx->lightness_ctx; + struct lightness_ctx *lightness_ctx = hsl_ctx->lightness_ctx; ctx->remaining -= ctx->period; @@ -907,111 +923,6 @@ static const struct bt_mesh_light_sat_srv_handlers sat_cb = { .get = light_sat_get, }; -static void periodic_light_hsl_lightness_work(struct k_work *work) -{ - struct lightness_ctx *ctx = - CONTAINER_OF(work, struct lightness_ctx, work); - struct light_hsl_ctx *hsl_ctx = - CONTAINER_OF(ctx, struct light_hsl_ctx, lightness_ctx); - struct light_hue_ctx *hue_ctx = &hsl_ctx->light_hue_ctx; - struct light_sat_ctx *sat_ctx = &hsl_ctx->light_sat_ctx; - - ctx->remaining -= ctx->period; - - if ((ctx->remaining <= ctx->period) || - (abs(ctx->target - ctx->current) <= PWM_SIZE_STEP)) { - ctx->current = ctx->target; - ctx->remaining = 0; - /* Publish the new value at the end of the transition */ - struct bt_mesh_lightness_status status; - - lightness_status(ctx, &status); - bt_mesh_lightness_srv_pub(&hsl_ctx->srv.lightness, NULL, - &status); - - if (hue_ctx->remaining == 0 && sat_ctx->remaining == 0) { - struct bt_mesh_light_hsl_status hsl_status; - - light_hsl_status(hsl_ctx, &hsl_status); - bt_mesh_light_hsl_srv_pub(&hsl_ctx->srv, NULL, &hsl_status); - } - return; - } else if (ctx->target > ctx->current) { - ctx->current += PWM_SIZE_STEP; - } else { - ctx->current -= PWM_SIZE_STEP; - } - - k_work_reschedule(&ctx->work, K_MSEC(ctx->period)); -} - -static void light_hsl_lightness_set(struct bt_mesh_lightness_srv *srv, - struct bt_mesh_msg_ctx *ctx, - const struct bt_mesh_lightness_set *set, - struct bt_mesh_lightness_status *rsp) -{ - struct bt_mesh_light_hsl_srv *hsl_srv = - CONTAINER_OF(srv, struct bt_mesh_light_hsl_srv, lightness); - struct light_hsl_ctx *hsl_ctx = - CONTAINER_OF(hsl_srv, struct light_hsl_ctx, srv); - struct lightness_ctx *l_ctx = &hsl_ctx->lightness_ctx; - uint32_t step_cnt; - - l_ctx->target = set->lvl; - if (set->transition) { - l_ctx->remaining = set->transition->time + set->transition->delay; - } else { - l_ctx->remaining = 0; - } - - if (l_ctx->remaining) { - step_cnt = abs(l_ctx->target - l_ctx->current) / PWM_SIZE_STEP; - start_new_lightness_trans(step_cnt, set->transition, l_ctx); - } else { - l_ctx->current = l_ctx->target; - } - - lightness_status(l_ctx, rsp); - - struct bt_mesh_light_hsl_status hsl_status; - - light_hsl_status(hsl_ctx, &hsl_status); - bt_mesh_light_hsl_srv_pub(&hsl_ctx->srv, NULL, &hsl_status); -} - -static void light_hsl_lightness_get(struct bt_mesh_lightness_srv *srv, - struct bt_mesh_msg_ctx *ctx, - struct bt_mesh_lightness_status *rsp) -{ - struct bt_mesh_light_hsl_srv *hsl_srv = - CONTAINER_OF(srv, struct bt_mesh_light_hsl_srv, lightness); - struct light_hsl_ctx *hsl_ctx = - CONTAINER_OF(hsl_srv, struct light_hsl_ctx, srv); - struct lightness_ctx *l_ctx = &hsl_ctx->lightness_ctx; - - lightness_status(l_ctx, rsp); -} - -static const struct bt_mesh_lightness_srv_handlers hsl_lightness_srv_handlers = { - .light_set = light_hsl_lightness_set, - .light_get = light_hsl_lightness_get, -}; - -static struct light_hsl_ctx light_hsl_ctx = { - .srv = BT_MESH_LIGHT_HSL_SRV_INIT(&hue_cb, &sat_cb, - &hsl_lightness_srv_handlers), -}; - -struct light_xy_ctx { - struct bt_mesh_light_xyl_srv srv; - struct k_work_delayable work; - uint32_t remaining; - uint32_t period; - struct bt_mesh_light_xy current; - struct bt_mesh_light_xy target; - struct lightness_ctx xyl_lightness_ctx; -}; - static void start_new_light_xy_trans(uint32_t step_cnt, const struct bt_mesh_model_transition *transition, @@ -1036,7 +947,7 @@ static void xyl_get(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_lightness_status lightness = { 0 }; struct bt_mesh_light_xy_status xy = { 0 }; - srv->lightness_srv.handlers->light_get(&srv->lightness_srv, ctx, + srv->lightness_srv->handlers->light_get(srv->lightness_srv, ctx, &lightness); srv->handlers->xy_get(srv, ctx, &xy); @@ -1050,6 +961,8 @@ static void periodic_light_xy_work(struct k_work *work) { struct light_xy_ctx *ctx = CONTAINER_OF(work, struct light_xy_ctx, work); + struct light_xyl_hsl_ctx *xyl_hsl_ctx = + CONTAINER_OF(ctx, struct light_xyl_hsl_ctx, xyl_ctx); ctx->remaining -= ctx->period; @@ -1060,10 +973,15 @@ static void periodic_light_xy_work(struct k_work *work) ctx->current.y = ctx->target.y; ctx->remaining = 0; /* Publish the new value at the end of the transition */ - struct bt_mesh_light_xyl_status status; + struct bt_mesh_light_xyl_status xyl_status; + struct bt_mesh_light_hsl_status hsl_status; + + xyl_get(&ctx->srv, NULL, &xyl_status); + bt_mesh_light_xyl_srv_pub(&ctx->srv, NULL, &xyl_status); + + light_hsl_status(&xyl_hsl_ctx->hsl_ctx, &hsl_status); + bt_mesh_light_hsl_srv_pub(&xyl_hsl_ctx->hsl_ctx.srv, NULL, &hsl_status); - xyl_get(&ctx->srv, NULL, &status); - bt_mesh_light_xyl_srv_pub(&ctx->srv, NULL, &status); return; } else if ((ctx->target.x > ctx->current.x) && (ctx->target.y > ctx->current.y)) { @@ -1084,6 +1002,9 @@ static void light_xy_set(struct bt_mesh_light_xyl_srv *srv, { struct light_xy_ctx *l_ctx = CONTAINER_OF(srv, struct light_xy_ctx, srv); + struct light_xyl_hsl_ctx *xyl_hsl_ctx = + CONTAINER_OF(l_ctx, struct light_xyl_hsl_ctx, xyl_ctx); + struct bt_mesh_light_hsl_status hsl_status; uint32_t step_cnt; l_ctx->target.x = set->params.x; @@ -1105,6 +1026,9 @@ static void light_xy_set(struct bt_mesh_light_xyl_srv *srv, l_ctx->current.y = l_ctx->target.y; } light_xy_status(l_ctx, rsp); + + light_hsl_status(&xyl_hsl_ctx->hsl_ctx, &hsl_status); + bt_mesh_light_hsl_srv_pub(&xyl_hsl_ctx->hsl_ctx.srv, NULL, &hsl_status); } static void light_xy_get(struct bt_mesh_light_xyl_srv *srv, struct bt_mesh_msg_ctx *ctx, @@ -1121,12 +1045,14 @@ static const struct bt_mesh_light_xyl_srv_handlers light_xyl_handlers = { .xy_get = light_xy_get, }; -static void periodic_light_xyl_lightness_work(struct k_work *work) +static void periodic_light_xyl_hsl_lightness_work(struct k_work *work) { struct lightness_ctx *ctx = CONTAINER_OF(work, struct lightness_ctx, work); - struct light_xy_ctx *xyl_ctx = - CONTAINER_OF(ctx, struct light_xy_ctx, xyl_lightness_ctx); + struct light_xyl_hsl_ctx *xyl_hsl_ctx = + CONTAINER_OF(ctx, struct light_xyl_hsl_ctx, lightness_ctx); + struct light_hue_ctx *hue_ctx = &xyl_hsl_ctx->hsl_ctx.light_hue_ctx; + struct light_sat_ctx *sat_ctx = &xyl_hsl_ctx->hsl_ctx.light_sat_ctx; ctx->remaining -= ctx->period; @@ -1138,8 +1064,14 @@ static void periodic_light_xyl_lightness_work(struct k_work *work) struct bt_mesh_lightness_status status; lightness_status(ctx, &status); - bt_mesh_lightness_srv_pub(&xyl_ctx->srv.lightness_srv, NULL, - &status); + bt_mesh_lightness_srv_pub(&xyl_hsl_ctx->lightness_ctx.srv, NULL, &status); + + if (hue_ctx->remaining == 0 && sat_ctx->remaining == 0) { + struct bt_mesh_light_hsl_status hsl_status; + + light_hsl_status(&xyl_hsl_ctx->hsl_ctx, &hsl_status); + bt_mesh_light_hsl_srv_pub(&xyl_hsl_ctx->hsl_ctx.srv, NULL, &hsl_status); + } return; } else if (ctx->target > ctx->current) { ctx->current += PWM_SIZE_STEP; @@ -1150,16 +1082,16 @@ static void periodic_light_xyl_lightness_work(struct k_work *work) k_work_reschedule(&ctx->work, K_MSEC(ctx->period)); } -static void light_xyl_lightness_set(struct bt_mesh_lightness_srv *srv, +static void light_xyl_hsl_lightness_set(struct bt_mesh_lightness_srv *srv, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_lightness_set *set, struct bt_mesh_lightness_status *rsp) { - struct bt_mesh_light_xyl_srv *xyl_srv = - CONTAINER_OF(srv, struct bt_mesh_light_xyl_srv, lightness_srv); - struct light_xy_ctx *xyl_ctx = - CONTAINER_OF(xyl_srv, struct light_xy_ctx, srv); - struct lightness_ctx *l_ctx = &xyl_ctx->xyl_lightness_ctx; + struct lightness_ctx *l_ctx = CONTAINER_OF(srv, struct lightness_ctx, srv); + struct light_xyl_hsl_ctx *xyl_hsl_ctx = + CONTAINER_OF(l_ctx, struct light_xyl_hsl_ctx, lightness_ctx); + struct bt_mesh_light_xyl_status xyl_status; + struct bt_mesh_light_hsl_status hsl_status; uint32_t step_cnt; l_ctx->target = set->lvl; @@ -1177,29 +1109,39 @@ static void light_xyl_lightness_set(struct bt_mesh_lightness_srv *srv, } lightness_status(l_ctx, rsp); + + xyl_get(&xyl_hsl_ctx->xyl_ctx.srv, NULL, &xyl_status); + bt_mesh_light_xyl_srv_pub(&xyl_hsl_ctx->xyl_ctx.srv, NULL, &xyl_status); + + light_hsl_status(&xyl_hsl_ctx->hsl_ctx, &hsl_status); + bt_mesh_light_hsl_srv_pub(&xyl_hsl_ctx->hsl_ctx.srv, NULL, &hsl_status); } -static void light_xyl_lightness_get(struct bt_mesh_lightness_srv *srv, +static void light_xyl_hsl_lightness_get(struct bt_mesh_lightness_srv *srv, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_lightness_status *rsp) { - struct bt_mesh_light_xyl_srv *xyl_srv = - CONTAINER_OF(srv, struct bt_mesh_light_xyl_srv, lightness_srv); - struct light_xy_ctx *xyl_ctx = - CONTAINER_OF(xyl_srv, struct light_xy_ctx, srv); - struct lightness_ctx *l_ctx = &xyl_ctx->xyl_lightness_ctx; + struct lightness_ctx *l_ctx = CONTAINER_OF(srv, struct lightness_ctx, srv); lightness_status(l_ctx, rsp); } -static const struct bt_mesh_lightness_srv_handlers xyl_lightness_srv_handlers = { - .light_set = light_xyl_lightness_set, - .light_get = light_xyl_lightness_get, +static const struct bt_mesh_lightness_srv_handlers xyl_hsl_lightness_srv_handlers = { + .light_set = light_xyl_hsl_lightness_set, + .light_get = light_xyl_hsl_lightness_get, }; -static struct light_xy_ctx light_xy_ctx = { - .srv = BT_MESH_LIGHT_XYL_SRV_INIT(&xyl_lightness_srv_handlers, - &light_xyl_handlers), +static struct light_xyl_hsl_ctx xyl_hsl_ctx = { + .lightness_ctx.srv = BT_MESH_LIGHTNESS_SRV_INIT(&xyl_hsl_lightness_srv_handlers), + .xyl_ctx = { + .srv = BT_MESH_LIGHT_XYL_SRV_INIT(&xyl_hsl_ctx.lightness_ctx.srv, + &light_xyl_handlers), + .lightness_ctx = &xyl_hsl_ctx.lightness_ctx, + }, + .hsl_ctx = { + .srv = BT_MESH_LIGHT_HSL_SRV_INIT(&xyl_hsl_ctx.lightness_ctx.srv, &hue_cb, &sat_cb), + .lightness_ctx = &xyl_hsl_ctx.lightness_ctx, + } }; static void get_faults(uint8_t *faults, uint8_t faults_size, uint8_t *dst, @@ -1357,29 +1299,27 @@ static struct bt_mesh_elem elements[] = { BT_MESH_MODEL_NONE), BT_MESH_ELEM(50, BT_MESH_MODEL_LIST( - BT_MESH_MODEL_LIGHT_HSL_SRV(&light_hsl_ctx.srv)), + BT_MESH_MODEL_LIGHTNESS_SRV(&xyl_hsl_ctx.lightness_ctx.srv), + BT_MESH_MODEL_LIGHT_XYL_SRV(&xyl_hsl_ctx.xyl_ctx.srv), + BT_MESH_MODEL_LIGHT_HSL_SRV(&xyl_hsl_ctx.hsl_ctx.srv)), BT_MESH_MODEL_NONE), BT_MESH_ELEM(51, BT_MESH_MODEL_LIST( - BT_MESH_MODEL_LIGHT_HUE_SRV(&light_hsl_ctx.srv.hue)), + BT_MESH_MODEL_LIGHT_HUE_SRV(&xyl_hsl_ctx.hsl_ctx.srv.hue)), BT_MESH_MODEL_NONE), BT_MESH_ELEM(52, BT_MESH_MODEL_LIST( - BT_MESH_MODEL_LIGHT_SAT_SRV(&light_hsl_ctx.srv.sat)), + BT_MESH_MODEL_LIGHT_SAT_SRV(&xyl_hsl_ctx.hsl_ctx.srv.sat)), BT_MESH_MODEL_NONE), BT_MESH_ELEM(60, - BT_MESH_MODEL_LIST( - BT_MESH_MODEL_LIGHT_XYL_SRV(&light_xy_ctx.srv)), - BT_MESH_MODEL_NONE), - BT_MESH_ELEM(70, BT_MESH_MODEL_LIST( BT_MESH_MODEL_LIGHT_CTL_SRV(&light_ctl_ctx.srv)), BT_MESH_MODEL_NONE), - BT_MESH_ELEM(71, + BT_MESH_ELEM(61, BT_MESH_MODEL_LIST( BT_MESH_MODEL_LIGHT_TEMP_SRV(&light_ctl_ctx.srv.temp_srv)), BT_MESH_MODEL_NONE), - BT_MESH_ELEM(80, + BT_MESH_ELEM(70, BT_MESH_MODEL_LIST( BT_MESH_MODEL_ONOFF_CLI(&onoff_cli), BT_MESH_MODEL_LVL_CLI(&lvl_cli), @@ -1411,18 +1351,16 @@ const struct bt_mesh_comp *model_handler_init(void) { k_work_init_delayable(&lvl_ctx.work, periodic_led_work); k_work_init_delayable(&lightness_ctx.work, periodic_led_lightness_work); - k_work_init_delayable(&light_xy_ctx.work, periodic_light_xy_work); - k_work_init_delayable(&light_xy_ctx.xyl_lightness_ctx.work, - periodic_light_xyl_lightness_work); + k_work_init_delayable(&xyl_hsl_ctx.xyl_ctx.work, periodic_light_xy_work); + k_work_init_delayable(&xyl_hsl_ctx.lightness_ctx.work, + periodic_light_xyl_hsl_lightness_work); + k_work_init_delayable(&xyl_hsl_ctx.hsl_ctx.light_hue_ctx.work, + periodic_light_hue_work); + k_work_init_delayable(&xyl_hsl_ctx.hsl_ctx.light_sat_ctx.work, + periodic_light_sat_work); k_work_init_delayable(&light_ctl_ctx.ctl_lightness_ctx.work, periodic_light_ctl_lightness_work); k_work_init_delayable(&light_ctl_ctx.light_temp_ctx.work, periodic_light_temp_work); - k_work_init_delayable(&light_hsl_ctx.light_hue_ctx.work, - periodic_light_hue_work); - k_work_init_delayable(&light_hsl_ctx.light_sat_ctx.work, - periodic_light_sat_work); - k_work_init_delayable(&light_hsl_ctx.lightness_ctx.work, - periodic_light_hsl_lightness_work); return ∁ } From 006789428d0f7950631250af4d7bab8140501e09 Mon Sep 17 00:00:00 2001 From: Deidre Casey Date: Mon, 16 Aug 2021 10:53:42 +0200 Subject: [PATCH 019/126] doc: improve instructions for building on cmd line ref: NCSDK-10742 Improve the instructions for building images on the command line in the Getting Started sections. Emphasized installing nrfjprog after using Toolchain Manager. Signed-off-by: Deidre Casey --- doc/nrf/gs_assistant.rst | 16 +++++++--------- doc/nrf/gs_programming.rst | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/doc/nrf/gs_assistant.rst b/doc/nrf/gs_assistant.rst index e13ad9a8f5ce..2d0532f3f601 100644 --- a/doc/nrf/gs_assistant.rst +++ b/doc/nrf/gs_assistant.rst @@ -54,18 +54,16 @@ Once you have installed the Toolchain manager, open it in nRF Connect for Deskto Click :guilabel:`Settings` in the navigation bar to specify where you want to install the |NCS|. Then, in :guilabel:`SDK Environments`, click the :guilabel:`Install` button next to the |NCS| version that you want to install. - The |NCS| version of your choice is installed on your machine, and the :guilabel:`Install` button changes to :guilabel:`Open IDE`. -This button lets you start SEGGER Embedded Studio if you want to start :ref:`gs_programming_ses`. -.. figure:: images/gs-assistant_tm_installed.png - :alt: The Toolchain manager options after installing the nRF Connect SDK version, cropped +There are two ways you can build an application: - The Toolchain Manager options after installing the |NCS| version +1. To :ref:`build with SES `, click on the :guilabel:`Open IDE` button. +#. To build on the command line, use the following steps: -Additionally, the dropdown menu becomes available. -Among other options, this menu lets you open bash and command prompt that use the installed Toolchain manager tools. -You can use the :guilabel:`Open bash` option from this menu when you start :ref:`gs_programming_cmd`. + 1. With admin permissions enabled, download and install the `nRF Command Line Tools`_. + #. Restart the Toolchain manager application. + #. Follow the instructions in :ref:`gs_programming_cmd`. .. figure:: images/gs-assistant_tm_dropdown.png :alt: The Toolchain manager dropdown menu for the installed nRF Connect SDK version, cropped @@ -77,7 +75,7 @@ You can use the :guilabel:`Open bash` option from this menu when you start :ref: Getting Started Assistant ************************* -The |GSA| app is available for Linux. +The |GSA| app is the automatic installation option for Linux. It provides you with step-by-step instructions for installing the toolchain for |NCS|. The app allows you to check which of the required tools are already installed on your computer and verify the installation. diff --git a/doc/nrf/gs_programming.rst b/doc/nrf/gs_programming.rst index 0a87518b9640..78990de81c25 100644 --- a/doc/nrf/gs_programming.rst +++ b/doc/nrf/gs_programming.rst @@ -143,7 +143,7 @@ If it is installed, verify that its location is correct in the PATH variable or, Building on the command line **************************** -Complete the following steps to build |NCS| projects on the command line after completing the :ref:`command-line build setup `. +After completing the :ref:`manual ` or :ref:`automatic ` command-line build setup, use the following steps to build |NCS| projects on the command line. 1. Open a terminal window. From 7769bfcd608547cc1fffffe136b1fa5ad5b84963 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Robert=20Ga=C5=82at?= Date: Thu, 29 Jul 2021 17:42:01 +0200 Subject: [PATCH 020/126] manifest: update homekit manifest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - [x] https://github.com/nrfconnect/sdk-homekit/pull/201 Signed-off-by: Robert Gałat --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 6d933afc1489..5c9e68407458 100644 --- a/west.yml +++ b/west.yml @@ -166,7 +166,7 @@ manifest: path: modules/lib/cddl-gen - name: homekit repo-path: sdk-homekit - revision: c01ec0692c959790b0f73f036c8485da6ade562a + revision: b62c2a617e3b404d44baf0df6cd3a3b12c98429c groups: - homekit - name: find-my From 372f2a990d704b74179a90105070cfaf6959eea1 Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk Date: Tue, 10 Aug 2021 13:39:41 +0200 Subject: [PATCH 021/126] samples: matter: Fixed BLE advertising when not in pairing mode. Currently for the Device Firmware Upgrade purposes nrfconnect devices may advertise over BLE even with Thread enabled and not in the pairing mode. However they should not advertise CHIPoBLE service, but the one used for DFU (SMP). * Added dfu_over_smp module handling performing DFU over BLE using SMP protocol. * Changed light_bulb config to start pairing mode autostart on boot, as it is no longer forbidden by the spec. Signed-off-by: Kamil Kasperczyk --- doc/nrf/releases/release-notes-latest.rst | 2 + samples/matter/common/src/dfu_over_smp.cpp | 117 ++++++++++++++++++ samples/matter/common/src/dfu_over_smp.h | 39 ++++++ samples/matter/light_bulb/CMakeLists.txt | 4 + samples/matter/light_bulb/README.rst | 5 +- samples/matter/light_bulb/prj.conf | 4 + samples/matter/light_bulb/src/app_event.h | 9 +- samples/matter/light_bulb/src/app_task.cpp | 98 ++++++--------- samples/matter/light_bulb/src/app_task.h | 9 +- samples/matter/lock/CMakeLists.txt | 4 + samples/matter/lock/prj.conf | 1 + samples/matter/lock/src/app_event.h | 11 +- samples/matter/lock/src/app_task.cpp | 98 ++++++--------- samples/matter/lock/src/app_task.h | 9 +- samples/matter/template/prj.conf | 1 + samples/matter/weather_station/CMakeLists.txt | 4 + samples/matter/weather_station/prj_debug.conf | 1 + .../matter/weather_station/prj_release.conf | 1 + .../matter/weather_station/src/app_event.h | 9 +- .../matter/weather_station/src/app_task.cpp | 90 ++++++-------- samples/matter/weather_station/src/app_task.h | 8 +- west.yml | 2 +- 22 files changed, 346 insertions(+), 180 deletions(-) create mode 100644 samples/matter/common/src/dfu_over_smp.cpp create mode 100644 samples/matter/common/src/dfu_over_smp.h diff --git a/doc/nrf/releases/release-notes-latest.rst b/doc/nrf/releases/release-notes-latest.rst index 91d270fec702..499cd7a19d41 100644 --- a/doc/nrf/releases/release-notes-latest.rst +++ b/doc/nrf/releases/release-notes-latest.rst @@ -185,6 +185,8 @@ The following list summarizes the most important changes inherited from the upst * Support for Certificate-Authenticated Session Establishment (CASE) for communication among operational Matter nodes. * Support for OpenThread's DNS Client to enable Matter node discovery on Thread devices. + * Fixed the known issue KRKNWK-10387 where Matter service was needlessly advertised over Bluetooth LE during DFU. + Now if Matter pairing mode is not opened and the Bluetooth LE advertising is needed due to DFU requirements, only the SMP service is advertised. Documentation ============= diff --git a/samples/matter/common/src/dfu_over_smp.cpp b/samples/matter/common/src/dfu_over_smp.cpp new file mode 100644 index 000000000000..361aac95400f --- /dev/null +++ b/samples/matter/common/src/dfu_over_smp.cpp @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include "dfu_over_smp.h" + +#if !defined(CONFIG_MCUMGR_SMP_BT) || !defined(CONFIG_MCUMGR_CMD_IMG_MGMT) || !defined(CONFIG_MCUMGR_CMD_OS_MGMT) +#error "DFUOverSMP requires MCUMGR module configs enabled" +#endif + +#include +#include +#include +#include + +#include + +#include + +DFUOverSMP DFUOverSMP::sDFUOverSMP; + +void DFUOverSMP::Init(DFUOverSMPRestartAdvertisingHandler startAdvertisingCb) +{ + os_mgmt_register_group(); + img_mgmt_register_group(); + img_mgmt_set_upload_cb(UploadConfirmHandler, NULL); + + memset(&mBleConnCallbacks, 0, sizeof(mBleConnCallbacks)); + mBleConnCallbacks.disconnected = OnBleDisconnect; + + bt_conn_cb_register(&mBleConnCallbacks); + + restartAdvertisingCallback = startAdvertisingCb; +} + +void DFUOverSMP::ConfirmNewImage() +{ + /* Check if the image is run in the REVERT mode and eventually + * confirm it to prevent reverting on the next boot. */ + if (mcuboot_swap_type() == BOOT_SWAP_TYPE_REVERT) { + if (boot_write_img_confirmed()) { + ChipLogError(DeviceLayer, + "Confirming firmware image failed, it will be reverted on the next boot."); + } else { + ChipLogProgress(DeviceLayer, "New firmware image confirmed."); + } + } +} + +int DFUOverSMP::UploadConfirmHandler(uint32_t offset, uint32_t size, void *arg) +{ + /* For now just print update progress and confirm data chunk without any additional checks. */ + ChipLogProgress(DeviceLayer, "Software update progress %d B / %d B", offset, size); + + return 0; +} + +void DFUOverSMP::StartServer() +{ + if (!mIsEnabled) { + mIsEnabled = true; + smp_bt_register(); + + ChipLogProgress(DeviceLayer, "Enabled software update"); + + /* Start SMP advertising only in case CHIPoBLE advertising is not working. */ + if (!chip::DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled()) + StartBLEAdvertising(); + } else { + ChipLogProgress(DeviceLayer, "Software update is already enabled"); + } +} + +void DFUOverSMP::StartBLEAdvertising() +{ + if (!mIsEnabled) + return; + + const char *deviceName = bt_get_name(); + const uint8_t advFlags = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR; + + bt_data ad[] = { BT_DATA(BT_DATA_FLAGS, &advFlags, sizeof(advFlags)), + BT_DATA(BT_DATA_NAME_COMPLETE, deviceName, static_cast(strlen(deviceName))) }; + + int rc; + bt_le_adv_param advParams = BT_LE_ADV_PARAM_INIT(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME, + BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, nullptr); + + rc = bt_le_adv_stop(); + if (rc) { + ChipLogError(DeviceLayer, "SMP advertising stop failed (rc %d)", rc); + } + + rc = bt_le_adv_start(&advParams, ad, ARRAY_SIZE(ad), NULL, 0); + if (rc) { + ChipLogError(DeviceLayer, "SMP advertising start failed (rc %d)", rc); + } else { + ChipLogProgress(DeviceLayer, "Started SMP service BLE advertising"); + } +} + +void DFUOverSMP::OnBleDisconnect(struct bt_conn *conId, uint8_t reason) +{ + chip::DeviceLayer::PlatformMgr().LockChipStack(); + + /* After BLE disconnect SMP advertising needs to be restarted. Before making it ensure that BLE disconnect was + * not triggered by closing CHIPoBLE service connection (in that case CHIPoBLE advertising needs to be + * restarted). */ + if (!chip::DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled() && + chip::DeviceLayer::ConnectivityMgr().NumBLEConnections() == 0) { + sDFUOverSMP.restartAdvertisingCallback(); + } + + chip::DeviceLayer::PlatformMgr().UnlockChipStack(); +} diff --git a/samples/matter/common/src/dfu_over_smp.h b/samples/matter/common/src/dfu_over_smp.h new file mode 100644 index 000000000000..a44a74f6e424 --- /dev/null +++ b/samples/matter/common/src/dfu_over_smp.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#pragma once + +#include + +#include + +typedef void (*DFUOverSMPRestartAdvertisingHandler)(void); + +class DFUOverSMP { +public: + void Init(DFUOverSMPRestartAdvertisingHandler startAdvertisingCb); + void ConfirmNewImage(); + void StartServer(); + void StartBLEAdvertising(); + bool IsEnabled() { return mIsEnabled; } + +private: + friend DFUOverSMP &GetDFUOverSMP(void); + + static int UploadConfirmHandler(uint32_t offset, uint32_t size, void *arg); + static void OnBleDisconnect(bt_conn *conn, uint8_t reason); + + bool mIsEnabled; + bt_conn_cb mBleConnCallbacks; + DFUOverSMPRestartAdvertisingHandler restartAdvertisingCallback; + + static DFUOverSMP sDFUOverSMP; +}; + +inline DFUOverSMP &GetDFUOverSMP(void) +{ + return DFUOverSMP::sDFUOverSMP; +} diff --git a/samples/matter/light_bulb/CMakeLists.txt b/samples/matter/light_bulb/CMakeLists.txt index 789f1244e590..39be6d5fda84 100644 --- a/samples/matter/light_bulb/CMakeLists.txt +++ b/samples/matter/light_bulb/CMakeLists.txt @@ -72,3 +72,7 @@ target_sources(app PRIVATE ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/server/Server.cpp ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/server/StorablePeerConnection.cpp) # NORDIC SDK APP END + +if(BUILD_WITH_DFU) + target_sources(app PRIVATE ${COMMON_ROOT}/src/dfu_over_smp.cpp) +endif() diff --git a/samples/matter/light_bulb/README.rst b/samples/matter/light_bulb/README.rst index 3a4dd598476c..6e92bccdb1bc 100644 --- a/samples/matter/light_bulb/README.rst +++ b/samples/matter/light_bulb/README.rst @@ -189,9 +189,8 @@ Commissioning the device :start-after: matter_door_lock_sample_commissioning_start :end-before: matter_door_lock_sample_commissioning_end -Before starting the commissioning procedure, you must make the device discoverable over Bluetooth LE. -To enable Bluetooth LE for a predefined period of time (15 minutes by default), press **Button 4**. -If the Bluetooth LE advertising times out, you can re-enable using the same button. +Before starting the commissioning procedure, the device must be made discoverable over Bluetooth LE, which starts automatically upon the device startup, but only for a predefined period of time (15 minutes by default). +If the Bluetooth LE advertising times out, you can re-enable it by pressing **Button 4**. When you start the commissioning procedure, the controller must get the commissioning information from the Matter accessory device. The data payload, which includes the device discriminator and setup PIN code, is encoded within a QR code, printed to the UART console, and can be shared using an NFC tag. diff --git a/samples/matter/light_bulb/prj.conf b/samples/matter/light_bulb/prj.conf index 27e6f356b7f6..f18d7f186685 100644 --- a/samples/matter/light_bulb/prj.conf +++ b/samples/matter/light_bulb/prj.conf @@ -9,6 +9,9 @@ CONFIG_CHIP=y CONFIG_CHIP_PROJECT_CONFIG="src/chip_project_config.h" CONFIG_STD_CPP14=y +# Enable CHIP pairing automatically on application start. +CONFIG_CHIP_ENABLE_PAIRING_AUTOSTART=y + # General networking settings CONFIG_NETWORKING=y CONFIG_NET_IPV6_NBR_CACHE=n @@ -34,6 +37,7 @@ CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" # Enable Bluetooth Low Energy CONFIG_BT=y CONFIG_BT_PERIPHERAL=y +CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_DEVICE_APPEARANCE=0 CONFIG_BT_DEVICE_NAME_DYNAMIC=y CONFIG_BT_DEVICE_NAME_MAX=15 diff --git a/samples/matter/light_bulb/src/app_event.h b/samples/matter/light_bulb/src/app_event.h index b1cba9a3c81f..1fbc613e27a3 100644 --- a/samples/matter/light_bulb/src/app_event.h +++ b/samples/matter/light_bulb/src/app_event.h @@ -13,7 +13,14 @@ struct AppEvent { enum FunctionEventType : uint8_t { FunctionPress = Level + 1, FunctionRelease, FunctionTimer }; - enum OtherEventType : uint8_t { StartThread = FunctionTimer + 1, StartBleAdvertising, PublishLightBulbService }; + enum OtherEventType : uint8_t { + StartThread = FunctionTimer + 1, + StartBleAdvertising, + PublishLightBulbService, +#ifdef CONFIG_MCUMGR_SMP_BT + StartSMPAdvertising +#endif + }; AppEvent() = default; diff --git a/samples/matter/light_bulb/src/app_task.cpp b/samples/matter/light_bulb/src/app_task.cpp index 5c9a31ddd715..9dd4a7db6d44 100644 --- a/samples/matter/light_bulb/src/app_task.cpp +++ b/samples/matter/light_bulb/src/app_task.cpp @@ -20,20 +20,6 @@ #include #include -/* MCUMgr BT FOTA includes */ -#ifdef CONFIG_MCUMGR_CMD_OS_MGMT -#include "os_mgmt/os_mgmt.h" -#endif -#ifdef CONFIG_MCUMGR_CMD_IMG_MGMT -#include "img_mgmt/img_mgmt.h" -#endif -#ifdef CONFIG_MCUMGR_SMP_BT -#include -#endif -#ifdef CONFIG_BOOTLOADER_MCUBOOT -#include -#endif - #include #include #include @@ -87,16 +73,9 @@ int AppTask::Init() return ret; } -#ifdef CONFIG_BOOTLOADER_MCUBOOT - /* Check if the image is run in the REVERT mode and eventually - confirm it to prevent reverting on the next boot. */ - if (mcuboot_swap_type() == BOOT_SWAP_TYPE_REVERT) { - if (boot_write_img_confirmed()) { - LOG_ERR("Confirming firmware image failed, it will be reverted on the next boot."); - } else { - LOG_INF("New firmware image confirmed."); - } - } +#ifdef CONFIG_MCUMGR_SMP_BT + GetDFUOverSMP().Init(RequestSMPAdvertisingStart); + GetDFUOverSMP().ConfirmNewImage(); #endif /* Initialize function timer */ @@ -116,7 +95,7 @@ int AppTask::Init() ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); -#ifdef CONFIG_CHIP_NFC_COMMISSIONING +#if defined(CONFIG_CHIP_NFC_COMMISSIONING) || defined(CONFIG_MCUMGR_SMP_BT) PlatformMgr().AddEventHandler(AppTask::ChipEventHandler, 0); #endif @@ -214,13 +193,12 @@ void AppTask::UpdateClusterState() } } -int AppTask::SoftwareUpdateConfirmationHandler(uint32_t offset, uint32_t size, void *arg) +#ifdef CONFIG_MCUMGR_SMP_BT +void AppTask::RequestSMPAdvertisingStart(void) { - /* For now just print update progress and confirm data chunk without any additional checks. */ - LOG_INF("Software update progress %d B / %d B", offset, size); - - return 0; + sAppTask.PostEvent(AppEvent{ AppEvent::StartSMPAdvertising }); } +#endif void AppTask::DispatchEvent(const AppEvent &aEvent) { @@ -257,6 +235,11 @@ void AppTask::DispatchEvent(const AppEvent &aEvent) case AppEvent::StartBleAdvertising: StartBLEAdvertisingHandler(); break; +#ifdef CONFIG_MCUMGR_SMP_BT + case AppEvent::StartSMPAdvertising: + GetDFUOverSMP().StartBLEAdvertising(); + break; +#endif case AppEvent::PublishLightBulbService: sLightBulbPublishService.Publish(); break; @@ -304,19 +287,8 @@ void AppTask::FunctionReleaseHandler() sAppTask.CancelFunctionTimer(); sAppTask.mFunction = TimerFunction::NoneSelected; -#if defined(CONFIG_MCUMGR_SMP_BT) && defined(CONFIG_MCUMGR_CMD_IMG_MGMT) && defined(CONFIG_MCUMGR_CMD_OS_MGMT) - if (!sAppTask.mSoftwareUpdateEnabled) { - sAppTask.mSoftwareUpdateEnabled = true; - os_mgmt_register_group(); - img_mgmt_register_group(); - img_mgmt_set_upload_cb(SoftwareUpdateConfirmationHandler, NULL); - smp_bt_register(); - - LOG_INF("Enabled software update"); - } else { - LOG_INF("Software update is already enabled"); - } - +#ifdef CONFIG_MCUMGR_SMP_BT + GetDFUOverSMP().StartServer(); #else LOG_INF("Software update is disabled"); #endif @@ -372,8 +344,9 @@ void AppTask::StartThreadHandler() void AppTask::StartBLEAdvertisingHandler() { - if (chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned() && !sAppTask.mSoftwareUpdateEnabled) { - LOG_INF("NFC Tag emulation and BLE advertisement not started - device is commissioned to a Thread network."); + /* Don't allow on starting Matter service BLE advertising after Thread provisioning. */ + if (ConnectivityMgr().IsThreadProvisioned()) { + LOG_INF("NFC Tag emulation and Matter service BLE advertisement not started - device is commissioned to a Thread network."); return; } @@ -389,23 +362,34 @@ void AppTask::StartBLEAdvertisingHandler() } } -#ifdef CONFIG_CHIP_NFC_COMMISSIONING void AppTask::ChipEventHandler(const ChipDeviceEvent *event, intptr_t /* arg */) { - if (event->Type == DeviceEventType::kCHIPoBLEAdvertisingChange) { - if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) { - if (NFCMgr().IsTagEmulationStarted()) { - LOG_INF("NFC Tag emulation is already started"); - } else { - ShareQRCodeOverNFC( - chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); - } - } else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) { - NFCMgr().StopTagEmulation(); + if (event->Type != DeviceEventType::kCHIPoBLEAdvertisingChange) + return; + + if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) { +#ifdef CONFIG_CHIP_NFC_COMMISSIONING + NFCMgr().StopTagEmulation(); +#endif +#ifdef CONFIG_MCUMGR_SMP_BT + /* After CHIPoBLE advertising stop, start advertising SMP in case Thread is enabled or there are no + * active CHIPoBLE connections (exclude the case when CHIPoBLE advertising is stopped on the connection + * time) */ + if (GetDFUOverSMP().IsEnabled() && + (ConnectivityMgr().IsThreadProvisioned() || ConnectivityMgr().NumBLEConnections() == 0)) + sAppTask.RequestSMPAdvertisingStart(); +#endif + } +#ifdef CONFIG_CHIP_NFC_COMMISSIONING + else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) { + if (NFCMgr().IsTagEmulationStarted()) { + LOG_INF("NFC Tag emulation is already started"); + } else { + ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); } } -} #endif +} void AppTask::ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged) { diff --git a/samples/matter/light_bulb/src/app_task.h b/samples/matter/light_bulb/src/app_task.h index 3fff5159b0e5..b2716e8dd09c 100644 --- a/samples/matter/light_bulb/src/app_task.h +++ b/samples/matter/light_bulb/src/app_task.h @@ -11,6 +11,10 @@ #include +#ifdef CONFIG_MCUMGR_SMP_BT +#include "dfu_over_smp.h" +#endif + struct k_timer; class AppTask { @@ -40,7 +44,9 @@ class AppTask { static void ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged); static void TimerEventHandler(k_timer *timer); static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent *event, intptr_t arg); - static int SoftwareUpdateConfirmationHandler(uint32_t offset, uint32_t size, void *arg); +#ifdef CONFIG_MCUMGR_SMP_BT + static void RequestSMPAdvertisingStart(void); +#endif friend AppTask &GetAppTask(); @@ -49,7 +55,6 @@ class AppTask { TimerFunction mFunction = TimerFunction::NoneSelected; static AppTask sAppTask; - bool mSoftwareUpdateEnabled = false; }; inline AppTask &GetAppTask() diff --git a/samples/matter/lock/CMakeLists.txt b/samples/matter/lock/CMakeLists.txt index d2be93dbca49..6ff7389d779e 100644 --- a/samples/matter/lock/CMakeLists.txt +++ b/samples/matter/lock/CMakeLists.txt @@ -70,3 +70,7 @@ target_sources(app PRIVATE ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/server/Server.cpp ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/server/StorablePeerConnection.cpp) # NORDIC SDK APP END + +if(BUILD_WITH_DFU) + target_sources(app PRIVATE ${COMMON_ROOT}/src/dfu_over_smp.cpp) +endif() diff --git a/samples/matter/lock/prj.conf b/samples/matter/lock/prj.conf index c14dc25e577e..2cf1b1f8a832 100644 --- a/samples/matter/lock/prj.conf +++ b/samples/matter/lock/prj.conf @@ -34,6 +34,7 @@ CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" # Enable Bluetooth Low Energy CONFIG_BT=y CONFIG_BT_PERIPHERAL=y +CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_DEVICE_APPEARANCE=0 CONFIG_BT_DEVICE_NAME_DYNAMIC=y CONFIG_BT_DEVICE_NAME_MAX=15 diff --git a/samples/matter/lock/src/app_event.h b/samples/matter/lock/src/app_event.h index e8c96de5fe6e..87e2d81d2ce3 100644 --- a/samples/matter/lock/src/app_event.h +++ b/samples/matter/lock/src/app_event.h @@ -13,7 +13,13 @@ struct AppEvent { enum FunctionEventType : uint8_t { FunctionPress = CompleteLockAction + 1, FunctionRelease, FunctionTimer }; - enum OtherEventType : uint8_t { StartThread = FunctionTimer + 1, StartBleAdvertising }; + enum OtherEventType : uint8_t { + StartThread = FunctionTimer + 1, + StartBleAdvertising, +#ifdef CONFIG_MCUMGR_SMP_BT + StartSMPAdvertising +#endif + }; AppEvent() = default; AppEvent(LockEventType type, bool chipInitiated) : Type(type), LockEvent{ chipInitiated } {} @@ -23,8 +29,7 @@ struct AppEvent { uint8_t Type; union { - struct { - /* was the event triggered by CHIP Data Model layer */ + struct { /* was the event triggered by CHIP Data Model layer */ bool ChipInitiated; } LockEvent; }; diff --git a/samples/matter/lock/src/app_task.cpp b/samples/matter/lock/src/app_task.cpp index 702cf679ea3f..f92a9dd86718 100644 --- a/samples/matter/lock/src/app_task.cpp +++ b/samples/matter/lock/src/app_task.cpp @@ -19,20 +19,6 @@ #include #include -/* MCUMgr BT FOTA includes */ -#ifdef CONFIG_MCUMGR_CMD_OS_MGMT -#include "os_mgmt/os_mgmt.h" -#endif -#ifdef CONFIG_MCUMGR_CMD_IMG_MGMT -#include "img_mgmt/img_mgmt.h" -#endif -#ifdef CONFIG_MCUMGR_SMP_BT -#include -#endif -#ifdef CONFIG_BOOTLOADER_MCUBOOT -#include -#endif - #include #include #include @@ -83,16 +69,9 @@ int AppTask::Init() return ret; } -#ifdef CONFIG_BOOTLOADER_MCUBOOT - /* Check if the image is run in the REVERT mode and eventually - confirm it to prevent reverting on the next boot. */ - if (mcuboot_swap_type() == BOOT_SWAP_TYPE_REVERT) { - if (boot_write_img_confirmed()) { - LOG_ERR("Confirming firmware image failed, it will be reverted on the next boot."); - } else { - LOG_INF("New firmware image confirmed."); - } - } +#ifdef CONFIG_MCUMGR_SMP_BT + GetDFUOverSMP().Init(RequestSMPAdvertisingStart); + GetDFUOverSMP().ConfirmNewImage(); #endif /* Initialize function timer */ @@ -107,7 +86,7 @@ int AppTask::Init() ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); -#ifdef CONFIG_CHIP_NFC_COMMISSIONING +#if defined(CONFIG_CHIP_NFC_COMMISSIONING) || defined(CONFIG_MCUMGR_SMP_BT) PlatformMgr().AddEventHandler(AppTask::ChipEventHandler, 0); #endif @@ -196,13 +175,12 @@ void AppTask::UpdateClusterState() } } -int AppTask::SoftwareUpdateConfirmationHandler(uint32_t offset, uint32_t size, void *arg) +#ifdef CONFIG_MCUMGR_SMP_BT +void AppTask::RequestSMPAdvertisingStart(void) { - /* For now just print update progress and confirm data chunk without any additional checks. */ - LOG_INF("Software update progress %d B / %d B", offset, size); - - return 0; + sAppTask.PostEvent(AppEvent{ AppEvent::StartSMPAdvertising }); } +#endif void AppTask::DispatchEvent(const AppEvent &event) { @@ -236,6 +214,11 @@ void AppTask::DispatchEvent(const AppEvent &event) case AppEvent::StartBleAdvertising: StartBLEAdvertisingHandler(); break; +#ifdef CONFIG_MCUMGR_SMP_BT + case AppEvent::StartSMPAdvertising: + GetDFUOverSMP().StartBLEAdvertising(); + break; +#endif default: LOG_INF("Unknown event received"); break; @@ -277,19 +260,8 @@ void AppTask::FunctionReleaseHandler() sAppTask.CancelFunctionTimer(); sAppTask.mFunction = TimerFunction::NoneSelected; -#if defined(CONFIG_MCUMGR_SMP_BT) && defined(CONFIG_MCUMGR_CMD_IMG_MGMT) && defined(CONFIG_MCUMGR_CMD_OS_MGMT) - if (!sAppTask.mSoftwareUpdateEnabled) { - sAppTask.mSoftwareUpdateEnabled = true; - os_mgmt_register_group(); - img_mgmt_register_group(); - img_mgmt_set_upload_cb(SoftwareUpdateConfirmationHandler, NULL); - smp_bt_register(); - - LOG_INF("Enabled software update"); - } else { - LOG_INF("Software update is already enabled"); - } - +#ifdef CONFIG_MCUMGR_SMP_BT + GetDFUOverSMP().StartServer(); #else LOG_INF("Software update is disabled"); #endif @@ -348,8 +320,9 @@ void AppTask::StartThreadHandler() void AppTask::StartBLEAdvertisingHandler() { - if (chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned() && !sAppTask.mSoftwareUpdateEnabled) { - LOG_INF("NFC Tag emulation and BLE advertisement not started - device is commissioned to a Thread network."); + /* Don't allow on starting Matter service BLE advertising after Thread provisioning. */ + if (ConnectivityMgr().IsThreadProvisioned()) { + LOG_INF("NFC Tag emulation and Matter service BLE advertisement not started - device is commissioned to a Thread network."); return; } @@ -365,23 +338,34 @@ void AppTask::StartBLEAdvertisingHandler() } } -#ifdef CONFIG_CHIP_NFC_COMMISSIONING void AppTask::ChipEventHandler(const ChipDeviceEvent *event, intptr_t /* arg */) { - if (event->Type == DeviceEventType::kCHIPoBLEAdvertisingChange) { - if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) { - if (NFCMgr().IsTagEmulationStarted()) { - LOG_INF("NFC Tag emulation is already started"); - } else { - ShareQRCodeOverNFC( - chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); - } - } else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) { - NFCMgr().StopTagEmulation(); + if (event->Type != DeviceEventType::kCHIPoBLEAdvertisingChange) + return; + + if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) { +#ifdef CONFIG_CHIP_NFC_COMMISSIONING + NFCMgr().StopTagEmulation(); +#endif +#ifdef CONFIG_MCUMGR_SMP_BT + /* After CHIPoBLE advertising stop, start advertising SMP in case Thread is enabled or there are no + * active CHIPoBLE connections (exclude the case when CHIPoBLE advertising is stopped on the connection + * time) */ + if (GetDFUOverSMP().IsEnabled() && + (ConnectivityMgr().IsThreadProvisioned() || ConnectivityMgr().NumBLEConnections() == 0)) + sAppTask.RequestSMPAdvertisingStart(); +#endif + } +#ifdef CONFIG_CHIP_NFC_COMMISSIONING + else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) { + if (NFCMgr().IsTagEmulationStarted()) { + LOG_INF("NFC Tag emulation is already started"); + } else { + ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); } } -} #endif +} void AppTask::ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged) { diff --git a/samples/matter/lock/src/app_task.h b/samples/matter/lock/src/app_task.h index f33a6415075a..3794fdf057e9 100644 --- a/samples/matter/lock/src/app_task.h +++ b/samples/matter/lock/src/app_task.h @@ -11,6 +11,10 @@ #include +#ifdef CONFIG_MCUMGR_SMP_BT +#include "dfu_over_smp.h" +#endif + struct k_timer; class AppTask { @@ -38,7 +42,9 @@ class AppTask { static void ButtonEventHandler(uint32_t buttonState, uint32_t hasChanged); static void TimerEventHandler(k_timer *timer); static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent *event, intptr_t arg); - static int SoftwareUpdateConfirmationHandler(uint32_t offset, uint32_t size, void *arg); +#ifdef CONFIG_MCUMGR_SMP_BT + static void RequestSMPAdvertisingStart(void); +#endif friend AppTask &GetAppTask(); @@ -48,7 +54,6 @@ class AppTask { static AppTask sAppTask; bool mFunctionTimerActive = false; - bool mSoftwareUpdateEnabled = false; }; inline AppTask &GetAppTask() diff --git a/samples/matter/template/prj.conf b/samples/matter/template/prj.conf index d676d1ca4c63..a03862677437 100644 --- a/samples/matter/template/prj.conf +++ b/samples/matter/template/prj.conf @@ -35,6 +35,7 @@ CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" # Enable Bluetooth Low Energy CONFIG_BT=y CONFIG_BT_PERIPHERAL=y +CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_DEVICE_APPEARANCE=0 CONFIG_BT_DEVICE_NAME_DYNAMIC=y CONFIG_BT_DEVICE_NAME_MAX=15 diff --git a/samples/matter/weather_station/CMakeLists.txt b/samples/matter/weather_station/CMakeLists.txt index 31281251b916..f272a6ec9832 100644 --- a/samples/matter/weather_station/CMakeLists.txt +++ b/samples/matter/weather_station/CMakeLists.txt @@ -71,3 +71,7 @@ target_sources(app PRIVATE ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/server/Server.cpp ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/server/StorablePeerConnection.cpp) # NORDIC SDK APP END + +if(BUILD_WITH_DFU) + target_sources(app PRIVATE ${COMMON_ROOT}/src/dfu_over_smp.cpp) +endif() diff --git a/samples/matter/weather_station/prj_debug.conf b/samples/matter/weather_station/prj_debug.conf index b0e54e7c208e..f0ad8bf28df1 100644 --- a/samples/matter/weather_station/prj_debug.conf +++ b/samples/matter/weather_station/prj_debug.conf @@ -35,6 +35,7 @@ CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" # Enable Bluetooth Low Energy CONFIG_BT=y CONFIG_BT_PERIPHERAL=y +CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_DEVICE_APPEARANCE=0 CONFIG_BT_DEVICE_NAME_DYNAMIC=y CONFIG_BT_DEVICE_NAME_MAX=15 diff --git a/samples/matter/weather_station/prj_release.conf b/samples/matter/weather_station/prj_release.conf index 06600db8e33c..21de91e15c2a 100644 --- a/samples/matter/weather_station/prj_release.conf +++ b/samples/matter/weather_station/prj_release.conf @@ -35,6 +35,7 @@ CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" # Enable Bluetooth Low Energy CONFIG_BT=y CONFIG_BT_PERIPHERAL=y +CONFIG_BT_GATT_DYNAMIC_DB=y CONFIG_BT_DEVICE_APPEARANCE=0 CONFIG_BT_DEVICE_NAME_DYNAMIC=y CONFIG_BT_DEVICE_NAME_MAX=15 diff --git a/samples/matter/weather_station/src/app_event.h b/samples/matter/weather_station/src/app_event.h index 2bb80bc649c7..d826d70b6db7 100644 --- a/samples/matter/weather_station/src/app_event.h +++ b/samples/matter/weather_station/src/app_event.h @@ -7,7 +7,14 @@ #pragma once struct AppEvent { - enum class Type { kButtonPush, kButtonRelease, kTimer }; + enum class Type { + kButtonPush, + kButtonRelease, + kTimer, +#ifdef CONFIG_MCUMGR_SMP_BT + kStartSMPAdvertising +#endif + }; using Handler = void (*)(AppEvent *); diff --git a/samples/matter/weather_station/src/app_task.cpp b/samples/matter/weather_station/src/app_task.cpp index 1002364657d7..7d7ea14424a3 100644 --- a/samples/matter/weather_station/src/app_task.cpp +++ b/samples/matter/weather_station/src/app_task.cpp @@ -16,20 +16,6 @@ #include #include -/* MCUMgr BT FOTA includes */ -#ifdef CONFIG_MCUMGR_CMD_OS_MGMT -#include "os_mgmt/os_mgmt.h" -#endif -#ifdef CONFIG_MCUMGR_CMD_IMG_MGMT -#include "img_mgmt/img_mgmt.h" -#endif -#ifdef CONFIG_MCUMGR_SMP_BT -#include -#endif -#ifdef CONFIG_BOOTLOADER_MCUBOOT -#include -#endif - #include #include #include @@ -100,22 +86,10 @@ int AppTask::Init() return -1; } -#ifdef CONFIG_BOOTLOADER_MCUBOOT - /* Check if the image is run in the REVERT mode and eventually - confirm it to prevent reverting on the next boot. */ - if (mcuboot_swap_type() == BOOT_SWAP_TYPE_REVERT) { - if (boot_write_img_confirmed()) { - LOG_ERR("Confirming firmware image failed, it will be reverted on the next boot."); - } else { - LOG_INF("New firmware image confirmed."); - } - } - - /* Register SMP service for software update purpose */ - os_mgmt_register_group(); - img_mgmt_register_group(); - img_mgmt_set_upload_cb(SoftwareUpdateConfirmationHandler, NULL); - smp_bt_register(); +#ifdef CONFIG_MCUMGR_SMP_BT + GetDFUOverSMP().Init(RequestSMPAdvertisingStart); + GetDFUOverSMP().ConfirmNewImage(); + GetDFUOverSMP().StartServer(); #endif /* Initialize timer */ @@ -128,7 +102,7 @@ int AppTask::Init() ConfigurationMgr().LogDeviceConfig(); PrintOnboardingCodes(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); -#ifdef CONFIG_CHIP_NFC_COMMISSIONING +#if defined(CONFIG_CHIP_NFC_COMMISSIONING) || defined(CONFIG_MCUMGR_SMP_BT) PlatformMgr().AddEventHandler(AppTask::ChipEventHandler, 0); #endif @@ -137,13 +111,11 @@ int AppTask::Init() void AppTask::OpenPairingWindow() { - /* Start BLE advertising despite having Thread provisioned only in case of supporting for DFU over BLE. */ -#ifndef CONFIG_BOOTLOADER_MCUBOOT + /* Don't allow on starting Matter service BLE advertising after Thread provisioning. */ if (ConnectivityMgr().IsThreadProvisioned()) { - LOG_INF("NFC Tag emulation and BLE advertisement not started - device is commissioned to a Thread network."); + LOG_INF("NFC Tag emulation and Matter service BLE advertisement not started - device is commissioned to a Thread network."); return; } -#endif if (ConnectivityMgr().IsBLEAdvertisingEnabled()) { LOG_INF("BLE Advertisement is already enabled"); @@ -204,13 +176,16 @@ void AppTask::PostEvent(AppEvent::Type type, AppEvent::Handler handler) PostEvent(&event); } -int AppTask::SoftwareUpdateConfirmationHandler(uint32_t offset, uint32_t size, void *arg) +#ifdef CONFIG_MCUMGR_SMP_BT +void AppTask::RequestSMPAdvertisingStart(void) { - /* For now just print update progress and confirm data chunk without any additional checks. */ - LOG_INF("Software update progress %d B / %d B", offset, size); - - return 0; + // AppEvent event; + // event.mType = AppEvent::Type::kStartSMPAdvertising; + // event.mHandler = [](AppEvent *) { GetDFUOverSMP().StartBLEAdvertising(); }; + sAppTask.PostEvent(AppEvent::Type::kStartSMPAdvertising, + [](AppEvent *) { GetDFUOverSMP().StartBLEAdvertising(); }); } +#endif void AppTask::DispatchEvent(AppEvent *event) { @@ -393,20 +368,31 @@ void AppTask::UpdateLedState() sRedLED.Animate(); } -#ifdef CONFIG_CHIP_NFC_COMMISSIONING void AppTask::ChipEventHandler(const ChipDeviceEvent *event, intptr_t /* arg */) { - if (event->Type == DeviceEventType::kCHIPoBLEAdvertisingChange) { - if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) { - if (NFCMgr().IsTagEmulationStarted()) { - LOG_INF("NFC Tag emulation is already started"); - } else { - ShareQRCodeOverNFC( - chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); - } - } else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) { - NFCMgr().StopTagEmulation(); + if (event->Type != DeviceEventType::kCHIPoBLEAdvertisingChange) + return; + + if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Stopped) { +#ifdef CONFIG_CHIP_NFC_COMMISSIONING + NFCMgr().StopTagEmulation(); +#endif +#ifdef CONFIG_MCUMGR_SMP_BT + /* After CHIPoBLE advertising stop, start advertising SMP in case Thread is enabled or there are no + * active CHIPoBLE connections (exclude the case when CHIPoBLE advertising is stopped on the connection + * time) */ + if (GetDFUOverSMP().IsEnabled() && + (ConnectivityMgr().IsThreadProvisioned() || ConnectivityMgr().NumBLEConnections() == 0)) + sAppTask.RequestSMPAdvertisingStart(); +#endif + } +#ifdef CONFIG_CHIP_NFC_COMMISSIONING + else if (event->CHIPoBLEAdvertisingChange.Result == kActivity_Started) { + if (NFCMgr().IsTagEmulationStarted()) { + LOG_INF("NFC Tag emulation is already started"); + } else { + ShareQRCodeOverNFC(chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)); } } -} #endif +} diff --git a/samples/matter/weather_station/src/app_task.h b/samples/matter/weather_station/src/app_task.h index 178d6fd76709..4cb6e2240ed1 100644 --- a/samples/matter/weather_station/src/app_task.h +++ b/samples/matter/weather_station/src/app_task.h @@ -10,6 +10,10 @@ #include +#ifdef CONFIG_MCUMGR_SMP_BT +#include "dfu_over_smp.h" +#endif + struct k_timer; class AppTask { @@ -28,7 +32,9 @@ class AppTask { void OpenPairingWindow(); void DispatchEvent(AppEvent *event); - static int SoftwareUpdateConfirmationHandler(uint32_t offset, uint32_t size, void *arg); +#ifdef CONFIG_MCUMGR_SMP_BT + static void RequestSMPAdvertisingStart(void); +#endif static void ButtonStateHandler(uint32_t buttonState, uint32_t hasChanged); static void ButtonPushHandler(AppEvent *event); static void ButtonReleaseHandler(AppEvent *event); diff --git a/west.yml b/west.yml index 5c9e68407458..c18f8c941ec6 100644 --- a/west.yml +++ b/west.yml @@ -116,7 +116,7 @@ manifest: - name: matter repo-path: sdk-connectedhomeip path: modules/lib/matter - revision: 5b90f5789e317812a49e981071de20b29a5fd343 + revision: 5f323a8e4aca12bd1c7ed819aab26075812d7f3d submodules: - name: nlio path: third_party/nlio/repo From f0a05573f6abbaba7a9a04a05b753d0ec4a65ff8 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Mon, 16 Aug 2021 12:46:36 +0200 Subject: [PATCH 022/126] caf: Fix typo in net_state event Fix typo that made it unable to see net_state events. Signed-off-by: Emil Obalski --- subsys/caf/events/net_state_event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/caf/events/net_state_event.c b/subsys/caf/events/net_state_event.c index d049c3cf7fd5..c0386e427a46 100644 --- a/subsys/caf/events/net_state_event.c +++ b/subsys/caf/events/net_state_event.c @@ -46,6 +46,6 @@ EVENT_INFO_DEFINE(net_state_event, profile_net_state_event); EVENT_TYPE_DEFINE(net_state_event, - IS_ENABLED(CONFIG_CAF_INIT_LOG_NET_EVENTS), + IS_ENABLED(CONFIG_CAF_INIT_LOG_NET_STATE_EVENTS), log_net_state_event, &net_state_event_info); From 818dcce9a9e2c88b2800bdbb2da7fddea3a51e73 Mon Sep 17 00:00:00 2001 From: Balaji Srinivasan Date: Sat, 14 Aug 2021 13:15:32 +0200 Subject: [PATCH 023/126] gps_sim: Fix validation of timeout configuration Make gps_sim validate timeout only for navigation modes other than GPS_NAV_MODE_SINGLE_FIX. This is because when in the navigation mode is GPS_NAV_MODE_SINGLE_FIX, the value of interval is irrelevant. Signed-off-by: Balaji Srinivasan --- drivers/gps/gps_sim/gps_sim.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gps/gps_sim/gps_sim.c b/drivers/gps/gps_sim/gps_sim.c index cd5a5aef21b4..0494dbf4d4b9 100644 --- a/drivers/gps/gps_sim/gps_sim.c +++ b/drivers/gps/gps_sim/gps_sim.c @@ -317,7 +317,8 @@ static int start(const struct device *dev, struct gps_config *cfg) return -EALREADY; } - if (cfg->timeout >= cfg->interval) { + if ((drv_data->cfg.nav_mode != GPS_NAV_MODE_SINGLE_FIX) && + (cfg->timeout >= cfg->interval)) { LOG_ERR("The timeout must be less than the interval"); return -EINVAL; } From 82d1ec0319d9ac7b01df1d62d4373276707464ca Mon Sep 17 00:00:00 2001 From: Tommi Kangas Date: Tue, 17 Aug 2021 08:20:10 +0300 Subject: [PATCH 024/126] net: lib: nrf_cloud: fix A-GPS data processing with GNSS API Support for GNSS API was still missing from one place. Changed code to allow A-GPS data processing also when no socket has been provided and GPS driver is not enabled. Signed-off-by: Tommi Kangas --- subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c index fd877aaa771f..63af12c02bf3 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_agps.c @@ -705,13 +705,12 @@ int nrf_cloud_agps_process(const char *buf, size_t buf_len, const int *socket) gps_dev = NULL; fd = *socket; - } else if (gps_dev == NULL) { + } else { gps_dev = device_get_binding("NRF9160_GPS"); - if (gps_dev == NULL) { - LOG_ERR("GPS is not enabled, A-GPS response unhandled"); - LOG_DBG("A-GPS_inject_active UNLOCKED"); - k_sem_give(&agps_injection_active); - return -ENODEV; + if (gps_dev != NULL) { + LOG_DBG("Using GPS driver to input assistance data"); + } else { + LOG_DBG("Using GNSS API to input assistance data"); } } From c566b40b5de02ea930dbd7be2646aad8afbf9a4b Mon Sep 17 00:00:00 2001 From: Tommi Kangas Date: Tue, 17 Aug 2021 08:28:10 +0300 Subject: [PATCH 025/126] lib: agps: fix debug log output Fixed incorrect debug log output when GNSS API is used. Signed-off-by: Tommi Kangas --- lib/agps/agps.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/agps/agps.c b/lib/agps/agps.c index 50b093cf2d41..abf31992bf60 100644 --- a/lib/agps/agps.c +++ b/lib/agps/agps.c @@ -258,11 +258,11 @@ static int init_supl(int socket) gnss_fd = socket; } else { gps_dev = device_get_binding("NRF9160_GPS"); - if (gps_dev == NULL) { + if (gps_dev != NULL) { + LOG_DBG("Using GPS driver to input assistance data"); + } else { LOG_DBG("Using GNSS API to input assistance data"); } - - LOG_DBG("Using GPS driver to input assistance data"); } LOG_INF("SUPL is initialized"); From 0fc8888738cbdc810d43d85402255f9fe5421b95 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Tue, 17 Aug 2021 12:48:29 +0200 Subject: [PATCH 026/126] thingy53: Update USB PID and device name Update USB device PID and device name according to agreed convention. Signed-off-by: Emil Obalski --- .../bluetooth/mesh/light/boards/thingy53_nrf5340_cpuapp.conf | 2 +- .../mesh/light_switch/boards/thingy53_nrf5340_cpuapp.conf | 2 +- .../peripheral_lbs/boards/thingy53_nrf5340_cpuapp.conf | 2 +- .../peripheral_uart/boards/thingy53_nrf5340_cpuapp.conf | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/bluetooth/mesh/light/boards/thingy53_nrf5340_cpuapp.conf b/samples/bluetooth/mesh/light/boards/thingy53_nrf5340_cpuapp.conf index ce39b5c95bd9..ebac1268e439 100644 --- a/samples/bluetooth/mesh/light/boards/thingy53_nrf5340_cpuapp.conf +++ b/samples/bluetooth/mesh/light/boards/thingy53_nrf5340_cpuapp.conf @@ -54,7 +54,7 @@ CONFIG_PM_EXTERNAL_FLASH_SIZE=0x800000 CONFIG_USB=y CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="Application Thingy:53" +CONFIG_USB_DEVICE_PRODUCT="Thingy:53 Application" CONFIG_USB_DEVICE_VID=0x1915 CONFIG_USB_DEVICE_PID=0x530C CONFIG_USB_CDC_ACM=y diff --git a/samples/bluetooth/mesh/light_switch/boards/thingy53_nrf5340_cpuapp.conf b/samples/bluetooth/mesh/light_switch/boards/thingy53_nrf5340_cpuapp.conf index c02b6f41df48..43ebf1b4f37a 100644 --- a/samples/bluetooth/mesh/light_switch/boards/thingy53_nrf5340_cpuapp.conf +++ b/samples/bluetooth/mesh/light_switch/boards/thingy53_nrf5340_cpuapp.conf @@ -55,7 +55,7 @@ CONFIG_PM_EXTERNAL_FLASH_SIZE=0x800000 CONFIG_USB=y CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="Application Thingy:53" +CONFIG_USB_DEVICE_PRODUCT="Thingy:53 Application" CONFIG_USB_DEVICE_VID=0x1915 CONFIG_USB_DEVICE_PID=0x530C CONFIG_USB_CDC_ACM=y diff --git a/samples/bluetooth/peripheral_lbs/boards/thingy53_nrf5340_cpuapp.conf b/samples/bluetooth/peripheral_lbs/boards/thingy53_nrf5340_cpuapp.conf index 996de735be47..67f6f28815e7 100644 --- a/samples/bluetooth/peripheral_lbs/boards/thingy53_nrf5340_cpuapp.conf +++ b/samples/bluetooth/peripheral_lbs/boards/thingy53_nrf5340_cpuapp.conf @@ -54,7 +54,7 @@ CONFIG_PM_EXTERNAL_FLASH_SIZE=0x800000 CONFIG_USB=y CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="Application Thingy:53" +CONFIG_USB_DEVICE_PRODUCT="Thingy:53 Application" CONFIG_USB_DEVICE_VID=0x1915 CONFIG_USB_DEVICE_PID=0x530C CONFIG_USB_CDC_ACM=y diff --git a/samples/bluetooth/peripheral_uart/boards/thingy53_nrf5340_cpuapp.conf b/samples/bluetooth/peripheral_uart/boards/thingy53_nrf5340_cpuapp.conf index 522baf021532..a11ce849cdf5 100644 --- a/samples/bluetooth/peripheral_uart/boards/thingy53_nrf5340_cpuapp.conf +++ b/samples/bluetooth/peripheral_uart/boards/thingy53_nrf5340_cpuapp.conf @@ -45,9 +45,9 @@ CONFIG_PM_EXTERNAL_FLASH_SIZE=0x800000 CONFIG_USB=y CONFIG_USB_DEVICE_STACK=y -CONFIG_USB_DEVICE_PRODUCT="Application Thingy:53" +CONFIG_USB_DEVICE_PRODUCT="Thingy:53 Nordic UART Service sample" CONFIG_USB_DEVICE_VID=0x1915 -CONFIG_USB_DEVICE_PID=0x530C +CONFIG_USB_DEVICE_PID=0x530E CONFIG_USB_CDC_ACM=y # Use CDC_ACM0 for logs, CDC_ACM1 has application-specific usage From 0a91ee47c3af152aca7b58ae4bbce8c973b91dd1 Mon Sep 17 00:00:00 2001 From: Akash Patel Date: Wed, 21 Jul 2021 19:09:30 -0700 Subject: [PATCH 027/126] doc: fixing typo from nrf5840 to nrf52840 Documentation references to nrf5840 or nRF5840 have been changed to nrf52840 or nRF52840 respectively Signed-off-by: Akash Patel --- doc/nrf/ug_bootloader_adding.rst | 6 +++--- doc/nrf/ug_bootloader_config.rst | 4 ++-- doc/nrf/ug_matter_configuring.rst | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/doc/nrf/ug_bootloader_adding.rst b/doc/nrf/ug_bootloader_adding.rst index f63885588751..f2220ae7b2c9 100644 --- a/doc/nrf/ug_bootloader_adding.rst +++ b/doc/nrf/ug_bootloader_adding.rst @@ -53,7 +53,7 @@ To ensure that the immutable bootloader occupies as little flash memory as possi .. code-block:: console - west build -b nrf52840dk_nrf5840 zephyr/samples/hello_world -- \ + west build -b nrf52840dk_nrf52840 zephyr/samples/hello_world -- \ -DCONFIG_SECURE_BOOT=y \ -Db0_CONF_FILE=prj_minimal.conf @@ -181,7 +181,7 @@ To use a custom signing command with this bootloader, set the following options .. code-block:: console - west build -b nrf52840dk_nrf5840 zephyr/samples/hello_world -- \ + west build -b nrf52840dk_nrf52840 zephyr/samples/hello_world -- \ -DCONFIG_SECURE_BOOT=y \ -DCONFIG_SB_SIGNING_CUSTOM=y \ -DCONFIG_SB_SIGNING_PUBLIC_KEY=\"/path/to/pub.pem\" \ @@ -302,7 +302,7 @@ To enable this configuration, apply the :file:`overlay-minimal-external-crypto.c .. code-block:: - west build -b nrf52840dk_nrf5840 zephyr/samples/hello_world -- \ + west build -b nrf52840dk_nrf52840 zephyr/samples/hello_world -- \ -DCONFIG_BOOTLOADER_MCUBOOT=y \ -Dmcuboot_OVERLAY_CONFIG=overlay-minimal-external-crypto.conf diff --git a/doc/nrf/ug_bootloader_config.rst b/doc/nrf/ug_bootloader_config.rst index 2b1596f13540..01f7f2c1ebef 100644 --- a/doc/nrf/ug_bootloader_config.rst +++ b/doc/nrf/ug_bootloader_config.rst @@ -40,7 +40,7 @@ For example, you can assign the :file:`my-custom-fragment.conf` fragment to the .. code-block:: console - west build -b nrf52840dk_nrf5840 zephyr/samples/hello_world -- \ + west build -b nrf52840dk_nrf52840 zephyr/samples/hello_world -- \ -DCONFIG_SECURE_BOOT=y \ -DCONFIG_BOOTLOADER_MCUBOOT=y \ -Db0_OVERLAY_CONFIG=my-custom-fragment.conf @@ -49,7 +49,7 @@ In the same way, you can replace ``b0`` with ``mcuboot`` to apply the :file:`my- .. code-block:: console - west build -b nrf52840dk_nrf5840 zephyr/samples/hello_world -- \ + west build -b nrf52840dk_nrf52840 zephyr/samples/hello_world -- \ -DCONFIG_SECURE_BOOT=y \ -DCONFIG_BOOTLOADER_MCUBOOT=y \ -Dmcuboot_OVERLAY_CONFIG=my-custom-fragment.conf diff --git a/doc/nrf/ug_matter_configuring.rst b/doc/nrf/ug_matter_configuring.rst index 1449fb42c96f..f44d2c6e8815 100644 --- a/doc/nrf/ug_matter_configuring.rst +++ b/doc/nrf/ug_matter_configuring.rst @@ -80,7 +80,7 @@ To use this setup, you need the following hardware: * 1x PC with Ubuntu (20.04 or newer) or 1x smartphone with Android 8+ * 1x Raspberry Pi Model 3B+ or newer (along with a SD card with at least 8 GB of memory) * 1x Wi-Fi Access Point supporting IPv6 (without the IPv6 Router Advertisement Guard enabled on the router) -* 1x nRF52840 DK or nRF5840 Dongle - for the Radio Co-Processor (RCP) device +* 1x nRF52840 DK or nRF52840 Dongle - for the Radio Co-Processor (RCP) device * 1x nRF52840 DK or nRF5340 DK - for the Matter accessory device (programmed with one of :ref:`matter_samples`) For information about how to configure and use the required components, complete steps from the following user guides: @@ -107,7 +107,7 @@ To use this setup, you need the following hardware: * 1x PC with Ubuntu (20.04 or newer) or Raspberry Pi Model 3B+ or newer with Ubuntu (20.04 or newer) instead of Raspbian OS * 1x Bluetooth LE dongle (can be embedded inside the PC, like it is on Raspberry Pi) -* 1x nRF52840 DK or nRF5840 Dongle - for the Radio Co-Processor (RCP) device +* 1x nRF52840 DK or nRF52840 Dongle - for the Radio Co-Processor (RCP) device * 1x nRF52840 DK or nRF5340 DK - for the Matter accessory device (programmed with one of :ref:`matter_samples`) For information about how to configure and use the required components, see the following user guides: From fb2bdb16dc2b9204ae9b53df64711e054f7b7521 Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Thu, 22 Jul 2021 12:29:00 +0200 Subject: [PATCH 028/126] workflows: contribs: Allow external contributions Update the text automatically added to PRs by external contributors to begin allowing external contributions, with some caveats. NCSDK-10067. Signed-off-by: Carles Cufi --- .github/workflows/contribs.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/contribs.yml b/.github/workflows/contribs.yml index 4cf1f0a0400e..67dc5ed61e27 100644 --- a/.github/workflows/contribs.yml +++ b/.github/workflows/contribs.yml @@ -15,9 +15,14 @@ jobs: command: 'external' messages: | Thank you for your contribution! - It seems you are not a member of the nrfconnect GitHub organization. - At this time we are not accepting external contributions, but this may change soon. - Please visit https://devzone.nordicsemi.com/ to raise any issues you found or ask for help. + It seems you are not a member of the nrfconnect GitHub organization. External contributions are handled as follows: + Large contributions, affecting multiple subsystems for example, may be rejected if they are complex, may introduce regressions due to lack of test coverage, or if they are not consistent with the architecture of nRF Connect SDK. + PRs will be run in our continuous integration (CI) test system. + If CI passes, PRs will be tagged for review and merged on successful completion of review. You may be asked to make some modifications to your contribution during review. + If CI fails, PRs may be rejected or may be tagged for review and rework. + PRs that become outdated due to other changes in the repository may be rejected or rework requested. + External contributions will be prioritized for review based on the relevance to current development efforts in nRF Connect SDK. Bug fix PRs will be prioritized. + You may raise issues or ask for help from our Technical Support team by visiting https://devzone.nordicsemi.com/. | The author of this pull request has now been added to the nrfconnect GitHub organization. labels: 'external' From 58db2cf0be9b80af57c82e29f26469e83bc15d6a Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Fri, 23 Jul 2021 12:20:27 +0200 Subject: [PATCH 029/126] samples: central_hids: Fix wrong protocol mode log Change fixes wrong log displayed during protocol mode change. Signed-off-by: Marek Pieta --- samples/bluetooth/central_hids/src/main.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/samples/bluetooth/central_hids/src/main.c b/samples/bluetooth/central_hids/src/main.c index 1e393fbf5f94..fe2933d67c55 100644 --- a/samples/bluetooth/central_hids/src/main.c +++ b/samples/bluetooth/central_hids/src/main.c @@ -421,14 +421,10 @@ static void button_bootmode(void) } int err; enum bt_hids_pm pm = bt_hogp_pm_get(&hogp); + enum bt_hids_pm new_pm = ((pm == BT_HIDS_PM_BOOT) ? BT_HIDS_PM_REPORT : BT_HIDS_PM_BOOT); - printk("Setting protocol mode: %s\n", - (pm == BT_HIDS_PM_BOOT) ? - "BOOT" : "REPORT"); - err = bt_hogp_pm_write(&hogp, - (pm == BT_HIDS_PM_BOOT) ? - BT_HIDS_PM_REPORT : - BT_HIDS_PM_BOOT); + printk("Setting protocol mode: %s\n", (new_pm == BT_HIDS_PM_BOOT) ? "BOOT" : "REPORT"); + err = bt_hogp_pm_write(&hogp, new_pm); if (err) { printk("Cannot change protocol mode (err %d)\n", err); } From d6e37f849d8530ee960215683366e2df781e3017 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 15:25:35 +0200 Subject: [PATCH 030/126] doc: nrf: improve libraries doc structure Improve the libraries documentation structure by using folders for each library. This removed the need of using the "lib_" prefix everywhere (a bad naming/organizational practice). Signed-off-by: Gerard Marull-Paretas --- doc/nrf/index.rst | 2 +- doc/nrf/libraries/{lib_bin.rst => bin/index.rst} | 2 +- .../index.rst} | 4 ++-- doc/nrf/libraries/{lib_caf.rst => caf/index.rst} | 4 ++-- doc/nrf/libraries/{lib_debug.rst => debug/index.rst} | 2 +- doc/nrf/libraries/{lib_dfu.rst => dfu/index.rst} | 4 ++-- doc/nrf/{libraries.rst => libraries/index.rst} | 2 +- doc/nrf/libraries/{lib_modem.rst => modem/index.rst} | 6 +++--- doc/nrf/libraries/{lib_mpsl.rst => mpsl/index.rst} | 2 +- .../{lib_networking.rst => networking/index.rst} | 2 +- doc/nrf/libraries/{lib_nfc.rst => nfc/index.rst} | 8 ++++---- doc/nrf/libraries/{lib_others.rst => others/index.rst} | 2 +- doc/nrf/libraries/{lib_shell.rst => shell/index.rst} | 2 +- doc/nrf/libraries/{lib_tfm.rst => tfm/index.rst} | 2 +- doc/nrf/libraries/{lib_zigbee.rst => zigbee/index.rst} | 6 +++--- 15 files changed, 25 insertions(+), 25 deletions(-) rename doc/nrf/libraries/{lib_bin.rst => bin/index.rst} (82%) rename doc/nrf/libraries/{lib_bluetooth_services.rst => bluetooth_services/index.rst} (77%) rename doc/nrf/libraries/{lib_caf.rst => caf/index.rst} (65%) rename doc/nrf/libraries/{lib_debug.rst => debug/index.rst} (80%) rename doc/nrf/libraries/{lib_dfu.rst => dfu/index.rst} (67%) rename doc/nrf/{libraries.rst => libraries/index.rst} (95%) rename doc/nrf/libraries/{lib_modem.rst => modem/index.rst} (59%) rename doc/nrf/libraries/{lib_mpsl.rst => mpsl/index.rst} (85%) rename doc/nrf/libraries/{lib_networking.rst => networking/index.rst} (83%) rename doc/nrf/libraries/{lib_nfc.rst => nfc/index.rst} (81%) rename doc/nrf/libraries/{lib_others.rst => others/index.rst} (83%) rename doc/nrf/libraries/{lib_shell.rst => shell/index.rst} (80%) rename doc/nrf/libraries/{lib_tfm.rst => tfm/index.rst} (80%) rename doc/nrf/libraries/{lib_zigbee.rst => zigbee/index.rst} (86%) diff --git a/doc/nrf/index.rst b/doc/nrf/index.rst index 21d134ac463b..3066cbd8e52b 100644 --- a/doc/nrf/index.rst +++ b/doc/nrf/index.rst @@ -62,7 +62,7 @@ In addition to the |NCS| documentation, information is available in the followin applications samples drivers - libraries + libraries/index scripts release_notes known_issues diff --git a/doc/nrf/libraries/lib_bin.rst b/doc/nrf/libraries/bin/index.rst similarity index 82% rename from doc/nrf/libraries/lib_bin.rst rename to doc/nrf/libraries/bin/index.rst index 841c0792ef6d..171c89e41f97 100644 --- a/doc/nrf/libraries/lib_bin.rst +++ b/doc/nrf/libraries/bin/index.rst @@ -8,4 +8,4 @@ Binary libraries :glob: :caption: Subpages: - ../../lib/bin/*/* + ../../../lib/bin/*/* diff --git a/doc/nrf/libraries/lib_bluetooth_services.rst b/doc/nrf/libraries/bluetooth_services/index.rst similarity index 77% rename from doc/nrf/libraries/lib_bluetooth_services.rst rename to doc/nrf/libraries/bluetooth_services/index.rst index b2b8d0cdf0d4..5004fb440ff8 100644 --- a/doc/nrf/libraries/lib_bluetooth_services.rst +++ b/doc/nrf/libraries/bluetooth_services/index.rst @@ -8,7 +8,7 @@ Bluetooth libraries and services :caption: Bluetooth libraries: :glob: - ../../include/bluetooth/* + ../../../include/bluetooth/* .. toctree:: @@ -16,4 +16,4 @@ Bluetooth libraries and services :caption: Bluetooth services: :glob: - ../../include/bluetooth/services/* + ../../../include/bluetooth/services/* diff --git a/doc/nrf/libraries/lib_caf.rst b/doc/nrf/libraries/caf/index.rst similarity index 65% rename from doc/nrf/libraries/lib_caf.rst rename to doc/nrf/libraries/caf/index.rst index bd4cb9cc099f..505aeeaabd98 100644 --- a/doc/nrf/libraries/lib_caf.rst +++ b/doc/nrf/libraries/caf/index.rst @@ -8,5 +8,5 @@ Common Application Framework :glob: :caption: Subpages: - ../../../include/caf/caf_overview.rst - ../../../include/caf/* + ../../../../include/caf/caf_overview.rst + ../../../../include/caf/* diff --git a/doc/nrf/libraries/lib_debug.rst b/doc/nrf/libraries/debug/index.rst similarity index 80% rename from doc/nrf/libraries/lib_debug.rst rename to doc/nrf/libraries/debug/index.rst index 35f6ade1c5a2..aa672f17bb50 100644 --- a/doc/nrf/libraries/lib_debug.rst +++ b/doc/nrf/libraries/debug/index.rst @@ -8,4 +8,4 @@ Debug libraries :glob: :caption: Subpages: - ../../include/debug/* + ../../../include/debug/* diff --git a/doc/nrf/libraries/lib_dfu.rst b/doc/nrf/libraries/dfu/index.rst similarity index 67% rename from doc/nrf/libraries/lib_dfu.rst rename to doc/nrf/libraries/dfu/index.rst index d0f3e73a3688..4584cb19f26d 100644 --- a/doc/nrf/libraries/lib_dfu.rst +++ b/doc/nrf/libraries/dfu/index.rst @@ -8,5 +8,5 @@ DFU libraries :glob: :caption: Subpages: - ../../include/dfu/* - ../../include/mgmt/* + ../../../include/dfu/* + ../../../include/mgmt/* diff --git a/doc/nrf/libraries.rst b/doc/nrf/libraries/index.rst similarity index 95% rename from doc/nrf/libraries.rst rename to doc/nrf/libraries/index.rst index 78be832058d4..33c377867726 100644 --- a/doc/nrf/libraries.rst +++ b/doc/nrf/libraries/index.rst @@ -12,4 +12,4 @@ Here you can find documentation for these libraries, including API documentation :glob: :caption: Subpages: - libraries/* + */index diff --git a/doc/nrf/libraries/lib_modem.rst b/doc/nrf/libraries/modem/index.rst similarity index 59% rename from doc/nrf/libraries/lib_modem.rst rename to doc/nrf/libraries/modem/index.rst index 623ae992873c..5ae097dca36c 100644 --- a/doc/nrf/libraries/lib_modem.rst +++ b/doc/nrf/libraries/modem/index.rst @@ -8,6 +8,6 @@ Modem libraries :glob: :caption: Subpages: - ../../include/modem/* - ../../lib/zzhc/* - ../../lib/at_host/* + ../../../include/modem/* + ../../../lib/zzhc/* + ../../../lib/at_host/* diff --git a/doc/nrf/libraries/lib_mpsl.rst b/doc/nrf/libraries/mpsl/index.rst similarity index 85% rename from doc/nrf/libraries/lib_mpsl.rst rename to doc/nrf/libraries/mpsl/index.rst index 4c77692f57b6..04b3d54372ea 100644 --- a/doc/nrf/libraries/lib_mpsl.rst +++ b/doc/nrf/libraries/mpsl/index.rst @@ -8,4 +8,4 @@ Multiprotocol Service Layer libraries :caption: Subpages: :glob: - ../../include/mpsl/* + ../../../include/mpsl/* diff --git a/doc/nrf/libraries/lib_networking.rst b/doc/nrf/libraries/networking/index.rst similarity index 83% rename from doc/nrf/libraries/lib_networking.rst rename to doc/nrf/libraries/networking/index.rst index e9440d8e9860..cc86176dada4 100644 --- a/doc/nrf/libraries/lib_networking.rst +++ b/doc/nrf/libraries/networking/index.rst @@ -8,4 +8,4 @@ Libraries for networking :glob: :caption: Subpages: - ../../include/net/* + ../../../include/net/* diff --git a/doc/nrf/libraries/lib_nfc.rst b/doc/nrf/libraries/nfc/index.rst similarity index 81% rename from doc/nrf/libraries/lib_nfc.rst rename to doc/nrf/libraries/nfc/index.rst index cf2a84b164f8..fc85854da4c9 100644 --- a/doc/nrf/libraries/lib_nfc.rst +++ b/doc/nrf/libraries/nfc/index.rst @@ -12,7 +12,7 @@ See the :ref:`ug_nfc` user guide for an overview of the technology and informati :glob: :caption: Subpages: - nfc/lib_nfc_t2t - nfc/lib_nfc_t4t - nfc/lib_nfc_ndef - nfc/lib_nfc_tnep + lib_nfc_t2t + lib_nfc_t4t + lib_nfc_ndef + lib_nfc_tnep diff --git a/doc/nrf/libraries/lib_others.rst b/doc/nrf/libraries/others/index.rst similarity index 83% rename from doc/nrf/libraries/lib_others.rst rename to doc/nrf/libraries/others/index.rst index 81e9f706b78e..401365be714e 100644 --- a/doc/nrf/libraries/lib_others.rst +++ b/doc/nrf/libraries/others/index.rst @@ -8,4 +8,4 @@ Other libraries :glob: :caption: Subpages: - ../../include/* + ../../../include/* diff --git a/doc/nrf/libraries/lib_shell.rst b/doc/nrf/libraries/shell/index.rst similarity index 80% rename from doc/nrf/libraries/lib_shell.rst rename to doc/nrf/libraries/shell/index.rst index b28eab38babb..6b8b881db160 100644 --- a/doc/nrf/libraries/lib_shell.rst +++ b/doc/nrf/libraries/shell/index.rst @@ -8,4 +8,4 @@ Shell libraries :glob: :caption: Subpages: - ../../include/shell/* + ../../../include/shell/* diff --git a/doc/nrf/libraries/lib_tfm.rst b/doc/nrf/libraries/tfm/index.rst similarity index 80% rename from doc/nrf/libraries/lib_tfm.rst rename to doc/nrf/libraries/tfm/index.rst index 071d93fba48d..e01f459765b7 100644 --- a/doc/nrf/libraries/lib_tfm.rst +++ b/doc/nrf/libraries/tfm/index.rst @@ -8,4 +8,4 @@ TF-M libraries :glob: :caption: Subpages: - ../../include/tfm/* + ../../../include/tfm/* diff --git a/doc/nrf/libraries/lib_zigbee.rst b/doc/nrf/libraries/zigbee/index.rst similarity index 86% rename from doc/nrf/libraries/lib_zigbee.rst rename to doc/nrf/libraries/zigbee/index.rst index 5addb8f2c5a6..138dc42a54f6 100644 --- a/doc/nrf/libraries/lib_zigbee.rst +++ b/doc/nrf/libraries/zigbee/index.rst @@ -16,6 +16,6 @@ For information on how to use the supplied libraries, see :ref:`ug_zigbee_config :glob: :caption: Subpages: - zigbee/lib_zigbee_osif - ../../include/zigbee/* - zigbee/lib_zigbee_shell + lib_zigbee_osif + ../../../include/zigbee/* + lib_zigbee_shell From 24285a22c8e7026d5727dddce8d2b1d1b4763d3a Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 15:30:51 +0200 Subject: [PATCH 031/126] doc: nrf: remove unnecessary namespacing from file names Some files were prefixed even though they are already in a subfolder. Signed-off-by: Gerard Marull-Paretas --- doc/nrf/libraries/nfc/index.rst | 5 +---- doc/nrf/libraries/nfc/{lib_nfc_ndef.rst => ndef.rst} | 0 doc/nrf/libraries/nfc/{lib_nfc_t2t.rst => t2t.rst} | 0 doc/nrf/libraries/nfc/{lib_nfc_t4t.rst => t4t.rst} | 0 doc/nrf/libraries/nfc/{lib_nfc_tnep.rst => tnep.rst} | 0 doc/nrf/libraries/zigbee/index.rst | 3 +-- doc/nrf/libraries/zigbee/{lib_zigbee_osif.rst => osif.rst} | 0 doc/nrf/libraries/zigbee/{lib_zigbee_shell.rst => shell.rst} | 0 8 files changed, 2 insertions(+), 6 deletions(-) rename doc/nrf/libraries/nfc/{lib_nfc_ndef.rst => ndef.rst} (100%) rename doc/nrf/libraries/nfc/{lib_nfc_t2t.rst => t2t.rst} (100%) rename doc/nrf/libraries/nfc/{lib_nfc_t4t.rst => t4t.rst} (100%) rename doc/nrf/libraries/nfc/{lib_nfc_tnep.rst => tnep.rst} (100%) rename doc/nrf/libraries/zigbee/{lib_zigbee_osif.rst => osif.rst} (100%) rename doc/nrf/libraries/zigbee/{lib_zigbee_shell.rst => shell.rst} (100%) diff --git a/doc/nrf/libraries/nfc/index.rst b/doc/nrf/libraries/nfc/index.rst index fc85854da4c9..2585f6f00079 100644 --- a/doc/nrf/libraries/nfc/index.rst +++ b/doc/nrf/libraries/nfc/index.rst @@ -12,7 +12,4 @@ See the :ref:`ug_nfc` user guide for an overview of the technology and informati :glob: :caption: Subpages: - lib_nfc_t2t - lib_nfc_t4t - lib_nfc_ndef - lib_nfc_tnep + * diff --git a/doc/nrf/libraries/nfc/lib_nfc_ndef.rst b/doc/nrf/libraries/nfc/ndef.rst similarity index 100% rename from doc/nrf/libraries/nfc/lib_nfc_ndef.rst rename to doc/nrf/libraries/nfc/ndef.rst diff --git a/doc/nrf/libraries/nfc/lib_nfc_t2t.rst b/doc/nrf/libraries/nfc/t2t.rst similarity index 100% rename from doc/nrf/libraries/nfc/lib_nfc_t2t.rst rename to doc/nrf/libraries/nfc/t2t.rst diff --git a/doc/nrf/libraries/nfc/lib_nfc_t4t.rst b/doc/nrf/libraries/nfc/t4t.rst similarity index 100% rename from doc/nrf/libraries/nfc/lib_nfc_t4t.rst rename to doc/nrf/libraries/nfc/t4t.rst diff --git a/doc/nrf/libraries/nfc/lib_nfc_tnep.rst b/doc/nrf/libraries/nfc/tnep.rst similarity index 100% rename from doc/nrf/libraries/nfc/lib_nfc_tnep.rst rename to doc/nrf/libraries/nfc/tnep.rst diff --git a/doc/nrf/libraries/zigbee/index.rst b/doc/nrf/libraries/zigbee/index.rst index 138dc42a54f6..2b5a20a7bacf 100644 --- a/doc/nrf/libraries/zigbee/index.rst +++ b/doc/nrf/libraries/zigbee/index.rst @@ -16,6 +16,5 @@ For information on how to use the supplied libraries, see :ref:`ug_zigbee_config :glob: :caption: Subpages: - lib_zigbee_osif + * ../../../include/zigbee/* - lib_zigbee_shell diff --git a/doc/nrf/libraries/zigbee/lib_zigbee_osif.rst b/doc/nrf/libraries/zigbee/osif.rst similarity index 100% rename from doc/nrf/libraries/zigbee/lib_zigbee_osif.rst rename to doc/nrf/libraries/zigbee/osif.rst diff --git a/doc/nrf/libraries/zigbee/lib_zigbee_shell.rst b/doc/nrf/libraries/zigbee/shell.rst similarity index 100% rename from doc/nrf/libraries/zigbee/lib_zigbee_shell.rst rename to doc/nrf/libraries/zigbee/shell.rst From 85d9f69cd6bff4128c40aa93097e6c770eb5feac Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 15:59:22 +0200 Subject: [PATCH 032/126] doc: nrf: move bin libraries docs to doc Move documentation content to the right place, i.e. doc/ folder. Signed-off-by: Gerard Marull-Paretas --- applications/asset_tracker/README.rst | 2 +- doc/nrf/libraries/bin/index.rst | 2 +- .../nrf/libraries/bin/lwm2m_carrier}/CHANGELOG.rst | 0 .../libraries/bin/lwm2m_carrier}/app_integration.rst | 0 .../nrf/libraries/bin/lwm2m_carrier}/certification.rst | 0 .../nrf/libraries/bin/lwm2m_carrier/index.rst | 10 +++++----- .../nrf/libraries/bin/lwm2m_carrier}/msc.rst | 0 .../nrf/libraries/bin/lwm2m_carrier}/requirements.rst | 0 samples/nrf9160/lwm2m_carrier/README.rst | 2 +- 9 files changed, 8 insertions(+), 8 deletions(-) rename {lib/bin/lwm2m_carrier/doc => doc/nrf/libraries/bin/lwm2m_carrier}/CHANGELOG.rst (100%) rename {lib/bin/lwm2m_carrier/doc => doc/nrf/libraries/bin/lwm2m_carrier}/app_integration.rst (100%) rename {lib/bin/lwm2m_carrier/doc => doc/nrf/libraries/bin/lwm2m_carrier}/certification.rst (100%) rename lib/bin/lwm2m_carrier/lwm2m_carrier.rst => doc/nrf/libraries/bin/lwm2m_carrier/index.rst (93%) rename {lib/bin/lwm2m_carrier/doc => doc/nrf/libraries/bin/lwm2m_carrier}/msc.rst (100%) rename {lib/bin/lwm2m_carrier/doc => doc/nrf/libraries/bin/lwm2m_carrier}/requirements.rst (100%) diff --git a/applications/asset_tracker/README.rst b/applications/asset_tracker/README.rst index 9819973bdbb4..39afed97d938 100644 --- a/applications/asset_tracker/README.rst +++ b/applications/asset_tracker/README.rst @@ -289,7 +289,7 @@ This application uses the following |NCS| libraries and drivers: * :ref:`lte_lc_readme` * |NCS| modules abstracted via the LwM2M carrier OS abstraction layer (:file:`lwm2m_os.h`) -.. include:: /lib/bin/lwm2m_carrier/doc/app_integration.rst +.. include:: /libraries/bin/lwm2m_carrier/app_integration.rst :start-after: lwm2m_osal_mod_list_start :end-before: lwm2m_osal_mod_list_end diff --git a/doc/nrf/libraries/bin/index.rst b/doc/nrf/libraries/bin/index.rst index 171c89e41f97..2b3c8fec0deb 100644 --- a/doc/nrf/libraries/bin/index.rst +++ b/doc/nrf/libraries/bin/index.rst @@ -8,4 +8,4 @@ Binary libraries :glob: :caption: Subpages: - ../../../lib/bin/*/* + */index diff --git a/lib/bin/lwm2m_carrier/doc/CHANGELOG.rst b/doc/nrf/libraries/bin/lwm2m_carrier/CHANGELOG.rst similarity index 100% rename from lib/bin/lwm2m_carrier/doc/CHANGELOG.rst rename to doc/nrf/libraries/bin/lwm2m_carrier/CHANGELOG.rst diff --git a/lib/bin/lwm2m_carrier/doc/app_integration.rst b/doc/nrf/libraries/bin/lwm2m_carrier/app_integration.rst similarity index 100% rename from lib/bin/lwm2m_carrier/doc/app_integration.rst rename to doc/nrf/libraries/bin/lwm2m_carrier/app_integration.rst diff --git a/lib/bin/lwm2m_carrier/doc/certification.rst b/doc/nrf/libraries/bin/lwm2m_carrier/certification.rst similarity index 100% rename from lib/bin/lwm2m_carrier/doc/certification.rst rename to doc/nrf/libraries/bin/lwm2m_carrier/certification.rst diff --git a/lib/bin/lwm2m_carrier/lwm2m_carrier.rst b/doc/nrf/libraries/bin/lwm2m_carrier/index.rst similarity index 93% rename from lib/bin/lwm2m_carrier/lwm2m_carrier.rst rename to doc/nrf/libraries/bin/lwm2m_carrier/index.rst index c49bc3876888..16af80b2f79d 100644 --- a/lib/bin/lwm2m_carrier/lwm2m_carrier.rst +++ b/doc/nrf/libraries/bin/lwm2m_carrier/index.rst @@ -26,11 +26,11 @@ The LwM2M carrier library is also used in the :ref:`asset_tracker` application. :maxdepth: 1 :caption: Subpages: - doc/certification - doc/app_integration - doc/requirements - doc/msc - doc/CHANGELOG + certification + app_integration + requirements + msc + CHANGELOG diff --git a/lib/bin/lwm2m_carrier/doc/msc.rst b/doc/nrf/libraries/bin/lwm2m_carrier/msc.rst similarity index 100% rename from lib/bin/lwm2m_carrier/doc/msc.rst rename to doc/nrf/libraries/bin/lwm2m_carrier/msc.rst diff --git a/lib/bin/lwm2m_carrier/doc/requirements.rst b/doc/nrf/libraries/bin/lwm2m_carrier/requirements.rst similarity index 100% rename from lib/bin/lwm2m_carrier/doc/requirements.rst rename to doc/nrf/libraries/bin/lwm2m_carrier/requirements.rst diff --git a/samples/nrf9160/lwm2m_carrier/README.rst b/samples/nrf9160/lwm2m_carrier/README.rst index df5645db00ab..f25f3d0d39ab 100644 --- a/samples/nrf9160/lwm2m_carrier/README.rst +++ b/samples/nrf9160/lwm2m_carrier/README.rst @@ -58,7 +58,7 @@ This sample uses the following |NCS| libraries: * |NCS| modules abstracted via the LwM2M carrier OS abstraction layer (:file:`lwm2m_os.h`) - .. include:: /lib/bin/lwm2m_carrier/doc/app_integration.rst + .. include:: /libraries/bin/lwm2m_carrier/app_integration.rst :start-after: lwm2m_osal_mod_list_start :end-before: lwm2m_osal_mod_list_end From 52302d74aba621868066c08e42aec7b425c67d05 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 16:07:25 +0200 Subject: [PATCH 033/126] doc: nrf: move bluetooth docs to doc folder Move all bluetooth docs in include to doc. Signed-off-by: Gerard Marull-Paretas --- .../bluetooth_services}/conn_ctx.rst | 0 .../libraries/bluetooth_services}/enocean.rst | 0 .../libraries/bluetooth_services}/gatt_dm.rst | 0 .../bluetooth_services}/gatt_pool.rst | 0 .../libraries/bluetooth_services/index.rst | 4 +- .../libraries/bluetooth_services}/mesh.rst | 0 .../bluetooth_services}/mesh/dk_prov.rst | 0 .../bluetooth_services}/mesh/gen_battery.rst | 0 .../mesh/gen_battery_cli.rst | 0 .../mesh/gen_battery_srv.rst | 0 .../bluetooth_services}/mesh/gen_dtt.rst | 0 .../bluetooth_services}/mesh/gen_dtt_cli.rst | 0 .../bluetooth_services}/mesh/gen_dtt_srv.rst | 0 .../bluetooth_services}/mesh/gen_loc.rst | 0 .../bluetooth_services}/mesh/gen_loc_cli.rst | 0 .../bluetooth_services}/mesh/gen_loc_srv.rst | 0 .../bluetooth_services}/mesh/gen_lvl.rst | 0 .../bluetooth_services}/mesh/gen_lvl_cli.rst | 0 .../bluetooth_services}/mesh/gen_lvl_srv.rst | 0 .../bluetooth_services}/mesh/gen_onoff.rst | 0 .../mesh/gen_onoff_cli.rst | 0 .../mesh/gen_onoff_srv.rst | 0 .../bluetooth_services}/mesh/gen_plvl.rst | 0 .../bluetooth_services}/mesh/gen_plvl_cli.rst | 0 .../bluetooth_services}/mesh/gen_plvl_srv.rst | 0 .../bluetooth_services}/mesh/gen_ponoff.rst | 0 .../mesh/gen_ponoff_cli.rst | 0 .../mesh/gen_ponoff_srv.rst | 0 .../bluetooth_services}/mesh/gen_prop.rst | 0 .../bluetooth_services}/mesh/gen_prop_cli.rst | 0 .../bluetooth_services}/mesh/gen_prop_srv.rst | 0 .../mesh}/images/CIExy1931.png | Bin .../images/bt_mesh_light_ctrl_composition.svg | 0 .../bt_mesh_light_ctrl_composition.vsdx | Bin .../images/bt_mesh_light_ctrl_levels.svg | 0 .../images/bt_mesh_light_ctrl_levels.vsdx | Bin .../mesh}/images/bt_mesh_light_ctrl_nodes.svg | 0 .../images/bt_mesh_light_ctrl_nodes.vsdx | Bin .../mesh}/images/bt_mesh_light_ctrl_reg.svg | 0 .../mesh}/images/bt_mesh_light_ctrl_reg.vsdx | Bin .../images/bt_mesh_light_ctrl_states.svg | 0 .../images/bt_mesh_light_ctrl_states.vsdx | Bin .../bluetooth_services}/mesh/light_ctl.rst | 0 .../mesh/light_ctl_cli.rst | 0 .../mesh/light_ctl_srv.rst | 0 .../bluetooth_services}/mesh/light_ctrl.rst | 0 .../mesh/light_ctrl_cli.rst | 0 .../mesh/light_ctrl_srv.rst | 10 +- .../bluetooth_services}/mesh/light_hsl.rst | 0 .../mesh/light_hsl_cli.rst | 0 .../mesh/light_hsl_srv.rst | 0 .../mesh/light_hue_srv.rst | 0 .../mesh/light_sat_srv.rst | 0 .../mesh/light_temp_srv.rst | 0 .../bluetooth_services}/mesh/light_xyl.rst | 2 +- .../mesh/light_xyl_cli.rst | 0 .../mesh/light_xyl_srv.rst | 0 .../bluetooth_services}/mesh/lightness.rst | 0 .../mesh/lightness_cli.rst | 0 .../mesh/lightness_srv.rst | 0 .../bluetooth_services}/mesh/model_types.rst | 0 .../bluetooth_services/mesh/models.rst | 32 +++ .../bluetooth_services}/mesh/properties.rst | 0 .../bluetooth_services}/mesh/scene.rst | 0 .../bluetooth_services}/mesh/scene_cli.rst | 0 .../bluetooth_services}/mesh/scene_srv.rst | 2 +- .../bluetooth_services}/mesh/scheduler.rst | 0 .../mesh/scheduler_cli.rst | 0 .../mesh/scheduler_srv.rst | 0 .../bluetooth_services}/mesh/sensor.rst | 0 .../bluetooth_services}/mesh/sensor_cli.rst | 0 .../mesh/sensor_models.rst | 0 .../bluetooth_services}/mesh/sensor_srv.rst | 0 .../bluetooth_services}/mesh/sensor_types.rst | 0 .../bluetooth_services}/mesh/time.rst | 0 .../bluetooth_services}/mesh/time_cli.rst | 0 .../bluetooth_services}/mesh/time_srv.rst | 0 .../bluetooth_services}/mesh/time_tai.rst | 0 .../mesh/vnd/silvair_enocean_srv.rst | 0 .../nrf/libraries/bluetooth_services}/rpc.rst | 0 .../libraries/bluetooth_services}/scan.rst | 2 +- .../services/ancs_client.rst | 0 .../services/bas_client.rst | 0 .../bluetooth_services}/services/bms.rst | 0 .../services/cts_client.rst | 0 .../bluetooth_services}/services/dfu_smp.rst | 0 .../bluetooth_services}/services/gadgets.rst | 0 .../bluetooth_services}/services/gattp.rst | 0 .../bluetooth_services}/services/hids.rst | 0 .../bluetooth_services}/services/hogp.rst | 0 .../bluetooth_services}/services/latency.rst | 0 .../services/latency_client.rst | 0 .../bluetooth_services}/services/lbs.rst | 0 .../bluetooth_services}/services/nus.rst | 0 .../services/nus_client.rst | 0 .../services/throughput.rst | 0 include/bluetooth/mesh/models.rst | 32 --- samples/bluetooth/mesh/light_ctrl/README.rst | 2 +- .../images/bt_mesh_light_ctrl_levels.svg | 230 ++++++++++++++++++ .../images/bt_mesh_light_ctrl_levels.vsdx | Bin 0 -> 195781 bytes 100 files changed, 273 insertions(+), 43 deletions(-) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/conn_ctx.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/enocean.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/gatt_dm.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/gatt_pool.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/dk_prov.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_battery.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_battery_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_battery_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_dtt.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_dtt_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_dtt_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_loc.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_loc_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_loc_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_lvl.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_lvl_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_lvl_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_onoff.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_onoff_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_onoff_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_plvl.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_plvl_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_plvl_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_ponoff.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_ponoff_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_ponoff_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_prop.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_prop_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/gen_prop_srv.rst (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/CIExy1931.png (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_composition.svg (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_composition.vsdx (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_levels.svg (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_levels.vsdx (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_nodes.svg (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_nodes.vsdx (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_reg.svg (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_reg.vsdx (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_states.svg (100%) rename doc/nrf/{ => libraries/bluetooth_services/mesh}/images/bt_mesh_light_ctrl_states.vsdx (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_ctl.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_ctl_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_ctl_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_ctrl.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_ctrl_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_ctrl_srv.rst (98%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_hsl.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_hsl_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_hsl_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_hue_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_sat_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_temp_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_xyl.rst (97%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_xyl_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/light_xyl_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/lightness.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/lightness_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/lightness_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/model_types.rst (100%) create mode 100644 doc/nrf/libraries/bluetooth_services/mesh/models.rst rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/properties.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/scene.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/scene_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/scene_srv.rst (98%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/scheduler.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/scheduler_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/scheduler_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/sensor.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/sensor_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/sensor_models.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/sensor_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/sensor_types.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/time.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/time_cli.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/time_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/time_tai.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/mesh/vnd/silvair_enocean_srv.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/rpc.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/scan.rst (99%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/ancs_client.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/bas_client.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/bms.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/cts_client.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/dfu_smp.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/gadgets.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/gattp.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/hids.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/hogp.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/latency.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/latency_client.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/lbs.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/nus.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/nus_client.rst (100%) rename {include/bluetooth => doc/nrf/libraries/bluetooth_services}/services/throughput.rst (100%) delete mode 100644 include/bluetooth/mesh/models.rst create mode 100644 samples/bluetooth/mesh/light_ctrl/images/bt_mesh_light_ctrl_levels.svg create mode 100644 samples/bluetooth/mesh/light_ctrl/images/bt_mesh_light_ctrl_levels.vsdx diff --git a/include/bluetooth/conn_ctx.rst b/doc/nrf/libraries/bluetooth_services/conn_ctx.rst similarity index 100% rename from include/bluetooth/conn_ctx.rst rename to doc/nrf/libraries/bluetooth_services/conn_ctx.rst diff --git a/include/bluetooth/enocean.rst b/doc/nrf/libraries/bluetooth_services/enocean.rst similarity index 100% rename from include/bluetooth/enocean.rst rename to doc/nrf/libraries/bluetooth_services/enocean.rst diff --git a/include/bluetooth/gatt_dm.rst b/doc/nrf/libraries/bluetooth_services/gatt_dm.rst similarity index 100% rename from include/bluetooth/gatt_dm.rst rename to doc/nrf/libraries/bluetooth_services/gatt_dm.rst diff --git a/include/bluetooth/gatt_pool.rst b/doc/nrf/libraries/bluetooth_services/gatt_pool.rst similarity index 100% rename from include/bluetooth/gatt_pool.rst rename to doc/nrf/libraries/bluetooth_services/gatt_pool.rst diff --git a/doc/nrf/libraries/bluetooth_services/index.rst b/doc/nrf/libraries/bluetooth_services/index.rst index 5004fb440ff8..a0d39fe2b635 100644 --- a/doc/nrf/libraries/bluetooth_services/index.rst +++ b/doc/nrf/libraries/bluetooth_services/index.rst @@ -8,7 +8,7 @@ Bluetooth libraries and services :caption: Bluetooth libraries: :glob: - ../../../include/bluetooth/* + * .. toctree:: @@ -16,4 +16,4 @@ Bluetooth libraries and services :caption: Bluetooth services: :glob: - ../../../include/bluetooth/services/* + services/* diff --git a/include/bluetooth/mesh.rst b/doc/nrf/libraries/bluetooth_services/mesh.rst similarity index 100% rename from include/bluetooth/mesh.rst rename to doc/nrf/libraries/bluetooth_services/mesh.rst diff --git a/include/bluetooth/mesh/dk_prov.rst b/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst similarity index 100% rename from include/bluetooth/mesh/dk_prov.rst rename to doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst diff --git a/include/bluetooth/mesh/gen_battery.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_battery.rst similarity index 100% rename from include/bluetooth/mesh/gen_battery.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_battery.rst diff --git a/include/bluetooth/mesh/gen_battery_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_battery_cli.rst similarity index 100% rename from include/bluetooth/mesh/gen_battery_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_battery_cli.rst diff --git a/include/bluetooth/mesh/gen_battery_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_battery_srv.rst similarity index 100% rename from include/bluetooth/mesh/gen_battery_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_battery_srv.rst diff --git a/include/bluetooth/mesh/gen_dtt.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_dtt.rst similarity index 100% rename from include/bluetooth/mesh/gen_dtt.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_dtt.rst diff --git a/include/bluetooth/mesh/gen_dtt_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_cli.rst similarity index 100% rename from include/bluetooth/mesh/gen_dtt_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_cli.rst diff --git a/include/bluetooth/mesh/gen_dtt_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_srv.rst similarity index 100% rename from include/bluetooth/mesh/gen_dtt_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_srv.rst diff --git a/include/bluetooth/mesh/gen_loc.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_loc.rst similarity index 100% rename from include/bluetooth/mesh/gen_loc.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_loc.rst diff --git a/include/bluetooth/mesh/gen_loc_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_loc_cli.rst similarity index 100% rename from include/bluetooth/mesh/gen_loc_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_loc_cli.rst diff --git a/include/bluetooth/mesh/gen_loc_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_loc_srv.rst similarity index 100% rename from include/bluetooth/mesh/gen_loc_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_loc_srv.rst diff --git a/include/bluetooth/mesh/gen_lvl.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_lvl.rst similarity index 100% rename from include/bluetooth/mesh/gen_lvl.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_lvl.rst diff --git a/include/bluetooth/mesh/gen_lvl_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_lvl_cli.rst similarity index 100% rename from include/bluetooth/mesh/gen_lvl_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_lvl_cli.rst diff --git a/include/bluetooth/mesh/gen_lvl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_lvl_srv.rst similarity index 100% rename from include/bluetooth/mesh/gen_lvl_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_lvl_srv.rst diff --git a/include/bluetooth/mesh/gen_onoff.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_onoff.rst similarity index 100% rename from include/bluetooth/mesh/gen_onoff.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_onoff.rst diff --git a/include/bluetooth/mesh/gen_onoff_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_onoff_cli.rst similarity index 100% rename from include/bluetooth/mesh/gen_onoff_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_onoff_cli.rst diff --git a/include/bluetooth/mesh/gen_onoff_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_onoff_srv.rst similarity index 100% rename from include/bluetooth/mesh/gen_onoff_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_onoff_srv.rst diff --git a/include/bluetooth/mesh/gen_plvl.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_plvl.rst similarity index 100% rename from include/bluetooth/mesh/gen_plvl.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_plvl.rst diff --git a/include/bluetooth/mesh/gen_plvl_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_plvl_cli.rst similarity index 100% rename from include/bluetooth/mesh/gen_plvl_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_plvl_cli.rst diff --git a/include/bluetooth/mesh/gen_plvl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_plvl_srv.rst similarity index 100% rename from include/bluetooth/mesh/gen_plvl_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_plvl_srv.rst diff --git a/include/bluetooth/mesh/gen_ponoff.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff.rst similarity index 100% rename from include/bluetooth/mesh/gen_ponoff.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff.rst diff --git a/include/bluetooth/mesh/gen_ponoff_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff_cli.rst similarity index 100% rename from include/bluetooth/mesh/gen_ponoff_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff_cli.rst diff --git a/include/bluetooth/mesh/gen_ponoff_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff_srv.rst similarity index 100% rename from include/bluetooth/mesh/gen_ponoff_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff_srv.rst diff --git a/include/bluetooth/mesh/gen_prop.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop.rst similarity index 100% rename from include/bluetooth/mesh/gen_prop.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_prop.rst diff --git a/include/bluetooth/mesh/gen_prop_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_cli.rst similarity index 100% rename from include/bluetooth/mesh/gen_prop_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_prop_cli.rst diff --git a/include/bluetooth/mesh/gen_prop_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst similarity index 100% rename from include/bluetooth/mesh/gen_prop_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst diff --git a/doc/nrf/images/CIExy1931.png b/doc/nrf/libraries/bluetooth_services/mesh/images/CIExy1931.png similarity index 100% rename from doc/nrf/images/CIExy1931.png rename to doc/nrf/libraries/bluetooth_services/mesh/images/CIExy1931.png diff --git a/doc/nrf/images/bt_mesh_light_ctrl_composition.svg b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_composition.svg similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_composition.svg rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_composition.svg diff --git a/doc/nrf/images/bt_mesh_light_ctrl_composition.vsdx b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_composition.vsdx similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_composition.vsdx rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_composition.vsdx diff --git a/doc/nrf/images/bt_mesh_light_ctrl_levels.svg b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_levels.svg similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_levels.svg rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_levels.svg diff --git a/doc/nrf/images/bt_mesh_light_ctrl_levels.vsdx b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_levels.vsdx similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_levels.vsdx rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_levels.vsdx diff --git a/doc/nrf/images/bt_mesh_light_ctrl_nodes.svg b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_nodes.svg similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_nodes.svg rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_nodes.svg diff --git a/doc/nrf/images/bt_mesh_light_ctrl_nodes.vsdx b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_nodes.vsdx similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_nodes.vsdx rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_nodes.vsdx diff --git a/doc/nrf/images/bt_mesh_light_ctrl_reg.svg b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_reg.svg similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_reg.svg rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_reg.svg diff --git a/doc/nrf/images/bt_mesh_light_ctrl_reg.vsdx b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_reg.vsdx similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_reg.vsdx rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_reg.vsdx diff --git a/doc/nrf/images/bt_mesh_light_ctrl_states.svg b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_states.svg similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_states.svg rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_states.svg diff --git a/doc/nrf/images/bt_mesh_light_ctrl_states.vsdx b/doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_states.vsdx similarity index 100% rename from doc/nrf/images/bt_mesh_light_ctrl_states.vsdx rename to doc/nrf/libraries/bluetooth_services/mesh/images/bt_mesh_light_ctrl_states.vsdx diff --git a/include/bluetooth/mesh/light_ctl.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctl.rst similarity index 100% rename from include/bluetooth/mesh/light_ctl.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_ctl.rst diff --git a/include/bluetooth/mesh/light_ctl_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctl_cli.rst similarity index 100% rename from include/bluetooth/mesh/light_ctl_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_ctl_cli.rst diff --git a/include/bluetooth/mesh/light_ctl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctl_srv.rst similarity index 100% rename from include/bluetooth/mesh/light_ctl_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_ctl_srv.rst diff --git a/include/bluetooth/mesh/light_ctrl.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl.rst similarity index 100% rename from include/bluetooth/mesh/light_ctrl.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_ctrl.rst diff --git a/include/bluetooth/mesh/light_ctrl_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_cli.rst similarity index 100% rename from include/bluetooth/mesh/light_ctrl_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_cli.rst diff --git a/include/bluetooth/mesh/light_ctrl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst similarity index 98% rename from include/bluetooth/mesh/light_ctrl_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst index dc642b7be8d3..db4a07dcafcf 100644 --- a/include/bluetooth/mesh/light_ctrl_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst @@ -38,7 +38,7 @@ As both the Light LC Server and the Light Lightness Server extend the Generic On .. note:: Due to implementation limitations, the Light LC Server is instantiated on the next element after the Light Lightness Server it is controlling. -.. figure:: /images/bt_mesh_light_ctrl_composition.svg +.. figure:: images/bt_mesh_light_ctrl_composition.svg :alt: Light Lightness Control Server composition data structure Light Lightness Control Server composition data structure @@ -65,7 +65,7 @@ Relationship with other nodes When the Light LC Server model controls a Light Lightness Server, all nodes should publish to the LC Server or its extended Generic OnOff model, instead of publishing directly to the Light Lightness Server: -.. figure:: /images/bt_mesh_light_ctrl_nodes.svg +.. figure:: images/bt_mesh_light_ctrl_nodes.svg :alt: Light Lightness Control Server node organization The dimmer devices that want to override the light level of the Lightness Server can publish directly to the Lightness Server. @@ -93,7 +93,7 @@ When the state changes, the light level fades from the previous state's level to When the Light LC Server is turned on, the following sequence takes place: -.. figure:: /images/bt_mesh_light_ctrl_levels.svg +.. figure:: images/bt_mesh_light_ctrl_levels.svg :alt: Light Lightness Control Server light levels Light Lightness Control Server light levels @@ -114,7 +114,7 @@ The On and Prolong states will start a timer as soon as the transition into the When this timer expires, the state machine will automatically go into the next state. If the On event is triggered while in the On state, the timer is reset, and the transition to the Prolong state is postponed. -.. figure:: /images/bt_mesh_light_ctrl_states.svg +.. figure:: images/bt_mesh_light_ctrl_states.svg :alt: Light Lightness Control Server state machine Light Lightness Control Server state machine @@ -300,7 +300,7 @@ Illuminance regulator The illuminance regulator complements the light level state machine by adding an ambient illuminance sensor feedback loop. This allows the Lightness Server to adjust its output level that is based on the room's ambient light, and as a result conserve energy and achieve more consistent light levels. -.. figure:: /images/bt_mesh_light_ctrl_reg.svg +.. figure:: images/bt_mesh_light_ctrl_reg.svg :alt: Light Lightness Control Server illuminance regulator Light Lightness Control Server illuminance regulator diff --git a/include/bluetooth/mesh/light_hsl.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_hsl.rst similarity index 100% rename from include/bluetooth/mesh/light_hsl.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_hsl.rst diff --git a/include/bluetooth/mesh/light_hsl_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_hsl_cli.rst similarity index 100% rename from include/bluetooth/mesh/light_hsl_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_hsl_cli.rst diff --git a/include/bluetooth/mesh/light_hsl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_hsl_srv.rst similarity index 100% rename from include/bluetooth/mesh/light_hsl_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_hsl_srv.rst diff --git a/include/bluetooth/mesh/light_hue_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_hue_srv.rst similarity index 100% rename from include/bluetooth/mesh/light_hue_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_hue_srv.rst diff --git a/include/bluetooth/mesh/light_sat_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_sat_srv.rst similarity index 100% rename from include/bluetooth/mesh/light_sat_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_sat_srv.rst diff --git a/include/bluetooth/mesh/light_temp_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_temp_srv.rst similarity index 100% rename from include/bluetooth/mesh/light_temp_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_temp_srv.rst diff --git a/include/bluetooth/mesh/light_xyl.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_xyl.rst similarity index 97% rename from include/bluetooth/mesh/light_xyl.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_xyl.rst index c32445f647eb..a7faa0a4f6df 100644 --- a/include/bluetooth/mesh/light_xyl.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_xyl.rst @@ -12,7 +12,7 @@ The CIE1931 color spaces are the first defined quantitative links between distri The CIE1931 color space chart is utilized by the models to determine the color light emitted by an element. The xyL models allow remote control and configuration of a light device with x and y chromaticity coordinates support in a mesh network. -.. figure:: /images/CIExy1931.png +.. figure:: images/CIExy1931.png :scale: 50 % :alt: CIE1931 color space chromaticity diagram diff --git a/include/bluetooth/mesh/light_xyl_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_xyl_cli.rst similarity index 100% rename from include/bluetooth/mesh/light_xyl_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_xyl_cli.rst diff --git a/include/bluetooth/mesh/light_xyl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_xyl_srv.rst similarity index 100% rename from include/bluetooth/mesh/light_xyl_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/light_xyl_srv.rst diff --git a/include/bluetooth/mesh/lightness.rst b/doc/nrf/libraries/bluetooth_services/mesh/lightness.rst similarity index 100% rename from include/bluetooth/mesh/lightness.rst rename to doc/nrf/libraries/bluetooth_services/mesh/lightness.rst diff --git a/include/bluetooth/mesh/lightness_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/lightness_cli.rst similarity index 100% rename from include/bluetooth/mesh/lightness_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/lightness_cli.rst diff --git a/include/bluetooth/mesh/lightness_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/lightness_srv.rst similarity index 100% rename from include/bluetooth/mesh/lightness_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/lightness_srv.rst diff --git a/include/bluetooth/mesh/model_types.rst b/doc/nrf/libraries/bluetooth_services/mesh/model_types.rst similarity index 100% rename from include/bluetooth/mesh/model_types.rst rename to doc/nrf/libraries/bluetooth_services/mesh/model_types.rst diff --git a/doc/nrf/libraries/bluetooth_services/mesh/models.rst b/doc/nrf/libraries/bluetooth_services/mesh/models.rst new file mode 100644 index 000000000000..3585df90ae8f --- /dev/null +++ b/doc/nrf/libraries/bluetooth_services/mesh/models.rst @@ -0,0 +1,32 @@ +.. _bt_mesh_models: + +Bluetooth mesh models +##################### + +Nordic Semiconductor provides a variety of model implementations from the `Bluetooth mesh model specification`_ and their API documentation, as well as vendor-specific models. + +For more information about these and other models, see also `Bluetooth mesh model overview`_. + +.. toctree:: + :maxdepth: 1 + :caption: Subpages: + :glob: + + gen_onoff.rst + gen_lvl.rst + gen_dtt.rst + gen_ponoff.rst + gen_plvl.rst + gen_battery.rst + gen_loc.rst + gen_prop.rst + lightness.rst + light_ctrl.rst + light_ctl.rst + light_xyl.rst + light_hsl.rst + sensor_models.rst + time.rst + scene.rst + scheduler.rst + vnd/silvair_enocean_srv.rst diff --git a/include/bluetooth/mesh/properties.rst b/doc/nrf/libraries/bluetooth_services/mesh/properties.rst similarity index 100% rename from include/bluetooth/mesh/properties.rst rename to doc/nrf/libraries/bluetooth_services/mesh/properties.rst diff --git a/include/bluetooth/mesh/scene.rst b/doc/nrf/libraries/bluetooth_services/mesh/scene.rst similarity index 100% rename from include/bluetooth/mesh/scene.rst rename to doc/nrf/libraries/bluetooth_services/mesh/scene.rst diff --git a/include/bluetooth/mesh/scene_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/scene_cli.rst similarity index 100% rename from include/bluetooth/mesh/scene_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/scene_cli.rst diff --git a/include/bluetooth/mesh/scene_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/scene_srv.rst similarity index 98% rename from include/bluetooth/mesh/scene_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/scene_srv.rst index 048217da3218..57cc71a0c8bf 100644 --- a/include/bluetooth/mesh/scene_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/scene_srv.rst @@ -58,7 +58,7 @@ These macros will allocate the structure in flash, and make them known to the Sc For instance, the Generic OnOff Server model defines its scene entry by declaring a :c:type:`bt_mesh_scene_entry` structure with the Generic OnOff Server model ID and a set of callbacks: -.. literalinclude:: ../../../subsys/bluetooth/mesh/gen_onoff_srv.c +.. literalinclude:: ../../../../../subsys/bluetooth/mesh/gen_onoff_srv.c :language: c :start-after: include_startingpoint_scene_srv_rst_1 :end-before: include_endpoint_scene_srv_rst_1 diff --git a/include/bluetooth/mesh/scheduler.rst b/doc/nrf/libraries/bluetooth_services/mesh/scheduler.rst similarity index 100% rename from include/bluetooth/mesh/scheduler.rst rename to doc/nrf/libraries/bluetooth_services/mesh/scheduler.rst diff --git a/include/bluetooth/mesh/scheduler_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/scheduler_cli.rst similarity index 100% rename from include/bluetooth/mesh/scheduler_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/scheduler_cli.rst diff --git a/include/bluetooth/mesh/scheduler_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/scheduler_srv.rst similarity index 100% rename from include/bluetooth/mesh/scheduler_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/scheduler_srv.rst diff --git a/include/bluetooth/mesh/sensor.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst similarity index 100% rename from include/bluetooth/mesh/sensor.rst rename to doc/nrf/libraries/bluetooth_services/mesh/sensor.rst diff --git a/include/bluetooth/mesh/sensor_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor_cli.rst similarity index 100% rename from include/bluetooth/mesh/sensor_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/sensor_cli.rst diff --git a/include/bluetooth/mesh/sensor_models.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor_models.rst similarity index 100% rename from include/bluetooth/mesh/sensor_models.rst rename to doc/nrf/libraries/bluetooth_services/mesh/sensor_models.rst diff --git a/include/bluetooth/mesh/sensor_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor_srv.rst similarity index 100% rename from include/bluetooth/mesh/sensor_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/sensor_srv.rst diff --git a/include/bluetooth/mesh/sensor_types.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor_types.rst similarity index 100% rename from include/bluetooth/mesh/sensor_types.rst rename to doc/nrf/libraries/bluetooth_services/mesh/sensor_types.rst diff --git a/include/bluetooth/mesh/time.rst b/doc/nrf/libraries/bluetooth_services/mesh/time.rst similarity index 100% rename from include/bluetooth/mesh/time.rst rename to doc/nrf/libraries/bluetooth_services/mesh/time.rst diff --git a/include/bluetooth/mesh/time_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/time_cli.rst similarity index 100% rename from include/bluetooth/mesh/time_cli.rst rename to doc/nrf/libraries/bluetooth_services/mesh/time_cli.rst diff --git a/include/bluetooth/mesh/time_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/time_srv.rst similarity index 100% rename from include/bluetooth/mesh/time_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/time_srv.rst diff --git a/include/bluetooth/mesh/time_tai.rst b/doc/nrf/libraries/bluetooth_services/mesh/time_tai.rst similarity index 100% rename from include/bluetooth/mesh/time_tai.rst rename to doc/nrf/libraries/bluetooth_services/mesh/time_tai.rst diff --git a/include/bluetooth/mesh/vnd/silvair_enocean_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/vnd/silvair_enocean_srv.rst similarity index 100% rename from include/bluetooth/mesh/vnd/silvair_enocean_srv.rst rename to doc/nrf/libraries/bluetooth_services/mesh/vnd/silvair_enocean_srv.rst diff --git a/include/bluetooth/rpc.rst b/doc/nrf/libraries/bluetooth_services/rpc.rst similarity index 100% rename from include/bluetooth/rpc.rst rename to doc/nrf/libraries/bluetooth_services/rpc.rst diff --git a/include/bluetooth/scan.rst b/doc/nrf/libraries/bluetooth_services/scan.rst similarity index 99% rename from include/bluetooth/scan.rst rename to doc/nrf/libraries/bluetooth_services/scan.rst index c5b6e9dcdd4a..868bfa717b9b 100644 --- a/include/bluetooth/scan.rst +++ b/doc/nrf/libraries/bluetooth_services/scan.rst @@ -154,7 +154,7 @@ If there is no match, you can establish a connection without the need to disable The following code sample demonstrates the usage of the ``filter_no_match`` event: -.. literalinclude:: ../../samples/bluetooth/central_hids/src/main.c +.. literalinclude:: ../../../../samples/bluetooth/central_hids/src/main.c :language: c :start-after: include_startingpoint_scan_rst :end-before: include_endpoint_scan_rst diff --git a/include/bluetooth/services/ancs_client.rst b/doc/nrf/libraries/bluetooth_services/services/ancs_client.rst similarity index 100% rename from include/bluetooth/services/ancs_client.rst rename to doc/nrf/libraries/bluetooth_services/services/ancs_client.rst diff --git a/include/bluetooth/services/bas_client.rst b/doc/nrf/libraries/bluetooth_services/services/bas_client.rst similarity index 100% rename from include/bluetooth/services/bas_client.rst rename to doc/nrf/libraries/bluetooth_services/services/bas_client.rst diff --git a/include/bluetooth/services/bms.rst b/doc/nrf/libraries/bluetooth_services/services/bms.rst similarity index 100% rename from include/bluetooth/services/bms.rst rename to doc/nrf/libraries/bluetooth_services/services/bms.rst diff --git a/include/bluetooth/services/cts_client.rst b/doc/nrf/libraries/bluetooth_services/services/cts_client.rst similarity index 100% rename from include/bluetooth/services/cts_client.rst rename to doc/nrf/libraries/bluetooth_services/services/cts_client.rst diff --git a/include/bluetooth/services/dfu_smp.rst b/doc/nrf/libraries/bluetooth_services/services/dfu_smp.rst similarity index 100% rename from include/bluetooth/services/dfu_smp.rst rename to doc/nrf/libraries/bluetooth_services/services/dfu_smp.rst diff --git a/include/bluetooth/services/gadgets.rst b/doc/nrf/libraries/bluetooth_services/services/gadgets.rst similarity index 100% rename from include/bluetooth/services/gadgets.rst rename to doc/nrf/libraries/bluetooth_services/services/gadgets.rst diff --git a/include/bluetooth/services/gattp.rst b/doc/nrf/libraries/bluetooth_services/services/gattp.rst similarity index 100% rename from include/bluetooth/services/gattp.rst rename to doc/nrf/libraries/bluetooth_services/services/gattp.rst diff --git a/include/bluetooth/services/hids.rst b/doc/nrf/libraries/bluetooth_services/services/hids.rst similarity index 100% rename from include/bluetooth/services/hids.rst rename to doc/nrf/libraries/bluetooth_services/services/hids.rst diff --git a/include/bluetooth/services/hogp.rst b/doc/nrf/libraries/bluetooth_services/services/hogp.rst similarity index 100% rename from include/bluetooth/services/hogp.rst rename to doc/nrf/libraries/bluetooth_services/services/hogp.rst diff --git a/include/bluetooth/services/latency.rst b/doc/nrf/libraries/bluetooth_services/services/latency.rst similarity index 100% rename from include/bluetooth/services/latency.rst rename to doc/nrf/libraries/bluetooth_services/services/latency.rst diff --git a/include/bluetooth/services/latency_client.rst b/doc/nrf/libraries/bluetooth_services/services/latency_client.rst similarity index 100% rename from include/bluetooth/services/latency_client.rst rename to doc/nrf/libraries/bluetooth_services/services/latency_client.rst diff --git a/include/bluetooth/services/lbs.rst b/doc/nrf/libraries/bluetooth_services/services/lbs.rst similarity index 100% rename from include/bluetooth/services/lbs.rst rename to doc/nrf/libraries/bluetooth_services/services/lbs.rst diff --git a/include/bluetooth/services/nus.rst b/doc/nrf/libraries/bluetooth_services/services/nus.rst similarity index 100% rename from include/bluetooth/services/nus.rst rename to doc/nrf/libraries/bluetooth_services/services/nus.rst diff --git a/include/bluetooth/services/nus_client.rst b/doc/nrf/libraries/bluetooth_services/services/nus_client.rst similarity index 100% rename from include/bluetooth/services/nus_client.rst rename to doc/nrf/libraries/bluetooth_services/services/nus_client.rst diff --git a/include/bluetooth/services/throughput.rst b/doc/nrf/libraries/bluetooth_services/services/throughput.rst similarity index 100% rename from include/bluetooth/services/throughput.rst rename to doc/nrf/libraries/bluetooth_services/services/throughput.rst diff --git a/include/bluetooth/mesh/models.rst b/include/bluetooth/mesh/models.rst deleted file mode 100644 index 288cc8f3516a..000000000000 --- a/include/bluetooth/mesh/models.rst +++ /dev/null @@ -1,32 +0,0 @@ -.. _bt_mesh_models: - -Bluetooth mesh models -##################### - -Nordic Semiconductor provides a variety of model implementations from the `Bluetooth mesh model specification`_ and their API documentation, as well as vendor-specific models. - -For more information about these and other models, see also `Bluetooth mesh model overview`_. - -.. toctree:: - :maxdepth: 1 - :caption: Subpages: - :glob: - - ../../../include/bluetooth/mesh/gen_onoff.rst - ../../../include/bluetooth/mesh/gen_lvl.rst - ../../../include/bluetooth/mesh/gen_dtt.rst - ../../../include/bluetooth/mesh/gen_ponoff.rst - ../../../include/bluetooth/mesh/gen_plvl.rst - ../../../include/bluetooth/mesh/gen_battery.rst - ../../../include/bluetooth/mesh/gen_loc.rst - ../../../include/bluetooth/mesh/gen_prop.rst - ../../../include/bluetooth/mesh/lightness.rst - ../../../include/bluetooth/mesh/light_ctrl.rst - ../../../include/bluetooth/mesh/light_ctl.rst - ../../../include/bluetooth/mesh/light_xyl.rst - ../../../include/bluetooth/mesh/light_hsl.rst - ../../../include/bluetooth/mesh/sensor_models.rst - ../../../include/bluetooth/mesh/time.rst - ../../../include/bluetooth/mesh/scene.rst - ../../../include/bluetooth/mesh/scheduler.rst - ../../../include/bluetooth/mesh/vnd/silvair_enocean_srv.rst diff --git a/samples/bluetooth/mesh/light_ctrl/README.rst b/samples/bluetooth/mesh/light_ctrl/README.rst index 46c440d62047..af6ebfa97dbd 100644 --- a/samples/bluetooth/mesh/light_ctrl/README.rst +++ b/samples/bluetooth/mesh/light_ctrl/README.rst @@ -164,7 +164,7 @@ You should now see the following actions: The default value of :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` is 10000 (~15%). -.. figure:: /images/bt_mesh_light_ctrl_levels.svg +.. figure:: images/bt_mesh_light_ctrl_levels.svg :alt: Light level transitions over time Light level transitions over time diff --git a/samples/bluetooth/mesh/light_ctrl/images/bt_mesh_light_ctrl_levels.svg b/samples/bluetooth/mesh/light_ctrl/images/bt_mesh_light_ctrl_levels.svg new file mode 100644 index 000000000000..385eb439bc33 --- /dev/null +++ b/samples/bluetooth/mesh/light_ctrl/images/bt_mesh_light_ctrl_levels.svg @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Page-1 + + + + Dynamic connector.79 + + + + Dynamic connector.80 + + + + Dynamic connector.81 + + + + Dynamic connector.82 + + + + Dynamic connector.83 + + + + Dynamic connector.84 + + + + Dynamic connector + + + + Dynamic connector.70 + + + + Dynamic connector.71 + + + + Multi-Line + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Sheet.66 + On level + + + + On level + + Sheet.67 + Standby level + + + + Standby level + + Sheet.68 + Prolong level + + + + Prolong level + + Nordic Sky + Standby + + + + Standby + + Nordic Sky.87 + On + + + + On + + Nordic Sky.88 + Prolong + + + + Prolong + + Nordic Sky.89 + Standby + + + + Standby + + Signal + Fade on + + + + + Fade on + + Signal.91 + On + + + + + On + + Signal.92 + Fade Prolong + + + + + Fade Prolong + + Signal.93 + Fade Standby + + + + + Fade Standby + + Signal.94 + Prolong + + + + + Prolong + + diff --git a/samples/bluetooth/mesh/light_ctrl/images/bt_mesh_light_ctrl_levels.vsdx b/samples/bluetooth/mesh/light_ctrl/images/bt_mesh_light_ctrl_levels.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..4b01de202fd1448d18b9c88adfcb42945ad32bab GIT binary patch literal 195781 zcmeFXgOhKu^CmpDZQFNj+qUl5zGK_AZQHhOe8#rt4)%U`fA4O+wfi6Jo;sCtD(Olm zo$jYA$)hL(3Wf#*0R#mE1Vjv!Uw8&?4FUv2jSB>X3IqkBBVupoVru7Npz7gZ>a54$ zZfiqS2nIrx5A;vy|2_XVTcA5*CN_%+$^SOx10mcRJl3{zN1fQ~Y_4Hv=mnUL37Tdd z!?kgv?KVBW8P^ndJES8XEd9Mc3^C#U!ETRzLEg1>l_t)zGn}*nMsL+BXH0;wm%Po< zBuBBtqB+sylg!q;&GWC>`<+Q~43YK*?=Gh~KeAC&j7^AKO9D)+YNvHbP~J`^meMDR zwbZ(iqXhq}N!CB1_ytI^2=9G;hi5*+5g$qIP9?mv3577B;K2H*0|96Q4w3nsVh-6PlJdxO zWl)(aU~|}kr*H$#p#UzCyKG|jStMR_s9cu+uR0dMC2^Nc>OPCidkU573^vCVc#1dR z{NJm2MehFBn>FGL3eNzW!@M5)DR&84>n8baf=JVh2rEUPx<7v;RDz#|r)^r|3zvCE zeDqPRxntu)x{$ck7C)F9_#K9(dPI88JuVcck?6}4de@DbeO6fs>tSW}Vi}ljd{bMI zVQkm=ugGOoVHxYzke$JM%>BjYJnc2MJpJpIxXvU{?KOuTLtTTL>)@AjC=Y|p+u5)n z$wr5EZYnziJyCXeeK9fuuNQ`7-;2s5bF!XI&C+$%eHbeypxEF{`wIdH=;sF%Nb&!N zQDvHgE#$yJK>DCSK(PNX%D~Cg#+i}fKjr_!rvIA}>3_|=I%!INhzUvTRq`|F*ypgA zH&`*r4oTS!Dg+VhO3DaXz(k?)<+cF^oP^wTfq{=;&&#Z~Tl-dat`)1$we?6W)j3q1 zyTn%Kq3y%tzF&*19>&wW;m9l6TTjoRM!x}4I?kxf$3$vmG|^4;TPd81hZTwCbfGkB z6dW`;wg8>r2(pXZ3@$ZZHk6F84@6%Ckw0Ch6L3JLC1?(U15lt z_w_r>n_;wLIvgH5e!(4^1EYE(T~kE5TnjHmP`3vZiTVWz>OV{_K9nF;{D7YG!t51B$INS%%KX+rZ-%9JsArF0Q^VhrY393q^>1*Wm`a z9@ZSMQx&IwI}CEKy2U`Qh4U!CXXQS;cJT4=Y5F)bYjR?!ZVNRLSpwZacSRj3>8Kd6t2co`~CLD3yzF^>wMi8{C$ z?Hj<5IIiI>;X~iV>h!3mk!d)rHA@ur3jHB#w~mpumVFR&Xya)dHLfhG1>7{7Z}Op# zwDaV|oIY8*)0AuG%{%0UEBH=9FB zT@ui50e~Ar6L?uG9LWEu;v`6{fx1B`eM?I(DgfM=KnaIyr!$4RU&lfiC+Vh(4D8f$ zF-@=-QnkZonJ|%9B5#KrHu050@S$yoJgyLxyec}ZHI}MO6++OrTPxUVn`23Dx0D{K zQy_yLh)$;ahZCom&4&wd7~n7cbm2=Y7ex3Qb*^_ z99K$LzqA9V^5Hi!UBR*-9SYZ%Ep7Ux2p=7oEfu}L-7xlGD{YiVg=6S6Zub5TZm0t!1BLtk!tVa*bbOGTf|Y=)DTdlO;Kw?Fl3`|Tg4^% zvEQAxjmvl98Qwe8RT^Ahaw z5N{g-hvWw=*t*@VY0Pr32VxiOFnPx47tMUT;^MzC(zRFIZVSaAz+tueroz!a;q_%h ztxJnj%7Bp~TAV%M)P3*~NfD1&JmK!7W06%PC$mt(KuHUla%|nT{dVcJjW;x#8%G)J zSg=HtZU>f;a0sG*q2rh(48V_qSSQ3W-`(*^CJlRCz655A!C)izAb|r2Lw-L%C%n%? ztYDWOF%^KQL$f?i-{_^AyoZfe_-qGf#IDVX%^UWc9lG%B+7=n2WA+ma`QdX|g01KE zE3>-#^f@|i|8u`)&H?v@^k;;rdv`@33m+P=d}0|;cTo09OC;^An4j^@QxZ-)!Y!>?^a3AgD^vYrRl#*rX{+J zv43$p+;%flF0D^w9Au5nlNcqlin@%^7byOqa$ECb!!(T!SOt-Gcx*cur6^~U88*Yd zFs`;R$7zn!{r0F_Kf2)L=rZt5#8vYg7S1@8E)b11;|!#b>sW5X06q~8Uck#JxJQa& zOq;5~^%;-j3wrB;a=i5V+31*l(E`ev!QTtn!2>52p>87T#C_+{udbIxo4W~8c;}zp zHg&lPt|xmmU26|<2{H6sMUM%D5)G?;%E1*UfE$14;W5(LuU(_79PYo~o-HKWg@NR2 zTDc4u1*VkhS_(_jM`2x0y$&%Xg;;X-^)95Hk>-RwA>8wdI^#D$kJ^ckl*=>%|xbK{ef2`e%LWaaMc%S-T2-W>W0UloBIA%S8W7E8k zqYQn}J*{0>l|l~38OtZxU#Wl; z{kWrd%5Z>T5)F{8^Kulpxt&rBHvKa7M5v9vY1~x!=*%8M9WY`?BwO+Eox^w;FyqjDJk`*;Aao))yR0t>(YBn&K;HUbD^C#yJLa zdmBlPoVw_T6=*p)x1iZ&fJuU!=u|AUaJIE(mVyM-%I?DX#|6Ui$oXim#cD4PIZAV*o{ zCEKPo0{;Q}4!%i~va{lA5>`U8Z$DvI@LVEZ%Wkw-lmLUDBm!j}j89tgS?PNz%n^6% zd&uq7JNe{20!b>yK44laSBXYbSy-6r@-&q8Wo1i2*61iU<19`<>B*7cC`D}(1q?`1 zgDO&Z_W%i~kv83FPvhbGEmvI19;u}c$egbNU@X6(> zO9V!cI?!xM=6C2*4DR<-)C|O=T`$O#2Gx#Y@}JjRe2ZP#2f%O{gqn-AGzxJ@K}jtL z9L59)qDj4BJ?4UB%>U$_!MVim3e+hv_AvLAw5hf!kZAx zm{{0wM7rRUyC%o^dt!#cl3DY@FgO8fH-(_}hRxH65N^FN@h)oA&Gj3QLpNcG4|_6` zKXt{~rAQ1c)7r3R8J|`lZ0t_`o5|_e)TCE^x^6+3w0C$Yk*6(PqFWSj3dY&;z)!rz z$C9$S!_C>f1-bRs@$sDx+$dr=i}l$QRuD>0N#NNrnFn!ptbKU_35*K2(J7WKZx zfXRa(wVRu6H1N0!Ox5nde9{1emv)aoq=@V_+`Vr7DYMi(Ozw&z)lp7JJPT;?+elkV zEYs8uY^}P!$!NlcZcZvr#4w1N!ayuC*5ycLu%zv9!}8wn79gQCd#|mp7I({rMq6x~ zlNnd3)q#ntLF9_A>kIT5~1s7W?(|DcF{gd~a(uSiM)r8PGs2*t!j^ON$iOyK1x?PEf z9st+m!HD$xA;?26!J80(7ev>Yjkg77MXIsb4s**r!5?locbgK_o-8 zF3_Y-8r~ThvKDr=$tg%`E)|sPjMPgB!hS&Kt|Ej#8|EHO`r1JF1xt@Ps0%b(>~){P zU<$$2a1|xo(9JCmGDqkIg9fp9D)yJGbFH?{oEEGdZ6}hr(+p7XEBQRe4BNX;vpzpl zJgU{}4YMN#V(E}d6MDzv6F5x!z&nMLU=uMIRB;|c-RpOn&sV07YDxZ059pbfX4xTU z-g(0a7VbZKO=peCg@M!^j&^O6HvO3trwAF;wIWZW@{zwbNp{9z>YR{f7E>IVG!_0x zVn$2!Led;c4^14k_EBeq$woJncj_wY;r)V~1fR7(bczYE>MZAm2OB!U;Z&$5Or4Fm zlJpz&JSa;h)|DEK%)H}5=x>DqwlNK4Oo}ov-F=1WH{Lu6#FufXox+8*lr5{qqJ#`N zPcU?pEqZujx;ru#dAeJkj!zq19r23mC!;?{wux^bC@Q16mKl$5C7xQ$DYa+C+%5|{ zumW1q68%6YU4p7H(ru9v=_%9R3$I=+WzD6@7UslNMXwjNXLDySRGedVg*NicN7L8D zo~?sa18C7V3FlN7Y86B>(W~}L-$x9yPkn%xP$xQrjE7)f_UR7KSgstRp~t|677XYLX#)h$~^PsSEw1=PEw|}kZq%Ejvr&T1x z@UNUzs0U#qfrqI+HuMrMre=rvb!5uY!Kvw$0yl2T5;b11Kr1a zr$8`BhJM(uqpQ=tPl{_Ll)hIvky^}IhfYh&o^V;~%=OfoEDsfEsC`Afpr0g&Pa)P) zQxf#6a!tHyU@ZpM$zNHK-`cur^@v0Qj>);cWwf}WHu5bKnXSmYyugan~|-jwL& zt@86vLZcLDYmx{>qC8Jek_l6VxS{4ZI;&4mjEmx*>o~Tx(^!r<_8Y7)Yn%db; zdQq3K_cv3!*`&*8qVe_Yi8hsLmO)eVdoeI1uNZs_ILnE|yPeETn!@(!2*~C#D_u@# z@Td@3mHKPTFv8Dte`q`n#eQE4bfQX)c7mD1ioBy@t=BPQ4MJ(siRkI>)*7iM#Uxzr zjY8UK^`%;%EF#DqF(j}&M~TklJY|jWXt6sp-+emI-!mR>N;H*upxmal@t~#~%4uWL z1eK16XhxfY$>fDOV9MkdYPdH$3-F`~8!8lYS4O{26rFjY4yVzQjd@}AxF?08$qP$B zkRbzQ7Pwr$)5bg)MH0Fkky8URSSUWaRVr&hVN(e-ku^h-SOuL6dOy7=xIb%@GO&_X zGPhOZc{H~!MVTBVD7e~8?J}^lhZ`7Dpeb!UCMBy`Bg6TLVwX5k*Ug2!x^j|op`K$B z(9xq<=fm5uStIi^JTtqzs4E4q3H+p1W(XFSP7)A`Ru+o%LvT!0D9Xk2;xbjSxZz>c zDLI5Gb+;l3BbWIilSm=bjFM$A-MJ#lcj+oHKM3VcXSk$DVU+AJaR8EI2+!Bzk^~V7 z{0S*CG?KAtR{LYWC!97&H8JeOA;Mu)1`NGX8E)7s|1Sw$h0q+!DdbYXG%5@hv{>!jvl ziTZ@oq7I9}MTRIT)GOInE$XPqYD`wPb~Lu%>K`zc(K6Ix)65hbxze;~Zy=U|FuH** z;FjZF^%&OYwuCMUi<&QI5rjhz#?I*J;=F=w_BGj$iX7#|b%E{;iIw2$iHVu2PnuFG ziA0S?SdjsAMRZa5h1TR! zt%FkP+?~bZnO$lfk;%hqH3)5^P@9tExeG%9)KaFB5h#4DY0olej@7R=FLelz99V3y z?KqeRRtNP}>a=O}x;5GiLGFE4URQOj8m@>7x$2d(vCXlPoAmgq+GU;HXxQBwxTrnP zVBT^2v{L;gLF1GVX&Mt0u&CAov)=kCq-P6SjuS;X+(~k-!$#s%b~u*?~3q^mqyTe zv6}D;MC2UC4(xKcdpsI&xGu`>2oQ;B@^Ev+9n>OnB69)j!olT-Zxai;9asdoqUb~{ z8R$T469uo#e5%4OgY~!K418v_R+sPl zPI_jWk%;d#Iic$qQY0nUf| z%Nk#oIl_HjfRp))gis~DfV-rCdna(@XoP)9NJ;cJTuL`Oz`yo|u6lS|H*DhXfu}5v zRo$3(SHIm`b=RlFE>B;55j{suVinwooGT{U{>bL{Wo=8L^`N3Is`xC1z+jmd%D#Pv-q>^|;Vjl(#GCmgl=lPpld9*w*=r!4h-WlCVPM@6C>j>Epy*RoDHNgC7N zr;+XV_wIH&l0uYCDhaTmfim};L$soQxh+L#VE?n=Ou6%1)y5(%E9kH>`sLY?w35_L zuI7rE6s}5})LheMD*5N-SAgV7@A#9@?pI$M*Wv9V-NeB6y0q!{Mw)h;tUNn8+$GON z>Y~%mBP~?$@pAmpkg2v# zv3z=c`GW5m{LY(1$lbCU=2!DQu>4yc<>5@M@eN(l8_+bhh3tLO8p$j3F6|(g$c}e^fGOSK`{ujpq^q{l(AR z%<~Pd@ezfSab?~PvOxF;neH|+xj<7jga#Obtzie{Flc-Z>omb@l=$e=ME1!Sfj09J zoO;EcydG7NpJ4sTl~Wrs;>VoG$%frnifC63<6%KXwhl_mwwBp%DN)LEW8q*JFD*Yw z#35CyoE~an89>OWw)xM7i);LD!z};9e$h=#6wwbo>RYZb9FN_FlGe_b1p5GO9-Q!w zl4lSFVdGMOHPlaOu$754tx>*0mzNq_GbJBg$nMA0@$*D^>$;cU!>NTed7m%KPQsxm zqx}!k1*}J2HT}zMWzjkG+<8_EU+fSTleH64bX*KEzwRr3D3R@u^N8Oux4 z*XM|g<7c;Fn0%M5e-bzzJ^h^`6~y6m%#0obJZA5&6nE{)=AB>r-=Wut5v@P1GI+Tq zK?s`DaCdLbD?%&2X$H@r8Tosu-9#{XgKwHIE>uSU&a_^Gc0V!%-@FEn97B+-y8_}; zF*%I8dT||dB)1S)#xXcRU)GKK{~&Rhenszt+K<$9NAW9Q=ugDY3#i3{RJ1xtYjX#P zE}=vMqR1X!?ISC4f#ar5es^z)zkPKcq?Z1!HxgAV$kqCtUSy}UO#?cbVTB$~!q+9; zgaxMwp4KZ=t{1v?10m3&B>S5kG&cP5aLJK?&RxZ%Tle!C4w&Q?_LGH+L*D%qgRXe# z+UDAZ3~giooL#HcR1%j3T!=sVmd_8l)0$5}K6_>I_lQXvQ=HP7jqxI)r)v8v)zi&Q zQA=0MX}oxV8sj#a63K2qIpvz`T0k3py5@E*Sha6_0_^ zGjLdUDo&we5~LfxQ1tEk>j@!wGhc?b{hS@eEd?gW#Ve*}45ErA8%lS%XubQUgj7oti#n(MIqWoJ^yOIy8I^mfY>z#}pDSWO-eU zT&Vn z^6O&YF0@QYrmJap&h^jWi#|{hvlZl0M{;A1QM#SD*S~Z6=H1=4$=rGjE%6^zPZ>>K zb*|yxGk4>&Q+6CvWgzVu#ZvD!jz&8>a%CwAYislNvIq58)l6#M@os8m*Z<`908Rak z!em6}g%LCcYEbCem3d=apN)ch+)$*MWU6B|kVP2PIi3(wKKM~O@-CqFYtRLHrl#DG z0^-;_f~DSO+_iJ-4*~kQT#-U^AUK=TGJ_RFgpAueP!FQH3uIg|jdfZO8=$;!Q47wg z0FiP*5p&WL{Oe&mUB*gpC~G^tw&&uozdZUW_8CF)Fd0Et8S_qe*2R88xMT*61Zery zSCP33%R5L@&wf%x3}xt(=b5MH&dmApo?s-^xS#=1`T}UA*tc#1f24ed?_Ycu5jb0Z zW&bdyvO_{?B5^C^?2_EEJjC=^>5vXhAMbdEz49L!^)Apc-5n~0Ri5IKg-X)y6nm0>Z}XyQo@IL5V20~wCBU7v?@qa7F%P}jP{g@s zn>my|67bVbE=dZwW7cHsfk_d%cNXsdZgVdDOHYkrA-SGw<@!j ziQxO{W#VJs|6?C0t&d#2k9_)FG3$!0mDS9?=J58{VnFlaGR5B%ow2<`dblO=i?_eJ zE^7FG24j1enX?(2Gd437Epccq+X?|Emnep|jcZ#kD$d^M(+12NKYAxefw;C$SYB99 z>6^M&Lcw=@CX~B7mudYOxI(fot}5v)V@AV^Pzp{<--dCL4;mo@aGvh?-hn@HYvm8= z%3mLSHZLC|B9~oUh(bZ&Ga|jh8AbkJzH)v6M%QJZ;9&VLnA_u3e@`8ESHD3fx#qG- zo@Ht`kUpdQ$yH+l=RDE#eUGFjK5Gd*jAV|zd{Tw#=GPclCyvvs4n0Gm1=8G`t3g_Q zouBnrajpD>0{FTS?$`1vTl)U>yL|hM77V=h9k^+r_!pKr;H6JA{HN}QG2YocOi!r_Bi!!EIQa;AGk&k(8g#E)wC=gkwpw|3^X zd}g7AtCL;gC-US>v~7w%SuiAHg>iO%!_mDy`YtDAIaf$L;!y2?%mstMmu)C$eRD93 z%(S_smlpnA0$25U)zl?r)zr!ziQy+O?E8T1Rj~#lu3U2TZa3;i3rPVwZ`UrM;tsvA zI2Yo(>aX5~xlis#6Mv$V@86Gcgp)3GC=|0o%-g^HS^fjv{U8d-<}o)^or1|sSpr@5 zh3=>VC5S!-H-$3{gLRM*alumZyxpmKAvZy%zL7)0#lqGN{ZD~A6b4TSG-s2B7V9=A zzh&w44m==6Q`jPRK9Lo)xE{)cY$Qayz{3nZvC`+wwwNKd|g0+ z)NMr1BwlIAH|UnEaSl@RaU6ElrfH;%_%Fv?3BTO|CE%^E=FZM*n>V`-W9*upAxU-$ z;GLum;kK35<~@#c@I=`A*s32Nef#{6%k_Vto`{~GhB^PEo^XZ$17ZJ9>WS@dXBSf^ zXU6~f{tpIE?RS;3JBs?=M4Y(~{e4XCajw019X|sKD#j-I#SQE zBU7Oh{8?79oFwp(V;7}*t}#V4{bi3GX4CvWylMddOwYL?TpKi*J7Kgq|F+J0%+3C3 zm=4KhS6f<8gCE=dm)fZa(`%hNq6#Oli#}71nMB^#PxWGvo4u_c_w}dm>d5R5oOqQ~ z+au)@_X?UGhp5s#ydJZv*0pPI_8&%u&K~cyS6`;w>de=U%;+0|-EF$B6$3{~p?UBC zOma0e4=vQ=NLbUH-b8skzs-EijM#lcm_8(C5`AVec>5%Z$H2mgyD~+b#3romp}onK z*d2gGa9fbBVrg0ANtW^*tC$}@bZyYeinjyqgiPLWfj3l`0RMZN${TD1w4(Rr;TWP? z^6ZBz4&1(5XTXchkHTA0FGA_SMS-_m_LG&;#C3b_fx=#PT+(|$lXR&qDG4`tiKSSW*VEFgeiEk_hOMT80J`~-H1;3^9=bIb?_UD_pIK$gU zNQwDP&`6A}Hm&zCh{06qzLO6^LUOb&r}1Y2ej4co!BD&~T|bhY zB2J*&YCrkTPu}IJ_(MUd*Og$MhB2Od`V>1xH>1>@4R@Oj-XrmayHm+;nmbH9`=c=L zh@2d+Pa6-oEA5wcNrmDlY82>w`@5?v+c;j5UEhbYoDuthv+Az1xWX~XVtiOA;R<0S znSSECY#Sg_8Y;vPa^2koAYLS}fqGH$?{P!mArv^7ZYR3?$HF(nd}zZoqsuv1_u@32 zePn~uU`hco5AS5ft4ZRupSSP>xmnhD;xXd2JjquognpjOyd(wz#AoIsPQ}F?($xG| zxBd9bJn6PH9>;{84b4Uy0;&pV1b-GCj=~xPs8po;ni7o&@?w(IH>S4+eDUN6gkU1L z4F`NtB#T5ts6gWIX@{X|WW)0!IIU@%fVrn5e6GJ{tKk+5u8riyw|~ctDG@qe-4!dR zaqjVIkd^rYfr>nL^BkW+;Tm+VkjOJd_94d{7kr4P-~^UE1k=Gu9^IH=hY>Ks{o>Oq z()MSdK1TeEy;12}AbjrHlXZSmM1BQ*bN-tdRl$0SNbS$Pl2RnZzu6pppq>+q0K1!i zIWHcc7U+lKK}vW2(k3cD)ce;~ws?Ik|J1~TE0a0{O3pSd+;mN@MHEihu?Yg)`@rk# z01-u)^BB^HFSe{m040+i36p@}Pwo;*j+JVdfQ*#f_%j}!7EDe<@OYG=ztC%pYTR}> zEY!Bf;l?m8vO0^^-%C z{H1rDJCTUHPLu~^%`L+z{nGD$E>$^|7$~+Ap3_%^OWXlachfi5`NN|kqev_$`3}-~ab)u>Bga=kg;l;(fa)>7W00QCC2z9t-s54;^V*f$)=ddW)Py?ak z8@sExBLEKCQVV48MhVZ~ZB>9$&zIoBblg#L9H1k?Dl}u_RLL9Z`A@XMg~vHuEc~PF z3T2?tLsA=%MVDLt{(PKifRZ_HwGa$eg=MS&>CWM;>D5UtdEos^b1+jm^MVKi@2 zjLab^4tht#lXw~#I&2v^L%;-`Zbj>ru75<`7wqyEV)Jjvi9>@Q) zuxfH)036r9@rrgzI0Efz{bakmdz7aUj|C*!MF4)sxf$jBCjbge-Pj3q*bzIFj);W6 z24p}GJ?Y(%ei!(`5%dZ-2Ho+;!3yf2vxw`~z(O4=t_QTqvGPi)gI@Kch>LQ;WET65 z1C41cMvzDM!(oAC^mGOz!|{-L#xG`i*a}&8%MM+M8JB$2#lS(^YJr5}Cw5pmF`{l- z5d8DXHkPY+vS=o&hM?q~bc%t;T3>f?A@ zEdZTZQ~w#j0>s3%Q8x@5|A0;tj4VemhkQ2_0@@oDk?pY`!&o` zSpqst_s6E=uof?oHvYThNxbR5$Bnp9u@@R7Am@2b>Xnq^zmVZeuxMy6$#>&*_Ay<$ zjU`O8v)s?s+<2qWV?1WirnQHxC`b^aM~z`N-lzy99rM5>W!I2Dp5^Y3oO$RG7=A;y6Ysv z@tzw@8oMl{ zin!XYlP>Z_f=Z@6&&g;AL}ve6>L+Y4c&~0$Erjx(?Ffq-3y&s`e4Q+zQ1=mNbm_1tPh}r)1m*mD1eEs&l~Xt?Z!K9ZPl{1g<}50q?o&!~6kJ`M|N-#Og14 za>0P>P{<)>HKG>IF$|)Smfw%r$3l(PVk>ZSfetbQqsi-XD!P|}1w!Hug&eOb$J*%d zpoy-u5JxxaU;))}1uRA?2?!n0LK(Gna(q%1AJLt=_(BORCU+>P8hvCYiudcWxdG^u zuGXF?uBTMA&+@oEx3N>uSrfSI&7`*T8UhesLI&3gfHUjta-FX?zTubKV2Nc7vz z{6MO#+ui;i*1f$UNJ)wK0SUC7K@8N@HbEN(Wlm;q&6$lC&k_rT#SV7IKR&G!bSoms zQ4a=+r689K^T@F-WFpZpHxFoG!r-Ol(Bc2w-wnw_ui0hom`tISOAGAZ$+IOy8CL3P zX6zB?;!9(uNj(a=Gt zCrn;yyAtAGNqe!GbIJuvF#@HEsAP)Wf$w}b)Y*x190YC7fI{r|Yg~(6-5<%$$APhY zRs`$N58ge(rw8u0^h1BJ)1cl!XoB;BLFDK{>Cl$c8HATncurMGAlKL16g-N{Mz}S= zGUHqk%tTV5%=}`2?(YndXFAzRGC@@*@8vsrfRBucWbcIizs$KEIq4N)QO?;ItZ>co zJ1rjsJf-%NfZyd2f`8%xfeH{fcDDdXFTYpk^S9;Wt0!eX>-a;{Ql8HqR4f=mDOwLG zW`QfybSOi>Bs2LTbq=Vy3x{@rQ(wm@11blaG=xStwL+nbt(Ps&HwCU$bkT6Z-$2sc z`dpa?KW;$)?+4P)*Gm;qT=j=jWjX|gH3|+pajx@JyPq#L6du`Fl~WjtrD}aD!H)&_ zqSLyWjs{s9kpPhb10?|^8<@+3+f=D6e|*O#X}2$((-8l@4cc+dFk1Y^0vt z$JS^mM50wT`vPO#m66MUh`^8$6mC|{T^Ju25CDYD6vNR$7pmT_W^5DerrE?wA5luc zaUS2wt0DVlmJ?f9=T>@^Pk=mm)&$fQ-e~mVflR2d2%!Sdt$xRXTJ|6meS_P&A=m}M zVE1Y`V0qKwGWPR3e)n)x0u;$XvDk(munb+7zB61f@{=B@E>0X1oh09ea-gJY5{ikx zdlCB5WFd#)l?Mte$cPs4xAX5pv5-bB)QBKLIfi-aztYQJ)cM%;3rd6v*x`%wO(HOA z^Zz+idr;&fBnV_A1G0l5D==i?rFLk(W;VYeSvJ@zikOP5L|Y67KrkWX z3j!ai%%#Qpi75Hm7noMEEHodd(ugXs5En#KxIUJriPjK{OavAel~(tCNDXPWVeoI* zKv19m-b2}4@6r#f9JQ7hlP;m0`sC)mH-cV&uw+L5)p#kCwWJt1CW&(kPW5WMc}O)w z33q(wf#dJHZXR3Y=>co#rw%jJ;O;1}@f75N%u~}F%a|v;xW{wugLrFl*uGQX?%{s6 zOUPG`U+F4`X9IY^i;=AGTN6XfK;&y3@FzKc4cX3vt0MZ&=xFmXZ960Kx8!XQ0s$uau1L*y-8;j`M-LeG zQrvW`$art{XmKnaB8OyJYkFG&CDqEfkF!gMZ8Xk`C#%03Na)m$*wS4WPd#U5FPCi3 zMUxFjJHRDL0e=`*!nJ38~)bfM{V#m)cw4dvlEl|_|#Dup|%$85)(UO^` z(?2+9?a-Z~=o^ZE(QF9%BCP`+3E1dJ+3+&fjFupH?^f~KCAS$XZCo#dG)^dPxCHzL~FQ^r?Tj1=Y07ZHH^@u#u zAqr-+(3C64@&Sr1{-Nj#o7! zP2*3@HzA#wZVd$|!W$}B#UI=T{2l;EKbeddk3Nl|c$XfKJI2nvaY%( zi7SvYtljKY)N{aFLo0BK%h!rm+zVXvD=j$FR|p$px`RDvOXMAjgqpyTF0D>{ zj{^5Kjaov{Ak(?w$T<+^hZx5q0v#Cv(gF{*+*$^EFrh|lb+R9{qfLqiJU8%w5iMC} zw_f_n2&!jIXekQ*;}(~r`mZqERRO;j0MgBQ&O%vkESrVV7J}sLlK>L zvMOms_#sCA(3KMoYz;0A{@PGNzil^cj|98Q7cWwg&7kiw9$;3GdzzQJo;x7B!_Cu5Z|5a$YII8R0kUo7~A=uUwB<`CzLtQwmkxki2$Vd zC=Qz~MY4kg8x-q0+F1I^(0(ouieXiodjE*|oo2ofb=##Dy7P0QHHLiynmUo@bdVrL z7yVVuH%weajXs>gR5_CwA~|DNtoo)&Y90>g`g>iLbN0r31%6OhNMPMZ zG^?Hh(BZ{Z3Lbi34IgGFE@w#;UN)H9Qyn6Wj3dQ-*lHDvgT)>SR|YjyK5Uqb`@~Ae z#!1k##)8obYHg6WzwQ|tzQpt3Q*v!y_|D}r$WjI32jyE5YGQg`a*cMa?RO|}bbO(bAu9Wi9pw2zAo=S*-Cq{Vavw=`+q@=nzn zetb&;+$cTYl?&U3cT-w;NE%ulaC_kr}AAXz2l?uY?4{ z#=LJMPmCyFBtbQ_daVnmJ{0kcgdbFdAl0`W3qi{X-!V<}_qlJ)caQ7xJM9&3BV72E znCsgW@6@tzAggh(1LdS02`_;~kE&$+k;Yxzc1UHK{ha4-v7_Cy}j zE&X^~f^`?bP)Q!a@>uzRvw*1nYY2;(n+G`C1%;+ZWl@^V- zK!e3M`01Gba0BF+12L#yGN0kbrIdq|za4i)Ed1Dpde%ZAyEDJkiadde;v#$c-yAij z$Fh1ALebU$y0DG@7UrAaM>R>LjcdazH;6|ibB{~Jpe)G6aLmi?k0>HMAs?}6Ne5vI zyFu{&t|j?X)K%q!&?UpSBG70Ien4ZEVYmKU4z+)i7_2HJQ>^$OtQfHZ?%lwaD3V{( z``iJxt6T~y;2NpAvr2rqNv0$HWY}1ZCz6%r(6vU*4YSajzEh+r0h_B1EfjkC%)?V^ z(q>W2xQvssPA9%t(_=niXrV8s+i6vHV?39_vV>pUjv@A@KX-&TLn9Vak^*B2S*YGC z!i&4)yp**Ry?vgq7(cpu31ju9nY9~jGXmd2xhL}BG?OA~zfpaJ_`iuxby5EvV#=@B zZ~GfWB!*`(<1<5iNv_A+XI;hZCr-{Bu!Z6+cTfq5!3lnsmoM#O3Qf zktN1STC?`enLZc9m0ygzSdSkquh08!DGYq2p+ zJiBZv@E%s|@I)xJLus{Cc9CSaIZbDYrtM+?^`~z_tOE=zE;xZOwB-IL%WN^jHW)$_W-=gJ773AA{6ykZ*PV0a7qJsixzd-ipr;Da$Y+-VtUqQRDWjxUF8Q^Ma1 z1G+?qSKwpWBWe;7jEEErqOfq>w-yxACtEF@vs}rF6~ny`5-rnohcK=5o5`TX5z~&H z?!5B|Dm6wDHj2-Vg-!~=A9c=&Q(?hoytlGFyH-l^MJY{f&FRnB%4YFjl$WU1Osoh+ z+Md@UoU?rAOqbu9v}y-7=qA9uS7sWWdck{N`!rCel*R(t?^Pp1(Aq7KQAz0C$}#eG zpnhk2kTO3hv6v-v9INO7BsrHOhHpa#e}Ej` zqPhl}39#8N6hoydUg_^IQg|JPo0})*S{1sIU?OCZ{~I6g6kpl5MSsSrsAAi;Z9A2u z;)-qCwr$(Cb&`smRBYQxr+&BZ{rtQ8_I=ssVV{?C<{s<2#@uraP*zFdn$z|QDuo8c z7AJ}RqTAY$2nceuRPuf_Aed{~oy|uZmwq+M$}-c^PAaUZn{4yWYN4^=Qi_xNh;c=qf}MGcYO9AQ9L)C-+%Ze?yD>-5&8FQ7(&0uOwP_eh;!UoH0;CcGtu6GD{Lel1Yx=TCH#Z z94Q!2wU*#Igaj`32w)Lq3=2P*1IsXa)jwNtl-Qd=R*id zFt%KJM-j8*G!NnFkyafw@UfN|aR-Mvee37=UZTM?D|d+Ym|&KovOxLYL%PkG2O^ZS z%q_6=IUW}UZe<;@rx$6DR^qc@Y93BS(r>Bi0$9gJNRQi1)Ip|J&{BI17Zf>vq=?F) z;7HctPTKFYUH_z+eXESXlY$r|;*gYyT^xzQH+6g}`ZTG9tqw4&bq^h*z=D$;k zs}Of$U5Ph4>vzK5=U?LK(oJS7qExi6YhiPQPM^V5JiaUj~axYb~2!0HkfBR z(Q8Y%8B$JeQaUKm2vP1xIxh4pR4w zy#lgg0BtrG+OJ-^56v=>btlacCAcOd9x{UCwNKxO9BW?08BujpH1Ey)nKo=P0`>ic z)!jy4qD*WzWi(?BIRD~3qw;qd~TRjI*%FmA><@Fv-% zX}dmDW|cd_VIee^$xZQ?IvvX34C;@WiKsL%f*3&-^e3t4gzF1hLCn^`_JHk&pA{iy zi9_Qs#dBvz4WBtG?unF)XKz!wjp+zQc{$77*YB z;~hmubQ)g_^kiu&!)`>8_Js1v-!xh}bf5RfNy&=OT+*tniP;YB#3ib%2O>dxLU7^Z zLn=!^^>^LW8A!Y@E?!jLdpDA>aWOiW;me5=qSGUjJEn9m9HCQqtRH;>zMbwwm?y*m zC}E#@uKQL*{yZg@q{`Tv)ew%_qZOc-_H{K}khKd7ApdEk-IzrcA(hPyGmWS}x`8fP zO&=JeyR;Af_Dt<2t3sqgZ`t_CVA`)G8=HUchVAK%XnGU3NA}``jNhcJCVFF%+Z#@F z={*7QYB9MX?MK%1+?Hhibyz1sY`Rdu<(nzdRc$$-_oRm>H}YH+SfE{s;6=XPHgd@;X`9XB#%aQ})ABkGM46SyJ0mI4Dpww*+Nx1f>? zHoZ~NMCQ3At%~RTG@~O0MArOP9;S{JOdr@gq_VcJ7B4|LiysWl@BWys#)GRLp#m6f zh8GWqwYGU25jb`<{LrqJ3`gm~HF(c7dslLN_?xydnVvC{F&W`A6#jXio*GFFBRhT< zpI5sZ-)g3pm&2n{t%Q}gDPco`Zsll?>d{Eq2(c3jWFHBLWjrk*PT#8D+U&RX;Bq%S zU8LH$Z<&^YUeGWCaEEQhCc<&hDm(0|xCW_#dPu>N7-VL-h`(}(EEy=_B$wA&GfSbF zm|W<=5(Lb#wBpnd*UODbsfk`kdPH=5E61IpGc@vrbCFgQRaX3XhIr_aP3uW3B55<) zN!oZ!q+&H7&`>Zl{qTKNL`LJzT06%5ke>ozjNfErNufyJ(D}hSQW2xlzL86nLS7?l{ zn}+9@sg;+_NlJas<8EZP+=bwk%laN@taG0C{=;!dwo2# zSkbJfxsgv>&NcTvgo03u`6!tXaU{?rp9JzrsH92IZc;(JlU3oLD~n#0Lmb*`txO^HT=1+)~m3olqf-{4BB0 zr5!0|J|uyYeIL`@?G1|9W{{XW*M?C7YqkYS^-*g_3F*P!aYzS8WVL*{Pm!j7=qbpa~vqO<6q}|gw(mI>KXF=viBQvpLrML=c$?$@rnA{oiWMo z$fjT2o`ANGR!fhPg0>{z|CEzFeDj6U?l8L3LkeQ#0QR^kgFMZ9?htT+n|gpE(~fLs zGxPSuKk62w*<1N$0I8We50gPdiMk3deJsKwnE~_=J9K?uCWSwAa7<=|FHKeOycf4U zeg0S#9R=Y$ay_O#GSa+cSG(2%;T4F;`3`IC&Jx`O5J*{h$(S5OLL*BF;1!~oYSJEQ zMyy2Bb$eB1UxW5hXjX$R(o+v!8qx+ddo87mb1RbpRt6S4bri1UjtK_pJpn?sbdhnw zwR4WOao#nB-1HFuAe5UXGegkvZ-_Y@qxNB-Ms29VSw~Cdbv{RTlm+8?Yg+De7aAav zVP?P4VA7=rM^H{kPOeiAV?!9Ta(K<=s1Oz0R7CxQ)hjGx@r$ILM+QmY8mJbFEuaR# zWB4M?(1fd&K$z|tDk>th{qPZ}+%MVrk8VzY}5ccQ3-SXKZIo*QK9@p8_u=z6Hm`wX;) zWjo3Xll8>NeW#-@sa%lTie?nK3S!1P4u$3fG9X?i4X*&?C6{h;Id@#&IN9C^=C2{Y z`+xH6JqEMcPhB1U@)7R&=?-TIamyJs=y2=Y($FV2cI0;+?Sf{X}-R0i}ZAIrYWQGL_NuleMX z%j7tEJqLt^L7@3;^v{}i$HhYO@hz%GRg3v@;hB#53jR6^{G1pLYB&==5`_i2!XatK z%#LQkywH6TMU!QvqIs89UL$!uI$?hY!AX!EY{pp2aB0%zPyPA&y5Z9M=AfDGX=ne& zW3h%+Fu#ydOjL_!#0+qEzI00Y6N>~9Hwz@E?-StZwCIk_ITG(G^+y54vrB01a>cQN zx<9;zOFTF27;b!(5L>)B% zacMrdU$q>4FTta>eW^vz&)>#tw%aoDJTc4JHo%n2GS;b+*?KNvCIjHYDNm}83>iHU z6%h-P#|#(${eRv&j7`W$pjWgZd|NtuqN=9q>14E9nJ(^i@9-QnG?$MLDUy zY8JjW61YNFvpIpqXH!w?HdY_K43RojaNWb02R35i=NbvOUe2GG0S}|(D89|Ol4L&}aKcWLXoqOhHS|C*8ipm}~Itib*c5^C`Toa8rn^Uk%-HOsGVZzVafj%eud~Y{b+i6JAYtn5r^WNZK&itf(2^x~F zP;duw_DH}L0&SQhL1C-*RJpZZ5>L@CNmvlIB%QS}{z$7Fb#cEsho$b*=(-gYeNuYh z7!VZb5gagvA_!0Y!NzEg_>C`&AtW&@Bbj@ZUCi)`$5(di=K{5^ZLsLp`|=x-Kb$dE z;oT)Tb%>yNfW?0h<6GqbVY575Kq?r9`}cym$%ocb!QwTK5){6TA)stfAeZdmV|vi; zmlm3y|5}uD*52!`uR9(nKtLq_DayZRB>z>M|6@|}pV~C0PD%|3paeboUm_UWkU##Z zYo49Y+ETp(7UHrBn1oMLxI4#17!1!$GQkwOOmSe&q<6f%`jZvzkg3Fdmy{rS9KOsx zP<;-cC{spFN{z9h?wB9tn#B;i`>N3gU?g>{$JoV+8P05Z zD#G~at!)zcMuCz(&sJnz! zWC7tZ1rtfD~J7KHtIXr3max>SJ(%pxne zW~CX|ikQCTilV?1x{E0KtFC|F4b5zl#5#?Z-c*uZ#nj{}X^0^cIlnMZ-^!h_uon z&`kIYL?~~FcxOd5|4R(UmesjY#!O6V-es$H*YCwh_;9p!WsLNpI*hkfx3BM+f zpzMfoj{{2OO4K)P!}ma*>9kFnu0_&iY4JzcWPHu1CJlU?m`Y9r0$7VH@x5Db3 z1cC0BCX2PzPs_>G<^!XI2=^D8uiyFqU7fa()hwmI#)yNz0&D;OhK1SwZo?u~wQW`z zP`q*)KM}0pt=W@E5QLNvi=zcX=JTVctvwtA2p5sK?PZp%SA8~{5~{w}HuEIvZhHJ~ z%Q?Op@QTxP5m8QT_|}FCsUBG5DY`-?q}j#?6??CD_p)$>^fNw`(IlQhU43h~{F{+d za!Ipx5hkVW0;MUH>(Ekt!p+y_9fMKn123w_pH323+a)a&HC0?X zHaL-qIV<2spq-~?0?uTDmT^;cv&OmdLCP=%N(s?HT)_gp`0aS*$rjcK;(75!9P~Xd zp-qYGTl~>1X{^ox-Uxvk)!2c8^mn|Q zfv+M*WC`>Pom*`Q#E)w~>6n%W`0433)_{;;DEvsRDDg`^Cs?InRNu9t zOL=08>$H^GAX3R#_Z6m-|{n3T{qVo2)3~FNxNWhIYNGh8kmoPbT1W2cN{4dLO7;j&MwsX z!s+}wqX=~y-**wR>FRs4k$cS?;CfwNZQ8YE(X@nD64b`T5Rv6vXO_kc1r0`RK?!U> zz!^WI*ZKkHOzxCfcvCTX>2E0dP!#xD6&ED-!*ZTivs8x#=aAnCGFFEh(P_7V+r=%D zV3W^>w6Z-T2qy&z2s3`;dwG z{8t4kHsUn@`ch!||4<DgR1fD(&fFNhSxm6KD*<#PYq-3+1+q9V+zs-DV8QD+;%y9}j}~sz+5*jq%-a-e{9Ysd>L?=!BmiOYT>eNITR_atS%# zEML^-8*_UJg2sB*+Ud;#Rv+ zYO;>5km9a~#<^PqQfaTOx{9t2yjqhPAyKj=j3BiDtb7f@h}LKov(h5;c_W=22q6`9 zX4+vaB+;aA%45A#fTh!m`}-3ciAhC zKU2L(EwY=Og_j;d0Zi|`Eud4^?Y237mP{Ye1JcPnB?=iq5_a9}5Y{QV*RK_Z$4jQm zPCNw}I9Phxo$7MqZ1No=w33gmP^`~TKP|n0%=+zBhw3@?eWB%PKa5hT05j38>~`WKhO9 zuRuWJQebBMIR#qvB6z1xByr7lNbQO4pxRt?fjDa2HLMj`iy^S$r|sF@39d~wx9+ezv@Bw*By{*no+mVQ5HB7ZU9elFE1%ynalDu$uyl}U3V2O!aHnP?L zC}?SEB}%ndQG7hVw)@!wb_!wQOi$0aF+q$9Kb?@FrZ{0nW~Hx)RVTS;DaWL>EwU#* zaT@G6T1u6x%Mf|-7hcFoJ1Xxe~qrgGt4NZ<)k{5+N`9 zcom%>Q>bUuju2D}!?dh)d^Mpg@OhD!K%%0L82$6SJNKI;iVYX>f_-#EpZ|4($kP%T&-bND z+y9|Tj{jSg)@ux~Uih^>47HF=Ygp8E4rYiZY7Uxyq(?iBDdG!x272{Iqf$%O%RMpO zmT|~6R(MDmMDXyGc$5P!k9D;d0!CV7cxEjWbp%j*!Q`4TXO6CH1dAOr0Q3QH0843| z3=0WY0|U(%50Y7y&ayL_2tvbGM3BIkOmI8u=yI~&C}`~^hyNPx>cukSSJ9j%I6mXo=VQn*A^t)}Y#7cjuvzyhUt#}Q+dq#18>GC@S z=l65?7dorQ&>&GdwBlFDtu+b$&CdeZ59yR0iA1Q%G;wI68nX(EV(Nj6)6$TX!SB19 zwn#j&%t{P2O(^~sXlhmV6@@k{9ptEYwWpAG5+f*yPUU3ym=Ug15YV%S2ywCe` z?z}Fu_&JIvTu-9ME4n92o+mSXt_RZ>Mu(5b7B9t-%n!C$!3amfu7~S}AyQJ)$En~- z47tV>ts{Pm_e3Y^WC-F_trA7}GL0WR?W&i93!aLhI#6pl zoyS8yB}XuxM_qcGxW$J)n#H_0K;7?C1bnbQh+yD_&BQjT-L$YW3 z*5O0xrZ7$TF2f_w)Kyi^H4n$=NbNdHb-T*FUHBB)CuB%$^|)~7TAJHMw<9N;S0n+Z_L z#Ms%zw9Y4L*t;PWz2YQ-JlTTWNL#VM&YCY>he}16bZ9lhC>}CvX!kh3+YB7R|5p^6 z<}ywH72VJOAv(_gh>ion>zD4Qpa6bqW0>ezygp=d#Bd6WfPo>c$r>Ni%_vba5_q^= zg7)1ecVc3cVTa_~7QpskB5gY}P8=VfNpB;7s%=7e=k7~)G5hI<8L^g5_FM#uBiA`T zk=5#Dg0hCygiA$1dTyBU%BMT)%>a&|$fT~w5vgRRnJzWsW*H>B0Iw;;b?36(Rm@$^ zGJ~lFokki0@pX~%$m4qQg<`+dan}sJFWvc72{1%C0us@Uf}C~GXo6!=prsTZ1%?YK zjKC8oOPpBY!sIK#0b6V&n}Xk-1Jr)*8)}-Tu^N{+b9hE~5iXw8_0piS)OBCs5WQ1O z`-?l!4c^wE@*Exf#2=Gk$ZPsG1~=7%czPK-t@CMl!b3os;Q&yktG(LpRbnq*zXTk|Phj-kyG;EcdM0w_=*^~`=>8`i*%HRTyGbsN) zHZW@)+aIl~{NuUmHpy8w`nKj%bckmJ7L_V_7e4Yfl8O{*8w(e6q#tbSDIKM z81v|McTCd-+WZV7Xs9*lE`67{WKoBOEHGmYn^ZBV0-#B-=7x*`>7hj&RyM#&mhXLc zLfX~OtYjtTcmBnn)pKIB9h7jZT2#w>PUS9=NHvt!_?=%sT)98Hd6=_zZ|v;ku=n~L zEc$@r<+Dy;`*t3VI7^N@z zl95i=EF=K_f>mNRbR49dLclzIg1EFNw~IF0=-mScV|H*9%PTe6zJco(6luQ*YtbPH z^SqQi@+ng{e@NgEP!UTbs0Hv)8%s}~Yo7weE@+}Xk;+koT_8vK+J8En+K8CZzoY|z z6UXn6&~0L*#miVzek#7T6XqELV$I88^C(uWtB2?*96( zqT@o~NB=82%P-MkeSPC!N#*};h5YN2k>Nk86GQN#pY|b$4QWbH(+W$Jz|QwqLmv?! zY0Y0RjIl7Mpljbl0wfu<9QC*)8&WIjTb>H0tfVoU(3zB7my{^0#pFWMHTd3nB&x-V z+5;N21s=G%ufp!lZcgcUNvT;%%O+S1+iMwUs6paQvwp2OBa+6}=cn9Aj0p|5qmRue z+f5MH;&b}1fv(~&Q|@Ax>DSClHck)-F1HoXDR#qs0=|snP_!`c~>mSFY)|(>KakX!dZOa|~7^Slnh3 zdqYW8*6;)<@WV82&G^IEJvI4}Yk%6u4xv0gUF}VXn0EH!nU_#Q2M(?QqM%7KsQ* z;~pE?EsHDqJ5EhQehxftkZ~(32FsOvX%E!gPu~O6bdD}R%LsyT4W>&EJ}=pg_fr+5Vbn#Ypjt7> zm@{K#ayv?2GrB*+<;Y@kG4k+KHCBkD0|W}8JXTvUz0+=13dtz}bo z0TMhtIYmV-Z3{k}y$;Yt39p$?yWqW=hVWQZ|L{_<2%si)Y%wz^Y4a^%P~utA{wq7o zH782f8eH@Cfq3We{V{p-_CGMdq+e%aj7dw-l{S231S?EB`C_nI;*0M~tkfhM#I+w7 z;`q7FF)LD-n#$3r7u@ko;1e?*CF9-Q8H}r{xOd!Q*f+ahApyKrfFuhZjmgIR$F?09zQxa{!Z0 z584<%78lbIGSe z;L(!4(1KD#c;B$T=cAw(TKY6aDEev@%G!xpgWLr$4C8wwyG1reFli;lo17Cj*g;Px zMu0~(nSy(&d^P)L52nBkD}E51#~+ZyPr=e$nF?WQZcdIRSYBEZpbF_*VdYw+`-rbv z`9@}Yt-Ih%vAoD_p1po~!05FYm)4D$AQ{abgQdsUWTO|a%?pp{lKw2@cA0%{9D27m zEMY68T&_dE8HWWh+4YFTiq_x(mQ3f3BZrI&Xd~OIWw_toZ%K_e|k28FX zoD7cr%wb6({Wd6@M-^uV4o(iM1|VqYd9Z_1r(Cy|Q0rtVFJ!t=reE`<-cnkd^}5A* zqtDMz=AO>CPHd|gSy>nA(H^F&!+BQcmo6AUgRIF6r@3!yQghH8$10=kFHlpWkj7cjRm<909~ zw#0UeJGoBI*<{>`60{#E_G7ruIjv(%wG-sX;ze#CBs*rQQPe;~Le+V3O<{42P zwiy^voaUD~Mky)2hv-}7InIB|p*YR4YdPo67caGPXlij8%-Fgi4|%~$!F87To-DB9 z42pW3)Ph0pYuMnO-cPGyS^a8pf3)epqW`Y~Wa)Q8(trd4GDiO&*kk%Dz)m$yn>98R zZ~WTN+@@Z`mT2p4m#<*SltF>B;^c&7dTNxk=AhAhvN5w+y-%-@Lc=&FTzIckKQ;n4 zy3Mw$OyMja@0FKv=5T#@NZf^aSQSCPh!maLi_#85r$wctDfFHXdp_qKFi~C{5()`@ z@MZtj0_%8^x5Cr94na-w#pZ16ZHyYE$stYL8rAHGI}`Z8(_}r3m&I$4q-*c+@2z&B zAh8|&GmDb?aN?)RBKRF0w58yLV!|=8mn1;!e_ZusioPb)M?`U1BNZa^O$v1~*RaV& z>|TCi-gBF4tC0Oh+i+4|bIFct?u&Z_ov`y%!5r$+&fKz+(q)?ck+?;#lGYWRn^yiK z37cNP`Q~Kc`;*ntvv+rTUW#E)JI5vA=1(%*`$d?8a{En1xGM9-Rk#AZrnO|Vg;Uws zX+`N2Q#cZQ$Ub|WMOqbfHFQd9jFu8@gjG?$hdxcRj6{yPY3qf`b~7fO*HcGTDnwcn z8G~o}Q(|@cWq06HrkZyww^P}Ek#gu(C!T{Cn_7=?mhj_%yao7Yr4FXHL5|`Yi9c|Q zeB%N@DlUszYCLDqHb^z5M;>}7&pXb=S-1BnLx12|h5<5|F2iq0{uCF7h&yuMiVgY@ z#`eypY%yPAyr&-5$$vl5w*-t?GUV_^l93XsBCp?fIoXE&qG%e!_T0Zjkkofq+Ly<} z`8;M5qDB#v)IAjX@Y`q@)vQrWlp@u8VZ;AjTu@Qb*T_P^a42k>4g?YTiP^j&ee(lq z=&3%oILw_V&-ZOlTQ7{-6>-@R-Ty0+f5W&w~GXpmDTaE3d;ig6>I#FvvQTxbb^33-TZA;5jl(&}W7Y zyhzBOE*oY&EM4t1n5Ydi)oNk|G<#riw$F*T{B)-kDsh|L7Y~r6a_ajB*6a9iA*AJn zchNZawJ`-Q`%-oQ_n*PP5bvuJ1bzl&JIaT1y4;^l-gM|HRc%;yOyl+yTD%q;E}Emx zSt{o$zz9L%)6Z`O*-x9qAq(7sG(n=w!;AmsR1>Gny+*8m&q70)788x`sZ?c@A_1=z zh$~9n%1|Ck5#M~Z2zhFZk6WqUEy&v?2{WqYh{0OE2o-}98_0uHiT5X1q?|`pRz{o>A@HvK9f34l#e` z_OwIUga`eHF+W#&$I8b;x2g?Wx+jhYhiB05_-ORkBqe(Q^n|a9Q6^lv6udZL^pQX* zr4)KF)i?(AF-_~dYadOU@TN4OHb+ zvwlL@!jV!_{WZf`u>##Nj7qUCovOKVM-zA{pA4}%tY*jn<^hHypJ8) z?jf1aceY|vC_{l^OzojS=ZMx&hbyy@V=>RJ$~VLm@Rnu$F~>E#s5U72H`zzksm?xx z-W+YCw#cLpip@J#St8Nk86D>S1lhA2jg+j5@WchvE}FKooJi9R?OjkaC=x}RWj~+! z+!SUP6Y}8RdIr{G?2mneU-fv@C*S95S1@)Xt5(Y zO7j>h;7mikp%$>loJ`B!^@xcZ8A(3%qkf@|Rx(5hAU7s`C;u+i_=a0t00&RdT#*L1 z4N0%kO5MVYC&d1csT-qcs$O{dd^F@tOfU05vN7u5snZ{YTq*8VjtFkz@&M(dP1q?a zc?Vtd>|a8bs(dUQK$bf1y3*a%w^{Vs*9}PUL^nuVD26IN&%@_jDYcb=K^IBuOTgqW zz%&je-IrDMS5k`yq`#6U$yEXhr7MI~d7!!(J28hU)bgfqv_0=lRER6GF-3^-JsHEtuDSJC{se3XoT<&;FpJH7k zNyO+Z=r467s1CE>q()q~#WLONI+-1Mt7>-fUz# zyAfR)0B7R(A~MMTA~N&8iM%6*;$1WUxn+(o!xmNih>SAPm00yMEz~xgYV$nw9ya;)Ybov~a+YS$PMnohSVaM6%MF8``-JRQ zX0yuv>2pm_X4D&vxEcHiXZWoQa5KkgX$6mb_mMkV<@D-QqZ39U$3TP@%$3GSgeV5V zJ15xo-&Z2t4+CmOoxf&ztuu2m_ULTeA8us^j_VO-M*585%mqVd=6|3(bM{WE>cuOX z{i+{?R}hy~O3b^%EITy07?)R2eWO}>k2bFuU;b6l5q%=|!93f0#B)ci()QaugJ$G( zXWr29GTyI5dB{UrfLx`Jid`>q{f*Y2eXC9nLv$e_MCbN=?pYmPG>++_v_+3cCFwQV z+|<`^4inAP_vwF`Zx4y`-*M4*ql8MpwTkKlv>>+(5ZRg1>yItN}r}3 zE6tjtM&i;t-?cew{#_z4$IAv6*%b2wPrxBD-UKRiN=0UvGOF#7=^*~*mM^m`bc+6q z%-MmZp=VH9k(NHrT#NLds1(F}0+~r`OxhClmUP;Z8M=uR_l>%t47>h}QEEIfJtYzS zN2jph08T;mCvvQ9&L7rSG!s5S4dA;+VIo+4Bn9Lb^nWhFqd=KmgX@p@#k#(x>@awv zj=v&Gm$7BKLQd^uLpLy73T!cdZT*z8x;dgRfFqKWl|OkK3&7{yC^q#|GW~w0B_Ut? zTY6w0sVGPpsTqGRkG-wC6Gz4z<-qZq9CEL39RI*U*8zW$Ze$ItP+V&WGVCaSC2sPl zKf0f+DnVwp_KlAs18MRGk?$iUz!*lPUm11EOq&_I_*_l4!&>-U;NJFG6l(>c#1wPN z%#a^5_%asO_sRWdz|7W7HTUrnSqeJq?w}CHBcwS%(I#uFV4<+S= z5f)9MLtK!S)An~CmjtkISgcirjDmnT6z4~?nju9>VFZ4qo|ns0>6mwp-G>3WN6Z#e_vQ3{W?%16(aVIoh@M^KcEeHp1| zG_Q&U=I?vGz1q9azBt5wW4fz;v0Mp+AN!K5(F zMx#^Sy6pb7xHVBWMSrpxix$>BY09Jhug2ynQ~&HYUh-41+^TBph(`K_)vV?0PCi1 z-+0UaLveu{kZ80l*d>5H~QB`z0`AMGNpQ8#yRbZgw%SO&BG4{%@CPs7U%RPVU% zn3f;edmR{nddrd2-<94cDHZ*Ev?!rFeMM;e#PH06@egDcg5Wfgb*dkfg~+E;$FtQ6 zZ1Vm#U@aVVDDp=`!swU#MoSbOCQxyqM>?(CM2(o*(G_^$Y`3K+T6{K|?kg3ArIjv< zNs}kq%8TNqSV+pv2FuN6&6#YEDgj(ajWRqxGN8S>9Ft&`hnNd^AbAY|wLr1WW*nCW zh_9s58RyfxxPy9mJdkxPq-qa*II*R5)U-dxgQ#7rEbEMZ<$gD}lw^r#I8*<%!qD`L z*N>8;I_HfKg5HC<&l_4yD@+W4`7SFQE|!cmLCAwO?tu_RENF1mG>{j&NBSfZoUflg zW3`>@o{%HDwz|(PMQTnpHU!F8mTK&X&sX`GHd&Gay=er1XW|iTVh)&RQdFnnpk#)2rgU=A!<^e$^^JvjPQNF)x#y3 zBo+ckbCs82mirUo(+8MtD7vhiR2EU?(0jjad!7|xO1X24D{*NU2nZy2h-NiO~H z324?Sw*uwwqtr1jLR%Av^j+Q!LsM##7@t2q@ep`>;iU8#@HrLzN9B zCqJjS2LCvZRq#A*oM}EVfMo)53KmU;(Gu?X=?7ny3Y7=|b58Aj;6)-E{mcz`N=4_D z6?!ov@-KNWT_=8R>VERhQ564ztFoI&SyLG$9cJ_j+1oJ1%?ANfa5C8l8ycv-Cc6#~ z)NGKXH$KrLD%D(FzSOElKpZd-D- zw`0jrgCa#gBg6~aa)CX2EF06WxS)RDrB-66ADs&V-Mf4MQ_cMc;7^&^!Z)AO-=Jwi zhTsk(HT4(pLIWjDp{LVc0;sVXW@=}%?x^oxQk)*v(hPc4qIg4AY>Gv*D_Gsln~y+q zC<^o7?fe&K;*I;Kg14I_hXwd1sv&p#7PMVfYh-HZsKq87S6KnJrt--+qFVT%6zfZ8ngK2O#{TI!l>RMr8Zr##T*k`9!!m`{toN_ z8-K}r=Z5nEHXt(X4tCTAotm`bAIw$31c_JILU1}1kY35Ih_Dt49wLJ8wmaDYPVpcR zyo75@jk&(x4ej5JnxquT%nqb9k4EE z8oknNA&}Pj=D}tyProu;81jmtuCmM|{)POZj?go|kuT(TJq?1VF_QZ)46LO}B#nfJ zc1d*_0a-aBxWy3a?~`(b?#*|I{K#}$(ODFZwYnKPWB9yK%I)uHjiq3OdX?8ILFNII zJwE31z@!0f{`{7*L=kDi@!gZ^mQSLmJtq6WrkVd;%Z4S341WYK`j=k)p2hr!WZ9Dn zxU-HXCVE8E?0{q>ayyVk_-xRA98VA~dP*RgYvUYUG@VYlgr|Eo{IBk=mCZCh6N`8`Y$usmX&m-oomWO`ec-UbDs$iwIF` zHM6|!`}56+#@-AOQL+?BGrqEdQkR;ckN$6#rteG?JB{4hF1jAZXf zat0jr3%3^IXt+KrR?{25onEfhHV3Y@E3ke^`ti3OvZ|ytO!&ME2%W}}uVi5+IH9|p z7fA#Yk9cb&S3>&j;fTcozJ<{I2JT1Pf9$aO4YbWYWOlmlY*#eg*Y(x#@B+doAzS?Q zSo}si(r6}wEVX&kdk2;HE)@;>%MMdBdw(@=5TsW#D#7<_Nrp6D$W!DhsSBk$gl7J+ z!_47DY6Yh~blvyp+6711;D7D#F<$62nxh$w2g>q9LH(BxEB^oB6={MQr-t zWQ)wj=f&-VhZNI^5=%oJAmG96^M)1E{y*?+s4;D|UHBKzuYd7OX-+pbgv?0!<&uB! zReeTzOLB=*n$k@eNKz#i!bpufCJU!|wsmnl?t0c9p-_>#VZ z8BLjk-p4|5W}2ZijmcMw+I{y6(J%i(bg8J>Pi+(RH_4ELIq_U#u9oT1{RW`1&x>=0*XD@;b`Lx{nh_?WF zXoOHsgz_q(TxL^$InKI(YDq9~{fst{eXB+hA$Va9rOSAKZp92gD39r)yhV`ZN78Hc zmo>JWSFt!W1;30AnbCLtYmG;LJE(W8)LIo7HR6s~rqX8o$UeyD$etb35sECt2h3%cWTx4|1ZaC!R!N1m}L%hZItEL*vVt>0~eP}C?+*Xpw8Eb1} zX6kxN4bt90Z{DnSrPl}w%?8Y;(-th)Spv+Qu+HTo@G98Pqi8=c$lnm3qr|^}9k=YI zox80or-1bqW_{&vWqn08;bWx0N!w0TC&nvV<8Jv&76a3C_m6OWD`_{6y z?aGxYi(fs=O6cqrKS4*S>WE4^O}${3E}K!bmBn58zJS3Y_ci{r^wpjp@CjD5fyah; z+s8Qn7-dU8T-+4Ti83f28BnK-%Q;VP;qHv_6(B-b6$eJ(_(8mt_6R3CBpliiX$N1< z%{6isNM`dwv`(bdd3VOvbF&pB-vXtP4@MDN1!MG0F_Wy%JjfTG;MEU|fY)b2Y;J5} zXvkKnU^_L6fD^1ln88QP>LvYMnUJxIXypckS4)E6gHXKIAGPzFITO*=!wTvr`k;dD z3azuNPb{7k0a8&o$w@PWLemXuW6U`%XK^VJHdeG1gRxFRE0 z+^7jI@Y)&C`4U<@uAJH;_98T8bf!>5mV7a_-4VZ#e_dSub}3_%k2RfEytJDydec{R zj0VDZoV@4&pOWEfWn7j~g~}^)kRxv{rAXxE_chT?kw%`IMpnIHO7 zcTl&a3G+@5_7_wo2TBVi?mcN(3#}O5)nZxNgq6UiMR#aHj;;nmdrjs^3d#Cz^QOT} zbW~T}ztubOHD0KGXhSQxVxyx~7~1C<4D`wltJ(ug*nUHP0PBfGzd8+piW$<%SZXkC zT&)V$}vAG)1P-bu)dPH=}_Q7WQX3LnK z-|kc~Al!9@%D^NMhYSB9Q(&X{mA3{7U@uA`c`}OX4C?QMF)RwO0Ap8YVqd}SFv76H z)88(h{c1;}0`S|yT#4W{%V%uO=2LKT#y46DM1nYq)c=iN+p>xq#CW!{c*N@T$1^%W z+shwneN$+#VemM%1xD3eR_o?G@xKOnqoL;k>49(`4%eOuz`qmI2^C znDjjk4pX(kE&daE1a@5I_4ueiDX?onM*PVSfRMO+o)|JM4N6bN2puTYE*Pq#%@4Ix ziE>Qphkk=r-DT>;n#-ME>V4?FRRa^qP9gng3$1InjFAkb*(aBg?2X*xvidsW&P(}g zQtwiqCZZnKV0=GdkXqxYn+7G6DM*^uTkOXddylGg>8f$U8AX*UlYHz?_Z)+qD5+8Q zB(FAlY2|2!khx+{ce*-tqx^YcLI*`I*EbmRCXc7p>`*e(#El%DwUpfZRFsq#J4&JJ z-O-co5zB+Yl6D;{qs`W6GhWLDah2(jrsj=7YS63W{r)e$-m$r|Ms3%Qt&VLw>2z#c z9ox2(j&0kv)v;~cw$bsPeXsTG{Z_r}SwCQYnN?%dF-}}(xzmx-ac)RDGp$OAVK4tD zFM1q8N)o_MWz_fu`fmQQRG-Dq_5#ls?&iA=VT8r+%k?_N<92*orLmi7R44&WQP^;xm|@m;WO{mnI$oB2j(B+X~YX?@TuI4>(>yA>H8VMNZAR zQx=HL%+KKK-nKt@Zx;mr(G`v>M93Wm2Lh@@_%E*TKYf@?)&EyZwtDrQCs*5(rH~!2 zyEPt?Z3rfv`Wa#{XcF)ZlwHQf^y>{DIuzW6p~2hE;573ZaMczgN2j^&LAsthUqWsO zCY~%l&HU7UQ0fL7X*LLLi7&IsZ zXr<;oYsX>Rs*>%g>^un^NTfb3VN}=~X(#go-3Be;Xp(88^4Yh(?nb3 zu147u>Jy9Fvm;Uadsc=p%hJor#o2)KC}M2iBJ@ifMV1Kv^vbA=&sTd;yW&70;sVn| z>z_BDsRbXN1RJ(gD$+$l2H(yMwZy0l7K6Au_9!~zae#m{ccN{OhH6?9pxl9 z<^cOWTf1HRJ-nciI-T&x*);bvfAs@|=t&hqhy!fAm`?(S_F{3+S@LPMmPJj36S z77E}zA%-4sU<)wRM?=DHEaCaFAD6>Dh^mc|ND(vr%SOT@XO>93w>Qf6j=0xQB%%Fy zlodH5=gvtggvjD6DTgDv(!++Xv-UZD>&YZ1VWMIJR9`V`$2C59uKVdz`KBODVEps^ znXZxZfdiBNMm%_T&heSs9vhS9_1}!ypXpAjDa&fWm_(pUkqt%Z_q!5>XBqdqQ6U{; zXvdjot<135&RV^S5ABVC64;tJkw03t~+y(vO)@UX~UefYdye zi?ub76;0s{?*`FpuezoubGA^o`sXIrQhCV3z+JC%q54R-H&}l~t-tvS6KeH>@_dxA ziDELjO+3TkdFDm}s$RjN_74lx-i^1ziZcpw39n2+tnH@A3&yl^-{ez_tKA9-DK^2( z1KLq3r`MLZ1Yu~AyVqkZ1dEjUPz_W#>ErInp=7JlCW1;h)L8nXw@-1eg#QoCcXn&@ zslbhOS152mo*r>mqIi>OY)*znJ_VkpFTV9;FEPwq7d?g_Kj8u3s5g=o8ywD%K(^hzLI6~w)V z8l~t+x=4ad6&^Avl|)aIP$oVI)FDFKUPyY;?Wxfg8Z@Eu!4SM{<2tUmJ7jDDA*ZN52$K|~P*4t8s%FlI z6i9BNu25G7I2v!kI<3^Ms)neo6KI~acV+wn6Ody3d*jT3T>ny;XR~dR;`q?#KfeAU zRW;kF0jaz>z-QP0nuYzRj8&-o|LTy=h{4REC?G{>d3z02N;5ExGzq|8;sNtzSV< z;6u;;1a1wOKf~JfJcEQ4^|_^qJZRNwNUOm7oHO>Jps{S~N$vAz>EkiMS0I^&p^tFj zG$u!p2iYaQsxq<>EqciVPT#}0ZMOK)&K_PFhuHP) z6{-@FphvRmh#h{|&!*|BZKgsBi~yCBJ(0YKH;WJ58e@fHd3EWBA=l652A=h6Bl_gE zm9h?|%+_qk>8A4o8*VyOREbq2be|TortGvw>FNmeJ4@-lBF2Z+4^4E>#Q5k#rK4Xb zDMtlD%y4fm*4U!#Mar*@C6{p-@DG-(VYK~(#P-yWpHIoGBv+Ue2N?MEFUhoyCa9bf z+Sk{T@wf6!odw=oXQjU_vZj8DA7k&03w||<&YyqQ`Z#anKf}B}=6PwdpXTmR9aza6 zYojxHE7Eeb&TUpn+!SgmJf0&#%j!tmscXBal*jNjpE01bBaIFRgT8cjn-+o031mnU z2_O5>`c~f0N)sSagu-0zW}-T(pBXfAm`;ksThL{JQUpyxT`|I*%Uxq;=Ib) zqoT#?wjwa2dfu%#eu1J)^7!tpm;6?lxB`jJk!#Ki-On61_VpK=4Q{GfyvvmQR186_cMR-a2l>0=%`rApOgAT{wPJK7EU6pt?#ZzX)k zz1*Lyd<&1pbb-urv)|;Tg_QBnHP+EqUcbtS3o$aYx>Gg(^EHHisNV{sfTwE<^S?Y{ z{}ihR)Yl#MS&_ZA%ReB=-E+C?sBUCs)n&~|&lHUwey~NhD!tB|?vSlvfie_o_=LOEjOAO)t&|l~8wU zecThIuqmkT8t~V{m@1d`)K*@UotKaCxwIR13}uuquu5pf#&aucNV96+JtPjayu|~# zE%Ud{ZVF2j-_;RBbk33vW9{(98K5W^iH0k~Gm+ljLllD}9XP>eilVh>Rwr~AnGuY0 zhuh0d!fNg9fmf)e>~fCTtA8mM_h$pV{yjR#3VVTUN99&oW?U6pstqP(s&m$!8F4H^6B=<4ube+pZOx zxu(!oI9s3K1YZNkn{y;zVg{SB^^RI-F9vJUVh}AmI?vvu4-9KB=*RISO}+q|KYh0B z^UnKigguRTH%l@-OM~GSN$7}`d$nhabnpxt-*I&jjf0ARdC2bBTG4cgiu65Y$xwiw z-0#~uS+0W03FF5mq7uo-a!)4zNm6HTwiaXtyhj2BjsbH7_LX^DE&LR^wh1BFlg--*DB4|iHCM~YefxgM4Y>L6Uqs6%CFlw)a>k+h)E4g@*yO9_|l zoPIuYZ#zpb2R+W3p~@Bg zo!LrCC7>at9`(AcUu&w$MG~mDeWg@(uja@+Yt;{_(c}rq!5@i$Xw@>*GIv4HOk^)J z?hqHEwcJ1oW1=RO4@xSXGUt1_M^cQn`LTwUmi{PIElw-_vl_om?(2Hm6R&f355gAT zzE?r`w@G0RdBp|Ft`hkqEI41E+Y9F4_6mO(@$l*QEr-GfFu^9u_{H+<=-*+w*J2Sb zPTUAbSv%mI*B?+P>TC9Dhq_qgicJSYky;cCE#!1&=ekteP;l;e#ucZro5QPvDY2Kk zESeFlkts(9t$R^f0pjk!uR%{$Z}W_yjB*L(;rQoELqc=umbV(#zb?V6oS*!x zg0ij7JjF3-UnATZ&*WE?VjCAI>9*pT^Ik<@C_+%~h8UgKzw@B9#_l-}We3jVulW*B ztGAJO0dffgm;NHR#Xj5WV9yclr*=%I`~`VB*;(rZ5a*>cf+v&KMq!}v+MkTl;cU>w z`=j~5+#zJlF>89vDA*(42V+jm0%lZ*>~aEFZs+6ZyjrAc7I!s5c8PJqB_LZJD9RZM zNvPthQ@vRlQup-CA5jG32m&a9tNr9Rz&ffXhI2Siv|QgEK{-qnX>$u-MFhI;D-#Qe zlS)Vwca)p0ddd_z;G(DE;H1U2MbS=N<+m^U_OQBjyb+fl7ZkPUM4}?h(tu#Wu&SW1 zfRR;YDcqLLWXns}3^vIY(`6>P<7f03x}mYi=YhC!gv~wKR&__gN?!aABqs2^WX5#+ z`6HGy2)z9rLBXU}R)9yheIG28J3AG7 zUHa%1&i3cc=~S5g;yCIBZFK!K7aULU6E70xvT-5I{9bPiLN#H>7qPPg2R7F>jbJXMCi4+nyctQ!uaBhGrE8z7Q+= zQUjma(tKjPDy}|?9s+(3=SBxaz1mpQKCC zEl!B%_6+>6UR2p7dS(rOu_pQ*9f8ELliwv4G;{{A9rDT&Qv^-*tEQHbl)U)20#m(_ zDRRX*BCRE)k$kDTj0YjR`e48H)1o-Bg8(-VhE$+ZwsrTVK=*moZ`FAq4LH# zwgFfvHVx6jc`V}t$=wuaMnl##fvyumv9LZM9}H4(*!BWkmpK$MuraP7_`e!RPpi9+ z!Q&}0x6B2;BC=7}RHZ&ZDYDLV-hIKbe&uh!6SS#ToWE;t!Y*mMCUeMsc@F23(LGY| zb8O}pR?{N&Q=!)J++4W>1#NN$89>V%nIU>(41SVOTHUX`IMo*g-{g}>?&=~|Esbf? zcC6caTwVpg%Y|3`XIDcknhEy?0086v4FLWrc>(~yW}h7yQ1bi~n7=11p@=JMUkLqf zw|)mMzM(#z#V!XrXksNZo=-@1YJ~oFtw~Cjk;rh0rB`c1h$l7JZ%}u(K;-zceon5S zW2ZAfdRf{QtOQ;HTOT>EEapX@L(i@Ja(PzbqrD|85_XR-A(fdN1kyj3Ur;^H{I+0& z5%FV7IH)-cgM(`1XBpi{u}pUM9=J{S0MHg|tW6`ELT0(=MTw^^%cvbpiyY~;uyJ0T zr?SAq=$(U+fZz5@MZE^R49@&Ps*q(Wk`gBH8;V z$u_ALn#{jSCt|PFgR9=6O-bh2tVgeSb&}7=X4tf(AV~p~FwKbf%{FjH$?hkcbXN8a`Tqh;gW3j^3xBcihX-Ef(bdvT{>fVj--|S)s)X~b0_AStFZ&5LB zbN&R=A`*VQap-s&YT9EQGOfF^W)XpSy1xh5(EZvCWAGp)au-iPiJ2$!Hb#%O&WMGp zEw0g@d5u|g#jUu0qDQKi{^K_jgrNrI?HId^lRENg_5OT8@|yH-1c<1IwtcOKG=~v= z)A5A`SpYgaW0{fG0n0Jw8^=>l6UKRODtOwSg92=9$BuzcvM3pAJ!D73TTzo_WqgJH zs1?!{u+k{=*DCYh$&eSIPu%x|iAPxl9@ZBN)@`5nu6V?%$zAYLl1241;qz)-KAvY?bf6R_jmtC1;mmYFmg?jykmQAYlv`bW5s-#{Oj=sR@n@$kDgC z1L?Y4%)r@4a`j+iA$$SVn^+2aRG9%7^KPn8`4GI;=q)?%0Ja$RW6Jy#lsTC_<<~Sj z{{#<^nI541L&L^DLlBa(@Cl|J#5VLz`rX6kstuNFtnH<|UXSV(3|ZC!DM zF6ap?%KzxG@>kt5FEYmzP9?Kf7mZQw-zPGk`0>X4L*Wi07;VQ5)tT>j{+i}}80^6o3(ZQ6CUqRf*CfP!>i;+KCx!RydvB=~JH zm+hqg%Z2wwPL#%sS80mr@zd}Y=U5XGwhM|nv8YfAA6&v-l>ee%M3-d8%{_ z#GUjl38w}LOA$2pF`@IjlaUm`)tse!%Z^@)c$~qMK>0>QJlv^xcp;4mfebCVklNOV zzx)9Me;JS~Kcx-GmgP!~>*o0qWU<3seAEnIri8w})zYNnUDk0eDS6(VOHJ%auMOtr z4_2jeCTcH8(%}jx^*3>4`T60~8%Nlze!f*I&R16IT`QomF7@mVo2BvV-8Kh}^t2(9 zRIzc)7E*C@V|zr>=Toq2Y#9lxB+bgV7OjS|G%;lC!T~lSg(B*bYY&C`7J|zfqre0! z(R#ODoz20)YyDihrHmXOzwgjsQX?_=qg%e5G=p6q#lCsf8w(VqMPhf62hy_^fW!m} z1dbBrB9Td%!VJ;?$qWdOmy##2g@t6-JS4F#6n2G;+OG?eKWfWhcNv+)n3I04?qE$k zwCO#N(9)3u{RnzK`2|pG0ijGG>ZvGN8Bvf`4D%}N8Nr(wxoFXCzk!XD(&eV6_&nLU z2nNT~s|mG58bh#Uw(2O0vSMqLS-K}j$!S*asivsIP1ce%n)C^FOq)dRbbuv9VJX8c zeh)dav%vgntP(E#Q922x-lwj%0-ZNm6oZk#a6RD-n^1E{sY#ILC49%1X0THAXFwx3 z)ygidyLUIQE*v^(9n-!!nj6xOdgTwr5C`%22x5ovOrr;7iS+Ctutppgi=2y_!sx?T!b zV?;G2q7sI&B@Vj#_scn}AloY`X*br{i`S_Ju~hw3(xv@ z+-1K4;=nfa;ie8}XOxF3)3mM_TJz3HzzPa#AlxP+92hhmzjb@nVL#+ShvNVmnE309>6FZ_fjDt7WnHfi ze7lg$o?M2euK$_}G|eExe+Ta#X`xq_|7$(m|0p-N1p!w-<}4Dx2knIhATk#_*G@sM z&cw@lZTmSmBXQ2DGYZ({_-1=bLc7PsbdQ&65_a!jGxFF`J2@7VwO8R6CG0QfGDbDV zKx3!XM7Ig@Z5_bZp5GKEI=38wf_MO&aG590bkx-mVekb718O4~o}f)1_!dFw*ZrNP z4e#2+E>8D%_a^8I1G4IWUNI)aVQa<*lw<#1CHvo`IOcz9>5b}|j(aW0-h9e$1l;Y2 z2Yp+W$lze70=ca@M1ij{BkEq%Move zj?f}mEe||NF#GLi3=GCm1xKL|e0Fs1mhrt&?u9kdPHfYJeR%b|N=?ntxn0El-EZbA zS0znl@?D5+=LPdj)}&1pKQ*Nv}FJludlkx=h5YMN1erdzbqYc02wMx)5JNoV8>sZ1@zp zyS52;owXN>zoNZ$`_K9rSM;LmuM{YC@^}7|xqCV=AC8f8cxfXa*3VzJ-#*5Up-T?< zcy>!m`!lQ+xCo_T1cxa-IvB|= zE$L9m5aXjbZ9>4!`IgE%mCgIH%mS8AqtMiJFYFOs+yI$wCZXX*eq}*bJ;{lkh11V@W z#d^}gE1@&1KfVon*+9<~n8eKdzL5#ZD+NTHhuAFkQB6vA_eS{RWNYGsq&57;cC-@> z_)p#UVcu^JRA-G`meLdghFwD~GaHCxhUWgW=pOeAHv!&6RAVvuS_cQMAFvVf(@9Ue z?$O2^+2{5Qhv91kPhwI+Sj<`|91fLvTm62iLQ41LBxq^&C|!FO=m4ETWeUk)DbOjw zEyuLx7E!6o2rh2WgRVlt2HEtYFV+g`*B5~fCl2>CSgk$hp5 z`was5cR3-{ez)g5uw>WOe@!ztct}`Ci_Q3hl_CHq8CAog2aVnWJ-^s8J!J3U&SrWZ zHQz)ED$>`P>KA9@u{U2W)lfLd?;}8IC5Du&kJCHS{mAiR(mxHqu#n|4&mVmerU#r1 zbrg#n13&%#5K9@`;_xHkT2YcH#Jog5AVshgr@YpXBRHB{jG=QLv8{K4fW-_vEsk{A zj6ElwySOORDIE8T9Y(-@pMSJ3>q&-P1|b5762eT=o3PH$-L^eKbcezJ&7KeQ2jQyX zBYpZ`=$K$>yKajXYz&q+A4TM2?!kH4-=!=C%1EMiX5?_dseW+7t=bUj3%$+QBkk0NF|RvKiZR`zrR$t=>@SjGQA`O*X1@nnNvuP2$c-q%m%z`aG$X&@6vWD_UL^CGdO`c(!v4mc$8oor zKOkYGsgv!$y$yNKWWC1T!t*dDb9}nYqW6r^fYQbH&V+)LioPSNs!va}J3F7QNW3h{$oYjB4aH87OTL9MN$OD_;K4`U)2u>AbLYaNLJW~Rd?9T*%!DQ|tLHm>!z|o8`1XXYZFb=Ui zG`UllweT+F{pYlma);FAQ6vd4u*9!2o^7bm^qYs#t2NsPS4eff&5#HD_(L{bN^OiH zXBj3GAZH8m=^h|=siv&?MlHhiwiZ|TgR3MpODcr<&LDD)-!ecQX0XB+* z0DT=&0|7VBw3FN`)O^~wTQ0C5JtZfmis58R;i@z)ZO4<>-xUko?thhTT>N2D82m?C z7FiRLXl_QoH;4LZ5gT-rzY_g|kGvD?)v$NATlxc<0gN0z>}3J#Kugq>F45Q_*R3F% zb1K}Hcoy{q5#5`is*kmto2aBD9hu^_u0i5_v+UT0sF3q#W&f%=^es{!eW#e876egV zBx>J^LSm)hOia7QA)gaN5@3<@WLO<~Y(oVhG-=o`Hq=qWZ2PUpn1Py>9j1{6xGP=Y;k?Mf2V(IKrASA`1#0sS85kbL*+SL(IoNK0)<{ZIH$ zzL`CO^1?Bne(?8M{!xuTN}ok=Jq7AI7p09@0c?^b(POW&JGgjh!RoUL>#?p9RFVll zcKt*6`D?6B*fEyfTemrBSL45;>_7PaqroRchAP4UpbB{aQv9z}@z2?f1$Ax5wGm{m zZslh_%67!QFgnp~#WA-C-=6CFFoqE(@3nY+xHTwvveD>H&A08}$3l!GJ+kGjh$)ck z;yk7vCa;-S_&J|X9b=6YT8UJnTy5rr+Wjw)6Z4+4vji0(3H;06TyNJtvNiGbeIhXj zXj2u60s8K%vnk3=pDQ*g4P-iGMRk&<;8deR#uFpuGWhs&ST=k`KwHhR=1r;+>F1so z!v>}->if8M1mbm)<#U9Cg8UDo7xv%)_2F&}d@3GhgD&N??XUmf%-oOXrM-iUA*aU2 zl|`HIgMQHVGJktkTN{Ur#&dplzwq4xFjl9X*g0HJOmn+&fDQ?#=jue~t=`Yw@6TQB ze91g{Tj(*m6INvzz%t&vZSbyT-IbN~WS4AS5bd3H^i%t7ZZ>Y0v)CHaCKTjAvzp+{ zdhkLvb+s!%digiq0edpEj+Dvo(+&-0F7}q5JI`%6>1ijepUs@Zrv~cK?Ay?>)|}Y^ z{ylYcx~v_f4FR96=#{kv4OrU&_wD;nTo`%b*7WU29htgm?@_@f5Im?=;OB^#YMxR;gvn(rf$(T6`Qn@Jye+ zb)p2~;&>A}Aqyk;cXOjYK(IRSsrwLgiV^%_KV{4hf#j}8ziD>RQM|(+=d6N}O&7NX54!wZ;cuJjD$)wDjGiB4cI)m9(oT_a6i-Q>(BpsO?5~tVU&FszlHW^T(xXlc=f^R?Ln@T zohqzz#;YQtmI|#h%N)Ekqo|D_S`APUl58jhwv+cICyy`+G1$f7t?`1uZR^Jk5n(g* ze-`b92(P0Uu_qg^MPqpIqf84iBRKB{(w)cx%b!N}_0(-dap_RH*XuuK-+D6i1Pqys z;9IR$0a=~GtAh*k)3$FbR~mWSRzYlzOEem)qI~{nUqMDvprG_H#?zY@f2db;+0kc=1;6U!pA3<=bHNSCEU9AUzn31y~z2b@SqFCn_zpFAeJkkjIg2Gy* zK4*~IO`I6`J=R!F)DvG@BvWpGw*;M&wex00FdI9p7L@jzG$GlQ4R^%6P*^_xSTL2k z6PFdA)w`C2vM?Q2v}qdUjr6xHg^j4;*<6wHQGcT%fy4LoL@K(A#GeOt?bKjJ(U9P9 zh-<35aLVYw^5|x&AN&RZmz`&_n)WPFwhXVg?y&K6&eta^UfY`FL4ZH{K|#?nR#NQa zh6J?Z{=~oyf7y4qiAIJ|xs^`$1q@fFGGAR0n3RA{+&VS+wM=XoOjU{llfI%Eb(5AX zX4G&{N(UXIm_m#uldLK7Tg zLP|iZ4#z01DoJEp_iz<9yQwWhm7Ot4y0+IBW_?%m3_f-T;j#XnD*6{Sh}A<=9!f=p zarjd{Q^^+Wu?3hy$=&;ycIngOBP^hZD1>K3z>DV&pqtig0(uG~N|~wxQdyOFdFx}( zuYfn{vePVnxVBHOkm_OrFr(?s-*f?Ec5Yt7VEtmnKErRmXVxbmiFoUAziQ>!wFP~ZU&76o|9kt?BZJZBtl>IG=wF>Dv?HR|J zfQEU1JC17CrE`+;7w&Glt6sp9#1o=zY#j;CTr^eoC*S4DR^~>43SpW66OBQ2TAJ%x zuMg26o8r^7v8xLL2O?UqHn-wAN)ZOM-~M zH#gT)iaVrV41Qd@ic7Lm4a>Uv4LbX=BnOA|?`D1%I=cIvB9qU(-w`UYrr-=;1|v)I zkIAu_EQgU@{_gTP-%W4Zmp|YhQ%EK|F6gIkKC7^7oaSZmJHjlAO+U|ikCFo1ow_O1 zYVF{ZD%$Ri1LCIH mjdSB_#kna$(KqB~Oj~DR^IW26|K?O{{T>j-hDThYK%s{dh z&C2~sJ+qu}T7Z1)pNI5h(r|#yz>S8@}l~+;UFT+&^bF7;D^*G#Ay2x(^l#&E8 zN#AT8-xaUAw6&k?;wclNJ#b23m0QnC#T#(PZ#}mKqIchdFUze*FY=g$x=gW}ueh?K zq_-PoX8*_J@SF!H-K_PRW~H6A`IpJz`hQK1u;{iE%-WIYv7`4;mN&Z%`a0=XftMbf(HlPvAMu9I+B;zbX;A7p{3tcZ=>925sUzJ1Bg+^%hf z-ES)1c*Pa=IXuIsgUeWsj+xaWIOOs_>*?HsjtQg9fTQ57fl_5|`XVY=-~&>PCA5-v z4VCxZ#IYSGbtUso*1FCKVL9mUVlPj$5=?qKxN;x@(5-VE;!&}ahBXxj8e{(29c~Cr zI_>Cp(wk3S%fS;L-?%UH!YHY;!NX|0mB1|qFEardh<3BdfWdcw-4UZ9Z(o}6FS}!+ z2@Cavip+hp|ky~je{a!jGNAm>tbF|0l!CFmF4iV2i z!I1l9dHlM;`A3tm!dRw0KD{AQAYswN4nAR=zLUReRB<8PINp+%R`u$_1PL^J^CRHK zF0%4zyH2X`b3uPnq+R@^1iIM8qPEsMFKi<~*LcBTm*TGtI5M}V3(1NO+6=s!9uou3L5t=Xxq3`v4lV> zd~+Mf2&DomKW(VT0=u0^#Dt3YqelVS14Zx`k^s71f5%ReEw`ChTC>UhY2`1JMw5ao zYyPG@m7s=uM1rX)vD8rba8D=V7l@TY=)f{iVI}rUg~CeKjvM`(I%x8m^_XDufM_gZ+}C5cf02Q`Wu4l z+iHV>@*d1cVUmr1ifscO1zjWw2MMxEh;WMq__3!~d#eyD%5>&BGLXQ*EE{A5u_4BS z-NibIrrl&)BHEBn!V&h0VO9}`&$Mm9J6Cus(WtdWqbzXq@f+Ryl1Cf(Z+EPVY#1M{ zgEQh^&X~u_kw9h1-?xrx)}XR*0Pc{Vm#%v-rw= z#H12H^cY@dEK^Q!nR((5t}WD8g3Vg*<@upiXi*QBEGe` zAI@Ojyq)$lbuc7HO%<&`XyjGa{bLU0P)?=bzyB5TN_=?Fr>d*Bne-rMf0tqj;}}0| z9plgzEN(z1|BM>$E+4kVuOB0urv^!>7}?5joxj58Pds3}O_xRMo~yQA7|4goB1ypD zXGfyD-1hW51 zfty%Db@4|bH9Pbuwd9hvvnscCOZnaSVz+lo2lO3?saHHIJCy@?FqymRCaTD5+2&L~ z{1!xOb5vjC!9m%KV7+xhNeSh^cPm6Kg1PQp`u<577iv3g0*3dTaRu?9nB% z0pGxOI%!zK5pzKM8^(@pTiASRhWF4MX|Fo{-xde`aR%X_`^(QXxHbSIL@c9Liejx6 z0T_V{U}FsZWdwcH;SgKccg2ft03+Dr(f}GGIAl@)Mkog`LjT!Hv8fA^|Mp_D(WATu z(R33a2#LEas%M#zzvYmP{# zW~gfH=q;SSiR-#%${EY0K(H#c#B`J$=G)IMInKXGkkSwuW6B=mJIp2gg;BUsNmmLO=h%`Pcg}8(`_GQY5&3Nv73n2|6vHds6 zb6hO)K_(eZHm8WOu;-n|5YAk2spKnh0%c&)Zf(YmjIH{no0N#RQ9ULb0o~kx@{n&C zg!4x;lIJ5J#=T?C|FFPHPUKJo%nfex2zPnFXrnRVGAdtw0h*vTOOGRh;v%@P?5kah zPPmZ%l8a&?JrQDQFit#NO#+%!aE=)diF{)%PHhKH4$7I;Lu=5~?si%uD3%T)+Iio~9-LU>|SRa)gSSJuT`>F*BVgsvsWZFSIPk0 z;`0V3jD`=cpmjA8PkWjYR^^*rSk6q-{bmCH$x(+T3yFyQMcq|_!B1+m6&Yywx$6vh zROYmvc5kGR=lvu6DEmx$aqJ)fJtTf{J~!DleB4s7r}F1Rx2{l}(#V^Ztv~;Z9?nt= zA0(3FBTqGC6g=!E^a31;xJN5lU^pS6p;3in2+7#|iqqq+AN)oX{O9&A&!Fa^d9#lg zdd;9a#*=@6MHJ5})T5Hz5(43pjs263r~|_}0<%p^&_5rq{GmH>)QQvmgW%c5YfKN# zH7m>KkDUu|ve?x4|S^;jF(310HmYiXuh zwC|k14CzRun_EV7cA*qB2NP%Zj0hEpW~;Msp^p~2iTkPY&0g;(DygOG3^xgU0Z*)O|r{$tmF>Uxzs7t<30ZF=*Wc! zV?Dl!GU)KC(`R=Xc8Dv}%nrzu9A9wyz3U=JtA~J=9LbX-h{6v#TDb)A^`~%!IU$DuuJyH|qZZk(SdkP1RaN0og4d^csm~lm?yuhw=;Vix zG4_1Huo!t$T^p}It659v!i3F}!yL+p8jPl@Dk@wj$`)R6PH6At#=oDP+ds;q2u|Lg zneX0S&HQv#t$Z3x{*=vdQ|+=BsNmXa^}|(ffTk;UDFj+_tLVQ8K$VxzDg+z;@DiY50 ze5j53R+9^5&v8=3mVv*4ez^zo`6_Se-2vVA=)DM!hr1A5wv&wl zj1tC|Ru74wRnC7_FzC8+9e49uBOiVQ>!lDdy>qYuA4cHxRyazi;Y!VaLz+Cp z4Ldu_xjKz6iIhp<)+~uY9}^-PSpmkr5Y?-l&d|bi=H;-Qlw9`2N2X4C(uxCAtXBJs+4@R@c(KK+@C1A35VYbw_WTXvRZdFQwJxGFW67lbg#d1 zZH!^FLpMmEM@?85Zz;9+D9CqLnxXxGT-(yXtG+b6hU;E!uHlHr0|}tA-2H-f7;2qt z^@!ghZo3m=PEfWf{;<2b^(ZKWuz9Hmuz=?kqv!eq{qW87z%!%Q_0O4$w6j}c-`L5B zUh|O^8WABQE`lg$9{bhaL71T^cwBEA4nm>i-j9%YHLHh>8JMi?n7V%IY8K88XF(vD+77j}Y60)B==p{WtcGJs?Fi<`m0}~+ z8*kqL_IxlfTx*O}>6?LyI;V;EGNf?Zq@`rTlM%;=MjLy!OX@9bPj9UBbK<;CTzt%UW{Qa5R|VE7Cu)rL(*6Sn6;M` z^n?nrlHc`{i``Os&D=O@faGYD&-9qTV^=@ivTL|Ucu;`EI$#vw+?A|plf`ZT_qxQP z1)bz+?~>By-UcwKnGjUqPFijc#nYSy_6wVj3$=z5#jrcXvN~V+$%Sgo4!y z+Z-BfyNEyQbw~(6oxn>v+3mopF>>mn3FRU*z&^nb`pPUC|H+aHS*Un#w2gF2(Hb z1$UvmRh~`V=2+^!cOGSN+;_654GOi&VZ+XK*p%^6t@O6}E7ySN!=rD0)8!ub zS~Avhmv3Jocki!PR^2jciZ6JEJ{-ic#-O4*24f(i$um{4A`~Le0`(b%RZJiWvH!!@ zIR%N*ElRp=Tf1%Bwry+oZriqP+qP}n)^6MG>GR)vXJRJKoTrMYw|c3_mFvsQ9O?eb zlTuz3HO27xaOu`vKgbgg%(u*l^Ue|*ylBgbZ`sxt=zpgXf`pJOSbzKm#s7pp{8J~j z`2PZx|DzF(6#qvf@c-XHWnCb_nDQkr4sJZYON(aJSND}Ot&hj{;5f2uLntxLKS-sq zK(a!;d0EHDZNE~|PPO;j%wL(*zwDQ>#3K^f6uHU9G)`H^8*)=7&FTj-sb(3baq*Gd zN9+EU>4&!rn!86zAj26ye!~%IBvR73x1`0oaRhShyZF3J>K`l#wV*IsjSJRV8Vmth zrXjo3fQ~iJb(6{U5=(4aTdA#L_JLDm)f(E8AEvTlzlHIl`G=_#{b4Gb7k42o&Dvqb zuuZabk`rWZg^wA@MDPX689mnebw3j?n*XsQ(t8GL4a+6z!Vk_iVEB&TZPZeJ;f#!z z7DX2rS5xX~QO;XRvB}Il{UrMaoN1aU!nV*2N$X={w8dOt@i3bS!nZ^wJb%E-yZ-}L zDwz8gEOF9Ja*P6FZqU|1ZX}ADSA(N8pf?2YD?g>O0#@xW}GnZ`yxEtaB88Dx>>C zAl_Gg>*u0^ehIj+%i5F_PjH(=Jo)m+WOXx1&HuaOGPjRCF;QcH#X!zLK~dGs{ULFm z$)m5P0G`+YuKY{_3HUbdk0QneTgfI2>RSg(;@gJQyPE+(k52D{r2mhU*i~I4dA8X| zur9d8tN{q?5iC6VBXb}PgUFvN{d-HG+34MuVxyU6q(-B)1nml*M!8lv{l9L291-n# z_&G!nUG{hLcDj;35cEC#m=|W9kR#KItBH0VK)4ozpq+C)#(ZJ^{39l|;@}#@9ud88 zp>O!%z`A1Y@KIYyKB2bc)t~xHH%b?}8QG%nUBV`2-1!M4Iu2OZh}yWCAV~FqG0R20Q>ON&?3(w0G0hnNh%H&NQDH{* z%PoA7#+0Gx4`=y+-aBp^xrW~g$sQs7mV^D@iAZ}=K@jy{se&Sv;Msr8RLEdX>5C|p z62eW3oHs8nIMCBW$o2R)^sK_+>nGGC&_SbQrj>n(|i_U1j~mJ-N>5mrmN?y--H6%z{aL zUXuK}1n4i|O^W*N=aYnt80~&2%e_gxa$INS+UX`}d5d-epH{jVH%QyI1YoDQrl1QG zR5w9qj%!y9-IM6lD%+Gs0u#nQhiMXFz;*nX0UT1uRA2xeMNNkHg~z*hM;&Hbq?cX! zoj?q!Hpv{PepfrT(rb?1TW8VcIe(rvtlvJ;z*cqJo-d%oki>4Y1RLnN8Tm@vK1%#Q z;mq+p(bHH*DaB2087#Bq;2 zv|JRrY10b_#J5fGLGLBZ>eg+>sW7vIpmqfgm3tigVj8`a9FDrv|{>`?q`y=pI0$#IG5zcSB+=2zcPgZ>B)- zaDBfXH{1&}QbX?INT_$wRgHzAkT#a8*zG(QQ>cH6x?2Z%kHvvN=+R^f(ap3BnJLy6^EhFMD-&nhfI}Z1d)v)W6Xq>h9|{)<*wp2 z=E8}%FlQa?h0zNz=}kW=i@<+U7PR9Ofz)_?2%tix!nmM1Dt6?NKkG4~Q3;|lre4~{ z_!xf&C$^7^HiPP-;0v~lO_6pmXE6h0-a)5JsfL8*Ji^S^OKL#9ZP#09h6jGPG+oaN zUk7mv+Eb4>YeR3Nt2a+@r760|9ab9=91aBP^W%||2&r6ef2Q}|Xtz>q2yjO7G?N6W z(8}FeL_YVB&eANfQm+KmK|s0Lm3|r&+O<+jpnorW08!{xGF|WvW?=;XCb;a03_!Gj z7KIH1AIw&$7j_V(bpzkZm?TqNDUuSXL7!2hnUj12#_mz^+QazG5m&M5hb%VSoX~VB zv!rxQsjdy;41z>!!i*p4&lcE(^(Q&-;cJp+Ev#L;xD;Z^IuT72v+}n)^%`EFFxN=X zQvw2BS`2iP3&*LE?nt2{wi@VBC{gB}EXWCl(YLK{BbF5eVgmQ4Px$Iw{HC7-zBWId z*5RgsLA6Z4H-8Xc>FT#?P>tjp$cT-y6C&tu=W995LM(N+u1Kl0TUjcTDol36AQ}lX zpWO(R2Ew7#_q$@$cOKQ$y@Be0C)l5ai&dY(6czc;7SYE@(O6ER4&*oN_k1Z0iZFOg zcuyj3EPw@^CS{h%9`^6tUT#9x^xP{K5x7pTM!9-`SKxoxXi5<5&C)#Qv+%WTr z;*XfTihsYK>%O8Bm-C}Gu(AIGX!%c(*5HrY*l0)ezLx$5mb>HUi2LbzFsaOpbE;!D zny4;ie_Fsy_a|XR>5ES^%8~u{KnI`zTqKd;%DU@I4jl>^GIZ(DIoW?+amw%9{TBeC z^4|bN=)!Nct;Ct*9{}R(wZ^Bd6*2vg{9{QpZF;|Z&W%XqOLv^1qy)3C*Rn0nA>4}doQdm3 zBw=2&f3LP*yRtHREwGBT)!gQ5GYIG`SS>v2Y&9WbjN1vARBR&7{4@Q3`B%Zpx-ne))Sa-ulz2alJbGyUHPJwzDAxD~JZa`NTQuJ5fN?2@h zEOwt}5PveB0kdsvjR>Chu`76KqutD3PEUYdhxdU-xV(G^rI!5}-IW6A{mvs3uI%R+fAWiZ`{cOF zA#TM9a5E4(YPrPH%}(0Q1Z_E+i@2HzN(EB*j?2Xhu+jj$WRkMJ0R51{W|>V6!Ez78!ISoiouj0vtXg=%p>Czi~nU^@OTcp~xHdB1?JuLLv0`sBsb z_eKPx7L3#E{xCW3{Sy%Nl|Y}_K-Q;k?S=g)F;F^ z5(F9j&{V7v^1JI!hjo_`iHv4F=358T7&XcnEp^^uuzwpS)NU6=)$AGs5-@;&eai76 z7d8X&h{<@6{0mSz^Ph@GZg?eJ*Ll~RN~ZQ*RuA!lMqAuC9J+;}?tI6aJ1w4vuQZ-X z{Da;0p!HHKb@6q!EIY@YKJ!~0?eng`9o`@`(CVo`XUR*;P9;^?%^;G;VYwr$wu1m0 zIyjiQD1X<&B(1za(ki33fSFjIDu##!u z)aAXmz7S!U&zXO2c$gx^Ire+ScLDaP@GL%M0QtAuE45Tg<{V;WfUqnB!xs^jM}9tmhXPesKVtQg@DL;3{&0#9OrBdKQz zEAUS`%U?*c9jbl$t!i2t{(A?1y#Vro&~~C?#j1%bt0L7Wwp5J9x^) z0F4P|A9slrY$aeb8w#094_+e~&Z+IU0K+AY!i3)h8@!~|$qV-u(tsvDSu$J@6B|}lUL}S~G!J3A z_Bku{aEk_8>O5?m_BP=}NYmw;J>u<#|K;8MBvFv>>I$^3n4VfTS-Dra#h=f;U5ZmO zTQ#!5waYEr@s4maDasL3_0hlT1;WV=d`<&;2s?C7viaY+Ka~^ru#3QKgt^aqPL zFnp=O0KZq)f5VXVOjCN`0FjrN2^-21IJP~yw1<)(;bQ*cH>mlcHa!0EVEBaVe87IV z(9cuiQ@{-Jnwt)lfOmHAet01k%q!i|9$T+3wtt%+F{MMJv;zSEfP(oCvgV)qsz}uh z`vP`^f9k88j{rTE0sU+wD5p{CZi^_NjA7DN<+MPkM3MOudnG#c_}YCDS;t`DB{a@> zw>Z5Pt14=26iPe!;|X!#m4$%IfsF8MXBI&@ zMJ)JX8Ee>=otNSDj!HE_yn>XxP%L=joW7hwzRLRuplGxC8Jxw17^=MJ#v|Kg_NMOh z8X&o8lpEAf5s0qth%i%w0`g?_&Q6%NoB75k7U&d*9S``WBcux60WF}oL3OQ2>oV|zn1S*Ou~yS@!mOc z+SroqfPLG|1cX@}>uSPb!D6$Oy8LQ7m?|&JkWr}tsQgCIp8{AO0f0A60Ojzvv&QJP ze3nLbd@~V~^b6ueHdF4GBUlH+bm3!ag#TRW_tClS8T#@A%5|dSZ?Q-uR|MjoqFXE+ z)x*vu9WLi;T4#voc?@oN8{5{&B#KARzbB})m4hY zF5*<42)nET67%e&?BhWyjE(sWsZtAoC2AQ?fXb596V*-||Abs$B1KA+Ak?+CT)Kg3 zPk#r>Q(OnNRar2~qXuUofk$0e9{L-+QXZe14b;Hk5aiwKGJN9K@oGAr@V93%4GO@T zV`u^o$3xHnT@V)5c&F*fI6?vl^0q6BNS&$Bp=??F^JWxj0BtR5zLjUdj;sUrp3c`dnv?sv z<_#gna0O!Gtp-5^tQ5H8%aF|ajWd61?1R!C5kk}fyuf-pZcgn?JMslHHw?w8$=G0L z8QsxokRQ@fN#@b?5&iYjw&gT-VMDGX0-FCSp;WVI73uNNPPhwp!sZ(-M|X`NSj&d# z3*EJdO8rbt0G7T~ot)1hqKE?I=Sjt8pa-Ofsxa{>2aLAio^&}cEdXSXqO+@!mu z(u&={)S)?QHZ4oqy>@0jy{jrMzH6=YY?4tb_R(4GVbZn$Y;1z5%V*^_Rx5Sfd}+31 zznZT*avn(2bYZnH6``_d=JhgfE;dzi97ih^H`B>giROJUbe@nDg-*YMh(@~QR_`ay zfr2_nEGkusKHbUmeygWEr}ty`$6Tuzw;T%BX6)&eX5v=r^k>}`{0yguA3XvEmSV_ds80g9WST&I8Z_{g z41qc73qr@wO_RcT`NE5T=ER+aQ^_ceQ>qY_>`TeU!p2Vn8xMkPF3o_uaDeWb-#W$OPs)J3QKbwifQ+^z@FI4jMW%<+?;V^i?MP_h?18UE5pD(5*ku zw@mt8R&2gMM$QlR)?L)zxBFetzt(*XBb++uZ$JOmczB%84Q9cwB)vK|-Ysu8>0!Fv z^IX5VbJ{=i%H`ehY&2eUz1p^u*Vgw`6Bcz9b@;m1bS-(F)KG1o1*^^7i?%qJqERxO zdr-NsKIC_rA-f0 zp&J{x`fpEK>kt;7WRO;WJ{)|5(NT*uXSxPndbmUojOxXP?s3KhM`R4(dR@^v)6rpc z(2}+~lfs^`bvPH97~C$0dt#7{)ARU8<}EEzEopXb*J}x1Eu}jHuZR-Ee^OGSDd-3* zUwbgwi12-`75V_>Ep(CN>fk=Z!NaBAxUFzdUO9#o$g$y{pc`r0mM9ndhjkOxXY#0mJLMWHgl~vEvv3*fZ9OYNAX?qcJ5k0`O*bAFFfP<_IJKuVK zyrZ?ITyghlQb~DTy(UKU1&T~(Oia7gm{Mv}@^+8k-TK7yb^}cNW~EpL37Zd0yIy$_ z^zeJSs8U@|4E~Cq^M194IFv@0LA3cpWz&5KW84@O)M7gk4Emk#sljUbay;4fG!YE^ z{dV$-Jf7zSc2AkNWfB} z+!aK6d@0V-_lOzmBlwn&2R(()%nMzpw2;%(R zOFY_-S5|j=P##Z~tcB)h@s8P-lZ9bjM{BQZdx_8&f~?jeme}SHFw^tlOv&CRg-p3W zSL@);U`V+2JhH5>6Hl^ZWqEsa}bHI5EUSu6i301(5prV zg$T>Jot4N$Ib|{+Si3{J+@hS0!$#_!^nRm2v9Gp0vVH2Bk*S5L(ksKE7zq60&<81d z^IAPvZ(p{|e$#b1!~LH~lZ3Nt^l^#p15Mae`Z%?eSf~x=T(H>EiK(>kq}6p#Ayj&Z zcsKHsTS%o7*aP*jUZR(U0tfEw8C7F!+0jF#)?T$(^E`r5dZdn(DphGLw>^+s9Y?4N zX3#wEf*1J9c}Y?Xgrrn;P$(+c%iH;CO=c*!RlqQkMOO4b@(I_!<9K74e8H#`QB@q2dL* z)kEIV-3B71EXP7IEJaYTN}y$DB&*=i0uNB4OYwO>bI^6GSNVP`$sf)NC-59$1zke72=hI$rSL3sbKSg$__ z1uysMBOi!i);Z|ktTU?fB;aoiO2YD+c}V2SOQI8$y7YIwJ}h5Zg&bf8ZE*bx%#a8c z%lk!N5QKFP=jqQkw=3}}Rct%ZexR0A>d zB1ZF@rQ>Kg4mJCNkSd%H2-yX*bmy&VmU9_NiY_9~!-%l+x1=MvdbrO(F-@=w{^T~B zj;f1GBunOA{-%bPdzMcju{IxfM|W9ptO(=vCal(s6QA;X2s;tuheGr~0dm{&>mUGk z0}-b#2+3=G9Jb4LqE%L*bL|Zx0EVTPQSv7;A+T>n5Dhm}X@{~(ZaH$KNT}KaQ)Hkl zxb4vyNY5%}f2jD8hw&8=V2lvFv8DZP5&D46kP@28`PFh-JnTc zh4-MAJ0F*8Qw@ZNksMEviM)X57autEo70Da{e0yrJ_R22gar##uG_E{=(ibtG7P~S zzCKndETwh?J5~aNR(RTzA&f*0RmydKkaPll@HLl4=4Qmbo)dV^fcx%E3}AVlb5OjzH9mtac-bFECs0G4ss$$WiDNE+U{8H~SNBP6l%ch3S&fe5h-S2^^& zu5`SARvvzPhWL+z1n(2#e!UF{8t$#?Y$~<^5lF85oG)!zV8|uMqk#E+Zu9Hj0`ZY3 zi3ogGF(Aa2UY;ShYZ80`vS0;P&5aK@T*c(j8>WC%C-$Lq$qJE@Oc_@RCCu?AuR67I zf^kFbMkHVQZi3Zy9y&k(m%2cq4ejvrIgq+H@o!Q3MHANWSq2Mls*wxz%p5o?w}Ic;O4Lf@u+du4VA(xXB$>wkcOh~ z?idE6i&XrEs7>Pe1P$>MakP`d0Y=`fgy(bZ`HCC;ayLQ3RXqX9T+A=?SL-7B7kwJZ z4n*qksME;SB{ipU%F_r$KXT>74e%kTszTnUX=lAH7u~EDT_*jRlE{vdk%|Bu ztb%p8=QFih#P?@5$JfZfLxQMn6!%rf2GWtVLkr|EMl~fzBdU-W67iAmD;5ELfF2}N zyc*y%O;4yK&ocdaEq!Z3CJ0OkJ-3?&PAAX$8jOAtl4#eA<`fGKkg({B)A%~D3-MlYsETEc zfb)RhA*atfcHvtn9lm+_2#iSp(qc^V3)7c|<2wezf`S;Au`0<$PUvgBG&usXum~eg zh=sWP?+tKRQ33{|9E_rXnTd48aw*UuFd!B8<@nmzu29^H(y4mU*5^XRuFDE#SMKrd zqA{}?^%rn{IyMVd17MOiXplGwdI(wHb*dz1BNDkrBegh-5~;v^lxElyY<9T2kWHNV zEUE%IeX8y^?9r#!EhQ^|5&C-&2*jADp^ONzCV{sFqZIRkz^Mqmn`AL4ub3l-F)I?E zi9;NUCo&AHv+xEslPVo+lm-VvquJ#6$c)jXW;3Bix$1Ug18QLj0>hWWQU1A<#$ga4 z%Bu3k{6UZEfHjMGH0;Pa&Mx|x$JT-r`)f(NR;`_Wf~l3C6R2PeDLlo!w4iFy@VAD$ zL=TG2?`ver)xRwKv_!L?&MZMvba`%`tca1?n>=amVOl*fjRF$sFAhi{Q0d_qklva> z#0?CDC|xUL0)UMF7Lw zXl(Nfa*&&))V(f!5%l>8WM?h>>

`eR;gykikw;&S&A7125SNW;*=s+@yz;sweOZ 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 U2HX&Vf4#tR*~%Jl%?0~^0OEakEC2ui literal 0 HcmV?d00001 From 063696bba5417dceababb1ad12accda2f146c951 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 16:12:03 +0200 Subject: [PATCH 034/126] doc: nrf: move caf docs to doc folder Move all docs in include to the doc folder. Signed-off-by: Gerard Marull-Paretas --- {include => doc/nrf/libraries}/caf/ble_adv.rst | 0 {include => doc/nrf/libraries}/caf/ble_smp.rst | 0 {include => doc/nrf/libraries}/caf/ble_state.rst | 2 +- {include => doc/nrf/libraries}/caf/buttons.rst | 2 +- {include => doc/nrf/libraries}/caf/caf_overview.rst | 2 +- .../nrf/libraries}/caf/click_detector.rst | 0 .../caf}/images/caf_ble_state_transitions.svg | 0 .../caf}/images/caf_ble_state_transitions.vsdx | Bin .../caf}/images/caf_buttons_states.svg | 0 .../caf}/images/caf_buttons_states.vsdx | Bin .../caf}/images/caf_led_effect_structure.png | Bin .../caf}/images/caf_led_effect_structure.svg | 0 .../caf}/images/caf_led_effect_structure.vsdx | Bin doc/nrf/{ => libraries/caf}/images/caf_overview.svg | 0 .../caf}/images/caf_sensor_states.svg | 0 .../caf}/images/caf_sensor_states.vsdx | Bin doc/nrf/libraries/caf/index.rst | 4 ++-- {include => doc/nrf/libraries}/caf/leds.rst | 2 +- .../nrf/libraries}/caf/power_manager.rst | 0 .../nrf/libraries}/caf/sensor_sampler.rst | 2 +- 20 files changed, 7 insertions(+), 7 deletions(-) rename {include => doc/nrf/libraries}/caf/ble_adv.rst (100%) rename {include => doc/nrf/libraries}/caf/ble_smp.rst (100%) rename {include => doc/nrf/libraries}/caf/ble_state.rst (99%) rename {include => doc/nrf/libraries}/caf/buttons.rst (99%) rename {include => doc/nrf/libraries}/caf/caf_overview.rst (99%) rename {include => doc/nrf/libraries}/caf/click_detector.rst (100%) rename doc/nrf/{ => libraries/caf}/images/caf_ble_state_transitions.svg (100%) rename doc/nrf/{ => libraries/caf}/images/caf_ble_state_transitions.vsdx (100%) rename doc/nrf/{ => libraries/caf}/images/caf_buttons_states.svg (100%) rename doc/nrf/{ => libraries/caf}/images/caf_buttons_states.vsdx (100%) rename doc/nrf/{ => libraries/caf}/images/caf_led_effect_structure.png (100%) rename doc/nrf/{ => libraries/caf}/images/caf_led_effect_structure.svg (100%) rename doc/nrf/{ => libraries/caf}/images/caf_led_effect_structure.vsdx (100%) rename doc/nrf/{ => libraries/caf}/images/caf_overview.svg (100%) rename doc/nrf/{ => libraries/caf}/images/caf_sensor_states.svg (100%) rename doc/nrf/{ => libraries/caf}/images/caf_sensor_states.vsdx (100%) rename {include => doc/nrf/libraries}/caf/leds.rst (99%) rename {include => doc/nrf/libraries}/caf/power_manager.rst (100%) rename {include => doc/nrf/libraries}/caf/sensor_sampler.rst (99%) diff --git a/include/caf/ble_adv.rst b/doc/nrf/libraries/caf/ble_adv.rst similarity index 100% rename from include/caf/ble_adv.rst rename to doc/nrf/libraries/caf/ble_adv.rst diff --git a/include/caf/ble_smp.rst b/doc/nrf/libraries/caf/ble_smp.rst similarity index 100% rename from include/caf/ble_smp.rst rename to doc/nrf/libraries/caf/ble_smp.rst diff --git a/include/caf/ble_state.rst b/doc/nrf/libraries/caf/ble_state.rst similarity index 99% rename from include/caf/ble_state.rst rename to doc/nrf/libraries/caf/ble_state.rst index 1cc887a7bec4..927721784839 100644 --- a/include/caf/ble_state.rst +++ b/doc/nrf/libraries/caf/ble_state.rst @@ -51,7 +51,7 @@ Connection state change The module propagates information about the connection state changes using :c:struct:`ble_peer_event`. In this event, :c:member:`ble_peer_event.id` is a pointer to the connection object and :c:member:`ble_peer_event.state` is the connection state. -.. figure:: /images/caf_ble_state_transitions.svg +.. figure:: images/caf_ble_state_transitions.svg :alt: Bluetooth connection state handling in CAF Bluetooth connection state handling in CAF diff --git a/include/caf/buttons.rst b/doc/nrf/libraries/caf/buttons.rst similarity index 99% rename from include/caf/buttons.rst rename to doc/nrf/libraries/caf/buttons.rst index 5ed9b1315058..f4c91613419f 100644 --- a/include/caf/buttons.rst +++ b/doc/nrf/libraries/caf/buttons.rst @@ -65,7 +65,7 @@ Implementation details Depending on the configuration, the module can use from two to four states. -.. figure:: /images/caf_buttons_states.svg +.. figure:: images/caf_buttons_states.svg :alt: State transitions of the buttons module State transitions of the buttons module diff --git a/include/caf/caf_overview.rst b/doc/nrf/libraries/caf/caf_overview.rst similarity index 99% rename from include/caf/caf_overview.rst rename to doc/nrf/libraries/caf/caf_overview.rst index c5779cf30876..fed91b95b4c2 100644 --- a/include/caf/caf_overview.rst +++ b/doc/nrf/libraries/caf/caf_overview.rst @@ -19,7 +19,7 @@ In an event-based application, parts of the application functionality are separa These events are defined either by CAF or by the application. They are submitted by modules and other modules can subscribe and react to them. -.. figure:: ../../doc/nrf/images/caf_overview.svg +.. figure:: images/caf_overview.svg :alt: Common Application Framework architecture example Common Application Framework architecture example diff --git a/include/caf/click_detector.rst b/doc/nrf/libraries/caf/click_detector.rst similarity index 100% rename from include/caf/click_detector.rst rename to doc/nrf/libraries/caf/click_detector.rst diff --git a/doc/nrf/images/caf_ble_state_transitions.svg b/doc/nrf/libraries/caf/images/caf_ble_state_transitions.svg similarity index 100% rename from doc/nrf/images/caf_ble_state_transitions.svg rename to doc/nrf/libraries/caf/images/caf_ble_state_transitions.svg diff --git a/doc/nrf/images/caf_ble_state_transitions.vsdx b/doc/nrf/libraries/caf/images/caf_ble_state_transitions.vsdx similarity index 100% rename from doc/nrf/images/caf_ble_state_transitions.vsdx rename to doc/nrf/libraries/caf/images/caf_ble_state_transitions.vsdx diff --git a/doc/nrf/images/caf_buttons_states.svg b/doc/nrf/libraries/caf/images/caf_buttons_states.svg similarity index 100% rename from doc/nrf/images/caf_buttons_states.svg rename to doc/nrf/libraries/caf/images/caf_buttons_states.svg diff --git a/doc/nrf/images/caf_buttons_states.vsdx b/doc/nrf/libraries/caf/images/caf_buttons_states.vsdx similarity index 100% rename from doc/nrf/images/caf_buttons_states.vsdx rename to doc/nrf/libraries/caf/images/caf_buttons_states.vsdx diff --git a/doc/nrf/images/caf_led_effect_structure.png b/doc/nrf/libraries/caf/images/caf_led_effect_structure.png similarity index 100% rename from doc/nrf/images/caf_led_effect_structure.png rename to doc/nrf/libraries/caf/images/caf_led_effect_structure.png diff --git a/doc/nrf/images/caf_led_effect_structure.svg b/doc/nrf/libraries/caf/images/caf_led_effect_structure.svg similarity index 100% rename from doc/nrf/images/caf_led_effect_structure.svg rename to doc/nrf/libraries/caf/images/caf_led_effect_structure.svg diff --git a/doc/nrf/images/caf_led_effect_structure.vsdx b/doc/nrf/libraries/caf/images/caf_led_effect_structure.vsdx similarity index 100% rename from doc/nrf/images/caf_led_effect_structure.vsdx rename to doc/nrf/libraries/caf/images/caf_led_effect_structure.vsdx diff --git a/doc/nrf/images/caf_overview.svg b/doc/nrf/libraries/caf/images/caf_overview.svg similarity index 100% rename from doc/nrf/images/caf_overview.svg rename to doc/nrf/libraries/caf/images/caf_overview.svg diff --git a/doc/nrf/images/caf_sensor_states.svg b/doc/nrf/libraries/caf/images/caf_sensor_states.svg similarity index 100% rename from doc/nrf/images/caf_sensor_states.svg rename to doc/nrf/libraries/caf/images/caf_sensor_states.svg diff --git a/doc/nrf/images/caf_sensor_states.vsdx b/doc/nrf/libraries/caf/images/caf_sensor_states.vsdx similarity index 100% rename from doc/nrf/images/caf_sensor_states.vsdx rename to doc/nrf/libraries/caf/images/caf_sensor_states.vsdx diff --git a/doc/nrf/libraries/caf/index.rst b/doc/nrf/libraries/caf/index.rst index 505aeeaabd98..1da094a7a75a 100644 --- a/doc/nrf/libraries/caf/index.rst +++ b/doc/nrf/libraries/caf/index.rst @@ -8,5 +8,5 @@ Common Application Framework :glob: :caption: Subpages: - ../../../../include/caf/caf_overview.rst - ../../../../include/caf/* + caf_overview.rst + * diff --git a/include/caf/leds.rst b/doc/nrf/libraries/caf/leds.rst similarity index 99% rename from include/caf/leds.rst rename to doc/nrf/libraries/caf/leds.rst index 10d1cdad14cc..e70f5dfbe238 100644 --- a/include/caf/leds.rst +++ b/doc/nrf/libraries/caf/leds.rst @@ -278,7 +278,7 @@ The LED effect (:c:struct:`led_effect`) is described by the following characteri To achieve the desired LED effect, the LED color is updated periodically based on the LED steps defined for the given LED effect, which in turn are divided in multiple smaller updates called *substeps*. -.. figure:: /images/caf_led_effect_structure.svg +.. figure:: images/caf_led_effect_structure.svg :alt: Characteristics of a led_effect Characteristics of a led_effect diff --git a/include/caf/power_manager.rst b/doc/nrf/libraries/caf/power_manager.rst similarity index 100% rename from include/caf/power_manager.rst rename to doc/nrf/libraries/caf/power_manager.rst diff --git a/include/caf/sensor_sampler.rst b/doc/nrf/libraries/caf/sensor_sampler.rst similarity index 99% rename from include/caf/sensor_sampler.rst rename to doc/nrf/libraries/caf/sensor_sampler.rst index 57af9d7447fe..8f38d1be1030 100644 --- a/include/caf/sensor_sampler.rst +++ b/doc/nrf/libraries/caf/sensor_sampler.rst @@ -187,7 +187,7 @@ Each sensor can be in one of the following states: The following figure shows the possible state transitions. -.. figure:: /images/caf_sensor_states.svg +.. figure:: images/caf_sensor_states.svg :alt: State transitions of the sensors used by the sensor sampler module State transitions of the sensors used by the sensor sampler module From 332fb6ad626c1a4d437c2cbbdcadab8db176b5d5 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 16:13:46 +0200 Subject: [PATCH 035/126] doc: nrf: move debug docs to doc folder Move debug docs from include to doc folder. Signed-off-by: Gerard Marull-Paretas --- {include => doc/nrf/libraries}/debug/cpu_load.rst | 0 doc/nrf/libraries/debug/index.rst | 2 +- {include => doc/nrf/libraries}/debug/ppi_trace.rst | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename {include => doc/nrf/libraries}/debug/cpu_load.rst (100%) rename {include => doc/nrf/libraries}/debug/ppi_trace.rst (100%) diff --git a/include/debug/cpu_load.rst b/doc/nrf/libraries/debug/cpu_load.rst similarity index 100% rename from include/debug/cpu_load.rst rename to doc/nrf/libraries/debug/cpu_load.rst diff --git a/doc/nrf/libraries/debug/index.rst b/doc/nrf/libraries/debug/index.rst index aa672f17bb50..121d37e6832d 100644 --- a/doc/nrf/libraries/debug/index.rst +++ b/doc/nrf/libraries/debug/index.rst @@ -8,4 +8,4 @@ Debug libraries :glob: :caption: Subpages: - ../../../include/debug/* + * diff --git a/include/debug/ppi_trace.rst b/doc/nrf/libraries/debug/ppi_trace.rst similarity index 100% rename from include/debug/ppi_trace.rst rename to doc/nrf/libraries/debug/ppi_trace.rst From 2d889bbde29e9ef977c474443ade0f4d2b7d8fd6 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 16:33:15 +0200 Subject: [PATCH 036/126] doc: nrf: move dfu docs to doc folder Move dfu docs from include to doc folder. Signed-off-by: Gerard Marull-Paretas --- {include => doc/nrf/libraries}/dfu/dfu_target.rst | 0 {include => doc/nrf/libraries}/dfu/fmfu_fdev.rst | 2 +- {include/mgmt => doc/nrf/libraries/dfu}/fmfu_mgmt.rst | 0 doc/nrf/libraries/dfu/index.rst | 3 +-- {include => doc/nrf/libraries}/dfu/pcd.rst | 0 5 files changed, 2 insertions(+), 3 deletions(-) rename {include => doc/nrf/libraries}/dfu/dfu_target.rst (100%) rename {include => doc/nrf/libraries}/dfu/fmfu_fdev.rst (95%) rename {include/mgmt => doc/nrf/libraries/dfu}/fmfu_mgmt.rst (100%) rename {include => doc/nrf/libraries}/dfu/pcd.rst (100%) diff --git a/include/dfu/dfu_target.rst b/doc/nrf/libraries/dfu/dfu_target.rst similarity index 100% rename from include/dfu/dfu_target.rst rename to doc/nrf/libraries/dfu/dfu_target.rst diff --git a/include/dfu/fmfu_fdev.rst b/doc/nrf/libraries/dfu/fmfu_fdev.rst similarity index 95% rename from include/dfu/fmfu_fdev.rst rename to doc/nrf/libraries/dfu/fmfu_fdev.rst index a611a83da2b6..7cbf144763d0 100644 --- a/include/dfu/fmfu_fdev.rst +++ b/doc/nrf/libraries/dfu/fmfu_fdev.rst @@ -26,7 +26,7 @@ Serialization The modem firmware is serialized using the following CDDL scheme. -.. literalinclude:: ../../subsys/dfu/fmfu_fdev/cddl/modem_update.cddl +.. literalinclude:: ../../../../subsys/dfu/fmfu_fdev/cddl/modem_update.cddl :language: none The resulting serialized firmware file uses the :file:`.cbor` extension. diff --git a/include/mgmt/fmfu_mgmt.rst b/doc/nrf/libraries/dfu/fmfu_mgmt.rst similarity index 100% rename from include/mgmt/fmfu_mgmt.rst rename to doc/nrf/libraries/dfu/fmfu_mgmt.rst diff --git a/doc/nrf/libraries/dfu/index.rst b/doc/nrf/libraries/dfu/index.rst index 4584cb19f26d..a5930ba7d7f0 100644 --- a/doc/nrf/libraries/dfu/index.rst +++ b/doc/nrf/libraries/dfu/index.rst @@ -8,5 +8,4 @@ DFU libraries :glob: :caption: Subpages: - ../../../include/dfu/* - ../../../include/mgmt/* + * diff --git a/include/dfu/pcd.rst b/doc/nrf/libraries/dfu/pcd.rst similarity index 100% rename from include/dfu/pcd.rst rename to doc/nrf/libraries/dfu/pcd.rst From ef8f14ad2d3e57e6369dbf98fd22a6b975ea674c Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 16:44:00 +0200 Subject: [PATCH 037/126] doc: nrf: move modem docs to doc folder Mode all the modem docs to doc folder. Signed-off-by: Gerard Marull-Paretas --- {include => doc/nrf/libraries}/modem/at_cmd.rst | 0 {include => doc/nrf/libraries}/modem/at_cmd_parser.rst | 0 .../at_host/lib_at_host.rst => libraries/modem/at_host.rst} | 0 {include => doc/nrf/libraries}/modem/at_monitor.rst | 0 {include => doc/nrf/libraries}/modem/at_notif.rst | 0 {include => doc/nrf/libraries}/modem/at_params.rst | 0 doc/nrf/libraries/modem/index.rst | 4 +--- {include => doc/nrf/libraries}/modem/lte_lc.rst | 0 {include => doc/nrf/libraries}/modem/modem_attest_token.rst | 0 {include => doc/nrf/libraries}/modem/modem_info.rst | 0 {include => doc/nrf/libraries}/modem/modem_jwt.rst | 0 {include => doc/nrf/libraries}/modem/modem_key_mgmt.rst | 0 {include => doc/nrf/libraries}/modem/nrf_modem_lib.rst | 0 {include => doc/nrf/libraries}/modem/pdn.rst | 0 {include => doc/nrf/libraries}/modem/sms.rst | 0 doc/nrf/{lib/zzhc => libraries/modem}/zzhc.rst | 0 16 files changed, 1 insertion(+), 3 deletions(-) rename {include => doc/nrf/libraries}/modem/at_cmd.rst (100%) rename {include => doc/nrf/libraries}/modem/at_cmd_parser.rst (100%) rename doc/nrf/{lib/at_host/lib_at_host.rst => libraries/modem/at_host.rst} (100%) rename {include => doc/nrf/libraries}/modem/at_monitor.rst (100%) rename {include => doc/nrf/libraries}/modem/at_notif.rst (100%) rename {include => doc/nrf/libraries}/modem/at_params.rst (100%) rename {include => doc/nrf/libraries}/modem/lte_lc.rst (100%) rename {include => doc/nrf/libraries}/modem/modem_attest_token.rst (100%) rename {include => doc/nrf/libraries}/modem/modem_info.rst (100%) rename {include => doc/nrf/libraries}/modem/modem_jwt.rst (100%) rename {include => doc/nrf/libraries}/modem/modem_key_mgmt.rst (100%) rename {include => doc/nrf/libraries}/modem/nrf_modem_lib.rst (100%) rename {include => doc/nrf/libraries}/modem/pdn.rst (100%) rename {include => doc/nrf/libraries}/modem/sms.rst (100%) rename doc/nrf/{lib/zzhc => libraries/modem}/zzhc.rst (100%) diff --git a/include/modem/at_cmd.rst b/doc/nrf/libraries/modem/at_cmd.rst similarity index 100% rename from include/modem/at_cmd.rst rename to doc/nrf/libraries/modem/at_cmd.rst diff --git a/include/modem/at_cmd_parser.rst b/doc/nrf/libraries/modem/at_cmd_parser.rst similarity index 100% rename from include/modem/at_cmd_parser.rst rename to doc/nrf/libraries/modem/at_cmd_parser.rst diff --git a/doc/nrf/lib/at_host/lib_at_host.rst b/doc/nrf/libraries/modem/at_host.rst similarity index 100% rename from doc/nrf/lib/at_host/lib_at_host.rst rename to doc/nrf/libraries/modem/at_host.rst diff --git a/include/modem/at_monitor.rst b/doc/nrf/libraries/modem/at_monitor.rst similarity index 100% rename from include/modem/at_monitor.rst rename to doc/nrf/libraries/modem/at_monitor.rst diff --git a/include/modem/at_notif.rst b/doc/nrf/libraries/modem/at_notif.rst similarity index 100% rename from include/modem/at_notif.rst rename to doc/nrf/libraries/modem/at_notif.rst diff --git a/include/modem/at_params.rst b/doc/nrf/libraries/modem/at_params.rst similarity index 100% rename from include/modem/at_params.rst rename to doc/nrf/libraries/modem/at_params.rst diff --git a/doc/nrf/libraries/modem/index.rst b/doc/nrf/libraries/modem/index.rst index 5ae097dca36c..0bc669519e2b 100644 --- a/doc/nrf/libraries/modem/index.rst +++ b/doc/nrf/libraries/modem/index.rst @@ -8,6 +8,4 @@ Modem libraries :glob: :caption: Subpages: - ../../../include/modem/* - ../../../lib/zzhc/* - ../../../lib/at_host/* + * diff --git a/include/modem/lte_lc.rst b/doc/nrf/libraries/modem/lte_lc.rst similarity index 100% rename from include/modem/lte_lc.rst rename to doc/nrf/libraries/modem/lte_lc.rst diff --git a/include/modem/modem_attest_token.rst b/doc/nrf/libraries/modem/modem_attest_token.rst similarity index 100% rename from include/modem/modem_attest_token.rst rename to doc/nrf/libraries/modem/modem_attest_token.rst diff --git a/include/modem/modem_info.rst b/doc/nrf/libraries/modem/modem_info.rst similarity index 100% rename from include/modem/modem_info.rst rename to doc/nrf/libraries/modem/modem_info.rst diff --git a/include/modem/modem_jwt.rst b/doc/nrf/libraries/modem/modem_jwt.rst similarity index 100% rename from include/modem/modem_jwt.rst rename to doc/nrf/libraries/modem/modem_jwt.rst diff --git a/include/modem/modem_key_mgmt.rst b/doc/nrf/libraries/modem/modem_key_mgmt.rst similarity index 100% rename from include/modem/modem_key_mgmt.rst rename to doc/nrf/libraries/modem/modem_key_mgmt.rst diff --git a/include/modem/nrf_modem_lib.rst b/doc/nrf/libraries/modem/nrf_modem_lib.rst similarity index 100% rename from include/modem/nrf_modem_lib.rst rename to doc/nrf/libraries/modem/nrf_modem_lib.rst diff --git a/include/modem/pdn.rst b/doc/nrf/libraries/modem/pdn.rst similarity index 100% rename from include/modem/pdn.rst rename to doc/nrf/libraries/modem/pdn.rst diff --git a/include/modem/sms.rst b/doc/nrf/libraries/modem/sms.rst similarity index 100% rename from include/modem/sms.rst rename to doc/nrf/libraries/modem/sms.rst diff --git a/doc/nrf/lib/zzhc/zzhc.rst b/doc/nrf/libraries/modem/zzhc.rst similarity index 100% rename from doc/nrf/lib/zzhc/zzhc.rst rename to doc/nrf/libraries/modem/zzhc.rst From a35187347a72be137651edde24957d48a0a2e798 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 16:46:11 +0200 Subject: [PATCH 038/126] doc: nrf: move mpsl docs to doc folder Move all mpsl docs to the doc folder. Signed-off-by: Gerard Marull-Paretas --- doc/nrf/libraries/mpsl/index.rst | 2 +- {include => doc/nrf/libraries}/mpsl/mpsl_assert.rst | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {include => doc/nrf/libraries}/mpsl/mpsl_assert.rst (100%) diff --git a/doc/nrf/libraries/mpsl/index.rst b/doc/nrf/libraries/mpsl/index.rst index 04b3d54372ea..910f63d21237 100644 --- a/doc/nrf/libraries/mpsl/index.rst +++ b/doc/nrf/libraries/mpsl/index.rst @@ -8,4 +8,4 @@ Multiprotocol Service Layer libraries :caption: Subpages: :glob: - ../../../include/mpsl/* + * diff --git a/include/mpsl/mpsl_assert.rst b/doc/nrf/libraries/mpsl/mpsl_assert.rst similarity index 100% rename from include/mpsl/mpsl_assert.rst rename to doc/nrf/libraries/mpsl/mpsl_assert.rst From e5bfc2b73b58c771daf0a6d4fcd81f922a71faf1 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 17:06:04 +0200 Subject: [PATCH 039/126] doc: nrf: move networking docs to doc folder Mode all networking docs to the doc folder. Signed-off-by: Gerard Marull-Paretas --- .../nrf/libraries/networking}/aws_fota.rst | 2 +- .../nrf/libraries/networking}/aws_iot.rst | 0 .../nrf/libraries/networking}/aws_jobs.rst | 0 .../nrf/libraries/networking}/azure_fota.rst | 0 .../nrf/libraries/networking}/azure_iot_hub.rst | 0 .../net => doc/nrf/libraries/networking}/cloud.rst | 0 .../nrf/libraries/networking}/coap_utils.rst | 0 .../nrf/libraries/networking}/download_client.rst | 0 .../nrf/libraries/networking}/fota_download.rst | 0 .../nrf/libraries/networking}/ftp_client.rst | 0 .../nrf/libraries/networking}/icalendar_parser.rst | 0 .../networking}/images/aws_fota_dfu_sequence.png | Bin .../networking}/images/aws_fota_dfu_sequence.svg | 0 .../images/aws_fota_dfu_sequence.uml.txt | 0 .../networking}/images/lib_lwm2m_client_utils.svg | 0 doc/nrf/libraries/networking/index.rst | 2 +- .../libraries/networking}/lwm2m_client_utils.rst | 2 +- .../libraries/networking}/multicell_location.rst | 0 .../nrf/libraries/networking}/nrf_cloud.rst | 0 .../nrf/libraries/networking}/nrf_cloud_agps.rst | 2 +- .../libraries/networking}/nrf_cloud_cell_pos.rst | 0 .../nrf/libraries/networking}/nrf_cloud_pgps.rst | 0 22 files changed, 4 insertions(+), 4 deletions(-) rename {include/net => doc/nrf/libraries/networking}/aws_fota.rst (98%) rename {include/net => doc/nrf/libraries/networking}/aws_iot.rst (100%) rename {include/net => doc/nrf/libraries/networking}/aws_jobs.rst (100%) rename {include/net => doc/nrf/libraries/networking}/azure_fota.rst (100%) rename {include/net => doc/nrf/libraries/networking}/azure_iot_hub.rst (100%) rename {include/net => doc/nrf/libraries/networking}/cloud.rst (100%) rename {include/net => doc/nrf/libraries/networking}/coap_utils.rst (100%) rename {include/net => doc/nrf/libraries/networking}/download_client.rst (100%) rename {include/net => doc/nrf/libraries/networking}/fota_download.rst (100%) rename {include/net => doc/nrf/libraries/networking}/ftp_client.rst (100%) rename {include/net => doc/nrf/libraries/networking}/icalendar_parser.rst (100%) rename doc/nrf/{ => libraries/networking}/images/aws_fota_dfu_sequence.png (100%) rename doc/nrf/{ => libraries/networking}/images/aws_fota_dfu_sequence.svg (100%) rename doc/nrf/{ => libraries/networking}/images/aws_fota_dfu_sequence.uml.txt (100%) rename doc/nrf/{ => libraries/networking}/images/lib_lwm2m_client_utils.svg (100%) rename {include/net => doc/nrf/libraries/networking}/lwm2m_client_utils.rst (99%) rename {include/net => doc/nrf/libraries/networking}/multicell_location.rst (100%) rename {include/net => doc/nrf/libraries/networking}/nrf_cloud.rst (100%) rename {include/net => doc/nrf/libraries/networking}/nrf_cloud_agps.rst (98%) rename {include/net => doc/nrf/libraries/networking}/nrf_cloud_cell_pos.rst (100%) rename {include/net => doc/nrf/libraries/networking}/nrf_cloud_pgps.rst (100%) diff --git a/include/net/aws_fota.rst b/doc/nrf/libraries/networking/aws_fota.rst similarity index 98% rename from include/net/aws_fota.rst rename to doc/nrf/libraries/networking/aws_fota.rst index 08b539eeeee3..b272948ee5b6 100644 --- a/include/net/aws_fota.rst +++ b/doc/nrf/libraries/networking/aws_fota.rst @@ -39,7 +39,7 @@ Implementation The following sequence diagram shows how a firmware over-the-air update is implemented through the use of `AWS IoT MQTT`_, `AWS IoT jobs`_, and `AWS Simple Storage Service (S3)`_. -.. figure:: /images/aws_fota_dfu_sequence.svg +.. figure:: images/aws_fota_dfu_sequence.svg :alt: AWS FOTA sequence diagram for doing FOTA through AWS jobs diff --git a/include/net/aws_iot.rst b/doc/nrf/libraries/networking/aws_iot.rst similarity index 100% rename from include/net/aws_iot.rst rename to doc/nrf/libraries/networking/aws_iot.rst diff --git a/include/net/aws_jobs.rst b/doc/nrf/libraries/networking/aws_jobs.rst similarity index 100% rename from include/net/aws_jobs.rst rename to doc/nrf/libraries/networking/aws_jobs.rst diff --git a/include/net/azure_fota.rst b/doc/nrf/libraries/networking/azure_fota.rst similarity index 100% rename from include/net/azure_fota.rst rename to doc/nrf/libraries/networking/azure_fota.rst diff --git a/include/net/azure_iot_hub.rst b/doc/nrf/libraries/networking/azure_iot_hub.rst similarity index 100% rename from include/net/azure_iot_hub.rst rename to doc/nrf/libraries/networking/azure_iot_hub.rst diff --git a/include/net/cloud.rst b/doc/nrf/libraries/networking/cloud.rst similarity index 100% rename from include/net/cloud.rst rename to doc/nrf/libraries/networking/cloud.rst diff --git a/include/net/coap_utils.rst b/doc/nrf/libraries/networking/coap_utils.rst similarity index 100% rename from include/net/coap_utils.rst rename to doc/nrf/libraries/networking/coap_utils.rst diff --git a/include/net/download_client.rst b/doc/nrf/libraries/networking/download_client.rst similarity index 100% rename from include/net/download_client.rst rename to doc/nrf/libraries/networking/download_client.rst diff --git a/include/net/fota_download.rst b/doc/nrf/libraries/networking/fota_download.rst similarity index 100% rename from include/net/fota_download.rst rename to doc/nrf/libraries/networking/fota_download.rst diff --git a/include/net/ftp_client.rst b/doc/nrf/libraries/networking/ftp_client.rst similarity index 100% rename from include/net/ftp_client.rst rename to doc/nrf/libraries/networking/ftp_client.rst diff --git a/include/net/icalendar_parser.rst b/doc/nrf/libraries/networking/icalendar_parser.rst similarity index 100% rename from include/net/icalendar_parser.rst rename to doc/nrf/libraries/networking/icalendar_parser.rst diff --git a/doc/nrf/images/aws_fota_dfu_sequence.png b/doc/nrf/libraries/networking/images/aws_fota_dfu_sequence.png similarity index 100% rename from doc/nrf/images/aws_fota_dfu_sequence.png rename to doc/nrf/libraries/networking/images/aws_fota_dfu_sequence.png diff --git a/doc/nrf/images/aws_fota_dfu_sequence.svg b/doc/nrf/libraries/networking/images/aws_fota_dfu_sequence.svg similarity index 100% rename from doc/nrf/images/aws_fota_dfu_sequence.svg rename to doc/nrf/libraries/networking/images/aws_fota_dfu_sequence.svg diff --git a/doc/nrf/images/aws_fota_dfu_sequence.uml.txt b/doc/nrf/libraries/networking/images/aws_fota_dfu_sequence.uml.txt similarity index 100% rename from doc/nrf/images/aws_fota_dfu_sequence.uml.txt rename to doc/nrf/libraries/networking/images/aws_fota_dfu_sequence.uml.txt diff --git a/doc/nrf/images/lib_lwm2m_client_utils.svg b/doc/nrf/libraries/networking/images/lib_lwm2m_client_utils.svg similarity index 100% rename from doc/nrf/images/lib_lwm2m_client_utils.svg rename to doc/nrf/libraries/networking/images/lib_lwm2m_client_utils.svg diff --git a/doc/nrf/libraries/networking/index.rst b/doc/nrf/libraries/networking/index.rst index cc86176dada4..9528dde0589f 100644 --- a/doc/nrf/libraries/networking/index.rst +++ b/doc/nrf/libraries/networking/index.rst @@ -8,4 +8,4 @@ Libraries for networking :glob: :caption: Subpages: - ../../../include/net/* + * diff --git a/include/net/lwm2m_client_utils.rst b/doc/nrf/libraries/networking/lwm2m_client_utils.rst similarity index 99% rename from include/net/lwm2m_client_utils.rst rename to doc/nrf/libraries/networking/lwm2m_client_utils.rst index a68d24ec56c5..831ed900e2a3 100644 --- a/include/net/lwm2m_client_utils.rst +++ b/doc/nrf/libraries/networking/lwm2m_client_utils.rst @@ -22,7 +22,7 @@ Following are the fixed set of readily initialized objects that are available to These objects do not indicate a complete set of resources that a device is expected to support. Based on the use case, a user application can, and is expected to, define additional set of resources based on the capabilities of the device. -.. figure:: /images/lib_lwm2m_client_utils.svg +.. figure:: images/lib_lwm2m_client_utils.svg :alt: LwM2M client utils software stack Configuration and implementation diff --git a/include/net/multicell_location.rst b/doc/nrf/libraries/networking/multicell_location.rst similarity index 100% rename from include/net/multicell_location.rst rename to doc/nrf/libraries/networking/multicell_location.rst diff --git a/include/net/nrf_cloud.rst b/doc/nrf/libraries/networking/nrf_cloud.rst similarity index 100% rename from include/net/nrf_cloud.rst rename to doc/nrf/libraries/networking/nrf_cloud.rst diff --git a/include/net/nrf_cloud_agps.rst b/doc/nrf/libraries/networking/nrf_cloud_agps.rst similarity index 98% rename from include/net/nrf_cloud_agps.rst rename to doc/nrf/libraries/networking/nrf_cloud_agps.rst index 1af8178d05f8..b15688abf59d 100644 --- a/include/net/nrf_cloud_agps.rst +++ b/doc/nrf/libraries/networking/nrf_cloud_agps.rst @@ -60,7 +60,7 @@ If the GPS service has already started before the device enters the RRC idle mod Limitations *********** -.. include:: ../../samples/nrf9160/agps/README.rst +.. include:: ../../../../samples/nrf9160/agps/README.rst :start-after: agpslimitation_start :end-before: agpslimitation_end diff --git a/include/net/nrf_cloud_cell_pos.rst b/doc/nrf/libraries/networking/nrf_cloud_cell_pos.rst similarity index 100% rename from include/net/nrf_cloud_cell_pos.rst rename to doc/nrf/libraries/networking/nrf_cloud_cell_pos.rst diff --git a/include/net/nrf_cloud_pgps.rst b/doc/nrf/libraries/networking/nrf_cloud_pgps.rst similarity index 100% rename from include/net/nrf_cloud_pgps.rst rename to doc/nrf/libraries/networking/nrf_cloud_pgps.rst From 4f0ea87f0046c4d421e12f72086e8c67f99dd51a Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 17:09:42 +0200 Subject: [PATCH 040/126] doc: nrf: move shell docs to doc folder Move the shell docs to the doc folder. Signed-off-by: Gerard Marull-Paretas --- doc/nrf/libraries/shell/index.rst | 2 +- {include => doc/nrf/libraries}/shell/shell_bt_nus.rst | 0 samples/bluetooth/shell_bt_nus/README.rst | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename {include => doc/nrf/libraries}/shell/shell_bt_nus.rst (100%) diff --git a/doc/nrf/libraries/shell/index.rst b/doc/nrf/libraries/shell/index.rst index 6b8b881db160..5e92cf083f0b 100644 --- a/doc/nrf/libraries/shell/index.rst +++ b/doc/nrf/libraries/shell/index.rst @@ -8,4 +8,4 @@ Shell libraries :glob: :caption: Subpages: - ../../../include/shell/* + * diff --git a/include/shell/shell_bt_nus.rst b/doc/nrf/libraries/shell/shell_bt_nus.rst similarity index 100% rename from include/shell/shell_bt_nus.rst rename to doc/nrf/libraries/shell/shell_bt_nus.rst diff --git a/samples/bluetooth/shell_bt_nus/README.rst b/samples/bluetooth/shell_bt_nus/README.rst index ba813f04e93f..9981d35f8baf 100644 --- a/samples/bluetooth/shell_bt_nus/README.rst +++ b/samples/bluetooth/shell_bt_nus/README.rst @@ -46,7 +46,7 @@ The |NCS| provides two alternatives for testing the sample: Testing using shell_bt_nus ========================== -.. include:: ../../../include/shell/shell_bt_nus.rst +.. include:: ../../../doc/nrf/libraries/shell/shell_bt_nus.rst :start-after: testing_bt_nus_shell_intro_start :end-before: testing_bt_nus_shell_intro_end From 2d5bf2136d8a75cb578ed9f2f4ac9003cf107a10 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 17:12:07 +0200 Subject: [PATCH 041/126] doc: nrf: move tfm docs to doc folder Move all TFM docs to the doc folder. Signed-off-by: Gerard Marull-Paretas --- doc/nrf/libraries/tfm/index.rst | 2 +- {include => doc/nrf/libraries}/tfm/tfm_ioctl_api.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename {include => doc/nrf/libraries}/tfm/tfm_ioctl_api.rst (95%) diff --git a/doc/nrf/libraries/tfm/index.rst b/doc/nrf/libraries/tfm/index.rst index e01f459765b7..53850ac1df7e 100644 --- a/doc/nrf/libraries/tfm/index.rst +++ b/doc/nrf/libraries/tfm/index.rst @@ -8,4 +8,4 @@ TF-M libraries :glob: :caption: Subpages: - ../../../include/tfm/* + * diff --git a/include/tfm/tfm_ioctl_api.rst b/doc/nrf/libraries/tfm/tfm_ioctl_api.rst similarity index 95% rename from include/tfm/tfm_ioctl_api.rst rename to doc/nrf/libraries/tfm/tfm_ioctl_api.rst index 146cbce0fa2d..41e0200d1be4 100644 --- a/include/tfm/tfm_ioctl_api.rst +++ b/doc/nrf/libraries/tfm/tfm_ioctl_api.rst @@ -21,7 +21,7 @@ Wrapper functions for these accesses are defined in :file:`tfm_ioctl_ns_api.c` a The supported platform services are defined by :c:struct:`fm_platform_ioctl_request_types_t` in :file:`tfm_ioctl_api.h`. -.. literalinclude:: tfm_ioctl_api.h +.. literalinclude:: ../../../../include/tfm/tfm_ioctl_api.h :language: c :start-at: /** @brief Supported request types. :end-before: /** @brief Argument list for each platform read service. From e44cde450e95e593370ff963b11f9c54232edef6 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 17:16:18 +0200 Subject: [PATCH 042/126] doc: nrf: move zigbee docs to doc folder Mode all zigbee docs to the doc folder. Signed-off-by: Gerard Marull-Paretas --- .../zigbee_signal_handler_00_stack_init.png | Bin .../zigbee_signal_handler_00_stack_init.uml | 0 ...ee_signal_handler_01_production_config.png | Bin ...ee_signal_handler_01_production_config.svg | 0 ...ee_signal_handler_01_production_config.uml | 0 ...e_signal_handler_01_production_config.vsdx | Bin .../zigbee_signal_handler_02_startup.png | Bin .../zigbee_signal_handler_02_startup.svg | 0 .../zigbee_signal_handler_02_startup.uml | 0 .../zigbee_signal_handler_02_startup.vsdx | Bin .../zigbee_signal_handler_03_first_start.png | Bin .../zigbee_signal_handler_03_first_start.svg | 0 .../zigbee_signal_handler_03_first_start.uml | 0 .../zigbee_signal_handler_03_first_start.vsdx | Bin .../zigbee_signal_handler_04_reboot.png | Bin .../zigbee_signal_handler_04_reboot.svg | 0 .../zigbee_signal_handler_04_reboot.uml | 0 .../zigbee_signal_handler_04_reboot.vsdx | Bin .../zigbee_signal_handler_05_formation.png | Bin .../zigbee_signal_handler_05_formation.svg | 0 .../zigbee_signal_handler_05_formation.uml | 0 .../zigbee_signal_handler_05_formation.vsdx | Bin .../zigbee_signal_handler_06_steering.png | Bin .../zigbee_signal_handler_06_steering.svg | 0 .../zigbee_signal_handler_06_steering.uml | 0 .../zigbee_signal_handler_06_steering.vsdx | Bin .../images/zigbee_signal_handler_07_idle.png | Bin .../images/zigbee_signal_handler_07_idle.svg | 0 .../images/zigbee_signal_handler_07_idle.uml | 0 .../images/zigbee_signal_handler_07_idle.vsdx | Bin .../zigbee_signal_handler_08_deep_sleep.png | Bin .../zigbee_signal_handler_08_deep_sleep.svg | 0 .../zigbee_signal_handler_08_deep_sleep.uml | 0 .../zigbee_signal_handler_08_deep_sleep.vsdx | Bin .../images/zigbee_signal_handler_09_leave.png | Bin .../images/zigbee_signal_handler_09_leave.svg | 0 .../images/zigbee_signal_handler_09_leave.uml | 0 .../zigbee_signal_handler_09_leave.vsdx | Bin .../zigbee_signal_handler_10_rejoin.svg | 0 .../zigbee_signal_handler_10_rejoin.vsdx | Bin .../zigbee_signal_handler_10_rejoin_stop.svg | 0 .../zigbee_signal_handler_10_rejoin_stop.vsdx | Bin ...ee_signal_handler_10_rejoin_user_input.svg | 0 ...e_signal_handler_10_rejoin_user_input.vsdx | Bin .../images/zigbee_signal_handler_overview.svg | 0 .../zigbee_signal_handler_overview.vsdx | Bin doc/nrf/libraries/zigbee/index.rst | 1 - .../libraries}/zigbee/zigbee_app_utils.rst | 26 +++++++++--------- .../zigbee/zigbee_error_handler.rst | 0 .../nrf/libraries}/zigbee/zigbee_fota.rst | 0 .../zigbee/zigbee_logger_eprxzcl.rst | 0 .../libraries}/zigbee/zigbee_zcl_scenes.rst | 0 doc/nrf/ug_zigbee_tools.rst | 2 +- 53 files changed, 14 insertions(+), 15 deletions(-) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_00_stack_init.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_00_stack_init.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_01_production_config.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_01_production_config.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_01_production_config.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_01_production_config.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_02_startup.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_02_startup.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_02_startup.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_02_startup.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_03_first_start.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_03_first_start.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_03_first_start.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_03_first_start.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_04_reboot.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_04_reboot.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_04_reboot.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_04_reboot.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_05_formation.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_05_formation.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_05_formation.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_05_formation.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_06_steering.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_06_steering.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_06_steering.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_06_steering.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_07_idle.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_07_idle.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_07_idle.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_07_idle.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_08_deep_sleep.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_08_deep_sleep.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_08_deep_sleep.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_08_deep_sleep.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_09_leave.png (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_09_leave.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_09_leave.uml (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_09_leave.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_10_rejoin.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_10_rejoin.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_10_rejoin_stop.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_10_rejoin_stop.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_10_rejoin_user_input.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_10_rejoin_user_input.vsdx (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_overview.svg (100%) rename doc/nrf/{ => libraries/zigbee}/images/zigbee_signal_handler_overview.vsdx (100%) rename {include => doc/nrf/libraries}/zigbee/zigbee_app_utils.rst (96%) rename {include => doc/nrf/libraries}/zigbee/zigbee_error_handler.rst (100%) rename {include => doc/nrf/libraries}/zigbee/zigbee_fota.rst (100%) rename {include => doc/nrf/libraries}/zigbee/zigbee_logger_eprxzcl.rst (100%) rename {include => doc/nrf/libraries}/zigbee/zigbee_zcl_scenes.rst (100%) diff --git a/doc/nrf/images/zigbee_signal_handler_00_stack_init.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_00_stack_init.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_00_stack_init.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_00_stack_init.png diff --git a/doc/nrf/images/zigbee_signal_handler_00_stack_init.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_00_stack_init.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_00_stack_init.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_00_stack_init.uml diff --git a/doc/nrf/images/zigbee_signal_handler_01_production_config.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_01_production_config.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_01_production_config.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_01_production_config.png diff --git a/doc/nrf/images/zigbee_signal_handler_01_production_config.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_01_production_config.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_01_production_config.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_01_production_config.svg diff --git a/doc/nrf/images/zigbee_signal_handler_01_production_config.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_01_production_config.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_01_production_config.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_01_production_config.uml diff --git a/doc/nrf/images/zigbee_signal_handler_01_production_config.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_01_production_config.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_01_production_config.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_01_production_config.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_02_startup.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_02_startup.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_02_startup.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_02_startup.png diff --git a/doc/nrf/images/zigbee_signal_handler_02_startup.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_02_startup.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_02_startup.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_02_startup.svg diff --git a/doc/nrf/images/zigbee_signal_handler_02_startup.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_02_startup.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_02_startup.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_02_startup.uml diff --git a/doc/nrf/images/zigbee_signal_handler_02_startup.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_02_startup.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_02_startup.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_02_startup.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_03_first_start.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_03_first_start.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_03_first_start.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_03_first_start.png diff --git a/doc/nrf/images/zigbee_signal_handler_03_first_start.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_03_first_start.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_03_first_start.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_03_first_start.svg diff --git a/doc/nrf/images/zigbee_signal_handler_03_first_start.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_03_first_start.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_03_first_start.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_03_first_start.uml diff --git a/doc/nrf/images/zigbee_signal_handler_03_first_start.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_03_first_start.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_03_first_start.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_03_first_start.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_04_reboot.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_04_reboot.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_04_reboot.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_04_reboot.png diff --git a/doc/nrf/images/zigbee_signal_handler_04_reboot.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_04_reboot.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_04_reboot.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_04_reboot.svg diff --git a/doc/nrf/images/zigbee_signal_handler_04_reboot.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_04_reboot.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_04_reboot.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_04_reboot.uml diff --git a/doc/nrf/images/zigbee_signal_handler_04_reboot.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_04_reboot.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_04_reboot.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_04_reboot.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_05_formation.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_05_formation.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_05_formation.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_05_formation.png diff --git a/doc/nrf/images/zigbee_signal_handler_05_formation.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_05_formation.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_05_formation.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_05_formation.svg diff --git a/doc/nrf/images/zigbee_signal_handler_05_formation.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_05_formation.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_05_formation.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_05_formation.uml diff --git a/doc/nrf/images/zigbee_signal_handler_05_formation.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_05_formation.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_05_formation.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_05_formation.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_06_steering.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_06_steering.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_06_steering.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_06_steering.png diff --git a/doc/nrf/images/zigbee_signal_handler_06_steering.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_06_steering.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_06_steering.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_06_steering.svg diff --git a/doc/nrf/images/zigbee_signal_handler_06_steering.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_06_steering.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_06_steering.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_06_steering.uml diff --git a/doc/nrf/images/zigbee_signal_handler_06_steering.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_06_steering.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_06_steering.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_06_steering.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_07_idle.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_07_idle.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_07_idle.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_07_idle.png diff --git a/doc/nrf/images/zigbee_signal_handler_07_idle.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_07_idle.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_07_idle.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_07_idle.svg diff --git a/doc/nrf/images/zigbee_signal_handler_07_idle.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_07_idle.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_07_idle.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_07_idle.uml diff --git a/doc/nrf/images/zigbee_signal_handler_07_idle.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_07_idle.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_07_idle.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_07_idle.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_08_deep_sleep.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_08_deep_sleep.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_08_deep_sleep.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_08_deep_sleep.png diff --git a/doc/nrf/images/zigbee_signal_handler_08_deep_sleep.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_08_deep_sleep.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_08_deep_sleep.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_08_deep_sleep.svg diff --git a/doc/nrf/images/zigbee_signal_handler_08_deep_sleep.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_08_deep_sleep.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_08_deep_sleep.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_08_deep_sleep.uml diff --git a/doc/nrf/images/zigbee_signal_handler_08_deep_sleep.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_08_deep_sleep.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_08_deep_sleep.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_08_deep_sleep.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_09_leave.png b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_09_leave.png similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_09_leave.png rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_09_leave.png diff --git a/doc/nrf/images/zigbee_signal_handler_09_leave.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_09_leave.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_09_leave.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_09_leave.svg diff --git a/doc/nrf/images/zigbee_signal_handler_09_leave.uml b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_09_leave.uml similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_09_leave.uml rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_09_leave.uml diff --git a/doc/nrf/images/zigbee_signal_handler_09_leave.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_09_leave.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_09_leave.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_09_leave.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_10_rejoin.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin.svg diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_10_rejoin.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin_stop.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin_stop.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_10_rejoin_stop.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin_stop.svg diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin_stop.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin_stop.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_10_rejoin_stop.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin_stop.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin_user_input.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin_user_input.svg diff --git a/doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin_user_input.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_10_rejoin_user_input.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_10_rejoin_user_input.vsdx diff --git a/doc/nrf/images/zigbee_signal_handler_overview.svg b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_overview.svg similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_overview.svg rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_overview.svg diff --git a/doc/nrf/images/zigbee_signal_handler_overview.vsdx b/doc/nrf/libraries/zigbee/images/zigbee_signal_handler_overview.vsdx similarity index 100% rename from doc/nrf/images/zigbee_signal_handler_overview.vsdx rename to doc/nrf/libraries/zigbee/images/zigbee_signal_handler_overview.vsdx diff --git a/doc/nrf/libraries/zigbee/index.rst b/doc/nrf/libraries/zigbee/index.rst index 2b5a20a7bacf..87f9d9d6c9aa 100644 --- a/doc/nrf/libraries/zigbee/index.rst +++ b/doc/nrf/libraries/zigbee/index.rst @@ -17,4 +17,3 @@ For information on how to use the supplied libraries, see :ref:`ug_zigbee_config :caption: Subpages: * - ../../../include/zigbee/* diff --git a/include/zigbee/zigbee_app_utils.rst b/doc/nrf/libraries/zigbee/zigbee_app_utils.rst similarity index 96% rename from include/zigbee/zigbee_app_utils.rst rename to doc/nrf/libraries/zigbee/zigbee_app_utils.rst index 62d4abb2bca2..f18fd0429e71 100644 --- a/include/zigbee/zigbee_app_utils.rst +++ b/doc/nrf/libraries/zigbee/zigbee_app_utils.rst @@ -135,7 +135,7 @@ Complete zigbee_default_signal_handler implementation In its complete implementation, the `zboss_signal_handler()`_ allows the application to control a broader set of basic functionalities, including joining, commissioning, and network formation. -.. figure:: /images/zigbee_signal_handler_overview.svg +.. figure:: images/zigbee_signal_handler_overview.svg :alt: Zigbee default signal handler logic (simplified) Zigbee default signal handler logic (simplified) @@ -156,14 +156,14 @@ The reception of these signals determines the behavior of the default signal han * Upon reception of `ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY`_, the default signal handler prints out a log with the signal status, and then exits. -.. figure:: /images/zigbee_signal_handler_01_production_config.svg +.. figure:: images/zigbee_signal_handler_01_production_config.svg :alt: ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY signal handler ZB_ZDO_SIGNAL_PRODUCTION_CONFIG_READY signal handler * Upon reception of `ZB_ZDO_SIGNAL_SKIP_STARTUP`_ signal, the default signal handler performs the BDB initialization procedure, and then exits. -.. figure:: /images/zigbee_signal_handler_02_startup.svg +.. figure:: images/zigbee_signal_handler_02_startup.svg :alt: ZB_ZDO_SIGNAL_SKIP_STARTUP signal handler ZB_ZDO_SIGNAL_SKIP_STARTUP signal handler @@ -200,7 +200,7 @@ For factory new devices, the default signal handler performs the following actio Once handling of the signal is finished, the stack generates the `ZB_BDB_SIGNAL_STEERING`_ signal, and continues to :ref:`zarco_signal_handler_network`. -.. figure:: /images/zigbee_signal_handler_03_first_start.svg +.. figure:: images/zigbee_signal_handler_03_first_start.svg :alt: Scenario for factory new devices (ZB_BDB_SIGNAL_DEVICE_FIRST_START) Scenario for factory new devices (ZB_BDB_SIGNAL_DEVICE_FIRST_START) @@ -225,7 +225,7 @@ For devices that have been already commissioned, the default handler performs th Once finished, the stack generates the `ZB_BDB_SIGNAL_STEERING`_ signal, and continues to :ref:`zarco_signal_handler_network`. -.. figure:: /images/zigbee_signal_handler_04_reboot.svg +.. figure:: images/zigbee_signal_handler_04_reboot.svg :alt: Scenario for already commissioned devices (ZB_BDB_SIGNAL_DEVICE_REBOOT) Scenario for already commissioned devices (ZB_BDB_SIGNAL_DEVICE_REBOOT) @@ -240,7 +240,7 @@ According to the logic implemented inside the default signal handler, the device 1. Coordinators first form a network. Attempts to form the network continue infinitely, with a one-second delay between each attempt. - .. figure:: /images/zigbee_signal_handler_05_formation.svg + .. figure:: images/zigbee_signal_handler_05_formation.svg :alt: Forming a network following the generation of ZB_BDB_SIGNAL_FORMATION Forming a network following the generation of ZB_BDB_SIGNAL_FORMATION @@ -251,7 +251,7 @@ According to the logic implemented inside the default signal handler, the device * When a device has joined and :ref:`zarco_network_rejoin` is running, the procedure is cancelled. * If no device has joined and the procedure is not running, the procedure is started. - .. figure:: /images/zigbee_signal_handler_06_steering.svg + .. figure:: images/zigbee_signal_handler_06_steering.svg :alt: Forming a network following the generation of ZB_BDB_SIGNAL_STEERING Forming a network following the generation of ZB_BDB_SIGNAL_STEERING @@ -266,7 +266,7 @@ When leaving the network, the default handler calls :c:func:`start_network_rejoi Once :c:func:`start_network_rejoin` is called, the stack generates the `ZB_BDB_SIGNAL_STEERING`_ signal and continues to :ref:`zarco_signal_handler_network`. -.. figure:: /images/zigbee_signal_handler_09_leave.svg +.. figure:: images/zigbee_signal_handler_09_leave.svg :alt: Leaving the network following ZB_ZDO_SIGNAL_LEAVE Leaving the network following ZB_ZDO_SIGNAL_LEAVE @@ -287,14 +287,14 @@ The period is limited to the time specified in ``REJOIN_INTERVAL_MAX_S``, which When :c:func:`start_network_rejoin` is called, the rejoin procedure is started. -.. figure:: /images/zigbee_signal_handler_10_rejoin.svg +.. figure:: images/zigbee_signal_handler_10_rejoin.svg :alt: Starting the rejoin procedure Starting the rejoin procedure When ``stop_network_rejoin(was_scheduled)`` is called, the network rejoin is canceled and the alarms scheduled by :c:func:`start_network_rejoin` are canceled. -.. figure:: /images/zigbee_signal_handler_10_rejoin_stop.svg +.. figure:: images/zigbee_signal_handler_10_rejoin_stop.svg :alt: Stopping the rejoin procedure Stopping the rejoin procedure @@ -314,7 +314,7 @@ The rejoin procedure is different for routers and end devices in the following a :c:func:`user_input_indicate` restarts the rejoin procedure if the device did not join the network and is not trying to join a network. It is safe to call this function from an interrupt and to call it multiple times. - .. figure:: /images/zigbee_signal_handler_10_rejoin_user_input.svg + .. figure:: images/zigbee_signal_handler_10_rejoin_user_input.svg :alt: User input restarting the the rejoin procedure User input restarting the the rejoin procedure @@ -335,7 +335,7 @@ The minimal inactivity duration that causes the signal to be generated is define By default, the inactivity duration equals approximately 15 ms. The value can be modified by the ``zb_sleep_set_threshold`` API. -.. figure:: /images/zigbee_signal_handler_07_idle.svg +.. figure:: images/zigbee_signal_handler_07_idle.svg :alt: Generation of the ZB_COMMON_SIGNAL_CAN_SLEEP signal Generation of the ZB_COMMON_SIGNAL_CAN_SLEEP signal @@ -350,7 +350,7 @@ If so, it allows the Zigbee stack to enter the sleep state and suspend the Zigbe If the default behavior is not applicable for the application, you can customize the sleep functionality by overwriting the :c:func:`zb_osif_sleep` weak function and implementing a custom logic for handling the stack sleep state. -.. figure:: /images/zigbee_signal_handler_08_deep_sleep.svg +.. figure:: images/zigbee_signal_handler_08_deep_sleep.svg :alt: Implementing a custom logic for putting the stack into the sleep mode Implementing a custom logic for putting the stack into the sleep mode diff --git a/include/zigbee/zigbee_error_handler.rst b/doc/nrf/libraries/zigbee/zigbee_error_handler.rst similarity index 100% rename from include/zigbee/zigbee_error_handler.rst rename to doc/nrf/libraries/zigbee/zigbee_error_handler.rst diff --git a/include/zigbee/zigbee_fota.rst b/doc/nrf/libraries/zigbee/zigbee_fota.rst similarity index 100% rename from include/zigbee/zigbee_fota.rst rename to doc/nrf/libraries/zigbee/zigbee_fota.rst diff --git a/include/zigbee/zigbee_logger_eprxzcl.rst b/doc/nrf/libraries/zigbee/zigbee_logger_eprxzcl.rst similarity index 100% rename from include/zigbee/zigbee_logger_eprxzcl.rst rename to doc/nrf/libraries/zigbee/zigbee_logger_eprxzcl.rst diff --git a/include/zigbee/zigbee_zcl_scenes.rst b/doc/nrf/libraries/zigbee/zigbee_zcl_scenes.rst similarity index 100% rename from include/zigbee/zigbee_zcl_scenes.rst rename to doc/nrf/libraries/zigbee/zigbee_zcl_scenes.rst diff --git a/doc/nrf/ug_zigbee_tools.rst b/doc/nrf/ug_zigbee_tools.rst index 40db7fc37be4..b25eaf2024c5 100644 --- a/doc/nrf/ug_zigbee_tools.rst +++ b/doc/nrf/ug_zigbee_tools.rst @@ -38,7 +38,7 @@ The tool is available for download as a standalone :file:`zip` package using the Zigbee endpoint logger ********************** -.. include:: ../../include/zigbee/zigbee_logger_eprxzcl.rst +.. include:: libraries/zigbee/zigbee_logger_eprxzcl.rst :start-after: zigbee_logger_endpoint_intro_start :end-before: zigbee_logger_endpoint_intro_end From 3aad6dd7a56651c7de0702bfed9d316e2ef0ec87 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 17:29:35 +0200 Subject: [PATCH 043/126] doc: nrf: move other libraries to doc folder Mode all 'other' libraries docs to doc folder. Signed-off-by: Gerard Marull-Paretas --- {include => doc/nrf/libraries/others}/bl_crypto.rst | 0 .../nrf/libraries/others}/bl_storage.rst | 0 .../nrf/libraries/others}/bl_validation.rst | 0 {include => doc/nrf/libraries/others}/date_time.rst | 0 .../nrf/libraries/others}/dk_buttons_and_leds.rst | 0 .../nrf/libraries/others}/ei_wrapper.rst | 0 {include => doc/nrf/libraries/others}/esb.rst | 0 .../nrf/libraries/others}/event_manager.rst | 2 +- {include => doc/nrf/libraries/others}/fprotect.rst | 0 {include => doc/nrf/libraries/others}/fw_info.rst | 0 .../nrf/libraries/others}/hw_unique_key.rst | 0 .../{ => libraries/others}/images/em_overview.svg | 0 .../{ => libraries/others}/images/em_overview.vsdx | Bin doc/nrf/{ => libraries/others}/images/supl_msc.svg | 0 doc/nrf/libraries/others/index.rst | 2 +- .../nrf/libraries/others}/memfault_ncs.rst | 0 {include => doc/nrf/libraries/others}/profiler.rst | 0 {include => doc/nrf/libraries/others}/ram_pwrdn.rst | 0 .../nrf/libraries/others}/secure_services.rst | 0 {include => doc/nrf/libraries/others}/spm.rst | 0 .../nrf/libraries/others}/st25r3911b_nfc.rst | 0 .../nrf/libraries/others}/supl_os_client.rst | 2 +- samples/nrf9160/memfault/README.rst | 2 +- 23 files changed, 4 insertions(+), 4 deletions(-) rename {include => doc/nrf/libraries/others}/bl_crypto.rst (100%) rename {include => doc/nrf/libraries/others}/bl_storage.rst (100%) rename {include => doc/nrf/libraries/others}/bl_validation.rst (100%) rename {include => doc/nrf/libraries/others}/date_time.rst (100%) rename {include => doc/nrf/libraries/others}/dk_buttons_and_leds.rst (100%) rename {include => doc/nrf/libraries/others}/ei_wrapper.rst (100%) rename {include => doc/nrf/libraries/others}/esb.rst (100%) rename {include => doc/nrf/libraries/others}/event_manager.rst (99%) rename {include => doc/nrf/libraries/others}/fprotect.rst (100%) rename {include => doc/nrf/libraries/others}/fw_info.rst (100%) rename {include => doc/nrf/libraries/others}/hw_unique_key.rst (100%) rename doc/nrf/{ => libraries/others}/images/em_overview.svg (100%) rename doc/nrf/{ => libraries/others}/images/em_overview.vsdx (100%) rename doc/nrf/{ => libraries/others}/images/supl_msc.svg (100%) rename {include => doc/nrf/libraries/others}/memfault_ncs.rst (100%) rename {include => doc/nrf/libraries/others}/profiler.rst (100%) rename {include => doc/nrf/libraries/others}/ram_pwrdn.rst (100%) rename {include => doc/nrf/libraries/others}/secure_services.rst (100%) rename {include => doc/nrf/libraries/others}/spm.rst (100%) rename {include => doc/nrf/libraries/others}/st25r3911b_nfc.rst (100%) rename {include => doc/nrf/libraries/others}/supl_os_client.rst (99%) diff --git a/include/bl_crypto.rst b/doc/nrf/libraries/others/bl_crypto.rst similarity index 100% rename from include/bl_crypto.rst rename to doc/nrf/libraries/others/bl_crypto.rst diff --git a/include/bl_storage.rst b/doc/nrf/libraries/others/bl_storage.rst similarity index 100% rename from include/bl_storage.rst rename to doc/nrf/libraries/others/bl_storage.rst diff --git a/include/bl_validation.rst b/doc/nrf/libraries/others/bl_validation.rst similarity index 100% rename from include/bl_validation.rst rename to doc/nrf/libraries/others/bl_validation.rst diff --git a/include/date_time.rst b/doc/nrf/libraries/others/date_time.rst similarity index 100% rename from include/date_time.rst rename to doc/nrf/libraries/others/date_time.rst diff --git a/include/dk_buttons_and_leds.rst b/doc/nrf/libraries/others/dk_buttons_and_leds.rst similarity index 100% rename from include/dk_buttons_and_leds.rst rename to doc/nrf/libraries/others/dk_buttons_and_leds.rst diff --git a/include/ei_wrapper.rst b/doc/nrf/libraries/others/ei_wrapper.rst similarity index 100% rename from include/ei_wrapper.rst rename to doc/nrf/libraries/others/ei_wrapper.rst diff --git a/include/esb.rst b/doc/nrf/libraries/others/esb.rst similarity index 100% rename from include/esb.rst rename to doc/nrf/libraries/others/esb.rst diff --git a/include/event_manager.rst b/doc/nrf/libraries/others/event_manager.rst similarity index 99% rename from include/event_manager.rst rename to doc/nrf/libraries/others/event_manager.rst index 63e22f2add80..eaae2a45a3f3 100644 --- a/include/event_manager.rst +++ b/doc/nrf/libraries/others/event_manager.rst @@ -11,7 +11,7 @@ The Event Manager is a piece of software that supports development of consistent In an event-based application, parts of the application functionality are separated into isolated modules that communicate with each other using events. Events are submitted by modules and other modules can subscribe and react to them. -.. figure:: ../doc/nrf/images/em_overview.svg +.. figure:: images/em_overview.svg :alt: Architecture of an application based on Event Manager For a usage example of the Event Manger module and event structure in the |NCS|, see the :ref:`lib_caf` (CAF). diff --git a/include/fprotect.rst b/doc/nrf/libraries/others/fprotect.rst similarity index 100% rename from include/fprotect.rst rename to doc/nrf/libraries/others/fprotect.rst diff --git a/include/fw_info.rst b/doc/nrf/libraries/others/fw_info.rst similarity index 100% rename from include/fw_info.rst rename to doc/nrf/libraries/others/fw_info.rst diff --git a/include/hw_unique_key.rst b/doc/nrf/libraries/others/hw_unique_key.rst similarity index 100% rename from include/hw_unique_key.rst rename to doc/nrf/libraries/others/hw_unique_key.rst diff --git a/doc/nrf/images/em_overview.svg b/doc/nrf/libraries/others/images/em_overview.svg similarity index 100% rename from doc/nrf/images/em_overview.svg rename to doc/nrf/libraries/others/images/em_overview.svg diff --git a/doc/nrf/images/em_overview.vsdx b/doc/nrf/libraries/others/images/em_overview.vsdx similarity index 100% rename from doc/nrf/images/em_overview.vsdx rename to doc/nrf/libraries/others/images/em_overview.vsdx diff --git a/doc/nrf/images/supl_msc.svg b/doc/nrf/libraries/others/images/supl_msc.svg similarity index 100% rename from doc/nrf/images/supl_msc.svg rename to doc/nrf/libraries/others/images/supl_msc.svg diff --git a/doc/nrf/libraries/others/index.rst b/doc/nrf/libraries/others/index.rst index 401365be714e..e21a41e93766 100644 --- a/doc/nrf/libraries/others/index.rst +++ b/doc/nrf/libraries/others/index.rst @@ -8,4 +8,4 @@ Other libraries :glob: :caption: Subpages: - ../../../include/* + * diff --git a/include/memfault_ncs.rst b/doc/nrf/libraries/others/memfault_ncs.rst similarity index 100% rename from include/memfault_ncs.rst rename to doc/nrf/libraries/others/memfault_ncs.rst diff --git a/include/profiler.rst b/doc/nrf/libraries/others/profiler.rst similarity index 100% rename from include/profiler.rst rename to doc/nrf/libraries/others/profiler.rst diff --git a/include/ram_pwrdn.rst b/doc/nrf/libraries/others/ram_pwrdn.rst similarity index 100% rename from include/ram_pwrdn.rst rename to doc/nrf/libraries/others/ram_pwrdn.rst diff --git a/include/secure_services.rst b/doc/nrf/libraries/others/secure_services.rst similarity index 100% rename from include/secure_services.rst rename to doc/nrf/libraries/others/secure_services.rst diff --git a/include/spm.rst b/doc/nrf/libraries/others/spm.rst similarity index 100% rename from include/spm.rst rename to doc/nrf/libraries/others/spm.rst diff --git a/include/st25r3911b_nfc.rst b/doc/nrf/libraries/others/st25r3911b_nfc.rst similarity index 100% rename from include/st25r3911b_nfc.rst rename to doc/nrf/libraries/others/st25r3911b_nfc.rst diff --git a/include/supl_os_client.rst b/doc/nrf/libraries/others/supl_os_client.rst similarity index 99% rename from include/supl_os_client.rst rename to doc/nrf/libraries/others/supl_os_client.rst index db0f80cefaba..75a1c979076c 100644 --- a/include/supl_os_client.rst +++ b/doc/nrf/libraries/others/supl_os_client.rst @@ -159,7 +159,7 @@ It is assumed that the GNSS socket is already available. The following message sequence chart (MSC) describes the flow of communication in a SUPL session. -.. figure:: /images/supl_msc.svg +.. figure:: images/supl_msc.svg :alt: SUPL Session MSC .. _supl_session_msc_desc: diff --git a/samples/nrf9160/memfault/README.rst b/samples/nrf9160/memfault/README.rst index b6d598cabe78..e2fc09e22c31 100644 --- a/samples/nrf9160/memfault/README.rst +++ b/samples/nrf9160/memfault/README.rst @@ -140,7 +140,7 @@ If :option:`CONFIG_MEMFAULT_NCS_INTERNAL_FLASH_BACKED_COREDUMP` is enabled, :opt Configuration files =================== -.. include:: ../../../include/memfault_ncs.rst +.. include:: ../../../doc/nrf/libraries/others/memfault_ncs.rst :start-after: memfault_config_files_start :end-before: memfault_config_files_end From 9ef51ef0078b5ee1ec2a2ce4ee783adbb919e241 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 17:50:53 +0200 Subject: [PATCH 044/126] doc: nrf: move nfc docs to doc folder Move all nfc docs to the doc folder. Signed-off-by: Gerard Marull-Paretas --- doc/nrf/libraries/nfc/index.rst | 2 +- .../nrf/libraries}/nfc/ndef/ch_msg.rst | 2 +- .../nrf/libraries}/nfc/ndef/ch_rec_parser.rst | 2 +- .../nfc/{ndef.rst => ndef/index.rst} | 2 +- .../nrf/libraries}/nfc/ndef/le_oob_rec.rst | 0 .../libraries}/nfc/ndef/le_oob_rec_parser.rst | 2 +- .../nrf/libraries}/nfc/ndef/msg.rst | 0 .../nrf/libraries}/nfc/ndef/msg_parser.rst | 0 .../nrf/libraries}/nfc/ndef/text_rec.rst | 0 .../nrf/libraries}/nfc/ndef/uri_msg.rst | 0 .../libraries/nfc/{t2t.rst => t2t/index.rst} | 2 +- .../nrf/libraries}/nfc/t2t/t2t_parser.rst | 0 .../nrf/libraries}/nfc/t4t/apdu.rst | 0 .../nrf/libraries}/nfc/t4t/cc_file.rst | 0 .../nrf/libraries}/nfc/t4t/hl_procedure.rst | 0 .../libraries/nfc/{t4t.rst => t4t/index.rst} | 2 +- .../nrf/libraries}/nfc/t4t/isodep.rst | 0 .../nrf/libraries}/nfc/t4t/ndef_file.rst | 2 +- .../nrf/libraries}/nfc/tnep/ch.rst | 8 +- .../nfc_negotiated_connection_handover.svg | 0 .../nfc_negotiated_connection_handover.vsdx | Bin .../images/nfc_static_connection_handover.svg | 0 .../nfc_static_connection_handover.vsdx | Bin .../nfc/{tnep.rst => tnep/index.rst} | 2 +- .../nrf/libraries}/nfc/tnep/poller.rst | 0 .../nrf/libraries}/nfc/tnep/tag.rst | 6 +- .../bluetooth/central_nfc_pairing/README.rst | 4 +- .../nfc_negotiated_connection_handover.svg | 591 ++++++++++++++++++ .../nfc_negotiated_connection_handover.vsdx | Bin 0 -> 25210 bytes .../images/nfc_static_connection_handover.svg | 508 +++++++++++++++ .../nfc_static_connection_handover.vsdx | Bin 0 -> 23083 bytes .../peripheral_nfc_pairing/README.rst | 4 +- .../nfc_negotiated_connection_handover.svg | 591 ++++++++++++++++++ .../nfc_negotiated_connection_handover.vsdx | Bin 0 -> 25210 bytes .../images/nfc_static_connection_handover.svg | 508 +++++++++++++++ .../nfc_static_connection_handover.vsdx | Bin 0 -> 23083 bytes 36 files changed, 2218 insertions(+), 20 deletions(-) rename {include => doc/nrf/libraries}/nfc/ndef/ch_msg.rst (95%) rename {include => doc/nrf/libraries}/nfc/ndef/ch_rec_parser.rst (95%) rename doc/nrf/libraries/nfc/{ndef.rst => ndef/index.rst} (96%) rename {include => doc/nrf/libraries}/nfc/ndef/le_oob_rec.rst (100%) rename {include => doc/nrf/libraries}/nfc/ndef/le_oob_rec_parser.rst (95%) rename {include => doc/nrf/libraries}/nfc/ndef/msg.rst (100%) rename {include => doc/nrf/libraries}/nfc/ndef/msg_parser.rst (100%) rename {include => doc/nrf/libraries}/nfc/ndef/text_rec.rst (100%) rename {include => doc/nrf/libraries}/nfc/ndef/uri_msg.rst (100%) rename doc/nrf/libraries/nfc/{t2t.rst => t2t/index.rst} (94%) rename {include => doc/nrf/libraries}/nfc/t2t/t2t_parser.rst (100%) rename {include => doc/nrf/libraries}/nfc/t4t/apdu.rst (100%) rename {include => doc/nrf/libraries}/nfc/t4t/cc_file.rst (100%) rename {include => doc/nrf/libraries}/nfc/t4t/hl_procedure.rst (100%) rename doc/nrf/libraries/nfc/{t4t.rst => t4t/index.rst} (94%) rename {include => doc/nrf/libraries}/nfc/t4t/isodep.rst (100%) rename {include => doc/nrf/libraries}/nfc/t4t/ndef_file.rst (90%) rename {include => doc/nrf/libraries}/nfc/tnep/ch.rst (92%) rename doc/nrf/{ => libraries/nfc/tnep}/images/nfc_negotiated_connection_handover.svg (100%) rename doc/nrf/{ => libraries/nfc/tnep}/images/nfc_negotiated_connection_handover.vsdx (100%) rename doc/nrf/{ => libraries/nfc/tnep}/images/nfc_static_connection_handover.svg (100%) rename doc/nrf/{ => libraries/nfc/tnep}/images/nfc_static_connection_handover.vsdx (100%) rename doc/nrf/libraries/nfc/{tnep.rst => tnep/index.rst} (94%) rename {include => doc/nrf/libraries}/nfc/tnep/poller.rst (100%) rename {include => doc/nrf/libraries}/nfc/tnep/tag.rst (96%) create mode 100644 samples/bluetooth/central_nfc_pairing/images/nfc_negotiated_connection_handover.svg create mode 100644 samples/bluetooth/central_nfc_pairing/images/nfc_negotiated_connection_handover.vsdx create mode 100644 samples/bluetooth/central_nfc_pairing/images/nfc_static_connection_handover.svg create mode 100644 samples/bluetooth/central_nfc_pairing/images/nfc_static_connection_handover.vsdx create mode 100644 samples/bluetooth/peripheral_nfc_pairing/images/nfc_negotiated_connection_handover.svg create mode 100644 samples/bluetooth/peripheral_nfc_pairing/images/nfc_negotiated_connection_handover.vsdx create mode 100644 samples/bluetooth/peripheral_nfc_pairing/images/nfc_static_connection_handover.svg create mode 100644 samples/bluetooth/peripheral_nfc_pairing/images/nfc_static_connection_handover.vsdx diff --git a/doc/nrf/libraries/nfc/index.rst b/doc/nrf/libraries/nfc/index.rst index 2585f6f00079..c8ad672446bc 100644 --- a/doc/nrf/libraries/nfc/index.rst +++ b/doc/nrf/libraries/nfc/index.rst @@ -12,4 +12,4 @@ See the :ref:`ug_nfc` user guide for an overview of the technology and informati :glob: :caption: Subpages: - * + **/index diff --git a/include/nfc/ndef/ch_msg.rst b/doc/nrf/libraries/nfc/ndef/ch_msg.rst similarity index 95% rename from include/nfc/ndef/ch_msg.rst rename to doc/nrf/libraries/nfc/ndef/ch_msg.rst index 785d8553949e..4ac67937e018 100644 --- a/include/nfc/ndef/ch_msg.rst +++ b/doc/nrf/libraries/nfc/ndef/ch_msg.rst @@ -41,7 +41,7 @@ This library is used in the :ref:`peripheral_nfc_pairing` sample. The following code sample demonstrates how to create a Handover Select message with one Alternative Carrier record that has a reference to the :ref:`Bluetooth LE OOB record `: -.. literalinclude:: ../../../samples/bluetooth/peripheral_nfc_pairing/src/main.c +.. literalinclude:: ../../../../../samples/bluetooth/peripheral_nfc_pairing/src/main.c :language: c :start-after: include_startingpoint_pair_msg_rst :end-before: include_endpoint_pair_msg_rst diff --git a/include/nfc/ndef/ch_rec_parser.rst b/doc/nrf/libraries/nfc/ndef/ch_rec_parser.rst similarity index 95% rename from include/nfc/ndef/ch_rec_parser.rst rename to doc/nrf/libraries/nfc/ndef/ch_rec_parser.rst index 597c66a93316..c192c5d822b5 100644 --- a/include/nfc/ndef/ch_rec_parser.rst +++ b/doc/nrf/libraries/nfc/ndef/ch_rec_parser.rst @@ -19,7 +19,7 @@ This library should be used together with the :ref:`nfc_ndef_parser_readme` in t The following code sample demonstrates how to use this module: -.. literalinclude:: ../../../samples/nfc/tag_reader/src/main.c +.. literalinclude:: ../../../../../samples/nfc/tag_reader/src/main.c :language: c :start-after: include_startingpoint_ch_rec_parser_rst :end-before: include_endpoint_ch_rec_parser_rst diff --git a/doc/nrf/libraries/nfc/ndef.rst b/doc/nrf/libraries/nfc/ndef/index.rst similarity index 96% rename from doc/nrf/libraries/nfc/ndef.rst rename to doc/nrf/libraries/nfc/ndef/index.rst index da7d61b40cc4..4ee13f575f65 100644 --- a/doc/nrf/libraries/nfc/ndef.rst +++ b/doc/nrf/libraries/nfc/ndef/index.rst @@ -26,4 +26,4 @@ The NFC NDEF libraries are used in the following samples: :glob: :caption: Subpages: - ../../include/nfc/ndef/* + * diff --git a/include/nfc/ndef/le_oob_rec.rst b/doc/nrf/libraries/nfc/ndef/le_oob_rec.rst similarity index 100% rename from include/nfc/ndef/le_oob_rec.rst rename to doc/nrf/libraries/nfc/ndef/le_oob_rec.rst diff --git a/include/nfc/ndef/le_oob_rec_parser.rst b/doc/nrf/libraries/nfc/ndef/le_oob_rec_parser.rst similarity index 95% rename from include/nfc/ndef/le_oob_rec_parser.rst rename to doc/nrf/libraries/nfc/ndef/le_oob_rec_parser.rst index 881f31c8235a..2274da4c367c 100644 --- a/include/nfc/ndef/le_oob_rec_parser.rst +++ b/doc/nrf/libraries/nfc/ndef/le_oob_rec_parser.rst @@ -18,7 +18,7 @@ This library should be used together with the :ref:`nfc_ndef_parser_readme` in t The following code sample demonstrates how to use this module: -.. literalinclude:: ../../../samples/nfc/tag_reader/src/main.c +.. literalinclude:: ../../../../../samples/nfc/tag_reader/src/main.c :language: c :start-after: include_startingpoint_le_oob_rec_parser_rst :end-before: include_endpoint_le_oob_rec_parser_rst diff --git a/include/nfc/ndef/msg.rst b/doc/nrf/libraries/nfc/ndef/msg.rst similarity index 100% rename from include/nfc/ndef/msg.rst rename to doc/nrf/libraries/nfc/ndef/msg.rst diff --git a/include/nfc/ndef/msg_parser.rst b/doc/nrf/libraries/nfc/ndef/msg_parser.rst similarity index 100% rename from include/nfc/ndef/msg_parser.rst rename to doc/nrf/libraries/nfc/ndef/msg_parser.rst diff --git a/include/nfc/ndef/text_rec.rst b/doc/nrf/libraries/nfc/ndef/text_rec.rst similarity index 100% rename from include/nfc/ndef/text_rec.rst rename to doc/nrf/libraries/nfc/ndef/text_rec.rst diff --git a/include/nfc/ndef/uri_msg.rst b/doc/nrf/libraries/nfc/ndef/uri_msg.rst similarity index 100% rename from include/nfc/ndef/uri_msg.rst rename to doc/nrf/libraries/nfc/ndef/uri_msg.rst diff --git a/doc/nrf/libraries/nfc/t2t.rst b/doc/nrf/libraries/nfc/t2t/index.rst similarity index 94% rename from doc/nrf/libraries/nfc/t2t.rst rename to doc/nrf/libraries/nfc/t2t/index.rst index 99d63c03e919..b59e83356bfd 100644 --- a/doc/nrf/libraries/nfc/t2t.rst +++ b/doc/nrf/libraries/nfc/t2t/index.rst @@ -16,4 +16,4 @@ Note that these require an NFC polling device. :glob: :caption: Subpages: - ../../include/nfc/t2t/* + * diff --git a/include/nfc/t2t/t2t_parser.rst b/doc/nrf/libraries/nfc/t2t/t2t_parser.rst similarity index 100% rename from include/nfc/t2t/t2t_parser.rst rename to doc/nrf/libraries/nfc/t2t/t2t_parser.rst diff --git a/include/nfc/t4t/apdu.rst b/doc/nrf/libraries/nfc/t4t/apdu.rst similarity index 100% rename from include/nfc/t4t/apdu.rst rename to doc/nrf/libraries/nfc/t4t/apdu.rst diff --git a/include/nfc/t4t/cc_file.rst b/doc/nrf/libraries/nfc/t4t/cc_file.rst similarity index 100% rename from include/nfc/t4t/cc_file.rst rename to doc/nrf/libraries/nfc/t4t/cc_file.rst diff --git a/include/nfc/t4t/hl_procedure.rst b/doc/nrf/libraries/nfc/t4t/hl_procedure.rst similarity index 100% rename from include/nfc/t4t/hl_procedure.rst rename to doc/nrf/libraries/nfc/t4t/hl_procedure.rst diff --git a/doc/nrf/libraries/nfc/t4t.rst b/doc/nrf/libraries/nfc/t4t/index.rst similarity index 94% rename from doc/nrf/libraries/nfc/t4t.rst rename to doc/nrf/libraries/nfc/t4t/index.rst index 2203a105be73..b5f8a154a62a 100644 --- a/doc/nrf/libraries/nfc/t4t.rst +++ b/doc/nrf/libraries/nfc/t4t/index.rst @@ -17,4 +17,4 @@ Note that these require an NFC polling device. :glob: :caption: Subpages: - ../../include/nfc/t4t/* + * diff --git a/include/nfc/t4t/isodep.rst b/doc/nrf/libraries/nfc/t4t/isodep.rst similarity index 100% rename from include/nfc/t4t/isodep.rst rename to doc/nrf/libraries/nfc/t4t/isodep.rst diff --git a/include/nfc/t4t/ndef_file.rst b/doc/nrf/libraries/nfc/t4t/ndef_file.rst similarity index 90% rename from include/nfc/t4t/ndef_file.rst rename to doc/nrf/libraries/nfc/t4t/ndef_file.rst index 0e43e67d2aba..63af5849eb34 100644 --- a/include/nfc/t4t/ndef_file.rst +++ b/doc/nrf/libraries/nfc/t4t/ndef_file.rst @@ -13,7 +13,7 @@ To generate an NDEF message, you can use the :ref:`nfc_ndef_msg` and :ref:`nfc_n The following code sample demonstrates how to encode the NDEF file for NFC Type 4 Tag: -.. literalinclude:: ../../../samples/nfc/writable_ndef_msg/src/ndef_file_m.c +.. literalinclude:: ../../../../../samples/nfc/writable_ndef_msg/src/ndef_file_m.c :language: c :start-after: include_startingpoint_ndef_file_rst :end-before: include_endpoint_ndef_file_rst diff --git a/include/nfc/tnep/ch.rst b/doc/nrf/libraries/nfc/tnep/ch.rst similarity index 92% rename from include/nfc/tnep/ch.rst rename to doc/nrf/libraries/nfc/tnep/ch.rst index 748efe47f10a..ea28df475fd6 100644 --- a/include/nfc/tnep/ch.rst +++ b/doc/nrf/libraries/nfc/tnep/ch.rst @@ -28,7 +28,7 @@ Static handover In the static handover, the Handover Requester only reads a Handover Select Message from the NFC Tag Device. TNEP is not used in this communication form. -.. figure:: /images/nfc_static_connection_handover.svg +.. figure:: images/nfc_static_connection_handover.svg :alt: Static handover Negotiated handover @@ -38,7 +38,7 @@ In the negotiated handover, the Handover Requester provides a Handover Request M The Handover Selector replies with a Handover Select Message that contains the list of carriers that they both support. Connection Handover NDEF messages are exchanged as defined by TNEP. -.. figure:: /images/nfc_negotiated_connection_handover.svg +.. figure:: images/nfc_negotiated_connection_handover.svg :alt: Negotiated handover Device Role @@ -62,7 +62,7 @@ NFC Tag Device The following code sample demonstrates how to use this module with an NFC Tag Device: -.. literalinclude:: ../../../samples/bluetooth/peripheral_nfc_pairing/src/main.c +.. literalinclude:: ../../../../../samples/bluetooth/peripheral_nfc_pairing/src/main.c :language: c :start-after: include_startingpoint_nfc_tnep_ch_tag_rst :end-before: include_endpoint_nfc_tnep_ch_tag_rst @@ -74,7 +74,7 @@ NFC Poller Device The following code sample demonstrates how to use this module with an NFC Poller Device: -.. literalinclude:: ../../../samples/bluetooth/central_nfc_pairing/src/main.c +.. literalinclude:: ../../../../../samples/bluetooth/central_nfc_pairing/src/main.c :language: c :start-after: include_startingpoint_nfc_tnep_ch_poller_rst :end-before: include_endpoint_nfc_tnep_ch_poller_rst diff --git a/doc/nrf/images/nfc_negotiated_connection_handover.svg b/doc/nrf/libraries/nfc/tnep/images/nfc_negotiated_connection_handover.svg similarity index 100% rename from doc/nrf/images/nfc_negotiated_connection_handover.svg rename to doc/nrf/libraries/nfc/tnep/images/nfc_negotiated_connection_handover.svg diff --git a/doc/nrf/images/nfc_negotiated_connection_handover.vsdx b/doc/nrf/libraries/nfc/tnep/images/nfc_negotiated_connection_handover.vsdx similarity index 100% rename from doc/nrf/images/nfc_negotiated_connection_handover.vsdx rename to doc/nrf/libraries/nfc/tnep/images/nfc_negotiated_connection_handover.vsdx diff --git a/doc/nrf/images/nfc_static_connection_handover.svg b/doc/nrf/libraries/nfc/tnep/images/nfc_static_connection_handover.svg similarity index 100% rename from doc/nrf/images/nfc_static_connection_handover.svg rename to doc/nrf/libraries/nfc/tnep/images/nfc_static_connection_handover.svg diff --git a/doc/nrf/images/nfc_static_connection_handover.vsdx b/doc/nrf/libraries/nfc/tnep/images/nfc_static_connection_handover.vsdx similarity index 100% rename from doc/nrf/images/nfc_static_connection_handover.vsdx rename to doc/nrf/libraries/nfc/tnep/images/nfc_static_connection_handover.vsdx diff --git a/doc/nrf/libraries/nfc/tnep.rst b/doc/nrf/libraries/nfc/tnep/index.rst similarity index 94% rename from doc/nrf/libraries/nfc/tnep.rst rename to doc/nrf/libraries/nfc/tnep/index.rst index 458ae6f3c643..96b9d0efe7f8 100644 --- a/doc/nrf/libraries/nfc/tnep.rst +++ b/doc/nrf/libraries/nfc/tnep/index.rst @@ -14,4 +14,4 @@ The |NCS| provides libraries to implement TNEP for both the polling device and t :glob: :caption: Subpages: - ../../include/nfc/tnep/* + * diff --git a/include/nfc/tnep/poller.rst b/doc/nrf/libraries/nfc/tnep/poller.rst similarity index 100% rename from include/nfc/tnep/poller.rst rename to doc/nrf/libraries/nfc/tnep/poller.rst diff --git a/include/nfc/tnep/tag.rst b/doc/nrf/libraries/nfc/tnep/tag.rst similarity index 96% rename from include/nfc/tnep/tag.rst rename to doc/nrf/libraries/nfc/tnep/tag.rst index e21e49506c93..d91e10410f55 100644 --- a/include/nfc/tnep/tag.rst +++ b/doc/nrf/libraries/nfc/tnep/tag.rst @@ -53,14 +53,14 @@ You can also encode additional NDEF records into the Initial TNEP message in the See the following code for an example of the Initial message encoding: -.. literalinclude:: ../../../samples/nfc/tnep_tag/src/main.c +.. literalinclude:: ../../../../../samples/nfc/tnep_tag/src/main.c :language: c :start-after: include_startingpoint_initial_msg_cb_rst :end-before: include_endpoint_initial_cb_msg_rst The following code shows how to create the Initial NDEF message: -.. literalinclude:: ../../../samples/nfc/tnep_tag/src/main.c +.. literalinclude:: ../../../../../samples/nfc/tnep_tag/src/main.c :language: c :start-after: include_startingpoint_initial_msg_rst :end-before: include_endpoint_initial_msg_rst @@ -112,7 +112,7 @@ If the application does not reply before the expiration on the time period speci The following code demonstrates how to exchange NDEF messages using the tag library after initialization: -.. literalinclude:: ../../../samples/nfc/tnep_tag/src/main.c +.. literalinclude:: ../../../../../samples/nfc/tnep_tag/src/main.c :language: c :start-after: include_startingpoint_tnep_service_rst :end-before: include_endpoint_tnep_service_rst diff --git a/samples/bluetooth/central_nfc_pairing/README.rst b/samples/bluetooth/central_nfc_pairing/README.rst index 716bc2265844..eba0aff9821d 100644 --- a/samples/bluetooth/central_nfc_pairing/README.rst +++ b/samples/bluetooth/central_nfc_pairing/README.rst @@ -38,7 +38,7 @@ Static Handover =============== A tag in the Static Handover mode, contains a Handover Select Message with carrier information NDEF records or a single Carrier Configuration Record. -.. figure:: /images/nfc_static_connection_handover.svg +.. figure:: images/nfc_static_connection_handover.svg :alt: Static Handover Negotiated Handover @@ -49,7 +49,7 @@ In case of the OOB data for Bluetooth LE the NFC Devices can exchange OOB data 2 Handover messages are exchanged using the TNEP Single response communication mode. The NFC Poler Device can be the Handover Requester or Handover Selector Device, the role is taken based on the NFC Tag first NDEF message. -.. figure:: /images/nfc_negotiated_connection_handover.svg +.. figure:: images/nfc_negotiated_connection_handover.svg :alt: Negotiated Handover Requirements diff --git a/samples/bluetooth/central_nfc_pairing/images/nfc_negotiated_connection_handover.svg b/samples/bluetooth/central_nfc_pairing/images/nfc_negotiated_connection_handover.svg new file mode 100644 index 000000000000..7ca6275a48d2 --- /dev/null +++ b/samples/bluetooth/central_nfc_pairing/images/nfc_negotiated_connection_handover.svg @@ -0,0 +1,591 @@ + + + + + + + + Page-1 + + Sheet.134 + + id3 + + Sheet.4 + + + + Sheet.5 + + + + Sheet.6 + + + + + id4 + + Sheet.8 + + + + Sheet.9 + + + + Sheet.10 + + + + + id5 + + Sheet.12 + + + + Sheet.13 + NFC Forum Tag + + NFC Forum Tag + + + id6 + + Sheet.15 + + + + Sheet.16 + + + + + Sheet.17 + + + + + id7 + + Sheet.19 + + + + Sheet.20 + + + + Sheet.21 + + + + + id8 + + Sheet.23 + + + + Sheet.24 + NFC Poller Device + + NFC Poller Device + + + id9 + + Sheet.26 + + + + Sheet.27 + + + + Sheet.28 + + + + Sheet.29 + Alternative Carrier (Bluetooth LE) + + Alternative Carrier (Bluetooth LE) + + + id10 + + Sheet.31 + + + + Sheet.32 + + + + Sheet.33 + + + + Sheet.34 + Alternative Carrier (Bluetooth LE) + + Alternative Carrier (Bluetooth LE) + + + id11 + + Sheet.36 + + + + Sheet.37 + + + + + Sheet.38 + + + + + Sheet.39 + + + + + Sheet.40 + + + + + Sheet.41 + + + + + Sheet.42 + + + + + Sheet.43 + + + + + Sheet.44 + + + + + Sheet.45 + + + + + Sheet.46 + + + + + Sheet.47 + + + + + Sheet.48 + + + + + Sheet.49 + + + + + Sheet.50 + + + + + Sheet.51 + + + + + Sheet.52 + + + + + Sheet.53 + + + + + Sheet.54 + + + + + Sheet.55 + + + + + Sheet.56 + + + + + Sheet.57 + + + + + Sheet.58 + + + + + Sheet.59 + + + + + Sheet.60 + + + + + Sheet.61 + + + + + Sheet.62 + + + + + Sheet.63 + + + + + Sheet.64 + + + + + Sheet.65 + + + + + Sheet.66 + + + + + Sheet.67 + + + + + Sheet.68 + + + + + Sheet.69 + + + + + Sheet.70 + + + + + Sheet.71 + + + + + Sheet.72 + + + + + Sheet.73 + + + + + Sheet.74 + + + + + Sheet.75 + + + + + Sheet.76 + + + + + Sheet.77 + + + + + Sheet.78 + + + + + Sheet.79 + + + + + Sheet.80 + + + + + Sheet.81 + + + + + Sheet.82 + + + + + Sheet.83 + + + + + Sheet.84 + + + + + Sheet.85 + + + + + Sheet.86 + + + + + Sheet.87 + + + + + Sheet.88 + + + + + Sheet.89 + + + + + Sheet.90 + + + + + Sheet.91 + + + + + Sheet.92 + + + + + Sheet.93 + + + + + Sheet.94 + + + + + Sheet.95 + + + + + Sheet.96 + + + + + Sheet.97 + + + + + Sheet.98 + + + + + Sheet.99 + + + + Sheet.100 + + + + + id12 + + Sheet.102 + + + + Sheet.103 + Handover Select (Bluetooth LE, OOB data) + + Handover Select (Bluetooth LE, OOB data) + + + id13 + + Sheet.105 + + + + Sheet.106 + Data exchange over Bluetooth LE + + Data exchange over Bluetooth LE + + + id14 + + Sheet.108 + + + + Sheet.109 + + + + Sheet.110 + + + + + id15 + + Sheet.112 + + + + Sheet.113 + TNEP + + TNEP + + + id16 + + Sheet.115 + + + + Sheet.116 + + + + Sheet.117 + + + + + id17 + + Sheet.119 + + + + Sheet.120 + TNEP + + TNEP + + + id18 + + Sheet.122 + + + + Sheet.123 + + + + + Sheet.124 + + + + + id19 + + Sheet.126 + + + + Sheet.127 + Handover Request (Bluetooth LE, OOB data) + + Handover Request (Bluetooth LE, OOB data) + + + + diff --git a/samples/bluetooth/central_nfc_pairing/images/nfc_negotiated_connection_handover.vsdx b/samples/bluetooth/central_nfc_pairing/images/nfc_negotiated_connection_handover.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..7c349a189d2c2a974558586a859577cc64d05dc9 GIT binary patch literal 25210 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 NiHPo#Kei0g{{U1>sv-aY literal 0 HcmV?d00001 diff --git a/samples/bluetooth/central_nfc_pairing/images/nfc_static_connection_handover.svg b/samples/bluetooth/central_nfc_pairing/images/nfc_static_connection_handover.svg new file mode 100644 index 000000000000..ecae89f2170c --- /dev/null +++ b/samples/bluetooth/central_nfc_pairing/images/nfc_static_connection_handover.svg @@ -0,0 +1,508 @@ + + + + + + + + Page-1 + + Sheet.116 + + id3 + + Sheet.4 + + + + Sheet.5 + + + + Sheet.6 + + + + + id4 + + Sheet.8 + + + + Sheet.9 + + + + Sheet.10 + + + + + id5 + + Sheet.12 + + + + Sheet.13 + NFC Forum Tag + + NFC Forum Tag + + + id6 + + Sheet.15 + + + + Sheet.16 + + + + + Sheet.17 + + + + + id7 + + Sheet.19 + + + + Sheet.20 + + + + Sheet.21 + + + + + id8 + + Sheet.23 + + + + Sheet.24 + NFC Poller Device + + NFC Poller Device + + + id9 + + Sheet.26 + + + + Sheet.27 + + + + Sheet.28 + + + + Sheet.29 + Alternative Carrier (Bluetooth LE) + + Alternative Carrier (Bluetooth LE) + + + id11 + + Sheet.36 + + + + Sheet.37 + + + + + Sheet.38 + + + + + Sheet.39 + + + + + Sheet.40 + + + + + Sheet.41 + + + + + Sheet.42 + + + + + Sheet.43 + + + + + Sheet.44 + + + + + Sheet.45 + + + + + Sheet.46 + + + + + Sheet.47 + + + + + Sheet.48 + + + + + Sheet.49 + + + + + Sheet.50 + + + + + Sheet.51 + + + + + Sheet.52 + + + + + Sheet.53 + + + + + Sheet.54 + + + + + Sheet.55 + + + + + Sheet.56 + + + + + Sheet.57 + + + + + Sheet.58 + + + + + Sheet.59 + + + + + Sheet.60 + + + + + Sheet.61 + + + + + Sheet.62 + + + + + Sheet.63 + + + + + Sheet.64 + + + + + Sheet.65 + + + + + Sheet.66 + + + + + Sheet.67 + + + + + Sheet.68 + + + + + Sheet.69 + + + + + Sheet.70 + + + + + Sheet.71 + + + + + Sheet.72 + + + + + Sheet.73 + + + + + Sheet.74 + + + + + Sheet.75 + + + + + Sheet.76 + + + + + Sheet.77 + + + + + Sheet.78 + + + + + Sheet.79 + + + + + Sheet.80 + + + + + Sheet.81 + + + + + Sheet.82 + + + + + Sheet.83 + + + + + Sheet.84 + + + + + Sheet.85 + + + + + Sheet.86 + + + + + Sheet.87 + + + + + Sheet.88 + + + + + Sheet.89 + + + + + Sheet.90 + + + + + Sheet.91 + + + + + Sheet.92 + + + + + Sheet.93 + + + + + Sheet.94 + + + + + Sheet.95 + + + + + Sheet.96 + + + + + Sheet.97 + + + + + Sheet.98 + + + + + Sheet.99 + + + + Sheet.100 + + + + + id12 + + Sheet.102 + + + + Sheet.103 + Handover Select (Bluetooth LE, OOB data) + + Handover Select (Bluetooth LE, OOB data) + + + id13 + + Sheet.105 + + + + Sheet.106 + Data exchange over Bluetooth LE + + Data exchange over Bluetooth LE + + + id9.109 + + Sheet.110 + + + + Sheet.111 + + + + Sheet.112 + + + + Sheet.113 + Alternative Carrier (Bluetooth LE) + + Alternative Carrier (Bluetooth LE) + + + + diff --git a/samples/bluetooth/central_nfc_pairing/images/nfc_static_connection_handover.vsdx b/samples/bluetooth/central_nfc_pairing/images/nfc_static_connection_handover.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..ec103c41da34fbd9bc8919dff07e8b5c5ec3d660 GIT binary patch literal 23083 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 V76I0GI5?!(F92)Zle>Q${R=wndzJtI literal 0 HcmV?d00001 diff --git a/samples/bluetooth/peripheral_nfc_pairing/README.rst b/samples/bluetooth/peripheral_nfc_pairing/README.rst index b2256024a06a..04c97d70568a 100644 --- a/samples/bluetooth/peripheral_nfc_pairing/README.rst +++ b/samples/bluetooth/peripheral_nfc_pairing/README.rst @@ -43,7 +43,7 @@ Static Handover A tag in the Static Handover mode, contains a Handover Select Message with carrier information NDEF records or a single Carrier Configuration Record. -.. figure:: /images/nfc_static_connection_handover.svg +.. figure:: images/nfc_static_connection_handover.svg :alt: Static Handover Negotiated Handover @@ -59,7 +59,7 @@ This sample can be configured to take the Connection Handover Selector role or t The Connection Handover Selector role is default for this sample. You can change the default role by choosing ``CONFIG_NFC_TAG_CH_SELECTOR`` or ``CONFIG_NFC_TAG_CH_REQUESTER``. -.. figure:: /images/nfc_negotiated_connection_handover.svg +.. figure:: images/nfc_negotiated_connection_handover.svg :alt: Negotiated Handover diff --git a/samples/bluetooth/peripheral_nfc_pairing/images/nfc_negotiated_connection_handover.svg b/samples/bluetooth/peripheral_nfc_pairing/images/nfc_negotiated_connection_handover.svg new file mode 100644 index 000000000000..7ca6275a48d2 --- /dev/null +++ b/samples/bluetooth/peripheral_nfc_pairing/images/nfc_negotiated_connection_handover.svg @@ -0,0 +1,591 @@ + + + + + + + + Page-1 + + Sheet.134 + + id3 + + Sheet.4 + + + + Sheet.5 + + + + Sheet.6 + + + + + id4 + + Sheet.8 + + + + Sheet.9 + + + + Sheet.10 + + + + + id5 + + Sheet.12 + + + + Sheet.13 + NFC Forum Tag + + NFC Forum Tag + + + id6 + + Sheet.15 + + + + Sheet.16 + + + + + Sheet.17 + + + + + id7 + + Sheet.19 + + + + Sheet.20 + + + + Sheet.21 + + + + + id8 + + Sheet.23 + + + + Sheet.24 + NFC Poller Device + + NFC Poller Device + + + id9 + + Sheet.26 + + + + Sheet.27 + + + + Sheet.28 + + + + Sheet.29 + Alternative Carrier (Bluetooth LE) + + Alternative Carrier (Bluetooth LE) + + + id10 + + Sheet.31 + + + + Sheet.32 + + + + Sheet.33 + + + + Sheet.34 + Alternative Carrier (Bluetooth LE) + + Alternative Carrier (Bluetooth LE) + + + id11 + + Sheet.36 + + + + Sheet.37 + + + + + Sheet.38 + + + + + Sheet.39 + + + + + Sheet.40 + + + + + Sheet.41 + + + + + Sheet.42 + + + + + Sheet.43 + + + + + Sheet.44 + + + + + Sheet.45 + + + + + Sheet.46 + + + + + Sheet.47 + + + + + Sheet.48 + + + + + Sheet.49 + + + + + Sheet.50 + + + + + Sheet.51 + + + + + Sheet.52 + + + + + Sheet.53 + + + + + Sheet.54 + + + + + Sheet.55 + + + + + Sheet.56 + + + + + Sheet.57 + + + + + Sheet.58 + + + + + Sheet.59 + + + + + Sheet.60 + + + + + Sheet.61 + + + + + Sheet.62 + + + + + Sheet.63 + + + + + Sheet.64 + + + + + Sheet.65 + + + + + Sheet.66 + + + + + Sheet.67 + + + + + Sheet.68 + + + + + Sheet.69 + + + + + Sheet.70 + + + + + Sheet.71 + + + + + Sheet.72 + + + + + Sheet.73 + + + + + Sheet.74 + + + + + Sheet.75 + + + + + Sheet.76 + + + + + Sheet.77 + + + + + Sheet.78 + + + + + Sheet.79 + + + + + Sheet.80 + + + + + Sheet.81 + + + + + Sheet.82 + + + + + Sheet.83 + + + + + Sheet.84 + + + + + Sheet.85 + + + + + Sheet.86 + + + + + Sheet.87 + + + + + Sheet.88 + + + + + Sheet.89 + + + + + Sheet.90 + + + + + Sheet.91 + + + + + Sheet.92 + + + + + Sheet.93 + + + + + Sheet.94 + + + + + Sheet.95 + + + + + Sheet.96 + + + + + Sheet.97 + + + + + Sheet.98 + + + + + Sheet.99 + + + + Sheet.100 + + + + + id12 + + Sheet.102 + + + + Sheet.103 + Handover Select (Bluetooth LE, OOB data) + + Handover Select (Bluetooth LE, OOB data) + + + id13 + + Sheet.105 + + + + Sheet.106 + Data exchange over Bluetooth LE + + Data exchange over Bluetooth LE + + + id14 + + Sheet.108 + + + + Sheet.109 + + + + Sheet.110 + + + + + id15 + + Sheet.112 + + + + Sheet.113 + TNEP + + TNEP + + + id16 + + Sheet.115 + + + + Sheet.116 + + + + Sheet.117 + + + + + id17 + + Sheet.119 + + + + Sheet.120 + TNEP + + TNEP + + + id18 + + Sheet.122 + + + + Sheet.123 + + + + + Sheet.124 + + + + + id19 + + Sheet.126 + + + + Sheet.127 + Handover Request (Bluetooth LE, OOB data) + + Handover Request (Bluetooth LE, OOB data) + + + + diff --git a/samples/bluetooth/peripheral_nfc_pairing/images/nfc_negotiated_connection_handover.vsdx b/samples/bluetooth/peripheral_nfc_pairing/images/nfc_negotiated_connection_handover.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..7c349a189d2c2a974558586a859577cc64d05dc9 GIT binary patch literal 25210 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 NiHPo#Kei0g{{U1>sv-aY literal 0 HcmV?d00001 diff --git a/samples/bluetooth/peripheral_nfc_pairing/images/nfc_static_connection_handover.svg b/samples/bluetooth/peripheral_nfc_pairing/images/nfc_static_connection_handover.svg new file mode 100644 index 000000000000..ecae89f2170c --- /dev/null +++ b/samples/bluetooth/peripheral_nfc_pairing/images/nfc_static_connection_handover.svg @@ -0,0 +1,508 @@ + + + + + + + + Page-1 + + Sheet.116 + + id3 + + Sheet.4 + + + + Sheet.5 + + + + Sheet.6 + + + + + id4 + + Sheet.8 + + + + Sheet.9 + + + + Sheet.10 + + + + + id5 + + Sheet.12 + + + + Sheet.13 + NFC Forum Tag + + NFC Forum Tag + + + id6 + + Sheet.15 + + + + Sheet.16 + + + + + Sheet.17 + + + + + id7 + + Sheet.19 + + + + Sheet.20 + + + + Sheet.21 + + + + + id8 + + Sheet.23 + + + + Sheet.24 + NFC Poller Device + + NFC Poller Device + + + id9 + + Sheet.26 + + + + Sheet.27 + + + + Sheet.28 + + + + Sheet.29 + Alternative Carrier (Bluetooth LE) + + Alternative Carrier (Bluetooth LE) + + + id11 + + Sheet.36 + + + + Sheet.37 + + + + + Sheet.38 + + + + + Sheet.39 + + + + + Sheet.40 + + + + + Sheet.41 + + + + + Sheet.42 + + + + + Sheet.43 + + + + + Sheet.44 + + + + + Sheet.45 + + + + + Sheet.46 + + + + + Sheet.47 + + + + + Sheet.48 + + + + + Sheet.49 + + + + + Sheet.50 + + + + + Sheet.51 + + + + + Sheet.52 + + + + + Sheet.53 + + + + + Sheet.54 + + + + + Sheet.55 + + + + + Sheet.56 + + + + + Sheet.57 + + + + + Sheet.58 + + + + + Sheet.59 + + + + + Sheet.60 + + + + + Sheet.61 + + + + + Sheet.62 + + + + + Sheet.63 + + + + + Sheet.64 + + + + + Sheet.65 + + + + + Sheet.66 + + + + + Sheet.67 + + + + + Sheet.68 + + + + + Sheet.69 + + + + + Sheet.70 + + + + + Sheet.71 + + + + + Sheet.72 + + + + + Sheet.73 + + + + + Sheet.74 + + + + + Sheet.75 + + + + + Sheet.76 + + + + + Sheet.77 + + + + + Sheet.78 + + + + + Sheet.79 + + + + + Sheet.80 + + + + + Sheet.81 + + + + + Sheet.82 + + + + + Sheet.83 + + + + + Sheet.84 + + + + + Sheet.85 + + + + + Sheet.86 + + + + + Sheet.87 + + + + + Sheet.88 + + + + + Sheet.89 + + + + + Sheet.90 + + + + + Sheet.91 + + + + + Sheet.92 + + + + + Sheet.93 + + + + + Sheet.94 + + + + + Sheet.95 + + + + + Sheet.96 + + + + + Sheet.97 + + + + + Sheet.98 + + + + + Sheet.99 + + + + Sheet.100 + + + + + id12 + + Sheet.102 + + + + Sheet.103 + Handover Select (Bluetooth LE, OOB data) + + Handover Select (Bluetooth LE, OOB data) + + + id13 + + Sheet.105 + + + + Sheet.106 + Data exchange over Bluetooth LE + + Data exchange over Bluetooth LE + + + id9.109 + + Sheet.110 + + + + Sheet.111 + + + + Sheet.112 + + + + Sheet.113 + Alternative Carrier (Bluetooth LE) + + Alternative Carrier (Bluetooth LE) + + + + diff --git a/samples/bluetooth/peripheral_nfc_pairing/images/nfc_static_connection_handover.vsdx b/samples/bluetooth/peripheral_nfc_pairing/images/nfc_static_connection_handover.vsdx new file mode 100644 index 0000000000000000000000000000000000000000..ec103c41da34fbd9bc8919dff07e8b5c5ec3d660 GIT binary patch literal 23083 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 V76I0GI5?!(F92)Zle>Q${R=wndzJtI literal 0 HcmV?d00001 From f53ef51d59b98b7f6e174982068afe22974a4141 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 15 Jul 2021 17:55:29 +0200 Subject: [PATCH 045/126] doc: nrf: stop using include and lib folders as docs sources No more docs are present inside include nor lib folders, so delete the entries from the external_content extension. Signed-off-by: Gerard Marull-Paretas --- doc/nrf/conf.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/doc/nrf/conf.py b/doc/nrf/conf.py index 441b8e460ef1..746a77c0fc34 100644 --- a/doc/nrf/conf.py +++ b/doc/nrf/conf.py @@ -145,9 +145,6 @@ (NRF_BASE / "doc" / "nrf", "*"), (NRF_BASE, "applications/**/*.rst"), (NRF_BASE, "applications/**/doc"), - (NRF_BASE, "include/**/*.rst"), - (NRF_BASE, "lib/**/*.rst"), - (NRF_BASE, "lib/**/doc"), (NRF_BASE, "samples/**/*.rst"), (NRF_BASE, "scripts/**/*.rst"), (NRF_BASE, "tests/**/*.rst"), From e4433a9ec6e6e01742c6ef8b35fa444037e3a4d3 Mon Sep 17 00:00:00 2001 From: Jun Qing Zou Date: Fri, 28 May 2021 18:19:22 +0900 Subject: [PATCH 046/126] applications: serial_lte_modem Re-design of GNSS function GPS service in SLM is renamed to be GNSS service. Changed GPS function from GNSS socket based to new GNSS API. Added optional services: .nRF Cloud A-GPS function .nRF Cloud P-GPS function .nRF Cloud cellular positioning function (SCELL only) Removed SUPL A-GPS support. Requires nrf_modem 1.2.0 and later. JIRA Reference: NCSIDB-462 Signed-off-by: Jun Qing Zou --- applications/serial_lte_modem/CMakeLists.txt | 2 +- applications/serial_lte_modem/Kconfig | 2 +- .../doc/AT_commands_intro.rst | 2 +- .../serial_lte_modem/doc/GNSS_AT_commands.rst | 565 ++++++++++++ .../serial_lte_modem/doc/GPS_AT_commands.rst | 182 ---- .../serial_lte_modem/doc/slm_description.rst | 25 +- .../serial_lte_modem/doc/slm_testing.rst | 271 ------ applications/serial_lte_modem/prj.conf | 24 +- .../serial_lte_modem/src/gnss/CMakeLists.txt | 8 + .../serial_lte_modem/src/gnss/Kconfig | 30 + .../serial_lte_modem/src/gnss/slm_at_gnss.c | 856 ++++++++++++++++++ .../serial_lte_modem/src/gnss/slm_at_gnss.h | 34 + .../serial_lte_modem/src/gps/CMakeLists.txt | 8 - applications/serial_lte_modem/src/gps/Kconfig | 21 - .../serial_lte_modem/src/gps/slm_at_gps.c | 508 ----------- .../serial_lte_modem/src/gps/slm_at_gps.h | 53 -- applications/serial_lte_modem/src/main.c | 2 +- .../serial_lte_modem/src/slm_at_commands.c | 32 +- doc/nrf/releases/release-notes-latest.rst | 4 +- 19 files changed, 1554 insertions(+), 1075 deletions(-) create mode 100644 applications/serial_lte_modem/doc/GNSS_AT_commands.rst delete mode 100644 applications/serial_lte_modem/doc/GPS_AT_commands.rst create mode 100644 applications/serial_lte_modem/src/gnss/CMakeLists.txt create mode 100644 applications/serial_lte_modem/src/gnss/Kconfig create mode 100644 applications/serial_lte_modem/src/gnss/slm_at_gnss.c create mode 100644 applications/serial_lte_modem/src/gnss/slm_at_gnss.h delete mode 100644 applications/serial_lte_modem/src/gps/CMakeLists.txt delete mode 100644 applications/serial_lte_modem/src/gps/Kconfig delete mode 100644 applications/serial_lte_modem/src/gps/slm_at_gps.c delete mode 100644 applications/serial_lte_modem/src/gps/slm_at_gps.h diff --git a/applications/serial_lte_modem/CMakeLists.txt b/applications/serial_lte_modem/CMakeLists.txt index 46e77587dd40..665ee6c38702 100644 --- a/applications/serial_lte_modem/CMakeLists.txt +++ b/applications/serial_lte_modem/CMakeLists.txt @@ -25,7 +25,7 @@ target_sources_ifdef(CONFIG_SLM_SMS app PRIVATE src/slm_at_sms.c) target_sources_ifdef(CONFIG_SLM_NATIVE_TLS app PRIVATE src/slm_native_tls.c) target_sources_ifdef(CONFIG_SLM_NATIVE_TLS app PRIVATE src/slm_at_cmng.c) -add_subdirectory_ifdef(CONFIG_SLM_GPS src/gps) +add_subdirectory_ifdef(CONFIG_SLM_GNSS src/gnss) add_subdirectory_ifdef(CONFIG_SLM_FTPC src/ftp_c) add_subdirectory_ifdef(CONFIG_SLM_MQTTC src/mqtt_c) add_subdirectory_ifdef(CONFIG_SLM_HTTPC src/http_c) diff --git a/applications/serial_lte_modem/Kconfig b/applications/serial_lte_modem/Kconfig index 9420ccb2fda1..89a3789300ce 100644 --- a/applications/serial_lte_modem/Kconfig +++ b/applications/serial_lte_modem/Kconfig @@ -130,7 +130,7 @@ config SLM_SMS help Support SMS send/receive in plain text -rsource "src/gps/Kconfig" +rsource "src/gnss/Kconfig" rsource "src/ftp_c/Kconfig" rsource "src/mqtt_c/Kconfig" rsource "src/http_c/Kconfig" diff --git a/applications/serial_lte_modem/doc/AT_commands_intro.rst b/applications/serial_lte_modem/doc/AT_commands_intro.rst index e77bdb2164d5..c4ba34380831 100644 --- a/applications/serial_lte_modem/doc/AT_commands_intro.rst +++ b/applications/serial_lte_modem/doc/AT_commands_intro.rst @@ -41,7 +41,7 @@ The modem-specific AT commands are documented in the `nRF91 AT Commands Referenc FOTA_AT_commands SMS_AT_commands FTP_AT_commands - GPS_AT_commands + GNSS_AT_commands MQTT_AT_commands HTTPC_AT_commands TWI_AT_commands diff --git a/applications/serial_lte_modem/doc/GNSS_AT_commands.rst b/applications/serial_lte_modem/doc/GNSS_AT_commands.rst new file mode 100644 index 000000000000..97b555abf877 --- /dev/null +++ b/applications/serial_lte_modem/doc/GNSS_AT_commands.rst @@ -0,0 +1,565 @@ +.. _SLM_AT_GNSS: + +GNSS AT commands +**************** + +.. contents:: + :local: + :depth: 2 + +The following commands list contains GNSS-related AT commands. + +Run GPS +======= + +The ``#XGPS`` command controls the GPS. + +Set command +----------- + +The set command allows you to start and stop the GPS. + +Syntax +~~~~~~ + +:: + + #XGPS=[,[,]] + +The ```` parameter accepts the following integer values: + +* ``0`` - Stop GPS +* ``1`` - Start GPS + +The ```` parameter represents the GNSS fix interval in seconds. +It must be set when starting the GPS. +It accepts the following integer values: + +* ``0`` - Single-fix navigation mode. +* ``1`` - Continuous navigation mode. + The fix interval is set to 1 second +* Ranging from ``10`` to ``1800`` - Periodic navigation mode. + The fix interval is set to the specified value. + +In periodic navigation mode, the ```` parameter controls the maximum time in seconds that the GNSS receiver is allowed to run while trying to produce a valid PVT estimate. +In continuous navigation mode, this parameter doesn't have any effect. +It accepts the following integer values: + +* ``0`` - the GNSS receiver runs indefinitely until a valid PVT estimate is produced. +* Any positive integer lower than the ```` value - the GNSS receiver is turned off after the specified time is up, even if a valid PVT estimate was not produced. + +When not specified, it defaults to a timeout value of 60 seconds. + +Unsolicited notification +~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + #XGPS: ,,,,,, + +* The ```` value represents the latitude in degrees. +* The ```` value represents the longitude in degrees. +* The ```` value represents the altitude above the WGS-84 ellipsoid in meters. +* The ```` value represents the accuracy (2D 1-sigma) in meters. +* The ```` value represents the horizontal speed in meters. +* The ```` value represents the heading of the movement of the user in degrees. +* The ```` value represents the UTC date-time. + +Example +~~~~~~~ + +:: + + AT%XSYSTEMMODE=0,0,1,0 + + OK + AT%XCOEX0=1,1,1565,1586 + + OK + AT+CFUN=31 + + OK + at#xgps=1,1 + + OK + + #XGPS: 35.457576,139.625090,121.473785,22.199919,0.442868,0.000000,"2021-06-02 06:25:48" + + #XGPS: 35.457550,139.625115,124.293533,15.679427,0.263094,0.000000,"2021-06-02 06:25:49" + + #XGPS: 35.457517,139.625094,120.865372,12.768595,0.166673,0.000000,"2021-06-02 06:25:50" + +Read command +------------ + +The read command is not supported. + +Test command +------------ + +The test command tests the existence of the command and provides information about the type of its subparameters. + +Syntax +~~~~~~ + +:: + + #XGPS=? + +Example +~~~~~~~ + +:: + + AT#XGPS=? + + #XGPS: (0,1),, + + OK + + +Connect to nRF Cloud +==================== + +The ``#XNRFCLOUD`` command controls the connection to the nRF Cloud service. + +Set command +----------- + +The set command allows you to connect and disconnect the nRF Cloud service. + +Syntax +~~~~~~ + +:: + + #XNRFCLOUD=[,] + +The ```` parameter accepts the following integer values: + +* ``0`` - Disconnect from the nRF Cloud service +* ``1`` - Connect to the nRF Cloud service + +The ```` parameter accepts the following integer values: + +* ``0`` - It does not signify the location info to nRF Cloud +* ``1`` - It does signify the location info to nRF Cloud + +When not specified, it does not signify the location info to nRF Cloud. + +Unsolicited notification +~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + #XNRFCLOUD: , + +* The ```` value indicates whether the nRF Cloud connection is ready or not. +* The ```` value indicates whether the location info will be signified to nRF Cloud or not. + +Example +~~~~~~~ + +:: + + AT#XNRFCLOUD=1 + + OK + #XNRFCLOUD: 1,0 + AT#XNRFCLOUD=0 + + AT#XNRFCLOUD: 0,0 + + OK + AT#XNRFCLOUD=1,1 + + OK + #XNRFCLOUD: 1,1 + AT#XNRFCLOUD=0 + + AT#XNRFCLOUD: 0,1 + + OK + +Read command +------------ + +The read command checks if nRF Cloud is connected or not. + +Syntax +~~~~~~ + +:: + + #XNRFCLOUD? + +Response syntax +~~~~~~~~~~~~~~~ + +:: + + #XNRFCLOUD: , + +* The ```` value indicates whether the nRF Cloud connection is ready or not. +* The ```` value indicates whether the location info will be signified to nRF Cloud or not. + +Example +~~~~~~~ + +:: + + AT#XNRFCLOUD? + + #XNRFCLOUD: 1,0 + + OK + + +Test command +------------ + +The test command tests the existence of the command and provides information about the type of its subparameters. + +Syntax +~~~~~~ + +:: + + #XNRFCLOUD=? + +Example +~~~~~~~ + +:: + + AT#XNRFSIGNIFY=? + + #XNRFCLOUD: (1,0), + + OK + +Run GPS with nRF Cloud A-GPS +============================ + +The ``#XAGPS`` command runs the GPS together with the nRF Cloud A-GPS service. +This requires access to nRF Cloud through the LTE network for receiving A-GPS data. + +Set command +----------- + +The set command allows you to start and stop the GPS together with the nRF Cloud A-GPS service. + +Syntax +~~~~~~ + +:: + + #XAGPS=[,[,]] + +The ```` parameter accepts the following integer values: + +* ``0`` - Stop GPS with A-GPS +* ``1`` - Start GPS with A-GPS + +The ```` parameter represents the GNSS fix interval in seconds. +It must be set when starting the GPS. +It accepts the following integer values: + +* ``0`` - Single-fix navigation mode. +* ``1`` - Continuous navigation mode. + The fix interval is set to 1 second +* Ranging from ``10`` to ``1800`` - Periodic navigation mode. + The fix interval is set to the specified value. + +In periodic navigation mode, the ```` parameter controls the maximum time in seconds that the GNSS receiver is allowed to run while trying to produce a valid PVT estimate. +In continuous navigation mode, this parameter doesn't have any effect. +It accepts the following integer values: + +* ``0`` - the GNSS receiver runs indefinitely until a valid PVT estimate is produced. +* Any positive integer lower than the ```` value - the GNSS receiver is turned off after the specified time is up, even if a valid PVT estimate was not produced. + +When not specified, it defaults to a timeout value of 60 seconds. + +Unsolicited notification +~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + #XGPS: ,,,,,, + +* The ```` value represents the latitude in degrees. +* The ```` value represents the longitude in degrees. +* The ```` value represents the altitude above the WGS-84 ellipsoid in meters. +* The ```` value represents the accuracy (2D 1-sigma) in meters. +* The ```` value represents the horizontal speed in meters. +* The ```` value represents the heading of the movement of the user in degrees. +* The ```` value represents the UTC date-time. + +Example +~~~~~~~ + +:: + + AT%XSYSTEMMODE=1,0,1,0 + + OK + AT%XCOEX0=1,1,1565,1586 + + OK + AT+CPSMS=1 + + OK + AT+CFUN=1 + + OK + AT#XNRFCLOUD=1 + + OK + #XNRFCLOUD: 1,0 + AT#XAGPS=1,1 + + OK + + #XGPS: 35.457417,139.625211,162.850952,15.621976,1.418092,0.000000,"2021-06-02 05:21:31" + + #XGPS: 35.457435,139.625348,176.104797,14.245458,1.598184,69.148659,"2021-06-02 05:21:32" + + #XGPS: 35.457417,139.625415,179.132980,13.318132,1.235241,69.148659,"2021-06-02 05:21:33" + + #XGPS: 35.457410,139.625469,181.223541,12.667312,0.803951,69.148659,"2021-06-02 05:21:34" + +Read command +------------ + +The read command is not supported. + +Test command +------------ + +The test command tests the existence of the command and provides information about the type of its subparameters. + +Syntax +~~~~~~ + +:: + + #XAGPS=? + +Example +~~~~~~~ + +:: + + AT#XAGPS=? + + #XAGPS: (0,1),, + + OK + + +Run GPS with nRF Cloud P-GPS +============================ + +The ``#XPGPS`` command runs the GPS together with the nRF Cloud P-GPS service. +This requires access to nRF Cloud through the LTE network for receiving P-GPS data. + +Set command +----------- + +The set command allows you to start and stop the GPS together with the nRF Cloud P-GPS service. + +Syntax +~~~~~~ + +:: + + #XPGPS=[,[,]] + +The ```` parameter accepts the following integer values: + +* ``0`` - Stop GPS with P-GPS +* ``1`` - Start GPS with P-GPS + +The ```` parameter represents the GNSS fix interval in seconds. +It must be set when starting the GPS. +It accepts the following integer values: + +* Ranging from ``10`` to ``1800`` - Periodic navigation mode. + The fix interval is set to the specified value. + +In periodic navigation mode, the ```` parameter controls the maximum time in seconds that the GNSS receiver is allowed to run while trying to produce a valid PVT estimate. +In continuous navigation mode, this parameter doesn't have any effect. +It accepts the following integer values: + +* ``0`` - the GNSS receiver runs indefinitely until a valid PVT estimate is produced. +* Any positive integer lower than the ```` value - the GNSS receiver is turned off after the specified time is up, even if a valid PVT estimate was not produced. + +When not specified, it defaults to a timeout value of 60 seconds. + +Unsolicited notification +~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + #XGPS: ,,,,,, + +* The ```` value represents the latitude in degrees. +* The ```` value represents the longitude in degrees. +* The ```` value represents the altitude above the WGS-84 ellipsoid in meters. +* The ```` value represents the accuracy (2D 1-sigma) in meters. +* The ```` value represents the horizontal speed in meters. +* The ```` value represents the heading of the movement of the user in degrees. +* The ```` value represents the UTC date-time. + +Example +~~~~~~~ + +:: + + AT%XSYSTEMMODE=1,0,1,0 + + OK + AT%XCOEX0=1,1,1565,1586 + + OK + AT+CPSMS=1 + + OK + AT+CFUN=1 + + OK + AT#XNRFCLOUD=1 + + OK + #XNRFCLOUD: 1,0 + AT#XPGPS=1,30 + + OK + + #XGPS: 35.457243,139.625435,149.005020,28.184258,10.431827,281.446014,"2021-06-24 04:35:52" + + #XGPS: 35.457189,139.625602,176.811203,43.015198,0.601837,281.446014,"2021-06-24 04:36:28" + + #XGPS: 35.457498,139.625422,168.243591,31.753956,0.191195,281.446014,"2021-06-24 04:36:41" + + #XGPS: 35.457524,139.624667,100.745979,25.324850,6.347160,94.699837,"2021-06-24 04:37:10" + +Read command +------------ + +The read command is not supported. + +Test command +------------ + +The test command tests the existence of the command and provides information about the type of its subparameters. + +Syntax +~~~~~~ + +:: + + #XPGPS=? + +Example +~~~~~~~ + +:: + + AT#XPGPS=? + + #XPGPS: (0,1),, + + OK + +Run nRF Cloud cellular positioning +================================== + +The ``#XCELLPOS`` command runs the nRF Cloud cellular positioning service for position information. +This requires to define ``CONFIG_SLM_CELL_POS`` and to access nRF Cloud through the LTE network. + +Set command +----------- + +The set command allows you to start and stop the nRF Cloud cellular positioning service. + +Syntax +~~~~~~ + +:: + + #XCELLPOS= + +The ```` parameter accepts the following integer values: + +* ``0`` - Stop cellular positioning +* ``1`` - Start cellular positioning in single-cell mode +* ``2`` - Start cellular positioning in multi-cell mode + +Unsolicited notification +~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + #XCELLPOS: ,,, + +* The ```` value indicates in which mode the cellular positioning server is running: + + * ``0`` - The server is running in single-cell mode + * ``1`` - The server is running in multi-cell mode + +* The ```` value represents the latitude in degrees. +* The ```` value represents the longitude in degrees. +* The ```` value represents the certainty of the result. + +Example +~~~~~~~ + +:: + + AT%XSYSTEMMODE=1,0,0,0 + + OK + AT+CFUN=1 + + OK + AT#XNRFCLOUD=1 + + OK + #XNRFCLOUD: 1,0 + AT#XCELLPOS=1 + + OK + + #XCELLPOS: 0,35.455833,139.626111,1094 + AT#XCELLPOS=0 + + OK + +Read command +------------ + +The read command is not supported. + +Test command +------------ + +The test command tests the existence of the command and provides information about the type of its subparameters. + +Syntax +~~~~~~ + +:: + + #XCELLPOS=? + +Example +~~~~~~~ + +:: + + AT#XCELLPOS=? + + #XCELLPOS: (0,1,2) + + OK diff --git a/applications/serial_lte_modem/doc/GPS_AT_commands.rst b/applications/serial_lte_modem/doc/GPS_AT_commands.rst deleted file mode 100644 index e71075f42ff7..000000000000 --- a/applications/serial_lte_modem/doc/GPS_AT_commands.rst +++ /dev/null @@ -1,182 +0,0 @@ -.. _SLM_AT_GPS: - -GPS AT commands -*************** - -.. contents:: - :local: - :depth: 2 - -The following commands list contains GPS related AT commands. - -Run GPS #XGPS -============= - -The ``#XGPS`` command controls the GPS. - -Set command ------------ - -The set command allows you to start and stop the GPS. - -Syntax -~~~~~~ - -:: - - #XGPS=[,] - -The ```` parameter accepts the following integer values: - -* ``0`` - Start GPS -* ``1`` - Stop GPS - -The ```` parameter represents the NMEA data mask. -It accepts the following integer values: - -* Bit 0 - Global Positioning System fix data -* Bit 1 - Geographic position latitude/longitude and time -* Bit 2 - DOP and active satellites -* Bit 3 - Satellites in view -* Bit 4 - Recommended minimum specific GPS/transit data - -They are all set if the NMEA data mask value is ignored. - -Response syntax -~~~~~~~~~~~~~~~ - -:: - - #XGPS: [,] - -The ```` value represents the GPS running status. -It can have the following values: - -* ``0`` - Stopped. -* ``1`` - Running. -* *Negative Value* - Error code. - It indicates the reason for the failure. - -When the ```` value is 1, the ```` value syntax appears as follows: - -* Bit 0 - Global Positioning System Fix Data -* Bit 1 - Geographic position latitude/longitude and time -* Bit 2 - DOP and active satellites -* Bit 3 - Satellites in view -* Bit 4 - Recommended minimum specific GPS/transit data - -Unsolicited notification -~~~~~~~~~~~~~~~~~~~~~~~~ - -:: - - #XGPS: - #XGPSS: - #XGPSP: - - -* The ```` value represents the GPS running status. - It can have the following values: - - * ``0`` - Stopped. - * ``1`` - Running. - * *Negative Value* - Error code. - It indicates the reason for the failure. - -* The ```` value represents the satellite statistic info. -* The ```` value represents longitude, latitude, and UTC DateTime. -* The ```` value represents the NMEA raw data, notified after the first satellite fix. - -Example -~~~~~~~ - -:: - - #XGPS: 1,3 - OK - #XGPSS: "GPS suspended" - #XGPSS: "SUPL injection done" - #XGPSS: "GPS resumed" - #XGPSS: "track 3 use 3 unhealthy 0" - #XGPSS: "track 4 use 4 unhealthy 0" - #XGPSS: "track 5 use 5 unhealthy 0" - #XGPSS: "track 4 use 4 unhealthy 0" - #XGPSS: "track 5 use 5 unhealthy 0" - #XGPSS: "track 6 use 6 unhealthy 0" - #XGPSS: "track 7 use 7 unhealthy 0" - #XGPSS: "track 6 use 6 unhealthy 0" - #XGPSP: "long 139.721966 lat 35.534159" - #XGPSP: "2020-04-30 00:11:55" - #XGPSP: "TTFF 57s" - $GPGGA,001155.87,3532.04954,N,13943.31794,E,1,06,17.40,109.53,M,0,,*19 - $GPGLL,3532.04954,N,13943.31794,E,001155.87,A,A*69 - #XGPSP: "long 139.721969 lat 35.534148" - #XGPSP: "2020-04-30 00:11:56" - -Read command ------------- - -The read command checks if the GPS is running. - -Syntax -~~~~~~ - -:: - - #XGPS? - -Response syntax -~~~~~~~~~~~~~~~ - -:: - - #XGPS: [,] - -The ```` parameter represents the GPS running status. -It can accept the following values: - -* ``0`` - Stopped -* ``1`` - Running - -When the ```` value is 1, the ```` value syntax appears as follows: - -* Bit 0 - Global Positioning System fix data -* Bit 1 - Geographic position latitude/longitude and time -* Bit 2 - DOP and active satellites -* Bit 3 - Satellites in view -* Bit 4 - Recommended minimum specific GPS/transit data - -Example -~~~~~~~ - -:: - - AT#XGPS? - #XGPS: 1,2 - OK - -Test command ------------- - -The test command tests the existence of the command and provides information about the type of its subparameters. - -Syntax -~~~~~~ - -:: - - #XGPS=? - -Example -~~~~~~~ - -:: - - #XGPS: (0,1), - NMEA data mask: - Bit 0 - Global Positioning System fix data - Bit 1 - Geographic position latitude/longitude and time - Bit 2 - DOP and active satellites - Bit 3 - Satellites in view - Bit 4 - Recommended minimum specific GPS/transit data - OK diff --git a/applications/serial_lte_modem/doc/slm_description.rst b/applications/serial_lte_modem/doc/slm_description.rst index 3bd42c4c6af6..a415d715d9b4 100644 --- a/applications/serial_lte_modem/doc/slm_description.rst +++ b/applications/serial_lte_modem/doc/slm_description.rst @@ -179,17 +179,21 @@ Check and configure the following configuration options for the sample: This option enables additional AT commands for using the SMS service. -.. option:: CONFIG_SLM_GPS - GPS support in SLM +.. option:: CONFIG_SLM_GNSS - GNSS support in SLM - This option enables additional AT commands for using GPS service. + This option enables additional AT commands for using the GNSS service. -.. option:: CONFIG_SLM_SUPL_SERVER - SUPL server +.. option:: CONFIG_SLM_AGPS - nRF Cloud A-GPS support in SLM - This option specifies the SUPL server to use for retrieving SUPL A-GPS data. + This option enables additional AT commands for using the GPS service together with nRF Cloud A-GPS service. -.. option:: CONFIG_SLM_SUPL_PORT - SUPL server port +.. option:: CONFIG_SLM_PGPS - nRF Cloud P-GPS support in SLM - This option specifies the port to use for the specified SUPL server. + This option enables additional AT commands for using the GPS service together with nRF Cloud P-GPS service. + +.. option:: CONFIG_SLM_CELL_POS - nRF Cloud cellular positioning support in SLM + + This option enables additional AT commands for using the cellular positioning service from nRF Cloud. .. option:: CONFIG_SLM_FTPC - FTP client support in SLM @@ -210,10 +214,6 @@ Check and configure the following configuration options for the sample: Additional configuration ======================== -Check and configure the following library options that are used by the sample: - -* :option:`CONFIG_SUPL_CLIENT_LIB` - Enables the :ref:`supl_client`. - To save power, console and logging output over ``UART_0`` is disabled in this application. This information is logged to RTT instead. See :ref:`testing_rtt_connect` for instructions on how to view this information. @@ -308,7 +308,10 @@ This application uses the following |NCS| libraries: * :ref:`at_cmd_parser_readme` * :ref:`at_notif_readme` * :ref:`lib_ftp_client` -* :ref:`supl_client` +* :ref:`lib_fota_download` +* :ref:`cloud_api_readme` +* :ref:`lib_nrf_cloud` +* :ref:`lib_nrf_cloud_agps` It uses the following `sdk-nrfxlib`_ libraries: diff --git a/applications/serial_lte_modem/doc/slm_testing.rst b/applications/serial_lte_modem/doc/slm_testing.rst index d43f3fe555c5..c96f4372a57d 100644 --- a/applications/serial_lte_modem/doc/slm_testing.rst +++ b/applications/serial_lte_modem/doc/slm_testing.rst @@ -1740,274 +1740,3 @@ Complete the following steps to test the functionality provided by the :ref:`SLM 221-Goodbye. You uploaded 1 and downloaded 0 kbytes. 221 Logout. OK - -GPS AT commands -*************** - -Note that these commands are available only if :option:`CONFIG_SLM_GPS` is defined. -Before you test the GPS AT commands, check the following configuration values: - -* :option:`CONFIG_SUPL_CLIENT_LIB` - must be enabled to use the :ref:`supl_client` -* :option:`CONFIG_SLM_SUPL_SERVER` - use the default ("supl.google.com") or specify a different server -* :option:`CONFIG_SLM_SUPL_PORT` - use the default (7276) or specify a different port - -Complete the following steps to test the functionality provided by the :ref:`SLM_AT_GPS`: - -1. Test standalone GPS: - - a. Enable support for GNSS in the modem. - - .. parsed-literal:: - :class: highlight - - **AT+CFUN=0** - OK - - **AT%XSYSTEMMODE=0,0,1,0** - OK - - .. modem_config_start - - b. Configure the Low-Noise Amplifier (LNA). - The required commands depend on the version of the nRF9160 DK. - - For nRF9160 DK versions up to v0.9.0, configure the MAGPIO pin: - - .. parsed-literal:: - :class: highlight - - **AT%XMAGPIO=1,0,0,1,1,1574,1577** - OK - - For nRF9160 DK versions starting with v0.10.x, configure the COEX0 pin: - - .. parsed-literal:: - :class: highlight - - **AT%XCOEX0=1,1,1565,1586** - OK - - .. modem_config_end - - c. Turn on the modem. - - .. parsed-literal:: - :class: highlight - - **AT+CFUN=1** - OK - - #. Start GPS with GPS fix data and geographic position latitude/longitude and time, and observe the output. - Then check the GPS status. - - .. parsed-literal:: - :class: highlight - - **AT#XGPS=1,3** - #XGPS: 1,3 - OK - #XGPSS: tracking 1 using 1 unhealthy 0 - #XGPSS: tracking 2 using 2 unhealthy 0 - *[...]* - - **AT#XGPS?** - #XGPS: 1,3 - OK - - #. Turn off GPS and check the status again. - - .. parsed-literal:: - :class: highlight - - **AT#XGPS=0** - #XGPS: 0 - OK - - **AT#XGPS?** - #XGPS: 0 - OK - -#. Test GPS in PSM mode: - - a. Subscribe to unsolicited network status notifications. - Then enable support for LTE Cat-M1 and GNSS in the modem. - - .. parsed-literal:: - :class: highlight - - **AT+CFUN=0** - OK - - **AT+CEREG=5** - OK - - **AT%XSYSTEMMODE=1,0,1,0** - OK - -.. include:: slm_testing.rst - :start-after: modem_config_start - :end-before: modem_config_end - -.. - - c. Enable power-saving mode. - Then turn on the modem. - - .. parsed-literal:: - :class: highlight - - **AT+CPSMS=1,,,"00100100","00100001"** - OK - - **AT+CFUN=1** - OK - +CEREG: 2,"106A","00A3965D",7,0,0,"11100000","11100000" - +CEREG: 1,"106A","00A3965D",7,,,"00011110","00011000" - - #. Start GPS with GPS fix data and geographic position latitude/longitude and time, and observe the output. - - .. parsed-literal:: - :class: highlight - - **AT#XGPS=1,3** - #XGPS: 1,3 - OK - #XGPSS: tracking 1 using 1 unhealthy 0 - #XGPSS: tracking 2 using 2 unhealthy 0 - *[...]* - - #. Turn off GPS. - - .. parsed-literal:: - :class: highlight - - **AT#XGPS=0** - #XGPS: 0 - OK - -#. Test GPS in eDRX mode: - - a. Subscribe to unsolicited network status notifications. - Then enable support for LTE Cat-M1 and GNSS in the modem. - - .. parsed-literal:: - :class: highlight - - **AT+CFUN=0** - OK - - **AT+CEREG=2** - OK - - **AT%XSYSTEMMODE=1,0,1,0** - OK - -.. include:: slm_testing.rst - :start-after: modem_config_start - :end-before: modem_config_end - -.. - - c. Enable the use of eDRX and configure the PTW parameters. - Then turn on the modem. - - .. parsed-literal:: - :class: highlight - - **AT+CEDRXS=2,4,"1010"** - OK - - **AT%XPTW=4,"0001"** - OK - - **AT+CFUN=1** - OK - +CEREG: 2,"106A","00A3965D",7 - +CEREG: 1,"106A","00A3965D",7 - +CEDRXP: 4,"1010","1010","0001" - - #. Start GPS with GPS fix data and geographic position latitude/longitude and time, and observe the output. - - .. parsed-literal:: - :class: highlight - - **AT#XGPS=1,3** - #XGPS: 1,3 - OK - #XGPSS: tracking 1 using 1 unhealthy 0 - #XGPSS: tracking 2 using 2 unhealthy 0 - *[...]* - - #. Turn off GPS. - - .. parsed-literal:: - :class: highlight - - **AT#XGPS=0** - #XGPS: 0 - OK - -#. Test A-GPS: - - a. Subscribe to unsolicited network status notifications. - Then enable support for LTE Cat-M1 and GNSS in the modem. - - .. parsed-literal:: - :class: highlight - - **AT+CFUN=0** - OK - - **AT+CEREG=2** - OK - - **AT%XSYSTEMMODE=1,0,1,0** - OK - -.. include:: slm_testing.rst - :start-after: modem_config_start - :end-before: modem_config_end - -.. - - c. Turn on the modem. - - .. parsed-literal:: - :class: highlight - - **AT+CFUN=1** - OK - +CEREG: 2,"107E","00B02C03",7 - +CEREG: 1,"107E","00B02C03",7 - - #. Start GPS with GPS fix data and geographic position latitude/longitude and time, and observe the output. - Note that the TTFF printed in the AT response is from the time when AT#XGPS was issued. - For A-GPS, this includes the SUPL injection time. - - .. parsed-literal:: - :class: highlight - - **AT#XGPS=1,3** - #XGPS: 1,3 - OK - GPS suspended - SUPL injection done - GPS resumed - #XGPSS: track 3 use 3 unhealthy 0 - #XGPSS: track 4 use 4 unhealthy 0 - #XGPSS: track 5 use 5 unhealthy 0 - #XGPSS: track 4 use 4 unhealthy 0 - #XGPSS: track 5 use 5 unhealthy 0 - #XGPSS: track 6 use 6 unhealthy 0 - #XGPSS: track 7 use 7 unhealthy 0 - #XGPSS: track 6 use 6 unhealthy 0 - #XGPSP: long 139.721966 lat 35.534159 - #XGPSP: 2020-04-30 00:11:55 - #XGPSP: TTFF 57s - $GPGGA,001155.87,3532.04954,N,13943.31794,E,1,06,17.40,109.53,M,0,,*19 - $GPGLL,3532.04954,N,13943.31794,E,001155.87,A,A*69 - #XGPSP: long 139.721969 lat 35.534148 - #XGPSP: 2020-04-30 00:11:56 - $GPGGA,001156.87,3532.04889,N,13943.31811,E,1,07,17.38,111.08,M,0,,*10 - $GPGLL,3532.04889,N,13943.31811,E,001156.87,A,A*69 - #XGPSP: long 139.721982 lat 35.534138 diff --git a/applications/serial_lte_modem/prj.conf b/applications/serial_lte_modem/prj.conf index eeb4b643cb2b..386207078b06 100644 --- a/applications/serial_lte_modem/prj.conf +++ b/applications/serial_lte_modem/prj.conf @@ -45,16 +45,9 @@ CONFIG_MAIN_STACK_SIZE=4096 CONFIG_HEAP_MEM_POOL_SIZE=16384 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 -# AT_CMD -# Enable AT_CMD debug for details -#CONFIG_AT_CMD_LOG_LEVEL_DBG=y - # Device power management CONFIG_PM_DEVICE=y -# Enable SUPL client support -#CONFIG_SUPL_CLIENT_LIB=y - # FOTA CONFIG_HTTP_PARSER_URL=y CONFIG_FOTA_DOWNLOAD=y @@ -77,6 +70,19 @@ CONFIG_SETTINGS=y CONFIG_SETTINGS_FCB=y CONFIG_FCB=y +# nRF Cloud +CONFIG_CLOUD_API=y +CONFIG_NRF_CLOUD=y +CONFIG_NRF_CLOUD_AGPS=y +CONFIG_NRF_CLOUD_PGPS=y +CONFIG_NRF_CLOUD_CELL_POS=y +CONFIG_NRF_CLOUD_LOG_LEVEL_INF=y +CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD=y +CONFIG_NRF_CLOUD_MQTT_KEEPALIVE=1200 +CONFIG_DATE_TIME=y +CONFIG_MODEM_INFO=y +CONFIG_MODEM_INFO_ADD_DATE_TIME=n + # # SLM-specific configurations # @@ -89,3 +95,7 @@ CONFIG_UART_0_NRF_HW_ASYNC_TIMER=2 # Use UART_2 (when working with external MCU) #CONFIG_SLM_CONNECT_UART_2=y #CONFIG_UART_2_NRF_HW_ASYNC_TIMER=2 +# nRF Cloud based location services +CONFIG_SLM_AGPS=n +CONFIG_SLM_PGPS=n +CONFIG_SLM_CELL_POS=n diff --git a/applications/serial_lte_modem/src/gnss/CMakeLists.txt b/applications/serial_lte_modem/src/gnss/CMakeLists.txt new file mode 100644 index 000000000000..a2f907fe0961 --- /dev/null +++ b/applications/serial_lte_modem/src/gnss/CMakeLists.txt @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021 Nordic Semiconductor +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +zephyr_include_directories(.) +target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/slm_at_gnss.c) diff --git a/applications/serial_lte_modem/src/gnss/Kconfig b/applications/serial_lte_modem/src/gnss/Kconfig new file mode 100644 index 000000000000..394cc273cb55 --- /dev/null +++ b/applications/serial_lte_modem/src/gnss/Kconfig @@ -0,0 +1,30 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + +config SLM_GNSS + bool "GNSS support in SLM" + default y + +if SLM_GNSS + +config SLM_AGPS + bool "Use nRF Cloud A-GPS" + depends on NRF_CLOUD_AGPS + help + Use nRF Cloud A-GPS in GPS operation + +config SLM_PGPS + bool "Use nRF Cloud P-GPS" + depends on NRF_CLOUD_PGPS + help + Use nRF Cloud P-GPS in GPS operation + +config SLM_CELL_POS + bool "Use nRF Cloud cellular positioning" + depends on NRF_CLOUD_CELL_POS + help + Request nRF Cloud cellular positioning service + +endif # SLM_GNSS diff --git a/applications/serial_lte_modem/src/gnss/slm_at_gnss.c b/applications/serial_lte_modem/src/gnss/slm_at_gnss.c new file mode 100644 index 000000000000..d44133afeda1 --- /dev/null +++ b/applications/serial_lte_modem/src/gnss/slm_at_gnss.c @@ -0,0 +1,856 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "slm_util.h" +#include "slm_at_host.h" +#include "slm_at_gnss.h" + +LOG_MODULE_REGISTER(slm_gnss, CONFIG_SLM_LOG_LEVEL); + +#define SERVICE_INFO_GPS \ + "{\"state\":{\"reported\":{\"device\": {\"serviceInfo\":{\"ui\":[\"GPS\"]}}}}}" + +/**@brief GNSS operations. */ +enum slm_gnss_operation { + GPS_STOP, + GPS_START, + nRF_CLOUD_DISCONNECT = GPS_STOP, + nRF_CLOUD_CONNECT = GPS_START, + AGPS_STOP = GPS_STOP, + AGPS_START = GPS_START, + PGPS_STOP = GPS_STOP, + PGPS_START = GPS_START, + CELLPOS_STOP = GPS_STOP, + CELLPOS_START_SCELL = GPS_START, + CELLPOS_START_MCELL +}; + +static struct k_work agps_req; +static struct k_work pgps_req; +static struct k_work fix_rep; +static struct k_work cell_pos_req; +static enum nrf_cloud_cell_pos_type cell_pos_type; + +static struct cloud_backend *nrf_cloud; +static bool nrf_cloud_ready; +static bool location_signify; +static uint64_t ttft_start; +static enum { + RUN_TYPE_NONE, + RUN_TYPE_GPS, + RUN_TYPE_AGPS, + RUN_TYPE_PGPS, + RUN_TYPE_CELL_POS +} run_type; + +K_SEM_DEFINE(sem_date_time, 0, 1); + +/* global functions defined in different files */ +void rsp_send(const char *str, size_t len); + +/* global variable defined in different files */ +extern struct k_work_q slm_work_q; +extern struct at_param_list at_param_list; +extern char rsp_buf[CONFIG_SLM_SOCKET_RX_MAX * 2]; + +static int read_agps_req(struct gps_agps_request *req) +{ + int err; + struct nrf_modem_gnss_agps_data_frame agps_data; + + err = nrf_modem_gnss_read((void *)&agps_data, sizeof(agps_data), + NRF_MODEM_GNSS_DATA_AGPS_REQ); + if (err) { + LOG_ERR("Failed to read GNSS AGPS req, error %d", err); + return -EAGAIN; + } + + req->sv_mask_ephe = agps_data.sv_mask_ephe, + req->sv_mask_alm = agps_data.sv_mask_alm, + req->utc = (agps_data.data_flags & NRF_MODEM_GNSS_AGPS_GPS_UTC_REQUEST) ? 1 : 0, + req->klobuchar = (agps_data.data_flags & NRF_MODEM_GNSS_AGPS_KLOBUCHAR_REQUEST) ? 1 : 0, + req->nequick = (agps_data.data_flags & NRF_MODEM_GNSS_AGPS_NEQUICK_REQUEST) ? 1 : 0, + req->system_time_tow = + (agps_data.data_flags & NRF_MODEM_GNSS_AGPS_SYS_TIME_AND_SV_TOW_REQUEST) ? 1 : 0, + req->position = (agps_data.data_flags & NRF_MODEM_GNSS_AGPS_POSITION_REQUEST) ? 1 : 0, + req->integrity = (agps_data.data_flags & NRF_MODEM_GNSS_AGPS_INTEGRITY_REQUEST) ? 1 : 0; + + return 0; +} + +static void agps_req_wk(struct k_work *work) +{ + int err; + struct gps_agps_request req; + + ARG_UNUSED(work); + + err = read_agps_req(&req); + if (err) { + return; + } + + err = nrf_cloud_agps_request(req); + if (err) { + LOG_ERR("Failed to request A-GPS data: %d", err); + } +} + +static void pgps_req_wk(struct k_work *work) +{ + int err; + + ARG_UNUSED(work); + + /* Indirect request of P-GPS data and periodic injection */ + err = nrf_cloud_pgps_notify_prediction(); + if (err) { + LOG_ERR("Failed to request notify of prediction: %d", err); + } +} + +static void cell_pos_req_wk(struct k_work *work) +{ + int err; + + ARG_UNUSED(work); + + err = nrf_cloud_cell_pos_request(cell_pos_type, true); + if (err) { + LOG_ERR("Failed to request cell_pos %d, error: %d", cell_pos_type, err); + } +} + +static void pgps_event_handler(enum nrf_cloud_pgps_event event, + struct nrf_cloud_pgps_prediction *prediction) +{ + int err; + + switch (event) { + /* P-GPS initialization beginning. */ + case PGPS_EVT_INIT: + LOG_INF("PGPS_EVT_INIT"); + break; + /* There are currently no P-GPS predictions available. */ + case PGPS_EVT_UNAVAILABLE: + LOG_INF("PGPS_EVT_UNAVAILABLE"); + break; + /* P-GPS predictions are being loaded from the cloud. */ + case PGPS_EVT_LOADING: + LOG_INF("PGPS_EVT_LOADING"); + break; + /* A P-GPS prediction is available now for the current date and time. */ + case PGPS_EVT_AVAILABLE: { + struct gps_agps_request req; + + LOG_INF("PGPS_EVT_AVAILABLE"); + /* read out previous NRF_MODEM_GNSS_EVT_AGPS_REQ */ + err = read_agps_req(&req); + if (err) { + /* All assistance elements as requested */ + err = nrf_cloud_pgps_inject(prediction, &req, NULL); + } else { + /* ephemerides assistance only */ + err = nrf_cloud_pgps_inject(prediction, NULL, NULL); + } + if (err) { + LOG_ERR("Unable to send prediction to modem: %d", err); + break; + } + err = nrf_cloud_pgps_preemptive_updates(); + if (err) { + LOG_ERR("Preemptive updates error: %d", err); + } + } break; + /* All P-GPS predictions are available. */ + case PGPS_EVT_READY: + LOG_INF("PGPS_EVT_READY"); + break; + default: + break; + } +} + +static void on_gnss_evt_pvt(void) +{ + struct nrf_modem_gnss_pvt_data_frame pvt; + int err; + + err = nrf_modem_gnss_read((void *)&pvt, sizeof(pvt), NRF_MODEM_GNSS_DATA_PVT); + if (err) { + LOG_ERR("Failed to read GNSS PVT data, error %d", err); + return; + } + for (int i = 0; i < NRF_MODEM_GNSS_MAX_SATELLITES; ++i) { + if (pvt.sv[i].sv) { /* SV number 0 indicates no satellite */ + LOG_DBG("SV:%3d sig: %d c/n0:%4d", + pvt.sv[i].sv, pvt.sv[i].signal, pvt.sv[i].cn0); + } + } +} + +static void fix_rep_wk(struct k_work *work) +{ + int err; + struct nrf_modem_gnss_pvt_data_frame pvt; + + ARG_UNUSED(work); + + err = nrf_modem_gnss_read((void *)&pvt, sizeof(pvt), NRF_MODEM_GNSS_DATA_PVT); + if (err) { + LOG_ERR("Failed to read GNSS PVT data, error %d", err); + return; + } + + sprintf(rsp_buf, + "\r\n#XGPS: %lf,%lf,%f,%f,%f,%f,\"%04u-%02u-%02u %02u:%02u:%02u\"\r\n", + pvt.latitude, pvt.longitude, pvt.altitude, + pvt.accuracy, pvt.speed, pvt.heading, + pvt.datetime.year, pvt.datetime.month, pvt.datetime.day, + pvt.datetime.hour, pvt.datetime.minute, pvt.datetime.seconds); + rsp_send(rsp_buf, strlen(rsp_buf)); + + for (int i = 0; i < NRF_MODEM_GNSS_MAX_SATELLITES; ++i) { + if (pvt.sv[i].sv) { /* SV number 0 indicates no satellite */ + LOG_INF("SV:%3d sig: %d c/n0:%4d el:%3d az:%3d in-fix: %d unhealthy: %d", + pvt.sv[i].sv, pvt.sv[i].signal, pvt.sv[i].cn0, + pvt.sv[i].elevation, pvt.sv[i].azimuth, + (pvt.sv[i].flags & NRF_MODEM_GNSS_SV_FLAG_USED_IN_FIX) ? 1 : 0, + (pvt.sv[i].flags & NRF_MODEM_GNSS_SV_FLAG_UNHEALTHY) ? 1 : 0); + } + } + + if (run_type == RUN_TYPE_PGPS) { + struct tm gps_time = { + .tm_year = pvt.datetime.year - 1900, + .tm_mon = pvt.datetime.month - 1, + .tm_mday = pvt.datetime.day, + .tm_hour = pvt.datetime.hour, + .tm_min = pvt.datetime.minute, + .tm_sec = pvt.datetime.seconds, + }; + + /* help date_time to save SNTP transactions */ + date_time_set(&gps_time); + /* help nrf_cloud_pgps as most recent known location */ + nrf_cloud_pgps_set_location(pvt.latitude, pvt.longitude); + } +} + +static void on_gnss_evt_fix(void) +{ + if (ttft_start != 0) { + LOG_INF("TTFF %ds", (int)k_uptime_delta(&ttft_start)/1000); + ttft_start = 0; + } + + k_work_submit_to_queue(&slm_work_q, &fix_rep); +} + +static void on_gnss_evt_agps_req(void) +{ + if (run_type == RUN_TYPE_AGPS) { + k_work_submit_to_queue(&slm_work_q, &agps_req); + } else if (run_type == RUN_TYPE_PGPS) { + /* Check whether prediction data available or not */ + k_work_submit_to_queue(&slm_work_q, &pgps_req); + } +} + +/* NOTE this event handler runs in interrupt context */ +static void gnss_event_handler(int event) +{ + switch (event) { + case NRF_MODEM_GNSS_EVT_PVT: + LOG_DBG("GNSS_EVT_PVT"); + on_gnss_evt_pvt(); + break; + case NRF_MODEM_GNSS_EVT_FIX: + LOG_INF("GNSS_EVT_FIX"); + on_gnss_evt_fix(); + break; + case NRF_MODEM_GNSS_EVT_NMEA: + LOG_DBG("GNSS_EVT_NMEA"); + break; + case NRF_MODEM_GNSS_EVT_AGPS_REQ: + LOG_INF("GNSS_EVT_AGPS_REQ"); + on_gnss_evt_agps_req(); + break; + case NRF_MODEM_GNSS_EVT_BLOCKED: + LOG_INF("GNSS_EVT_BLOCKED"); + break; + case NRF_MODEM_GNSS_EVT_UNBLOCKED: + LOG_INF("GNSS_EVT_UNBLOCKED"); + break; + case NRF_MODEM_GNSS_EVT_PERIODIC_WAKEUP: + LOG_DBG("GNSS_EVT_PERIODIC_WAKEUP"); + break; + case NRF_MODEM_GNSS_EVT_SLEEP_AFTER_TIMEOUT: + LOG_DBG("GNSS_EVT_SLEEP_AFTER_TIMEOUT"); + break; + case NRF_MODEM_GNSS_EVT_SLEEP_AFTER_FIX: + LOG_DBG("GNSS_EVT_SLEEP_AFTER_FIX"); + break; + case NRF_MODEM_GNSS_EVT_REF_ALT_EXPIRED: + LOG_DBG("GNSS_EVT_REF_ALT_EXPIRED"); + break; + default: + break; + } +} + +static void on_cloud_evt_ready(void) +{ + if (location_signify) { + int err; + struct cloud_msg msg = { + .qos = CLOUD_QOS_AT_MOST_ONCE, + .endpoint.type = CLOUD_EP_STATE, + .buf = SERVICE_INFO_GPS, + .len = strlen(SERVICE_INFO_GPS) + }; + + /* Update nRF Cloud with GPS service info signifying GPS capabilities. */ + err = cloud_send(nrf_cloud, &msg); + if (err) { + LOG_WRN("Failed to send message to cloud, error: %d", err); + } + } + + nrf_cloud_ready = true; + sprintf(rsp_buf, "\r\n#XNRFCLOUD: %d,%d\r\n", nrf_cloud_ready, location_signify); + rsp_send(rsp_buf, strlen(rsp_buf)); +} + +static void on_cloud_evt_disconnected(void) +{ + nrf_cloud_ready = false; + sprintf(rsp_buf, "\r\n#XNRFCLOUD: %d,%d\r\n", nrf_cloud_ready, location_signify); + rsp_send(rsp_buf, strlen(rsp_buf)); +} + +static void on_cloud_evt_data_received(const struct cloud_event *const evt) +{ + int err = 0; + + if (run_type == RUN_TYPE_AGPS) { + err = nrf_cloud_agps_process(evt->data.msg.buf, evt->data.msg.len, NULL); + if (err) { + LOG_INF("Unable to process A-GPS data, error: %d", err); + } + } else if (run_type == RUN_TYPE_PGPS) { + err = nrf_cloud_pgps_process(evt->data.msg.buf, evt->data.msg.len); + if (err) { + LOG_ERR("Unable to process P-GPS data, error: %d", err); + } + } else if (run_type == RUN_TYPE_CELL_POS) { + struct nrf_cloud_cell_pos_result result; + + err = nrf_cloud_cell_pos_process(evt->data.msg.buf, &result); + if (err == 0) { + if (ttft_start != 0) { + LOG_INF("TTFF %ds", (int)k_uptime_delta(&ttft_start)/1000); + ttft_start = 0; + } + sprintf(rsp_buf, "\r\n#XCELLPOS: %d,%lf,%lf,%d\r\n", + result.type, result.lat, result.lon, result.unc); + rsp_send(rsp_buf, strlen(rsp_buf)); + run_type = RUN_TYPE_NONE; + } else if (err == 1) { + LOG_WRN("No position found"); + } else { + LOG_ERR("Unable to process cell pos data, error: %d", err); + } + } +} + +static void cloud_event_handler(const struct cloud_backend *const backend, + const struct cloud_event *const evt, void *user_data) +{ + ARG_UNUSED(backend); + ARG_UNUSED(user_data); + + switch (evt->type) { + case CLOUD_EVT_CONNECTING: + LOG_DBG("CLOUD_EVT_CONNECTING"); + break; + case CLOUD_EVT_CONNECTED: + LOG_INF("CLOUD_EVT_CONNECTED"); + break; + case CLOUD_EVT_READY: + LOG_INF("CLOUD_EVT_READY"); + on_cloud_evt_ready(); + break; + case CLOUD_EVT_DISCONNECTED: + LOG_INF("CLOUD_EVT_DISCONNECTED"); + on_cloud_evt_disconnected(); + break; + case CLOUD_EVT_ERROR: + LOG_ERR("CLOUD_EVT_ERROR"); + break; + case CLOUD_EVT_DATA_SENT: + LOG_DBG("CLOUD_EVT_DATA_SENT"); + break; + case CLOUD_EVT_DATA_RECEIVED: + LOG_INF("CLOUD_EVT_DATA_RECEIVED"); + on_cloud_evt_data_received(evt); + break; + case CLOUD_EVT_PAIR_REQUEST: + LOG_DBG("CLOUD_EVT_PAIR_REQUEST"); + break; + case CLOUD_EVT_PAIR_DONE: + LOG_DBG("CLOUD_EVT_PAIR_DONE"); + break; + case CLOUD_EVT_FOTA_DONE: + LOG_DBG("CLOUD_EVT_FOTA_DONE"); + break; + case CLOUD_EVT_FOTA_ERROR: + LOG_ERR("CLOUD_EVT_FOTA_ERROR"); + break; + default: + break; + } +} + +static void date_time_event_handler(const struct date_time_evt *evt) +{ + switch (evt->type) { + case DATE_TIME_OBTAINED_MODEM: + case DATE_TIME_OBTAINED_NTP: + case DATE_TIME_OBTAINED_EXT: + LOG_DBG("DATE_TIME OBTAINED"); + k_sem_give(&sem_date_time); + break; + case DATE_TIME_NOT_OBTAINED: + LOG_INF("DATE_TIME_NOT_OBTAINED"); + break; + default: + break; + } +} + +/**@brief handle AT#XGPS commands + * AT#XGPS=[,[,]] + * AT#XGPS? READ command not supported + * AT#XGPS=? + */ +int handle_at_gps(enum at_cmd_type cmd_type) +{ + int err = -EINVAL; + uint16_t op; + uint16_t interval; + uint16_t timeout; + + switch (cmd_type) { + case AT_CMD_TYPE_SET_COMMAND: + err = at_params_unsigned_short_get(&at_param_list, 1, &op); + if (err < 0) { + return err; + } + if (op == GPS_START && run_type == RUN_TYPE_NONE) { + err = at_params_unsigned_short_get(&at_param_list, 2, &interval); + if (err < 0) { + return err; + } + /* GNSS API spec check */ + if (interval != 0 && interval != 1 && + (interval < 10 || interval > 65535)) { + return -EINVAL; + } + if (interval == 0) { + err = nrf_modem_gnss_use_case_set( + NRF_MODEM_GNSS_USE_CASE_LOW_ACCURACY); + if (err) { + LOG_ERR("Failed to set use case, error: %d", err); + return err; + } + } + err = nrf_modem_gnss_fix_interval_set(interval); + if (err) { + LOG_ERR("Failed to set fix interval, error: %d", err); + return err; + } + if (at_params_unsigned_short_get(&at_param_list, 3, &timeout) == 0) { + err = nrf_modem_gnss_fix_retry_set(timeout); + if (err) { + LOG_ERR("Failed to set fix retry, error: %d", err); + return err; + } + } + + run_type = RUN_TYPE_GPS; + err = nrf_modem_gnss_start(); + if (err) { + LOG_ERR("Failed to start GPS, error: %d", err); + run_type = RUN_TYPE_NONE; + } else { + ttft_start = k_uptime_get(); + } + } else if (op == GPS_STOP && run_type == RUN_TYPE_GPS) { + err = nrf_modem_gnss_stop(); + run_type = RUN_TYPE_NONE; + } else { + err = -EINVAL; + } break; + + case AT_CMD_TYPE_TEST_COMMAND: + sprintf(rsp_buf, "\r\n#XGPS: (%d,%d),,\r\n", + GPS_STOP, GPS_START); + rsp_send(rsp_buf, strlen(rsp_buf)); + err = 0; + break; + + default: + break; + } + + return err; +} + +/**@brief handle AT#XNRFCLOUD commands + * AT#XNRFCLOUD=[,] + * AT#XNRFCLOUD? + * AT#XNRFCLOUD=? + */ +int handle_at_nrf_cloud(enum at_cmd_type cmd_type) +{ + int err = -EINVAL; + uint16_t op; + uint16_t signify = 0; + + switch (cmd_type) { + case AT_CMD_TYPE_SET_COMMAND: + err = at_params_unsigned_short_get(&at_param_list, 1, &op); + if (err < 0) { + return err; + } + if (op == nRF_CLOUD_CONNECT && !nrf_cloud_ready) { + location_signify = 0; + if (at_params_valid_count_get(&at_param_list) > 2) { + err = at_params_unsigned_short_get(&at_param_list, 2, &signify); + if (err < 0) { + return err; + } + location_signify = (signify > 0); + } + err = cloud_connect(nrf_cloud); + if (err) { + LOG_ERR("Cloud connection failed, error: %d", err); + } + } else if (op == nRF_CLOUD_DISCONNECT && nrf_cloud_ready) { + err = cloud_disconnect(nrf_cloud); + if (err) { + LOG_ERR("Cloud disconnection failed, error: %d", err); + } + } else { + err = -EINVAL; + } break; + + case AT_CMD_TYPE_READ_COMMAND: + sprintf(rsp_buf, "\r\n#XNRFCLOUD: %d,%d\r\n", nrf_cloud_ready, location_signify); + rsp_send(rsp_buf, strlen(rsp_buf)); + err = 0; + break; + + case AT_CMD_TYPE_TEST_COMMAND: + sprintf(rsp_buf, "\r\n#XNRFCLOUD: (%d,%d),\r\n", + nRF_CLOUD_CONNECT, nRF_CLOUD_DISCONNECT); + rsp_send(rsp_buf, strlen(rsp_buf)); + err = 0; + break; + + default: + break; + } + + return err; +} + +/**@brief handle AT#XAGPS commands + * AT#XAGPS=[,[,]] + * AT#XAGPS? READ command not supported + * AT#XAGPS=? + */ +int handle_at_agps(enum at_cmd_type cmd_type) +{ + int err = -EINVAL; + uint16_t op; + uint16_t interval; + uint16_t timeout; + + switch (cmd_type) { + case AT_CMD_TYPE_SET_COMMAND: + err = at_params_unsigned_short_get(&at_param_list, 1, &op); + if (err < 0) { + return err; + } + if (op == AGPS_START && nrf_cloud_ready && run_type == RUN_TYPE_NONE) { + err = at_params_unsigned_short_get(&at_param_list, 2, &interval); + if (err < 0) { + return err; + } + /* GNSS API spec check */ + if (interval != 0 && interval != 1 && + (interval < 10 || interval > 65535)) { + return -EINVAL; + } + if (interval == 0) { + err = nrf_modem_gnss_use_case_set( + NRF_MODEM_GNSS_USE_CASE_LOW_ACCURACY); + if (err) { + LOG_ERR("Failed to set use case, error: %d", err); + return err; + } + } + err = nrf_modem_gnss_fix_interval_set(interval); + if (err) { + LOG_ERR("Failed to set fix interval, error: %d", err); + return err; + } + if (at_params_unsigned_short_get(&at_param_list, 3, &timeout) == 0) { + err = nrf_modem_gnss_fix_retry_set(timeout); + if (err) { + LOG_ERR("Failed to set fix retry, error: %d", err); + return err; + } + } + + /* A-GPS needs date_time, trigger to update current time */ + date_time_update_async(date_time_event_handler); + if (k_sem_take(&sem_date_time, K_SECONDS(10)) != 0) { + LOG_ERR("Failed to get current time"); + return -EAGAIN; + } + + /** set the flag before starting GNSS as modem instantly + * send NRF_MODEM_GNSS_EVT_AGPS_REQ event + */ + run_type = RUN_TYPE_AGPS; + err = nrf_modem_gnss_start(); + LOG_INF("[JUZO] nrf_modem_gnss_start %d", err); + if (err) { + LOG_ERR("Failed to start GNSS, error: %d", err); + run_type = RUN_TYPE_NONE; + } else { + ttft_start = k_uptime_get(); + } + } else if (op == AGPS_STOP && run_type == RUN_TYPE_AGPS) { + err = nrf_modem_gnss_stop(); + run_type = RUN_TYPE_NONE; + } else { + err = -EINVAL; + } break; + + case AT_CMD_TYPE_TEST_COMMAND: + sprintf(rsp_buf, "\r\n#XAGPS: (%d,%d),,\r\n", + AGPS_STOP, AGPS_START); + rsp_send(rsp_buf, strlen(rsp_buf)); + err = 0; + break; + + default: + break; + } + + return err; +} + +/**@brief handle AT#XPGPS commands + * AT#XPGPS=[,[,]] + * AT#XPGPS? READ command not supported + * AT#XPGPS=? + */ +int handle_at_pgps(enum at_cmd_type cmd_type) +{ + int err = -EINVAL; + uint16_t op; + uint16_t interval; + uint16_t timeout; + + switch (cmd_type) { + case AT_CMD_TYPE_SET_COMMAND: + err = at_params_unsigned_short_get(&at_param_list, 1, &op); + if (err < 0) { + return err; + } + if (op == PGPS_START && nrf_cloud_ready && run_type == RUN_TYPE_NONE) { + err = at_params_unsigned_short_get(&at_param_list, 2, &interval); + if (err < 0) { + return err; + } + /* GNSS API spec check, P-GPS is used in periodic mode only */ + if (interval < 10 || interval > 65535) { + return -EINVAL; + } + err = nrf_modem_gnss_fix_interval_set(interval); + if (err) { + LOG_ERR("Failed to set fix interval, error: %d", err); + return err; + } + if (at_params_unsigned_short_get(&at_param_list, 3, &timeout) == 0) { + err = nrf_modem_gnss_fix_retry_set(timeout); + if (err) { + LOG_ERR("Failed to set fix retry, error: %d", err); + return err; + } + } + + /* P-GPS needs date_time, trigger to update current time */ + date_time_update_async(date_time_event_handler); + if (k_sem_take(&sem_date_time, K_SECONDS(10)) != 0) { + LOG_ERR("Failed to get current time"); + return -EAGAIN; + } + + struct nrf_cloud_pgps_init_param param = { + .event_handler = pgps_event_handler, + .storage_base = PM_MCUBOOT_SECONDARY_ADDRESS, + .storage_size = PM_MCUBOOT_SECONDARY_SIZE}; + + err = nrf_cloud_pgps_init(¶m); + if (err) { + LOG_ERR("Error from P-GPS init: %d", err); + return err; + } + + run_type = RUN_TYPE_PGPS; + err = nrf_modem_gnss_start(); + if (err) { + LOG_ERR("Failed to start GNSS, error: %d", err); + run_type = RUN_TYPE_NONE; + } else { + ttft_start = k_uptime_get(); + } + } else if (op == PGPS_STOP && run_type == RUN_TYPE_PGPS) { + err = nrf_modem_gnss_stop(); + run_type = RUN_TYPE_NONE; + } else { + err = -EINVAL; + } break; + + case AT_CMD_TYPE_TEST_COMMAND: + sprintf(rsp_buf, "\r\n#XPGPS: (%d,%d),,\r\n", + PGPS_STOP, PGPS_START); + rsp_send(rsp_buf, strlen(rsp_buf)); + err = 0; + break; + + default: + break; + } + + return err; +} + +/**@brief handle AT#XCELLPOS commands + * AT#XCELLPOS= + * AT#XCELLPOS? READ command not supported + * AT#XCELLPOS=? + */ +int handle_at_cellpos(enum at_cmd_type cmd_type) +{ + int err = -EINVAL; + uint16_t op; + + switch (cmd_type) { + case AT_CMD_TYPE_SET_COMMAND: + err = at_params_unsigned_short_get(&at_param_list, 1, &op); + if (err < 0) { + return err; + } + if ((op == CELLPOS_START_SCELL || op == CELLPOS_START_MCELL) && + nrf_cloud_ready && run_type == RUN_TYPE_NONE) { + if (op == CELLPOS_START_SCELL) { + cell_pos_type = CELL_POS_TYPE_SINGLE; + } else { + sprintf(rsp_buf, "\r\n#XCELLPOS: \"not supported\"\r\n"); + rsp_send(rsp_buf, strlen(rsp_buf)); + return -ENOTSUP; + } + ttft_start = k_uptime_get(); + k_work_submit_to_queue(&slm_work_q, &cell_pos_req); + run_type = RUN_TYPE_CELL_POS; + } else if (op == CELLPOS_STOP) { + run_type = RUN_TYPE_NONE; + } else { + err = -EINVAL; + } break; + + case AT_CMD_TYPE_TEST_COMMAND: + sprintf(rsp_buf, "\r\n#XCELLPOS: (%d,%d,%d)\r\n", + CELLPOS_STOP, CELLPOS_START_SCELL, CELLPOS_START_MCELL); + rsp_send(rsp_buf, strlen(rsp_buf)); + err = 0; + break; + + default: + break; + } + + return err; +} + +/**@brief API to initialize GNSS AT commands handler + */ +int slm_at_gnss_init(void) +{ + int err = 0; + + err = nrf_modem_gnss_init(); + if (err) { + LOG_ERR("Could not initialize GNSS, error: %d", err); + return err; + } + err = nrf_modem_gnss_event_handler_set(gnss_event_handler); + if (err) { + LOG_ERR("Could set GNSS event handler, error: %d", err); + return err; + } + + if (nrf_cloud == NULL) { + nrf_cloud = cloud_get_binding("NRF_CLOUD"); + if (nrf_cloud == NULL) { + LOG_ERR("Could not get binding to backend"); + return -EINVAL; + } + err = cloud_init(nrf_cloud, cloud_event_handler); + if (err) { + LOG_ERR("Cloud backend could not be initialized, error: %d", err); + return err; + } + } + + k_work_init(&agps_req, agps_req_wk); + k_work_init(&pgps_req, pgps_req_wk); + k_work_init(&cell_pos_req, cell_pos_req_wk); + k_work_init(&fix_rep, fix_rep_wk); + + return err; +} + +/**@brief API to uninitialize GNSS AT commands handler + */ +int slm_at_gnss_uninit(void) +{ + if (nrf_cloud_ready) { + (void)cloud_disconnect(nrf_cloud); + } + (void)cloud_uninit(nrf_cloud); + nrf_cloud = NULL; + (void)nrf_modem_gnss_deinit(); + + return 0; +} diff --git a/applications/serial_lte_modem/src/gnss/slm_at_gnss.h b/applications/serial_lte_modem/src/gnss/slm_at_gnss.h new file mode 100644 index 000000000000..d39673bbc675 --- /dev/null +++ b/applications/serial_lte_modem/src/gnss/slm_at_gnss.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +#ifndef SLM_AT_GNSS_ +#define SLM_AT_GNSS_ + +/**@file slm_at_gnss.h + * + * @brief Vendor-specific AT command for GNSS service. + * @{ + */ + +/** + * @brief Initialize GNSS AT command parser. + * + * @retval 0 If the operation was successful. + * Otherwise, a (negative) error code is returned. + */ +int slm_at_gnss_init(void); + +/** + * @brief Uninitialize GNSS AT command parser. + * + * @retval 0 If the operation was successful. + * Otherwise, a (negative) error code is returned. + */ +int slm_at_gnss_uninit(void); + +/** @} */ + +#endif /* SLM_AT_GNSS_ */ diff --git a/applications/serial_lte_modem/src/gps/CMakeLists.txt b/applications/serial_lte_modem/src/gps/CMakeLists.txt deleted file mode 100644 index 58f8eccb2715..000000000000 --- a/applications/serial_lte_modem/src/gps/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# -# Copyright (c) 2020 Nordic Semiconductor -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -# - -zephyr_include_directories(.) -target_sources_ifdef(CONFIG_SLM_GPS app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/slm_at_gps.c) diff --git a/applications/serial_lte_modem/src/gps/Kconfig b/applications/serial_lte_modem/src/gps/Kconfig deleted file mode 100644 index 28af44d23ddf..000000000000 --- a/applications/serial_lte_modem/src/gps/Kconfig +++ /dev/null @@ -1,21 +0,0 @@ -# -# Copyright (c) 2020 Nordic Semiconductor ASA -# -# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - -config SLM_GPS - bool "GPS support in SLM" - default y - - -if SLM_GPS - -config SLM_SUPL_SERVER - string "SUPL server" - default "supl.google.com" - -config SLM_SUPL_PORT - int "SUPL server port" - default 7276 - -endif diff --git a/applications/serial_lte_modem/src/gps/slm_at_gps.c b/applications/serial_lte_modem/src/gps/slm_at_gps.c deleted file mode 100644 index ead15e495f33..000000000000 --- a/applications/serial_lte_modem/src/gps/slm_at_gps.c +++ /dev/null @@ -1,508 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ -#include - -#include -#include -#include -#include "slm_util.h" -#include "slm_at_host.h" -#include "slm_at_gps.h" - -#ifdef CONFIG_SUPL_CLIENT_LIB -#include -#include -#include -#endif - -LOG_MODULE_REGISTER(slm_gps, CONFIG_SLM_LOG_LEVEL); - -#define IS_FIX(_flag) (_flag & NRF_GNSS_PVT_FLAG_FIX_VALID_BIT) -#define IS_UNHEALTHY(_flag) (_flag & NRF_GNSS_SV_FLAG_UNHEALTHY) - -#define INVALID_SOCKET -1 - -/**@brief List of supported AT commands. */ -enum slm_gps_mode { - GPS_MODE_STANDALONE, - GPS_MODE_PSM, - GPS_MODE_EDRX, - GPS_MODE_AGPS -}; - -static struct gps_client { - int sock; /* Socket descriptor. */ - uint16_t mask; /* NMEA mask */ - bool running; /* GPS running status */ - bool has_fix; /* At least one fix is got */ -} client; - -static nrf_gnss_data_frame_t gps_data; - -#define THREAD_STACK_SIZE KB(1) -#define THREAD_PRIORITY K_LOWEST_APPLICATION_THREAD_PRIO - -static struct k_thread gps_thread; -static k_tid_t gps_thread_id; -static K_THREAD_STACK_DEFINE(gps_thread_stack, THREAD_STACK_SIZE); -static uint64_t ttft_start; - -/* global variable defined in different files */ -extern struct at_param_list at_param_list; -extern char rsp_buf[CONFIG_AT_CMD_RESPONSE_MAX_LEN]; -extern struct k_work_q slm_work_q; - -#ifdef CONFIG_SUPL_CLIENT_LIB -static int supl_fd; -int connect_supl_server(void) -{ - int ret; - struct sockaddr_in server; - struct addrinfo *res; - struct addrinfo hints = { - .ai_family = AF_INET, - .ai_socktype = SOCK_STREAM, - .ai_protocol = IPPROTO_TCP, - /* Either a valid, - * NULL-terminated access point name or NULL. - */ - .ai_canonname = NULL, - }; - - ret = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (ret < 0) { - LOG_ERR("socket() error: %d", -errno); - return -errno; - } - - supl_fd = ret; - ret = getaddrinfo(CONFIG_SLM_SUPL_SERVER, NULL, &hints, &res); - if (ret || res == NULL) { - LOG_ERR("getaddrinfo() error: %d", ret); - close(supl_fd); - return ret; - } - server.sin_family = AF_INET; - server.sin_port = htons(CONFIG_SLM_SUPL_PORT); - server.sin_addr.s_addr = - ((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr; - ret = connect(supl_fd, (struct sockaddr *)&server, - sizeof(struct sockaddr_in)); - if (ret) { - LOG_ERR("connect() error: %d", -errno); - close(supl_fd); - ret = -errno; - } - - freeaddrinfo(res); - return ret; -} - -ssize_t supl_write(const void *buff, size_t nbytes, void *user_data) -{ - ARG_UNUSED(user_data); - return send(supl_fd, buff, nbytes, 0); -} - -int supl_logger(int level, const char *fmt, ...) -{ - char buffer[256] = { 0 }; - va_list args; - - va_start(args, fmt); - int ret = vsnprintk(buffer, sizeof(buffer), fmt, args); - - va_end(args); - - if (ret < 0) { - LOG_ERR("[SUPL] Encoding error"); - return ret; - } else if ((size_t)ret >= sizeof(buffer)) { - LOG_WRN("[SUPL] Too long message"); - } - - LOG_DBG("[SUPL] %s", log_strdup(buffer)); - - return ret; -} - -ssize_t supl_read(void *buff, size_t nbytes, void *user_data) -{ - ssize_t rc = recv(supl_fd, buff, nbytes, 0); - - ARG_UNUSED(user_data); - - if (rc < 0 && (errno == ETIMEDOUT)) { - return 0; - } - - return rc; -} - -int supl_inject(void *agps, size_t agps_size, nrf_gnss_agps_data_type_t type, - void *user_data) -{ - int ret; - - ARG_UNUSED(user_data); - - ret = nrf_sendto(client.sock, agps, agps_size, 0, &type, sizeof(type)); - if (ret) { - LOG_ERR("Inject error, type: %d (err: %d)", type, errno); - return ret; - } - - LOG_INF("Injected AGPS data, flags: %d, size: %d", type, agps_size); - return 0; -} - -void supl_handler(struct k_work *work) -{ - int ret; - nrf_gnss_delete_mask_t delete_mask = 0; - - ARG_UNUSED(work); - - /* suspend GPS */ - ret = nrf_setsockopt(client.sock, NRF_SOL_GNSS, NRF_SO_GNSS_STOP, - &delete_mask, sizeof(delete_mask)); - if (ret) { - LOG_ERR("Failed to suspend GPS (err: %d)", -errno); - return; - } - k_thread_suspend(gps_thread_id); - sprintf(rsp_buf, "#XGPSS: \"GPS suspended\"\r\n"); - rsp_send(rsp_buf, strlen(rsp_buf)); - - /* SUPL injection */ - ret = connect_supl_server(); - if (ret == 0) { - LOG_DBG("SUPL session start"); - supl_session(&gps_data.agps); - LOG_DBG("SUPL session done"); - close(supl_fd); - } - sprintf(rsp_buf, "#XGPSS: \"SUPL injection done\"\r\n"); - rsp_send(rsp_buf, strlen(rsp_buf)); - - /* Resume GPS */ - k_thread_resume(gps_thread_id); - ret = nrf_setsockopt(client.sock, NRF_SOL_GNSS, NRF_SO_GNSS_START, - &delete_mask, sizeof(delete_mask)); - if (ret) { - LOG_ERR("Failed to resume GPS (err: %d)", -errno); - } else { - ttft_start = k_uptime_get(); - sprintf(rsp_buf, "#XGPSS: \"GPS resumed\"\r\n"); - rsp_send(rsp_buf, strlen(rsp_buf)); - } -} - -K_WORK_DEFINE(supl_work, supl_handler); - -#endif /* CONFIG_SUPL_CLIENT_LIB */ - -static void gps_satellite_stats(void) -{ - static uint8_t last_tracked; - uint8_t tracked = 0; - uint8_t in_fix = 0; - uint8_t unhealthy = 0; - - if (gps_data.data_id != NRF_GNSS_PVT_DATA_ID || client.has_fix) { - return; - } - - for (int i = 0; i < NRF_GNSS_MAX_SATELLITES; ++i) { - if ((gps_data.pvt.sv[i].sv > 0) && - (gps_data.pvt.sv[i].sv < 33)) { - LOG_DBG("GPS tracking: %d", gps_data.pvt.sv[i].sv); - tracked++; - if (IS_FIX(gps_data.pvt.sv[i].flags)) { - in_fix++; - } - if (IS_UNHEALTHY(gps_data.pvt.sv[i].flags)) { - unhealthy++; - } - } - } - - if (last_tracked != tracked) { - sprintf(rsp_buf, - "#XGPSS: \"track %d use %d unhealthy %d\"\r\n", - tracked, in_fix, unhealthy); - rsp_send(rsp_buf, strlen(rsp_buf)); - last_tracked = tracked; - } -} - -static void gps_pvt_notify(void) -{ - sprintf(rsp_buf, "#XGPSP: \"long %f lat %f\"\r\n", - gps_data.pvt.longitude, - gps_data.pvt.latitude); - rsp_send(rsp_buf, strlen(rsp_buf)); - sprintf(rsp_buf, "#XGPSP: \"%04u-%02u-%02u %02u:%02u:%02u\"\r\n", - gps_data.pvt.datetime.year, - gps_data.pvt.datetime.month, - gps_data.pvt.datetime.day, - gps_data.pvt.datetime.hour, - gps_data.pvt.datetime.minute, - gps_data.pvt.datetime.seconds); - rsp_send(rsp_buf, strlen(rsp_buf)); -} - -static void gps_thread_fn(void *arg1, void *arg2, void *arg3) -{ - ARG_UNUSED(arg1); - ARG_UNUSED(arg2); - ARG_UNUSED(arg3); - - while (true) { - if (nrf_recv(client.sock, &gps_data, sizeof(gps_data), 0) - <= 0) { - LOG_ERR("GPS nrf_recv(): %d", -errno); - sprintf(rsp_buf, "#XGPS: %d\r\n", -errno); - rsp_send(rsp_buf, strlen(rsp_buf)); - nrf_close(client.sock); - client.running = false; - break; - } - gps_satellite_stats(); - switch (gps_data.data_id) { - case NRF_GNSS_PVT_DATA_ID: - if (IS_FIX(gps_data.pvt.flags)) { - gps_pvt_notify(); - if (!client.has_fix) { - uint64_t now = k_uptime_get(); - - sprintf(rsp_buf, - "#XGPSP: \"TTFF %ds\"\r\n", - (int)(now - ttft_start)/1000); - rsp_send(rsp_buf, strlen(rsp_buf)); - client.has_fix = true; - } - } - break; - case NRF_GNSS_NMEA_DATA_ID: - if (client.has_fix) { - rsp_send(gps_data.nmea, - strlen(gps_data.nmea)); - } - break; - - case NRF_GNSS_AGPS_DATA_ID: -#ifdef CONFIG_SUPL_CLIENT_LIB - LOG_INF("New AGPS data requested, flags 0x%08x", - gps_data.agps.data_flags); - k_work_submit_to_queue(&slm_work_q, &supl_work); -#endif - break; - - default: - break; - } - } -} - -static int do_gps_start(void) -{ - int ret = -EINVAL; - - nrf_gnss_fix_retry_t fix_retry = 0; /* unlimited retry period */ - nrf_gnss_fix_interval_t fix_interval = 1; /* 1s delay between fixes */ - nrf_gnss_delete_mask_t delete_mask = 0; - nrf_gnss_nmea_mask_t nmea_mask = (nrf_gnss_nmea_mask_t)client.mask; - - client.sock = nrf_socket(NRF_AF_LOCAL, NRF_SOCK_DGRAM, NRF_PROTO_GNSS); - if (client.sock < 0) { - LOG_ERR("Could not init socket (err: %d)", -errno); - goto error; - } - ret = nrf_setsockopt(client.sock, NRF_SOL_GNSS, NRF_SO_GNSS_FIX_RETRY, - &fix_retry, sizeof(fix_retry)); - if (ret) { - LOG_ERR("Failed to set fix retry value (err: %d)", -errno); - goto error; - } - ret = nrf_setsockopt(client.sock, NRF_SOL_GNSS, - NRF_SO_GNSS_FIX_INTERVAL, &fix_interval, sizeof(fix_interval)); - if (ret) { - LOG_ERR("Failed to set fix interval value (err: %d)", -errno); - goto error; - } - ret = nrf_setsockopt(client.sock, NRF_SOL_GNSS, NRF_SO_GNSS_NMEA_MASK, - &nmea_mask, sizeof(nmea_mask)); - if (ret) { - LOG_ERR("Failed to set nmea mask (err: %d)", -errno); - goto error; - } - ret = nrf_setsockopt(client.sock, NRF_SOL_GNSS, NRF_SO_GNSS_START, - &delete_mask, sizeof(delete_mask)); - if (ret) { - LOG_ERR("Failed to start GPS (err: %d)", -errno); - goto error; - } - - /* Start GPS listening thread */ - if (gps_thread_id != NULL) { - k_thread_resume(gps_thread_id); - } else { - gps_thread_id = k_thread_create(&gps_thread, gps_thread_stack, - K_THREAD_STACK_SIZEOF(gps_thread_stack), - gps_thread_fn, NULL, NULL, NULL, - THREAD_PRIORITY, 0, K_NO_WAIT); - } - - client.running = true; - LOG_DBG("GPS started"); - - sprintf(rsp_buf, "#XGPS: 1,%d\r\n", client.mask); - rsp_send(rsp_buf, strlen(rsp_buf)); - ttft_start = k_uptime_get(); - return 0; - -error: - nrf_close(client.sock); - LOG_ERR("GPS start failed: %d", ret); - sprintf(rsp_buf, "#XGPS: %d\r\n", ret); - rsp_send(rsp_buf, strlen(rsp_buf)); - client.running = false; - - return -errno; -} - -static int do_gps_stop(void) -{ - int ret = 0; - nrf_gnss_delete_mask_t delete_mask = 0; - - if (client.sock != INVALID_SOCKET) { - ret = nrf_setsockopt(client.sock, NRF_SOL_GNSS, - NRF_SO_GNSS_STOP, &delete_mask, sizeof(delete_mask)); - if (ret != 0) { - LOG_ERR("Failed to stop GPS (err: %d)", -errno); - ret = -errno; - } else { - k_thread_suspend(gps_thread_id); - nrf_close(client.sock); - client.running = false; - sprintf(rsp_buf, "#XGPS: 0\r\n"); - rsp_send(rsp_buf, strlen(rsp_buf)); - LOG_DBG("GPS stopped"); - } - - } - - return ret; -} - -/**@brief handle AT#XGPS commands - * AT#XGPS=[,] - * AT#XGPS? - * AT#XGPS=? TEST command not supported - */ -int handle_at_gps(enum at_cmd_type cmd_type) -{ - int err = -EINVAL; - uint16_t op; - - switch (cmd_type) { - case AT_CMD_TYPE_SET_COMMAND: - err = at_params_unsigned_short_get(&at_param_list, 1, &op); - if (err < 0) { - return err; - } - if (op == 1) { - if (at_params_valid_count_get(&at_param_list) > 2) { - err = at_params_unsigned_short_get(&at_param_list, 2, - &client.mask); - if (err < 0) { - return err; - } - } - if (client.running) { - LOG_WRN("GPS is running"); - } else { - err = do_gps_start(); - } - } else if (op == 0) { - if (!client.running) { - LOG_WRN("GPS is not running"); - } else { - err = do_gps_stop(); - } - } break; - - case AT_CMD_TYPE_READ_COMMAND: - if (client.running) { - sprintf(rsp_buf, "#XGPS: 1,%d\r\n", client.mask); - } else { - sprintf(rsp_buf, "#XGPS: 0\r\n"); - } - rsp_send(rsp_buf, strlen(rsp_buf)); - err = 0; - break; - - case AT_CMD_TYPE_TEST_COMMAND: - sprintf(rsp_buf, "#XGPS: (0,1),(bitmask)\r\n"); - rsp_send(rsp_buf, strlen(rsp_buf)); - err = 0; - break; - - default: - break; - } - - return err; -} - -/**@brief API to initialize GPS AT commands handler - */ -int slm_at_gps_init(void) -{ -#ifdef CONFIG_SUPL_CLIENT_LIB - int ret; - static struct supl_api supl_api = { - .read = supl_read, - .write = supl_write, - .handler = supl_inject, - .logger = supl_logger, - .counter_ms = k_uptime_get - }; - - ret = supl_init(&supl_api); - if (ret) { - LOG_ERR("SUPL init error: %d", ret); - return ret; - } -#endif - - client.sock = INVALID_SOCKET; - client.mask = NRF_GNSS_NMEA_GSV_MASK | - NRF_GNSS_NMEA_GSA_MASK | - NRF_GNSS_NMEA_GLL_MASK | - NRF_GNSS_NMEA_GGA_MASK | - NRF_GNSS_NMEA_RMC_MASK; - client.running = false; - client.has_fix = false; - gps_thread_id = NULL; - - return 0; -} - -/**@brief API to uninitialize GPS AT commands handler - */ -int slm_at_gps_uninit(void) -{ - if (gps_thread_id != NULL) { - do_gps_stop(); - k_thread_abort(gps_thread_id); - gps_thread_id = NULL; - } - - return 0; -} diff --git a/applications/serial_lte_modem/src/gps/slm_at_gps.h b/applications/serial_lte_modem/src/gps/slm_at_gps.h deleted file mode 100644 index 0d12f5133561..000000000000 --- a/applications/serial_lte_modem/src/gps/slm_at_gps.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2020 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -#ifndef SLM_AT_GPS_ -#define SLM_AT_GPS_ - -/**@file slm_at_gps.h - * - * @brief Vendor-specific AT command for GPS service. - * @{ - */ - -#include -#include - -/** - * @brief GPS AT command parser. - * - * @param at_cmd AT command string. - * - * @retval 0 If the operation was successful. - * Otherwise, a (negative) error code is returned. - */ -int slm_at_gps_parse(const char *at_cmd); - -/** - * @brief List GPS AT commands. - * - */ -void slm_at_gps_clac(void); - -/** - * @brief Initialize GPS AT command parser. - * - * @retval 0 If the operation was successful. - * Otherwise, a (negative) error code is returned. - */ -int slm_at_gps_init(void); - -/** - * @brief Uninitialize GPS AT command parser. - * - * @retval 0 If the operation was successful. - * Otherwise, a (negative) error code is returned. - */ -int slm_at_gps_uninit(void); - -/** @} */ - -#endif /* SLM_AT_GPS_ */ diff --git a/applications/serial_lte_modem/src/main.c b/applications/serial_lte_modem/src/main.c index 6bd0c79df633..c29662fc783c 100644 --- a/applications/serial_lte_modem/src/main.c +++ b/applications/serial_lte_modem/src/main.c @@ -26,7 +26,7 @@ LOG_MODULE_REGISTER(slm, CONFIG_SLM_LOG_LEVEL); -#define SLM_WQ_STACK_SIZE KB(2) +#define SLM_WQ_STACK_SIZE KB(4) #define SLM_WQ_PRIORITY K_LOWEST_APPLICATION_THREAD_PRIO static K_THREAD_STACK_DEFINE(slm_wq_stack_area, SLM_WQ_STACK_SIZE); diff --git a/applications/serial_lte_modem/src/slm_at_commands.c b/applications/serial_lte_modem/src/slm_at_commands.c index 3cf2129982d7..3a60534ea6a0 100644 --- a/applications/serial_lte_modem/src/slm_at_commands.c +++ b/applications/serial_lte_modem/src/slm_at_commands.c @@ -28,8 +28,8 @@ #include "slm_at_icmp.h" #include "slm_at_sms.h" #include "slm_at_fota.h" -#if defined(CONFIG_SLM_GPS) -#include "slm_at_gps.h" +#if defined(CONFIG_SLM_GNSS) +#include "slm_at_gnss.h" #endif #if defined(CONFIG_SLM_FTPC) #include "slm_at_ftp.h" @@ -340,8 +340,12 @@ int handle_at_sms(enum at_cmd_type cmd_type); /* FOTA commands */ int handle_at_fota(enum at_cmd_type cmd_type); -#if defined(CONFIG_SLM_GPS) +#if defined(CONFIG_SLM_GNSS) int handle_at_gps(enum at_cmd_type cmd_type); +int handle_at_nrf_cloud(enum at_cmd_type cmd_type); +int handle_at_agps(enum at_cmd_type cmd_type); +int handle_at_pgps(enum at_cmd_type cmd_type); +int handle_at_cellpos(enum at_cmd_type cmd_type); #endif #if defined(CONFIG_SLM_FTPC) @@ -420,9 +424,19 @@ static struct slm_at_cmd { /* FOTA commands */ {"AT#XFOTA", handle_at_fota}, -#if defined(CONFIG_SLM_GPS) - /* GPS commands */ +#if defined(CONFIG_SLM_GNSS) + /* GNSS commands */ {"AT#XGPS", handle_at_gps}, + {"AT#XNRFCLOUD", handle_at_nrf_cloud}, +#if defined(CONFIG_SLM_AGPS) + {"AT#XAGPS", handle_at_agps}, +#endif +#if defined(CONFIG_SLM_PGPS) + {"AT#XPGPS", handle_at_pgps}, +#endif +#if defined(CONFIG_SLM_CELL_POS) + {"AT#XCELLPOS", handle_at_cellpos}, +#endif #endif #if defined(CONFIG_SLM_FTPC) @@ -536,8 +550,8 @@ int slm_at_init(void) LOG_ERR("FOTA could not be initialized: %d", err); return -EFAULT; } -#if defined(CONFIG_SLM_GPS) - err = slm_at_gps_init(); +#if defined(CONFIG_SLM_GNSS) + err = slm_at_gnss_init(); if (err) { LOG_ERR("GPS could not be initialized: %d", err); return -EFAULT; @@ -611,8 +625,8 @@ void slm_at_uninit(void) if (err) { LOG_WRN("FOTA could not be uninitialized: %d", err); } -#if defined(CONFIG_SLM_GPS) - err = slm_at_gps_uninit(); +#if defined(CONFIG_SLM_GNSS) + err = slm_at_gnss_uninit(); if (err) { LOG_WRN("GPS could not be uninitialized: %d", err); } diff --git a/doc/nrf/releases/release-notes-latest.rst b/doc/nrf/releases/release-notes-latest.rst index 499cd7a19d41..5daa459893ca 100644 --- a/doc/nrf/releases/release-notes-latest.rst +++ b/doc/nrf/releases/release-notes-latest.rst @@ -56,7 +56,9 @@ nRF9160 * Added a separate document page to explain data mode mechanism and how it works. * Removed datatype in all sending AT commands. If no sending data is specified, switch data mode to receive and send any arbitrary data. * Added a separate document page to describe the FOTA service. - * Added IPv6 support to Socket and ICMP services. + * Added IPv6 support to all SLM services. + * Added the GNSS service to replace the existing GPS test functionality. + * Added the optional support of location services from nRF Cloud, like A-GPS, P-GPS, and cellular positioning. * :ref:`asset_tracker_v2` application: From 14d0ec3993d1059d02abc4c26eefda3a77e2f942 Mon Sep 17 00:00:00 2001 From: Jun Qing Zou Date: Tue, 17 Aug 2021 10:34:37 +0900 Subject: [PATCH 047/126] net: nrf_cloud: Handle nRF Cloud MQTT KEEPALIVE timeout Add NRF_CLOUD_MQTT_KEEPALIVE so the keepalive timer for nRF Cloud MQTT access would not affect other MQTT service. Suppress log prints in PGPS module as it causes message drop. Signed-off-by: Jun Qing Zou --- subsys/net/lib/nrf_cloud/Kconfig | 7 +++++++ subsys/net/lib/nrf_cloud/src/nrf_cloud_codec.c | 2 +- subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c | 6 ++++-- subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps_utils.c | 2 +- subsys/net/lib/nrf_cloud/src/nrf_cloud_transport.c | 1 + 5 files changed, 14 insertions(+), 4 deletions(-) diff --git a/subsys/net/lib/nrf_cloud/Kconfig b/subsys/net/lib/nrf_cloud/Kconfig index 5d84a0e09085..d2d457e5ba93 100644 --- a/subsys/net/lib/nrf_cloud/Kconfig +++ b/subsys/net/lib/nrf_cloud/Kconfig @@ -291,6 +291,13 @@ endif config NRF_CLOUD_CONNECTION_POLL_THREAD bool "Poll cloud connection in a separate thread" +config NRF_CLOUD_MQTT_KEEPALIVE + int "Maximum number of keep alive time for MQTT (in seconds)" + default MQTT_KEEPALIVE + help + Keep alive time for MQTT (in seconds) connection to nRF Cloud, + allow overwriting CONFIG_MQTT_KEEPALIVE value. + module=NRF_CLOUD module-dep=LOG module-str=Log level for nRF Cloud diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_codec.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_codec.c index 9d989e723f8f..cee7c0c8b1b6 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_codec.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_codec.c @@ -391,7 +391,7 @@ int nrf_cloud_encode_state(uint32_t reported_state, struct nrf_cloud_data *outpu /* Report keepalive value. */ if (cJSON_AddNumberToObjectCS(connection_obj, JSON_KEY_KEEPALIVE, - CONFIG_MQTT_KEEPALIVE) == NULL) { + CONFIG_NRF_CLOUD_MQTT_KEEPALIVE) == NULL) { ret = -ENOMEM; } diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c index e024e9b7594a..4edbf76e0624 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps.c @@ -244,9 +244,11 @@ static int validate_prediction(const struct nrf_cloud_pgps_prediction *p, err = -EINVAL; } } +#if IS_ENABLED(CONFIG_NRF_CLOUD_LOG_LEVEL_DBG) if (!err) { print_time_details("prediction:", pred_sec, p->time.date_day, p->time.time_full_s); } +#endif return err; } @@ -283,7 +285,7 @@ static int validate_stored_predictions(uint16_t *first_bad_day, pred->time.time_full_s); } else if (index.predictions[pnum] == NULL) { index.predictions[pnum] = pred; - LOG_INF("Prediction num:%u stored at idx:%d", pnum, i); + LOG_DBG("Prediction num:%u stored at idx:%d", pnum, i); } else { LOG_WRN("Prediction num:%u stored more than once!", pnum); } @@ -319,7 +321,7 @@ static int validate_stored_predictions(uint16_t *first_bad_day, } i = npgps_pointer_to_block((uint8_t *)pred); - LOG_INF("Prediction num:%u, loc:%p, blk:%d", pnum, pred, i); + LOG_DBG("Prediction num:%u, loc:%p, blk:%d", pnum, pred, i); __ASSERT(i != -1, "unexpected pointer value %p", pred); npgps_mark_block_used(i, true); } diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps_utils.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps_utils.c index d7545025fc11..cc8f698bbff3 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps_utils.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_pgps_utils.c @@ -351,7 +351,7 @@ void npgps_print_blocks(void) map[i] = pool.block_used[i] ? '1' : '0'; } map[i] = '\0'; - LOG_INF("map:%s", map); + LOG_INF("map:%s", log_strdup(map)); } diff --git a/subsys/net/lib/nrf_cloud/src/nrf_cloud_transport.c b/subsys/net/lib/nrf_cloud/src/nrf_cloud_transport.c index 0ab411437996..6794455efe7b 100644 --- a/subsys/net/lib/nrf_cloud/src/nrf_cloud_transport.c +++ b/subsys/net/lib/nrf_cloud/src/nrf_cloud_transport.c @@ -677,6 +677,7 @@ int nct_mqtt_connect(void) nct.client.protocol_version = MQTT_VERSION_3_1_1; nct.client.password = NULL; nct.client.user_name = NULL; + nct.client.keepalive = CONFIG_NRF_CLOUD_MQTT_KEEPALIVE; nct.client.clean_session = persistent_session ? 0U : 1U; LOG_DBG("MQTT clean session flag: %u", nct.client.clean_session); From 1fe059fe099be18d603952a323b8ffaba59eb417 Mon Sep 17 00:00:00 2001 From: Mariusz Poslinski Date: Mon, 2 Aug 2021 12:07:41 +0200 Subject: [PATCH 048/126] manifest: update homekit revision [KRKNWK-10905] - [x] nrfconnect/sdk-homekit#203 - [x] nrfconnect/sdk-homekit#204 Signed-off-by: Mariusz Poslinski --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index c18f8c941ec6..fcb825b161e0 100644 --- a/west.yml +++ b/west.yml @@ -166,7 +166,7 @@ manifest: path: modules/lib/cddl-gen - name: homekit repo-path: sdk-homekit - revision: b62c2a617e3b404d44baf0df6cd3a3b12c98429c + revision: 3f55be95580310972cf0af0e535ee0c909230294 groups: - homekit - name: find-my From 5291aa14b295fcb05c9a676c8d2883dce2b59a70 Mon Sep 17 00:00:00 2001 From: Markus Swarowsky Date: Tue, 17 Aug 2021 15:39:28 +0200 Subject: [PATCH 049/126] test: lib: dfu_target fix B1 upgrade url In PR-5223 the way how the B1 upgrade image for the S0 and the S1 partition got changed. From SPACE " " to "+". Therefore it was also needed to change the corresponding twister test, which was missed in the original PR. Signed-off-by: Markus Swarowsky --- tests/subsys/dfu/dfu_target_mcuboot/src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/subsys/dfu/dfu_target_mcuboot/src/main.c b/tests/subsys/dfu/dfu_target_mcuboot/src/main.c index bdcdad29f2c4..a0e4d6923beb 100644 --- a/tests/subsys/dfu/dfu_target_mcuboot/src/main.c +++ b/tests/subsys/dfu/dfu_target_mcuboot/src/main.c @@ -17,7 +17,7 @@ */ char buf[1024]; -#define S0_S1 "s0 s1" +#define S0_S1 "s0+s1" #define NO_SPACE "s0s1" const char *flash_ptr = S0_S1; From 863e0709e55533aa0ba1916affdb390e82dc18bf Mon Sep 17 00:00:00 2001 From: Richard McCrae Date: Wed, 18 Aug 2021 09:13:37 +0200 Subject: [PATCH 050/126] samples: nrf9160: gps: Move SUPL work queue init It was found that a race condition was occuring with the SUPL work queue. The queue is called by the gnss_event_handler function, which can take place prior to the queue's initialization. Therefor the queue's init has been moved to preceed the gnss_event_handler function. Signed-off-by: Richard McCrae --- samples/nrf9160/gps/src/main.c | 46 ++++++++++++++++------------------ 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/samples/nrf9160/gps/src/main.c b/samples/nrf9160/gps/src/main.c index 1bd3c0b6701b..b9a2b49e47e6 100644 --- a/samples/nrf9160/gps/src/main.c +++ b/samples/nrf9160/gps/src/main.c @@ -229,6 +229,28 @@ static int init_app(void) } lte_lc_register_handler(lte_handler); + + static struct supl_api supl_api = { + .read = supl_read, + .write = supl_write, + .handler = inject_agps_type, + .logger = supl_logger, + .counter_ms = k_uptime_get + }; + + k_work_queue_start( + &agps_work_q, + agps_workq_stack_area, + K_THREAD_STACK_SIZEOF(agps_workq_stack_area), + AGPS_WORKQ_THREAD_PRIORITY, + NULL); + + k_work_init(&get_agps_data_work, get_agps_data); + + if (supl_init(&supl_api) != 0) { + printk("Failed to initialize SUPL library\n"); + return -1; + } #endif /* CONFIG_SUPL_CLIENT_LIB */ if (setup_modem() != 0) { @@ -271,30 +293,6 @@ static int init_app(void) return -1; } -#ifdef CONFIG_SUPL_CLIENT_LIB - static struct supl_api supl_api = { - .read = supl_read, - .write = supl_write, - .handler = inject_agps_type, - .logger = supl_logger, - .counter_ms = k_uptime_get - }; - - k_work_queue_start( - &agps_work_q, - agps_workq_stack_area, - K_THREAD_STACK_SIZEOF(agps_workq_stack_area), - AGPS_WORKQ_THREAD_PRIORITY, - NULL); - - k_work_init(&get_agps_data_work, get_agps_data); - - if (supl_init(&supl_api) != 0) { - printk("Failed to initialize SUPL library\n"); - return -1; - } -#endif - return 0; } From 5fb1e871e3284cb4508bee9b2890a20a662e8924 Mon Sep 17 00:00:00 2001 From: Tommi Kangas Date: Mon, 16 Aug 2021 12:58:34 +0300 Subject: [PATCH 051/126] samples: nrf9160: modem_shell: update GNSS use case configuration Changed how use case configuration is set using modem_shell commands. Added support for disabling scheduled downloads in periodic tracking mode. Signed-off-by: Tommi Kangas --- samples/nrf9160/modem_shell/src/gnss/gnss.h | 7 ++-- .../modem_shell/src/gnss/gnss_gps_driver.c | 2 +- .../modem_shell/src/gnss/gnss_interface.c | 9 ++-- .../nrf9160/modem_shell/src/gnss/gnss_shell.c | 41 ++++++++----------- .../modem_shell/src/gnss/gnss_socket.c | 11 ++++- 5 files changed, 38 insertions(+), 32 deletions(-) diff --git a/samples/nrf9160/modem_shell/src/gnss/gnss.h b/samples/nrf9160/modem_shell/src/gnss/gnss.h index b2dffeba4abd..fe38b2494ebc 100644 --- a/samples/nrf9160/modem_shell/src/gnss/gnss.h +++ b/samples/nrf9160/modem_shell/src/gnss/gnss.h @@ -185,14 +185,15 @@ int gnss_set_duty_cycling_policy(enum gnss_duty_cycling_policy policy); int gnss_set_elevation_threshold(uint8_t elevation); /** - * @brief Sets whether low accuracy fixes are allowed. + * @brief Sets the GNSS use case configuration. * - * @param value True if low accuracy fixes are allowed, false if not. + * @param low_accuracy_enabled True if low accuracy fixes are allowed, false if not. + * @param scheduled_downloads_disabled True if scheduled downloads are disabled, false if not. * * @retval 0 if the operation was successful. * Otherwise, a (negative) error code is returned. */ -int gnss_set_low_accuracy(bool value); +int gnss_set_use_case(bool low_accuracy_enabled, bool scheduled_downloads_disabled); /** * @brief Sets the NMEA mask. diff --git a/samples/nrf9160/modem_shell/src/gnss/gnss_gps_driver.c b/samples/nrf9160/modem_shell/src/gnss/gnss_gps_driver.c index 78e74bb88a49..ee9ce5097c3f 100644 --- a/samples/nrf9160/modem_shell/src/gnss/gnss_gps_driver.c +++ b/samples/nrf9160/modem_shell/src/gnss/gnss_gps_driver.c @@ -302,7 +302,7 @@ int gnss_set_elevation_threshold(uint8_t elevation) return -EOPNOTSUPP; } -int gnss_set_low_accuracy(bool value) +int gnss_set_use_case(bool low_accuracy_enabled, bool scheduled_downloads_disabled) { shell_error(shell_global, "GNSS: Operation not supported in GPS driver mode"); diff --git a/samples/nrf9160/modem_shell/src/gnss/gnss_interface.c b/samples/nrf9160/modem_shell/src/gnss/gnss_interface.c index f6da7a269041..50847b014f34 100644 --- a/samples/nrf9160/modem_shell/src/gnss/gnss_interface.c +++ b/samples/nrf9160/modem_shell/src/gnss/gnss_interface.c @@ -933,20 +933,23 @@ int gnss_set_elevation_threshold(uint8_t elevation) return err; } -int gnss_set_low_accuracy(bool value) +int gnss_set_use_case(bool low_accuracy_enabled, bool scheduled_downloads_disabled) { int err; uint8_t use_case = NRF_MODEM_GNSS_USE_CASE_MULTIPLE_HOT_START; gnss_api_init(); - if (value) { + if (low_accuracy_enabled) { use_case |= NRF_MODEM_GNSS_USE_CASE_LOW_ACCURACY; } + if (scheduled_downloads_disabled) { + use_case |= NRF_MODEM_GNSS_USE_CASE_SCHED_DOWNLOAD_DISABLE; + } err = nrf_modem_gnss_use_case_set(use_case); if (err) { - shell_error(shell_global, "GNSS: Failed to set use case"); + shell_error(shell_global, "GNSS: Failed to set use case, check modem FW version"); } return err; diff --git a/samples/nrf9160/modem_shell/src/gnss/gnss_shell.c b/samples/nrf9160/modem_shell/src/gnss/gnss_shell.c index d092a8774b79..93fea8f47afd 100644 --- a/samples/nrf9160/modem_shell/src/gnss/gnss_shell.c +++ b/samples/nrf9160/modem_shell/src/gnss/gnss_shell.c @@ -297,29 +297,28 @@ static int cmd_gnss_config_elevation(const struct shell *shell, size_t argc, cha return gnss_set_elevation_threshold(elevation); } -static int cmd_gnss_config_accuracy(const struct shell *shell, size_t argc, char **argv) -{ - return print_help(shell, argc, argv); -} - -static int cmd_gnss_config_accuracy_normal(const struct shell *shell, size_t argc, char **argv) +static int cmd_gnss_config_use_case(const struct shell *shell, size_t argc, char **argv) { if (gnss_running) { shell_error(shell, "%s: stop GNSS to execute command", argv[0]); return -ENOEXEC; } - return gnss_set_low_accuracy(false); -} + uint8_t value; + bool low_accuracy_enabled = false; + bool scheduled_downloads_disabled = false; -static int cmd_gnss_config_accuracy_low(const struct shell *shell, size_t argc, char **argv) -{ - if (gnss_running) { - shell_error(shell, "%s: stop GNSS to execute command", argv[0]); - return -ENOEXEC; + value = atoi(argv[1]); + if (value == 1) { + low_accuracy_enabled = true; + } + + value = atoi(argv[2]); + if (value == 1) { + scheduled_downloads_disabled = true; } - return gnss_set_low_accuracy(true); + return gnss_set_use_case(low_accuracy_enabled, scheduled_downloads_disabled); } static int cmd_gnss_config_nmea(const struct shell *shell, size_t argc, char **argv) @@ -877,14 +876,6 @@ SHELL_STATIC_SUBCMD_SET_CREATE( SHELL_SUBCMD_SET_END ); -SHELL_STATIC_SUBCMD_SET_CREATE( - sub_gnss_config_accuracy, - SHELL_CMD_ARG(normal, NULL, "Normal accuracy fixes (default).", - cmd_gnss_config_accuracy_normal, 1, 0), - SHELL_CMD_ARG(low, NULL, "Low accuracy fixes allowed.", cmd_gnss_config_accuracy_low, 1, 0), - SHELL_SUBCMD_SET_END -); - SHELL_STATIC_SUBCMD_SET_CREATE( sub_gnss_config_powersave, SHELL_CMD_ARG(off, NULL, "Power saving off (default).", @@ -930,7 +921,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE( cmd_gnss_config_system, 2, 0), SHELL_CMD(elevation, NULL, "\nElevation threshold angle.", cmd_gnss_config_elevation), - SHELL_CMD(accuracy, &sub_gnss_config_accuracy, "Fix accuracy.", cmd_gnss_config_accuracy), + SHELL_CMD_ARG(use_case, NULL, + " \n" + "Use case configuration. 0 = option disabled, 1 = option enabled " + "(default all disabled).", + cmd_gnss_config_use_case, 3, 0), SHELL_CMD_ARG(nmea, NULL, " \n" "NMEA mask. 0 = disabled, 1 = enabled (default all enabled).", diff --git a/samples/nrf9160/modem_shell/src/gnss/gnss_socket.c b/samples/nrf9160/modem_shell/src/gnss/gnss_socket.c index a2fcd592defe..bf98350611e4 100644 --- a/samples/nrf9160/modem_shell/src/gnss/gnss_socket.c +++ b/samples/nrf9160/modem_shell/src/gnss/gnss_socket.c @@ -781,9 +781,16 @@ int gnss_set_elevation_threshold(uint8_t elevation) return 0; } -int gnss_set_low_accuracy(bool value) +int gnss_set_use_case(bool low_accuracy_enabled, bool scheduled_downloads_disabled) { - low_accuracy = value; + if (scheduled_downloads_disabled) { + shell_error(shell_global, + "GNSS: Disabling scheduled downloads not supported in " + "GNSS socket API mode"); + return -EOPNOTSUPP; + } + + low_accuracy = low_accuracy_enabled; return 0; } From 009f5f18b91a1df8bda52efc329a3266ee7f1318 Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk Date: Tue, 17 Aug 2021 12:10:38 +0200 Subject: [PATCH 052/126] samples: matter: Optimized fetching data from device sensors Modified fetching data from sensors in weather station sample to be triggered by the timer instead of loop reads. Signed-off-by: Kamil Kasperczyk --- .../matter/weather_station/src/app_task.cpp | 24 +++++++++++++++---- samples/matter/weather_station/src/app_task.h | 1 + 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/samples/matter/weather_station/src/app_task.cpp b/samples/matter/weather_station/src/app_task.cpp index 7d7ea14424a3..e214a5296fcf 100644 --- a/samples/matter/weather_station/src/app_task.cpp +++ b/samples/matter/weather_station/src/app_task.cpp @@ -33,6 +33,7 @@ enum class LedState { kAlive, kAdvertisingBle, kConnectedBle, kProvisioned }; constexpr size_t kAppEventQueueSize = 10; constexpr size_t kFactoryResetTriggerTimeoutMs = 3000; constexpr size_t kFactoryResetCompleteTimeoutMs = 3000; +constexpr size_t kMeasurementsIntervalMs = 250; constexpr uint8_t kTemperatureMeasurementEndpointId = 1; constexpr int16_t kTemperatureMeasurementAttributeMaxValue = 0x7fff; constexpr int16_t kTemperatureMeasurementAttributeMinValue = 0x954d; @@ -48,6 +49,8 @@ constexpr int16_t kPressureMeasurementAttributeInvalidValue = 0x8000; K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent)); k_timer sFunctionTimer; +k_timer sMeasurementsTimer; +bool sMeasurementTrigger; FunctionTimerMode sFunctionTimerMode = FunctionTimerMode::kDisabled; LEDWidget sRedLED; @@ -92,10 +95,14 @@ int AppTask::Init() GetDFUOverSMP().StartServer(); #endif - /* Initialize timer */ + /* Initialize timers */ k_timer_init( &sFunctionTimer, [](k_timer *) { sAppTask.PostEvent(AppEvent::Type::kTimer, FunctionTimerHandler); }, nullptr); + k_timer_init( + &sMeasurementsTimer, + [](k_timer *) { sAppTask.PostEvent(AppEvent::Type::kTimer, MeasurementsTimerHandler); }, nullptr); + k_timer_start(&sMeasurementsTimer, K_MSEC(kMeasurementsIntervalMs), K_NO_WAIT); /* Init ZCL Data Model and start server */ InitServer(); @@ -156,7 +163,11 @@ int AppTask::StartApp() PlatformMgr().UnlockChipStack(); } - UpdateClusterState(); + if (sMeasurementTrigger) { + sMeasurementTrigger = false; + UpdateClusterState(); + } + UpdateLedState(); } } @@ -179,9 +190,6 @@ void AppTask::PostEvent(AppEvent::Type type, AppEvent::Handler handler) #ifdef CONFIG_MCUMGR_SMP_BT void AppTask::RequestSMPAdvertisingStart(void) { - // AppEvent event; - // event.mType = AppEvent::Type::kStartSMPAdvertising; - // event.mHandler = [](AppEvent *) { GetDFUOverSMP().StartBLEAdvertising(); }; sAppTask.PostEvent(AppEvent::Type::kStartSMPAdvertising, [](AppEvent *) { GetDFUOverSMP().StartBLEAdvertising(); }); } @@ -238,6 +246,12 @@ void AppTask::FunctionTimerHandler(AppEvent *) } } +void AppTask::MeasurementsTimerHandler(AppEvent *) +{ + sMeasurementTrigger = true; + k_timer_start(&sMeasurementsTimer, K_MSEC(kMeasurementsIntervalMs), K_NO_WAIT); +} + void AppTask::UpdateClusterState() { struct sensor_value sTemperature, sPressure, sHumidity; diff --git a/samples/matter/weather_station/src/app_task.h b/samples/matter/weather_station/src/app_task.h index 4cb6e2240ed1..c7a42e3c72ba 100644 --- a/samples/matter/weather_station/src/app_task.h +++ b/samples/matter/weather_station/src/app_task.h @@ -39,6 +39,7 @@ class AppTask { static void ButtonPushHandler(AppEvent *event); static void ButtonReleaseHandler(AppEvent *event); static void FunctionTimerHandler(AppEvent *event); + static void MeasurementsTimerHandler(AppEvent *event); static void ChipEventHandler(const chip::DeviceLayer::ChipDeviceEvent *event, intptr_t arg); static AppTask sAppTask; From 43c133cf50f864d35e24e61074d8376d7067f657 Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk Date: Tue, 17 Aug 2021 11:48:32 +0200 Subject: [PATCH 053/126] manifest: Updated sdk-connectedhomeip version sdk-connectedhomeip upmerge containing documentation changes only Signed-off-by: Kamil Kasperczyk --- doc/nrf/links.txt | 14 +++++++------- west.yml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/nrf/links.txt b/doc/nrf/links.txt index def30da970a2..f4092e3071ad 100644 --- a/doc/nrf/links.txt +++ b/doc/nrf/links.txt @@ -90,13 +90,13 @@ .. _`SMP over Bluetooth`: https://github.com/apache/mynewt-mcumgr/blob/master/transport/smp-bluetooth.md -.. _`Android CHIPTool`: https://github.com/nrfconnect/sdk-connectedhomeip/tree/5b90f5/src/android/CHIPTool -.. _`Commissioning nRF Connect Accessory using Android CHIPTool`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/5b90f5/docs/guides/nrfconnect_android_commissioning.md -.. _`Working with Python Controller`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/5b90f5/src/controller/python/README.md -.. _`Performing Device Firmware Upgrade in Matter device`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/5b90f5/docs/guides/nrfconnect_examples_software_update.md -.. _`Matter Protocol Overview`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/5b90f5/README.md -.. _`nRF Connect platform overview`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/5b90f5/docs/guides/nrfconnect_platform_overview.md -.. _`other controller setups`: https://github.com/nrfconnect/sdk-connectedhomeip/tree/5b90f5/src/controller +.. _`Android CHIPTool`: https://github.com/nrfconnect/sdk-connectedhomeip/tree/27bce6d/src/android/CHIPTool +.. _`Commissioning nRF Connect Accessory using Android CHIPTool`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/27bce6d/docs/guides/nrfconnect_android_commissioning.md +.. _`Working with Python Controller`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/27bce6d/docs/guides/python_chip_controller_building.md +.. _`Performing Device Firmware Upgrade in Matter device`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/27bce6d/docs/guides/nrfconnect_examples_software_update.md +.. _`Matter Protocol Overview`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/27bce6d/README.md +.. _`nRF Connect platform overview`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/27bce6d/docs/guides/nrfconnect_platform_overview.md +.. _`other controller setups`: https://github.com/nrfconnect/sdk-connectedhomeip/tree/27bce6d/src/controller .. _`ZCL Advanced Platform`: https://github.com/project-chip/zap .. _`nRF Cloud JSON protocol schemas`: https://github.com/nRFCloud/application-protocols diff --git a/west.yml b/west.yml index fcb825b161e0..c336991981c3 100644 --- a/west.yml +++ b/west.yml @@ -116,7 +116,7 @@ manifest: - name: matter repo-path: sdk-connectedhomeip path: modules/lib/matter - revision: 5f323a8e4aca12bd1c7ed819aab26075812d7f3d + revision: 27bce6d82a1227b1f9fb442c16ea74e4930acd6c submodules: - name: nlio path: third_party/nlio/repo From 442f63ddc32333c7b811ef0f3c7bd55f0c78e399 Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Tue, 17 Aug 2021 18:25:52 +0200 Subject: [PATCH 054/126] nfc: ndef: enable encoding of long uri messages The NDEF URI Message module now supports long URI payload encoding. It is possible to encode URIs longer than 255 bytes. Signed-off-by: Kamil Piszczek --- include/nfc/ndef/uri_msg.h | 2 +- include/nfc/ndef/uri_rec.h | 2 +- subsys/nfc/ndef/uri_msg.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/nfc/ndef/uri_msg.h b/include/nfc/ndef/uri_msg.h index 31eb1f1fbfbd..67e1cef8da11 100644 --- a/include/nfc/ndef/uri_msg.h +++ b/include/nfc/ndef/uri_msg.h @@ -47,7 +47,7 @@ extern "C" { */ int nfc_ndef_uri_msg_encode(enum nfc_ndef_uri_rec_id uri_id_code, uint8_t const *const uri_data, - uint8_t uri_data_len, + uint16_t uri_data_len, uint8_t *buf, uint32_t *len); diff --git a/include/nfc/ndef/uri_rec.h b/include/nfc/ndef/uri_rec.h index 0b565444c982..a3d39cbb38e8 100644 --- a/include/nfc/ndef/uri_rec.h +++ b/include/nfc/ndef/uri_rec.h @@ -80,7 +80,7 @@ struct nfc_ndef_uri_rec_payload { /** Pointer to a URI string. */ uint8_t const *uri_data; /** Length of the URI string. */ - uint8_t uri_data_len; + uint16_t uri_data_len; }; /** diff --git a/subsys/nfc/ndef/uri_msg.c b/subsys/nfc/ndef/uri_msg.c index d32c85163f57..4c3ad2cf7c93 100644 --- a/subsys/nfc/ndef/uri_msg.c +++ b/subsys/nfc/ndef/uri_msg.c @@ -9,7 +9,7 @@ int nfc_ndef_uri_msg_encode(enum nfc_ndef_uri_rec_id uri_id_code, uint8_t const *const uri_data, - uint8_t uri_data_len, + uint16_t uri_data_len, uint8_t *buf, uint32_t *len) { From e3f12916483de1ea85a609f5891d941306ba5a74 Mon Sep 17 00:00:00 2001 From: Mariusz Poslinski Date: Wed, 18 Aug 2021 09:36:06 +0200 Subject: [PATCH 055/126] manifest: update homekit revision - [x] nrfconnect/sdk-homekit#213 Signed-off-by: Mariusz Poslinski --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index c336991981c3..435200ab7bc8 100644 --- a/west.yml +++ b/west.yml @@ -166,7 +166,7 @@ manifest: path: modules/lib/cddl-gen - name: homekit repo-path: sdk-homekit - revision: 3f55be95580310972cf0af0e535ee0c909230294 + revision: 56b570c249d302e3affccc43423eee3bc82f0273 groups: - homekit - name: find-my From 3144409b803a90dd2c018eaf89c4a14379e9305a Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc Date: Tue, 17 Aug 2021 13:54:43 +0200 Subject: [PATCH 056/126] doc: matter: samples: advertising time Added the default advertising time information. KRKNWK-10944. Signed-off-by: Grzegorz Ferenc --- samples/matter/light_bulb/README.rst | 2 +- samples/matter/lock/README.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/matter/light_bulb/README.rst b/samples/matter/light_bulb/README.rst index 6e92bccdb1bc..8a7b07ded542 100644 --- a/samples/matter/light_bulb/README.rst +++ b/samples/matter/light_bulb/README.rst @@ -106,7 +106,7 @@ Button 3: If for some reason the light switch device is not able to receive messages during this predefined period of time, you can restart publishing service by pressing this button again. Button 4: - Starts the the NFC tag emulation, enables Bluetooth LE advertising for the predefined period of time, and makes the device discoverable over Bluetooth LE. + Starts the NFC tag emulation, enables Bluetooth LE advertising for the predefined period of time (15 minutes by default), and makes the device discoverable over Bluetooth LE. This button is used during the :ref:`commissioning procedure `. .. include:: ../lock/README.rst diff --git a/samples/matter/lock/README.rst b/samples/matter/lock/README.rst index 6db02ac0df4f..d0e448b733ec 100644 --- a/samples/matter/lock/README.rst +++ b/samples/matter/lock/README.rst @@ -136,7 +136,7 @@ Button 3: Starts the Thread networking in the :ref:`test mode ` using the default configuration. Button 4: - Starts the the NFC tag emulation, enables Bluetooth LE advertising for the predefined period of time, and makes the device discoverable over Bluetooth LE. + Starts the the NFC tag emulation, enables Bluetooth LE advertising for the predefined period of time (15 minutes by default), and makes the device discoverable over Bluetooth LE. This button is used during the :ref:`commissioning procedure `. .. matter_door_lock_sample_jlink_start From f5663f36075b53ede50f89835a590c066925b39a Mon Sep 17 00:00:00 2001 From: Agata Ponitka Date: Mon, 16 Aug 2021 11:39:22 +0200 Subject: [PATCH 057/126] Bluetooth: Tester: Fix Scheduler Action set Fix inncorrectly declared month parameter in the Scheduler Action Set struct in the bttester.h. Signed-off-by: Agata Ponitka --- tests/bluetooth/tester/src/bttester.h | 2 +- tests/bluetooth/tester/src/mmdl.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bluetooth/tester/src/bttester.h b/tests/bluetooth/tester/src/bttester.h index aef564dec5a4..e8cb63e7d4b4 100644 --- a/tests/bluetooth/tester/src/bttester.h +++ b/tests/bluetooth/tester/src/bttester.h @@ -621,7 +621,7 @@ struct mesh_scheduler_action_set { uint8_t ack; uint8_t index; uint8_t year; - uint8_t month; + uint16_t month; uint8_t day; uint8_t hour; uint8_t minute; diff --git a/tests/bluetooth/tester/src/mmdl.c b/tests/bluetooth/tester/src/mmdl.c index 10e9e929d985..9962ef1ee467 100644 --- a/tests/bluetooth/tester/src/mmdl.c +++ b/tests/bluetooth/tester/src/mmdl.c @@ -5159,7 +5159,7 @@ static void scheduler_action_set(uint8_t *data, uint16_t len) if (cmd->ack) { net_buf_simple_init(buf, 0); net_buf_simple_add_u8(buf, status.year); - net_buf_simple_add_u8(buf, status.month); + net_buf_simple_add_le16(buf, status.month); net_buf_simple_add_u8(buf, status.day); net_buf_simple_add_u8(buf, status.hour); net_buf_simple_add_u8(buf, status.minute); From a4112aeb6e455af36871c6b87d2cbe06e72f0a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 17 Aug 2021 08:08:32 -0700 Subject: [PATCH 058/126] scripts: get_pulls_in_range: add copyright/license MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These were omitted in previous commits. I am the sole author of this script. Signed-off-by: Martí Bolívar --- scripts/get_pulls_in_range.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/get_pulls_in_range.py b/scripts/get_pulls_in_range.py index 92a6db3fb064..c5d94f7eb788 100755 --- a/scripts/get_pulls_in_range.py +++ b/scripts/get_pulls_in_range.py @@ -1,5 +1,9 @@ #!/usr/bin/env python3 +# Copyright (c) 2020-2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: Apache-2.0 + import argparse from contextlib import closing from collections import defaultdict From b685cc9946e573cd40f2a199c929f15db8c6bbf4 Mon Sep 17 00:00:00 2001 From: Jun Qing Zou Date: Wed, 18 Aug 2021 17:10:33 +0900 Subject: [PATCH 059/126] application: serial_lte_modem: Bug-fix for native TLS Do not unload credential twice with same , or crash. Fix a bug in parsing incoming connection's IPv6 address. Easier way to terminate connection when server thread quits. Signed-off-by: Jun Qing Zou --- .../serial_lte_modem/src/slm_at_tcp_proxy.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/applications/serial_lte_modem/src/slm_at_tcp_proxy.c b/applications/serial_lte_modem/src/slm_at_tcp_proxy.c index 8e5482680e7d..65eea65ba496 100644 --- a/applications/serial_lte_modem/src/slm_at_tcp_proxy.c +++ b/applications/serial_lte_modem/src/slm_at_tcp_proxy.c @@ -202,6 +202,7 @@ static int do_tcp_server_start(uint16_t port) #if defined(CONFIG_SLM_NATIVE_TLS) if (proxy.sec_tag != INVALID_SEC_TAG) { (void)slm_tls_unloadcrdl(proxy.sec_tag); + proxy.sec_tag = INVALID_SEC_TAG; } #endif if (proxy.sock != INVALID_SOCKET) { @@ -224,6 +225,7 @@ static int do_tcp_server_stop(void) #if defined(CONFIG_SLM_NATIVE_TLS) if (proxy.sec_tag != INVALID_SEC_TAG) { (void)slm_tls_unloadcrdl(proxy.sec_tag); + proxy.sec_tag = INVALID_SEC_TAG; } #endif if (proxy.sock_peer != INVALID_SOCKET) { @@ -256,7 +258,6 @@ static int do_tcp_client_connect(const char *url, uint16_t port) ret = socket(proxy.family, SOCK_STREAM, IPPROTO_TCP); } else { ret = socket(proxy.family, SOCK_STREAM, IPPROTO_TLS_1_2); - } if (ret < 0) { LOG_ERR("socket() failed: %d", -errno); @@ -516,7 +517,7 @@ static void tcpsvr_thread_func(void *p1, void *p2, void *p3) LOG_WRN("accept(ipv6) error: %d", -errno); goto client_events; } - (void)inet_ntop(AF_INET, &client.sin6_addr, peer_addr, + (void)inet_ntop(AF_INET6, &client.sin6_addr, peer_addr, sizeof(peer_addr)); } if (fds[1].fd != INVALID_SOCKET) { @@ -578,15 +579,10 @@ static void tcpsvr_thread_func(void *p1, void *p2, void *p3) #if defined(CONFIG_SLM_NATIVE_TLS) if (proxy.sec_tag != INVALID_SEC_TAG) { (void)slm_tls_unloadcrdl(proxy.sec_tag); + proxy.sec_tag = INVALID_SEC_TAG; } #endif - if (in_datamode()) { - (void)exit_datamode(false); - } - if (proxy.sock_peer != INVALID_SOCKET) { - (void)close(proxy.sock_peer); - proxy.sock_peer = INVALID_SOCKET; - } + tcpsvr_terminate_connection(ret); if (proxy.sock != INVALID_SOCKET) { (void)close(proxy.sock); proxy.sock = INVALID_SOCKET; From 13b0f55e7ea3342d06cb2fd1a163f680377bc50d Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk Date: Wed, 18 Aug 2021 11:29:15 +0200 Subject: [PATCH 060/126] samples: matter: Fixed assigning SDC_MAX_CONN_EVENT_LEN_DEFAULT on nRF53 Currently the value for SDC_MAX_CONN_EVENT_LEN_DEFAULT was assigned in the dfu overlay attached to the application image. For nRF52 this solution works, however not for nRF53, where this config should be added to the net core image. Signed-off-by: Kamil Kasperczyk --- samples/matter/light_bulb/boards/nrf52840dk_nrf52840.conf | 3 +++ .../light_bulb/child_image/multiprotocol_rpmsg.conf | 8 ++++++++ samples/matter/light_bulb/prj.conf | 1 - samples/matter/lock/boards/nrf52840dk_nrf52840.conf | 3 +++ samples/matter/lock/child_image/multiprotocol_rpmsg.conf | 8 ++++++++ samples/matter/lock/prj.conf | 1 - 6 files changed, 22 insertions(+), 2 deletions(-) create mode 100644 samples/matter/light_bulb/child_image/multiprotocol_rpmsg.conf create mode 100644 samples/matter/lock/child_image/multiprotocol_rpmsg.conf diff --git a/samples/matter/light_bulb/boards/nrf52840dk_nrf52840.conf b/samples/matter/light_bulb/boards/nrf52840dk_nrf52840.conf index 4cbd0e90c3af..bc0d51b58efc 100644 --- a/samples/matter/light_bulb/boards/nrf52840dk_nrf52840.conf +++ b/samples/matter/light_bulb/boards/nrf52840dk_nrf52840.conf @@ -8,3 +8,6 @@ CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y CONFIG_OPENTHREAD_DUA=y CONFIG_OPENTHREAD_MLR=y + +# TODO: remove increasing connection interval after fixing MPSL driver blocking issues +CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 diff --git a/samples/matter/light_bulb/child_image/multiprotocol_rpmsg.conf b/samples/matter/light_bulb/child_image/multiprotocol_rpmsg.conf new file mode 100644 index 000000000000..8b53fef45668 --- /dev/null +++ b/samples/matter/light_bulb/child_image/multiprotocol_rpmsg.conf @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# TODO: remove increasing connection interval after fixing MPSL driver blocking issues +CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 diff --git a/samples/matter/light_bulb/prj.conf b/samples/matter/light_bulb/prj.conf index f18d7f186685..1c6ca4e85d7d 100644 --- a/samples/matter/light_bulb/prj.conf +++ b/samples/matter/light_bulb/prj.conf @@ -51,7 +51,6 @@ CONFIG_BT_MAX_PAIRED=0 CONFIG_BT_BONDABLE=n CONFIG_BT_TINYCRYPT_ECC=n CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY=y -CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 # Use NFC to share commissioning information CONFIG_CHIP_NFC_COMMISSIONING=y diff --git a/samples/matter/lock/boards/nrf52840dk_nrf52840.conf b/samples/matter/lock/boards/nrf52840dk_nrf52840.conf index 4cbd0e90c3af..bc0d51b58efc 100644 --- a/samples/matter/lock/boards/nrf52840dk_nrf52840.conf +++ b/samples/matter/lock/boards/nrf52840dk_nrf52840.conf @@ -8,3 +8,6 @@ CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y CONFIG_OPENTHREAD_DUA=y CONFIG_OPENTHREAD_MLR=y + +# TODO: remove increasing connection interval after fixing MPSL driver blocking issues +CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 diff --git a/samples/matter/lock/child_image/multiprotocol_rpmsg.conf b/samples/matter/lock/child_image/multiprotocol_rpmsg.conf new file mode 100644 index 000000000000..8b53fef45668 --- /dev/null +++ b/samples/matter/lock/child_image/multiprotocol_rpmsg.conf @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# TODO: remove increasing connection interval after fixing MPSL driver blocking issues +CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 diff --git a/samples/matter/lock/prj.conf b/samples/matter/lock/prj.conf index 2cf1b1f8a832..4302abafbc50 100644 --- a/samples/matter/lock/prj.conf +++ b/samples/matter/lock/prj.conf @@ -48,7 +48,6 @@ CONFIG_BT_MAX_PAIRED=0 CONFIG_BT_BONDABLE=n CONFIG_BT_TINYCRYPT_ECC=n CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY=y -CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 # Use NFC to share commissioning information CONFIG_CHIP_NFC_COMMISSIONING=y From 378f87f6c5c2d9e73bd183314d3556321412acfd Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc Date: Wed, 18 Aug 2021 11:32:57 +0200 Subject: [PATCH 061/126] doc: add Matter tools page Added a page that documents Matter tools. Signed-off-by: Grzegorz Ferenc --- doc/nrf/links.txt | 2 + doc/nrf/releases/release-notes-latest.rst | 1 + doc/nrf/ug_matter.rst | 1 + doc/nrf/ug_matter_configuring.rst | 14 ++-- doc/nrf/ug_matter_tools.rst | 88 +++++++++++++++++++++++ doc/nrf/ug_thread_tools.rst | 12 ++++ 6 files changed, 111 insertions(+), 7 deletions(-) create mode 100644 doc/nrf/ug_matter_tools.rst diff --git a/doc/nrf/links.txt b/doc/nrf/links.txt index f4092e3071ad..b57b7b85e08d 100644 --- a/doc/nrf/links.txt +++ b/doc/nrf/links.txt @@ -98,6 +98,8 @@ .. _`nRF Connect platform overview`: https://github.com/nrfconnect/sdk-connectedhomeip/blob/27bce6d/docs/guides/nrfconnect_platform_overview.md .. _`other controller setups`: https://github.com/nrfconnect/sdk-connectedhomeip/tree/27bce6d/src/controller .. _`ZCL Advanced Platform`: https://github.com/project-chip/zap +.. _`Matter nRF Connect releases`: https://github.com/nrfconnect/sdk-connectedhomeip/releases +.. _`Building Android CHIPTool`: https://github.com/project-chip/connectedhomeip/blob/27bce6d/docs/guides/android_chiptool_building.md .. _`nRF Cloud JSON protocol schemas`: https://github.com/nRFCloud/application-protocols diff --git a/doc/nrf/releases/release-notes-latest.rst b/doc/nrf/releases/release-notes-latest.rst index 5daa459893ca..12b203a857af 100644 --- a/doc/nrf/releases/release-notes-latest.rst +++ b/doc/nrf/releases/release-notes-latest.rst @@ -96,6 +96,7 @@ Matter * :ref:`Weather station ` sample. * :ref:`Template ` sample with a guide about :ref:`ug_matter_creating_accessory`. + * :ref:`ug_matter_tools` page with information about building options for Matter controllers. Zigbee ------ diff --git a/doc/nrf/ug_matter.rst b/doc/nrf/ug_matter.rst index 125036ae5fad..93b3c2bfae22 100644 --- a/doc/nrf/ug_matter.rst +++ b/doc/nrf/ug_matter.rst @@ -30,4 +30,5 @@ If you are new to Matter, check also the tutorials on `DevZone`_. ug_matter_architecture.rst ug_matter_configuring.rst + ug_matter_tools.rst ug_matter_creating_accessory.rst diff --git a/doc/nrf/ug_matter_configuring.rst b/doc/nrf/ug_matter_configuring.rst index f44d2c6e8815..5970d41724a5 100644 --- a/doc/nrf/ug_matter_configuring.rst +++ b/doc/nrf/ug_matter_configuring.rst @@ -36,11 +36,11 @@ Matter controller types The Matter controller implementation for the nRF Connect platform can be of the following types: -* Python Controller for Linux -* Mobile Controller for Android +* Python controller for Linux +* Mobile controller for Android -.. note:: - In the Matter upstream repository, you can find information and resources for implementing `other controller setups`_ (for example, for iOS). +These controller types are also described in :ref:`ug_matter_tools` and are recommended in the |NCS|. +In the Matter upstream repository, you can find information and resources for implementing `other controller setups`_ (for example, for iOS). Matter development environment setup options ******************************************** @@ -88,8 +88,8 @@ For information about how to configure and use the required components, complete * Configuring the Thread Border Router on a Raspberry Pi - see :ref:`ug_thread_tools_tbr` in the |NCS| documentation * Depending on the Matter controller type: - * Testing with the Python Matter Controller - see `Working with Python Controller`_ in the Matter documentation - * Testing with the Android Mobile Controller - see `Commissioning nRF Connect Accessory using Android CHIPTool`_ in the Matter documentation + * Python Matter controller - See :ref:`ug_matter_tools` for building instructions and `Working with Python Controller`_ in the Matter documentation for information about testing. + * Android Mobile controller - See :ref:`ug_matter_tools` for building instructions and `Commissioning nRF Connect Accessory using Android CHIPTool`_ in the Matter documentation for information about testing. Running Thread Border Router and Matter controller on the same device ===================================================================== @@ -113,7 +113,7 @@ To use this setup, you need the following hardware: For information about how to configure and use the required components, see the following user guides: * Configuring Thread Border Router on a PC or a Raspberry Pi - see :ref:`ug_thread_tools_tbr` in the |NCS| documentation -* Testing with the Python Matter Controller - see `Working with Python Controller`_ in the Matter documentation +* Python Matter controller - See :ref:`ug_matter_tools` for building instructions and `Working with Python Controller`_ in the Matter documentation for information about testing. .. note:: The Python Matter controller is currently not supported for building on Raspbian OS. diff --git a/doc/nrf/ug_matter_tools.rst b/doc/nrf/ug_matter_tools.rst new file mode 100644 index 000000000000..e35baa66a2ce --- /dev/null +++ b/doc/nrf/ug_matter_tools.rst @@ -0,0 +1,88 @@ +.. _ug_matter_tools: + +Matter tools +############ + +.. contents:: + :local: + :depth: 2 + +Use tools listed on this page to test :ref:`matter_samples` and develop Matter applications in the |NCS|. + +GN tool +******* + +To build and develop Matter applications, you need the `GN`_ meta-build system. +This system generates the Ninja files that the |NCS| uses. + +If you are updating from the |NCS| version earlier than v1.5.0, see the :ref:`GN installation instructions `. + +Matter controller tools +*********************** + +The Matter controller is a role within the :ref:`Matter development environment `. +The controller device is used to pair and control the Matter accessory device remotely over a network, interacting with it using Bluetooth LE and the regular IPv6 communication. + +The following figure shows the available Matter controllers in the |NCS|. + +.. figure:: images/matter_protocols_controllers.svg + :width: 600 + :alt: Controllers used by Matter + + Controllers used by Matter + +Python controller for Linux +=========================== + +The Python Matter controller allows you to test Matter applications on a PC running Linux. +You can use it either on a separate device from Thread Border Router or on the same device as Thread Border Router, depending on which :ref:`development environment setup option ` you choose. + +To use this controller type, you need to build it first using one of the following options: + +* Use the prebuilt tool package from the `Matter nRF Connect releases`_ GitHub page. + Make sure that the package is compatible with your |NCS| version. +* Build it manually from the source files available in the :file:`modules/lib/matter/src/controller/python` directory and using the building instructions from the `Working with Python Controller`_ page in the Matter documentation. + +For instructions about how to test using the Python Controller for Linux, see `Working with Python Controller`_. + +Mobile controller for Android +============================= + +The Mobile Controller for Android allows you to test Matter applications using an Android smartphone. +You can use it in the :ref:`development environment setup option ` where Thread Border Router and Matter controller are running on separate devices. + +To use this controller type, you need to build it first using one of the following options: + +* Use the prebuilt tool package from the `Matter nRF Connect releases`_ GitHub page. + Make sure that the package is compatible with your |NCS| version. +* Build it manually from the source files available in the :file:`modules/lib/matter/src/android/CHIPTool` directory and using the building instructions from the `Building Android CHIPTool`_ page in the Matter documentation. + +For instructions about how to test using the Mobile Controller for Android, see `Commissioning nRF Connect Accessory using Android CHIPTool`_. + +Thread tools +************ + +Because Matter is based on the Thread network, you can use the following :ref:`ug_thread_tools` when working with Matter in the |NCS|. + +Thread Border Router +==================== + +.. include:: ug_thread_tools.rst + :start-after: tbr_shortdesc_start + :end-before: tbr_shortdesc_end + +See the :ref:`ug_thread_tools_tbr` documentation for configuration instructions. + +nRF Sniffer for 802.15.4 +======================== + +.. include:: ug_thread_tools.rst + :start-after: sniffer_shortdesc_start + :end-before: sniffer_shortdesc_end + +nRF Thread Topology Monitor +=========================== + +.. include:: ug_thread_tools.rst + :start-after: ttm_shortdesc_start + :end-before: ttm_shortdesc_end diff --git a/doc/nrf/ug_thread_tools.rst b/doc/nrf/ug_thread_tools.rst index 7ef6eac2a1b9..7906eedb4a40 100644 --- a/doc/nrf/ug_thread_tools.rst +++ b/doc/nrf/ug_thread_tools.rst @@ -14,29 +14,41 @@ The tools listed on this page can be helpful when developing your Thread applica nRF Sniffer for 802.15.4 ************************ +.. sniffer_shortdesc_start + The nRF Sniffer for 802.15.4 is a tool for learning about and debugging applications that are using protocols based on IEEE 802.15.4, like Thread or Zigbee. It provides a near real-time display of 802.15.4 packets that are sent back and forth between devices, even when the link is encrypted. See `nRF Sniffer for 802.15.4`_ for documentation. +.. sniffer_shortdesc_end + .. _ug_thread_tools_ttm: nRF Thread Topology Monitor *************************** +.. ttm_shortdesc_start + nRF Thread Topology Monitor is a desktop application that connects to a Thread network through a serial connection to visualize the topology of Thread devices. It allows you to scan for new devices in real time, check their parameters, and inspect network processes through the log. See `nRF Thread Topology Monitor`_ for documentation. +.. ttm_shortdesc_end + .. _ug_thread_tools_tbr: Thread Border Router ******************** +.. tbr_shortdesc_start + The Thread Border Router is a specific type of Border Router device that provides connectivity from the IEEE 802.15.4 network to adjacent networks on other physical layers (such as Wi-Fi or Ethernet). Border Routers provide services for devices within the IEEE 802.15.4 network, including routing services for off-network operations. +.. tbr_shortdesc_end + Typically, a Border Router solution consists of the following parts: * An application based on the :ref:`thread_architectures_designs_cp_ncp` design or its :ref:`thread_architectures_designs_cp_rcp` variant compatible with the IEEE 802.15.4 standard. From 11bdbaf1311f6ea11f0b0f2e7185cbdc86786dcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simen=20S=2E=20R=C3=B8stad?= Date: Thu, 19 Aug 2021 11:03:14 +0200 Subject: [PATCH 062/126] lib: date_time: Check LTE registration status before performing NTP MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a guard that prevents the library from performing NTP if the device is not connected to LTE. Signed-off-by: Simen S. Røstad --- lib/date_time/date_time.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/lib/date_time/date_time.c b/lib/date_time/date_time.c index 028ffa7fdc7e..b93e78aa8eab 100644 --- a/lib/date_time/date_time.c +++ b/lib/date_time/date_time.c @@ -13,6 +13,9 @@ #if defined(CONFIG_DATE_TIME_MODEM) #include #endif +#if defined(CONFIG_LTE_LINK_CONTROL) +#include +#endif #include #include #include @@ -193,10 +196,41 @@ static int sntp_time_request(struct ntp_servers *server, uint32_t timeout, return err; } +#if defined(CONFIG_LTE_LINK_CONTROL) +static bool is_connected_to_lte(void) +{ + int err; + enum lte_lc_nw_reg_status reg_status; + + err = lte_lc_nw_reg_status_get(®_status); + if (err) { + LOG_WRN("Failed getting LTE network registration status, error: %d", err); + return false; + } + + if (reg_status == LTE_LC_NW_REG_REGISTERED_EMERGENCY || + reg_status == LTE_LC_NW_REG_REGISTERED_HOME || + reg_status == LTE_LC_NW_REG_REGISTERED_ROAMING) { + return true; + } + + return false; +} +#endif /* defined(CONFIG_LTE_LINK_CONTROL) */ + static int time_NTP_server_get(void) { int err; +#if defined(CONFIG_LTE_LINK_CONTROL) + if (!is_connected_to_lte()) { + LOG_DBG("Not connected to LTE, skipping NTP UTC time update"); + return -ENODATA; + } + + LOG_DBG("Connected to LTE, performing NTP UTC time update"); +#endif + for (int i = 0; i < ARRAY_SIZE(servers); i++) { err = sntp_time_request(&servers[i], MSEC_PER_SEC * CONFIG_DATE_TIME_NTP_QUERY_TIME_SECONDS, From 004e0bfef03d8f63f9f9d6202a9968a116a7e6cc Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc Date: Tue, 17 Aug 2021 14:25:45 +0200 Subject: [PATCH 063/126] doc: rename release-notes-latest and other edits Renamed release-notes-latest to -changelog. Removed Highlights from changelog. Removed KI section from sample template. NCSDK-10540. Signed-off-by: Grzegorz Ferenc --- .github/labeler.yml | 2 +- doc/nrf/release_notes.rst | 4 ++-- ...s-latest.rst => release-notes-changelog.rst} | 17 +++++++---------- doc/nrf/templates/sample_README.rst | 6 ------ 4 files changed, 10 insertions(+), 19 deletions(-) rename doc/nrf/releases/{release-notes-latest.rst => release-notes-changelog.rst} (96%) diff --git a/.github/labeler.yml b/.github/labeler.yml index dd8361c5a559..1cf20f3fc671 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -200,4 +200,4 @@ - "!subsys/bluetooth/mesh/**/*" "no-changelog": - - "!doc/nrf/releases/release-notes-latest.rst" + - "!doc/nrf/releases/release-notes-changelog.rst" diff --git a/doc/nrf/release_notes.rst b/doc/nrf/release_notes.rst index 196def0b0467..5bd852e441fe 100644 --- a/doc/nrf/release_notes.rst +++ b/doc/nrf/release_notes.rst @@ -12,7 +12,7 @@ This page is included only in the latest documentation, because it might contain A "99" at the end of the version number of this documentation indicates continuous updates on the master branch since the previous major.minor release. When looking at this latest documentation, be aware of the following aspects: - * Changes between releases are tracked on the :ref:`ncs_release_notes_latest` page, but the master branch might contain additional changes that are not listed on that page. + * Changes between releases are tracked on the :ref:`ncs_release_notes_changelog` page, but the master branch might contain additional changes that are not listed on that page. * The release note pages that are available in the latest documentation might differ slightly from the release notes that were included in the respective |NCS| release at its release date. Therefore, to see the official version of the release notes for a specific |NCS| release, switch to the documentation for the corresponding |NCS| version using the selector in the upper left-hand corner. @@ -20,7 +20,7 @@ This page is included only in the latest documentation, because it might contain :maxdepth: 1 :caption: Subpages: - releases/release-notes-latest + releases/release-notes-changelog releases/release-notes-1.6.1 releases/release-notes-1.6.0 releases/release-notes-1.5.1 diff --git a/doc/nrf/releases/release-notes-latest.rst b/doc/nrf/releases/release-notes-changelog.rst similarity index 96% rename from doc/nrf/releases/release-notes-latest.rst rename to doc/nrf/releases/release-notes-changelog.rst index 12b203a857af..b48ab0ee1fee 100644 --- a/doc/nrf/releases/release-notes-latest.rst +++ b/doc/nrf/releases/release-notes-changelog.rst @@ -1,22 +1,17 @@ -.. _ncs_release_notes_latest: +.. _ncs_release_notes_changelog: -Changes in |NCS| v1.6.99 -######################## +Changelog for |NCS| v1.6.99 +########################### .. contents:: :local: :depth: 2 -The most relevant changes that are present on the master branch of the |NCS|, as compared to the latest release, are tracked in this file. +The most relevant changes that are present on the master branch of the |NCS|, as compared to the latest official release, are tracked in this file. .. note:: This file is a work in progress and might not cover all relevant changes. -Highlights -********** - -There are no entries for this section yet. - Known issues ************ @@ -194,4 +189,6 @@ The following list summarizes the most important changes inherited from the upst Documentation ============= -There are no entries for this section yet. +* Updated: + + * Renamed :ref:`ncs_release_notes_changelog`. diff --git a/doc/nrf/templates/sample_README.rst b/doc/nrf/templates/sample_README.rst index deb20112c8d1..3b82d3814d67 100644 --- a/doc/nrf/templates/sample_README.rst +++ b/doc/nrf/templates/sample_README.rst @@ -223,12 +223,6 @@ Troubleshooting* If the LEDs do not start blinking, check if the music is loud enough. - -Known issues and limitations* -***************************** - -The sample only works with good music. - References* *********** From 99762aede5f5a4f60b4d79565b33e7b695774e64 Mon Sep 17 00:00:00 2001 From: Grzegorz Ferenc Date: Wed, 18 Aug 2021 12:20:13 +0200 Subject: [PATCH 064/126] labeler: rename no-changelog label Renamed no-changelog label to changelog-entry-required. Signed-off-by: Grzegorz Ferenc --- .github/labeler.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 1cf20f3fc671..7c905cc18642 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -199,5 +199,5 @@ - "subsys/bluetooth/**/*" - "!subsys/bluetooth/mesh/**/*" -"no-changelog": +"changelog-entry-required": - "!doc/nrf/releases/release-notes-changelog.rst" From 8dec56c98e2b7d6d38595920f4492c4a89108eb7 Mon Sep 17 00:00:00 2001 From: Kamil Piszczek Date: Thu, 19 Aug 2021 11:52:21 +0200 Subject: [PATCH 065/126] manifest: update Find My revision Updated Find My revision to include Bluetooth LE bond clearing logic on an successful Find My pairing attempt. Signed-off-by: Kamil Piszczek --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 435200ab7bc8..114859bed5b0 100644 --- a/west.yml +++ b/west.yml @@ -171,7 +171,7 @@ manifest: - homekit - name: find-my repo-path: sdk-find-my - revision: v1.6.0 + revision: 454c7c39037dafe9be1fb793c492b22b4eacacd1 groups: - find-my - name: memfault-firmware-sdk From 1fc7112d313bd1b6286dc6c719958fb6ae4ebc2d Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 18 Aug 2021 10:25:13 +0200 Subject: [PATCH 066/126] cmake: multi image: a domain may only contain a single child image A domain may only contain a single child image. That child image is considered the parent image of the domain and may hold additional child images inside itself. Fixes: NCSDK: #10898 Signed-off-by: Torsten Rasmussen --- cmake/multi_image.cmake | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/cmake/multi_image.cmake b/cmake/multi_image.cmake index a39bd28d7ab7..89307692d6ba 100644 --- a/cmake/multi_image.cmake +++ b/cmake/multi_image.cmake @@ -116,6 +116,20 @@ function(add_child_image_from_source) "typically defined in ${BOARD_DIR}/Kconfig") endif() + set(domain_parent ${${ACI_DOMAIN}_PM_DOMAIN_DYNAMIC_PARTITION}) + if(DEFINED ${ACI_DOMAIN}_PM_DOMAIN_DYNAMIC_PARTITION + AND NOT "${domain_parent}" STREQUAL "${ACI_NAME}" + ) + # A domain may only have one child image, which can then act as a parent + # to other images in the domain. + # As it is a cache variable we check it's content so that CMake re-run + # will pass the check as long as the child image hasn't changed. + message(FATAL_ERROR "A domain may only have a single child image." + "Current domain image is: ${domain_parent}, `${domain_parent}` is a " + "domain parent image, so you may add `${ACI_NAME}` as a child inside " + "`${domain_parent}`" + ) + endif() # This needs to be made globally available as it is used in other files. set(${ACI_DOMAIN}_PM_DOMAIN_DYNAMIC_PARTITION ${ACI_NAME} CACHE INTERNAL "") From d37180e9bd27219e6c30fbca1cccf93bdc916353 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 18 Aug 2021 10:28:42 +0200 Subject: [PATCH 067/126] cmake: tests: add hello_world as domain image if the is no image already A domain may only contain a single child image, which then can hold additional images inside it. Therefore hello_world is only added if no child image is already present. Fixes: #10898 Signed-off-by: Torsten Rasmussen --- tests/CMakeLists.txt | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index eec7dc32652d..aa1cc62b62d6 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,16 +13,20 @@ if (CONFIG_ZTEST AND "${ZEPHYR_NRF_MODULE_DIR}/subsys/bootloader/image/secure_boot.conf" ) - # Add a child image in the network core. - # Since we have enabled MCUBoot in the app core, the B0N bootloader is - # automatically added. This can not be done from the test CMakeLists.txt - # since it will not be considered when running partition_manager.cmake. - add_child_image( - NAME hello_world - SOURCE_DIR ${ZEPHYR_BASE}/samples/hello_world - DOMAIN CPUNET - BOARD ${CONFIG_DOMAIN_CPUNET_BOARD}) + if(NOT DEFINED CPUNET_PM_DOMAIN_DYNAMIC_PARTITION + OR "${CPUNET_PM_DOMAIN_DYNAMIC_PARTITION}" STREQUAL hello_world + ) + # Add a child image in the network core if there is not an image already. + # Since we have enabled MCUBoot in the app core, the B0N bootloader is + # automatically added. This can not be done from the test CMakeLists.txt + # since it will not be considered when running partition_manager.cmake. + add_child_image( + NAME hello_world + SOURCE_DIR ${ZEPHYR_BASE}/samples/hello_world + DOMAIN CPUNET + BOARD ${CONFIG_DOMAIN_CPUNET_BOARD}) + endif() endif() From ea7b460e9de2349e88d2d903a96de74fb604a2e4 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 12 May 2021 17:05:12 +0200 Subject: [PATCH 068/126] cmake: multi image: reworked shared variables for child images Sharing of variables from a child image to the parent has been reworked. All internal knowledge on how sharing is done from child has been removed from the caller of share(). Instead of writing CMake code in the `share()` call, such as: `share("set( )")` or `share("list(APPEND )"` then dedicated functions has been implemented to facilitate sharing of variables through the use of dedicated target with properties behind the scene. The following calls have been implemented: - set_shared(IMAGE PROPERTY ) - get_shared( IMAGE PROPERTY ) This further has the benefit of variable names not colliding between child and parent. A user providing a setting, such as `_PROPERTY=value` will always indicate a value defined by user or parent image that will be provided to the child image. The actual value shared by the child will be fetched using `get_shared( IMAGE PROPERTY )` The new design for sharing of variables also mean that other parts of the build system should no longer include the `shared_vars.cmake` file directly but instead rely on the `get_shared()` function which returns the value for the shared variable. Signed-off-by: Torsten Rasmussen --- cmake/extensions.cmake | 166 ++++++++++++++++++++++++ cmake/multi_image.cmake | 48 +++---- cmake/partition_manager.cmake | 76 ++++++----- cmake/s1.cmake | 17 +-- modules/mcuboot/CMakeLists.txt | 12 +- subsys/partition_manager/CMakeLists.txt | 4 +- subsys/spm/CMakeLists.txt | 6 +- 7 files changed, 238 insertions(+), 91 deletions(-) diff --git a/cmake/extensions.cmake b/cmake/extensions.cmake index 1aad6d1a0337..fbef1053bb01 100644 --- a/cmake/extensions.cmake +++ b/cmake/extensions.cmake @@ -4,6 +4,66 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # +# +# Helper macro for verifying that at least one of the required arguments has +# been provided by the caller. +# +# As FATAL_ERROR will be raised if not one of the required arguments has been +# passed by the caller. +# +# Usage: +# check_arguments_required( [ ...]) +# +macro(check_arguments_required function prefix) + set(required_found FALSE) + foreach(required ${ARGN}) + if(DEFINED ${prefix}_${required}) + set(required_found TRUE) + endif() + endforeach() + + if(NOT required_found) + message(FATAL_ERROR "${function}(...) missing a required argument: ${ARGN}") + endif() +endmacro() + +# +# Helper macro for verifying that all the required arguments has # been +# provided by the caller. +# +# As FATAL_ERROR will be raised if one of the required arguments is missing. +# +# Usage: +# check_arguments_required_all( [ ...]) +# +macro(check_arguments_required_all function prefix) + foreach(required ${ARGN}) + if(NOT DEFINED ${prefix}_${required}) + message(FATAL_ERROR "${function}(...) missing a required argument: ${required}") + endif() + endforeach() +endmacro() + +# +# Helper macro for verifying that none of the mutual exclusive arguments are +# provided together with the first argument. +# +# As FATAL_ERROR will be raised if first argument is given together with one +# of the following mutual exclusive arguments. +# +# Usage: +# check_arguments_exclusive( [ ...]) +# +macro(check_arguments_exclusive function prefix argument) + foreach(prohibited ${ARGN}) + if(DEFINED ${prefix}_${argument} AND ${prefix}_${prohibited}) + message(FATAL_ERROR "set_shared(${argument} ...) cannot be used with " + "argument: ${prohibited}" + ) + endif() + endforeach() +endmacro() + function(get_board_without_ns_suffix board_in board_out) string(REGEX REPLACE "(_?ns)$" "" board_in_without_suffix ${board_in}) if(NOT ${board_in} STREQUAL ${board_in_without_suffix}) @@ -140,3 +200,109 @@ Please provide one of following: CONF_FILES") set(${ZEPHYR_FILE_DTS} ${${ZEPHYR_FILE_DTS}} PARENT_SCOPE) endif() endfunction() + +# +# Usage +# set_shared(IMAGE [APPEND] PROPERTY ) +# +# Shares a property from child to parent. +# The property is shared through an intermediate shared_vars.cmake file which +# will be parsed by the parent image at CMake configure time. +# +# Example usage 'set_shared(IMAGE child PROPERTY visible_in_parent "I AM YOUR CHILD")' +# +# Usage +# set_shared(FILE ) +# +# Shares all properties in file to parent. +# This function can be used to re-share properties from a child to its +# grand parent. +# +function(set_shared) + set(flags "APPEND") + set(single_args "FILE;IMAGE") + set(multi_args "PROPERTY") + cmake_parse_arguments(SHARE "${flags}" "${single_args}" "${multi_args}" ${ARGN}) + + check_arguments_required("set_shared" SHARE IMAGE FILE) + + check_arguments_exclusive("set_shared" SHARE FILE IMAGE PROPERTY APPEND) + check_arguments_exclusive("set_shared" SHARE IMAGE FILE) + + set(prop_target ${IMAGE_NAME}_shared_property_target) + if(NOT TARGET ${prop_target}) + add_custom_target(${prop_target}) + endif() + + if(DEFINED SHARE_IMAGE) + # When using IMAGE, then PROPERTY is also required. + check_arguments_required("set_shared" SHARE PROPERTY) + + set(share_prop_target ${SHARE_IMAGE}_shared_property_target) + + if(SHARE_APPEND) + set(SHARE_APPEND APPEND) + else() + set(SHARE_APPEND) + endif() + + get_property(string_targets TARGET ${prop_target} PROPERTY image_targets) + if(NOT "add_custom_target(${share_prop_target})" IN_LIST string_targets) + set_property( + TARGET ${prop_target} APPEND PROPERTY + image_targets "add_custom_target(${share_prop_target})" + ) + endif() + + set_property(TARGET ${prop_target} APPEND_STRING PROPERTY shared_vars + "set_property(TARGET ${share_prop_target} ${SHARE_APPEND} PROPERTY ${SHARE_PROPERTY})\n" + ) + endif() + + if(DEFINED SHARE_FILE) + set_property(TARGET ${prop_target} APPEND_STRING PROPERTY shared_vars + "include(${SHARE_FILE})\n" + ) + endif() +endfunction() + +# generate_shared(IMAGE FILE ) +function(generate_shared) + set(single_args "IMAGE;FILE") + cmake_parse_arguments(SHARE "" "${single_args}" "" ${ARGN}) + + check_arguments_required_all("generate_shared" SHARE IMAGE FILE) + + set(prop_target ${IMAGE_NAME}_shared_property_target) + file(GENERATE OUTPUT ${SHARE_FILE} + CONTENT + "$,\n> +$" + ) +endfunction() + +# +# Usage +# get_shared( IMAGE PROPERTY ) +# +# Get a property value defined by the child image or domain if it exists. +# The property value will be returned in the variable referenced by . +# +# Example usage 'get_shared(prop_value IMAGE child PROPERTY property_in_child)' +# +function(get_shared var) + set(single_args "IMAGE") + set(multi_args "PROPERTY") + cmake_parse_arguments(SHARE "" "${single_args}" "${multi_args}" ${ARGN}) + + check_arguments_required_all("get_shared" SHARE IMAGE PROPERTY) + + if(TARGET ${SHARE_IMAGE}_shared_property_target) + get_property( + ${var} + TARGET ${SHARE_IMAGE}_shared_property_target + PROPERTY ${SHARE_PROPERTY} + ) + set(${var} ${${var}} PARENT_SCOPE) + endif() +endfunction() diff --git a/cmake/multi_image.cmake b/cmake/multi_image.cmake index 89307692d6ba..b4728348b384 100644 --- a/cmake/multi_image.cmake +++ b/cmake/multi_image.cmake @@ -4,41 +4,25 @@ # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # -function(share content) - # Adds 'content' as a line in the 'shared_vars' property. - # This property is again written to a file which is imported as a cmake file - # by the parent image. In other words, this function can be used to share - # information (variables, lists etc) with the parent image. - # - # Example usage 'share("set(visible_in_parent \"I AM YOUR CHILD\")")' - - set_property( - TARGET zephyr_property_target - APPEND_STRING - PROPERTY shared_vars - "${content}\n" - ) -endfunction() - if(IMAGE_NAME) - share("set(${IMAGE_NAME}KERNEL_HEX_NAME ${KERNEL_HEX_NAME})") - share("set(${IMAGE_NAME}ZEPHYR_BINARY_DIR ${ZEPHYR_BINARY_DIR})") + set_shared(IMAGE ${IMAGE_NAME} PROPERTY KERNEL_HEX_NAME ${KERNEL_HEX_NAME}) + set_shared(IMAGE ${IMAGE_NAME} PROPERTY ZEPHYR_BINARY_DIR ${ZEPHYR_BINARY_DIR}) # Share the elf file, in order to support symbol loading for debuggers. - share("set(${IMAGE_NAME}KERNEL_ELF_NAME ${KERNEL_ELF_NAME})") - share("list(APPEND ${IMAGE_NAME}BUILD_BYPRODUCTS ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME})") - share("list(APPEND ${IMAGE_NAME}BUILD_BYPRODUCTS ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME})") + set_shared(IMAGE ${IMAGE_NAME} PROPERTY KERNEL_ELF_NAME ${KERNEL_ELF_NAME}) + set_shared(IMAGE ${IMAGE_NAME} + PROPERTY BUILD_BYPRODUCTS + ${PROJECT_BINARY_DIR}/${KERNEL_HEX_NAME} + ${PROJECT_BINARY_DIR}/${KERNEL_ELF_NAME} + ) # Share the signing key file so that the parent image can use it to # generate signed update candidates. if(CONFIG_BOOT_SIGNATURE_KEY_FILE) - share("set(${IMAGE_NAME}SIGNATURE_KEY_FILE ${CONFIG_BOOT_SIGNATURE_KEY_FILE})") + set_shared(IMAGE ${IMAGE_NAME} PROPERTY SIGNATURE_KEY_FILE ${CONFIG_BOOT_SIGNATURE_KEY_FILE}) endif() - file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/shared_vars.cmake - CONTENT $ - ) + generate_shared(IMAGE ${IMAGE_NAME} FILE ${CMAKE_BINARY_DIR}/shared_vars.cmake) endif(IMAGE_NAME) - function(add_child_image) # Adds a child image to the build. # @@ -296,7 +280,7 @@ function(add_child_image_from_source) COMMAND ${CMAKE_COMMAND} -G${CMAKE_GENERATOR} ${EXTRA_MULTI_IMAGE_CMAKE_ARGS} # E.g. --trace-expand - -DIMAGE_NAME=${ACI_NAME}_ + -DIMAGE_NAME=${ACI_NAME} ${image_cmake_args} ${ACI_SOURCE_DIR} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/${ACI_NAME} @@ -305,7 +289,7 @@ function(add_child_image_from_source) if (IMAGE_NAME) # Expose your childrens secrets to your parent - share("include(${CMAKE_BINARY_DIR}/${ACI_NAME}/shared_vars.cmake)") + set_shared(FILE ${CMAKE_BINARY_DIR}/${ACI_NAME}/shared_vars.cmake) endif() set_property(DIRECTORY APPEND PROPERTY @@ -323,10 +307,6 @@ function(add_child_image_from_source) # namespace include(${CMAKE_BINARY_DIR}/${ACI_NAME}/shared_vars.cmake) - # Increase the scope of this variable to make it more available - set(${ACI_NAME}_KERNEL_HEX_NAME ${${ACI_NAME}_KERNEL_HEX_NAME} CACHE STRING "" FORCE) - set(${ACI_NAME}_KERNEL_ELF_NAME ${${ACI_NAME}_KERNEL_ELF_NAME} CACHE STRING "" FORCE) - if(MULTI_IMAGE_DEBUG_MAKEFILE AND "${CMAKE_GENERATOR}" STREQUAL "Ninja") set(multi_image_build_args "-d" "${MULTI_IMAGE_DEBUG_MAKEFILE}") endif() @@ -334,11 +314,13 @@ function(add_child_image_from_source) set(multi_image_build_args "--debug=${MULTI_IMAGE_DEBUG_MAKEFILE}") endif() + get_shared(${ACI_NAME}_byproducts IMAGE ${ACI_NAME} PROPERTY BUILD_BYPRODUCTS) + include(ExternalProject) ExternalProject_Add(${ACI_NAME}_subimage SOURCE_DIR ${ACI_SOURCE_DIR} BINARY_DIR ${CMAKE_BINARY_DIR}/${ACI_NAME} - BUILD_BYPRODUCTS ${${ACI_NAME}_BUILD_BYPRODUCTS} # Set by shared_vars.cmake + BUILD_BYPRODUCTS ${${ACI_NAME}_byproducts} CONFIGURE_COMMAND "" BUILD_COMMAND ${CMAKE_COMMAND} --build . -- ${multi_image_build_args} INSTALL_COMMAND "" diff --git a/cmake/partition_manager.cmake b/cmake/partition_manager.cmake index 9aa61b61b948..214c8c76a41e 100644 --- a/cmake/partition_manager.cmake +++ b/cmake/partition_manager.cmake @@ -55,7 +55,9 @@ endif() # # The dynamic partition is specified by the parent domain (i.e. the domain # which creates the current domain through 'create_domain_image()'. -if("${IMAGE_NAME}" STREQUAL "${${DOMAIN}_PM_DOMAIN_DYNAMIC_PARTITION}_") +if(DEFINED ${DOMAIN}_PM_DOMAIN_DYNAMIC_PARTITION + AND "${IMAGE_NAME}" STREQUAL "${${DOMAIN}_PM_DOMAIN_DYNAMIC_PARTITION}" +) set(is_dynamic_partition_in_domain TRUE) endif() @@ -111,22 +113,22 @@ set_property(GLOBAL PROPERTY # Prepare the input_files, header_files, and images lists set(generated_path include/generated) foreach (image ${PM_IMAGES}) - set(shared_vars_file ${CMAKE_BINARY_DIR}/${image}/shared_vars.cmake) - if (NOT (EXISTS ${shared_vars_file})) - message(FATAL_ERROR "Could not find shared vars file: ${shared_vars_file}") - endif() - include(${shared_vars_file}) list(APPEND prefixed_images ${DOMAIN}:${image}) list(APPEND images ${image}) - list(APPEND input_files ${${image}_PM_YML_FILES}) - list(APPEND header_files ${${image}_ZEPHYR_BINARY_DIR}/${generated_path}/pm_config.h) + + get_shared(${image}_input_files IMAGE ${image} PROPERTY PM_YML_FILES) + get_shared(${image}_binary_dir IMAGE ${image} PROPERTY ZEPHYR_BINARY_DIR) + + list(APPEND input_files ${${image}_input_files}) + list(APPEND header_files ${${image}_binary_dir}/${generated_path}/pm_config.h) # Re-configure (Re-execute all CMakeLists.txt code) when original # (not preprocessed) configuration file changes. + get_shared(dependencies IMAGE ${image} PROPERTY PM_YML_DEP_FILES) set_property( DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS - ${${image}_PM_YML_DEP_FILES} + ${dependencies} ) endforeach() @@ -271,8 +273,11 @@ foreach(part ${PM_ALL_BY_SIZE}) list(APPEND explicitly_assigned ${part}) else() if(${part} IN_LIST images) - set(${part}_PM_HEX_FILE ${${part}_ZEPHYR_BINARY_DIR}/${${part}_KERNEL_HEX_NAME}) - set(${part}_PM_ELF_FILE ${${part}_ZEPHYR_BINARY_DIR}/${${part}_KERNEL_ELF_NAME}) + get_shared(${part}_bin_dir IMAGE ${part} PROPERTY ZEPHYR_BINARY_DIR) + get_shared(${part}_hex_file IMAGE ${part} PROPERTY KERNEL_HEX_NAME) + get_shared(${part}_elf_file IMAGE ${part} PROPERTY KERNEL_ELF_NAME) + set(${part}_PM_HEX_FILE ${${part}_bin_dir}/${${part}_hex_file}) + set(${part}_PM_ELF_FILE ${${part}_bin_dir}/${${part}_elf_file}) set(${part}_PM_TARGET ${part}_subimage) elseif(${part} IN_LIST containers) set(${part}_PM_HEX_FILE ${PROJECT_BINARY_DIR}/${part}.hex) @@ -371,18 +376,18 @@ if (is_dynamic_partition_in_domain) # Expose the generated partition manager configuration files to parent image. # This is used by the root image to create the global configuration in # pm_config.h. - share("set(${DOMAIN}_PM_DOMAIN_PARTITIONS ${pm_out_partition_file})") - share("set(${DOMAIN}_PM_DOMAIN_REGIONS ${pm_out_region_file})") - share("set(${DOMAIN}_PM_DOMAIN_HEADER_FILES ${header_files})") - share("set(${DOMAIN}_PM_DOMAIN_IMAGES ${prefixed_images})") - share("set(${DOMAIN}_PM_HEX_FILE ${PROJECT_BINARY_DIR}/${merged}.hex)") - share("set(${DOMAIN}_PM_DOTCONF_FILES ${pm_out_dotconf_file})") - share("set(${DOMAIN}_PM_APP_HEX ${PROJECT_BINARY_DIR}/app.hex)") - share("set(${DOMAIN}_PM_SIGNED_APP_HEX ${PROJECT_BINARY_DIR}/signed_by_b0_app.hex)") - share("list(APPEND ${IMAGE_NAME}BUILD_BYPRODUCTS ${PROJECT_BINARY_DIR}/${merged}.hex)") + set_shared(IMAGE ${DOMAIN} PROPERTY PM_DOMAIN_PARTITIONS ${pm_out_partition_file}) + set_shared(IMAGE ${DOMAIN} PROPERTY PM_DOMAIN_REGIONS ${pm_out_region_file}) + set_shared(IMAGE ${DOMAIN} PROPERTY PM_DOMAIN_HEADER_FILES ${header_files}) + set_shared(IMAGE ${DOMAIN} PROPERTY PM_DOMAIN_IMAGES ${prefixed_images}) + set_shared(IMAGE ${DOMAIN} PROPERTY PM_HEX_FILE ${PROJECT_BINARY_DIR}/${merged}.hex) + set_shared(IMAGE ${DOMAIN} PROPERTY PM_DOTCONF_FILES ${pm_out_dotconf_file}) + set_shared(IMAGE ${DOMAIN} PROPERTY PM_APP_HEX ${PROJECT_BINARY_DIR}/app.hex) + set_shared(IMAGE ${DOMAIN} PROPERTY PM_SIGNED_APP_HEX ${PROJECT_BINARY_DIR}/signed_by_b0_app.hex) + set_shared(IMAGE ${IMAGE_NAME} APPEND PROPERTY BUILD_BYPRODUCTS ${PROJECT_BINARY_DIR}/${merged}.hex) else() # This is the root image, generate the global pm_config.h - # First, include the shared_vars.cmake file for all child images. + # First, include the shared properties for all child images. if (PM_DOMAINS) # We ensure the existence of PM_DOMAINS to support older cmake versions. # When version >= 3.17 is required this check can be removed. @@ -391,19 +396,18 @@ else() foreach (d ${PM_DOMAINS}) # Don't include shared vars from own domain. if (NOT ("${DOMAIN}" STREQUAL "${d}")) - set(shared_vars_file - ${CMAKE_BINARY_DIR}/${${d}_PM_DOMAIN_DYNAMIC_PARTITION}/shared_vars.cmake - ) - if (NOT (EXISTS ${shared_vars_file})) - message(FATAL_ERROR "Could not find shared vars file: ${shared_vars_file}") - endif() - include(${shared_vars_file}) - list(APPEND header_files ${${d}_PM_DOMAIN_HEADER_FILES}) - list(APPEND prefixed_images ${${d}_PM_DOMAIN_IMAGES}) - list(APPEND pm_out_partition_file ${${d}_PM_DOMAIN_PARTITIONS}) - list(APPEND pm_out_region_file ${${d}_PM_DOMAIN_REGIONS}) - list(APPEND global_hex_depends ${${d}_PM_DOMAIN_DYNAMIC_PARTITION}_subimage) - list(APPEND domain_hex_files ${${d}_PM_HEX_FILE}) + get_shared(shared_header_files IMAGE ${d} PROPERTY PM_DOMAIN_HEADER_FILES) + get_shared(shared_prefixed_images IMAGE ${d} PROPERTY PM_DOMAIN_IMAGES) + get_shared(shared_pm_out_partition_file IMAGE ${d} PROPERTY PM_DOMAIN_PARTITIONS) + get_shared(shared_pm_out_region_file IMAGE ${d} PROPERTY PM_DOMAIN_REGIONS) + get_shared(shared_domain_hex_files IMAGE ${d} PROPERTY PM_HEX_FILE) + + list(APPEND header_files ${shared_header_files}) + list(APPEND prefixed_images ${shared_prefixed_images}) + list(APPEND pm_out_partition_file ${shared_pm_out_partition_file}) + list(APPEND pm_out_region_file ${shared_pm_out_region_file}) + list(APPEND domain_hex_files ${shared_domain_hex_files}) + list(APPEND global_hex_depends ${${d}_PM_DOMAIN_DYNAMIC_PARTITION}_subimage) # Add domain prefix cmake variables for all partitions # Here, we actually overwrite the already imported kconfig values @@ -411,7 +415,8 @@ else() # are accessed through the 'partition_manager' target, and most likely # through generator expression, as this file is one of the last # cmake files executed in the configure stage. - import_kconfig(PM_ ${${d}_PM_DOTCONF_FILES} ${d}_pm_var_names) + get_shared(conf_file IMAGE ${d} PROPERTY PM_DOTCONF_FILES) + import_kconfig(PM_ ${conf_file} ${d}_pm_var_names) foreach(name ${${d}_pm_var_names}) set_property( @@ -502,7 +507,6 @@ else() -o ${final_merged} ${domain_hex_files} DEPENDS - ${domain_hex_files} ${global_hex_depends} ) diff --git a/cmake/s1.cmake b/cmake/s1.cmake index 052ff287c875..108e0ad985b9 100644 --- a/cmake/s1.cmake +++ b/cmake/s1.cmake @@ -7,7 +7,7 @@ if (CONFIG_BUILD_S1_VARIANT AND ((${CONFIG_S1_VARIANT_IMAGE_NAME} STREQUAL "app" AND NOT IMAGE_NAME) OR - ("${CONFIG_S1_VARIANT_IMAGE_NAME}_" STREQUAL "${IMAGE_NAME}"))) + ("${CONFIG_S1_VARIANT_IMAGE_NAME}" STREQUAL "${IMAGE_NAME}"))) # Create second executable for the second slot of the second stage # bootloader. This is done inside this file since it is non-trivial to add # executable targets outside the root CMakeLists.txt. The problem is that @@ -143,15 +143,10 @@ if (CONFIG_BUILD_S1_VARIANT AND ) if (IMAGE_NAME) - # Register in the parent image that this child image will have - # ${link_variant}image.hex as a byproduct, this allows the parent image to know - # where the hex file comes from and create custom commands that - # depend on it. - set_property( - TARGET zephyr_property_target - APPEND_STRING - PROPERTY shared_vars - "list(APPEND ${IMAGE_NAME}BUILD_BYPRODUCTS ${output})\n" - ) + # Register in the parent image that this child image will have + # ${link_variant}image.hex as a byproduct, this allows the parent image to know + # where the hex file comes from and create custom commands that + # depend on it. + set_shared(IMAGE ${IMAGE_NAME} APPEND PROPERTY BUILD_BYPRODUCTS ${output}) endif() endif() diff --git a/modules/mcuboot/CMakeLists.txt b/modules/mcuboot/CMakeLists.txt index 6743dd426125..ff9124b93749 100644 --- a/modules/mcuboot/CMakeLists.txt +++ b/modules/mcuboot/CMakeLists.txt @@ -126,8 +126,8 @@ if(CONFIG_BOOTLOADER_MCUBOOT) $) if (NOT DEFINED CONFIG_BOOT_SIGNATURE_KEY_FILE) - include(${CMAKE_BINARY_DIR}/mcuboot/shared_vars.cmake) - set(CONFIG_BOOT_SIGNATURE_KEY_FILE ${mcuboot_SIGNATURE_KEY_FILE}) + get_shared(mcuboot_sign_key IMAGE mcuboot PROPERTY SIGNATURE_KEY_FILE) + set(CONFIG_BOOT_SIGNATURE_KEY_FILE ${mcuboot_sign_key}) endif () foreach (filepath ${mcuboot_CONF_FILE}) @@ -243,15 +243,15 @@ if(CONFIG_BOOTLOADER_MCUBOOT) # These updates are verified by the application core MCUBoot. # Create a signed variant of the network core application. - # Load the shared vars to get the path to the hex file to sign. - include(${CMAKE_BINARY_DIR}/hci_rpmsg/shared_vars.cmake) + get_shared(hci_rpmsg_byproducts IMAGE hci_rpmsg PROPERTY BUILD_BYPRODUCTS) + get_shared(cpunet_signed_app_hex IMAGE CPUNET PROPERTY PM_SIGNED_APP_HEX) sign( - SIGNED_BIN_FILE_IN ${CPUNET_PM_SIGNED_APP_HEX} + SIGNED_BIN_FILE_IN ${cpunet_signed_app_hex} SIGNED_HEX_FILE_NAME_PREFIX ${PROJECT_BINARY_DIR}/net_core_app START_ADDRESS_OFFSET $ SIGNED_HEX_FILE_OUT net_core_app_signed_hex - DEPENDS hci_rpmsg_subimage ${hci_rpmsg_BUILD_BYPRODUCTS} + DEPENDS hci_rpmsg_subimage ${hci_rpmsg_byproducts} ) add_custom_target( diff --git a/subsys/partition_manager/CMakeLists.txt b/subsys/partition_manager/CMakeLists.txt index c9a691c03a00..ce9879f76393 100644 --- a/subsys/partition_manager/CMakeLists.txt +++ b/subsys/partition_manager/CMakeLists.txt @@ -32,11 +32,11 @@ function(preprocess_pm_yml in_file out_file) if (DEFINED IMAGE_NAME) # Share location of original source file so that the parent image can add it # to the CMAKE_CONFIGURE_DEPENDS list. - share("list(APPEND ${IMAGE_NAME}PM_YML_DEP_FILES ${in_file})") + set_shared(IMAGE ${IMAGE_NAME} APPEND PROPERTY PM_YML_DEP_FILES ${in_file}) # Share location of preprocessed pm.yml file so that the parent image can # use it as source for partition manager configuration. - share("list(APPEND ${IMAGE_NAME}PM_YML_FILES ${out_file})") + set_shared(IMAGE ${IMAGE_NAME} APPEND PROPERTY PM_YML_FILES ${out_file}) endif() # Re-configure (Re-execute all CMakeLists.txt code) when original diff --git a/subsys/spm/CMakeLists.txt b/subsys/spm/CMakeLists.txt index eb71b00cfc60..48dca747e954 100644 --- a/subsys/spm/CMakeLists.txt +++ b/subsys/spm/CMakeLists.txt @@ -10,7 +10,7 @@ zephyr_sources_ifdef(CONFIG_SPM_SHARE_CONSOLE_UART spm_uart.c) zephyr_linker_sources(SECTIONS secure_services.ld) if(CONFIG_ARM_FIRMWARE_HAS_SECURE_ENTRY_FUNCS) - share( - "list(APPEND ${IMAGE_NAME}BUILD_BYPRODUCTS - ${CMAKE_BINARY_DIR}/${CONFIG_ARM_ENTRY_VENEERS_LIB_NAME})") + set_shared(IMAGE ${IMAGE_NAME} APPEND PROPERTY BUILD_BYPRODUCTS + ${CMAKE_BINARY_DIR}/${CONFIG_ARM_ENTRY_VENEERS_LIB_NAME} + ) endif() From db4294a9adeae9da355bf821d6c1ab8e0ce37b6a Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 18 Aug 2021 23:32:48 +0200 Subject: [PATCH 069/126] cmake: partition manager: conditionally share b0n signed image Only share the b0n signed image when secure boot is enabled. Currently PM_SIGNED_APP_HEX is always shared when a domain is having mcuboot enabled. However, this is not the same as having secure boot enabled, so the sharing of the non-existing signed_by_b0_app.hex file may cause other parts of the build system to fail. Therefore the sharing of signed_by_b0_app.hex is now safeguarded with if(CONFIG_SECURE_BOOT) Signed-off-by: Torsten Rasmussen --- cmake/partition_manager.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/partition_manager.cmake b/cmake/partition_manager.cmake index 214c8c76a41e..3fdbb301146e 100644 --- a/cmake/partition_manager.cmake +++ b/cmake/partition_manager.cmake @@ -383,8 +383,11 @@ if (is_dynamic_partition_in_domain) set_shared(IMAGE ${DOMAIN} PROPERTY PM_HEX_FILE ${PROJECT_BINARY_DIR}/${merged}.hex) set_shared(IMAGE ${DOMAIN} PROPERTY PM_DOTCONF_FILES ${pm_out_dotconf_file}) set_shared(IMAGE ${DOMAIN} PROPERTY PM_APP_HEX ${PROJECT_BINARY_DIR}/app.hex) - set_shared(IMAGE ${DOMAIN} PROPERTY PM_SIGNED_APP_HEX ${PROJECT_BINARY_DIR}/signed_by_b0_app.hex) set_shared(IMAGE ${IMAGE_NAME} APPEND PROPERTY BUILD_BYPRODUCTS ${PROJECT_BINARY_DIR}/${merged}.hex) + if(CONFIG_SECURE_BOOT) + # Only when secure boot is enabled the app will be signed. + set_shared(IMAGE ${DOMAIN} PROPERTY PM_SIGNED_APP_HEX ${PROJECT_BINARY_DIR}/signed_by_b0_app.hex) + endif() else() # This is the root image, generate the global pm_config.h # First, include the shared properties for all child images. From dfe7168b3194180bb8496a8464f63e7b71c00e12 Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Tue, 17 Aug 2021 15:53:43 +0200 Subject: [PATCH 070/126] mcuboot: using DOMAIN shared properties instead of fixed hci_rpmsg Using PM_DOMAIN_IMAGES and PM_SIGNED_APP_HEX properties from CPUNET domain in order to setup correct dependencies instead of hard coded hci_rpmsg image properties. Fixes: NCSDK-9502 Signed-off-by: Torsten Rasmussen --- modules/mcuboot/CMakeLists.txt | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/modules/mcuboot/CMakeLists.txt b/modules/mcuboot/CMakeLists.txt index ff9124b93749..a70e6762bd99 100644 --- a/modules/mcuboot/CMakeLists.txt +++ b/modules/mcuboot/CMakeLists.txt @@ -235,23 +235,33 @@ if(CONFIG_BOOTLOADER_MCUBOOT) "version_MCUBOOT=${CONFIG_MCUBOOT_IMAGE_VERSION}" ) + get_shared(cpunet_signed_app_hex IMAGE CPUNET PROPERTY PM_SIGNED_APP_HEX) + if (CONFIG_NRF53_UPGRADE_NETWORK_CORE - AND CONFIG_HCI_RPMSG_BUILD_STRATEGY_FROM_SOURCE) + AND DEFINED cpunet_signed_app_hex) # Network core application updates are enabled. # We know this since MCUBoot is enabled on the application core, and # a network core child image is included in the build. # These updates are verified by the application core MCUBoot. # Create a signed variant of the network core application. - get_shared(hci_rpmsg_byproducts IMAGE hci_rpmsg PROPERTY BUILD_BYPRODUCTS) - get_shared(cpunet_signed_app_hex IMAGE CPUNET PROPERTY PM_SIGNED_APP_HEX) + get_shared(cpunet_images IMAGE CPUNET PROPERTY PM_DOMAIN_IMAGES) + foreach(image ${cpunet_images}) + if(${image} MATCHES "CPUNET:(.*)") + set(image_name ${CMAKE_MATCH_1}) + if(TARGET ${image_name}_subimage) + get_shared(${image_name}_byproducts IMAGE ${image_name} PROPERTY BUILD_BYPRODUCTS) + list(APPEND sign_depends ${image_name}_subimage ${${image_name}_byproducts}) + endif() + endif() + endforeach() sign( SIGNED_BIN_FILE_IN ${cpunet_signed_app_hex} SIGNED_HEX_FILE_NAME_PREFIX ${PROJECT_BINARY_DIR}/net_core_app START_ADDRESS_OFFSET $ SIGNED_HEX_FILE_OUT net_core_app_signed_hex - DEPENDS hci_rpmsg_subimage ${hci_rpmsg_byproducts} + DEPENDS ${sign_depends} ) add_custom_target( From 81fda456b394f99957141e8396b8c4bf3e8e97cd Mon Sep 17 00:00:00 2001 From: Torsten Rasmussen Date: Wed, 18 Aug 2021 12:40:05 +0200 Subject: [PATCH 071/126] cmake: adding missing file extension, .c to zephyr_sources filename CMake >= 3.20 requires file extensions explicitly added to source files. See CMP0115: > Starting in CMake 3.20, CMake prefers all source files to have their > extensions explicitly listed: The zephyr_sources_ifdef() added a file without extension causing CMake to fail. The line: zephyr_sources_ifdef(CONFIG_NFC_T4T_HL_PROCEDURE hl_procedure) has been updated to: zephyr_sources_ifdef(CONFIG_NFC_T4T_HL_PROCEDURE hl_procedure.c) Signed-off-by: Torsten Rasmussen --- subsys/nfc/t4t/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/nfc/t4t/CMakeLists.txt b/subsys/nfc/t4t/CMakeLists.txt index ae7a863ab2cc..7c6762faa8e0 100644 --- a/subsys/nfc/t4t/CMakeLists.txt +++ b/subsys/nfc/t4t/CMakeLists.txt @@ -10,4 +10,4 @@ zephyr_sources_ifdef(CONFIG_NFC_T4T_APDU apdu.c) zephyr_sources_ifdef(CONFIG_NFC_T4T_CC_FILE cc_file.c tlv_block.c) -zephyr_sources_ifdef(CONFIG_NFC_T4T_HL_PROCEDURE hl_procedure) +zephyr_sources_ifdef(CONFIG_NFC_T4T_HL_PROCEDURE hl_procedure.c) From 88d6b0239d78effc214808fc4d4312fa5e45fabd Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Thu, 19 Aug 2021 08:48:42 +0200 Subject: [PATCH 072/126] caf: power_manager: Update log level of a log Change switches to using debug level log to avoid flooding logs with irrelevant messages. Jira: NCSDK-10901 Signed-off-by: Marek Pieta --- subsys/caf/modules/power_manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/caf/modules/power_manager.c b/subsys/caf/modules/power_manager.c index 26de9feee07a..f7290b274fb1 100644 --- a/subsys/caf/modules/power_manager.c +++ b/subsys/caf/modules/power_manager.c @@ -60,7 +60,7 @@ static void power_down_counter_reset(void) if ((power_state == POWER_STATE_IDLE) && check_if_power_state_allowed(POWER_MANAGER_LEVEL_SUSPENDED)) { k_work_reschedule(&power_down_trigger, POWER_DOWN_TIMEOUT); - LOG_INF("Power down timer restarted"); + LOG_DBG("Power down timer restarted"); } } From 1d83ed98b461524d3915e9d14827ad052d0bae6e Mon Sep 17 00:00:00 2001 From: Marek Pieta Date: Thu, 19 Aug 2021 08:53:32 +0200 Subject: [PATCH 073/126] applications: nrf_desktop: Disable disaplaying keep alive event log Displaying keep alive event log is disabled to avoid flooding logs with irrelevant messages. Jira: NCSDK-10901 Signed-off-by: Marek Pieta --- .../configuration/nrf52810dmouse_nrf52810/app_ZDebug.conf | 1 + .../configuration/nrf52820dongle_nrf52820/app_ZDebug.conf | 1 + .../configuration/nrf52833dk_nrf52833/app_ZDebug.conf | 1 + .../configuration/nrf52833dk_nrf52833/app_ZDebugWithShell.conf | 1 + .../configuration/nrf52833dongle_nrf52833/app_ZDebug.conf | 1 + .../configuration/nrf52833dongle_nrf52833/app_ZDebugMCUBoot.conf | 1 + .../nrf52833dongle_nrf52833/app_ZDebugWithShell.conf | 1 + .../configuration/nrf52840dk_nrf52840/app_ZDebug.conf | 1 + .../configuration/nrf52840dk_nrf52840/app_ZDebugB0.conf | 1 + .../configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootQSPI.conf | 1 + .../configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootSMP.conf | 1 + .../configuration/nrf52840dk_nrf52840/app_ZDebugWithShell.conf | 1 + .../configuration/nrf52840dk_nrf52840/app_ZDebug_dongle.conf | 1 + .../configuration/nrf52840dk_nrf52840/app_ZDebug_keyboard.conf | 1 + .../configuration/nrf52840dongle_nrf52840/app_ZDebug.conf | 1 + .../nrf52840dongle_nrf52840/app_ZDebug3BLEconn.conf | 1 + .../nrf52840dongle_nrf52840/app_ZDebug4LLPMconn.conf | 1 + .../configuration/nrf52840dongle_nrf52840/app_ZDebugB0.conf | 1 + .../configuration/nrf52840dongle_nrf52840/app_ZDebugSplitLL.conf | 1 + .../nrf52840dongle_nrf52840/app_ZDebugWithShell.conf | 1 + .../configuration/nrf52840gmouse_nrf52840/app_ZDebug.conf | 1 + .../configuration/nrf52840gmouse_nrf52840/app_ZDebugB0.conf | 1 + .../configuration/nrf52840gmouse_nrf52840/app_ZDebugSplitLL.conf | 1 + .../nrf52840gmouse_nrf52840/app_ZDebugWithShell.conf | 1 + .../configuration/nrf52dmouse_nrf52832/app_ZDebug.conf | 1 + .../nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebug.conf | 1 + .../configuration/nrf52kbd_nrf52832/app_ZDebugB0.conf | 1 + .../configuration/nrf52kbd_nrf52832/app_ZDebugSplitLL.conf | 1 + .../configuration/nrf52kbd_nrf52832/app_ZDebugWithShell.conf | 1 + .../configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebug.conf | 1 + .../configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebugB0.conf | 1 + 31 files changed, 31 insertions(+) diff --git a/applications/nrf_desktop/configuration/nrf52810dmouse_nrf52810/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52810dmouse_nrf52810/app_ZDebug.conf index d5c675bcbc49..aa38de4d219c 100644 --- a/applications/nrf_desktop/configuration/nrf52810dmouse_nrf52810/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52810dmouse_nrf52810/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52820dongle_nrf52820/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52820dongle_nrf52820/app_ZDebug.conf index 3bd43d1a07ef..af5c99df85de 100644 --- a/applications/nrf_desktop/configuration/nrf52820dongle_nrf52820/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52820dongle_nrf52820/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52833dk_nrf52833/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52833dk_nrf52833/app_ZDebug.conf index 90969121d2e1..d36a0d93c693 100644 --- a/applications/nrf_desktop/configuration/nrf52833dk_nrf52833/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52833dk_nrf52833/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52833dk_nrf52833/app_ZDebugWithShell.conf b/applications/nrf_desktop/configuration/nrf52833dk_nrf52833/app_ZDebugWithShell.conf index 0c0095465594..79990e3cf752 100644 --- a/applications/nrf_desktop/configuration/nrf52833dk_nrf52833/app_ZDebugWithShell.conf +++ b/applications/nrf_desktop/configuration/nrf52833dk_nrf52833/app_ZDebugWithShell.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebug.conf index 01305ff62786..4378bfb55995 100644 --- a/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebugMCUBoot.conf b/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebugMCUBoot.conf index 10f79d05eb68..10f46fb922b6 100644 --- a/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebugMCUBoot.conf +++ b/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebugMCUBoot.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebugWithShell.conf b/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebugWithShell.conf index 7afa64d54ff5..2422383f2d80 100644 --- a/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebugWithShell.conf +++ b/applications/nrf_desktop/configuration/nrf52833dongle_nrf52833/app_ZDebugWithShell.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug.conf index 3f51a3af6d7c..c11d75a988e4 100644 --- a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugB0.conf b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugB0.conf index ccc994dabd90..e352a8bd9bee 100644 --- a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugB0.conf +++ b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugB0.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootQSPI.conf b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootQSPI.conf index 36e28280cb6b..d4cfc075b555 100644 --- a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootQSPI.conf +++ b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootQSPI.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootSMP.conf b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootSMP.conf index 903f78626f80..120071f3cce9 100644 --- a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootSMP.conf +++ b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugMCUBootSMP.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugWithShell.conf b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugWithShell.conf index 642d8da906ce..27f10c2b2793 100644 --- a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugWithShell.conf +++ b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebugWithShell.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug_dongle.conf b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug_dongle.conf index 8e485db098f0..146f7b6de8e4 100644 --- a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug_dongle.conf +++ b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug_dongle.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug_keyboard.conf b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug_keyboard.conf index 7e4bfe3c086d..7aa505193d59 100644 --- a/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug_keyboard.conf +++ b/applications/nrf_desktop/configuration/nrf52840dk_nrf52840/app_ZDebug_keyboard.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug.conf index 4550d725e1fb..c68dd20a6921 100644 --- a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug3BLEconn.conf b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug3BLEconn.conf index d046dc883e0e..24658e14b223 100644 --- a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug3BLEconn.conf +++ b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug3BLEconn.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug4LLPMconn.conf b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug4LLPMconn.conf index 2b10191788b1..636c7954ee0b 100644 --- a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug4LLPMconn.conf +++ b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebug4LLPMconn.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugB0.conf b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugB0.conf index eaba560dafa4..9e61e0101fe0 100644 --- a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugB0.conf +++ b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugB0.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugSplitLL.conf b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugSplitLL.conf index a7eb81ab7a2d..b28b3cbd23da 100644 --- a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugSplitLL.conf +++ b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugSplitLL.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugWithShell.conf b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugWithShell.conf index ebdfbf4a800b..a7749abb994f 100644 --- a/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugWithShell.conf +++ b/applications/nrf_desktop/configuration/nrf52840dongle_nrf52840/app_ZDebugWithShell.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebug.conf index d2bc3bd80ad3..ae06fd7b4453 100644 --- a/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugB0.conf b/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugB0.conf index 9e7522af0a98..25dab2e3ad50 100644 --- a/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugB0.conf +++ b/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugB0.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugSplitLL.conf b/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugSplitLL.conf index e8e0dad99e65..0284a5096225 100644 --- a/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugSplitLL.conf +++ b/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugSplitLL.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugWithShell.conf b/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugWithShell.conf index 304fb23d91ac..d1165b45b79d 100644 --- a/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugWithShell.conf +++ b/applications/nrf_desktop/configuration/nrf52840gmouse_nrf52840/app_ZDebugWithShell.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52dmouse_nrf52832/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52dmouse_nrf52832/app_ZDebug.conf index 5d220bc5eb57..e39fca444348 100644 --- a/applications/nrf_desktop/configuration/nrf52dmouse_nrf52832/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52dmouse_nrf52832/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebug.conf index 396bf786eacd..65f4ddd3531e 100644 --- a/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugB0.conf b/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugB0.conf index 95063d88091b..da72daca555e 100644 --- a/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugB0.conf +++ b/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugB0.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugSplitLL.conf b/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugSplitLL.conf index f7fd3bd104f2..1739458223da 100644 --- a/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugSplitLL.conf +++ b/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugSplitLL.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugWithShell.conf b/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugWithShell.conf index 8fbce35c0d7e..0db4b093a27c 100644 --- a/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugWithShell.conf +++ b/applications/nrf_desktop/configuration/nrf52kbd_nrf52832/app_ZDebugWithShell.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebug.conf b/applications/nrf_desktop/configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebug.conf index d5b04eb10084..cbe5b95f3344 100644 --- a/applications/nrf_desktop/configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebug.conf +++ b/applications/nrf_desktop/configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebug.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" diff --git a/applications/nrf_desktop/configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebugB0.conf b/applications/nrf_desktop/configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebugB0.conf index 2f6ee037a8ec..63d2ce923d4a 100644 --- a/applications/nrf_desktop/configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebugB0.conf +++ b/applications/nrf_desktop/configuration/nrf5340dk_nrf5340_cpuapp/app_ZDebugB0.conf @@ -9,6 +9,7 @@ CONFIG_DESKTOP_INIT_LOG_MOTION_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_EVENT=n CONFIG_DESKTOP_INIT_LOG_HID_REPORT_SENT_EVENT=n +CONFIG_CAF_INIT_LOG_KEEP_ALIVE_EVENTS=n CONFIG_DESKTOP_HID_REPORT_DESC="configuration/common/hid_report_desc.c" From 0ac2cb44974077a87748f7be6addbbb339b832f3 Mon Sep 17 00:00:00 2001 From: Jun Qing Zou Date: Mon, 16 Aug 2021 11:27:34 +0900 Subject: [PATCH 074/126] application: serial_lte_modem: Add secondary PDN support to #XPING Allow to specify which PDN to use in Ping test. Prepare for multiple PDN support in other services. Signed-off-by: Jun Qing Zou --- .../serial_lte_modem/doc/ICMP_AT_commands.rst | 13 +++++++- .../serial_lte_modem/src/slm_at_icmp.c | 31 +++++++++++++++++-- .../serial_lte_modem/src/slm_at_socket.c | 4 +-- .../serial_lte_modem/src/slm_at_tcp_proxy.c | 4 +-- .../serial_lte_modem/src/slm_at_udp_proxy.c | 4 +-- applications/serial_lte_modem/src/slm_util.c | 12 ++++--- applications/serial_lte_modem/src/slm_util.h | 5 +-- 7 files changed, 56 insertions(+), 17 deletions(-) diff --git a/applications/serial_lte_modem/doc/ICMP_AT_commands.rst b/applications/serial_lte_modem/doc/ICMP_AT_commands.rst index 2a842adb7399..44f4f9feab29 100644 --- a/applications/serial_lte_modem/doc/ICMP_AT_commands.rst +++ b/applications/serial_lte_modem/doc/ICMP_AT_commands.rst @@ -24,7 +24,7 @@ Syntax :: - #XPING=,,[,[,]] + #XPING=,,[,[,[,]]] * The ```` parameter is a string. It represents the hostname, the IPv4, or the IPv6 address of the target host. @@ -38,6 +38,9 @@ Syntax * The ```` parameter is an integer. It represents the time to wait for sending the next echo request, in milliseconds. Its default value is ``1000``. +* The ```` parameter is an integer. + It represents ``cid`` in the ``+CGDCONT`` command. + Its default value is ``0``. Unsolicited notification ~~~~~~~~~~~~~~~~~~~~~~~~ @@ -73,6 +76,14 @@ Example #XPING: 0.037 seconds #XPING: 0.106 seconds #XPING: average 0.123 seconds + AT#XPING="5.189.130.26",45,5000,5,1000,1 + OK + #XPING: 1.612 seconds + #XPING: 0.349 seconds + #XPING: 0.334 seconds + #XPING: 0.278 seconds + #XPING: 0.278 seconds + #XPING: average 0.570 seconds Read command ------------ diff --git a/applications/serial_lte_modem/src/slm_at_icmp.c b/applications/serial_lte_modem/src/slm_at_icmp.c index c47b41a10270..8598c7183da4 100644 --- a/applications/serial_lte_modem/src/slm_at_icmp.c +++ b/applications/serial_lte_modem/src/slm_at_icmp.c @@ -35,6 +35,7 @@ static struct ping_argv_t { uint16_t waitms; uint16_t count; uint16_t interval; + uint16_t pdn; } ping_argv; /* global variable defined in different files */ @@ -249,6 +250,23 @@ static uint32_t send_ping_wait_reply(void) return (uint32_t)delta_t; } + /* Use non-primary PDN if specified, fail if cannot proceed + */ + if (ping_argv.pdn != 0) { + size_t len; + struct ifreq ifr = { 0 }; + + snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "pdn%d", ping_argv.pdn); + len = strlen(ifr.ifr_name); + if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, &ifr, len) < 0) { + LOG_WRN("Unable to set socket SO_BINDTODEVICE, abort"); + goto close_end; + } + LOG_DBG("Use PDN: %d", ping_argv.pdn); + } else { + LOG_DBG("Use PDN: 0"); + } + /* We have a blocking socket and we do not want to block for * a long for sending. Thus, let's set the timeout: */ @@ -469,7 +487,7 @@ static int ping_test_handler(const char *target) char ipv4_addr[NET_IPV4_ADDR_LEN] = {0}; LOG_INF("Ping target's IPv4 address"); - util_get_ip_addr(ipv4_addr, NULL); + util_get_ip_addr(ping_argv.pdn, ipv4_addr, NULL); if (strlen(ipv4_addr) == 0) { LOG_ERR("Unable to obtain local IPv4 address"); freeaddrinfo(res); @@ -489,7 +507,7 @@ static int ping_test_handler(const char *target) char ipv6_addr[NET_IPV6_ADDR_LEN] = {0}; LOG_INF("Ping target's IPv6 address"); - util_get_ip_addr(NULL, ipv6_addr); + util_get_ip_addr(ping_argv.pdn, NULL, ipv6_addr); if (strlen(ipv6_addr) == 0) { LOG_ERR("Unable to obtain local IPv6 address"); freeaddrinfo(res); @@ -514,7 +532,7 @@ static int ping_test_handler(const char *target) } /**@brief handle AT#XPING commands - * AT#XPING=,,[,[,]] + * AT#XPING=,,[,[,[,]]] * AT#XPING? READ command not supported * AT#XPING=? TEST command not supported */ @@ -552,6 +570,13 @@ int handle_at_icmp_ping(enum at_cmd_type cmd_type) return err; }; } + ping_argv.pdn = 0; /* default 0 primary PDN */ + if (at_params_valid_count_get(&at_param_list) > 6) { + err = at_params_unsigned_short_get(&at_param_list, 6, &ping_argv.pdn); + if (err < 0) { + return err; + }; + } err = ping_test_handler(target); break; diff --git a/applications/serial_lte_modem/src/slm_at_socket.c b/applications/serial_lte_modem/src/slm_at_socket.c index ac086ef2e333..b420a28def69 100644 --- a/applications/serial_lte_modem/src/slm_at_socket.c +++ b/applications/serial_lte_modem/src/slm_at_socket.c @@ -430,7 +430,7 @@ static int do_bind(uint16_t port) if (sock.family == AF_INET) { char ipv4_addr[INET_ADDRSTRLEN] = {0}; - util_get_ip_addr(ipv4_addr, NULL); + util_get_ip_addr(0, ipv4_addr, NULL); if (strlen(ipv4_addr) == 0) { LOG_ERR("Get local IPv4 address failed"); return -EINVAL; @@ -455,7 +455,7 @@ static int do_bind(uint16_t port) } else if (sock.family == AF_INET6) { char ipv6_addr[INET6_ADDRSTRLEN] = {0}; - util_get_ip_addr(NULL, ipv6_addr); + util_get_ip_addr(0, NULL, ipv6_addr); if (strlen(ipv6_addr) == 0) { LOG_ERR("Get local IPv6 address failed"); return -EINVAL; diff --git a/applications/serial_lte_modem/src/slm_at_tcp_proxy.c b/applications/serial_lte_modem/src/slm_at_tcp_proxy.c index 65eea65ba496..06ee66896420 100644 --- a/applications/serial_lte_modem/src/slm_at_tcp_proxy.c +++ b/applications/serial_lte_modem/src/slm_at_tcp_proxy.c @@ -134,7 +134,7 @@ static int do_tcp_server_start(uint16_t port) if (proxy.family == AF_INET) { char ipv4_addr[NET_IPV4_ADDR_LEN] = {0}; - util_get_ip_addr(ipv4_addr, NULL); + util_get_ip_addr(0, ipv4_addr, NULL); if (strlen(ipv4_addr) == 0) { LOG_ERR("Unable to obtain local IPv4 address"); ret = -ENETUNREACH; @@ -155,7 +155,7 @@ static int do_tcp_server_start(uint16_t port) } else { char ipv6_addr[NET_IPV6_ADDR_LEN] = {0}; - util_get_ip_addr(NULL, ipv6_addr); + util_get_ip_addr(0, NULL, ipv6_addr); if (strlen(ipv6_addr) == 0) { LOG_ERR("Unable to obtain local IPv6 address"); ret = -ENETUNREACH; diff --git a/applications/serial_lte_modem/src/slm_at_udp_proxy.c b/applications/serial_lte_modem/src/slm_at_udp_proxy.c index 7f30e1fd6db0..d63883150aa0 100644 --- a/applications/serial_lte_modem/src/slm_at_udp_proxy.c +++ b/applications/serial_lte_modem/src/slm_at_udp_proxy.c @@ -77,7 +77,7 @@ static int do_udp_server_start(uint16_t port) if (proxy.family == AF_INET) { char ipv4_addr[NET_IPV4_ADDR_LEN] = {0}; - util_get_ip_addr(ipv4_addr, NULL); + util_get_ip_addr(0, ipv4_addr, NULL); if (strlen(ipv4_addr) == 0) { LOG_ERR("Unable to obtain local IPv4 address"); close(proxy.sock); @@ -98,7 +98,7 @@ static int do_udp_server_start(uint16_t port) } else { char ipv6_addr[NET_IPV6_ADDR_LEN] = {0}; - util_get_ip_addr(NULL, ipv6_addr); + util_get_ip_addr(0, NULL, ipv6_addr); if (strlen(ipv6_addr) == 0) { LOG_ERR("Unable to obtain local IPv6 address"); close(proxy.sock); diff --git a/applications/serial_lte_modem/src/slm_util.c b/applications/serial_lte_modem/src/slm_util.c index 511b966bc62d..3ed42cbb5705 100644 --- a/applications/serial_lte_modem/src/slm_util.c +++ b/applications/serial_lte_modem/src/slm_util.c @@ -153,27 +153,29 @@ int util_string_get(const struct at_param_list *list, size_t index, char *value, } /** - * @brief use AT command to get IPv4 and/or IPv6 address + * @brief use AT command to get IPv4 and/or IPv6 address for specified PDN */ -void util_get_ip_addr(char *addr4, char *addr6) +void util_get_ip_addr(int cid, char *addr4, char *addr6) { int err; - char rsp[128]; + char buf[128]; char tmp[sizeof(struct in6_addr)]; char addr[NET_IPV6_ADDR_LEN]; size_t addr_len; - err = at_cmd_write("AT+CGPADDR", rsp, sizeof(rsp), NULL); + sprintf(buf, "AT+CGPADDR=%d", cid); + err = at_cmd_write(buf, buf, sizeof(buf), NULL); if (err) { return; } + /** parse +CGPADDR: ,, * PDN type "IP": PDP_addr_1 is * PDN type "IPV6": PDP_addr_1 is * PDN type "IPV4V6": , or or */ at_params_list_clear(&at_param_list); - err = at_parser_params_from_str(rsp, NULL, &at_param_list); + err = at_parser_params_from_str(buf, NULL, &at_param_list); if (err) { return; } diff --git a/applications/serial_lte_modem/src/slm_util.h b/applications/serial_lte_modem/src/slm_util.h index 305eece3f251..7859c0ba2de9 100644 --- a/applications/serial_lte_modem/src/slm_util.h +++ b/applications/serial_lte_modem/src/slm_util.h @@ -94,12 +94,13 @@ int slm_util_atoh(const char *ascii, uint16_t ascii_len, uint8_t *hex, uint16_t int util_string_get(const struct at_param_list *list, size_t index, char *value, size_t *len); /** - * @brief use AT command to get IPv4 and IPv6 addresses + * @brief use AT command to get IPv4 and IPv6 addresses for specified PDN * + * @param[in] cid PDP Context ID as defined in "+CGDCONT" command (0~10) * @param[in] addr4 buffer to hold the IPv4 address, size NET_IPV4_ADDR_LEN * @param[in] addr6 buffer to hold the IPv6 address, size NET_IPV6_ADDR_LEN */ -void util_get_ip_addr(char *addr4, char *addr6); +void util_get_ip_addr(int cid, char *addr4, char *addr6); /** @} */ #endif /* SLM_UTIL_ */ From 2525cf4e3077fa129dda56a3730fba5b1d9a2c7a Mon Sep 17 00:00:00 2001 From: Jun Qing Zou Date: Mon, 16 Aug 2021 09:56:04 +0900 Subject: [PATCH 075/126] application: serial_lte_modem: Datamode error handling Based on customer project experience, needs to quit datamode as soon as sending function fails in order for upper-layer protocol to re-act on the failure. Add to support "ERROR" response for sending function in datamode. No more re-transmit by datamode and all buffered data is dropped. Piggyback: static code analysis check handling Signed-off-by: Jun Qing Zou --- .../serial_lte_modem/doc/slm_data_mode.rst | 2 ++ .../serial_lte_modem/src/ftp_c/slm_at_ftp.c | 6 +++--- .../serial_lte_modem/src/gnss/slm_at_gnss.c | 1 - .../serial_lte_modem/src/http_c/slm_at_httpc.c | 2 +- .../serial_lte_modem/src/slm_at_host.c | 18 +++++++++++++----- .../serial_lte_modem/src/slm_at_host.h | 13 ++++++++++--- .../serial_lte_modem/src/slm_at_socket.c | 2 +- .../serial_lte_modem/src/slm_at_tcp_proxy.c | 6 +++--- 8 files changed, 33 insertions(+), 17 deletions(-) diff --git a/applications/serial_lte_modem/doc/slm_data_mode.rst b/applications/serial_lte_modem/doc/slm_data_mode.rst index 4edce71f427b..8b51e68e669e 100644 --- a/applications/serial_lte_modem/doc/slm_data_mode.rst +++ b/applications/serial_lte_modem/doc/slm_data_mode.rst @@ -54,6 +54,8 @@ To exit data mode, the MCU sends the termination command set by the ``CONFIG_SLM When instructed to exit data mode, the SLM application returns the AT command response ``OK``. +If the current sending function fails, the SLM application exits data mode and returns the AT command response ``ERROR``. + The SLM application also exits data mode automatically in the following scenarios: * The TCP server is stopped. diff --git a/applications/serial_lte_modem/src/ftp_c/slm_at_ftp.c b/applications/serial_lte_modem/src/ftp_c/slm_at_ftp.c index 6297868ba1f6..f22de669c4a4 100644 --- a/applications/serial_lte_modem/src/ftp_c/slm_at_ftp.c +++ b/applications/serial_lte_modem/src/ftp_c/slm_at_ftp.c @@ -139,7 +139,7 @@ void ftp_ctrl_callback(const uint8_t *msg, uint16_t len) sprintf(rsp_buf, "\r\n#XFTP: %d,\"disconnected\"\r\n", -ENOEXEC); break; } - if (ftp_data_mode_handler && exit_datamode(false)) { + if (ftp_data_mode_handler && exit_datamode(DATAMODE_EXIT_URC)) { ftp_data_mode_handler = NULL; } if (ftp_verbose_on) { @@ -466,7 +466,7 @@ static int ftp_put_handler(const uint8_t *data, int len) ret = ftp_put(filepath, data, len, FTP_PUT_NORMAL); } - if (exit_datamode(false)) { + if (exit_datamode(DATAMODE_EXIT_URC)) { ftp_data_mode_handler = NULL; } @@ -518,7 +518,7 @@ static int ftp_uput_handler(const uint8_t *data, int len) ret = ftp_put(NULL, data, len, FTP_PUT_UNIQUE); } - if (exit_datamode(false)) { + if (exit_datamode(DATAMODE_EXIT_URC)) { ftp_data_mode_handler = NULL; } diff --git a/applications/serial_lte_modem/src/gnss/slm_at_gnss.c b/applications/serial_lte_modem/src/gnss/slm_at_gnss.c index d44133afeda1..3c79b25928f1 100644 --- a/applications/serial_lte_modem/src/gnss/slm_at_gnss.c +++ b/applications/serial_lte_modem/src/gnss/slm_at_gnss.c @@ -640,7 +640,6 @@ int handle_at_agps(enum at_cmd_type cmd_type) */ run_type = RUN_TYPE_AGPS; err = nrf_modem_gnss_start(); - LOG_INF("[JUZO] nrf_modem_gnss_start %d", err); if (err) { LOG_ERR("Failed to start GNSS, error: %d", err); run_type = RUN_TYPE_NONE; diff --git a/applications/serial_lte_modem/src/http_c/slm_at_httpc.c b/applications/serial_lte_modem/src/http_c/slm_at_httpc.c index 7921ad720db2..6e5e279fa4ce 100644 --- a/applications/serial_lte_modem/src/http_c/slm_at_httpc.c +++ b/applications/serial_lte_modem/src/http_c/slm_at_httpc.c @@ -507,7 +507,7 @@ static void httpc_thread_fn(void *arg1, void *arg2, void *arg3) int err; err = do_http_request(); - (void)exit_datamode(false); + (void)exit_datamode(DATAMODE_EXIT_URC); if (err < 0) { LOG_ERR("do_http_request fail:%d", err); /* Disconnect from server */ diff --git a/applications/serial_lte_modem/src/slm_at_host.c b/applications/serial_lte_modem/src/slm_at_host.c index e3319f690903..965d25c834ca 100644 --- a/applications/serial_lte_modem/src/slm_at_host.c +++ b/applications/serial_lte_modem/src/slm_at_host.c @@ -164,7 +164,7 @@ bool in_datamode(void) return (slm_operation_mode == SLM_DATA_MODE); } -bool exit_datamode(bool response) +bool exit_datamode(int exit_mode) { if (slm_operation_mode == SLM_DATA_MODE) { ring_buf_reset(&data_rb); @@ -173,8 +173,10 @@ bool exit_datamode(bool response) k_sleep(K_MSEC(10)); (void)uart_receive(); - if (response) { + if (exit_mode == DATAMODE_EXIT_OK) { strcpy(rsp_buf, OK_STR); + } else if (exit_mode == DATAMODE_EXIT_ERROR) { + strcpy(rsp_buf, ERROR_STR); } else { sprintf(rsp_buf, "\r\n#XDATAMODE: 0\r\n"); } @@ -282,7 +284,7 @@ static void response_handler(void *context, const char *response) static void raw_send(struct k_work *work) { uint8_t *data = NULL; - uint32_t size_send, size_sent; + int size_send, size_sent; ARG_UNUSED(work); @@ -299,7 +301,13 @@ static void raw_send(struct k_work *work) } else if (size_sent == 0) { (void)ring_buf_get_finish(&data_rb, size_send); } else { - LOG_WRN("Raw send failed"); + LOG_WRN("Raw send failed, %d dropped", size_send); + (void)ring_buf_get_finish(&data_rb, size_send); + (void)exit_datamode(DATAMODE_EXIT_ERROR); + if (datamode_rx_disabled) { + /* UART RX already resumed */ + datamode_rx_disabled = false; + } break; } } else { @@ -347,7 +355,7 @@ static void silence_timer_handler(struct k_timer *timer) } else { LOG_WRN("missing datamode handler"); } - (void)exit_datamode(true); + (void)exit_datamode(DATAMODE_EXIT_OK); datamode_off_pending = false; } diff --git a/applications/serial_lte_modem/src/slm_at_host.h b/applications/serial_lte_modem/src/slm_at_host.h index fad67e9d1a34..e8c0c0a49d0f 100644 --- a/applications/serial_lte_modem/src/slm_at_host.h +++ b/applications/serial_lte_modem/src/slm_at_host.h @@ -20,11 +20,18 @@ #include "slm_defines.h" /**@brief Operations in datamode. */ -enum slm_datamode_operation_t { +enum slm_datamode_operation { DATAMODE_SEND, /* Send data in datamode */ DATAMODE_EXIT /* Exit data mode */ }; +/**@brief Exit modes in datamode. */ +enum slm_datamode_exit_mode { + DATAMODE_EXIT_OK, /* Exit datamode, send OK response */ + DATAMODE_EXIT_ERROR, /* Exit datamode, send ERROR response */ + DATAMODE_EXIT_URC /* Exit datamode, send URC notification */ +}; + /**@brief Data mode sending handler type. * * @retval 0 means all data is sent successfully. @@ -87,12 +94,12 @@ bool in_datamode(void); /** * @brief Request SLM AT host to exit data mode * - * @param response Whether to send "OK" response or not + * @param exit_mode Response type. Refer to enum slm_datamode_exit_mode. * * @retval true If normal exit from data mode. * false If not in data mode. */ -bool exit_datamode(bool response); +bool exit_datamode(int exit_mode); /** @} */ #endif /* SLM_AT_HOST_ */ diff --git a/applications/serial_lte_modem/src/slm_at_socket.c b/applications/serial_lte_modem/src/slm_at_socket.c index b420a28def69..f28cfddee45b 100644 --- a/applications/serial_lte_modem/src/slm_at_socket.c +++ b/applications/serial_lte_modem/src/slm_at_socket.c @@ -757,11 +757,11 @@ static int do_sendto(const char *url, uint16_t port, const uint8_t *data, int da sprintf(rsp_buf, "\r\n#XSENDTO: %d\r\n", offset); rsp_send(rsp_buf, strlen(rsp_buf)); + freeaddrinfo(res); if (ret >= 0) { return 0; } - freeaddrinfo(res); return ret; } diff --git a/applications/serial_lte_modem/src/slm_at_tcp_proxy.c b/applications/serial_lte_modem/src/slm_at_tcp_proxy.c index 06ee66896420..66c201ac2092 100644 --- a/applications/serial_lte_modem/src/slm_at_tcp_proxy.c +++ b/applications/serial_lte_modem/src/slm_at_tcp_proxy.c @@ -431,7 +431,7 @@ static int tcp_datamode_callback(uint8_t op, const uint8_t *data, int len) static void tcpsvr_terminate_connection(int cause) { if (in_datamode()) { - (void)exit_datamode(false); + (void)exit_datamode(DATAMODE_EXIT_URC); } if (proxy.sock_peer != INVALID_SOCKET) { close(proxy.sock_peer); @@ -520,7 +520,7 @@ static void tcpsvr_thread_func(void *p1, void *p2, void *p3) (void)inet_ntop(AF_INET6, &client.sin6_addr, peer_addr, sizeof(peer_addr)); } - if (fds[1].fd != INVALID_SOCKET) { + if (fds[1].fd >= 0) { LOG_WRN("Full. Close connection."); close(ret); goto client_events; @@ -657,7 +657,7 @@ static void tcpcli_thread_func(void *p1, void *p2, void *p3) } if (in_datamode()) { - (void)exit_datamode(false); + (void)exit_datamode(DATAMODE_EXIT_URC); } if (proxy.sock != INVALID_SOCKET) { (void)close(proxy.sock); From d34214d69056671a3d9184332c139f98edbebff0 Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Wed, 11 Aug 2021 19:42:26 +0200 Subject: [PATCH 076/126] zigbee: samples: Add application template sample Introduce a bare minimum sample that can be used as a starting point for custom Zigbee applications. Signed-off-by: Tomasz Chyrowicz --- doc/nrf/releases/release-notes-changelog.rst | 3 + samples/zigbee/template/CMakeLists.txt | 17 ++ samples/zigbee/template/README.rst | 95 +++++++ .../boards/nrf21540dk_nrf52840.overlay | 11 + .../boards/nrf52833dk_nrf52833.overlay | 11 + .../boards/nrf52840dk_nrf52840.overlay | 11 + .../boards/nrf5340dk_nrf5340_cpuapp.conf | 18 ++ samples/zigbee/template/prj.conf | 43 ++++ samples/zigbee/template/sample.yaml | 13 + samples/zigbee/template/src/main.c | 232 ++++++++++++++++++ 10 files changed, 454 insertions(+) create mode 100644 samples/zigbee/template/CMakeLists.txt create mode 100644 samples/zigbee/template/README.rst create mode 100644 samples/zigbee/template/boards/nrf21540dk_nrf52840.overlay create mode 100644 samples/zigbee/template/boards/nrf52833dk_nrf52833.overlay create mode 100644 samples/zigbee/template/boards/nrf52840dk_nrf52840.overlay create mode 100644 samples/zigbee/template/boards/nrf5340dk_nrf5340_cpuapp.conf create mode 100644 samples/zigbee/template/prj.conf create mode 100644 samples/zigbee/template/sample.yaml create mode 100644 samples/zigbee/template/src/main.c diff --git a/doc/nrf/releases/release-notes-changelog.rst b/doc/nrf/releases/release-notes-changelog.rst index b48ab0ee1fee..cee8f2dd198c 100644 --- a/doc/nrf/releases/release-notes-changelog.rst +++ b/doc/nrf/releases/release-notes-changelog.rst @@ -101,6 +101,9 @@ Zigbee * :ref:`lib_zigbee_zcl_scenes` library with documentation. This library was separated from the Zigbee light bulb sample. + * :ref:`zigbee_template_sample` sample. + This minimal Zigbee router application can be used as the starting point for developing custom Zigbee devices. + Common ====== diff --git a/samples/zigbee/template/CMakeLists.txt b/samples/zigbee/template/CMakeLists.txt new file mode 100644 index 000000000000..851fc1414ed0 --- /dev/null +++ b/samples/zigbee/template/CMakeLists.txt @@ -0,0 +1,17 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +cmake_minimum_required(VERSION 3.17.3) + +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) + +project("Zigbee application template") + +# NORDIC SDK APP START +target_sources(app PRIVATE + src/main.c +) +# NORDIC SDK APP END diff --git a/samples/zigbee/template/README.rst b/samples/zigbee/template/README.rst new file mode 100644 index 000000000000..6f17fa70e6fb --- /dev/null +++ b/samples/zigbee/template/README.rst @@ -0,0 +1,95 @@ +.. _zigbee_template_sample: + +Zigbee: Template +################ + +.. contents:: + :local: + :depth: 2 + +This :ref:`Zigbee ` sample is a minimal implementation of the Zigbee Router role. + +You can use this sample as the starting point for developing your own Zigbee device. + +Requirements +************ + +The sample supports the following development kits: + +.. table-from-rows:: /includes/sample_board_rows.txt + :header: heading + :rows: nrf52840dk_nrf52840, nrf52833dk_nrf52833, nrf5340dk_nrf5340_cpuapp, nrf21540dk_nrf52840 + +You can use one or more of the development kits listed above and mix different development kits. + +For this sample to work, the following samples also need to be programmed: + +* The :ref:`Zigbee network coordinator ` sample on one separate device. + +Overview +******** + +The Zigbee template sample takes the Zigbee Router role and implements two clusters (Basic and Identify) that used to be required by the Zigbee Home Automation profile. +The Basic cluster provides attributes and commands for determining basic information about the node. +The Identify cluster allows to put the device into the identification mode, which provides a way to locate the device. + +User interface +************** + +LED 3: + Turns on when the device joins the network. + +LED 4: + Blinks to indicate that the identification mode is on. + +Button 4: + Toggles the identification mode on the device. + +Building and running +******************** +.. |sample path| replace:: :file:`samples/zigbee/template` + +|enable_zigbee_before_testing| + +.. include:: /includes/build_and_run.txt + +.. _zigbee_application_template_testing: + +Testing +======= + +After programming the sample to your development kit, test it by performing the following steps: + +1. Turn on the development kit that runs the network coordinator sample. + When **LED 3** turns on, this development kit has become the Coordinator of the Zigbee network and the network is established. +#. Turn on the development kit that runs the template sample. + When **LED 3** turns on, the light bulb has become a Router inside the network. + + .. tip:: + If **LED 3** does not turn on, press **Button 1** on the Coordinator to reopen the network. + +The device running the template sample is now part of the Zigbee network as a Router. +As a result, the network range is extended by the template application radio range. + +Dependencies +************ + +This sample uses the following |NCS| libraries: + +* :file:`include/zigbee/zigbee_error_handler.h` +* :ref:`lib_zigbee_application_utilities` +* Zigbee subsystem: + + * :file:`zb_nrf_platform.h` + +* :ref:`dk_buttons_and_leds_readme` + +This sample uses the following `sdk-nrfxlib`_ libraries: + +* :ref:`nrfxlib:zboss` |zboss_version| (`API documentation`_) + +In addition, it uses the following Zephyr libraries: + +* :file:`include/zephyr.h` +* :file:`include/device.h` +* :ref:`zephyr:logging_api` diff --git a/samples/zigbee/template/boards/nrf21540dk_nrf52840.overlay b/samples/zigbee/template/boards/nrf21540dk_nrf52840.overlay new file mode 100644 index 000000000000..129fb915f3d3 --- /dev/null +++ b/samples/zigbee/template/boards/nrf21540dk_nrf52840.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + chosen { + zephyr,entropy = &rng; + }; +}; diff --git a/samples/zigbee/template/boards/nrf52833dk_nrf52833.overlay b/samples/zigbee/template/boards/nrf52833dk_nrf52833.overlay new file mode 100644 index 000000000000..129fb915f3d3 --- /dev/null +++ b/samples/zigbee/template/boards/nrf52833dk_nrf52833.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + chosen { + zephyr,entropy = &rng; + }; +}; diff --git a/samples/zigbee/template/boards/nrf52840dk_nrf52840.overlay b/samples/zigbee/template/boards/nrf52840dk_nrf52840.overlay new file mode 100644 index 000000000000..129fb915f3d3 --- /dev/null +++ b/samples/zigbee/template/boards/nrf52840dk_nrf52840.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + chosen { + zephyr,entropy = &rng; + }; +}; diff --git a/samples/zigbee/template/boards/nrf5340dk_nrf5340_cpuapp.conf b/samples/zigbee/template/boards/nrf5340dk_nrf5340_cpuapp.conf new file mode 100644 index 000000000000..67fefbb9fbad --- /dev/null +++ b/samples/zigbee/template/boards/nrf5340dk_nrf5340_cpuapp.conf @@ -0,0 +1,18 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_MAIN_STACK_SIZE=2048 + +# Use software cryptography on nRF5340 +CONFIG_CRYPTO=n +CONFIG_CRYPTO_NRF_ECB=n +CONFIG_TINYCRYPT=y +CONFIG_CTR_DRBG_CSPRNG_GENERATOR=y +CONFIG_ZIGBEE_USE_SOFTWARE_AES=y +CONFIG_ENTROPY_CC3XX=y + +# Networking +CONFIG_MPSL=n diff --git a/samples/zigbee/template/prj.conf b/samples/zigbee/template/prj.conf new file mode 100644 index 000000000000..71899eaf60a4 --- /dev/null +++ b/samples/zigbee/template/prj.conf @@ -0,0 +1,43 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_NCS_SAMPLES_DEFAULTS=y + +CONFIG_UART_INTERRUPT_DRIVEN=y +CONFIG_SERIAL=y +CONFIG_GPIO=y + +# Make sure printk is not printing to the UART console +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y + +CONFIG_HEAP_MEM_POOL_SIZE=2048 +CONFIG_MAIN_THREAD_PRIORITY=7 + +CONFIG_ZIGBEE=y +CONFIG_ZIGBEE_APP_UTILS=y +CONFIG_ZIGBEE_ROLE_ROUTER=y + +# Enable DK LED and Buttons library +CONFIG_DK_LIBRARY=y + +# This example requires more workqueue stack +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 + +# Enable nRF ECB driver +CONFIG_CRYPTO=y +CONFIG_CRYPTO_NRF_ECB=y +CONFIG_CRYPTO_INIT_PRIORITY=80 + +# Cryptocell is not supported through CSPRNG driver API: NCSDK-4813 +CONFIG_ENTROPY_CC3XX=n + +# Networking +CONFIG_NET_IPV6_MLD=n +CONFIG_NET_IPV6_NBR_CACHE=n +CONFIG_NET_IPV6_RA_RDNSS=n +CONFIG_NET_IP_ADDR_CHECK=n +CONFIG_NET_UDP=n diff --git a/samples/zigbee/template/sample.yaml b/samples/zigbee/template/sample.yaml new file mode 100644 index 000000000000..261217d1a29b --- /dev/null +++ b/samples/zigbee/template/sample.yaml @@ -0,0 +1,13 @@ +sample: + name: Zigbee application template + description: Zigbee application template +tests: + zigbee.template: + build_only: true + platform_allow: nrf52840dk_nrf52840 nrf52833dk_nrf52833 nrf5340dk_nrf5340_cpuapp nrf21540dk_nrf52840 + tags: ci_build smoke + integration_platforms: + - nrf52840dk_nrf52840 + - nrf52833dk_nrf52833 + - nrf5340dk_nrf5340_cpuapp + - nrf21540dk_nrf52840 diff --git a/samples/zigbee/template/src/main.c b/samples/zigbee/template/src/main.c new file mode 100644 index 000000000000..aba4161260d0 --- /dev/null +++ b/samples/zigbee/template/src/main.c @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/** @file + * + * @brief Zigbee application template. + */ + +#include +#include +#include + +#include +#include +#include +#include + + +/* Device endpoint, used to receive ZCL commands. */ +#define APP_TEMPLATE_ENDPOINT 10 + +/* Type of power sources available for the device. + * For possible values see section 3.2.2.2.8 of ZCL specification. + */ +#define BULB_INIT_BASIC_POWER_SOURCE ZB_ZCL_BASIC_POWER_SOURCE_DC_SOURCE + +/* LED indicating that device successfully joined Zigbee network. */ +#define ZIGBEE_NETWORK_STATE_LED DK_LED3 + +/* LED used for device identification. */ +#define IDENTIFY_LED DK_LED4 + +/* Button used to enter the Identify mode. */ +#define IDENTIFY_MODE_BUTTON DK_BTN4_MSK + + +LOG_MODULE_REGISTER(app); + +/* Main application customizable context. + * Stores all settings and static values. + */ +struct zb_device_ctx { + zb_zcl_basic_attrs_t basic_attr; + zb_zcl_identify_attrs_t identify_attr; +}; + +/* Zigbee device application context storage. */ +static struct zb_device_ctx dev_ctx; + +ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST( + identify_attr_list, + &dev_ctx.identify_attr.identify_time); + +ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST( + basic_attr_list, + &dev_ctx.basic_attr.zcl_version, + &dev_ctx.basic_attr.power_source); + +ZB_HA_DECLARE_RANGE_EXTENDER_CLUSTER_LIST( + app_template_clusters, + identify_attr_list, + basic_attr_list); + +ZB_HA_DECLARE_RANGE_EXTENDER_EP( + app_template_ep, + APP_TEMPLATE_ENDPOINT, + app_template_clusters); + +ZBOSS_DECLARE_DEVICE_CTX_1_EP( + app_template_ctx, + app_template_ep); + + +/**@brief Function for initializing all clusters attributes. */ +static void app_clusters_attr_init(void) +{ + /* Basic cluster attributes data */ + dev_ctx.basic_attr.zcl_version = ZB_ZCL_VERSION; + dev_ctx.basic_attr.power_source = BULB_INIT_BASIC_POWER_SOURCE; + + /* Identify cluster attributes data. */ + dev_ctx.identify_attr.identify_time = + ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE; +} + +/**@brief Function to toggle the identify LED + * + * @param bufid Unused parameter, required by ZBOSS scheduler API. + */ +static void toggle_identify_led(zb_bufid_t bufid) +{ + static int blink_status; + + dk_set_led(IDENTIFY_LED, (++blink_status) % 2); + ZB_SCHEDULE_APP_ALARM(toggle_identify_led, bufid, ZB_MILLISECONDS_TO_BEACON_INTERVAL(100)); +} + +/**@brief Function to handle identify notification events on the first endpoint. + * + * @param bufid Unused parameter, required by ZBOSS scheduler API. + */ +static void identify_cb(zb_bufid_t bufid) +{ + zb_ret_t zb_err_code; + + if (bufid) { + /* Schedule a self-scheduling function that will toggle the LED */ + ZB_SCHEDULE_APP_CALLBACK(toggle_identify_led, bufid); + } else { + /* Cancel the toggling function alarm and turn off LED */ + zb_err_code = ZB_SCHEDULE_APP_ALARM_CANCEL(toggle_identify_led, ZB_ALARM_ANY_PARAM); + ZVUNUSED(zb_err_code); + + dk_set_led(IDENTIFY_LED, 0); + } +} + +/**@breif Starts identifying the device. + * + * @param bufid Unused parameter, required by ZBOSS scheduler API. + */ +static void start_identifying(zb_bufid_t bufid) +{ + zb_ret_t zb_err_code; + + ZVUNUSED(bufid); + + /* Check if endpoint is in identifying mode, + * if not put desired endpoint in identifying mode. + */ + if (dev_ctx.identify_attr.identify_time == + ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE) { + LOG_INF("Enter identify mode"); + zb_err_code = zb_bdb_finding_binding_target( + APP_TEMPLATE_ENDPOINT); + ZB_ERROR_CHECK(zb_err_code); + } else { + LOG_INF("Cancel identify mode"); + zb_bdb_finding_binding_target_cancel(); + } +} + +/**@brief Callback for button events. + * + * @param[in] button_state Bitmask containing buttons state. + * @param[in] has_changed Bitmask containing buttons + * that have changed their state. + */ +static void button_changed(uint32_t button_state, uint32_t has_changed) +{ + /* Calculate bitmask of buttons that are pressed + * and have changed their state. + */ + uint32_t buttons = button_state & has_changed; + + if (buttons & IDENTIFY_MODE_BUTTON) { + ZB_SCHEDULE_APP_CALLBACK(start_identifying, 0); + } +} + +/**@brief Function for initializing LEDs and Buttons. */ +static void configure_gpio(void) +{ + int err; + + err = dk_buttons_init(button_changed); + if (err) { + LOG_ERR("Cannot init buttons (err: %d)", err); + } + + err = dk_leds_init(); + if (err) { + LOG_ERR("Cannot init LEDs (err: %d)", err); + } +} + +/**@brief Zigbee stack event handler. + * + * @param[in] bufid Reference to the Zigbee stack buffer + * used to pass signal. + */ +void zboss_signal_handler(zb_bufid_t bufid) +{ + /* Update network status LED. */ + zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED); + + /* No application-specific behavior is required. + * Call default signal handler. + */ + ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid)); + + /* All callbacks should either reuse or free passed buffers. + * If bufid == 0, the buffer is invalid (not passed). + */ + if (bufid) { + zb_buf_free(bufid); + } +} + +void error(void) +{ + dk_set_leds_state(DK_ALL_LEDS_MSK, DK_NO_LEDS_MSK); + + while (true) { + /* Spin forever */ + k_sleep(K_MSEC(1000)); + } +} + +void main(void) +{ + LOG_INF("Starting Zigbee application template example"); + + /* Initialize */ + configure_gpio(); + + /* Register device context (endpoints). */ + ZB_AF_REGISTER_DEVICE_CTX(&app_template_ctx); + + app_clusters_attr_init(); + + /* Register handlers to identify notifications */ + ZB_AF_SET_IDENTIFY_NOTIFICATION_HANDLER(APP_TEMPLATE_ENDPOINT, identify_cb); + + /* Start Zigbee default thread */ + zigbee_enable(); + + LOG_INF("Zigbee application template started"); +} From 98f397db81d2cff2d551e12f2faa8a8de5398eda Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Wed, 30 Jun 2021 14:19:02 +0200 Subject: [PATCH 077/126] zigbee: Reduce ZBOSS timer unit conversion errors Since the upper layer divides the sleep time by beacon intervals, if the ceiling operation works on milliseconds, it does not have a desired effect on the timer value calculation. Signed-off-by: Tomasz Chyrowicz --- subsys/zigbee/osif/zb_nrf_pwr_mgmt.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/subsys/zigbee/osif/zb_nrf_pwr_mgmt.c b/subsys/zigbee/osif/zb_nrf_pwr_mgmt.c index bf3e99191a05..78d5d3052d58 100644 --- a/subsys/zigbee/osif/zb_nrf_pwr_mgmt.c +++ b/subsys/zigbee/osif/zb_nrf_pwr_mgmt.c @@ -68,10 +68,11 @@ __weak zb_uint32_t zb_osif_sleep(zb_uint32_t sleep_tmo) time_slept_us = zigbee_event_poll(sleep_tmo * USEC_PER_MSEC); /* Calculate sleep duration in milliseconds. Round up the result - * to avoid possible errors in the event of - * another time unit conversion. + * using the basic time unit of ZBOSS API to avoid possible errors + * in the time unit conversion. */ - time_slept_ms = ceiling_fraction(time_slept_us, USEC_PER_MSEC); + time_slept_ms = ZB_TIME_BEACON_INTERVAL_TO_MSEC( + ceiling_fraction(time_slept_us, ZB_BEACON_INTERVAL_USEC)); /* Unlock timer value updates. */ ZVUNUSED(atomic_set((atomic_t *)&is_sleeping, 0)); From 8c10e9ba1d275f885c7dd6b0c046906bfb24eaf0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 26 Jul 2021 11:07:01 -0700 Subject: [PATCH 078/126] west.yml: sort zephyr name-allowlist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This list is not sorted; fix it. (I'm putting uppercase first as that's the "ASCIIbetical" order.) Signed-off-by: Martí Bolívar --- west.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/west.yml b/west.yml index 114859bed5b0..d077b4f15804 100644 --- a/west.yml +++ b/west.yml @@ -70,9 +70,10 @@ manifest: # # Please keep this list sorted alphabetically. name-allowlist: + - TraceRecorderSource - canopennode - - cmsis - civetweb + - cmsis - edtt - fatfs - hal_nordic @@ -91,7 +92,6 @@ manifest: - segger - tinycbor - tinycrypt - - TraceRecorderSource # NCS repositories. # From 6cead9dd65183e7b1302b97330668f8eec7bba3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 26 Jul 2021 11:20:39 -0700 Subject: [PATCH 079/126] scripts: west: improve ncs-compare heuristic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 'west ncs-compare' extension command, among other things, will print a list of patches that have been merged upstream which look like they may have been taken as out of tree (OOT) patches downstream. It currently does this by comparing shortlogs between unmerged upstream commits and OOT downstream commits. If the edit distance between a pair of these commits is below a configurable threshold, the heuristic considers them potentially the same commit. This doesn't work with restrictions that were introduced in NCS since the tool was originally merged. Specifically, we now have sdk-zephyr linting that limits the commit shortlog length. That has led to people truncating upstream shortlogs that are too long to add the [nrf xyz] sauce tag prefixes to. Handle this case better by also checking for downstream commits that have shortlogs which are prefixes of an upstream shortlog. This will probably decrease the SNR of the command output for shortlogs which are small, but that seems worth it to avoid missing some commits. Signed-off-by: Martí Bolívar --- scripts/west_commands/ncs_west_helpers.py | 48 +++++++++++++++++++---- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/scripts/west_commands/ncs_west_helpers.py b/scripts/west_commands/ncs_west_helpers.py index f9163de9ae19..7f1c428e1154 100644 --- a/scripts/west_commands/ncs_west_helpers.py +++ b/scripts/west_commands/ncs_west_helpers.py @@ -237,11 +237,39 @@ def _downstream_outstanding_commits(self): def _likely_merged_commits(self): # Compute patches which are downstream and probably were - # merged upstream, using a shortlog edit distance heuristic. - # This is a map from pygit2 commit objects for downstream - # patches, to a list of pygit2 commit objects that are - # upstream patches which have similar shortlogs and the same - # authors. + # merged upstream, using the following heuristics: + # + # 1. downstream patches with small shortlog edit distances + # from upstream patches + # + # 2. downstream patches with shortlogs that are prefixes of + # upstream patches + # + # Heuristic #1 catches patches with typos in the shortlogs + # that reviewers asked to be fixed, etc. E.g. upstream + # shortlog + # + # Bluetoth: do foo + # + # matches downstream shortlog + # + # [nrf fromlist] Bluetooth: do foo + # + # Heuristic #2 catches situations where we had to shorten our + # downstream shortlog to fit the "[nrf xyz]" sauce tag at the + # beginning and still fit within CI's shortlog length + # restrictions. E.g. upstream shortlog + # + # subsys: do a thing that is very useful for everyone + # + # matches downstream shortlog + # + # [nrf fromlist] subsys: do a thing that is very + # + # The return value is a map from pygit2 commit objects for + # downstream patches, to a list of pygit2 commit objects that + # are upstream patches which have similar shortlogs and the + # same authors. likely_merged = OrderedDict() for dc in self.downstream_outstanding: @@ -252,8 +280,14 @@ def ed(upstream_commit): shortlog_no_sauce(sl, self._downstream_sauce), commit_shortlog(upstream_commit)) - matches = [c for c in self.upstream_new if - ed(c) < self._edit_dist_threshold] + matches = [ + uc for uc in self.upstream_new if + # Heuristic #1: + ed(uc) < self._edit_dist_threshold or + # Heuristic #2: + commit_shortlog(uc).startswith(sl) + ] + if len(matches) != 0: likely_merged[dc] = matches From 4d4601f74386e0691d9f705c82f598df352ed63c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 26 Jul 2021 11:01:13 -0700 Subject: [PATCH 080/126] scripts: west: zephyr uses 'main' branch now MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Our downstream scripts are comparing against zephyr's 'master' branch, but that is no longer actively used. Switch to 'main' to keep up with upstream. Signed-off-by: Martí Bolívar --- scripts/west_commands/ncs_commands.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/west_commands/ncs_commands.py b/scripts/west_commands/ncs_commands.py index 2b7f50b0bcb9..37397a8e14ee 100644 --- a/scripts/west_commands/ncs_commands.py +++ b/scripts/west_commands/ncs_commands.py @@ -28,7 +28,7 @@ def add_zephyr_rev_arg(parser): parser.add_argument('-z', '--zephyr-rev', metavar='REF', help='''zephyr git ref (commit, branch, etc.); - default: upstream/master''') + default: upstream/main''') def add_projects_arg(parser): parser.add_argument('projects', metavar='PROJECT', nargs='*', @@ -142,7 +142,7 @@ def validate_zephyr_rev(self, args): if args.zephyr_rev: zephyr_rev = args.zephyr_rev else: - zephyr_rev = 'upstream/master' + zephyr_rev = 'upstream/main' zephyr_project = self.manifest.get_projects(['zephyr'])[0] try: self.zephyr_sha = zephyr_project.sha(zephyr_rev) From 1baa67770fb7b2b8ca860b64085b5822fa642ba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 27 Jul 2021 10:25:52 -0700 Subject: [PATCH 081/126] scripts: west: output tweaks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve output on 80 column terminals. Signed-off-by: Martí Bolívar --- scripts/west_commands/ncs_commands.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/west_commands/ncs_commands.py b/scripts/west_commands/ncs_commands.py index 37397a8e14ee..475f332ba00d 100644 --- a/scripts/west_commands/ncs_commands.py +++ b/scripts/west_commands/ncs_commands.py @@ -262,7 +262,8 @@ def print_loot(self, name, project, z_project, args, json_data): return log.banner(name_path) - log.inf(f'NCS commit (manifest-rev): {nsha}, upstream commit: {zsha}') + log.inf(f' NCS commit: {nsha}\n' + f'upstream commit: {zsha}') log.inf('OOT patches: ' + (f'{len(loot)} total' if loot else 'none') + (', output limited by --file' if args.files else '')) @@ -442,7 +443,8 @@ def allowed_project(self, zp): else: status = f'diverged: {ahead} ahead, {behind} behind' - commits = f'NCS commit: {nsha}, upstream commit: {zsha}' + commits = (f' NCS commit: {nsha}\n' + f'upstream commit: {zsha}') if 'up to date' in status or 'ahead by' in status: if log.VERBOSE > log.VERBOSE_NONE: # Up to date or ahead: only print in verbose mode. From d3aed0bb3f33dc2714b34350485a5cb9358dff90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 27 Jul 2021 14:17:34 -0700 Subject: [PATCH 082/126] scripts: west_commands: refactor for readability MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improve some variable names. Signed-off-by: Martí Bolívar --- scripts/west_commands/ncs_commands.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/west_commands/ncs_commands.py b/scripts/west_commands/ncs_commands.py index 475f332ba00d..7768c8a8b9c1 100644 --- a/scripts/west_commands/ncs_commands.py +++ b/scripts/west_commands/ncs_commands.py @@ -320,14 +320,14 @@ def do_run(self, args, unknown_args): # Get a dict containing projects that are in the NCS which are # *not* imported from Zephyr in nrf/west.yml. We will treat # these specially to make the output easier to understand. - ignored_imports = Manifest.from_file( - import_flags=ImportFlag.IGNORE_PROJECTS) - in_nrf = set(p.name for p in - ignored_imports.projects[MANIFEST_PROJECT_INDEX + 1:]) + ncs_only = Manifest.from_file(import_flags=ImportFlag.IGNORE_PROJECTS) + ncs_only_projects = ncs_only.projects[MANIFEST_PROJECT_INDEX + 1:] + ncs_only_names = set(p.name for p in ncs_only_projects) # This is a dict mapping names of projects which *are* imported # from zephyr to the Project instances. - self.imported_pmap = {name: project for name, project in - self.ncs_pmap.items() if name not in in_nrf} + self.imported_pmap = {name: project + for name, project in self.ncs_pmap.items() + if name not in ncs_only_names} log.inf('Comparing your manifest-rev branches with zephyr/west.yml ' f'at {self.zephyr_rev}' + From a7393257f5812516f77903fd3f6be049a9369872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 27 Jul 2021 16:10:30 -0700 Subject: [PATCH 083/126] scripts: west: extend west ncs-loot json output MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the project path, NCS sha, and upstream SHA as well. This information is present in the human readable output but not the JSON output. It is now going to be as useful to scripts as humans, so add it in. Signed-off-by: Martí Bolívar --- scripts/west_commands/ncs_commands.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/west_commands/ncs_commands.py b/scripts/west_commands/ncs_commands.py index 7768c8a8b9c1..9ab446644ecc 100644 --- a/scripts/west_commands/ncs_commands.py +++ b/scripts/west_commands/ncs_commands.py @@ -289,6 +289,9 @@ def print_loot(self, name, project, z_project, args, json_data): if args.json: json_data[name] = { + 'path': project.path, + 'ncs-commit': nsha, + 'upstream-commit': zsha, 'shas': json_sha_list, 'shortlogs': json_shortlog_list, } From 60588e7a51ed1427b0c2e8885a486dcd5c6c6867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 26 Jul 2021 11:08:29 -0700 Subject: [PATCH 084/126] treewide: synchronize imported OSS repositories MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - mcuboot: update to zephyrproject-rtos commit 7a5196820ba48a6ad7e7d573c9048c021960677c - zephyr: update to zephyrproject-rtos commit 14f09a3b00d49a453e9c3ecfa6c524bdd59679a9 - add lz4 to allowlist, integrating the lossless compression algorithm with the same name - add nanopb to allowlist, removing the NCS-only metadata (this pulls in over 100 patches since nanopb 0.4.2) - trusted-firmware-m: update to zephyrproject-rtos commit e18b7a9b040b5b5324520388047c9e7d678447e6 - block telink HAL in ncs_commands.py Signed-off-by: Martí Bolívar --- scripts/west_commands/ncs_commands.py | 1 + west.yml | 14 +++++--------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/scripts/west_commands/ncs_commands.py b/scripts/west_commands/ncs_commands.py index 9ab446644ecc..5827e37424c9 100644 --- a/scripts/west_commands/ncs_commands.py +++ b/scripts/west_commands/ncs_commands.py @@ -490,6 +490,7 @@ def _name_and_path(project): 'modules/hal/quicklogic', 'modules/hal/silabs', 'modules/hal/stm32', + 'modules/hal/telink', 'modules/hal/ti', 'modules/hal/xtensa', 'modules/lib/tensorflow', diff --git a/west.yml b/west.yml index d077b4f15804..1197ae2ff1a6 100644 --- a/west.yml +++ b/west.yml @@ -27,8 +27,6 @@ manifest: url-base: https://github.com/ThrowTheSwitch - name: armmbed url-base: https://github.com/ARMmbed - - name: nanopb - url-base: https://github.com/nanopb - name: alexa url-base: https://github.com/alexa - name: nordicsemi @@ -56,7 +54,7 @@ manifest: # https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/modules.html - name: zephyr repo-path: sdk-zephyr - revision: 0944459b5b622048a08ad1f8cf8a044c135fd0d3 + revision: 01a38e7fa55913350c647df1f51715fea5d80daa import: # In addition to the zephyr repository itself, NCS also # imports the contents of zephyr/west.yml at the above @@ -82,9 +80,11 @@ manifest: - littlefs - loramac-node - lvgl + - lz4 - mbedtls - mcumgr - mipi-sys-t + - nanopb - net-tools - nrf_hw_models - open-amp @@ -99,7 +99,7 @@ manifest: # changes. - name: mcuboot repo-path: sdk-mcuboot - revision: 5a6bf2fa11503ea0a3ef2b42a8afeed43053b6b9 + revision: 274ff833dabea621483cafa3e5aede9a9bf11b9e path: bootloader/mcuboot - name: nrfxlib repo-path: sdk-nrfxlib @@ -108,7 +108,7 @@ manifest: - name: trusted-firmware-m repo-path: sdk-trusted-firmware-m path: modules/tee/tfm - revision: v1.3.99-ncs1 + revision: 52a2fbefe02da485f4c6103d40a86b3a529cbd8e - name: tfm-mcuboot # This is used by the trusted-firmware-m module. repo-path: sdk-mcuboot path: modules/tee/tfm-mcuboot @@ -148,10 +148,6 @@ manifest: repo-path: mbedtls revision: mbedtls-2.26.0 remote: armmbed - - name: nanopb - path: modules/lib/nanopb - revision: nanopb-0.4.2 - remote: nanopb - name: Alexa-Gadgets-Embedded-Sample-Code path: modules/alexa-embedded revision: face92d8c62184832793f518bb1f19379538c5c1 From f5947aaaf8d251255a7afffbdde7a8aadb7940b2 Mon Sep 17 00:00:00 2001 From: Trond Einar Snekvik Date: Tue, 27 Jul 2021 12:56:02 +0200 Subject: [PATCH 085/126] Bluetooth: Mesh: Adjust to new opcode handler API The message opcode handler definition changed in zephyrproject-rtos/zephyr#34606, adding a return code to the callbacks and allowing exact and minimal length matches for the len field. Update all mesh models to use the new opcode handler format, including adding return codes and using the new BT_MESH_LEN_ macros for the length definition. Signed-off-by: Trond Einar Snekvik --- include/bluetooth/mesh/light_ctrl.h | 13 ++ samples/bluetooth/mesh/chat/src/chat_cli.c | 41 ++-- subsys/bluetooth/mesh/gen_battery_cli.c | 15 +- subsys/bluetooth/mesh/gen_battery_srv.c | 10 +- subsys/bluetooth/mesh/gen_dtt_cli.c | 17 +- subsys/bluetooth/mesh/gen_dtt_srv.c | 51 +++-- subsys/bluetooth/mesh/gen_loc_cli.c | 26 +-- subsys/bluetooth/mesh/gen_loc_srv.c | 68 +++--- subsys/bluetooth/mesh/gen_lvl_cli.c | 12 +- subsys/bluetooth/mesh/gen_lvl_srv.c | 83 ++++--- subsys/bluetooth/mesh/gen_onoff_cli.c | 17 +- subsys/bluetooth/mesh/gen_onoff_srv.c | 37 ++- subsys/bluetooth/mesh/gen_plvl_cli.c | 50 ++-- subsys/bluetooth/mesh/gen_plvl_srv.c | 144 ++++++------ subsys/bluetooth/mesh/gen_ponoff_cli.c | 15 +- subsys/bluetooth/mesh/gen_ponoff_srv.c | 46 ++-- subsys/bluetooth/mesh/gen_prop_cli.c | 75 +++--- subsys/bluetooth/mesh/gen_prop_srv.c | 165 +++++++------- subsys/bluetooth/mesh/light_ctl_cli.c | 66 +++--- subsys/bluetooth/mesh/light_ctl_srv.c | 119 ++++------ subsys/bluetooth/mesh/light_ctrl_cli.c | 60 +++-- subsys/bluetooth/mesh/light_ctrl_srv.c | 213 +++++++++--------- subsys/bluetooth/mesh/light_hsl_cli.c | 80 +++---- subsys/bluetooth/mesh/light_hsl_srv.c | 147 ++++++------ subsys/bluetooth/mesh/light_hue_srv.c | 47 ++-- subsys/bluetooth/mesh/light_sat_srv.c | 36 +-- subsys/bluetooth/mesh/light_temp_srv.c | 36 +-- subsys/bluetooth/mesh/light_xyl_cli.c | 54 ++--- subsys/bluetooth/mesh/light_xyl_srv.c | 136 +++++------ subsys/bluetooth/mesh/lightness_cli.c | 65 +++--- subsys/bluetooth/mesh/lightness_srv.c | 176 ++++++--------- subsys/bluetooth/mesh/scene_cli.c | 24 +- subsys/bluetooth/mesh/scene_srv.c | 106 +++++---- subsys/bluetooth/mesh/scheduler_cli.c | 28 ++- subsys/bluetooth/mesh/scheduler_srv.c | 49 ++-- subsys/bluetooth/mesh/sensor_cli.c | 99 ++++---- subsys/bluetooth/mesh/sensor_srv.c | 197 +++++++++------- subsys/bluetooth/mesh/time_cli.c | 55 ++--- subsys/bluetooth/mesh/time_srv.c | 88 ++++---- .../bluetooth/mesh/vnd/silvair_enocean_srv.c | 50 ++-- 40 files changed, 1383 insertions(+), 1433 deletions(-) diff --git a/include/bluetooth/mesh/light_ctrl.h b/include/bluetooth/mesh/light_ctrl.h index 2f603fd846d0..9203453061c7 100644 --- a/include/bluetooth/mesh/light_ctrl.h +++ b/include/bluetooth/mesh/light_ctrl.h @@ -202,6 +202,19 @@ enum bt_mesh_light_ctrl_coeff { #define BT_MESH_LIGHT_CTRL_OP_PROP_SET_UNACK BT_MESH_MODEL_OP_1(0x63) #define BT_MESH_LIGHT_CTRL_OP_PROP_STATUS BT_MESH_MODEL_OP_1(0x64) +#define BT_MESH_LIGHT_CTRL_MSG_LEN_MODE_GET 0 +#define BT_MESH_LIGHT_CTRL_MSG_LEN_MODE_SET 1 +#define BT_MESH_LIGHT_CTRL_MSG_LEN_MODE_STATUS 1 +#define BT_MESH_LIGHT_CTRL_MSG_LEN_OM_GET 0 +#define BT_MESH_LIGHT_CTRL_MSG_LEN_OM_SET 1 +#define BT_MESH_LIGHT_CTRL_MSG_LEN_OM_STATUS 1 +#define BT_MESH_LIGHT_CTRL_MSG_LEN_LIGHT_ONOFF_GET 0 +#define BT_MESH_LIGHT_CTRL_MSG_MINLEN_LIGHT_ONOFF_SET 2 +#define BT_MESH_LIGHT_CTRL_MSG_MINLEN_LIGHT_ONOFF_STATUS 1 +#define BT_MESH_LIGHT_CTRL_MSG_LEN_PROP_GET 2 +#define BT_MESH_LIGHT_CTRL_MSG_MINLEN_PROP_SET 2 +#define BT_MESH_LIGHT_CTRL_MSG_MINLEN_PROP_STATUS 2 + #if CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG #define BT_MESH_LIGHT_CTRL_SRV_REG_CFG_INIT \ { \ diff --git a/samples/bluetooth/mesh/chat/src/chat_cli.c b/samples/bluetooth/mesh/chat/src/chat_cli.c index 61fad2525f97..6d3c2fef3607 100644 --- a/samples/bluetooth/mesh/chat/src/chat_cli.c +++ b/samples/bluetooth/mesh/chat/src/chat_cli.c @@ -35,9 +35,8 @@ static const uint8_t *extract_msg(struct net_buf_simple *buf) return net_buf_simple_pull_mem(buf, buf->len); } -static void handle_message(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_message(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_chat_cli *chat = model->user_data; const uint8_t *msg; @@ -47,6 +46,8 @@ static void handle_message(struct bt_mesh_model *model, if (chat->handlers->message) { chat->handlers->message(chat, ctx, msg); } + + return 0; } /* .. include_startingpoint_chat_cli_rst_1 */ @@ -60,7 +61,7 @@ static void send_message_reply(struct bt_mesh_chat_cli *chat, (void)bt_mesh_model_send(chat->model, ctx, &msg, NULL, NULL); } -static void handle_private_message(struct bt_mesh_model *model, +static int handle_private_message(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -74,23 +75,24 @@ static void handle_private_message(struct bt_mesh_model *model, } send_message_reply(chat, ctx); + return 0; } /* .. include_endpoint_chat_cli_rst_1 */ -static void handle_message_reply(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_message_reply(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_chat_cli *chat = model->user_data; if (chat->handlers->message_reply) { chat->handlers->message_reply(chat, ctx); } + + return 0; } -static void handle_presence(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_presence(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_chat_cli *chat = model->user_data; enum bt_mesh_chat_cli_presence presence; @@ -100,11 +102,12 @@ static void handle_presence(struct bt_mesh_model *model, if (chat->handlers->presence) { chat->handlers->presence(chat, ctx, presence); } + + return 0; } -static void handle_presence_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_presence_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_chat_cli *chat = model->user_data; @@ -114,33 +117,35 @@ static void handle_presence_get(struct bt_mesh_model *model, encode_presence(&msg, chat->presence); (void) bt_mesh_model_send(chat->model, ctx, &msg, NULL, NULL); + + return 0; } /* .. include_startingpoint_chat_cli_rst_2 */ const struct bt_mesh_model_op _bt_mesh_chat_cli_op[] = { { BT_MESH_CHAT_CLI_OP_MESSAGE, - BT_MESH_CHAT_CLI_MSG_MINLEN_MESSAGE, + BT_MESH_LEN_MIN(BT_MESH_CHAT_CLI_MSG_MINLEN_MESSAGE), handle_message }, { BT_MESH_CHAT_CLI_OP_PRIVATE_MESSAGE, - BT_MESH_CHAT_CLI_MSG_MINLEN_MESSAGE, + BT_MESH_LEN_MIN(BT_MESH_CHAT_CLI_MSG_MINLEN_MESSAGE), handle_private_message }, { BT_MESH_CHAT_CLI_OP_MESSAGE_REPLY, - BT_MESH_CHAT_CLI_MSG_LEN_MESSAGE_REPLY, + BT_MESH_LEN_EXACT(BT_MESH_CHAT_CLI_MSG_LEN_MESSAGE_REPLY), handle_message_reply }, { BT_MESH_CHAT_CLI_OP_PRESENCE, - BT_MESH_CHAT_CLI_MSG_LEN_PRESENCE, + BT_MESH_LEN_EXACT(BT_MESH_CHAT_CLI_MSG_LEN_PRESENCE), handle_presence }, { BT_MESH_CHAT_CLI_OP_PRESENCE_GET, - BT_MESH_CHAT_CLI_MSG_LEN_PRESENCE_GET, + BT_MESH_LEN_EXACT(BT_MESH_CHAT_CLI_MSG_LEN_PRESENCE_GET), handle_presence_get }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_battery_cli.c b/subsys/bluetooth/mesh/gen_battery_cli.c index d535f770a150..6afdf7cdaf68 100644 --- a/subsys/bluetooth/mesh/gen_battery_cli.c +++ b/subsys/bluetooth/mesh/gen_battery_cli.c @@ -43,16 +43,17 @@ int bt_mesh_gen_bat_decode_status(struct net_buf_simple *buf, return 0; } -static void handle_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_battery_cli *cli = model->user_data; struct bt_mesh_battery_status status; struct bt_mesh_battery_status *rsp; + int err; - if (bt_mesh_gen_bat_decode_status(buf, &status)) { - return; + err = bt_mesh_gen_bat_decode_status(buf, &status); + if (err) { + return err; } if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_BATTERY_OP_STATUS, ctx->addr, @@ -64,12 +65,14 @@ static void handle_status(struct bt_mesh_model *model, if (cli->status_handler) { cli->status_handler(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_battery_cli_op[] = { { BT_MESH_BATTERY_OP_STATUS, - BT_MESH_BATTERY_MSG_LEN_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_BATTERY_MSG_LEN_STATUS), handle_status, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_battery_srv.c b/subsys/bluetooth/mesh/gen_battery_srv.c index 1d00f1308cf8..693d59fcf76b 100644 --- a/subsys/bluetooth/mesh/gen_battery_srv.c +++ b/subsys/bluetooth/mesh/gen_battery_srv.c @@ -58,7 +58,7 @@ static void rsp_status(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_battery_srv *srv = model->user_data; @@ -67,10 +67,16 @@ static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, srv->get(srv, ctx, &status); rsp_status(model, ctx, &status); + + return 0; } const struct bt_mesh_model_op _bt_mesh_battery_srv_op[] = { - { BT_MESH_BATTERY_OP_GET, BT_MESH_BATTERY_MSG_LEN_GET, handle_get }, + { + BT_MESH_BATTERY_OP_GET, + BT_MESH_LEN_EXACT(BT_MESH_BATTERY_MSG_LEN_GET), + handle_get, + }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/gen_dtt_cli.c b/subsys/bluetooth/mesh/gen_dtt_cli.c index f06411df6ee4..a34e49059634 100644 --- a/subsys/bluetooth/mesh/gen_dtt_cli.c +++ b/subsys/bluetooth/mesh/gen_dtt_cli.c @@ -7,14 +7,9 @@ #include #include "model_utils.h" -static void handle_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_DTT_MSG_LEN_STATUS) { - return; - } - struct bt_mesh_dtt_cli *cli = model->user_data; int32_t transition_time = model_transition_decode(net_buf_simple_pull_u8(buf)); @@ -29,10 +24,16 @@ static void handle_status(struct bt_mesh_model *model, if (cli->status_handler) { cli->status_handler(cli, ctx, transition_time); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_dtt_cli_op[] = { - { BT_MESH_DTT_OP_STATUS, BT_MESH_DTT_MSG_LEN_STATUS, handle_status }, + { + BT_MESH_DTT_OP_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_DTT_MSG_LEN_STATUS), + handle_status, + }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/gen_dtt_srv.c b/subsys/bluetooth/mesh/gen_dtt_srv.c index 36a913cb8d08..dfc6e5ecd83a 100644 --- a/subsys/bluetooth/mesh/gen_dtt_srv.c +++ b/subsys/bluetooth/mesh/gen_dtt_srv.c @@ -24,32 +24,26 @@ static void rsp_status(struct bt_mesh_dtt_srv *srv, (void)bt_mesh_model_send(srv->model, rx_ctx, &msg, NULL, NULL); } -static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_DTT_MSG_LEN_GET) { - return; - } - struct bt_mesh_dtt_srv *srv = model->user_data; rsp_status(srv, ctx); + + return 0; } -static void set_dtt(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int set_dtt(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_DTT_MSG_LEN_SET) { - return; - } - struct bt_mesh_dtt_srv *srv = model->user_data; uint32_t old_time = srv->transition_time; uint32_t new_time = model_transition_decode(net_buf_simple_pull_u8(buf)); if (new_time == SYS_FOREVER_MS) { /* Invalid parameter */ - return; + return -EINVAL; } srv->transition_time = new_time; @@ -69,25 +63,38 @@ static void set_dtt(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, } (void)bt_mesh_dtt_srv_pub(srv, NULL); + + return 0; } -static void handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_dtt(model, ctx, buf, true); + return set_dtt(model, ctx, buf, true); } -static void handle_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_dtt(model, ctx, buf, false); + return set_dtt(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_dtt_srv_op[] = { - { BT_MESH_DTT_OP_GET, BT_MESH_DTT_MSG_LEN_GET, handle_get }, - { BT_MESH_DTT_OP_SET, BT_MESH_DTT_MSG_LEN_SET, handle_set }, - { BT_MESH_DTT_OP_SET_UNACK, BT_MESH_DTT_MSG_LEN_SET, handle_set_unack }, + { + BT_MESH_DTT_OP_GET, + BT_MESH_LEN_EXACT(BT_MESH_DTT_MSG_LEN_GET), + handle_get, + }, + { + BT_MESH_DTT_OP_SET, + BT_MESH_LEN_EXACT(BT_MESH_DTT_MSG_LEN_SET), + handle_set, + }, + { + BT_MESH_DTT_OP_SET_UNACK, + BT_MESH_LEN_EXACT(BT_MESH_DTT_MSG_LEN_SET), + handle_set_unack, + }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/gen_loc_cli.c b/subsys/bluetooth/mesh/gen_loc_cli.c index 39787860ade9..620fbabdeccd 100644 --- a/subsys/bluetooth/mesh/gen_loc_cli.c +++ b/subsys/bluetooth/mesh/gen_loc_cli.c @@ -8,14 +8,9 @@ #include "model_utils.h" #include "gen_loc_internal.h" -static void handle_global_loc(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_global_loc(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LOC_MSG_LEN_GLOBAL_STATUS) { - return; - } - struct bt_mesh_loc_cli *cli = model->user_data; struct bt_mesh_loc_global loc; struct bt_mesh_loc_global *rsp; @@ -31,16 +26,13 @@ static void handle_global_loc(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->global_status) { cli->handlers->global_status(cli, ctx, &loc); } + + return 0; } -static void handle_local_loc(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_local_loc(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LOC_MSG_LEN_LOCAL_STATUS) { - return; - } - struct bt_mesh_loc_cli *cli = model->user_data; struct bt_mesh_loc_local loc; struct bt_mesh_loc_local *rsp; @@ -56,17 +48,19 @@ static void handle_local_loc(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->local_status) { cli->handlers->local_status(cli, ctx, &loc); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_loc_cli_op[] = { { BT_MESH_LOC_OP_GLOBAL_STATUS, - BT_MESH_LOC_MSG_LEN_GLOBAL_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_LOC_MSG_LEN_GLOBAL_STATUS), handle_global_loc, }, { BT_MESH_LOC_OP_LOCAL_STATUS, - BT_MESH_LOC_MSG_LEN_LOCAL_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_LOC_MSG_LEN_LOCAL_STATUS), handle_local_loc, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_loc_srv.c b/subsys/bluetooth/mesh/gen_loc_srv.c index ff43a2ad4a51..0bdb1d2fb7e7 100644 --- a/subsys/bluetooth/mesh/gen_loc_srv.c +++ b/subsys/bluetooth/mesh/gen_loc_srv.c @@ -44,29 +44,22 @@ static void rsp_global(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void handle_global_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_global_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LOC_MSG_LEN_GLOBAL_GET) { - return; - } - struct bt_mesh_loc_srv *srv = model->user_data; struct bt_mesh_loc_global global = LOC_GLOBAL_DEFAULT; srv->handlers->global_get(srv, ctx, &global); rsp_global(model, ctx, &global); + + return 0; } -static void global_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int global_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_LOC_MSG_LEN_GLOBAL_SET) { - return; - } - struct bt_mesh_loc_srv *srv = model->user_data; struct bt_mesh_loc_global global; @@ -82,20 +75,21 @@ static void global_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, srv->pub_op != BT_MESH_LOC_OP_GLOBAL_STATUS) { (void)bt_mesh_loc_srv_global_pub(srv, NULL, &global); } + + return 0; } -static void handle_global_set(struct bt_mesh_model *model, +static int handle_global_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - global_set(model, ctx, buf, true); + return global_set(model, ctx, buf, true); } -static void handle_global_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_global_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - global_set(model, ctx, buf, false); + return global_set(model, ctx, buf, false); } /* Local location */ @@ -113,29 +107,23 @@ static void rsp_local(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void handle_local_get(struct bt_mesh_model *model, +static int handle_local_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LOC_MSG_LEN_LOCAL_GET) { - return; - } - struct bt_mesh_loc_srv *srv = model->user_data; struct bt_mesh_loc_local local = LOC_LOCAL_DEFAULT; srv->handlers->local_get(srv, ctx, &local); rsp_local(model, ctx, &local); + + return 0; } -static void local_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int local_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_LOC_MSG_LEN_LOCAL_SET) { - return; - } - struct bt_mesh_loc_srv *srv = model->user_data; struct bt_mesh_loc_local local; @@ -151,31 +139,33 @@ static void local_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, srv->pub_op != BT_MESH_LOC_OP_LOCAL_STATUS) { (void)bt_mesh_loc_srv_local_pub(srv, NULL, &local); } + + return 0; } -static void handle_local_set(struct bt_mesh_model *model, +static int handle_local_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - local_set(model, ctx, buf, true); + return local_set(model, ctx, buf, true); } -static void handle_local_set_unack(struct bt_mesh_model *model, +static int handle_local_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - local_set(model, ctx, buf, false); + return local_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_loc_srv_op[] = { { BT_MESH_LOC_OP_GLOBAL_GET, - BT_MESH_LOC_MSG_LEN_GLOBAL_GET, + BT_MESH_LEN_EXACT(BT_MESH_LOC_MSG_LEN_GLOBAL_GET), handle_global_get, }, { BT_MESH_LOC_OP_LOCAL_GET, - BT_MESH_LOC_MSG_LEN_LOCAL_GET, + BT_MESH_LEN_EXACT(BT_MESH_LOC_MSG_LEN_LOCAL_GET), handle_local_get, }, BT_MESH_MODEL_OP_END @@ -183,22 +173,22 @@ const struct bt_mesh_model_op _bt_mesh_loc_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_loc_setup_srv_op[] = { { BT_MESH_LOC_OP_GLOBAL_SET, - BT_MESH_LOC_MSG_LEN_GLOBAL_SET, + BT_MESH_LEN_EXACT(BT_MESH_LOC_MSG_LEN_GLOBAL_SET), handle_global_set, }, { BT_MESH_LOC_OP_GLOBAL_SET_UNACK, - BT_MESH_LOC_MSG_LEN_GLOBAL_SET, + BT_MESH_LEN_EXACT(BT_MESH_LOC_MSG_LEN_GLOBAL_SET), handle_global_set_unack, }, { BT_MESH_LOC_OP_LOCAL_SET, - BT_MESH_LOC_MSG_LEN_LOCAL_SET, + BT_MESH_LEN_EXACT(BT_MESH_LOC_MSG_LEN_LOCAL_SET), handle_local_set, }, { BT_MESH_LOC_OP_LOCAL_SET_UNACK, - BT_MESH_LOC_MSG_LEN_LOCAL_SET, + BT_MESH_LEN_EXACT(BT_MESH_LOC_MSG_LEN_LOCAL_SET), handle_local_set_unack, }, BT_MESH_MODEL_OP_END diff --git a/subsys/bluetooth/mesh/gen_lvl_cli.c b/subsys/bluetooth/mesh/gen_lvl_cli.c index ad6dfb361f7e..395619142b10 100644 --- a/subsys/bluetooth/mesh/gen_lvl_cli.c +++ b/subsys/bluetooth/mesh/gen_lvl_cli.c @@ -7,13 +7,13 @@ #include #include "model_utils.h" -static void handle_status(struct bt_mesh_model *model, +static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { if (buf->len != BT_MESH_LVL_MSG_MINLEN_STATUS && buf->len != BT_MESH_LVL_MSG_MAXLEN_STATUS) { - return; + return -EMSGSIZE; } struct bt_mesh_lvl_cli *cli = model->user_data; @@ -39,10 +39,16 @@ static void handle_status(struct bt_mesh_model *model, if (cli->status_handler) { cli->status_handler(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_lvl_cli_op[] = { - { BT_MESH_LVL_OP_STATUS, BT_MESH_LVL_MSG_MINLEN_STATUS, handle_status }, + { + BT_MESH_LVL_OP_STATUS, + BT_MESH_LEN_MIN(BT_MESH_LVL_MSG_MINLEN_STATUS), + handle_status, + }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/gen_lvl_srv.c b/subsys/bluetooth/mesh/gen_lvl_srv.c index 8032fbd12bb1..ffe91fe8ea77 100644 --- a/subsys/bluetooth/mesh/gen_lvl_srv.c +++ b/subsys/bluetooth/mesh/gen_lvl_srv.c @@ -36,27 +36,25 @@ static void rsp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, bt_mesh_model_send(model, ctx, &rsp, NULL, 0); } -static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LVL_MSG_LEN_GET) { - return; - } - struct bt_mesh_lvl_srv *srv = model->user_data; struct bt_mesh_lvl_status status = { 0 }; srv->handlers->get(srv, ctx, &status); rsp_status(model, ctx, &status); + + return 0; } -static void set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_LVL_MSG_MINLEN_SET && buf->len != BT_MESH_LVL_MSG_MAXLEN_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_lvl_srv *srv = model->user_data; @@ -80,14 +78,16 @@ static void set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, } (void)bt_mesh_lvl_srv_pub(srv, NULL, &status); + + return 0; } -static void delta_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int delta_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_LVL_MSG_MINLEN_DELTA_SET && buf->len != BT_MESH_LVL_MSG_MAXLEN_DELTA_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_lvl_srv *srv = model->user_data; @@ -111,14 +111,16 @@ static void delta_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, } (void)bt_mesh_lvl_srv_pub(srv, NULL, &status); + + return 0; } -static void move_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int move_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_LVL_MSG_MINLEN_MOVE_SET && buf->len != BT_MESH_LVL_MSG_MAXLEN_MOVE_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_lvl_srv *srv = model->user_data; @@ -151,85 +153,82 @@ static void move_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, } (void)bt_mesh_lvl_srv_pub(srv, ctx, &status); + + return 0; } /* Message handlers */ -static void handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set(model, ctx, buf, true); + return set(model, ctx, buf, true); } -static void handle_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set(model, ctx, buf, false); + return set(model, ctx, buf, false); } -static void handle_delta_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_delta_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - delta_set(model, ctx, buf, true); + return delta_set(model, ctx, buf, true); } -static void handle_delta_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_delta_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - delta_set(model, ctx, buf, false); + return delta_set(model, ctx, buf, false); } -static void handle_move_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_move_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - move_set(model, ctx, buf, true); + return move_set(model, ctx, buf, true); } -static void handle_move_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_move_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - move_set(model, ctx, buf, false); + return move_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_lvl_srv_op[] = { { BT_MESH_LVL_OP_GET, - BT_MESH_LVL_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_LVL_MSG_LEN_GET), handle_get, }, { BT_MESH_LVL_OP_SET, - BT_MESH_LVL_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_LVL_MSG_MINLEN_SET), handle_set, }, { BT_MESH_LVL_OP_SET_UNACK, - BT_MESH_LVL_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_LVL_MSG_MINLEN_SET), handle_set_unack, }, { BT_MESH_LVL_OP_DELTA_SET, - BT_MESH_LVL_MSG_MINLEN_DELTA_SET, + BT_MESH_LEN_MIN(BT_MESH_LVL_MSG_MINLEN_DELTA_SET), handle_delta_set, }, { BT_MESH_LVL_OP_DELTA_SET_UNACK, - BT_MESH_LVL_MSG_MINLEN_DELTA_SET, + BT_MESH_LEN_MIN(BT_MESH_LVL_MSG_MINLEN_DELTA_SET), handle_delta_set_unack, }, { BT_MESH_LVL_OP_MOVE_SET, - BT_MESH_LVL_MSG_MINLEN_MOVE_SET, + BT_MESH_LEN_MIN(BT_MESH_LVL_MSG_MINLEN_MOVE_SET), handle_move_set, }, { BT_MESH_LVL_OP_MOVE_SET_UNACK, - BT_MESH_LVL_MSG_MINLEN_MOVE_SET, + BT_MESH_LEN_MIN(BT_MESH_LVL_MSG_MINLEN_MOVE_SET), handle_move_set_unack, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_onoff_cli.c b/subsys/bluetooth/mesh/gen_onoff_cli.c index d7ef4dd6f6aa..8c77e33b2ec5 100644 --- a/subsys/bluetooth/mesh/gen_onoff_cli.c +++ b/subsys/bluetooth/mesh/gen_onoff_cli.c @@ -35,21 +35,22 @@ static int decode_status(struct net_buf_simple *buf, return 0; } -static void handle_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { if (buf->len != BT_MESH_ONOFF_MSG_MINLEN_STATUS && buf->len != BT_MESH_ONOFF_MSG_MAXLEN_STATUS) { - return; + return -EMSGSIZE; } struct bt_mesh_onoff_cli *cli = model->user_data; struct bt_mesh_onoff_status status; struct bt_mesh_onoff_status *rsp; + int err; - if (decode_status(buf, &status)) { - return; + err = decode_status(buf, &status); + if (err) { + return err; } if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_ONOFF_OP_STATUS, ctx->addr, @@ -61,12 +62,14 @@ static void handle_status(struct bt_mesh_model *model, if (cli->status_handler) { cli->status_handler(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_onoff_cli_op[] = { { BT_MESH_ONOFF_OP_STATUS, - BT_MESH_ONOFF_MSG_MINLEN_STATUS, + BT_MESH_LEN_MIN(BT_MESH_ONOFF_MSG_MINLEN_STATUS), handle_status, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_onoff_srv.c b/subsys/bluetooth/mesh/gen_onoff_srv.c index bcaff7b963e3..5db57d23284f 100644 --- a/subsys/bluetooth/mesh/gen_onoff_srv.c +++ b/subsys/bluetooth/mesh/gen_onoff_srv.c @@ -34,27 +34,25 @@ static void rsp_status(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_ONOFF_MSG_LEN_GET) { - return; - } - struct bt_mesh_onoff_srv *srv = model->user_data; struct bt_mesh_onoff_status status = { 0 }; srv->handlers->get(srv, ctx, &status); rsp_status(model, ctx, &status); + + return 0; } -static void onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_ONOFF_MSG_MINLEN_SET && buf->len != BT_MESH_ONOFF_MSG_MAXLEN_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_onoff_srv *srv = model->user_data; @@ -66,7 +64,7 @@ static void onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint8_t tid = net_buf_simple_pull_u8(buf); if (on_off > 1) { - return; + return -EINVAL; } set.on_off = on_off; @@ -101,35 +99,36 @@ static void onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (ack) { rsp_status(model, ctx, &status); } + + return 0; } -static void handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - onoff_set(model, ctx, buf, true); + return onoff_set(model, ctx, buf, true); } -static void handle_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - onoff_set(model, ctx, buf, false); + return onoff_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_onoff_srv_op[] = { { BT_MESH_ONOFF_OP_GET, - BT_MESH_ONOFF_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_ONOFF_MSG_LEN_GET), handle_get, }, { BT_MESH_ONOFF_OP_SET, - BT_MESH_ONOFF_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_ONOFF_MSG_MINLEN_SET), handle_set, }, { BT_MESH_ONOFF_OP_SET_UNACK, - BT_MESH_ONOFF_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_ONOFF_MSG_MINLEN_SET), handle_set_unack, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_plvl_cli.c b/subsys/bluetooth/mesh/gen_plvl_cli.c index bd8e99ce1ab1..e29525908098 100644 --- a/subsys/bluetooth/mesh/gen_plvl_cli.c +++ b/subsys/bluetooth/mesh/gen_plvl_cli.c @@ -6,13 +6,12 @@ #include #include "model_utils.h" -static void handle_power_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_power_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { if (buf->len != BT_MESH_PLVL_MSG_MINLEN_LEVEL_STATUS && buf->len != BT_MESH_PLVL_MSG_MAXLEN_LEVEL_STATUS) { - return; + return -EMSGSIZE; } struct bt_mesh_plvl_cli *cli = model->user_data; @@ -38,16 +37,13 @@ static void handle_power_status(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->power_status) { cli->handlers->power_status(cli, ctx, &status); } + + return 0; } -static void handle_last_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_last_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_LAST_STATUS) { - return; - } - struct bt_mesh_plvl_cli *cli = model->user_data; uint16_t last = net_buf_simple_pull_le16(buf); uint16_t *rsp; @@ -61,16 +57,13 @@ static void handle_last_status(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->last_status) { cli->handlers->last_status(cli, ctx, last); } + + return 0; } -static void handle_default_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_DEFAULT_STATUS) { - return; - } - struct bt_mesh_plvl_cli *cli = model->user_data; uint16_t default_lvl = net_buf_simple_pull_le16(buf); uint16_t *rsp; @@ -84,16 +77,13 @@ static void handle_default_status(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->default_status) { cli->handlers->default_status(cli, ctx, default_lvl); } + + return 0; } -static void handle_range_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_RANGE_STATUS) { - return; - } - struct bt_mesh_plvl_cli *cli = model->user_data; struct bt_mesh_plvl_range_status status; struct bt_mesh_plvl_range_status *rsp; @@ -111,27 +101,29 @@ static void handle_range_status(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->range_status) { cli->handlers->range_status(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_plvl_cli_op[] = { { BT_MESH_PLVL_OP_LEVEL_STATUS, - BT_MESH_PLVL_MSG_MINLEN_LEVEL_STATUS, + BT_MESH_LEN_MIN(BT_MESH_PLVL_MSG_MINLEN_LEVEL_STATUS), handle_power_status, }, { BT_MESH_PLVL_OP_LAST_STATUS, - BT_MESH_PLVL_MSG_LEN_LAST_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_LAST_STATUS), handle_last_status, }, { BT_MESH_PLVL_OP_DEFAULT_STATUS, - BT_MESH_PLVL_MSG_LEN_DEFAULT_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_DEFAULT_STATUS), handle_default_status, }, { BT_MESH_PLVL_OP_RANGE_STATUS, - BT_MESH_PLVL_MSG_LEN_RANGE_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_RANGE_STATUS), handle_range_status, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_plvl_srv.c b/subsys/bluetooth/mesh/gen_plvl_srv.c index 19fb7fb88c7d..861c147c1752 100644 --- a/subsys/bluetooth/mesh/gen_plvl_srv.c +++ b/subsys/bluetooth/mesh/gen_plvl_srv.c @@ -111,23 +111,20 @@ static void rsp_plvl_status(struct bt_mesh_model *model, bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); } -static void handle_lvl_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_lvl_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_LEVEL_GET) { - return; - } - struct bt_mesh_plvl_srv *srv = model->user_data; struct bt_mesh_plvl_status status = { 0 }; srv->handlers->power_get(srv, ctx, &status); rsp_plvl_status(model, ctx, &status); + + return 0; } -static void change_lvl(struct bt_mesh_plvl_srv *srv, +static int change_lvl(struct bt_mesh_plvl_srv *srv, struct bt_mesh_msg_ctx *ctx, struct bt_mesh_plvl_set *set, struct bt_mesh_plvl_status *status) @@ -149,14 +146,16 @@ static void change_lvl(struct bt_mesh_plvl_srv *srv, memset(status, 0, sizeof(*status)); srv->handlers->power_set(srv, ctx, set, status); + + return 0; } -static void plvl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int plvl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_PLVL_MSG_MINLEN_LEVEL_SET && buf->len != BT_MESH_PLVL_MSG_MAXLEN_LEVEL_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_plvl_srv *srv = model->user_data; @@ -183,30 +182,25 @@ static void plvl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (ack) { rsp_plvl_status(model, ctx, &status); } + + return 0; } -static void handle_plvl_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_plvl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - plvl_set(model, ctx, buf, true); + return plvl_set(model, ctx, buf, true); } -static void handle_plvl_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_plvl_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - plvl_set(model, ctx, buf, false); + return plvl_set(model, ctx, buf, false); } -static void handle_last_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_last_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_LAST_GET) { - return; - } - struct bt_mesh_plvl_srv *srv = model->user_data; BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PLVL_OP_LAST_STATUS, @@ -215,16 +209,13 @@ static void handle_last_get(struct bt_mesh_model *model, net_buf_simple_add_le16(&rsp, srv->last); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_default_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_DEFAULT_GET) { - return; - } - struct bt_mesh_plvl_srv *srv = model->user_data; BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PLVL_OP_DEFAULT_STATUS, @@ -233,15 +224,13 @@ static void handle_default_get(struct bt_mesh_model *model, net_buf_simple_add_le16(&rsp, srv->default_power); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void set_default(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int set_default(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_DEFAULT_SET) { - return; - } - struct bt_mesh_plvl_srv *srv = model->user_data; uint16_t new = net_buf_simple_pull_le16(buf); @@ -257,7 +246,7 @@ static void set_default(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx } if (!ack) { - return; + return 0; } BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PLVL_OP_DEFAULT_STATUS, @@ -266,30 +255,25 @@ static void set_default(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx net_buf_simple_add_le16(&rsp, srv->default_power); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_default_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_default(model, ctx, buf, true); + return set_default(model, ctx, buf, true); } -static void handle_default_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_default(model, ctx, buf, false); + return set_default(model, ctx, buf, false); } -static void handle_range_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_RANGE_GET) { - return; - } - struct bt_mesh_plvl_srv *srv = model->user_data; BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PLVL_OP_RANGE_STATUS, @@ -301,15 +285,13 @@ static void handle_range_get(struct bt_mesh_model *model, net_buf_simple_add_le16(&rsp, srv->range.max); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_PLVL_MSG_LEN_RANGE_SET) { - return; - } - struct bt_mesh_plvl_srv *srv = model->user_data; struct bt_mesh_plvl_range new; @@ -321,7 +303,7 @@ static void set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, * parameters. */ if (new.min == 0 || new.max == 0 || new.min > new.max) { - return; + return -EINVAL; } if (new.min != srv->range.min || new.max != srv->range.max) { @@ -336,7 +318,7 @@ static void set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, } if (!ack) { - return; + return 0; } BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PLVL_OP_RANGE_STATUS, @@ -348,51 +330,51 @@ static void set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, net_buf_simple_add_le16(&rsp, srv->range.max); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_range_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_range(model, ctx, buf, true); + return set_range(model, ctx, buf, true); } -static void handle_range_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_range(model, ctx, buf, false); + return set_range(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_plvl_srv_op[] = { { BT_MESH_PLVL_OP_LEVEL_GET, - BT_MESH_PLVL_MSG_LEN_LEVEL_GET, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_LEVEL_GET), handle_lvl_get, }, { BT_MESH_PLVL_OP_LEVEL_SET, - BT_MESH_PLVL_MSG_MINLEN_LEVEL_SET, + BT_MESH_LEN_MIN(BT_MESH_PLVL_MSG_MINLEN_LEVEL_SET), handle_plvl_set, }, { BT_MESH_PLVL_OP_LEVEL_SET_UNACK, - BT_MESH_PLVL_MSG_MINLEN_LEVEL_SET, + BT_MESH_LEN_MIN(BT_MESH_PLVL_MSG_MINLEN_LEVEL_SET), handle_plvl_set_unack, }, { BT_MESH_PLVL_OP_LAST_GET, - BT_MESH_PLVL_MSG_LEN_LAST_GET, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_LAST_GET), handle_last_get, }, { BT_MESH_PLVL_OP_DEFAULT_GET, - BT_MESH_PLVL_MSG_LEN_DEFAULT_GET, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_DEFAULT_GET), handle_default_get, }, { BT_MESH_PLVL_OP_RANGE_GET, - BT_MESH_PLVL_MSG_LEN_RANGE_GET, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_RANGE_GET), handle_range_get, }, BT_MESH_MODEL_OP_END, @@ -401,22 +383,22 @@ const struct bt_mesh_model_op _bt_mesh_plvl_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_plvl_setup_srv_op[] = { { BT_MESH_PLVL_OP_DEFAULT_SET, - BT_MESH_PLVL_MSG_LEN_DEFAULT_SET, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_DEFAULT_SET), handle_default_set, }, { BT_MESH_PLVL_OP_DEFAULT_SET_UNACK, - BT_MESH_PLVL_MSG_LEN_DEFAULT_SET, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_DEFAULT_SET), handle_default_set_unack, }, { BT_MESH_PLVL_OP_RANGE_SET, - BT_MESH_PLVL_MSG_LEN_RANGE_SET, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_RANGE_SET), handle_range_set, }, { BT_MESH_PLVL_OP_RANGE_SET_UNACK, - BT_MESH_PLVL_MSG_LEN_RANGE_SET, + BT_MESH_LEN_EXACT(BT_MESH_PLVL_MSG_LEN_RANGE_SET), handle_range_set_unack, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_ponoff_cli.c b/subsys/bluetooth/mesh/gen_ponoff_cli.c index edf7362fc287..8c116f6cf3f6 100644 --- a/subsys/bluetooth/mesh/gen_ponoff_cli.c +++ b/subsys/bluetooth/mesh/gen_ponoff_cli.c @@ -7,20 +7,15 @@ #include #include "model_utils.h" -static void handle_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PONOFF_MSG_LEN_STATUS) { - return; - } - struct bt_mesh_ponoff_cli *cli = model->user_data; enum bt_mesh_on_power_up on_power_up = net_buf_simple_pull_u8(buf); enum bt_mesh_on_power_up *rsp; if (on_power_up >= BT_MESH_ON_POWER_UP_INVALID) { - return; + return -EINVAL; } if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_PONOFF_OP_STATUS, ctx->addr, @@ -33,12 +28,14 @@ static void handle_status(struct bt_mesh_model *model, if (cli->status_handler) { cli->status_handler(cli, ctx, on_power_up); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_ponoff_cli_op[] = { { BT_MESH_PONOFF_OP_STATUS, - BT_MESH_PONOFF_MSG_LEN_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_PONOFF_MSG_LEN_STATUS), handle_status, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_ponoff_srv.c b/subsys/bluetooth/mesh/gen_ponoff_srv.c index c5f795fa9cc2..2ea438922a35 100644 --- a/subsys/bluetooth/mesh/gen_ponoff_srv.c +++ b/subsys/bluetooth/mesh/gen_ponoff_srv.c @@ -103,14 +103,12 @@ static void send_rsp(struct bt_mesh_ponoff_srv *srv, bt_mesh_model_send(srv->ponoff_model, ctx, &msg, NULL, NULL); } -static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PONOFF_MSG_LEN_GET) { - return; - } - send_rsp(model->user_data, ctx); + + return 0; } static void set_on_power_up(struct bt_mesh_ponoff_srv *srv, @@ -136,19 +134,14 @@ static void set_on_power_up(struct bt_mesh_ponoff_srv *srv, store_state(srv); } -static void handle_set_msg(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int handle_set_msg(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_PONOFF_MSG_LEN_SET) { - return; - } - struct bt_mesh_ponoff_srv *srv = model->user_data; enum bt_mesh_on_power_up new = net_buf_simple_pull_u8(buf); if (new >= BT_MESH_ON_POWER_UP_INVALID) { - return; + return -EINVAL; } set_on_power_up(srv, ctx, new); @@ -158,19 +151,20 @@ static void handle_set_msg(struct bt_mesh_model *model, } (void)bt_mesh_ponoff_srv_pub(srv, NULL); + + return 0; } -static void handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - handle_set_msg(model, ctx, buf, true); + return handle_set_msg(model, ctx, buf, true); } -static void handle_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - handle_set_msg(model, ctx, buf, false); + return handle_set_msg(model, ctx, buf, false); } /* Need to intercept the onoff state to get the right value on power up. */ @@ -201,19 +195,23 @@ static void onoff_intercept_get(struct bt_mesh_onoff_srv *onoff_srv, } const struct bt_mesh_model_op _bt_mesh_ponoff_srv_op[] = { - { BT_MESH_PONOFF_OP_GET, BT_MESH_PONOFF_MSG_LEN_GET, handle_get }, + { + BT_MESH_PONOFF_OP_GET, + BT_MESH_LEN_EXACT(BT_MESH_PONOFF_MSG_LEN_GET), + handle_get, + }, BT_MESH_MODEL_OP_END, }; const struct bt_mesh_model_op _bt_mesh_ponoff_setup_srv_op[] = { { BT_MESH_PONOFF_OP_SET, - BT_MESH_PONOFF_MSG_LEN_SET, + BT_MESH_LEN_EXACT(BT_MESH_PONOFF_MSG_LEN_SET), handle_set, }, { BT_MESH_PONOFF_OP_SET_UNACK, - BT_MESH_PONOFF_MSG_LEN_SET, + BT_MESH_LEN_EXACT(BT_MESH_PONOFF_MSG_LEN_SET), handle_set_unack, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_prop_cli.c b/subsys/bluetooth/mesh/gen_prop_cli.c index 6eda77e1702a..860e3b174729 100644 --- a/subsys/bluetooth/mesh/gen_prop_cli.c +++ b/subsys/bluetooth/mesh/gen_prop_cli.c @@ -24,13 +24,13 @@ struct prop_list_ctx { int status; }; -static void properties_status(struct bt_mesh_model *model, +static int properties_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, enum bt_mesh_prop_srv_kind kind) { if ((buf->len % 2) != 0) { - return; + return -EMSGSIZE; } struct bt_mesh_prop_cli *cli = model->user_data; @@ -56,44 +56,42 @@ static void properties_status(struct bt_mesh_model *model, if (cli->prop_list) { cli->prop_list(cli, ctx, kind, &list); } + + return 0; } -static void handle_mfr_properties_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_mfr_properties_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - properties_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_MFR); + return properties_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_MFR); } -static void handle_admin_properties_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_admin_properties_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - properties_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_ADMIN); + return properties_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_ADMIN); } -static void handle_user_properties_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_user_properties_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - properties_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_USER); + return properties_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_USER); } -static void handle_client_properties_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_client_properties_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - properties_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_CLIENT); + return properties_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_CLIENT); } -static void property_status(struct bt_mesh_model *model, +static int property_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, enum bt_mesh_prop_srv_kind kind) { if (buf->len < BT_MESH_PROP_MSG_MINLEN_PROP_STATUS || buf->len > BT_MESH_PROP_MSG_MAXLEN_PROP_STATUS) { - return; + return -EMSGSIZE; } struct bt_mesh_prop_cli *cli = model->user_data; @@ -116,63 +114,62 @@ static void property_status(struct bt_mesh_model *model, if (cli->prop_status) { cli->prop_status(cli, ctx, kind, &val); } + + return 0; } -static void handle_mfr_property_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_mfr_property_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - property_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_MFR); + return property_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_MFR); } -static void handle_admin_property_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_admin_property_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - property_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_ADMIN); + return property_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_ADMIN); } -static void handle_user_property_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_user_property_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - property_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_USER); + return property_status(model, ctx, buf, BT_MESH_PROP_SRV_KIND_USER); } const struct bt_mesh_model_op _bt_mesh_prop_cli_op[] = { { BT_MESH_PROP_OP_MFR_PROPS_STATUS, - BT_MESH_PROP_MSG_MINLEN_PROPS_STATUS, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_PROPS_STATUS), handle_mfr_properties_status, }, { BT_MESH_PROP_OP_ADMIN_PROPS_STATUS, - BT_MESH_PROP_MSG_MINLEN_PROPS_STATUS, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_PROPS_STATUS), handle_admin_properties_status, }, { BT_MESH_PROP_OP_USER_PROPS_STATUS, - BT_MESH_PROP_MSG_MINLEN_PROPS_STATUS, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_PROPS_STATUS), handle_user_properties_status, }, { BT_MESH_PROP_OP_CLIENT_PROPS_STATUS, - BT_MESH_PROP_MSG_MINLEN_PROPS_STATUS, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_PROPS_STATUS), handle_client_properties_status, }, { BT_MESH_PROP_OP_MFR_PROP_STATUS, - BT_MESH_PROP_MSG_MINLEN_PROP_STATUS, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_PROP_STATUS), handle_mfr_property_status, }, { BT_MESH_PROP_OP_ADMIN_PROP_STATUS, - BT_MESH_PROP_MSG_MINLEN_PROP_STATUS, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_PROP_STATUS), handle_admin_property_status, }, { BT_MESH_PROP_OP_USER_PROP_STATUS, - BT_MESH_PROP_MSG_MINLEN_PROP_STATUS, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_PROP_STATUS), handle_user_property_status, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/gen_prop_srv.c b/subsys/bluetooth/mesh/gen_prop_srv.c index 234ee53539fa..da4086047cfb 100644 --- a/subsys/bluetooth/mesh/gen_prop_srv.c +++ b/subsys/bluetooth/mesh/gen_prop_srv.c @@ -114,34 +114,26 @@ static void pub_list_build(const struct bt_mesh_prop_srv *srv, /* Owner properties */ -static void handle_owner_properties_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_owner_properties_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PROP_MSG_LEN_PROPS_GET) { - return; - } - BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PROP_OP_ADMIN_PROPS_STATUS, BT_MESH_PROP_MSG_MAXLEN_PROPS_STATUS); pub_list_build(model->user_data, &rsp, 0); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_owner_property_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_owner_property_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PROP_MSG_LEN_PROP_GET) { - return; - } - struct bt_mesh_prop_srv *srv = model->user_data; uint16_t id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } const struct bt_mesh_prop *prop = prop_get(srv, id); @@ -174,26 +166,31 @@ static void handle_owner_property_get(struct bt_mesh_model *model, respond: bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void owner_property_set(struct bt_mesh_model *model, +static int owner_property_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if ((IS_MFR_SRV(model) && (buf->len != 3)) || (buf->len > BT_MESH_PROP_MSG_MAXLEN_ADMIN_PROP_SET || buf->len < BT_MESH_PROP_MSG_MINLEN_ADMIN_PROP_SET)) { - return; + return -EMSGSIZE; } struct bt_mesh_prop_srv *srv = model->user_data; uint16_t id = net_buf_simple_pull_le16(buf); enum bt_mesh_prop_access user_access = net_buf_simple_pull_u8(buf); - if (id == BT_MESH_PROP_ID_PROHIBITED || - (IS_MFR_SRV(model) && (user_access & BT_MESH_PROP_ACCESS_WRITE)) || + if (id == BT_MESH_PROP_ID_PROHIBITED) { + return -EINVAL; + } + + if ((IS_MFR_SRV(model) && (user_access & BT_MESH_PROP_ACCESS_WRITE)) || user_access > BT_MESH_PROP_ACCESS_READ_WRITE) { - return; + return -EPERM; } BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PROP_OP_ADMIN_PROP_STATUS, @@ -237,7 +234,7 @@ static void owner_property_set(struct bt_mesh_model *model, /* User callbacks wipe the id to indicate invalid * behavior */ - return; + return -EINVAL; } } @@ -248,41 +245,41 @@ static void owner_property_set(struct bt_mesh_model *model, if (ack) { bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); } + + return 0; } -static void handle_owner_property_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_owner_property_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - owner_property_set(model, ctx, buf, true); + return owner_property_set(model, ctx, buf, true); } -static void handle_owner_property_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_owner_property_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - owner_property_set(model, ctx, buf, false); + return owner_property_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_prop_admin_srv_op[] = { { BT_MESH_PROP_OP_ADMIN_PROPS_GET, - BT_MESH_PROP_MSG_LEN_PROPS_GET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_PROPS_GET), handle_owner_properties_get, }, { BT_MESH_PROP_OP_ADMIN_PROP_GET, - BT_MESH_PROP_MSG_LEN_PROP_GET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_PROP_GET), handle_owner_property_get, }, { BT_MESH_PROP_OP_ADMIN_PROP_SET, - BT_MESH_PROP_MSG_MINLEN_ADMIN_PROP_SET, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_ADMIN_PROP_SET), handle_owner_property_set, }, { BT_MESH_PROP_OP_ADMIN_PROP_SET_UNACK, - BT_MESH_PROP_MSG_MINLEN_ADMIN_PROP_SET, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_ADMIN_PROP_SET), handle_owner_property_set_unack, }, BT_MESH_MODEL_OP_END, @@ -291,35 +288,30 @@ const struct bt_mesh_model_op _bt_mesh_prop_admin_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_prop_mfr_srv_op[] = { { BT_MESH_PROP_OP_MFR_PROPS_GET, - BT_MESH_PROP_MSG_LEN_PROPS_GET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_PROPS_GET), handle_owner_properties_get, }, { BT_MESH_PROP_OP_MFR_PROP_GET, - BT_MESH_PROP_MSG_LEN_PROP_GET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_PROP_GET), handle_owner_property_get, }, { BT_MESH_PROP_OP_MFR_PROP_SET, - BT_MESH_PROP_MSG_LEN_MFR_PROP_SET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_MFR_PROP_SET), handle_owner_property_set, }, { BT_MESH_PROP_OP_MFR_PROP_SET_UNACK, - BT_MESH_PROP_MSG_LEN_MFR_PROP_SET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_MFR_PROP_SET), handle_owner_property_set_unack, }, BT_MESH_MODEL_OP_END, }; -static void handle_client_properties_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_client_properties_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PROP_MSG_LEN_CLIENT_PROPS_GET) { - return; - } - uint16_t start_prop = net_buf_simple_pull_le16(buf); BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PROP_OP_CLIENT_PROPS_STATUS, @@ -327,11 +319,16 @@ static void handle_client_properties_get(struct bt_mesh_model *model, pub_list_build(model->user_data, &rsp, start_prop); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } const struct bt_mesh_model_op _bt_mesh_prop_client_srv_op[] = { - { BT_MESH_PROP_OP_CLIENT_PROPS_GET, - BT_MESH_PROP_MSG_LEN_CLIENT_PROPS_GET, handle_client_properties_get }, + { + BT_MESH_PROP_OP_CLIENT_PROPS_GET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_CLIENT_PROPS_GET), + handle_client_properties_get, + }, BT_MESH_MODEL_OP_END, }; @@ -368,14 +365,9 @@ static struct bt_mesh_prop *user_prop_get(struct bt_mesh_model *model, uint16_t return NULL; } -static void handle_user_properties_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_user_properties_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PROP_MSG_LEN_PROPS_GET) { - return; - } - BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PROP_OP_PROPS_STATUS, BT_MESH_PROP_MSG_MAXLEN_PROPS_STATUS); @@ -409,20 +401,17 @@ static void handle_user_properties_get(struct bt_mesh_model *model, } bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_user_property_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_user_property_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_PROP_MSG_LEN_PROP_GET) { - return; - } - uint16_t id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_PROP_OP_USER_PROP_STATUS, @@ -457,15 +446,16 @@ static void handle_user_property_get(struct bt_mesh_model *model, respond: bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void user_property_set(struct bt_mesh_model *model, +static int user_property_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { - if (buf->len < BT_MESH_PROP_MSG_MINLEN_USER_PROP_SET || - buf->len > BT_MESH_PROP_MSG_MAXLEN_USER_PROP_SET) { - return; + if (buf->len > BT_MESH_PROP_MSG_MAXLEN_USER_PROP_SET) { + return -EMSGSIZE; } uint16_t id = net_buf_simple_pull_le16(buf); @@ -478,7 +468,7 @@ static void user_property_set(struct bt_mesh_model *model, net_buf_simple_add_le16(&rsp, id); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } struct bt_mesh_prop_srv *user_srv = model->user_data; @@ -515,7 +505,7 @@ static void user_property_set(struct bt_mesh_model *model, if (value.meta.id == BT_MESH_PROP_ID_PROHIBITED) { /* User callbacks wipe the id to indicate invalid behavior */ - return; + return -EINVAL; } net_buf_simple_add(&rsp, value.size); @@ -526,28 +516,43 @@ static void user_property_set(struct bt_mesh_model *model, if (ack) { bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); } + + return 0; } -static void handle_user_property_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_user_property_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - user_property_set(model, ctx, buf, true); + return user_property_set(model, ctx, buf, true); } -static void handle_user_property_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_user_property_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - user_property_set(model, ctx, buf, false); + return user_property_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_prop_user_srv_op[] = { - { BT_MESH_PROP_OP_USER_PROPS_GET, 0, handle_user_properties_get }, - { BT_MESH_PROP_OP_USER_PROP_GET, 2, handle_user_property_get }, - { BT_MESH_PROP_OP_USER_PROP_SET, 2, handle_user_property_set }, - { BT_MESH_PROP_OP_USER_PROP_SET_UNACK, 2, - handle_user_property_set_unack }, + { + BT_MESH_PROP_OP_USER_PROPS_GET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_PROPS_GET), + handle_user_properties_get, + }, + { + BT_MESH_PROP_OP_USER_PROP_GET, + BT_MESH_LEN_EXACT(BT_MESH_PROP_MSG_LEN_PROP_GET), + handle_user_property_get, + }, + { + BT_MESH_PROP_OP_USER_PROP_SET, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_USER_PROP_SET), + handle_user_property_set, + }, + { + BT_MESH_PROP_OP_USER_PROP_SET_UNACK, + BT_MESH_LEN_MIN(BT_MESH_PROP_MSG_MINLEN_USER_PROP_SET), + handle_user_property_set_unack, + }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_ctl_cli.c b/subsys/bluetooth/mesh/light_ctl_cli.c index ab39fad03de7..72791edaa495 100644 --- a/subsys/bluetooth/mesh/light_ctl_cli.c +++ b/subsys/bluetooth/mesh/light_ctl_cli.c @@ -7,13 +7,12 @@ #include #include "model_utils.h" -static void ctl_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_ctl_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { if (buf->len != BT_MESH_LIGHT_CTL_MSG_MINLEN_STATUS && buf->len != BT_MESH_LIGHT_CTL_MSG_MAXLEN_STATUS) { - return; + return -EMSGSIZE; } struct bt_mesh_light_ctl_cli *cli = model->user_data; @@ -24,7 +23,7 @@ static void ctl_status_handle(struct bt_mesh_model *model, status.current_temp = net_buf_simple_pull_le16(buf); if ((status.current_temp < BT_MESH_LIGHT_TEMP_MIN) || (status.current_temp > BT_MESH_LIGHT_TEMP_MAX)) { - return; + return -EINVAL; } if (buf->len == 5) { @@ -32,7 +31,7 @@ static void ctl_status_handle(struct bt_mesh_model *model, status.target_temp = net_buf_simple_pull_le16(buf); if ((status.target_temp < BT_MESH_LIGHT_TEMP_MIN) || (status.target_temp > BT_MESH_LIGHT_TEMP_MAX)) { - return; + return -EINVAL; } status.remaining_time = @@ -52,16 +51,13 @@ static void ctl_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->ctl_status) { cli->handlers->ctl_status(cli, ctx, &status); } + + return 0; } -static void temp_range_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_temp_range_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_STATUS) { - return; - } - struct bt_mesh_light_ctl_cli *cli = model->user_data; struct bt_mesh_light_temp_range_status status; struct bt_mesh_light_temp_range_status *rsp; @@ -79,15 +75,16 @@ static void temp_range_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->temp_range_status) { cli->handlers->temp_range_status(cli, ctx, &status); } + + return 0; } -static void temp_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_temp_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { if (buf->len != BT_MESH_LIGHT_CTL_MSG_MINLEN_TEMP_STATUS && buf->len != BT_MESH_LIGHT_CTL_MSG_MAXLEN_TEMP_STATUS) { - return; + return -EMSGSIZE; } struct bt_mesh_light_ctl_cli *cli = model->user_data; @@ -97,7 +94,7 @@ static void temp_status_handle(struct bt_mesh_model *model, status.current.temp = net_buf_simple_pull_le16(buf); if ((status.current.temp < BT_MESH_LIGHT_TEMP_MIN) || (status.current.temp > BT_MESH_LIGHT_TEMP_MAX)) { - return; + return -EINVAL; } status.current.delta_uv = net_buf_simple_pull_le16(buf); @@ -106,7 +103,7 @@ static void temp_status_handle(struct bt_mesh_model *model, status.target.temp = net_buf_simple_pull_le16(buf); if ((status.target.temp < BT_MESH_LIGHT_TEMP_MIN) || (status.target.temp > BT_MESH_LIGHT_TEMP_MAX)) { - return; + return -EINVAL; } status.target.delta_uv = net_buf_simple_pull_le16(buf); @@ -127,16 +124,13 @@ static void temp_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->temp_status) { cli->handlers->temp_status(cli, ctx, &status); } + + return 0; } -static void default_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG) { - return; - } - struct bt_mesh_light_ctl_cli *cli = model->user_data; struct bt_mesh_light_ctl status; struct bt_mesh_light_ctl *rsp; @@ -145,7 +139,7 @@ static void default_status_handle(struct bt_mesh_model *model, status.temp = net_buf_simple_pull_le16(buf); if ((status.temp < BT_MESH_LIGHT_TEMP_MIN) || (status.temp > BT_MESH_LIGHT_TEMP_MAX)) { - return; + return -EINVAL; } status.delta_uv = net_buf_simple_pull_le16(buf); @@ -159,28 +153,30 @@ static void default_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->default_status) { cli->handlers->default_status(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_light_ctl_cli_op[] = { { BT_MESH_LIGHT_CTL_STATUS, - BT_MESH_LIGHT_CTL_MSG_MINLEN_STATUS, - ctl_status_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTL_MSG_MINLEN_STATUS), + handle_ctl_status, }, { BT_MESH_LIGHT_TEMP_RANGE_STATUS, - BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_STATUS, - temp_range_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_STATUS), + handle_temp_range_status, }, { BT_MESH_LIGHT_TEMP_STATUS, - BT_MESH_LIGHT_CTL_MSG_MINLEN_TEMP_STATUS, - temp_status_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTL_MSG_MINLEN_TEMP_STATUS), + handle_temp_status, }, { BT_MESH_LIGHT_CTL_DEFAULT_STATUS, - BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG, - default_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG), + handle_default_status, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_ctl_srv.c b/subsys/bluetooth/mesh/light_ctl_srv.c index a1dc01770897..0750cc5fbff2 100644 --- a/subsys/bluetooth/mesh/light_ctl_srv.c +++ b/subsys/bluetooth/mesh/light_ctl_srv.c @@ -50,12 +50,12 @@ static void ctl_get(struct bt_mesh_light_ctl_srv *srv, status->remaining_time = MAX(temp.remaining_time, light.remaining_time); } -static void ctl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int ctl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_LIGHT_CTL_MSG_MINLEN_SET && buf->len != BT_MESH_LIGHT_CTL_MSG_MAXLEN_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_light_ctl_srv *srv = model->user_data; @@ -74,7 +74,7 @@ static void ctl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if ((temp.params.temp < BT_MESH_LIGHT_TEMP_MIN) || (temp.params.temp > BT_MESH_LIGHT_TEMP_MAX)) { - return; + return -EINVAL; } if (light.lvl != 0) { @@ -113,31 +113,32 @@ static void ctl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (IS_ENABLED(CONFIG_BT_MESH_SCENE_SRV)) { bt_mesh_scene_invalidate(srv->model); } + + return 0; } -static void handle_ctl_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_ctl_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctl_srv *srv = model->user_data; struct bt_mesh_light_ctl_status status = { 0 }; ctl_get(srv, ctx, &status); bt_mesh_light_ctl_pub(srv, ctx, &status); + + return 0; } -static void handle_ctl_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_ctl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - ctl_set(model, ctx, buf, true); + return ctl_set(model, ctx, buf, true); } -static void handle_ctl_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_ctl_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - ctl_set(model, ctx, buf, false); + return ctl_set(model, ctx, buf, false); } static void range_encode_status(struct net_buf_simple *buf, @@ -186,37 +187,28 @@ static enum bt_mesh_model_status temp_range_set(struct bt_mesh_model *model, return BT_MESH_MODEL_SUCCESS; } -static void handle_temp_range_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_temp_range_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_GET) { - return; - } - temp_range_rsp(model, ctx, BT_MESH_MODEL_SUCCESS); + + return 0; } -static void handle_temp_range_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_temp_range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_SET) { - return; - } - temp_range_rsp(model, ctx, temp_range_set(model, ctx, buf)); + + return 0; } -static void handle_temp_range_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_temp_range_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_SET) { - return; - } - temp_range_set(model, ctx, buf); + + return 0; } static void default_encode_status(struct net_buf_simple *buf, @@ -240,7 +232,7 @@ static void default_rsp(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void default_set(struct bt_mesh_model *model, +static int default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { struct bt_mesh_light_ctl_srv *srv = model->user_data; @@ -253,7 +245,7 @@ static void default_set(struct bt_mesh_model *model, if ((temp.temp < BT_MESH_LIGHT_TEMP_MIN) || (temp.temp > BT_MESH_LIGHT_TEMP_MAX)) { - return; + return -EINVAL; } lightness_srv_default_set(&srv->lightness_srv, ctx, light); @@ -264,65 +256,54 @@ static void default_set(struct bt_mesh_model *model, if (ack) { default_rsp(model, ctx); } + + return 0; } -static void handle_default_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_GET) { - return; - } - default_rsp(model, ctx); + + return 0; } -static void handle_default_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG) { - return; - } - - default_set(model, ctx, buf, true); + return default_set(model, ctx, buf, true); } -static void handle_default_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG) { - return; - } - - default_set(model, ctx, buf, false); + return default_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_light_ctl_srv_op[] = { { BT_MESH_LIGHT_CTL_GET, - BT_MESH_LIGHT_CTL_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_GET), handle_ctl_get, }, { BT_MESH_LIGHT_CTL_SET, - BT_MESH_LIGHT_CTL_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTL_MSG_MINLEN_SET), handle_ctl_set, }, { BT_MESH_LIGHT_CTL_SET_UNACK, - BT_MESH_LIGHT_CTL_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTL_MSG_MINLEN_SET), handle_ctl_set_unack, }, { BT_MESH_LIGHT_TEMP_RANGE_GET, - BT_MESH_LIGHT_CTL_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_GET), handle_temp_range_get, }, { BT_MESH_LIGHT_CTL_DEFAULT_GET, - BT_MESH_LIGHT_CTL_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_GET), handle_default_get, }, BT_MESH_MODEL_OP_END, @@ -331,22 +312,22 @@ const struct bt_mesh_model_op _bt_mesh_light_ctl_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_light_ctl_setup_srv_op[] = { { BT_MESH_LIGHT_TEMP_RANGE_SET, - BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_SET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_SET), handle_temp_range_set, }, { BT_MESH_LIGHT_TEMP_RANGE_SET_UNACK, - BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_SET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_TEMP_RANGE_SET), handle_temp_range_set_unack, }, { BT_MESH_LIGHT_CTL_DEFAULT_SET, - BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG), handle_default_set, }, { BT_MESH_LIGHT_CTL_DEFAULT_SET_UNACK, - BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_DEFAULT_MSG), handle_default_set_unack, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/light_ctrl_cli.c b/subsys/bluetooth/mesh/light_ctrl_cli.c index e446ee34b981..38638c3e825d 100644 --- a/subsys/bluetooth/mesh/light_ctrl_cli.c +++ b/subsys/bluetooth/mesh/light_ctrl_cli.c @@ -17,20 +17,15 @@ struct prop_status_ctx { union prop_value val; }; -static void handle_mode(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_mode(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { bool *ack_buf; struct bt_mesh_light_ctrl_cli *cli = model->user_data; - - if (buf->len != 1) { - return; - } - uint8_t enabled = net_buf_simple_pull_u8(buf); if (enabled > 1) { - return; + return -EINVAL; } if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_LIGHT_CTRL_OP_MODE_STATUS, ctx->addr, @@ -42,23 +37,19 @@ static void handle_mode(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx if (cli->handlers && cli->handlers->mode) { cli->handlers->mode(cli, ctx, enabled); } + + return 0; } -static void handle_occupancy(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_occupancy(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { bool *ack_buf; struct bt_mesh_light_ctrl_cli *cli = model->user_data; - - if (buf->len != 1) { - return; - } - uint8_t enabled = net_buf_simple_pull_u8(buf); if (enabled > 1) { - return; + return -EINVAL; } if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_LIGHT_CTRL_OP_OM_STATUS, ctx->addr, @@ -70,11 +61,12 @@ static void handle_occupancy(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->occupancy_mode) { cli->handlers->occupancy_mode(cli, ctx, enabled); } + + return 0; } -static void handle_light_onoff(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_light_onoff(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_cli *cli = model->user_data; struct bt_mesh_onoff_status status; @@ -83,7 +75,7 @@ static void handle_light_onoff(struct bt_mesh_model *model, uint8_t onoff = net_buf_simple_pull_u8(buf); if (onoff > 1) { - return; + return -EINVAL; } status.present_on_off = onoff; @@ -91,7 +83,7 @@ static void handle_light_onoff(struct bt_mesh_model *model, if (buf->len == 2) { onoff = net_buf_simple_pull_u8(buf); if (onoff > 1) { - return; + return -EINVAL; } status.target_on_off = onoff; @@ -101,7 +93,7 @@ static void handle_light_onoff(struct bt_mesh_model *model, status.target_on_off = onoff; status.remaining_time = 0; } else { - return; + return -EMSGSIZE; } if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_LIGHT_CTRL_OP_LIGHT_ONOFF_STATUS, @@ -113,10 +105,12 @@ static void handle_light_onoff(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->light_onoff) { cli->handlers->light_onoff(cli, ctx, &status); } + + return 0; } -static void handle_prop(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_prop(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_cli *cli = model->user_data; struct prop_status_ctx *rsp; @@ -132,7 +126,7 @@ static void handle_prop(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx if (coeff) { if (buf->len != sizeof(float)) { - return; + return -EINVAL; } memcpy(&value.coeff, @@ -141,12 +135,12 @@ static void handle_prop(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx } else { format = prop_format_get(id); if (!format) { - return; + return -ENOENT; } err = sensor_ch_decode(buf, format, &value.prop); if (err) { - return; + return -EINVAL; } } @@ -164,27 +158,29 @@ static void handle_prop(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx } else if (cli->handlers && cli->handlers->prop) { cli->handlers->prop(cli, ctx, id, &value.prop); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_light_ctrl_cli_op[] = { { BT_MESH_LIGHT_CTRL_OP_MODE_STATUS, - 1, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_MODE_STATUS), handle_mode, }, { BT_MESH_LIGHT_CTRL_OP_OM_STATUS, - 1, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_OM_STATUS), handle_occupancy, }, { BT_MESH_LIGHT_CTRL_OP_LIGHT_ONOFF_STATUS, - 1, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTRL_MSG_MINLEN_LIGHT_ONOFF_STATUS), handle_light_onoff, }, { BT_MESH_LIGHT_CTRL_OP_PROP_STATUS, - 2, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTRL_MSG_MINLEN_PROP_STATUS), handle_prop, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/light_ctrl_srv.c b/subsys/bluetooth/mesh/light_ctrl_srv.c index ae46dcd7f6be..c08c49cc8bdc 100644 --- a/subsys/bluetooth/mesh/light_ctrl_srv.c +++ b/subsys/bluetooth/mesh/light_ctrl_srv.c @@ -750,26 +750,19 @@ static void mode_rsp(struct bt_mesh_light_ctrl_srv *srv, model_send(srv->model, ctx, &rsp); } -static void handle_mode_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_mode_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - if (buf->len != 0) { - return; - } - mode_rsp(srv, ctx); + + return 0; } static int mode_set(struct bt_mesh_light_ctrl_srv *srv, struct net_buf_simple *buf) { - if (buf->len != 1) { - return -EINVAL; - } - uint8_t mode = net_buf_simple_pull_u8(buf); if (mode > 1) { @@ -787,32 +780,28 @@ static int mode_set(struct bt_mesh_light_ctrl_srv *srv, return 0; } -static void handle_mode_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_mode_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; int err; err = mode_set(srv, buf); if (err) { - return; + return err; } mode_rsp(srv, ctx); + + return 0; } -static void handle_mode_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_mode_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - int err; - err = mode_set(srv, buf); - if (err) { - return; - } + return mode_set(srv, buf); } static void om_rsp(struct bt_mesh_light_ctrl_srv *srv, @@ -826,26 +815,19 @@ static void om_rsp(struct bt_mesh_light_ctrl_srv *srv, model_send(srv->model, ctx, &rsp); } -static void handle_om_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_om_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - if (buf->len != 0) { - return; - } - om_rsp(srv, ctx); + + return 0; } static int om_set(struct bt_mesh_light_ctrl_srv *srv, struct net_buf_simple *buf) { - if (buf->len != 1) { - return -EINVAL; - } - uint8_t mode = net_buf_simple_pull_u8(buf); if (mode > 1) { @@ -864,57 +846,49 @@ static int om_set(struct bt_mesh_light_ctrl_srv *srv, return 0; } -static void handle_om_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_om_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; int err; err = om_set(srv, buf); if (err) { - return; + return err; } om_rsp(srv, ctx); + + return 0; } -static void handle_om_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_om_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - int err; - err = om_set(srv, buf); - if (err) { - return; - } + return om_set(srv, buf); } -static void handle_light_onoff_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_light_onoff_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - if (buf->len != 0) { - return; - } - BT_DBG("Get Light OnOff"); light_onoff_status_send(srv, ctx, srv->state); + + return 0; } -static void light_onoff_set(struct bt_mesh_light_ctrl_srv *srv, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int light_onoff_set(struct bt_mesh_light_ctrl_srv *srv, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { uint8_t onoff = net_buf_simple_pull_u8(buf); if (onoff > 1) { - return; + return -EINVAL; } uint8_t tid = net_buf_simple_pull_u8(buf); @@ -945,29 +919,28 @@ static void light_onoff_set(struct bt_mesh_light_ctrl_srv *srv, if (ack) { light_onoff_status_send(srv, ctx, prev_state); } + + return 0; } -static void handle_light_onoff_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_light_onoff_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - light_onoff_set(srv, ctx, buf, true); + return light_onoff_set(srv, ctx, buf, true); } -static void handle_light_onoff_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_light_onoff_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - light_onoff_set(srv, ctx, buf, false); + return light_onoff_set(srv, ctx, buf, false); } -static void handle_sensor_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_sensor_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; int err; @@ -1009,7 +982,7 @@ static void handle_sensor_status(struct bt_mesh_model *model, err = sensor_value_decode(buf, type, &value); if (err) { - return; + return -ENOENT; } BT_DBG("Sensor 0x%04x: %s", id, bt_mesh_sensor_ch_str(&value)); @@ -1037,57 +1010,59 @@ static void handle_sensor_status(struct bt_mesh_model *model, turn_on(srv, NULL, true); } } + + return 0; } const struct bt_mesh_model_op _bt_mesh_light_ctrl_srv_op[] = { { BT_MESH_LIGHT_CTRL_OP_MODE_GET, - 0, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_MODE_GET), handle_mode_get, }, { BT_MESH_LIGHT_CTRL_OP_MODE_SET, - 1, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_MODE_SET), handle_mode_set, }, { BT_MESH_LIGHT_CTRL_OP_MODE_SET_UNACK, - 1, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_MODE_SET), handle_mode_set_unack, }, { BT_MESH_LIGHT_CTRL_OP_OM_GET, - 0, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_OM_GET), handle_om_get, }, { BT_MESH_LIGHT_CTRL_OP_OM_SET, - 1, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_OM_SET), handle_om_set, }, { BT_MESH_LIGHT_CTRL_OP_OM_SET_UNACK, - 1, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_OM_SET), handle_om_set_unack, }, { BT_MESH_LIGHT_CTRL_OP_LIGHT_ONOFF_GET, - 0, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_LIGHT_ONOFF_GET), handle_light_onoff_get, }, { BT_MESH_LIGHT_CTRL_OP_LIGHT_ONOFF_SET, - 2, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTRL_MSG_MINLEN_LIGHT_ONOFF_SET), handle_light_onoff_set, }, { BT_MESH_LIGHT_CTRL_OP_LIGHT_ONOFF_SET_UNACK, - 2, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTRL_MSG_MINLEN_LIGHT_ONOFF_SET), handle_light_onoff_set_unack, }, { BT_MESH_SENSOR_OP_STATUS, - 3, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_STATUS), handle_sensor_status, }, BT_MESH_MODEL_OP_END, @@ -1293,7 +1268,7 @@ static int prop_set(struct net_buf_simple *buf, return 0; } -static void prop_tx(struct bt_mesh_light_ctrl_srv *srv, +static int prop_tx(struct bt_mesh_light_ctrl_srv *srv, struct bt_mesh_msg_ctx *ctx, uint16_t id) { int err; @@ -1306,53 +1281,51 @@ static void prop_tx(struct bt_mesh_light_ctrl_srv *srv, err = prop_get(&buf, srv, id); if (err) { - return; + return -ENOENT; } model_send(srv->setup_srv, ctx, &buf); + + return 0; } -static void handle_prop_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_prop_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - - if (buf->len != 2) { - return; - } - uint16_t id = net_buf_simple_pull_le16(buf); - prop_tx(srv, ctx, id); + return prop_tx(srv, ctx, id); + + return 0; } -static void handle_prop_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_prop_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; - int err; - uint16_t id = net_buf_simple_pull_le16(buf); + int err; err = prop_set(buf, srv, id); + if (err) { + return err; + } - if (!err) { - prop_tx(srv, ctx, id); - prop_tx(srv, NULL, id); + (void)prop_tx(srv, ctx, id); + (void)prop_tx(srv, NULL, id); - if (IS_ENABLED(CONFIG_BT_MESH_SCENE_SRV)) { - bt_mesh_scene_invalidate(srv->model); - } + if (IS_ENABLED(CONFIG_BT_MESH_SCENE_SRV)) { + bt_mesh_scene_invalidate(srv->model); } store(srv, FLAG_STORE_CFG); + + return 0; } -static void handle_prop_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_prop_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_ctrl_srv *srv = model->user_data; int err; @@ -1360,21 +1333,37 @@ static void handle_prop_set_unack(struct bt_mesh_model *model, uint16_t id = net_buf_simple_pull_le16(buf); err = prop_set(buf, srv, id); - if (!err) { - prop_tx(srv, NULL, id); + if (err) { + return err; + } - if (IS_ENABLED(CONFIG_BT_MESH_SCENE_SRV)) { - bt_mesh_scene_invalidate(srv->model); - } + (void)prop_tx(srv, NULL, id); + + if (IS_ENABLED(CONFIG_BT_MESH_SCENE_SRV)) { + bt_mesh_scene_invalidate(srv->model); } store(srv, FLAG_STORE_CFG); + + return 0; } const struct bt_mesh_model_op _bt_mesh_light_ctrl_setup_srv_op[] = { - { BT_MESH_LIGHT_CTRL_OP_PROP_GET, 2, handle_prop_get }, - { BT_MESH_LIGHT_CTRL_OP_PROP_SET, 3, handle_prop_set }, - { BT_MESH_LIGHT_CTRL_OP_PROP_SET_UNACK, 3, handle_prop_set_unack }, + { + BT_MESH_LIGHT_CTRL_OP_PROP_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTRL_MSG_LEN_PROP_GET), + handle_prop_get, + }, + { + BT_MESH_LIGHT_CTRL_OP_PROP_SET, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTRL_MSG_MINLEN_PROP_SET), + handle_prop_set, + }, + { + BT_MESH_LIGHT_CTRL_OP_PROP_SET_UNACK, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTRL_MSG_MINLEN_PROP_SET), + handle_prop_set_unack, + }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_hsl_cli.c b/subsys/bluetooth/mesh/light_hsl_cli.c index 22f5bb2d422d..4c61dfe2ae72 100644 --- a/subsys/bluetooth/mesh/light_hsl_cli.c +++ b/subsys/bluetooth/mesh/light_hsl_cli.c @@ -34,9 +34,8 @@ static int status_decode(struct bt_mesh_light_hsl_cli *cli, return 0; } -static void hsl_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_hsl_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_hsl_cli *cli = model->user_data; struct bt_mesh_light_hsl_status status; @@ -45,17 +44,18 @@ static void hsl_status_handle(struct bt_mesh_model *model, err = status_decode(cli, ctx, buf, BT_MESH_LIGHT_HSL_OP_STATUS, &status); if (err) { - return; + return err; } if (cli->handlers && cli->handlers->status) { cli->handlers->status(cli, ctx, &status); } + + return 0; } -static void hsl_target_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_hsl_target_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_hsl_cli *cli = model->user_data; struct bt_mesh_light_hsl_status status; @@ -64,21 +64,22 @@ static void hsl_target_status_handle(struct bt_mesh_model *model, err = status_decode(cli, ctx, buf, BT_MESH_LIGHT_HSL_OP_TARGET_STATUS, &status); if (err) { - return; + return err; } if (cli->handlers && cli->handlers->target_status) { cli->handlers->target_status(cli, ctx, &status); } + + return 0; } -static void default_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { if (buf->len != BT_MESH_LIGHT_HSL_MSG_MINLEN_STATUS && buf->len != BT_MESH_LIGHT_HSL_MSG_MAXLEN_STATUS) { - return; + return -EMSGSIZE; } struct bt_mesh_light_hsl_cli *cli = model->user_data; @@ -96,16 +97,13 @@ static void default_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->default_status) { cli->handlers->default_status(cli, ctx, &status); } + + return 0; } -static void range_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_STATUS) { - return; - } - struct bt_mesh_light_hsl_cli *cli = model->user_data; struct bt_mesh_light_hsl_range_status status; struct bt_mesh_light_hsl_range_status *rsp; @@ -122,11 +120,12 @@ static void range_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->range_status) { cli->handlers->range_status(cli, ctx, &status); } + + return 0; } -static void hue_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_hue_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_hsl_cli *cli = model->user_data; struct bt_mesh_light_hue_status status; @@ -134,7 +133,7 @@ static void hue_status_handle(struct bt_mesh_model *model, if (buf->len != BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE_STATUS && buf->len != BT_MESH_LIGHT_HSL_MSG_MAXLEN_HUE_STATUS) { - return; + return -EMSGSIZE; } status.current = net_buf_simple_pull_le16(buf); @@ -156,11 +155,12 @@ static void hue_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->hue_status) { cli->handlers->hue_status(cli, ctx, &status); } + + return 0; } -static void saturation_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_saturation_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_hsl_cli *cli = model->user_data; struct bt_mesh_light_sat_status status; @@ -168,7 +168,7 @@ static void saturation_status_handle(struct bt_mesh_model *model, if (buf->len != BT_MESH_LIGHT_HSL_MSG_MINLEN_SAT_STATUS && buf->len != BT_MESH_LIGHT_HSL_MSG_MAXLEN_SAT_STATUS) { - return; + return -EMSGSIZE; } status.current = net_buf_simple_pull_le16(buf); @@ -190,38 +190,40 @@ static void saturation_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->saturation_status) { cli->handlers->saturation_status(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_light_hsl_cli_op[] = { { BT_MESH_LIGHT_HSL_OP_STATUS, - BT_MESH_LIGHT_HSL_MSG_MINLEN_STATUS, - hsl_status_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_STATUS), + handle_hsl_status, }, { BT_MESH_LIGHT_HSL_OP_TARGET_STATUS, - BT_MESH_LIGHT_HSL_MSG_MINLEN_STATUS, - hsl_target_status_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_STATUS), + handle_hsl_target_status, }, { BT_MESH_LIGHT_HSL_OP_DEFAULT_STATUS, - BT_MESH_LIGHT_HSL_MSG_LEN_DEFAULT, - default_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_DEFAULT), + handle_default_status, }, { BT_MESH_LIGHT_HSL_OP_RANGE_STATUS, - BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_STATUS, - range_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_STATUS), + handle_range_status, }, { BT_MESH_LIGHT_HUE_OP_STATUS, - BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE_STATUS, - hue_status_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE_STATUS), + handle_hue_status, }, { BT_MESH_LIGHT_SAT_OP_STATUS, - BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE_STATUS, - saturation_status_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE_STATUS), + handle_saturation_status, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_hsl_srv.c b/subsys/bluetooth/mesh/light_hsl_srv.c index 5a46cc07ccb2..a57082115eeb 100644 --- a/subsys/bluetooth/mesh/light_hsl_srv.c +++ b/subsys/bluetooth/mesh/light_hsl_srv.c @@ -61,23 +61,21 @@ static void hsl_get(struct bt_mesh_light_hsl_srv *srv, &hue, &sat, &lightness, current); } -static void hsl_get_handle(struct bt_mesh_model *model, +static int handle_hsl_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_light_hsl_srv *srv = model->user_data; struct bt_mesh_light_hsl_status status; - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_GET) { - return; - } - hsl_get(srv, ctx, &status); (void)bt_mesh_light_hsl_srv_pub(srv, ctx, &status); + + return 0; } -static void hsl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int hsl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { struct bt_mesh_light_hsl_srv *srv = model->user_data; struct bt_mesh_model_transition transition; @@ -93,7 +91,7 @@ static void hsl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (buf->len != BT_MESH_LIGHT_HSL_MSG_MINLEN_SET && buf->len != BT_MESH_LIGHT_HSL_MSG_MAXLEN_SET) { - return; + return -EMSGSIZE; } set.l.lvl = repr_to_light(net_buf_simple_pull_le16(buf), ACTUAL); @@ -109,7 +107,7 @@ static void hsl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, (void)bt_mesh_light_hsl_srv_pub(srv, ctx, &status); } - return; + return 0; } set.h.transition = model_transition_get(srv->model, &transition, buf); @@ -146,23 +144,25 @@ static void hsl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (IS_ENABLED(CONFIG_BT_MESH_SCENE_SRV)) { bt_mesh_scene_invalidate(srv->model); } + + return 0; } -static void hsl_set_handle(struct bt_mesh_model *model, +static int handle_hsl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - hsl_set(model, ctx, buf, true); + return hsl_set(model, ctx, buf, true); } -static void hsl_set_unack_handle(struct bt_mesh_model *model, +static int handle_hsl_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - hsl_set(model, ctx, buf, false); + return hsl_set(model, ctx, buf, false); } -static void hsl_target_get_handle(struct bt_mesh_model *model, +static int handle_hsl_target_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { @@ -171,10 +171,6 @@ static void hsl_target_get_handle(struct bt_mesh_model *model, struct bt_mesh_light_hue_status hue; struct bt_mesh_light_sat_status sat; - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_GET) { - return; - } - srv->hue.handlers->get(&srv->hue, ctx, &hue); srv->sat.handlers->get(&srv->sat, ctx, &sat); srv->lightness->handlers->light_get(srv->lightness, ctx, &lightness); @@ -187,6 +183,8 @@ static void hsl_target_get_handle(struct bt_mesh_model *model, hsl_status_encode(&rsp, BT_MESH_LIGHT_HSL_OP_TARGET_STATUS, &status); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } static void default_rsp(struct bt_mesh_model *model, @@ -207,7 +205,7 @@ static void default_rsp(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void default_set(struct bt_mesh_model *model, +static int default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_light_hsl_srv *srv = model->user_data; @@ -218,40 +216,36 @@ static void default_set(struct bt_mesh_model *model, lightness_srv_default_set(srv->lightness, ctx, val.lightness); bt_mesh_light_hue_srv_default_set(&srv->hue, ctx, val.hue); bt_mesh_light_sat_srv_default_set(&srv->sat, ctx, val.saturation); + + return 0; } -static void default_get_handle(struct bt_mesh_model *model, +static int handle_default_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_GET) { - return; - } - default_rsp(model, ctx); + + return 0; } -static void default_set_handle(struct bt_mesh_model *model, +static int handle_default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_DEFAULT) { - return; - } - default_set(model, ctx, buf); default_rsp(model, ctx); + + return 0; } -static void default_set_unack_handle(struct bt_mesh_model *model, +static int handle_default_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_DEFAULT) { - return; - } - default_set(model, ctx, buf); + + return 0; } static void range_encode_status(struct net_buf_simple *buf, @@ -286,9 +280,8 @@ static void range_rsp(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static enum bt_mesh_model_status range_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_hsl_srv *srv = model->user_data; struct bt_mesh_light_hsl_range hue, sat; @@ -296,90 +289,90 @@ static enum bt_mesh_model_status range_set(struct bt_mesh_model *model, hue.min = net_buf_simple_pull_le16(buf); hue.max = net_buf_simple_pull_le16(buf); if (hue.max < hue.min) { - return BT_MESH_MODEL_ERROR_INVALID_RANGE_MIN; + return -EINVAL; } sat.min = net_buf_simple_pull_le16(buf); sat.max = net_buf_simple_pull_le16(buf); if (sat.max < sat.min) { - return BT_MESH_MODEL_ERROR_INVALID_RANGE_MIN; + return -EINVAL; } bt_mesh_light_hue_srv_range_set(&srv->hue, ctx, &hue); bt_mesh_light_sat_srv_range_set(&srv->sat, ctx, &sat); - return BT_MESH_MODEL_SUCCESS; + return 0; } -static void range_get_handle(struct bt_mesh_model *model, +static int handle_range_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_GET) { - return; - } - range_rsp(model, ctx, BT_MESH_MODEL_SUCCESS); + + return 0; } -static void range_set_handle(struct bt_mesh_model *model, +static int handle_range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_SET) { - return; - } + int err; /* According to Test specification MMDL/SR/LHSLSE/BI-01-C, ignore * message if max < min: */ - if (range_set(model, ctx, buf) == BT_MESH_MODEL_SUCCESS) { - range_rsp(model, ctx, BT_MESH_MODEL_SUCCESS); + err = range_set(model, ctx, buf); + if (err) { + return err; } + + range_rsp(model, ctx, BT_MESH_MODEL_SUCCESS); + + return 0; } -static void range_set_unack_handle(struct bt_mesh_model *model, +static int handle_range_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_SET) { - return; - } - - range_set(model, ctx, buf); + /* According to Test specification MMDL/SR/LHSLSE/BI-01-C, ignore + * message if max < min: + */ + return range_set(model, ctx, buf); } const struct bt_mesh_model_op _bt_mesh_light_hsl_srv_op[] = { { BT_MESH_LIGHT_HSL_OP_GET, - BT_MESH_LIGHT_HSL_MSG_LEN_GET, - hsl_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_GET), + handle_hsl_get, }, { BT_MESH_LIGHT_HSL_OP_SET, - BT_MESH_LIGHT_HSL_MSG_MINLEN_SET, - hsl_set_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_SET), + handle_hsl_set, }, { BT_MESH_LIGHT_HSL_OP_SET_UNACK, - BT_MESH_LIGHT_HSL_MSG_MINLEN_SET, - hsl_set_unack_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_SET), + handle_hsl_set_unack, }, { BT_MESH_LIGHT_HSL_OP_TARGET_GET, - BT_MESH_LIGHT_HSL_MSG_LEN_GET, - hsl_target_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_GET), + handle_hsl_target_get, }, { BT_MESH_LIGHT_HSL_OP_DEFAULT_GET, - BT_MESH_LIGHT_HSL_MSG_LEN_GET, - default_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_GET), + handle_default_get, }, { BT_MESH_LIGHT_HSL_OP_RANGE_GET, - BT_MESH_LIGHT_HSL_MSG_LEN_GET, - range_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_GET), + handle_range_get, }, BT_MESH_MODEL_OP_END, }; @@ -387,23 +380,23 @@ const struct bt_mesh_model_op _bt_mesh_light_hsl_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_light_hsl_setup_srv_op[] = { { BT_MESH_LIGHT_HSL_OP_DEFAULT_SET, - BT_MESH_LIGHT_HSL_MSG_LEN_DEFAULT, - default_set_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_DEFAULT), + handle_default_set, }, { BT_MESH_LIGHT_HSL_OP_DEFAULT_SET_UNACK, - BT_MESH_LIGHT_HSL_MSG_LEN_DEFAULT, - default_set_unack_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_DEFAULT), + handle_default_set_unack, }, { BT_MESH_LIGHT_HSL_OP_RANGE_SET, - BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_SET, - range_set_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_SET), + handle_range_set, }, { BT_MESH_LIGHT_HSL_OP_RANGE_SET_UNACK, - BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_SET, - range_set_unack_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_RANGE_SET), + handle_range_set_unack, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_hue_srv.c b/subsys/bluetooth/mesh/light_hue_srv.c index 4622c1ce0f32..dda8abe3eda3 100644 --- a/subsys/bluetooth/mesh/light_hue_srv.c +++ b/subsys/bluetooth/mesh/light_hue_srv.c @@ -65,12 +65,12 @@ static void encode_status(struct net_buf_simple *buf, } } -static void hue_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int hue_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE && buf->len != BT_MESH_LIGHT_HSL_MSG_MAXLEN_HUE) { - return; + return -EMSGSIZE; } struct bt_mesh_light_hue_srv *srv = model->user_data; @@ -95,7 +95,7 @@ static void hue_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, */ srv->handlers->get(srv, NULL, &status); (void)bt_mesh_light_hue_srv_pub(srv, ctx, &status); - return; + return 0; } if (buf->len == 2) { @@ -133,52 +133,49 @@ static void hue_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (IS_ENABLED(CONFIG_BT_MESH_SCENE_SRV)) { bt_mesh_scene_invalidate(srv->model); } + + return 0; } -static void hue_get_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_hue_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_GET) { - return; - } - struct bt_mesh_light_hue_srv *srv = model->user_data; struct bt_mesh_light_hue_status status = { 0 }; srv->handlers->get(srv, ctx, &status); (void)bt_mesh_light_hue_srv_pub(srv, ctx, &status); + + return 0; } -static void hue_set_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_hue_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - hue_set(model, ctx, buf, true); + return hue_set(model, ctx, buf, true); } -static void hue_set_unack_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_hue_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - hue_set(model, ctx, buf, false); + return hue_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_light_hue_srv_op[] = { { BT_MESH_LIGHT_HUE_OP_GET, - BT_MESH_LIGHT_HSL_MSG_LEN_GET, - hue_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_GET), + handle_hue_get, }, { BT_MESH_LIGHT_HUE_OP_SET, - BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE, - hue_set_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE), + handle_hue_set, }, { BT_MESH_LIGHT_HUE_OP_SET_UNACK, - BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE, - hue_set_unack_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_HUE), + handle_hue_set_unack, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_sat_srv.c b/subsys/bluetooth/mesh/light_sat_srv.c index 968a7f120409..2316c2f7e318 100644 --- a/subsys/bluetooth/mesh/light_sat_srv.c +++ b/subsys/bluetooth/mesh/light_sat_srv.c @@ -65,12 +65,12 @@ static void encode_status(struct net_buf_simple *buf, } } -static void sat_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int sat_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_LIGHT_HSL_MSG_MINLEN_SAT && buf->len != BT_MESH_LIGHT_HSL_MSG_MAXLEN_SAT) { - return; + return -EMSGSIZE; } struct bt_mesh_light_sat_srv *srv = model->user_data; @@ -94,7 +94,7 @@ static void sat_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, */ srv->handlers->get(srv, NULL, &status); (void)bt_mesh_light_sat_srv_pub(srv, ctx, &status); - return; + return 0; } if (buf->len == 2) { @@ -132,52 +132,52 @@ static void sat_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (IS_ENABLED(CONFIG_BT_MESH_SCENE_SRV)) { bt_mesh_scene_invalidate(srv->model); } + + return 0; } -static void sat_get_handle(struct bt_mesh_model *model, +static int handle_sat_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_HSL_MSG_LEN_GET) { - return; - } - struct bt_mesh_light_sat_srv *srv = model->user_data; struct bt_mesh_light_sat_status status = { 0 }; srv->handlers->get(srv, ctx, &status); (void)bt_mesh_light_sat_srv_pub(srv, ctx, &status); + + return 0; } -static void sat_set_handle(struct bt_mesh_model *model, +static int handle_sat_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - sat_set(model, ctx, buf, true); + return sat_set(model, ctx, buf, true); } -static void sat_set_unack_handle(struct bt_mesh_model *model, +static int handle_sat_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - sat_set(model, ctx, buf, false); + return sat_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_light_sat_srv_op[] = { { BT_MESH_LIGHT_SAT_OP_GET, - BT_MESH_LIGHT_HSL_MSG_LEN_GET, - sat_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_HSL_MSG_LEN_GET), + handle_sat_get, }, { BT_MESH_LIGHT_SAT_OP_SET, - BT_MESH_LIGHT_HSL_MSG_MINLEN_SAT, - sat_set_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_SAT), + handle_sat_set, }, { BT_MESH_LIGHT_SAT_OP_SET_UNACK, - BT_MESH_LIGHT_HSL_MSG_MINLEN_SAT, - sat_set_unack_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_HSL_MSG_MINLEN_SAT), + handle_sat_set_unack, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_temp_srv.c b/subsys/bluetooth/mesh/light_temp_srv.c index 688c3430fac0..4949ee152a3e 100644 --- a/subsys/bluetooth/mesh/light_temp_srv.c +++ b/subsys/bluetooth/mesh/light_temp_srv.c @@ -64,12 +64,12 @@ static void encode_status(struct net_buf_simple *buf, } } -static void temp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int temp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_LIGHT_CTL_MSG_MINLEN_TEMP_SET && buf->len != BT_MESH_LIGHT_CTL_MSG_MAXLEN_TEMP_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_light_temp_srv *srv = model->user_data; @@ -83,7 +83,7 @@ static void temp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if ((set.params.temp < BT_MESH_LIGHT_TEMP_MIN) || (set.params.temp > BT_MESH_LIGHT_TEMP_MAX)) { - return; + return -EINVAL; } if (tid_check_and_update(&srv->prev_transaction, tid, ctx) != 0) { @@ -106,52 +106,52 @@ static void temp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (ack) { (void)bt_mesh_light_temp_srv_pub(srv, ctx, &status); } + + return 0; } -static void temp_get_handle(struct bt_mesh_model *model, +static int handle_temp_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_CTL_MSG_LEN_GET) { - return; - } - struct bt_mesh_light_temp_srv *srv = model->user_data; struct bt_mesh_light_temp_status status = { 0 }; srv->handlers->get(srv, ctx, &status); (void)bt_mesh_light_temp_srv_pub(srv, ctx, &status); + + return 0; } -static void temp_set_handle(struct bt_mesh_model *model, +static int handle_temp_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - temp_set(model, ctx, buf, true); + return temp_set(model, ctx, buf, true); } -static void temp_set_unack_handle(struct bt_mesh_model *model, +static int handle_temp_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - temp_set(model, ctx, buf, false); + return temp_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_light_temp_srv_op[] = { { BT_MESH_LIGHT_TEMP_GET, - BT_MESH_LIGHT_CTL_MSG_LEN_GET, - temp_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_CTL_MSG_LEN_GET), + handle_temp_get, }, { BT_MESH_LIGHT_TEMP_SET, - BT_MESH_LIGHT_CTL_MSG_MINLEN_TEMP_SET, - temp_set_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTL_MSG_MINLEN_TEMP_SET), + handle_temp_set, }, { BT_MESH_LIGHT_TEMP_SET_UNACK, - BT_MESH_LIGHT_CTL_MSG_MINLEN_TEMP_SET, - temp_set_unack_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_CTL_MSG_MINLEN_TEMP_SET), + handle_temp_set_unack, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_xyl_cli.c b/subsys/bluetooth/mesh/light_xyl_cli.c index c15bacbbddc4..db13fefe516a 100644 --- a/subsys/bluetooth/mesh/light_xyl_cli.c +++ b/subsys/bluetooth/mesh/light_xyl_cli.c @@ -16,7 +16,7 @@ static int status_decode(struct bt_mesh_light_xyl_cli *cli, if (buf->len != BT_MESH_LIGHT_XYL_MSG_MINLEN_STATUS && buf->len != BT_MESH_LIGHT_XYL_MSG_MAXLEN_STATUS) { - return -EAGAIN; + return -EMSGSIZE; } status->params.lightness = net_buf_simple_pull_le16(buf); @@ -34,9 +34,8 @@ static int status_decode(struct bt_mesh_light_xyl_cli *cli, return 0; } -static void xyl_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_xyl_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_xyl_cli *cli = model->user_data; struct bt_mesh_light_xyl_status status; @@ -47,11 +46,12 @@ static void xyl_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->xyl_status && !err) { cli->handlers->xyl_status(cli, ctx, &status); } + + return err; } -static void target_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_target_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_light_xyl_cli *cli = model->user_data; struct bt_mesh_light_xyl_status status; @@ -62,16 +62,13 @@ static void target_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->target_status && !err) { cli->handlers->target_status(cli, ctx, &status); } + + return err; } -static void default_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_XYL_MSG_LEN_DEFAULT) { - return; - } - struct bt_mesh_light_xyl_cli *cli = model->user_data; struct bt_mesh_light_xyl status; struct bt_mesh_light_xyl *rsp; @@ -89,16 +86,13 @@ static void default_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->default_status) { cli->handlers->default_status(cli, ctx, &status); } + + return 0; } -static void range_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_XYL_MSG_LEN_RANGE_STATUS) { - return; - } - struct bt_mesh_light_xyl_cli *cli = model->user_data; struct bt_mesh_light_xyl_range_status status; struct bt_mesh_light_xyl_range_status *rsp; @@ -118,28 +112,30 @@ static void range_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->range_status) { cli->handlers->range_status(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_light_xyl_cli_op[] = { { BT_MESH_LIGHT_XYL_OP_STATUS, - BT_MESH_LIGHT_XYL_MSG_MINLEN_STATUS, - xyl_status_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_XYL_MSG_MINLEN_STATUS), + handle_xyl_status, }, { BT_MESH_LIGHT_XYL_OP_TARGET_STATUS, - BT_MESH_LIGHT_XYL_MSG_MINLEN_STATUS, - target_status_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_XYL_MSG_MINLEN_STATUS), + handle_target_status, }, { BT_MESH_LIGHT_XYL_OP_DEFAULT_STATUS, - BT_MESH_LIGHT_XYL_MSG_LEN_DEFAULT, - default_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_DEFAULT), + handle_default_status, }, { BT_MESH_LIGHT_XYL_OP_RANGE_STATUS, - BT_MESH_LIGHT_XYL_MSG_LEN_RANGE_STATUS, - range_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_RANGE_STATUS), + handle_range_status, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/light_xyl_srv.c b/subsys/bluetooth/mesh/light_xyl_srv.c index ad256cf35e92..0d6d33c95107 100644 --- a/subsys/bluetooth/mesh/light_xyl_srv.c +++ b/subsys/bluetooth/mesh/light_xyl_srv.c @@ -87,12 +87,12 @@ static void xyl_rsp(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *rx_ctx, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void xyl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int xyl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { if (buf->len != BT_MESH_LIGHT_XYL_MSG_MINLEN_SET && buf->len != BT_MESH_LIGHT_XYL_MSG_MAXLEN_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_light_xyl_srv *srv = model->user_data; @@ -108,17 +108,8 @@ static void xyl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, set.params.y = net_buf_simple_pull_le16(buf); uint8_t tid = net_buf_simple_pull_u8(buf); - if (set.params.x > srv->range.max.x) { - set.params.x = srv->range.max.x; - } else if (set.params.x < srv->range.min.x) { - set.params.x = srv->range.min.x; - } - - if (set.params.y > srv->range.max.y) { - set.params.y = srv->range.max.y; - } else if (set.params.y < srv->range.min.y) { - set.params.y = srv->range.min.y; - } + set.params.x = CLAMP(set.params.x, srv->range.min.x, srv->range.max.x); + set.params.y = CLAMP(set.params.y, srv->range.min.y, srv->range.max.y); if (tid_check_and_update(&srv->prev_transaction, tid, ctx) != 0) { /* If this is the same transaction, we don't need to send it @@ -128,7 +119,7 @@ static void xyl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, xyl_get(srv, NULL, &xyl_status); xyl_rsp(model, ctx, &xyl_status, BT_MESH_LIGHT_XYL_OP_STATUS); - return; + return 0; } } @@ -154,45 +145,41 @@ static void xyl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (ack) { xyl_rsp(model, ctx, &xyl_status, BT_MESH_LIGHT_XYL_OP_STATUS); } + + return 0; } -static void xyl_get_handle(struct bt_mesh_model *model, +static int handle_xyl_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_XYL_MSG_LEN_GET) { - return; - } - struct bt_mesh_light_xyl_srv *srv = model->user_data; struct bt_mesh_light_xyl_status status = { 0 }; xyl_get(srv, ctx, &status); xyl_rsp(model, ctx, &status, BT_MESH_LIGHT_XYL_OP_STATUS); + + return 0; } -static void xyl_set_handle(struct bt_mesh_model *model, +static int handle_xyl_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - xyl_set(model, ctx, buf, true); + return xyl_set(model, ctx, buf, true); } -static void xyl_set_unack_handle(struct bt_mesh_model *model, +static int handle_xyl_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - xyl_set(model, ctx, buf, false); + return xyl_set(model, ctx, buf, false); } -static void target_get_handle(struct bt_mesh_model *model, +static int handle_target_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_XYL_MSG_LEN_GET) { - return; - } - struct bt_mesh_light_xyl_srv *srv = model->user_data; struct bt_mesh_light_xy_status status = { 0 }; struct bt_mesh_lightness_status light = { 0 }; @@ -208,6 +195,8 @@ static void target_get_handle(struct bt_mesh_model *model, }; xyl_rsp(model, ctx, &xyl_status, BT_MESH_LIGHT_XYL_OP_TARGET_STATUS); + + return 0; } static void default_encode_status(struct bt_mesh_light_xyl_srv *srv, @@ -230,14 +219,10 @@ static void default_rsp(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void default_set(struct bt_mesh_model *model, +static int default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_LIGHT_XYL_MSG_LEN_DEFAULT) { - return; - } - struct bt_mesh_light_xyl_srv *srv = model->user_data; struct bt_mesh_light_xy old_default = srv->xy_default; uint16_t light = repr_to_light(net_buf_simple_pull_le16(buf), ACTUAL); @@ -257,31 +242,31 @@ static void default_set(struct bt_mesh_model *model, if (ack) { default_rsp(model, ctx); } + + return 0; } -static void default_get_handle(struct bt_mesh_model *model, +static int handle_default_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_XYL_MSG_LEN_GET) { - return; - } - default_rsp(model, ctx); + + return 0; } -static void default_set_handle(struct bt_mesh_model *model, +static int handle_default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - default_set(model, ctx, buf, true); + return default_set(model, ctx, buf, true); } -static void default_set_unack_handle(struct bt_mesh_model *model, +static int handle_default_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - default_set(model, ctx, buf, false); + return default_set(model, ctx, buf, false); } static void range_encode_status(struct net_buf_simple *buf, @@ -308,13 +293,9 @@ static void range_rsp(struct bt_mesh_model *model, (void)bt_mesh_model_send(model, rx_ctx, &msg, NULL, NULL); } -static void range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_LIGHT_XYL_MSG_LEN_RANGE_SET) { - return; - } - struct bt_mesh_light_xyl_srv *srv = model->user_data; struct bt_mesh_light_xy_range new_range; struct bt_mesh_light_xy_range old_range; @@ -327,8 +308,7 @@ static void range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if ((new_range.min.x > new_range.max.x) || (new_range.min.y > new_range.max.y)) { - status_code = BT_MESH_MODEL_STATUS_INVALID; - return; + return -EINVAL; } status_code = BT_MESH_MODEL_SUCCESS; @@ -345,63 +325,63 @@ static void range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, if (ack) { range_rsp(model, ctx, status_code); } + + return 0; } -static void range_get_handle(struct bt_mesh_model *model, +static int handle_range_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHT_XYL_MSG_LEN_GET) { - return; - } - range_rsp(model, ctx, BT_MESH_MODEL_SUCCESS); + + return 0; } -static void range_set_handle(struct bt_mesh_model *model, +static int handle_range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - range_set(model, ctx, buf, true); + return range_set(model, ctx, buf, true); } -static void range_set_unack_handle(struct bt_mesh_model *model, +static int handle_range_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - range_set(model, ctx, buf, false); + return range_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_light_xyl_srv_op[] = { { BT_MESH_LIGHT_XYL_OP_GET, - BT_MESH_LIGHT_XYL_MSG_LEN_GET, - xyl_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_GET), + handle_xyl_get, }, { BT_MESH_LIGHT_XYL_OP_SET, - BT_MESH_LIGHT_XYL_MSG_MINLEN_SET, - xyl_set_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_XYL_MSG_MINLEN_SET), + handle_xyl_set, }, { BT_MESH_LIGHT_XYL_OP_SET_UNACK, - BT_MESH_LIGHT_XYL_MSG_MINLEN_SET, - xyl_set_unack_handle, + BT_MESH_LEN_MIN(BT_MESH_LIGHT_XYL_MSG_MINLEN_SET), + handle_xyl_set_unack, }, { BT_MESH_LIGHT_XYL_OP_TARGET_GET, - BT_MESH_LIGHT_XYL_MSG_LEN_GET, - target_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_GET), + handle_target_get, }, { BT_MESH_LIGHT_XYL_OP_DEFAULT_GET, - BT_MESH_LIGHT_XYL_MSG_LEN_GET, - default_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_GET), + handle_default_get, }, { BT_MESH_LIGHT_XYL_OP_RANGE_GET, - BT_MESH_LIGHT_XYL_MSG_LEN_GET, - range_get_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_GET), + handle_range_get, }, BT_MESH_MODEL_OP_END, }; @@ -409,23 +389,23 @@ const struct bt_mesh_model_op _bt_mesh_light_xyl_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_light_xyl_setup_srv_op[] = { { BT_MESH_LIGHT_XYL_OP_DEFAULT_SET, - BT_MESH_LIGHT_XYL_MSG_LEN_DEFAULT, - default_set_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_DEFAULT), + handle_default_set, }, { BT_MESH_LIGHT_XYL_OP_DEFAULT_SET_UNACK, - BT_MESH_LIGHT_XYL_MSG_LEN_DEFAULT, - default_set_unack_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_DEFAULT), + handle_default_set_unack, }, { BT_MESH_LIGHT_XYL_OP_RANGE_SET, - BT_MESH_LIGHT_XYL_MSG_LEN_RANGE_SET, - range_set_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_RANGE_SET), + handle_range_set, }, { BT_MESH_LIGHT_XYL_OP_RANGE_SET_UNACK, - BT_MESH_LIGHT_XYL_MSG_LEN_RANGE_SET, - range_set_unack_handle, + BT_MESH_LEN_EXACT(BT_MESH_LIGHT_XYL_MSG_LEN_RANGE_SET), + handle_range_set_unack, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/lightness_cli.c b/subsys/bluetooth/mesh/lightness_cli.c index 301912c63a6f..b948d901969e 100644 --- a/subsys/bluetooth/mesh/lightness_cli.c +++ b/subsys/bluetooth/mesh/lightness_cli.c @@ -7,12 +7,12 @@ #include "model_utils.h" #include "lightness_internal.h" -static void light_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, enum light_repr repr) +static int light_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, enum light_repr repr) { if (buf->len != BT_MESH_LIGHTNESS_MSG_MINLEN_STATUS && buf->len != BT_MESH_LIGHTNESS_MSG_MAXLEN_STATUS) { - return; + return -EMSGSIZE; } struct bt_mesh_lightness_cli *cli = model->user_data; @@ -39,30 +39,25 @@ static void light_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ct if (cli->handlers && cli->handlers->light_status) { cli->handlers->light_status(cli, ctx, &status); } + + return 0; } -static void handle_light_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_light_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - light_status(model, ctx, buf, ACTUAL); + return light_status(model, ctx, buf, ACTUAL); } -static void handle_light_linear_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_light_linear_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - light_status(model, ctx, buf, LINEAR); + return light_status(model, ctx, buf, LINEAR); } -static void handle_last_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_last_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_LAST_STATUS) { - return; - } - struct bt_mesh_lightness_cli *cli = model->user_data; uint16_t last = repr_to_light(net_buf_simple_pull_le16(buf), ACTUAL); uint16_t *rsp; @@ -76,16 +71,13 @@ static void handle_last_status(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->last_light_status) { cli->handlers->last_light_status(cli, ctx, last); } + + return 0; } -static void handle_default_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_STATUS) { - return; - } - struct bt_mesh_lightness_cli *cli = model->user_data; uint16_t default_lvl = repr_to_light(net_buf_simple_pull_le16(buf), ACTUAL); @@ -100,16 +92,13 @@ static void handle_default_status(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->default_status) { cli->handlers->default_status(cli, ctx, default_lvl); } + + return 0; } -static void handle_range_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_RANGE_STATUS) { - return; - } - struct bt_mesh_lightness_cli *cli = model->user_data; struct bt_mesh_lightness_range_status status; struct bt_mesh_lightness_range_status *rsp; @@ -127,32 +116,34 @@ static void handle_range_status(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->range_status) { cli->handlers->range_status(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_lightness_cli_op[] = { { BT_MESH_LIGHTNESS_OP_STATUS, - BT_MESH_LIGHTNESS_MSG_MINLEN_STATUS, + BT_MESH_LEN_MIN(BT_MESH_LIGHTNESS_MSG_MINLEN_STATUS), handle_light_status, }, { BT_MESH_LIGHTNESS_OP_LINEAR_STATUS, - BT_MESH_LIGHTNESS_MSG_MINLEN_STATUS, + BT_MESH_LEN_MIN(BT_MESH_LIGHTNESS_MSG_MINLEN_STATUS), handle_light_linear_status, }, { BT_MESH_LIGHTNESS_OP_LAST_STATUS, - BT_MESH_LIGHTNESS_MSG_LEN_LAST_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_LAST_STATUS), handle_last_status, }, { BT_MESH_LIGHTNESS_OP_DEFAULT_STATUS, - BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_STATUS), handle_default_status, }, { BT_MESH_LIGHTNESS_OP_RANGE_STATUS, - BT_MESH_LIGHTNESS_MSG_LEN_RANGE_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_RANGE_STATUS), handle_range_status, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/lightness_srv.c b/subsys/bluetooth/mesh/lightness_srv.c index 279cc9f5bf07..f127b494ba22 100644 --- a/subsys/bluetooth/mesh/lightness_srv.c +++ b/subsys/bluetooth/mesh/lightness_srv.c @@ -133,14 +133,9 @@ static void rsp_lightness_status(struct bt_mesh_model *model, bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); } -static void handle_light_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, enum light_repr repr) +static int handle_light_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, enum light_repr repr) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_GET) { - return; - } - BT_DBG("%s", repr_str[repr]); struct bt_mesh_lightness_srv *srv = model->user_data; @@ -149,20 +144,20 @@ static void handle_light_get(struct bt_mesh_model *model, srv->handlers->light_get(srv, ctx, &status); rsp_lightness_status(model, ctx, &status, repr); + + return 0; } -static void handle_actual_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_actual_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - handle_light_get(model, ctx, buf, ACTUAL); + return handle_light_get(model, ctx, buf, ACTUAL); } -static void handle_linear_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_linear_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - handle_light_get(model, ctx, buf, LINEAR); + return handle_light_get(model, ctx, buf, LINEAR); } void lightness_srv_disable_control(struct bt_mesh_lightness_srv *srv) @@ -226,14 +221,12 @@ void lightness_srv_change_lvl(struct bt_mesh_lightness_srv *srv, } } -static void lightness_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack, - enum light_repr repr) +static int lightness_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack, enum light_repr repr) { if (buf->len != BT_MESH_LIGHTNESS_MSG_MINLEN_SET && buf->len != BT_MESH_LIGHTNESS_MSG_MAXLEN_SET) { - return; + return -EMSGSIZE; } struct bt_mesh_lightness_srv *srv = model->user_data; @@ -270,44 +263,37 @@ static void lightness_set(struct bt_mesh_model *model, if (ack) { rsp_lightness_status(model, ctx, &status, repr); } + + return 0; } -static void handle_actual_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_actual_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - lightness_set(model, ctx, buf, true, ACTUAL); + return lightness_set(model, ctx, buf, true, ACTUAL); } -static void handle_actual_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_actual_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - lightness_set(model, ctx, buf, false, ACTUAL); + return lightness_set(model, ctx, buf, false, ACTUAL); } -static void handle_linear_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_linear_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - lightness_set(model, ctx, buf, true, LINEAR); + return lightness_set(model, ctx, buf, true, LINEAR); } -static void handle_linear_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_linear_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - lightness_set(model, ctx, buf, false, LINEAR); + return lightness_set(model, ctx, buf, false, LINEAR); } -static void handle_last_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_last_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_LAST_GET) { - return; - } - struct bt_mesh_lightness_srv *srv = model->user_data; BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_LIGHTNESS_OP_LAST_STATUS, @@ -316,16 +302,13 @@ static void handle_last_get(struct bt_mesh_model *model, net_buf_simple_add_le16(&rsp, light_to_repr(srv->last, ACTUAL)); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_default_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_GET) { - return; - } - struct bt_mesh_lightness_srv *srv = model->user_data; BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_LIGHTNESS_OP_DEFAULT_STATUS, @@ -335,6 +318,8 @@ static void handle_default_get(struct bt_mesh_model *model, net_buf_simple_add_le16(&rsp, light_to_repr(srv->default_light, ACTUAL)); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } void lightness_srv_default_set(struct bt_mesh_lightness_srv *srv, @@ -356,19 +341,15 @@ void lightness_srv_default_set(struct bt_mesh_lightness_srv *srv, store_state(srv); } -static void set_default(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int set_default(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_SET) { - return; - } - struct bt_mesh_lightness_srv *srv = model->user_data; uint16_t new = repr_to_light(net_buf_simple_pull_le16(buf), ACTUAL); lightness_srv_default_set(srv, ctx, new); if (!ack) { - return; + return 0; } BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_LIGHTNESS_OP_DEFAULT_STATUS, @@ -377,30 +358,25 @@ static void set_default(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx net_buf_simple_add_le16(&rsp, srv->default_light); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_default_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_default(model, ctx, buf, true); + return set_default(model, ctx, buf, true); } -static void handle_default_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_default_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_default(model, ctx, buf, false); + return set_default(model, ctx, buf, false); } -static void handle_range_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_RANGE_GET) { - return; - } - struct bt_mesh_lightness_srv *srv = model->user_data; BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_LIGHTNESS_OP_RANGE_STATUS, @@ -412,15 +388,13 @@ static void handle_range_get(struct bt_mesh_model *model, net_buf_simple_add_le16(&rsp, light_to_repr(srv->range.max, ACTUAL)); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, bool ack) +static int set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { - if (buf->len != BT_MESH_LIGHTNESS_MSG_LEN_RANGE_SET) { - return; - } - struct bt_mesh_lightness_srv *srv = model->user_data; struct bt_mesh_lightness_range new; @@ -432,7 +406,7 @@ static void set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, * parameters. */ if (new.min == 0 || new.max == 0 || new.min > new.max) { - return; + return -EINVAL; } if (new.min != srv->range.min || new.max != srv->range.max) { @@ -447,7 +421,7 @@ static void set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, } if (!ack) { - return; + return 0; } BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_LIGHTNESS_OP_RANGE_STATUS, @@ -459,66 +433,66 @@ static void set_range(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, net_buf_simple_add_le16(&rsp, light_to_repr(srv->range.max, ACTUAL)); bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_range_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_range(model, ctx, buf, true); + return set_range(model, ctx, buf, true); } -static void handle_range_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_range_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - set_range(model, ctx, buf, false); + return set_range(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_lightness_srv_op[] = { { BT_MESH_LIGHTNESS_OP_GET, - BT_MESH_LIGHTNESS_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_GET), handle_actual_get, }, { BT_MESH_LIGHTNESS_OP_SET, - BT_MESH_LIGHTNESS_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_LIGHTNESS_MSG_MINLEN_SET), handle_actual_set, }, { BT_MESH_LIGHTNESS_OP_SET_UNACK, - BT_MESH_LIGHTNESS_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_LIGHTNESS_MSG_MINLEN_SET), handle_actual_set_unack, }, { BT_MESH_LIGHTNESS_OP_LINEAR_GET, - BT_MESH_LIGHTNESS_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_GET), handle_linear_get, }, { BT_MESH_LIGHTNESS_OP_LINEAR_SET, - BT_MESH_LIGHTNESS_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_LIGHTNESS_MSG_MINLEN_SET), handle_linear_set, }, { BT_MESH_LIGHTNESS_OP_LINEAR_SET_UNACK, - BT_MESH_LIGHTNESS_MSG_MINLEN_SET, + BT_MESH_LEN_MIN(BT_MESH_LIGHTNESS_MSG_MINLEN_SET), handle_linear_set_unack, }, { BT_MESH_LIGHTNESS_OP_LAST_GET, - BT_MESH_LIGHTNESS_MSG_LEN_LAST_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_LAST_GET), handle_last_get, }, { BT_MESH_LIGHTNESS_OP_DEFAULT_GET, - BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_GET), handle_default_get, }, { BT_MESH_LIGHTNESS_OP_RANGE_GET, - BT_MESH_LIGHTNESS_MSG_LEN_RANGE_GET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_RANGE_GET), handle_range_get, }, BT_MESH_MODEL_OP_END, @@ -527,22 +501,22 @@ const struct bt_mesh_model_op _bt_mesh_lightness_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_lightness_setup_srv_op[] = { { BT_MESH_LIGHTNESS_OP_DEFAULT_SET, - BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_SET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_SET), handle_default_set, }, { BT_MESH_LIGHTNESS_OP_DEFAULT_SET_UNACK, - BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_SET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_DEFAULT_SET), handle_default_set_unack, }, { BT_MESH_LIGHTNESS_OP_RANGE_SET, - BT_MESH_LIGHTNESS_MSG_LEN_RANGE_SET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_RANGE_SET), handle_range_set, }, { BT_MESH_LIGHTNESS_OP_RANGE_SET_UNACK, - BT_MESH_LIGHTNESS_MSG_LEN_RANGE_SET, + BT_MESH_LEN_EXACT(BT_MESH_LIGHTNESS_MSG_LEN_RANGE_SET), handle_range_set_unack, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/scene_cli.c b/subsys/bluetooth/mesh/scene_cli.c index 2ed679cadf74..97bca39aa5d9 100644 --- a/subsys/bluetooth/mesh/scene_cli.c +++ b/subsys/bluetooth/mesh/scene_cli.c @@ -7,7 +7,7 @@ #include #include "model_utils.h" -static void scene_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int handle_scene_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_scene_state *rsp; @@ -24,7 +24,7 @@ static void scene_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ct state.remaining_time = 0; } else { /* Invalid size */ - return; + return -EMSGSIZE; } if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_SCENE_OP_STATUS, ctx->addr, @@ -36,10 +36,12 @@ static void scene_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ct if (cli->status) { cli->status(cli, ctx, &state); } + + return 0; } -static void scene_reg(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_scene_reg(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scene_register *rsp; struct bt_mesh_scene_cli *cli = model->user_data; @@ -47,6 +49,10 @@ static void scene_reg(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, reg.status = net_buf_simple_pull_u8(buf); reg.current = net_buf_simple_pull_le16(buf); + if (buf->len % 2) { + return -EMSGSIZE; + } + reg.count = buf->len / sizeof(uint16_t); reg.scenes = net_buf_simple_pull_mem(buf, buf->len); @@ -82,18 +88,20 @@ static void scene_reg(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, for (int i = 0; i < reg.count; i++) { reg.scenes[i] = sys_cpu_to_le16(reg.scenes[i]); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_scene_cli_op[] = { { BT_MESH_SCENE_OP_STATUS, - BT_MESH_SCENE_MSG_MINLEN_STATUS, - scene_status, + BT_MESH_LEN_MIN(BT_MESH_SCENE_MSG_MINLEN_STATUS), + handle_scene_status, }, { BT_MESH_SCENE_OP_REGISTER_STATUS, - BT_MESH_SCENE_MSG_MINLEN_REGISTER_STATUS, - scene_reg, + BT_MESH_LEN_MIN(BT_MESH_SCENE_MSG_MINLEN_REGISTER_STATUS), + handle_scene_reg, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/scene_srv.c b/subsys/bluetooth/mesh/scene_srv.c index 8b946cf6aca2..e10250c54b6e 100644 --- a/subsys/bluetooth/mesh/scene_srv.c +++ b/subsys/bluetooth/mesh/scene_srv.c @@ -153,15 +153,17 @@ static int scene_status_send(struct bt_mesh_scene_srv *srv, return model_send(srv->model, ctx, &buf); } -static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scene_srv *srv = model->user_data; (void)scene_status_send(srv, ctx, BT_MESH_SCENE_SUCCESS); + + return 0; } -static void scene_recall(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int scene_recall(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { struct bt_mesh_scene_srv *srv = model->user_data; @@ -174,7 +176,7 @@ static void scene_recall(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ct scene = net_buf_simple_pull_le16(buf); if (scene == BT_MESH_SCENE_NONE) { - return; /* Prohibited */ + return -EINVAL; /* Prohibited */ } tid = net_buf_simple_pull_u8(buf); @@ -183,7 +185,7 @@ static void scene_recall(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ct if (tid_check_and_update(&srv->tid, tid, ctx)) { BT_DBG("Duplicate TID"); scene_status_send(srv, ctx, BT_MESH_SCENE_SUCCESS); - return; + return 0; } err = bt_mesh_scene_srv_set(srv, scene, has_trans ? &transition : NULL); @@ -198,20 +200,20 @@ static void scene_recall(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ct /* Publish */ scene_status_send(srv, NULL, status); } + + return 0; } -static void handle_recall(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_recall(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - scene_recall(model, ctx, buf, true); + return scene_recall(model, ctx, buf, true); } -static void handle_recall_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_recall_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - scene_recall(model, ctx, buf, false); + return scene_recall(model, ctx, buf, false); } static int scene_register_status_send(struct bt_mesh_scene_srv *srv, @@ -232,34 +234,35 @@ static int scene_register_status_send(struct bt_mesh_scene_srv *srv, return model_send(srv->model, ctx, &buf); } -static void handle_register_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_register_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scene_srv *srv = model->user_data; - scene_register_status_send(srv, ctx, BT_MESH_SCENE_SUCCESS); + (void)scene_register_status_send(srv, ctx, BT_MESH_SCENE_SUCCESS); + + return 0; } const struct bt_mesh_model_op _bt_mesh_scene_srv_op[] = { { BT_MESH_SCENE_OP_GET, - BT_MESH_SCENE_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_SCENE_MSG_LEN_GET), handle_get, }, { BT_MESH_SCENE_OP_RECALL, - BT_MESH_SCENE_MSG_MINLEN_RECALL, + BT_MESH_LEN_MIN(BT_MESH_SCENE_MSG_MINLEN_RECALL), handle_recall, }, { BT_MESH_SCENE_OP_RECALL_UNACK, - BT_MESH_SCENE_MSG_MINLEN_RECALL, + BT_MESH_LEN_MIN(BT_MESH_SCENE_MSG_MINLEN_RECALL), handle_recall_unack, }, { BT_MESH_SCENE_OP_REGISTER_GET, - BT_MESH_SCENE_MSG_LEN_REGISTER_GET, + BT_MESH_LEN_EXACT(BT_MESH_SCENE_MSG_LEN_REGISTER_GET), handle_register_get, }, BT_MESH_MODEL_OP_END, @@ -563,8 +566,8 @@ static void scene_delete(struct bt_mesh_scene_srv *srv, uint16_t *scene) *scene = srv->all[--srv->count]; } -static void handle_store(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_store(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scene_srv *srv = model->user_data; enum bt_mesh_scene_status status; @@ -572,34 +575,34 @@ static void handle_store(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ct scene_number = net_buf_simple_pull_le16(buf); if (scene_number == BT_MESH_SCENE_NONE) { - return; + return -EINVAL; } status = scene_store(srv, scene_number); scene_register_status_send(srv, ctx, status); + + return 0; } -static void handle_store_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_store_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scene_srv *srv = model->user_data; uint16_t scene_number; scene_number = net_buf_simple_pull_le16(buf); if (scene_number == BT_MESH_SCENE_NONE) { - return; + return -EINVAL; } (void)scene_store(srv, scene_number); + + return 0; } -static void handle_delete(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int delete_scene(struct bt_mesh_scene_srv *srv, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - struct bt_mesh_scene_srv *srv = model->user_data; - enum bt_mesh_scene_status status; uint16_t *scene; scene = scene_find(srv, net_buf_simple_pull_le16(buf)); @@ -607,43 +610,52 @@ static void handle_delete(struct bt_mesh_model *model, scene_delete(srv, scene); } - status = BT_MESH_SCENE_SUCCESS; - - scene_register_status_send(srv, ctx, status); + return 0; } -static void handle_delete_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_delete(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scene_srv *srv = model->user_data; - uint16_t *scene; + int err; - scene = scene_find(srv, net_buf_simple_pull_le16(buf)); - if (scene != BT_MESH_SCENE_NONE) { - scene_delete(srv, scene); + err = delete_scene(srv, ctx, buf); + if (err) { + return err; } + + scene_register_status_send(srv, ctx, BT_MESH_SCENE_SUCCESS); + + return 0; +} + +static int handle_delete_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) +{ + struct bt_mesh_scene_srv *srv = model->user_data; + + return delete_scene(srv, ctx, buf); } const struct bt_mesh_model_op _bt_mesh_scene_setup_srv_op[] = { { BT_MESH_SCENE_OP_STORE, - BT_MESH_SCENE_MSG_LEN_STORE, + BT_MESH_LEN_EXACT(BT_MESH_SCENE_MSG_LEN_STORE), handle_store, }, { BT_MESH_SCENE_OP_STORE_UNACK, - BT_MESH_SCENE_MSG_LEN_STORE, + BT_MESH_LEN_EXACT(BT_MESH_SCENE_MSG_LEN_STORE), handle_store_unack, }, { BT_MESH_SCENE_OP_DELETE, - BT_MESH_SCENE_MSG_LEN_DELETE, + BT_MESH_LEN_EXACT(BT_MESH_SCENE_MSG_LEN_DELETE), handle_delete, }, { BT_MESH_SCENE_OP_DELETE_UNACK, - BT_MESH_SCENE_MSG_LEN_DELETE, + BT_MESH_LEN_EXACT(BT_MESH_SCENE_MSG_LEN_DELETE), handle_delete_unack, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/scheduler_cli.c b/subsys/bluetooth/mesh/scheduler_cli.c index 15258c629a7a..d61c4de896f7 100644 --- a/subsys/bluetooth/mesh/scheduler_cli.c +++ b/subsys/bluetooth/mesh/scheduler_cli.c @@ -8,18 +8,13 @@ #include "scheduler_internal.h" #include "model_utils.h" -static void status_op(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scheduler_cli *cli = model->user_data; uint16_t schedules; uint16_t *rsp; - if (buf->len != BT_MESH_SCHEDULER_MSG_LEN_STATUS) { - return; - } - schedules = net_buf_simple_pull_le16(buf); if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_SCHEDULER_OP_STATUS, ctx->addr, @@ -31,11 +26,12 @@ static void status_op(struct bt_mesh_model *model, if (cli->status_handler) { cli->status_handler(cli, ctx, schedules); } + + return 0; } -static void action_status_op(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_action_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scheduler_cli *cli = model->user_data; struct bt_mesh_schedule_entry action = {0}; @@ -44,7 +40,7 @@ static void action_status_op(struct bt_mesh_model *model, if (buf->len != BT_MESH_SCHEDULER_MSG_LEN_ACTION_STATUS && buf->len != BT_MESH_SCHEDULER_MSG_LEN_ACTION_STATUS_REDUCED) { - return; + return -EMSGSIZE; } if (buf->len == BT_MESH_SCHEDULER_MSG_LEN_ACTION_STATUS) { @@ -66,18 +62,20 @@ static void action_status_op(struct bt_mesh_model *model, buf->len == BT_MESH_SCHEDULER_MSG_LEN_ACTION_STATUS ? &action : NULL); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_scheduler_cli_op[] = { { BT_MESH_SCHEDULER_OP_STATUS, - BT_MESH_SCHEDULER_MSG_LEN_STATUS, - status_op, + BT_MESH_LEN_EXACT(BT_MESH_SCHEDULER_MSG_LEN_STATUS), + handle_status, }, { BT_MESH_SCHEDULER_OP_ACTION_STATUS, - BT_MESH_SCHEDULER_MSG_LEN_ACTION_STATUS_REDUCED, - action_status_op, + BT_MESH_LEN_MIN(BT_MESH_SCHEDULER_MSG_LEN_ACTION_STATUS_REDUCED), + handle_action_status, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/scheduler_srv.c b/subsys/bluetooth/mesh/scheduler_srv.c index d0fe43d10919..7ff3c020fb86 100644 --- a/subsys/bluetooth/mesh/scheduler_srv.c +++ b/subsys/bluetooth/mesh/scheduler_srv.c @@ -586,10 +586,8 @@ static int send_scheduler_action_status(struct bt_mesh_model *model, return model_send(model, ctx, &buf); } -static void action_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf, - bool ack) +static int action_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf, bool ack) { struct bt_mesh_scheduler_srv *srv = model->user_data; uint8_t idx; @@ -606,7 +604,7 @@ static void action_set(struct bt_mesh_model *model, (tmp.action > BT_MESH_SCHEDULER_SCENE_RECALL && tmp.action != BT_MESH_SCHEDULER_NO_ACTIONS) || idx >= BT_MESH_SCHEDULER_ACTION_ENTRY_COUNT) { - return; + return -EINVAL; } srv->sch_reg[idx] = tmp; @@ -635,55 +633,58 @@ static void action_set(struct bt_mesh_model *model, if (ack) { /* reply on the action set command */ send_scheduler_action_status(model, ctx, idx, false); } + + return 0; } -static void handle_scheduler_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_scheduler_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { BT_DBG("Rx: scheduler server get"); send_scheduler_status(model, ctx); + + return 0; } -static void handle_scheduler_action_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_scheduler_action_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_scheduler_srv *srv = model->user_data; uint8_t idx = net_buf_simple_pull_u8(buf); if (idx >= BT_MESH_SCHEDULER_ACTION_ENTRY_COUNT) { - return; + return -ENOENT; } BT_DBG("Rx: scheduler server action index %d get", idx); send_scheduler_action_status(model, ctx, idx, !is_entry_defined(srv, idx)); + + return 0; } -static void handle_scheduler_action_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_scheduler_action_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - action_set(model, ctx, buf, true); + return action_set(model, ctx, buf, true); } -static void handle_scheduler_action_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_scheduler_action_set_unack(struct bt_mesh_model *model, + struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - action_set(model, ctx, buf, false); + return action_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_scheduler_srv_op[] = { { BT_MESH_SCHEDULER_OP_GET, - BT_MESH_SCHEDULER_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_SCHEDULER_MSG_LEN_GET), handle_scheduler_get, }, { BT_MESH_SCHEDULER_OP_ACTION_GET, - BT_MESH_SCHEDULER_MSG_LEN_ACTION_GET, + BT_MESH_LEN_EXACT(BT_MESH_SCHEDULER_MSG_LEN_ACTION_GET), handle_scheduler_action_get, }, BT_MESH_MODEL_OP_END, @@ -692,12 +693,12 @@ const struct bt_mesh_model_op _bt_mesh_scheduler_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_scheduler_setup_srv_op[] = { { BT_MESH_SCHEDULER_OP_ACTION_SET, - BT_MESH_SCHEDULER_MSG_LEN_ACTION_SET, + BT_MESH_LEN_EXACT(BT_MESH_SCHEDULER_MSG_LEN_ACTION_SET), handle_scheduler_action_set, }, { BT_MESH_SCHEDULER_OP_ACTION_SET_UNACK, - BT_MESH_SCHEDULER_MSG_LEN_ACTION_SET, + BT_MESH_LEN_EXACT(BT_MESH_SCHEDULER_MSG_LEN_ACTION_SET), handle_scheduler_action_set_unack, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/sensor_cli.c b/subsys/bluetooth/mesh/sensor_cli.c index 7f7c834a44fd..ffe308338ddd 100644 --- a/subsys/bluetooth/mesh/sensor_cli.c +++ b/subsys/bluetooth/mesh/sensor_cli.c @@ -59,12 +59,11 @@ static void unknown_type(struct bt_mesh_sensor_cli *cli, } } -static void handle_descriptor_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_descriptor_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { if (buf->len != 2 && buf->len % 8) { - return; + return -EMSGSIZE; } struct bt_mesh_sensor_cli *cli = model->user_data; @@ -101,11 +100,12 @@ static void handle_descriptor_status(struct bt_mesh_model *model, ack_ctx->count = count; bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } + + return 0; } -static void handle_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_cli *cli = model->user_data; struct sensor_data_list_rsp *rsp = NULL; @@ -137,7 +137,7 @@ static void handle_status(struct bt_mesh_model *model, if (buf->len < length) { BT_WARN("Invalid length for 0x%04x: %u", id, length); - return; + return -EMSGSIZE; } net_buf_simple_pull(buf, length); unknown_type(cli, ctx, id, BT_MESH_SENSOR_OP_STATUS); @@ -149,7 +149,7 @@ static void handle_status(struct bt_mesh_model *model, if (length != expected_len) { BT_WARN("Invalid length for 0x%04x: %u (expected %u)", id, length, expected_len); - return; + return -EMSGSIZE; } struct sensor_value value[CONFIG_BT_MESH_SENSOR_CHANNELS_MAX]; @@ -157,7 +157,7 @@ static void handle_status(struct bt_mesh_model *model, err = sensor_value_decode(buf, type, value); if (err) { BT_ERR("Invalid format, err=%d", err); - return; /* Invalid format, should ignore message */ + return err; /* Invalid format, should ignore message */ } if (cli->cb && cli->cb->data) { @@ -178,6 +178,8 @@ static void handle_status(struct bt_mesh_model *model, rsp->count = count; bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } + + return 0; } static int parse_series_entry(const struct bt_mesh_sensor_type *type, @@ -214,9 +216,8 @@ static int parse_series_entry(const struct bt_mesh_sensor_type *type, return sensor_value_decode(buf, type, entry->value); } -static void handle_column_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_column_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_cli *cli = model->user_data; struct series_data_rsp *rsp; @@ -229,13 +230,13 @@ static void handle_column_status(struct bt_mesh_model *model, type = bt_mesh_sensor_type_get(id); if (!type) { unknown_type(cli, ctx, id, BT_MESH_SENSOR_OP_COLUMN_STATUS); - return; + return -ENOENT; } col_format = bt_mesh_sensor_column_format_get(type); if (!col_format) { BT_WARN("Received unsupported column format 0x%04x", id); - return; + return -ENOENT; } struct bt_mesh_sensor_series_entry entry; @@ -247,7 +248,7 @@ static void handle_column_status(struct bt_mesh_model *model, } if (err) { - return; /* Invalid format, should ignore message */ + return err; /* Invalid format, should ignore message */ } if (cli->cb && cli->cb->series_entry) { @@ -267,11 +268,12 @@ static void handle_column_status(struct bt_mesh_model *model, } bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } + + return 0; } -static void handle_series_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_series_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_cli *cli = model->user_data; const struct bt_mesh_sensor_format *col_format; @@ -283,7 +285,7 @@ static void handle_series_status(struct bt_mesh_model *model, type = bt_mesh_sensor_type_get(id); if (!type) { unknown_type(cli, ctx, id, BT_MESH_SENSOR_OP_SERIES_STATUS); - return; + return -ENOENT; } if (bt_mesh_msg_ack_ctx_match(&cli->ack_ctx, BT_MESH_SENSOR_OP_SERIES_STATUS, ctx->addr, @@ -302,7 +304,7 @@ static void handle_series_status(struct bt_mesh_model *model, bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } - return; + return -ENOENT; } size_t val_len = (col_format->size * 2) + sensor_value_len(type); @@ -315,7 +317,7 @@ static void handle_series_status(struct bt_mesh_model *model, err = parse_series_entry(type, col_format, buf, &entry); if (err) { BT_ERR("Failed parsing column %u (err: %d)", i, err); - return; + return err; } if (cli->cb && cli->cb->series_entry) { @@ -331,11 +333,12 @@ static void handle_series_status(struct bt_mesh_model *model, rsp->count = count; bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } + + return 0; } -static void handle_cadence_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_cadence_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_cli *cli = model->user_data; struct cadence_rsp *rsp; @@ -346,7 +349,7 @@ static void handle_cadence_status(struct bt_mesh_model *model, if (!type) { unknown_type(cli, ctx, id, BT_MESH_SENSOR_OP_CADENCE_STATUS); - return; + return -ENOENT; } if (buf->len == 0 || type->channel_count != 1) { @@ -360,7 +363,7 @@ static void handle_cadence_status(struct bt_mesh_model *model, err = sensor_cadence_decode(buf, type, &cadence.fast_period_div, &cadence.min_int, &cadence.threshold); if (err) { - return; + return err; } if (cli->cb && cli->cb->cadence) { @@ -379,17 +382,18 @@ static void handle_cadence_status(struct bt_mesh_model *model, bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } + + return 0; } -static void handle_settings_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_settings_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_cli *cli = model->user_data; struct settings_rsp *rsp; if (buf->len % 2) { - return; + return -EMSGSIZE; } uint16_t id = net_buf_simple_pull_le16(buf); @@ -397,7 +401,7 @@ static void handle_settings_status(struct bt_mesh_model *model, if (!type) { unknown_type(cli, ctx, id, BT_MESH_SENSOR_OP_SETTINGS_STATUS); - return; + return -ENOENT; } /* The list may be unaligned: */ @@ -421,11 +425,12 @@ static void handle_settings_status(struct bt_mesh_model *model, rsp->count = count; bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } + + return 0; } -static void handle_setting_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_setting_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_cli *cli = model->user_data; struct setting_rsp *rsp; @@ -442,14 +447,14 @@ static void handle_setting_status(struct bt_mesh_model *model, access = net_buf_simple_pull_u8(buf); if (access != 0x01 && access != 0x03) { - return; + return -EINVAL; } const struct bt_mesh_sensor_type *type = bt_mesh_sensor_type_get(id); if (!type) { unknown_type(cli, ctx, id, BT_MESH_SENSOR_OP_SETTING_STATUS); - return; + return -ENOENT; } @@ -457,7 +462,7 @@ static void handle_setting_status(struct bt_mesh_model *model, if (!setting.type) { unknown_type( cli, ctx, setting_id, BT_MESH_SENSOR_OP_SETTING_STATUS); - return; + return -ENOENT; } setting.writable = (access == 0x03); @@ -472,7 +477,7 @@ static void handle_setting_status(struct bt_mesh_model *model, err = sensor_value_decode(buf, setting.type, setting.value); if (err) { - return; + return err; } if (cli->cb && cli->cb->setting_status) { @@ -486,42 +491,44 @@ static void handle_setting_status(struct bt_mesh_model *model, *rsp->setting = setting; bt_mesh_msg_ack_ctx_rx(&cli->ack_ctx); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_sensor_cli_op[] = { { BT_MESH_SENSOR_OP_DESCRIPTOR_STATUS, - BT_MESH_SENSOR_MSG_MINLEN_DESCRIPTOR_STATUS, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_DESCRIPTOR_STATUS), handle_descriptor_status, }, { BT_MESH_SENSOR_OP_STATUS, - BT_MESH_SENSOR_MSG_MINLEN_STATUS, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_STATUS), handle_status, }, { BT_MESH_SENSOR_OP_COLUMN_STATUS, - BT_MESH_SENSOR_MSG_MINLEN_COLUMN_STATUS, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_COLUMN_STATUS), handle_column_status, }, { BT_MESH_SENSOR_OP_SERIES_STATUS, - BT_MESH_SENSOR_MSG_MINLEN_SERIES_STATUS, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_SERIES_STATUS), handle_series_status, }, { BT_MESH_SENSOR_OP_CADENCE_STATUS, - BT_MESH_SENSOR_MSG_MINLEN_CADENCE_STATUS, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_CADENCE_STATUS), handle_cadence_status, }, { BT_MESH_SENSOR_OP_SETTINGS_STATUS, - BT_MESH_SENSOR_MSG_MINLEN_SETTINGS_STATUS, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_SETTINGS_STATUS), handle_settings_status, }, { BT_MESH_SENSOR_OP_SETTING_STATUS, - BT_MESH_SENSOR_MSG_MINLEN_SETTING_STATUS, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_SETTING_STATUS), handle_setting_status, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/sensor_srv.c b/subsys/bluetooth/mesh/sensor_srv.c index 39556a7bdc6c..efa358bcb006 100644 --- a/subsys/bluetooth/mesh/sensor_srv.c +++ b/subsys/bluetooth/mesh/sensor_srv.c @@ -120,14 +120,14 @@ static int buf_status_add(struct bt_mesh_sensor *sensor, return err; } -static void handle_descriptor_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_descriptor_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_srv *srv = model->user_data; - if (buf->len != 0 && buf->len != 2) { - return; + if (buf->len != BT_MESH_SENSOR_MSG_MINLEN_DESCRIPTOR_GET && + buf->len != BT_MESH_SENSOR_MSG_MAXLEN_DESCRIPTOR_GET) { + return -EMSGSIZE; } NET_BUF_SIMPLE_DEFINE(rsp, BT_MESH_TX_SDU_MAX); @@ -139,7 +139,7 @@ static void handle_descriptor_get(struct bt_mesh_model *model, uint16_t id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } sensor = sensor_get(srv, id); @@ -165,15 +165,18 @@ static void handle_descriptor_get(struct bt_mesh_model *model, respond: bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_srv *srv = model->user_data; - if (buf->len != 0 && buf->len != 2) { - return; + if (buf->len != BT_MESH_SENSOR_MSG_MINLEN_GET && + buf->len != BT_MESH_SENSOR_MSG_MAXLEN_GET) { + return -EMSGSIZE; } NET_BUF_SIMPLE_DEFINE(rsp, BT_MESH_TX_SDU_MAX); @@ -185,7 +188,7 @@ static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, uint16_t id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } sensor = sensor_get(srv, id); @@ -205,6 +208,8 @@ static void handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, respond: bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } static const struct bt_mesh_sensor_column * @@ -221,21 +226,16 @@ column_get(const struct bt_mesh_sensor_series *series, return NULL; } -static void handle_column_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_column_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_srv *srv = model->user_data; int err; - if (buf->len < 2) { - return; - } - uint16_t id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } struct bt_mesh_sensor *sensor = sensor_get(srv, id); @@ -261,7 +261,7 @@ static void handle_column_get(struct bt_mesh_model *model, err = sensor_ch_decode(buf, col_format, &col_x); if (err) { - return; + return err; } BT_DBG("Column %s", bt_mesh_sensor_ch_str(&col_x)); @@ -276,28 +276,25 @@ static void handle_column_get(struct bt_mesh_model *model, err = sensor_column_encode(&rsp, sensor, ctx, col); if (err) { BT_WARN("Failed encoding sensor column: %d", err); - return; + return err; } respond: bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void handle_series_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_series_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_srv *srv = model->user_data; const struct bt_mesh_sensor_format *col_format; - if (buf->len < 2) { - return; - } - uint16_t id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } struct bt_mesh_sensor *sensor = sensor_get(srv, id); @@ -325,18 +322,18 @@ static void handle_series_get(struct bt_mesh_model *model, err = sensor_ch_decode(buf, col_format, &range.start); if (err) { BT_WARN("Range start decode failed: %d", err); - return; + return err; } err = sensor_ch_decode(buf, col_format, &range.end); if (err) { BT_WARN("Range end decode failed: %d", err); - return; + return err; } } else if (buf->len != 0) { /* invalid length */ BT_WARN("Invalid length (%u)", buf->len); - return; + return -EMSGSIZE; } for (uint32_t i = 0; i < sensor->series.column_count; ++i) { @@ -354,41 +351,42 @@ static void handle_series_get(struct bt_mesh_model *model, if (err) { BT_WARN("Failed encoding: %d", err); - return; + return err; } } respond: bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } const struct bt_mesh_model_op _bt_mesh_sensor_srv_op[] = { { BT_MESH_SENSOR_OP_DESCRIPTOR_GET, - BT_MESH_SENSOR_MSG_MINLEN_DESCRIPTOR_GET, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_DESCRIPTOR_GET), handle_descriptor_get, }, { BT_MESH_SENSOR_OP_GET, - BT_MESH_SENSOR_MSG_MINLEN_GET, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_GET), handle_get, }, { BT_MESH_SENSOR_OP_COLUMN_GET, - BT_MESH_SENSOR_MSG_MINLEN_COLUMN_GET, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_COLUMN_GET), handle_column_get, }, { BT_MESH_SENSOR_OP_SERIES_GET, - BT_MESH_SENSOR_MSG_MINLEN_SERIES_GET, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_SERIES_GET), handle_series_get, }, BT_MESH_MODEL_OP_END, }; -static void handle_cadence_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_cadence_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_srv *srv = model->user_data; struct bt_mesh_sensor *sensor; @@ -401,7 +399,7 @@ static void handle_cadence_get(struct bt_mesh_model *model, id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } net_buf_simple_add_le16(&rsp, id); @@ -416,14 +414,16 @@ static void handle_cadence_get(struct bt_mesh_model *model, sensor->state.min_int, &sensor->state.threshold); if (err) { - return; + return err; } respond: bt_mesh_model_send(srv->model, ctx, &rsp, NULL, NULL); + + return 0; } -static void cadence_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int cadence_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { struct bt_mesh_sensor_srv *srv = model->user_data; @@ -436,7 +436,7 @@ static void cadence_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } net_buf_simple_add_le16(&rsp, id); @@ -455,7 +455,7 @@ static void cadence_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx &threshold); if (err) { BT_WARN("Invalid cadence"); - return; + return err; } BT_DBG("Min int: %u div: %u " @@ -480,7 +480,7 @@ static void cadence_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx sensor->state.min_int, &sensor->state.threshold); if (err) { - return; + return err; } model_send(model, NULL, &rsp); @@ -489,32 +489,31 @@ static void cadence_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx if (ack) { bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); } + + return 0; } -static void handle_cadence_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_cadence_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - cadence_set(model, ctx, buf, true); + return cadence_set(model, ctx, buf, true); } -static void handle_cadence_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_cadence_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - cadence_set(model, ctx, buf, false); + return cadence_set(model, ctx, buf, false); } -static void handle_settings_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_settings_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_srv *srv = model->user_data; uint16_t id = net_buf_simple_pull_le16(buf); if (id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } BT_DBG("0x%04x", id); @@ -540,6 +539,8 @@ static void handle_settings_get(struct bt_mesh_model *model, respond: bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } static const struct bt_mesh_sensor_setting * @@ -553,9 +554,8 @@ setting_get(struct bt_mesh_sensor *sensor, uint16_t setting_id) return NULL; } -static void handle_setting_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_setting_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_sensor_srv *srv = model->user_data; uint16_t id = net_buf_simple_pull_le16(buf); @@ -564,7 +564,7 @@ static void handle_setting_get(struct bt_mesh_model *model, if (id == BT_MESH_PROP_ID_PROHIBITED || setting_id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_SENSOR_OP_SETTING_STATUS, @@ -604,9 +604,11 @@ static void handle_setting_get(struct bt_mesh_model *model, respond: bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); + + return 0; } -static void setting_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, +static int setting_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf, bool ack) { struct bt_mesh_sensor_srv *srv = model->user_data; @@ -616,7 +618,7 @@ static void setting_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx if (id == BT_MESH_PROP_ID_PROHIBITED || setting_id == BT_MESH_PROP_ID_PROHIBITED) { - return; + return -EINVAL; } BT_MESH_MODEL_BUF_DEFINE(rsp, BT_MESH_SENSOR_OP_SETTING_STATUS, @@ -646,7 +648,7 @@ static void setting_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx setting->type->id, err); /* Invalid parameters: ignore this message */ - return; + return err; } setting->set(sensor, setting, ctx, values); @@ -673,38 +675,59 @@ static void setting_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx if (ack) { bt_mesh_model_send(model, ctx, &rsp, NULL, NULL); } + + return 0; } -static void handle_setting_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_setting_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - setting_set(model, ctx, buf, true); + return setting_set(model, ctx, buf, true); } -static void handle_setting_set_unack(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_setting_set_unack(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - setting_set(model, ctx, buf, false); + return setting_set(model, ctx, buf, false); } const struct bt_mesh_model_op _bt_mesh_sensor_setup_srv_op[] = { - { BT_MESH_SENSOR_OP_CADENCE_GET, BT_MESH_SENSOR_MSG_LEN_CADENCE_GET, - handle_cadence_get }, - { BT_MESH_SENSOR_OP_CADENCE_SET, BT_MESH_SENSOR_MSG_MINLEN_CADENCE_SET, - handle_cadence_set }, - { BT_MESH_SENSOR_OP_CADENCE_SET_UNACKNOWLEDGED, - BT_MESH_SENSOR_MSG_MINLEN_CADENCE_SET, handle_cadence_set_unack }, - { BT_MESH_SENSOR_OP_SETTINGS_GET, BT_MESH_SENSOR_MSG_LEN_SETTINGS_GET, - handle_settings_get }, - { BT_MESH_SENSOR_OP_SETTING_GET, BT_MESH_SENSOR_MSG_LEN_SETTING_GET, - handle_setting_get }, - { BT_MESH_SENSOR_OP_SETTING_SET, BT_MESH_SENSOR_MSG_MINLEN_SETTING_SET, - handle_setting_set }, - { BT_MESH_SENSOR_OP_SETTING_SET_UNACKNOWLEDGED, - BT_MESH_SENSOR_MSG_MINLEN_SETTING_SET, handle_setting_set_unack }, + { + BT_MESH_SENSOR_OP_CADENCE_GET, + BT_MESH_LEN_EXACT(BT_MESH_SENSOR_MSG_LEN_CADENCE_GET), + handle_cadence_get, + }, + { + BT_MESH_SENSOR_OP_CADENCE_SET, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_CADENCE_SET), + handle_cadence_set, + }, + { + BT_MESH_SENSOR_OP_CADENCE_SET_UNACKNOWLEDGED, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_CADENCE_SET), + handle_cadence_set_unack, + }, + { + BT_MESH_SENSOR_OP_SETTINGS_GET, + BT_MESH_LEN_EXACT(BT_MESH_SENSOR_MSG_LEN_SETTINGS_GET), + handle_settings_get, + }, + { + BT_MESH_SENSOR_OP_SETTING_GET, + BT_MESH_LEN_EXACT(BT_MESH_SENSOR_MSG_LEN_SETTING_GET), + handle_setting_get, + }, + { + BT_MESH_SENSOR_OP_SETTING_SET, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_SETTING_SET), + handle_setting_set, + }, + { + BT_MESH_SENSOR_OP_SETTING_SET_UNACKNOWLEDGED, + BT_MESH_LEN_MIN(BT_MESH_SENSOR_MSG_MINLEN_SETTING_SET), + handle_setting_set_unack, + }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/time_cli.c b/subsys/bluetooth/mesh/time_cli.c index 1e8a5d152837..c9e24f2e819c 100644 --- a/subsys/bluetooth/mesh/time_cli.c +++ b/subsys/bluetooth/mesh/time_cli.c @@ -8,14 +8,10 @@ #include "time_internal.h" #include "model_utils.h" -static void handle_status(struct bt_mesh_model *model, +static int handle_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { - if (buf->len != BT_MESH_TIME_MSG_LEN_TIME_STATUS) { - return; - } - struct bt_mesh_time_cli *cli = model->user_data; struct bt_mesh_time_status status; struct bt_mesh_time_status *rsp; @@ -31,16 +27,13 @@ static void handle_status(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->time_status) { cli->handlers->time_status(cli, ctx, &status); } + + return 0; } -static void time_role_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_time_role_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_TIME_MSG_LEN_TIME_ROLE_STATUS) { - return; - } - struct bt_mesh_time_cli *cli = model->user_data; enum bt_mesh_time_role status; uint8_t *rsp; @@ -56,16 +49,13 @@ static void time_role_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->time_role_status) { cli->handlers->time_role_status(cli, ctx, status); } + + return 0; } -static void time_zone_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_time_zone_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_TIME_MSG_LEN_TIME_ZONE_STATUS) { - return; - } - struct bt_mesh_time_cli *cli = model->user_data; struct bt_mesh_time_zone_status status; struct bt_mesh_time_zone_status *rsp; @@ -85,16 +75,13 @@ static void time_zone_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->time_zone_status) { cli->handlers->time_zone_status(cli, ctx, &status); } + + return 0; } -static void tai_utc_delta_status_handle(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_tai_utc_delta_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { - if (buf->len != BT_MESH_TIME_MSG_LEN_TAI_UTC_DELTA_STATUS) { - return; - } - struct bt_mesh_time_cli *cli = model->user_data; struct bt_mesh_time_tai_utc_delta_status status; struct bt_mesh_time_tai_utc_delta_status *rsp; @@ -114,28 +101,30 @@ static void tai_utc_delta_status_handle(struct bt_mesh_model *model, if (cli->handlers && cli->handlers->tai_utc_delta_status) { cli->handlers->tai_utc_delta_status(cli, ctx, &status); } + + return 0; } const struct bt_mesh_model_op _bt_mesh_time_cli_op[] = { { BT_MESH_TIME_OP_TIME_STATUS, - BT_MESH_TIME_MSG_LEN_TIME_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TIME_STATUS), handle_status, }, { BT_MESH_TIME_OP_TIME_ROLE_STATUS, - BT_MESH_TIME_MSG_LEN_TIME_ROLE_STATUS, - time_role_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TIME_ROLE_STATUS), + handle_time_role_status, }, { BT_MESH_TIME_OP_TIME_ZONE_STATUS, - BT_MESH_TIME_MSG_LEN_TIME_ZONE_STATUS, - time_zone_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TIME_ZONE_STATUS), + handle_time_zone_status, }, { BT_MESH_TIME_OP_TAI_UTC_DELTA_STATUS, - BT_MESH_TIME_MSG_LEN_TAI_UTC_DELTA_STATUS, - tai_utc_delta_status_handle, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TAI_UTC_DELTA_STATUS), + handle_tai_utc_delta_status, }, BT_MESH_MODEL_OP_END, }; diff --git a/subsys/bluetooth/mesh/time_srv.c b/subsys/bluetooth/mesh/time_srv.c index 796c83ae9cee..286b381ba26f 100644 --- a/subsys/bluetooth/mesh/time_srv.c +++ b/subsys/bluetooth/mesh/time_srv.c @@ -187,15 +187,15 @@ static int send_time_status(struct bt_mesh_model *model, return model_send(model, ctx, &msg); } -static void handle_time_status(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_time_status(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_time_srv *srv = model->user_data; if ((srv->data.role != BT_MESH_TIME_CLIENT) && (srv->data.role != BT_MESH_TIME_RELAY)) { - return; + /* Not relevant for this role, ignore. */ + return 0; } struct bt_mesh_time_status status; @@ -205,7 +205,7 @@ static void handle_time_status(struct bt_mesh_model *model, if (status.is_authority <= srv->data.sync.status.is_authority && srv->data.sync.status.uncertainty < status.uncertainty) { /* The new time status is not an improvement, ignore. */ - return; + return 0; } srv->data.sync.uptime = k_uptime_get(); @@ -220,18 +220,20 @@ static void handle_time_status(struct bt_mesh_model *model, if (srv->data.role == BT_MESH_TIME_RELAY) { (void)bt_mesh_time_srv_time_status_send(srv, NULL); } + + return 0; } -static void handle_time_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_time_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { send_time_status(model, ctx, k_uptime_get()); + + return 0; } -static void handle_time_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_time_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_time_srv *srv = model->user_data; @@ -243,18 +245,20 @@ static void handle_time_set(struct bt_mesh_model *model, } send_time_status(model, ctx, srv->data.sync.uptime); + + return 0; } -static void handle_zone_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_zone_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { send_zone_status(model, ctx); + + return 0; } -static void handle_zone_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_zone_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_time_srv *srv = model->user_data; @@ -268,18 +272,20 @@ static void handle_zone_set(struct bt_mesh_model *model, } send_zone_status(model, ctx); + + return 0; } -static void handle_tai_utc_delta_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_tai_utc_delta_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { send_tai_utc_delta_status(model, ctx); + + return 0; } -static void handle_tai_utc_delta_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_tai_utc_delta_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_time_srv *srv = model->user_data; @@ -292,18 +298,20 @@ static void handle_tai_utc_delta_set(struct bt_mesh_model *model, } send_tai_utc_delta_status(model, ctx); + + return 0; } -static void handle_role_get(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_role_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { send_role_status(model, ctx); + + return 0; } -static void handle_role_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_role_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_time_srv *srv = model->user_data; enum bt_mesh_time_role role; @@ -311,34 +319,36 @@ static void handle_role_set(struct bt_mesh_model *model, role = net_buf_simple_pull_u8(buf); if (role != BT_MESH_TIME_NONE && role != BT_MESH_TIME_AUTHORITY && role != BT_MESH_TIME_RELAY && role != BT_MESH_TIME_CLIENT) { - return; + return -EINVAL; } srv->data.role = role; store_state(srv); send_role_status(model, ctx); + + return 0; } const struct bt_mesh_model_op _bt_mesh_time_srv_op[] = { { BT_MESH_TIME_OP_TIME_GET, - BT_MESH_TIME_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_GET), handle_time_get, }, { BT_MESH_TIME_OP_TIME_STATUS, - BT_MESH_TIME_MSG_LEN_TIME_STATUS, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TIME_STATUS), handle_time_status, }, { BT_MESH_TIME_OP_TIME_ZONE_GET, - BT_MESH_TIME_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_GET), handle_zone_get, }, { BT_MESH_TIME_OP_TAI_UTC_DELTA_GET, - BT_MESH_TIME_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_GET), handle_tai_utc_delta_get, }, BT_MESH_MODEL_OP_END, @@ -347,27 +357,27 @@ const struct bt_mesh_model_op _bt_mesh_time_srv_op[] = { const struct bt_mesh_model_op _bt_mesh_time_setup_srv_op[] = { { BT_MESH_TIME_OP_TIME_SET, - BT_MESH_TIME_MSG_LEN_TIME_SET, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TIME_SET), handle_time_set, }, { BT_MESH_TIME_OP_TIME_ZONE_SET, - BT_MESH_TIME_MSG_LEN_TIME_ZONE_SET, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TIME_ZONE_SET), handle_zone_set, }, { BT_MESH_TIME_OP_TAI_UTC_DELTA_SET, - BT_MESH_TIME_MSG_LEN_TAI_UTC_DELTA_SET, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TAI_UTC_DELTA_SET), handle_tai_utc_delta_set, }, { BT_MESH_TIME_OP_TIME_ROLE_GET, - BT_MESH_TIME_MSG_LEN_GET, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_GET), handle_role_get, }, { BT_MESH_TIME_OP_TIME_ROLE_SET, - BT_MESH_TIME_MSG_LEN_TIME_ROLE_SET, + BT_MESH_LEN_EXACT(BT_MESH_TIME_MSG_LEN_TIME_ROLE_SET), handle_role_set, }, BT_MESH_MODEL_OP_END, diff --git a/subsys/bluetooth/mesh/vnd/silvair_enocean_srv.c b/subsys/bluetooth/mesh/vnd/silvair_enocean_srv.c index 9bf58e757a20..bfe2ad2b353c 100644 --- a/subsys/bluetooth/mesh/vnd/silvair_enocean_srv.c +++ b/subsys/bluetooth/mesh/vnd/silvair_enocean_srv.c @@ -208,25 +208,30 @@ static void decommission_device(struct bt_mesh_silvair_enocean_srv *srv) #endif } -static void handle_get(struct bt_mesh_model *model, +static int handle_get(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, struct net_buf_simple *buf) { struct bt_mesh_silvair_enocean_srv *srv = model->user_data; + if (buf->len != 0) { + return -EMSGSIZE; + } + if (!bt_addr_le_cmp(&srv->addr, BT_ADDR_LE_NONE)) { status_pub(model, ctx, BT_MESH_SILVAIR_ENOCEAN_STATUS_NOT_SET, NULL); } else { status_pub(model, ctx, BT_MESH_SILVAIR_ENOCEAN_STATUS_SET, srv->addr.a.val); } + + return 0; } -static void handle_set(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_set(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { if (buf->len != BT_MESH_SILVAIR_ENOCEAN_PROXY_MSG_MAXLEN - 1) { - return; + return -EMSGSIZE; } struct bt_mesh_silvair_enocean_srv *srv = model->user_data; @@ -245,7 +250,7 @@ static void handle_set(struct bt_mesh_model *model, if (bt_addr_le_cmp(&srv->addr, &addr)) { status_pub(model, ctx, BT_MESH_SILVAIR_ENOCEAN_STATUS_UNSPECIFIED_ERROR, NULL); - return; + return -EINVAL; } } else { /* PTM 215B User Manual: By default, PTM 215B uses static source @@ -264,7 +269,7 @@ static void handle_set(struct bt_mesh_model *model, status_pub(model, ctx, BT_MESH_SILVAIR_ENOCEAN_STATUS_UNSPECIFIED_ERROR, NULL); bt_addr_le_copy(&srv->addr, BT_ADDR_LE_NONE); - return; + return err; } #if CONFIG_BT_ENOCEAN_STORE if (err != -EBUSY) { @@ -276,14 +281,19 @@ static void handle_set(struct bt_mesh_model *model, } status_pub(model, ctx, BT_MESH_SILVAIR_ENOCEAN_STATUS_SET, srv->addr.a.val); + + return 0; } -static void handle_delete(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_delete(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { struct bt_mesh_silvair_enocean_srv *srv = model->user_data; + if (buf->len != 0) { + return -EMSGSIZE; + } + if (bt_addr_le_cmp(&srv->addr, BT_ADDR_LE_NONE)) { decommission_device(srv); } @@ -293,11 +303,12 @@ static void handle_delete(struct bt_mesh_model *model, if (IS_ENABLED(CONFIG_BT_MESH_SILVAIR_ENOCEAN_AUTO_COMMISSION)) { bt_enocean_commissioning_enable(); } + + return 0; } -static void handle_message(struct bt_mesh_model *model, - struct bt_mesh_msg_ctx *ctx, - struct net_buf_simple *buf) +static int handle_message(struct bt_mesh_model *model, struct bt_mesh_msg_ctx *ctx, + struct net_buf_simple *buf) { uint8_t sub_opcode; @@ -305,21 +316,20 @@ static void handle_message(struct bt_mesh_model *model, switch (sub_opcode) { case BT_MESH_SILVAIR_ENOCEAN_PROXY_SUB_OP_GET: - handle_get(model, ctx, buf); - break; + return handle_get(model, ctx, buf); case BT_MESH_SILVAIR_ENOCEAN_PROXY_SUB_OP_SET: - handle_set(model, ctx, buf); - break; + return handle_set(model, ctx, buf); case BT_MESH_SILVAIR_ENOCEAN_PROXY_SUB_OP_DELETE: - handle_delete(model, ctx, buf); - break; + return handle_delete(model, ctx, buf); } + + return -EOPNOTSUPP; } const struct bt_mesh_model_op _bt_mesh_silvair_enocean_srv_op[] = { { BT_MESH_SILVAIR_ENOCEAN_PROXY_OP, - BT_MESH_SILVAIR_ENOCEAN_PROXY_MSG_MINLEN, + BT_MESH_LEN_MIN(BT_MESH_SILVAIR_ENOCEAN_PROXY_MSG_MINLEN), handle_message, }, BT_MESH_MODEL_OP_END, From 4d32486616acb48677cc26c062426c49945a112a Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 27 Jul 2021 16:06:45 +0200 Subject: [PATCH 086/126] doc: kconfig: enable kconfig-role extension The kconfig-role extension is now required since the introduction of the new :kconfig: role. Signed-off-by: Gerard Marull-Paretas --- doc/kconfig/conf.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/kconfig/conf.py b/doc/kconfig/conf.py index 009452e05e4d..441711ee8c3d 100644 --- a/doc/kconfig/conf.py +++ b/doc/kconfig/conf.py @@ -11,6 +11,8 @@ sys.path.insert(0, str(NRF_BASE / "doc" / "_utils")) import utils +ZEPHYR_BASE = utils.get_projdir("zephyr") + # General configuration -------------------------------------------------------- project = "Kconfig reference" @@ -19,9 +21,10 @@ # NOTE: use blank space as version to preserve space version = " " +sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_extensions")) sys.path.insert(0, str(NRF_BASE / "doc" / "_extensions")) -extensions = ["ncs_cache"] +extensions = ["zephyr.kconfig-role", "ncs_cache"] # Options for HTML output ------------------------------------------------------ From b7b27782b27b41c7ff2b0c01cdbad4125aa6eec9 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 27 Jul 2021 16:21:34 +0200 Subject: [PATCH 087/126] doc: mcuboot: enable kconfig-role extension References to Kconfig options now require usage of the :kconfig: role, so enable the required extension and move all :option: roles to :kconfig:. Signed-off-by: Gerard Marull-Paretas --- doc/mcuboot/conf.py | 10 +++++++++- doc/mcuboot/readme-ncs.rst | 2 +- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/doc/mcuboot/conf.py b/doc/mcuboot/conf.py index b6871f60872b..58fc27b2f860 100644 --- a/doc/mcuboot/conf.py +++ b/doc/mcuboot/conf.py @@ -12,6 +12,7 @@ import utils MCUBOOT_BASE = utils.get_projdir("mcuboot") +ZEPHYR_BASE = utils.get_projdir("zephyr") # General configuration -------------------------------------------------------- @@ -19,9 +20,16 @@ copyright = "2019-2021" version = release = "1.7.99" +sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_extensions")) sys.path.insert(0, str(NRF_BASE / "doc" / "_extensions")) -extensions = ["sphinx.ext.intersphinx", "recommonmark", "ncs_cache", "external_content"] +extensions = [ + "zephyr.kconfig-role", + "sphinx.ext.intersphinx", + "recommonmark", + "ncs_cache", + "external_content" +] source_suffix = [".rst", ".md"] master_doc = "wrapper" diff --git a/doc/mcuboot/readme-ncs.rst b/doc/mcuboot/readme-ncs.rst index 2cf18e61ecde..c03cf5289a5b 100644 --- a/doc/mcuboot/readme-ncs.rst +++ b/doc/mcuboot/readme-ncs.rst @@ -8,7 +8,7 @@ See :doc:`readme-zephyr` for general information on how to integrate MCUboot wit nRF Connect SDK provides additional functionality that is available when MCUboot is included. This functionality is implemented in the files in the ``modules/mcuboot`` subfolder in the `sdk-nrf`_ repository. -To include MCUboot in your nRF Connect SDK application, enable :option:`CONFIG_BOOTLOADER_MCUBOOT`. +To include MCUboot in your nRF Connect SDK application, enable :kconfig:`CONFIG_BOOTLOADER_MCUBOOT`. When you build your application with this option set, the following files that can be used for firmware over-the-air (FOTA) upgrades are automatically generated: From a718ae218664be80e9eda5988bfa3a6ae1eb436c Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 27 Jul 2021 16:26:27 +0200 Subject: [PATCH 088/126] doc: nrf: enable kconfig-role extension Kconfig references need to use now the :kconfig: role, provided by the Zephyr's kconfig-role extension. This patch also updates documentation (rst files and Doxygen) to make use of it. Signed-off-by: Gerard Marull-Paretas --- doc/nrf/app_memory.rst | 48 +++---- doc/nrf/app_power_opt.rst | 4 +- doc/nrf/conf.py | 1 + doc/nrf/doc_styleguide.rst | 4 +- doc/nrf/drivers/eth_rtt.rst | 2 +- doc/nrf/drivers/hw_cc310.rst | 2 +- doc/nrf/drivers/uart_nrf_sw_lpuart.rst | 12 +- doc/nrf/includes/ieee802154_eui64_conf.txt | 12 +- doc/nrf/known_issues.rst | 80 +++++------ doc/nrf/libraries/modem/at_host.rst | 22 +-- doc/nrf/libraries/modem/zzhc.rst | 28 ++-- doc/nrf/libraries/zigbee/osif.rst | 18 +-- doc/nrf/libraries/zigbee/shell.rst | 8 +- doc/nrf/nrf.doxyfile.in | 2 +- doc/nrf/releases/release-notes-1.1.0.rst | 14 +- doc/nrf/releases/release-notes-1.2.0.rst | 2 +- doc/nrf/releases/release-notes-1.3.0.rst | 4 +- doc/nrf/releases/release-notes-1.4.0.rst | 8 +- doc/nrf/releases/release-notes-1.5.0.rst | 68 ++++----- doc/nrf/releases/release-notes-1.6.0.rst | 12 +- doc/nrf/samples.rst | 2 +- doc/nrf/shortcuts.txt | 4 +- .../mesh_model_server_client_template.rst | 6 +- doc/nrf/templates/sample_README.rst | 8 +- doc/nrf/ug_ble_controller.rst | 2 +- doc/nrf/ug_bootloader_adding.rst | 16 +-- doc/nrf/ug_bootloader_config.rst | 2 +- doc/nrf/ug_bootloader_testing.rst | 2 +- doc/nrf/ug_bt_mesh_configuring.rst | 26 ++-- ..._vendor_model_chat_sample_walk_through.rst | 2 +- .../ug_bt_mesh_vendor_model_dev_overview.rst | 2 +- doc/nrf/ug_edge_impulse.rst | 20 +-- doc/nrf/ug_fw_update.rst | 2 +- doc/nrf/ug_logging.rst | 36 ++--- doc/nrf/ug_multi_image.rst | 6 +- doc/nrf/ug_multiprotocol_support.rst | 2 +- doc/nrf/ug_nrf52.rst | 2 +- doc/nrf/ug_nrf5340.rst | 22 +-- doc/nrf/ug_nrf9160.rst | 14 +- doc/nrf/ug_pelion.rst | 12 +- doc/nrf/ug_radio_fem.rst | 2 +- doc/nrf/ug_tfm.rst | 12 +- doc/nrf/ug_thread_configuring.rst | 136 +++++++++--------- doc/nrf/ug_thread_ot_memory.rst | 14 +- doc/nrf/ug_thread_supported_features.rst | 2 +- doc/nrf/ug_unity_testing.rst | 2 +- doc/nrf/ug_zigbee_configuring.rst | 48 +++---- doc/nrf/ug_zigbee_configuring_libraries.rst | 40 +++--- doc/nrf/ug_zigbee_memory.rst | 4 +- doc/nrf/ug_zigbee_other_ecosystems.rst | 8 +- include/bl_storage.h | 2 +- include/bl_validation.h | 2 +- include/bluetooth/mesh/gen_prop_srv.h | 2 +- include/bluetooth/mesh/light_ctrl_srv.h | 2 +- include/bluetooth/mesh/sensor.h | 2 +- include/bluetooth/mesh/sensor_srv.h | 2 +- include/bluetooth/services/gadgets_profile.h | 2 +- include/esb.h | 4 +- include/fw_info.h | 2 +- include/net/aws_iot.h | 2 +- include/net/azure_iot_hub.h | 2 +- include/net/download_client.h | 4 +- include/net/fota_download.h | 4 +- 63 files changed, 420 insertions(+), 419 deletions(-) diff --git a/doc/nrf/app_memory.rst b/doc/nrf/app_memory.rst index fb5ccb5bb38a..dea79c53ea3e 100644 --- a/doc/nrf/app_memory.rst +++ b/doc/nrf/app_memory.rst @@ -42,23 +42,23 @@ Complete the following actions to optimize the Bluetooth part of your applicatio The following configuration options affect the stack sizes of the Bluetooth threads: - * :option:`CONFIG_SDC_RX_STACK_SIZE` - * :option:`CONFIG_BT_RX_STACK_SIZE` - * :option:`CONFIG_BT_HCI_TX_STACK_SIZE` - * :option:`CONFIG_MPSL_SIGNAL_STACK_SIZE` + * :kconfig:`CONFIG_SDC_RX_STACK_SIZE` + * :kconfig:`CONFIG_BT_RX_STACK_SIZE` + * :kconfig:`CONFIG_BT_HCI_TX_STACK_SIZE` + * :kconfig:`CONFIG_MPSL_SIGNAL_STACK_SIZE` * Reduce the overall number and the sizes of the Bluetooth buffers, based on the expected data traffic in your application. The following configuration options affect the Bluetooth buffers: - * :option:`CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT` - * :option:`CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE` - * :option:`CONFIG_BT_BUF_EVT_RX_COUNT` - * :option:`CONFIG_BT_CONN_TX_MAX` - * :option:`CONFIG_BT_L2CAP_TX_BUF_COUNT` - * :option:`CONFIG_BT_CTLR_RX_BUFFERS` - * :option:`CONFIG_BT_BUF_ACL_TX_COUNT` - * :option:`CONFIG_BT_BUF_ACL_TX_SIZE` + * :kconfig:`CONFIG_BT_BUF_EVT_DISCARDABLE_COUNT` + * :kconfig:`CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE` + * :kconfig:`CONFIG_BT_BUF_EVT_RX_COUNT` + * :kconfig:`CONFIG_BT_CONN_TX_MAX` + * :kconfig:`CONFIG_BT_L2CAP_TX_BUF_COUNT` + * :kconfig:`CONFIG_BT_CTLR_RX_BUFFERS` + * :kconfig:`CONFIG_BT_BUF_ACL_TX_COUNT` + * :kconfig:`CONFIG_BT_BUF_ACL_TX_SIZE` For reference, you can find minimal footprint configurations of the :ref:`peripheral_lbs` sample in :file:`nrf/samples/bluetooth/peripheral_lbs/minimal.conf` and the :ref:`peripheral_uart` sample in :file:`nrf/samples/bluetooth/peripheral_uart/minimal.conf`. @@ -82,17 +82,17 @@ Complete the following actions to optimize the Thread part of your application: The following configuration options affect the stack sizes of the Thread threads: - * :option:`CONFIG_OPENTHREAD_THREAD_STACK_SIZE` - * :option:`CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE` - * :option:`CONFIG_NET_RX_STACK_SIZE` - * :option:`CONFIG_NET_TX_STACK_SIZE` - * :option:`CONFIG_NET_MGMT_EVENT_STACK_SIZE` - * :option:`CONFIG_IEEE802154_NRF5_RX_STACK_SIZE` - * :option:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` - * :option:`CONFIG_MPSL_SIGNAL_STACK_SIZE` - * :option:`CONFIG_SHELL_STACK_SIZE` - * :option:`CONFIG_IDLE_STACK_SIZE` - * :option:`CONFIG_MAIN_STACK_SIZE` - * :option:`CONFIG_ISR_STACK_SIZE` + * :kconfig:`CONFIG_OPENTHREAD_THREAD_STACK_SIZE` + * :kconfig:`CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE` + * :kconfig:`CONFIG_NET_RX_STACK_SIZE` + * :kconfig:`CONFIG_NET_TX_STACK_SIZE` + * :kconfig:`CONFIG_NET_MGMT_EVENT_STACK_SIZE` + * :kconfig:`CONFIG_IEEE802154_NRF5_RX_STACK_SIZE` + * :kconfig:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` + * :kconfig:`CONFIG_MPSL_SIGNAL_STACK_SIZE` + * :kconfig:`CONFIG_SHELL_STACK_SIZE` + * :kconfig:`CONFIG_IDLE_STACK_SIZE` + * :kconfig:`CONFIG_MAIN_STACK_SIZE` + * :kconfig:`CONFIG_ISR_STACK_SIZE` For reference, you can find minimal footprint configurations for the single protocol and multiprotocol variants of the :ref:`ot_cli_sample` sample in :file:`nrf/samples/openthread/cli/overlay-minimal_*protocol.conf`. diff --git a/doc/nrf/app_power_opt.rst b/doc/nrf/app_power_opt.rst index 8a4e7afc21aa..dc92699d8eb1 100644 --- a/doc/nrf/app_power_opt.rst +++ b/doc/nrf/app_power_opt.rst @@ -192,7 +192,7 @@ To measure current on an nRF9160 DK using the Power Profiler Kit II, while it is Even though the requested time-out value in the use case is 60 minutes, it is decided by the network. The PSM floor current is now 4.69 µA. -#. Since the data transfer interval is 20 minutes, you can increase the frequency of transmission. Set :option:`CONFIG_UDP_DATA_UPLOAD_FREQUENCY_SECONDS` to ``120`` in :file:`prj.conf`. +#. Since the data transfer interval is 20 minutes, you can increase the frequency of transmission. Set :kconfig:`CONFIG_UDP_DATA_UPLOAD_FREQUENCY_SECONDS` to ``120`` in :file:`prj.conf`. #. Rebuild and program the sample. #. A 40-byte data packet is now sent every two minutes. Make sure that the frequency is sufficiently higher than the duration of RRC inactivity present in the network. @@ -217,7 +217,7 @@ To measure current on an nRF9160 DK using the Power Profiler Kit II, while it is It is recommended to send a batch of six measurements for every 60 minutes to have some margin. Hence, you can change the payload size to a value of 120 bytes in the :file:`prj.conf` to observe how it affects the charge in a single transmission. -#. To change the payload size, set :option:`CONFIG_UDP_DATA_UPLOAD_SIZE_BYTES` to ``120`` in :file:`prj.conf` +#. To change the payload size, set :kconfig:`CONFIG_UDP_DATA_UPLOAD_SIZE_BYTES` to ``120`` in :file:`prj.conf` #. Rebuild and program the sample. Observe the results in the Power Profiler Kit II interface: diff --git a/doc/nrf/conf.py b/doc/nrf/conf.py index 746a77c0fc34..c45a1194ba14 100644 --- a/doc/nrf/conf.py +++ b/doc/nrf/conf.py @@ -34,6 +34,7 @@ "sphinxcontrib.mscgen", "zephyr.html_redirects", "zephyr.warnings_filter", + "zephyr.kconfig-role", "ncs_cache", "external_content", "doxyrunner", diff --git a/doc/nrf/doc_styleguide.rst b/doc/nrf/doc_styleguide.rst index 1c68a44d0e14..4ec6784b55f4 100644 --- a/doc/nrf/doc_styleguide.rst +++ b/doc/nrf/doc_styleguide.rst @@ -118,9 +118,9 @@ To link directly to a doxygen reference from RST, use the following Breathe doma Kconfig ------- -Kconfig options can be linked to from RST by using the ``:option:`` domain:: +Kconfig options can be linked to from RST by using the ``:kconfig:`` domain:: - :option:`CONFIG_DEBUG` + :kconfig:`CONFIG_DEBUG` Doxygen |gl| ************ diff --git a/doc/nrf/drivers/eth_rtt.rst b/doc/nrf/drivers/eth_rtt.rst index c455ee153bdb..345652dc64a1 100644 --- a/doc/nrf/drivers/eth_rtt.rst +++ b/doc/nrf/drivers/eth_rtt.rst @@ -42,7 +42,7 @@ The content of this frame is constant and it is available in the driver source c Initialization ************** -You can initialize the RTT driver using the :option:`CONFIG_ETH_RTT` Kconfig option. +You can initialize the RTT driver using the :kconfig:`CONFIG_ETH_RTT` Kconfig option. API documentation ***************** diff --git a/doc/nrf/drivers/hw_cc310.rst b/doc/nrf/drivers/hw_cc310.rst index 1f86e8f31707..cc86d176f330 100644 --- a/doc/nrf/drivers/hw_cc310.rst +++ b/doc/nrf/drivers/hw_cc310.rst @@ -15,7 +15,7 @@ It initializes the following elements of the library: * hardware mutex and mutex API, * platform with or without RNG. -You can initialize the hw_cc310 driver using the :option:`CONFIG_HW_CC3XX` Kconfig option. +You can initialize the hw_cc310 driver using the :kconfig:`CONFIG_HW_CC3XX` Kconfig option. API documentation ***************** diff --git a/doc/nrf/drivers/uart_nrf_sw_lpuart.rst b/doc/nrf/drivers/uart_nrf_sw_lpuart.rst index 400557a4571c..d3ba72c853e6 100644 --- a/doc/nrf/drivers/uart_nrf_sw_lpuart.rst +++ b/doc/nrf/drivers/uart_nrf_sw_lpuart.rst @@ -7,8 +7,8 @@ Low power UART driver :local: :depth: 2 -The low power UART driver implements the standard *asynchronous UART API* that can be enabled with the :option:`CONFIG_UART_ASYNC_API` configuration option. -Alternatively, you can also enable the *interrupt-driven UART API* using the :option:`CONFIG_NRF_SW_LPUART_INT_DRIVEN` configuration option. +The low power UART driver implements the standard *asynchronous UART API* that can be enabled with the :kconfig:`CONFIG_UART_ASYNC_API` configuration option. +Alternatively, you can also enable the *interrupt-driven UART API* using the :kconfig:`CONFIG_NRF_SW_LPUART_INT_DRIVEN` configuration option. The protocol used by this driver implements two control lines, instead of standard hardware flow control lines, to allow for disabling the UART receiver during the idle period. This results in low power consumption, as you can shut down the high-frequency clock when UART is in idle state. @@ -84,15 +84,15 @@ See the following configuration example: The low power UART configuration includes: -* :option:`CONFIG_NRF_SW_LPUART_MAX_PACKET_SIZE`: Sets the maximum RX packet size. +* :kconfig:`CONFIG_NRF_SW_LPUART_MAX_PACKET_SIZE`: Sets the maximum RX packet size. -* :option:`CONFIG_NRF_SW_LPUART_INT_DRIVEN`: Enables the interrupt-driven API. +* :kconfig:`CONFIG_NRF_SW_LPUART_INT_DRIVEN`: Enables the interrupt-driven API. When enabled, the asynchronous API cannot be used. -* :option:`CONFIG_NRF_SW_LPUART_DEFAULT_TX_TIMEOUT`: Sets the timeout value, in milliseconds. +* :kconfig:`CONFIG_NRF_SW_LPUART_DEFAULT_TX_TIMEOUT`: Sets the timeout value, in milliseconds. It is used in :c:func:`uart_poll_out` and :c:func:`uart_fifo_fill` when the interrupt-driven API is enabled. -* :option:`CONFIG_NRF_SW_LPUART_INT_DRV_TX_BUF_SIZE`: Set the size of the internal buffer created and used by :c:func:`uart_fifo_fill`. +* :kconfig:`CONFIG_NRF_SW_LPUART_INT_DRV_TX_BUF_SIZE`: Set the size of the internal buffer created and used by :c:func:`uart_fifo_fill`. For optimal performance, it should be able to fit the longest possible packet. Usage diff --git a/doc/nrf/includes/ieee802154_eui64_conf.txt b/doc/nrf/includes/ieee802154_eui64_conf.txt index 7bc25114d486..f8f22df96eba 100644 --- a/doc/nrf/includes/ieee802154_eui64_conf.txt +++ b/doc/nrf/includes/ieee802154_eui64_conf.txt @@ -10,8 +10,8 @@ Use the default The extension identifier is set to the DEVICEID from the factory information configuration registers (FICR). Replace the company ID - You can enable :option:`CONFIG_IEEE802154_VENDOR_OUI_ENABLE` to replace Nordic Semiconductor's company ID with your own company ID. - Specify your company ID in :option:`CONFIG_IEEE802154_VENDOR_OUI`. + You can enable :kconfig:`CONFIG_IEEE802154_VENDOR_OUI_ENABLE` to replace Nordic Semiconductor's company ID with your own company ID. + Specify your company ID in :kconfig:`CONFIG_IEEE802154_VENDOR_OUI`. The extension identifier is set to the default, namely the DEVICEID from FICR. @@ -20,12 +20,12 @@ Replace the full EUI-64 For nRF52 Series devices, the CUSTOMER registers block is used. For nRF53 Series devices, the OTP registers block is used. - To use the EUI-64 value from the UICR, enable :option:`CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE` and set :option:`CONFIG_IEEE802154_NRF5_UICR_EUI64_REG` to the base of the two consecutive registers that contain your EUI-64 value. + To use the EUI-64 value from the UICR, enable :kconfig:`CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE` and set :kconfig:`CONFIG_IEEE802154_NRF5_UICR_EUI64_REG` to the base of the two consecutive registers that contain your EUI-64 value. The following example shows how to replace the full EUI-64 on an nRF52840 device: - 1. Enable :option:`CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE`. - #. Specify the offset for the UICR registers in :option:`CONFIG_IEEE802154_NRF5_UICR_EUI64_REG`. + 1. Enable :kconfig:`CONFIG_IEEE802154_NRF5_UICR_EUI64_ENABLE`. + #. Specify the offset for the UICR registers in :kconfig:`CONFIG_IEEE802154_NRF5_UICR_EUI64_REG`. This example uses UICR->CUSTOMER[0] and UICR->CUSTOMER[1], which means that you can keep the default value ``0``. #. Build and program your application erasing the whole memory (replace *serial_number* with the serial number of your debugger): @@ -44,4 +44,4 @@ Replace the full EUI-64 nrfjprog --snr *serial_number* --memwr 0x10001084 --val 0x55667788 nrfjprog --snr *serial_number* --reset - If you used a different value for :option:`CONFIG_IEEE802154_NRF5_UICR_EUI64_REG`, you must use different register addresses. + If you used a different value for :kconfig:`CONFIG_IEEE802154_NRF5_UICR_EUI64_REG`, you must use different register addresses. diff --git a/doc/nrf/known_issues.rst b/doc/nrf/known_issues.rst index d9baaec5efa5..9d740512c32d 100644 --- a/doc/nrf/known_issues.rst +++ b/doc/nrf/known_issues.rst @@ -63,19 +63,19 @@ Asset tracker .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 -NCSDK-6898: Setting :option:`CONFIG_SECURE_BOOT` does not work +NCSDK-6898: Setting :kconfig:`CONFIG_SECURE_BOOT` does not work The immutable bootloader is not able to find the required metadata in the MCUboot image. See the related NCSDK-6898 known issue in `Build system`_ for more details. - **Workaround:** Set :option:`CONFIG_FW_INFO` in MCUboot. + **Workaround:** Set :kconfig:`CONFIG_FW_INFO` in MCUboot. .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 External antenna performance setting The preprogrammed Asset Tracker does not come with the best external antenna performance. - **Workaround:** If you are using nRF9160 DK v0.15.0 or higher and Thingy:91 v1.4.0 or higher, set :option:`CONFIG_NRF9160_GPS_ANTENNA_EXTERNAL` to ``y``. - Alternatively, for nRF9160 DK v0.15.0, you can set the :option:`CONFIG_NRF9160_GPS_COEX0_STRING` option to ``AT%XCOEX0`` when building the preprogrammed Asset Tracker to achieve the best external antenna performance. + **Workaround:** If you are using nRF9160 DK v0.15.0 or higher and Thingy:91 v1.4.0 or higher, set :kconfig:`CONFIG_NRF9160_GPS_ANTENNA_EXTERNAL` to ``y``. + Alternatively, for nRF9160 DK v0.15.0, you can set the :kconfig:`CONFIG_NRF9160_GPS_COEX0_STRING` option to ``AT%XCOEX0`` when building the preprogrammed Asset Tracker to achieve the best external antenna performance. .. rst-class:: v1-3-2 v1-3-1 v1-3-0 @@ -202,10 +202,10 @@ nRF5340 .. rst-class:: v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 NCSDK-9786: Wrong FLASH_PAGE_ERASE_MAX_TIME_US for the nRF53 network core - ``FLASH_PAGE_ERASE_MAX_TIME_US`` defines the execution window duration when doing the flash operation synchronously along the radio operations (:option:`CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE` not enabled). + ``FLASH_PAGE_ERASE_MAX_TIME_US`` defines the execution window duration when doing the flash operation synchronously along the radio operations (:kconfig:`CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE` not enabled). The ``FLASH_PAGE_ERASE_MAX_TIME_US`` value of the nRF53 network core is lower than required. - For this reason, if :option:`CONFIG_SOC_FLASH_NRF_RADIO_SYNC_MPSL` is set to ``y`` and :option:`CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE` is set to ``n``, a flash erase operation on the nRF5340 network core will result in an MPSL timeslot OVERSTAYED assert. + For this reason, if :kconfig:`CONFIG_SOC_FLASH_NRF_RADIO_SYNC_MPSL` is set to ``y`` and :kconfig:`CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE` is set to ``n``, a flash erase operation on the nRF5340 network core will result in an MPSL timeslot OVERSTAYED assert. **Workaround:** Increase ``FLASH_PAGE_ERASE_MAX_TIME_US`` (defined in :file:`ncs/zephyr/soc/arm/nordic_nrf/nrf53/soc.h`) from 44850UL to 89700UL (the same value as for the application core). @@ -289,10 +289,10 @@ KRKNWK-7885: Throughput is lower when using CC310 nrf_security backend **Workaround:** Use AES-CCM ciphers from the nrf_oberon backend by setting the following options: - * :option:`CONFIG_OBERON_BACKEND` to ``y`` - * :option:`CONFIG_OBERON_MBEDTLS_AES_C` to ``y`` - * :option:`CONFIG_OBERON_MBEDTLS_CCM_C` to ``y`` - * :option:`CONFIG_CC3XX_MBEDTLS_AES_C` to ``n`` + * :kconfig:`CONFIG_OBERON_BACKEND` to ``y`` + * :kconfig:`CONFIG_OBERON_MBEDTLS_AES_C` to ``y`` + * :kconfig:`CONFIG_OBERON_MBEDTLS_CCM_C` to ``y`` + * :kconfig:`CONFIG_CC3XX_MBEDTLS_AES_C` to ``n`` .. rst-class:: v1-4-2 v1-4-1 v1-4-0 @@ -305,7 +305,7 @@ KRKNWK-7721: MAC counter updating issue .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 KRKNWK-7962: Logging interferes with shell output - :option:`CONFIG_LOG_MINIMAL` is configured by default for most OpenThread samples. + :kconfig:`CONFIG_LOG_MINIMAL` is configured by default for most OpenThread samples. It accesses the UART independently from the shell backend, which sometimes leads to malformed output. **Workaround:** Disable logging or enable a more advanced logging option. @@ -540,7 +540,7 @@ DESK-978: Directed advertising issues with SoftDevice Link Layer For more detailed information, see the ``Known issues and limitations`` section of the SoftDevice Controller's :ref:`nrfxlib:softdevice_controller_changelog`. .. note:: - The Kconfig option name changed from ``CONFIG_DESKTOP_BLE_DIRECT_ADV`` to :option:`CONFIG_CAF_BLE_ADV_DIRECT_ADV` beginning with the nRF Connect SDK v1.5.99. + The Kconfig option name changed from ``CONFIG_DESKTOP_BLE_DIRECT_ADV`` to :kconfig:`CONFIG_CAF_BLE_ADV_DIRECT_ADV` beginning with the nRF Connect SDK v1.5.99. **Workaround:** Directed advertising is disabled by default for nRF Desktop. @@ -558,7 +558,7 @@ Pelion .. rst-class:: v1-6-1 v1-6-0 NCSDK-10196: DFU fails for some configurations with the quick session resume feature enabled - Enabling :option:`CONFIG_PELION_QUICK_SESSION_RESUME` together with the OpenThread network backend leads to the quick session resume failure during the DFU packet exchange. + Enabling :kconfig:`CONFIG_PELION_QUICK_SESSION_RESUME` together with the OpenThread network backend leads to the quick session resume failure during the DFU packet exchange. This is valid for the :ref:`nRF52840 DK ` and the :ref:`nRF5340 DK `. **Workaround:** Use the quick session resume feature only for configurations with the cellular network backend. @@ -578,7 +578,7 @@ NCSDK-9820: The :ref:`peripheral_lbs` - If **Button 1** is pushed and released w NCSDK-9106: Bluetooth ECC thread stack size too small The Bluetooth ECC thread used during the pairing procedure with LE Secure Connections might overflow when an interrupt is triggered when the stack usage is at its maximum. - **Workaround:** Increase the ECC stack size by setting :option:`CONFIG_BT_HCI_ECC_STACK_SIZE` to ``1140``. + **Workaround:** Increase the ECC stack size by setting :kconfig:`CONFIG_BT_HCI_ECC_STACK_SIZE` to ``1140``. .. rst-class:: v1-5-0 v1-4-2 v1-4-1 v1-4-0 @@ -615,7 +615,7 @@ NCSDK-8223: GATT requests might deadlock RX thread This causes a deadlock because only the RX thread releases the TX buffers for the GATT requests. The deadlock is resolved by a 30 second timeout, but the ATT bearer cannot transmit without reconnecting. - **Workaround:** Set :option:`CONFIG_BT_L2CAP_TX_BUF_COUNT` >= ``CONFIG_BT_ATT_TX_MAX`` + 2. + **Workaround:** Set :kconfig:`CONFIG_BT_L2CAP_TX_BUF_COUNT` >= ``CONFIG_BT_ATT_TX_MAX`` + 2. .. rst-class:: v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 v1-2-1 v1-2-0 v1-1-0 v1-0-0 @@ -669,8 +669,8 @@ Unstable samples .. rst-class:: v1-2-1 v1-2-0 v1-1-0 -:option:`CONFIG_BT_SMP` alignment requirement - When running the :ref:`bluetooth_central_dfu_smp` sample, the :option:`CONFIG_BT_SMP` configuration must be aligned between this sample and the Zephyr counterpart (:ref:`zephyr:smp_svr_sample`). +:kconfig:`CONFIG_BT_SMP` alignment requirement + When running the :ref:`bluetooth_central_dfu_smp` sample, the :kconfig:`CONFIG_BT_SMP` configuration must be aligned between this sample and the Zephyr counterpart (:ref:`zephyr:smp_svr_sample`). However, security is not enabled by default in the Zephyr sample. .. rst-class:: v1-2-1 v1-2-0 v1-1-0 v1-0-0 @@ -807,7 +807,7 @@ NCSDK-6898: Overriding child images .. rst-class:: v1-4-2 v1-4-1 v1-4-0 -NCSDK-6777: Project out of date when :option:`CONFIG_SECURE_BOOT` is set +NCSDK-6777: Project out of date when :kconfig:`CONFIG_SECURE_BOOT` is set The DFU :file:`.zip` file is regenerated even when no changes are made to the files it depends on. As a consequence, SES displays a "Project out of date" message even when the project is not out of date. @@ -816,9 +816,9 @@ NCSDK-6777: Project out of date when :option:`CONFIG_SECURE_BOOT` is set .. rst-class:: v1-4-2 v1-4-1 v1-4-0 NCSDK-6848: MCUboot must be built from source when included - The build will fail if either :option:`CONFIG_MCUBOOT_BUILD_STRATEGY_SKIP_BUILD` or :option:`CONFIG_MCUBOOT_BUILD_STRATEGY_USE_HEX_FILE` is set. + The build will fail if either :kconfig:`CONFIG_MCUBOOT_BUILD_STRATEGY_SKIP_BUILD` or :kconfig:`CONFIG_MCUBOOT_BUILD_STRATEGY_USE_HEX_FILE` is set. - **Workaround:** Set :option:`CONFIG_MCUBOOT_BUILD_STRATEGY_FROM_SOURCE` instead. + **Workaround:** Set :kconfig:`CONFIG_MCUBOOT_BUILD_STRATEGY_FROM_SOURCE` instead. .. rst-class:: v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 v1-2-1 v1-2-0 v1-1-0 v1-0-0 v0-4-0 v0-3-0 @@ -830,9 +830,9 @@ KRKNWK-7827: Application build system is not aware of the settings partition You can use one of the following solutions: * :ref:`partition_manager` from |NCS| - see the page for all configuration options. - For example, for single image (without bootloader and with the settings partition used), set the :option:`CONFIG_PM_SINGLE_IMAGE` Kconfig option to ``y`` and define the value for :option:`CONFIG_PM_PARTITION_SIZE_SETTINGS_STORAGE` to the required settings storage size. + For example, for single image (without bootloader and with the settings partition used), set the :kconfig:`CONFIG_PM_SINGLE_IMAGE` Kconfig option to ``y`` and define the value for :kconfig:`CONFIG_PM_PARTITION_SIZE_SETTINGS_STORAGE` to the required settings storage size. * :ref:`Devicetree code partition ` from Zephyr. - Set :option:`CONFIG_USE_DT_CODE_PARTITION` Kconfig option to ``y``. + Set :kconfig:`CONFIG_USE_DT_CODE_PARTITION` Kconfig option to ``y``. Make sure that the code partition is defined and chosen correctly (``offset`` and ``size``). .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 @@ -871,7 +871,7 @@ NCSDK-6238: Socket API calls may hang when using Download client When using the :ref:`lib_download_client` library with HTTP (without TLS), the application might not process incoming fragments fast enough, which can starve the :ref:`nrfxlib:nrf_modem` buffers and make calls to the Modem library hang. Samples and applications that are affected include those that use :ref:`lib_download_client` to download files through HTTP, or those that use :ref:`lib_fota_download` with modem updates enabled. - **Workaround:** Set :option:`CONFIG_DOWNLOAD_CLIENT_RANGE_REQUESTS`. + **Workaround:** Set :kconfig:`CONFIG_DOWNLOAD_CLIENT_RANGE_REQUESTS`. .. rst-class:: v1-1-0 @@ -1027,15 +1027,15 @@ DRGN-15979: :option:`CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION` must be set .. rst-class:: v1-5-0 v1-4-2 v1-4-1 DRGN-15223: `CONFIG_SYSTEM_CLOCK_NO_WAIT` is not supported for nRF5340 - Using :option:`CONFIG_SYSTEM_CLOCK_NO_WAIT` with nRF5340 devices might not work as expected. + Using :kconfig:`CONFIG_SYSTEM_CLOCK_NO_WAIT` with nRF5340 devices might not work as expected. .. rst-class:: v1-4-2 v1-4-1 DRGN-15176: `CONFIG_SYSTEM_CLOCK_NO_WAIT` is ignored when Low Frequency Clock is started before initializing MPSL - If the application starts the Low Frequency Clock before calling :c:func:`mpsl_init()`, the clock configuration option :option:`CONFIG_SYSTEM_CLOCK_NO_WAIT` has no effect. + If the application starts the Low Frequency Clock before calling :c:func:`mpsl_init()`, the clock configuration option :kconfig:`CONFIG_SYSTEM_CLOCK_NO_WAIT` has no effect. MPSL will wait for the Low Frequency Clock to start. - **Workaround:** When :option:`CONFIG_SYSTEM_CLOCK_NO_WAIT` is set, do not start the Low Frequency Clock. + **Workaround:** When :kconfig:`CONFIG_SYSTEM_CLOCK_NO_WAIT` is set, do not start the Low Frequency Clock. .. rst-class:: v1-4-0 v1-3-2 v1-3-1 v1-3-0 @@ -1097,7 +1097,7 @@ DRGN-15852: In rare cases on nRF53 Series devices, an assert can occur while sca This is default configuration of the Bluetooth host. **Workaround:** Use extended scanning commands. - That is, set :option:`CONFIG_BT_EXT_ADV` to use HCI LE Set Extended Scan Enable instead. + That is, set :kconfig:`CONFIG_BT_EXT_ADV` to use HCI LE Set Extended Scan Enable instead. .. rst-class:: v1-6-0 v1-5-0 v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 v1-2-1 v1-2-0 @@ -1125,8 +1125,8 @@ DRGN-15547: Assertion when updating PHY and the event length is configured too l * :c:union:`sdc_cfg_t` with :c:member:`event_length` is set to less than 2500 us and the PHY is updated from 2M to 1M, or from either 1M or 2M to Coded PHY. * :c:union:`sdc_cfg_t` with :c:member:`event_length` is set to less than 7500 us and a PHY update to Coded PHY is performed. - | The default value of :option:`CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT` is 7500 us. - | The minimum event length supported by :option:`CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT` is 2500 us. + | The default value of :kconfig:`CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT` is 7500 us. + | The minimum event length supported by :kconfig:`CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT` is 2500 us. **Workaround:** * Set :c:union:`sdc_cfg_t` with :c:member:`event_length` to at least 2500 us if the application is using 1M PHY. @@ -1189,7 +1189,7 @@ DRGN-15251: Very rare assertion fault when connected as peripheral on Coded PHY * The devices have performed a data length update, and the supported values are above the minimum specification defined values. * A packet is received with a CRC error. - **Workaround:** Do not enable :option:`CONFIG_BT_DATA_LEN_UPDATE` for applications that require Coded PHY as a peripheral device. + **Workaround:** Do not enable :kconfig:`CONFIG_BT_DATA_LEN_UPDATE` for applications that require Coded PHY as a peripheral device. .. rst-class:: v1-5-0 v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 v1-2-1 v1-2-0 v1-1-0 @@ -1198,7 +1198,7 @@ DRGN-15310: HCI Read RSSI fails .. rst-class:: v1-5-0 -DRGN-15465: Corrupted advertising data when :option:`CONFIG_BT_EXT_ADV` is set +DRGN-15465: Corrupted advertising data when :kconfig:`CONFIG_BT_EXT_ADV` is set Setting scan response data for a legacy advertiser on a build with extended advertising support corrupts parts of the advertising data. When using ``BT_LE_ADV_OPT_USE_NAME`` (which is the default configuration in most samples), the device name is put in the scan response. This corrupts the advertising data. @@ -1213,7 +1213,7 @@ DRGN-15475: Samples might not initialize the SoftDevice Controller HCI driver co Samples using both the advertising and the scanning state, but not the connected state, fail to initialize the SoftDevice Controller HCI driver. As a result, the function :c:func:`bt_enable()` returns an error code. - **Workaround:** Manually enable :option:`CONFIG_SOFTDEVICE_CONTROLLER_MULTIROLE` for the project configuration. + **Workaround:** Manually enable :kconfig:`CONFIG_SOFTDEVICE_CONTROLLER_MULTIROLE` for the project configuration. .. rst-class:: v1-5-0 @@ -1237,7 +1237,7 @@ DRGN-15291: The generation of QoS Connection events is not disabled after an HCI DRGN-15226: Link disconnects with reason "LMP Response Timeout (0x22)" If the slave receives an encryption request while the "HCI LE Long Term Key Request" event is disabled, the link disconnects with the reason "LMP Response Timeout (0x22)". - The event is disabled when :option:`CONFIG_BT_SMP` and/or :option:`CONFIG_BT_CTLR_LE_ENC` is disabled. + The event is disabled when :kconfig:`CONFIG_BT_SMP` and/or :kconfig:`CONFIG_BT_CTLR_LE_ENC` is disabled. .. rst-class:: v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 v1-2-1 v1-2-0 v1-1-0 @@ -1288,18 +1288,18 @@ DRGN-13079: An assert occurs when setting a secondary PHY to 0 when using HCI LE .. rst-class:: v1-1-0 -:option:`CONFIG_BT_HCI_TX_STACK_SIZE` requires specific value - :option:`CONFIG_BT_HCI_TX_STACK_SIZE` must be set to 1536 when selecting :option:`CONFIG_BT_LL_SOFTDEVICE`. +:kconfig:`CONFIG_BT_HCI_TX_STACK_SIZE` requires specific value + :kconfig:`CONFIG_BT_HCI_TX_STACK_SIZE` must be set to 1536 when selecting :kconfig:`CONFIG_BT_LL_SOFTDEVICE`. .. rst-class:: v1-1-0 -:option:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` requires specific value - :option:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` must be set to 2048 when selecting :option:`CONFIG_BT_LL_SOFTDEVICE` on :ref:`central_uart` and :ref:`central_bas`. +:kconfig:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` requires specific value + :kconfig:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` must be set to 2048 when selecting :kconfig:`CONFIG_BT_LL_SOFTDEVICE` on :ref:`central_uart` and :ref:`central_bas`. .. rst-class:: v1-1-0 -:option:`CONFIG_NFCT_IRQ_PRIORITY` requires specific value - :option:`CONFIG_NFCT_IRQ_PRIORITY` must be set to 5 or less when selecting :option:`CONFIG_BT_LL_SOFTDEVICE` on :ref:`peripheral_hids_keyboard`. +:kconfig:`CONFIG_NFCT_IRQ_PRIORITY` requires specific value + :kconfig:`CONFIG_NFCT_IRQ_PRIORITY` must be set to 5 or less when selecting :kconfig:`CONFIG_BT_LL_SOFTDEVICE` on :ref:`peripheral_hids_keyboard`. .. rst-class:: v1-1-0 @@ -1439,7 +1439,7 @@ NCSDK-6832: SMP Server sample fails upon initialization The :ref:`zephyr:smp_svr_sample` will fail upon initialization when using the :file:`bt-overlay.conf` Kconfig overlay file. This happens because of a stack overflow. - **Workaround:** Set :option:`CONFIG_MAIN_STACK_SIZE` to ``2048``. + **Workaround:** Set :kconfig:`CONFIG_MAIN_STACK_SIZE` to ``2048``. SEGGER Embedded Studio Nordic Edition ************************************* diff --git a/doc/nrf/libraries/modem/at_host.rst b/doc/nrf/libraries/modem/at_host.rst index 1a0e3a320169..f7089bff1a68 100644 --- a/doc/nrf/libraries/modem/at_host.rst +++ b/doc/nrf/libraries/modem/at_host.rst @@ -19,23 +19,23 @@ Specifically, if it is desirable for the client to use SMS functionality, the te The various configuration options used in the library are listed below: -* :option:`CONFIG_AT_HOST_LIBRARY` - Enables the AT Host library -* :option:`CONFIG_AT_HOST_UART_INIT_TIMEOUT` - Sets the timeout value to wait for a valid UART line on initialization -* :option:`CONFIG_AT_HOST_CMD_MAX_LEN` - Sets the maximum length for an AT command -* :option:`CONFIG_AT_HOST_THREAD_PRIO` - Sets the priority level for the AT host work queue thread +* :kconfig:`CONFIG_AT_HOST_LIBRARY` - Enables the AT Host library +* :kconfig:`CONFIG_AT_HOST_UART_INIT_TIMEOUT` - Sets the timeout value to wait for a valid UART line on initialization +* :kconfig:`CONFIG_AT_HOST_CMD_MAX_LEN` - Sets the maximum length for an AT command +* :kconfig:`CONFIG_AT_HOST_THREAD_PRIO` - Sets the priority level for the AT host work queue thread Configuration options for setting the UART: -* :option:`CONFIG_AT_HOST_UART_0` - Enables UART 0 -* :option:`CONFIG_AT_HOST_UART_1` - Enables UART 1 -* :option:`CONFIG_AT_HOST_UART_2` - Enables UART 2 +* :kconfig:`CONFIG_AT_HOST_UART_0` - Enables UART 0 +* :kconfig:`CONFIG_AT_HOST_UART_1` - Enables UART 1 +* :kconfig:`CONFIG_AT_HOST_UART_2` - Enables UART 2 Configuration options for setting the termination character: -* :option:`CONFIG_NULL_TERMINATION` - Enables ```` as the termination character -* :option:`CONFIG_CR_TERMINATION` - Enables ```` as the termination character -* :option:`CONFIG_LF_TERMINATION` - Enables ```` as the termination character -* :option:`CONFIG_CR_LF_TERMINATION` - Enables ```` as the termination character +* :kconfig:`CONFIG_NULL_TERMINATION` - Enables ```` as the termination character +* :kconfig:`CONFIG_CR_TERMINATION` - Enables ```` as the termination character +* :kconfig:`CONFIG_LF_TERMINATION` - Enables ```` as the termination character +* :kconfig:`CONFIG_CR_LF_TERMINATION` - Enables ```` as the termination character Usage ***** diff --git a/doc/nrf/libraries/modem/zzhc.rst b/doc/nrf/libraries/modem/zzhc.rst index 54efc8ea5f3a..bca24fc9c88b 100644 --- a/doc/nrf/libraries/modem/zzhc.rst +++ b/doc/nrf/libraries/modem/zzhc.rst @@ -38,30 +38,30 @@ Enabling the ZZHC library To enable the ZZHC library, edit the :file:`prj.conf` file according to the following steps: -1. Set :option:`CONFIG_ZZHC` to ``y``. +1. Set :kconfig:`CONFIG_ZZHC` to ``y``. This option enables the ZZHC library and ensures that China Telecom can approve the end product. The following required options are automatically selected when the ZZHC library is enabled: - * :option:`CONFIG_NRF_MODEM_LIB` - * :option:`CONFIG_SETTINGS` - * :option:`CONFIG_AT_CMD` - * :option:`CONFIG_AT_CMD_PARSER` - * :option:`CONFIG_AT_NOTIF` - * :option:`CONFIG_BASE64` - * :option:`CONFIG_JSON_LIBRARY` + * :kconfig:`CONFIG_NRF_MODEM_LIB` + * :kconfig:`CONFIG_SETTINGS` + * :kconfig:`CONFIG_AT_CMD` + * :kconfig:`CONFIG_AT_CMD_PARSER` + * :kconfig:`CONFIG_AT_NOTIF` + * :kconfig:`CONFIG_BASE64` + * :kconfig:`CONFIG_JSON_LIBRARY` -#. Set :option:`CONFIG_TRUSTED_EXECUTION_NONSECURE` to ``y``. +#. Set :kconfig:`CONFIG_TRUSTED_EXECUTION_NONSECURE` to ``y``. This option enables the Trusted Execution: Non-Secure firmware image. The ZZHC library only works when this option is enabled. -#. Set :option:`CONFIG_HEAP_MEM_POOL_SIZE` to the minimum heap size required (2560 bytes): ``CONFIG_HEAP_MEM_POOL_SIZE=2560``. -#. Set the following options required by :option:`CONFIG_NRF_MODEM_LIB`: +#. Set :kconfig:`CONFIG_HEAP_MEM_POOL_SIZE` to the minimum heap size required (2560 bytes): ``CONFIG_HEAP_MEM_POOL_SIZE=2560``. +#. Set the following options required by :kconfig:`CONFIG_NRF_MODEM_LIB`: * ``CONFIG_NETWORKING=y`` * ``CONFIG_NET_NATIVE=n`` * ``CONFIG_NET_SOCKETS=y`` * ``CONFIG_NET_SOCKETS_OFFLOAD=y`` -#. Set the following options required by :option:`CONFIG_SETTINGS`: +#. Set the following options required by :kconfig:`CONFIG_SETTINGS`: * ``CONFIG_FLASH=y`` * ``CONFIG_FLASH_PAGE_LAYOUT=y`` @@ -75,8 +75,8 @@ Configuring additional thread behavior You can configure the thread behavior using the following Kconfig options: -* To adjust the stack size for the thread, change :option:`CONFIG_ZZHC_STACK_SIZE`. -* To adjust the thread priority, change :option:`CONFIG_ZZHC_THREAD_PRIO`. +* To adjust the stack size for the thread, change :kconfig:`CONFIG_ZZHC_STACK_SIZE`. +* To adjust the thread priority, change :kconfig:`CONFIG_ZZHC_THREAD_PRIO`. Allowing for automatic registration to LTE-M or NB-IoT on boot -------------------------------------------------------------- diff --git a/doc/nrf/libraries/zigbee/osif.rst b/doc/nrf/libraries/zigbee/osif.rst index 5a7bb7067b4f..d59f38f916ae 100644 --- a/doc/nrf/libraries/zigbee/osif.rst +++ b/doc/nrf/libraries/zigbee/osif.rst @@ -16,29 +16,29 @@ Configuration The ZBOSS OSIF layer implements a series of functions used by ZBOSS and is included in the |NCS|'s Zigbee subsystem. -The ZBOSS OSIF layer is automatically enabled when you enable the ZBOSS library with the :option:`CONFIG_ZIGBEE` Kconfig option. +The ZBOSS OSIF layer is automatically enabled when you enable the ZBOSS library with the :kconfig:`CONFIG_ZIGBEE` Kconfig option. You can also configure the following OSIF-related Kconfig options: -* :option:`CONFIG_ZIGBEE_APP_CB_QUEUE_LENGTH` - Defines the length of the application callback and alarm queue. +* :kconfig:`CONFIG_ZIGBEE_APP_CB_QUEUE_LENGTH` - Defines the length of the application callback and alarm queue. This queue is used to pass application callbacks and alarms from other threads or interrupts to the ZBOSS main loop context. -* :option:`CONFIG_ZIGBEE_DEBUG_FUNCTIONS` - Includes functions to suspend and resume the ZBOSS thread. +* :kconfig:`CONFIG_ZIGBEE_DEBUG_FUNCTIONS` - Includes functions to suspend and resume the ZBOSS thread. .. note:: These functions are useful for debugging, but they can cause instability of the device. -* :option:`CONFIG_ZIGBEE_HAVE_SERIAL` - Enables the UART serial abstract for the ZBOSS OSIF layer and allows to configure the serial glue layer. -* :option:`CONFIG_ZIGBEE_USE_BUTTONS` - Enables the buttons abstract for the ZBOSS OSIF layer. +* :kconfig:`CONFIG_ZIGBEE_HAVE_SERIAL` - Enables the UART serial abstract for the ZBOSS OSIF layer and allows to configure the serial glue layer. +* :kconfig:`CONFIG_ZIGBEE_USE_BUTTONS` - Enables the buttons abstract for the ZBOSS OSIF layer. You can use this option if you want to test ZBOSS examples directly in the |NCS|. -* :option:`CONFIG_ZIGBEE_USE_DIMMABLE_LED` - Dimmable LED (PWM) abstract for the ZBOSS OSIF layer. +* :kconfig:`CONFIG_ZIGBEE_USE_DIMMABLE_LED` - Dimmable LED (PWM) abstract for the ZBOSS OSIF layer. You can use this option if you want to test ZBOSS examples directly in the |NCS|. -* :option:`CONFIG_ZIGBEE_USE_LEDS` - LEDs abstract for the ZBOSS OSIF layer. +* :kconfig:`CONFIG_ZIGBEE_USE_LEDS` - LEDs abstract for the ZBOSS OSIF layer. You can use this option if you want to test ZBOSS examples directly in the |NCS|. -* :option:`CONFIG_ZIGBEE_USE_SOFTWARE_AES` - Configures the ZBOSS OSIF layer to use the software encryption. +* :kconfig:`CONFIG_ZIGBEE_USE_SOFTWARE_AES` - Configures the ZBOSS OSIF layer to use the software encryption. Additionally, the following Kconfig option is available when setting :ref:`zigbee_ug_logging_logger_options`: -* :option:`CONFIG_ZBOSS_OSIF_LOG_LEVEL` - Configures the custom logger options for the ZBOSS OSIF layer. +* :kconfig:`CONFIG_ZBOSS_OSIF_LOG_LEVEL` - Configures the custom logger options for the ZBOSS OSIF layer. API documentation ***************** diff --git a/doc/nrf/libraries/zigbee/shell.rst b/doc/nrf/libraries/zigbee/shell.rst index 0598ace7536c..2c5ebfb8a55f 100644 --- a/doc/nrf/libraries/zigbee/shell.rst +++ b/doc/nrf/libraries/zigbee/shell.rst @@ -23,10 +23,10 @@ To change this and other Zephyr's shell settings (for example, the prompt or the To configure the Zigbee shell library, use the following options: -* :option:`CONFIG_ZIGBEE_SHELL` -* :option:`CONFIG_ZIGBEE_SHELL_ENDPOINT` -* :option:`CONFIG_ZIGBEE_SHELL_DEBUG_CMD` -* :option:`CONFIG_ZIGBEE_SHELL_LOG_LEVEL` +* :kconfig:`CONFIG_ZIGBEE_SHELL` +* :kconfig:`CONFIG_ZIGBEE_SHELL_ENDPOINT` +* :kconfig:`CONFIG_ZIGBEE_SHELL_DEBUG_CMD` +* :kconfig:`CONFIG_ZIGBEE_SHELL_LOG_LEVEL` For detailed steps about configuring the library in a Zigbee sample or application, see :ref:`ug_zigbee_configuring_components_logger_ep`. diff --git a/doc/nrf/nrf.doxyfile.in b/doc/nrf/nrf.doxyfile.in index 12737f4ddb29..85d383f4bc7f 100644 --- a/doc/nrf/nrf.doxyfile.in +++ b/doc/nrf/nrf.doxyfile.in @@ -227,7 +227,7 @@ ALIASES = "rst=\verbatim embed:rst" \ "r=\verbatim embed:rst:leading-asterisk" \ "er=\endverbatim" -ALIASES += option{1}="\verbatim embed:rst:inline :option:`\1` \endverbatim" +ALIASES += kconfig{1}="\verbatim embed:rst:inline :kconfig:`\1` \endverbatim" ALIASES += "req=\xrefitem req \"Requirement\" \"Requirements\" " # This tag can be used to specify a number of word-keyword mappings (TCL only). diff --git a/doc/nrf/releases/release-notes-1.1.0.rst b/doc/nrf/releases/release-notes-1.1.0.rst index fe324e5d0e7f..a9611b64f3a0 100644 --- a/doc/nrf/releases/release-notes-1.1.0.rst +++ b/doc/nrf/releases/release-notes-1.1.0.rst @@ -337,7 +337,7 @@ nRF BLE Controller * Improved the default static memory pool allocation. The controller now determines its static memory pool size based on the maximum Link Layer packet length. - This is determined by the Kconfig macro :option:`CONFIG_BT_CTLR_DATA_LENGTH_MAX` (if defined), or else the minimum packet length (which is 27 B). + This is determined by the Kconfig macro :kconfig:`CONFIG_BT_CTLR_DATA_LENGTH_MAX` (if defined), or else the minimum packet length (which is 27 B). The memory pool is large enough to facilitate one master and one slave link. * Added support for connection intervals less than the standard minimum of 7.5 ms. @@ -392,7 +392,7 @@ Bluetooth Low Energy * Added "Numeric Comparison" pairing support and aligned LED usage in peripheral samples. * Added nRF52840 Dongle support in :ref:`peripheral_lbs`. -* Fixed default connections configuration when selecting :option:`CONFIG_BT_LL_SOFTDEVICE`. +* Fixed default connections configuration when selecting :kconfig:`CONFIG_BT_LL_SOFTDEVICE`. NFC @@ -514,15 +514,15 @@ Subsystems Bluetooth Low Energy -------------------- -* :option:`CONFIG_BT_HCI_TX_STACK_SIZE` must be set to 1536 when selecting :option:`CONFIG_BT_LL_SOFTDEVICE`. +* :kconfig:`CONFIG_BT_HCI_TX_STACK_SIZE` must be set to 1536 when selecting :kconfig:`CONFIG_BT_LL_SOFTDEVICE`. * The :ref:`nrfxlib:softdevice_controller` 0.3.0-3.prealpha might assert when receiving a packet with an CRC error on LE Coded PHY after performing a DLE procedure where RX Octets is changed to a value above 140. -* :option:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` must be set to 2048 when selecting :option:`CONFIG_BT_LL_SOFTDEVICE` on :ref:`central_uart` and :ref:`central_bas`. -* :option:`CONFIG_NFCT_IRQ_PRIORITY` must be set to 5 or less when selecting :option:`CONFIG_BT_LL_SOFTDEVICE` on :ref:`peripheral_hids_keyboard`. -* When selecting :option:`CONFIG_BT_LL_SOFTDEVICE`: +* :kconfig:`CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE` must be set to 2048 when selecting :kconfig:`CONFIG_BT_LL_SOFTDEVICE` on :ref:`central_uart` and :ref:`central_bas`. +* :kconfig:`CONFIG_NFCT_IRQ_PRIORITY` must be set to 5 or less when selecting :kconfig:`CONFIG_BT_LL_SOFTDEVICE` on :ref:`peripheral_hids_keyboard`. +* When selecting :kconfig:`CONFIG_BT_LL_SOFTDEVICE`: If a directed high duty cycle advertiser times out, the application might have to wait a short time before starting a new connectable advertiser. Otherwise, starting the advertiser will fail. * Bluetooth Low Energy peripheral samples are unstable in some conditions (when pairing and bonding are performed and then disconnections/re-connections happen). -* When running the :ref:`bluetooth_central_dfu_smp` sample, the :option:`CONFIG_BT_SMP` configuration must be aligned between this sample and the Zephyr counterpart (:ref:`zephyr:smp_svr_sample`). +* When running the :ref:`bluetooth_central_dfu_smp` sample, the :kconfig:`CONFIG_BT_SMP` configuration must be aligned between this sample and the Zephyr counterpart (:ref:`zephyr:smp_svr_sample`). However, security is not enabled by default in the Zephyr sample. * The central samples (:ref:`central_uart`, :ref:`bluetooth_central_hids`) do not support any pairing methods with MITM protection. * On some operating systems, the nrf_desktop application is unable to reconnect to a host. diff --git a/doc/nrf/releases/release-notes-1.2.0.rst b/doc/nrf/releases/release-notes-1.2.0.rst index dadc1bf211a8..a995ef4bf203 100644 --- a/doc/nrf/releases/release-notes-1.2.0.rst +++ b/doc/nrf/releases/release-notes-1.2.0.rst @@ -556,7 +556,7 @@ Bluetooth Low Energy NFC requires this API to work correctly. * When the :ref:`peripheral_hids_mouse` sample is used with the Zephyr Bluetooth LE Controller, directed advertising does not time out and the regular advertising cannot be started. * The :ref:`bluetooth_central_hids` sample cannot connect to a peripheral that uses directed advertising. -* When running the :ref:`bluetooth_central_dfu_smp` sample, the :option:`CONFIG_BT_SMP` configuration must be aligned between this sample and the Zephyr counterpart (:ref:`zephyr:smp_svr_sample`). +* When running the :ref:`bluetooth_central_dfu_smp` sample, the :kconfig:`CONFIG_BT_SMP` configuration must be aligned between this sample and the Zephyr counterpart (:ref:`zephyr:smp_svr_sample`). However, security is not enabled by default in the Zephyr sample. * The central samples (:ref:`central_uart`, :ref:`bluetooth_central_hids`) do not support any pairing methods with MITM protection. * On some operating systems, the nrf_desktop application is unable to reconnect to a host. diff --git a/doc/nrf/releases/release-notes-1.3.0.rst b/doc/nrf/releases/release-notes-1.3.0.rst index 65b856e5ef1f..171cea7995f4 100644 --- a/doc/nrf/releases/release-notes-1.3.0.rst +++ b/doc/nrf/releases/release-notes-1.3.0.rst @@ -370,7 +370,7 @@ Secure Partition Manager (SPM) * Added support for disabling some services in the :ref:`secure_services` sample. It now works in more bootloader configurations. -* Disabled :option:`CONFIG_SPM_SERVICE_PREVALIDATE` in the :ref:`lib_spm` library, because this option requires the immutable bootloader. +* Disabled :kconfig:`CONFIG_SPM_SERVICE_PREVALIDATE` in the :ref:`lib_spm` library, because this option requires the immutable bootloader. * Updated the :ref:`lib_spm` library to make it compatible with nRF5340 (with or without `anomaly 19`_). CPU load measurement @@ -589,7 +589,7 @@ Bluetooth Low Energy NFC requires this API to work correctly. (fixed) * When the :ref:`peripheral_hids_mouse` sample is used with the Zephyr Bluetooth LE Controller, directed advertising does not time out and the regular advertising cannot be started. (fixed) * The :ref:`bluetooth_central_hids` sample cannot connect to a peripheral that uses directed advertising. (fixed) -* When running the :ref:`bluetooth_central_dfu_smp` sample, the :option:`CONFIG_BT_SMP` configuration must be aligned between this sample and the Zephyr counterpart (:ref:`zephyr:smp_svr_sample`). +* When running the :ref:`bluetooth_central_dfu_smp` sample, the :kconfig:`CONFIG_BT_SMP` configuration must be aligned between this sample and the Zephyr counterpart (:ref:`zephyr:smp_svr_sample`). However, security is not enabled by default in the Zephyr sample. (fixed) * On some operating systems, the nrf_desktop application is unable to reconnect to a host. (fixed) diff --git a/doc/nrf/releases/release-notes-1.4.0.rst b/doc/nrf/releases/release-notes-1.4.0.rst index e0fb3a50127d..90e63fc501d1 100644 --- a/doc/nrf/releases/release-notes-1.4.0.rst +++ b/doc/nrf/releases/release-notes-1.4.0.rst @@ -92,7 +92,7 @@ nRF9160 * :ref:`lib_download_client` library: - * Added CoAP block-wise transfer support, which can be enabled with :option:`CONFIG_COAP`. + * Added CoAP block-wise transfer support, which can be enabled with :kconfig:`CONFIG_COAP`. * Updated functions that end with ``_connect()`` and ``_start()`` to parse complete URLs, with port and schema. * Removed ``port`` field in :c:struct:`download_client_cfg`. The port number can now be passed together with the URL. @@ -178,9 +178,9 @@ nRF9160 * :ref:`lib_nrf_cloud` library: * Added saving of a valid session flag to settings after all subscriptions have completed, so that the persistent session is only used when the flag is valid. - * Replaced ``CONFIG_CLOUD_PERSISTENT_SESSIONS`` usage with Zephyr's :option:`CONFIG_MQTT_CLEAN_SESSION`. + * Replaced ``CONFIG_CLOUD_PERSISTENT_SESSIONS`` usage with Zephyr's :kconfig:`CONFIG_MQTT_CLEAN_SESSION`. * Made the MQTT client ID prefix configurable. - * Added an option to set send time-out for the socket used by nRF Cloud library (:option:`CONFIG_NRF_CLOUD_SEND_TIMEOUT`). + * Added an option to set send time-out for the socket used by nRF Cloud library (:kconfig:`CONFIG_NRF_CLOUD_SEND_TIMEOUT`). nRF5 ==== @@ -284,7 +284,7 @@ Bluetooth Mesh * :ref:`bt_mesh_light_ctl_readme` - These models allow remote control and configuration of CTLs on a mesh device. * :ref:`bt_mesh_scene_readme` - These models allow storing the model state of the entire mesh network as a *scene*, which can be recalled at a later time. * Added support for Mesh Device Properties v2.0. - * Added :option:`CONFIG_BT_TINYCRYPT_ECC` option in :file:`prj.conf` files for samples that support nRF5340 (:ref:`bluetooth_mesh_light` or :ref:`bluetooth_mesh_light_switch`). + * Added :kconfig:`CONFIG_BT_TINYCRYPT_ECC` option in :file:`prj.conf` files for samples that support nRF5340 (:ref:`bluetooth_mesh_light` or :ref:`bluetooth_mesh_light_switch`). * Updated: diff --git a/doc/nrf/releases/release-notes-1.5.0.rst b/doc/nrf/releases/release-notes-1.5.0.rst index ac02e8c23b5d..4129e2c7f2c0 100644 --- a/doc/nrf/releases/release-notes-1.5.0.rst +++ b/doc/nrf/releases/release-notes-1.5.0.rst @@ -104,7 +104,7 @@ nRF9160 * :ref:`lib_nrf_cloud` library: * nRF Connect for Cloud FOTA replaced AWS Jobs as the FOTA mechanism for devices connected to nRF Connect for Cloud. - * Removed :option:`CONFIG_CLOUD_API` dependency from :option:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD`. + * Removed :kconfig:`CONFIG_CLOUD_API` dependency from :kconfig:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD`. * Added a new API :c:func:`nrf_cloud_send` that can be used for sending pre-encoded data to specified endpoint topics in nRF Connect for Cloud. * :ref:`at_cmd_parser_readme` library - The library can now parse AT command strings with negative numbers in the range supported by the int32_t type. @@ -154,7 +154,7 @@ nRF5340 SoC * :ref:`esb_readme` subsystem - Added support for nRF5340 (CPUNET) in the ESB subsystem. * :ref:`lib_spm` subsystem - Added support for nRF5340 peripherals in non-secure applications. * :ref:`ble_samples` - Added configuration overlays for child image to the required Bluetooth LE samples so that no Kconfig updates in the :ref:`zephyr:bluetooth-hci-rpmsg-sample` sample are needed by default. - * :ref:`nrf5340_empty_app_core` sample - Disabled the kernel memory pool option :option:`CONFIG_KERNEL_MEM_POOL` to reduce the memory footprint. + * :ref:`nrf5340_empty_app_core` sample - Disabled the kernel memory pool option :kconfig:`CONFIG_KERNEL_MEM_POOL` to reduce the memory footprint. * ``bl_boot`` library - Disabled clock interrupts before booting the application. This change fixes an issue where the :ref:`bootloader` sample would not be able to boot a Zephyr application on the nRF5340 SoC. @@ -369,7 +369,7 @@ Crypto * :ref:`nrfxlib:nrf_security`: * Added Kconfig options for TLS/DTLS and x509 certificates. - * Added Kconfig options for ``PK`` and ``PK_WRITE`` (:option:`CONFIG_MBEDTLS_PK_C` and :option:`CONFIG_MBEDTLS_PK_WRITE_C`). + * Added Kconfig options for ``PK`` and ``PK_WRITE`` (:kconfig:`CONFIG_MBEDTLS_PK_C` and :kconfig:`CONFIG_MBEDTLS_PK_WRITE_C`). * Rewrote the stripping mechanism of the library to not use the ``POST_BUILD`` option in a custom build rule. The library stripping mechanism was non-functional in certain versions of |SES| Nordic Edition. @@ -435,11 +435,11 @@ The following list summarizes the most important changes inherited from upstream * Allowed the final data chunk in the image to be unaligned in the serial-recovery protocol. * Updated the ``CONFIG_BOOT_DIRECT_XIP_REVERT`` option to be valid only in xip-mode. * Added an offset parameter to the tinycrypt ctr mode so that it can be properly used as a streaming cipher. - * Configured the bootloader to use a minimal CBPRINTF (:option:`CONFIG_CBPRINTF_NANO`) implementation. - * Configured logging to use :option:`CONFIG_LOG_MINIMAL` by default. + * Configured the bootloader to use a minimal CBPRINTF (:kconfig:`CONFIG_CBPRINTF_NANO`) implementation. + * Configured logging to use :kconfig:`CONFIG_LOG_MINIMAL` by default. * Fixed a vulnerability with nokogiri<=1.11.0.rc4. * Introduced a bootutil_public library that contains code common to MCUboot and the DFU application. - See :option:`CONFIG_MCUBOOT_BOOTUTIL_LIB`. + See :kconfig:`CONFIG_MCUBOOT_BOOTUTIL_LIB`. * Image tool: @@ -460,7 +460,7 @@ The following list summarizes the most important changes inherited from upstream In this case, it was not possible to update the device and mcumgr would return error code 6 (``MGMT_ERR_EBADSTATE``). * Added support for invoking shell commands (shell management) from the mcumgr command line. * Added optional verification of an uploaded direct-xip binary, which will reject any binary that cannot boot from the base address of the offered upload slot. - This verification can be enabled through :option:`CONFIG_IMG_MGMT_REJECT_DIRECT_XIP_MISMATCHED_SLOT`. + This verification can be enabled through :kconfig:`CONFIG_IMG_MGMT_REJECT_DIRECT_XIP_MISMATCHED_SLOT`. Zephyr ====== @@ -543,7 +543,7 @@ The following list summarizes the most important changes inherited from upstream * Updated :c:func:`k_timer_user_data_get` to take a ``const struct k_timer *timer`` instead of a non-\ ``const`` pointer. * Added a :c:macro:`K_DELAYED_WORK_DEFINE` macro. - * Added a :option:`CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION` option. + * Added a :kconfig:`CONFIG_MEM_SLAB_TRACE_MAX_UTILIZATION` option. If enabled, :c:func:`k_mem_slab_max_used_get` can be used to get a memory slab's maximum utilization in blocks. * Bug fixes: @@ -636,8 +636,8 @@ The following list summarizes the most important changes inherited from upstream * Flash: * Modified the nRF QSPI NOR driver so that it also supports nRF53 Series SoCs. - * Added missing selection of :option:`CONFIG_FLASH_HAS_PAGE_LAYOUT` for the SPI NOR and AT45 family flash drivers. - * Refactored the nRF QSPI NOR driver so that it no longer depends on :option:`CONFIG_MULTITHREADING`. + * Added missing selection of :kconfig:`CONFIG_FLASH_HAS_PAGE_LAYOUT` for the SPI NOR and AT45 family flash drivers. + * Refactored the nRF QSPI NOR driver so that it no longer depends on :kconfig:`CONFIG_MULTITHREADING`. * Removed ``CONFIG_NORDIC_QSPI_NOR_QE_BIT``. Use the ``quad-enable-requirements`` devicetree property instead. * Added JESD216 support to the nRF QSPI NOR driver. @@ -735,14 +735,14 @@ The following list summarizes the most important changes inherited from upstream * Added support for RX packet queueing in TCP2. * Added network management events for DHCPv4. * Added periodic throughput printout to the :ref:`zephyr:sockets-echo-server-sample` sample. - * Added an experimental option to set preemptive priority for networking threads (:option:`CONFIG_NET_TC_THREAD_PREEMPTIVE`). - * Added a Kconfig option that enables a hostname update on link address change (:option:`CONFIG_NET_HOSTNAME_UNIQUE_UPDATE`). + * Added an experimental option to set preemptive priority for networking threads (:kconfig:`CONFIG_NET_TC_THREAD_PREEMPTIVE`). + * Added a Kconfig option that enables a hostname update on link address change (:kconfig:`CONFIG_NET_HOSTNAME_UNIQUE_UPDATE`). * Added multiple fixes to the DHCP implementation. * Added support for the Distributed Switch Architecture (DSA). * LwM2M: - * Made the endpoint name length configurable with Kconfig (see :option:`CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH`). + * Made the endpoint name length configurable with Kconfig (see :kconfig:`CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH`). * Fixed PUSH FOTA block transfer with Opaque content format. * Added various improvements to the bootstrap procedure. * Fixed token generation. @@ -764,22 +764,22 @@ The following list summarizes the most important changes inherited from upstream * Added new OpenThread options: * ``CONFIG_OPENTHREAD_NCP_BUFFER_SIZE`` - * :option:`CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS` - * :option:`CONFIG_OPENTHREAD_MAX_STATECHANGE_HANDLERS` - * :option:`CONFIG_OPENTHREAD_TMF_ADDRESS_CACHE_ENTRIES` - * :option:`CONFIG_OPENTHREAD_MAX_CHILDREN` - * :option:`CONFIG_OPENTHREAD_MAX_IP_ADDR_PER_CHILD` - * :option:`CONFIG_OPENTHREAD_LOG_PREPEND_LEVEL_ENABLE` - * :option:`CONFIG_OPENTHREAD_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE` - * :option:`CONFIG_OPENTHREAD_MAC_SOFTWARE_RETRANSMIT_ENABLE` + * :kconfig:`CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS` + * :kconfig:`CONFIG_OPENTHREAD_MAX_STATECHANGE_HANDLERS` + * :kconfig:`CONFIG_OPENTHREAD_TMF_ADDRESS_CACHE_ENTRIES` + * :kconfig:`CONFIG_OPENTHREAD_MAX_CHILDREN` + * :kconfig:`CONFIG_OPENTHREAD_MAX_IP_ADDR_PER_CHILD` + * :kconfig:`CONFIG_OPENTHREAD_LOG_PREPEND_LEVEL_ENABLE` + * :kconfig:`CONFIG_OPENTHREAD_MAC_SOFTWARE_ACK_TIMEOUT_ENABLE` + * :kconfig:`CONFIG_OPENTHREAD_MAC_SOFTWARE_RETRANSMIT_ENABLE` * ``CONFIG_OPENTHREAD_PLATFORM_USEC_TIMER_ENABLE`` - * :option:`CONFIG_OPENTHREAD_RADIO_LINK_IEEE_802_15_4_ENABLE` - * :option:`CONFIG_OPENTHREAD_RADIO_LINK_TREL_ENABLE` - * :option:`CONFIG_OPENTHREAD_CSL_SAMPLE_WINDOW` - * :option:`CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD` - * :option:`CONFIG_OPENTHREAD_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE` - * :option:`CONFIG_OPENTHREAD_PLATFORM_INFO` - * :option:`CONFIG_OPENTHREAD_RADIO_WORKQUEUE_STACK_SIZE` + * :kconfig:`CONFIG_OPENTHREAD_RADIO_LINK_IEEE_802_15_4_ENABLE` + * :kconfig:`CONFIG_OPENTHREAD_RADIO_LINK_TREL_ENABLE` + * :kconfig:`CONFIG_OPENTHREAD_CSL_SAMPLE_WINDOW` + * :kconfig:`CONFIG_OPENTHREAD_CSL_RECEIVE_TIME_AHEAD` + * :kconfig:`CONFIG_OPENTHREAD_MAC_SOFTWARE_CSMA_BACKOFF_ENABLE` + * :kconfig:`CONFIG_OPENTHREAD_PLATFORM_INFO` + * :kconfig:`CONFIG_OPENTHREAD_RADIO_WORKQUEUE_STACK_SIZE` * Added support for RCP co-processor mode. * Fixed multicast packet reception. @@ -800,7 +800,7 @@ The following list summarizes the most important changes inherited from upstream * CoAP: * Added a retransmission counter to the :c:struct:`coap_pending` structure to simplify the retransmission logic. - * Added a Kconfig option to randomize the initial ACK time-out, as specified in RFC 7252 (:option:`CONFIG_COAP_RANDOMIZE_ACK_TIMEOUT`). + * Added a Kconfig option to randomize the initial ACK time-out, as specified in RFC 7252 (:kconfig:`CONFIG_COAP_RANDOMIZE_ACK_TIMEOUT`). * Fixed encoding of long options (larger than 268 bytes). * Bluetooth Mesh: @@ -835,12 +835,12 @@ The following list summarizes the most important changes inherited from upstream * Added a :c:macro:`FS_MOUNT_FLAG_NO_FORMAT` flag to the FatFs options. This flag removes formatting capabilities from the FAT/exFAT file system driver and prevents unformatted devices to be formatted, to FAT or exFAT, on mount attempt. * Added support for the following :c:func:`fs_mount` flags: :c:macro:`FS_MOUNT_FLAG_READ_ONLY`, :c:macro:`FS_MOUNT_FLAG_NO_FORMAT` - * Updated the FS API to not perform a runtime check of a driver interface when the :option:`CONFIG_NO_RUNTIME_CHECKS` option is enabled. + * Updated the FS API to not perform a runtime check of a driver interface when the :kconfig:`CONFIG_NO_RUNTIME_CHECKS` option is enabled. * DFU: * Added shell module for MCUboot enabled application. - See :option:`CONFIG_MCUBOOT_SHELL`. + See :kconfig:`CONFIG_MCUBOOT_SHELL`. * Reworked the implementation to use MCUboot's bootutil_public library instead of the Zephyr implementation of the same API. * IPC: @@ -853,7 +853,7 @@ The following list summarizes the most important changes inherited from upstream * Renamed sanitycheck to Twister. * Ensured that shields can be placed in other BOARD_ROOT folders. * Added basic support for Clang 10 with x86. - * Fixed a bug that prevented compiling the :ref:`bootloader` with :option:`CONFIG_SB_SIGNING_PUBLIC_KEY` + * Fixed a bug that prevented compiling the :ref:`bootloader` with :kconfig:`CONFIG_SB_SIGNING_PUBLIC_KEY` * System: @@ -880,7 +880,7 @@ The following list summarizes the most important changes inherited from upstream * Modules: - * Introduced a :option:`CONFIG_MBEDTLS_MEMORY_DEBUG` option for mbedtls. + * Introduced a :kconfig:`CONFIG_MBEDTLS_MEMORY_DEBUG` option for mbedtls. * Updated LVGL to v7.6.1. * Updated libmetal and openamp to v2020.10. * Updated nrfx in hal-nordic to version 2.4.0. @@ -992,7 +992,7 @@ Applications and samples * :ref:`serial_lte_modem` - Added documentation for new commands. Fixed the syntax and examples of some existing commands. - * Added a note about :option:`CONFIG_MQTT_KEEPALIVE` option to the :ref:`aws_iot`, :ref:`azure_iot_hub`, and :ref:`cloud_client` samples. + * Added a note about :kconfig:`CONFIG_MQTT_KEEPALIVE` option to the :ref:`aws_iot`, :ref:`azure_iot_hub`, and :ref:`cloud_client` samples. * Bluetooth: * Added a note about child-image overlay to the :ref:`bluetooth_central_hr_coded` and :ref:`peripheral_hr_coded` samples. diff --git a/doc/nrf/releases/release-notes-1.6.0.rst b/doc/nrf/releases/release-notes-1.6.0.rst index 40cb00c6a55d..a57735d5936e 100644 --- a/doc/nrf/releases/release-notes-1.6.0.rst +++ b/doc/nrf/releases/release-notes-1.6.0.rst @@ -118,7 +118,7 @@ nRF9160 * :ref:`lib_nrf_cloud` library: * Added cellular positioning support to the :ref:`lib_nrf_cloud_cell_pos` library. - * Added Kconfig option :option:`CONFIG_NRF_CLOUD_CELL_POS` to obtain cell-based location from nRF Cloud instead of using the modem's GPS. + * Added Kconfig option :kconfig:`CONFIG_NRF_CLOUD_CELL_POS` to obtain cell-based location from nRF Cloud instead of using the modem's GPS. * Added function :c:func:`nrf_cloud_modem_fota_completed`, which is to be called by the application after it re-initializes the modem (instead of rebooting) after a modem FOTA update. * Updated to include the FOTA type value in the :c:enumerator:`NRF_CLOUD_EVT_FOTA_DONE` event. * Updated configuration options for setting the source of the MQTT client ID (nRF Cloud device ID). @@ -132,7 +132,7 @@ nRF9160 * Added :file:`overlay-agps-pgps.conf` to enable A-GPS and P-GPS support. * Updated to handle new Kconfig options: - * :option:`CONFIG_NRF_CLOUD_CELL_POS` + * :kconfig:`CONFIG_NRF_CLOUD_CELL_POS` * :ref:`asset_tracker_v2` application: @@ -206,8 +206,8 @@ nRF9160 * Removed provisioning using :ref:`modem_key_mgmt` and :file:`certificates.h`, because this is not the recommended way of provisioning private certificates. * Renamed the following Kconfig options: - * ``CONFIG_CLOUD_CERT_SEC_TAG`` renamed to :option:`CONFIG_CERT_SEC_TAG`. - * ``CONFIG_USE_CLOUD_CLIENT_ID`` renamed to :option:`CONFIG_USE_CUSTOM_CLIENT_ID`. + * ``CONFIG_CLOUD_CERT_SEC_TAG`` renamed to :kconfig:`CONFIG_CERT_SEC_TAG`. + * ``CONFIG_USE_CLOUD_CLIENT_ID`` renamed to :kconfig:`CONFIG_USE_CUSTOM_CLIENT_ID`. * ``CONFIG_CLOUD_CLIENT_ID`` renamed to ``CONFIG_CLIENT_ID``. * ``CONFIG_NRF_CLOUD_CLIENT_ID_PREFIX`` renamed to ``CONFIG_CLIENT_ID_PREFIX``. @@ -257,7 +257,7 @@ Bluetooth mesh * Updated the :ref:`bt_mesh_light_xyl_srv_readme` model to publish its state values that were loaded from flash after powering up. * Replaced the linked list of scene entries in the model contexts, with a lookup in ROM-allocated scene entries. * Updated so the transition pointer can be NULL, if no transition time parameters are provided in APIs. - * Renamed Kconfig option ``CONFIG_BT_MESH_LIGHT_CTRL_STORE_TIMEOUT`` to :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`, and default value is set to 0. + * Renamed Kconfig option ``CONFIG_BT_MESH_LIGHT_CTRL_STORE_TIMEOUT`` to :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`, and default value is set to 0. * Updated the :ref:`bt_mesh_light_ctrl_srv_readme` model with a timer, allowing it to resume operation after a certain delay. * Updated the proportional-integral (PI) feedback regulator to use instant transition time to relieve the application from overhead. * Fixed an issue where an undefined state for some sensor properties is a valid state, and should be handled without giving errors. @@ -273,7 +273,7 @@ Bluetooth mesh * Fixed an issue where :ref:`bt_mesh_light_ctrl_srv_readme` should disable control when the lightness is set by receiving a message. * Added persistent storage to the :ref:`bt_mesh_scheduler_readme` to restore previously configured entries on power-up. * Fixed an issue where CTL temperature bindings should use rounding operation for division in the binding formula. - * Samples are using :option:`CONFIG_NVS` instead of :option:`CONFIG_FCB` as the default storage backend. + * Samples are using :kconfig:`CONFIG_NVS` instead of :kconfig:`CONFIG_FCB` as the default storage backend. * Fixed an issue in :ref:`bt_mesh_light_ctrl_srv_readme` by always setting the transition time to a Fade Standby Manual state time when a Light Off event is received. * Fixed an issue by reporting maximum remaining time for all components for CTL state transition time when GET is processed. * Fixed an issue where a deleted :ref:`bt_mesh_scene_srv_readme` did not delete all its pages from the file system. diff --git a/doc/nrf/samples.rst b/doc/nrf/samples.rst index 0a9029e09105..f2e6366fb7a7 100644 --- a/doc/nrf/samples.rst +++ b/doc/nrf/samples.rst @@ -15,7 +15,7 @@ Those samples are a good starting point for understanding how to put together yo .. note:: All samples in the |NCS| are configured to perform a system reset if a fatal error occurs. This behavior is different from how fatal errors are handled in the Zephyr samples. - You can change the default behavior by updating the configuration option :option:`CONFIG_RESET_ON_FATAL_ERROR`. + You can change the default behavior by updating the configuration option :kconfig:`CONFIG_RESET_ON_FATAL_ERROR`. .. toctree:: :maxdepth: 1 diff --git a/doc/nrf/shortcuts.txt b/doc/nrf/shortcuts.txt index d030628651dd..bed9d1a6d69c 100644 --- a/doc/nrf/shortcuts.txt +++ b/doc/nrf/shortcuts.txt @@ -40,9 +40,9 @@ .. |fota_upgrades_def| replace:: You can upgrade the firmware of the device over the air, thus without a wired connection. Such an upgrade is called a FOTA (firmware over-the-air) upgrade. -.. |fota_upgrades_req_mcuboot| replace:: To upgrade the application, you must use :doc:`mcuboot:index` as the upgradable bootloader (:option:`CONFIG_BOOTLOADER_MCUBOOT` must be enabled). +.. |fota_upgrades_req_mcuboot| replace:: To upgrade the application, you must use :doc:`mcuboot:index` as the upgradable bootloader (:kconfig:`CONFIG_BOOTLOADER_MCUBOOT` must be enabled). -.. |fota_upgrades_building| replace:: To create a binary file for an application upgrade, make sure that :option:`CONFIG_BOOTLOADER_MCUBOOT` is enabled and build the application as usual. +.. |fota_upgrades_building| replace:: To create a binary file for an application upgrade, make sure that :kconfig:`CONFIG_BOOTLOADER_MCUBOOT` is enabled and build the application as usual. The build will create several binary files (see :ref:`mcuboot:mcuboot_ncs`). .. |Google_CCLicense| replace:: Portions of this page are reproduced from work created and `shared by Google`_, and used according to terms described in the `Creative Commons 4.0 Attribution License`_. diff --git a/doc/nrf/templates/mesh_model_server_client_template.rst b/doc/nrf/templates/mesh_model_server_client_template.rst index 81021c7cdcd4..33704deebd39 100644 --- a/doc/nrf/templates/mesh_model_server_client_template.rst +++ b/doc/nrf/templates/mesh_model_server_client_template.rst @@ -46,11 +46,11 @@ Configuration* The following configuration parameters are associated with the XYZ Server/XYZ Client model: -* ``:option:PARAM_1`` - Short description of the first parameter. -* ``:option:PARAM_2`` - Short description of the second parameter. +* ``:kconfig:PARAM_1`` - Short description of the first parameter. +* ``:kconfig:PARAM_2`` - Short description of the second parameter. .. tip:: - List Kconfig options associated with the model, and link to them using the `:option:` reference. + List Kconfig options associated with the model, and link to them using the `:kconfig:` reference. This section is optional, because not all models have Kconfig parameters that allow configuration. Do not go into details here, as the link will allow the reader to get the required information. However, do provide a short description of each option. diff --git a/doc/nrf/templates/sample_README.rst b/doc/nrf/templates/sample_README.rst index 3b82d3814d67..ad8b11ea2fd9 100644 --- a/doc/nrf/templates/sample_README.rst +++ b/doc/nrf/templates/sample_README.rst @@ -124,7 +124,7 @@ Configuration options* .. note:: * You do not need to list all configuration options of the sample, but only the ones that are important for the sample and make sense for the user to know about. - * The syntax below allows sample configuration options to link to the option descriptions in the same way as the library configuration options link to the corresponding Kconfig descriptions (``:option:`SAMPLE_CONFIG```, which results in :option:`SAMPLE_CONFIG`). + * The syntax below allows sample configuration options to link to the option descriptions in the same way as the library configuration options link to the corresponding Kconfig descriptions (``:kconfig:`SAMPLE_CONFIG```, which results in :kconfig:`SAMPLE_CONFIG`). * For each configuration option, list the symbol name and the string describing it. Check and configure the following configuration options for the sample: @@ -143,13 +143,13 @@ Additional configuration* .. note:: * Add this section to describe and link to any library configuration options that might be important to run this sample. - You can link to options with ``:option:`CONFIG_XXX```. + You can link to options with ``:kconfig:`CONFIG_XXX```. * You do not need to list all possible configuration options, but only the ones that are relevant. Check and configure the following library options that are used by the sample: -* :option:`CONFIG_BT_DEVICE_NAME` - Defines the Bluetooth device name. -* :option:`CONFIG_BT_LBS` - Enables the :ref:`lbs_readme`. +* :kconfig:`CONFIG_BT_DEVICE_NAME` - Defines the Bluetooth device name. +* :kconfig:`CONFIG_BT_LBS` - Enables the :ref:`lbs_readme`. Configuration files* ==================== diff --git a/doc/nrf/ug_ble_controller.rst b/doc/nrf/ug_ble_controller.rst index 907dcc36becd..7fb172f1d25e 100644 --- a/doc/nrf/ug_ble_controller.rst +++ b/doc/nrf/ug_ble_controller.rst @@ -59,4 +59,4 @@ Most :ref:`Bluetooth LE samples ` in the |NCS| can use either Bluet An exception is the :ref:`ble_llpm` sample, which requires the SoftDevice Controller that supports LLPM. By default, all samples except for the Bluetooth mesh samples are currently configured to use SoftDevice Controller. -To use the Zephyr Bluetooth LE Controller instead, set :option:`CONFIG_BT_LL_SW_SPLIT` to ``y`` in the :file:`prj.conf` file (see :ref:`configure_application`) and make sure to build from a clean build directory. +To use the Zephyr Bluetooth LE Controller instead, set :kconfig:`CONFIG_BT_LL_SW_SPLIT` to ``y`` in the :file:`prj.conf` file (see :ref:`configure_application`) and make sure to build from a clean build directory. diff --git a/doc/nrf/ug_bootloader_adding.rst b/doc/nrf/ug_bootloader_adding.rst index f2220ae7b2c9..ccbcea3a1a36 100644 --- a/doc/nrf/ug_bootloader_adding.rst +++ b/doc/nrf/ug_bootloader_adding.rst @@ -39,7 +39,7 @@ The following sections describe how to add either |NSIB| or MCUboot as an immuta Adding |NSIB| as an immutable bootloader ======================================== -To build |NSIB| with a Zephyr or |NCS| sample, enable the :option:`CONFIG_SECURE_BOOT` in the application's ``prj.conf`` file, in an associated Kconfig fragment, or using the command line: +To build |NSIB| with a Zephyr or |NCS| sample, enable the :kconfig:`CONFIG_SECURE_BOOT` in the application's ``prj.conf`` file, in an associated Kconfig fragment, or using the command line: .. code-block:: console @@ -64,7 +64,7 @@ See :ref:`ug_bootloader_config` for more information about using Kconfig fragmen Adding a custom signature key file ---------------------------------- -To add a signature key file to this bootloader, set the :option:`CONFIG_SB_SIGNING_KEY_FILE` option in the application's ``prj.conf`` file, in an associated Kconfig fragment, or using the command line: +To add a signature key file to this bootloader, set the :kconfig:`CONFIG_SB_SIGNING_KEY_FILE` option in the application's ``prj.conf`` file, in an associated Kconfig fragment, or using the command line: .. tabs:: @@ -137,9 +137,9 @@ See :ref:`ug_fw_update_keys` for information on how to generate custom keys for Additionally, the |NSIB| supports the following methods for signing images with private keys: -* :ref:`ug_fw_update_keys_python` - The default method, using the :option:`CONFIG_SB_SIGNING_PYTHON`. -* :ref:`ug_fw_update_keys_openssl` - Uses the :option:`CONFIG_SB_SIGNING_OPENSSL`. -* :ref:`Using a custom command ` - Uses the :option:`CONFIG_SB_SIGNING_CUSTOM`. +* :ref:`ug_fw_update_keys_python` - The default method, using the :kconfig:`CONFIG_SB_SIGNING_PYTHON`. +* :ref:`ug_fw_update_keys_openssl` - Uses the :kconfig:`CONFIG_SB_SIGNING_OPENSSL`. +* :ref:`Using a custom command ` - Uses the :kconfig:`CONFIG_SB_SIGNING_CUSTOM`. Both Python and OpenSSL methods are handled internally by the build system, whereas using custom commands requires more configuration steps. @@ -193,7 +193,7 @@ To use a custom signing command with this bootloader, set the following options The public key string must be an absolute path to the location of the public key file, as mentioned previously in :ref:`ug_bootloader_adding_immutable_keys`. -See :option:`CONFIG_SB_SIGNING_COMMAND` for specifics about what a usable signing command must do. +See :kconfig:`CONFIG_SB_SIGNING_COMMAND` for specifics about what a usable signing command must do. The command string can include its own arguments like a typical terminal command, including arguments specific to the build system: .. parsed-literal:: @@ -201,7 +201,7 @@ The command string can include its own arguments like a typical terminal command my_command *[options]* ** ** -See the description of :option:`CONFIG_SB_SIGNING_COMMAND` for which arguments can be be sent to the build system in this way. +See the description of :kconfig:`CONFIG_SB_SIGNING_COMMAND` for which arguments can be be sent to the build system in this way. .. note:: @@ -326,7 +326,7 @@ The process to use specific signature keys with MCUboot used as the upgradable b Generating pre-signed variants ------------------------------ -Enable the :option:`CONFIG_BUILD_S1_VARIANT` option when building the upgradable bootloader to automatically generate :ref:`pre-signed variants ` of the image for both slots: +Enable the :kconfig:`CONFIG_BUILD_S1_VARIANT` option when building the upgradable bootloader to automatically generate :ref:`pre-signed variants ` of the image for both slots: .. code-block:: diff --git a/doc/nrf/ug_bootloader_config.rst b/doc/nrf/ug_bootloader_config.rst index 01f7f2c1ebef..f0ac6baced78 100644 --- a/doc/nrf/ug_bootloader_config.rst +++ b/doc/nrf/ug_bootloader_config.rst @@ -27,7 +27,7 @@ For example, you can assign custom project configurations for both the bootloade -Dmcuboot_CONF_FILE=prj_upgradable.conf \ -DCONF_FILE=prj_app.conf -In the example above, :file:`prj_app.conf` includes :option:`CONFIG_SECURE_BOOT` and ``CONFIG_BOOTLOADER_MCUBOOT`` to enable the immutable and upgradable bootloaders by default. +In the example above, :file:`prj_app.conf` includes :kconfig:`CONFIG_SECURE_BOOT` and ``CONFIG_BOOTLOADER_MCUBOOT`` to enable the immutable and upgradable bootloaders by default. You can use custom project configuration files in combination with temporary configuration options associated with a single build, set using either the command line or Kconfig fragments. diff --git a/doc/nrf/ug_bootloader_testing.rst b/doc/nrf/ug_bootloader_testing.rst index 98f6ce756cac..41b9561b1cf8 100644 --- a/doc/nrf/ug_bootloader_testing.rst +++ b/doc/nrf/ug_bootloader_testing.rst @@ -6,7 +6,7 @@ Testing the bootloader chain To test either of the bootloaders and the secure bootloader chain, build and program them with any sample as described in :ref:`Adding a bootloader chain `. By default, both |NSIB| and MCUboot print information to their serial output on boot. -This output includes information about the validation of images in its slots, as well as firmware-specific information if using :option:`CONFIG_FW_INFO` with the |NSIB|. +This output includes information about the validation of images in its slots, as well as firmware-specific information if using :kconfig:`CONFIG_FW_INFO` with the |NSIB|. To see this output: 1. |connect_terminal| diff --git a/doc/nrf/ug_bt_mesh_configuring.rst b/doc/nrf/ug_bt_mesh_configuring.rst index dffc2f078546..b4c148eaa096 100644 --- a/doc/nrf/ug_bt_mesh_configuring.rst +++ b/doc/nrf/ug_bt_mesh_configuring.rst @@ -7,29 +7,29 @@ Configuring Bluetooth mesh in |NCS| :local: :depth: 2 -The Bluetooth mesh support is controlled by :option:`CONFIG_BT_MESH`, which depends on the following configuration options: +The Bluetooth mesh support is controlled by :kconfig:`CONFIG_BT_MESH`, which depends on the following configuration options: -* :option:`CONFIG_BT` - Enables the Bluetooth subsystem. -* :option:`CONFIG_BT_OBSERVER` - Enables the Bluetooth Observer role. -* :option:`CONFIG_BT_PERIPHERAL` - Enables the Bluetooth Peripheral role. +* :kconfig:`CONFIG_BT` - Enables the Bluetooth subsystem. +* :kconfig:`CONFIG_BT_OBSERVER` - Enables the Bluetooth Observer role. +* :kconfig:`CONFIG_BT_PERIPHERAL` - Enables the Bluetooth Peripheral role. The Bluetooth mesh subsystem currently performs best with :ref:`Zephyr's Bluetooth LE Controller `. -To force |NCS| to build with this controller, enable :option:`CONFIG_BT_LL_SW_SPLIT`. +To force |NCS| to build with this controller, enable :kconfig:`CONFIG_BT_LL_SW_SPLIT`. Optional features configuration ******************************* Optional features in the Bluetooth mesh stack must be explicitly enabled: -* :option:`CONFIG_BT_MESH_RELAY` - Enables message relaying. -* :option:`CONFIG_BT_MESH_FRIEND` - Enables the Friend role. -* :option:`CONFIG_BT_MESH_LOW_POWER` - Enabels the Low Power role. -* :option:`CONFIG_BT_MESH_PROVISIONER` - Enables the Provisioner role. -* :option:`CONFIG_BT_MESH_GATT_PROXY` - Enables the GATT Proxy Server role. -* :option:`CONFIG_BT_MESH_PB_GATT` - Enables the GATT provisioning bearer. -* :option:`CONFIG_BT_MESH_CDB` - Enables the Configuration Database subsystem. +* :kconfig:`CONFIG_BT_MESH_RELAY` - Enables message relaying. +* :kconfig:`CONFIG_BT_MESH_FRIEND` - Enables the Friend role. +* :kconfig:`CONFIG_BT_MESH_LOW_POWER` - Enabels the Low Power role. +* :kconfig:`CONFIG_BT_MESH_PROVISIONER` - Enables the Provisioner role. +* :kconfig:`CONFIG_BT_MESH_GATT_PROXY` - Enables the GATT Proxy Server role. +* :kconfig:`CONFIG_BT_MESH_PB_GATT` - Enables the GATT provisioning bearer. +* :kconfig:`CONFIG_BT_MESH_CDB` - Enables the Configuration Database subsystem. -The persistent storage of the Bluetooth mesh provisioning and configuration data is enabled by :option:`CONFIG_BT_SETTINGS`. +The persistent storage of the Bluetooth mesh provisioning and configuration data is enabled by :kconfig:`CONFIG_BT_SETTINGS`. See the :ref:`zephyr:bluetooth-persistent-storage` section of :ref:`zephyr:bluetooth-arch` for details. Mesh models diff --git a/doc/nrf/ug_bt_mesh_vendor_model_chat_sample_walk_through.rst b/doc/nrf/ug_bt_mesh_vendor_model_chat_sample_walk_through.rst index 769419e3eebe..77df355d47f1 100644 --- a/doc/nrf/ug_bt_mesh_vendor_model_chat_sample_walk_through.rst +++ b/doc/nrf/ug_bt_mesh_vendor_model_chat_sample_walk_through.rst @@ -72,7 +72,7 @@ This is done through the :c:member:`bt_mesh_model_cb.reset` handler: :end-before: include_endpoint_chat_cli_rst_6 .. note:: - The :c:member:`bt_mesh_model_cb.settings_set` handler, and both :c:func:`bt_mesh_model_data_store` calls, are only compiled if :option:`CONFIG_BT_SETTINGS` is enabled, making it possible to exclude this functionality if the persistent storage is not enabled. + The :c:member:`bt_mesh_model_cb.settings_set` handler, and both :c:func:`bt_mesh_model_data_store` calls, are only compiled if :kconfig:`CONFIG_BT_SETTINGS` is enabled, making it possible to exclude this functionality if the persistent storage is not enabled. The following code initializes the model callbacks structure: diff --git a/doc/nrf/ug_bt_mesh_vendor_model_dev_overview.rst b/doc/nrf/ug_bt_mesh_vendor_model_dev_overview.rst index 0a5c5f7b1d44..3f58c1e60473 100644 --- a/doc/nrf/ug_bt_mesh_vendor_model_dev_overview.rst +++ b/doc/nrf/ug_bt_mesh_vendor_model_dev_overview.rst @@ -297,7 +297,7 @@ These callbacks are defined in :c:struct:`bt_mesh_model_cb`. :c:member:`bt_mesh_model_cb.settings_set` This handler is called when the model data is restored from the persistent storage. If you need to store data in the persistent storage, use the :c:func:`bt_mesh_model_data_store` function. - To use the persitent storage, it needs to be enabled with :option:`CONFIG_BT_SETTINGS`. + To use the persitent storage, it needs to be enabled with :kconfig:`CONFIG_BT_SETTINGS`. For more information on persistent storage, see :ref:`zephyr:settings_api`. :c:member:`bt_mesh_model_cb.start` diff --git a/doc/nrf/ug_edge_impulse.rst b/doc/nrf/ug_edge_impulse.rst index 7d668d1c547f..2bab5f167758 100644 --- a/doc/nrf/ug_edge_impulse.rst +++ b/doc/nrf/ug_edge_impulse.rst @@ -57,16 +57,16 @@ Complete the following steps to configure the building process: 1. Make sure that the following Kconfig options are enabled: - * :option:`CONFIG_CPLUSPLUS` - * :option:`CONFIG_STD_CPP11` - * :option:`CONFIG_LIB_CPLUSPLUS` - * :option:`CONFIG_NEWLIB_LIBC` - * :option:`CONFIG_NEWLIB_LIBC_FLOAT_PRINTF` - * :option:`CONFIG_FPU` - -#. Enable building the downloaded library by setting the :option:`CONFIG_EDGE_IMPULSE` Kconfig option. + * :kconfig:`CONFIG_CPLUSPLUS` + * :kconfig:`CONFIG_STD_CPP11` + * :kconfig:`CONFIG_LIB_CPLUSPLUS` + * :kconfig:`CONFIG_NEWLIB_LIBC` + * :kconfig:`CONFIG_NEWLIB_LIBC_FLOAT_PRINTF` + * :kconfig:`CONFIG_FPU` + +#. Enable building the downloaded library by setting the :kconfig:`CONFIG_EDGE_IMPULSE` Kconfig option. Setting this option also enables the :ref:`ei_wrapper`. -#. Enable and specify the Uniform Resource Identifier (URI) in the :option:`CONFIG_EDGE_IMPULSE_URI` Kconfig option. +#. Enable and specify the Uniform Resource Identifier (URI) in the :kconfig:`CONFIG_EDGE_IMPULSE_URI` Kconfig option. You can set it to one of the following values: * An absolute path to a file in the local file system. @@ -86,7 +86,7 @@ Downloading model directly from Edge Impulse studio As an example of downloadable URI, you can configure the |NCS| build system to download your model directly from the Edge Impulse studio. Complete the following steps to do this: -1. Set :option:`CONFIG_EDGE_IMPULSE_URI` to the URI from Edge Impulse studio: +1. Set :kconfig:`CONFIG_EDGE_IMPULSE_URI` to the URI from Edge Impulse studio: .. parsed-literal:: :class: highlight diff --git a/doc/nrf/ug_fw_update.rst b/doc/nrf/ug_fw_update.rst index e786c969c081..6d1886a85ea0 100644 --- a/doc/nrf/ug_fw_update.rst +++ b/doc/nrf/ug_fw_update.rst @@ -140,7 +140,7 @@ Key revocation can be a useful security measure for devices that have already be If a private key has been compromised or lost, you can invalidate its public key by uploading a new firmware image signed by another key known to the bootloader. These keys are kept internally by the bootloader, so the list of available public keys cannot change once it is deployed. -See :option:`CONFIG_SB_PUBLIC_KEY_FILES` for details on how this mechanism is implemented. +See :kconfig:`CONFIG_SB_PUBLIC_KEY_FILES` for details on how this mechanism is implemented. You can add this feature to your own project and check its functionality as follows: diff --git a/doc/nrf/ug_logging.rst b/doc/nrf/ug_logging.rst index 733d5f79e956..eadd82865100 100644 --- a/doc/nrf/ug_logging.rst +++ b/doc/nrf/ug_logging.rst @@ -35,8 +35,8 @@ You can use the Zephyr system logger in |NCS| for the following use cases: * Internal system logs - Useful for analyzing detailed system performance, for example issues with threads stack sizes. * Logs from external components - Useful for gathering messages from sample applications and custom modules. -The logger can be enabled with the :option:`CONFIG_LOG` Kconfig option. -This option is automatically set alongside the minimal logging implementation (:option:`CONFIG_LOG_MINIMAL`) with the :option:`CONFIG_NCS_SAMPLES_DEFAULTS` Kconfig option, which is enabled by default for all samples in |NCS|. +The logger can be enabled with the :kconfig:`CONFIG_LOG` Kconfig option. +This option is automatically set alongside the minimal logging implementation (:kconfig:`CONFIG_LOG_MINIMAL`) with the :kconfig:`CONFIG_NCS_SAMPLES_DEFAULTS` Kconfig option, which is enabled by default for all samples in |NCS|. For more information about configuring Zephyr's logger, see :ref:`zephyr:logging_api`. .. _ug_logging_net_application: @@ -83,8 +83,8 @@ UART The UART interface can be configured as a logging backend using the following Kconfig options: -* :option:`CONFIG_LOG_BACKEND_UART` - This option enables the UART logging backend. -* :option:`CONFIG_LOG_BACKEND_UART_SYST_ENABLE` - This option is used to output logs in system format. +* :kconfig:`CONFIG_LOG_BACKEND_UART` - This option enables the UART logging backend. +* :kconfig:`CONFIG_LOG_BACKEND_UART_SYST_ENABLE` - This option is used to output logs in system format. For information about how to see UART output, see :ref:`putty`. @@ -95,17 +95,17 @@ RTT SEGGER's J-Link RTT backend logging can be handled with the following Kconfig options: -* :option:`CONFIG_LOG_BACKEND_RTT` - This option enables RTT logging backend. -* :option:`CONFIG_LOG_BACKEND_RTT_MODE_DROP` - This option enables the mode in which messages that do not fit the buffer are dropped. -* :option:`CONFIG_LOG_BACKEND_RTT_MODE_BLOCK` - This option enables the mode in which the device is blocked until a message is transferred. -* :option:`CONFIG_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE` - This option defines the size of the buffer used for storing data prepared for sending. -* :option:`CONFIG_LOG_BACKEND_RTT_RETRY_CNT` - This option defines the number of retries before a message is dropped. -* :option:`CONFIG_LOG_BACKEND_RTT_RETRY_DELAY_MS` - This option defines the time interval between transmission retries. -* :option:`CONFIG_LOG_BACKEND_RTT_SYST_ENABLE` - This option is used to output logs in the system format. -* :option:`CONFIG_LOG_BACKEND_RTT_MESSAGE_SIZE` - This option defines the maximum message size. -* :option:`CONFIG_LOG_BACKEND_RTT_BUFFER` - This option selects the index of the buffer used for logger output. -* :option:`CONFIG_LOG_BACKEND_RTT_BUFFER_SIZE` - This option defines the size of the buffer used for logger output. -* :option:`CONFIG_LOG_BACKEND_RTT_FORCE_PRINTK` - This option enables processing of ``printk`` calls in the logger buffers instead of the RTT buffer. +* :kconfig:`CONFIG_LOG_BACKEND_RTT` - This option enables RTT logging backend. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_MODE_DROP` - This option enables the mode in which messages that do not fit the buffer are dropped. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_MODE_BLOCK` - This option enables the mode in which the device is blocked until a message is transferred. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE` - This option defines the size of the buffer used for storing data prepared for sending. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_RETRY_CNT` - This option defines the number of retries before a message is dropped. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_RETRY_DELAY_MS` - This option defines the time interval between transmission retries. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_SYST_ENABLE` - This option is used to output logs in the system format. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_MESSAGE_SIZE` - This option defines the maximum message size. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_BUFFER` - This option selects the index of the buffer used for logger output. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_BUFFER_SIZE` - This option defines the size of the buffer used for logger output. +* :kconfig:`CONFIG_LOG_BACKEND_RTT_FORCE_PRINTK` - This option enables processing of ``printk`` calls in the logger buffers instead of the RTT buffer. For information about how to run SEGGER's J-Link RTT on your PC and see the logs, see :ref:`testing_rtt`. @@ -117,8 +117,8 @@ Spinel Using `Spinel protocol`_ as a logging backend is specific to OpenThread's :ref:`thread_architectures_designs_cp_ncp` and :ref:`thread_architectures_designs_cp_rcp` architectures. The Spinel protocol can be configured as a logging backend using the following Kconfig options: -* :option:`CONFIG_LOG_BACKEND_SPINEL` - This option enables the Spinel logging backend. -* :option:`CONFIG_LOG_BACKEND_SPINEL_BUFFER_SIZE` - This option defines the size of buffer used for logger output. +* :kconfig:`CONFIG_LOG_BACKEND_SPINEL` - This option enables the Spinel logging backend. +* :kconfig:`CONFIG_LOG_BACKEND_SPINEL_BUFFER_SIZE` - This option defines the size of buffer used for logger output. To communicate using the Spinel protocol and gather logs, you need one of the following tools: @@ -137,7 +137,7 @@ Shell When you enable Zephyr's :ref:`zephyr:shell_api`, it by default becomes a logging backend. You can disable this backend by using the following Kconfig option: -* :option:`CONFIG_SHELL_LOG_BACKEND` - This option enables and disables the shell logging backend. +* :kconfig:`CONFIG_SHELL_LOG_BACKEND` - This option enables and disables the shell logging backend. .. note:: The UART and RTT logging backends can also be configured as shell backends. diff --git a/doc/nrf/ug_multi_image.rst b/doc/nrf/ug_multi_image.rst index 9c3234fb692a..05d0fb532b19 100644 --- a/doc/nrf/ug_multi_image.rst +++ b/doc/nrf/ug_multi_image.rst @@ -73,8 +73,8 @@ When building the child image from the source or using a prebuilt HEX file, the This means that you can enable and integrate an additional image just by using the default configuration. To change the default configuration and configure how a child image is handled, locate the BUILD_STRATEGY configuration options for the child image in the parent image configuration. -For example, to use a prebuilt HEX file of the :ref:`secure_partition_manager` instead of building it, select :option:`CONFIG_SPM_BUILD_STRATEGY_USE_HEX_FILE` instead of the default :option:`CONFIG_SPM_BUILD_STRATEGY_FROM_SOURCE`, and specify the HEX file in :option:`CONFIG_SPM_HEX_FILE`. -To ignore an MCUboot child image, select :option:`CONFIG_MCUBOOT_BUILD_STRATEGY_SKIP_BUILD` instead of :option:`CONFIG_MCUBOOT_BUILD_STRATEGY_FROM_SOURCE`. +For example, to use a prebuilt HEX file of the :ref:`secure_partition_manager` instead of building it, select :kconfig:`CONFIG_SPM_BUILD_STRATEGY_USE_HEX_FILE` instead of the default :kconfig:`CONFIG_SPM_BUILD_STRATEGY_FROM_SOURCE`, and specify the HEX file in :kconfig:`CONFIG_SPM_HEX_FILE`. +To ignore an MCUboot child image, select :kconfig:`CONFIG_MCUBOOT_BUILD_STRATEGY_SKIP_BUILD` instead of :kconfig:`CONFIG_MCUBOOT_BUILD_STRATEGY_FROM_SOURCE`. .. _ug_multi_image_defining: @@ -341,7 +341,7 @@ Memory placement **************** In a multi-image build, all images must be placed in memory so that they do not overlap. -The flash memory start address for each image must be specified by, for example, :option:`CONFIG_FLASH_LOAD_OFFSET`. +The flash memory start address for each image must be specified by, for example, :kconfig:`CONFIG_FLASH_LOAD_OFFSET`. Hardcoding the image locations like this works fine for simple use cases like a bootloader that prepares a device, where there are no further requirements on where in memory each image must be placed. However, more advanced use cases require a memory layout where images are located in a specific order relative to one another. diff --git a/doc/nrf/ug_multiprotocol_support.rst b/doc/nrf/ug_multiprotocol_support.rst index c8495580ccff..4ec9da3d5095 100644 --- a/doc/nrf/ug_multiprotocol_support.rst +++ b/doc/nrf/ug_multiprotocol_support.rst @@ -22,7 +22,7 @@ Enabling multiprotocol support To enable the multiprotocol support for either Thread or Zigbee, set the following Kconfig option: -* :option:`CONFIG_BT_LL_SOFTDEVICE_DEFAULT` +* :kconfig:`CONFIG_BT_LL_SOFTDEVICE_DEFAULT` This option activates the :ref:`nrfxlib:softdevice_controller`, which by default supports the multiprotocol features. Disabling the SoftDevice Controller also disables the multiprotocol support. diff --git a/doc/nrf/ug_nrf52.rst b/doc/nrf/ug_nrf52.rst index 4d487068635a..cda6938b6956 100644 --- a/doc/nrf/ug_nrf52.rst +++ b/doc/nrf/ug_nrf52.rst @@ -213,7 +213,7 @@ To perform a FOTA upgrade, complete the following steps: * You must enable the mcumgr module, which handles the transport protocol over Bluetooth Low Energy. To enable this module in your application, complete the following steps: - a. Enable :option:`CONFIG_MCUMGR_CMD_OS_MGMT`, :option:`CONFIG_MCUMGR_CMD_IMG_MGMT`, and :option:`CONFIG_MCUMGR_SMP_BT`. + a. Enable :kconfig:`CONFIG_MCUMGR_CMD_OS_MGMT`, :kconfig:`CONFIG_MCUMGR_CMD_IMG_MGMT`, and :kconfig:`CONFIG_MCUMGR_SMP_BT`. #. Call ``os_mgmt_register_group()`` and ``img_mgmt_register_group()`` in your application. #. Call ``smp_bt_register()`` in your application to initialize the mcumgr Bluetooth Low Energy transport. diff --git a/doc/nrf/ug_nrf5340.rst b/doc/nrf/ug_nrf5340.rst index 0dc4902f1295..a8e32f71b820 100644 --- a/doc/nrf/ug_nrf5340.rst +++ b/doc/nrf/ug_nrf5340.rst @@ -87,7 +87,7 @@ The OpenAMP library uses the IPM SHIM layer, which in turn uses the IPC driver i .. |note| replace:: The following instructions are for the application core. To upgrade the firmware on the network core, perform the steps for FOTA upgrade described below, replacing :file:`app_update.bin`, which is the file used when upgrading firmware on the application core, with :file:`net_core_app_update.bin`. - In addition, ensure that :option:`CONFIG_PCD_APP` is enabled for the MCUboot child image. + In addition, ensure that :kconfig:`CONFIG_PCD_APP` is enabled for the MCUboot child image. For more details, see :ref:`nc_bootloader`. Protocols and use cases @@ -224,13 +224,13 @@ Direct use of the radio peripheral Samples that directly use the radio peripheral can run on the network core of the nRF5340. They do not require any functionality from the application core. -However, on nRF5340, the application core is responsible for starting the network core and connecting its GPIO pins (see :option:`CONFIG_BOARD_ENABLE_CPUNET` and the code in :file:`zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c`). +However, on nRF5340, the application core is responsible for starting the network core and connecting its GPIO pins (see :kconfig:`CONFIG_BOARD_ENABLE_CPUNET` and the code in :file:`zephyr/boards/arm/nrf5340dk_nrf5340/nrf5340_cpunet_reset.c`). Therefore, you must always program the application core, even if the firmware is supposed to run only on the network core. You can use the :ref:`nrf5340_empty_app_core` sample for this purpose. Configure the network core application to automatically include this sample as a child image. This is the default configuration for the listed network core samples. -For more information, see :option:`CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE` and :ref:`ug_nrf5340_multi_image`. +For more information, see :kconfig:`CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE` and :ref:`ug_nrf5340_multi_image`. No radio communication @@ -254,7 +254,7 @@ Samples that do not need radio communication can run on the application core of They do not require any firmware on the network core. Therefore, the network core can remain empty. -If you want to enable the network core anyway, set the :option:`CONFIG_BOARD_ENABLE_CPUNET` option in the image for the application core. +If you want to enable the network core anyway, set the :kconfig:`CONFIG_BOARD_ENABLE_CPUNET` option in the image for the application core. .. _ug_nrf5340_multi_image: @@ -280,9 +280,9 @@ For other samples, the images are built separately. The build configuration depends on the following Kconfig options that must be set in the configuration of the parent image: -* :option:`CONFIG_BT_RPMSG_NRF53` - set to ``y`` in all Bluetooth LE samples for the application core -* :option:`CONFIG_NRF_802154_SER_HOST` - set to ``y`` in all Thread, Zigbee, and Matter samples for the application core -* :option:`CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE` - set to ``y`` in all network core samples that require the :ref:`nrf5340_empty_app_core` sample +* :kconfig:`CONFIG_BT_RPMSG_NRF53` - set to ``y`` in all Bluetooth LE samples for the application core +* :kconfig:`CONFIG_NRF_802154_SER_HOST` - set to ``y`` in all Thread, Zigbee, and Matter samples for the application core +* :kconfig:`CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE` - set to ``y`` in all network core samples that require the :ref:`nrf5340_empty_app_core` sample The combination of these options determines which (if any) sample is included in the build of the parent image: @@ -292,16 +292,16 @@ The combination of these options determines which (if any) sample is included in * - Enabled options - Child image sample for the network core - Child image sample for the application core - * - :option:`CONFIG_BT_RPMSG_NRF53` + * - :kconfig:`CONFIG_BT_RPMSG_NRF53` - :ref:`zephyr:bluetooth-hci-rpmsg-sample` - --- - * - :option:`CONFIG_NRF_802154_SER_HOST` + * - :kconfig:`CONFIG_NRF_802154_SER_HOST` - :ref:`zephyr:nrf-ieee802154-rpmsg-sample` - --- - * - :option:`CONFIG_BT_RPMSG_NRF53` and :option:`CONFIG_NRF_802154_SER_HOST` + * - :kconfig:`CONFIG_BT_RPMSG_NRF53` and :kconfig:`CONFIG_NRF_802154_SER_HOST` - :ref:`multiprotocol-rpmsg-sample` - --- - * - :option:`CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE` + * - :kconfig:`CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE` - --- - :ref:`nrf5340_empty_app_core` diff --git a/doc/nrf/ug_nrf9160.rst b/doc/nrf/ug_nrf9160.rst index f34b2a23fb1d..9049c5ad1ed1 100644 --- a/doc/nrf/ug_nrf9160.rst +++ b/doc/nrf/ug_nrf9160.rst @@ -62,7 +62,7 @@ It provides a reference implementation of a Secure Partition Manager firmware. This firmware is required to set up the nRF9160 DK so that it can run user applications in the non-secure domain. The Secure Partition Manager sample is automatically included in the build for the ``nrf9160dk_nrf9160ns`` build target. -To disable the automatic inclusion of the Secure Partition Manager sample, set the option :option:`CONFIG_SPM` to "n" in the project configuration. +To disable the automatic inclusion of the Secure Partition Manager sample, set the option :kconfig:`CONFIG_SPM` to "n" in the project configuration. Trusted Firmware-M (TF-M) support --------------------------------- @@ -85,8 +85,8 @@ Therefore, it must be built for the ``nrf9160dk_nrf9160ns`` build target. The application image might require other images to be present. Depending on the configuration, all these images can be built at the same time in a :ref:`multi-image build `. -All nRF9160 samples include the :ref:`secure_partition_manager` sample, which can be enabled or disabled with the :option:`CONFIG_SPM` option. -Some also include the :ref:`bootloader` sample (:option:`CONFIG_SECURE_BOOT`) and :doc:`mcuboot:index` (:option:`CONFIG_BOOTLOADER_MCUBOOT`). +All nRF9160 samples include the :ref:`secure_partition_manager` sample, which can be enabled or disabled with the :kconfig:`CONFIG_SPM` option. +Some also include the :ref:`bootloader` sample (:kconfig:`CONFIG_SECURE_BOOT`) and :doc:`mcuboot:index` (:kconfig:`CONFIG_BOOTLOADER_MCUBOOT`). LTE modem @@ -168,7 +168,7 @@ Then, enable the LTE band lock feature and the band lock mask in the configurati CONFIG_LTE_LOCK_BAND_MASK="10000001000000001100" The band lock mask allows you to set the bands on which you want the modem to operate. -Each bit in the :option:`CONFIG_LTE_LOCK_BAND_MASK` option represents one band. +Each bit in the :kconfig:`CONFIG_LTE_LOCK_BAND_MASK` option represents one band. The maximum length of the string is 88 characters (bit string, 88 bits). The band lock is a non-volatile setting that must be set before activating the modem. @@ -192,7 +192,7 @@ Network mode The modem supports LTE-M (Cat-M1) and Narrowband Internet of Things (NB-IoT or LTE Cat-NB). By default, the modem starts in LTE-M mode. -When using the LTE Link Control driver, you can select LTE-M with :option:`CONFIG_LTE_NETWORK_MODE_LTE_M` or NB-IoT with :option:`CONFIG_LTE_NETWORK_MODE_NBIOT`. +When using the LTE Link Control driver, you can select LTE-M with :kconfig:`CONFIG_LTE_NETWORK_MODE_LTE_M` or NB-IoT with :kconfig:`CONFIG_LTE_NETWORK_MODE_NBIOT`. To start in NB-IoT mode without the driver, send the following command before starting the modem protocols (by using ``AT+CFUN=1``):: @@ -257,7 +257,7 @@ To perform a FOTA upgrade, complete the following steps: In addition, the following requirements apply: * |fota_upgrades_req_mcuboot| - * If you want to upgrade the upgradable bootloader, the :ref:`bootloader` must be used (:option:`CONFIG_SECURE_BOOT`). + * If you want to upgrade the upgradable bootloader, the :ref:`bootloader` must be used (:kconfig:`CONFIG_SECURE_BOOT`). * If you want to upgrade the modem firmware through modem delta updates, neither MCUboot nor the immutable bootloader are required, because the modem firmware upgrade is handled by the modem itself. * If you want to perform a full modem firmware upgrade, an |external_flash_size| is required. @@ -270,7 +270,7 @@ To perform a FOTA upgrade, complete the following steps: |fota_upgrades_building| The :file:`app_update.bin` file is the file that should be uploaded to the server. - To create binary files for a bootloader upgrade, make sure that :option:`CONFIG_SECURE_BOOT` and :option:`CONFIG_BUILD_S1_VARIANT` are enabled and build MCUboot as usual. + To create binary files for a bootloader upgrade, make sure that :kconfig:`CONFIG_SECURE_BOOT` and :kconfig:`CONFIG_BUILD_S1_VARIANT` are enabled and build MCUboot as usual. The build will create a binary file for each variant of the upgradable bootloader, one for each bootloader slot. See :ref:`upgradable_bootloader` for more information. diff --git a/doc/nrf/ug_pelion.rst b/doc/nrf/ug_pelion.rst index 58f8438a4334..b0b71b554fec 100644 --- a/doc/nrf/ug_pelion.rst +++ b/doc/nrf/ug_pelion.rst @@ -43,12 +43,12 @@ Enable and configure Mbed TLS The Pelion Device Management library depends on a properly configured Mbed TLS library. To simplify the development within the |NCS|, you can use a predefined set of Mbed TLS configuration options. -To enable the set that is compatible with :ref:`nrfxlib:nrf_security`, use the :option:`CONFIG_PELION_NRF_SECURITY` Kconfig option. +To enable the set that is compatible with :ref:`nrfxlib:nrf_security`, use the :kconfig:`CONFIG_PELION_NRF_SECURITY` Kconfig option. Make sure to properly configure the memory region used by Mbed TLS library for dynamic allocations. Memory for this library is allocated from either the libc heap or a dedicated buffer, depending on the configuration. -For more information about using the dedicated buffer for Mbed TLS heap, see help for the :option:`CONFIG_MBEDTLS_ENABLE_HEAP` and :option:`CONFIG_MBEDTLS_HEAP_SIZE` Kconfig options. -If :option:`CONFIG_MBEDTLS_ENABLE_HEAP` is disabled and Mbed TLS configuration files do not add any overrides, the libc heap is used. +For more information about using the dedicated buffer for Mbed TLS heap, see help for the :kconfig:`CONFIG_MBEDTLS_ENABLE_HEAP` and :kconfig:`CONFIG_MBEDTLS_HEAP_SIZE` Kconfig options. +If :kconfig:`CONFIG_MBEDTLS_ENABLE_HEAP` is disabled and Mbed TLS configuration files do not add any overrides, the libc heap is used. Provision the device with credentials ===================================== @@ -114,12 +114,12 @@ For more information, see :ref:`zephyr:thread_protocol_interface` in the Zephyr Pelion configuration ******************** -To enable the Pelion Device Management library in the |NCS|, use the :option:`CONFIG_PELION_CLIENT` Kconfig option. +To enable the Pelion Device Management library in the |NCS|, use the :kconfig:`CONFIG_PELION_CLIENT` Kconfig option. You can control the Pelion Device Management library features using Kconfig options that are defined within the Pelion Device Management library repository. The following options are among the most important ones: -* :option:`CONFIG_PELION_UPDATE` - This option enables the device firmware update (DFU) feature. -* :option:`CONFIG_PELION_TRANSPORT_MODE_TCP`, :option:`CONFIG_PELION_TRANSPORT_MODE_UDP`, :option:`CONFIG_PELION_TRANSPORT_MODE_UDP_QUEUE` - These options select the transport protocol used by the library. +* :kconfig:`CONFIG_PELION_UPDATE` - This option enables the device firmware update (DFU) feature. +* :kconfig:`CONFIG_PELION_TRANSPORT_MODE_TCP`, :kconfig:`CONFIG_PELION_TRANSPORT_MODE_UDP`, :kconfig:`CONFIG_PELION_TRANSPORT_MODE_UDP_QUEUE` - These options select the transport protocol used by the library. To see all options, check the Pelion Device Management library subtree in configuration system (menuconfig) or read the `Zephyr integration tutorial`_ in the Pelion documentation. diff --git a/doc/nrf/ug_radio_fem.rst b/doc/nrf/ug_radio_fem.rst index 42a22cd865a6..7b0b89aecce3 100644 --- a/doc/nrf/ug_radio_fem.rst +++ b/doc/nrf/ug_radio_fem.rst @@ -42,7 +42,7 @@ Before you add the devicetree node in your application, complete the following s 1. Add support for the MPSL library in your application. The MPSL library provides API to configure FEM. See :ref:`nrfxlib:mpsl_lib` in the nrfxlib documentation for details. -#. Enable support for MPSL implementation in |NCS| by setting the :option:`CONFIG_MPSL` Kconfig option to ``y``. +#. Enable support for MPSL implementation in |NCS| by setting the :kconfig:`CONFIG_MPSL` Kconfig option to ``y``. .. _ug_radio_fem_nrf21540_gpio: diff --git a/doc/nrf/ug_tfm.rst b/doc/nrf/ug_tfm.rst index 3ccb79103a2f..fad96280c599 100644 --- a/doc/nrf/ug_tfm.rst +++ b/doc/nrf/ug_tfm.rst @@ -36,11 +36,11 @@ TF-M is one of the images that are built as part of a multi-image application. If TF-M is used in the application, SPM will not be included in it. For more information about multi-image builds, see :ref:`ug_multi_image`. -To add TF-M to your build, enable the :option:`CONFIG_BUILD_WITH_TFM` configuration option by adding it to your :file:`prj.conf` file. -To build a :ref:`minimal version ` of TF-M, you must also enable the :option:`CONFIG_TFM_MINIMAL` configuration. +To add TF-M to your build, enable the :kconfig:`CONFIG_BUILD_WITH_TFM` configuration option by adding it to your :file:`prj.conf` file. +To build a :ref:`minimal version ` of TF-M, you must also enable the :kconfig:`CONFIG_TFM_MINIMAL` configuration. .. note:: - If you use menuconfig to enable :option:`CONFIG_BUILD_WITH_TFM`, you must also enable its dependencies. + If you use menuconfig to enable :kconfig:`CONFIG_BUILD_WITH_TFM`, you must also enable its dependencies. You must build TF-M using a non-secure build target. The following targets are currently supported: @@ -55,7 +55,7 @@ The recommended way to do this is to copy the .overlay file from the :ref:`tfm_h Enabling secure services ======================== -When using the :ref:`nrfxlib:nrf_security`, if :option:`CONFIG_BUILD_WITH_TFM` is enabled together with :option:`CONFIG_NORDIC_SECURITY_BACKEND`, the TF-M secure image will enable the use of the hardware acceleration of Arm CryptoCell. +When using the :ref:`nrfxlib:nrf_security`, if :kconfig:`CONFIG_BUILD_WITH_TFM` is enabled together with :kconfig:`CONFIG_NORDIC_SECURITY_BACKEND`, the TF-M secure image will enable the use of the hardware acceleration of Arm CryptoCell. In such case, the Kconfig configurations in the Nordic Security Backend control the features enabled through TF-M. You can configure what crypto modules to include in TF-M by using the ``TFM_CRYPTO_`` Kconfig options found in file :file:`zephyr/modules/trusted-firmware-m/Kconfig.tfm.crypto_modules`. @@ -74,9 +74,9 @@ The secure services supported by this minimal version allow for generating rando This corresponds to the feature set provided by the :ref:`secure_partition_manager`. -The minimal version of TF-M is enabled by setting the :option:`CONFIG_TFM_MINIMAL` option. +The minimal version of TF-M is enabled by setting the :kconfig:`CONFIG_TFM_MINIMAL` option. -When :option:`CONFIG_TFM_MINIMAL` is set, the configurability of TF-M is severely limited. +When :kconfig:`CONFIG_TFM_MINIMAL` is set, the configurability of TF-M is severely limited. Hence, it is not possible to modify the TF-M minimal configuration to create your own variant of the minimal configuration. Instead, the default configuration must be used as a starting point. diff --git a/doc/nrf/ug_thread_configuring.rst b/doc/nrf/ug_thread_configuring.rst index cf4b1fb2de5d..990a21de3080 100644 --- a/doc/nrf/ug_thread_configuring.rst +++ b/doc/nrf/ug_thread_configuring.rst @@ -26,9 +26,9 @@ Enabling OpenThread in |NCS| To use the Thread protocol in |NCS|, set the following Kconfig options: -* :option:`CONFIG_NETWORKING` - This option enables the generic link layer and the IP networking support. -* :option:`CONFIG_NET_L2_OPENTHREAD` - This option enables the OpenThread stack required for the correct operation of the Thread protocol and allows you to use it. -* :option:`CONFIG_MPSL` - This option enables the :ref:`nrfxlib:mpsl` (MPSL) implementation, which provides services for both :ref:`single-protocol and multi-protocol implementations `. +* :kconfig:`CONFIG_NETWORKING` - This option enables the generic link layer and the IP networking support. +* :kconfig:`CONFIG_NET_L2_OPENTHREAD` - This option enables the OpenThread stack required for the correct operation of the Thread protocol and allows you to use it. +* :kconfig:`CONFIG_MPSL` - This option enables the :ref:`nrfxlib:mpsl` (MPSL) implementation, which provides services for both :ref:`single-protocol and multi-protocol implementations `. .. _ug_thread_configuring_basic_building: @@ -42,18 +42,18 @@ Building the OpenThread libraries from source gives you full flexibility in conf Using pre-built variants can be useful for certification purposes. Configure OpenThread to build from source - Set :option:`CONFIG_OPENTHREAD_SOURCES` to build the libraries from source. + Set :kconfig:`CONFIG_OPENTHREAD_SOURCES` to build the libraries from source. This option is selected by default. This alternative allows you to define :ref:`ug_thread_configuring_additional` one by one. - By default, the :ref:`thread_ug_feature_sets` option is set to custom (:option:`CONFIG_OPENTHREAD_USER_CUSTOM_LIBRARY`), which allows you to create your own OpenThread stack configuration. + By default, the :ref:`thread_ug_feature_sets` option is set to custom (:kconfig:`CONFIG_OPENTHREAD_USER_CUSTOM_LIBRARY`), which allows you to create your own OpenThread stack configuration. However, you can select other feature sets as a basis. When building the OpenThread libraries from source, you can also :ref:`update the pre-built OpenThread libraries `. Configure OpenThread to use pre-built libraries - Set :option:`CONFIG_OPENTHREAD_LIBRARY_1_1` to use pre-built libraries. - Select one of the :ref:`thread_ug_feature_sets` by enabling :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER`, :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD`, or :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD`. + Set :kconfig:`CONFIG_OPENTHREAD_LIBRARY_1_1` to use pre-built libraries. + Select one of the :ref:`thread_ug_feature_sets` by enabling :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER`, :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD`, or :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD`. This alternative disables building OpenThread from source files and links pre-built libraries instead. @@ -64,17 +64,17 @@ Additional configuration options Depending on your configuration needs, you can also set the following options: -* :option:`CONFIG_NET_SOCKETS` - This option enables API similar to BSD Sockets on top of the native Zephyr networking API. +* :kconfig:`CONFIG_NET_SOCKETS` - This option enables API similar to BSD Sockets on top of the native Zephyr networking API. This configuration is needed for managing networking protocols. -* :option:`CONFIG_NET_SHELL` - This option enables Zephyr's :ref:`zephyr:net_shell`. +* :kconfig:`CONFIG_NET_SHELL` - This option enables Zephyr's :ref:`zephyr:net_shell`. This configuration is needed for managing the network, based on Zephyr's IP stack, from the command line. -* :option:`CONFIG_OPENTHREAD_SHELL` - This option enables OpenThread CLI (see `OpenThread CLI Reference`_). -* :option:`CONFIG_COAP` - This option enables Zephyr's :ref:`zephyr:coap_sock_interface` support. -* :option:`CONFIG_COAP_UTILS` - This option enables the :ref:`CoAP utils library `. -* :option:`CONFIG_OPENTHREAD_COAP` - This option enables OpenThread's native CoAP API. -* :option:`CONFIG_OPENTHREAD_CHANNEL` - By default set to ``11``. +* :kconfig:`CONFIG_OPENTHREAD_SHELL` - This option enables OpenThread CLI (see `OpenThread CLI Reference`_). +* :kconfig:`CONFIG_COAP` - This option enables Zephyr's :ref:`zephyr:coap_sock_interface` support. +* :kconfig:`CONFIG_COAP_UTILS` - This option enables the :ref:`CoAP utils library `. +* :kconfig:`CONFIG_OPENTHREAD_COAP` - This option enables OpenThread's native CoAP API. +* :kconfig:`CONFIG_OPENTHREAD_CHANNEL` - By default set to ``11``. You can set any value ranging from ``11`` to ``26``. -* :option:`CONFIG_OPENTHREAD_PANID` - By default set to ``43981``. +* :kconfig:`CONFIG_OPENTHREAD_PANID` - By default set to ``43981``. You can set any value ranging from ``0`` to ``65535``. See the following files for more options that you might want to change: @@ -110,7 +110,7 @@ Hardware-accelerated cryptography You can enable hardware-accelerated cryptography by using the :ref:`nrfxlib:nrf_security`. To do this, modify the setting of the following Kconfig option: -* :option:`CONFIG_OPENTHREAD_MBEDTLS` - Disable this option to disable the default mbedTLS configuration for OpenThread. +* :kconfig:`CONFIG_OPENTHREAD_MBEDTLS` - Disable this option to disable the default mbedTLS configuration for OpenThread. The nrf_security module is enabled by default when mbedTLS for OpenThread is disabled. For more configuration options, read the module documentation. @@ -123,9 +123,9 @@ Thread 1.2 Specification options The OpenThread stack can be configured to operate in compliance with either the Thread 1.1 Specification or the :ref:`Thread 1.2 Specification `. You can change the stack version by using the following Kconfig options: -* :option:`CONFIG_OPENTHREAD_THREAD_VERSION_1_1` - Selects the Thread stack version that is compliant with the Thread 1.1 Specification. +* :kconfig:`CONFIG_OPENTHREAD_THREAD_VERSION_1_1` - Selects the Thread stack version that is compliant with the Thread 1.1 Specification. This option is enabled by default if no other option is selected. -* :option:`CONFIG_OPENTHREAD_THREAD_VERSION_1_2` - Selects the Thread stack version that is compliant with the Thread 1.2 Specification. +* :kconfig:`CONFIG_OPENTHREAD_THREAD_VERSION_1_2` - Selects the Thread stack version that is compliant with the Thread 1.2 Specification. By selecting support for Thread 1.2, you enable the following features in addition to the :ref:`Thread 1.1 features `: @@ -136,12 +136,12 @@ By selecting support for Thread 1.2, you enable the following features in additi Moreover, Thread 1.2 also comes with the following features that are supported for development, but not production: -* Domain Unicast Addresses - Set :option:`CONFIG_OPENTHREAD_DUA` to enable this feature. -* Multicast Listener Registration - Set :option:`CONFIG_OPENTHREAD_MLR` to enable this feature. -* Backbone Router - Set :option:`CONFIG_OPENTHREAD_BACKBONE_ROUTER` to enable this feature. -* Link Metrics - Set :option:`CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR` to enable the link metrics initiator functionality. - Set :option:`CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT` to enable the link metrics subject functionality. -* Coordinated Sampled Listening (CSL) Receiver - Set :option:`CONFIG_OPENTHREAD_CSL_RECEIVER` to enable this feature. +* Domain Unicast Addresses - Set :kconfig:`CONFIG_OPENTHREAD_DUA` to enable this feature. +* Multicast Listener Registration - Set :kconfig:`CONFIG_OPENTHREAD_MLR` to enable this feature. +* Backbone Router - Set :kconfig:`CONFIG_OPENTHREAD_BACKBONE_ROUTER` to enable this feature. +* Link Metrics - Set :kconfig:`CONFIG_OPENTHREAD_LINK_METRICS_INITIATOR` to enable the link metrics initiator functionality. + Set :kconfig:`CONFIG_OPENTHREAD_LINK_METRICS_SUBJECT` to enable the link metrics subject functionality. +* Coordinated Sampled Listening (CSL) Receiver - Set :kconfig:`CONFIG_OPENTHREAD_CSL_RECEIVER` to enable this feature. .. note:: The Link Metrics and Coordinated Sampled Listening features are not supported for nRF53 Series devices yet. @@ -161,22 +161,22 @@ Configuring this process is optional, because the :ref:`openthread_samples` in | If you want to manually enable the Thread network Commissioner role on a device, set the following Kconfig option to the provided value: -* :option:`CONFIG_OPENTHREAD_COMMISSIONER` to ``y``. +* :kconfig:`CONFIG_OPENTHREAD_COMMISSIONER` to ``y``. To enable the Thread network Joiner role on a device, set the following Kconfig option to the provided value: -* :option:`CONFIG_OPENTHREAD_JOINER` to ``y``. +* :kconfig:`CONFIG_OPENTHREAD_JOINER` to ``y``. You can also configure how the commissioning process is to be started. The following options are available: * Start automatically after the Joiner powers up. - To configure this option, configure the :option:`CONFIG_OPENTHREAD_JOINER_AUTOSTART` option for the Joiner device. + To configure this option, configure the :kconfig:`CONFIG_OPENTHREAD_JOINER_AUTOSTART` option for the Joiner device. * Start from the application. * Trigger by Command Line Interface commands. In this case, the shell stack size must be increased to at least 3 KB by setting the following option: - * :option:`CONFIG_SHELL_STACK_SIZE` to ``3168``. + * :kconfig:`CONFIG_SHELL_STACK_SIZE` to ``3168``. For more details about the commissioning process, see `Thread Commissioning on OpenThread portal`_. @@ -187,8 +187,8 @@ OpenThread stack logging options You can enable the OpenThread stack logging for your project with the following options: -* :option:`CONFIG_LOG` - This option enables Zephyr's :ref:`zephyr:logging_api`. -* :option:`CONFIG_OPENTHREAD_DEBUG` - This option enables logging for the OpenThread stack. +* :kconfig:`CONFIG_LOG` - This option enables Zephyr's :ref:`zephyr:logging_api`. +* :kconfig:`CONFIG_OPENTHREAD_DEBUG` - This option enables logging for the OpenThread stack. Both options must be enabled to allow logging. @@ -196,25 +196,25 @@ After setting these options, you can choose one of several :ref:`logging backend .. note:: If you are working with Thread samples, enabling logging and logging backend is optional. - By default, all Thread samples have logging enabled in the :file:`overlay-ot-defaults.conf` file and are configured to provide output at the informational level (:option:`CONFIG_OPENTHREAD_LOG_LEVEL_INFO`). + By default, all Thread samples have logging enabled in the :file:`overlay-ot-defaults.conf` file and are configured to provide output at the informational level (:kconfig:`CONFIG_OPENTHREAD_LOG_LEVEL_INFO`). Logging levels -------------- Select one of the following logging levels to customize the logging output: -* :option:`CONFIG_OPENTHREAD_LOG_LEVEL_CRIT` - This option enables critical error logging only. -* :option:`CONFIG_OPENTHREAD_LOG_LEVEL_WARN` - This option enables warning logging in addition to critical errors. -* :option:`CONFIG_OPENTHREAD_LOG_LEVEL_NOTE` - This option additionally enables notice logging. -* :option:`CONFIG_OPENTHREAD_LOG_LEVEL_INFO` - This option additionally enables informational logging. -* :option:`CONFIG_OPENTHREAD_LOG_LEVEL_DEBG` - This option additionally enables debug logging. +* :kconfig:`CONFIG_OPENTHREAD_LOG_LEVEL_CRIT` - This option enables critical error logging only. +* :kconfig:`CONFIG_OPENTHREAD_LOG_LEVEL_WARN` - This option enables warning logging in addition to critical errors. +* :kconfig:`CONFIG_OPENTHREAD_LOG_LEVEL_NOTE` - This option additionally enables notice logging. +* :kconfig:`CONFIG_OPENTHREAD_LOG_LEVEL_INFO` - This option additionally enables informational logging. +* :kconfig:`CONFIG_OPENTHREAD_LOG_LEVEL_DEBG` - This option additionally enables debug logging. The more detailed logging level you select, the more logging buffers you need to be able to see all messages. The buffer size must also be increased. Use the following Kconfig options for this purpose: -* :option:`CONFIG_LOG_STRDUP_BUF_COUNT` - This option specifies the number of logging buffers. -* :option:`CONFIG_LOG_STRDUP_MAX_STRING` - This option specifies the size of logging buffers. +* :kconfig:`CONFIG_LOG_STRDUP_BUF_COUNT` - This option specifies the number of logging buffers. +* :kconfig:`CONFIG_LOG_STRDUP_MAX_STRING` - This option specifies the size of logging buffers. Zephyr L2 logging options @@ -222,19 +222,19 @@ Zephyr L2 logging options If you want to get logging output related to Zephyr's L2 layer, enable one of the following Kconfig options: -* :option:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_ERR` - Enables logging only for errors. -* :option:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_WRN` - Enables logging for errors and warnings. -* :option:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_INF` - Enables logging for informational messages, errors, and warnings. -* :option:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_DBG` - Enables logging for debug messages, informational messages, errors, and warnings. +* :kconfig:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_ERR` - Enables logging only for errors. +* :kconfig:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_WRN` - Enables logging for errors and warnings. +* :kconfig:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_INF` - Enables logging for informational messages, errors, and warnings. +* :kconfig:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_DBG` - Enables logging for debug messages, informational messages, errors, and warnings. Choosing one of these options enables writing the appropriate information in the L2 debug log. -Additionally, enabling :option:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_DBG` allows you to set the :option:`CONFIG_OPENTHREAD_L2_DEBUG` option, which in turn has the following settings: +Additionally, enabling :kconfig:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_DBG` allows you to set the :kconfig:`CONFIG_OPENTHREAD_L2_DEBUG` option, which in turn has the following settings: -* :option:`CONFIG_OPENTHREAD_L2_DEBUG_DUMP_15_4` - Enables dumping 802.15.4 frames in the debug log output. -* :option:`CONFIG_OPENTHREAD_L2_DEBUG_DUMP_IPV6` - Enables dumping IPv6 frames in the debug log output. +* :kconfig:`CONFIG_OPENTHREAD_L2_DEBUG_DUMP_15_4` - Enables dumping 802.15.4 frames in the debug log output. +* :kconfig:`CONFIG_OPENTHREAD_L2_DEBUG_DUMP_IPV6` - Enables dumping IPv6 frames in the debug log output. -You can disable writing to log with the :option:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_OFF` option. +You can disable writing to log with the :kconfig:`CONFIG_OPENTHREAD_L2_LOG_LEVEL_OFF` option. .. _thread_ug_device_type: @@ -244,14 +244,14 @@ Device type options You can configure OpenThread devices to run as a specific :ref:`device type `. Full Thread Device (FTD) - Set :option:`CONFIG_OPENTHREAD_FTD` to configure the device as FTD. + Set :kconfig:`CONFIG_OPENTHREAD_FTD` to configure the device as FTD. This is the default configuration. Minimal Thread Device (MTD) - Set :option:`CONFIG_OPENTHREAD_MTD` to configure the device as MTD. + Set :kconfig:`CONFIG_OPENTHREAD_MTD` to configure the device as MTD. By default, the MTD operates as Minimal End Device (MED). - To make it operate as Sleepy End Device (SED), enabling :option:`CONFIG_OPENTHREAD_MTD_SED`. + To make it operate as Sleepy End Device (SED), enabling :kconfig:`CONFIG_OPENTHREAD_MTD_SED`. .. _thread_ug_prebuilt: @@ -262,7 +262,7 @@ The |NCS| provides a set of :ref:`nrfxlib:ot_libs`. These pre-built libraries are available in nrfxlib and provide features and optional functionalities from the OpenThread stack. You can use these libraries for building applications with support for the complete Thread 1.1 Specification. -To use a pre-built library, configure OpenThread to use pre-built libraries by setting the :option:`CONFIG_OPENTHREAD_LIBRARY_1_1` Kconfig option and select one of the provided :ref:`thread_ug_feature_sets`. +To use a pre-built library, configure OpenThread to use pre-built libraries by setting the :kconfig:`CONFIG_OPENTHREAD_LIBRARY_1_1` Kconfig option and select one of the provided :ref:`thread_ug_feature_sets`. .. _thread_ug_feature_sets: @@ -274,12 +274,12 @@ These feature sets are mainly used for pre-built libraries, but you can also use The |NCS| provides the following feature sets: -* :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER` - Enable the complete set of OpenThread features for the Thread 1.1 Specification. -* :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD` - Enable optimized OpenThread features for FTD (Thread 1.1). -* :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD` - Enable optimized OpenThread features for MTD (Thread 1.1). -* :option:`CONFIG_OPENTHREAD_USER_CUSTOM_LIBRARY` - Create a custom feature set for compilation when :ref:`building using OpenThread sources `. +* :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER` - Enable the complete set of OpenThread features for the Thread 1.1 Specification. +* :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD` - Enable optimized OpenThread features for FTD (Thread 1.1). +* :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD` - Enable optimized OpenThread features for MTD (Thread 1.1). +* :kconfig:`CONFIG_OPENTHREAD_USER_CUSTOM_LIBRARY` - Create a custom feature set for compilation when :ref:`building using OpenThread sources `. This option is the default. - If you select :option:`CONFIG_OPENTHREAD_LIBRARY_1_1`, choose a different feature set. + If you select :kconfig:`CONFIG_OPENTHREAD_LIBRARY_1_1`, choose a different feature set. .. note:: When :ref:`building OpenThread from source `, you can select another feature set as base. @@ -422,37 +422,37 @@ Be aware of the following limitations when customizing the configuration of a pr The following list shows some of the configuration options that you might want to customize: -* :option:`CONFIG_OPENTHREAD_FTD` or :option:`CONFIG_OPENTHREAD_MTD` - Select the :ref:`device type `. - The :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD` feature set supports only the MTD device type. +* :kconfig:`CONFIG_OPENTHREAD_FTD` or :kconfig:`CONFIG_OPENTHREAD_MTD` - Select the :ref:`device type `. + The :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD` feature set supports only the MTD device type. The other feature sets support both device types. -* :option:`CONFIG_OPENTHREAD_COPROCESSOR` and :option:`CONFIG_OPENTHREAD_COPROCESSOR_NCP` - Select the OpenThread architecture to use. +* :kconfig:`CONFIG_OPENTHREAD_COPROCESSOR` and :kconfig:`CONFIG_OPENTHREAD_COPROCESSOR_NCP` - Select the OpenThread architecture to use. See :ref:`thread_architectures_designs_cp`. -* :option:`CONFIG_OPENTHREAD_MANUAL_START` - Choose whether to configure and join the Thread network automatically. +* :kconfig:`CONFIG_OPENTHREAD_MANUAL_START` - Choose whether to configure and join the Thread network automatically. If you set this option to ``n``, also check and configure the network parameters that are used, for example: - * :option:`CONFIG_OPENTHREAD_CHANNEL` - * :option:`CONFIG_OPENTHREAD_NETWORKKEY` - * :option:`CONFIG_OPENTHREAD_NETWORK_NAME` - * :option:`CONFIG_OPENTHREAD_PANID` - * :option:`CONFIG_OPENTHREAD_XPANID` + * :kconfig:`CONFIG_OPENTHREAD_CHANNEL` + * :kconfig:`CONFIG_OPENTHREAD_NETWORKKEY` + * :kconfig:`CONFIG_OPENTHREAD_NETWORK_NAME` + * :kconfig:`CONFIG_OPENTHREAD_PANID` + * :kconfig:`CONFIG_OPENTHREAD_XPANID` .. _thread_ug_feature_updating_libs: Updating pre-built OpenThread libraries ======================================= -You can update the :ref:`nrfxlib:ot_libs` in nrfxlib when using any Thread sample if you configure the sample to build the OpenThread stack from source with :option:`CONFIG_OPENTHREAD_SOURCES`. +You can update the :ref:`nrfxlib:ot_libs` in nrfxlib when using any Thread sample if you configure the sample to build the OpenThread stack from source with :kconfig:`CONFIG_OPENTHREAD_SOURCES`. Use this functionality for :ref:`certification ` of your configuration of the OpenThread libraries, for example. .. note:: The libraries destination directory can differ. - When you selected :option:`CONFIG_OPENTHREAD_USER_CUSTOM_LIBRARY`, the location depends on the chosen :ref:`nrf_security backend `, either :option:`CONFIG_CC3XX_BACKEND` or :option:`CONFIG_OBERON_BACKEND`. + When you selected :kconfig:`CONFIG_OPENTHREAD_USER_CUSTOM_LIBRARY`, the location depends on the chosen :ref:`nrf_security backend `, either :kconfig:`CONFIG_CC3XX_BACKEND` or :kconfig:`CONFIG_OBERON_BACKEND`. Updating libraries without debug symbols ---------------------------------------- You can install the release version of the latest nrfxlib libraries without the debug symbols. -This is handled with the :option:`CONFIG_OPENTHREAD_BUILD_OUTPUT_STRIPPED` Kconfig option. +This is handled with the :kconfig:`CONFIG_OPENTHREAD_BUILD_OUTPUT_STRIPPED` Kconfig option. This option is disabled by default. Run the following command to update the nrfxlib libraries: @@ -464,7 +464,7 @@ Run the following command to update the nrfxlib libraries: This command builds two versions of the libraries, with and without debug symbols, and installs only the version without debug symbols. |board_note_for_updating_libs| -The :option:`CONFIG_OPENTHREAD_BUILD_OUTPUT_STRIPPED` Kconfig option will be disabled again after this command completes. +The :kconfig:`CONFIG_OPENTHREAD_BUILD_OUTPUT_STRIPPED` Kconfig option will be disabled again after this command completes. Updating libraries to debug version ----------------------------------- diff --git a/doc/nrf/ug_thread_ot_memory.rst b/doc/nrf/ug_thread_ot_memory.rst index c6102039e985..ba53c9260e5a 100644 --- a/doc/nrf/ug_thread_ot_memory.rst +++ b/doc/nrf/ug_thread_ot_memory.rst @@ -25,13 +25,13 @@ Moreover, take into account the following considerations: * The multiprotocol samples were optimized with the overlay :file:`overlay-minimal_multiprotocol.conf`. * To enable the multiprotocol support, the following options were used: - * :option:`CONFIG_MPSL` set to ``y`` (default setting for all samples) - * :option:`CONFIG_BT_LL_SOFTDEVICE_DEFAULT` set to ``y`` - * :option:`CONFIG_BT` set to ``y`` - * :option:`CONFIG_BT_PERIPHERAL` set to ``y`` - * :option:`CONFIG_BT_DEVICE_NAME` set to ``"NCS DUT"`` - * :option:`CONFIG_BT_DEVICE_APPEARANCE` set to ``833`` - * :option:`CONFIG_BT_MAX_CONN` set to ``1`` + * :kconfig:`CONFIG_MPSL` set to ``y`` (default setting for all samples) + * :kconfig:`CONFIG_BT_LL_SOFTDEVICE_DEFAULT` set to ``y`` + * :kconfig:`CONFIG_BT` set to ``y`` + * :kconfig:`CONFIG_BT_PERIPHERAL` set to ``y`` + * :kconfig:`CONFIG_BT_DEVICE_NAME` set to ``"NCS DUT"`` + * :kconfig:`CONFIG_BT_DEVICE_APPEARANCE` set to ``833`` + * :kconfig:`CONFIG_BT_MAX_CONN` set to ``1`` * Values for the :ref:`Thread CLI sample `, which works with all OpenThread calls, are the highest possible for the OpenThread stack using the master image library configuration. diff --git a/doc/nrf/ug_thread_supported_features.rst b/doc/nrf/ug_thread_supported_features.rst index ca3a730e5876..7edbe9d585fa 100644 --- a/doc/nrf/ug_thread_supported_features.rst +++ b/doc/nrf/ug_thread_supported_features.rst @@ -45,6 +45,6 @@ Limitations for Thread 1.2 support The Thread 1.2 Specification support has the following limitations: * The current implementation does not guarantee that all retransmitted frames will be secured when using the radio driver transmission security capabilities. - For this reason, OpenThread retransmissions are disabled by default when the :option:`CONFIG_NRF_802154_ENCRYPTION` Kconfig option is enabled. + For this reason, OpenThread retransmissions are disabled by default when the :kconfig:`CONFIG_NRF_802154_ENCRYPTION` Kconfig option is enabled. You can enable the retransmissions at your own risk. * Due to code size limitation, the combination of complete set of Thread 1.2 features with the Bluetooth LE multiprotocol support is not possible for the nRF52833 DKs. diff --git a/doc/nrf/ug_unity_testing.rst b/doc/nrf/ug_unity_testing.rst index 3a637f3bd243..b34388a315ac 100644 --- a/doc/nrf/ug_unity_testing.rst +++ b/doc/nrf/ug_unity_testing.rst @@ -21,7 +21,7 @@ Setting up a unit test An example for a unit test can be found in :file:`tests/unity/example_test`. The file `tests/unity/example_test/CMakeLists.txt`_ shows how to set up the generation of the test runner file and mocks. -To run the unit test, enable the Unity module (:option:`CONFIG_UNITY`) and the module under test. +To run the unit test, enable the Unity module (:kconfig:`CONFIG_UNITY`) and the module under test. The module under test and all dependencies are enabled and compiled into the binary, even the mocked modules. The linker replaces all calls to the mocked API with a mock implementation using the wrapping feature. diff --git a/doc/nrf/ug_zigbee_configuring.rst b/doc/nrf/ug_zigbee_configuring.rst index 9620644628cc..4b2df0c49b8b 100644 --- a/doc/nrf/ug_zigbee_configuring.rst +++ b/doc/nrf/ug_zigbee_configuring.rst @@ -17,7 +17,7 @@ Required libraries and drivers Zigbee requires the following modules to properly operate in the |NCS|: * :ref:`nrfxlib:zboss` available in nrfxlib, with the :ref:`lib_zigbee_osif` subsystem acting as the linking layer between the ZBOSS stack and the |NCS|. - The ZBOSS library is enabled by the :option:`CONFIG_ZIGBEE` Kconfig option. + The ZBOSS library is enabled by the :kconfig:`CONFIG_ZIGBEE` Kconfig option. For more information about the ZBOSS stack, see also the `external ZBOSS development guide and API documentation`_. * :ref:`zephyr:ieee802154_interface` radio driver - This library is automatically enabled when working with Zigbee on Nordic Semiconductor's development kits. @@ -26,14 +26,14 @@ Zigbee requires the following modules to properly operate in the |NCS|: Mandatory configuration *********************** -To use the Zigbee protocol, set the :option:`CONFIG_ZIGBEE` Kconfig option. +To use the Zigbee protocol, set the :kconfig:`CONFIG_ZIGBEE` Kconfig option. Setting this option enables all the peripherals required for the correct operation of the Zigbee protocol and allows you to use them. After that, you have to define the Zigbee device role for the Zigbee application or sample by setting one of the following Kconfig options: -* Router role: :option:`CONFIG_ZIGBEE_ROLE_ROUTER` -* End Device role: :option:`CONFIG_ZIGBEE_ROLE_END_DEVICE` -* Coordinator role: :option:`CONFIG_ZIGBEE_ROLE_COORDINATOR` +* Router role: :kconfig:`CONFIG_ZIGBEE_ROLE_ROUTER` +* End Device role: :kconfig:`CONFIG_ZIGBEE_ROLE_END_DEVICE` +* Coordinator role: :kconfig:`CONFIG_ZIGBEE_ROLE_COORDINATOR` Setting any of these options enables the respective ZBOSS role library. This is needed because End Devices use different libraries than Routers and Coordinators. @@ -69,9 +69,9 @@ Power saving during sleep With the sleepy behavior enabled, the unused part of RAM memory is powered off, which allows to lower the power consumption even more. The sleep current of MCU can be lowered to about 1.8 uA by completing the following steps: -1. Turn off UART by setting :option:`CONFIG_SERIAL` to ``n``. +1. Turn off UART by setting :kconfig:`CONFIG_SERIAL` to ``n``. #. For current measurements for the :ref:`nRF52840 DK ` (PCA10056), the :ref:`nRF52833 DK ` (PCA10100), or the :ref:`nRF5340 ` (PCA10095), set **SW6** to ``nRF ONLY`` position to get the desired results. -#. Enable the :option:`CONFIG_RAM_POWER_DOWN_LIBRARY` Kconfig option. +#. Enable the :kconfig:`CONFIG_RAM_POWER_DOWN_LIBRARY` Kconfig option. Optional configuration ********************** @@ -83,11 +83,11 @@ Device operational channel You can enable one of the following alternative options to select the channel on which the Zigbee device can operate: - * :option:`CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_SINGLE` - Single mode is enabled by default. + * :kconfig:`CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_SINGLE` - Single mode is enabled by default. The default channel is set to 16. - To set a different channel, edit the :option:`CONFIG_ZIGBEE_CHANNEL` option to the desired value. - * :option:`CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_MULTI` - In this mode, you get all the channels enabled by default. - To configure a custom set of channels in the range from 11 to 26, edit the :option:`CONFIG_ZIGBEE_CHANNEL_MASK` option. + To set a different channel, edit the :kconfig:`CONFIG_ZIGBEE_CHANNEL` option to the desired value. + * :kconfig:`CONFIG_ZIGBEE_CHANNEL_SELECTION_MODE_MULTI` - In this mode, you get all the channels enabled by default. + To configure a custom set of channels in the range from 11 to 26, edit the :kconfig:`CONFIG_ZIGBEE_CHANNEL_MASK` option. For example, you can set channels 13, 16, and 21. You must have at least one channel enabled with this option. @@ -126,15 +126,15 @@ The ZBOSS stack can be started using one of the following options: The dedicated thread can be configured using the following options: -* :option:`CONFIG_ZBOSS_DEFAULT_THREAD_PRIORITY` - Defines thread priority; set to 3 by default. -* :option:`CONFIG_ZBOSS_DEFAULT_THREAD_STACK_SIZE` - Defines the size of the thread stack; set to 2048 by default. +* :kconfig:`CONFIG_ZBOSS_DEFAULT_THREAD_PRIORITY` - Defines thread priority; set to 3 by default. +* :kconfig:`CONFIG_ZBOSS_DEFAULT_THREAD_STACK_SIZE` - Defines the size of the thread stack; set to 2048 by default. .. _zigbee_ug_logging: Custom logging per module ========================= -Logging is handled with the :option:`CONFIG_LOG` option. +Logging is handled with the :kconfig:`CONFIG_LOG` option. This option enables logging for both the stack and Zephyr's :ref:`zephyr:logging_api` API. .. _zigbee_ug_logging_stack_logs: @@ -145,9 +145,9 @@ Stack logs The stack logs are independent from Zephyr's :ref:`zephyr:logging_api` API. To customize them, use the following options: -* :option:`CONFIG_ZBOSS_ERROR_PRINT_TO_LOG` - Allows the application to log ZBOSS error names; enabled by default. -* :option:`CONFIG_ZBOSS_TRACE_MASK` - Sets the modules from which ZBOSS will log the debug messages with :option:`CONFIG_ZBOSS_TRACE_LOG_LEVEL`; no module is set by default. -* :option:`CONFIG_ZBOSS_TRAF_DUMP` - Enables logging of the received 802.15.4 frames over ZBOSS trace log if :option:`CONFIG_ZBOSS_TRACE_LOG_LEVEL` is set; disabled by default. +* :kconfig:`CONFIG_ZBOSS_ERROR_PRINT_TO_LOG` - Allows the application to log ZBOSS error names; enabled by default. +* :kconfig:`CONFIG_ZBOSS_TRACE_MASK` - Sets the modules from which ZBOSS will log the debug messages with :kconfig:`CONFIG_ZBOSS_TRACE_LOG_LEVEL`; no module is set by default. +* :kconfig:`CONFIG_ZBOSS_TRAF_DUMP` - Enables logging of the received 802.15.4 frames over ZBOSS trace log if :kconfig:`CONFIG_ZBOSS_TRACE_LOG_LEVEL` is set; disabled by default. The stack logs are provided in a binary format (hex dump). @@ -162,12 +162,12 @@ This level is used by default by the application. You can configure custom logger options for each Zigbee and ZBOSS module. To do this, configure the related Kconfig option for one or more modules: -* :option:`CONFIG_ZBOSS_TRACE_LOG_LEVEL` -* :option:`CONFIG_ZBOSS_OSIF_LOG_LEVEL` -* :option:`CONFIG_ZIGBEE_SHELL_LOG_LEVEL` -* :option:`CONFIG_ZIGBEE_APP_UTILS_LOG_LEVEL` -* :option:`CONFIG_ZIGBEE_LOGGER_EP_LOG_LEVEL` -* :option:`CONFIG_ZIGBEE_SCENES_LOG_LEVEL` +* :kconfig:`CONFIG_ZBOSS_TRACE_LOG_LEVEL` +* :kconfig:`CONFIG_ZBOSS_OSIF_LOG_LEVEL` +* :kconfig:`CONFIG_ZIGBEE_SHELL_LOG_LEVEL` +* :kconfig:`CONFIG_ZIGBEE_APP_UTILS_LOG_LEVEL` +* :kconfig:`CONFIG_ZIGBEE_LOGGER_EP_LOG_LEVEL` +* :kconfig:`CONFIG_ZIGBEE_SCENES_LOG_LEVEL` For each of the modules, you can set the following logging options: @@ -177,7 +177,7 @@ For each of the modules, you can set the following logging options: * ``LOG_LEVEL_INF`` - Enables logging for informational messages, errors, and warnings. * ``LOG_LEVEL_DBG`` - Enables logging for debug messages, informational messages, errors, and warnings. -For example, setting :option:`CONFIG_ZBOSS_TRACE_LOG_LEVEL_INF` will enable logging of informational messages, errors, and warnings for the ZBOSS Trace module. +For example, setting :kconfig:`CONFIG_ZBOSS_TRACE_LOG_LEVEL_INF` will enable logging of informational messages, errors, and warnings for the ZBOSS Trace module. Reduced power consumption ========================= diff --git a/doc/nrf/ug_zigbee_configuring_libraries.rst b/doc/nrf/ug_zigbee_configuring_libraries.rst index 7da30202d4b5..a1ead891142f 100644 --- a/doc/nrf/ug_zigbee_configuring_libraries.rst +++ b/doc/nrf/ug_zigbee_configuring_libraries.rst @@ -16,7 +16,7 @@ Configuring ZBOSS OSIF ********************** The Zigbee ZBOSS OSIF layer subsystem acts as the linking layer between the :ref:`nrfxlib:zboss` and the |NCS|. -The layer is automatically enabled when you enable the ZBOSS library with the :option:`CONFIG_ZIGBEE` Kconfig option. +The layer is automatically enabled when you enable the ZBOSS library with the :kconfig:`CONFIG_ZIGBEE` Kconfig option. For more information about the library, see :ref:`lib_zigbee_osif`. @@ -26,9 +26,9 @@ Configuring Zigbee application utilities **************************************** The :ref:`lib_zigbee_application_utilities` library provides a set of components that are ready for use in Zigbee applications. -To enable and use this library, set the :option:`CONFIG_ZIGBEE_APP_UTILS` Kconfig option. +To enable and use this library, set the :kconfig:`CONFIG_ZIGBEE_APP_UTILS` Kconfig option. -For additional logs for this library, configure the :option:`CONFIG_ZIGBEE_APP_UTILS_LOG_LEVEL` Kconfig option. +For additional logs for this library, configure the :kconfig:`CONFIG_ZIGBEE_APP_UTILS_LOG_LEVEL` Kconfig option. See :ref:`zigbee_ug_logging_logger_options` for more information. Default signal handler @@ -56,15 +56,15 @@ Configuring Zigbee FOTA The Zigbee Over The Air Device Firmware Upgrade (:ref:`lib_zigbee_fota`) library provides a mechanism to upgrade the firmware of the device through the Zigbee network. -To enable and configure the library, you must set the :option:`CONFIG_ZIGBEE_FOTA` Kconfig option. +To enable and configure the library, you must set the :kconfig:`CONFIG_ZIGBEE_FOTA` Kconfig option. Other :ref:`Zigbee FOTA Kconfig options ` can be used with default values. Because the Zigbee OTA DFU performs the upgrade using the :ref:`lib_dfu_target` library, the are several non-Zigbee options that must be set to configure the update process: -* :option:`CONFIG_MCUBOOT_IMAGE_VERSION` - This option specifies the current image version. -* :option:`CONFIG_DFU_TARGET_MCUBOOT` - This option enables updates that are performed by MCUboot. -* :option:`CONFIG_IMG_MANAGER` - This option enables the support for managing the DFU image downloaded using MCUboot. -* :option:`CONFIG_IMG_ERASE_PROGRESSIVELY` - This option instructs MCUboot to erase the flash memory progressively. +* :kconfig:`CONFIG_MCUBOOT_IMAGE_VERSION` - This option specifies the current image version. +* :kconfig:`CONFIG_DFU_TARGET_MCUBOOT` - This option enables updates that are performed by MCUboot. +* :kconfig:`CONFIG_IMG_MANAGER` - This option enables the support for managing the DFU image downloaded using MCUboot. +* :kconfig:`CONFIG_IMG_ERASE_PROGRESSIVELY` - This option instructs MCUboot to erase the flash memory progressively. This allows to avoid long wait times at the beginning of the DFU process. Configuring these options and updating the default values (at least updating the ``image_version`` to the application version) allows you to use Zigbee FOTA in the :ref:`zigbee_light_switch_sample` sample. @@ -133,10 +133,10 @@ Options for generating Zigbee FOTA upgrade image By enabling the Zigbee OTA DFU, the west tool will automatically generate the upgrade image. To specify the target device of the generated image, use the following Kconfig options: -* :option:`CONFIG_ZIGBEE_FOTA_COMMENT` - This option allows to specify a human-readable image name. -* :option:`CONFIG_ENABLE_ZIGBEE_FOTA_MIN_HW_VERSION` and :option:`CONFIG_ZIGBEE_FOTA_MIN_HW_VERSION` - These options allow to specify the minimum hardware version of the device that will accept the generated image. +* :kconfig:`CONFIG_ZIGBEE_FOTA_COMMENT` - This option allows to specify a human-readable image name. +* :kconfig:`CONFIG_ENABLE_ZIGBEE_FOTA_MIN_HW_VERSION` and :kconfig:`CONFIG_ZIGBEE_FOTA_MIN_HW_VERSION` - These options allow to specify the minimum hardware version of the device that will accept the generated image. No value makes these options unused. -* :option:`CONFIG_ENABLE_ZIGBEE_FOTA_MAX_HW_VERSION` and :option:`CONFIG_ZIGBEE_FOTA_MAX_HW_VERSION` - These options allow to specify the maximum hardware version of the device that will accept the generated image. +* :kconfig:`CONFIG_ENABLE_ZIGBEE_FOTA_MAX_HW_VERSION` and :kconfig:`CONFIG_ZIGBEE_FOTA_MAX_HW_VERSION` - These options allow to specify the maximum hardware version of the device that will accept the generated image. No value makes these options unused. The manufacturer ID, image type and version of the generated image are obtained from the application settings. @@ -152,8 +152,8 @@ The Zigbee endpoint logger library provides an endpoint handler for parsing and To enable the endpoint logger library in your application, complete the following steps: -1. Enable the library by setting the :option:`CONFIG_ZIGBEE_LOGGER_EP` Kconfig option. -2. Define the logging level for the library by setting the :option:`CONFIG_ZIGBEE_LOGGER_EP_LOG_LEVEL` Kconfig option. +1. Enable the library by setting the :kconfig:`CONFIG_ZIGBEE_LOGGER_EP` Kconfig option. +2. Define the logging level for the library by setting the :kconfig:`CONFIG_ZIGBEE_LOGGER_EP_LOG_LEVEL` Kconfig option. See :ref:`zigbee_ug_logging_logger_options` for more information. 3. Include the required header file :file:`include/zigbee/zigbee_logger_eprxzcl.h` into your project. 4. Register :c:func:`zigbee_logger_eprxzcl_ep_handler` as handler for the given *your_ep_number* endpoint using :c:macro:`ZB_AF_SET_ENDPOINT_HANDLER`, after the device context is registered with :c:macro:`ZB_AF_REGISTER_DEVICE_CTX`, but before starting the Zigbee stack: @@ -167,7 +167,7 @@ To enable the endpoint logger library in your application, complete the followin For applications that implement multiple handlers, :c:func:`zigbee_logger_eprxzcl_ep_handler` can be registered as handler for each endpoint. .. note:: - If :ref:`lib_zigbee_shell` is already enabled and configured for the given endpoint, set the :option:`CONFIG_ZIGBEE_SHELL_DEBUG_CMD` Kconfig option to enable the endpoint logger instead of registering a handler. + If :ref:`lib_zigbee_shell` is already enabled and configured for the given endpoint, set the :kconfig:`CONFIG_ZIGBEE_SHELL_DEBUG_CMD` Kconfig option to enable the endpoint logger instead of registering a handler. This is because the Zigbee shell library registers its own handler for the endpoint. For more information about the library, see :ref:`lib_zigbee_logger_endpoint`. @@ -179,7 +179,7 @@ Configuring Zigbee ZCL scene helper The Zigbee ZCL scene helper library provides a set of functions that implement the callbacks required by the ZCL scene cluster in the application. -To enable the Zigbee ZCL scene helper library, set the :option:`CONFIG_ZIGBEE_SCENES` Kconfig option. +To enable the Zigbee ZCL scene helper library, set the :kconfig:`CONFIG_ZIGBEE_SCENES` Kconfig option. Because the library uses Zephyr's :ref:`settings_api` subsystem, the application must call the following functions for the library to work correctly: @@ -201,15 +201,15 @@ The Zigbee shell library implements a set of :ref:`Zigbee shell commands Date: Tue, 27 Jul 2021 16:29:30 +0200 Subject: [PATCH 089/126] doc: nrfxlib: enable kconfig-role extension MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Kconfig references now require the usage of the :kconfig: role, provided by the Zephyr's kconfig-role extension. This patch also updates the manifest file to point to updated docs. Signed-off-by: Gerard Marull-Paretas Signed-off-by: Martí Bolívar --- doc/nrfxlib/conf.py | 3 +++ doc/nrfxlib/nrfxlib.doxyfile.in | 2 +- west.yml | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/doc/nrfxlib/conf.py b/doc/nrfxlib/conf.py index 9c340cdd5cb6..7336dfd10386 100644 --- a/doc/nrfxlib/conf.py +++ b/doc/nrfxlib/conf.py @@ -13,6 +13,7 @@ sys.path.insert(0, str(NRF_BASE / "doc" / "_utils")) import utils +ZEPHYR_BASE = utils.get_projdir("zephyr") NRFXLIB_BASE = utils.get_projdir("nrfxlib") # General configuration -------------------------------------------------------- @@ -22,6 +23,7 @@ author = "Nordic Semiconductor" version = release = "1.6.99" +sys.path.insert(0, str(ZEPHYR_BASE / "doc" / "_extensions")) sys.path.insert(0, str(NRF_BASE / "doc" / "_extensions")) extensions = [ @@ -29,6 +31,7 @@ "breathe", "sphinxcontrib.mscgen", "inventory_builder", + "zephyr.kconfig-role", "ncs_cache", "external_content", "doxyrunner", diff --git a/doc/nrfxlib/nrfxlib.doxyfile.in b/doc/nrfxlib/nrfxlib.doxyfile.in index d129fc35fe8f..361206d8a05d 100644 --- a/doc/nrfxlib/nrfxlib.doxyfile.in +++ b/doc/nrfxlib/nrfxlib.doxyfile.in @@ -226,7 +226,7 @@ ALIASES = "rst=\verbatim embed:rst" \ "endrststar=\endverbatim" \ "r=\verbatim embed:rst:leading-asterisk" \ "er=\endverbatim" -ALIASES += option{1}="\verbatim embed:rst:inline :option:`\1` \endverbatim" +ALIASES += kconfig{1}="\verbatim embed:rst:inline :kconfig:`\1` \endverbatim" ALIASES += "req=\xrefitem req \"Requirement\" \"Requirements\" " # This tag can be used to specify a number of word-keyword mappings (TCL only). diff --git a/west.yml b/west.yml index 1197ae2ff1a6..512f075abc12 100644 --- a/west.yml +++ b/west.yml @@ -104,7 +104,7 @@ manifest: - name: nrfxlib repo-path: sdk-nrfxlib path: nrfxlib - revision: aa5661dbe16ab55b5f0665220660b051277eac25 + revision: 1c0ba974a1db404110f36976ac942645fedc4a36 - name: trusted-firmware-m repo-path: sdk-trusted-firmware-m path: modules/tee/tfm From 15d01990dba0c99acf902f9adc547160d6b66055 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Tue, 27 Jul 2021 17:23:53 +0200 Subject: [PATCH 090/126] doc: zephyr: remove custom external_content usage Zephyr docs already use this extension, current overrides were added before upstream Zephyr migrated to the external_content extension. Signed-off-by: Gerard Marull-Paretas --- doc/zephyr/conf.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/doc/zephyr/conf.py b/doc/zephyr/conf.py index 32a7d20d30bf..58f6ef3273f9 100644 --- a/doc/zephyr/conf.py +++ b/doc/zephyr/conf.py @@ -32,7 +32,6 @@ extensions = [ "sphinx.ext.intersphinx", "ncs_cache", - "external_content", "doxyrunner", ] + extensions @@ -62,21 +61,6 @@ if kconfig_mapping: intersphinx_mapping["kconfig"] = kconfig_mapping -# Options for external_content ------------------------------------------------- - -external_content_contents = [ - (ZEPHYR_BASE / "doc", "[!_]*"), - (ZEPHYR_BASE, "boards/**/*.rst"), - (ZEPHYR_BASE, "boards/**/doc"), - (ZEPHYR_BASE, "samples/**/*.rst"), - (ZEPHYR_BASE, "samples/**/doc"), -] -external_content_keep = [ - "reference/devicetree/bindings.rst", - "reference/devicetree/bindings/**/*", - "reference/devicetree/compatibles/**/*", -] - # Options for ncs_cache -------------------------------------------------------- ncs_cache_docset = "zephyr" From 8963fad387e50aefc4702d35789f7df720fd098e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 10 Aug 2021 10:46:47 -0700 Subject: [PATCH 091/126] treewide: handle nRF5340DK non-secure rename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream zephyr commit b8c9dc169e ("boards: arm: nrf5340dk_nrf5340: Rename NS target") renamed nrf5340dk_nrf5340_cpuappns to nrf5340dk_nrf5340_cpuapp_ns. Make the necessary changes in NCS code, including renames for .overlay and .conf files. Signed-off-by: Martí Bolívar --- .../app_ZDebug.conf | 0 .../app_ZRelease.conf | 0 .../buttons_def.h | 0 .../dts.overlay | 0 .../led_state_def.h | 0 .../mcuboot_ZDebug.conf | 0 .../mcuboot_ZRelease.conf | 0 .../mcuboot_private.pem | 0 .../pm_static_ZDebug.yml | 0 .../pm_static_ZRelease.yml | 0 modules/tfm/tfm/boards/board/RTE_Device.h | 2 +- samples/bluetooth/central_bas/sample.yaml | 4 ++-- samples/bluetooth/central_hids/sample.yaml | 4 ++-- samples/bluetooth/central_smp_client/sample.yaml | 4 ++-- samples/bluetooth/central_uart/sample.yaml | 6 +++--- samples/bluetooth/mesh/light/sample.yaml | 4 ++-- samples/bluetooth/mesh/light_switch/sample.yaml | 4 ++-- samples/bluetooth/mesh/silvair_enocean/sample.yaml | 4 ++-- samples/bluetooth/peripheral_ancs_client/sample.yaml | 4 ++-- samples/bluetooth/peripheral_cts_client/sample.yaml | 4 ++-- samples/bluetooth/peripheral_gatt_dm/sample.yaml | 4 ++-- samples/bluetooth/peripheral_hids_keyboard/sample.yaml | 4 ++-- samples/bluetooth/peripheral_hids_mouse/sample.yaml | 4 ++-- samples/bluetooth/peripheral_lbs/sample.yaml | 6 +++--- samples/bluetooth/peripheral_nfc_pairing/sample.yaml | 4 ++-- samples/bluetooth/peripheral_uart/sample.yaml | 4 ++-- samples/bluetooth/shell_bt_nus/sample.yaml | 4 ++-- samples/bluetooth/throughput/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/aes_cbc/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/aes_ccm/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/aes_ctr/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/aes_gcm/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/chachapoly/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/ecdh/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/ecdsa/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/hkdf/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/hmac/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/persistent_key_usage/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/psa_tls/sample.yaml | 2 +- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/rng/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/rsa/sample.yaml | 4 ++-- ...f5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} | 0 samples/crypto/sha256/sample.yaml | 4 ++-- samples/nfc/record_text/sample.yaml | 2 +- samples/nfc/system_off/sample.yaml | 2 +- samples/nfc/tnep_tag/sample.yaml | 2 +- samples/nfc/writable_ndef_msg/sample.yaml | 2 +- samples/tfm/tfm_hello_world/sample.yaml | 4 ++-- tests/drivers/fprotect/negative/testcase.yaml | 2 +- tests/drivers/fprotect/positive/testcase.yaml | 2 +- tests/lib/hw_unique_key_tfm/testcase.yaml | 2 +- tests/subsys/bootloader/bl_crypto/testcase.yaml | 2 +- tests/subsys/bootloader/bl_storage/testcase.yaml | 2 +- tests/subsys/bootloader/bl_validation/testcase.yaml | 2 +- tests/subsys/bootloader/bl_validation_neg/testcase.yaml | 2 +- tests/subsys/fw_info/testcase.yaml | 2 +- tests/subsys/spm/secure_services/testcase.yaml | 2 +- tests/subsys/spm/thread_swap/testcase.yaml | 2 +- 71 files changed, 80 insertions(+), 80 deletions(-) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/app_ZDebug.conf (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/app_ZRelease.conf (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/buttons_def.h (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/dts.overlay (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/led_state_def.h (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/mcuboot_ZDebug.conf (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/mcuboot_ZRelease.conf (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/mcuboot_private.pem (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/pm_static_ZDebug.yml (100%) rename applications/pelion_client/configuration/{nrf5340dk_nrf5340_cpuappns => nrf5340dk_nrf5340_cpuapp_ns}/pm_static_ZRelease.yml (100%) rename samples/crypto/aes_cbc/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/aes_ccm/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/aes_ctr/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/aes_gcm/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/chachapoly/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/ecdh/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/ecdsa/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/hkdf/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/hmac/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/persistent_key_usage/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/psa_tls/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/rng/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/rsa/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) rename samples/crypto/sha256/boards/{nrf5340dk_nrf5340_cpuappns.conf => nrf5340dk_nrf5340_cpuapp_ns.conf} (100%) diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/app_ZDebug.conf b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/app_ZDebug.conf similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/app_ZDebug.conf rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/app_ZDebug.conf diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/app_ZRelease.conf b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/app_ZRelease.conf similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/app_ZRelease.conf rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/app_ZRelease.conf diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/buttons_def.h b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/buttons_def.h similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/buttons_def.h rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/buttons_def.h diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/dts.overlay b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/dts.overlay similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/dts.overlay rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/dts.overlay diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/led_state_def.h b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/led_state_def.h similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/led_state_def.h rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/led_state_def.h diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/mcuboot_ZDebug.conf b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/mcuboot_ZDebug.conf similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/mcuboot_ZDebug.conf rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/mcuboot_ZDebug.conf diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/mcuboot_ZRelease.conf b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/mcuboot_ZRelease.conf similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/mcuboot_ZRelease.conf rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/mcuboot_ZRelease.conf diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/mcuboot_private.pem b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/mcuboot_private.pem similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/mcuboot_private.pem rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/mcuboot_private.pem diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/pm_static_ZDebug.yml b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/pm_static_ZDebug.yml similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/pm_static_ZDebug.yml rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/pm_static_ZDebug.yml diff --git a/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/pm_static_ZRelease.yml b/applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/pm_static_ZRelease.yml similarity index 100% rename from applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuappns/pm_static_ZRelease.yml rename to applications/pelion_client/configuration/nrf5340dk_nrf5340_cpuapp_ns/pm_static_ZRelease.yml diff --git a/modules/tfm/tfm/boards/board/RTE_Device.h b/modules/tfm/tfm/boards/board/RTE_Device.h index 813cd41a034b..07eaa588641f 100644 --- a/modules/tfm/tfm/boards/board/RTE_Device.h +++ b/modules/tfm/tfm/boards/board/RTE_Device.h @@ -42,7 +42,7 @@ // Configuration settings for Driver_USART1 in component ::Drivers:USART #define RTE_USART1 1 // Pin Selection (0xFFFFFFFF means Disconnected) -#if defined(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPPNS) +#if defined(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP_NS) // TXD #define RTE_USART1_TXD_PIN 25 // TODO: Add to devicetree // RXD diff --git a/samples/bluetooth/central_bas/sample.yaml b/samples/bluetooth/central_bas/sample.yaml index 1e8a66fd677f..78d3d178b311 100644 --- a/samples/bluetooth/central_bas/sample.yaml +++ b/samples/bluetooth/central_bas/sample.yaml @@ -13,11 +13,11 @@ tests: samples.bluetooth.central_bas.build: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/central_hids/sample.yaml b/samples/bluetooth/central_hids/sample.yaml index a55fe2cc0c30..2dd643024c3d 100644 --- a/samples/bluetooth/central_hids/sample.yaml +++ b/samples/bluetooth/central_hids/sample.yaml @@ -13,11 +13,11 @@ tests: samples.bluetooth.central_hids.build: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/central_smp_client/sample.yaml b/samples/bluetooth/central_smp_client/sample.yaml index 9b9c817d2885..0c1bb274f07a 100644 --- a/samples/bluetooth/central_smp_client/sample.yaml +++ b/samples/bluetooth/central_smp_client/sample.yaml @@ -13,11 +13,11 @@ tests: samples.bluetooth.central_dfu_smp.build: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/central_uart/sample.yaml b/samples/bluetooth/central_uart/sample.yaml index 3e3647c3f0ff..ad1413ac867c 100644 --- a/samples/bluetooth/central_uart/sample.yaml +++ b/samples/bluetooth/central_uart/sample.yaml @@ -4,12 +4,12 @@ sample: tests: samples.bluetooth.central_uart: build_only: true - platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 nrf52dk_nrf52810 + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/mesh/light/sample.yaml b/samples/bluetooth/mesh/light/sample.yaml index c733d2a99f69..41160554b96c 100644 --- a/samples/bluetooth/mesh/light/sample.yaml +++ b/samples/bluetooth/mesh/light/sample.yaml @@ -5,12 +5,12 @@ tests: samples.bluetooth.mesh.light: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns thingy53_nrf5340_cpuapp + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns thingy53_nrf5340_cpuapp tags: bluetooth ci_build integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf51dk_nrf51422 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - thingy53_nrf5340_cpuapp diff --git a/samples/bluetooth/mesh/light_switch/sample.yaml b/samples/bluetooth/mesh/light_switch/sample.yaml index c716f20d7e5b..0eb589165d44 100644 --- a/samples/bluetooth/mesh/light_switch/sample.yaml +++ b/samples/bluetooth/mesh/light_switch/sample.yaml @@ -5,12 +5,12 @@ tests: samples.bluetooth.mesh.light_switch: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns thingy53_nrf5340_cpuapp + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns thingy53_nrf5340_cpuapp tags: bluetooth ci_build integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf51dk_nrf51422 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - thingy53_nrf5340_cpuapp diff --git a/samples/bluetooth/mesh/silvair_enocean/sample.yaml b/samples/bluetooth/mesh/silvair_enocean/sample.yaml index db483330d304..400e9d717599 100644 --- a/samples/bluetooth/mesh/silvair_enocean/sample.yaml +++ b/samples/bluetooth/mesh/silvair_enocean/sample.yaml @@ -6,10 +6,10 @@ tests: build_only: true build_on_all: false platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build integration_platforms: - rf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns diff --git a/samples/bluetooth/peripheral_ancs_client/sample.yaml b/samples/bluetooth/peripheral_ancs_client/sample.yaml index 1947af176589..003635251eca 100644 --- a/samples/bluetooth/peripheral_ancs_client/sample.yaml +++ b/samples/bluetooth/peripheral_ancs_client/sample.yaml @@ -4,10 +4,10 @@ sample: tests: samples.bluetooth.peripheral_ancs_client.build: build_only: true - platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/peripheral_cts_client/sample.yaml b/samples/bluetooth/peripheral_cts_client/sample.yaml index 50909f393cac..4d3838aebeae 100644 --- a/samples/bluetooth/peripheral_cts_client/sample.yaml +++ b/samples/bluetooth/peripheral_cts_client/sample.yaml @@ -4,10 +4,10 @@ sample: tests: samples.bluetooth.peripheral_cts_client.build: build_only: true - platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/peripheral_gatt_dm/sample.yaml b/samples/bluetooth/peripheral_gatt_dm/sample.yaml index 64085e8f62f2..169f83e7221d 100644 --- a/samples/bluetooth/peripheral_gatt_dm/sample.yaml +++ b/samples/bluetooth/peripheral_gatt_dm/sample.yaml @@ -5,11 +5,11 @@ tests: samples.bluetooth.peripheral_gatt_dm: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/peripheral_hids_keyboard/sample.yaml b/samples/bluetooth/peripheral_hids_keyboard/sample.yaml index 060773337426..2162bf32791d 100644 --- a/samples/bluetooth/peripheral_hids_keyboard/sample.yaml +++ b/samples/bluetooth/peripheral_hids_keyboard/sample.yaml @@ -12,10 +12,10 @@ tests: samples.bluetooth.peripheral_hids_keyboard.build: build_only: true platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/peripheral_hids_mouse/sample.yaml b/samples/bluetooth/peripheral_hids_mouse/sample.yaml index a73b7a50054f..f64969757284 100644 --- a/samples/bluetooth/peripheral_hids_mouse/sample.yaml +++ b/samples/bluetooth/peripheral_hids_mouse/sample.yaml @@ -13,11 +13,11 @@ tests: samples.bluetooth.peripheral_hids_mouse.build: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/peripheral_lbs/sample.yaml b/samples/bluetooth/peripheral_lbs/sample.yaml index 916def56855b..abca8f434e66 100644 --- a/samples/bluetooth/peripheral_lbs/sample.yaml +++ b/samples/bluetooth/peripheral_lbs/sample.yaml @@ -4,16 +4,16 @@ sample: tests: samples.bluetooth.peripheral_lbs: build_only: true - platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns thingy53_nrf5340_cpuapp integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - thingy53_nrf5340_cpuapp tags: bluetooth ci_build + platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 nrf52dk_nrf52810 + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns thingy53_nrf5340_cpuapp samples.bluetooth.peripheral_lbs_minimal: extra_args: OVERLAY_CONFIG=prj_minimal.conf build_only: true diff --git a/samples/bluetooth/peripheral_nfc_pairing/sample.yaml b/samples/bluetooth/peripheral_nfc_pairing/sample.yaml index 5d1422be1983..a35fa765e178 100644 --- a/samples/bluetooth/peripheral_nfc_pairing/sample.yaml +++ b/samples/bluetooth/peripheral_nfc_pairing/sample.yaml @@ -4,10 +4,10 @@ sample: tests: samples.bluetooth.peripheral_nfc_pairing: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf52840dk_nrf52840 - nrf52dk_nrf52832 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/peripheral_uart/sample.yaml b/samples/bluetooth/peripheral_uart/sample.yaml index ec5b068d8767..4b8e0afa0eb9 100644 --- a/samples/bluetooth/peripheral_uart/sample.yaml +++ b/samples/bluetooth/peripheral_uart/sample.yaml @@ -5,13 +5,13 @@ tests: samples.bluetooth.peripheral_uart: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns thingy53_nrf5340_cpuapp + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns thingy53_nrf5340_cpuapp integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - thingy53_nrf5340_cpuapp tags: bluetooth ci_build samples.bluetooth.peripheral_uart_minimal: diff --git a/samples/bluetooth/shell_bt_nus/sample.yaml b/samples/bluetooth/shell_bt_nus/sample.yaml index 78bc6d12a245..072cbde71704 100644 --- a/samples/bluetooth/shell_bt_nus/sample.yaml +++ b/samples/bluetooth/shell_bt_nus/sample.yaml @@ -5,11 +5,11 @@ tests: samples.bluetooth.shell_bt_nus: build_only: true platform_allow: nrf51dk_nrf51422 nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/bluetooth/throughput/sample.yaml b/samples/bluetooth/throughput/sample.yaml index 52d6a0b06272..c2d28924f210 100644 --- a/samples/bluetooth/throughput/sample.yaml +++ b/samples/bluetooth/throughput/sample.yaml @@ -5,10 +5,10 @@ tests: samples.bluetooth.throughput: build_only: true platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns tags: bluetooth ci_build diff --git a/samples/crypto/aes_cbc/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/aes_cbc/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/aes_cbc/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/aes_cbc/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/aes_cbc/sample.yaml b/samples/crypto/aes_cbc/sample.yaml index 607df87c2572..6a8bddd57168 100644 --- a/samples/crypto/aes_cbc/sample.yaml +++ b/samples/crypto/aes_cbc/sample.yaml @@ -5,14 +5,14 @@ sample: tests: sample.aes_cbc: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/aes_ccm/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/aes_ccm/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/aes_ccm/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/aes_ccm/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/aes_ccm/sample.yaml b/samples/crypto/aes_ccm/sample.yaml index 71ee8c291e90..1d9777303232 100644 --- a/samples/crypto/aes_ccm/sample.yaml +++ b/samples/crypto/aes_ccm/sample.yaml @@ -5,14 +5,14 @@ sample: tests: sample.aes_ccm: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/aes_ctr/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/aes_ctr/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/aes_ctr/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/aes_ctr/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/aes_ctr/sample.yaml b/samples/crypto/aes_ctr/sample.yaml index dc65058b5f10..257a383aee00 100644 --- a/samples/crypto/aes_ctr/sample.yaml +++ b/samples/crypto/aes_ctr/sample.yaml @@ -5,14 +5,14 @@ sample: tests: sample.aes_cbc: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/aes_gcm/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/aes_gcm/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/aes_gcm/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/aes_gcm/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/aes_gcm/sample.yaml b/samples/crypto/aes_gcm/sample.yaml index fb1a98c3b25a..bd63116ebdd2 100644 --- a/samples/crypto/aes_gcm/sample.yaml +++ b/samples/crypto/aes_gcm/sample.yaml @@ -5,14 +5,14 @@ sample: tests: sample.aes_gcm: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/chachapoly/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/chachapoly/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/chachapoly/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/chachapoly/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/chachapoly/sample.yaml b/samples/crypto/chachapoly/sample.yaml index e5049c3304a5..2a3b590203b7 100644 --- a/samples/crypto/chachapoly/sample.yaml +++ b/samples/crypto/chachapoly/sample.yaml @@ -5,14 +5,14 @@ sample: tests: sample.chacha_poly: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/ecdh/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/ecdh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/ecdh/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/ecdh/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/ecdh/sample.yaml b/samples/crypto/ecdh/sample.yaml index b9602c3a324f..9773d8a59e2d 100644 --- a/samples/crypto/ecdh/sample.yaml +++ b/samples/crypto/ecdh/sample.yaml @@ -6,14 +6,14 @@ sample: tests: sample.ecdh: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/ecdsa/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/ecdsa/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/ecdsa/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/ecdsa/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/ecdsa/sample.yaml b/samples/crypto/ecdsa/sample.yaml index 39aac77fd672..73190a1ec8f3 100644 --- a/samples/crypto/ecdsa/sample.yaml +++ b/samples/crypto/ecdsa/sample.yaml @@ -5,14 +5,14 @@ sample: tests: sample.ecdsa: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/hkdf/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/hkdf/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/hkdf/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/hkdf/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/hkdf/sample.yaml b/samples/crypto/hkdf/sample.yaml index 5ee267594ee3..db79c77769ab 100644 --- a/samples/crypto/hkdf/sample.yaml +++ b/samples/crypto/hkdf/sample.yaml @@ -4,14 +4,14 @@ sample: tests: sample.hkdf: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/hmac/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/hmac/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/hmac/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/hmac/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/hmac/sample.yaml b/samples/crypto/hmac/sample.yaml index ed92ceed93fb..4336b0295b5c 100644 --- a/samples/crypto/hmac/sample.yaml +++ b/samples/crypto/hmac/sample.yaml @@ -6,14 +6,14 @@ sample: tests: sample.hmac: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/persistent_key_usage/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/persistent_key_usage/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/persistent_key_usage/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/persistent_key_usage/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/persistent_key_usage/sample.yaml b/samples/crypto/persistent_key_usage/sample.yaml index 70d57038766e..eb110971a31f 100644 --- a/samples/crypto/persistent_key_usage/sample.yaml +++ b/samples/crypto/persistent_key_usage/sample.yaml @@ -6,14 +6,14 @@ sample: tests: sample.aes_cbc: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/psa_tls/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/psa_tls/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/psa_tls/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/psa_tls/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/psa_tls/sample.yaml b/samples/crypto/psa_tls/sample.yaml index 0b21b076f07f..b67a0714aa90 100644 --- a/samples/crypto/psa_tls/sample.yaml +++ b/samples/crypto/psa_tls/sample.yaml @@ -5,5 +5,5 @@ sample: tests: samples.psa_tls: build_only: true - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 tags: ci_build diff --git a/samples/crypto/rng/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/rng/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/rng/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/rng/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/rng/sample.yaml b/samples/crypto/rng/sample.yaml index 53a59c588e70..582630fd837f 100644 --- a/samples/crypto/rng/sample.yaml +++ b/samples/crypto/rng/sample.yaml @@ -4,14 +4,14 @@ sample: tests: sample.rng: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/rsa/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/rsa/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/rsa/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/rsa/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/rsa/sample.yaml b/samples/crypto/rsa/sample.yaml index 6c49f1533c38..be03cfee3efd 100644 --- a/samples/crypto/rsa/sample.yaml +++ b/samples/crypto/rsa/sample.yaml @@ -6,14 +6,14 @@ tests: sample.rsa: skip: true tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/crypto/sha256/boards/nrf5340dk_nrf5340_cpuappns.conf b/samples/crypto/sha256/boards/nrf5340dk_nrf5340_cpuapp_ns.conf similarity index 100% rename from samples/crypto/sha256/boards/nrf5340dk_nrf5340_cpuappns.conf rename to samples/crypto/sha256/boards/nrf5340dk_nrf5340_cpuapp_ns.conf diff --git a/samples/crypto/sha256/sample.yaml b/samples/crypto/sha256/sample.yaml index 3de49af6e995..f898875fabf5 100644 --- a/samples/crypto/sha256/sample.yaml +++ b/samples/crypto/sha256/sample.yaml @@ -4,14 +4,14 @@ sample: tests: sample.sha256: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuappns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line regex: - ".*Example finished successfully!.*" integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - nrf9160dk_nrf9160ns - nrf9160dk_nrf9160 diff --git a/samples/nfc/record_text/sample.yaml b/samples/nfc/record_text/sample.yaml index 7a882fd08452..c087c96b5233 100644 --- a/samples/nfc/record_text/sample.yaml +++ b/samples/nfc/record_text/sample.yaml @@ -4,5 +4,5 @@ sample: tests: samples.nfc.record_text: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: ci_build diff --git a/samples/nfc/system_off/sample.yaml b/samples/nfc/system_off/sample.yaml index 85f8b907ac3c..c96f477cc1f4 100644 --- a/samples/nfc/system_off/sample.yaml +++ b/samples/nfc/system_off/sample.yaml @@ -4,5 +4,5 @@ sample: tests: samples.nfc.system_off: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: ci_build diff --git a/samples/nfc/tnep_tag/sample.yaml b/samples/nfc/tnep_tag/sample.yaml index b434980e3df8..f81387b8cb91 100644 --- a/samples/nfc/tnep_tag/sample.yaml +++ b/samples/nfc/tnep_tag/sample.yaml @@ -4,5 +4,5 @@ sample: tests: samples.nfc.tnep_tag: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: ci_build diff --git a/samples/nfc/writable_ndef_msg/sample.yaml b/samples/nfc/writable_ndef_msg/sample.yaml index 3dc1d5e4753e..c993aec8e749 100644 --- a/samples/nfc/writable_ndef_msg/sample.yaml +++ b/samples/nfc/writable_ndef_msg/sample.yaml @@ -4,5 +4,5 @@ sample: tests: samples.nfc.writable_ndef_msg: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: ci_build diff --git a/samples/tfm/tfm_hello_world/sample.yaml b/samples/tfm/tfm_hello_world/sample.yaml index d5ba5aef618f..9af628051ec2 100644 --- a/samples/tfm/tfm_hello_world/sample.yaml +++ b/samples/tfm/tfm_hello_world/sample.yaml @@ -4,9 +4,9 @@ sample: name: hello world TFM common: tags: tfm - platform_allow: nrf5340dk_nrf5340_cpuappns nrf9160dk_nrf9160ns + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160ns integration_platforms: - - nrf5340dk_nrf5340_cpuappns + - nrf5340dk_nrf5340_cpuapp_ns - nrf9160dk_nrf9160ns harness: console harness_config: diff --git a/tests/drivers/fprotect/negative/testcase.yaml b/tests/drivers/fprotect/negative/testcase.yaml index 78887a750f27..f0901646fb2a 100644 --- a/tests/drivers/fprotect/negative/testcase.yaml +++ b/tests/drivers/fprotect/negative/testcase.yaml @@ -1,5 +1,5 @@ tests: drivers.fprotect.negative: platform_allow: nrf9160dk_nrf9160 nrf52dk_nrf52832 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns nrf52840dk_nrf52840 nrf51dk_nrf51422 + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns nrf52840dk_nrf52840 nrf51dk_nrf51422 tags: b0 fprotect ignore_faults diff --git a/tests/drivers/fprotect/positive/testcase.yaml b/tests/drivers/fprotect/positive/testcase.yaml index 197d10ac95e8..7f6497a854dd 100644 --- a/tests/drivers/fprotect/positive/testcase.yaml +++ b/tests/drivers/fprotect/positive/testcase.yaml @@ -1,5 +1,5 @@ tests: drivers.fprotect.positive: platform_allow: nrf9160dk_nrf9160 nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf51dk_nrf51422 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: b0 fprotect diff --git a/tests/lib/hw_unique_key_tfm/testcase.yaml b/tests/lib/hw_unique_key_tfm/testcase.yaml index f75e5d33c7c7..3cbd4166eea9 100644 --- a/tests/lib/hw_unique_key_tfm/testcase.yaml +++ b/tests/lib/hw_unique_key_tfm/testcase.yaml @@ -1,5 +1,5 @@ tests: lib.hw_unique_key_tfm: - platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuappns + platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuapp_ns tags: hw_unique_key build_only: true diff --git a/tests/subsys/bootloader/bl_crypto/testcase.yaml b/tests/subsys/bootloader/bl_crypto/testcase.yaml index ab3c427b65f7..2ad450b74c54 100644 --- a/tests/subsys/bootloader/bl_crypto/testcase.yaml +++ b/tests/subsys/bootloader/bl_crypto/testcase.yaml @@ -1,5 +1,5 @@ tests: bootloader.bl_crypto: platform_allow: nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf9160dk_nrf9160 nrf51dk_nrf51422 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: b0 diff --git a/tests/subsys/bootloader/bl_storage/testcase.yaml b/tests/subsys/bootloader/bl_storage/testcase.yaml index 10e75d5aa91f..4b95757e4d2f 100644 --- a/tests/subsys/bootloader/bl_storage/testcase.yaml +++ b/tests/subsys/bootloader/bl_storage/testcase.yaml @@ -1,7 +1,7 @@ tests: bootloader.bl_storage: platform_allow: nrf9160dk_nrf9160 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: b0 harness: console harness_config: diff --git a/tests/subsys/bootloader/bl_validation/testcase.yaml b/tests/subsys/bootloader/bl_validation/testcase.yaml index 75b0e3277cef..6d8fc8285f6f 100644 --- a/tests/subsys/bootloader/bl_validation/testcase.yaml +++ b/tests/subsys/bootloader/bl_validation/testcase.yaml @@ -1,5 +1,5 @@ tests: bootloader.bl_validation: platform_allow: nrf9160dk_nrf9160 nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf51dk_nrf51422 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: b0 bl_validation diff --git a/tests/subsys/bootloader/bl_validation_neg/testcase.yaml b/tests/subsys/bootloader/bl_validation_neg/testcase.yaml index 244d8bae9ea3..6151ec8c2c30 100644 --- a/tests/subsys/bootloader/bl_validation_neg/testcase.yaml +++ b/tests/subsys/bootloader/bl_validation_neg/testcase.yaml @@ -1,7 +1,7 @@ tests: bootloader.bl_validation.negative: platform_allow: nrf9160dk_nrf9160 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: b0 bl_validation negative bl_validation_negative harness: console harness_config: diff --git a/tests/subsys/fw_info/testcase.yaml b/tests/subsys/fw_info/testcase.yaml index 88da38d041b1..4e9eb77ca42f 100644 --- a/tests/subsys/fw_info/testcase.yaml +++ b/tests/subsys/fw_info/testcase.yaml @@ -1,5 +1,5 @@ tests: fw_info.core: platform_allow: nrf9160dk_nrf9160 nrf52840dk_nrf52840 nrf52dk_nrf52832 nrf51dk_nrf51422 - nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuappns + nrf5340dk_nrf5340_cpuapp nrf5340dk_nrf5340_cpuapp_ns tags: b0 fw_info diff --git a/tests/subsys/spm/secure_services/testcase.yaml b/tests/subsys/spm/secure_services/testcase.yaml index 47f7fb113fe7..282ac349cf0c 100644 --- a/tests/subsys/spm/secure_services/testcase.yaml +++ b/tests/subsys/spm/secure_services/testcase.yaml @@ -1,4 +1,4 @@ tests: spm.secure_services: - platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuappns + platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuapp_ns tags: spm secure_services diff --git a/tests/subsys/spm/thread_swap/testcase.yaml b/tests/subsys/spm/thread_swap/testcase.yaml index 1324dcae22d2..b393fd752aa2 100644 --- a/tests/subsys/spm/thread_swap/testcase.yaml +++ b/tests/subsys/spm/thread_swap/testcase.yaml @@ -1,4 +1,4 @@ tests: spm.secure_services.thread_swap: - platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuappns + platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuapp_ns tags: spm secure_services thread_swap From 2c0c74820ba6f716cb7773a65f36daa279815668 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 9 Aug 2021 12:53:10 -0700 Subject: [PATCH 092/126] treewide: handle nRF9160 non-secure rename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream zephyr commit 703021a78a ("boards: arm: nrf9160dk_nrf9160: Rename NS target") renamed boards/nrf9160dk_nrf9160ns to boards/nrf9160dk_nrf9160_ns. Make the necessary changes in NCS code, including renames for .overlay and .conf files. Signed-off-by: Martí Bolívar --- applications/asset_tracker/Kconfig | 10 +++++----- applications/asset_tracker/sample.yaml | 2 +- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 .../led_state_def.h | 0 applications/asset_tracker_v2/sample.yaml | 6 +++--- .../asset_tracker_v2/src/modules/ui_module.c | 2 +- .../app_ZDebug.conf | 0 .../app_ZRelease.conf | 0 .../buttons_def.h | 0 .../dts.overlay | 0 .../led_state_def.h | 0 .../mcuboot_ZDebug.conf | 0 .../mcuboot_ZRelease.conf | 0 .../mcuboot_private.pem | 0 .../pm_static_ZDebug.yml | 0 .../pm_static_ZRelease.yml | 0 .../spm_ZRelease.conf | 0 .../app_ZDebug.conf | 0 .../app_ZRelease.conf | 0 .../buttons_def.h | 0 .../dts.overlay | 0 .../led_state_def.h | 0 .../mcuboot_ZDebug.conf | 0 .../mcuboot_ZRelease.conf | 0 .../mcuboot_private.pem | 0 .../pm_static_ZDebug.yml | 0 .../pm_static_ZRelease.yml | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 applications/serial_lte_modem/sample.yaml | 4 ++-- doc/nrf/includes/tfm.txt | 2 +- drivers/gps/nrf9160_gps/Kconfig | 10 +++++----- modules/memfault/Kconfig | 6 +++--- samples/CMakeLists.txt | 2 +- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/aes_cbc/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/aes_ccm/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/aes_ctr/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/aes_gcm/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/chachapoly/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/ecdh/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/ecdsa/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/hkdf/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/hmac/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/persistent_key_usage/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/psa_tls/sample.yaml | 2 +- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/rng/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/rsa/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/crypto/sha256/sample.yaml | 4 ++-- samples/debug/ppi_trace/Kconfig | 6 +++--- samples/edge_impulse/data_forwarder/sample.yaml | 2 +- samples/edge_impulse/wrapper/sample.yaml | 4 ++-- samples/event_manager/sample.yaml | 2 +- samples/nrf9160/agps/sample.yaml | 4 ++-- samples/nrf9160/at_client/sample.yaml | 4 ++-- samples/nrf9160/aws_fota/sample.yaml | 4 ++-- samples/nrf9160/aws_iot/sample.yaml | 4 ++-- samples/nrf9160/azure_fota/sample.yaml | 4 ++-- samples/nrf9160/azure_iot_hub/sample.yaml | 4 ++-- samples/nrf9160/cloud_client/sample.yaml | 4 ++-- samples/nrf9160/coap_client/sample.yaml | 4 ++-- ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/nrf9160/download/sample.yaml | 8 ++++---- samples/nrf9160/fmfu_smp_svr/sample.yaml | 4 ++-- samples/nrf9160/gps/Kconfig | 6 +++--- samples/nrf9160/gps/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/nrf9160/https_client/sample.yaml | 4 ++-- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 ...0.overlay => nrf9160dk_nrf9160_ns_0_14_0.overlay} | 0 samples/nrf9160/lte_ble_gateway/sample.yaml | 4 ++-- samples/nrf9160/lwm2m_carrier/sample.yaml | 4 ++-- samples/nrf9160/lwm2m_client/Kconfig | 8 ++++---- samples/nrf9160/lwm2m_client/sample.yaml | 4 ++-- samples/nrf9160/lwm2m_client/src/ui/Kconfig | 2 +- samples/nrf9160/memfault/sample.yaml | 2 +- ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/nrf9160/modem_shell/sample.yaml | 4 ++-- samples/nrf9160/mqtt_simple/sample.yaml | 4 ++-- samples/nrf9160/multicell_location/sample.yaml | 4 ++-- samples/nrf9160/pdn/sample.yaml | 4 ++-- samples/nrf9160/secure_services/sample.yaml | 12 ++++++------ samples/nrf9160/sms/sample.yaml | 4 ++-- samples/nrf9160/udp/sample.yaml | 4 ++-- samples/profiler/sample.yaml | 2 +- ...rf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} | 0 samples/tfm/tfm_hello_world/sample.yaml | 4 ++-- tests/lib/hw_unique_key_tfm/README.txt | 2 +- tests/lib/hw_unique_key_tfm/testcase.yaml | 2 +- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 tests/subsys/event_manager/testcase.yaml | 2 +- ...60dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} | 0 tests/subsys/net/lib/fota_download/testcase.yaml | 2 +- tests/subsys/spm/secure_services/testcase.yaml | 2 +- tests/subsys/spm/thread_swap/testcase.yaml | 2 +- 125 files changed, 124 insertions(+), 124 deletions(-) rename applications/asset_tracker_v2/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename applications/asset_tracker_v2/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename applications/asset_tracker_v2/boards/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/led_state_def.h (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/app_ZDebug.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/app_ZRelease.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/buttons_def.h (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/dts.overlay (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/led_state_def.h (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/mcuboot_ZDebug.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/mcuboot_ZRelease.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/mcuboot_private.pem (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/pm_static_ZDebug.yml (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/pm_static_ZRelease.yml (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns => nrf9160dk_nrf9160_ns}/spm_ZRelease.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/app_ZDebug.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/app_ZRelease.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/buttons_def.h (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/dts.overlay (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/led_state_def.h (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/mcuboot_ZDebug.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/mcuboot_ZRelease.conf (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/mcuboot_private.pem (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/pm_static_ZDebug.yml (100%) rename applications/pelion_client/configuration/{nrf9160dk_nrf9160ns@1.0.0 => nrf9160dk_nrf9160_ns@1.0.0}/pm_static_ZRelease.yml (100%) rename applications/serial_lte_modem/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/aes_cbc/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/aes_cbc/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/aes_ccm/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/aes_ccm/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/aes_ctr/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/aes_ctr/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/aes_gcm/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/aes_gcm/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/chachapoly/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/chachapoly/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/ecdh/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/ecdh/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/ecdsa/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/ecdsa/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/hkdf/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/hkdf/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/hmac/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/hmac/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/persistent_key_usage/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/persistent_key_usage/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/psa_tls/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/psa_tls/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/rng/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/rng/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/rsa/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/rsa/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/crypto/sha256/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/crypto/sha256/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/nrf9160/download/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/nrf9160/http_update/full_modem_update/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/nrf9160/http_update/full_modem_update/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/nrf9160/lte_ble_gateway/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename samples/nrf9160/lte_ble_gateway/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/nrf9160/lte_ble_gateway/boards/{nrf9160dk_nrf9160ns_0_14_0.overlay => nrf9160dk_nrf9160_ns_0_14_0.overlay} (100%) rename samples/nrf9160/modem_shell/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename samples/tfm/tfm_hello_world/boards/{nrf9160dk_nrf9160ns.overlay => nrf9160dk_nrf9160_ns.overlay} (100%) rename tests/lib/lte_lc/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename tests/subsys/dfu/dfu_target_stream/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) rename tests/subsys/net/lib/fota_download/boards/{nrf9160dk_nrf9160ns.conf => nrf9160dk_nrf9160_ns.conf} (100%) diff --git a/applications/asset_tracker/Kconfig b/applications/asset_tracker/Kconfig index b2d14223aea0..9b9c58d8a21e 100644 --- a/applications/asset_tracker/Kconfig +++ b/applications/asset_tracker/Kconfig @@ -207,9 +207,9 @@ config ACCEL_TRIGGER config FLIP_INPUT int "Button or switch number to simulate flip" - range 1 4 if BOARD_NRF9160DK_NRF9160NS + range 1 4 if BOARD_NRF9160DK_NRF9160_NS range 1 1 if BOARD_THINGY91_NRF9160NS - default 3 if BOARD_NRF9160DK_NRF9160NS + default 3 if BOARD_NRF9160DK_NRF9160_NS default 1 if BOARD_THINGY91_NRF9160NS help Button or switch number to use for simulating @@ -258,7 +258,7 @@ config CLOUD_BUTTON config CLOUD_BUTTON_INPUT int "Set button sensor button number" - range 1 4 if BOARD_NRF9160DK_NRF9160NS + range 1 4 if BOARD_NRF9160DK_NRF9160_NS range 1 1 if BOARD_THINGY91_NRF9160NS default 1 @@ -388,9 +388,9 @@ config TEMP_TRIGGER config TEMP_SIM_BUTTON int "Button or switch to trigger 'data ready' event" - range 1 4 if BOARD_NRF9160DK_NRF9160NS + range 1 4 if BOARD_NRF9160DK_NRF9160_NS range 1 1 if BOARD_THINGY91_NRF9160NS - default 3 if BOARD_NRF9160DK_NRF9160NS + default 3 if BOARD_NRF9160DK_NRF9160_NS default 1 if BOARD_THINGY91_NRF9160NS help Button or switch number to use for triggering diff --git a/applications/asset_tracker/sample.yaml b/applications/asset_tracker/sample.yaml index 9ccc271835f0..16d00a67ce0f 100644 --- a/applications/asset_tracker/sample.yaml +++ b/applications/asset_tracker/sample.yaml @@ -3,5 +3,5 @@ sample: tests: applications.asset_tracker: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns qemu_x86 + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns qemu_x86 tags: ci_build diff --git a/applications/asset_tracker_v2/boards/nrf9160dk_nrf9160ns.conf b/applications/asset_tracker_v2/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from applications/asset_tracker_v2/boards/nrf9160dk_nrf9160ns.conf rename to applications/asset_tracker_v2/boards/nrf9160dk_nrf9160_ns.conf diff --git a/applications/asset_tracker_v2/boards/nrf9160dk_nrf9160ns.overlay b/applications/asset_tracker_v2/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from applications/asset_tracker_v2/boards/nrf9160dk_nrf9160ns.overlay rename to applications/asset_tracker_v2/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/applications/asset_tracker_v2/boards/nrf9160dk_nrf9160ns/led_state_def.h b/applications/asset_tracker_v2/boards/nrf9160dk_nrf9160_ns/led_state_def.h similarity index 100% rename from applications/asset_tracker_v2/boards/nrf9160dk_nrf9160ns/led_state_def.h rename to applications/asset_tracker_v2/boards/nrf9160dk_nrf9160_ns/led_state_def.h diff --git a/applications/asset_tracker_v2/sample.yaml b/applications/asset_tracker_v2/sample.yaml index 092261d7ba43..fa4ac17dcd68 100644 --- a/applications/asset_tracker_v2/sample.yaml +++ b/applications/asset_tracker_v2/sample.yaml @@ -3,11 +3,11 @@ sample: tests: applications.asset_tracker_v2.nrf_cloud: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns tags: ci_build applications.asset_tracker_v2.aws: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns extra_configs: - CONFIG_AWS_IOT_BROKER_HOST_NAME="example-hostname.aws.com" - CONFIG_AWS_IOT_SEC_TAG=42 @@ -31,7 +31,7 @@ tests: tags: ci_build applications.asset_tracker_v2.azure: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns extra_configs: - CONFIG_AZURE_IOT_HUB_DPS_HOSTNAME="global.azure-devices-provisioning.net" - CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE="IDSCOPE" diff --git a/applications/asset_tracker_v2/src/modules/ui_module.c b/applications/asset_tracker_v2/src/modules/ui_module.c index c1fda06e2968..124de07e5b9b 100644 --- a/applications/asset_tracker_v2/src/modules/ui_module.c +++ b/applications/asset_tracker_v2/src/modules/ui_module.c @@ -195,7 +195,7 @@ static void button_handler(uint32_t button_states, uint32_t has_changed) EVENT_SUBMIT(ui_module_event); } -#if defined(CONFIG_BOARD_NRF9160DK_NRF9160NS) +#if defined(CONFIG_BOARD_NRF9160DK_NRF9160_NS) if (has_changed & button_states & DK_BTN2_MSK) { struct ui_module_event *ui_module_event = diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/app_ZDebug.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/app_ZDebug.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/app_ZDebug.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/app_ZDebug.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/app_ZRelease.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/app_ZRelease.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/app_ZRelease.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/app_ZRelease.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/buttons_def.h b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/buttons_def.h similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/buttons_def.h rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/buttons_def.h diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/dts.overlay b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/dts.overlay similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/dts.overlay rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/dts.overlay diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/led_state_def.h b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/led_state_def.h similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/led_state_def.h rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/led_state_def.h diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/mcuboot_ZDebug.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/mcuboot_ZDebug.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/mcuboot_ZDebug.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/mcuboot_ZDebug.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/mcuboot_ZRelease.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/mcuboot_ZRelease.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/mcuboot_ZRelease.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/mcuboot_ZRelease.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/mcuboot_private.pem b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/mcuboot_private.pem similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/mcuboot_private.pem rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/mcuboot_private.pem diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/pm_static_ZDebug.yml b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/pm_static_ZDebug.yml similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/pm_static_ZDebug.yml rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/pm_static_ZDebug.yml diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/pm_static_ZRelease.yml b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/pm_static_ZRelease.yml similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/pm_static_ZRelease.yml rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/pm_static_ZRelease.yml diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns/spm_ZRelease.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/spm_ZRelease.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns/spm_ZRelease.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns/spm_ZRelease.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/app_ZDebug.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/app_ZDebug.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/app_ZDebug.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/app_ZDebug.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/app_ZRelease.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/app_ZRelease.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/app_ZRelease.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/app_ZRelease.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/buttons_def.h b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/buttons_def.h similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/buttons_def.h rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/buttons_def.h diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/dts.overlay b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/dts.overlay similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/dts.overlay rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/dts.overlay diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/led_state_def.h b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/led_state_def.h similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/led_state_def.h rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/led_state_def.h diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/mcuboot_ZDebug.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/mcuboot_ZDebug.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/mcuboot_ZDebug.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/mcuboot_ZDebug.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/mcuboot_ZRelease.conf b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/mcuboot_ZRelease.conf similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/mcuboot_ZRelease.conf rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/mcuboot_ZRelease.conf diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/mcuboot_private.pem b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/mcuboot_private.pem similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/mcuboot_private.pem rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/mcuboot_private.pem diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/pm_static_ZDebug.yml b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/pm_static_ZDebug.yml similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/pm_static_ZDebug.yml rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/pm_static_ZDebug.yml diff --git a/applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/pm_static_ZRelease.yml b/applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/pm_static_ZRelease.yml similarity index 100% rename from applications/pelion_client/configuration/nrf9160dk_nrf9160ns@1.0.0/pm_static_ZRelease.yml rename to applications/pelion_client/configuration/nrf9160dk_nrf9160_ns@1.0.0/pm_static_ZRelease.yml diff --git a/applications/serial_lte_modem/nrf9160dk_nrf9160ns.overlay b/applications/serial_lte_modem/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from applications/serial_lte_modem/nrf9160dk_nrf9160ns.overlay rename to applications/serial_lte_modem/nrf9160dk_nrf9160_ns.overlay diff --git a/applications/serial_lte_modem/sample.yaml b/applications/serial_lte_modem/sample.yaml index 90e1525e4af3..08dd412e229c 100644 --- a/applications/serial_lte_modem/sample.yaml +++ b/applications/serial_lte_modem/sample.yaml @@ -3,10 +3,10 @@ sample: tests: samples.nrf9160.serial_lte_modem: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns tags: ci_build samples.nrf9160.serial_lte_modem.native_tls: build_only: true extra_args: OVERLAY_CONFIG=overlay-native_tls.conf - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns tags: ci_build diff --git a/doc/nrf/includes/tfm.txt b/doc/nrf/includes/tfm.txt index 0f8f14c82f9e..4690373abeb8 100644 --- a/doc/nrf/includes/tfm.txt +++ b/doc/nrf/includes/tfm.txt @@ -1,2 +1,2 @@ -When built for nrf5340dk_nrf5340_cpuappns and nrf9160dk_nrf9160ns targets, the sample is configured to compile and run as a non-secure application. +When built for nrf5340dk_nrf5340_cpuappns and nrf9160dk_nrf9160_ns targets, the sample is configured to compile and run as a non-secure application. Therefore, it automatically includes :ref:`TF-M ` that prepares the required peripherals to be available for the application. diff --git a/drivers/gps/nrf9160_gps/Kconfig b/drivers/gps/nrf9160_gps/Kconfig index 16b8ef044371..062158b7481f 100644 --- a/drivers/gps/nrf9160_gps/Kconfig +++ b/drivers/gps/nrf9160_gps/Kconfig @@ -72,27 +72,27 @@ endchoice config NRF9160_GPS_SET_MAGPIO bool "Let the driver set MAGPIO configuration" - default y if BOARD_NRF9160DK_NRF9160NS || BOARD_THINGY91_NRF9160NS + default y if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS if NRF9160_GPS_SET_MAGPIO config NRF9160_GPS_MAGPIO_STRING string "MAGPIO string" - default "AT\%XMAGPIO=1,0,0,1,1,1565,1586" if BOARD_NRF9160DK_NRF9160NS + default "AT\%XMAGPIO=1,0,0,1,1,1565,1586" if BOARD_NRF9160DK_NRF9160_NS default "AT\%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586" if BOARD_THINGY91_NRF9160NS endif # NRF9160_GPS_SET_MAGPIO config NRF9160_GPS_SET_COEX0 bool "Let the driver set COEX0 configuration" - default y if BOARD_NRF9160DK_NRF9160NS || BOARD_THINGY91_NRF9160NS + default y if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS if NRF9160_GPS_SET_COEX0 config NRF9160_GPS_COEX0_STRING string "COEX0 string" - default "AT\%XCOEX0=1,1,1565,1586" if (BOARD_NRF9160DK_NRF9160NS || BOARD_THINGY91_NRF9160NS) && NRF9160_GPS_ANTENNA_ONBOARD - default "AT\%XCOEX0" if (BOARD_NRF9160DK_NRF9160NS || BOARD_THINGY91_NRF9160NS) && NRF9160_GPS_ANTENNA_EXTERNAL + default "AT\%XCOEX0=1,1,1565,1586" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) && NRF9160_GPS_ANTENNA_ONBOARD + default "AT\%XCOEX0" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) && NRF9160_GPS_ANTENNA_EXTERNAL endif # NRF9160_GPS_SET_COEX0 diff --git a/modules/memfault/Kconfig b/modules/memfault/Kconfig index 033d0bba17e5..f10ebebf1db5 100644 --- a/modules/memfault/Kconfig +++ b/modules/memfault/Kconfig @@ -13,7 +13,7 @@ config MEMFAULT_NCS_PROJECT_KEY choice prompt "Memfault device ID generation method" - default MEMFAULT_NCS_DEVICE_ID_IMEI if (BOARD_NRF9160DK_NRF9160NS || BOARD_THINGY91_NRF9160NS) + default MEMFAULT_NCS_DEVICE_ID_IMEI if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) default MEMFAULT_NCS_DEVICE_ID_STATIC config MEMFAULT_NCS_DEVICE_ID_IMEI @@ -50,14 +50,14 @@ config MEMFAULT_NCS_DEVICE_ID_MAX_LEN config MEMFAULT_NCS_HW_VERSION string "Hardware version" - default "nrf9160dk" if BOARD_NRF9160DK_NRF9160NS + default "nrf9160dk" if BOARD_NRF9160DK_NRF9160_NS default "thingy91" if BOARD_THINGY91_NRF9160NS help Device hardware version config MEMFAULT_NCS_FW_TYPE string "Firmware type" - default "nrf91ns-fw" if BOARD_NRF9160DK_NRF9160NS || BOARD_THINGY91_NRF9160NS + default "nrf91ns-fw" if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS help Firmware type running on the board diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index ac7f85bb3e85..e1f92e5fd8c8 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -76,7 +76,7 @@ if (CONFIG_BUILD_WITH_TFM AND CONFIG_UART_1_NRF_UARTE) Non-secure applications built with TF-M cannot use UART1, because this instance is used by the TF-M secure application. Disable the uart1 node in devicetree. See the following file: - nrf/samples/tfm/tfm_hello_world/boards/nrf9160dk_nrf9160ns.overlay + nrf/samples/tfm/tfm_hello_world/boards/nrf9160dk_nrf9160_ns.overlay for an example how to do it.") endif() diff --git a/samples/crypto/aes_cbc/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/aes_cbc/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/aes_cbc/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/aes_cbc/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/aes_cbc/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/aes_cbc/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/aes_cbc/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/aes_cbc/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/aes_cbc/sample.yaml b/samples/crypto/aes_cbc/sample.yaml index 6a8bddd57168..cc1900659403 100644 --- a/samples/crypto/aes_cbc/sample.yaml +++ b/samples/crypto/aes_cbc/sample.yaml @@ -5,7 +5,7 @@ sample: tests: sample.aes_cbc: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -14,6 +14,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/aes_ccm/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/aes_ccm/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/aes_ccm/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/aes_ccm/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/aes_ccm/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/aes_ccm/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/aes_ccm/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/aes_ccm/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/aes_ccm/sample.yaml b/samples/crypto/aes_ccm/sample.yaml index 1d9777303232..0dfb0bc66cf1 100644 --- a/samples/crypto/aes_ccm/sample.yaml +++ b/samples/crypto/aes_ccm/sample.yaml @@ -5,7 +5,7 @@ sample: tests: sample.aes_ccm: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -14,6 +14,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/aes_ctr/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/aes_ctr/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/aes_ctr/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/aes_ctr/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/aes_ctr/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/aes_ctr/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/aes_ctr/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/aes_ctr/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/aes_ctr/sample.yaml b/samples/crypto/aes_ctr/sample.yaml index 257a383aee00..a919678aaec8 100644 --- a/samples/crypto/aes_ctr/sample.yaml +++ b/samples/crypto/aes_ctr/sample.yaml @@ -5,7 +5,7 @@ sample: tests: sample.aes_cbc: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -14,6 +14,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/aes_gcm/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/aes_gcm/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/aes_gcm/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/aes_gcm/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/aes_gcm/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/aes_gcm/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/aes_gcm/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/aes_gcm/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/aes_gcm/sample.yaml b/samples/crypto/aes_gcm/sample.yaml index bd63116ebdd2..c1065f4b7efb 100644 --- a/samples/crypto/aes_gcm/sample.yaml +++ b/samples/crypto/aes_gcm/sample.yaml @@ -5,7 +5,7 @@ sample: tests: sample.aes_gcm: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -14,6 +14,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/chachapoly/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/chachapoly/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/chachapoly/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/chachapoly/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/chachapoly/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/chachapoly/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/chachapoly/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/chachapoly/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/chachapoly/sample.yaml b/samples/crypto/chachapoly/sample.yaml index 2a3b590203b7..8fc34f071132 100644 --- a/samples/crypto/chachapoly/sample.yaml +++ b/samples/crypto/chachapoly/sample.yaml @@ -5,7 +5,7 @@ sample: tests: sample.chacha_poly: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -14,6 +14,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/ecdh/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/ecdh/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/ecdh/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/ecdh/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/ecdh/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/ecdh/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/ecdh/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/ecdh/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/ecdh/sample.yaml b/samples/crypto/ecdh/sample.yaml index 9773d8a59e2d..6c0bb22c612d 100644 --- a/samples/crypto/ecdh/sample.yaml +++ b/samples/crypto/ecdh/sample.yaml @@ -6,7 +6,7 @@ sample: tests: sample.ecdh: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -15,6 +15,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/ecdsa/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/ecdsa/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/ecdsa/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/ecdsa/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/ecdsa/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/ecdsa/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/ecdsa/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/ecdsa/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/ecdsa/sample.yaml b/samples/crypto/ecdsa/sample.yaml index 73190a1ec8f3..4ab32484fccf 100644 --- a/samples/crypto/ecdsa/sample.yaml +++ b/samples/crypto/ecdsa/sample.yaml @@ -5,7 +5,7 @@ sample: tests: sample.ecdsa: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -14,6 +14,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/hkdf/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/hkdf/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/hkdf/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/hkdf/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/hkdf/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/hkdf/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/hkdf/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/hkdf/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/hkdf/sample.yaml b/samples/crypto/hkdf/sample.yaml index db79c77769ab..b352ba2f98e9 100644 --- a/samples/crypto/hkdf/sample.yaml +++ b/samples/crypto/hkdf/sample.yaml @@ -4,7 +4,7 @@ sample: tests: sample.hkdf: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -13,6 +13,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/hmac/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/hmac/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/hmac/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/hmac/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/hmac/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/hmac/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/hmac/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/hmac/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/hmac/sample.yaml b/samples/crypto/hmac/sample.yaml index 4336b0295b5c..59e0026cd6af 100644 --- a/samples/crypto/hmac/sample.yaml +++ b/samples/crypto/hmac/sample.yaml @@ -6,7 +6,7 @@ sample: tests: sample.hmac: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -15,6 +15,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/persistent_key_usage/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/persistent_key_usage/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/persistent_key_usage/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/persistent_key_usage/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/persistent_key_usage/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/persistent_key_usage/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/persistent_key_usage/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/persistent_key_usage/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/persistent_key_usage/sample.yaml b/samples/crypto/persistent_key_usage/sample.yaml index eb110971a31f..550a7f7580b1 100644 --- a/samples/crypto/persistent_key_usage/sample.yaml +++ b/samples/crypto/persistent_key_usage/sample.yaml @@ -6,7 +6,7 @@ sample: tests: sample.aes_cbc: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -15,6 +15,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/psa_tls/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/psa_tls/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/psa_tls/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/psa_tls/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/psa_tls/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/psa_tls/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/psa_tls/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/psa_tls/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/psa_tls/sample.yaml b/samples/crypto/psa_tls/sample.yaml index b67a0714aa90..bf28024184dc 100644 --- a/samples/crypto/psa_tls/sample.yaml +++ b/samples/crypto/psa_tls/sample.yaml @@ -5,5 +5,5 @@ sample: tests: samples.psa_tls: build_only: true - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 tags: ci_build diff --git a/samples/crypto/rng/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/rng/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/rng/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/rng/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/rng/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/rng/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/rng/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/rng/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/rng/sample.yaml b/samples/crypto/rng/sample.yaml index 582630fd837f..468cd87bd6a9 100644 --- a/samples/crypto/rng/sample.yaml +++ b/samples/crypto/rng/sample.yaml @@ -4,7 +4,7 @@ sample: tests: sample.rng: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -13,6 +13,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/rsa/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/rsa/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/rsa/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/rsa/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/rsa/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/rsa/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/rsa/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/rsa/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/rsa/sample.yaml b/samples/crypto/rsa/sample.yaml index be03cfee3efd..af3744473c01 100644 --- a/samples/crypto/rsa/sample.yaml +++ b/samples/crypto/rsa/sample.yaml @@ -6,7 +6,7 @@ tests: sample.rsa: skip: true tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -15,6 +15,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/crypto/sha256/boards/nrf9160dk_nrf9160ns.conf b/samples/crypto/sha256/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/crypto/sha256/boards/nrf9160dk_nrf9160ns.conf rename to samples/crypto/sha256/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/crypto/sha256/boards/nrf9160dk_nrf9160ns.overlay b/samples/crypto/sha256/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/crypto/sha256/boards/nrf9160dk_nrf9160ns.overlay rename to samples/crypto/sha256/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/crypto/sha256/sample.yaml b/samples/crypto/sha256/sample.yaml index f898875fabf5..b94912752834 100644 --- a/samples/crypto/sha256/sample.yaml +++ b/samples/crypto/sha256/sample.yaml @@ -4,7 +4,7 @@ sample: tests: sample.sha256: tags: introduction - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf5340dk_nrf5340_cpuapp nrf9160dk_nrf9160_ns nrf9160dk_nrf9160 nrf52840dk_nrf52840 harness: console harness_config: type: multi_line @@ -13,6 +13,6 @@ tests: integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - nrf5340dk_nrf5340_cpuapp - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - nrf9160dk_nrf9160 - nrf52840dk_nrf52840 diff --git a/samples/debug/ppi_trace/Kconfig b/samples/debug/ppi_trace/Kconfig index 56f8b1aaaa95..e6ec1f0ae051 100644 --- a/samples/debug/ppi_trace/Kconfig +++ b/samples/debug/ppi_trace/Kconfig @@ -11,7 +11,7 @@ menu "PPI trace pins configuration" config PPI_TRACE_PIN_RTC_COMPARE_EVT int "Trace pin for RTC Compare event" - default 10 if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160NS + default 10 if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160_NS default 1 if BOARD_NRF51DK_NRF51422 default 3 help @@ -19,7 +19,7 @@ config PPI_TRACE_PIN_RTC_COMPARE_EVT config PPI_TRACE_PIN_RTC_TICK_EVT int "Trace pin for RTC Tick event" - default 11 if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160NS + default 11 if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160_NS default 2 if BOARD_NRF51DK_NRF51422 default 4 help @@ -27,7 +27,7 @@ config PPI_TRACE_PIN_RTC_TICK_EVT config PPI_TRACE_PIN_LFCLOCK_STARTED_EVT int "Trace pin for LFCLOCK Started event" - default 12 if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160NS + default 12 if BOARD_NRF9160DK_NRF9160 || BOARD_NRF9160DK_NRF9160_NS default 3 if BOARD_NRF51DK_NRF51422 default 28 help diff --git a/samples/edge_impulse/data_forwarder/sample.yaml b/samples/edge_impulse/data_forwarder/sample.yaml index be954e19cafd..1076f4355516 100644 --- a/samples/edge_impulse/data_forwarder/sample.yaml +++ b/samples/edge_impulse/data_forwarder/sample.yaml @@ -7,5 +7,5 @@ tests: integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/edge_impulse/wrapper/sample.yaml b/samples/edge_impulse/wrapper/sample.yaml index 77ed19f39bc5..255e8eae1227 100644 --- a/samples/edge_impulse/wrapper/sample.yaml +++ b/samples/edge_impulse/wrapper/sample.yaml @@ -4,9 +4,9 @@ sample: tests: samples.edge_impulse.wrapper: build_only: true - platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 nrf9160dk_nrf9160ns + platform_allow: nrf52dk_nrf52832 nrf52840dk_nrf52840 nrf9160dk_nrf9160_ns integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/event_manager/sample.yaml b/samples/event_manager/sample.yaml index dfbdd0ba8293..befba1cd21ac 100644 --- a/samples/event_manager/sample.yaml +++ b/samples/event_manager/sample.yaml @@ -7,5 +7,5 @@ tests: integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/agps/sample.yaml b/samples/nrf9160/agps/sample.yaml index 857995fc3c4c..bea68a65a267 100644 --- a/samples/nrf9160/agps/sample.yaml +++ b/samples/nrf9160/agps/sample.yaml @@ -3,8 +3,8 @@ sample: tests: samples.nrf9160.agps: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - thingy91_nrf9160ns tags: ci_build diff --git a/samples/nrf9160/at_client/sample.yaml b/samples/nrf9160/at_client/sample.yaml index 3e495ecba9e4..6a48fddecb70 100644 --- a/samples/nrf9160/at_client/sample.yaml +++ b/samples/nrf9160/at_client/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.at_client: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/aws_fota/sample.yaml b/samples/nrf9160/aws_fota/sample.yaml index b6a72d798386..b4313320e298 100644 --- a/samples/nrf9160/aws_fota/sample.yaml +++ b/samples/nrf9160/aws_fota/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.aws_fota: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/aws_iot/sample.yaml b/samples/nrf9160/aws_iot/sample.yaml index 3efa31a9c011..362eca0f3df5 100644 --- a/samples/nrf9160/aws_iot/sample.yaml +++ b/samples/nrf9160/aws_iot/sample.yaml @@ -3,8 +3,8 @@ sample: tests: samples.nrf9160.aws_iot: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - thingy91_nrf9160ns tags: ci_build diff --git a/samples/nrf9160/azure_fota/sample.yaml b/samples/nrf9160/azure_fota/sample.yaml index 1f3ff3d91254..b1174628ab9c 100644 --- a/samples/nrf9160/azure_fota/sample.yaml +++ b/samples/nrf9160/azure_fota/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.azure_fota: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/azure_iot_hub/sample.yaml b/samples/nrf9160/azure_iot_hub/sample.yaml index ab7fc48cdc90..fe709286eda3 100644 --- a/samples/nrf9160/azure_iot_hub/sample.yaml +++ b/samples/nrf9160/azure_iot_hub/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.azure_iot_hub: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/cloud_client/sample.yaml b/samples/nrf9160/cloud_client/sample.yaml index 4fadbc8e7032..fbbef81ae562 100644 --- a/samples/nrf9160/cloud_client/sample.yaml +++ b/samples/nrf9160/cloud_client/sample.yaml @@ -3,8 +3,8 @@ sample: tests: samples.nrf9160.cloud_client: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - thingy91_nrf9160ns tags: ci_build diff --git a/samples/nrf9160/coap_client/sample.yaml b/samples/nrf9160/coap_client/sample.yaml index 8ec327dcbfe4..3f76c3b99595 100644 --- a/samples/nrf9160/coap_client/sample.yaml +++ b/samples/nrf9160/coap_client/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.coap_client: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/download/boards/nrf9160dk_nrf9160ns.overlay b/samples/nrf9160/download/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/nrf9160/download/boards/nrf9160dk_nrf9160ns.overlay rename to samples/nrf9160/download/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/nrf9160/download/sample.yaml b/samples/nrf9160/download/sample.yaml index c2a00821e8aa..0b419c506e2e 100644 --- a/samples/nrf9160/download/sample.yaml +++ b/samples/nrf9160/download/sample.yaml @@ -3,9 +3,9 @@ sample: tests: samples.nrf9160.download_client: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build extra_configs: - CONFIG_SHELL=y @@ -13,8 +13,8 @@ tests: - CONFIG_DOWNLOAD_CLIENT_SHELL=y samples.nrf9160.download.tfm: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build extra_args: OVERLAY_CONFIG="overlay-tfm.conf" diff --git a/samples/nrf9160/fmfu_smp_svr/sample.yaml b/samples/nrf9160/fmfu_smp_svr/sample.yaml index 6c1dacc3b48e..9695852503de 100644 --- a/samples/nrf9160/fmfu_smp_svr/sample.yaml +++ b/samples/nrf9160/fmfu_smp_svr/sample.yaml @@ -4,7 +4,7 @@ sample: tests: samples.nrf9160.fmfu_smp_svr: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/gps/Kconfig b/samples/nrf9160/gps/Kconfig index 9955e6e9eafe..797284c913ef 100644 --- a/samples/nrf9160/gps/Kconfig +++ b/samples/nrf9160/gps/Kconfig @@ -25,7 +25,7 @@ endchoice config GPS_SAMPLE_AT_MAGPIO string "AT%XMAGPIO command" - default "AT\%XMAGPIO=1,0,0,1,1,1574,1577" if BOARD_NRF9160DK_NRF9160NS + default "AT\%XMAGPIO=1,0,0,1,1,1574,1577" if BOARD_NRF9160DK_NRF9160_NS default "AT\%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586" if BOARD_THINGY91_NRF9160NS help Defines what is the AT%XMAGPIO command to be sent to GPS module. Leave @@ -33,8 +33,8 @@ config GPS_SAMPLE_AT_MAGPIO config GPS_SAMPLE_AT_COEX0 string "AT%XCOEX0 command" - default "AT\%XCOEX0=1,1,1565,1586" if (BOARD_NRF9160DK_NRF9160NS || BOARD_THINGY91_NRF9160NS) && GPS_SAMPLE_ANTENNA_ONBOARD - default "AT\%XCOEX0" if (BOARD_NRF9160DK_NRF9160NS || BOARD_THINGY91_NRF9160NS) && GPS_SAMPLE_ANTENNA_EXTERNAL + default "AT\%XCOEX0=1,1,1565,1586" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) && GPS_SAMPLE_ANTENNA_ONBOARD + default "AT\%XCOEX0" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) && GPS_SAMPLE_ANTENNA_EXTERNAL help Defines what is the AT%XCOEX0 command to be sent to GPS module. Leave empty if this command should not be sent. diff --git a/samples/nrf9160/gps/sample.yaml b/samples/nrf9160/gps/sample.yaml index a161322f2bae..548a219a3921 100644 --- a/samples/nrf9160/gps/sample.yaml +++ b/samples/nrf9160/gps/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.gps: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/http_update/full_modem_update/boards/nrf9160dk_nrf9160ns.conf b/samples/nrf9160/http_update/full_modem_update/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/nrf9160/http_update/full_modem_update/boards/nrf9160dk_nrf9160ns.conf rename to samples/nrf9160/http_update/full_modem_update/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/nrf9160/http_update/full_modem_update/boards/nrf9160dk_nrf9160ns.overlay b/samples/nrf9160/http_update/full_modem_update/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/nrf9160/http_update/full_modem_update/boards/nrf9160dk_nrf9160ns.overlay rename to samples/nrf9160/http_update/full_modem_update/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/nrf9160/https_client/sample.yaml b/samples/nrf9160/https_client/sample.yaml index 284831423eef..3fcae542d155 100644 --- a/samples/nrf9160/https_client/sample.yaml +++ b/samples/nrf9160/https_client/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.https_client: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160ns.conf b/samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160ns.conf rename to samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160_ns.conf diff --git a/samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160ns.overlay b/samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160ns.overlay rename to samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160ns_0_14_0.overlay b/samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160_ns_0_14_0.overlay similarity index 100% rename from samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160ns_0_14_0.overlay rename to samples/nrf9160/lte_ble_gateway/boards/nrf9160dk_nrf9160_ns_0_14_0.overlay diff --git a/samples/nrf9160/lte_ble_gateway/sample.yaml b/samples/nrf9160/lte_ble_gateway/sample.yaml index 9b18b6d8f779..a7dc16092b72 100644 --- a/samples/nrf9160/lte_ble_gateway/sample.yaml +++ b/samples/nrf9160/lte_ble_gateway/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.lte_ble_gateway: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/lwm2m_carrier/sample.yaml b/samples/nrf9160/lwm2m_carrier/sample.yaml index e8ede0b3754d..246b2111bf07 100644 --- a/samples/nrf9160/lwm2m_carrier/sample.yaml +++ b/samples/nrf9160/lwm2m_carrier/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.lwm2m_carrier: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/lwm2m_client/Kconfig b/samples/nrf9160/lwm2m_client/Kconfig index 5a05aeb070cd..9e536e212aab 100644 --- a/samples/nrf9160/lwm2m_client/Kconfig +++ b/samples/nrf9160/lwm2m_client/Kconfig @@ -134,8 +134,8 @@ config ACCEL_TRIGGER config FLIP_INPUT int "Button or switch number to simulate flip" - range 1 4 if BOARD_NRF9160DK_NRF9160NS - default 3 if BOARD_NRF9160DK_NRF9160NS + range 1 4 if BOARD_NRF9160DK_NRF9160_NS + default 3 if BOARD_NRF9160DK_NRF9160_NS default 0 help Button or switch number to use for simulating @@ -195,8 +195,8 @@ config ACCEL_CALIBRATION_ITERATIONS config CALIBRATION_INPUT int "Button to trigger accelerometer calibration" - range 1 2 if BOARD_NRF9160DK_NRF9160NS - default 1 if BOARD_NRF9160DK_NRF9160NS + range 1 2 if BOARD_NRF9160DK_NRF9160_NS + default 1 if BOARD_NRF9160DK_NRF9160_NS help Button number to use to trigger accelerometer calibration: 1 - Button 1 diff --git a/samples/nrf9160/lwm2m_client/sample.yaml b/samples/nrf9160/lwm2m_client/sample.yaml index fc64f4a17705..f4b871d2e0ee 100644 --- a/samples/nrf9160/lwm2m_client/sample.yaml +++ b/samples/nrf9160/lwm2m_client/sample.yaml @@ -4,7 +4,7 @@ tests: samples.nrf9160.lwm2m_client: build_only: true extra_args: OVERLAY_CONFIG=overlay-ci.conf - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/lwm2m_client/src/ui/Kconfig b/samples/nrf9160/lwm2m_client/src/ui/Kconfig index ac54ae4e24d8..09538ca1c283 100644 --- a/samples/nrf9160/lwm2m_client/src/ui/Kconfig +++ b/samples/nrf9160/lwm2m_client/src/ui/Kconfig @@ -48,7 +48,7 @@ endif # UI_BUZZER config UI_BUTTON bool "Enable buttons" - default y if BOARD_NRF9160DK_NRF9160NS + default y if BOARD_NRF9160DK_NRF9160_NS endmenu diff --git a/samples/nrf9160/memfault/sample.yaml b/samples/nrf9160/memfault/sample.yaml index a1b614d84a9c..6cf158e45267 100644 --- a/samples/nrf9160/memfault/sample.yaml +++ b/samples/nrf9160/memfault/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.memfault: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns tags: ci_build extra_configs: - CONFIG_MEMFAULT_NCS_PROJECT_KEY="dummy-key" diff --git a/samples/nrf9160/modem_shell/boards/nrf9160dk_nrf9160ns.overlay b/samples/nrf9160/modem_shell/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/nrf9160/modem_shell/boards/nrf9160dk_nrf9160ns.overlay rename to samples/nrf9160/modem_shell/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/nrf9160/modem_shell/sample.yaml b/samples/nrf9160/modem_shell/sample.yaml index 129209fed2f3..215b1bfb1ad8 100644 --- a/samples/nrf9160/modem_shell/sample.yaml +++ b/samples/nrf9160/modem_shell/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.modem_shell: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/mqtt_simple/sample.yaml b/samples/nrf9160/mqtt_simple/sample.yaml index 5049691f2cdd..16e47631e60a 100644 --- a/samples/nrf9160/mqtt_simple/sample.yaml +++ b/samples/nrf9160/mqtt_simple/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.mqtt_simple: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/multicell_location/sample.yaml b/samples/nrf9160/multicell_location/sample.yaml index da6670eb9ea4..a64704adfa27 100644 --- a/samples/nrf9160/multicell_location/sample.yaml +++ b/samples/nrf9160/multicell_location/sample.yaml @@ -3,9 +3,9 @@ sample: tests: samples.nrf9160.multicell_location: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - thingy91_nrf9160ns tags: ci_build extra_configs: diff --git a/samples/nrf9160/pdn/sample.yaml b/samples/nrf9160/pdn/sample.yaml index ce9734c26770..c2b909127908 100644 --- a/samples/nrf9160/pdn/sample.yaml +++ b/samples/nrf9160/pdn/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.pdn: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/secure_services/sample.yaml b/samples/nrf9160/secure_services/sample.yaml index d4c533f81547..a7c672402544 100644 --- a/samples/nrf9160/secure_services/sample.yaml +++ b/samples/nrf9160/secure_services/sample.yaml @@ -2,9 +2,9 @@ sample: name: secure services tests: samples.nrf9160.secure_services.default: - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build harness: console harness_config: @@ -37,9 +37,9 @@ tests: - "Secure Services example." samples.nrf9160.secure_services.bootloaders: - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns extra_args: CONFIG_BOOTLOADER_MCUBOOT=y CONFIG_SECURE_BOOT=y CONFIG_SPM_SERVICE_PREVALIDATE=y mcuboot_CONFIG_EXT_API_PROVIDE_EXT_API_ENABLED=y CONFIG_SPM_SERVICE_S0_ACTIVE=y harness: console harness_config: @@ -73,9 +73,9 @@ tests: - "Secure Services example." samples.nrf9160.secure_services.b0_mcuboot: - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns extra_args: OVERLAY_CONFIG="b0_mcuboot_overlay.conf" build_only: true tags: ci_build diff --git a/samples/nrf9160/sms/sample.yaml b/samples/nrf9160/sms/sample.yaml index 9916eb7f3314..a4ecc16ae189 100644 --- a/samples/nrf9160/sms/sample.yaml +++ b/samples/nrf9160/sms/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.sms: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/udp/sample.yaml b/samples/nrf9160/udp/sample.yaml index b8e347bec87a..22645f6615af 100644 --- a/samples/nrf9160/udp/sample.yaml +++ b/samples/nrf9160/udp/sample.yaml @@ -3,8 +3,8 @@ sample: tests: samples.nrf9160.udp: build_only: true - platform_allow: nrf9160dk_nrf9160ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns - thingy91_nrf9160ns tags: ci_build diff --git a/samples/profiler/sample.yaml b/samples/profiler/sample.yaml index db1f5a0b4606..690137c206a1 100644 --- a/samples/profiler/sample.yaml +++ b/samples/profiler/sample.yaml @@ -8,5 +8,5 @@ tests: integration_platforms: - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/tfm/tfm_hello_world/boards/nrf9160dk_nrf9160ns.overlay b/samples/tfm/tfm_hello_world/boards/nrf9160dk_nrf9160_ns.overlay similarity index 100% rename from samples/tfm/tfm_hello_world/boards/nrf9160dk_nrf9160ns.overlay rename to samples/tfm/tfm_hello_world/boards/nrf9160dk_nrf9160_ns.overlay diff --git a/samples/tfm/tfm_hello_world/sample.yaml b/samples/tfm/tfm_hello_world/sample.yaml index 9af628051ec2..6c8ee424a964 100644 --- a/samples/tfm/tfm_hello_world/sample.yaml +++ b/samples/tfm/tfm_hello_world/sample.yaml @@ -4,10 +4,10 @@ sample: name: hello world TFM common: tags: tfm - platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160ns + platform_allow: nrf5340dk_nrf5340_cpuapp_ns nrf9160dk_nrf9160_ns integration_platforms: - nrf5340dk_nrf5340_cpuapp_ns - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns harness: console harness_config: type: multi_line diff --git a/tests/lib/hw_unique_key_tfm/README.txt b/tests/lib/hw_unique_key_tfm/README.txt index 1e9914ae7fe0..5bd61f6f50d6 100644 --- a/tests/lib/hw_unique_key_tfm/README.txt +++ b/tests/lib/hw_unique_key_tfm/README.txt @@ -14,4 +14,4 @@ This means that the SEGGER id of the development kit must be passed both to west Here is an example of passing the id to the build: - west build -b nrf9160dk_nrf9160ns -- -DCONFIG_HUK_TEST_BOARD_SNR=\"901234567\" + west build -b nrf9160dk_nrf9160_ns -- -DCONFIG_HUK_TEST_BOARD_SNR=\"901234567\" diff --git a/tests/lib/hw_unique_key_tfm/testcase.yaml b/tests/lib/hw_unique_key_tfm/testcase.yaml index 3cbd4166eea9..6559ff5b4b73 100644 --- a/tests/lib/hw_unique_key_tfm/testcase.yaml +++ b/tests/lib/hw_unique_key_tfm/testcase.yaml @@ -1,5 +1,5 @@ tests: lib.hw_unique_key_tfm: - platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuapp_ns + platform_allow: nrf9160dk_nrf9160_ns nrf5340dk_nrf5340_cpuapp_ns tags: hw_unique_key build_only: true diff --git a/tests/lib/lte_lc/boards/nrf9160dk_nrf9160ns.conf b/tests/lib/lte_lc/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from tests/lib/lte_lc/boards/nrf9160dk_nrf9160ns.conf rename to tests/lib/lte_lc/boards/nrf9160dk_nrf9160_ns.conf diff --git a/tests/subsys/dfu/dfu_target_stream/boards/nrf9160dk_nrf9160ns.conf b/tests/subsys/dfu/dfu_target_stream/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from tests/subsys/dfu/dfu_target_stream/boards/nrf9160dk_nrf9160ns.conf rename to tests/subsys/dfu/dfu_target_stream/boards/nrf9160dk_nrf9160_ns.conf diff --git a/tests/subsys/event_manager/testcase.yaml b/tests/subsys/event_manager/testcase.yaml index 8185b164ce7a..f5bb1bff9e86 100644 --- a/tests/subsys/event_manager/testcase.yaml +++ b/tests/subsys/event_manager/testcase.yaml @@ -5,5 +5,5 @@ tests: - nrf51dk_nrf51422 - nrf52dk_nrf52832 - nrf52840dk_nrf52840 - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: event_manager diff --git a/tests/subsys/net/lib/fota_download/boards/nrf9160dk_nrf9160ns.conf b/tests/subsys/net/lib/fota_download/boards/nrf9160dk_nrf9160_ns.conf similarity index 100% rename from tests/subsys/net/lib/fota_download/boards/nrf9160dk_nrf9160ns.conf rename to tests/subsys/net/lib/fota_download/boards/nrf9160dk_nrf9160_ns.conf diff --git a/tests/subsys/net/lib/fota_download/testcase.yaml b/tests/subsys/net/lib/fota_download/testcase.yaml index 2b11885e2feb..06ddffbc5712 100644 --- a/tests/subsys/net/lib/fota_download/testcase.yaml +++ b/tests/subsys/net/lib/fota_download/testcase.yaml @@ -1,4 +1,4 @@ tests: net.lib.fota_download: tags: aws fota - platform_allow: nrf9160dk_nrf9160 nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160 nrf9160dk_nrf9160_ns diff --git a/tests/subsys/spm/secure_services/testcase.yaml b/tests/subsys/spm/secure_services/testcase.yaml index 282ac349cf0c..02e8a15fdbea 100644 --- a/tests/subsys/spm/secure_services/testcase.yaml +++ b/tests/subsys/spm/secure_services/testcase.yaml @@ -1,4 +1,4 @@ tests: spm.secure_services: - platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuapp_ns + platform_allow: nrf9160dk_nrf9160_ns nrf5340dk_nrf5340_cpuapp_ns tags: spm secure_services diff --git a/tests/subsys/spm/thread_swap/testcase.yaml b/tests/subsys/spm/thread_swap/testcase.yaml index b393fd752aa2..dbb6fbd64ce4 100644 --- a/tests/subsys/spm/thread_swap/testcase.yaml +++ b/tests/subsys/spm/thread_swap/testcase.yaml @@ -1,4 +1,4 @@ tests: spm.secure_services.thread_swap: - platform_allow: nrf9160dk_nrf9160ns nrf5340dk_nrf5340_cpuapp_ns + platform_allow: nrf9160dk_nrf9160_ns nrf5340dk_nrf5340_cpuapp_ns tags: spm secure_services thread_swap From 8407befdc25c14c14c8f1a7f5ec54f8fa209cd9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 9 Aug 2021 13:02:27 -0700 Subject: [PATCH 093/126] treewide: thingy91_nrf9160: Rename NS target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For consistency with the rest of the NS targets handled in previous commits, switch to an _ns postfix instead of ns. Include a boards/deprecated.cmake update for the previous name and update the existing deprecation for this configuration. (This is the second time that it has been renamed.) Signed-off-by: Martí Bolívar --- Kconfig.nrf | 4 +- applications/asset_tracker/Kconfig | 18 ++++----- ...60ns.conf => prj_thingy91_nrf9160_ns.conf} | 0 applications/asset_tracker/sample.yaml | 2 +- applications/asset_tracker/src/ui/Kconfig | 40 +++++++++---------- ...rf9160ns.conf => thingy91_nrf9160_ns.conf} | 0 ...ns.overlay => thingy91_nrf9160_ns.overlay} | 0 .../led_state_def.h | 0 applications/asset_tracker_v2/sample.yaml | 6 +-- .../src/modules/Kconfig.sensor_module | 2 +- boards/arm/thingy91_nrf9160/CMakeLists.txt | 2 +- boards/arm/thingy91_nrf9160/Kconfig.board | 2 +- boards/arm/thingy91_nrf9160/Kconfig.defconfig | 8 ++-- ..._nrf9160ns.dts => thingy91_nrf9160_ns.dts} | 0 ...rf9160ns.yaml => thingy91_nrf9160_ns.yaml} | 2 +- ...efconfig => thingy91_nrf9160_ns_defconfig} | 2 +- boards/deprecated.cmake | 3 +- drivers/gps/nrf9160_gps/Kconfig | 10 ++--- lib/lte_link_control/lte_lc.c | 6 +-- modules/memfault/Kconfig | 6 +-- samples/nrf9160/agps/sample.yaml | 4 +- samples/nrf9160/aws_iot/sample.yaml | 4 +- samples/nrf9160/cloud_client/sample.yaml | 4 +- samples/nrf9160/gps/Kconfig | 6 +-- samples/nrf9160/lwm2m_client/src/ui/Kconfig | 8 ++-- samples/nrf9160/memfault/sample.yaml | 2 +- ...rf9160ns.conf => thingy91_nrf9160_ns.conf} | 0 .../modem_shell/src/gnss/gnss_common.c | 2 +- .../nrf9160/multicell_location/sample.yaml | 4 +- samples/nrf9160/udp/sample.yaml | 4 +- 30 files changed, 76 insertions(+), 75 deletions(-) rename applications/asset_tracker/{prj_thingy91_nrf9160ns.conf => prj_thingy91_nrf9160_ns.conf} (100%) rename applications/asset_tracker_v2/boards/{thingy91_nrf9160ns.conf => thingy91_nrf9160_ns.conf} (100%) rename applications/asset_tracker_v2/boards/{thingy91_nrf9160ns.overlay => thingy91_nrf9160_ns.overlay} (100%) rename applications/asset_tracker_v2/boards/{thingy91_nrf9160ns => thingy91_nrf9160_ns}/led_state_def.h (100%) rename boards/arm/thingy91_nrf9160/{thingy91_nrf9160ns.dts => thingy91_nrf9160_ns.dts} (100%) rename boards/arm/thingy91_nrf9160/{thingy91_nrf9160ns.yaml => thingy91_nrf9160_ns.yaml} (80%) rename boards/arm/thingy91_nrf9160/{thingy91_nrf9160ns_defconfig => thingy91_nrf9160_ns_defconfig} (94%) rename samples/nrf9160/modem_shell/boards/{thingy91_nrf9160ns.conf => thingy91_nrf9160_ns.conf} (100%) diff --git a/Kconfig.nrf b/Kconfig.nrf index d3d2ab5e3fe7..cdc4430778ab 100644 --- a/Kconfig.nrf +++ b/Kconfig.nrf @@ -24,8 +24,8 @@ config MBEDTLS_LIBRARY_NRF_SECURITY endchoice # This is a temporary solution to whitelist -# BOARD_THINGY91_NRF9160NS in compliance -config BOARD_THINGY91_NRF9160NS +# BOARD_THINGY91_NRF9160_NS in compliance +config BOARD_THINGY91_NRF9160_NS bool # nRF Connect SDK needs a larger default stacks in certain configurations diff --git a/applications/asset_tracker/Kconfig b/applications/asset_tracker/Kconfig index 9b9c58d8a21e..81d6d1f4e866 100644 --- a/applications/asset_tracker/Kconfig +++ b/applications/asset_tracker/Kconfig @@ -208,9 +208,9 @@ config ACCEL_TRIGGER config FLIP_INPUT int "Button or switch number to simulate flip" range 1 4 if BOARD_NRF9160DK_NRF9160_NS - range 1 1 if BOARD_THINGY91_NRF9160NS + range 1 1 if BOARD_THINGY91_NRF9160_NS default 3 if BOARD_NRF9160DK_NRF9160_NS - default 1 if BOARD_THINGY91_NRF9160NS + default 1 if BOARD_THINGY91_NRF9160_NS help Button or switch number to use for simulating a board flip event. @@ -232,7 +232,7 @@ endif config ACCEL_INVERTED bool "Accelerometer inverted" - default y if BOARD_THINGY91_NRF9160NS + default y if BOARD_THINGY91_NRF9160_NS help Enable if the accelerometer is mounted with the top side facing down when the board itself is in normal position. @@ -259,7 +259,7 @@ config CLOUD_BUTTON config CLOUD_BUTTON_INPUT int "Set button sensor button number" range 1 4 if BOARD_NRF9160DK_NRF9160_NS - range 1 1 if BOARD_THINGY91_NRF9160NS + range 1 1 if BOARD_THINGY91_NRF9160_NS default 1 config CLOUD_CONNECT_RETRY_DELAY @@ -389,9 +389,9 @@ config TEMP_TRIGGER config TEMP_SIM_BUTTON int "Button or switch to trigger 'data ready' event" range 1 4 if BOARD_NRF9160DK_NRF9160_NS - range 1 1 if BOARD_THINGY91_NRF9160NS + range 1 1 if BOARD_THINGY91_NRF9160_NS default 3 if BOARD_NRF9160DK_NRF9160_NS - default 1 if BOARD_THINGY91_NRF9160NS + default 1 if BOARD_THINGY91_NRF9160_NS help Button or switch number to use for triggering a 'data ready' event. @@ -415,14 +415,14 @@ endif # ENVIRONMENT_SENSORS menuconfig LIGHT_SENSOR bool "Light sensor" - select BH1749 if BOARD_THINGY91_NRF9160NS - default y if BOARD_THINGY91_NRF9160NS + select BH1749 if BOARD_THINGY91_NRF9160_NS + default y if BOARD_THINGY91_NRF9160_NS if LIGHT_SENSOR config LIGHT_SENSOR_DEV_NAME string "Light sensor device name" - default "BH1749" if BOARD_THINGY91_NRF9160NS + default "BH1749" if BOARD_THINGY91_NRF9160_NS config LIGHT_SENSOR_DATA_SEND_INTERVAL int "Interval in seconds for sending light sensor data" diff --git a/applications/asset_tracker/prj_thingy91_nrf9160ns.conf b/applications/asset_tracker/prj_thingy91_nrf9160_ns.conf similarity index 100% rename from applications/asset_tracker/prj_thingy91_nrf9160ns.conf rename to applications/asset_tracker/prj_thingy91_nrf9160_ns.conf diff --git a/applications/asset_tracker/sample.yaml b/applications/asset_tracker/sample.yaml index 16d00a67ce0f..3e5a94026e1b 100644 --- a/applications/asset_tracker/sample.yaml +++ b/applications/asset_tracker/sample.yaml @@ -3,5 +3,5 @@ sample: tests: applications.asset_tracker: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns qemu_x86 + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns qemu_x86 tags: ci_build diff --git a/applications/asset_tracker/src/ui/Kconfig b/applications/asset_tracker/src/ui/Kconfig index 9e8effe93816..d8864d72a6b2 100644 --- a/applications/asset_tracker/src/ui/Kconfig +++ b/applications/asset_tracker/src/ui/Kconfig @@ -16,15 +16,15 @@ menu "User Interface" config UI_LED_USE_PWM bool "Use PWM to control LEDs" - default y if BOARD_THINGY91_NRF9160NS - select PWM if BOARD_THINGY91_NRF9160NS - select PWM_0 if BOARD_THINGY91_NRF9160NS + default y if BOARD_THINGY91_NRF9160_NS + select PWM if BOARD_THINGY91_NRF9160_NS + select PWM_0 if BOARD_THINGY91_NRF9160_NS if UI_LED_USE_PWM config UI_LED_PWM_DEV_NAME string "PWM device name for RGB LED" - default "PWM_0" if BOARD_THINGY91_NRF9160NS + default "PWM_0" if BOARD_THINGY91_NRF9160_NS config UI_LED_PWM_FREQUENCY int "LED PWM frequency" @@ -33,33 +33,33 @@ config UI_LED_PWM_FREQUENCY config UI_LED_RED_PIN int "Red LED pin number" - default 29 if BOARD_THINGY91_NRF9160NS + default 29 if BOARD_THINGY91_NRF9160_NS config UI_LED_GREEN_PIN int "Green LED pin number" - default 30 if BOARD_THINGY91_NRF9160NS + default 30 if BOARD_THINGY91_NRF9160_NS config UI_LED_BLUE_PIN int "Blue LED pin number" - default 31 if BOARD_THINGY91_NRF9160NS + default 31 if BOARD_THINGY91_NRF9160_NS endif # UI_LED_USE_PWM config UI_BUZZER bool "Enable buzzer" - default y if BOARD_THINGY91_NRF9160NS - select PWM if BOARD_THINGY91_NRF9160NS - select PWM_1 if BOARD_THINGY91_NRF9160NS + default y if BOARD_THINGY91_NRF9160_NS + select PWM if BOARD_THINGY91_NRF9160_NS + select PWM_1 if BOARD_THINGY91_NRF9160_NS if UI_BUZZER config UI_BUZZER_PWM_DEV_NAME string "PWM device name for buzzer" - default "PWM_1" if BOARD_THINGY91_NRF9160NS + default "PWM_1" if BOARD_THINGY91_NRF9160_NS config UI_BUZZER_PIN int "Buzzer pin number" - default 28 if BOARD_THINGY91_NRF9160NS + default 28 if BOARD_THINGY91_NRF9160_NS config UI_BUZZER_MIN_FREQUENCY int "Minimum buzzer frequency" @@ -73,31 +73,31 @@ endif # UI_BUZZER config UI_NMOS bool "Enable NMOS control" - default y if BOARD_THINGY91_NRF9160NS - select PWM if BOARD_THINGY91_NRF9160NS - select PWM_2 if BOARD_THINGY91_NRF9160NS + default y if BOARD_THINGY91_NRF9160_NS + select PWM if BOARD_THINGY91_NRF9160_NS + select PWM_2 if BOARD_THINGY91_NRF9160_NS if UI_NMOS config UI_NMOS_PWM_DEV_NAME string "PWM device name for buzzer" - default "PWM_2" if BOARD_THINGY91_NRF9160NS + default "PWM_2" if BOARD_THINGY91_NRF9160_NS config UI_NMOS_1_PIN int "NMOS 1 pin" - default 13 if BOARD_THINGY91_NRF9160NS + default 13 if BOARD_THINGY91_NRF9160_NS config UI_NMOS_2_PIN int "NMOS 2 pin" - default 14 if BOARD_THINGY91_NRF9160NS + default 14 if BOARD_THINGY91_NRF9160_NS config UI_NMOS_3_PIN int "NMOS 3 pin" - default 15 if BOARD_THINGY91_NRF9160NS + default 15 if BOARD_THINGY91_NRF9160_NS config UI_NMOS_4_PIN int "NMOS 4 pin" - default 16 if BOARD_THINGY91_NRF9160NS + default 16 if BOARD_THINGY91_NRF9160_NS endif # UI_NMOS diff --git a/applications/asset_tracker_v2/boards/thingy91_nrf9160ns.conf b/applications/asset_tracker_v2/boards/thingy91_nrf9160_ns.conf similarity index 100% rename from applications/asset_tracker_v2/boards/thingy91_nrf9160ns.conf rename to applications/asset_tracker_v2/boards/thingy91_nrf9160_ns.conf diff --git a/applications/asset_tracker_v2/boards/thingy91_nrf9160ns.overlay b/applications/asset_tracker_v2/boards/thingy91_nrf9160_ns.overlay similarity index 100% rename from applications/asset_tracker_v2/boards/thingy91_nrf9160ns.overlay rename to applications/asset_tracker_v2/boards/thingy91_nrf9160_ns.overlay diff --git a/applications/asset_tracker_v2/boards/thingy91_nrf9160ns/led_state_def.h b/applications/asset_tracker_v2/boards/thingy91_nrf9160_ns/led_state_def.h similarity index 100% rename from applications/asset_tracker_v2/boards/thingy91_nrf9160ns/led_state_def.h rename to applications/asset_tracker_v2/boards/thingy91_nrf9160_ns/led_state_def.h diff --git a/applications/asset_tracker_v2/sample.yaml b/applications/asset_tracker_v2/sample.yaml index fa4ac17dcd68..6e950a82199b 100644 --- a/applications/asset_tracker_v2/sample.yaml +++ b/applications/asset_tracker_v2/sample.yaml @@ -3,11 +3,11 @@ sample: tests: applications.asset_tracker_v2.nrf_cloud: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns tags: ci_build applications.asset_tracker_v2.aws: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns extra_configs: - CONFIG_AWS_IOT_BROKER_HOST_NAME="example-hostname.aws.com" - CONFIG_AWS_IOT_SEC_TAG=42 @@ -31,7 +31,7 @@ tests: tags: ci_build applications.asset_tracker_v2.azure: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns extra_configs: - CONFIG_AZURE_IOT_HUB_DPS_HOSTNAME="global.azure-devices-provisioning.net" - CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE="IDSCOPE" diff --git a/applications/asset_tracker_v2/src/modules/Kconfig.sensor_module b/applications/asset_tracker_v2/src/modules/Kconfig.sensor_module index 246fdcb1873b..13372960a15a 100644 --- a/applications/asset_tracker_v2/src/modules/Kconfig.sensor_module +++ b/applications/asset_tracker_v2/src/modules/Kconfig.sensor_module @@ -6,7 +6,7 @@ menuconfig SENSOR_MODULE bool "Sensor module" - select EXTERNAL_SENSORS if BOARD_THINGY91_NRF9160NS + select EXTERNAL_SENSORS if BOARD_THINGY91_NRF9160_NS default y if SENSOR_MODULE diff --git a/boards/arm/thingy91_nrf9160/CMakeLists.txt b/boards/arm/thingy91_nrf9160/CMakeLists.txt index 11781f16d657..3681c4346ed2 100644 --- a/boards/arm/thingy91_nrf9160/CMakeLists.txt +++ b/boards/arm/thingy91_nrf9160/CMakeLists.txt @@ -9,7 +9,7 @@ if(CONFIG_BOARD_THINGY91_NRF9160 AND NOT DEFINED CONFIG_MCUBOOT) zephyr_library_sources(board_secure.c) endif() -if(CONFIG_BOARD_THINGY91_NRF9160NS) +if(CONFIG_BOARD_THINGY91_NRF9160_NS) zephyr_library() zephyr_library_sources(board_nonsecure.c) diff --git a/boards/arm/thingy91_nrf9160/Kconfig.board b/boards/arm/thingy91_nrf9160/Kconfig.board index 8f6f5016f9e5..220bc075d0e0 100644 --- a/boards/arm/thingy91_nrf9160/Kconfig.board +++ b/boards/arm/thingy91_nrf9160/Kconfig.board @@ -9,7 +9,7 @@ if SOC_NRF9160_SICA config BOARD_THINGY91_NRF9160 bool "nRF9160 THINGY91" -config BOARD_THINGY91_NRF9160NS +config BOARD_THINGY91_NRF9160_NS bool "nRF9160 THINGY91 non-secure" endif # SOC_NRF9160_SICA diff --git a/boards/arm/thingy91_nrf9160/Kconfig.defconfig b/boards/arm/thingy91_nrf9160/Kconfig.defconfig index 61bffe59d509..4d46041c86ef 100644 --- a/boards/arm/thingy91_nrf9160/Kconfig.defconfig +++ b/boards/arm/thingy91_nrf9160/Kconfig.defconfig @@ -4,7 +4,7 @@ # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause -if BOARD_THINGY91_NRF9160 || BOARD_THINGY91_NRF9160NS +if BOARD_THINGY91_NRF9160 || BOARD_THINGY91_NRF9160_NS config BOARD default "thingy91_nrf9160" @@ -26,7 +26,7 @@ config FLASH_LOAD_SIZE endif # BOARD_THINGY91_NRF9160 && TRUSTED_EXECUTION_SECURE -if BOARD_THINGY91_NRF9160NS +if BOARD_THINGY91_NRF9160_NS config FLASH_LOAD_OFFSET default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) @@ -34,7 +34,7 @@ config FLASH_LOAD_OFFSET config FLASH_LOAD_SIZE default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION)) -endif # BOARD_THINGY91_NRF9160NS +endif # BOARD_THINGY91_NRF9160_NS config BT_HCI_VS default y if BT @@ -42,4 +42,4 @@ config BT_HCI_VS config HW_STACK_PROTECTION default ARCH_HAS_STACK_PROTECTION -endif # BOARD_THINGY91_NRF9160 || BOARD_THINGY91_NRF9160NS +endif # BOARD_THINGY91_NRF9160 || BOARD_THINGY91_NRF9160_NS diff --git a/boards/arm/thingy91_nrf9160/thingy91_nrf9160ns.dts b/boards/arm/thingy91_nrf9160/thingy91_nrf9160_ns.dts similarity index 100% rename from boards/arm/thingy91_nrf9160/thingy91_nrf9160ns.dts rename to boards/arm/thingy91_nrf9160/thingy91_nrf9160_ns.dts diff --git a/boards/arm/thingy91_nrf9160/thingy91_nrf9160ns.yaml b/boards/arm/thingy91_nrf9160/thingy91_nrf9160_ns.yaml similarity index 80% rename from boards/arm/thingy91_nrf9160/thingy91_nrf9160ns.yaml rename to boards/arm/thingy91_nrf9160/thingy91_nrf9160_ns.yaml index 40dd4cf43e6d..fb69b8d7b9ca 100644 --- a/boards/arm/thingy91_nrf9160/thingy91_nrf9160ns.yaml +++ b/boards/arm/thingy91_nrf9160/thingy91_nrf9160_ns.yaml @@ -1,4 +1,4 @@ -identifier: thingy91_nrf9160ns +identifier: thingy91_nrf9160_ns name: THINGY91-nRF9160-Non-Secure type: mcu arch: arm diff --git a/boards/arm/thingy91_nrf9160/thingy91_nrf9160ns_defconfig b/boards/arm/thingy91_nrf9160/thingy91_nrf9160_ns_defconfig similarity index 94% rename from boards/arm/thingy91_nrf9160/thingy91_nrf9160ns_defconfig rename to boards/arm/thingy91_nrf9160/thingy91_nrf9160_ns_defconfig index 9fc33268d083..80b8f3f4213f 100644 --- a/boards/arm/thingy91_nrf9160/thingy91_nrf9160ns_defconfig +++ b/boards/arm/thingy91_nrf9160/thingy91_nrf9160_ns_defconfig @@ -1,6 +1,6 @@ CONFIG_SOC_SERIES_NRF91X=y CONFIG_SOC_NRF9160_SICA=y -CONFIG_BOARD_THINGY91_NRF9160NS=y +CONFIG_BOARD_THINGY91_NRF9160_NS=y # Enable MPU CONFIG_ARM_MPU=y diff --git a/boards/deprecated.cmake b/boards/deprecated.cmake index 4e2d819bc567..e6c5da056928 100644 --- a/boards/deprecated.cmake +++ b/boards/deprecated.cmake @@ -14,4 +14,5 @@ set(nrf52840_pca20035_DEPRECATED thingy91_nrf52840) set(nrf9160_pca20035_DEPRECATED thingy91_nrf9160) -set(nrf9160_pca20035ns_DEPRECATED thingy91_nrf9160ns) +set(nrf9160_pca20035ns_DEPRECATED thingy91_nrf9160_ns) +set(thingy91_nrf9160ns_DEPRECATED thingy91_nrf9160_ns) diff --git a/drivers/gps/nrf9160_gps/Kconfig b/drivers/gps/nrf9160_gps/Kconfig index 062158b7481f..521aa8128350 100644 --- a/drivers/gps/nrf9160_gps/Kconfig +++ b/drivers/gps/nrf9160_gps/Kconfig @@ -72,27 +72,27 @@ endchoice config NRF9160_GPS_SET_MAGPIO bool "Let the driver set MAGPIO configuration" - default y if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS + default y if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160_NS if NRF9160_GPS_SET_MAGPIO config NRF9160_GPS_MAGPIO_STRING string "MAGPIO string" default "AT\%XMAGPIO=1,0,0,1,1,1565,1586" if BOARD_NRF9160DK_NRF9160_NS - default "AT\%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586" if BOARD_THINGY91_NRF9160NS + default "AT\%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586" if BOARD_THINGY91_NRF9160_NS endif # NRF9160_GPS_SET_MAGPIO config NRF9160_GPS_SET_COEX0 bool "Let the driver set COEX0 configuration" - default y if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS + default y if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160_NS if NRF9160_GPS_SET_COEX0 config NRF9160_GPS_COEX0_STRING string "COEX0 string" - default "AT\%XCOEX0=1,1,1565,1586" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) && NRF9160_GPS_ANTENNA_ONBOARD - default "AT\%XCOEX0" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) && NRF9160_GPS_ANTENNA_EXTERNAL + default "AT\%XCOEX0=1,1,1565,1586" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160_NS) && NRF9160_GPS_ANTENNA_ONBOARD + default "AT\%XCOEX0" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160_NS) && NRF9160_GPS_ANTENNA_EXTERNAL endif # NRF9160_GPS_SET_COEX0 diff --git a/lib/lte_link_control/lte_lc.c b/lib/lte_link_control/lte_lc.c index bf1fffefdb0c..61d51d3e8e08 100644 --- a/lib/lte_link_control/lte_lc.c +++ b/lib/lte_link_control/lte_lc.c @@ -152,13 +152,13 @@ static const char system_mode_preference[] = { }; #if !defined(CONFIG_NRF_MODEM_LIB_SYS_INIT) && \ - defined(CONFIG_BOARD_THINGY91_NRF9160NS) + defined(CONFIG_BOARD_THINGY91_NRF9160_NS) static const char thingy91_magpio[] = { "AT%XMAGPIO=1,1,1,7,1,746,803,2,698,748," "2,1710,2200,3,824,894,4,880,960,5,791,849," "7,1565,1586" }; -#endif /* !CONFIG_NRF_MODEM_LIB_SYS_INIT && CONFIG_BOARD_THINGY91_NRF9160NS */ +#endif /* !CONFIG_NRF_MODEM_LIB_SYS_INIT && CONFIG_BOARD_THINGY91_NRF9160_NS */ static struct k_sem link; @@ -572,7 +572,7 @@ static int init_and_config(void) } #if !defined(CONFIG_NRF_MODEM_LIB_SYS_INIT) && \ - defined(CONFIG_BOARD_THINGY91_NRF9160NS) + defined(CONFIG_BOARD_THINGY91_NRF9160_NS) /* Configuring MAGPIO, so that the correct antenna * matching network is used for each LTE band and GPS. */ diff --git a/modules/memfault/Kconfig b/modules/memfault/Kconfig index f10ebebf1db5..deaa8590410f 100644 --- a/modules/memfault/Kconfig +++ b/modules/memfault/Kconfig @@ -13,7 +13,7 @@ config MEMFAULT_NCS_PROJECT_KEY choice prompt "Memfault device ID generation method" - default MEMFAULT_NCS_DEVICE_ID_IMEI if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) + default MEMFAULT_NCS_DEVICE_ID_IMEI if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160_NS) default MEMFAULT_NCS_DEVICE_ID_STATIC config MEMFAULT_NCS_DEVICE_ID_IMEI @@ -51,13 +51,13 @@ config MEMFAULT_NCS_DEVICE_ID_MAX_LEN config MEMFAULT_NCS_HW_VERSION string "Hardware version" default "nrf9160dk" if BOARD_NRF9160DK_NRF9160_NS - default "thingy91" if BOARD_THINGY91_NRF9160NS + default "thingy91" if BOARD_THINGY91_NRF9160_NS help Device hardware version config MEMFAULT_NCS_FW_TYPE string "Firmware type" - default "nrf91ns-fw" if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS + default "nrf91ns-fw" if BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160_NS help Firmware type running on the board diff --git a/samples/nrf9160/agps/sample.yaml b/samples/nrf9160/agps/sample.yaml index bea68a65a267..55feef7d440a 100644 --- a/samples/nrf9160/agps/sample.yaml +++ b/samples/nrf9160/agps/sample.yaml @@ -3,8 +3,8 @@ sample: tests: samples.nrf9160.agps: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns integration_platforms: - nrf9160dk_nrf9160_ns - - thingy91_nrf9160ns + - thingy91_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/aws_iot/sample.yaml b/samples/nrf9160/aws_iot/sample.yaml index 362eca0f3df5..887db5cfb0d8 100644 --- a/samples/nrf9160/aws_iot/sample.yaml +++ b/samples/nrf9160/aws_iot/sample.yaml @@ -3,8 +3,8 @@ sample: tests: samples.nrf9160.aws_iot: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns integration_platforms: - nrf9160dk_nrf9160_ns - - thingy91_nrf9160ns + - thingy91_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/cloud_client/sample.yaml b/samples/nrf9160/cloud_client/sample.yaml index fbbef81ae562..eb771ab23f55 100644 --- a/samples/nrf9160/cloud_client/sample.yaml +++ b/samples/nrf9160/cloud_client/sample.yaml @@ -3,8 +3,8 @@ sample: tests: samples.nrf9160.cloud_client: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns integration_platforms: - nrf9160dk_nrf9160_ns - - thingy91_nrf9160ns + - thingy91_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/gps/Kconfig b/samples/nrf9160/gps/Kconfig index 797284c913ef..3035e54d02f9 100644 --- a/samples/nrf9160/gps/Kconfig +++ b/samples/nrf9160/gps/Kconfig @@ -26,15 +26,15 @@ endchoice config GPS_SAMPLE_AT_MAGPIO string "AT%XMAGPIO command" default "AT\%XMAGPIO=1,0,0,1,1,1574,1577" if BOARD_NRF9160DK_NRF9160_NS - default "AT\%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586" if BOARD_THINGY91_NRF9160NS + default "AT\%XMAGPIO=1,1,1,7,1,746,803,2,698,748,2,1710,2200,3,824,894,4,880,960,5,791,849,7,1565,1586" if BOARD_THINGY91_NRF9160_NS help Defines what is the AT%XMAGPIO command to be sent to GPS module. Leave empty if this command should not be sent. config GPS_SAMPLE_AT_COEX0 string "AT%XCOEX0 command" - default "AT\%XCOEX0=1,1,1565,1586" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) && GPS_SAMPLE_ANTENNA_ONBOARD - default "AT\%XCOEX0" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160NS) && GPS_SAMPLE_ANTENNA_EXTERNAL + default "AT\%XCOEX0=1,1,1565,1586" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160_NS) && GPS_SAMPLE_ANTENNA_ONBOARD + default "AT\%XCOEX0" if (BOARD_NRF9160DK_NRF9160_NS || BOARD_THINGY91_NRF9160_NS) && GPS_SAMPLE_ANTENNA_EXTERNAL help Defines what is the AT%XCOEX0 command to be sent to GPS module. Leave empty if this command should not be sent. diff --git a/samples/nrf9160/lwm2m_client/src/ui/Kconfig b/samples/nrf9160/lwm2m_client/src/ui/Kconfig index 09538ca1c283..a0a180e0281a 100644 --- a/samples/nrf9160/lwm2m_client/src/ui/Kconfig +++ b/samples/nrf9160/lwm2m_client/src/ui/Kconfig @@ -10,8 +10,8 @@ config UI_LED_USE_PWM bool "Use PWM to control LEDs" default y depends on $(dt_alias_enabled,rgb-pwm) - select PWM if BOARD_THINGY91_NRF9160NS - select PWM_0 if BOARD_THINGY91_NRF9160NS + select PWM if BOARD_THINGY91_NRF9160_NS + select PWM_0 if BOARD_THINGY91_NRF9160_NS help If enabled, LEDs will be controlled with PWM. In order to enable this option, the devicetree must have an @@ -24,8 +24,8 @@ config UI_BUZZER bool "Enable buzzer" default y depends on $(dt_alias_enabled,buzzer-pwm) - select PWM if BOARD_THINGY91_NRF9160NS - select PWM_1 if BOARD_THINGY91_NRF9160NS + select PWM if BOARD_THINGY91_NRF9160_NS + select PWM_1 if BOARD_THINGY91_NRF9160_NS help If enabled, a buzzer will be controllable with PWM. In order to enable this option, the devicetree must have diff --git a/samples/nrf9160/memfault/sample.yaml b/samples/nrf9160/memfault/sample.yaml index 6cf158e45267..8e4a1c06d5f2 100644 --- a/samples/nrf9160/memfault/sample.yaml +++ b/samples/nrf9160/memfault/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.memfault: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns tags: ci_build extra_configs: - CONFIG_MEMFAULT_NCS_PROJECT_KEY="dummy-key" diff --git a/samples/nrf9160/modem_shell/boards/thingy91_nrf9160ns.conf b/samples/nrf9160/modem_shell/boards/thingy91_nrf9160_ns.conf similarity index 100% rename from samples/nrf9160/modem_shell/boards/thingy91_nrf9160ns.conf rename to samples/nrf9160/modem_shell/boards/thingy91_nrf9160_ns.conf diff --git a/samples/nrf9160/modem_shell/src/gnss/gnss_common.c b/samples/nrf9160/modem_shell/src/gnss/gnss_common.c index 25fef6d16970..00e524115174 100644 --- a/samples/nrf9160/modem_shell/src/gnss/gnss_common.c +++ b/samples/nrf9160/modem_shell/src/gnss/gnss_common.c @@ -13,7 +13,7 @@ #include "gnss.h" -#ifdef CONFIG_BOARD_THINGY91_NRF9160NS +#ifdef CONFIG_BOARD_THINGY91_NRF9160_NS #define GNSS_LNA_ENABLE_XMAGPIO "AT\%XMAGPIO=1,1,1,7,1,746,803,2,698,748," \ "2,1710,2200,3,824,894,4,880,960,5,791,849," \ "7,1565,1586" diff --git a/samples/nrf9160/multicell_location/sample.yaml b/samples/nrf9160/multicell_location/sample.yaml index a64704adfa27..667c7237865c 100644 --- a/samples/nrf9160/multicell_location/sample.yaml +++ b/samples/nrf9160/multicell_location/sample.yaml @@ -3,10 +3,10 @@ sample: tests: samples.nrf9160.multicell_location: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns integration_platforms: - nrf9160dk_nrf9160_ns - - thingy91_nrf9160ns + - thingy91_nrf9160_ns tags: ci_build extra_configs: - CONFIG_MULTICELL_LOCATION_SERVICE_HERE=y diff --git a/samples/nrf9160/udp/sample.yaml b/samples/nrf9160/udp/sample.yaml index 22645f6615af..88dff6892776 100644 --- a/samples/nrf9160/udp/sample.yaml +++ b/samples/nrf9160/udp/sample.yaml @@ -3,8 +3,8 @@ sample: tests: samples.nrf9160.udp: build_only: true - platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns thingy91_nrf9160_ns integration_platforms: - nrf9160dk_nrf9160_ns - - thingy91_nrf9160ns + - thingy91_nrf9160_ns tags: ci_build From 5656a65b9f5cef8bec5aa1d1ed9d1f06c483bba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 9 Aug 2021 12:35:13 -0700 Subject: [PATCH 094/126] doc: handle nRF5340DK non-secure rename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream zephyr commit b8c9dc169e ("boards: arm: nrf5340dk_nrf5340: Rename NS target") renamed nrf5340dk_nrf5340_cpuappns to nrf5340dk_nrf5340_cpuapp_ns. Make the necessary changes in NCS documentation. The documentation changes are in a separate commit from the code changes because they require manual cleanup in RST tables after doing a scripted search and replace. Signed-off-by: Martí Bolívar --- applications/pelion_client/README.rst | 2 +- doc/nrf/app_boards.rst | 2 +- .../boardname_tables/sample_boardnames.txt | 32 +++++++++---------- doc/nrf/includes/sample_board_rows.txt | 10 +++--- doc/nrf/includes/tfm.txt | 2 +- doc/nrf/known_issues.rst | 4 +-- doc/nrf/ug_nrf5340.rst | 6 ++-- doc/nrf/ug_tfm.rst | 2 +- samples/crypto/aes_cbc/README.rst | 2 +- samples/crypto/aes_ccm/README.rst | 2 +- samples/crypto/aes_ctr/README.rst | 2 +- samples/crypto/aes_gcm/README.rst | 2 +- samples/crypto/chachapoly/README.rst | 2 +- samples/crypto/ecdh/README.rst | 2 +- samples/crypto/ecdsa/README.rst | 2 +- samples/crypto/hkdf/README.rst | 2 +- samples/crypto/hmac/README.rst | 2 +- .../crypto/persistent_key_usage/README.rst | 2 +- samples/crypto/psa_tls/README.rst | 2 +- samples/crypto/rng/README.rst | 2 +- samples/crypto/rsa/README.rst | 2 +- samples/crypto/sha256/README.rst | 2 +- samples/tfm/tfm_hello_world/README.rst | 2 +- 23 files changed, 45 insertions(+), 45 deletions(-) diff --git a/applications/pelion_client/README.rst b/applications/pelion_client/README.rst index 42e7cd74e3dd..34908822f958 100644 --- a/applications/pelion_client/README.rst +++ b/applications/pelion_client/README.rst @@ -354,7 +354,7 @@ The application supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns, nrf5340dk_nrf5340_cpuapp, nrf5340dk_nrf5340_cpuappns, nrf52840dk_nrf52840 + :rows: nrf9160dk_nrf9160ns, nrf5340dk_nrf5340_cpuapp, nrf5340dk_nrf5340_cpuapp_ns, nrf52840dk_nrf52840 The nRF Pelion Client application is configured to compile and run as a non-secure application on nRF91's and nRF5340's Cortex-M33. Therefore, it automatically includes the :ref:`secure_partition_manager` that prepares the required peripherals to be available for the application. diff --git a/doc/nrf/app_boards.rst b/doc/nrf/app_boards.rst index b3ee95cc6ccd..b8bc970368ea 100644 --- a/doc/nrf/app_boards.rst +++ b/doc/nrf/app_boards.rst @@ -52,7 +52,7 @@ Also see the :ref:`zephyr:boards` section in the Zephyr documentation. | | | | | | | | | ``nrf5340dk_nrf5340_cpuapp`` | | | | | | -| | | | ``nrf5340dk_nrf5340_cpuappns`` | +| | | | ``nrf5340dk_nrf5340_cpuapp_ns`` | +-------------------+------------+-----------------------------------------------------------------+---------------------------------------+ | nRF9160 DK | PCA10090 | :ref:`nrf9160dk_nrf9160 ` | ``nrf9160dk_nrf9160`` | | | | | | diff --git a/doc/nrf/includes/boardname_tables/sample_boardnames.txt b/doc/nrf/includes/boardname_tables/sample_boardnames.txt index 5a0704094b8c..61e1587f1078 100644 --- a/doc/nrf/includes/boardname_tables/sample_boardnames.txt +++ b/doc/nrf/includes/boardname_tables/sample_boardnames.txt @@ -9,7 +9,7 @@ Set used by Bluetooth LE Samples, NFC samples, and NUS shell transport sample. +================================+===========+================================================+================================+ |:ref:`nRF5340 DK ` |PCA10095 |:ref:`nrf5340dk_nrf5340 ` |``nrf5340dk_nrf5340_cpuapp`` | | | | | | -| | | |``nrf5340dk_nrf5340_cpuappns`` | +| | | |``nrf5340dk_nrf5340_cpuapp_ns`` | +--------------------------------+-----------+------------------------------------------------+--------------------------------+ |:ref:`nRF52840 DK ` |PCA10056 |:ref:`nrf52840dk_nrf52840 `|``nrf52840dk_nrf52840`` | +--------------------------------+-----------+------------------------------------------------+--------------------------------+ @@ -36,19 +36,19 @@ Set used by Bluetooth LE samples (Peripheral LBS) .. set3_start -+---------------------------------+-----------+--------------------------------------------------------+-------------------------------+ -|Hardware platforms |PCA |Board name |Build target | -+=================================+===========+========================================================+===============================+ -|:ref:`nRF5340 DK ` |PCA10095 |:ref:`nrf5340dk_nrf5340 ` |``nrf5340dk_nrf5340_cpuapp`` | -| | | | | -| | | |``nrf5340dk_nrf5340_cpuappns`` | -+---------------------------------+-----------+--------------------------------------------------------+-------------------------------+ -|:ref:`nRF52840 Dongle `|PCA10059 |:ref:`nrf52840dongle_nrf52840 `|``nrf52840dongle_nrf52840`` | -+---------------------------------+-----------+--------------------------------------------------------+-------------------------------+ -|:ref:`nRF52840 DK ` |PCA10056 |:ref:`nrf52840dk_nrf52840 ` |``nrf52840dk_nrf52840`` | -+---------------------------------+-----------+--------------------------------------------------------+-------------------------------+ -|:ref:`nRF52 DK ` |PCA10040 |:ref:`nrf52dk_nrf52832 ` |``nrf52dk_nrf52832`` | -+---------------------------------+-----------+--------------------------------------------------------+-------------------------------+ ++---------------------------------+-----------+--------------------------------------------------------+--------------------------------+ +|Hardware platforms |PCA |Board name |Build target | ++=================================+===========+========================================================+================================+ +|:ref:`nRF5340 DK ` |PCA10095 |:ref:`nrf5340dk_nrf5340 ` |``nrf5340dk_nrf5340_cpuapp`` | +| | | | | +| | | |``nrf5340dk_nrf5340_cpuapp_ns`` | ++---------------------------------+-----------+--------------------------------------------------------+--------------------------------+ +|:ref:`nRF52840 Dongle `|PCA10059 |:ref:`nrf52840dongle_nrf52840 `|``nrf52840dongle_nrf52840`` | ++---------------------------------+-----------+--------------------------------------------------------+--------------------------------+ +|:ref:`nRF52840 DK ` |PCA10056 |:ref:`nrf52840dk_nrf52840 ` |``nrf52840dk_nrf52840`` | ++---------------------------------+-----------+--------------------------------------------------------+--------------------------------+ +|:ref:`nRF52 DK ` |PCA10040 |:ref:`nrf52dk_nrf52832 ` |``nrf52dk_nrf52832`` | ++---------------------------------+-----------+--------------------------------------------------------+--------------------------------+ .. set3_end @@ -214,7 +214,7 @@ Set used by nRF53 samples (Empty firmware for application core) +================================+===========+===============================================+================================+ |:ref:`nRF5340 DK ` |PCA10095 |:ref:`nrf5340dk_nrf5340 ` |``nrf5340dk_nrf5340_cpuapp`` | | | | | | -| | | |``nrf5340dk_nrf5340_cpuappns`` | +| | | |``nrf5340dk_nrf5340_cpuapp_ns`` | +--------------------------------+-----------+-----------------------------------------------+--------------------------------+ .. set15_end @@ -230,7 +230,7 @@ Set used by sample (Immutable bootloader) +--------------------------------+-----------+------------------------------------------------+--------------------------------+ |:ref:`nRF5340 DK ` |PCA10095 |:ref:`nrf5340dk_nrf5340 ` |``nrf5340dk_nrf5340_cpuapp`` | | | | | | -| | | |``nrf5340dk_nrf5340_cpuappns`` | +| | | |``nrf5340dk_nrf5340_cpuapp_ns`` | +--------------------------------+-----------+------------------------------------------------+--------------------------------+ |:ref:`nRF52840 DK ` |PCA10056 |:ref:`nrf52840dk_nrf52840 `|``nrf52840dk_nrf52840`` | +--------------------------------+-----------+------------------------------------------------+--------------------------------+ diff --git a/doc/nrf/includes/sample_board_rows.txt b/doc/nrf/includes/sample_board_rows.txt index 718281d72648..1c7b58efee56 100644 --- a/doc/nrf/includes/sample_board_rows.txt +++ b/doc/nrf/includes/sample_board_rows.txt @@ -30,9 +30,9 @@ | :ref:`nRF5340 DK ` | PCA10095 | :ref:`nrf5340dk_nrf5340 ` | ``nrf5340dk_nrf5340_cpuapp`` | -.. nrf5340dk_nrf5340_cpuappns +.. nrf5340dk_nrf5340_cpuapp_ns -| :ref:`nRF5340 DK ` | PCA10095 | :ref:`nrf5340dk_nrf5340 ` | ``nrf5340dk_nrf5340_cpuappns`` | +| :ref:`nRF5340 DK ` | PCA10095 | :ref:`nrf5340dk_nrf5340 ` | ``nrf5340dk_nrf5340_cpuapp_ns`` | .. nrf5340dk_nrf5340_cpunet @@ -92,9 +92,9 @@ .. nrf5340dk_nrf5340_cpuapp_and_cpuappns -| :ref:`nRF5340 DK ` | PCA10095 | :ref:`nrf5340dk_nrf5340 ` | ``nrf5340dk_nrf5340_cpuapp`` | -| | | | | -| | | | ``nrf5340dk_nrf5340_cpuappns`` | +| :ref:`nRF5340 DK ` | PCA10095 | :ref:`nrf5340dk_nrf5340 ` | ``nrf5340dk_nrf5340_cpuapp`` | +| | | | | +| | | | ``nrf5340dk_nrf5340_cpuapp_ns`` | .. nrf5340dk_nrf5340_cpuapp_and_cpunet diff --git a/doc/nrf/includes/tfm.txt b/doc/nrf/includes/tfm.txt index 4690373abeb8..924bc9ecf1de 100644 --- a/doc/nrf/includes/tfm.txt +++ b/doc/nrf/includes/tfm.txt @@ -1,2 +1,2 @@ -When built for nrf5340dk_nrf5340_cpuappns and nrf9160dk_nrf9160_ns targets, the sample is configured to compile and run as a non-secure application. +When built for nrf5340dk_nrf5340_cpuapp_ns and nrf9160dk_nrf9160ns targets, the sample is configured to compile and run as a non-secure application. Therefore, it automatically includes :ref:`TF-M ` that prepares the required peripherals to be available for the application. diff --git a/doc/nrf/known_issues.rst b/doc/nrf/known_issues.rst index 9d740512c32d..0a14ac8f7903 100644 --- a/doc/nrf/known_issues.rst +++ b/doc/nrf/known_issues.rst @@ -212,7 +212,7 @@ NCSDK-9786: Wrong FLASH_PAGE_ERASE_MAX_TIME_US for the nRF53 network core .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 NCSDK-7234: UART output is not received from the network core - The UART output is not received from the network core if the application core is programmed and running with a non-secure image (using the ``nrf5340dk_nrf5340_cpuappns`` build target). + The UART output is not received from the network core if the application core is programmed and running with a non-secure image (using the ``nrf5340dk_nrf5340_cpuapp_ns`` build target). .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 @@ -796,7 +796,7 @@ Build system Missing files or permissions when building on Windows Because of the Windows path length limitations, the build can fail with errors related to permissions or missing files if some paths in the build are too long. - **Workaround:** Shorten the build folder name, for example, from "build_nrf5340dk_nrf5340_cpuappns" to "build", or shorten the path to the build folder in some other way. + **Workaround:** Shorten the build folder name, for example, from "build_nrf5340dk_nrf5340_cpuapp_ns" to "build", or shorten the path to the build folder in some other way. .. rst-class:: v1-4-2 v1-4-1 v1-4-0 diff --git a/doc/nrf/ug_nrf5340.rst b/doc/nrf/ug_nrf5340.rst index a8e32f71b820..650b16cd8b3e 100644 --- a/doc/nrf/ug_nrf5340.rst +++ b/doc/nrf/ug_nrf5340.rst @@ -69,7 +69,7 @@ Trusted Firmware-M (TF-M) In Zephyr, the application core is divided into two different build targets: * ``nrf5340dk_nrf5340_cpuapp`` for the secure domain -* ``nrf5340dk_nrf5340_cpuappns`` for the non-secure domain +* ``nrf5340dk_nrf5340_cpuapp_ns`` for the non-secure domain Inter-core communication ======================== @@ -335,7 +335,7 @@ To program a multi-image HEX file, you must add the project files for the networ Separate images --------------- -To build and program only the application core, follow the instructions in :ref:`gs_programming_ses` and use ``nrf5340dk_nrf5340_cpuapp`` or ``nrf5340dk_nrf5340_cpuappns`` as build target. +To build and program only the application core, follow the instructions in :ref:`gs_programming_ses` and use ``nrf5340dk_nrf5340_cpuapp`` or ``nrf5340dk_nrf5340_cpuapp_ns`` as build target. To build and program a dedicated network sample, follow the instructions in :ref:`gs_programming_ses` and use ``nrf5340dk_nrf5340_cpunet`` as the build target. @@ -357,7 +357,7 @@ You must manually add a network core project to the application core project to Follow these steps to build and program a multi-image build to the nRF5340 application core and network core: 1. Follow the instructions in :ref:`gs_programming_ses` and open the application core sample (for example, :ref:`peripheral_lbs`) in |SES|. - Use ``nrf5340dk_nrf5340_cpuapp`` or ``nrf5340dk_nrf5340_cpuappns`` as the build target. + Use ``nrf5340dk_nrf5340_cpuapp`` or ``nrf5340dk_nrf5340_cpuapp_ns`` as the build target. #. Build the sample as described in :ref:`gs_programming_ses`. This creates both the application core image and the network core image. #. Select :guilabel:`File` > :guilabel:`New Project`. diff --git a/doc/nrf/ug_tfm.rst b/doc/nrf/ug_tfm.rst index fad96280c599..2c2a7d162c35 100644 --- a/doc/nrf/ug_tfm.rst +++ b/doc/nrf/ug_tfm.rst @@ -45,7 +45,7 @@ To build a :ref:`minimal version ` of TF-M, you must also ena You must build TF-M using a non-secure build target. The following targets are currently supported: -* ``nrf5340dk_nrf5340_cpuappns`` +* ``nrf5340dk_nrf5340_cpuapp_ns`` * ``nrf9160dk_nrf9160ns`` When building for ``nrf9160dk_nrf9160ns``, UART1 must be disabled in the non-secure application, because it is used by the TF-M secure application. diff --git a/samples/crypto/aes_cbc/README.rst b/samples/crypto/aes_cbc/README.rst index 31b843d3860c..9af69103930e 100644 --- a/samples/crypto/aes_cbc/README.rst +++ b/samples/crypto/aes_cbc/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/aes_ccm/README.rst b/samples/crypto/aes_ccm/README.rst index 00aaf2078c20..9c9f2e79e0c6 100644 --- a/samples/crypto/aes_ccm/README.rst +++ b/samples/crypto/aes_ccm/README.rst @@ -37,7 +37,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/aes_ctr/README.rst b/samples/crypto/aes_ctr/README.rst index 7d592fad80e9..f5f0f6ded0c7 100644 --- a/samples/crypto/aes_ctr/README.rst +++ b/samples/crypto/aes_ctr/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/aes_gcm/README.rst b/samples/crypto/aes_gcm/README.rst index 309c8ffb1cb8..e91445410fe2 100644 --- a/samples/crypto/aes_gcm/README.rst +++ b/samples/crypto/aes_gcm/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/chachapoly/README.rst b/samples/crypto/chachapoly/README.rst index e113925cd7ec..1f759fb4df7b 100644 --- a/samples/crypto/chachapoly/README.rst +++ b/samples/crypto/chachapoly/README.rst @@ -37,7 +37,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/ecdh/README.rst b/samples/crypto/ecdh/README.rst index 4c6a0d4dd445..9683d3a9eabf 100644 --- a/samples/crypto/ecdh/README.rst +++ b/samples/crypto/ecdh/README.rst @@ -32,7 +32,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/ecdsa/README.rst b/samples/crypto/ecdsa/README.rst index 9439500b36a2..8e11a3490ad4 100644 --- a/samples/crypto/ecdsa/README.rst +++ b/samples/crypto/ecdsa/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/hkdf/README.rst b/samples/crypto/hkdf/README.rst index 66b78407ff65..ff1060ddcf6c 100644 --- a/samples/crypto/hkdf/README.rst +++ b/samples/crypto/hkdf/README.rst @@ -32,7 +32,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/hmac/README.rst b/samples/crypto/hmac/README.rst index 6084e9abf183..257915d3b93b 100644 --- a/samples/crypto/hmac/README.rst +++ b/samples/crypto/hmac/README.rst @@ -34,7 +34,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/persistent_key_usage/README.rst b/samples/crypto/persistent_key_usage/README.rst index 07f855030d21..d5ff6f23de9e 100644 --- a/samples/crypto/persistent_key_usage/README.rst +++ b/samples/crypto/persistent_key_usage/README.rst @@ -37,7 +37,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/psa_tls/README.rst b/samples/crypto/psa_tls/README.rst index 5b397a325f9d..07b69254f5ce 100644 --- a/samples/crypto/psa_tls/README.rst +++ b/samples/crypto/psa_tls/README.rst @@ -113,7 +113,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf9160dk_nrf9160ns + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf9160dk_nrf9160ns The sample requires a `TAP adapter`_ to perform the TLS handshake. This functionality is currently only supported in Linux. diff --git a/samples/crypto/rng/README.rst b/samples/crypto/rng/README.rst index d8b7c91d23f1..5109725f3fde 100644 --- a/samples/crypto/rng/README.rst +++ b/samples/crypto/rng/README.rst @@ -25,7 +25,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/rsa/README.rst b/samples/crypto/rsa/README.rst index f0407054e097..92c74f828830 100644 --- a/samples/crypto/rsa/README.rst +++ b/samples/crypto/rsa/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/sha256/README.rst b/samples/crypto/sha256/README.rst index 0dfb97afc030..be710958e1e4 100644 --- a/samples/crypto/sha256/README.rst +++ b/samples/crypto/sha256/README.rst @@ -28,7 +28,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/tfm/tfm_hello_world/README.rst b/samples/tfm/tfm_hello_world/README.rst index 097f2b0ab904..e6fce25c746e 100644 --- a/samples/tfm/tfm_hello_world/README.rst +++ b/samples/tfm/tfm_hello_world/README.rst @@ -22,7 +22,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuappns, nrf9160dk_nrf9160ns + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf9160dk_nrf9160ns Building and Running ******************** From fed5f975c6f33de1967bb346ab015ba3aff08e96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 9 Aug 2021 12:44:23 -0700 Subject: [PATCH 095/126] doc: handle nRF9160 non-secure rename MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream zephyr commit 703021a78a ("boards: arm: nrf9160dk_nrf9160: Rename NS target") renamed boards/nrf9160dk_nrf9160ns to boards/nrf9160dk_nrf9160_ns. Make the necessary changes in NCS documentation. The documentation changes are in a separate commit from the code changes because they require manual cleanup in RST tables after doing a scripted search and replace. Signed-off-by: Martí Bolívar --- applications/asset_tracker/README.rst | 2 +- applications/asset_tracker_v2/README.rst | 8 ++++---- applications/pelion_client/README.rst | 2 +- .../serial_lte_modem/doc/Generic_AT_commands.rst | 4 ++-- applications/serial_lte_modem/doc/slm_description.rst | 2 +- doc/nrf/app_boards.rst | 2 +- doc/nrf/app_power_opt.rst | 4 ++-- doc/nrf/gs_programming.rst | 2 +- .../includes/boardname_tables/sample_boardnames.txt | 10 +++++----- doc/nrf/includes/sample_board_rows.txt | 4 ++-- doc/nrf/includes/tfm.txt | 2 +- doc/nrf/ug_nrf9160.rst | 8 ++++---- doc/nrf/ug_tfm.rst | 4 ++-- samples/bootloader/README.rst | 2 +- samples/crypto/aes_cbc/README.rst | 2 +- samples/crypto/aes_ccm/README.rst | 2 +- samples/crypto/aes_ctr/README.rst | 2 +- samples/crypto/aes_gcm/README.rst | 2 +- samples/crypto/chachapoly/README.rst | 2 +- samples/crypto/ecdh/README.rst | 2 +- samples/crypto/ecdsa/README.rst | 2 +- samples/crypto/hkdf/README.rst | 2 +- samples/crypto/hmac/README.rst | 2 +- samples/crypto/persistent_key_usage/README.rst | 2 +- samples/crypto/psa_tls/README.rst | 2 +- samples/crypto/rng/README.rst | 2 +- samples/crypto/rsa/README.rst | 2 +- samples/crypto/sha256/README.rst | 2 +- samples/edge_impulse/data_forwarder/README.rst | 2 +- samples/edge_impulse/wrapper/README.rst | 2 +- samples/event_manager/README.rst | 2 +- samples/nrf9160/agps/README.rst | 2 +- samples/nrf9160/at_client/README.rst | 2 +- samples/nrf9160/at_monitor/README.rst | 2 +- samples/nrf9160/at_monitor/sample.yaml | 4 ++-- samples/nrf9160/aws_iot/README.rst | 2 +- samples/nrf9160/azure_fota/README.rst | 2 +- samples/nrf9160/azure_iot_hub/README.rst | 2 +- samples/nrf9160/coap_client/README.rst | 2 +- samples/nrf9160/download/README.rst | 2 +- samples/nrf9160/fmfu_smp_svr/README.rst | 4 ++-- samples/nrf9160/gps/README.rst | 2 +- .../nrf9160/http_update/application_update/README.rst | 4 ++-- .../nrf9160/http_update/full_modem_update/README.rst | 4 ++-- .../nrf9160/http_update/modem_delta_update/README.rst | 4 ++-- samples/nrf9160/https_client/README.rst | 2 +- samples/nrf9160/lte_ble_gateway/README.rst | 4 ++-- samples/nrf9160/lwm2m_carrier/README.rst | 2 +- samples/nrf9160/lwm2m_client/README.rst | 2 +- samples/nrf9160/memfault/README.rst | 2 +- samples/nrf9160/modem_shell/README.rst | 8 ++++---- samples/nrf9160/mqtt_simple/README.rst | 4 ++-- samples/nrf9160/multicell_location/README.rst | 2 +- samples/nrf9160/pdn/README.rst | 2 +- samples/nrf9160/secure_services/README.rst | 2 +- samples/nrf9160/sms/README.rst | 2 +- samples/nrf9160/udp/README.rst | 2 +- samples/profiler/README.rst | 2 +- samples/spm/README.rst | 4 ++-- samples/tfm/tfm_hello_world/README.rst | 2 +- tests/crypto/README.rst | 2 +- 61 files changed, 86 insertions(+), 86 deletions(-) diff --git a/applications/asset_tracker/README.rst b/applications/asset_tracker/README.rst index 39afed97d938..b3583f86d961 100644 --- a/applications/asset_tracker/README.rst +++ b/applications/asset_tracker/README.rst @@ -101,7 +101,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/applications/asset_tracker_v2/README.rst b/applications/asset_tracker_v2/README.rst index 4d9efd83eb06..f61d97cef80c 100644 --- a/applications/asset_tracker_v2/README.rst +++ b/applications/asset_tracker_v2/README.rst @@ -214,7 +214,7 @@ The application supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt @@ -378,7 +378,7 @@ The following configuration files are available in the application folder: * :file:`prj.conf` - Configuration file common for all build targets * :file:`boards/thingy91_nrf9160ns.conf` - Configuration file specific for Thingy:91. This file is automatically merged with the :file:`prj.conf` file when you build for the ``thingy91_nrf9160ns`` build target. -* :file:`boards/nrf9160dk_nrf9160ns.conf` - Configuration file specific for nRF9160 DK. This file is automatically merged with the :file:`prj.conf` file when you build for the ``nrf9160dk_nrf9160ns`` build target. +* :file:`boards/nrf9160dk_nrf9160_ns.conf` - Configuration file specific for nRF9160 DK. This file is automatically merged with the :file:`prj.conf` file when you build for the ``nrf9160dk_nrf9160_ns`` build target. * :file:`overlay-low-power.conf` - Configuration file that achieves the lowest power consumption by disabling features that consume extra power like LED control and logging. * :file:`overlay-debug.conf` - Configuration file that adds additional verbose logging capabilities to the application * :file:`boards//led_state_def.h` - Header file that describes the LED behavior of the CAF LEDs module. @@ -415,9 +415,9 @@ Building with overlays To build with Kconfig overlay, it must be based to the build system, as shown in the following example: -``west build -b nrf9160dk_nrf9160ns -- -DOVERLAY_CONFIG=overlay-low-power.conf`` +``west build -b nrf9160dk_nrf9160_ns -- -DOVERLAY_CONFIG=overlay-low-power.conf`` -The above command will build for nRF9160 DK using the configurations found in :file:`overlay-low-power.conf`, in addition to the configurations found in :file:`prj_nrf9160dk_nrf9160ns.conf`. +The above command will build for nRF9160 DK using the configurations found in :file:`overlay-low-power.conf`, in addition to the configurations found in :file:`prj_nrf9160dk_nrf9160_ns.conf`. If some options are defined in both files, the options set in the overlay take precedence. Testing diff --git a/applications/pelion_client/README.rst b/applications/pelion_client/README.rst index 34908822f958..7e539b4a8315 100644 --- a/applications/pelion_client/README.rst +++ b/applications/pelion_client/README.rst @@ -354,7 +354,7 @@ The application supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns, nrf5340dk_nrf5340_cpuapp, nrf5340dk_nrf5340_cpuapp_ns, nrf52840dk_nrf52840 + :rows: nrf9160dk_nrf9160_ns, nrf5340dk_nrf5340_cpuapp, nrf5340dk_nrf5340_cpuapp_ns, nrf52840dk_nrf52840 The nRF Pelion Client application is configured to compile and run as a non-secure application on nRF91's and nRF5340's Cortex-M33. Therefore, it automatically includes the :ref:`secure_partition_manager` that prepares the required peripherals to be available for the application. diff --git a/applications/serial_lte_modem/doc/Generic_AT_commands.rst b/applications/serial_lte_modem/doc/Generic_AT_commands.rst index fbe41a47d828..2bdf0acdf835 100644 --- a/applications/serial_lte_modem/doc/Generic_AT_commands.rst +++ b/applications/serial_lte_modem/doc/Generic_AT_commands.rst @@ -119,8 +119,8 @@ Power saving #XSLEEP The ``#XSLEEP`` command makes the nRF91 development kit go into idle or sleep mode. If you are going to do power measurements on the nRF9160 DK while running the SLM application it is recommended to disable unused peripherals. -By default UART2 is enabled in the :file:`nrf9160dk_nrf9160ns.overlay` file so disable the UART2 by switching the status. -Change the line ``status = "okay"`` to ``status = "disabled"`` and then save the :file:`nrf9160dk_nrf9160ns.overlay`` file to make sure you will get the expected power consumption numbers when doing the measurements. +By default UART2 is enabled in the :file:`nrf9160dk_nrf9160_ns.overlay` file so disable the UART2 by switching the status. +Change the line ``status = "okay"`` to ``status = "disabled"`` and then save the :file:`nrf9160dk_nrf9160_ns.overlay`` file to make sure you will get the expected power consumption numbers when doing the measurements. Set command ----------- diff --git a/applications/serial_lte_modem/doc/slm_description.rst b/applications/serial_lte_modem/doc/slm_description.rst index a415d715d9b4..fd4a6a2f07ae 100644 --- a/applications/serial_lte_modem/doc/slm_description.rst +++ b/applications/serial_lte_modem/doc/slm_description.rst @@ -18,7 +18,7 @@ The application supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/doc/nrf/app_boards.rst b/doc/nrf/app_boards.rst index b8bc970368ea..bef003b61118 100644 --- a/doc/nrf/app_boards.rst +++ b/doc/nrf/app_boards.rst @@ -56,7 +56,7 @@ Also see the :ref:`zephyr:boards` section in the Zephyr documentation. +-------------------+------------+-----------------------------------------------------------------+---------------------------------------+ | nRF9160 DK | PCA10090 | :ref:`nrf9160dk_nrf9160 ` | ``nrf9160dk_nrf9160`` | | | | | | -| | | | ``nrf9160dk_nrf9160ns`` | +| | | | ``nrf9160dk_nrf9160_ns`` | | | +-----------------------------------------------------------------+---------------------------------------+ | | | :ref:`nrf9160dk_nrf52840 ` | ``nrf9160dk_nrf52840`` | +-------------------+------------+-----------------------------------------------------------------+---------------------------------------+ diff --git a/doc/nrf/app_power_opt.rst b/doc/nrf/app_power_opt.rst index dc92699d8eb1..0efd91589e51 100644 --- a/doc/nrf/app_power_opt.rst +++ b/doc/nrf/app_power_opt.rst @@ -51,7 +51,7 @@ To disable serial output, you must change the project configuration associated w See :ref:`ug_nrf5340` and :ref:`ug_multi_image`. 1. Set the project configuration ``CONFIG_SERIAL`` to ``n`` irrespective of whether you are building the sample for the secure or non-secure build targets. -#. For the non-secure build target (``nrf9160dk_nrf9160ns``), ensure that serial logging is also disabled in :ref:`secure_partition_manager`. To disable serial logging in Secure Partition Manager, complete the following steps: +#. For the non-secure build target (``nrf9160dk_nrf9160_ns``), ensure that serial logging is also disabled in :ref:`secure_partition_manager`. To disable serial logging in Secure Partition Manager, complete the following steps: a. Add a :file:`spm.conf` file in the project directory with the following content: @@ -78,7 +78,7 @@ The average current reduces to 4 µA, which implies 14 years of battery life on For a similar configuration, see the :ref:`udp` sample, which transmits UDP packets to an LTE network using an nRF9160 DK. You can use the sample to characterize the current consumption of the nRF9160 SiP. -It is optimized for low power operation on the ``nrf9160dk_nrf9160ns`` build target without any modifications. +It is optimized for low power operation on the ``nrf9160dk_nrf9160_ns`` build target without any modifications. Idle current due to other peripherals ************************************* diff --git a/doc/nrf/gs_programming.rst b/doc/nrf/gs_programming.rst index 78990de81c25..dd7b5d2e4f83 100644 --- a/doc/nrf/gs_programming.rst +++ b/doc/nrf/gs_programming.rst @@ -73,7 +73,7 @@ Complete the following steps to build |NCS| projects with SES after :ref:`instal .. build_SES_projimport_open_end - The following figure shows an example configuration for the Asset Tracker application built for the ``nrf9160dk_nrf9160ns`` build target: + The following figure shows an example configuration for the Asset Tracker application built for the ``nrf9160dk_nrf9160_ns`` build target: .. figure:: images/ses_config.png :alt: Opening the Asset Tracker project diff --git a/doc/nrf/includes/boardname_tables/sample_boardnames.txt b/doc/nrf/includes/boardname_tables/sample_boardnames.txt index 61e1587f1078..83e08a365162 100644 --- a/doc/nrf/includes/boardname_tables/sample_boardnames.txt +++ b/doc/nrf/includes/boardname_tables/sample_boardnames.txt @@ -76,7 +76,7 @@ LTE Sensor Gateway, LwM2M carrier, LwM2M Client, Simple MQTT, Secure Services S +--------------------------------+-----------+------------------------------------------------+-------------------------------+ |Hardware platforms |PCA |Board name |Build target | +================================+===========+================================================+===============================+ -|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160ns`` | +|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160_ns`` | +--------------------------------+-----------+------------------------------------------------+-------------------------------+ .. set5_end @@ -90,7 +90,7 @@ Set used by nRF9160 samples (Cloud Client, nRF Cloud A-GPS) and application (Ass +================================+===========+================================================+==============================+ |:ref:`Thingy:91 ` |PCA20035 |thingy91_nrf9160 |``thingy91_nrf9160ns`` | +--------------------------------+-----------+------------------------------------------------+------------------------------+ -|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160ns`` | +|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160_ns`` | +--------------------------------+-----------+------------------------------------------------+------------------------------+ .. set6_end @@ -128,7 +128,7 @@ Set used by samples (Event Manager, Profiler, PPI Trace) +--------------------------------+-----------+------------------------------------------------+-------------------------------+ |Hardware platforms |PCA |Board name |Build target | +================================+===========+================================================+===============================+ -|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160ns`` | +|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160_ns`` | +--------------------------------+-----------+------------------------------------------------+-------------------------------+ |:ref:`nRF52840 DK ` |PCA10056 |:ref:`nrf52840dk_nrf52840 `|``nrf52840dk_nrf52840`` | +--------------------------------+-----------+------------------------------------------------+-------------------------------+ @@ -226,7 +226,7 @@ Set used by sample (Immutable bootloader) +--------------------------------+-----------+------------------------------------------------+--------------------------------+ |Hardware platforms |PCA |Board name |Build target | +================================+===========+================================================+================================+ -|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160ns`` | +|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160_ns`` | +--------------------------------+-----------+------------------------------------------------+--------------------------------+ |:ref:`nRF5340 DK ` |PCA10095 |:ref:`nrf5340dk_nrf5340 ` |``nrf5340dk_nrf5340_cpuapp`` | | | | | | @@ -258,7 +258,7 @@ Set used by Tests (Crypto) +--------------------------------+-----------+------------------------------------------------+--------------------------------+ |Hardware platforms |PCA |Board name |Build target | +================================+===========+================================================+================================+ -|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160ns`` | +|:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160_ns`` | +--------------------------------+-----------+------------------------------------------------+--------------------------------+ |:ref:`nRF52840 DK ` |PCA10056 |:ref:`nrf52840dk_nrf52840 `|``nrf52840dk_nrf52840`` | +--------------------------------+-----------+------------------------------------------------+--------------------------------+ diff --git a/doc/nrf/includes/sample_board_rows.txt b/doc/nrf/includes/sample_board_rows.txt index 1c7b58efee56..cf351a720b2a 100644 --- a/doc/nrf/includes/sample_board_rows.txt +++ b/doc/nrf/includes/sample_board_rows.txt @@ -18,9 +18,9 @@ | :ref:`nRF9160 DK ` | PCA10090 | :ref:`nrf9160dk_nrf9160 ` | ``nrf9160dk_nrf9160`` | -.. nrf9160dk_nrf9160ns +.. nrf9160dk_nrf9160_ns -| :ref:`nRF9160 DK ` | PCA10090 | :ref:`nrf9160dk_nrf9160 ` | ``nrf9160dk_nrf9160ns`` | +| :ref:`nRF9160 DK ` | PCA10090 | :ref:`nrf9160dk_nrf9160 ` | ``nrf9160dk_nrf9160_ns`` | .. nrf9160dk_nrf52840 diff --git a/doc/nrf/includes/tfm.txt b/doc/nrf/includes/tfm.txt index 924bc9ecf1de..1563ab77c964 100644 --- a/doc/nrf/includes/tfm.txt +++ b/doc/nrf/includes/tfm.txt @@ -1,2 +1,2 @@ -When built for nrf5340dk_nrf5340_cpuapp_ns and nrf9160dk_nrf9160ns targets, the sample is configured to compile and run as a non-secure application. +When built for nrf5340dk_nrf5340_cpuapp_ns and nrf9160dk_nrf9160_ns targets, the sample is configured to compile and run as a non-secure application. Therefore, it automatically includes :ref:`TF-M ` that prepares the required peripherals to be available for the application. diff --git a/doc/nrf/ug_nrf9160.rst b/doc/nrf/ug_nrf9160.rst index 9049c5ad1ed1..1bbc7dd7e141 100644 --- a/doc/nrf/ug_nrf9160.rst +++ b/doc/nrf/ug_nrf9160.rst @@ -39,7 +39,7 @@ The secure bootloader chain starts the :ref:`nrf9160_ug_secure_partition_manager In Zephyr, :ref:`zephyr:nrf9160dk_nrf9160` is divided into two different build targets: * ``nrf9160dk_nrf9160`` for firmware in the secure domain -* ``nrf9160dk_nrf9160ns`` for firmware in the non-secure domain +* ``nrf9160dk_nrf9160_ns`` for firmware in the non-secure domain Make sure to select a suitable build target when building your application. @@ -61,7 +61,7 @@ All nRF9160 samples require the :ref:`secure_partition_manager` sample. It provides a reference implementation of a Secure Partition Manager firmware. This firmware is required to set up the nRF9160 DK so that it can run user applications in the non-secure domain. -The Secure Partition Manager sample is automatically included in the build for the ``nrf9160dk_nrf9160ns`` build target. +The Secure Partition Manager sample is automatically included in the build for the ``nrf9160dk_nrf9160_ns`` build target. To disable the automatic inclusion of the Secure Partition Manager sample, set the option :kconfig:`CONFIG_SPM` to "n" in the project configuration. Trusted Firmware-M (TF-M) support @@ -80,7 +80,7 @@ Application ----------- The user application runs in the non-secure domain. -Therefore, it must be built for the ``nrf9160dk_nrf9160ns`` build target. +Therefore, it must be built for the ``nrf9160dk_nrf9160_ns`` build target. The application image might require other images to be present. Depending on the configuration, all these images can be built at the same time in a :ref:`multi-image build `. @@ -328,7 +328,7 @@ For example, when building a non-secure application for nRF9160 DK v1.0.0, use ` When building with |SES|, specify the board revision as additional CMake option (see :ref:`cmake_options` for instructions). For example, for nRF9160 DK v1.0.0, add the following CMake option:: - -DBOARD=nrf9160dk_nrf9160ns@1.0.0 + -DBOARD=nrf9160dk_nrf9160_ns@1.0.0 See :ref:`zephyr:application_board_version` and :ref:`zephyr:nrf9160dk_additional_hardware` for more information. diff --git a/doc/nrf/ug_tfm.rst b/doc/nrf/ug_tfm.rst index 2c2a7d162c35..34b05fb63fec 100644 --- a/doc/nrf/ug_tfm.rst +++ b/doc/nrf/ug_tfm.rst @@ -46,9 +46,9 @@ You must build TF-M using a non-secure build target. The following targets are currently supported: * ``nrf5340dk_nrf5340_cpuapp_ns`` -* ``nrf9160dk_nrf9160ns`` +* ``nrf9160dk_nrf9160_ns`` -When building for ``nrf9160dk_nrf9160ns``, UART1 must be disabled in the non-secure application, because it is used by the TF-M secure application. +When building for ``nrf9160dk_nrf9160_ns``, UART1 must be disabled in the non-secure application, because it is used by the TF-M secure application. Otherwise, the non-secure application will fail to run. The recommended way to do this is to copy the .overlay file from the :ref:`tfm_hello_world` sample. diff --git a/samples/bootloader/README.rst b/samples/bootloader/README.rst index 8c0cea4bc9cd..fe2ff28969e4 100644 --- a/samples/bootloader/README.rst +++ b/samples/bootloader/README.rst @@ -221,7 +221,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns, nrf5340dk_nrf5340_cpuapp_and_cpuappns, nrf52840dk_nrf52840, nrf52dk_nrf52832 + :rows: nrf9160dk_nrf9160_ns, nrf5340dk_nrf5340_cpuapp_and_cpuappns, nrf52840dk_nrf52840, nrf52dk_nrf52832 .. _bootloader_build_and_run: diff --git a/samples/crypto/aes_cbc/README.rst b/samples/crypto/aes_cbc/README.rst index 9af69103930e..d19b14ef602b 100644 --- a/samples/crypto/aes_cbc/README.rst +++ b/samples/crypto/aes_cbc/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/aes_ccm/README.rst b/samples/crypto/aes_ccm/README.rst index 9c9f2e79e0c6..4476b233f279 100644 --- a/samples/crypto/aes_ccm/README.rst +++ b/samples/crypto/aes_ccm/README.rst @@ -37,7 +37,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/aes_ctr/README.rst b/samples/crypto/aes_ctr/README.rst index f5f0f6ded0c7..bac771021909 100644 --- a/samples/crypto/aes_ctr/README.rst +++ b/samples/crypto/aes_ctr/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/aes_gcm/README.rst b/samples/crypto/aes_gcm/README.rst index e91445410fe2..15aba0ac24e3 100644 --- a/samples/crypto/aes_gcm/README.rst +++ b/samples/crypto/aes_gcm/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/chachapoly/README.rst b/samples/crypto/chachapoly/README.rst index 1f759fb4df7b..fdfdcb22cab0 100644 --- a/samples/crypto/chachapoly/README.rst +++ b/samples/crypto/chachapoly/README.rst @@ -37,7 +37,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/ecdh/README.rst b/samples/crypto/ecdh/README.rst index 9683d3a9eabf..b6f97369d42b 100644 --- a/samples/crypto/ecdh/README.rst +++ b/samples/crypto/ecdh/README.rst @@ -32,7 +32,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/ecdsa/README.rst b/samples/crypto/ecdsa/README.rst index 8e11a3490ad4..b4015cbdec6a 100644 --- a/samples/crypto/ecdsa/README.rst +++ b/samples/crypto/ecdsa/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/hkdf/README.rst b/samples/crypto/hkdf/README.rst index ff1060ddcf6c..a890d3834479 100644 --- a/samples/crypto/hkdf/README.rst +++ b/samples/crypto/hkdf/README.rst @@ -32,7 +32,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/hmac/README.rst b/samples/crypto/hmac/README.rst index 257915d3b93b..0e042624f68c 100644 --- a/samples/crypto/hmac/README.rst +++ b/samples/crypto/hmac/README.rst @@ -34,7 +34,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/persistent_key_usage/README.rst b/samples/crypto/persistent_key_usage/README.rst index d5ff6f23de9e..edb36e879dd3 100644 --- a/samples/crypto/persistent_key_usage/README.rst +++ b/samples/crypto/persistent_key_usage/README.rst @@ -37,7 +37,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/psa_tls/README.rst b/samples/crypto/psa_tls/README.rst index 07b69254f5ce..e0dcc1533d28 100644 --- a/samples/crypto/psa_tls/README.rst +++ b/samples/crypto/psa_tls/README.rst @@ -113,7 +113,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf9160dk_nrf9160ns + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf9160dk_nrf9160_ns The sample requires a `TAP adapter`_ to perform the TLS handshake. This functionality is currently only supported in Linux. diff --git a/samples/crypto/rng/README.rst b/samples/crypto/rng/README.rst index 5109725f3fde..f4f08aa094e8 100644 --- a/samples/crypto/rng/README.rst +++ b/samples/crypto/rng/README.rst @@ -25,7 +25,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/rsa/README.rst b/samples/crypto/rsa/README.rst index 92c74f828830..4eb77d8df30f 100644 --- a/samples/crypto/rsa/README.rst +++ b/samples/crypto/rsa/README.rst @@ -36,7 +36,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/crypto/sha256/README.rst b/samples/crypto/sha256/README.rst index be710958e1e4..8174b90d222e 100644 --- a/samples/crypto/sha256/README.rst +++ b/samples/crypto/sha256/README.rst @@ -28,7 +28,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf5340dk_nrf5340_cpuapp, nrf9160dk_nrf9160_ns, nrf9160dk_nrf9160, nrf52840dk_nrf52840 .. include:: /includes/tfm.txt diff --git a/samples/edge_impulse/data_forwarder/README.rst b/samples/edge_impulse/data_forwarder/README.rst index e58c553b288d..dae2903218ac 100644 --- a/samples/edge_impulse/data_forwarder/README.rst +++ b/samples/edge_impulse/data_forwarder/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns, nrf52dk_nrf52832, nrf52840dk_nrf52840 + :rows: nrf9160dk_nrf9160_ns, nrf52dk_nrf52832, nrf52840dk_nrf52840 Overview ******** diff --git a/samples/edge_impulse/wrapper/README.rst b/samples/edge_impulse/wrapper/README.rst index 28b3665a516f..37f568d33e28 100644 --- a/samples/edge_impulse/wrapper/README.rst +++ b/samples/edge_impulse/wrapper/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns, nrf52840dk_nrf52840, nrf52dk_nrf52832 + :rows: nrf9160dk_nrf9160_ns, nrf52840dk_nrf52840, nrf52dk_nrf52832 Overview ******** diff --git a/samples/event_manager/README.rst b/samples/event_manager/README.rst index 106a78e9466d..1188291db264 100644 --- a/samples/event_manager/README.rst +++ b/samples/event_manager/README.rst @@ -38,7 +38,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns, nrf52dk_nrf52832, nrf52840dk_nrf52840 + :rows: nrf9160dk_nrf9160_ns, nrf52dk_nrf52832, nrf52840dk_nrf52840 Building and running diff --git a/samples/nrf9160/agps/README.rst b/samples/nrf9160/agps/README.rst index 60e5bc46d459..4d639216103a 100644 --- a/samples/nrf9160/agps/README.rst +++ b/samples/nrf9160/agps/README.rst @@ -18,7 +18,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns The sample also requires an nRF Connect for Cloud account. diff --git a/samples/nrf9160/at_client/README.rst b/samples/nrf9160/at_client/README.rst index 41d8618e6a2d..fb5a02d5899c 100644 --- a/samples/nrf9160/at_client/README.rst +++ b/samples/nrf9160/at_client/README.rst @@ -28,7 +28,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/at_monitor/README.rst b/samples/nrf9160/at_monitor/README.rst index 1e0dc3c93c8f..9b4cca1e1922 100644 --- a/samples/nrf9160/at_monitor/README.rst +++ b/samples/nrf9160/at_monitor/README.rst @@ -16,7 +16,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/at_monitor/sample.yaml b/samples/nrf9160/at_monitor/sample.yaml index 6014b5cdc1c8..be6611003857 100644 --- a/samples/nrf9160/at_monitor/sample.yaml +++ b/samples/nrf9160/at_monitor/sample.yaml @@ -3,7 +3,7 @@ sample: tests: samples.nrf9160.at_monitor: build_only: true - platform_allow: nrf9160dk_nrf9160ns + platform_allow: nrf9160dk_nrf9160_ns integration_platforms: - - nrf9160dk_nrf9160ns + - nrf9160dk_nrf9160_ns tags: ci_build diff --git a/samples/nrf9160/aws_iot/README.rst b/samples/nrf9160/aws_iot/README.rst index 28167b053dac..69fbdbaefa02 100644 --- a/samples/nrf9160/aws_iot/README.rst +++ b/samples/nrf9160/aws_iot/README.rst @@ -33,7 +33,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/azure_fota/README.rst b/samples/nrf9160/azure_fota/README.rst index 26684473f356..7733fe067dcb 100644 --- a/samples/nrf9160/azure_fota/README.rst +++ b/samples/nrf9160/azure_fota/README.rst @@ -16,7 +16,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns The sample also requires an Azure IoT Hub instance, and optionally an `Azure IoT Hub Device Provisioning Service (DPS)`_ instance, if the device is not already registered with the IoT hub. diff --git a/samples/nrf9160/azure_iot_hub/README.rst b/samples/nrf9160/azure_iot_hub/README.rst index ad84eefebd2f..5019b4c3b446 100644 --- a/samples/nrf9160/azure_iot_hub/README.rst +++ b/samples/nrf9160/azure_iot_hub/README.rst @@ -18,7 +18,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/coap_client/README.rst b/samples/nrf9160/coap_client/README.rst index 17792dcb9e91..2c7a32507bb0 100644 --- a/samples/nrf9160/coap_client/README.rst +++ b/samples/nrf9160/coap_client/README.rst @@ -34,7 +34,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns The sample also requires a public CoAP server IP address or URL available on the internet. diff --git a/samples/nrf9160/download/README.rst b/samples/nrf9160/download/README.rst index 490befa884a6..4e86fb89ca48 100644 --- a/samples/nrf9160/download/README.rst +++ b/samples/nrf9160/download/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/fmfu_smp_svr/README.rst b/samples/nrf9160/fmfu_smp_svr/README.rst index 89df9b36ace2..b1904bb5a7ed 100644 --- a/samples/nrf9160/fmfu_smp_svr/README.rst +++ b/samples/nrf9160/fmfu_smp_svr/README.rst @@ -18,7 +18,7 @@ This sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt @@ -48,7 +48,7 @@ For example, when building on the command line, add the UART overlay for nRF9160 .. code-block:: console - west build -b nrf9160dk_nrf9160ns -- -DDTC_OVERLAY_FILE=uart.overlay + west build -b nrf9160dk_nrf9160_ns -- -DDTC_OVERLAY_FILE=uart.overlay Testing ======= diff --git a/samples/nrf9160/gps/README.rst b/samples/nrf9160/gps/README.rst index 8430d95b3016..2dc1821e3468 100644 --- a/samples/nrf9160/gps/README.rst +++ b/samples/nrf9160/gps/README.rst @@ -43,7 +43,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns The sample can be optionally used with the SUPL Client library (for details on download, see :ref:`supl_client`). diff --git a/samples/nrf9160/http_update/application_update/README.rst b/samples/nrf9160/http_update/application_update/README.rst index f1343afc3f9c..fdf57984ac9d 100644 --- a/samples/nrf9160/http_update/application_update/README.rst +++ b/samples/nrf9160/http_update/application_update/README.rst @@ -27,7 +27,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns The sample also requires a signed firmware image that is available for download from an HTTP server. This image is automatically generated when building the application. @@ -41,7 +41,7 @@ Building and running .. include:: /includes/build_and_run.txt -The sample is built as a non-secure firmware image for the nrf9160dk_nrf9160ns build target. +The sample is built as a non-secure firmware image for the nrf9160dk_nrf9160_ns build target. Because of this, it automatically includes the :ref:`secure_partition_manager`. The sample also uses MCUboot, which is automatically built and merged into the final HEX file when building the sample. diff --git a/samples/nrf9160/http_update/full_modem_update/README.rst b/samples/nrf9160/http_update/full_modem_update/README.rst index cf0c00bed58b..08b7c864eacb 100644 --- a/samples/nrf9160/http_update/full_modem_update/README.rst +++ b/samples/nrf9160/http_update/full_modem_update/README.rst @@ -33,7 +33,7 @@ The sample supports the following development kit, version 0.14.0 or higher: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt @@ -44,7 +44,7 @@ Building and running .. include:: /includes/build_and_run.txt -The sample is built as a non-secure firmware image for the ``nrf9160dk_nrf9160ns`` build target. +The sample is built as a non-secure firmware image for the ``nrf9160dk_nrf9160_ns`` build target. Because of this, it automatically includes the :ref:`secure_partition_manager`. You can customize the firmware files downloaded by the sample through the following Kconfig options in the :file:`prj.conf` file: diff --git a/samples/nrf9160/http_update/modem_delta_update/README.rst b/samples/nrf9160/http_update/modem_delta_update/README.rst index 2bdf5c8dcec7..21d91f7438aa 100644 --- a/samples/nrf9160/http_update/modem_delta_update/README.rst +++ b/samples/nrf9160/http_update/modem_delta_update/README.rst @@ -26,7 +26,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt @@ -38,7 +38,7 @@ Building and running .. include:: /includes/build_and_run.txt -The sample is built as a non-secure firmware image for the ``nrf9160dk_nrf9160ns`` build target. +The sample is built as a non-secure firmware image for the ``nrf9160dk_nrf9160_ns`` build target. Because of this, it automatically includes the :ref:`secure_partition_manager`. Testing diff --git a/samples/nrf9160/https_client/README.rst b/samples/nrf9160/https_client/README.rst index 151558d4650b..b1d072f7fdc1 100644 --- a/samples/nrf9160/https_client/README.rst +++ b/samples/nrf9160/https_client/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/lte_ble_gateway/README.rst b/samples/nrf9160/lte_ble_gateway/README.rst index 99e268d98b73..1764ec707ed6 100644 --- a/samples/nrf9160/lte_ble_gateway/README.rst +++ b/samples/nrf9160/lte_ble_gateway/README.rst @@ -31,7 +31,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns The sample also requires a `Nordic Thingy:52`_. @@ -77,7 +77,7 @@ After programming the board controller, you must program the main controller wit You can program the main controller as follows: 1. Set the **SW5** switch, marked as *debug/prog*, in the **NRF91** position. -#. Build the LTE Sensor Gateway sample (this sample) for the nrf9160dk_nrf9160ns build target and program the main controller with it. +#. Build the LTE Sensor Gateway sample (this sample) for the nrf9160dk_nrf9160_ns build target and program the main controller with it. #. Verify that the program was successful. To do so, use a terminal emulator, like PuTTY, to connect to the first serial port and check the output. See :ref:`putty` for the required settings. diff --git a/samples/nrf9160/lwm2m_carrier/README.rst b/samples/nrf9160/lwm2m_carrier/README.rst index f25f3d0d39ab..64482f796d74 100644 --- a/samples/nrf9160/lwm2m_carrier/README.rst +++ b/samples/nrf9160/lwm2m_carrier/README.rst @@ -16,7 +16,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/lwm2m_client/README.rst b/samples/nrf9160/lwm2m_client/README.rst index 0c401767367e..73022f098a04 100644 --- a/samples/nrf9160/lwm2m_client/README.rst +++ b/samples/nrf9160/lwm2m_client/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns The sample also requires an LwM2M server URL address available on the internet. For this sample, the URL address mentioned on the `Leshan Demo Server`_ page is used. diff --git a/samples/nrf9160/memfault/README.rst b/samples/nrf9160/memfault/README.rst index e2fc09e22c31..2012a8326462 100644 --- a/samples/nrf9160/memfault/README.rst +++ b/samples/nrf9160/memfault/README.rst @@ -18,7 +18,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns Before using the Memfault platform, you must register an account in `Memfault`_ and a set up a project according to the instructions in `Memfault documentation `_. diff --git a/samples/nrf9160/modem_shell/README.rst b/samples/nrf9160/modem_shell/README.rst index b6fdb4b56504..dfeea8b6f247 100644 --- a/samples/nrf9160/modem_shell/README.rst +++ b/samples/nrf9160/modem_shell/README.rst @@ -346,7 +346,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns Configuration ************* @@ -430,7 +430,7 @@ PPP support To build the MoSh sample with PPP/dial up support for Windows, use the ``-DOVERLAY_CONFIG=overlay-ppp.conf`` option. For example: -``west build -p -b nrf9160dk_nrf9160ns -d build -- -DOVERLAY_CONFIG=overlay-ppp.conf`` +``west build -p -b nrf9160dk_nrf9160_ns -d build -- -DOVERLAY_CONFIG=overlay-ppp.conf`` See :ref:`cmake_options` for more instructions on how to add this option. @@ -440,7 +440,7 @@ Application FOTA support To build the MoSh sample with application FOTA support, use the ``-DOVERLAY_CONFIG=overlay-app_fota.conf`` option. For example: -``west build -p -b nrf9160dk_nrf9160ns -d build -- -DOVERLAY_CONFIG=overlay-app_fota.conf`` +``west build -p -b nrf9160dk_nrf9160_ns -d build -- -DOVERLAY_CONFIG=overlay-app_fota.conf`` See :ref:`cmake_options` for more instructions on how to add this option. @@ -450,7 +450,7 @@ LwM2M carrier library support To build the MoSh sample with LwM2M carrier library support, use the ``-DOVERLAY_CONFIG=overlay-lwm2m_carrier.conf`` option. For example: -``west build -p -b nrf9160dk_nrf9160ns -d build -- -DOVERLAY_CONFIG=overlay-lwm2m_carrier.conf`` +``west build -p -b nrf9160dk_nrf9160_ns -d build -- -DOVERLAY_CONFIG=overlay-lwm2m_carrier.conf`` See :ref:`cmake_options` for more instructions on how to add this option. diff --git a/samples/nrf9160/mqtt_simple/README.rst b/samples/nrf9160/mqtt_simple/README.rst index c6df99e21ea9..7aea2f370227 100644 --- a/samples/nrf9160/mqtt_simple/README.rst +++ b/samples/nrf9160/mqtt_simple/README.rst @@ -16,7 +16,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns Additionally, the sample supports :ref:`qemu_x86`. @@ -100,7 +100,7 @@ For example, when building on the command line, you can build the sample with th .. code-block:: console - west build -b nrf9160dk_nrf9160ns -- -DOVERLAY_CONFIG=overlay-tls.conf + west build -b nrf9160dk_nrf9160_ns -- -DOVERLAY_CONFIG=overlay-tls.conf .. note:: The CA certificate for the default MQTT broker is included in the project and automatically provisioned after boot if the sample is built with the TLS configuration. diff --git a/samples/nrf9160/multicell_location/README.rst b/samples/nrf9160/multicell_location/README.rst index 3eb2588ecb30..3ad7b321f98f 100644 --- a/samples/nrf9160/multicell_location/README.rst +++ b/samples/nrf9160/multicell_location/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/pdn/README.rst b/samples/nrf9160/pdn/README.rst index eb4687e51edd..aa9965febb8f 100644 --- a/samples/nrf9160/pdn/README.rst +++ b/samples/nrf9160/pdn/README.rst @@ -16,7 +16,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/secure_services/README.rst b/samples/nrf9160/secure_services/README.rst index d692e0f9f2f9..1edc46f0d130 100644 --- a/samples/nrf9160/secure_services/README.rst +++ b/samples/nrf9160/secure_services/README.rst @@ -23,7 +23,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/sms/README.rst b/samples/nrf9160/sms/README.rst index fe68c0d5876f..9844fd4948b2 100644 --- a/samples/nrf9160/sms/README.rst +++ b/samples/nrf9160/sms/README.rst @@ -30,7 +30,7 @@ The sample supports the following development kit: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns + :rows: nrf9160dk_nrf9160_ns Configuration diff --git a/samples/nrf9160/udp/README.rst b/samples/nrf9160/udp/README.rst index da3ed93a3ca6..9a376f9ee620 100644 --- a/samples/nrf9160/udp/README.rst +++ b/samples/nrf9160/udp/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160ns + :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns Additionally, it supports :ref:`qemu_x86`. diff --git a/samples/profiler/README.rst b/samples/profiler/README.rst index 80d56b24de0d..62a1fff78acc 100644 --- a/samples/profiler/README.rst +++ b/samples/profiler/README.rst @@ -31,7 +31,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns, nrf52840dk_nrf52840, nrf52dk_nrf52832 + :rows: nrf9160dk_nrf9160_ns, nrf52840dk_nrf52840, nrf52dk_nrf52832 Building and running ******************** diff --git a/samples/spm/README.rst b/samples/spm/README.rst index d37454628a3a..eae92ba6ca73 100644 --- a/samples/spm/README.rst +++ b/samples/spm/README.rst @@ -42,12 +42,12 @@ Requirements for the application firmware For more details, see the partition configuration file for the chosen board (e.g. `nrf9160dk_nrf9160_partition_conf.dts`_ for the nRF9160 DK). Note that if you build your application firmware with the |NCS|, this requirement is automatically fulfilled. -* The application firmware must be built as a non-secure firmware for the build target (e.g. nrf9160dk_nrf9160ns for the nRF9160 DK). +* The application firmware must be built as a non-secure firmware for the build target (e.g. nrf9160dk_nrf9160_ns for the nRF9160 DK). Automatic building of SPM ========================= -The sample is automatically built by the non-secure applications when the non-secure build target is used (e.g. nrf9160dk_nrf9160ns). +The sample is automatically built by the non-secure applications when the non-secure build target is used (e.g. nrf9160dk_nrf9160_ns). However, it is not a part of the non-secure application. Instead of programming SPM and the non-secure application at the same time, you might want to program them individually. diff --git a/samples/tfm/tfm_hello_world/README.rst b/samples/tfm/tfm_hello_world/README.rst index e6fce25c746e..e60e34cfddeb 100644 --- a/samples/tfm/tfm_hello_world/README.rst +++ b/samples/tfm/tfm_hello_world/README.rst @@ -22,7 +22,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf9160dk_nrf9160ns + :rows: nrf5340dk_nrf5340_cpuapp_ns, nrf9160dk_nrf9160_ns Building and Running ******************** diff --git a/tests/crypto/README.rst b/tests/crypto/README.rst index 7812195a1c29..58a15fb02045 100644 --- a/tests/crypto/README.rst +++ b/tests/crypto/README.rst @@ -129,7 +129,7 @@ The tests support the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf9160dk_nrf9160ns, nrf52840dk_nrf52840 + :rows: nrf9160dk_nrf9160_ns, nrf52840dk_nrf52840 .. note:: Nordic devices such as nRF51, nRF52810, or nRF52811 cannot run the full test suite because of limited flash capacity. From e21053739f1c970bf799299bab73b2f40b5fc4da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 9 Aug 2021 12:46:43 -0700 Subject: [PATCH 096/126] doc: thingy91_nrf9160: rename non-secure target MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Document the changes related to thingy91_nrf9160ns being renamed to thingy91_nrf9160_ns in NCS. Signed-off-by: Martí Bolívar --- applications/asset_tracker/README.rst | 2 +- applications/asset_tracker_v2/README.rst | 4 +-- doc/nrf/app_boards.rst | 2 +- .../boardname_tables/sample_boardnames.txt | 4 +-- doc/nrf/includes/sample_board_rows.txt | 4 +-- doc/nrf/known_issues.rst | 4 +-- doc/nrf/ug_thingy91.rst | 26 +++++++++---------- samples/nrf9160/agps/README.rst | 2 +- samples/nrf9160/aws_iot/README.rst | 2 +- samples/nrf9160/azure_fota/README.rst | 2 +- samples/nrf9160/azure_iot_hub/README.rst | 2 +- samples/nrf9160/memfault/README.rst | 2 +- samples/nrf9160/multicell_location/README.rst | 2 +- samples/nrf9160/udp/README.rst | 2 +- samples/sensor/bh1749/README.rst | 2 +- 15 files changed, 31 insertions(+), 31 deletions(-) diff --git a/applications/asset_tracker/README.rst b/applications/asset_tracker/README.rst index b3583f86d961..5a63f92941af 100644 --- a/applications/asset_tracker/README.rst +++ b/applications/asset_tracker/README.rst @@ -101,7 +101,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/applications/asset_tracker_v2/README.rst b/applications/asset_tracker_v2/README.rst index f61d97cef80c..4a4289b4ab94 100644 --- a/applications/asset_tracker_v2/README.rst +++ b/applications/asset_tracker_v2/README.rst @@ -214,7 +214,7 @@ The application supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt @@ -377,7 +377,7 @@ The application contains examples of Kconfig overlays. The following configuration files are available in the application folder: * :file:`prj.conf` - Configuration file common for all build targets -* :file:`boards/thingy91_nrf9160ns.conf` - Configuration file specific for Thingy:91. This file is automatically merged with the :file:`prj.conf` file when you build for the ``thingy91_nrf9160ns`` build target. +* :file:`boards/thingy91_nrf9160_ns.conf` - Configuration file specific for Thingy:91. This file is automatically merged with the :file:`prj.conf` file when you build for the ``thingy91_nrf9160_ns`` build target. * :file:`boards/nrf9160dk_nrf9160_ns.conf` - Configuration file specific for nRF9160 DK. This file is automatically merged with the :file:`prj.conf` file when you build for the ``nrf9160dk_nrf9160_ns`` build target. * :file:`overlay-low-power.conf` - Configuration file that achieves the lowest power consumption by disabling features that consume extra power like LED control and logging. * :file:`overlay-debug.conf` - Configuration file that adds additional verbose logging capabilities to the application diff --git a/doc/nrf/app_boards.rst b/doc/nrf/app_boards.rst index bef003b61118..b1aa1db44f31 100644 --- a/doc/nrf/app_boards.rst +++ b/doc/nrf/app_boards.rst @@ -90,7 +90,7 @@ The following boards are defined in the :file:`nrf/boards/arm/` folder. +-------------------+------------+----------------------------------------------------------+---------------------------------------+ | Thingy:91 | PCA20035 | :ref:`thingy91_nrf9160 ` | ``thingy91_nrf9160`` | | | | | | -| | | | ``thingy91_nrf9160ns`` | +| | | | ``thingy91_nrf9160_ns`` | | | +----------------------------------------------------------+---------------------------------------+ | | | :ref:`thingy91_nrf52840 ` | ``thingy91_nrf52840`` | +-------------------+------------+----------------------------------------------------------+---------------------------------------+ diff --git a/doc/nrf/includes/boardname_tables/sample_boardnames.txt b/doc/nrf/includes/boardname_tables/sample_boardnames.txt index 83e08a365162..80b957982eb9 100644 --- a/doc/nrf/includes/boardname_tables/sample_boardnames.txt +++ b/doc/nrf/includes/boardname_tables/sample_boardnames.txt @@ -88,7 +88,7 @@ Set used by nRF9160 samples (Cloud Client, nRF Cloud A-GPS) and application (Ass +--------------------------------+-----------+------------------------------------------------+------------------------------+ |Hardware platforms |PCA |Board name |Build target | +================================+===========+================================================+==============================+ -|:ref:`Thingy:91 ` |PCA20035 |thingy91_nrf9160 |``thingy91_nrf9160ns`` | +|:ref:`Thingy:91 ` |PCA20035 |thingy91_nrf9160 |``thingy91_nrf9160_ns`` | +--------------------------------+-----------+------------------------------------------------+------------------------------+ |:ref:`nRF9160 DK ` |PCA10090 |:ref:`nrf9160dk_nrf9160 ` |``nrf9160dk_nrf9160_ns`` | +--------------------------------+-----------+------------------------------------------------+------------------------------+ @@ -144,7 +144,7 @@ Set used by samples (BH1749: Ambient Light Sensor IC) +--------------------------------+-----------+------------------+---------------------------+ |Hardware platforms |PCA |Board name |Build target | +================================+===========+==================+===========================+ -|:ref:`Thingy:91 ` |PCA20035 |thingy91_nrf9160 |``thingy91_nrf9160ns`` | +|:ref:`Thingy:91 ` |PCA20035 |thingy91_nrf9160 |``thingy91_nrf9160_ns`` | +--------------------------------+-----------+------------------+---------------------------+ .. set10_end diff --git a/doc/nrf/includes/sample_board_rows.txt b/doc/nrf/includes/sample_board_rows.txt index cf351a720b2a..db5da7cf8dc0 100644 --- a/doc/nrf/includes/sample_board_rows.txt +++ b/doc/nrf/includes/sample_board_rows.txt @@ -54,9 +54,9 @@ | nRF52820 Dongle | PCA10114 | nrf52820dongle_nrf52820 | ``nrf52820dongle_nrf52820`` | -.. thingy91_nrf9160ns +.. thingy91_nrf9160_ns -| :ref:`Thingy:91 ` | PCA20035 | thingy91_nrf9160 | ``thingy91_nrf9160ns`` | +| :ref:`Thingy:91 ` | PCA20035 | thingy91_nrf9160 | ``thingy91_nrf9160_ns`` | .. nrf52dk_nrf52810 diff --git a/doc/nrf/known_issues.rst b/doc/nrf/known_issues.rst index 0a14ac8f7903..0191ba9ac883 100644 --- a/doc/nrf/known_issues.rst +++ b/doc/nrf/known_issues.rst @@ -934,8 +934,8 @@ Secure Partition Manager (SPM) .. rst-class:: v1-5-1 v1-5-0 -CIA-248: Samples with default SPM config fails to build for ``thingy91_nrf9160ns`` - All samples using the default SPM config fails to build for the ``thingy91_nrf9160ns`` build target if the sample is not set up with MCUboot. +CIA-248: Samples with default SPM config fails to build for ``thingy91_nrf9160_ns`` + All samples using the default SPM config fails to build for the ``thingy91_nrf9160_ns`` build target if the sample is not set up with MCUboot. **Workaround:** Use the master branch. diff --git a/doc/nrf/ug_thingy91.rst b/doc/nrf/ug_thingy91.rst index 3cb6785f8e1b..d1f98c90c66e 100644 --- a/doc/nrf/ug_thingy91.rst +++ b/doc/nrf/ug_thingy91.rst @@ -153,17 +153,17 @@ You can also program the Thingy:91 by using the images obtained by building the To set up your system to be able to build a compatible firmware image, follow the :ref:`getting_started` guide for |NCS|. The build targets of interest for Thingy:91 in |NCS| are as follows: -+---------------+--------------------------------------------------+ -|Component | Build target | -+===============+==================================================+ -|nRF9160 SiP |``thingy91_nrf9160`` for the secure version | -| | | -| |``thingy91_nrf9160ns`` for the non-secure version | -+---------------+--------------------------------------------------+ -|nRF52840 SoC |``thingy91_nrf52840`` | -+---------------+--------------------------------------------------+ - -You must use the build target ``thingy91_nrf9160`` or ``thingy91_nrf9160ns`` when building the application code for the nRF9160 SiP and the build target ``thingy91_nrf52840`` when building the application code for the onboard nRF52840 SoC. ++---------------+---------------------------------------------------+ +|Component | Build target | ++===============+===================================================+ +|nRF9160 SiP |``thingy91_nrf9160`` for the secure version | +| | | +| |``thingy91_nrf9160_ns`` for the non-secure version | ++---------------+---------------------------------------------------+ +|nRF52840 SoC |``thingy91_nrf52840`` | ++---------------+---------------------------------------------------+ + +You must use the build target ``thingy91_nrf9160`` or ``thingy91_nrf9160_ns`` when building the application code for the nRF9160 SiP and the build target ``thingy91_nrf52840`` when building the application code for the onboard nRF52840 SoC. .. note:: @@ -223,7 +223,7 @@ Building and programming using SEGGER Embedded Studio .. figure:: images/ses_thingy_configuration.png :alt: Opening the Asset tracker application - Opening the Asset tracker application for the thingy91_nrf9160ns build target + Opening the Asset tracker application for the thingy91_nrf9160_ns build target .. note:: @@ -293,7 +293,7 @@ To build and program the source code from the command line, complete the followi west build -b *build_target* -d *destination_directory_name* - The parameter *build_target* should be ``thingy91_nrf9160`` or ``thingy91_nrf9160ns`` if building for the nRF9160 SiP component and ``thingy91_nrf52840`` if building for the nRF52840 SoC component. + The parameter *build_target* should be ``thingy91_nrf9160`` or ``thingy91_nrf9160_ns`` if building for the nRF9160 SiP component and ``thingy91_nrf52840`` if building for the nRF52840 SoC component. .. note:: diff --git a/samples/nrf9160/agps/README.rst b/samples/nrf9160/agps/README.rst index 4d639216103a..8a20937f00e0 100644 --- a/samples/nrf9160/agps/README.rst +++ b/samples/nrf9160/agps/README.rst @@ -18,7 +18,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns The sample also requires an nRF Connect for Cloud account. diff --git a/samples/nrf9160/aws_iot/README.rst b/samples/nrf9160/aws_iot/README.rst index 69fbdbaefa02..f7bcdfb10974 100644 --- a/samples/nrf9160/aws_iot/README.rst +++ b/samples/nrf9160/aws_iot/README.rst @@ -33,7 +33,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/azure_fota/README.rst b/samples/nrf9160/azure_fota/README.rst index 7733fe067dcb..00cfbb62011e 100644 --- a/samples/nrf9160/azure_fota/README.rst +++ b/samples/nrf9160/azure_fota/README.rst @@ -16,7 +16,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns The sample also requires an Azure IoT Hub instance, and optionally an `Azure IoT Hub Device Provisioning Service (DPS)`_ instance, if the device is not already registered with the IoT hub. diff --git a/samples/nrf9160/azure_iot_hub/README.rst b/samples/nrf9160/azure_iot_hub/README.rst index 5019b4c3b446..e3e69e1ea57b 100644 --- a/samples/nrf9160/azure_iot_hub/README.rst +++ b/samples/nrf9160/azure_iot_hub/README.rst @@ -18,7 +18,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/memfault/README.rst b/samples/nrf9160/memfault/README.rst index 2012a8326462..bb591e0521bb 100644 --- a/samples/nrf9160/memfault/README.rst +++ b/samples/nrf9160/memfault/README.rst @@ -18,7 +18,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns Before using the Memfault platform, you must register an account in `Memfault`_ and a set up a project according to the instructions in `Memfault documentation `_. diff --git a/samples/nrf9160/multicell_location/README.rst b/samples/nrf9160/multicell_location/README.rst index 3ad7b321f98f..a5ad6d2c2e11 100644 --- a/samples/nrf9160/multicell_location/README.rst +++ b/samples/nrf9160/multicell_location/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns .. include:: /includes/spm.txt diff --git a/samples/nrf9160/udp/README.rst b/samples/nrf9160/udp/README.rst index 9a376f9ee620..43af887d2c7e 100644 --- a/samples/nrf9160/udp/README.rst +++ b/samples/nrf9160/udp/README.rst @@ -17,7 +17,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns, nrf9160dk_nrf9160_ns + :rows: thingy91_nrf9160_ns, nrf9160dk_nrf9160_ns Additionally, it supports :ref:`qemu_x86`. diff --git a/samples/sensor/bh1749/README.rst b/samples/sensor/bh1749/README.rst index af3dc7a963d4..ed040818eac3 100644 --- a/samples/sensor/bh1749/README.rst +++ b/samples/sensor/bh1749/README.rst @@ -21,7 +21,7 @@ The sample supports the following nRF9160-based device: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: thingy91_nrf9160ns + :rows: thingy91_nrf9160_ns Building and Running ******************** From c804d8fee96b52f7157e2947b575300344136f5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 27 Jul 2021 17:25:40 -0700 Subject: [PATCH 097/126] .github: improve action-oss-history checks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The oss-history repository can now check the histoires of additional repositories. Add mcuboot and trusted-firmware-m to the default set of repositories to check. Signed-off-by: Martí Bolívar --- .github/workflows/oss-history.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/oss-history.yml b/.github/workflows/oss-history.yml index 718bcc583ac1..919e55bfb38d 100644 --- a/.github/workflows/oss-history.yml +++ b/.github/workflows/oss-history.yml @@ -21,7 +21,7 @@ jobs: run: | west init -l ncs/nrf cd ncs - west update zephyr + west update zephyr mcuboot trusted-firmware-m git -C zephyr remote add upstream https://github.com/zephyrproject-rtos/zephyr - name: Check OSS history From 6a283c7c8081985de6b9fb67e4af7a1a584bbc75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Thu, 29 Jul 2021 13:52:30 -0700 Subject: [PATCH 098/126] west.yml: update memfault-firmware-sdk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Release 0.24.1 fixes some issues with renamed Kconfig symbols for non-secure board configurations. https://github.com/memfault/memfault-firmware-sdk/blob/1b88521c5f736a4acd57e7e75e859a69deb9d845/CHANGES.md Signed-off-by: Martí Bolívar --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index 512f075abc12..f1a73cd7745f 100644 --- a/west.yml +++ b/west.yml @@ -172,7 +172,7 @@ manifest: - find-my - name: memfault-firmware-sdk path: modules/lib/memfault-firmware-sdk - revision: 0.21.1 + revision: 0.24.1 remote: memfault # West-related configuration for the nrf repository. From befbfaf4e65418f38243bf254a99ecf8441fbcf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 3 Aug 2021 12:25:01 -0700 Subject: [PATCH 099/126] bluetooth: services: hids: keep up with API change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Upstream zephyr commit 6e665ccd1325d9fd5191c8930b0b1bd499a5579d ("sys: util: remove deprecated GET_ARG{1,2} and GET_ARGS_LESS_1 macros") did just what it says in the shortlog. Provide a local GET_ARG1 implementation to keep this header working. Signed-off-by: Martí Bolívar --- include/bluetooth/services/hids.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/bluetooth/services/hids.h b/include/bluetooth/services/hids.h index a0276f81d776..d67a785909c3 100644 --- a/include/bluetooth/services/hids.h +++ b/include/bluetooth/services/hids.h @@ -65,8 +65,9 @@ extern "C" { * the link context size for HIDS instance. */ #define _BT_HIDS_CONN_CTX_SIZE_CALC(...) \ - (FOR_EACH(GET_ARG1, (+), __VA_ARGS__) + \ + (FOR_EACH(_BT_HIDS_GET_ARG1, (+), __VA_ARGS__) + \ sizeof(struct bt_hids_conn_data)) +#define _BT_HIDS_GET_ARG1(...) GET_ARG_N(1, __VA_ARGS__) /** @brief Possible values for the Protocol Mode Characteristic value. */ From d2cc0a8a9d0e6b1376dc82565d6cb48d43a59a9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 3 Aug 2021 19:20:43 -0700 Subject: [PATCH 100/126] treewide: remove unused pm_device_state_set callback args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Zephyr commit 26ad8376bd5a9dca7b225a7b7baa9c332e876fb8 ("pm: remove callback from control function") removed the callback and its argument from the pm_device_state_set() API. Keep up. Signed-off-by: Martí Bolívar --- applications/asset_tracker/src/ui/buzzer.c | 8 ++------ applications/asset_tracker/src/ui/led_pwm.c | 8 ++------ applications/asset_tracker/src/ui/nmos.c | 8 ++------ .../connectivity_bridge/src/modules/uart_handler.c | 2 +- applications/nrf_desktop/src/hw_interface/wheel.c | 6 ++---- applications/serial_lte_modem/src/slm_at_host.c | 8 ++++---- samples/bluetooth/direct_test_mode/src/fem/nrf21540.c | 6 ++---- samples/nrf9160/lwm2m_client/src/ui/buzzer.c | 8 ++------ samples/nrf9160/lwm2m_client/src/ui/led_pwm.c | 6 ++---- samples/nrf9160/modem_shell/src/uart/uart.c | 8 ++++---- samples/openthread/coap_client/src/coap_client.c | 4 ++-- subsys/caf/modules/leds.c | 6 ++---- 12 files changed, 27 insertions(+), 51 deletions(-) diff --git a/applications/asset_tracker/src/ui/buzzer.c b/applications/asset_tracker/src/ui/buzzer.c index b31960d99bcb..1fd96777cc17 100644 --- a/applications/asset_tracker/src/ui/buzzer.c +++ b/applications/asset_tracker/src/ui/buzzer.c @@ -63,9 +63,7 @@ static void buzzer_disable(void) pwm_out(0, 0); #ifdef CONFIG_PM_DEVICE - int err = pm_device_state_set(pwm_dev, - PM_DEVICE_STATE_SUSPEND, - NULL, NULL); + int err = pm_device_state_set(pwm_dev, PM_DEVICE_STATE_SUSPEND); if (err) { LOG_ERR("PWM disable failed"); } @@ -79,9 +77,7 @@ static int buzzer_enable(void) atomic_set(&buzzer_enabled, 1); #ifdef CONFIG_PM_DEVICE - err = pm_device_state_set(pwm_dev, - PM_DEVICE_STATE_ACTIVE, - NULL, NULL); + err = pm_device_state_set(pwm_dev, PM_DEVICE_STATE_ACTIVE); if (err) { LOG_ERR("PWM enable failed"); return err; diff --git a/applications/asset_tracker/src/ui/led_pwm.c b/applications/asset_tracker/src/ui/led_pwm.c index 66d4c1124365..057e706595db 100644 --- a/applications/asset_tracker/src/ui/led_pwm.c +++ b/applications/asset_tracker/src/ui/led_pwm.c @@ -188,9 +188,7 @@ int ui_leds_init(void) void ui_leds_start(void) { #ifdef CONFIG_PM_DEVICE - int err = pm_device_state_set(leds.pwm_dev, - PM_DEVICE_STATE_ACTIVE, - NULL, NULL); + int err = pm_device_state_set(leds.pwm_dev, PM_DEVICE_STATE_ACTIVE); if (err) { LOG_ERR("PWM enable failed"); } @@ -202,9 +200,7 @@ void ui_leds_stop(void) { k_work_cancel_delayable_sync(&leds.work, &leds.work_sync); #ifdef CONFIG_PM_DEVICE - int err = pm_device_state_set(leds.pwm_dev, - PM_DEVICE_STATE_SUSPEND, - NULL, NULL); + int err = pm_device_state_set(leds.pwm_dev, PM_DEVICE_STATE_SUSPEND); if (err) { LOG_ERR("PWM disable failed"); } diff --git a/applications/asset_tracker/src/ui/nmos.c b/applications/asset_tracker/src/ui/nmos.c index d1ad5ab32371..5ecc607fc767 100644 --- a/applications/asset_tracker/src/ui/nmos.c +++ b/applications/asset_tracker/src/ui/nmos.c @@ -89,9 +89,7 @@ static void nmos_pwm_disable(uint32_t nmos_idx) return; } - int err = pm_device_state_set(pwm_dev, - PM_DEVICE_STATE_SUSPEND, - NULL, NULL); + int err = pm_device_state_set(pwm_dev, PM_DEVICE_STATE_SUSPEND); if (err) { LOG_WRN("PWM disable failed"); } @@ -113,9 +111,7 @@ static int nmos_pwm_enable(size_t nmos_idx) return 0; } - err = pm_device_state_set(pwm_dev, - PM_DEVICE_STATE_ACTIVE, - NULL, NULL); + err = pm_device_state_set(pwm_dev, PM_DEVICE_STATE_ACTIVE); if (err) { LOG_ERR("PWM enable failed"); return err; diff --git a/applications/connectivity_bridge/src/modules/uart_handler.c b/applications/connectivity_bridge/src/modules/uart_handler.c index 89aaa65db4c0..10dfcfe87c6d 100644 --- a/applications/connectivity_bridge/src/modules/uart_handler.c +++ b/applications/connectivity_bridge/src/modules/uart_handler.c @@ -258,7 +258,7 @@ static void set_uart_power_state(uint8_t dev_idx, bool active) return; } - err = pm_device_state_set(dev, target_state, NULL, NULL); + err = pm_device_state_set(dev, target_state); if (err) { LOG_ERR("device_set_power_state: %d", err); return; diff --git a/applications/nrf_desktop/src/hw_interface/wheel.c b/applications/nrf_desktop/src/hw_interface/wheel.c index b1b25bbe7d72..ce78b9cc4643 100644 --- a/applications/nrf_desktop/src/hw_interface/wheel.c +++ b/applications/nrf_desktop/src/hw_interface/wheel.c @@ -199,8 +199,7 @@ static int enable_qdec(enum state next_state) { __ASSERT_NO_MSG(next_state == STATE_ACTIVE); - int err = pm_device_state_set(qdec_dev, PM_DEVICE_STATE_ACTIVE, - NULL, NULL); + int err = pm_device_state_set(qdec_dev, PM_DEVICE_STATE_ACTIVE); if (err) { LOG_ERR("Cannot activate QDEC"); return err; @@ -238,8 +237,7 @@ static int disable_qdec(enum state next_state) return err; } - err = pm_device_state_set(qdec_dev, PM_DEVICE_STATE_SUSPEND, - NULL, NULL); + err = pm_device_state_set(qdec_dev, PM_DEVICE_STATE_SUSPEND); if (err) { LOG_ERR("Cannot suspend QDEC"); } else { diff --git a/applications/serial_lte_modem/src/slm_at_host.c b/applications/serial_lte_modem/src/slm_at_host.c index 965d25c834ca..97f658aff189 100644 --- a/applications/serial_lte_modem/src/slm_at_host.c +++ b/applications/serial_lte_modem/src/slm_at_host.c @@ -197,7 +197,7 @@ int poweroff_uart(void) uart_rx_disable(uart_dev); k_sleep(K_MSEC(100)); - err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_OFF, NULL, NULL); + err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_OFF); if (err) { LOG_ERR("Can't power off uart: %d", err); } @@ -217,7 +217,7 @@ int poweron_uart(void) } if (current_state != PM_DEVICE_STATE_ACTIVE) { - pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE, NULL, NULL); + pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE); k_sleep(K_MSEC(100)); err = uart_receive(); if (err == 0) { @@ -776,7 +776,7 @@ int slm_at_host_init(void) return -EFAULT; } /* Power on UART module */ - pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE, NULL, NULL); + pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE); err = uart_receive(); if (err) { return -EFAULT; @@ -835,7 +835,7 @@ void slm_at_host_uninit(void) /* Power off UART module */ uart_rx_disable(uart_dev); k_sleep(K_MSEC(100)); - err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_OFF, NULL, NULL); + err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_OFF); if (err) { LOG_WRN("Can't power off uart: %d", err); } diff --git a/samples/bluetooth/direct_test_mode/src/fem/nrf21540.c b/samples/bluetooth/direct_test_mode/src/fem/nrf21540.c index 7262d2ad5f99..432b73a96bc3 100644 --- a/samples/bluetooth/direct_test_mode/src/fem/nrf21540.c +++ b/samples/bluetooth/direct_test_mode/src/fem/nrf21540.c @@ -706,8 +706,7 @@ int nrf21540_tx_gain_set(uint8_t gain) } if (uart_ready) { - err = pm_device_state_set(uart, PM_DEVICE_STATE_OFF, - NULL, NULL); + err = pm_device_state_set(uart, PM_DEVICE_STATE_OFF); if (err) { goto error; } @@ -728,8 +727,7 @@ int nrf21540_tx_gain_set(uint8_t gain) uarte_configuration_restore(uarte_inst, &uarte_cfg); if (uart_ready) { - err = pm_device_state_set(uart, PM_DEVICE_STATE_ACTIVE, - NULL, NULL); + err = pm_device_state_set(uart, PM_DEVICE_STATE_ACTIVE); } if (uart_irq) { diff --git a/samples/nrf9160/lwm2m_client/src/ui/buzzer.c b/samples/nrf9160/lwm2m_client/src/ui/buzzer.c index 3a18d28e8cc9..2495481ba0c9 100644 --- a/samples/nrf9160/lwm2m_client/src/ui/buzzer.c +++ b/samples/nrf9160/lwm2m_client/src/ui/buzzer.c @@ -65,9 +65,7 @@ static void buzzer_disable(void) pwm_out(0, 0); #ifdef CONFIG_PM_DEVICE - int err = pm_device_state_set(pwm_dev, - PM_DEVICE_STATE_SUSPEND, - NULL, NULL); + int err = pm_device_state_set(pwm_dev, PM_DEVICE_STATE_SUSPEND); if (err) { LOG_ERR("PWM disable failed"); } @@ -81,9 +79,7 @@ static int buzzer_enable(void) atomic_set(&buzzer_enabled, 1); #ifdef CONFIG_PM_DEVICE - err = pm_device_state_set(pwm_dev, - PM_DEVICE_STATE_ACTIVE, - NULL, NULL); + err = pm_device_state_set(pwm_dev, PM_DEVICE_STATE_ACTIVE); if (err) { LOG_ERR("PWM enable failed"); return err; diff --git a/samples/nrf9160/lwm2m_client/src/ui/led_pwm.c b/samples/nrf9160/lwm2m_client/src/ui/led_pwm.c index 8131f0dafde5..682ebce3be88 100644 --- a/samples/nrf9160/lwm2m_client/src/ui/led_pwm.c +++ b/samples/nrf9160/lwm2m_client/src/ui/led_pwm.c @@ -183,8 +183,7 @@ void ui_leds_start(void) { #ifdef CONFIG_PM_DEVICE int err = pm_device_state_set(leds.pwm_dev, - PM_DEVICE_STATE_ACTIVE, - NULL, NULL); + PM_DEVICE_STATE_ACTIVE); if (err) { LOG_ERR("PWM enable failed"); } @@ -197,8 +196,7 @@ void ui_leds_stop(void) k_work_cancel_delayable_sync(&leds.work, &leds.work_sync); #ifdef CONFIG_PM_DEVICE int err = pm_device_state_set(leds.pwm_dev, - PM_DEVICE_STATE_SUSPEND, - NULL, NULL); + PM_DEVICE_STATE_SUSPEND); if (err) { LOG_ERR("PWM disable failed"); } diff --git a/samples/nrf9160/modem_shell/src/uart/uart.c b/samples/nrf9160/modem_shell/src/uart/uart.c index b45832ed9511..5b82fd9da27c 100644 --- a/samples/nrf9160/modem_shell/src/uart/uart.c +++ b/samples/nrf9160/modem_shell/src/uart/uart.c @@ -16,12 +16,12 @@ void disable_uarts(void) uart_dev = device_get_binding(DT_LABEL(DT_NODELABEL(uart0))); if (uart_dev) { - pm_device_state_set(uart_dev, PM_DEVICE_STATE_LOW_POWER, NULL, NULL); + pm_device_state_set(uart_dev, PM_DEVICE_STATE_LOW_POWER); } uart_dev = device_get_binding(DT_LABEL(DT_NODELABEL(uart1))); if (uart_dev) { - pm_device_state_set(uart_dev, PM_DEVICE_STATE_LOW_POWER, NULL, NULL); + pm_device_state_set(uart_dev, PM_DEVICE_STATE_LOW_POWER); } } @@ -45,12 +45,12 @@ void enable_uarts(void) } if (uart_dev) { - pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE, NULL, NULL); + pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE); } uart_dev = device_get_binding(DT_LABEL(DT_NODELABEL(uart1))); if (uart_dev) { - pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE, NULL, NULL); + pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE); } printk("UARTs enabled\n"); diff --git a/samples/openthread/coap_client/src/coap_client.c b/samples/openthread/coap_client/src/coap_client.c index 6e74c60002de..b307108dd175 100644 --- a/samples/openthread/coap_client/src/coap_client.c +++ b/samples/openthread/coap_client/src/coap_client.c @@ -98,9 +98,9 @@ static void on_mtd_mode_toggle(uint32_t med) const struct device *cons = device_get_binding(CONSOLE_LABEL); if (med) { - pm_device_state_set(cons, PM_DEVICE_STATE_ACTIVE, NULL, NULL); + pm_device_state_set(cons, PM_DEVICE_STATE_ACTIVE); } else { - pm_device_state_set(cons, PM_DEVICE_STATE_OFF, NULL, NULL); + pm_device_state_set(cons, PM_DEVICE_STATE_OFF); } #endif dk_set_led(MTD_SED_LED, med); diff --git a/subsys/caf/modules/leds.c b/subsys/caf/modules/leds.c index bd2ca27e75af..c135d6a814b7 100644 --- a/subsys/caf/modules/leds.c +++ b/subsys/caf/modules/leds.c @@ -229,8 +229,7 @@ static void leds_start(void) for (size_t i = 0; i < ARRAY_SIZE(leds); i++) { #ifdef CONFIG_PM_DEVICE int err = pm_device_state_set(leds[i].dev, - PM_DEVICE_STATE_ACTIVE, - NULL, NULL); + PM_DEVICE_STATE_ACTIVE); if (err) { LOG_ERR("PWM enable failed"); } @@ -248,8 +247,7 @@ static void leds_stop(void) #ifdef CONFIG_PM_DEVICE int err = pm_device_state_set(leds[i].dev, - PM_DEVICE_STATE_SUSPEND, - NULL, NULL); + PM_DEVICE_STATE_SUSPEND); if (err) { LOG_ERR("PWM disable failed"); } From 457461c23eb5cefc4548f01ad09a6d1067830c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Tue, 3 Aug 2021 19:25:55 -0700 Subject: [PATCH 101/126] treewide: shrink names for null-pointer exception detection Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Keep up with zephyr commit d105a2b76c0b57d0ce130e2a57ea44e60d765f5f ("arm: shrink names for null-pointer exception detection Kconfigs"). Signed-off-by: Martí Bolívar --- tests/drivers/fprotect/positive/prj.conf | 2 +- tests/subsys/bootloader/bl_crypto/prj.conf | 2 +- tests/subsys/bootloader/bl_validation/prj.conf | 2 +- tests/subsys/bootloader/bl_validation_neg/prj.conf | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/drivers/fprotect/positive/prj.conf b/tests/drivers/fprotect/positive/prj.conf index 1ccbc79b0926..58a77c4dab45 100644 --- a/tests/drivers/fprotect/positive/prj.conf +++ b/tests/drivers/fprotect/positive/prj.conf @@ -12,4 +12,4 @@ CONFIG_STDOUT_CONSOLE=n CONFIG_MPU_ALLOW_FLASH_WRITE=y CONFIG_SECURE_BOOT=y CONFIG_FLASH=y -CONFIG_CORTEX_M_DEBUG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y diff --git a/tests/subsys/bootloader/bl_crypto/prj.conf b/tests/subsys/bootloader/bl_crypto/prj.conf index 55be3a221e06..1e374dee809a 100644 --- a/tests/subsys/bootloader/bl_crypto/prj.conf +++ b/tests/subsys/bootloader/bl_crypto/prj.conf @@ -17,4 +17,4 @@ CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1=y CONFIG_BOOTLOADER_MCUBOOT=y # To test FW_INFO_PROVIDE_EXT_API. CONFIG_SB_MONOTONIC_COUNTER=n # To test that this config works properly. CONFIG_FW_INFO=y -CONFIG_CORTEX_M_DEBUG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y diff --git a/tests/subsys/bootloader/bl_validation/prj.conf b/tests/subsys/bootloader/bl_validation/prj.conf index 302bfaefb9ba..08d659079f64 100644 --- a/tests/subsys/bootloader/bl_validation/prj.conf +++ b/tests/subsys/bootloader/bl_validation/prj.conf @@ -14,4 +14,4 @@ CONFIG_BL_VALIDATE_FW_EXT_API_REQUIRED=y CONFIG_SB_DEBUG_SIGNATURE_PUBLIC_KEY_LAST=y CONFIG_NRFX_NVMC=y CONFIG_MPU_ALLOW_FLASH_WRITE=y -CONFIG_CORTEX_M_DEBUG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y diff --git a/tests/subsys/bootloader/bl_validation_neg/prj.conf b/tests/subsys/bootloader/bl_validation_neg/prj.conf index eb093ab56bb2..d2a436e090e2 100644 --- a/tests/subsys/bootloader/bl_validation_neg/prj.conf +++ b/tests/subsys/bootloader/bl_validation_neg/prj.conf @@ -13,4 +13,4 @@ CONFIG_NRFX_NVMC=y CONFIG_MPU_ALLOW_FLASH_WRITE=y CONFIG_REBOOT=y CONFIG_SECURE_BOOT_STORAGE=y -CONFIG_CORTEX_M_DEBUG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y +CONFIG_NULL_POINTER_EXCEPTION_DETECTION_NONE=y From 66889e3cbf1966ba32f7e6f5ab9a77f9889f6103 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Wed, 4 Aug 2021 09:13:51 -0700 Subject: [PATCH 102/126] connectivity_bridge: adjust PM API usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I'm seeing complaints in CI about incompatible types here (uint32_t* vs. enum pm_device_state*). These are due to zephyr commit cc2f0e9c08dcad59a4cc0117028a5fcf9d73f433 ("pm: use enum for device PM states"), which moved the states from preprocessor defines to enums. Signed-off-by: Martí Bolívar --- applications/connectivity_bridge/src/modules/uart_handler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/applications/connectivity_bridge/src/modules/uart_handler.c b/applications/connectivity_bridge/src/modules/uart_handler.c index 10dfcfe87c6d..f3a60a85482f 100644 --- a/applications/connectivity_bridge/src/modules/uart_handler.c +++ b/applications/connectivity_bridge/src/modules/uart_handler.c @@ -243,8 +243,8 @@ static void set_uart_power_state(uint8_t dev_idx, bool active) #if UART_SET_PM_STATE const struct device *dev = devices[dev_idx]; int err; - uint32_t current_state; - uint32_t target_state; + enum pm_device_state current_state; + enum pm_device_state target_state; target_state = active ? PM_DEVICE_STATE_ACTIVE : PM_DEVICE_STATE_SUSPEND; From eb1000062bbcecfd8e8910537e5d6f64255540c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Wed, 4 Aug 2021 14:16:38 -0700 Subject: [PATCH 103/126] bl_storage: avoid use of memcpy() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are no guarantees about the read sizes that memcpy() uses, and we require 32 bit reads. Just do the reads ourselves rather than let memcpy() potentially do the wrong thing. Signed-off-by: Martí Bolívar Reported-by: Håkon Øye Amundsen --- subsys/bootloader/bl_storage/bl_storage.c | 26 ++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/subsys/bootloader/bl_storage/bl_storage.c b/subsys/bootloader/bl_storage/bl_storage.c index dfa0f42a4cc6..530fca716e15 100644 --- a/subsys/bootloader/bl_storage/bl_storage.c +++ b/subsys/bootloader/bl_storage/bl_storage.c @@ -112,6 +112,30 @@ int verify_public_keys(void) return 0; } +/** + * Helper procedure for public_key_data_read() + * + * Copies @p src into @p dst. Reads from @p src are done 32 bits at a + * time. Writes to @p dst are done a byte at a time. + * + * @param dst destination buffer + * @param src source buffer + * @param size number of *bytes* in src to copy into dst + */ +static void public_key_copy32(uint8_t *dst, const uint32_t *src, size_t size) +{ + while (size) { + uint32_t val = *src++; + + *dst++ = val & 0xFF; + *dst++ = (val >> 8U) & 0xFF; + *dst++ = (val >> 16U) & 0xFF; + *dst++ = (val >> 24U) & 0xFF; + + size -= 4; + } +} + int public_key_data_read(uint32_t key_idx, uint8_t *p_buf, size_t buf_size) { const uint8_t *p_key; @@ -138,7 +162,7 @@ int public_key_data_read(uint32_t key_idx, uint8_t *p_buf, size_t buf_size) BUILD_ASSERT(offsetof(struct bl_storage_data, key_data) % 4 == 0); __ASSERT(((uint32_t)p_key % 4 == 0), "Key address is not word aligned"); - memcpy(p_buf, p_key, CONFIG_SB_PUBLIC_KEY_HASH_LEN); + public_key_copy32(p_buf, (const uint32_t *)p_key, CONFIG_SB_PUBLIC_KEY_HASH_LEN); __DSB(); /* Because of nRF9160 Erratum 7 */ return CONFIG_SB_PUBLIC_KEY_HASH_LEN; From 45db726b7232edf3f373d311746f9b7667e00d0d Mon Sep 17 00:00:00 2001 From: Francesco Servidio Date: Thu, 5 Aug 2021 13:48:44 +0200 Subject: [PATCH 104/126] doc: _ns boards namechange mentioned in Userguides. Added mentions of _ns boards namechange in these userguides: - ug_nrf5340.rst - ug_nrf9160.rst - ug_thingy91.rst Signed-off-by: Francesco Servidio --- doc/nrf/ug_nrf5340.rst | 3 +++ doc/nrf/ug_nrf9160.rst | 3 +++ doc/nrf/ug_thingy91.rst | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/doc/nrf/ug_nrf5340.rst b/doc/nrf/ug_nrf5340.rst index 650b16cd8b3e..70deeacbb6fd 100644 --- a/doc/nrf/ug_nrf5340.rst +++ b/doc/nrf/ug_nrf5340.rst @@ -71,6 +71,9 @@ In Zephyr, the application core is divided into two different build targets: * ``nrf5340dk_nrf5340_cpuapp`` for the secure domain * ``nrf5340dk_nrf5340_cpuapp_ns`` for the non-secure domain +.. note:: + In |NCS| releases before v1.6.1, the build target ``nrf5340dk_nrf5340_cpuapp_ns`` was named ``nrf5340dk_nrf5340_cpuappns``. + Inter-core communication ======================== diff --git a/doc/nrf/ug_nrf9160.rst b/doc/nrf/ug_nrf9160.rst index 1bbc7dd7e141..cbbbec32342a 100644 --- a/doc/nrf/ug_nrf9160.rst +++ b/doc/nrf/ug_nrf9160.rst @@ -41,6 +41,9 @@ In Zephyr, :ref:`zephyr:nrf9160dk_nrf9160` is divided into two different build t * ``nrf9160dk_nrf9160`` for firmware in the secure domain * ``nrf9160dk_nrf9160_ns`` for firmware in the non-secure domain +.. note:: + In |NCS| releases before v1.6.1, the build target ``nrf9160dk_nrf9160_ns`` was named ``nrf9160dk_nrf9160ns``. + Make sure to select a suitable build target when building your application. Secure bootloader chain diff --git a/doc/nrf/ug_thingy91.rst b/doc/nrf/ug_thingy91.rst index d1f98c90c66e..52ad8d634baa 100644 --- a/doc/nrf/ug_thingy91.rst +++ b/doc/nrf/ug_thingy91.rst @@ -167,7 +167,8 @@ You must use the build target ``thingy91_nrf9160`` or ``thingy91_nrf9160_ns`` wh .. note:: - In |NCS| releases before v1.3.0, these build targets were named ``nrf9160_pca20035``, ``nrf9160_pca20035ns``, and ``nrf52840_pca20035``. + * In |NCS| releases before v1.3.0, these build targets were named ``nrf9160_pca20035``, ``nrf9160_pca20035ns``, and ``nrf52840_pca20035``. + * In |NCS| releases ranging from v1.3.0 to v1.6.1, the build target ``thingy91_nrf9160_ns`` was named ``thingy91_nrf9160ns``. .. note:: From 0c5b11d386ef00921480fa5de6eff7509db42fab Mon Sep 17 00:00:00 2001 From: Francesco Servidio Date: Fri, 6 Aug 2021 12:51:26 +0200 Subject: [PATCH 105/126] doc: updated release notes Updated the latest release notes. Signed-off-by: Francesco Servidio --- doc/nrf/releases/release-notes-changelog.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/doc/nrf/releases/release-notes-changelog.rst b/doc/nrf/releases/release-notes-changelog.rst index cee8f2dd198c..fbe7ae64862b 100644 --- a/doc/nrf/releases/release-notes-changelog.rst +++ b/doc/nrf/releases/release-notes-changelog.rst @@ -67,6 +67,10 @@ nRF9160 * The library has been deprecated in favor of the :ref:`at_monitor_readme` library. + * ``thingy91_nrf9160_ns`` board: + + * The ``thingy91_nrf9160ns`` board has been renamed to ``thingy91_nrf9160_ns`` for consistency with the changes inherited from upstream Zephyr. + nRF5 ==== @@ -175,6 +179,13 @@ For a complete list of |NCS| specific commits, run: The current |NCS| release is based on Zephyr v2.6.0-rc1. See the :ref:`zephyr:zephyr_2.6` Release Notes for an overview of the most important changes inherited from upstream Zephyr. +The following list summarizes the most important changes inherited from upstream Zephyr: + +* The ``nrf9160dk_nrf9160ns`` and the ``nrf5340dk_nrf5340_cpuappns`` boards have been renamed respectively to ``nrf9160dk_nrf9160_ns`` and ``nrf5340dk_nrf5340_cpuapp_ns``. +* A config option for ``memcpy`` that skips the word-based loop before the byte-based loop was added. + It is now enabled by default if :kconfig:`SIZE_OPTIMIZATIONS` is set. + As result, any application-specific assumptions about ``memcpy`` read or write size behavior should be rechecked if this option is enabled. + Matter (Project CHIP) ===================== From fbceba83f6c29ffaa72e6371ed7d1aa3851c5775 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Thu, 5 Aug 2021 11:11:27 +0200 Subject: [PATCH 106/126] doc: nrf: replace option role with kconfig Kconfig options are now referenced using :kconfig: instead of :option:. Signed-off-by: Gerard Marull-Paretas --- applications/asset_tracker/README.rst | 2 +- applications/asset_tracker_v2/README.rst | 30 ++++----- applications/machine_learning/README.rst | 2 +- applications/nrf_desktop/README.rst | 54 ++++++++-------- applications/nrf_desktop/doc/bas.rst | 4 +- .../nrf_desktop/doc/battery_charger.rst | 22 +++---- applications/nrf_desktop/doc/battery_meas.rst | 28 ++++---- applications/nrf_desktop/doc/ble_adv.rst | 2 +- applications/nrf_desktop/doc/ble_bond.rst | 20 +++--- .../nrf_desktop/doc/ble_conn_params.rst | 4 +- .../nrf_desktop/doc/ble_discovery.rst | 6 +- applications/nrf_desktop/doc/ble_latency.rst | 8 +-- applications/nrf_desktop/doc/ble_passkey.rst | 6 +- applications/nrf_desktop/doc/ble_qos.rst | 22 +++---- applications/nrf_desktop/doc/ble_scan.rst | 34 +++++----- applications/nrf_desktop/doc/board.rst | 2 +- applications/nrf_desktop/doc/buttons_sim.rst | 8 +-- .../nrf_desktop/doc/config_channel.rst | 4 +- applications/nrf_desktop/doc/constlat.rst | 4 +- applications/nrf_desktop/doc/cpu_meas.rst | 8 +-- applications/nrf_desktop/doc/dev_descr.rst | 4 +- applications/nrf_desktop/doc/dfu.rst | 6 +- applications/nrf_desktop/doc/failsafe.rst | 6 +- applications/nrf_desktop/doc/fn_keys.rst | 10 +-- applications/nrf_desktop/doc/hfclk_lock.rst | 2 +- applications/nrf_desktop/doc/hid_forward.rst | 14 ++-- applications/nrf_desktop/doc/hid_state.rst | 12 ++-- applications/nrf_desktop/doc/hids.rst | 14 ++-- applications/nrf_desktop/doc/info.rst | 6 +- applications/nrf_desktop/doc/led_state.rst | 2 +- applications/nrf_desktop/doc/led_stream.rst | 6 +- applications/nrf_desktop/doc/motion.rst | 36 +++++------ applications/nrf_desktop/doc/passkey.rst | 4 +- .../nrf_desktop/doc/profiler_sync.rst | 8 +-- applications/nrf_desktop/doc/qos.rst | 4 +- applications/nrf_desktop/doc/selector.rst | 4 +- .../nrf_desktop/doc/settings_loader.rst | 8 +-- applications/nrf_desktop/doc/usb_state.rst | 26 ++++---- applications/nrf_desktop/doc/watchdog.rst | 6 +- applications/nrf_desktop/doc/wheel.rst | 10 +-- applications/pelion_client/README.rst | 14 ++-- .../doc/HTTPC_AT_commands.rst | 4 +- .../serial_lte_modem/doc/slm_description.rst | 27 +++----- .../serial_lte_modem/doc/slm_testing.rst | 6 +- doc/nrf/known_issues.rst | 4 +- .../libraries/bin/lwm2m_carrier/CHANGELOG.rst | 4 +- .../bin/lwm2m_carrier/app_integration.rst | 26 ++++---- .../bin/lwm2m_carrier/requirements.rst | 2 +- .../libraries/bluetooth_services/enocean.rst | 6 +- .../bluetooth_services/mesh/dk_prov.rst | 10 +-- .../bluetooth_services/mesh/gen_dtt_srv.rst | 6 +- .../bluetooth_services/mesh/gen_plvl_srv.rst | 4 +- .../mesh/gen_ponoff_srv.rst | 8 +-- .../bluetooth_services/mesh/gen_prop.rst | 4 +- .../bluetooth_services/mesh/gen_prop_srv.rst | 4 +- .../mesh/light_ctrl_srv.rst | 38 +++++------ .../bluetooth_services/mesh/light_hue_srv.rst | 4 +- .../bluetooth_services/mesh/light_sat_srv.rst | 4 +- .../bluetooth_services/mesh/light_xyl_srv.rst | 4 +- .../bluetooth_services/mesh/lightness.rst | 4 +- .../bluetooth_services/mesh/lightness_srv.rst | 4 +- .../bluetooth_services/mesh/scene_srv.rst | 2 +- .../bluetooth_services/mesh/sensor.rst | 2 +- .../bluetooth_services/mesh/sensor_cli.rst | 2 +- .../bluetooth_services/mesh/sensor_srv.rst | 4 +- .../bluetooth_services/mesh/sensor_types.rst | 4 +- .../bluetooth_services/mesh/time_srv.rst | 8 +-- .../mesh/vnd/silvair_enocean_srv.rst | 4 +- doc/nrf/libraries/bluetooth_services/rpc.rst | 64 +++++++++---------- doc/nrf/libraries/bluetooth_services/scan.rst | 18 +++--- .../bluetooth_services/services/hogp.rst | 2 +- doc/nrf/libraries/caf/ble_adv.rst | 40 ++++++------ doc/nrf/libraries/caf/ble_smp.rst | 12 ++-- doc/nrf/libraries/caf/ble_state.rst | 14 ++-- doc/nrf/libraries/caf/buttons.rst | 26 ++++---- doc/nrf/libraries/caf/caf_overview.rst | 2 +- doc/nrf/libraries/caf/click_detector.rst | 14 ++-- doc/nrf/libraries/caf/leds.rst | 20 +++--- doc/nrf/libraries/caf/power_manager.rst | 12 ++-- doc/nrf/libraries/caf/sensor_sampler.rst | 16 ++--- doc/nrf/libraries/debug/cpu_load.rst | 2 +- doc/nrf/libraries/dfu/dfu_target.rst | 8 +-- doc/nrf/libraries/modem/at_cmd.rst | 2 +- doc/nrf/libraries/modem/at_monitor.rst | 2 +- doc/nrf/libraries/modem/lte_lc.rst | 16 ++--- .../libraries/modem/modem_attest_token.rst | 6 +- doc/nrf/libraries/modem/modem_jwt.rst | 4 +- doc/nrf/libraries/modem/modem_key_mgmt.rst | 2 +- doc/nrf/libraries/modem/nrf_modem_lib.rst | 16 ++--- doc/nrf/libraries/modem/pdn.rst | 6 +- doc/nrf/libraries/modem/sms.rst | 6 +- doc/nrf/libraries/mpsl/mpsl_assert.rst | 2 +- doc/nrf/libraries/networking/aws_fota.rst | 6 +- doc/nrf/libraries/networking/aws_iot.rst | 34 +++++----- doc/nrf/libraries/networking/aws_jobs.rst | 2 +- doc/nrf/libraries/networking/azure_fota.rst | 14 ++-- .../libraries/networking/azure_iot_hub.rst | 30 ++++----- doc/nrf/libraries/networking/coap_utils.rst | 2 +- .../libraries/networking/download_client.rst | 6 +- doc/nrf/libraries/networking/ftp_client.rst | 4 +- .../networking/lwm2m_client_utils.rst | 16 ++--- .../networking/multicell_location.rst | 24 +++---- doc/nrf/libraries/networking/nrf_cloud.rst | 26 ++++---- .../libraries/networking/nrf_cloud_agps.rst | 4 +- .../networking/nrf_cloud_cell_pos.rst | 4 +- .../libraries/networking/nrf_cloud_pgps.rst | 32 +++++----- doc/nrf/libraries/others/bl_crypto.rst | 12 ++-- doc/nrf/libraries/others/bl_storage.rst | 4 +- doc/nrf/libraries/others/date_time.rst | 6 +- doc/nrf/libraries/others/ei_wrapper.rst | 12 ++-- doc/nrf/libraries/others/event_manager.rst | 6 +- doc/nrf/libraries/others/fw_info.rst | 4 +- doc/nrf/libraries/others/hw_unique_key.rst | 6 +- doc/nrf/libraries/others/memfault_ncs.rst | 54 ++++++++-------- doc/nrf/libraries/others/profiler.rst | 8 +-- doc/nrf/libraries/others/secure_services.rst | 4 +- doc/nrf/libraries/others/supl_os_client.rst | 2 +- doc/nrf/libraries/tfm/tfm_ioctl_api.rst | 2 +- doc/nrf/libraries/zigbee/zigbee_app_utils.rst | 4 +- .../libraries/zigbee/zigbee_error_handler.rst | 4 +- doc/nrf/libraries/zigbee/zigbee_fota.rst | 34 +++++----- .../zigbee/zigbee_logger_eprxzcl.rst | 4 +- .../libraries/zigbee/zigbee_zcl_scenes.rst | 10 +-- samples/bluetooth/alexa_gadget/README.rst | 2 +- samples/bluetooth/direct_test_mode/README.rst | 2 +- samples/bluetooth/mesh/chat/chat_cli.rst | 2 +- samples/bluetooth/mesh/light_ctrl/README.rst | 8 +-- samples/bluetooth/peripheral_uart/README.rst | 2 +- samples/bluetooth/rpc_host/README.rst | 4 +- samples/bootloader/README.rst | 14 ++-- samples/edge_impulse/wrapper/README.rst | 2 +- .../nrf5340/multiprotocol_rpmsg/README.rst | 10 +-- samples/nrf5340/netboot/README.rst | 6 +- samples/nrf9160/agps/README.rst | 8 +-- samples/nrf9160/aws_fota/README.rst | 2 +- samples/nrf9160/aws_iot/README.rst | 8 +-- samples/nrf9160/azure_fota/README.rst | 16 ++--- samples/nrf9160/azure_iot_hub/README.rst | 12 ++-- samples/nrf9160/cloud_client/README.rst | 6 +- samples/nrf9160/download/README.rst | 14 ++-- samples/nrf9160/lwm2m_client/README.rst | 4 +- samples/nrf9160/memfault/README.rst | 34 +++++----- samples/nrf9160/mqtt_simple/README.rst | 10 +-- samples/nrf9160/multicell_location/README.rst | 12 ++-- samples/nrf9160/sms/README.rst | 18 +++--- samples/nrf9160/udp/README.rst | 26 ++++---- samples/openthread/cli/README.rst | 6 +- samples/openthread/coprocessor/README.rst | 10 +-- samples/peripheral/radio_test/README.rst | 2 +- samples/zigbee/ncp/README.rst | 6 +- .../partition_manager/partition_manager.rst | 10 +-- tests/crypto/README.rst | 6 +- 152 files changed, 809 insertions(+), 816 deletions(-) diff --git a/applications/asset_tracker/README.rst b/applications/asset_tracker/README.rst index 5a63f92941af..7f6028d7e8c4 100644 --- a/applications/asset_tracker/README.rst +++ b/applications/asset_tracker/README.rst @@ -216,7 +216,7 @@ Alternatively, use the command line tool ``menuconfig`` or configure the options .. external_antenna_note_start .. note:: - For nRF9160 DK v0.15.0 and later, set the :option:`CONFIG_NRF9160_GPS_ANTENNA_EXTERNAL` option to ``y`` when building the application to achieve the best external antenna performance. + For nRF9160 DK v0.15.0 and later, set the :kconfig:`CONFIG_NRF9160_GPS_ANTENNA_EXTERNAL` option to ``y`` when building the application to achieve the best external antenna performance. .. external_antenna_note_end diff --git a/applications/asset_tracker_v2/README.rst b/applications/asset_tracker_v2/README.rst index 4a4289b4ab94..26136c637e1d 100644 --- a/applications/asset_tracker_v2/README.rst +++ b/applications/asset_tracker_v2/README.rst @@ -285,7 +285,7 @@ Check and configure the following configuration options for the application: .. option:: CONFIG_ASSET_TRACKER_V2_APP_VERSION - Configuration for providing the application version - The application publishes its version number as a part of the static device data. The default value for the application version is ``0.0.0-development``. To configure the application version, set :option:`CONFIG_ASSET_TRACKER_V2_APP_VERSION` to the desired version. + The application publishes its version number as a part of the static device data. The default value for the application version is ``0.0.0-development``. To configure the application version, set :kconfig:`CONFIG_ASSET_TRACKER_V2_APP_VERSION` to the desired version. .. option:: CONFIG_CLOUD_CLIENT_ID_USE_CUSTOM - Configuration for enabling the use of custom cloud client ID @@ -293,7 +293,7 @@ Check and configure the following configuration options for the application: .. option:: CLOUD_CLIENT_ID - Configuration for providing a custom cloud client ID - This application configuration sets a custom client ID for the respective cloud. For setting a custom client ID, you need to set :option:`CONFIG_CLOUD_CLIENT_ID_USE_CUSTOM` to ``y``. + This application configuration sets a custom client ID for the respective cloud. For setting a custom client ID, you need to set :kconfig:`CONFIG_CLOUD_CLIENT_ID_USE_CUSTOM` to ``y``. .. _default_config_values: @@ -335,17 +335,17 @@ You can set the mandatory library-specific Kconfig options in the :file:`prj.con Configurations for AWS IoT library ---------------------------------- -* :option:`CONFIG_AWS_IOT_BROKER_HOST_NAME` -* :option:`CONFIG_AWS_IOT_SEC_TAG` +* :kconfig:`CONFIG_AWS_IOT_BROKER_HOST_NAME` +* :kconfig:`CONFIG_AWS_IOT_SEC_TAG` Configurations for Azure IoT Hub library ---------------------------------------- -* :option:`CONFIG_AZURE_IOT_HUB_DPS_HOSTNAME` -* :option:`CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE` -* :option:`CONFIG_AZURE_IOT_HUB_SEC_TAG` -* :option:`CONFIG_AZURE_FOTA_SEC_TAG` +* :kconfig:`CONFIG_AZURE_IOT_HUB_DPS_HOSTNAME` +* :kconfig:`CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE` +* :kconfig:`CONFIG_AZURE_IOT_HUB_SEC_TAG` +* :kconfig:`CONFIG_AZURE_FOTA_SEC_TAG` .. note: The nRF Cloud library does not require any library-specific Kconfig options to be set. @@ -355,15 +355,15 @@ Optional library configurations You can add the following optional configurations to configure the heap or to provide additional information such as APN to the modem for registering with an LTE network: -* :option:`CONFIG_HEAP_MEM_POOL_SIZE` - Configures the size of the heap that is used by the application when encoding and sending data to the cloud. More information can be found in :ref:`memory_allocation`. -* :option:`CONFIG_PDN_DEFAULTS_OVERRIDE` - Used for manual configuration of the APN. Set the option to ``y`` to override the default PDP context configuration. -* :option:`CONFIG_PDN_DEFAULT_APN` - Used for manual configuration of the APN. An example is ``apn.example.com``. +* :kconfig:`CONFIG_HEAP_MEM_POOL_SIZE` - Configures the size of the heap that is used by the application when encoding and sending data to the cloud. More information can be found in :ref:`memory_allocation`. +* :kconfig:`CONFIG_PDN_DEFAULTS_OVERRIDE` - Used for manual configuration of the APN. Set the option to ``y`` to override the default PDP context configuration. +* :kconfig:`CONFIG_PDN_DEFAULT_APN` - Used for manual configuration of the APN. An example is ``apn.example.com``. The application supports Assisted GPS. To set the source of the A-GPS data, set the following options: -* :option:`CONFIG_AGPS_SRC_SUPL` - Sets the external SUPL Client library as A-GPS data source. See the documentation on :ref:`supl_client_lib`. -* :option:`CONFIG_AGPS_SRC_NRF_CLOUD` - Sets nRF Cloud as A-GPS data source. You must set nRF Cloud as the firmware cloud backend. +* :kconfig:`CONFIG_AGPS_SRC_SUPL` - Sets the external SUPL Client library as A-GPS data source. See the documentation on :ref:`supl_client_lib`. +* :kconfig:`CONFIG_AGPS_SRC_NRF_CLOUD` - Sets nRF Cloud as A-GPS data source. You must set nRF Cloud as the firmware cloud backend. Configuration files =================== @@ -406,7 +406,7 @@ Also, the device must be provisioned and configured with the certificates accord .. external_antenna_note_start .. note:: - For nRF9160 DK v0.15.0 and later, set the :option:`CONFIG_NRF9160_GPS_ANTENNA_EXTERNAL` option to ``y`` when building the application to achieve the best external antenna performance. + For nRF9160 DK v0.15.0 and later, set the :kconfig:`CONFIG_NRF9160_GPS_ANTENNA_EXTERNAL` option to ``y`` when building the application to achieve the best external antenna performance. .. external_antenna_note_end @@ -624,7 +624,7 @@ Following are some features that rely on dynamically allocated memory, using the * Event manager events * Encoding of the data that will be sent to cloud -You can configure the heap memory by using the :option:`CONFIG_HEAP_MEM_POOL_SIZE`. +You can configure the heap memory by using the :kconfig:`CONFIG_HEAP_MEM_POOL_SIZE`. The data management module that encodes data destined for cloud is the biggest consumer of heap memory. Therefore, when adjusting buffer sizes in the data management module, you must also adjust the heap accordingly. This avoids the problem of running out of heap memory in worst-case scenarios. diff --git a/applications/machine_learning/README.rst b/applications/machine_learning/README.rst index 357c90554a42..1965280b584c 100644 --- a/applications/machine_learning/README.rst +++ b/applications/machine_learning/README.rst @@ -464,7 +464,7 @@ The nRF Machine Learning application also uses the following dedicated applicati ``ei_data_forwarder_bt_nus`` The module forwards the sensor readouts over NUS to the connected Bluetooth Central. - The sensor data is forwarded only if the connection is secured and connection interval is within the limit defined by :option:`CONFIG_BT_PERIPHERAL_PREF_MAX_INT` and :option:`CONFIG_BT_PERIPHERAL_PREF_MAX_INT`. + The sensor data is forwarded only if the connection is secured and connection interval is within the limit defined by :kconfig:`CONFIG_BT_PERIPHERAL_PREF_MAX_INT` and :kconfig:`CONFIG_BT_PERIPHERAL_PREF_MAX_INT`. ``ei_data_forwarder_uart`` The module forwards the sensor readouts over UART. diff --git a/applications/nrf_desktop/README.rst b/applications/nrf_desktop/README.rst index 62e1582dc803..6462c0a0daaf 100644 --- a/applications/nrf_desktop/README.rst +++ b/applications/nrf_desktop/README.rst @@ -169,7 +169,7 @@ The application uses dynamic allocation to: When configuring HEAP, make sure that the values for the following options match the typical event size and the system needs: -* :option:`CONFIG_HEAP_MEM_POOL_SIZE` - The size must be big enough to handle the worst possible use case for the given device. +* :kconfig:`CONFIG_HEAP_MEM_POOL_SIZE` - The size must be big enough to handle the worst possible use case for the given device. .. important:: The nRF Desktop uses ``k_heap`` as the backend for dynamic allocation. @@ -694,7 +694,7 @@ For example, LEDs are turned off and advertising is stopped. Moving the mouse or pressing any button wakes up the device and turns on the disabled functionalities. -You can define the amount of time after which the peripherals are suspended or powered off in :option:`CONFIG_CAF_POWER_MANAGER_TIMEOUT`. +You can define the amount of time after which the peripherals are suspended or powered off in :kconfig:`CONFIG_CAF_POWER_MANAGER_TIMEOUT`. By default, this period is set to 120 seconds. .. important:: @@ -760,7 +760,7 @@ After building the application with or without :ref:`specifying the build type < .. note:: You can manually start the scanning for new peripheral devices by pressing the **SW1** button on the dongle for a short time. This might be needed if the dongle does not connect with all the peripherals before timeout. - The scanning is interrupted after the amount of time predefined in :option:`CONFIG_DESKTOP_BLE_SCAN_DURATION_S`, because it negatively affects the performance of already connected peripherals. + The scanning is interrupted after the amount of time predefined in :kconfig:`CONFIG_DESKTOP_BLE_SCAN_DURATION_S`, because it negatively affects the performance of already connected peripherals. #. Move the mouse and press any key on the keyboard. The input is reflected on the host. @@ -953,7 +953,7 @@ To use the nRF Desktop application with your custom board: a. Ensure that the Bluetooth role is properly configured. For mouse, it should be configured as peripheral. #. Update the configuration related to peer control. - You can also disable the peer control using the :option:`CONFIG_DESKTOP_BLE_PEER_CONTROL` option. + You can also disable the peer control using the :kconfig:`CONFIG_DESKTOP_BLE_PEER_CONTROL` option. Peer control details are described in the :ref:`nrf_desktop_ble_bond` documentation. Refer to the :ref:`nrf_desktop_bluetooth_guide` section and Zephyr's :ref:`zephyr:bluetooth` page for more detailed information about the Bluetooth configuration. @@ -1158,8 +1158,8 @@ Since the nRF Desktop application uses the partition manager when the bootloader .. important:: By default, Zephyr does not use the code partition defined in the DTS files. - It is only used if :option:`CONFIG_USE_DT_CODE_PARTITION` is enabled. - If this option is disabled, the code is loaded at the address defined by :option:`CONFIG_FLASH_LOAD_OFFSET` and can spawn for :option:`CONFIG_FLASH_LOAD_SIZE` (or for the whole flash if the load size is set to zero). + It is only used if :kconfig:`CONFIG_USE_DT_CODE_PARTITION` is enabled. + If this option is disabled, the code is loaded at the address defined by :kconfig:`CONFIG_FLASH_LOAD_OFFSET` and can spawn for :kconfig:`CONFIG_FLASH_LOAD_SIZE` (or for the whole flash if the load size is set to zero). Because the nRF Desktop application depends on the DTS layout only for configurations without the bootloader, only the settings partition is relevant in such cases and other partitions are ignored. @@ -1209,13 +1209,13 @@ The nRF Desktop devices come in the following types: * Peripheral devices (mouse or keyboard) - * Support only the Bluetooth Peripheral role (:option:`CONFIG_BT_PERIPHERAL`). + * Support only the Bluetooth Peripheral role (:kconfig:`CONFIG_BT_PERIPHERAL`). * Handle only one Bluetooth LE connection at a time. * Use more than one Bluetooth local identity. * Central devices (dongle) - * Support only the Bluetooth Central role (:option:`CONFIG_BT_CENTRAL`). + * Support only the Bluetooth Central role (:kconfig:`CONFIG_BT_CENTRAL`). * Handle multiple Bluetooth LE connections simultaneously. * Use only one Bluetooth local identity (the default one). @@ -1237,12 +1237,12 @@ Configuration options This section describes the most important Bluetooth Kconfig options common for all nRF Desktop devices. For detailed information about every option, see the Kconfig help. -* :option:`CONFIG_BT_MAX_PAIRED` +* :kconfig:`CONFIG_BT_MAX_PAIRED` * nRF Desktop central: The maximum number of paired devices is greater than or equal to the maximum number of simultaneously connected peers. * nRF Desktop peripheral: The maximum number of paired devices is equal to the number of peers plus one, where the one additional paired device slot is used for erase advertising. -* :option:`CONFIG_BT_ID_MAX` +* :kconfig:`CONFIG_BT_ID_MAX` * nRF Desktop central: The device uses only one Bluetooth local identity, that is the default one. * nRF Desktop peripheral: The number of Bluetooth local identities must be equal to the number of peers plus two. @@ -1251,7 +1251,7 @@ For detailed information about every option, see the Kconfig help. * The other additional local identity is the default local identity, which is unused, because it cannot be reset after removing the bond. Without the identity reset, the previously bonded central could still try to reconnect after being removed from Bluetooth bonds on the peripheral side. -* :option:`CONFIG_BT_MAX_CONN` +* :kconfig:`CONFIG_BT_MAX_CONN` * nRF Desktop central: Set the option to the maximum number of simultaneously connected devices. * nRF Desktop peripheral: The default value (one) is used. @@ -1267,22 +1267,22 @@ Link Layer configuration options The nRF Desktop devices use one of the following Link Layers: -* :option:`CONFIG_BT_LL_SW_SPLIT` +* :kconfig:`CONFIG_BT_LL_SW_SPLIT` This Link Layer does not support the Low Latency Packet Mode (LLPM) and has a lower memory usage, so it can be used by memory-limited devices. -* :option:`CONFIG_BT_LL_SOFTDEVICE` +* :kconfig:`CONFIG_BT_LL_SOFTDEVICE` This Link Layer does support the Low Latency Packet Mode (LLPM). - If you opt for this Link Layer and enable the :option:`CONFIG_BT_CTLR_LLPM`, the :option:`CONFIG_CAF_BLE_USE_LLPM` is also enabled by default and can be configured further: + If you opt for this Link Layer and enable the :kconfig:`CONFIG_BT_CTLR_LLPM`, the :kconfig:`CONFIG_CAF_BLE_USE_LLPM` is also enabled by default and can be configured further: - * When :option:`CONFIG_CAF_BLE_USE_LLPM` is enabled, set the value for :option:`CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT` to ``3000``. + * When :kconfig:`CONFIG_CAF_BLE_USE_LLPM` is enabled, set the value for :kconfig:`CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT` to ``3000``. This is required by the nRF Desktop central and helps avoid scheduling conflicts with Bluetooth Link Layer. Such conflicts could lead to a drop in HID input report rate or a disconnection. Setting the value to ``3000`` also enables the nRF Desktop central to exchange data with up to 2 standard Bluetooth LE peripherals during every connection interval (every 7.5 ms). - * When :option:`CONFIG_CAF_BLE_USE_LLPM` is disabled, the device will use only standard Bluetooth LE connection parameters with the lowest available connection interval of 7.5 ms. + * When :kconfig:`CONFIG_CAF_BLE_USE_LLPM` is disabled, the device will use only standard Bluetooth LE connection parameters with the lowest available connection interval of 7.5 ms. - If the LLPM is disabled and more than 2 simultaneous Bluetooth connections are supported (:option:`CONFIG_BT_MAX_CONN`), you can set the value for :option:`CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT` to ``2500``. + If the LLPM is disabled and more than 2 simultaneous Bluetooth connections are supported (:kconfig:`CONFIG_BT_MAX_CONN`), you can set the value for :kconfig:`CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT` to ``2500``. With this value, the nRF Desktop central is able to exchange the data with up to 3 Bluetooth LE peripherals during every 7.5-ms connection interval. Using the value of ``3000`` for more than 2 simultaneous Bluetooth LE connections will result in a lower HID input report rate. @@ -1306,7 +1306,7 @@ Optionally, you can also enable the following module: The module can be used only with the SoftDevice Link Layer. .. note:: - The nRF Destkop devices enable :option:`CONFIG_BT_SETTINGS`. + The nRF Destkop devices enable :kconfig:`CONFIG_BT_SETTINGS`. When this option is enabled, the application is responsible for calling the :c:func:`settings_load` function - this is handled by the :ref:`nrf_desktop_settings_loader`. .. _nrf_desktop_bluetooth_guide_peripheral: @@ -1320,7 +1320,7 @@ The HID over GATT profile specification requires Bluetooth Peripherals to define * HID Service - Handled in the :ref:`nrf_desktop_hids`. * Battery Service - Handled in the :ref:`nrf_desktop_bas`. -* Device Information Service - Implemented in Zephyr and enabled with :option:`CONFIG_BT_DIS`. +* Device Information Service - Implemented in Zephyr and enabled with :kconfig:`CONFIG_BT_DIS`. It can be configured using Kconfig options with the ``CONFIG_BT_DIS`` prefix. The nRF Desktop peripherals must also define a dedicated GATT Service, which is used to provide the following information: @@ -1399,25 +1399,25 @@ The nRF Desktop application can use one of the following bootloaders: Configuring the B0 bootloader ----------------------------- -To enable the B0 bootloader, select the :option:`CONFIG_SECURE_BOOT` Kconfig option. +To enable the B0 bootloader, select the :kconfig:`CONFIG_SECURE_BOOT` Kconfig option. The B0 bootloader requires the following options enabled: -* :option:`CONFIG_SB_SIGNING_KEY_FILE` - Required for providing the signature used for image signing and verification. -* :option:`CONFIG_FW_INFO` - Required for the application versioning information. -* :option:`CONFIG_FW_INFO_FIRMWARE_VERSION` - Enable this option to set the version of the application after you enabled :option:`CONFIG_FW_INFO`. -* :option:`CONFIG_BUILD_S1_VARIANT` - Required for the build system to be able to construct the application binaries for both application's slots in flash memory. +* :kconfig:`CONFIG_SB_SIGNING_KEY_FILE` - Required for providing the signature used for image signing and verification. +* :kconfig:`CONFIG_FW_INFO` - Required for the application versioning information. +* :kconfig:`CONFIG_FW_INFO_FIRMWARE_VERSION` - Enable this option to set the version of the application after you enabled :kconfig:`CONFIG_FW_INFO`. +* :kconfig:`CONFIG_BUILD_S1_VARIANT` - Required for the build system to be able to construct the application binaries for both application's slots in flash memory. Configuring the MCUboot bootloader ---------------------------------- -To enable the MCUboot bootloader, select the :option:`CONFIG_BOOTLOADER_MCUBOOT` Kconfig option. +To enable the MCUboot bootloader, select the :kconfig:`CONFIG_BOOTLOADER_MCUBOOT` Kconfig option. Configure the MCUboot bootloader with the following options: * ``CONFIG_BOOT_SIGNATURE_KEY_FILE`` - This option defines the path to the private key that is used to sign the application and that is used by the bootloader to verify the application signature. The key must be defined only in the MCUboot bootloader configuration file. -* :option:`CONFIG_IMG_MANAGER` and :option:`CONFIG_MCUBOOT_IMG_MANAGER` - These options allow the application to manage the DFU image. +* :kconfig:`CONFIG_IMG_MANAGER` and :kconfig:`CONFIG_MCUBOOT_IMG_MANAGER` - These options allow the application to manage the DFU image. Enable both of them only for configurations that support :ref:`background DFU `. For these configurations, the :ref:`nrf_desktop_dfu` uses the provided API to request firmware upgrade and confirm the running image. @@ -1448,7 +1448,7 @@ The update image is generated in the build directory when building the firmware .. note:: By default, the build process for the B0 bootloader will construct an image for the first slot (slot 0 or S0). - To ensure that application is built for both slots, select the :option:`CONFIG_BUILD_S1_VARIANT` Kconfig option. + To ensure that application is built for both slots, select the :kconfig:`CONFIG_BUILD_S1_VARIANT` Kconfig option. When this option is selected, the :file:`zephyr/dfu_application.zip` contains both images. The update tool checks if the currently running image runs from either slot 0 or slot 1. diff --git a/applications/nrf_desktop/doc/bas.rst b/applications/nrf_desktop/doc/bas.rst index 79fa9c838c9d..699abf316935 100644 --- a/applications/nrf_desktop/doc/bas.rst +++ b/applications/nrf_desktop/doc/bas.rst @@ -22,8 +22,8 @@ Module events Configuration ************* -The module is enabled with the :option:`CONFIG_DESKTOP_BAS_ENABLE` option. -The option is selected by :option:`CONFIG_DESKTOP_HID_PERIPHERAL` -- Battery Service is required for the HID peripheral device. +The module is enabled with the :kconfig:`CONFIG_DESKTOP_BAS_ENABLE` option. +The option is selected by :kconfig:`CONFIG_DESKTOP_HID_PERIPHERAL` -- Battery Service is required for the HID peripheral device. Implementation details ********************** diff --git a/applications/nrf_desktop/doc/battery_charger.rst b/applications/nrf_desktop/doc/battery_charger.rst index eaaf83583124..5e68f2e52f07 100644 --- a/applications/nrf_desktop/doc/battery_charger.rst +++ b/applications/nrf_desktop/doc/battery_charger.rst @@ -23,22 +23,22 @@ Configuration ************* The module implemented in :file:`battery_charger.c` uses Zephyr's :ref:`zephyr:gpio_api` driver to control and monitor battery charging. -For this reason, you should set :option:`CONFIG_GPIO` option. +For this reason, you should set :kconfig:`CONFIG_GPIO` option. -By default, the module is disabled and the :option:`CONFIG_DESKTOP_BATTERY_CHARGER_NONE` option is selected. -Set the option :option:`CONFIG_DESKTOP_BATTERY_CHARGER_DISCRETE` to enable the module. +By default, the module is disabled and the :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_NONE` option is selected. +Set the option :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_DISCRETE` to enable the module. The following module configuration options are available: -* :option:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_PIN` - Configures the pin to which the charge status output (CSO) from the charger is connected. +* :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_PIN` - Configures the pin to which the charge status output (CSO) from the charger is connected. - * :option:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_PULL_NONE` - CSO pin pull disabled (default setting). - * :option:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_PULL_UP` - CSO pin pull up. - * :option:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_PULL_DOWN` - CSO pin pull down. + * :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_PULL_NONE` - CSO pin pull disabled (default setting). + * :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_PULL_UP` - CSO pin pull up. + * :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_PULL_DOWN` - CSO pin pull down. -* :option:`CONFIG_DESKTOP_BATTERY_CHARGER_ENABLE_PIN` - Configures the pin that enables the battery charging. -* :option:`CONFIG_DESKTOP_BATTERY_CHARGER_ENABLE_INVERSED` - Option for inversing the charging enable signal. -* :option:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_FREQ` - Set this Kconfig option to the CSO pin state switching frequency (in Hz) for when a charging error occurs. +* :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_ENABLE_PIN` - Configures the pin that enables the battery charging. +* :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_ENABLE_INVERSED` - Option for inversing the charging enable signal. +* :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_FREQ` - Set this Kconfig option to the CSO pin state switching frequency (in Hz) for when a charging error occurs. Implementation details ********************** @@ -59,4 +59,4 @@ The battery state can have one of the following values: * :c:enumerator:`BATTERY_STATE_IDLE` - Battery is not being charged (CSO pin set to logical high). * :c:enumerator:`BATTERY_STATE_CHARGING` - Battery is being charged (CSO pin set to logical low). -* :c:enumerator:`BATTERY_STATE_ERROR` - Battery charger reported an error (a signal with the :option:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_FREQ` frequency and a 50% duty cycle on the CSO pin). +* :c:enumerator:`BATTERY_STATE_ERROR` - Battery charger reported an error (a signal with the :kconfig:`CONFIG_DESKTOP_BATTERY_CHARGER_CSO_FREQ` frequency and a 50% duty cycle on the CSO pin). diff --git a/applications/nrf_desktop/doc/battery_meas.rst b/applications/nrf_desktop/doc/battery_meas.rst index 7d08f2c6da9a..31f5562cf2a9 100644 --- a/applications/nrf_desktop/doc/battery_meas.rst +++ b/applications/nrf_desktop/doc/battery_meas.rst @@ -25,18 +25,18 @@ Configuration The |battery_meas| uses Zephyr's :ref:`zephyr:adc_api` driver to measure voltage. For this reason, set the following options: -* :option:`CONFIG_ADC` - The module's implementation uses Zephyr ADC driver. -* :option:`CONFIG_ADC_ASYNC` - The module's implementation uses asynchronous calls. -* :option:`CONFIG_ADC_NRFX_SAADC` - The module's implementation uses nrfx SAADC driver for nRF52 MCU series. +* :kconfig:`CONFIG_ADC` - The module's implementation uses Zephyr ADC driver. +* :kconfig:`CONFIG_ADC_ASYNC` - The module's implementation uses asynchronous calls. +* :kconfig:`CONFIG_ADC_NRFX_SAADC` - The module's implementation uses nrfx SAADC driver for nRF52 MCU series. -Set :option:`CONFIG_DESKTOP_BATTERY_MEAS` to enable the module. -Also, make sure to define :option:`CONFIG_DESKTOP_BATTERY_MEAS_POLL_INTERVAL_MS`, that is the amount of time between the subsequent battery measurements (in ms). +Set :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS` to enable the module. +Also, make sure to define :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS_POLL_INTERVAL_MS`, that is the amount of time between the subsequent battery measurements (in ms). -If the measurement circuit contains a voltage divider made of two resistors, set the :option:`CONFIG_DESKTOP_BATTERY_MEAS_HAS_VOLTAGE_DIVIDER` option. +If the measurement circuit contains a voltage divider made of two resistors, set the :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS_HAS_VOLTAGE_DIVIDER` option. The following defines specify the values of these two resistors (in kOhm): -* :option:`CONFIG_DESKTOP_BATTERY_MEAS_VOLTAGE_DIVIDER_UPPER` - Upper resistor. -* :option:`CONFIG_DESKTOP_BATTERY_MEAS_VOLTAGE_DIVIDER_LOWER` - Lower resistor. +* :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS_VOLTAGE_DIVIDER_UPPER` - Upper resistor. +* :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS_VOLTAGE_DIVIDER_LOWER` - Lower resistor. The module measures the voltage over the lower resistor. @@ -45,14 +45,14 @@ You can find this file the in board-specific directory in the application config Remember to also define the following battery parameters (otherwise, the default values will be used): -* :option:`CONFIG_DESKTOP_BATTERY_MEAS_MIN_LEVEL` - Battery voltage in mV that corresponds to the 0% battery level. -* :option:`CONFIG_DESKTOP_BATTERY_MEAS_MAX_LEVEL` - Battery voltage in mV that corresponds to the 100% battery level. -* :option:`CONFIG_DESKTOP_VOLTAGE_TO_SOC_DELTA` - Difference in mV between the adjacent elements in the conversion lookup table. +* :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS_MIN_LEVEL` - Battery voltage in mV that corresponds to the 0% battery level. +* :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS_MAX_LEVEL` - Battery voltage in mV that corresponds to the 100% battery level. +* :kconfig:`CONFIG_DESKTOP_VOLTAGE_TO_SOC_DELTA` - Difference in mV between the adjacent elements in the conversion lookup table. -If a pin is used to enable the battery measurement, enable the :option:`CONFIG_DESKTOP_BATTERY_MEAS_HAS_ENABLE_PIN` option. -The number of the pin used for this purpose must be defined as :option:`CONFIG_DESKTOP_BATTERY_MEAS_ENABLE_PIN`. +If a pin is used to enable the battery measurement, enable the :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS_HAS_ENABLE_PIN` option. +The number of the pin used for this purpose must be defined as :kconfig:`CONFIG_DESKTOP_BATTERY_MEAS_ENABLE_PIN`. The implementation uses the ``GPIO0`` port. -Because Zephyr's :ref:`zephyr:gpio_api` driver is used to control this pin, also set the :option:`CONFIG_GPIO` option. +Because Zephyr's :ref:`zephyr:gpio_api` driver is used to control this pin, also set the :kconfig:`CONFIG_GPIO` option. Implementation details ********************** diff --git a/applications/nrf_desktop/doc/ble_adv.rst b/applications/nrf_desktop/doc/ble_adv.rst index dc258db29a4d..67f89c928a39 100644 --- a/applications/nrf_desktop/doc/ble_adv.rst +++ b/applications/nrf_desktop/doc/ble_adv.rst @@ -31,7 +31,7 @@ Avoiding connection requests from unbonded centrals when bonded =============================================================== If the Bluetooth local identity currently in use already has a bond and the nRF Desktop device uses indirect advertising, the device will not set the General Discoverable flag. -The nRF desktop devices also enable :option:`CONFIG_BT_WHITELIST` to whitelist incoming scan response data requests and connection requests. +The nRF desktop devices also enable :kconfig:`CONFIG_BT_WHITELIST` to whitelist incoming scan response data requests and connection requests. This is done to prevent Bluetooth Centrals other than the bonded one from connecting with the device. The nRF Desktop dongle scans for peripheral devices using the Bluetooth device name, which is provided in the scan response data. diff --git a/applications/nrf_desktop/doc/ble_bond.rst b/applications/nrf_desktop/doc/ble_bond.rst index d2a021648c8f..f7a130c39b46 100644 --- a/applications/nrf_desktop/doc/ble_bond.rst +++ b/applications/nrf_desktop/doc/ble_bond.rst @@ -109,7 +109,7 @@ The application local identity still uses the Bluetooth local identity that was The erase advertising timeout can be extended in case a new peer connects. This ensures that a new peer will have time to establish the Bluetooth security level. - The timeout is increased to a bigger value when the passkey authentication is enabled (:option:`CONFIG_DESKTOP_BLE_ENABLE_PASSKEY`). + The timeout is increased to a bigger value when the passkey authentication is enabled (:kconfig:`CONFIG_DESKTOP_BLE_ENABLE_PASSKEY`). This gives the end user enough time to enter the passkey. Standby states @@ -146,17 +146,17 @@ Peer control using a button Complete the following steps to let the user control Bluetooth peers using the dedicated button: -1. Set the :option:`CONFIG_DESKTOP_BLE_PEER_CONTROL` option to enable the feature. +1. Set the :kconfig:`CONFIG_DESKTOP_BLE_PEER_CONTROL` option to enable the feature. #. Configure the :ref:`caf_buttons`. -#. Define the button's key ID as :option:`CONFIG_DESKTOP_BLE_PEER_CONTROL_BUTTON`. +#. Define the button's key ID as :kconfig:`CONFIG_DESKTOP_BLE_PEER_CONTROL_BUTTON`. #. Add the button to the :ref:`nrf_desktop_click_detector` configuration, because the |ble_bond| reacts on ``click_event``. The following peer operations can be enabled: -* :option:`CONFIG_DESKTOP_BLE_PEER_ERASE` - Bluetooth LE peer erase triggered at any time. -* :option:`CONFIG_DESKTOP_BLE_PEER_ERASE_ON_START` - Erase advertising triggered by long press of the predefined button on system start. +* :kconfig:`CONFIG_DESKTOP_BLE_PEER_ERASE` - Bluetooth LE peer erase triggered at any time. +* :kconfig:`CONFIG_DESKTOP_BLE_PEER_ERASE_ON_START` - Erase advertising triggered by long press of the predefined button on system start. This option can be used only by nRF Desktop peripheral. -* :option:`CONFIG_DESKTOP_BLE_PEER_SELECT` - Select Bluetooth LE peer. +* :kconfig:`CONFIG_DESKTOP_BLE_PEER_SELECT` - Select Bluetooth LE peer. This option can be used only by nRF Desktop peripheral. * ``CONFIG_DESKTOP0_BLE_NEW_PEER_SCAN_REQUEST`` - Scan for new Bluetooth peers. This option can be used only by nRF Desktop central. @@ -167,7 +167,7 @@ Peer control using a hardware selector .. note:: This feature can be used only by nRF Desktop peripheral devices. -Set the :option:`CONFIG_DESKTOP_BLE_DONGLE_PEER_ENABLE` option to use the dedicated local identity to connect with the dongle. +Set the :kconfig:`CONFIG_DESKTOP_BLE_DONGLE_PEER_ENABLE` option to use the dedicated local identity to connect with the dongle. The last application local identity (the one with the highest ID) is used for this purpose. The dongle is the nRF Desktop central. @@ -177,8 +177,8 @@ This local identity is meant to be paired with the dongle during the production The dongle peer is selected using the :ref:`nrf_desktop_selector`. You must also define the following parameters of the selector used to switch between dongle peer and other Bluetooth LE peers: -* :option:`CONFIG_DESKTOP_BLE_DONGLE_PEER_SELECTOR_ID` - Selector ID. -* :option:`CONFIG_DESKTOP_BLE_DONGLE_PEER_SELECTOR_POS` - Selector position for the dongle peer (when selector is in other position, other Bluetooth peers are selected). +* :kconfig:`CONFIG_DESKTOP_BLE_DONGLE_PEER_SELECTOR_ID` - Selector ID. +* :kconfig:`CONFIG_DESKTOP_BLE_DONGLE_PEER_SELECTOR_POS` - Selector position for the dongle peer (when selector is in other position, other Bluetooth peers are selected). .. note:: The Bluetooth local identity used for the dongle peer does not provide any special capabilities. @@ -191,7 +191,7 @@ Default Bluetooth local identity on peripheral ============================================== By default, the default Bluetooth local identity is unused, because it cannot be reset. -You can set :option:`CONFIG_DESKTOP_BLE_USE_DEFAULT_ID` to make the nRF Desktop peripheral initially use the default Bluetooth local identity for the application local identity with ID ``0``. +You can set :kconfig:`CONFIG_DESKTOP_BLE_USE_DEFAULT_ID` to make the nRF Desktop peripheral initially use the default Bluetooth local identity for the application local identity with ID ``0``. After the successful erase advertising for application local identity with ID ``0``, the default Bluetooth local identity is switched out and it is no longer used. The peer bonded with the default Bluetooth local identity is unpaired. diff --git a/applications/nrf_desktop/doc/ble_conn_params.rst b/applications/nrf_desktop/doc/ble_conn_params.rst index f5a710df19e8..c6beb4dd9589 100644 --- a/applications/nrf_desktop/doc/ble_conn_params.rst +++ b/applications/nrf_desktop/doc/ble_conn_params.rst @@ -26,7 +26,7 @@ Configuration ************* The module requires the basic Bluetooth configuration, as described in :ref:`nrf_desktop_bluetooth_guide`. -The module is automatically enabled for every nRF Desktop central device (:option:`CONFIG_BT_CENTRAL`). +The module is automatically enabled for every nRF Desktop central device (:kconfig:`CONFIG_BT_CENTRAL`). Implementation details ********************** @@ -54,7 +54,7 @@ After the :ref:`nrf_desktop_ble_discovery` completes the peripheral discovery, t * If the central and the connected peripheral both support the Low Latency Packet Mode (LLPM), the connection interval is set to **1 ms**. * If neither the central nor the connected peripheral support LLPM, or if only one of them supports it, the interval is set to the following values: - * **7.5 ms** if LLPM is not supported by the central or :option:`CONFIG_BT_MAX_CONN` is set to value 2 or lower. + * **7.5 ms** if LLPM is not supported by the central or :kconfig:`CONFIG_BT_MAX_CONN` is set to value 2 or lower. This is the shortest interval allowed by the standard Bluetooth. * **10 ms** otherwise. This is required to avoid Bluetooth Link Layer scheduling conflicts that could lead to HID report rate drop. diff --git a/applications/nrf_desktop/doc/ble_discovery.rst b/applications/nrf_desktop/doc/ble_discovery.rst index a1910a4d08fd..d05f25f220e2 100644 --- a/applications/nrf_desktop/doc/ble_discovery.rst +++ b/applications/nrf_desktop/doc/ble_discovery.rst @@ -26,8 +26,8 @@ Configuration Complete the following steps to configure the module: 1. Complete the basic Bluetooth configuration, as described in :ref:`nrf_desktop_bluetooth_guide`. -#. Set the :option:`CONFIG_BT_GATT_CLIENT` Kconfig option to enable support for the GATT Client role. -#. Set the :option:`CONFIG_BT_GATT_DM` Kconfig option to enable the :ref:`gatt_dm_readme`. +#. Set the :kconfig:`CONFIG_BT_GATT_CLIENT` Kconfig option to enable support for the GATT Client role. +#. Set the :kconfig:`CONFIG_BT_GATT_DM` Kconfig option to enable the :ref:`gatt_dm_readme`. The :ref:`gatt_dm_readme` is used by the ``ble_discovery`` application module. #. Define the module configuration in the :file:`ble_discovery_def.h` file, located in the board-specific directory in the application configuration directory. You must define the following parameters for every nRF Desktop peripheral that connects with the given nRF Desktop central: @@ -49,7 +49,7 @@ Complete the following steps to configure the module: The assigned PIDs should be unique for devices with the same VID. -#. Set the :option:`CONFIG_DESKTOP_BLE_DISCOVERY_ENABLE` Kconfig option to enable the ``ble_discovery`` application module. +#. Set the :kconfig:`CONFIG_DESKTOP_BLE_DISCOVERY_ENABLE` Kconfig option to enable the ``ble_discovery`` application module. Implementation details ********************** diff --git a/applications/nrf_desktop/doc/ble_latency.rst b/applications/nrf_desktop/doc/ble_latency.rst index eb21f34cfb16..f7bba14d68e6 100644 --- a/applications/nrf_desktop/doc/ble_latency.rst +++ b/applications/nrf_desktop/doc/ble_latency.rst @@ -30,10 +30,10 @@ Configuration The module requires the basic Bluetooth configuration, as described in :ref:`nrf_desktop_bluetooth_guide`. The module is enabled for every nRF Desktop peripheral device. -You can use the option :option:`CONFIG_DESKTOP_BLE_SECURITY_FAIL_TIMEOUT_S` to define the maximum allowed time for establishing the connection security. +You can use the option :kconfig:`CONFIG_DESKTOP_BLE_SECURITY_FAIL_TIMEOUT_S` to define the maximum allowed time for establishing the connection security. If the connection is not secured during this period of time, the peripheral device disconnects. -You can set the option :option:`CONFIG_DESKTOP_BLE_LOW_LATENCY_LOCK` to keep the connection latency low for the LLPM connections. +You can set the option :kconfig:`CONFIG_DESKTOP_BLE_LOW_LATENCY_LOCK` to keep the connection latency low for the LLPM connections. This speeds up sending the first HID report after not sending a report for some connection intervals. Enabling this option increases the power consumption - the connection latency is kept low unless the device is in the low power mode. @@ -52,10 +52,10 @@ The module listens for the following events related to data transfer initiated b * ``ble_smp_transfer_event`` - This event is received when the firmware update is received by :ref:`nrf_desktop_ble_smp`. When these events are received, the module sets the connection latency to low. -When the :ref:`nrf_desktop_config_channel` is no longer in use and firmware update is not received by :ref:`nrf_desktop_ble_smp` (no mentioned events for ``LOW_LATENCY_CHECK_PERIOD_MS``), the module sets the connection latency to :option:`CONFIG_BT_PERIPHERAL_PREF_SLAVE_LATENCY` to reduce the power consumption. +When the :ref:`nrf_desktop_config_channel` is no longer in use and firmware update is not received by :ref:`nrf_desktop_ble_smp` (no mentioned events for ``LOW_LATENCY_CHECK_PERIOD_MS``), the module sets the connection latency to :kconfig:`CONFIG_BT_PERIPHERAL_PREF_SLAVE_LATENCY` to reduce the power consumption. .. note:: - If the option :option:`CONFIG_DESKTOP_BLE_LOW_LATENCY_LOCK` is enabled, the LLPM connection latency is not increased unless the device is in the low power mode. + If the option :kconfig:`CONFIG_DESKTOP_BLE_LOW_LATENCY_LOCK` is enabled, the LLPM connection latency is not increased unless the device is in the low power mode. When the device is in the low power mode and the events related to data transfer are not received, the connection latency is set to higher value to reduce the power consumption. diff --git a/applications/nrf_desktop/doc/ble_passkey.rst b/applications/nrf_desktop/doc/ble_passkey.rst index e60c29cafb20..d18001beca7d 100644 --- a/applications/nrf_desktop/doc/ble_passkey.rst +++ b/applications/nrf_desktop/doc/ble_passkey.rst @@ -23,9 +23,9 @@ Configuration ************* The module requires the basic Bluetooth configuration, as described in :ref:`nrf_desktop_bluetooth_guide`. -The module can be used only for Bluetooth Peripheral devices (:option:`CONFIG_BT_PERIPHERAL`). +The module can be used only for Bluetooth Peripheral devices (:kconfig:`CONFIG_BT_PERIPHERAL`). -Use the option :option:`CONFIG_DESKTOP_BLE_ENABLE_PASSKEY` to enable the module. +Use the option :kconfig:`CONFIG_DESKTOP_BLE_ENABLE_PASSKEY` to enable the module. Make sure to enable and configure the :ref:`nrf_desktop_passkey` if you decide to use this option. Implementation details @@ -43,4 +43,4 @@ The passkey input is handled in the :ref:`nrf_desktop_passkey`. .. note:: By default, Zephyr's Bluetooth Peripheral demands the security level 3 in case the passkey authentication is enabled. If the nRF Desktop dongle is unable to achieve the security level 3, it will be unable to connect with the peripheral. - Disable the :option:`CONFIG_BT_SMP_ENFORCE_MITM` option to allow the dongle to connect without the authentication. + Disable the :kconfig:`CONFIG_BT_SMP_ENFORCE_MITM` option to allow the dongle to connect without the authentication. diff --git a/applications/nrf_desktop/doc/ble_qos.rst b/applications/nrf_desktop/doc/ble_qos.rst index e7e9fe7f8231..69322df79823 100644 --- a/applications/nrf_desktop/doc/ble_qos.rst +++ b/applications/nrf_desktop/doc/ble_qos.rst @@ -8,7 +8,7 @@ Bluetooth LE Quality of Service module :depth: 2 Use the Bluetooth LE Quality of Service (QoS) module to achieve better connection quality and higher report rate by avoiding congested RF channels. -The module can be used by both nRF Desktop peripheral and nRF Desktop central with the SoftDevice Link Layer (:option:`CONFIG_BT_LL_SOFTDEVICE`). +The module can be used by both nRF Desktop peripheral and nRF Desktop central with the SoftDevice Link Layer (:kconfig:`CONFIG_BT_LL_SOFTDEVICE`). However, only the Bluetooth central can update the Bluetooth LE channel map that is in use. Module events @@ -27,27 +27,27 @@ Configuration The module requires the basic Bluetooth configuration, as described in :ref:`nrf_desktop_bluetooth_guide`. The QoS module uses the ``chmap_filter`` library, whose API is described in :file:`src/util/chmap_filter/include/chmap_filter.h`. -The library is linked if :option:`CONFIG_DESKTOP_BLE_QOS_ENABLE` Kconfig option is enabled. +The library is linked if :kconfig:`CONFIG_DESKTOP_BLE_QOS_ENABLE` Kconfig option is enabled. -Enable the module using the :option:`CONFIG_DESKTOP_BLE_QOS_ENABLE` Kconfig option. -The option selects :option:`CONFIG_BT_HCI_VS_EVT_USER`, because the module uses vendor-specific HCI events. +Enable the module using the :kconfig:`CONFIG_DESKTOP_BLE_QOS_ENABLE` Kconfig option. +The option selects :kconfig:`CONFIG_BT_HCI_VS_EVT_USER`, because the module uses vendor-specific HCI events. -You can use the :option:`CONFIG_DESKTOP_BLE_QOS_STATS_PRINTOUT_ENABLE` option to enable real-time QoS information printouts through a virtual COM port (serial port emulated over USB). +You can use the :kconfig:`CONFIG_DESKTOP_BLE_QOS_STATS_PRINTOUT_ENABLE` option to enable real-time QoS information printouts through a virtual COM port (serial port emulated over USB). This option also enables and configures the COM port (USB CDC ACM). -For this reason, the :option:`CONFIG_USB` must be enabled. +For this reason, the :kconfig:`CONFIG_USB` must be enabled. The QoS module creates additional thread for processing the QoS algorithm. You can define the following options: -* :option:`CONFIG_DESKTOP_BLE_QOS_INTERVAL` +* :kconfig:`CONFIG_DESKTOP_BLE_QOS_INTERVAL` This option specifies the amount of time of the processing interval for the QoS thread. The interval is defined in milliseconds. The thread periodically performs calculations and then sleeps during the interval. Longer intervals give more time to accumulate the Cyclic Redundancy Check (CRC) stats. -* :option:`CONFIG_DESKTOP_BLE_QOS_STACK_SIZE` +* :kconfig:`CONFIG_DESKTOP_BLE_QOS_STACK_SIZE` This option defines the base stack size for the QoS thread. -* :option:`CONFIG_DESKTOP_BLE_QOS_STATS_PRINT_STACK_SIZE` - This option specifies the stack size increase if :option:`CONFIG_DESKTOP_BLE_QOS_STATS_PRINTOUT_ENABLE` is enabled. +* :kconfig:`CONFIG_DESKTOP_BLE_QOS_STATS_PRINT_STACK_SIZE` + This option specifies the stack size increase if :kconfig:`CONFIG_DESKTOP_BLE_QOS_STATS_PRINTOUT_ENABLE` is enabled. .. tip:: You can use the default thread stack sizes as long as you do not modify the module source code. @@ -123,7 +123,7 @@ The thread is used to periodically perform the following operations: * Submit the suggested channel map as ``ble_qos_event``. * If the device is a Bluetooth central, update the used Bluetooth LE channel map. -If the :option:`CONFIG_DESKTOP_BLE_QOS_STATS_PRINTOUT_ENABLE` Kconfig option is set, the module prints the following information through the virtual COM port: +If the :kconfig:`CONFIG_DESKTOP_BLE_QOS_STATS_PRINTOUT_ENABLE` Kconfig option is set, the module prints the following information through the virtual COM port: * HID report rate The module counts the number of HID input reports received via Bluetoooth LE and prints the report rate through the virtual COM port every 100 packets. diff --git a/applications/nrf_desktop/doc/ble_scan.rst b/applications/nrf_desktop/doc/ble_scan.rst index 2f83a3364967..fe0cf37208e3 100644 --- a/applications/nrf_desktop/doc/ble_scan.rst +++ b/applications/nrf_desktop/doc/ble_scan.rst @@ -35,26 +35,26 @@ Complete the following steps to enable the |ble_scan|: 1. Configure Bluetooth, as described in :ref:`nrf_desktop_bluetooth_guide`. #. Enable the following configuration options: - * :option:`CONFIG_BT_SCAN` - * :option:`CONFIG_BT_SCAN_FILTER_ENABLE` + * :kconfig:`CONFIG_BT_SCAN` + * :kconfig:`CONFIG_BT_SCAN_FILTER_ENABLE` These options are used by the |NCS|'s :ref:`nrf_bt_scan_readme`. -#. Configure the number of scan filters based on the Bluetooth address (:option:`CONFIG_BT_SCAN_ADDRESS_CNT`). +#. Configure the number of scan filters based on the Bluetooth address (:kconfig:`CONFIG_BT_SCAN_ADDRESS_CNT`). The value must be equal to the number of Bluetooth bonds. - The number of Bluetooth bonds is defined by the :option:`CONFIG_BT_MAX_PAIRED` Kconfig option. + The number of Bluetooth bonds is defined by the :kconfig:`CONFIG_BT_MAX_PAIRED` Kconfig option. The |ble_scan| module uses the Bluetooth address filters to look for bonded peripherals. -#. Configure the number of scan filters based on the Bluetooth name (:option:`CONFIG_BT_SCAN_NAME_CNT`). +#. Configure the number of scan filters based on the Bluetooth name (:kconfig:`CONFIG_BT_SCAN_NAME_CNT`). The |ble_scan| module uses Bluetooth name filters to look for unbonded peripherals. The value must be equal to the number of peripheral types the nRF Desktop central connects to. The peripheral type may be either a mouse or a keyboard. -#. If you want to limit the number of attempts to connect to a device, you can enable the connection attempt filter with the :option:`CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER` Kconfig option. +#. If you want to limit the number of attempts to connect to a device, you can enable the connection attempt filter with the :kconfig:`CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER` Kconfig option. After the predefined number of disconnections or connection failures, the nRF Desktop central will no longer try to connect with the given peripheral device. This is done to prevent connecting and disconnecting with a peripheral in a never-ending loop. You can further configure this setting with the following Kconfig options: - * :option:`CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER_LEN` - This option defines the maximum number of filtered devices. - * :option:`CONFIG_BT_SCAN_CONN_ATTEMPTS_COUNT` - This option defines the connection attempt count for a given peripheral. + * :kconfig:`CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER_LEN` - This option defines the maximum number of filtered devices. + * :kconfig:`CONFIG_BT_SCAN_CONN_ATTEMPTS_COUNT` - This option defines the connection attempt count for a given peripheral. The :ref:`nrf_bt_scan_readme` counts all disconnections for a peripheral. The |ble_scan| uses :c:func:`bt_scan_conn_attempts_filter_clear` to clear all the connection attempt counters on the following occasions: @@ -63,30 +63,30 @@ Complete the following steps to enable the |ble_scan|: * When you request scan start or peer erase. If filters are not cleared by the application, the Bluetooth Central will be unable to reconnect to the peripheral after exceeding the maximum connection attempts. -#. Configure the maximum number of bonded mice (:option:`CONFIG_DESKTOP_BLE_SCAN_MOUSE_LIMIT`) and keyboards (:option:`CONFIG_DESKTOP_BLE_SCAN_KEYBOARD_LIMIT`) for the nRF Desktop central. +#. Configure the maximum number of bonded mice (:kconfig:`CONFIG_DESKTOP_BLE_SCAN_MOUSE_LIMIT`) and keyboards (:kconfig:`CONFIG_DESKTOP_BLE_SCAN_KEYBOARD_LIMIT`) for the nRF Desktop central. By default, the nRF Desktop central connects and bonds with only one mouse and one keyboard. #. Define the Bluetooth name filters in the :file:`ble_scan_def.h` file that is located in the board-specific directory in the application configuration directory. You must define a Bluetooth name filter for every peripheral type the nRF Desktop central connects to. For an example, see :file:`configuration/nrf52840dongle_nrf52840/ble_scan_def.h`. .. note:: - The Bluetooth device name for given peripheral is defined as the :option:`CONFIG_BT_DEVICE_NAME` Kconfig option in the peripheral's configuration. + The Bluetooth device name for given peripheral is defined as the :kconfig:`CONFIG_BT_DEVICE_NAME` Kconfig option in the peripheral's configuration. For more detailed information about the Bluetooth advertising configuration in the nRF Desktop application, see the :ref:`nrf_desktop_ble_adv` documentation. -#. Set the :option:`CONFIG_DESKTOP_BLE_SCANNING_ENABLE` option to enable the |ble_scan| module. +#. Set the :kconfig:`CONFIG_DESKTOP_BLE_SCANNING_ENABLE` option to enable the |ble_scan| module. By default, the nRF Desktop central always looks for both bonded and unbonded peripherals. -You can set the :option:`CONFIG_DESKTOP_BLE_NEW_PEER_SCAN_REQUEST` option to make the device look for unbonded peripherals only on user request. +You can set the :kconfig:`CONFIG_DESKTOP_BLE_NEW_PEER_SCAN_REQUEST` option to make the device look for unbonded peripherals only on user request. The request is submitted by :ref:`nrf_desktop_ble_bond` as :c:struct:`ble_peer_operation_event` with :c:member:`ble_peer_operation_event.op` set to :c:enumerator:`PEER_OPERATION_SCAN_REQUEST`. The central always looks for new bonds also after the bond erase (on :c:struct:`ble_peer_operation_event` with :c:member:`ble_peer_operation_event.op` set to :c:enumerator:`PEER_OPERATION_ERASED`). -If :option:`CONFIG_DESKTOP_BLE_NEW_PEER_SCAN_REQUEST` is enabled, you can also set the :option:`CONFIG_DESKTOP_BLE_NEW_PEER_SCAN_ON_BOOT` option to make the central scan for new peers after every boot. +If :kconfig:`CONFIG_DESKTOP_BLE_NEW_PEER_SCAN_REQUEST` is enabled, you can also set the :kconfig:`CONFIG_DESKTOP_BLE_NEW_PEER_SCAN_ON_BOOT` option to make the central scan for new peers after every boot. The following scanning scenarios are possible: * If no peripheral is connected, the central scans for the peripheral devices without interruption. * If a peripheral is connected, the scanning is triggered periodically. - If none of the connected peripherals is in use for at least :option:`CONFIG_DESKTOP_BLE_SCAN_START_TIMEOUT_S`, the scanning is started. + If none of the connected peripherals is in use for at least :kconfig:`CONFIG_DESKTOP_BLE_SCAN_START_TIMEOUT_S`, the scanning is started. Scanning not started ==================== @@ -97,7 +97,7 @@ The scanning will not start if one of the following conditions occurs: * The :ref:`nrf_desktop_ble_discovery` is in the process of discovering a peer. * The central is going to scan only for bonded peers and all the bonded peers are already connected. -The number of Bluetooth connections is defined as the :option:`CONFIG_BT_MAX_CONN` Kconfig option. +The number of Bluetooth connections is defined as the :kconfig:`CONFIG_BT_MAX_CONN` Kconfig option. Scanning interrupted ==================== @@ -106,7 +106,7 @@ The scanning is interrupted if one of the following conditions occurs: * A connected peripheral is in use. Scanning in this situation will have a negative impact on user experience. -* The maximum scan duration specified by :option:`CONFIG_DESKTOP_BLE_SCAN_DURATION_S` times out. +* The maximum scan duration specified by :kconfig:`CONFIG_DESKTOP_BLE_SCAN_DURATION_S` times out. The scanning is never interrupted if there is no connected Bluetooth peer. @@ -135,7 +135,7 @@ a. The scanning is stopped and the |NCS|'s :ref:`nrf_bt_scan_readme` automatical .. important:: If a Bluetooth peer is aready connected with a 1-ms connection interval, the next peer is connected with a 10-ms connection interval instead of 7.5 ms. - The peer is connected with a 10-ms connection interval also in case :option:`CONFIG_BT_MAX_CONN` is set to value greater than 2 and :option:`CONFIG_CAF_BLE_USE_LLPM` Kconfig option is enabled. + The peer is connected with a 10-ms connection interval also in case :kconfig:`CONFIG_BT_MAX_CONN` is set to value greater than 2 and :kconfig:`CONFIG_CAF_BLE_USE_LLPM` Kconfig option is enabled. This is required to avoid Bluetooth scheduling issues that may lead to HID input report rate drops and disconnections. At this point, the scanning can be restarted. diff --git a/applications/nrf_desktop/doc/board.rst b/applications/nrf_desktop/doc/board.rst index 39c89ab69da5..ed8f39a4e4f9 100644 --- a/applications/nrf_desktop/doc/board.rst +++ b/applications/nrf_desktop/doc/board.rst @@ -24,7 +24,7 @@ Configuration ************* The module uses Zephyr's :ref:`zephyr:gpio_api` driver to set the pin state. -For this reason, set the :option:`CONFIG_GPIO` option. +For this reason, set the :kconfig:`CONFIG_GPIO` option. For every configuration, you must define the :file:`port_state_def.h` file in the board-specific directory in the application configuration directory. diff --git a/applications/nrf_desktop/doc/buttons_sim.rst b/applications/nrf_desktop/doc/buttons_sim.rst index b0535db3cac6..d007d6431cf6 100644 --- a/applications/nrf_desktop/doc/buttons_sim.rst +++ b/applications/nrf_desktop/doc/buttons_sim.rst @@ -28,13 +28,13 @@ To configure the |button_sim|: 1. Enable and configure the :ref:`caf_buttons`. ``button_event`` is used to trigger the simulated button sequence. -#. Enable the ``buttons_sim`` module by setting the :option:`CONFIG_DESKTOP_BUTTONS_SIM_ENABLE` Kconfig option. +#. Enable the ``buttons_sim`` module by setting the :kconfig:`CONFIG_DESKTOP_BUTTONS_SIM_ENABLE` Kconfig option. #. Define the output key ID sequence in the :file:`buttons_sim_def.h` file located in the board-specific directory in the :file:`configuration` directory. The mapping from the defined key ID to the HID report ID and usage ID is defined in :file:`hid_keymap_def.h` (this might be different for different boards). -#. Define the interval between subsequent simulated button presses (:option:`CONFIG_DESKTOP_BUTTONS_SIM_INTERVAL`). +#. Define the interval between subsequent simulated button presses (:kconfig:`CONFIG_DESKTOP_BUTTONS_SIM_INTERVAL`). One second is used by default. -If you want the sequence to automatically restart after it ends, set :option:`CONFIG_DESKTOP_BUTTONS_SIM_LOOP_FOREVER`. +If you want the sequence to automatically restart after it ends, set :kconfig:`CONFIG_DESKTOP_BUTTONS_SIM_LOOP_FOREVER`. By default, the sequence is generated only once. Implementation details @@ -43,6 +43,6 @@ Implementation details The |button_sim| generates button sequence using :c:struct:`k_work_delayable`, which resubmits itself. The work handler submits the press and the release of a single button from the sequence. -Receiving ``button_event`` with the key ID set to :option:`CONFIG_DESKTOP_BUTTONS_SIM_TRIGGER_KEY_ID` either stops generating the sequence (in case it is already being generated) or starts generating it. +Receiving ``button_event`` with the key ID set to :kconfig:`CONFIG_DESKTOP_BUTTONS_SIM_TRIGGER_KEY_ID` either stops generating the sequence (in case it is already being generated) or starts generating it. .. |button_sim| replace:: button simulator module diff --git a/applications/nrf_desktop/doc/config_channel.rst b/applications/nrf_desktop/doc/config_channel.rst index 454cc15e5b58..4714a0a4dcd3 100644 --- a/applications/nrf_desktop/doc/config_channel.rst +++ b/applications/nrf_desktop/doc/config_channel.rst @@ -96,7 +96,7 @@ Each feature report contains the following components: Handling configuration channel in firmware ========================================== -To enable the configuration channel in the nRF Desktop firmware, set the :option:`CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE` Kconfig option. +To enable the configuration channel in the nRF Desktop firmware, set the :kconfig:`CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE` Kconfig option. This option also enables the mandatory :ref:`nrf_desktop_info`. Make sure you also configure the following configuration channel elements: @@ -129,7 +129,7 @@ Depending on the connection method: The GATT write without response operation cannot be performed on HID feature report. To allow GATT write without response, the peripheral must provide an additional HID output report. - Use the :option:`CONFIG_DESKTOP_CONFIG_CHANNEL_OUT_REPORT` Kconfig option in nRF Desktop peripheral configuration to add the mentioned HID output report. + Use the :kconfig:`CONFIG_DESKTOP_CONFIG_CHANNEL_OUT_REPORT` Kconfig option in nRF Desktop peripheral configuration to add the mentioned HID output report. Disabling this option reduces the memory consumption. The :c:struct:`config_event` is used to propagate the configuration channel data. diff --git a/applications/nrf_desktop/doc/constlat.rst b/applications/nrf_desktop/doc/constlat.rst index 034f5162325c..4b3d9954b08e 100644 --- a/applications/nrf_desktop/doc/constlat.rst +++ b/applications/nrf_desktop/doc/constlat.rst @@ -23,7 +23,7 @@ Module events Configuration ************* -Enable the module with the :option:`CONFIG_DESKTOP_CONSTLAT_ENABLE` Kconfig option. +Enable the module with the :kconfig:`CONFIG_DESKTOP_CONSTLAT_ENABLE` Kconfig option. -You can set the :option:`CONFIG_DESKTOP_CONSTLAT_DISABLE_ON_STANDBY` to disable the constant latency interrupts when the device goes to the low power mode (on ``power_down_event``). +You can set the :kconfig:`CONFIG_DESKTOP_CONSTLAT_DISABLE_ON_STANDBY` to disable the constant latency interrupts when the device goes to the low power mode (on ``power_down_event``). The constant latency interrupts are reenabled on ``wake_up_event``. diff --git a/applications/nrf_desktop/doc/cpu_meas.rst b/applications/nrf_desktop/doc/cpu_meas.rst index 7a986952ed1b..11c938eed1aa 100644 --- a/applications/nrf_desktop/doc/cpu_meas.rst +++ b/applications/nrf_desktop/doc/cpu_meas.rst @@ -22,11 +22,11 @@ Module events Configuration ************* -Enable the module using the :option:`CONFIG_DESKTOP_CPU_MEAS_ENABLE` Kconfig option. -This Kconfig option selects the :option:`CONFIG_CPU_LOAD` option. -The :option:`CONFIG_CPU_LOAD` option enables :ref:`cpu_load`, that is used to perform the measurements. +Enable the module using the :kconfig:`CONFIG_DESKTOP_CPU_MEAS_ENABLE` Kconfig option. +This Kconfig option selects the :kconfig:`CONFIG_CPU_LOAD` option. +The :kconfig:`CONFIG_CPU_LOAD` option enables :ref:`cpu_load`, that is used to perform the measurements. -Set the time between subsequent CPU load measurements, in milliseconds, using the :option:`CONFIG_DESKTOP_CPU_MEAS_PERIOD` option. +Set the time between subsequent CPU load measurements, in milliseconds, using the :kconfig:`CONFIG_DESKTOP_CPU_MEAS_PERIOD` option. Implementation details ********************** diff --git a/applications/nrf_desktop/doc/dev_descr.rst b/applications/nrf_desktop/doc/dev_descr.rst index 2e91edac348e..39c55e1c401c 100644 --- a/applications/nrf_desktop/doc/dev_descr.rst +++ b/applications/nrf_desktop/doc/dev_descr.rst @@ -13,7 +13,7 @@ The device description module defines custom GATT Service, which contains: * Hardware ID (HW ID) of the peripheral To support the LLPM, the peripheral must use the SoftDevice Link Layer. -This means that you must enable both the :option:`CONFIG_BT_LL_SOFTDEVICE` and the :option:`CONFIG_CAF_BLE_USE_LLPM` Kconfig options. +This means that you must enable both the :kconfig:`CONFIG_BT_LL_SOFTDEVICE` and the :kconfig:`CONFIG_CAF_BLE_USE_LLPM` Kconfig options. The Service is mandatory for all nRF Desktop peripherals that connect to the nRF Desktop centrals. @@ -26,7 +26,7 @@ Configuration ************* The module uses Zephyr's :ref:`zephyr:hwinfo_api` to obtain the hardware ID. -Enable the required driver using :option:`CONFIG_HWINFO`. +Enable the required driver using :kconfig:`CONFIG_HWINFO`. The module is enabled by default for all nRF Desktop peripheral devices. diff --git a/applications/nrf_desktop/doc/dfu.rst b/applications/nrf_desktop/doc/dfu.rst index 6c86484491bd..2e650c30c38d 100644 --- a/applications/nrf_desktop/doc/dfu.rst +++ b/applications/nrf_desktop/doc/dfu.rst @@ -35,10 +35,10 @@ For more information on how to enable the bootloader, see the :ref:`nrf_desktop_ * Requests the image upgrade after the whole image is transferred over the :ref:`nrf_desktop_config_channel`. * Confirms the running image after device reboot. -Enable the DFU module using the :option:`CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_ENABLE` option. -It requires the transport option :option:`CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE` to be selected, as it uses :ref:`nrf_desktop_config_channel` for the transmission of the update image. +Enable the DFU module using the :kconfig:`CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_ENABLE` option. +It requires the transport option :kconfig:`CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE` to be selected, as it uses :ref:`nrf_desktop_config_channel` for the transmission of the update image. -Set the value of :option:`CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_SYNC_BUFFER_SIZE` to specify the size of the sync buffer (in words). +Set the value of :kconfig:`CONFIG_DESKTOP_CONFIG_CHANNEL_DFU_SYNC_BUFFER_SIZE` to specify the size of the sync buffer (in words). During the DFU, the data is initially stored in the buffer and then it is moved to flash. The buffer is located in RAM, so increasing the buffer size increases the RAM usage. If the buffer is small, the host must perform the DFU progress synchronization more often. diff --git a/applications/nrf_desktop/doc/failsafe.rst b/applications/nrf_desktop/doc/failsafe.rst index 822a7408dc51..2c80bc22b806 100644 --- a/applications/nrf_desktop/doc/failsafe.rst +++ b/applications/nrf_desktop/doc/failsafe.rst @@ -23,12 +23,12 @@ Module Events Configuration ************* -Use the :option:`CONFIG_DESKTOP_FAILSAFE_ENABLE` option to enable the module. +Use the :kconfig:`CONFIG_DESKTOP_FAILSAFE_ENABLE` option to enable the module. Additionally, make sure that the following options are set as follows: -* :option:`CONFIG_WATCHDOG` - The watchdog must be enabled. -* :option:`CONFIG_RESET_ON_FATAL_ERROR` - The reset on fatal error must be disabled. +* :kconfig:`CONFIG_WATCHDOG` - The watchdog must be enabled. +* :kconfig:`CONFIG_RESET_ON_FATAL_ERROR` - The reset on fatal error must be disabled. This is to ensure that the device will be blocked after a fatal error and then the watchdog will trigger the reboot. diff --git a/applications/nrf_desktop/doc/fn_keys.rst b/applications/nrf_desktop/doc/fn_keys.rst index af04d399d235..cc2ff85565b6 100644 --- a/applications/nrf_desktop/doc/fn_keys.rst +++ b/applications/nrf_desktop/doc/fn_keys.rst @@ -25,14 +25,14 @@ Configuration The module uses ``button_event`` sent by :ref:`caf_buttons`. Make sure mentioned hardware interface is defined. -The module is enabled with :option:`CONFIG_DESKTOP_FN_KEYS_ENABLE` option. +The module is enabled with :kconfig:`CONFIG_DESKTOP_FN_KEYS_ENABLE` option. You must configure the following options: -* :option:`CONFIG_DESKTOP_FN_KEYS_SWITCH` - Fn key button. -* :option:`CONFIG_DESKTOP_FN_KEYS_LOCK` - Fn lock button. -* :option:`CONFIG_DESKTOP_STORE_FN_LOCK` - Option for defining if the device should store the Fn lock state after reboot (set by default to storing the state). -* :option:`CONFIG_DESKTOP_FN_KEYS_MAX_ACTIVE` - Maximum number of dual-purpose keys pressed at the same time (8 by default). +* :kconfig:`CONFIG_DESKTOP_FN_KEYS_SWITCH` - Fn key button. +* :kconfig:`CONFIG_DESKTOP_FN_KEYS_LOCK` - Fn lock button. +* :kconfig:`CONFIG_DESKTOP_STORE_FN_LOCK` - Option for defining if the device should store the Fn lock state after reboot (set by default to storing the state). +* :kconfig:`CONFIG_DESKTOP_FN_KEYS_MAX_ACTIVE` - Maximum number of dual-purpose keys pressed at the same time (8 by default). The module remembers the pressed keys to send proper key releases. In the file :file:`fn_keys_def.h``, define all the dual-purpose keys. diff --git a/applications/nrf_desktop/doc/hfclk_lock.rst b/applications/nrf_desktop/doc/hfclk_lock.rst index ddca17ceebba..ead25477fe2d 100644 --- a/applications/nrf_desktop/doc/hfclk_lock.rst +++ b/applications/nrf_desktop/doc/hfclk_lock.rst @@ -24,7 +24,7 @@ Module events Configuration ************* -Enable the module with the :option:`CONFIG_DESKTOP_HFCLK_LOCK_ENABLE` Kconfig option. +Enable the module with the :kconfig:`CONFIG_DESKTOP_HFCLK_LOCK_ENABLE` Kconfig option. Implementation details ********************** diff --git a/applications/nrf_desktop/doc/hid_forward.rst b/applications/nrf_desktop/doc/hid_forward.rst index 648414cf8d4b..f5daff0ebb2e 100644 --- a/applications/nrf_desktop/doc/hid_forward.rst +++ b/applications/nrf_desktop/doc/hid_forward.rst @@ -28,19 +28,19 @@ Configuration Complete the following steps to configure the module: 1. Complete the basic Bluetooth configuration, as described in :ref:`nrf_desktop_bluetooth_guide`. -#. Enable and configure the :ref:`hogp_readme` (:option:`CONFIG_BT_HOGP`). +#. Enable and configure the :ref:`hogp_readme` (:kconfig:`CONFIG_BT_HOGP`). .. note:: - Make sure to define the maximum number of supported HID reports (:option:`CONFIG_BT_HOGP_REPORTS_MAX`). + Make sure to define the maximum number of supported HID reports (:kconfig:`CONFIG_BT_HOGP_REPORTS_MAX`). -#. Make sure that the :option:`CONFIG_DESKTOP_HID_STATE_ENABLE` option is disabled. +#. Make sure that the :kconfig:`CONFIG_DESKTOP_HID_STATE_ENABLE` option is disabled. The nRF Desktop central does not generate its own HID input reports. It only forwards HID input reports that it receives from the peripherals connected over Bluetooth. -#. The |hid_forward| is enabled with the :option:`CONFIG_DESKTOP_HID_FORWARD_ENABLE` option. - This option is available only if you enable both the :option:`CONFIG_BT_CENTRAL` and :option:`CONFIG_BT_HOGP` Kconfig options. +#. The |hid_forward| is enabled with the :kconfig:`CONFIG_DESKTOP_HID_FORWARD_ENABLE` option. + This option is available only if you enable both the :kconfig:`CONFIG_BT_CENTRAL` and :kconfig:`CONFIG_BT_HOGP` Kconfig options. The module is used on Bluetooth Central to forward the HID reports that are received by the HID service client. -You can set the queued HID input reports limit using the :option:`CONFIG_DESKTOP_HID_FORWARD_MAX_ENQUEUED_REPORTS` Kconfig option. +You can set the queued HID input reports limit using the :kconfig:`CONFIG_DESKTOP_HID_FORWARD_MAX_ENQUEUED_REPORTS` Kconfig option. Implementation details ********************** @@ -89,7 +89,7 @@ Enqueuing incoming HID input reports The |hid_forward| forwards only one HID input report to the HID-class USB device at a time. Another HID input report may be received from a peripheral connected over Bluetooth before the previous one was sent. In that case, ``hid_report_event`` is enqueued and submitted later. -Up to :option:`CONFIG_DESKTOP_HID_FORWARD_MAX_ENQUEUED_REPORTS` reports can be enqueued at a time for each report type and for each connected peripheral. +Up to :kconfig:`CONFIG_DESKTOP_HID_FORWARD_MAX_ENQUEUED_REPORTS` reports can be enqueued at a time for each report type and for each connected peripheral. If there is not enough space to enqueue a new event, the module drops the oldest enqueued event that was received from this peripheral (of the same type). Upon receiving the ``hid_report_sent_event``, the |hid_forward| submits the ``hid_report_event`` enqueued for the peripheral that is associated with the HID-class USB device. diff --git a/applications/nrf_desktop/doc/hid_state.rst b/applications/nrf_desktop/doc/hid_state.rst index 72d9fdac434a..6632b85c65c3 100644 --- a/applications/nrf_desktop/doc/hid_state.rst +++ b/applications/nrf_desktop/doc/hid_state.rst @@ -28,19 +28,19 @@ Module events Configuration ************* -The |hid_state| module is enabled by selecting :option:`CONFIG_DESKTOP_HID_STATE_ENABLE`. +The |hid_state| module is enabled by selecting :kconfig:`CONFIG_DESKTOP_HID_STATE_ENABLE`. This module is optional and turned off by default. Report expiration ================= -With the :option:`CONFIG_DESKTOP_HID_REPORT_EXPIRATION` configuration option, you can set the amount of time after which a key will be considered expired. +With the :kconfig:`CONFIG_DESKTOP_HID_REPORT_EXPIRATION` configuration option, you can set the amount of time after which a key will be considered expired. The higher the value, the longer the period after which the nRF Desktop application will recall pressed keys when the connection is established. Queue event size ================ -With the :option:`CONFIG_DESKTOP_HID_EVENT_QUEUE_SIZE` configuration option, you can set the number of elements on the queue where the keys are stored before the connection is established. +With the :kconfig:`CONFIG_DESKTOP_HID_EVENT_QUEUE_SIZE` configuration option, you can set the number of elements on the queue where the keys are stored before the connection is established. When a key state changes (it is pressed or released) before the connection is established, an element containing this key's usage is pushed onto the queue. If there is no space in the queue, the oldest element is released. @@ -122,11 +122,11 @@ This queue preserves an order at which input data events are received. Storing limitations ------------------- -The number of events that can be inserted into the queue is limited by :option:`CONFIG_DESKTOP_HID_EVENT_QUEUE_SIZE`. +The number of events that can be inserted into the queue is limited by :kconfig:`CONFIG_DESKTOP_HID_EVENT_QUEUE_SIZE`. Discarding events When there is no space for a new input event, the |hid_state| module will try to free space by discarding the oldest event in the queue. - Events stored in the queue are automatically discarded after the period defined by :option:`CONFIG_DESKTOP_HID_REPORT_EXPIRATION`. + Events stored in the queue are automatically discarded after the period defined by :kconfig:`CONFIG_DESKTOP_HID_REPORT_EXPIRATION`. When discarding an event from the queue, the module checks if the key associated with the event is pressed. This is to avoid missing key releases for earlier key presses when the keys from the queue are replayed to the host. @@ -184,6 +184,6 @@ The :c:struct:`report_data` structure is passed as an argument to this function. .. note:: The HID report formatting function must work according to the HID report descriptor (``hid_report_desc``). - The source file containing the descriptor is given by :option:`CONFIG_DESKTOP_HID_REPORT_DESC`. + The source file containing the descriptor is given by :kconfig:`CONFIG_DESKTOP_HID_REPORT_DESC`. .. |hid_state| replace:: HID state module diff --git a/applications/nrf_desktop/doc/hids.rst b/applications/nrf_desktop/doc/hids.rst index f7c8bc0fe993..e1b33108f3ab 100644 --- a/applications/nrf_desktop/doc/hids.rst +++ b/applications/nrf_desktop/doc/hids.rst @@ -27,14 +27,14 @@ Configuration Complete the following steps to configure the module: 1. Complete the basic Bluetooth configuration, as described in :ref:`nrf_desktop_bluetooth_guide`. - During this configuration, you must enable the :option:`CONFIG_BT_PERIPHERAL` Kconfig option for every nRF Desktop peripheral. - When this option is enabled, the :option:`CONFIG_DESKTOP_HID_PERIPHERAL` is set to ``y``, which enables the following two additional options, among others: + During this configuration, you must enable the :kconfig:`CONFIG_BT_PERIPHERAL` Kconfig option for every nRF Desktop peripheral. + When this option is enabled, the :kconfig:`CONFIG_DESKTOP_HID_PERIPHERAL` is set to ``y``, which enables the following two additional options, among others: - * :option:`CONFIG_BT_HIDS` - This is required because the HID Service module is based on the :ref:`hids_readme` implementation of the GATT Service. - * :option:`CONFIG_DESKTOP_HIDS_ENABLE` - This enables the ``hids`` application module. + * :kconfig:`CONFIG_BT_HIDS` - This is required because the HID Service module is based on the :ref:`hids_readme` implementation of the GATT Service. + * :kconfig:`CONFIG_DESKTOP_HIDS_ENABLE` - This enables the ``hids`` application module. This step also enables the |GATT_HID|. -#. Enable the :ref:`bt_conn_ctx_readme` (:option:`CONFIG_BT_CONN_CTX`). +#. Enable the :ref:`bt_conn_ctx_readme` (:kconfig:`CONFIG_BT_CONN_CTX`). This is required by the |GATT_HID|. #. Configure the :ref:`hids_readme`. See its documentation for configuration details. @@ -46,13 +46,13 @@ The HID Service application module forwards the information about the enabled HI These notifications are enabled by the connected Bluetooth Central. By default, the ``hids`` application module starts forwarding the subscriptions right after the Bluetooth connection is secured. -You can define additional delay for forwarding the notifications on connection (:option:`CONFIG_DESKTOP_HIDS_FIRST_REPORT_DELAY`). +You can define additional delay for forwarding the notifications on connection (:kconfig:`CONFIG_DESKTOP_HIDS_FIRST_REPORT_DELAY`). Sending the first HID report to the connected Bluetooth peer is delayed by this period of time. .. note:: The nRF Desktop centrals perform the GATT service discovery and reenable the HID notifications on every reconnection. A HID report that is received before the subscription is reenabled will be dropped before it reaches the application. - The :option:`CONFIG_DESKTOP_HIDS_FIRST_REPORT_DELAY` is used for keyboard reference design (nRF52832 Desktop Keyboard) to make sure that the input will not be lost on reconnection with the nRF Desktop dongle. + The :kconfig:`CONFIG_DESKTOP_HIDS_FIRST_REPORT_DELAY` is used for keyboard reference design (nRF52832 Desktop Keyboard) to make sure that the input will not be lost on reconnection with the nRF Desktop dongle. Implementation details ********************** diff --git a/applications/nrf_desktop/doc/info.rst b/applications/nrf_desktop/doc/info.rst index 0750bbce2524..3fdda1c10f00 100644 --- a/applications/nrf_desktop/doc/info.rst +++ b/applications/nrf_desktop/doc/info.rst @@ -29,9 +29,9 @@ Configuration ************* The module uses Zephyr's :ref:`zephyr:hwinfo_api` to obtain the hardware ID. -Enable the required driver using :option:`CONFIG_HWINFO`. +Enable the required driver using :kconfig:`CONFIG_HWINFO`. -The module is enabled with the same Kconfig option as the :ref:`nrf_desktop_config_channel`: :option:`CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE`. +The module is enabled with the same Kconfig option as the :ref:`nrf_desktop_config_channel`: :kconfig:`CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE`. Implementation details ********************** @@ -39,4 +39,4 @@ Implementation details Providing the highest ID of the configuration channel listener is based on the number of elements in the ``config_channel_modules`` section. :c:macro:`GEN_CONFIG_EVENT_HANDLERS` adds an element to the section for every registered configuration channel listener. -The board name provided by the module through the :ref:`nrf_desktop_config_channel` is a part of the Zephyr board name (:option:`CONFIG_BOARD`), ending with the predefined character (:c:macro:`BOARD_NAME_SEPARATOR`). +The board name provided by the module through the :ref:`nrf_desktop_config_channel` is a part of the Zephyr board name (:kconfig:`CONFIG_BOARD`), ending with the predefined character (:c:macro:`BOARD_NAME_SEPARATOR`). diff --git a/applications/nrf_desktop/doc/led_state.rst b/applications/nrf_desktop/doc/led_state.rst index 1d0f7449f35d..aea3d6f222ac 100644 --- a/applications/nrf_desktop/doc/led_state.rst +++ b/applications/nrf_desktop/doc/led_state.rst @@ -46,7 +46,7 @@ Module events Configuration ************* -The |led_state| is enabled when you set the :option:`CONFIG_CAF_LEDS` option. +The |led_state| is enabled when you set the :kconfig:`CONFIG_CAF_LEDS` option. You must also configure :ref:`caf_leds`, which is used as sink module for ``led_state``. For every board that has this option enabled, you must define the module configuration. diff --git a/applications/nrf_desktop/doc/led_stream.rst b/applications/nrf_desktop/doc/led_stream.rst index eb910f25544f..ea6d872529ac 100644 --- a/applications/nrf_desktop/doc/led_stream.rst +++ b/applications/nrf_desktop/doc/led_stream.rst @@ -24,11 +24,11 @@ Configuration ************* The module receives LED effects through the :ref:`nrf_desktop_config_channel` and displays them using the :ref:`caf_leds`. -For this reason, make sure that :option:`CONFIG_CAF_LEDS` and :option:`CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE` are both set. +For this reason, make sure that :kconfig:`CONFIG_CAF_LEDS` and :kconfig:`CONFIG_DESKTOP_CONFIG_CHANNEL_ENABLE` are both set. -To enable the module, use the :option:`CONFIG_DESKTOP_LED_STREAM_ENABLE` Kconfig option. +To enable the module, use the :kconfig:`CONFIG_DESKTOP_LED_STREAM_ENABLE` Kconfig option. -You can also define the stream LED event queue size (:option:`CONFIG_DESKTOP_LED_STREAM_QUEUE_SIZE`). +You can also define the stream LED event queue size (:kconfig:`CONFIG_DESKTOP_LED_STREAM_QUEUE_SIZE`). The queue is used by the module as data buffer for the data received from the host computer. Configuration channel diff --git a/applications/nrf_desktop/doc/motion.rst b/applications/nrf_desktop/doc/motion.rst index bee7c3b77abe..fac4aaa7a530 100644 --- a/applications/nrf_desktop/doc/motion.rst +++ b/applications/nrf_desktop/doc/motion.rst @@ -27,11 +27,11 @@ Configuration The motion module selects the source of movement based on the following configuration options: -* :option:`CONFIG_DESKTOP_MOTION_NONE` - Module is disabled. -* :option:`CONFIG_DESKTOP_MOTION_SENSOR_PMW3360_ENABLE` - Movement data is obtained from the gaming-grade ``PMW3360`` motion sensor. -* :option:`CONFIG_DESKTOP_MOTION_SENSOR_PAW3212_ENABLE` - Movement data is obtained from ``PAW3212`` motion sensor. -* :option:`CONFIG_DESKTOP_MOTION_BUTTONS_ENABLE` - Movement data is generated using buttons. -* :option:`CONFIG_DESKTOP_MOTION_SIMULATED_ENABLE` - Movement data is simulated (controlled from Zephyr's :ref:`zephyr:shell_api`). +* :kconfig:`CONFIG_DESKTOP_MOTION_NONE` - Module is disabled. +* :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_PMW3360_ENABLE` - Movement data is obtained from the gaming-grade ``PMW3360`` motion sensor. +* :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_PAW3212_ENABLE` - Movement data is obtained from ``PAW3212`` motion sensor. +* :kconfig:`CONFIG_DESKTOP_MOTION_BUTTONS_ENABLE` - Movement data is generated using buttons. +* :kconfig:`CONFIG_DESKTOP_MOTION_SIMULATED_ENABLE` - Movement data is simulated (controlled from Zephyr's :ref:`zephyr:shell_api`). See the following sections for more information. @@ -40,31 +40,31 @@ Depending on the selected configuration option, different implementation file is Movement data from motion sensors ================================= -Selecting either of the motion sensors (:option:`CONFIG_DESKTOP_MOTION_SENSOR_PMW3360_ENABLE` or :option:`CONFIG_DESKTOP_MOTION_SENSOR_PAW3212_ENABLE`) adds the :file:`src/hw_interface/motion_sensor.c` file to the compilation. +Selecting either of the motion sensors (:kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_PMW3360_ENABLE` or :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_PAW3212_ENABLE`) adds the :file:`src/hw_interface/motion_sensor.c` file to the compilation. The motion sensor is sampled from the context of a dedicated thread. -The option :option:`CONFIG_DESKTOP_MOTION_SENSOR_THREAD_STACK_SIZE` is used to set the thread's stack size. +The option :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_THREAD_STACK_SIZE` is used to set the thread's stack size. The motion sensor default sensitivity and power saving switching times can be set with the following options: -* :option:`CONFIG_DESKTOP_MOTION_SENSOR_CPI` - Default CPI. -* :option:`CONFIG_DESKTOP_MOTION_SENSOR_SLEEP1_TIMEOUT_MS` - ``Sleep 1`` mode default switch time. -* :option:`CONFIG_DESKTOP_MOTION_SENSOR_SLEEP2_TIMEOUT_MS` - ``Sleep 2`` mode default switch time. -* :option:`CONFIG_DESKTOP_MOTION_SENSOR_SLEEP3_TIMEOUT_MS` - ``Sleep 3`` mode default switch time. +* :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_CPI` - Default CPI. +* :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_SLEEP1_TIMEOUT_MS` - ``Sleep 1`` mode default switch time. +* :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_SLEEP2_TIMEOUT_MS` - ``Sleep 2`` mode default switch time. +* :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_SLEEP3_TIMEOUT_MS` - ``Sleep 3`` mode default switch time. For more information, see the sensor documentation and the Kconfig help. Movement data from buttons ========================== -Selecting the :option:`CONFIG_DESKTOP_MOTION_BUTTONS_ENABLE` option adds the :file:`src/hw_interface/motion_buttons.c` file to the compilation. +Selecting the :kconfig:`CONFIG_DESKTOP_MOTION_BUTTONS_ENABLE` option adds the :file:`src/hw_interface/motion_buttons.c` file to the compilation. Simulated movement data ======================= -Selecting the :option:`CONFIG_DESKTOP_MOTION_SIMULATED_ENABLE` option adds the :file:`src/hw_interface/motion_simulated.c` file to the compilation. +Selecting the :kconfig:`CONFIG_DESKTOP_MOTION_SIMULATED_ENABLE` option adds the :file:`src/hw_interface/motion_simulated.c` file to the compilation. -If shell is available (:option:`CONFIG_SHELL` option is set) the motion module registers a shell module ``motion_sim`` and links to it two commands: ``start`` and ``stop``. +If shell is available (:kconfig:`CONFIG_SHELL` option is set) the motion module registers a shell module ``motion_sim`` and links to it two commands: ``start`` and ``stop``. If shell is not available motion generation starts automatically when the device is connected to the USB or Bluetooth. When started, the module will generate simulated motion events. @@ -72,15 +72,15 @@ The movement data in each event will be tracing the predefined path, an eight-si You can configure the path with the following options: -* :option:`CONFIG_DESKTOP_MOTION_SIMULATED_EDGE_TIME` - Sets how long each edge is traced. -* :option:`CONFIG_DESKTOP_MOTION_SIMULATED_SCALE_FACTOR` - Scales the size of the polygon. +* :kconfig:`CONFIG_DESKTOP_MOTION_SIMULATED_EDGE_TIME` - Sets how long each edge is traced. +* :kconfig:`CONFIG_DESKTOP_MOTION_SIMULATED_SCALE_FACTOR` - Scales the size of the polygon. The ``stop`` command will cause the module to stop generating new events. Configuration channel ********************* -In a :ref:`configuration ` where either :option:`CONFIG_DESKTOP_MOTION_SENSOR_PMW3360_ENABLE` or :option:`CONFIG_DESKTOP_MOTION_SENSOR_PAW3212_ENABLE` is used, you can configure the module through the :ref:`nrf_desktop_config_channel`. +In a :ref:`configuration ` where either :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_PMW3360_ENABLE` or :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_PAW3212_ENABLE` is used, you can configure the module through the :ref:`nrf_desktop_config_channel`. In these configurations, the module is a configuration channel listener and it provides the following configuration options: * :c:macro:`OPT_DESCR_MODULE_VARIANT` @@ -145,5 +145,5 @@ Upon connection, the following happens: #. At that point, a next motion sampling is performed and the next ``motion_event`` sent. The module continues to sample data until disconnection or when there is no motion detected. -The ``motion`` module assumes no motion when a number of consecutive samples equal to :option:`CONFIG_DESKTOP_MOTION_SENSOR_EMPTY_SAMPLES_COUNT` returns zero on both axis. +The ``motion`` module assumes no motion when a number of consecutive samples equal to :kconfig:`CONFIG_DESKTOP_MOTION_SENSOR_EMPTY_SAMPLES_COUNT` returns zero on both axis. In such case, the module will switch back to ``STATE_IDLE`` and wait for the motion sensor trigger. diff --git a/applications/nrf_desktop/doc/passkey.rst b/applications/nrf_desktop/doc/passkey.rst index ff6338c81c78..c4e4c94c665e 100644 --- a/applications/nrf_desktop/doc/passkey.rst +++ b/applications/nrf_desktop/doc/passkey.rst @@ -28,8 +28,8 @@ The passkey input handling is based on ``button_event``. To configure the passkey module, complete the following steps: 1. Enable and configure the :ref:`caf_buttons`. -#. Enable the passkey module by using the :option:`CONFIG_DESKTOP_PASSKEY_BUTTONS` Kconfig option. -#. Define the maximum number of digits in the passkey by using :option:`CONFIG_DESKTOP_PASSKEY_MAX_LEN` option. +#. Enable the passkey module by using the :kconfig:`CONFIG_DESKTOP_PASSKEY_BUTTONS` Kconfig option. +#. Define the maximum number of digits in the passkey by using :kconfig:`CONFIG_DESKTOP_PASSKEY_MAX_LEN` option. #. Define the IDs of the keys used by the passkey module in the :file:`passkey_buttons_def.h` file located in the board-specific directory in the :file:`configuration` directory. You must define the IDs of the following keys: diff --git a/applications/nrf_desktop/doc/profiler_sync.rst b/applications/nrf_desktop/doc/profiler_sync.rst index 8b236f36fd3d..7c8fe3f43c91 100644 --- a/applications/nrf_desktop/doc/profiler_sync.rst +++ b/applications/nrf_desktop/doc/profiler_sync.rst @@ -28,18 +28,18 @@ Configuration ************* A predefined signal on the GPIO is used to simultaneously generate synchronization profiler events on both devices. -For this reason, you must enable the :option:`CONFIG_GPIO` option. +For this reason, you must enable the :kconfig:`CONFIG_GPIO` option. -Make also sure that the :option:`CONFIG_EVENT_MANAGER_PROFILER_ENABLED` Kconfig option is enabled and the :option:`CONFIG_EVENT_MANAGER_TRACE_EVENT_EXECUTION` Kconfig option is disabled. +Make also sure that the :kconfig:`CONFIG_EVENT_MANAGER_PROFILER_ENABLED` Kconfig option is enabled and the :kconfig:`CONFIG_EVENT_MANAGER_TRACE_EVENT_EXECUTION` Kconfig option is disabled. The profiler synchronization module generates a :ref:`profiler` event (``sync_event``) that is not an :ref:`event_manager` event. For this reason, the ``sync_event`` execution is not traced. You also need to define: -* the GPIO port (:option:`CONFIG_DESKTOP_PROFILER_SYNC_GPIO_PORT`) and the pin (:option:`CONFIG_DESKTOP_PROFILER_SYNC_GPIO_PIN`) that are used for synchronization +* the GPIO port (:kconfig:`CONFIG_DESKTOP_PROFILER_SYNC_GPIO_PORT`) and the pin (:kconfig:`CONFIG_DESKTOP_PROFILER_SYNC_GPIO_PIN`) that are used for synchronization These GPIOs must be defined separately for both devices and connected using a physical wire. * the device role - One of the devices must be set as ``Central`` (:option:`CONFIG_DESKTOP_PROFILER_SYNC_CENTRAL`) and the other device must be set as ``Peripheral`` (:option:`CONFIG_DESKTOP_PROFILER_SYNC_PERIPHERAL`). + One of the devices must be set as ``Central`` (:kconfig:`CONFIG_DESKTOP_PROFILER_SYNC_CENTRAL`) and the other device must be set as ``Peripheral`` (:kconfig:`CONFIG_DESKTOP_PROFILER_SYNC_PERIPHERAL`). Implementation details ********************** diff --git a/applications/nrf_desktop/doc/qos.rst b/applications/nrf_desktop/doc/qos.rst index a01658b22bff..6ffd0266f5d6 100644 --- a/applications/nrf_desktop/doc/qos.rst +++ b/applications/nrf_desktop/doc/qos.rst @@ -8,7 +8,7 @@ Quality of Service module :depth: 2 The Quality of Service (QoS) module provides the QoS information through the Bluetooth GATT service. -The module can be used only by nRF Desktop peripheral with the SoftDevice Link Layer (:option:`CONFIG_BT_LL_SOFTDEVICE`). +The module can be used only by nRF Desktop peripheral with the SoftDevice Link Layer (:kconfig:`CONFIG_BT_LL_SOFTDEVICE`). The module is made available in case the peripheral is meant to be paired with a third party dongle. In such case, the vendor can use the Quality of Service data provided by the nRF Desktop peripheral to improve the link quality. @@ -34,7 +34,7 @@ Configuration The module requires the basic Bluetooth configuration, as described in :ref:`nrf_desktop_bluetooth_guide`. -The module is enabled with :option:`CONFIG_DESKTOP_QOS_ENABLE` option. +The module is enabled with :kconfig:`CONFIG_DESKTOP_QOS_ENABLE` option. The module is available on the :ref:`peripheral devices ` only and requires the :ref:`nrf_desktop_ble_qos` to be enabled. Implementation details diff --git a/applications/nrf_desktop/doc/selector.rst b/applications/nrf_desktop/doc/selector.rst index e60817134be8..6b6022c7f3e1 100644 --- a/applications/nrf_desktop/doc/selector.rst +++ b/applications/nrf_desktop/doc/selector.rst @@ -24,9 +24,9 @@ Configuration ************* The module implemented in :file:`selector_hw.c` uses the Zephyr :ref:`zephyr:gpio_api` driver to check the state of hardware selectors. -For this reason, you should set :option:`CONFIG_GPIO` option. +For this reason, you should set :kconfig:`CONFIG_GPIO` option. -Set :option:`CONFIG_DESKTOP_SELECTOR_HW_ENABLE` option to enable the module. +Set :kconfig:`CONFIG_DESKTOP_SELECTOR_HW_ENABLE` option to enable the module. The configuration for this module is an array of :c:struct:`selector_config` pointers. The array is written in the :file:`selector_hw_def.h` file located in the board-specific directory in the application configuration directory. diff --git a/applications/nrf_desktop/doc/settings_loader.rst b/applications/nrf_desktop/doc/settings_loader.rst index 19f0260bc2a1..0d89d12a5a06 100644 --- a/applications/nrf_desktop/doc/settings_loader.rst +++ b/applications/nrf_desktop/doc/settings_loader.rst @@ -23,7 +23,7 @@ Configuration ************* The settings loader module is enabled for every nRF Desktop device with Zephyr's :ref:`zephyr:settings_api` enabled. -The :ref:`zephyr:settings_api` subsystem is enabled with the :option:`CONFIG_SETTINGS` Kconfig option. +The :ref:`zephyr:settings_api` subsystem is enabled with the :kconfig:`CONFIG_SETTINGS` Kconfig option. Zephyr's Bluetooth stack does not load the :ref:`zephyr:settings_api` data on its own. Zephyr assumes that the application will call :c:func:`settings_load` after completing all necessary initialization. @@ -34,12 +34,12 @@ This function is called on the settings loader module initialization. Settings are by default loaded in the system workqueue context. This blocks the workqueue until the operation is finished. -You can set the :option:`CONFIG_DESKTOP_SETTINGS_LOADER_USE_THREAD` Kconfig option to load the settings in a separate thread in the background instead of using the system workqueue for that purpose. +You can set the :kconfig:`CONFIG_DESKTOP_SETTINGS_LOADER_USE_THREAD` Kconfig option to load the settings in a separate thread in the background instead of using the system workqueue for that purpose. This will prevent blocking the system workqueue, but it requires creating an additional thread. -The stack size for the background thread is defined as :option:`CONFIG_DESKTOP_SETTINGS_LOADER_THREAD_STACK_SIZE`. +The stack size for the background thread is defined as :kconfig:`CONFIG_DESKTOP_SETTINGS_LOADER_THREAD_STACK_SIZE`. .. tip:: Using separate thread is recommended for nRF Desktop keyboards. The :ref:`caf_buttons` uses the system workqueue to scan the keyboard matrix. Loading the settings in the system workqueue context could block the workqueue and result in missing key presses on system reboot. - For this reason, :option:`CONFIG_DESKTOP_SETTINGS_LOADER_USE_THREAD` is enabled for keyboard reference design (nRF52832 Desktop Keyboard) + For this reason, :kconfig:`CONFIG_DESKTOP_SETTINGS_LOADER_USE_THREAD` is enabled for keyboard reference design (nRF52832 Desktop Keyboard) diff --git a/applications/nrf_desktop/doc/usb_state.rst b/applications/nrf_desktop/doc/usb_state.rst index 164a16f80a9d..d6786045eba7 100644 --- a/applications/nrf_desktop/doc/usb_state.rst +++ b/applications/nrf_desktop/doc/usb_state.rst @@ -23,39 +23,39 @@ Module events Configuration ************* -The module is enabled by selecting :option:`CONFIG_DESKTOP_USB_ENABLE`. -It depends on :option:`CONFIG_USB_DEVICE_HID`. +The module is enabled by selecting :kconfig:`CONFIG_DESKTOP_USB_ENABLE`. +It depends on :kconfig:`CONFIG_USB_DEVICE_HID`. When enabling the USB support for the device, set the following generic device options: -* :option:`CONFIG_USB_DEVICE_MANUFACTURER` - Manufacturer's name. -* :option:`CONFIG_USB_DEVICE_PRODUCT` - Product name. -* :option:`CONFIG_USB_DEVICE_VID` - Vendor ID (VID) number. -* :option:`CONFIG_USB_DEVICE_PID` - Product ID (PID) number. +* :kconfig:`CONFIG_USB_DEVICE_MANUFACTURER` - Manufacturer's name. +* :kconfig:`CONFIG_USB_DEVICE_PRODUCT` - Product name. +* :kconfig:`CONFIG_USB_DEVICE_VID` - Vendor ID (VID) number. +* :kconfig:`CONFIG_USB_DEVICE_PID` - Product ID (PID) number. Additionally, you can also configure the options described in the following sections. Low latency device configuration ================================ -For low latency devices, make sure that the device requests a polling rate of 1 ms by setting :option:`CONFIG_USB_HID_POLL_INTERVAL_MS` to ``1``. +For low latency devices, make sure that the device requests a polling rate of 1 ms by setting :kconfig:`CONFIG_USB_HID_POLL_INTERVAL_MS` to ``1``. Boot protocol configuration =========================== If the device is meant to support the boot protocol, set the following options: -#. Enable :option:`CONFIG_USB_HID_BOOT_PROTOCOL`. -#. Make sure :option:`CONFIG_USB_HID_PROTOCOL_CODE` is set to either the mouse or the keyboard code. +#. Enable :kconfig:`CONFIG_USB_HID_BOOT_PROTOCOL`. +#. Make sure :kconfig:`CONFIG_USB_HID_PROTOCOL_CODE` is set to either the mouse or the keyboard code. USB device instance configuration ================================= The nRF Desktop device can provide multiple instances of a HID-class USB device. -The number of instances is controlled by :option:`CONFIG_USB_HID_DEVICE_COUNT`. +The number of instances is controlled by :kconfig:`CONFIG_USB_HID_DEVICE_COUNT`. * The Bluetooth Peripheral device will be able to use a single instance only. -* The Bluetooth Central device can use either a single instance or a number of instances equal to :option:`CONFIG_BT_MAX_PAIRED`. +* The Bluetooth Central device can use either a single instance or a number of instances equal to :kconfig:`CONFIG_BT_MAX_PAIRED`. On the Bluetooth Central device, if only one instance is used, reports from all Peripherals connected to the Central are forwarded to the same instance. In other cases, reports from each of the bonded peripherals will be forwarded to a dedicated HID-class USB device instance. @@ -66,7 +66,7 @@ USB wake-up configuration The nRF Desktop device can work as a source of wake-up events for the host device if connected through the USB. -To use the feature, select :option:`CONFIG_USB_DEVICE_REMOTE_WAKEUP`. +To use the feature, select :kconfig:`CONFIG_USB_DEVICE_REMOTE_WAKEUP`. When host enters the suspended state, the USB will be suspended as well. With this feature enabled, this state change is used to suspend the nRF Desktop device (see :ref:`nrf_desktop_power_manager`). @@ -79,7 +79,7 @@ When the nRF Desktop device wakes up from standby, the |usb_state| will issue a Implementation details ********************** -The |usb_state| registers the :option:`CONFIG_USB_HID_DEVICE_COUNT` instances of HID-class USB device and initializes the USB subsystem. +The |usb_state| registers the :kconfig:`CONFIG_USB_HID_DEVICE_COUNT` instances of HID-class USB device and initializes the USB subsystem. The necessary callbacks are connected to the module to ensure that the state of the USB connection is tracked. From the application's viewpoint, USB can be in the following states: diff --git a/applications/nrf_desktop/doc/watchdog.rst b/applications/nrf_desktop/doc/watchdog.rst index 73381b6f214e..0abc9db27fcd 100644 --- a/applications/nrf_desktop/doc/watchdog.rst +++ b/applications/nrf_desktop/doc/watchdog.rst @@ -26,11 +26,11 @@ Configuration ************* The module uses Zephyr's :ref:`zephyr:watchdog_api` driver. -For this reason, set the :option:`CONFIG_WATCHDOG` option. +For this reason, set the :kconfig:`CONFIG_WATCHDOG` option. -The module is enabled by the :option:`CONFIG_DESKTOP_WATCHDOG_ENABLE` option. +The module is enabled by the :kconfig:`CONFIG_DESKTOP_WATCHDOG_ENABLE` option. -You must define :option:`CONFIG_DESKTOP_WATCHDOG_TIMEOUT`. +You must define :kconfig:`CONFIG_DESKTOP_WATCHDOG_TIMEOUT`. After this amount of time (in ms), the device will be restarted if the watchdog timer was not reset. .. note:: diff --git a/applications/nrf_desktop/doc/wheel.rst b/applications/nrf_desktop/doc/wheel.rst index b38365415e7b..a938ac74be67 100644 --- a/applications/nrf_desktop/doc/wheel.rst +++ b/applications/nrf_desktop/doc/wheel.rst @@ -22,17 +22,17 @@ Module events Configuration ************* -Enable the module with the :option:`CONFIG_DESKTOP_WHEEL_ENABLE` Kconfig option. +Enable the module with the :kconfig:`CONFIG_DESKTOP_WHEEL_ENABLE` Kconfig option. For detecting rotation, the wheel module uses Zephyr's QDEC driver. -The module can be enabled only when QDEC is configured in DTS (that is, :option:`CONFIG_QDEC_NRFX` is set). +The module can be enabled only when QDEC is configured in DTS (that is, :kconfig:`CONFIG_QDEC_NRFX` is set). The QDEC DTS configuration specifies how many steps are done during one full angle. The sensor reports the rotation data in angle degrees. -Then, :option:`CONFIG_DESKTOP_WHEEL_SENSOR_VALUE_DIVIDER` (a wheel configuration option) converts the angle value into a value that is passed with a ``wheel_event`` to the destination module. +Then, :kconfig:`CONFIG_DESKTOP_WHEEL_SENSOR_VALUE_DIVIDER` (a wheel configuration option) converts the angle value into a value that is passed with a ``wheel_event`` to the destination module. For example, configuring QDEC with 24 steps means that for each step the sensor will report a rotation of 15 degrees. -For HID to see this rotation as increment of one, :option:`CONFIG_DESKTOP_WHEEL_SENSOR_VALUE_DIVIDER` should be set to 15. +For HID to see this rotation as increment of one, :kconfig:`CONFIG_DESKTOP_WHEEL_SENSOR_VALUE_DIVIDER` should be set to 15. Implementation details ********************** @@ -47,7 +47,7 @@ The wheel module can be in the following states: When in ``STATE_ACTIVE``, the module enables the QDEC driver and waits for callback that indicates rotation. The QDEC driver may consume power during its operation. -If no rotation is detected after the time specified in :option:`CONFIG_DESKTOP_WHEEL_SENSOR_IDLE_TIMEOUT`, the wheel module switches to ``STATE_ACTIVE_IDLE``, in which QDEC is disabled. +If no rotation is detected after the time specified in :kconfig:`CONFIG_DESKTOP_WHEEL_SENSOR_IDLE_TIMEOUT`, the wheel module switches to ``STATE_ACTIVE_IDLE``, in which QDEC is disabled. In this state, the rotation is detected using GPIO interrupts. When the rotation is detected, the module switches back to ``STATE_ACTIVE``. diff --git a/applications/pelion_client/README.rst b/applications/pelion_client/README.rst index 7e539b4a8315..36943d5d95a8 100644 --- a/applications/pelion_client/README.rst +++ b/applications/pelion_client/README.rst @@ -182,7 +182,7 @@ Zephyr's system heap -------------------- Zephyr contains its own memory allocation algorithm that implements heap. -To configure the heap memory size, use the :option:`CONFIG_HEAP_MEM_POOL_SIZE` Kconfig option. +To configure the heap memory size, use the :kconfig:`CONFIG_HEAP_MEM_POOL_SIZE` Kconfig option. For more information about Zephyr's system heap, see the :ref:`zephyr:heap_v2` page in Zephyr's documentation. @@ -199,7 +199,7 @@ The Mbed TLS library can use the libc heap for allocation. Alternatively, it can use the dedicated allocation area (see `mbedtls_memory_buffer_alloc_init`_ in the official Mbed TLS documentation). The :ref:`nrf_security` variant of the Mbed TLS library allows to set such dedicated allocation buffer. -See :option:`CONFIG_MBEDTLS_ENABLE_HEAP` and :option:`CONFIG_MBEDTLS_HEAP_SIZE` for more details. +See :kconfig:`CONFIG_MBEDTLS_ENABLE_HEAP` and :kconfig:`CONFIG_MBEDTLS_HEAP_SIZE` for more details. Flash memory layout =================== @@ -392,7 +392,7 @@ Configuration ************* |pelion_lib_explanation| -The Pelion Device Management library is enabled with :option:`CONFIG_PELION_CLIENT` configuration option. +The Pelion Device Management library is enabled with :kconfig:`CONFIG_PELION_CLIENT` configuration option. For the library to work, you must enable and properly configure the Mbed TLS library. To connect to Pelion Device Management Portal, the device must be provisioned with valid credentials. @@ -405,7 +405,7 @@ Mbed TLS The Pelion Device Management library is depending on a properly configured Mbed TLS library. To simplify the development within the |NCS|, a predefined set of Mbed TLS configuration options was prepared. -Set compatible with :ref:`nrfxlib:nrf_security` can be enabled using :option:`CONFIG_PELION_NRF_SECURITY` configuration option. +Set compatible with :ref:`nrfxlib:nrf_security` can be enabled using :kconfig:`CONFIG_PELION_NRF_SECURITY` configuration option. Pelion credentials ================== @@ -427,8 +427,8 @@ You can provide the devices with the new version of the firmware image over-the- Before the update, you must enable a compatible bootloader. The Pelion Device Management library is compatible with MCUboot. -Enable it with the :option:`CONFIG_BOOTLOADER_MCUBOOT` Kconfig option. -Along with the bootloader, you must also enable an image manager with the :option:`CONFIG_IMG_MANAGER` and :option:`CONFIG_MCUBOOT_IMG_MANAGER` Kconfig options. +Enable it with the :kconfig:`CONFIG_BOOTLOADER_MCUBOOT` Kconfig option. +Along with the bootloader, you must also enable an image manager with the :kconfig:`CONFIG_IMG_MANAGER` and :kconfig:`CONFIG_MCUBOOT_IMG_MANAGER` Kconfig options. When MCUboot is enabled the |NCS| build system generates the update image that can be uploaded to the secondary (update) slot. The resulting signed file named ``app_update.bin`` can be found in the build directory. @@ -440,7 +440,7 @@ If key is not present and configuration does not point to any specific key path, Additionally, if the application image is large, you may need to store the update image on an external flash device. In such case, enable the external flash support and correctly configure the partition layout. -The Pelion Device Management library's update manager is enabled when you select the :option:`CONFIG_PELION_UPDATE` Kconfig option. +The Pelion Device Management library's update manager is enabled when you select the :kconfig:`CONFIG_PELION_UPDATE` Kconfig option. This option enables components required for image transport and storage. For the update campaign to be recognized and the image be accepted, you need to provision the device with the valid update resources (device unique identifiers and certificate used for update process validation). diff --git a/applications/serial_lte_modem/doc/HTTPC_AT_commands.rst b/applications/serial_lte_modem/doc/HTTPC_AT_commands.rst index ee0e1c1e6098..c3e26ba631d2 100644 --- a/applications/serial_lte_modem/doc/HTTPC_AT_commands.rst +++ b/applications/serial_lte_modem/doc/HTTPC_AT_commands.rst @@ -131,8 +131,8 @@ Syntax It represents the length of the payload. If ``payload_length`` is greater than ``0``, the SLM will enter data mode and expect the upcoming UART input data as payload. The SLM will then send the payload to the HTTP server until the ``payload_length`` bytes are sent. - To abort sending the payload, terminate data mode by sending the terminator string defined in :option:`CONFIG_SLM_DATAMODE_TERMINATOR`. - The default pattern string is "+++". Keep in mind that UART silence as configured in :option:`CONFIG_SLM_DATAMODE_SILENCE` is required before and after the pattern string. + To abort sending the payload, terminate data mode by sending the terminator string defined in :kconfig:`CONFIG_SLM_DATAMODE_TERMINATOR`. + The default pattern string is "+++". Keep in mind that UART silence as configured in :kconfig:`CONFIG_SLM_DATAMODE_SILENCE` is required before and after the pattern string. Response syntax ~~~~~~~~~~~~~~~ diff --git a/applications/serial_lte_modem/doc/slm_description.rst b/applications/serial_lte_modem/doc/slm_description.rst index fd4a6a2f07ae..3b0b84e320d5 100644 --- a/applications/serial_lte_modem/doc/slm_description.rst +++ b/applications/serial_lte_modem/doc/slm_description.rst @@ -42,7 +42,7 @@ As a client, you can use either a PC or an external MCU. Connecting with a PC -------------------- -To connect to the nRF9160 DK with a PC, make sure that :option:`CONFIG_SLM_CONNECT_UART_0` is defined in the application. +To connect to the nRF9160 DK with a PC, make sure that :kconfig:`CONFIG_SLM_CONNECT_UART_0` is defined in the application. It is defined in the default configuration. Use LTE Link Monitor to connect to the nRF9160 DK. @@ -64,7 +64,7 @@ Connecting with an external MCU If you run your user application on an external MCU (for example, an nRF52 Series DK), you can control the modem on the nRF9160 directly from the application. See the `nRF52 client for serial LTE modem application`_ repository for a sample implementation of such an application. -To connect with an external MCU, you must set the configuration option :option:`CONFIG_UART_2_NRF_HW_ASYNC_TIMER` and :option:`CONFIG_SLM_CONNECT_UART_2` in the serial LTE modem application configuration. +To connect with an external MCU, you must set the configuration option :kconfig:`CONFIG_UART_2_NRF_HW_ASYNC_TIMER` and :kconfig:`CONFIG_SLM_CONNECT_UART_2` in the serial LTE modem application configuration. The following table shows how to connect an nRF52 Series DK to the nRF9160 DK to be able to communicate through UART: @@ -149,7 +149,7 @@ Check and configure the following configuration options for the sample: .. option:: CONFIG_SLM_INTERFACE_PIN - Interface GPIO to wake up from sleep or exit idle This option specifies which interface GPIO to use for exiting sleep or idle mode. - By default, **P0.6** (Button 1 on the nRF9160 DK) is used when :option:`CONFIG_SLM_CONNECT_UART_0` is selected, and **P0.31** is used when when :option:`CONFIG_SLM_CONNECT_UART_2` is selected. + By default, **P0.6** (Button 1 on the nRF9160 DK) is used when :kconfig:`CONFIG_SLM_CONNECT_UART_0` is selected, and **P0.31** is used when when :kconfig:`CONFIG_SLM_CONNECT_UART_2` is selected. .. option:: CONFIG_SLM_SOCKET_RX_MAX - Maximum RX buffer size for receiving socket data @@ -179,21 +179,17 @@ Check and configure the following configuration options for the sample: This option enables additional AT commands for using the SMS service. -.. option:: CONFIG_SLM_GNSS - GNSS support in SLM +.. option:: CONFIG_SLM_GPS - GPS support in SLM - This option enables additional AT commands for using the GNSS service. + This option enables additional AT commands for using GPS service. -.. option:: CONFIG_SLM_AGPS - nRF Cloud A-GPS support in SLM +.. option:: CONFIG_SLM_SUPL_SERVER - SUPL server - This option enables additional AT commands for using the GPS service together with nRF Cloud A-GPS service. + This option specifies the SUPL server to use for retrieving SUPL A-GPS data. -.. option:: CONFIG_SLM_PGPS - nRF Cloud P-GPS support in SLM +.. option:: CONFIG_SLM_SUPL_PORT - SUPL server port - This option enables additional AT commands for using the GPS service together with nRF Cloud P-GPS service. - -.. option:: CONFIG_SLM_CELL_POS - nRF Cloud cellular positioning support in SLM - - This option enables additional AT commands for using the cellular positioning service from nRF Cloud. + This option specifies the port to use for the specified SUPL server. .. option:: CONFIG_SLM_FTPC - FTP client support in SLM @@ -308,10 +304,7 @@ This application uses the following |NCS| libraries: * :ref:`at_cmd_parser_readme` * :ref:`at_notif_readme` * :ref:`lib_ftp_client` -* :ref:`lib_fota_download` -* :ref:`cloud_api_readme` -* :ref:`lib_nrf_cloud` -* :ref:`lib_nrf_cloud_agps` +* :ref:`supl_client` It uses the following `sdk-nrfxlib`_ libraries: diff --git a/applications/serial_lte_modem/doc/slm_testing.rst b/applications/serial_lte_modem/doc/slm_testing.rst index c96f4372a57d..8890d8de0324 100644 --- a/applications/serial_lte_modem/doc/slm_testing.rst +++ b/applications/serial_lte_modem/doc/slm_testing.rst @@ -1341,9 +1341,9 @@ Complete the following steps to test the functionality provided by the :ref:`SLM FTP AT commands *************** -Note that these commands are available only if :option:`CONFIG_SLM_FTPC` is defined. -Before you test the FTP AT commands, check the setting of the :option:`CONFIG_FTP_CLIENT_KEEPALIVE_TIME` option. -By default, the :ref:`lib_ftp_client` library keeps the connection to the FTP server alive for 60 seconds, but you can change the duration or turn KEEPALIVE off by setting :option:`CONFIG_FTP_CLIENT_KEEPALIVE_TIME` to 0. +Note that these commands are available only if :kconfig:`CONFIG_SLM_FTPC` is defined. +Before you test the FTP AT commands, check the setting of the :kconfig:`CONFIG_FTP_CLIENT_KEEPALIVE_TIME` option. +By default, the :ref:`lib_ftp_client` library keeps the connection to the FTP server alive for 60 seconds, but you can change the duration or turn KEEPALIVE off by setting :kconfig:`CONFIG_FTP_CLIENT_KEEPALIVE_TIME` to 0. The FTP client behavior depends on the FTP server that is used for testing. Complete the following steps to test the functionality provided by the :ref:`SLM_AT_FTP` with two example servers: diff --git a/doc/nrf/known_issues.rst b/doc/nrf/known_issues.rst index 0191ba9ac883..c0bfb72735fc 100644 --- a/doc/nrf/known_issues.rst +++ b/doc/nrf/known_issues.rst @@ -253,7 +253,7 @@ KRKNWK-10633: Incorrect data when using ACK-based Probing with Link Metrics KRKNWK-10467: Security issues for retransmitted frames with Thread 1.2 The Thread 1.2 current implementation does not guarantee that all retransmitted frames will be secured when using the transmission security capabilities of the radio driver. - For this reason, OpenThread retransmissions are disabled by default when the :option:`CONFIG_NRF_802154_ENCRYPTION` Kconfig option is enabled. + For this reason, OpenThread retransmissions are disabled by default when the :kconfig:`CONFIG_NRF_802154_ENCRYPTION` Kconfig option is enabled. You can enable the retransmissions at your own risk. .. rst-class:: v1-6-1 v1-6-0 @@ -1021,7 +1021,7 @@ Multiprotocol Service Layer (MPSL) .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 -DRGN-15979: :option:`CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION` must be set when :option:`CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC` is set. +DRGN-15979: :kconfig:`CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC_CALIBRATION` must be set when :kconfig:`CONFIG_CLOCK_CONTROL_NRF_K32SRC_RC` is set. MPSL requires RC clock calibration to be enabled when the RC clock is used as the Low Frequency clock source. .. rst-class:: v1-5-0 v1-4-2 v1-4-1 diff --git a/doc/nrf/libraries/bin/lwm2m_carrier/CHANGELOG.rst b/doc/nrf/libraries/bin/lwm2m_carrier/CHANGELOG.rst index cc8209a7effc..1d646e469662 100644 --- a/doc/nrf/libraries/bin/lwm2m_carrier/CHANGELOG.rst +++ b/doc/nrf/libraries/bin/lwm2m_carrier/CHANGELOG.rst @@ -44,8 +44,8 @@ Changes * Renamed the event :c:macro:`LWM2M_CARRIER_BSDLIB_INIT` to :c:macro:`LWM2M_CARRIER_EVENT_MODEM_INIT`. * Added a new error code :c:macro:`LWM2M_CARRIER_ERROR_SERVICE_UNAVAILABLE` which indicates that the LwM2M server is unavailable due to maintenance. * Added a new error code :c:macro:`LWM2M_CARRIER_ERROR_CONFIGURATION` which indicates that an illegal object configuration was detected. -* Added new Kconfig options :c:option:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_APN` and :c:option:`CONFIG_LWM2M_CARRIER_CUSTOM_APN` to set the ``apn`` member of :c:type:`lwm2m_carrier_config_t`. -* It is now possible to configure a custom bootstrap URI using :c:option:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI` regardless of operator SIM. +* Added new Kconfig options :c:kconfig:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_APN` and :c:kconfig:`CONFIG_LWM2M_CARRIER_CUSTOM_APN` to set the ``apn`` member of :c:type:`lwm2m_carrier_config_t`. +* It is now possible to configure a custom bootstrap URI using :c:kconfig:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI` regardless of operator SIM. liblwm2m_carrier 0.10.2 *********************** diff --git a/doc/nrf/libraries/bin/lwm2m_carrier/app_integration.rst b/doc/nrf/libraries/bin/lwm2m_carrier/app_integration.rst index 266fd2548358..86f9c2e4ef97 100644 --- a/doc/nrf/libraries/bin/lwm2m_carrier/app_integration.rst +++ b/doc/nrf/libraries/bin/lwm2m_carrier/app_integration.rst @@ -35,36 +35,36 @@ It provides an abstraction of the following modules: The OS abstraction layer is fully implemented for the |NCS|, and it would have to be ported if used with other RTOS or on other systems. To run the library in an application, you must implement the application with the API of the library. -You can enable the module using the :option:`CONFIG_LWM2M_CARRIER` Kconfig option. +You can enable the module using the :kconfig:`CONFIG_LWM2M_CARRIER` Kconfig option. The :ref:`lwm2m_carrier` sample project configuration (:file:`nrf/samples/nrf9160/lwm2m_carrier/prj.conf`) contains all the configurations that are needed by the LwM2M carrier library. You can provide the initialization parameter :c:type:`lwm2m_carrier_config_t` to overwrite the carrier default settings with the Kconfig options described below: -* :option:`CONFIG_LWM2M_CARRIER_CERTIFICATION_MODE`: +* :kconfig:`CONFIG_LWM2M_CARRIER_CERTIFICATION_MODE`: * This configuration specifies if the LwM2M carrier library will connect to the carrier's certification servers or production servers. * Expected to be set during self-testing part of the certification process. - * This configuration is ignored if :option:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI` is set. + * This configuration is ignored if :kconfig:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI` is set. -* :option:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI`: +* :kconfig:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI`: - * This configuration, together with :option:`CONFIG_LWM2M_CARRIER_CUSTOM_BOOTSTRAP_URI` lets the LwM2M carrier library connect to a bootstrap server other than the normal carrier server, thereby enabling the generic mode. + * This configuration, together with :kconfig:`CONFIG_LWM2M_CARRIER_CUSTOM_BOOTSTRAP_URI` lets the LwM2M carrier library connect to a bootstrap server other than the normal carrier server, thereby enabling the generic mode. * Expected to be set during self-testing, or if the end product is not to be certified with the applicable carriers. See :ref:`lwm2m_certification`. - * If this configuration is set, :option:`CONFIG_LWM2M_CARRIER_CERTIFICATION_MODE` is ignored. + * If this configuration is set, :kconfig:`CONFIG_LWM2M_CARRIER_CERTIFICATION_MODE` is ignored. -* :option:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_PSK`: +* :kconfig:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_PSK`: - * This configuration, together with :option:`CONFIG_LWM2M_CARRIER_CUSTOM_BOOTSTRAP_PSK` can be set to use a non-default `Pre-Shared Key (PSK)`_. + * This configuration, together with :kconfig:`CONFIG_LWM2M_CARRIER_CUSTOM_BOOTSTRAP_PSK` can be set to use a non-default `Pre-Shared Key (PSK)`_. * If connecting to the normal carrier device management servers (normal operation), this configuration must not be set unless your carrier explicitly states to use a custom PSK, for example during self-testing. - * If the :option:`CONFIG_LWM2M_CARRIER_CUSTOM_BOOTSTRAP_URI` option is set and the server requires a secure connection, a PSK is required. + * If the :kconfig:`CONFIG_LWM2M_CARRIER_CUSTOM_BOOTSTRAP_URI` option is set and the server requires a secure connection, a PSK is required. -* :option:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_APN`: +* :kconfig:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_APN`: - * This configuration, together with :option:`CONFIG_LWM2M_CARRIER_CUSTOM_APN` produce different results depending on normal or generic mode of operation. - * If :option:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI` is not set (normal), this configuration supplies a fallback APN. This might be required in your application, depending on the requirements from the carrier. - * If :option:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI` is set (generic), :option:`CONFIG_LWM2M_CARRIER_CUSTOM_APN` is used instead of the default APN, (and there is no fallback APN). + * This configuration, together with :kconfig:`CONFIG_LWM2M_CARRIER_CUSTOM_APN` produce different results depending on normal or generic mode of operation. + * If :kconfig:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI` is not set (normal), this configuration supplies a fallback APN. This might be required in your application, depending on the requirements from the carrier. + * If :kconfig:`CONFIG_LWM2M_CARRIER_USE_CUSTOM_BOOTSTRAP_URI` is set (generic), :kconfig:`CONFIG_LWM2M_CARRIER_CUSTOM_APN` is used instead of the default APN, (and there is no fallback APN). Note that these settings can put the LwM2M carrier library either in the normal mode where it connects to the applicable carriers, or in the generic mode where it can connect to any bootstrap server. diff --git a/doc/nrf/libraries/bin/lwm2m_carrier/requirements.rst b/doc/nrf/libraries/bin/lwm2m_carrier/requirements.rst index 7647102b9afe..9f2c35cdcd21 100644 --- a/doc/nrf/libraries/bin/lwm2m_carrier/requirements.rst +++ b/doc/nrf/libraries/bin/lwm2m_carrier/requirements.rst @@ -17,7 +17,7 @@ Below are some of the requirements and limitations of the application while runn * The application must not use the *NB-IoT* LTE mode. * The LwM2M carrier library is currently only certified for the *LTE-M* LTE mode. - * The :option:`CONFIG_LTE_NETWORK_USE_FALLBACK` must be disabled in your application, as seen in the :ref:`lwm2m_carrier` sample project configuration (:file:`nrf/samples/nrf9160/lwm2m_carrier/prj.conf`). + * The :kconfig:`CONFIG_LTE_NETWORK_USE_FALLBACK` must be disabled in your application, as seen in the :ref:`lwm2m_carrier` sample project configuration (:file:`nrf/samples/nrf9160/lwm2m_carrier/prj.conf`). * The LwM2M carrier library registers to receive several AT event reports using the :ref:`at_cmd_readme` and :ref:`at_notif_readme` libraries. The following notifications must not be deregistered by the application: diff --git a/doc/nrf/libraries/bluetooth_services/enocean.rst b/doc/nrf/libraries/bluetooth_services/enocean.rst index 9521cffb3fee..88c4ad199879 100644 --- a/doc/nrf/libraries/bluetooth_services/enocean.rst +++ b/doc/nrf/libraries/bluetooth_services/enocean.rst @@ -19,7 +19,7 @@ The library supports different types of commissioning for both wall switches and The library supports replay protection based on sequence numbers. Only new, authenticated packets from commissioned devices will go through to the event callbacks. -If the :option:`CONFIG_BT_SETTINGS` subsystem is enabled, the device information of all commissioned devices are stored persistently using the :ref:`zephyr:settings_api` subsystem, including the sequence number information. +If the :kconfig:`CONFIG_BT_SETTINGS` subsystem is enabled, the device information of all commissioned devices are stored persistently using the :ref:`zephyr:settings_api` subsystem, including the sequence number information. For a demonstration of the library features, see the :ref:`enocean_sample` sample. @@ -90,9 +90,9 @@ See the :ref:`enocean_sample` for a demonstration of the handler callback functi Dependencies ************ -The EnOcean library depends on the :option:`CONFIG_BT_OBSERVER` capability in the Bluetooth stack to function. +The EnOcean library depends on the :kconfig:`CONFIG_BT_OBSERVER` capability in the Bluetooth stack to function. -To enable persistent storage of device commissioning data, the :option:`CONFIG_BT_SETTINGS` subsystem must also be enabled. +To enable persistent storage of device commissioning data, the :kconfig:`CONFIG_BT_SETTINGS` subsystem must also be enabled. API documentation ================= diff --git a/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst b/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst index 56dc143acefc..b7c987e58f37 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst @@ -12,7 +12,7 @@ It supports four types of out-of-band (OOB) authentication methods and uses the For more information about provisioning in Bluetooth mesh, see the :ref:`zephyr:bluetooth_mesh_provisioning` page in Zephyr. Used primarily in :ref:`Bluetooth mesh sample applications `, this handler acts as a reference implementation for the application-specific part of provisioning. -It is enabled with the :option:`CONFIG_BT_MESH_DK_PROV` option and by calling :c:func:`bt_mesh_dk_prov_init` in main. +It is enabled with the :kconfig:`CONFIG_BT_MESH_DK_PROV` option and by calling :c:func:`bt_mesh_dk_prov_init` in main. The handling of the OOB authentication methods is closely tied to the hardware parameters of the Development Kits from Nordic Semiconductor. For deployments with custom hardware, do not extend this module. @@ -28,27 +28,27 @@ Output: Display number If selected, the node will print an authentication number in its serial log. Enter this number into the provisioner. - Enabled by :option:`CONFIG_BT_MESH_DK_PROV_OOB_LOG`. + Enabled by :kconfig:`CONFIG_BT_MESH_DK_PROV_OOB_LOG`. Output: Display string The Display string OOB method requires access to the application log through a serial connection. If selected, the node will print an authentication string in its serial log. Enter this number into the provisioner. - Enabled by :option:`CONFIG_BT_MESH_DK_PROV_OOB_LOG`. + Enabled by :kconfig:`CONFIG_BT_MESH_DK_PROV_OOB_LOG`. Output: Blink The Blink OOB method blinks the LEDs a certain number of times. Enter the number of blinks into the provisioner. The blinks occur at a frequency of two blinks per second, and the sequence is repeated every three seconds. - Enabled by :option:`CONFIG_BT_MESH_DK_PROV_OOB_BLINK`. + Enabled by :kconfig:`CONFIG_BT_MESH_DK_PROV_OOB_BLINK`. Input: Push button The Push button OOB method requires the user to press a button the number of times specified by the provisioner. After three seconds of inactivity, the button count is sent to the provisioner. - Enabled by :option:`CONFIG_BT_MESH_DK_PROV_OOB_BUTTON`. + Enabled by :kconfig:`CONFIG_BT_MESH_DK_PROV_OOB_BUTTON`. .. note:: It is also possible for the provisioner to select "No authentication" and skip the OOB authentication. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_srv.rst index 6cc965edcc4c..87b0c9165b1b 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/gen_dtt_srv.rst @@ -16,10 +16,10 @@ Configuration The following configuration parameters are associated with the Generic DTT Server model: -* :option:`CONFIG_BT_MESH_DTT_SRV_PERSISTENT` - Control whether changes to the Generic Default Transition Time are stored persistently. +* :kconfig:`CONFIG_BT_MESH_DTT_SRV_PERSISTENT` - Control whether changes to the Generic Default Transition Time are stored persistently. .. note:: - This option is only available if :option:`CONFIG_BT_SETTINGS` is enabled. + This option is only available if :kconfig:`CONFIG_BT_SETTINGS` is enabled. States ====== @@ -58,7 +58,7 @@ None. Persistent storage ================== -The Generic Default Transition Time is stored persistently if :option:`CONFIG_BT_MESH_DTT_SRV_PERSISTENT` is enabled. +The Generic Default Transition Time is stored persistently if :kconfig:`CONFIG_BT_MESH_DTT_SRV_PERSISTENT` is enabled. API documentation ================= diff --git a/doc/nrf/libraries/bluetooth_services/mesh/gen_plvl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_plvl_srv.rst index 11a0a8197249..a7723ba27a0f 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/gen_plvl_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/gen_plvl_srv.rst @@ -85,8 +85,8 @@ Persistent storage The Generic Power Level Server stores any changes to the Default Power and Power Range states, as well as the last known non-zero Generic Power Level and whether the Generic Power Level is on or off. This information is used to reestablish the correct Generic Power Level when the device powers up. -If :option:`CONFIG_BT_SETTINGS` is enabled, the Generic Power Level Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Generic Power Level Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. API documentation ================== diff --git a/doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff_srv.rst index 001d09c5da5e..cfcaccb182f2 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/gen_ponoff_srv.rst @@ -25,8 +25,8 @@ Configuration The following configuration parameters are associated with the Generic Power OnOff Server model: -* :option:`CONFIG_BT_SETTINGS` - The server requires this option to be enabled to work properly. - Unless :option:`CONFIG_BT_SETTINGS` is explicitly disabled, including the Generic Power OnOff Server will enable :option:`CONFIG_BT_SETTINGS`. +* :kconfig:`CONFIG_BT_SETTINGS` - The server requires this option to be enabled to work properly. + Unless :kconfig:`CONFIG_BT_SETTINGS` is explicitly disabled, including the Generic Power OnOff Server will enable :kconfig:`CONFIG_BT_SETTINGS`. States ====== @@ -61,8 +61,8 @@ Persistent storage The Generic On Power Up state is stored persistently, along with the current Generic OnOff state of the extended :ref:`bt_mesh_onoff_srv_readme`. -If :option:`CONFIG_BT_SETTINGS` is enabled, the Generic Power OnOff Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Generic Power OnOff Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. API documentation ================= diff --git a/doc/nrf/libraries/bluetooth_services/mesh/gen_prop.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop.rst index 5d31fc694b34..87ad32bbc982 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/gen_prop.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop.rst @@ -15,8 +15,8 @@ For types common to all models, see :ref:`bt_mesh_models`. The following configuration parameters are associated with the Generic Property models: -* :option:`CONFIG_BT_MESH_PROP_MAXSIZE` - The largest available property value. -* :option:`CONFIG_BT_MESH_PROP_MAXCOUNT` - The largest number of properties available on a single Generic Property Server. +* :kconfig:`CONFIG_BT_MESH_PROP_MAXSIZE` - The largest available property value. +* :kconfig:`CONFIG_BT_MESH_PROP_MAXCOUNT` - The largest number of properties available on a single Generic Property Server. .. toctree:: :maxdepth: 1 diff --git a/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst index 6a8798228383..97eba2d9c0da 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst @@ -60,8 +60,8 @@ Persistent storage The Generic Manufacturer Property Server and Generic Admin Property Server models will store changes to the user access rights of their properties. Any permanent changes to the property values themselves should be stored manually by the application. -If :option:`CONFIG_BT_SETTINGS` is enabled, the Generic Admin Property Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Generic Admin Property Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. API documentation ================= diff --git a/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst index db4a07dcafcf..249b5b584ee5 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst @@ -129,7 +129,7 @@ Whenever something but the Light LC Server interacts with the controlled Lightne To resume the state machine operation, the Light LC Server must be explicitly re-enabled. To avoid having a Lightness Server running independently forever, the Light LC Server implements a resume timer that lets the Light LC Server regain control after being disabled for a certain number of seconds. -The resume timer can be configured with the :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_RESUME_DELAY` option, and is disabled by default. +The resume timer can be configured with the :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_RESUME_DELAY` option, and is disabled by default. .. note:: The resume timer does not exist in the Bluetooth mesh specification, and may become incompatible with future specification changes. @@ -203,7 +203,7 @@ Off event The Off event can only be generated by a light switch being turned off. It moves the Light LC Server into Standby, transitioning from the previous light level with the manual mode Standby fade time (:c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_TIME_FADE_STANDBY_MANUAL`). -The Off event puts the Light LC Server into manual mode, which disables sensor input until the manual mode timeout (:option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_MANUAL`) expires. +The Off event puts the Light LC Server into manual mode, which disables sensor input until the manual mode timeout (:kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_MANUAL`) expires. This prevents the lights from turning back on by the movement of the person that presses the light switch. .. note:: @@ -231,35 +231,35 @@ Timing parameters This section lists compile and runtime options to be used when setting timing parameters. Delay from occupancy detected until light turns on - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_OCCUPANCY_DELAY` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_OCCUPANCY_DELAY` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_TIME_OCCUPANCY_DELAY` Transition time to On state - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_ON` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_ON` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_TIME_FADE_ON` Time in On state - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_ON` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_ON` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_TIME_ON` Transition time to Prolong state - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_PROLONG` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_PROLONG` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_TIME_FADE_PROLONG` Time in Prolong state - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_PROLONG` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_PROLONG` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_TIME_PROLONG` Transition time to Standby state (in auto mode) - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_STANDBY_AUTO` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_STANDBY_AUTO` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_TIME_FADE_STANDBY_AUTO` Transition time to Standby state (in manual mode) - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_STANDBY_MANUAL` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_FADE_STANDBY_MANUAL` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_TIME_FADE_STANDBY_MANUAL` Manual mode timeout - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_MANUAL` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_TIME_MANUAL` * No runtime option available. Output parameters @@ -268,27 +268,27 @@ Output parameters This section lists compile and runtime options to be used when setting output parameters. On state light level - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_ON` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_ON` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_LIGHTNESS_ON` Prolong state light level - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_LIGHTNESS_PROLONG` Standby state light level - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_STANDBY` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_STANDBY` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_LIGHTNESS_STANDBY` On state target illuminance - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_ON` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_ON` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_ILLUMINANCE_ON` Prolong state target illuminance - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_PROLONG` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_PROLONG` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_ILLUMINANCE_PROLONG` Standby state target illuminance - * Compile time: :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_STANDBY` + * Compile time: :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_LUX_STANDBY` * Runtime: :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_ILLUMINANCE_STANDBY` @@ -325,7 +325,7 @@ The error, the regulator coefficients, and the internal sum, are represented as The resulting output level is represented as an unsigned 16-bit integer. To reduce noise, the regulator has a configurable accuracy property, which allows it to ignore errors smaller than the configured accuracy (represented as a percentage of the light level). -See :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_ACCURACY` and :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_REG_ACCURACY` for more information. +See :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_REG_ACCURACY` and :c:enumerator:`BT_MESH_LIGHT_CTRL_PROP_REG_ACCURACY` for more information. Sensor input ------------ @@ -427,8 +427,8 @@ See the :ref:`bt_mesh_light_ctrl_srv_composition` section for details. Persistent Storage ****************** -If :option:`CONFIG_BT_SETTINGS` is enabled, the Light LC Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Light LC Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. Changes to the configuration properties are stored and restored on power-up, so the compile time configuration is only valid the first time the device powers up, until the configuration is changed. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/light_hue_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_hue_srv.rst index 92d74932ef26..888fa1da1f46 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/light_hue_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_hue_srv.rst @@ -71,8 +71,8 @@ The Light Hue Server stores the following information: This information is used to reestablish the correct Hue level when the device powers up. -If :option:`CONFIG_BT_SETTINGS` is enabled, the Light Hue Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Light Hue Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. API documentation ****************** diff --git a/doc/nrf/libraries/bluetooth_services/mesh/light_sat_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_sat_srv.rst index 9477e0d2c9bc..11832086050d 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/light_sat_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_sat_srv.rst @@ -64,8 +64,8 @@ The Light Saturation Server stores the following information: This information is used to reestablish the correct Saturation level when the device powers up. -If :option:`CONFIG_BT_SETTINGS` is enabled, the Light Saturation Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Light Saturation Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. API documentation ****************** diff --git a/doc/nrf/libraries/bluetooth_services/mesh/light_xyl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_xyl_srv.rst index f80de5cf67fd..8fd4cffbd504 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/light_xyl_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_xyl_srv.rst @@ -110,8 +110,8 @@ In addition, the model takes over the persistent storage responsibility of the : This information is used to reestablish the correct light configuration when the device powers up. -If :option:`CONFIG_BT_SETTINGS` is enabled, the Light xyL Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Light xyL Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. API documentation ***************** diff --git a/doc/nrf/libraries/bluetooth_services/mesh/lightness.rst b/doc/nrf/libraries/bluetooth_services/mesh/lightness.rst index 9fbceec8f712..66abd199d886 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/lightness.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/lightness.rst @@ -26,8 +26,8 @@ For types common to all models, see :ref:`bt_mesh_models`. The application can select whether to use the Actual or Linear representation. To do so, use the following options in the API at compile time: -* :option:`CONFIG_BT_MESH_LIGHTNESS_ACTUAL` - Used by default. -* :option:`CONFIG_BT_MESH_LIGHTNESS_LINEAR` +* :kconfig:`CONFIG_BT_MESH_LIGHTNESS_ACTUAL` - Used by default. +* :kconfig:`CONFIG_BT_MESH_LIGHTNESS_LINEAR` Internally, the models will always support both representations, so nodes with different representations can be be used interchangeably. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/lightness_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/lightness_srv.rst index 68816b1b5b9c..d4f3021c5b16 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/lightness_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/lightness_srv.rst @@ -100,8 +100,8 @@ The Light Lightness Server stores the following information: This information is used to reestablish the correct Light level when the device powers up. -If :option:`CONFIG_BT_SETTINGS` is enabled, the Light Lightness Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Light Lightness Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. API documentation ================== diff --git a/doc/nrf/libraries/bluetooth_services/mesh/scene_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/scene_srv.rst index 57cc71a0c8bf..df02b6d94404 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/scene_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/scene_srv.rst @@ -101,7 +101,7 @@ Current scene: ``uint16_t`` Scene registry: ``uint16_t[]`` The full list of scenes stored by the Scene Server. - The scene registry has a limited number of slots, controlled by :option:`CONFIG_BT_MESH_SCENES_MAX`. + The scene registry has a limited number of slots, controlled by :kconfig:`CONFIG_BT_MESH_SCENES_MAX`. Extended models ================ diff --git a/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst index 3af3fa27423b..ea83edaf92e7 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst @@ -82,7 +82,7 @@ For sensor values that are represented as whole numbers, the fractional part of Boolean types are inferred only from the integer part of the value (:c:member:`sensor_value.val1`). Every sensor channel has a name and a unit, as listed in the sensor type documentation. -The name and unit are only available if :option:`CONFIG_BT_MESH_SENSOR_LABELS` option is set, and can aid in debugging and presentation of the sensor output. +The name and unit are only available if :kconfig:`CONFIG_BT_MESH_SENSOR_LABELS` option is set, and can aid in debugging and presentation of the sensor output. Both the channel name and unit is also listed in the documentation for each sensor type. Most sensor values are reported as scalars with some scaling factor applied to them during encoding. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/sensor_cli.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor_cli.rst index 5c44f199783b..3ebfca132c7d 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/sensor_cli.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/sensor_cli.rst @@ -21,7 +21,7 @@ In most cases, the incoming data needs to be interpreted differently based on th When parsing incoming messages, the Sensor Client is required to do a lookup of the sensor type of the data so it can decode it correctly. For this purpose, the :ref:`bt_mesh_sensor_types` module includes the :ref:`list of available sensor types `. -By default, all sensor types are available when the Sensor Client model is compiled in, but this behavior can be overridden to reduce flash consumption by explicitly disabling :option:`CONFIG_BT_MESH_SENSOR_ALL_TYPES`. +By default, all sensor types are available when the Sensor Client model is compiled in, but this behavior can be overridden to reduce flash consumption by explicitly disabling :kconfig:`CONFIG_BT_MESH_SENSOR_ALL_TYPES`. In this case, only the referenced sensor types will be available. .. note:: diff --git a/doc/nrf/libraries/bluetooth_services/mesh/sensor_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor_srv.rst index babaa5a28f6e..f7aec9c3e8ca 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/sensor_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/sensor_srv.rst @@ -77,8 +77,8 @@ The Sensor Server stores the cadence state of each sensor instance persistently, Any other data is managed by the application and must be stored separately. This applies for example to sensor settings or sample data. -If :option:`CONFIG_BT_SETTINGS` is enabled, the Sensor Server stores all its states persistently using a configurable storage delay to stagger storing. -See :option:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Sensor Server stores all its states persistently using a configurable storage delay to stagger storing. +See :kconfig:`CONFIG_BT_MESH_MODEL_SRV_STORE_TIMEOUT`. API documentation ================= diff --git a/doc/nrf/libraries/bluetooth_services/mesh/sensor_types.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor_types.rst index 5674f164e403..51783ff5d931 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/sensor_types.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/sensor_types.rst @@ -10,8 +10,8 @@ Bluetooth mesh sensor types All sensor types are collected in :file:`include/bluetooth/mesh/sensor_types.h`, and are divided into the categories listed in the page index. To keep the total flash usage down, the sensor types are only instantiated if they're referenced by the application. -This behavior can be overridden by enabling :option:`CONFIG_BT_MESH_SENSOR_ALL_TYPES`. -Note that if the Sensor Client is enabled, :option:`CONFIG_BT_MESH_SENSOR_ALL_TYPES` is enabled by default. +This behavior can be overridden by enabling :kconfig:`CONFIG_BT_MESH_SENSOR_ALL_TYPES`. +Note that if the Sensor Client is enabled, :kconfig:`CONFIG_BT_MESH_SENSOR_ALL_TYPES` is enabled by default. Sensor types can be forced into the build by the :c:macro:`BT_MESH_SENSOR_TYPE_FORCE` macro. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/time_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/time_srv.rst index ab1bda6ea8d2..f097ff00f147 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/time_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/time_srv.rst @@ -57,14 +57,14 @@ The Time Server's time synchronization mechanism is not perfect, and every times The clock uncertainty is measured in milliseconds, and can come from various sources, like inaccuracies in the original clock source, internal clock drift or uncertainty in the mesh stack itself. The Time Server inherits the uncertainty of the node it got its Time Status from, and the clock uncertainty of each mesh node increases for every hop the Time Status had to make from the Time Authority. -The expected uncertainty in the mesh stack comes from the fluctuation in time to encrypt a message and broadcast it, and can be configured through the :option:`CONFIG_BT_MESH_TIME_MESH_HOP_UNCERTAINTY`. +The expected uncertainty in the mesh stack comes from the fluctuation in time to encrypt a message and broadcast it, and can be configured through the :kconfig:`CONFIG_BT_MESH_TIME_MESH_HOP_UNCERTAINTY`. In addition to the uncertainty added by the mesh stack itself, the internal clock of each device will increase the uncertainty of the timestamp over time. As crystal hardware is not perfectly accurate, it will gradually drift away from the correct time. The potential range of this clock drift is generally a known property of the onboard hardware, even if the actual drift fluctuates. As it's impossible to measure the actual clock drift at any given moment, the Time Server will instead gradually increase the uncertainty of its timestamp based on the known clock accuracy. -The Time Server's notion of the local clock accuracy can be configured with :option:`CONFIG_BT_MESH_TIME_SRV_CLOCK_ACCURACY`. +The Time Server's notion of the local clock accuracy can be configured with :kconfig:`CONFIG_BT_MESH_TIME_SRV_CLOCK_ACCURACY`. By default, it uses the configured kernel clock control accuracy. Leap seconds and time zones @@ -161,8 +161,8 @@ Configuration The clock uncertainty of the Time Server model can be configured with the following configuration options: -* :option:`CONFIG_BT_MESH_TIME_MESH_HOP_UNCERTAINTY`: The amount of uncertainty introduced in the mesh stack through sending a single message, in milliseconds. -* :option:`CONFIG_BT_MESH_TIME_SRV_CLOCK_ACCURACY`: The largest possible clock drift introduced by the kernel clock's hardware, in parts per million. +* :kconfig:`CONFIG_BT_MESH_TIME_MESH_HOP_UNCERTAINTY`: The amount of uncertainty introduced in the mesh stack through sending a single message, in milliseconds. +* :kconfig:`CONFIG_BT_MESH_TIME_SRV_CLOCK_ACCURACY`: The largest possible clock drift introduced by the kernel clock's hardware, in parts per million. States ====== diff --git a/doc/nrf/libraries/bluetooth_services/mesh/vnd/silvair_enocean_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/vnd/silvair_enocean_srv.rst index ebb5356ff13d..526e50ed43c0 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/vnd/silvair_enocean_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/vnd/silvair_enocean_srv.rst @@ -11,7 +11,7 @@ The Silvair EnOcean Proxy Server model integrates an EnOcean switch together wit It implements the `Silvair EnOcean Switch Mesh Proxy Server`_ specification. The model initializes the :ref:`bt_enocean_readme` library. -The EnOcean switch can be automatically commissioned if option :option:`CONFIG_BT_MESH_SILVAIR_ENOCEAN_AUTO_COMMISSION` is set. +The EnOcean switch can be automatically commissioned if option :kconfig:`CONFIG_BT_MESH_SILVAIR_ENOCEAN_AUTO_COMMISSION` is set. The Silvair EnOcean Proxy Server uses either one or two elements on a node. Each element handles its own button pair and has its own corresponding :ref:`bt_mesh_onoff_srv_readme` and :ref:`bt_mesh_lvl_srv_readme` models. @@ -55,7 +55,7 @@ None Persistent storage ================== -If :option:`CONFIG_BT_ENOCEAN_STORE` is enabled, the Silvair EnOcean Proxy Server stores the commissioned EnOcean device address. +If :kconfig:`CONFIG_BT_ENOCEAN_STORE` is enabled, the Silvair EnOcean Proxy Server stores the commissioned EnOcean device address. API documentation ================= diff --git a/doc/nrf/libraries/bluetooth_services/rpc.rst b/doc/nrf/libraries/bluetooth_services/rpc.rst index 2cbfdd5ad73c..1b5ade1253fa 100644 --- a/doc/nrf/libraries/bluetooth_services/rpc.rst +++ b/doc/nrf/libraries/bluetooth_services/rpc.rst @@ -12,9 +12,9 @@ The full Bluetooth LE stack can run on another device or CPU, such as the nRF534 .. note:: The |NCS| currently supports serialization of the :ref:`zephyr:bt_gap` and the :ref:`zephyr:bluetooth_connection_mgmt` only. - Due to the limited support, a special :option:`CONFIG_SUPPORT_BT_RPC` option was added and it allows enabling the :option:`CONFIG_BT_RPC` option. - Samples using other Bluetooth LE features, such as GATT, are currently not supported and they have the :option:`CONFIG_SUPPORT_BT_RPC` option disabled. - If you want to use the :option:`CONFIG_BT_RPC` option in your application, you must create a Kconfig file with following content: + Due to the limited support, a special :kconfig:`CONFIG_SUPPORT_BT_RPC` option was added and it allows enabling the :kconfig:`CONFIG_BT_RPC` option. + Samples using other Bluetooth LE features, such as GATT, are currently not supported and they have the :kconfig:`CONFIG_SUPPORT_BT_RPC` option disabled. + If you want to use the :kconfig:`CONFIG_BT_RPC` option in your application, you must create a Kconfig file with following content: .. code-block:: none @@ -35,7 +35,7 @@ Application core **************** To use the Bluetooth LE stack through nRF RPC, an additional configuration is needed. -When building samples for the application core, enable the :option:`CONFIG_BT_RPC` to run the Bluetooth LE stack on the network core. +When building samples for the application core, enable the :kconfig:`CONFIG_BT_RPC` to run the Bluetooth LE stack on the network core. This option builds :ref:`ble_rpc_host` automatically as a child image. For more details, see: :ref:`ug_nrf5340_building`. @@ -51,34 +51,34 @@ Requirements Some configuration options related to Bluetooth LE must be the same on the host (network core) and client (application core). Set the following options in the same way for the :ref:`ble_rpc_host` and application core sample: - * :option:`CONFIG_BT_CENTRAL` - * :option:`CONFIG_BT_PERIPHERAL` - * :option:`CONFIG_BT_WHITELIST` - * :option:`CONFIG_BT_USER_PHY_UPDATE` - * :option:`CONFIG_BT_USER_DATA_LEN_UPDATE` - * :option:`CONFIG_BT_PRIVACY` - * :option:`CONFIG_BT_SCAN_WITH_IDENTITY` - * :option:`CONFIG_BT_REMOTE_VERSION` - * :option:`CONFIG_BT_SMP` - * :option:`CONFIG_BT_CONN` - * :option:`CONFIG_BT_REMOTE_INFO` - * :option:`CONFIG_BT_FIXED_PASSKEY` - * :option:`CONFIG_BT_SMP_APP_PAIRING_ACCEPT` - * :option:`CONFIG_BT_EXT_ADV` - * :option:`CONFIG_BT_OBSERVER` - * :option:`CONFIG_BT_ECC` - * :option:`CONFIG_BT_DEVICE_NAME_DYNAMIC` - * :option:`CONFIG_BT_SMP_SC_PAIR_ONLY` - * :option:`CONFIG_BT_PER_ADV` - * :option:`CONFIG_BT_PER_ADV_SYNC` - * :option:`CONFIG_BT_MAX_CONN` - * :option:`CONFIG_BT_ID_MAX` - * :option:`CONFIG_BT_EXT_ADV_MAX_ADV_SET` - * :option:`CONFIG_BT_DEVICE_NAME_MAX` - * :option:`CONFIG_BT_DEVICE_NAME_MAX` - * :option:`CONFIG_BT_PER_ADV_SYNC_MAX` - * :option:`CONFIG_BT_DEVICE_NAME` - * :option:`CONFIG_CBKPROXY_OUT_SLOTS` on one core must be equal to :option:`CONFIG_CBKPROXY_IN_SLOTS` on the other. + * :kconfig:`CONFIG_BT_CENTRAL` + * :kconfig:`CONFIG_BT_PERIPHERAL` + * :kconfig:`CONFIG_BT_WHITELIST` + * :kconfig:`CONFIG_BT_USER_PHY_UPDATE` + * :kconfig:`CONFIG_BT_USER_DATA_LEN_UPDATE` + * :kconfig:`CONFIG_BT_PRIVACY` + * :kconfig:`CONFIG_BT_SCAN_WITH_IDENTITY` + * :kconfig:`CONFIG_BT_REMOTE_VERSION` + * :kconfig:`CONFIG_BT_SMP` + * :kconfig:`CONFIG_BT_CONN` + * :kconfig:`CONFIG_BT_REMOTE_INFO` + * :kconfig:`CONFIG_BT_FIXED_PASSKEY` + * :kconfig:`CONFIG_BT_SMP_APP_PAIRING_ACCEPT` + * :kconfig:`CONFIG_BT_EXT_ADV` + * :kconfig:`CONFIG_BT_OBSERVER` + * :kconfig:`CONFIG_BT_ECC` + * :kconfig:`CONFIG_BT_DEVICE_NAME_DYNAMIC` + * :kconfig:`CONFIG_BT_SMP_SC_PAIR_ONLY` + * :kconfig:`CONFIG_BT_PER_ADV` + * :kconfig:`CONFIG_BT_PER_ADV_SYNC` + * :kconfig:`CONFIG_BT_MAX_CONN` + * :kconfig:`CONFIG_BT_ID_MAX` + * :kconfig:`CONFIG_BT_EXT_ADV_MAX_ADV_SET` + * :kconfig:`CONFIG_BT_DEVICE_NAME_MAX` + * :kconfig:`CONFIG_BT_DEVICE_NAME_MAX` + * :kconfig:`CONFIG_BT_PER_ADV_SYNC_MAX` + * :kconfig:`CONFIG_BT_DEVICE_NAME` + * :kconfig:`CONFIG_CBKPROXY_OUT_SLOTS` on one core must be equal to :kconfig:`CONFIG_CBKPROXY_IN_SLOTS` on the other. To keep all the above configuration options in sync, create an overlay file that is shared between the application and network core. Then, you can invoke build command like this: diff --git a/doc/nrf/libraries/bluetooth_services/scan.rst b/doc/nrf/libraries/bluetooth_services/scan.rst index 868bfa717b9b..990071592cb0 100644 --- a/doc/nrf/libraries/bluetooth_services/scan.rst +++ b/doc/nrf/libraries/bluetooth_services/scan.rst @@ -109,7 +109,7 @@ After a scanning is started by the application, some peripheral devices can disc This might result in a loop of the connection and disconnection events. To avoid this loop, you can enable the connection attempts filter that limits number of the connection attempts. -Use the :option:`CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER` to enable this filter. +Use the :kconfig:`CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER` to enable this filter. This filter automatically tracks the connected devices and counts all disconnection events for them. If the disconnection count is greater than or equal to the number of allowed attempts, the scanning module ignores this device. @@ -119,17 +119,17 @@ It is recommended to use :cpp:func:`bt_scan_conn_attempts_filter_clear` before e If the filter array is full, the scanning module overwrites the oldest device with the new one. In the default configuration, the filter allows to add two devices and limits the connection tries to two. -You can increase the device number by setting the configuration option :option:`CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER_LEN`. -The option :option:`CONFIG_BT_SCAN_CONN_ATTEMPTS_COUNT` is responsible for the number of connection attempts. +You can increase the device number by setting the configuration option :kconfig:`CONFIG_BT_SCAN_CONN_ATTEMPTS_FILTER_LEN`. +The option :kconfig:`CONFIG_BT_SCAN_CONN_ATTEMPTS_COUNT` is responsible for the number of connection attempts. Blocklist ========= Devices can be added to the blocklist, which means that the scanning module ignores these devices and does not generate any events for them. -Use the option :option:`CONFIG_BT_SCAN_BLOCKLIST` to enable the blocklist. +Use the option :kconfig:`CONFIG_BT_SCAN_BLOCKLIST` to enable the blocklist. In the default configuration, the scanning module allows to add up to two devices to the blocklist. -You can increase the blocklist size by setting the option :option:`CONFIG_BT_SCAN_BLOCKLIST_LEN`. +You can increase the blocklist size by setting the option :kconfig:`CONFIG_BT_SCAN_BLOCKLIST_LEN`. Use the :cpp:func:`bt_scan_blocklist_device_add` function to add a new device to the blocklist. To remove all devices from the blocklist, use :cpp:func:`bt_scan_blocklist_clear`. @@ -141,11 +141,11 @@ Directed Advertising To receive directed advertising packets using the Scanning Module, enable one of the following options in Zephyr: -* :option:`CONFIG_BT_PRIVACY` - Scan with changing addresses -* :option:`CONFIG_BT_SCAN_WITH_IDENTITY` - Scan with a local identity address +* :kconfig:`CONFIG_BT_PRIVACY` - Scan with changing addresses +* :kconfig:`CONFIG_BT_SCAN_WITH_IDENTITY` - Scan with a local identity address -It is recommended to enable the :option:`CONFIG_BT_PRIVACY` option to support directed advertising only between bonded peers. -Use the :option:`CONFIG_BT_SCAN_WITH_IDENTITY` option only when the :option:`CONFIG_BT_PRIVACY` option is not available. +It is recommended to enable the :kconfig:`CONFIG_BT_PRIVACY` option to support directed advertising only between bonded peers. +Use the :kconfig:`CONFIG_BT_SCAN_WITH_IDENTITY` option only when the :kconfig:`CONFIG_BT_PRIVACY` option is not available. When the scanning module is set in advanced mode and :ref:`filters ` are set, you can use the ``filter_no_match`` event to check if directed advertising packets have been received. They will typically not match any filter as, by specification, they do not contain any advertising data. diff --git a/doc/nrf/libraries/bluetooth_services/services/hogp.rst b/doc/nrf/libraries/bluetooth_services/services/hogp.rst index 58ec6129c084..e88838900af6 100644 --- a/doc/nrf/libraries/bluetooth_services/services/hogp.rst +++ b/doc/nrf/libraries/bluetooth_services/services/hogp.rst @@ -25,7 +25,7 @@ Configuration Apart from standard configuration parameters, there is one important setting: -:option:`CONFIG_BT_HOGP_REPORTS_MAX` +:kconfig:`CONFIG_BT_HOGP_REPORTS_MAX` Sets the maximum number of total reports supported by the library. The report memory is shared along all HIDS client objects, so this option should be set to the maximum total number of reports supported by the application. diff --git a/doc/nrf/libraries/caf/ble_adv.rst b/doc/nrf/libraries/caf/ble_adv.rst index a632fa1436cd..72f51334b6e5 100644 --- a/doc/nrf/libraries/caf/ble_adv.rst +++ b/doc/nrf/libraries/caf/ble_adv.rst @@ -17,14 +17,14 @@ Configuration The following Kconfig options are available for this module: -* :option:`CONFIG_CAF_BLE_ADV` -* :option:`CONFIG_CAF_BLE_ADV_DEF_PATH` -* :option:`CONFIG_CAF_BLE_ADV_PM_EVENTS` -* :option:`CONFIG_CAF_BLE_ADV_DIRECT_ADV` -* :option:`CONFIG_CAF_BLE_ADV_FAST_ADV` -* :option:`CONFIG_CAF_BLE_ADV_FAST_ADV_TIMEOUT` -* :option:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR` -* :option:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR_GRACE_PERIOD` +* :kconfig:`CONFIG_CAF_BLE_ADV` +* :kconfig:`CONFIG_CAF_BLE_ADV_DEF_PATH` +* :kconfig:`CONFIG_CAF_BLE_ADV_PM_EVENTS` +* :kconfig:`CONFIG_CAF_BLE_ADV_DIRECT_ADV` +* :kconfig:`CONFIG_CAF_BLE_ADV_FAST_ADV` +* :kconfig:`CONFIG_CAF_BLE_ADV_FAST_ADV_TIMEOUT` +* :kconfig:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR` +* :kconfig:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR_GRACE_PERIOD` Read about some of these options in the following sections. @@ -34,9 +34,9 @@ Enabling the module To enable the |ble_adv|, complete the following steps: 1. Enable and configure the :ref:`CAF Bluetooth LE state module `. -#. Define the Bluetooth device name using the :option:`CONFIG_BT_DEVICE_NAME` Kconfig option. -#. Define the Bluetooth device appearance using the :option:`CONFIG_BT_DEVICE_APPEARANCE` Kconfig option. -#. Set the :option:`CONFIG_CAF_BLE_ADV` Kconfig option. +#. Define the Bluetooth device name using the :kconfig:`CONFIG_BT_DEVICE_NAME` Kconfig option. +#. Define the Bluetooth device appearance using the :kconfig:`CONFIG_BT_DEVICE_APPEARANCE` Kconfig option. +#. Set the :kconfig:`CONFIG_CAF_BLE_ADV` Kconfig option. #. Create a configuration file that defines Bluetooth LE advertising data. #. In the configuration file, define the following arrays of :c:struct:`bt_data`: @@ -67,7 +67,7 @@ To enable the |ble_adv|, complete the following steps: static const struct bt_data sd[] = {}; -#. Specify the path to the configuration file with the :option:`CONFIG_CAF_BLE_ADV_DEF_PATH` Kconfig option. +#. Specify the path to the configuration file with the :kconfig:`CONFIG_CAF_BLE_ADV_DEF_PATH` Kconfig option. .. note:: The configuration file should be included only by the configured module. @@ -77,7 +77,7 @@ Using directed advertising ========================== By default, the module uses indirect advertising. -Set the :option:`CONFIG_CAF_BLE_ADV_DIRECT_ADV` option to use directed advertising. +Set the :kconfig:`CONFIG_CAF_BLE_ADV_DIRECT_ADV` option to use directed advertising. The directed advertising can be used to call the selected peer device to connect as quickly as possible. .. note:: @@ -87,10 +87,10 @@ The directed advertising can be used to call the selected peer device to connect Changing advertising interval ============================= -Set the :option:`CONFIG_CAF_BLE_ADV_FAST_ADV` Kconfig option to make the Peripheral initially advertise with a shorter interval. +Set the :kconfig:`CONFIG_CAF_BLE_ADV_FAST_ADV` Kconfig option to make the Peripheral initially advertise with a shorter interval. This lets you speed up finding the Peripheral by Bluetooth Centrals. -* If the device uses indirect advertising, it will switch to slower advertising after the period of time defined in :option:`CONFIG_CAF_BLE_ADV_FAST_ADV_TIMEOUT` (in seconds). +* If the device uses indirect advertising, it will switch to slower advertising after the period of time defined in :kconfig:`CONFIG_CAF_BLE_ADV_FAST_ADV_TIMEOUT` (in seconds). * If the device uses directed advertising, the |ble_adv| will receive :c:struct:`ble_peer_event` with :c:member:`ble_peer_event.state` set to :c:enumerator:`PEER_STATE_CONN_FAILED` if the Central does not connect during the predefined period of fast directed advertising. The :c:struct:`ble_peer_event` is submitted by :ref:`caf_ble_state`. After the event is received, the device will switch to the low duty cycle directed advertising. @@ -100,11 +100,11 @@ Switching to slower advertising is done to reduce the energy consumption. Using Swift Pair ================ -You can use the :option:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR` option to enable the Swift Pair feature. +You can use the :kconfig:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR` option to enable the Swift Pair feature. The feature simplifies pairing the Bluetooth Peripheral with Windows 10 hosts. .. note:: - Make sure to add the Swift Pair data to advertising packets for unbonded device in the configuration file if you enable :option:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR` option. + Make sure to add the Swift Pair data to advertising packets for unbonded device in the configuration file if you enable :kconfig:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR` option. The Swift Pair data must be added as the last member of ``ad_unbonded`` array. Power-down @@ -112,7 +112,7 @@ Power-down When the system goes to the Power-down state, the advertising stops. -If the Swift Pair feature is enabled with :option:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR`, the device advertises without the Swift Pair data for additional :option:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR_GRACE_PERIOD` seconds to ensure that the user does not try to connect to the device that is no longer available. +If the Swift Pair feature is enabled with :kconfig:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR`, the device advertises without the Swift Pair data for additional :kconfig:`CONFIG_CAF_BLE_ADV_SWIFT_PAIR_GRACE_PERIOD` seconds to ensure that the user does not try to connect to the device that is no longer available. Implementation details ********************** @@ -124,7 +124,7 @@ The |ble_adv| uses Zephyr's :ref:`zephyr:settings_api` to store the information Reaction on Bluetooth peer operation ==================================== -If the application supports Bluetooth LE bond management (:option:`CONFIG_CAF_BLE_BOND_SUPPORTED`), the Bluetooth LE bond module defined for the application is used to control the Bluetooth bonds. +If the application supports Bluetooth LE bond management (:kconfig:`CONFIG_CAF_BLE_BOND_SUPPORTED`), the Bluetooth LE bond module defined for the application is used to control the Bluetooth bonds. The Bluetooth LE bond module broadcasts information related to bond control using :c:struct:`ble_peer_operation_event`. The |ble_adv| reacts on :c:struct:`ble_peer_operation_event` related to the Bluetooth peer change or erase advertising. @@ -136,7 +136,7 @@ The module performs one of the following operations: Avoiding connection requests from unbonded centrals when bonded =============================================================== -If :option:`CONFIG_BT_WHITELIST` is enabled and Bluetooth local identity that is in use already has a bond, the device will whitelist incoming scan response data requests and connection requests. +If :kconfig:`CONFIG_BT_WHITELIST` is enabled and Bluetooth local identity that is in use already has a bond, the device will whitelist incoming scan response data requests and connection requests. This is done to prevent Bluetooth Centrals other than the bonded one from connecting with the device. .. |ble_adv| replace:: Bluetooth LE advertising module diff --git a/doc/nrf/libraries/caf/ble_smp.rst b/doc/nrf/libraries/caf/ble_smp.rst index c7adb2bd1a89..040a7ddb88bb 100644 --- a/doc/nrf/libraries/caf/ble_smp.rst +++ b/doc/nrf/libraries/caf/ble_smp.rst @@ -14,12 +14,12 @@ Configuration To use the module, you must enable the following Kconfig options: -* :option:`CONFIG_CAF_BLE_STATE` - This module enables :ref:`caf_ble_state` module. -* :option:`CONFIG_CAF_BLE_SMP` - This option enables |smp| over Bluetooth LE. -* :option:`CONFIG_MCUMGR_CMD_IMG_MGMT` - This option enables MCUmgr image management handlers, which are required for the DFU process. +* :kconfig:`CONFIG_CAF_BLE_STATE` - This module enables :ref:`caf_ble_state` module. +* :kconfig:`CONFIG_CAF_BLE_SMP` - This option enables |smp| over Bluetooth LE. +* :kconfig:`CONFIG_MCUMGR_CMD_IMG_MGMT` - This option enables MCUmgr image management handlers, which are required for the DFU process. For details, see :ref:`zephyr:device_mgmt` in the Zephyr documentation. -* :option:`CONFIG_MCUMGR_SMP_BT` - This option enables support for the SMP commands over Bluetooth. -* :option:`CONFIG_BOOTLOADER_MCUBOOT` - This option enables the MCUboot bootloader. +* :kconfig:`CONFIG_MCUMGR_SMP_BT` - This option enables support for the SMP commands over Bluetooth. +* :kconfig:`CONFIG_BOOTLOADER_MCUBOOT` - This option enables the MCUboot bootloader. The DFU over Simple Management Protocol in Zephyr is supported only with the MCUboot bootloader. Enabling remote OS management @@ -27,7 +27,7 @@ Enabling remote OS management The |smp| supports registering OS management handlers automatically, which you can enable using the following Kconfig option: -* :option:`CONFIG_MCUMGR_CMD_OS_MGMT` - This option enables MCUmgr OS management handlers. +* :kconfig:`CONFIG_MCUMGR_CMD_OS_MGMT` - This option enables MCUmgr OS management handlers. Use these handlers to remotely trigger the device reboot after the image transfer is completed. After the reboot, the device starts using the new firmware. One of the applications that support the remote reboot functionality is `nRF Connect for Mobile`_. diff --git a/doc/nrf/libraries/caf/ble_state.rst b/doc/nrf/libraries/caf/ble_state.rst index 927721784839..d31b29e604e8 100644 --- a/doc/nrf/libraries/caf/ble_state.rst +++ b/doc/nrf/libraries/caf/ble_state.rst @@ -25,17 +25,17 @@ Configuration To use the module, you must enable the following Kconfig options: -* :option:`CONFIG_BT` -* :option:`CONFIG_BT_SMP` - This option enables Security Manager Protocol support. +* :kconfig:`CONFIG_BT` +* :kconfig:`CONFIG_BT_SMP` - This option enables Security Manager Protocol support. The |ble_state| on Bluetooth Peripheral requires at least the connection security level 2 (encryption). -* :option:`CONFIG_CAF_BLE_STATE` - This option enables the |ble_state| and selects the :option:`CONFIG_CAF_BLE_COMMON_EVENTS` Kconfig option, which enables Bluetooth LE common events in CAF. +* :kconfig:`CONFIG_CAF_BLE_STATE` - This option enables the |ble_state| and selects the :kconfig:`CONFIG_CAF_BLE_COMMON_EVENTS` Kconfig option, which enables Bluetooth LE common events in CAF. The following Kconfig options are also available for this module: -* :option:`CONFIG_CAF_BLE_STATE_EXCHANGE_MTU` - This option can be used for GATT client (:option:`CONFIG_BT_GATT_CLIENT`) to set the Maximum Transmission Unit (MTU) to the maximum possible size that the buffers can hold. +* :kconfig:`CONFIG_CAF_BLE_STATE_EXCHANGE_MTU` - This option can be used for GATT client (:kconfig:`CONFIG_BT_GATT_CLIENT`) to set the Maximum Transmission Unit (MTU) to the maximum possible size that the buffers can hold. This option is enabled by default. -* :option:`CONFIG_CAF_BLE_USE_LLPM` - This option enables the Low Latency Packet Mode (LLPM). - This option is enabled by default and depends on :option:`CONFIG_BT_CTLR_LLPM` and :option:`CONFIG_BT_LL_SOFTDEVICE`. +* :kconfig:`CONFIG_CAF_BLE_USE_LLPM` - This option enables the Low Latency Packet Mode (LLPM). + This option is enabled by default and depends on :kconfig:`CONFIG_BT_CTLR_LLPM` and :kconfig:`CONFIG_BT_LL_SOFTDEVICE`. Implementation details ********************** @@ -87,7 +87,7 @@ After :c:struct:`ble_peer_event` about disconnection or connection failure is re Behavior with SoftDevice Link Layer =================================== -If Nordic Semiconductor's SoftDevice Bluetooth LE Link Layer is selected (:option:`CONFIG_BT_LL_SOFTDEVICE`) and the :option:`CONFIG_CAF_BLE_USE_LLPM` option is enabled, the |ble_state| sends a Bluetooth HCI command to enable the LLPM when Bluetooth is ready. +If Nordic Semiconductor's SoftDevice Bluetooth LE Link Layer is selected (:kconfig:`CONFIG_BT_LL_SOFTDEVICE`) and the :kconfig:`CONFIG_CAF_BLE_USE_LLPM` option is enabled, the |ble_state| sends a Bluetooth HCI command to enable the LLPM when Bluetooth is ready. If the SoftDevice Link Layer is selected, the |ble_state| also sets the TX power for connections. The TX power is set according to Zephyr's Kconfig options related to selecting the default TX power. diff --git a/doc/nrf/libraries/caf/buttons.rst b/doc/nrf/libraries/caf/buttons.rst index f4c91613419f..f50a78dceee3 100644 --- a/doc/nrf/libraries/caf/buttons.rst +++ b/doc/nrf/libraries/caf/buttons.rst @@ -16,8 +16,8 @@ Configuration To use the module, you must enable the following Kconfig options: -* :option:`CONFIG_CAF_BUTTONS` - This option enables the buttons module. -* :option:`CONFIG_GPIO` - This option enables Zephyr's :ref:`zephyr:gpio_api` driver, which is required for interacting with the GPIO pins. +* :kconfig:`CONFIG_CAF_BUTTONS` - This option enables the buttons module. +* :kconfig:`CONFIG_GPIO` - This option enables Zephyr's :ref:`zephyr:gpio_api` driver, which is required for interacting with the GPIO pins. When defining how buttons are connected, you must create a configuration file with the following arrays: @@ -42,7 +42,7 @@ For example, the file contents should look like follows: { .port = 1, .pin = 14 }, }; -You must define both arrays in this configuration file, and specify its location with the :option:`CONFIG_CAF_BUTTONS_DEF_PATH` Kconfig option. +You must define both arrays in this configuration file, and specify its location with the :kconfig:`CONFIG_CAF_BUTTONS_DEF_PATH` Kconfig option. .. note:: The configuration file should be included only by the configured module. @@ -50,15 +50,15 @@ You must define both arrays in this configuration file, and specify its location The following Kconfig options are available for this module: -* :option:`CONFIG_CAF_BUTTONS_DEF_PATH` -* :option:`CONFIG_CAF_BUTTONS_PM_EVENTS` -* :option:`CONFIG_CAF_BUTTONS_SCAN_INTERVAL` -* :option:`CONFIG_CAF_BUTTONS_DEBOUNCE_INTERVAL` -* :option:`CONFIG_CAF_BUTTONS_POLARITY_INVERSED` -* :option:`CONFIG_CAF_BUTTONS_EVENT_LIMIT` +* :kconfig:`CONFIG_CAF_BUTTONS_DEF_PATH` +* :kconfig:`CONFIG_CAF_BUTTONS_PM_EVENTS` +* :kconfig:`CONFIG_CAF_BUTTONS_SCAN_INTERVAL` +* :kconfig:`CONFIG_CAF_BUTTONS_DEBOUNCE_INTERVAL` +* :kconfig:`CONFIG_CAF_BUTTONS_POLARITY_INVERSED` +* :kconfig:`CONFIG_CAF_BUTTONS_EVENT_LIMIT` By default, a button press is indicated by a pin switch from the low to the high state. -You can change this with :option:`CONFIG_CAF_BUTTONS_POLARITY_INVERSED`, which will cause the application to react to an opposite pin change (from the high to the low state). +You can change this with :kconfig:`CONFIG_CAF_BUTTONS_POLARITY_INVERSED`, which will cause the application to react to an opposite pin change (from the high to the low state). Implementation details ********************** @@ -80,17 +80,17 @@ If no buttons are pressed the module switches to ``STATE_ACTIVE``. In this state, the module enables the GPIO interrupts and waits for the pin state to change. Whenever a button is pressed, the module switches to ``STATE_SCANNING``. -When the switch occurs, the module submits a work with a delay set to :option:`CONFIG_CAF_BUTTONS_DEBOUNCE_INTERVAL`. +When the switch occurs, the module submits a work with a delay set to :kconfig:`CONFIG_CAF_BUTTONS_DEBOUNCE_INTERVAL`. The work scans the keyboard matrix, or directly connected buttons (depends on configuration). If any button state change occurs, the module sends related event. -* If the button is kept pressed while the scanning is performed, the work will be resubmitted with a delay set to :option:`CONFIG_CAF_BUTTONS_SCAN_INTERVAL`. +* If the button is kept pressed while the scanning is performed, the work will be resubmitted with a delay set to :kconfig:`CONFIG_CAF_BUTTONS_SCAN_INTERVAL`. * If no button is pressed, the module switches back to ``STATE_ACTIVE``. Power management states ======================= -If the :option:`CONFIG_CAF_BUTTONS_PM_EVENTS` Kconfig option is enabled, the module can react to power management events and submit ``wake_up_event``. +If the :kconfig:`CONFIG_CAF_BUTTONS_PM_EVENTS` Kconfig option is enabled, the module can react to power management events and submit ``wake_up_event``. In that case, the following additional states are available: * ``STATE_SUSPENDING`` diff --git a/doc/nrf/libraries/caf/caf_overview.rst b/doc/nrf/libraries/caf/caf_overview.rst index fed91b95b4c2..6c804acdaf58 100644 --- a/doc/nrf/libraries/caf/caf_overview.rst +++ b/doc/nrf/libraries/caf/caf_overview.rst @@ -38,7 +38,7 @@ Enabling CAF To enable CAF, complete the following steps: -1. Enable :option:`CONFIG_CAF` Kconfig option in your project configuration file. +1. Enable :kconfig:`CONFIG_CAF` Kconfig option in your project configuration file. #. Enable and initialize Event Manager. See :ref:`event_manager_configuration` for more details. #. Submit the first :c:struct:`module_state_event`. diff --git a/doc/nrf/libraries/caf/click_detector.rst b/doc/nrf/libraries/caf/click_detector.rst index 660a5c38cf3b..cbc3a670ae2b 100644 --- a/doc/nrf/libraries/caf/click_detector.rst +++ b/doc/nrf/libraries/caf/click_detector.rst @@ -14,13 +14,13 @@ Configuration To use the module, you must enable the following Kconfig options: -* :option:`CONFIG_CAF_CLICK_DETECTOR` - This option enables the |click_detector|. -* :option:`CONFIG_CAF_BUTTON_EVENTS` - This option enables the ``button_event`` that is required for the |click_detector| to work. +* :kconfig:`CONFIG_CAF_CLICK_DETECTOR` - This option enables the |click_detector|. +* :kconfig:`CONFIG_CAF_BUTTON_EVENTS` - This option enables the ``button_event`` that is required for the |click_detector| to work. -In addition to :option:`CONFIG_CAF_CLICK_DETECTOR`, the following Kconfig options are available for the module: +In addition to :kconfig:`CONFIG_CAF_CLICK_DETECTOR`, the following Kconfig options are available for the module: -* :option:`CONFIG_CAF_CLICK_DETECTOR_DEF_PATH` -* :option:`CONFIG_CAF_CLICK_DETECTOR_PM_EVENTS` +* :kconfig:`CONFIG_CAF_CLICK_DETECTOR_DEF_PATH` +* :kconfig:`CONFIG_CAF_CLICK_DETECTOR_PM_EVENTS` Adding module configuration file ================================ @@ -51,7 +51,7 @@ To do so, complete the following steps: .. note:: The :c:macro:`KEY_ID` macro is defined in :file:`include/caf/key_id.h`. -#. Specify the location of the file with the :option:`CONFIG_CAF_CLICK_DETECTOR_DEF_PATH` Kconfig option. +#. Specify the location of the file with the :kconfig:`CONFIG_CAF_CLICK_DETECTOR_DEF_PATH` Kconfig option. .. note:: The configuration file should be included only by the configured module. @@ -80,7 +80,7 @@ The exact values of time intervals for click types are defined in the :file:`sub Power management states ======================= -If the option :option:`CONFIG_CAF_CLICK_DETECTOR_PM_EVENTS` is enabled, the module can react to power management events. +If the option :kconfig:`CONFIG_CAF_CLICK_DETECTOR_PM_EVENTS` is enabled, the module can react to power management events. The module stops tracing of key states when ``power_down_event`` is received. The module starts operating again when ``wake_up_event`` is received. diff --git a/doc/nrf/libraries/caf/leds.rst b/doc/nrf/libraries/caf/leds.rst index e70f5dfbe238..ab82e9866113 100644 --- a/doc/nrf/libraries/caf/leds.rst +++ b/doc/nrf/libraries/caf/leds.rst @@ -22,31 +22,31 @@ To use the module, you must conplete the following requirements: 1. Enable the following Kconfig options: - * :option:`CONFIG_CAF_LEDS` - This option enables the LEDs module. - * :option:`CONFIG_LED` - This option enables the LED driver API. + * :kconfig:`CONFIG_CAF_LEDS` - This option enables the LEDs module. + * :kconfig:`CONFIG_LED` - This option enables the LED driver API. #. Complete one of the following steps to choose and configure the LED driver implementation: a. For the PWM-based implementation, Zephyr's :ref:`zephyr:pwm_api` driver is used for setting the LED color (that is, the brightness of the diodes). For this reason, set the following options: - * :option:`CONFIG_CAF_LEDS_PWM` - * :option:`CONFIG_LED_PWM` - * :option:`CONFIG_PWM` + * :kconfig:`CONFIG_CAF_LEDS_PWM` + * :kconfig:`CONFIG_LED_PWM` + * :kconfig:`CONFIG_PWM` b. For the GPIO-based implementation, Zephyr's :ref:`zephyr:gpio_api` driver is used for setting the LED color (that is, the brightness of the diodes). For this reason, set the following options: - * :option:`CONFIG_CAF_LEDS_GPIO` - * :option:`CONFIG_LED_GPIO` - * :option:`CONFIG_GPIO` + * :kconfig:`CONFIG_CAF_LEDS_GPIO` + * :kconfig:`CONFIG_LED_GPIO` + * :kconfig:`CONFIG_GPIO` #. Configure LEDs in DTS. See `Configuring LEDs in DTS`_ for details. The following Kconfig options are also available for this module: -* :option:`CONFIG_CAF_LEDS_PM_EVENTS` - This option enables the reaction to `Power management events`_. +* :kconfig:`CONFIG_CAF_LEDS_PM_EVENTS` - This option enables the reaction to `Power management events`_. .. note:: The GPIO-based LED driver implementation supports only turning LED on or off. @@ -293,7 +293,7 @@ If the flag is not set, the sequence stops and the given LED effect ends. Power management events ======================= -If the :option:`CONFIG_CAF_LEDS_PM_EVENTS` Kconfig option is enabled, the module can react to following power management events: +If the :kconfig:`CONFIG_CAF_LEDS_PM_EVENTS` Kconfig option is enabled, the module can react to following power management events: * ``power_down_event`` * ``wake_up_event`` diff --git a/doc/nrf/libraries/caf/power_manager.rst b/doc/nrf/libraries/caf/power_manager.rst index 125b3d4033cb..b3186c856207 100644 --- a/doc/nrf/libraries/caf/power_manager.rst +++ b/doc/nrf/libraries/caf/power_manager.rst @@ -13,22 +13,22 @@ The module achieves this reduction by switching to low power modes when the devi Configuration ************* -You can enable the |power_manager| by selecting the :option:`CONFIG_CAF_POWER_MANAGER` option in the configuration. +You can enable the |power_manager| by selecting the :kconfig:`CONFIG_CAF_POWER_MANAGER` option in the configuration. This module uses Zephyr's :ref:`zephyr:power_management_api` subsystem. Timeout configuration options ============================= -With the :option:`CONFIG_CAF_POWER_MANAGER_TIMEOUT` configuration option, you can set the period of time after which the application enters the low power mode. +With the :kconfig:`CONFIG_CAF_POWER_MANAGER_TIMEOUT` configuration option, you can set the period of time after which the application enters the low power mode. By default, the timeout is set to 120 seconds. -The :option:`CONFIG_CAF_POWER_MANAGER_ERROR_TIMEOUT` sets the period of time after which the device is turned off upon an internal error. +The :kconfig:`CONFIG_CAF_POWER_MANAGER_ERROR_TIMEOUT` sets the period of time after which the device is turned off upon an internal error. Optional boolean for keeping the system on ========================================== -The :option:`CONFIG_CAF_POWER_MANAGER_STAY_ON` lets the system stay on also when there are no active connections. +The :kconfig:`CONFIG_CAF_POWER_MANAGER_STAY_ON` lets the system stay on also when there are no active connections. For more information about configuration options, check the help in the configuration tool. @@ -100,7 +100,7 @@ Error The |power_manager| checks if any application modules have reported an error condition. When any application module switches to the error state (that is, broadcasts :c:enum:`MODULE_STATE_ERROR` through :c:struct:`module_state_event`), the |power_manager| puts the application into the error state. -Then, after the period of time defined by :option:`CONFIG_CAF_POWER_MANAGER_ERROR_TIMEOUT`, it puts the application to the off state. +Then, after the period of time defined by :kconfig:`CONFIG_CAF_POWER_MANAGER_ERROR_TIMEOUT`, it puts the application to the off state. During this period, other modules can report the error condition to the user (for example, :ref:`caf_leds` can keep working in the error state). Restricting power states @@ -128,7 +128,7 @@ Only after all modules confirmed that they have entered the low power state (by If a disconnection happens while the device is in the suspended state, the |power_manager| switches the application to the off state. However, the application can also be configured to keep the system in the suspended state when there are no active connections, instead of switching to the off state. -To select this behavior, use the :option:`CONFIG_CAF_POWER_MANAGER_STAY_ON` configuration option. +To select this behavior, use the :kconfig:`CONFIG_CAF_POWER_MANAGER_STAY_ON` configuration option. Wake-up scenarios ================= diff --git a/doc/nrf/libraries/caf/sensor_sampler.rst b/doc/nrf/libraries/caf/sensor_sampler.rst index 8f38d1be1030..a38967e7f2d2 100644 --- a/doc/nrf/libraries/caf/sensor_sampler.rst +++ b/doc/nrf/libraries/caf/sensor_sampler.rst @@ -21,16 +21,16 @@ To use the module, you must complete the following requirements: For more information about adding sensor device to devicetree, refer to :ref:`zephyr:use-dt-overlays`. #. Enable the following Kconfig options: - * :option:`CONFIG_CAF_SENSOR_SAMPLER` - This option enables the |sensor_sampler|. - * :option:`CONFIG_SENSOR` - This option enables Zephyr's :ref:`zephyr:sensor_api` driver, which is required for interacting with the sensors. + * :kconfig:`CONFIG_CAF_SENSOR_SAMPLER` - This option enables the |sensor_sampler|. + * :kconfig:`CONFIG_SENSOR` - This option enables Zephyr's :ref:`zephyr:sensor_api` driver, which is required for interacting with the sensors. Additionally, you need to configure the sensor that you want to use in your application and enable it in the sensor Kconfig option. The following Kconfig options are also available for the module: -* :option:`CONFIG_CAF_SENSOR_SAMPLER_DEF_PATH` -* :option:`CONFIG_CAF_SENSOR_SAMPLER_THREAD_STACK_SIZE` -* :option:`CONFIG_CAF_SENSOR_SAMPLER_THREAD_PRIORITY` +* :kconfig:`CONFIG_CAF_SENSOR_SAMPLER_DEF_PATH` +* :kconfig:`CONFIG_CAF_SENSOR_SAMPLER_THREAD_STACK_SIZE` +* :kconfig:`CONFIG_CAF_SENSOR_SAMPLER_THREAD_PRIORITY` Adding module configuration file ================================ @@ -78,7 +78,7 @@ To do so, complete the following steps: }, }; -#. Specify the location of the file with the :option:`CONFIG_CAF_SENSOR_SAMPLER_DEF_PATH` Kconfig option. +#. Specify the location of the file with the :kconfig:`CONFIG_CAF_SENSOR_SAMPLER_DEF_PATH` Kconfig option. .. note:: |only_configured_module_note| @@ -167,11 +167,11 @@ When started, it can do the following operations: The |sensor_sampler| samples sensors periodically, according to the configuration specified for each sensor. Sampling of the sensors is done from a dedicated preemptive thread. -You can change the thread priority by setting the :option:`CONFIG_CAF_SENSOR_SAMPLER_THREAD_PRIORITY` Kconfig option. +You can change the thread priority by setting the :kconfig:`CONFIG_CAF_SENSOR_SAMPLER_THREAD_PRIORITY` Kconfig option. Use the preemptive thread priority to make sure that the thread does not block other operations in the system. The dedicated thread uses its own thread stack. -You can change the size of the stack by setting the :option:`CONFIG_CAF_SENSOR_SAMPLER_THREAD_STACK_SIZE` Kconfig option. +You can change the size of the stack by setting the :kconfig:`CONFIG_CAF_SENSOR_SAMPLER_THREAD_STACK_SIZE` Kconfig option. The thread stack size must be big enough for the sensors used. Sensor state events diff --git a/doc/nrf/libraries/debug/cpu_load.rst b/doc/nrf/libraries/debug/cpu_load.rst index 3c5d6a7093ae..79b9ba9390f1 100644 --- a/doc/nrf/libraries/debug/cpu_load.rst +++ b/doc/nrf/libraries/debug/cpu_load.rst @@ -17,7 +17,7 @@ To precisely measure the sleep period, the module requires the POWER peripheral The events are connected to a TIMER peripheral using PPI/DPPI. The sleep period is measured using the TIMER peripheral, which is clocked by default by the high frequency clock. -Alternatively, it can be clocked using low frequency clock (see :option:`CONFIG_CPU_LOAD_ALIGNED_CLOCKS`). +Alternatively, it can be clocked using low frequency clock (see :kconfig:`CONFIG_CPU_LOAD_ALIGNED_CLOCKS`). It is then compared against the system clock, which is clocked by the low frequency clock. The accuracy of measurements depends on the accuracy of the given clock sources. diff --git a/doc/nrf/libraries/dfu/dfu_target.rst b/doc/nrf/libraries/dfu/dfu_target.rst index 5e3dc096c8b6..a1ece6d04f35 100644 --- a/doc/nrf/libraries/dfu/dfu_target.rst +++ b/doc/nrf/libraries/dfu/dfu_target.rst @@ -48,7 +48,7 @@ When the complete transfer is done, call the :c:func:`dfu_target_done` function On the next reboot, the device will run the new firmware. .. note:: - To maintain the writing progress in case the device reboots, enable the configuration options :option:`CONFIG_SETTINGS` and :option:`CONFIG_DFU_TARGET_STREAM_SAVE_PROGRESS`. + To maintain the writing progress in case the device reboots, enable the configuration options :kconfig:`CONFIG_SETTINGS` and :kconfig:`CONFIG_DFU_TARGET_STREAM_SAVE_PROGRESS`. The MCUboot target then uses the :ref:`zephyr:settings_api` subsystem in Zephyr to store the current progress used by the :c:func:`dfu_target_write` function across power failures and device resets. @@ -81,9 +81,9 @@ Configuration You can disable support for specific DFU targets with the following parameters: -* :option:`CONFIG_DFU_TARGET_MCUBOOT` -* :option:`CONFIG_DFU_TARGET_MODEM_DELTA` -* :option:`CONFIG_DFU_TARGET_FULL_MODEM` +* :kconfig:`CONFIG_DFU_TARGET_MCUBOOT` +* :kconfig:`CONFIG_DFU_TARGET_MODEM_DELTA` +* :kconfig:`CONFIG_DFU_TARGET_FULL_MODEM` API documentation ***************** diff --git a/doc/nrf/libraries/modem/at_cmd.rst b/doc/nrf/libraries/modem/at_cmd.rst index ceb53e74ccfb..bf61ed1b0b27 100644 --- a/doc/nrf/libraries/modem/at_cmd.rst +++ b/doc/nrf/libraries/modem/at_cmd.rst @@ -35,7 +35,7 @@ Data is returned to the user if the return code is OK. In the case of a handler function, the return code is removed and the rest of the string is delivered to the handler function through a char pointer parameter. Allocation and deallocation of the buffer is handled by the AT command interface, and the content should not be considered valid outside of the handler. -Both schemes are limited to the maximum reception size defined by :option:`CONFIG_AT_CMD_RESPONSE_MAX_LEN`. +Both schemes are limited to the maximum reception size defined by :kconfig:`CONFIG_AT_CMD_RESPONSE_MAX_LEN`. Notifications are always handled by a callback function. This callback function is separate from the one that is used to handle data returned immediately after sending a command. diff --git a/doc/nrf/libraries/modem/at_monitor.rst b/doc/nrf/libraries/modem/at_monitor.rst index c5e3b0f9418b..26164c7350c7 100644 --- a/doc/nrf/libraries/modem/at_monitor.rst +++ b/doc/nrf/libraries/modem/at_monitor.rst @@ -32,7 +32,7 @@ Initialization The application can initialize the AT monitor library in the following ways: * Manually by using the :c:func:`at_monitor_init` function. -* Automatically by using the ``SYS_INIT`` macro and by enabling :option:`CONFIG_AT_MONITOR_SYS_INIT`. +* Automatically by using the ``SYS_INIT`` macro and by enabling :kconfig:`CONFIG_AT_MONITOR_SYS_INIT`. Upon initialization, the AT monitor library registers itself as the receiver of AT notifications from the Modem library (using :c:func:`nrf_modem_at_notif_handler_set`). diff --git a/doc/nrf/libraries/modem/lte_lc.rst b/doc/nrf/libraries/modem/lte_lc.rst index 5dd97481fdf7..0a22c2045e20 100644 --- a/doc/nrf/libraries/modem/lte_lc.rst +++ b/doc/nrf/libraries/modem/lte_lc.rst @@ -16,7 +16,7 @@ The library also provides functionality that enables the application to receive Configuration ************* -To enable the link controller library, set the option :option:`CONFIG_LTE_LINK_CONTROL` option to ``y`` in the project configuration file :file:`prj.conf`. +To enable the link controller library, set the option :kconfig:`CONFIG_LTE_LINK_CONTROL` option to ``y`` in the project configuration file :file:`prj.conf`. Establishing an LTE connection ============================== @@ -99,7 +99,7 @@ The following list mentions some of the information that can be extracted from t To check if a desired feature is compatible with a certain modem firmware version, see nRF9160 `AT Commands Reference Guide`_. The library supports an auto initialization and connection feature that enables the library to initialize and connect to LTE prior to the start of the application. -To enable this feature, set the configuration option :option:`CONFIG_LTE_AUTO_INIT_AND_CONNECT` to ``y``. +To enable this feature, set the configuration option :kconfig:`CONFIG_LTE_AUTO_INIT_AND_CONNECT` to ``y``. If you enable this option, you need not run additional library APIs. Enabling power-saving features @@ -149,10 +149,10 @@ This saves the overhead related to the additional packet exchange. The timer values requested by the modem can be configured with the following options and API calls: -* :option:`CONFIG_LTE_PSM_REQ_RPTAU` -* :option:`CONFIG_LTE_PSM_REQ_RAT` -* :option:`CONFIG_LTE_EDRX_REQ_VALUE_LTE_M` -* :option:`CONFIG_LTE_EDRX_REQ_VALUE_NBIOT` +* :kconfig:`CONFIG_LTE_PSM_REQ_RPTAU` +* :kconfig:`CONFIG_LTE_PSM_REQ_RAT` +* :kconfig:`CONFIG_LTE_EDRX_REQ_VALUE_LTE_M` +* :kconfig:`CONFIG_LTE_EDRX_REQ_VALUE_NBIOT` * :c:func:`lte_lc_psm_param_set` * :c:func:`lte_lc_edrx_param_set` @@ -214,8 +214,8 @@ For instance, TAU pre-warning notifications can be used to schedule data transfe Modem sleep notifications can be used to schedule processing in the same operational window as the modem to limit the overall computation time of the nRF9160 SiP. To enable modem sleep and TAU pre-warning notifications, enable the following options: -* :option:`CONFIG_LTE_LC_MODEM_SLEEP_NOTIFICATIONS` -* :option:`CONFIG_LTE_LC_TAU_PRE_WARNING_NOTIFICATIONS` +* :kconfig:`CONFIG_LTE_LC_MODEM_SLEEP_NOTIFICATIONS` +* :kconfig:`CONFIG_LTE_LC_TAU_PRE_WARNING_NOTIFICATIONS` Additional configurations related to these features can be found in the API documentation for the link controller. diff --git a/doc/nrf/libraries/modem/modem_attest_token.rst b/doc/nrf/libraries/modem/modem_attest_token.rst index 4e22ccde9978..44c6696d4869 100644 --- a/doc/nrf/libraries/modem/modem_attest_token.rst +++ b/doc/nrf/libraries/modem/modem_attest_token.rst @@ -21,7 +21,7 @@ To use the library to obtain the attestation token, complete the following steps * Enable the Modem attestation token library. * Initialize the :ref:`nrf_modem_lib_readme` and :ref:`at_cmd_parser_readme` libraries. * Call the :c:func:`modem_attest_token_get` function to obtain the two base64url strings in the :c:struct:`nrf_attestation_token` structure. -* Enable token parsing (:option:`CONFIG_MODEM_ATTEST_TOKEN_PARSING`). +* Enable token parsing (:kconfig:`CONFIG_MODEM_ATTEST_TOKEN_PARSING`). * Call the :c:func:`modem_attest_token_parse` function to parse the token. The function :c:func:`modem_attest_token_parse` parses :c:struct:`nrf_attestation_token` and populates the :c:struct:`nrf_attestation_data` structure with the data. @@ -32,8 +32,8 @@ Configuration Configure the following options when using this library: -* :option:`CONFIG_MODEM_ATTEST_TOKEN` -* :option:`CONFIG_MODEM_ATTEST_TOKEN_PARSING` +* :kconfig:`CONFIG_MODEM_ATTEST_TOKEN` +* :kconfig:`CONFIG_MODEM_ATTEST_TOKEN_PARSING` API documentation ***************** diff --git a/doc/nrf/libraries/modem/modem_jwt.rst b/doc/nrf/libraries/modem/modem_jwt.rst index 236865cdcfe9..b0e9b5d27d02 100644 --- a/doc/nrf/libraries/modem/modem_jwt.rst +++ b/doc/nrf/libraries/modem/modem_jwt.rst @@ -33,8 +33,8 @@ Configuration Configure the following options when using the library: -* :option:`CONFIG_MODEM_JWT` -* :option:`CONFIG_MODEM_JWT_MAX_LEN` +* :kconfig:`CONFIG_MODEM_JWT` +* :kconfig:`CONFIG_MODEM_JWT_MAX_LEN` API documentation ***************** diff --git a/doc/nrf/libraries/modem/modem_key_mgmt.rst b/doc/nrf/libraries/modem/modem_key_mgmt.rst index d112a975503f..1603f142a158 100644 --- a/doc/nrf/libraries/modem/modem_key_mgmt.rst +++ b/doc/nrf/libraries/modem/modem_key_mgmt.rst @@ -21,7 +21,7 @@ See :ref:`nrfxlib:security_tags` for more information about how security tags ar .. important:: Security credentials usually exceed the default AT command response length. - Therefore, you must set :option:`CONFIG_AT_CMD_RESPONSE_MAX_LEN` to a sufficiently high value when using this library. + Therefore, you must set :kconfig:`CONFIG_AT_CMD_RESPONSE_MAX_LEN` to a sufficiently high value when using this library. .. _cert_dwload: diff --git a/doc/nrf/libraries/modem/nrf_modem_lib.rst b/doc/nrf/libraries/modem/nrf_modem_lib.rst index 6404af84fae3..71f8768a781e 100644 --- a/doc/nrf/libraries/modem/nrf_modem_lib.rst +++ b/doc/nrf/libraries/modem/nrf_modem_lib.rst @@ -24,7 +24,7 @@ The library wrapper eases the task of initializing the Modem library by automati For more information, see :ref:`partition_mgr_integration`. The library wrapper can also initialize the Modem library during system initialization using :c:macro:`SYS_INIT`. -The :option:`CONFIG_NRF_MODEM_LIB_SYS_INIT` Kconfig option can be used to control the initialization. +The :kconfig:`CONFIG_NRF_MODEM_LIB_SYS_INIT` Kconfig option can be used to control the initialization. Some libraries in |NCS|, such as the :ref:`at_cmd_readme` and the :ref:`lte_lc_readme` have similar configuration options to initialize during system initialization and these options depend on the configuration option of the integration layer. If your application performs an update of the nRF9160 modem firmware, you must disable this functionality to have full control on the initialization of the library. @@ -45,7 +45,7 @@ Modem library socket API sets errnos as defined in :file:`nrf_errno.h`. The socket offloading support in the integration layer in |NCS| converts those errnos to the errnos that adhere to the selected C library implementation. The socket offloading functionality is enabled by default. -To disable the functionality, set the :option:`CONFIG_NET_SOCKETS_OFFLOAD` Kconfig option to ``n`` in your project configuration. +To disable the functionality, set the :kconfig:`CONFIG_NET_SOCKETS_OFFLOAD` Kconfig option to ``n`` in your project configuration. If you disable the socket offloading functionality, the socket calls will no longer be offloaded to the nRF9160 modem firmware. Instead, the calls will be relayed to the native Zephyr TCP/IP implementation. This can be useful to switch between an emulator and a real device while running networking code on these devices. @@ -84,12 +84,12 @@ The RAM area that the Modem library shares with the nRF9160 modem core is divide The size of the RX, TX and the Trace regions can be configured by the following Kconfig options of the integration layer: -* :option:`CONFIG_NRF_MODEM_LIB_SHMEM_RX_SIZE` for the RX region -* :option:`CONFIG_NRF_MODEM_LIB_SHMEM_TX_SIZE` for the TX region -* :option:`CONFIG_NRF_MODEM_LIB_SHMEM_TRACE_SIZE` for the Trace region +* :kconfig:`CONFIG_NRF_MODEM_LIB_SHMEM_RX_SIZE` for the RX region +* :kconfig:`CONFIG_NRF_MODEM_LIB_SHMEM_TX_SIZE` for the TX region +* :kconfig:`CONFIG_NRF_MODEM_LIB_SHMEM_TRACE_SIZE` for the Trace region The size of the Control region is fixed. -The Modem library exports the size value through :option:`CONFIG_NRF_MODEM_SHMEM_CTRL_SIZE`. +The Modem library exports the size value through :kconfig:`CONFIG_NRF_MODEM_SHMEM_CTRL_SIZE`. This value is automatically passed by the integration layer to the library during the initialization through :c:func:`nrf_modem_lib_init`. When the application is built using CMake, the :ref:`partition_manager` automatically reads the Kconfig options of the integration layer. @@ -116,10 +116,10 @@ Diagnostic functionality ************************ The Modem library integration layer in |NCS| provides some diagnostic functionalities to log the allocations on the Modem library heap and the TX memory region. -These functionalities can be turned on by the :option:`CONFIG_NRF_MODEM_LIB_DEBUG_ALLOC` and :option:`CONFIG_NRF_MODEM_LIB_DEBUG_SHM_TX_ALLOC` options. +These functionalities can be turned on by the :kconfig:`CONFIG_NRF_MODEM_LIB_DEBUG_ALLOC` and :kconfig:`CONFIG_NRF_MODEM_LIB_DEBUG_SHM_TX_ALLOC` options. The contents of both the Modem library heap and the TX memory region can be examined through the :c:func:`nrf_modem_lib_heap_diagnose` and :c:func:`nrf_modem_lib_shm_tx_diagnose` functions, respectively. -Additionally, it is possible to schedule a periodic report of the contents of these two areas of memory by using the :option:`CONFIG_NRF_MODEM_LIB_HEAP_DUMP_PERIODIC` and :option:`CONFIG_NRF_MODEM_LIB_SHM_TX_DUMP_PERIODIC` options, respectively. +Additionally, it is possible to schedule a periodic report of the contents of these two areas of memory by using the :kconfig:`CONFIG_NRF_MODEM_LIB_HEAP_DUMP_PERIODIC` and :kconfig:`CONFIG_NRF_MODEM_LIB_SHM_TX_DUMP_PERIODIC` options, respectively. The report will be printed by a dedicated work queue that is distinct from the system work queue at configurable time intervals. API documentation diff --git a/doc/nrf/libraries/modem/pdn.rst b/doc/nrf/libraries/modem/pdn.rst index c566a4546af4..89301089d10c 100644 --- a/doc/nrf/libraries/modem/pdn.rst +++ b/doc/nrf/libraries/modem/pdn.rst @@ -41,8 +41,8 @@ Multiple PDP contexts might share the same PDN connection if they are configured The library requires the following Kconfig options to be set to ``y``: -* :option:`CONFIG_AT_CMD` -* :option:`CONFIG_AT_NOTIF` +* :kconfig:`CONFIG_AT_CMD` +* :kconfig:`CONFIG_AT_NOTIF` Configuration ************* @@ -54,7 +54,7 @@ The default PDP context configuration consists of the following parameters: * Authentication method * Authentication credentials -The PDN library can override the default PDP context configuration by using the :option:`CONFIG_PDN_DEFAULTS_OVERRIDE` Kconfig option. +The PDN library can override the default PDP context configuration by using the :kconfig:`CONFIG_PDN_DEFAULTS_OVERRIDE` Kconfig option. Limitations *********** diff --git a/doc/nrf/libraries/modem/sms.rst b/doc/nrf/libraries/modem/sms.rst index 038c70685bdf..2a5e85e0af94 100644 --- a/doc/nrf/libraries/modem/sms.rst +++ b/doc/nrf/libraries/modem/sms.rst @@ -31,9 +31,9 @@ Configuration Configure the following Kconfig options when using this library: -* :option:`CONFIG_SMS` - Enables the SMS subscriber library. -* :option:`CONFIG_SMS_SUBSCRIBERS_MAX_CNT` - Sets the maximum number of SMS subscribers. -* :option:`CONFIG_AT_CMD_RESPONSE_MAX_LEN` - Defines the maximum size of the AT command response, which might limit the size of the received SMS message. Values over 512 bytes will not restrict the size of the received message as the maximum data length of the SMS is 140 bytes. This parameter is defined in the :ref:`at_cmd_readme` module. +* :kconfig:`CONFIG_SMS` - Enables the SMS subscriber library. +* :kconfig:`CONFIG_SMS_SUBSCRIBERS_MAX_CNT` - Sets the maximum number of SMS subscribers. +* :kconfig:`CONFIG_AT_CMD_RESPONSE_MAX_LEN` - Defines the maximum size of the AT command response, which might limit the size of the received SMS message. Values over 512 bytes will not restrict the size of the received message as the maximum data length of the SMS is 140 bytes. This parameter is defined in the :ref:`at_cmd_readme` module. Limitations *********** diff --git a/doc/nrf/libraries/mpsl/mpsl_assert.rst b/doc/nrf/libraries/mpsl/mpsl_assert.rst index 296349fade96..4d61999d0558 100644 --- a/doc/nrf/libraries/mpsl/mpsl_assert.rst +++ b/doc/nrf/libraries/mpsl/mpsl_assert.rst @@ -10,7 +10,7 @@ Multiprotocol Service Layer assert The Multiprotocol Service Layer assert library makes it possible to add a custom assert handler to the :ref:`nrfxlib:mpsl` library. You can then use this assert handler to print custom error messages or log assert information. -:option:`CONFIG_MPSL_ASSERT_HANDLER` enables the custom assert handler. +:kconfig:`CONFIG_MPSL_ASSERT_HANDLER` enables the custom assert handler. If enabled, the application must provide the definition of :c:func:`mpsl_assert_handle`. The :c:func:`mpsl_assert_handle` function is invoked whenever the MPSL code encounters an unrecoverable error. diff --git a/doc/nrf/libraries/networking/aws_fota.rst b/doc/nrf/libraries/networking/aws_fota.rst index b272948ee5b6..facd6bad1b56 100644 --- a/doc/nrf/libraries/networking/aws_fota.rst +++ b/doc/nrf/libraries/networking/aws_fota.rst @@ -29,9 +29,9 @@ Configuration Configure the following parameters when using this library: -* :option:`CONFIG_AWS_FOTA_PAYLOAD_SIZE` -* :option:`CONFIG_AWS_FOTA_HOSTNAME_MAX_LEN` -* :option:`CONFIG_AWS_FOTA_FILE_PATH_MAX_LEN` +* :kconfig:`CONFIG_AWS_FOTA_PAYLOAD_SIZE` +* :kconfig:`CONFIG_AWS_FOTA_HOSTNAME_MAX_LEN` +* :kconfig:`CONFIG_AWS_FOTA_FILE_PATH_MAX_LEN` Implementation diff --git a/doc/nrf/libraries/networking/aws_iot.rst b/doc/nrf/libraries/networking/aws_iot.rst index 6deca97266d6..e14d2f1d45aa 100644 --- a/doc/nrf/libraries/networking/aws_iot.rst +++ b/doc/nrf/libraries/networking/aws_iot.rst @@ -56,46 +56,46 @@ Configuring the required library options To establish a connection to the AWS IoT message broker, set the following options: -* :option:`CONFIG_AWS_IOT_SEC_TAG` -* :option:`CONFIG_AWS_IOT_BROKER_HOST_NAME` -* :option:`CONFIG_AWS_IOT_CLIENT_ID_STATIC` +* :kconfig:`CONFIG_AWS_IOT_SEC_TAG` +* :kconfig:`CONFIG_AWS_IOT_BROKER_HOST_NAME` +* :kconfig:`CONFIG_AWS_IOT_CLIENT_ID_STATIC` To configure the required library options, complete the following steps: 1. In the `AWS IoT console`_, navigate to :guilabel:`IoT core` > :guilabel:`Manage` > :guilabel:`things` and click on the entry for the *thing* created during the steps of :ref:`creating_a_thing_in_AWS_IoT`. -#. Navigate to :guilabel:`interact`, find the ``Rest API Endpoint`` and set the configurable option :option:`CONFIG_AWS_IOT_BROKER_HOST_NAME` to this address string. -#. Set the option :option:`CONFIG_AWS_IOT_CLIENT_ID_STATIC` to the name of the *thing* created during the aforementioned steps. -#. Set the security tag configuration :option:`CONFIG_AWS_IOT_SEC_TAG` to the security tag, chosen while `Programming the certificates to the on-board modem of the nRF9160-based kit`_. +#. Navigate to :guilabel:`interact`, find the ``Rest API Endpoint`` and set the configurable option :kconfig:`CONFIG_AWS_IOT_BROKER_HOST_NAME` to this address string. +#. Set the option :kconfig:`CONFIG_AWS_IOT_CLIENT_ID_STATIC` to the name of the *thing* created during the aforementioned steps. +#. Set the security tag configuration :kconfig:`CONFIG_AWS_IOT_SEC_TAG` to the security tag, chosen while `Programming the certificates to the on-board modem of the nRF9160-based kit`_. Configuring the optional library options ======================================== To subscribe to the various `AWS IoT Device Shadow Topics`_, set the following options: -* :option:`CONFIG_AWS_IOT_TOPIC_GET_ACCEPTED_SUBSCRIBE` -* :option:`CONFIG_AWS_IOT_TOPIC_GET_REJECTED_SUBSCRIBE` -* :option:`CONFIG_AWS_IOT_TOPIC_UPDATE_ACCEPTED_SUBSCRIBE` -* :option:`CONFIG_AWS_IOT_TOPIC_UPDATE_REJECTED_SUBSCRIBE` -* :option:`CONFIG_AWS_IOT_TOPIC_UPDATE_DELTA_SUBSCRIBE` -* :option:`CONFIG_AWS_IOT_TOPIC_DELETE_ACCEPTED_SUBSCRIBE` -* :option:`CONFIG_AWS_IOT_TOPIC_DELETE_REJECTED_SUBSCRIBE` +* :kconfig:`CONFIG_AWS_IOT_TOPIC_GET_ACCEPTED_SUBSCRIBE` +* :kconfig:`CONFIG_AWS_IOT_TOPIC_GET_REJECTED_SUBSCRIBE` +* :kconfig:`CONFIG_AWS_IOT_TOPIC_UPDATE_ACCEPTED_SUBSCRIBE` +* :kconfig:`CONFIG_AWS_IOT_TOPIC_UPDATE_REJECTED_SUBSCRIBE` +* :kconfig:`CONFIG_AWS_IOT_TOPIC_UPDATE_DELTA_SUBSCRIBE` +* :kconfig:`CONFIG_AWS_IOT_TOPIC_DELETE_ACCEPTED_SUBSCRIBE` +* :kconfig:`CONFIG_AWS_IOT_TOPIC_DELETE_REJECTED_SUBSCRIBE` To subscribe to non-AWS specific topics, complete the following steps: -* Specify the number of additional topics that needs to be subscribed to, by setting the :option:`CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT` option +* Specify the number of additional topics that needs to be subscribed to, by setting the :kconfig:`CONFIG_AWS_IOT_APP_SUBSCRIPTION_LIST_COUNT` option * Pass a list containing application specific topics in the :c:func:`aws_iot_subscription_topics_add` function, after the :c:func:`aws_iot_init` function call and before the :c:func:`aws_iot_connect` function call The AWS IoT library also supports passing in the client ID at run time. To enable this feature, set the ``client_id`` entry in the :c:struct:`aws_iot_config` structure that is passed in the :c:func:`aws_iot_init` function when initializing the library, and set the following option: -* :option:`CONFIG_AWS_IOT_CLIENT_ID_APP` +* :kconfig:`CONFIG_AWS_IOT_CLIENT_ID_APP` .. note:: - If you are using a longer device ID that is either set by the option :option:`CONFIG_AWS_IOT_CLIENT_ID_STATIC` or passed in during initialization, it might be required to increase the value of the option :option:`CONFIG_AWS_IOT_CLIENT_ID_MAX_LEN` for proper initialization of the library. + If you are using a longer device ID that is either set by the option :kconfig:`CONFIG_AWS_IOT_CLIENT_ID_STATIC` or passed in during initialization, it might be required to increase the value of the option :kconfig:`CONFIG_AWS_IOT_CLIENT_ID_MAX_LEN` for proper initialization of the library. .. note:: The AWS IoT library is compatible with the :ref:`cloud_api_readme`, a generic API that enables multiple cloud backends to be interchanged, statically and at run time. - To enable the use of the cloud, API set the configurable option :option:`CONFIG_CLOUD_API`, in addition to the other selected library options. + To enable the use of the cloud, API set the configurable option :kconfig:`CONFIG_CLOUD_API`, in addition to the other selected library options. Initializing the library ************************ diff --git a/doc/nrf/libraries/networking/aws_jobs.rst b/doc/nrf/libraries/networking/aws_jobs.rst index 755e307f8c25..a46890c872c8 100644 --- a/doc/nrf/libraries/networking/aws_jobs.rst +++ b/doc/nrf/libraries/networking/aws_jobs.rst @@ -24,7 +24,7 @@ Configuration Configure the following parameters when using this library: -* :option:`CONFIG_UPDATE_JOB_PAYLOAD_LEN` +* :kconfig:`CONFIG_UPDATE_JOB_PAYLOAD_LEN` API documentation diff --git a/doc/nrf/libraries/networking/azure_fota.rst b/doc/nrf/libraries/networking/azure_fota.rst index cee2b100399c..e20852a998e6 100644 --- a/doc/nrf/libraries/networking/azure_fota.rst +++ b/doc/nrf/libraries/networking/azure_fota.rst @@ -33,7 +33,7 @@ The library uses ``fwVersion`` to determine whether the firmware should be downl Currently, a new version of the firmware is downloaded and applied only if the version is different from the current firmware version. Currently, the library does not use the ``protocol`` field. -Instead, the :option:`CONFIG_AZURE_FOTA_TLS` option is used at compile time to specify if HTTPS should be used as the transport protocol. +Instead, the :kconfig:`CONFIG_AZURE_FOTA_TLS` option is used at compile time to specify if HTTPS should be used as the transport protocol. The ``fwFragmentSize`` field specifies the maximum fragment size for the file that should be downloaded in each HTTP request. Below are the maximum total fragment sizes in different scenarios: @@ -53,12 +53,12 @@ Configuration Configure the following parameters when using this library: -* :option:`CONFIG_AZURE_FOTA_APP_VERSION` - Defines the application version string. Indicates the current firmware version on the development kit. -* :option:`CONFIG_AZURE_FOTA_APP_VERSION_AUTO` - Automatically generates the application version. If enabled, :option:`CONFIG_AZURE_FOTA_APP_VERSION` is ignored. -* :option:`CONFIG_AZURE_FOTA_TLS` - Enables HTTPS for downloads. By default, TLS is enabled and currently, the transport protocol must be configured at compile time. -* :option:`CONFIG_AZURE_FOTA_SEC_TAG` - Sets the security tag for TLS credentials when using HTTPS as the transport layer. See :ref:`azure_iot_hub_flash_certs` for more details. -* :option:`CONFIG_AZURE_FOTA_HOSTNAME_MAX_LEN` - Sets the host name buffer size. -* :option:`CONFIG_AZURE_FOTA_FILE_PATH_MAX_LEN` - Sets the file path buffer size. +* :kconfig:`CONFIG_AZURE_FOTA_APP_VERSION` - Defines the application version string. Indicates the current firmware version on the development kit. +* :kconfig:`CONFIG_AZURE_FOTA_APP_VERSION_AUTO` - Automatically generates the application version. If enabled, :kconfig:`CONFIG_AZURE_FOTA_APP_VERSION` is ignored. +* :kconfig:`CONFIG_AZURE_FOTA_TLS` - Enables HTTPS for downloads. By default, TLS is enabled and currently, the transport protocol must be configured at compile time. +* :kconfig:`CONFIG_AZURE_FOTA_SEC_TAG` - Sets the security tag for TLS credentials when using HTTPS as the transport layer. See :ref:`azure_iot_hub_flash_certs` for more details. +* :kconfig:`CONFIG_AZURE_FOTA_HOSTNAME_MAX_LEN` - Sets the host name buffer size. +* :kconfig:`CONFIG_AZURE_FOTA_FILE_PATH_MAX_LEN` - Sets the file path buffer size. Limitations diff --git a/doc/nrf/libraries/networking/azure_iot_hub.rst b/doc/nrf/libraries/networking/azure_iot_hub.rst index 3047250d9947..a7396b51bc72 100644 --- a/doc/nrf/libraries/networking/azure_iot_hub.rst +++ b/doc/nrf/libraries/networking/azure_iot_hub.rst @@ -55,7 +55,7 @@ To provision the certificates and the private key to the nRF9160 modem, complete #. Select a desired security tag (any positive integer, for example, ``42``) and click :guilabel:`Update certificates`. .. note:: - The chosen security tag while provisioning the certificates must be same as the security tag configured by the :option:`CONFIG_AZURE_IOT_HUB_SEC_TAG` option. + The chosen security tag while provisioning the certificates must be same as the security tag configured by the :kconfig:`CONFIG_AZURE_IOT_HUB_SEC_TAG` option. Configuring the library @@ -69,9 +69,9 @@ Configuration without using DPS To connect to Azure IoT Hub without using DPS, complete the following minimum required configuration: 1. In the `Azure Portal`_, navigate to :guilabel:`IoT Hub` and select the desired IoT hub. -#. In the overview page, locate and copy the ``Hostname`` and configure :option:`CONFIG_AZURE_IOT_HUB_HOSTNAME` to this address. -#. Set the option :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` to the device ID. The device ID must match the device ID used while creating the certificates. -#. Set :option:`CONFIG_AZURE_IOT_HUB_SEC_TAG` to the security tag used in :ref:`azure_iot_hub_flash_certs`. +#. In the overview page, locate and copy the ``Hostname`` and configure :kconfig:`CONFIG_AZURE_IOT_HUB_HOSTNAME` to this address. +#. Set the option :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` to the device ID. The device ID must match the device ID used while creating the certificates. +#. Set :kconfig:`CONFIG_AZURE_IOT_HUB_SEC_TAG` to the security tag used in :ref:`azure_iot_hub_flash_certs`. .. _dps_config: @@ -84,11 +84,11 @@ To connect to Azure IoT Hub using DPS, complete the following steps: 1. `Set up an Azure IoT Hub Device Provisioning Service (DPS) instance`_ and obtain the ID scope. #. `Add certificates to the DPS instance`_. #. Create an *enrollment group* as described in `Device enrollments with Azure Portal`_ and link it to your IoT hub. Select the certificate added in the previous step as the *Primary certificate​​​​​​​*. -#. Enable :option:`CONFIG_AZURE_IOT_HUB_DPS`. +#. Enable :kconfig:`CONFIG_AZURE_IOT_HUB_DPS`. #. In the `Azure Portal`_, click :guilabel:`Device Provisioning Services` and select the DPS instance to use. -#. In the overview page, locate and copy the ``ID Scope`` and configure :option:`CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE` to this string. -#. Set the :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` option to device ID, unless :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` is enabled. The device ID must match the device ID used while creating the certificates. -#. Set :option:`CONFIG_AZURE_IOT_HUB_SEC_TAG` to the security tag used while :ref:`azure_iot_hub_flash_certs`. +#. In the overview page, locate and copy the ``ID Scope`` and configure :kconfig:`CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE` to this string. +#. Set the :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` option to device ID, unless :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` is enabled. The device ID must match the device ID used while creating the certificates. +#. Set :kconfig:`CONFIG_AZURE_IOT_HUB_SEC_TAG` to the security tag used while :ref:`azure_iot_hub_flash_certs`. Initializing the library @@ -96,9 +96,9 @@ Initializing the library The library is initialized by calling the :c:func:`azure_iot_hub_init` function. If the initialization fails, the application cannot use any APIs of the library. -Optionally, you can enable :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` and include a pointer to the :c:struct:`azure_iot_hub_config` structure containing the device ID in the :c:func:`azure_iot_hub_init` function call. +Optionally, you can enable :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` and include a pointer to the :c:struct:`azure_iot_hub_config` structure containing the device ID in the :c:func:`azure_iot_hub_init` function call. -Below is an example for setting the device ID at run time instead of compile time by configuring the :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` option: +Below is an example for setting the device ID at run time instead of compile time by configuring the :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` option: .. code-block:: c @@ -135,11 +135,11 @@ Configuration Configure the following parameters when using this library: -* :option:`CONFIG_AZURE_IOT_HUB_HOSTNAME` - Sets the Azure IoT Hub host name. It must be configured, since DPS is not enabled by default. -* :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` - Specifies the device ID, which is used when connecting to Azure IoT Hub or when DPS is enabled. -* :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` - Used to provide the device ID at run time. -* :option:`CONFIG_AZURE_IOT_HUB_DPS` - Enables Azure IoT Hub DPS. -* :option:`CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE` - Sets the Azure IoT Hub DPS ID scope that is used while provisioning the device. +* :kconfig:`CONFIG_AZURE_IOT_HUB_HOSTNAME` - Sets the Azure IoT Hub host name. It must be configured, since DPS is not enabled by default. +* :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` - Specifies the device ID, which is used when connecting to Azure IoT Hub or when DPS is enabled. +* :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` - Used to provide the device ID at run time. +* :kconfig:`CONFIG_AZURE_IOT_HUB_DPS` - Enables Azure IoT Hub DPS. +* :kconfig:`CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE` - Sets the Azure IoT Hub DPS ID scope that is used while provisioning the device. API documentation ***************** diff --git a/doc/nrf/libraries/networking/coap_utils.rst b/doc/nrf/libraries/networking/coap_utils.rst index 5926300313f5..d16bd5a3d277 100644 --- a/doc/nrf/libraries/networking/coap_utils.rst +++ b/doc/nrf/libraries/networking/coap_utils.rst @@ -26,7 +26,7 @@ Currently, the library only supports the User Datagram Protocol (UDP) protocol. Configuration ************* -To enable the CoAP utils library, set the :option:`CONFIG_COAP_UTILS` Kconfig option. +To enable the CoAP utils library, set the :kconfig:`CONFIG_COAP_UTILS` Kconfig option. API documentation ***************** diff --git a/doc/nrf/libraries/networking/download_client.rst b/doc/nrf/libraries/networking/download_client.rst index b30992c17be4..443c4362eb10 100644 --- a/doc/nrf/libraries/networking/download_client.rst +++ b/doc/nrf/libraries/networking/download_client.rst @@ -9,7 +9,7 @@ Download client The download client library can be used to download files from an HTTP or a CoAP server. The download is carried out in a separate thread, and the application receives events such as :c:enumerator:`DOWNLOAD_CLIENT_EVT_FRAGMENT` that contain the data fragments as the download progresses. -The fragment size can be configured independently for HTTP and CoAP (block-wise transfer) using the :option:`CONFIG_DOWNLOAD_CLIENT_HTTP_FRAG_SIZE` and the :option:`CONFIG_DOWNLOAD_CLIENT_COAP_BLOCK_SIZE` options, respectively. +The fragment size can be configured independently for HTTP and CoAP (block-wise transfer) using the :kconfig:`CONFIG_DOWNLOAD_CLIENT_HTTP_FRAG_SIZE` and the :kconfig:`CONFIG_DOWNLOAD_CLIENT_COAP_BLOCK_SIZE` options, respectively. When the download completes, the library sends the :c:enumerator:`DOWNLOAD_CLIENT_EVT_DONE` event to the application. Protocols @@ -29,7 +29,7 @@ In the case of download via HTTPS, it is carried out through `Content-Range requ The library thus sends and receives as many requests and responses as the number of fragments that constitutes the download. For example, to download a file of size 47 kilobytes file with a fragment size of 2 kilobytes, a total of 24 HTTP GET requests are sent. It is therefore recommended to use the largest fragment size to minimize the network usage. -Make sure to configure the :option:`CONFIG_DOWNLOAD_CLIENT_BUF_SIZE` and the :option:`CONFIG_DOWNLOAD_CLIENT_HTTP_FRAG_SIZE` options so that the buffer is large enough to accommodate the entire HTTP header of the request and the response. +Make sure to configure the :kconfig:`CONFIG_DOWNLOAD_CLIENT_BUF_SIZE` and the :kconfig:`CONFIG_DOWNLOAD_CLIENT_HTTP_FRAG_SIZE` options so that the buffer is large enough to accommodate the entire HTTP header of the request and the response. The application must provision the TLS credentials and pass the security tag to the library when using HTTPS and calling the :c:func:`download_client_connect` function. To provision a TLS certificate to the modem, use :c:func:`modem_key_mgmt_write` and other :ref:`modem_key_mgmt` APIs. @@ -38,7 +38,7 @@ CoAP and CoAPS (DTLS 1.2) ========================= When downloading from a CoAP server, the library uses the CoAP block-wise transfer. -Make sure to configure the :option:`CONFIG_DOWNLOAD_CLIENT_BUF_SIZE` option and the :option:`CONFIG_DOWNLOAD_CLIENT_COAP_BLOCK_SIZE` option so that the buffer is large enough to accommodate the entire CoAP header and the CoAP block. +Make sure to configure the :kconfig:`CONFIG_DOWNLOAD_CLIENT_BUF_SIZE` option and the :kconfig:`CONFIG_DOWNLOAD_CLIENT_COAP_BLOCK_SIZE` option so that the buffer is large enough to accommodate the entire CoAP header and the CoAP block. The application must provision the TLS credentials and pass the security tag to the library when using CoAPS and calling :c:func:`download_client_connect`. diff --git a/doc/nrf/libraries/networking/ftp_client.rst b/doc/nrf/libraries/networking/ftp_client.rst index e16d594059c3..d370e7b50901 100644 --- a/doc/nrf/libraries/networking/ftp_client.rst +++ b/doc/nrf/libraries/networking/ftp_client.rst @@ -13,8 +13,8 @@ The file is downloaded in fragments of :c:enumerator:`NET_IPV4_MTU`. The size of a file can be fetched by LIST command. The FTP client library reports FTP control message and download data with two separate callback functions (:c:type:`ftp_client_callback_t` and :c:type:`ftp_client_callback_t`). -The library automatically sends KEEPALIVE message to the server through a timer if :option:`CONFIG_FTP_CLIENT_KEEPALIVE_TIME` is not zero. -The KEEPALIVE message is sent periodically at the completion of the time interval indicated by the value of :option:`CONFIG_FTP_CLIENT_KEEPALIVE_TIME`. +The library automatically sends KEEPALIVE message to the server through a timer if :kconfig:`CONFIG_FTP_CLIENT_KEEPALIVE_TIME` is not zero. +The KEEPALIVE message is sent periodically at the completion of the time interval indicated by the value of :kconfig:`CONFIG_FTP_CLIENT_KEEPALIVE_TIME`. If there is no username or password provided, the library performs a login as an anonymous user. diff --git a/doc/nrf/libraries/networking/lwm2m_client_utils.rst b/doc/nrf/libraries/networking/lwm2m_client_utils.rst index 831ed900e2a3..0a8c4cdf6c45 100644 --- a/doc/nrf/libraries/networking/lwm2m_client_utils.rst +++ b/doc/nrf/libraries/networking/lwm2m_client_utils.rst @@ -34,15 +34,15 @@ To use NB-IoT, a bootstrap server, or the queue mode, follow the implementation Configure the following parameters when using this library: -* :option:`CONFIG_LWM2M_CLIENT_UTILS` enabled -* :option:`CONFIG_LWM2M_CLIENT_UTILS_DEVICE_OBJ_SUPPORT` enabled -* :option:`CONFIG_LWM2M_CLIENT_UTILS_SECURITY_OBJ_SUPPORT` enabled -* :option:`CONFIG_LWM2M_CLIENT_UTILS_CONN_MON_OBJ_SUPPORT` enabled -* :option:`CONFIG_LWM2M_CLIENT_UTILS_LOCATION_OBJ_SUPPORT` enabled -* :option:`CONFIG_LWM2M_CLIENT_UTILS_FIRMWARE_UPDATE_OBJ_SUPPORT` enabled +* :kconfig:`CONFIG_LWM2M_CLIENT_UTILS` enabled +* :kconfig:`CONFIG_LWM2M_CLIENT_UTILS_DEVICE_OBJ_SUPPORT` enabled +* :kconfig:`CONFIG_LWM2M_CLIENT_UTILS_SECURITY_OBJ_SUPPORT` enabled +* :kconfig:`CONFIG_LWM2M_CLIENT_UTILS_CONN_MON_OBJ_SUPPORT` enabled +* :kconfig:`CONFIG_LWM2M_CLIENT_UTILS_LOCATION_OBJ_SUPPORT` enabled +* :kconfig:`CONFIG_LWM2M_CLIENT_UTILS_FIRMWARE_UPDATE_OBJ_SUPPORT` enabled Support for the objects can be set individually but are enabled by default. -Disable the :option:`CONFIG_LWM2M_CLIENT_UTILS_DEVICE_OBJ_SUPPORT` Kconfig option only if you are implementing a ``reboot`` resource on your application because of a mandatory requirement. +Disable the :kconfig:`CONFIG_LWM2M_CLIENT_UTILS_DEVICE_OBJ_SUPPORT` Kconfig option only if you are implementing a ``reboot`` resource on your application because of a mandatory requirement. Defining custom objects *********************** @@ -68,7 +68,7 @@ To define custom objects, complete the following steps: #. Pass the resource information to the LwM2M client utils library to register callbacks for the resource and to publish the sensor data. The following example describes how you can define an object that follows the Generic Sensor definition from IPSO. -To enable the support for Generic Sensor set the Kconfig option :option:`CONFIG_LWM2M_IPSO_GENERIC_SENSOR` to ``y``. +To enable the support for Generic Sensor set the Kconfig option :kconfig:`CONFIG_LWM2M_IPSO_GENERIC_SENSOR` to ``y``. To define an object that follows the Generic Sensor definition, complete the following steps: diff --git a/doc/nrf/libraries/networking/multicell_location.rst b/doc/nrf/libraries/networking/multicell_location.rst index 4b8244a703b6..139fbb39877d 100644 --- a/doc/nrf/libraries/networking/multicell_location.rst +++ b/doc/nrf/libraries/networking/multicell_location.rst @@ -37,30 +37,30 @@ The library has an API to handle provisioning of the required TLS certificates f Configuration ************* -To enable the multicell location library, enable the :option:`CONFIG_MULTICELL_LOCATION` Kconfig option. +To enable the multicell location library, enable the :kconfig:`CONFIG_MULTICELL_LOCATION` Kconfig option. The user must select nRF Cloud, HERE or Skyhook location services using one of the following options: -* :option:`CONFIG_MULTICELL_LOCATION_SERVICE_NRF_CLOUD` -* :option:`CONFIG_MULTICELL_LOCATION_SERVICE_HERE` -* :option:`CONFIG_MULTICELL_LOCATION_SERVICE_SKYHOOK`. +* :kconfig:`CONFIG_MULTICELL_LOCATION_SERVICE_NRF_CLOUD` +* :kconfig:`CONFIG_MULTICELL_LOCATION_SERVICE_HERE` +* :kconfig:`CONFIG_MULTICELL_LOCATION_SERVICE_SKYHOOK`. The next required step is to configure the authentication method. By default, API key is used for nRF Cloud, HERE and Skyhook. Depending on the selected service, one of the two options below must be configured: -* :option:`CONFIG_MULTICELL_LOCATION_NRF_CLOUD_API_KEY` -* :option:`CONFIG_MULTICELL_LOCATION_HERE_API_KEY` -* :option:`CONFIG_MULTICELL_LOCATION_SKYHOOK_API_KEY` +* :kconfig:`CONFIG_MULTICELL_LOCATION_NRF_CLOUD_API_KEY` +* :kconfig:`CONFIG_MULTICELL_LOCATION_HERE_API_KEY` +* :kconfig:`CONFIG_MULTICELL_LOCATION_SKYHOOK_API_KEY` Following are the options that can usually have default values: -* :option:`CONFIG_MULTICELL_LOCATION_HOSTNAME` -* :option:`CONFIG_MULTICELL_LOCATION_TLS_SEC_TAG` -* :option:`CONFIG_MULTICELL_LOCATION_SEND_BUF_SIZE` -* :option:`CONFIG_MULTICELL_LOCATION_RECV_BUF_SIZE` -* :option:`CONFIG_MULTICELL_LOCATION_HTTPS_PORT` +* :kconfig:`CONFIG_MULTICELL_LOCATION_HOSTNAME` +* :kconfig:`CONFIG_MULTICELL_LOCATION_TLS_SEC_TAG` +* :kconfig:`CONFIG_MULTICELL_LOCATION_SEND_BUF_SIZE` +* :kconfig:`CONFIG_MULTICELL_LOCATION_RECV_BUF_SIZE` +* :kconfig:`CONFIG_MULTICELL_LOCATION_HTTPS_PORT` Limitations *********** diff --git a/doc/nrf/libraries/networking/nrf_cloud.rst b/doc/nrf/libraries/networking/nrf_cloud.rst index 5bb0bc4d404c..71bdcec54fd5 100644 --- a/doc/nrf/libraries/networking/nrf_cloud.rst +++ b/doc/nrf/libraries/networking/nrf_cloud.rst @@ -33,11 +33,11 @@ Connecting The application can use :c:func:`nrf_cloud_connect` to connect to the cloud. This API triggers a series of events and actions in the system. If the API fails, the application must retry to connect. -If the :option:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` Kconfig option is enabled, an nRF Cloud library thread monitors the connection socket. -When :option:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` is enabled, an additional event, :c:enum:`NRF_CLOUD_EVT_TRANSPORT_CONNECTING`, is sent to the application. +If the :kconfig:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` Kconfig option is enabled, an nRF Cloud library thread monitors the connection socket. +When :kconfig:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` is enabled, an additional event, :c:enum:`NRF_CLOUD_EVT_TRANSPORT_CONNECTING`, is sent to the application. The status field of :c:struct:`nrf_cloud_evt` contains the connection status that is defined by :c:enumerator:`nrf_cloud_connect_result`. The event :c:enumerator:`NRF_CLOUD_EVT_TRANSPORT_DISCONNECTED` also contains additional information in the status field that is defined by :c:enumerator:`nrf_cloud_disconnect_status`. -See :ref:`connect_to_cloud` for additional information on :option:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD`. +See :ref:`connect_to_cloud` for additional information on :kconfig:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD`. When the poll thread option is used directly with the nRF Cloud library, the enumeration values are prefixed with ``NRF``. First, the library tries to establish the transport for communicating with the cloud. @@ -98,20 +98,20 @@ After receiving :c:enumerator:`NRF_CLOUD_EVT_READY`, the application can start s Configuration options for device ID =================================== -* :option:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_IMEI` - If you enable this option, the ID is automatically generated using a prefix and the modem's IMEI (````). You can configure the prefix by using :option:`CONFIG_NRF_CLOUD_CLIENT_ID_PREFIX`. The default format of the prefix is ``nrf-`` and it is valid only for Nordic devices such as Thingy:91 or nRF9160 DK. For custom hardware, use a prefix other than ``nrf-`` by modifying :option:`CONFIG_NRF_CLOUD_CLIENT_ID_PREFIX`. +* :kconfig:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_IMEI` - If you enable this option, the ID is automatically generated using a prefix and the modem's IMEI (````). You can configure the prefix by using :kconfig:`CONFIG_NRF_CLOUD_CLIENT_ID_PREFIX`. The default format of the prefix is ``nrf-`` and it is valid only for Nordic devices such as Thingy:91 or nRF9160 DK. For custom hardware, use a prefix other than ``nrf-`` by modifying :kconfig:`CONFIG_NRF_CLOUD_CLIENT_ID_PREFIX`. -* :option:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_INTERNAL_UUID` - If you enable this option, the ID is automatically generated using the modem's 128-bit internal UUID, which results in a 32-character string with no hyphens. This option requires modem firmware v1.3.0 or higher. +* :kconfig:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_INTERNAL_UUID` - If you enable this option, the ID is automatically generated using the modem's 128-bit internal UUID, which results in a 32-character string with no hyphens. This option requires modem firmware v1.3.0 or higher. -* :option:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME` - If you enable this option, the ID is set at compile time using the value specified by :option:`CONFIG_NRF_CLOUD_CLIENT_ID`. +* :kconfig:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_COMPILE_TIME` - If you enable this option, the ID is set at compile time using the value specified by :kconfig:`CONFIG_NRF_CLOUD_CLIENT_ID`. -* :option:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_RUNTIME` - If you enable this option, the ID is set at run time. If the nRF Cloud library is used directly, set the NULL-terminated ID string in :c:struct:`nrf_cloud_init_param` when calling :c:func:`nrf_cloud_init`. If the generic Cloud API is used, set the ID in :c:struct:`cloud_backend_config` and then call :c:func:`cloud_init`. +* :kconfig:`CONFIG_NRF_CLOUD_CLIENT_ID_SRC_RUNTIME` - If you enable this option, the ID is set at run time. If the nRF Cloud library is used directly, set the NULL-terminated ID string in :c:struct:`nrf_cloud_init_param` when calling :c:func:`nrf_cloud_init`. If the generic Cloud API is used, set the ID in :c:struct:`cloud_backend_config` and then call :c:func:`cloud_init`. .. _lib_nrf_cloud_fota: Firmware over-the-air (FOTA) updates ************************************ The nRF Cloud library supports FOTA updates for your nRF9160-based device. -When the library is included by the application, the :option:`CONFIG_NRF_CLOUD_FOTA` option is enabled by default, and the FOTA functionality is made available to the application. +When the library is included by the application, the :kconfig:`CONFIG_NRF_CLOUD_FOTA` option is enabled by default, and the FOTA functionality is made available to the application. For FOTA updates to work, the device must provide the information about the supported FOTA types to nRF Connect for Cloud. The device passes this information by writing a ``fota_v2`` field containing an array of FOTA types into the ``serviceInfo`` field in the device's shadow. @@ -211,7 +211,7 @@ The return values for a failure scenario of the :c:func:`cloud_init` function ar * -ENOMEM - Error building MQTT topics. The given client ID of the device could be too long. .. note:: - If :option:`CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES` is enabled, error values could be different or have different error descriptions. + If :kconfig:`CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES` is enabled, error values could be different or have different error descriptions. .. _connect_to_cloud: @@ -219,19 +219,19 @@ Connecting to the Cloud ======================= The nRF Cloud library offers two ways to handle backend connections when the :c:func:`cloud_connect` function is called. -If you enable the :option:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` Kconfig option, a cloud backend thread monitors the connection socket. +If you enable the :kconfig:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` Kconfig option, a cloud backend thread monitors the connection socket. If you disable the option, the user application must monitor the socket. The dual functionalities of the :c:func:`cloud_connect` function in the two scenarios are described below: -* :option:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` - If you enable this option, the function does not block and returns success if the connection monitoring thread has started. Below are some of the error codes that can be returned: +* :kconfig:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` - If you enable this option, the function does not block and returns success if the connection monitoring thread has started. Below are some of the error codes that can be returned: * :c:enumerator:`CLOUD_CONNECT_RES_ERR_NOT_INITD` - Cloud backend is not initialized * :c:enumerator:`CLOUD_CONNECT_RES_ERR_ALREADY_CONNECTED` - Connection process has already been started Upon success, the monitoring thread sends an event of type :c:enumerator:`CLOUD_EVT_CONNECTING` to the user’s cloud event handler, with the ``err`` field set to success. If an error occurs, another event of the same type is sent, with the ``err`` field set to indicate the cause. These additional errors are described in the following section. -* :option:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` - If you disable this option, the function blocks and returns success when the MQTT connection to the cloud completes. The connection socket is set in the backend binding and it becomes available for the application to use. Below are some of the error codes that can be returned: +* :kconfig:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` - If you disable this option, the function blocks and returns success when the MQTT connection to the cloud completes. The connection socket is set in the backend binding and it becomes available for the application to use. Below are some of the error codes that can be returned: * :c:enumerator:`CLOUD_CONNECT_RES_ERR_NOT_INITD`. * :c:enumerator:`CLOUD_CONNECT_RES_ERR_NETWORK` - Host cannot be found with the available network interfaces. @@ -264,7 +264,7 @@ The user application can generate a disconnect request with the :c:func:`cloud_d A successful disconnection is indicated by the :c:enumerator:`CLOUD_EVT_DISCONNECTED` event. The ``err`` field in the event message is set to :c:enumerator:`CLOUD_DISCONNECT_USER_REQUEST`. If an unexpected disconnect event is received, the ``err`` field contains the cause. -If :option:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` is not enabled, the only cause of disconnection is :c:enumerator:`CLOUD_DISCONNECT_MISC`. +If :kconfig:`CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD` is not enabled, the only cause of disconnection is :c:enumerator:`CLOUD_DISCONNECT_MISC`. The user application must use the connection socket to determine a reason. The following events can cause disconnection if the backend thread is monitoring the socket: diff --git a/doc/nrf/libraries/networking/nrf_cloud_agps.rst b/doc/nrf/libraries/networking/nrf_cloud_agps.rst index b15688abf59d..4f5657918324 100644 --- a/doc/nrf/libraries/networking/nrf_cloud_agps.rst +++ b/doc/nrf/libraries/networking/nrf_cloud_agps.rst @@ -23,8 +23,8 @@ Configuration Configure the following options to enable or disable the use of this library: -* :option:`CONFIG_NRF_CLOUD` -* :option:`CONFIG_NRF_CLOUD_AGPS` +* :kconfig:`CONFIG_NRF_CLOUD` +* :kconfig:`CONFIG_NRF_CLOUD_AGPS` See :ref:`configure_application` for information on how to change configuration options. diff --git a/doc/nrf/libraries/networking/nrf_cloud_cell_pos.rst b/doc/nrf/libraries/networking/nrf_cloud_cell_pos.rst index fc55d57b86a8..8bcb9a79bcc0 100644 --- a/doc/nrf/libraries/networking/nrf_cloud_cell_pos.rst +++ b/doc/nrf/libraries/networking/nrf_cloud_cell_pos.rst @@ -18,8 +18,8 @@ Configuration Configure the following options to enable or disable the use of this library: -* :option:`CONFIG_NRF_CLOUD` -* :option:`CONFIG_NRF_CLOUD_CELL_POS` +* :kconfig:`CONFIG_NRF_CLOUD` +* :kconfig:`CONFIG_NRF_CLOUD_CELL_POS` Request and process cellular positioning data diff --git a/doc/nrf/libraries/networking/nrf_cloud_pgps.rst b/doc/nrf/libraries/networking/nrf_cloud_pgps.rst index 4fc942a7a86c..62b0c8ad80a9 100644 --- a/doc/nrf/libraries/networking/nrf_cloud_pgps.rst +++ b/doc/nrf/libraries/networking/nrf_cloud_pgps.rst @@ -42,32 +42,32 @@ Configuration Configure the following options to enable or disable the use of this library: -* :option:`CONFIG_NRF_CLOUD` -* :option:`CONFIG_NRF_CLOUD_PGPS` +* :kconfig:`CONFIG_NRF_CLOUD` +* :kconfig:`CONFIG_NRF_CLOUD_PGPS` Configure these additional options to refine the behavior of P-GPS: -* :option:`CONFIG_NRF_CLOUD_PGPS_PREDICTION_PERIOD` -* :option:`CONFIG_NRF_CLOUD_PGPS_NUM_PREDICTIONS` -* :option:`CONFIG_NRF_CLOUD_PGPS_REPLACEMENT_THRESHOLD` -* :option:`CONFIG_NRF_CLOUD_PGPS_DOWNLOAD_FRAGMENT_SIZE` +* :kconfig:`CONFIG_NRF_CLOUD_PGPS_PREDICTION_PERIOD` +* :kconfig:`CONFIG_NRF_CLOUD_PGPS_NUM_PREDICTIONS` +* :kconfig:`CONFIG_NRF_CLOUD_PGPS_REPLACEMENT_THRESHOLD` +* :kconfig:`CONFIG_NRF_CLOUD_PGPS_DOWNLOAD_FRAGMENT_SIZE` Configure both of the following options if you need your application to use A-GPS as well, for coarse time and position data and to get the fastest TTFF: -* :option:`CONFIG_NRF_CLOUD_AGPS` -* :option:`CONFIG_AGPS` +* :kconfig:`CONFIG_NRF_CLOUD_AGPS` +* :kconfig:`CONFIG_AGPS` If A-GPS is not desired (due to data costs, low power requirements, or expected frequent loss of cloud connectivity), both options listed above must be disabled. For an application that uses P-GPS, the following options must be configured for storing settings, for having accurate clock time, and for having a location to store predictions: -* :option:`CONFIG_FLASH` -* :option:`CONFIG_FCB` -* :option:`CONFIG_SETTINGS_FCB` -* :option:`CONFIG_DATE_TIME` -* :option:`CONFIG_BOOTLOADER_MCUBOOT` -* :option:`CONFIG_IMG_MANAGER` -* :option:`CONFIG_MCUBOOT_IMG_MANAGER` +* :kconfig:`CONFIG_FLASH` +* :kconfig:`CONFIG_FCB` +* :kconfig:`CONFIG_SETTINGS_FCB` +* :kconfig:`CONFIG_DATE_TIME` +* :kconfig:`CONFIG_BOOTLOADER_MCUBOOT` +* :kconfig:`CONFIG_IMG_MANAGER` +* :kconfig:`CONFIG_MCUBOOT_IMG_MANAGER` See :ref:`configure_application` for information on how to change configuration options. @@ -157,7 +157,7 @@ If the use case involves possible long-distance travel between fix attempts, suc The application can also call :c:func:`nrf_cloud_pgps_preemptive_updates` to discard expired predictions and replace them with newer ones, prior to the expiration of the entire set of predictions. This can be useful for customer use cases where cloud connections are available infrequently. -The :option:`CONFIG_NRF_CLOUD_PGPS_REPLACEMENT_THRESHOLD` sets the minimum number of valid predictions remaining before such an update occurs. +The :kconfig:`CONFIG_NRF_CLOUD_PGPS_REPLACEMENT_THRESHOLD` sets the minimum number of valid predictions remaining before such an update occurs. For best performance, applications can call the P-GPS functions mentioned in this section from workqueue handlers rather than directly from various callback functions. diff --git a/doc/nrf/libraries/others/bl_crypto.rst b/doc/nrf/libraries/others/bl_crypto.rst index 195286270621..6041d71b27ab 100644 --- a/doc/nrf/libraries/others/bl_crypto.rst +++ b/doc/nrf/libraries/others/bl_crypto.rst @@ -33,15 +33,15 @@ When using the library, you can choose between the following backends: To configure which backend is used for hashing, set one of the following configuration options: -* :option:`CONFIG_SB_CRYPTO_OBERON_SHA256` -* :option:`CONFIG_SB_CRYPTO_CC310_SHA256` -* :option:`CONFIG_SB_CRYPTO_CLIENT_SHA256` +* :kconfig:`CONFIG_SB_CRYPTO_OBERON_SHA256` +* :kconfig:`CONFIG_SB_CRYPTO_CC310_SHA256` +* :kconfig:`CONFIG_SB_CRYPTO_CLIENT_SHA256` To configure which backend is used for firmware verification, set one of the following configuration options: -* :option:`CONFIG_SB_CRYPTO_CC310_ECDSA_SECP256R1` -* :option:`CONFIG_SB_CRYPTO_OBERON_ECDSA_SECP256R1` -* :option:`CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1` +* :kconfig:`CONFIG_SB_CRYPTO_CC310_ECDSA_SECP256R1` +* :kconfig:`CONFIG_SB_CRYPTO_OBERON_ECDSA_SECP256R1` +* :kconfig:`CONFIG_SB_CRYPTO_CLIENT_ECDSA_SECP256R1` diff --git a/doc/nrf/libraries/others/bl_storage.rst b/doc/nrf/libraries/others/bl_storage.rst index 593d00506bc5..8ee8a4d32a6d 100644 --- a/doc/nrf/libraries/others/bl_storage.rst +++ b/doc/nrf/libraries/others/bl_storage.rst @@ -40,10 +40,10 @@ This functionality is implemented as a monotonic version counter that contains a Each update to the counter is written to the next available slot. When reading the counter, the bootloader storage library iterates over each slot and returns the largest value. -The number of available slots, thus the number of different version numbers that can be stored, is configurable through :option:`CONFIG_SB_NUM_VER_COUNTER_SLOTS`. +The number of available slots, thus the number of different version numbers that can be stored, is configurable through :kconfig:`CONFIG_SB_NUM_VER_COUNTER_SLOTS`. The monotonic counter is enabled by default. -You can disable it through :option:`CONFIG_SB_MONOTONIC_COUNTER`. +You can disable it through :kconfig:`CONFIG_SB_MONOTONIC_COUNTER`. If the counter is enabled, the :ref:`doc_bl_validation` library checks it against an image's version during :c:func:`bl_validate_firmware`. diff --git a/doc/nrf/libraries/others/date_time.rst b/doc/nrf/libraries/others/date_time.rst index ec97bdda1207..a1923880c485 100644 --- a/doc/nrf/libraries/others/date_time.rst +++ b/doc/nrf/libraries/others/date_time.rst @@ -8,7 +8,7 @@ Date-Time :depth: 2 The date-time library maintains the current date-time information in UTC format. -The option :option:`CONFIG_DATE_TIME_UPDATE_INTERVAL_SECONDS` determines the frequency with which the library updates the date-time information. +The option :kconfig:`CONFIG_DATE_TIME_UPDATE_INTERVAL_SECONDS` determines the frequency with which the library updates the date-time information. The information is fetched in the following prioritized order: @@ -27,13 +27,13 @@ See the API documentation for more information on these functions. .. note:: - The first date-time update cycle (after boot) does not occur until the time set by the :option:`CONFIG_DATE_TIME_UPDATE_INTERVAL_SECONDS` has elapsed. + The first date-time update cycle (after boot) does not occur until the time set by the :kconfig:`CONFIG_DATE_TIME_UPDATE_INTERVAL_SECONDS` has elapsed. It is recommended to call the :c:func:`date_time_update_async` function after the device has connected to LTE, to get the initial date-time information. Configuration ************* -:option:`CONFIG_DATE_TIME_UPDATE_INTERVAL_SECONDS` +:kconfig:`CONFIG_DATE_TIME_UPDATE_INTERVAL_SECONDS` Configure this option to control the frequency with which the library fetches the time information. diff --git a/doc/nrf/libraries/others/ei_wrapper.rst b/doc/nrf/libraries/others/ei_wrapper.rst index c9389588d3b4..d6ce82153bba 100644 --- a/doc/nrf/libraries/others/ei_wrapper.rst +++ b/doc/nrf/libraries/others/ei_wrapper.rst @@ -24,14 +24,14 @@ Before using the wrapper, you need to :ref:`add the machine learning model /modules/lib/memfault-firmware-sdk/``. -To include Memfault in your build, enable the Kconfig option :option:`CONFIG_MEMFAULT`. +To include Memfault in your build, enable the Kconfig option :kconfig:`CONFIG_MEMFAULT`. The APIs in Memfault SDK can then be linked into your application. -In addition, you must configure a Memfault project key using :option:`CONFIG_MEMFAULT_NCS_PROJECT_KEY`. +In addition, you must configure a Memfault project key using :kconfig:`CONFIG_MEMFAULT_NCS_PROJECT_KEY`. To get access to all the benefits, like up to 100 free devices connected, register at the `Memfault registration page`_. @@ -57,7 +57,7 @@ Configuration files .. memfault_config_files_start -If you just want to do a quick test with a sample, disable the :option:`CONFIG_MEMFAULT_USER_CONFIG_ENABLE` option in the :file:`prj.conf` to avoid adding the user configuration files. +If you just want to do a quick test with a sample, disable the :kconfig:`CONFIG_MEMFAULT_USER_CONFIG_ENABLE` option in the :file:`prj.conf` to avoid adding the user configuration files. Otherwise, follow the instructions below. Memfault SDK requires three files in the include path during the build process. @@ -82,20 +82,20 @@ Configuration options in Memfault SDK Following are some of the configuration options that Memfault SDK define: -* :option:`CONFIG_MEMFAULT_SHELL` -* :option:`CONFIG_MEMFAULT_RAM_BACKED_COREDUMP` -* :option:`CONFIG_MEMFAULT_RAM_BACKED_COREDUMP_SIZE` -* :option:`CONFIG_MEMFAULT_COREDUMP_COLLECT_DATA_REGIONS` -* :option:`CONFIG_MEMFAULT_COREDUMP_COLLECT_BSS_REGIONS` -* :option:`CONFIG_MEMFAULT_HTTP_ENABLE` -* :option:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD_INTERVAL_SECS` -* :option:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD_USE_DEDICATED_WORKQUEUE` -* :option:`CONFIG_MEMFAULT_EVENT_STORAGE_SIZE` -* :option:`CONFIG_MEMFAULT_CLEAR_RESET_REG` -* :option:`CONFIG_MEMFAULT_METRICS` -* :option:`CONFIG_MEMFAULT_METRICS_DEFAULT_SET_ENABLE` -* :option:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD` -* :option:`CONFIG_MEMFAULT_ROOT_CERT_STORAGE_NRF9160_MODEM` +* :kconfig:`CONFIG_MEMFAULT_SHELL` +* :kconfig:`CONFIG_MEMFAULT_RAM_BACKED_COREDUMP` +* :kconfig:`CONFIG_MEMFAULT_RAM_BACKED_COREDUMP_SIZE` +* :kconfig:`CONFIG_MEMFAULT_COREDUMP_COLLECT_DATA_REGIONS` +* :kconfig:`CONFIG_MEMFAULT_COREDUMP_COLLECT_BSS_REGIONS` +* :kconfig:`CONFIG_MEMFAULT_HTTP_ENABLE` +* :kconfig:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD_INTERVAL_SECS` +* :kconfig:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD_USE_DEDICATED_WORKQUEUE` +* :kconfig:`CONFIG_MEMFAULT_EVENT_STORAGE_SIZE` +* :kconfig:`CONFIG_MEMFAULT_CLEAR_RESET_REG` +* :kconfig:`CONFIG_MEMFAULT_METRICS` +* :kconfig:`CONFIG_MEMFAULT_METRICS_DEFAULT_SET_ENABLE` +* :kconfig:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD` +* :kconfig:`CONFIG_MEMFAULT_ROOT_CERT_STORAGE_NRF9160_MODEM` You can find more details on each option using ``menuconfig``, ``guiconfig``, and in the Kconfig sources in ``modules/lib/memfault-firmware-sdk/ports/zephyr/Kconfig``. @@ -112,20 +112,20 @@ Configuration options in |NCS| The Kconfig options for Memfault that are defined in |NCS| provide some additional features compared to the options that are already implemented in Memfault SDK: -* :option:`CONFIG_MEMFAULT_NCS_PROJECT_KEY` -* :option:`CONFIG_MEMFAULT_NCS_PROVISION_CERTIFICATES` -* :option:`CONFIG_MEMFAULT_NCS_INTERNAL_FLASH_BACKED_COREDUMP` -* :option:`CONFIG_MEMFAULT_NCS_LTE_METRICS` -* :option:`CONFIG_MEMFAULT_NCS_STACK_METRICS` +* :kconfig:`CONFIG_MEMFAULT_NCS_PROJECT_KEY` +* :kconfig:`CONFIG_MEMFAULT_NCS_PROVISION_CERTIFICATES` +* :kconfig:`CONFIG_MEMFAULT_NCS_INTERNAL_FLASH_BACKED_COREDUMP` +* :kconfig:`CONFIG_MEMFAULT_NCS_LTE_METRICS` +* :kconfig:`CONFIG_MEMFAULT_NCS_STACK_METRICS` The |NCS| integration of `Memfault SDK`_ provides default values for some metadata that are required to identify the firmware when it is sent to Memfault cloud. These defaults can be controlled by using the configuration options below: -* :option:`CONFIG_MEMFAULT_NCS_DEVICE_ID` -* :option:`CONFIG_MEMFAULT_NCS_HW_VERSION` -* :option:`CONFIG_MEMFAULT_NCS_FW_TYPE` -* :option:`CONFIG_MEMFAULT_NCS_FW_VERSION_STATIC` -* :option:`CONFIG_MEMFAULT_NCS_FW_VERSION_PREFIX` +* :kconfig:`CONFIG_MEMFAULT_NCS_DEVICE_ID` +* :kconfig:`CONFIG_MEMFAULT_NCS_HW_VERSION` +* :kconfig:`CONFIG_MEMFAULT_NCS_FW_TYPE` +* :kconfig:`CONFIG_MEMFAULT_NCS_FW_VERSION_STATIC` +* :kconfig:`CONFIG_MEMFAULT_NCS_FW_VERSION_PREFIX` API documentation diff --git a/doc/nrf/libraries/others/profiler.rst b/doc/nrf/libraries/others/profiler.rst index 1c49034a2f5d..7a0b1183397b 100644 --- a/doc/nrf/libraries/others/profiler.rst +++ b/doc/nrf/libraries/others/profiler.rst @@ -22,12 +22,12 @@ Configuration Apart from standard configuration parameters, there is one required setting: -:option:`CONFIG_PROFILER` +:kconfig:`CONFIG_PROFILER` Set this option to add the Profiler source code to the application. - If you use the Event Manager, you can also set this option by selecting :option:`CONFIG_EVENT_MANAGER_PROFILER_ENABLED`. + If you use the Event Manager, you can also set this option by selecting :kconfig:`CONFIG_EVENT_MANAGER_PROFILER_ENABLED`. Call :c:func:`profiler_init` during the application start to initialize the Profiler. -If you set :option:`CONFIG_EVENT_MANAGER_PROFILER_ENABLED`, the Profiler is automatically initialized when you initialize the :ref:`event_manager`. +If you set :kconfig:`CONFIG_EVENT_MANAGER_PROFILER_ENABLED`, the Profiler is automatically initialized when you initialize the :ref:`event_manager`. Profiling custom events @@ -97,7 +97,7 @@ Select the custom backend to use dedicated tools written in Python for event vis To save profiling data, the tools use CSV files (for event occurrences) and JSON files (for event descriptions). The scripts can be found under :file:`scripts/profiler/` in the |NCS| folder structure. -Set :option:`CONFIG_PROFILER_NORDIC` to enable this backend. +Set :kconfig:`CONFIG_PROFILER_NORDIC` to enable this backend. To use the tools, run the scripts on the command line: diff --git a/doc/nrf/libraries/others/secure_services.rst b/doc/nrf/libraries/others/secure_services.rst index 99f14725780a..d80860454489 100644 --- a/doc/nrf/libraries/others/secure_services.rst +++ b/doc/nrf/libraries/others/secure_services.rst @@ -10,12 +10,12 @@ Secure Services Secure Services are functions implemented in the Secure Firmware (:ref:`secure_partition_manager`), but made available to be called from the Non-Secure Firmware. Calling functions in this API requires that the service is enabled in the :ref:`secure_partition_manager`. -See :option:`CONFIG_SPM_SECURE_SERVICES` in the :ref:`secure_partition_manager`'s menuconfig. +See :kconfig:`CONFIG_SPM_SECURE_SERVICES` in the :ref:`secure_partition_manager`'s menuconfig. Some services are enabled by default. .. Remove parts with regards to debugging and programming when NRF91-313 is resolved -By default :option:`CONFIG_SPM_BLOCK_NON_SECURE_RESET` is disabled. This is to make sure that your debugger will be able to issue a system reset during the development stage and that devices which do not have pin-reset routed can do a re-flashing routine correctly. This option should be turned off when you are putting a product into production to increase the security of your device. +By default :kconfig:`CONFIG_SPM_BLOCK_NON_SECURE_RESET` is disabled. This is to make sure that your debugger will be able to issue a system reset during the development stage and that devices which do not have pin-reset routed can do a re-flashing routine correctly. This option should be turned off when you are putting a product into production to increase the security of your device. API documentation ***************** diff --git a/doc/nrf/libraries/others/supl_os_client.rst b/doc/nrf/libraries/others/supl_os_client.rst index 75a1c979076c..c10f4f5d56e6 100644 --- a/doc/nrf/libraries/others/supl_os_client.rst +++ b/doc/nrf/libraries/others/supl_os_client.rst @@ -95,7 +95,7 @@ Make sure to maintain the folder structure that is used in the zip file. Configuration ============= -To enable the SUPL client library, set :option:`CONFIG_SUPL_CLIENT_LIB` to ``y``. +To enable the SUPL client library, set :kconfig:`CONFIG_SUPL_CLIENT_LIB` to ``y``. See :ref:`configure_application` for information on how to change configuration options. Resource initialization and ownership diff --git a/doc/nrf/libraries/tfm/tfm_ioctl_api.rst b/doc/nrf/libraries/tfm/tfm_ioctl_api.rst index 41e0200d1be4..f647e4be206c 100644 --- a/doc/nrf/libraries/tfm/tfm_ioctl_api.rst +++ b/doc/nrf/libraries/tfm/tfm_ioctl_api.rst @@ -26,7 +26,7 @@ The supported platform services are defined by :c:struct:`fm_platform_ioctl_requ :start-at: /** @brief Supported request types. :end-before: /** @brief Argument list for each platform read service. -Set the :option:``CONFIG_TFM_PARTITION_PLATFORM`` Kconfig option to enable the services. +Set the :kconfig:``CONFIG_TFM_PARTITION_PLATFORM`` Kconfig option to enable the services. See the :ref:`tfm_hello_world` sample for example usage. diff --git a/doc/nrf/libraries/zigbee/zigbee_app_utils.rst b/doc/nrf/libraries/zigbee/zigbee_app_utils.rst index f18fd0429e71..f905ed087737 100644 --- a/doc/nrf/libraries/zigbee/zigbee_app_utils.rst +++ b/doc/nrf/libraries/zigbee/zigbee_app_utils.rst @@ -461,9 +461,9 @@ Use the following code as reference, with a call to :c:func:`zigbee_default_sign Configuration ************* -To enable the Zigbee application utilities library, set the :option:`CONFIG_ZIGBEE_APP_UTILS` Kconfig option. +To enable the Zigbee application utilities library, set the :kconfig:`CONFIG_ZIGBEE_APP_UTILS` Kconfig option. -To configure the logging level of the library, use the :option:`CONFIG_ZIGBEE_APP_UTILS_LOG_LEVEL` Kconfig option. +To configure the logging level of the library, use the :kconfig:`CONFIG_ZIGBEE_APP_UTILS_LOG_LEVEL` Kconfig option. For detailed steps about configuring the library in a Zigbee sample or application, see :ref:`ug_zigbee_configuring_components_application_utilities`. diff --git a/doc/nrf/libraries/zigbee/zigbee_error_handler.rst b/doc/nrf/libraries/zigbee/zigbee_error_handler.rst index 304f3ae168d4..4dba4b4ecdab 100644 --- a/doc/nrf/libraries/zigbee/zigbee_error_handler.rst +++ b/doc/nrf/libraries/zigbee/zigbee_error_handler.rst @@ -20,8 +20,8 @@ Configuration To use this library, include its header in your application and pass the error code that should be checked using its macros. -Additionally, if you want the error code to be printed to log, enable the :option:`CONFIG_LOG` and :option:`CONFIG_ZBOSS_ERROR_PRINT_TO_LOG` Kconfig options. -The :option:`CONFIG_ZBOSS_ERROR_PRINT_TO_LOG` option automatically enables the :option:`CONFIG_ZIGBEE_ERROR_TO_STRING_ENABLED` Kconfig option, which obtains the ZBOSS error code name. +Additionally, if you want the error code to be printed to log, enable the :kconfig:`CONFIG_LOG` and :kconfig:`CONFIG_ZBOSS_ERROR_PRINT_TO_LOG` Kconfig options. +The :kconfig:`CONFIG_ZBOSS_ERROR_PRINT_TO_LOG` option automatically enables the :kconfig:`CONFIG_ZIGBEE_ERROR_TO_STRING_ENABLED` Kconfig option, which obtains the ZBOSS error code name. The library also provides a macro for checking the value returned by the :c:func:`bdb_start_top_level_commissioning` function. diff --git a/doc/nrf/libraries/zigbee/zigbee_fota.rst b/doc/nrf/libraries/zigbee/zigbee_fota.rst index 189da1727954..1b498a507944 100644 --- a/doc/nrf/libraries/zigbee/zigbee_fota.rst +++ b/doc/nrf/libraries/zigbee/zigbee_fota.rst @@ -39,10 +39,10 @@ The library uses :ref:`nrfxlib:zboss`'s ZCL API to download the image. After the OTA Upgrade Client downloads the Zigbee OTA image header, the stack verifies the following mandatory fields: -* Manufacturer ID - Defined by the :option:`CONFIG_ZIGBEE_FOTA_MANUFACTURER_ID` Kconfig option. -* Image type - Defined by the :option:`CONFIG_ZIGBEE_FOTA_IMAGE_TYPE` Kconfig option; it may be different than the MCUboot image type value. -* Hardware version - Defined by the :option:`CONFIG_ZIGBEE_FOTA_HW_VERSION` Kconfig option. -* Firmware version - Defined by the :option:`CONFIG_MCUBOOT_IMAGE_VERSION` Kconfig option; see :ref:`ug_zigbee_configuring_components_ota` for details. +* Manufacturer ID - Defined by the :kconfig:`CONFIG_ZIGBEE_FOTA_MANUFACTURER_ID` Kconfig option. +* Image type - Defined by the :kconfig:`CONFIG_ZIGBEE_FOTA_IMAGE_TYPE` Kconfig option; it may be different than the MCUboot image type value. +* Hardware version - Defined by the :kconfig:`CONFIG_ZIGBEE_FOTA_HW_VERSION` Kconfig option. +* Firmware version - Defined by the :kconfig:`CONFIG_MCUBOOT_IMAGE_VERSION` Kconfig option; see :ref:`ug_zigbee_configuring_components_ota` for details. If all values are accepted, the OTA Upgrade Client downloads the first fragment of the firmware image. @@ -63,21 +63,21 @@ When the consumer of the library receives this event, it should issue a reboot c Configuration ************* -To enable the Zigbee FOTA library, set the :option:`CONFIG_ZIGBEE_FOTA` Kconfig option. +To enable the Zigbee FOTA library, set the :kconfig:`CONFIG_ZIGBEE_FOTA` Kconfig option. To configure the Zigbee FOTA library, use the following options: -* :option:`CONFIG_ZIGBEE_FOTA_HW_VERSION` -* :option:`CONFIG_ZIGBEE_FOTA_DATA_BLOCK_SIZE` -* :option:`CONFIG_ZIGBEE_FOTA_ENDPOINT` -* :option:`CONFIG_ZIGBEE_FOTA_PROGRESS_EVT` -* :option:`CONFIG_ZIGBEE_FOTA_MANUFACTURER_ID` -* :option:`CONFIG_ZIGBEE_FOTA_IMAGE_TYPE` -* :option:`CONFIG_ZIGBEE_FOTA_COMMENT` -* :option:`CONFIG_ENABLE_ZIGBEE_FOTA_MIN_HW_VERSION` -* :option:`CONFIG_ZIGBEE_FOTA_MIN_HW_VERSION` -* :option:`CONFIG_ENABLE_ZIGBEE_FOTA_MAX_HW_VERSION` -* :option:`CONFIG_ZIGBEE_FOTA_MAX_HW_VERSION` +* :kconfig:`CONFIG_ZIGBEE_FOTA_HW_VERSION` +* :kconfig:`CONFIG_ZIGBEE_FOTA_DATA_BLOCK_SIZE` +* :kconfig:`CONFIG_ZIGBEE_FOTA_ENDPOINT` +* :kconfig:`CONFIG_ZIGBEE_FOTA_PROGRESS_EVT` +* :kconfig:`CONFIG_ZIGBEE_FOTA_MANUFACTURER_ID` +* :kconfig:`CONFIG_ZIGBEE_FOTA_IMAGE_TYPE` +* :kconfig:`CONFIG_ZIGBEE_FOTA_COMMENT` +* :kconfig:`CONFIG_ENABLE_ZIGBEE_FOTA_MIN_HW_VERSION` +* :kconfig:`CONFIG_ZIGBEE_FOTA_MIN_HW_VERSION` +* :kconfig:`CONFIG_ENABLE_ZIGBEE_FOTA_MAX_HW_VERSION` +* :kconfig:`CONFIG_ZIGBEE_FOTA_MAX_HW_VERSION` For detailed steps about configuring the library in a Zigbee sample or application, see :ref:`ug_zigbee_configuring_components_ota`. @@ -86,7 +86,7 @@ Limitations The Zigbee FOTA library has the following limitations: -* The endpoint definition in the library includes the endpoint ID, defined with :option:`CONFIG_ZIGBEE_FOTA_ENDPOINT`. +* The endpoint definition in the library includes the endpoint ID, defined with :kconfig:`CONFIG_ZIGBEE_FOTA_ENDPOINT`. When using the Zigbee FOTA library, this endpoint ID cannot be used for other endpoints. * The Zigbee FOTA upgrades are currently only supported on the nRF52840 DK (PCA10056). * The Zigbee FOTA library does not currently support bootloader upgrades. diff --git a/doc/nrf/libraries/zigbee/zigbee_logger_eprxzcl.rst b/doc/nrf/libraries/zigbee/zigbee_logger_eprxzcl.rst index 96c9fb4172b4..316ece7cfb94 100644 --- a/doc/nrf/libraries/zigbee/zigbee_logger_eprxzcl.rst +++ b/doc/nrf/libraries/zigbee/zigbee_logger_eprxzcl.rst @@ -72,9 +72,9 @@ For example, enabling the Zigbee endpoint logger library with the :ref:`zigbee_l Configuration ************* -To enable the Zigbee endpoint logger library, set the :option:`CONFIG_ZIGBEE_LOGGER_EP` Kconfig option. +To enable the Zigbee endpoint logger library, set the :kconfig:`CONFIG_ZIGBEE_LOGGER_EP` Kconfig option. -To configure the logging level of the library, use the :option:`CONFIG_ZIGBEE_LOGGER_EP_LOG_LEVEL` Kconfig option. +To configure the logging level of the library, use the :kconfig:`CONFIG_ZIGBEE_LOGGER_EP_LOG_LEVEL` Kconfig option. For detailed steps about configuring the library in a Zigbee sample or application, see :ref:`ug_zigbee_configuring_components_logger_ep`. diff --git a/doc/nrf/libraries/zigbee/zigbee_zcl_scenes.rst b/doc/nrf/libraries/zigbee/zigbee_zcl_scenes.rst index 32a9732528bc..b96192387ff2 100644 --- a/doc/nrf/libraries/zigbee/zigbee_zcl_scenes.rst +++ b/doc/nrf/libraries/zigbee/zigbee_zcl_scenes.rst @@ -24,7 +24,7 @@ If you are implementing clusters that are not included in this list, you must im Configuration ************* -To enable the Zigbee ZCL scene helper library, set the :option:`CONFIG_ZIGBEE_SCENES` Kconfig option. +To enable the Zigbee ZCL scene helper library, set the :kconfig:`CONFIG_ZIGBEE_SCENES` Kconfig option. Because the library uses Zephyr's :ref:`settings_api` subsystem, the application must call the following functions for the library to work correctly: @@ -55,12 +55,12 @@ You must implement these functions in the following manner: } } -Setting the :option:`CONFIG_ZIGBEE_SCENES` option allows you to configure the following library-specific Kconfig options: +Setting the :kconfig:`CONFIG_ZIGBEE_SCENES` option allows you to configure the following library-specific Kconfig options: -* :option:`CONFIG_ZIGBEE_SCENES_ENDPOINT` - This option sets the endpoint number on which the device implements the ZCL scene cluster. -* :option:`CONFIG_ZIGBEE_SCENE_TABLE_SIZE` - This options sets the value for the amount of scenes that can be configured. +* :kconfig:`CONFIG_ZIGBEE_SCENES_ENDPOINT` - This option sets the endpoint number on which the device implements the ZCL scene cluster. +* :kconfig:`CONFIG_ZIGBEE_SCENE_TABLE_SIZE` - This options sets the value for the amount of scenes that can be configured. -To configure the logging level of the library, use the :option:`CONFIG_ZIGBEE_SCENES_LOG_LEVEL` Kconfig option. +To configure the logging level of the library, use the :kconfig:`CONFIG_ZIGBEE_SCENES_LOG_LEVEL` Kconfig option. API documentation ***************** diff --git a/samples/bluetooth/alexa_gadget/README.rst b/samples/bluetooth/alexa_gadget/README.rst index df6111220b8b..dbb354e19e75 100644 --- a/samples/bluetooth/alexa_gadget/README.rst +++ b/samples/bluetooth/alexa_gadget/README.rst @@ -18,7 +18,7 @@ Overview ******** When connected, the sample performs the handshake procedure and informs the peer of its supported capabilities. -Directives sent by the connected peer are printed as log messages when :option:`CONFIG_LOG` is set. +Directives sent by the connected peer are printed as log messages when :kconfig:`CONFIG_LOG` is set. Additionally, when the "wake word" State Update directive is received, LED 3 on the development kit is turned on. Gadget capabilities diff --git a/samples/bluetooth/direct_test_mode/README.rst b/samples/bluetooth/direct_test_mode/README.rst index d1ea84a99a13..041397750e89 100644 --- a/samples/bluetooth/direct_test_mode/README.rst +++ b/samples/bluetooth/direct_test_mode/README.rst @@ -211,7 +211,7 @@ Building and running However, you must still program the application core to boot up the network core. You can use any sample for this, for example, the :ref:`nrf5340_empty_app_core`. The :ref:`nrf5340_empty_app_core` is built and programmed automatically by default. - If you want to program another sample for the application core, unset the :option:'CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE' option. + If you want to program another sample for the application core, unset the :kconfig:'CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE' option. .. _dtm_testing: diff --git a/samples/bluetooth/mesh/chat/chat_cli.rst b/samples/bluetooth/mesh/chat/chat_cli.rst index 834d97fc6f2a..0b5cf00cd21e 100644 --- a/samples/bluetooth/mesh/chat/chat_cli.rst +++ b/samples/bluetooth/mesh/chat/chat_cli.rst @@ -100,4 +100,4 @@ None. Persistent storage ****************** -If :option:`CONFIG_BT_SETTINGS` is enabled, the Chat Client stores its presence state. +If :kconfig:`CONFIG_BT_SETTINGS` is enabled, the Chat Client stores its presence state. diff --git a/samples/bluetooth/mesh/light_ctrl/README.rst b/samples/bluetooth/mesh/light_ctrl/README.rst index af6ebfa97dbd..72b135fbdd23 100644 --- a/samples/bluetooth/mesh/light_ctrl/README.rst +++ b/samples/bluetooth/mesh/light_ctrl/README.rst @@ -158,11 +158,11 @@ You should now see the following actions: 1. The LED fades from 0% to 100% over 500ms :guilabel:`Standby -> On`. #. The LED stays at 100% for three seconds :guilabel:`On`. -#. The LED fades from 100% to :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` over five seconds :guilabel:`On -> Prolong`. -#. The LED stays at :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` for three seconds :guilabel:`Prolong`. -#. The LED fades from :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` to 0% over five seconds :guilabel:`Prolong -> Standby`. +#. The LED fades from 100% to :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` over five seconds :guilabel:`On -> Prolong`. +#. The LED stays at :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` for three seconds :guilabel:`Prolong`. +#. The LED fades from :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` to 0% over five seconds :guilabel:`Prolong -> Standby`. -The default value of :option:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` is 10000 (~15%). +The default value of :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_LVL_PROLONG` is 10000 (~15%). .. figure:: images/bt_mesh_light_ctrl_levels.svg :alt: Light level transitions over time diff --git a/samples/bluetooth/peripheral_uart/README.rst b/samples/bluetooth/peripheral_uart/README.rst index 84a08234d0d0..2bbc1bff34ff 100644 --- a/samples/bluetooth/peripheral_uart/README.rst +++ b/samples/bluetooth/peripheral_uart/README.rst @@ -117,7 +117,7 @@ After programming the sample to your development kit, test it by performing the #. |connect_terminal| #. Optionally, you can display debug messages. See :ref:`peripheral_uart_debug` for details. #. Reset the kit. -#. Observe that **LED 1** is blinking and that the device is advertising with the device name that is configured in :option:`CONFIG_BT_DEVICE_NAME`. +#. Observe that **LED 1** is blinking and that the device is advertising with the device name that is configured in :kconfig:`CONFIG_BT_DEVICE_NAME`. #. Observe that the text "Starting Nordic UART service example" is printed on the COM listener running on the computer. #. Connect to the device using nRF Connect for Mobile. Observe that **LED 2** is on. diff --git a/samples/bluetooth/rpc_host/README.rst b/samples/bluetooth/rpc_host/README.rst index 6f758a0912c4..86fa7c262c2d 100644 --- a/samples/bluetooth/rpc_host/README.rst +++ b/samples/bluetooth/rpc_host/README.rst @@ -55,11 +55,11 @@ Example build ============= The recommended way of building the nRF RPC Host sample is to use the multi-image feature of the build system, building the sample with the same Bluetooth configuration as the application core sample. -In this way, the sample is built automatically as a child image when :option:`CONFIG_BT_RPC` is enabled. +In this way, the sample is built automatically as a child image when :kconfig:`CONFIG_BT_RPC` is enabled. See :ref:`configure_application` for information about how to configure a sample. -For example, building the :ref:`zephyr:bluetooth-beacon-sample` sample for the nRF5340 application core with the :option:`CONFIG_BT_RPC` configuration option will include the nRF RPC Host sample in the build. +For example, building the :ref:`zephyr:bluetooth-beacon-sample` sample for the nRF5340 application core with the :kconfig:`CONFIG_BT_RPC` configuration option will include the nRF RPC Host sample in the build. To do so on the command line, run the following command in the beacon sample directory: diff --git a/samples/bootloader/README.rst b/samples/bootloader/README.rst index fe2ff28969e4..4c2e15aab52d 100644 --- a/samples/bootloader/README.rst +++ b/samples/bootloader/README.rst @@ -156,7 +156,7 @@ This would result, for example, in a flash memory layout like the following, whe Pre-signed variants ------------------- -When the application uses a second-stage upgradable bootloader, *S1* can be programmed with the same image as *S0* when compiled with the :option:`CONFIG_BUILD_S1_VARIANT` option. +When the application uses a second-stage upgradable bootloader, *S1* can be programmed with the same image as *S0* when compiled with the :kconfig:`CONFIG_BUILD_S1_VARIANT` option. This ensures that the upgradable bootloader can be executed from either slot chosen by the |NSIB|. When the upgradable bootloader is upgraded, the new image is placed into the slot not in use by the current version of the bootloader. @@ -201,16 +201,16 @@ Monotonic Counter Firmware versions using the |NSIB| are kept in the form of a *monotonic counter*, a hardware-based version that prevents booting an image with a lower counter value. Counter values are kept as slots in the flash memory, with each new counter value occupying a new slot. -See :option:`CONFIG_SB_MONOTONIC_COUNTER` for more details. +See :kconfig:`CONFIG_SB_MONOTONIC_COUNTER` for more details. -An application's counter value can be set by building using the :option:`CONFIG_FW_INFO_FIRMWARE_VERSION` option: +An application's counter value can be set by building using the :kconfig:`CONFIG_FW_INFO_FIRMWARE_VERSION` option: .. code-block:: CONFIG_FW_INFO_FIRMWARE_VERSION= The number of slots available for counter values depends on the type of nRF devices being used. -For default values and ranges, see :option:`CONFIG_SB_NUM_VER_COUNTER_SLOTS`. +For default values and ranges, see :kconfig:`CONFIG_SB_NUM_VER_COUNTER_SLOTS`. .. bootloader_monotonic_counter_end @@ -249,15 +249,15 @@ To add the bootloader sample as a child image to your application: #. Enable the |NSIB| by running ``menuconfig`` on your application: a. Select :guilabel:`Project` > :guilabel:`Configure nRF Connect SDK project`. - #. Go to :guilabel:`Modules` > :guilabel:`Nordic nRF Connect` > :guilabel:`Bootloader` and set :guilabel:`Use Secure Bootloader` to enable :option:`CONFIG_SECURE_BOOT`. - #. Under :guilabel:`Private key PEM file` (:option:`CONFIG_SB_SIGNING_KEY_FILE`), enter the path to the private key that you created. + #. Go to :guilabel:`Modules` > :guilabel:`Nordic nRF Connect` > :guilabel:`Bootloader` and set :guilabel:`Use Secure Bootloader` to enable :kconfig:`CONFIG_SECURE_BOOT`. + #. Under :guilabel:`Private key PEM file` (:kconfig:`CONFIG_SB_SIGNING_KEY_FILE`), enter the path to the private key that you created. If you choose to run the sample with default debug keys, you can skip this step. There are additional configuration options that you can modify, but it is not recommended to do so. The default settings are suitable for most use cases. .. note:: - If you need more flexibility with signing, or if you do not want the build system to handle your private key, choose :option:`CONFIG_SB_SIGNING_CUSTOM`, and also specify :option:`CONFIG_SB_SIGNING_COMMAND` and :option:`CONFIG_SB_SIGNING_PUBLIC_KEY`. + If you need more flexibility with signing, or if you do not want the build system to handle your private key, choose :kconfig:`CONFIG_SB_SIGNING_CUSTOM`, and also specify :kconfig:`CONFIG_SB_SIGNING_COMMAND` and :kconfig:`CONFIG_SB_SIGNING_PUBLIC_KEY`. These options allow you to define the signing command. #. Click :guilabel:`Configure`. diff --git a/samples/edge_impulse/wrapper/README.rst b/samples/edge_impulse/wrapper/README.rst index 37f568d33e28..cc0e1c434eaa 100644 --- a/samples/edge_impulse/wrapper/README.rst +++ b/samples/edge_impulse/wrapper/README.rst @@ -44,7 +44,7 @@ To run the sample using a custom machine learning model, you must complete the f 1. Configure the Edge Impulse wrapper by completing the following steps: a. Prepare your own machine learning model using `Edge Impulse studio`_. - #. Set the :option:`CONFIG_EDGE_IMPULSE_URI` to URI of your machine learning model. + #. Set the :kconfig:`CONFIG_EDGE_IMPULSE_URI` to URI of your machine learning model. See the :ref:`ei_wrapper` page for detailed configuration steps. #. Define the input data for the machine learning model in :file:`samples/edge_impulse/wrapper/src/include/input_data.h`. diff --git a/samples/nrf5340/multiprotocol_rpmsg/README.rst b/samples/nrf5340/multiprotocol_rpmsg/README.rst index 87c6b05043aa..a48843242e86 100644 --- a/samples/nrf5340/multiprotocol_rpmsg/README.rst +++ b/samples/nrf5340/multiprotocol_rpmsg/README.rst @@ -16,12 +16,12 @@ The sample is compatible with the HCI RPMsg driver provided by the |NCS| Bluetoo See the following configuration options for more information: -* :option:`CONFIG_BT_RPMSG` -* :option:`CONFIG_NRF_802154_SER_HOST` -* :option:`CONFIG_BT_RPMSG_NRF53` +* :kconfig:`CONFIG_BT_RPMSG` +* :kconfig:`CONFIG_NRF_802154_SER_HOST` +* :kconfig:`CONFIG_BT_RPMSG_NRF53` You might need to adjust the Kconfig configuration of this sample to make it compatible with the peer application. -For example, :option:`CONFIG_BT_MAX_CONN` must be equal to the maximum number of connections supported by the peer application. +For example, :kconfig:`CONFIG_BT_MAX_CONN` must be equal to the maximum number of connections supported by the peer application. The following components have been disabled to make this sample energy-efficient: @@ -47,7 +47,7 @@ Building and Running You must program this sample to the nRF5340 network core. The recommended way of building the sample is to use the multi-image feature of the build system. -In this way, the sample is built automatically as a child image when both :option:`CONFIG_BT_RPMSG_NRF53` and :option:`CONFIG_NRF_802154_SER_HOST` are enabled. +In this way, the sample is built automatically as a child image when both :kconfig:`CONFIG_BT_RPMSG_NRF53` and :kconfig:`CONFIG_NRF_802154_SER_HOST` are enabled. See :ref:`configure_application` for information about how to configure the sample. diff --git a/samples/nrf5340/netboot/README.rst b/samples/nrf5340/netboot/README.rst index d843e8aa5c6a..71dde5bb4054 100644 --- a/samples/nrf5340/netboot/README.rst +++ b/samples/nrf5340/netboot/README.rst @@ -55,9 +55,9 @@ This sample can be found under :file:`samples/nrf5340/netboot/` in the |NCS| fol Follow the steps below to include the sample as a child image in a :ref:`multi-image ` build that contains a network core application: -#. Add MCUboot to the build by enabling the :option:`CONFIG_BOOTLOADER_MCUBOOT` option in the application that runs on the application core. - When doing so, the build system includes the sample in the build by automatically enabling the :option:`CONFIG_SECURE_BOOT` option for the application that runs on the network core. -#. Enable the :ref:`subsys_pcd` library for MCUboot by setting the :option:`CONFIG_PCD` option when building its image. +#. Add MCUboot to the build by enabling the :kconfig:`CONFIG_BOOTLOADER_MCUBOOT` option in the application that runs on the application core. + When doing so, the build system includes the sample in the build by automatically enabling the :kconfig:`CONFIG_SECURE_BOOT` option for the application that runs on the network core. +#. Enable the :ref:`subsys_pcd` library for MCUboot by setting the :kconfig:`CONFIG_PCD` option when building its image. The build system generates a new set of firmware update files. These files match the ones described in :ref:`mcuboot:mcuboot_ncs`, except that they contain the network core application firmware and are prefixed with ``net_core_``. diff --git a/samples/nrf9160/agps/README.rst b/samples/nrf9160/agps/README.rst index 8a20937f00e0..16067c93b4f4 100644 --- a/samples/nrf9160/agps/README.rst +++ b/samples/nrf9160/agps/README.rst @@ -8,7 +8,7 @@ nRF9160: A-GPS :depth: 2 The A-GPS sample demonstrates how the `nRF Connect for Cloud`_ Assisted GPS (`A-GPS`_) feature or an external :ref:`SUPL client ` can be used to implement A-GPS in your application. -The sample uses the generic A-GPS library, which allows the selection of different A-GPS sources via the :option:`CONFIG_AGPS_SRC_SUPL` configurable option. +The sample uses the generic A-GPS library, which allows the selection of different A-GPS sources via the :kconfig:`CONFIG_AGPS_SRC_SUPL` configurable option. By default, `nRF Connect for Cloud`_ is used for A-GPS and cloud communication. Requirements @@ -59,7 +59,7 @@ In RRC idle mode, the GPS is usually able to operate. It is recommended to use LTE Power Saving Mode (PSM) and extended Discontinuous Reception (eDRX) mode to increase the allowed time of operation for GPS. During the defined intervals of PSM and eDRX, LTE communication does not occur, and the GPS has full access to the radio resources. In this sample, both PSM and eDRX are enabled by default. -You can enable or disable these features by using the :option:`CONFIG_LTE_POWER_SAVING_MODE` and :option:`CONFIG_LTE_EDRX_REQ` configuration options. +You can enable or disable these features by using the :kconfig:`CONFIG_LTE_POWER_SAVING_MODE` and :kconfig:`CONFIG_LTE_EDRX_REQ` configuration options. .. include:: /applications/asset_tracker/README.rst :start-after: external_antenna_note_start @@ -69,7 +69,7 @@ User interface ************** You can send a predefined message to nRF Connect for Cloud by pressing button 1. -The message can be changed by setting the :option:`CONFIG_CLOUD_MESSAGE` to a new message. +The message can be changed by setting the :kconfig:`CONFIG_CLOUD_MESSAGE` to a new message. To ease outdoors and remote testing of A-GPS feature, two methods for resetting the kit are provided, if the default A-GPS source is used. Both are equivalent to pressing the reset button on the nRF9160 DK, or power-cycling the nRF9160 DK or Thingy:91. @@ -99,7 +99,7 @@ Additional configuration Check and configure the following library options that are used by the sample: -* :option:`CONFIG_LTE_EDRX_REQ` +* :kconfig:`CONFIG_LTE_EDRX_REQ` Building and running diff --git a/samples/nrf9160/aws_fota/README.rst b/samples/nrf9160/aws_fota/README.rst index 0ce6eea96573..2ea95ad3fe1f 100644 --- a/samples/nrf9160/aws_fota/README.rst +++ b/samples/nrf9160/aws_fota/README.rst @@ -93,7 +93,7 @@ Use LTE Link Monitor to write the certificates to the kit: #. Paste the three certificates into the respective fields. #. Choose a security tag. #. Click :guilabel:`Update certificates`. - #. Before programming the sample, make sure to configure the :option:`security tag ` to the one that you chose. + #. Before programming the sample, make sure to configure the :kconfig:`security tag ` to the one that you chose. .. include:: /includes/aws_s3_bucket.txt diff --git a/samples/nrf9160/aws_iot/README.rst b/samples/nrf9160/aws_iot/README.rst index f7bcdfb10974..160200e99dd1 100644 --- a/samples/nrf9160/aws_iot/README.rst +++ b/samples/nrf9160/aws_iot/README.rst @@ -68,10 +68,10 @@ Configures the time interval between each publishing of the message. .. note:: - The sample sets the option :option:`CONFIG_MQTT_KEEPALIVE` to the maximum allowed value, 1200 seconds (20 minutes) as specified by AWS IoT Core. + The sample sets the option :kconfig:`CONFIG_MQTT_KEEPALIVE` to the maximum allowed value, 1200 seconds (20 minutes) as specified by AWS IoT Core. This is to limit the IP traffic between the device and the AWS IoT message broker for supporting a low power sample. However, note that in certain LTE networks, the NAT timeout can be considerably lower than 1200 seconds. - So as a recommendation, and to prevent the likelihood of getting disconnected unexpectedly, the option :option:`CONFIG_MQTT_KEEPALIVE` must be set to the lowest of the aforementioned timeout limits (Maximum allowed MQTT keepalive and NAT timeout). + So as a recommendation, and to prevent the likelihood of getting disconnected unexpectedly, the option :kconfig:`CONFIG_MQTT_KEEPALIVE` must be set to the lowest of the aforementioned timeout limits (Maximum allowed MQTT keepalive and NAT timeout). Building and running ******************** @@ -86,12 +86,12 @@ Testing 1. Make sure that you have completed the steps in :ref:`setup_awsiot`. This retrieves the AWS IoT broker hostname, security tag and client-id. -#. Set the :option:`CONFIG_AWS_IOT_BROKER_HOST_NAME`, :option:`CONFIG_AWS_IOT_SEC_TAG`, and :option:`CONFIG_AWS_IOT_CLIENT_ID_STATIC` options to reflect the values retrieved during step 1. +#. Set the :kconfig:`CONFIG_AWS_IOT_BROKER_HOST_NAME`, :kconfig:`CONFIG_AWS_IOT_SEC_TAG`, and :kconfig:`CONFIG_AWS_IOT_CLIENT_ID_STATIC` options to reflect the values retrieved during step 1. #. Program the sample to hardware. .. note:: - The sample might require increasing the values of :option:`CONFIG_AWS_IOT_MQTT_RX_TX_BUFFER_LEN` and :option:`CONFIG_AWS_IOT_MQTT_PAYLOAD_BUFFER_LEN` options. + The sample might require increasing the values of :kconfig:`CONFIG_AWS_IOT_MQTT_RX_TX_BUFFER_LEN` and :kconfig:`CONFIG_AWS_IOT_MQTT_PAYLOAD_BUFFER_LEN` options. Sample Output ============= diff --git a/samples/nrf9160/azure_fota/README.rst b/samples/nrf9160/azure_fota/README.rst index 00cfbb62011e..517c344c6b54 100644 --- a/samples/nrf9160/azure_fota/README.rst +++ b/samples/nrf9160/azure_fota/README.rst @@ -56,16 +56,16 @@ Additional configuration Check and configure the following library options that are used by the sample: -* :option:`CONFIG_AZURE_FOTA_APP_VERSION` - Defines the application version string. Indicates the current firmware version on the development kit. -* :option:`CONFIG_AZURE_FOTA_APP_VERSION_AUTO` - Automatically generates the application version. If enabled, :option:`CONFIG_AZURE_FOTA_APP_VERSION` is ignored. -* :option:`CONFIG_AZURE_FOTA_TLS` - Enables HTTPS for downloads. By default, TLS is enabled and currently, the transport protocol must be configured at compile time. -* :option:`CONFIG_AZURE_FOTA_SEC_TAG` - Sets the security tag for TLS credentials when using HTTPS as the transport layer. See :ref:`certificates` for more details. -* :option:`CONFIG_AZURE_IOT_HUB_HOSTNAME` - Sets the Azure IoT Hub host name. If DPS is used, the sample assumes that the IoT hub host name is unknown, and the configuration is ignored. -* :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` - Specifies the device ID, which is used when connecting to Azure IoT Hub or when DPS is enabled. +* :kconfig:`CONFIG_AZURE_FOTA_APP_VERSION` - Defines the application version string. Indicates the current firmware version on the development kit. +* :kconfig:`CONFIG_AZURE_FOTA_APP_VERSION_AUTO` - Automatically generates the application version. If enabled, :kconfig:`CONFIG_AZURE_FOTA_APP_VERSION` is ignored. +* :kconfig:`CONFIG_AZURE_FOTA_TLS` - Enables HTTPS for downloads. By default, TLS is enabled and currently, the transport protocol must be configured at compile time. +* :kconfig:`CONFIG_AZURE_FOTA_SEC_TAG` - Sets the security tag for TLS credentials when using HTTPS as the transport layer. See :ref:`certificates` for more details. +* :kconfig:`CONFIG_AZURE_IOT_HUB_HOSTNAME` - Sets the Azure IoT Hub host name. If DPS is used, the sample assumes that the IoT hub host name is unknown, and the configuration is ignored. +* :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` - Specifies the device ID, which is used when connecting to Azure IoT Hub or when DPS is enabled. .. note:: - If the :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` option is disabled, the device ID must be set in :file:`prj.conf`. - If the :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` option is enabled, the device ID must be provided using the :c:struct:`azure_iot_hub_config` configuration struct in a call to the :c:func:`azure_iot_hub_init` function. + If the :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` option is disabled, the device ID must be set in :file:`prj.conf`. + If the :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` option is enabled, the device ID must be provided using the :c:struct:`azure_iot_hub_config` configuration struct in a call to the :c:func:`azure_iot_hub_init` function. Building and running ******************** diff --git a/samples/nrf9160/azure_iot_hub/README.rst b/samples/nrf9160/azure_iot_hub/README.rst index e3e69e1ea57b..124c3604110c 100644 --- a/samples/nrf9160/azure_iot_hub/README.rst +++ b/samples/nrf9160/azure_iot_hub/README.rst @@ -64,17 +64,17 @@ Additional Configuration Check and configure the following library options that are used by the sample: -* :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` - Sets the Azure IoT Hub device ID. Alternatively, enable :option:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` option and set the device ID at run time in :c:struct:`azure_iot_hub_config` passed to the :c:func:`azure_iot_hub_init` function. -* :option:`CONFIG_AZURE_IOT_HUB_HOSTNAME` - Sets the Azure IoT Hub host name. If DPS is used, the sample assumes that the IoT hub host name is unknown, and the configuration is ignored. -* :option:`CONFIG_AZURE_IOT_HUB_DPS` - Enables Azure IoT Hub DPS. -* :option:`CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE` - Sets the Azure IoT Hub DPS ID scope. +* :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID` - Sets the Azure IoT Hub device ID. Alternatively, enable :kconfig:`CONFIG_AZURE_IOT_HUB_DEVICE_ID_APP` option and set the device ID at run time in :c:struct:`azure_iot_hub_config` passed to the :c:func:`azure_iot_hub_init` function. +* :kconfig:`CONFIG_AZURE_IOT_HUB_HOSTNAME` - Sets the Azure IoT Hub host name. If DPS is used, the sample assumes that the IoT hub host name is unknown, and the configuration is ignored. +* :kconfig:`CONFIG_AZURE_IOT_HUB_DPS` - Enables Azure IoT Hub DPS. +* :kconfig:`CONFIG_AZURE_IOT_HUB_DPS_ID_SCOPE` - Sets the Azure IoT Hub DPS ID scope. .. note:: - The sample sets the option :option:`CONFIG_MQTT_KEEPALIVE` to the maximum allowed value, 1767 seconds (29.45 minutes) as specified by Azure IoT Hub. + The sample sets the option :kconfig:`CONFIG_MQTT_KEEPALIVE` to the maximum allowed value, 1767 seconds (29.45 minutes) as specified by Azure IoT Hub. This is to limit the IP traffic between the device and the Azure IoT Hub message broker for supporting a low power sample. However, note that in certain LTE networks, the NAT timeout can be considerably lower than 1767 seconds. - So as a recommendation, and to prevent the likelihood of getting disconnected unexpectedly, the option :option:`CONFIG_MQTT_KEEPALIVE` must be set to the lowest of the aforementioned timeout limits (Maximum allowed MQTT keepalive and NAT timeout). + So as a recommendation, and to prevent the likelihood of getting disconnected unexpectedly, the option :kconfig:`CONFIG_MQTT_KEEPALIVE` must be set to the lowest of the aforementioned timeout limits (Maximum allowed MQTT keepalive and NAT timeout). Building and running ******************** diff --git a/samples/nrf9160/cloud_client/README.rst b/samples/nrf9160/cloud_client/README.rst index c67c1f230a68..e2f2bfa6c5f6 100644 --- a/samples/nrf9160/cloud_client/README.rst +++ b/samples/nrf9160/cloud_client/README.rst @@ -20,7 +20,7 @@ The current version of the sample supports the following libraries as cloud back * :ref:`lib_aws_iot` * :ref:`lib_azure_iot_hub` -To swap between the supported libraries, change the option :option:`CONFIG_CLOUD_BACKEND` to match the configuration string of a compatible cloud backend. +To swap between the supported libraries, change the option :kconfig:`CONFIG_CLOUD_BACKEND` to match the configuration string of a compatible cloud backend. The identification strings for the different cloud backends are listed in the following table: .. list-table:: @@ -71,10 +71,10 @@ The configurations used in the sample are listed below. They can be added to ``c To output data in the terminal window located in the `nRF Connect for Cloud`_ web interface, the data format must be in JSON format. .. note:: - The sample sets the option :option:`CONFIG_MQTT_KEEPALIVE` to the maximum allowed value that is specified by the configured cloud backend. + The sample sets the option :kconfig:`CONFIG_MQTT_KEEPALIVE` to the maximum allowed value that is specified by the configured cloud backend. This is to limit the IP traffic between the device and the message broker of the cloud provider for supporting a low power sample. However, note that in certain LTE networks, the NAT timeout can be considerably lower than the maximum allowed MQTT keepalive. - So as a recommendation, and to prevent the likelihood of getting disconnected unexpectedly, the option :option:`CONFIG_MQTT_KEEPALIVE` must be set to the lowest of the aforementioned timeout limits (Maximum allowed MQTT keepalive and NAT timeout). + So as a recommendation, and to prevent the likelihood of getting disconnected unexpectedly, the option :kconfig:`CONFIG_MQTT_KEEPALIVE` must be set to the lowest of the aforementioned timeout limits (Maximum allowed MQTT keepalive and NAT timeout). Functionality and Supported Technologies **************************************** diff --git a/samples/nrf9160/download/README.rst b/samples/nrf9160/download/README.rst index 4e86fb89ca48..e2cb20c7e822 100644 --- a/samples/nrf9160/download/README.rst +++ b/samples/nrf9160/download/README.rst @@ -26,9 +26,9 @@ Overview ******** The sample first initializes the :ref:`nrfxlib:nrf_modem` and AT communications. -Next, it provisions a certificate to the modem using the :ref:`modem_key_mgmt` library if the :option:`CONFIG_SAMPLE_SECURE_SOCKET` option is set. +Next, it provisions a certificate to the modem using the :ref:`modem_key_mgmt` library if the :kconfig:`CONFIG_SAMPLE_SECURE_SOCKET` option is set. The provisioning of the certificates must be done before connecting to the LTE network since the certificates can only be provisioned when the device is not connected. -The certificate file name and security tag can be configured via the :option:`CONFIG_SAMPLE_SEC_TAG` and the :option:`CONFIG_SAMPLE_CERT_FILE` options, respectively. +The certificate file name and security tag can be configured via the :kconfig:`CONFIG_SAMPLE_SEC_TAG` and the :kconfig:`CONFIG_SAMPLE_CERT_FILE` options, respectively. The sample then performs the following actions: @@ -40,13 +40,13 @@ The sample then performs the following actions: Downloading from a CoAP server ============================== -To enable CoAP block-wise transfer, it is necessary to enable :ref:`Zephyr's CoAP stack ` via the :option:`CONFIG_COAP` option. +To enable CoAP block-wise transfer, it is necessary to enable :ref:`Zephyr's CoAP stack ` via the :kconfig:`CONFIG_COAP` option. Using TLS and DTLS ================== -When the :option:`CONFIG_SAMPLE_SECURE_SOCKET` option is set, the sample provisions the certificate found in the :file:`samples/nrf9160/download/cert` folder. -The certificate file name is indicated by the :option:`CONFIG_SAMPLE_CERT_FILE` option. +When the :kconfig:`CONFIG_SAMPLE_SECURE_SOCKET` option is set, the sample provisions the certificate found in the :file:`samples/nrf9160/download/cert` folder. +The certificate file name is indicated by the :kconfig:`CONFIG_SAMPLE_CERT_FILE` option. This certificate will work for the default test files. If you are using a custom download test file, you have to provision the correct certificate for the servers from which the certificates will be downloaded. @@ -80,11 +80,11 @@ If enabled, this option computes the SHA256 hash of the downloaded file. .. option:: CONFIG_SAMPLE_COMPARE_HASH - Hash compare configuration -If enabled, this option compares the hash against the SHA256 hash set by :option:`CONFIG_SAMPLE_SHA256_HASH` for a match. +If enabled, this option compares the hash against the SHA256 hash set by :kconfig:`CONFIG_SAMPLE_SHA256_HASH` for a match. .. option:: CONFIG_SAMPLE_SHA256_HASH - Hash configuration -This option sets the SHA256 hash to be compared with :option:`CONFIG_SAMPLE_COMPUTE_HASH`. +This option sets the SHA256 hash to be compared with :kconfig:`CONFIG_SAMPLE_COMPUTE_HASH`. Building and running diff --git a/samples/nrf9160/lwm2m_client/README.rst b/samples/nrf9160/lwm2m_client/README.rst index 73022f098a04..97818fbae180 100644 --- a/samples/nrf9160/lwm2m_client/README.rst +++ b/samples/nrf9160/lwm2m_client/README.rst @@ -97,9 +97,9 @@ Additional configurations Check and configure the following library options that are used by the sample: -* :option:`CONFIG_LWM2M_CLIENT_UTILS` - Enables the utility library :ref:`lib_lwm2m_client_utils`, which initializes a predefined set of objects. +* :kconfig:`CONFIG_LWM2M_CLIENT_UTILS` - Enables the utility library :ref:`lib_lwm2m_client_utils`, which initializes a predefined set of objects. -* :option:`CONFIG_LWM2M_IPSO_SUPPORT` - Enables support for different IPSO objects. If you are disabling this option, you must disable all the individual configuration options that enables the sensor. +* :kconfig:`CONFIG_LWM2M_IPSO_SUPPORT` - Enables support for different IPSO objects. If you are disabling this option, you must disable all the individual configuration options that enables the sensor. Configuration files diff --git a/samples/nrf9160/memfault/README.rst b/samples/nrf9160/memfault/README.rst index bb591e0521bb..fb9d5b777239 100644 --- a/samples/nrf9160/memfault/README.rst +++ b/samples/nrf9160/memfault/README.rst @@ -43,14 +43,14 @@ There are also some metrics, which are specific to |NCS| that are enabled by def * LTE metrics: - * Enabled and disabled using :option:`CONFIG_MEMFAULT_NCS_LTE_METRICS`. + * Enabled and disabled using :kconfig:`CONFIG_MEMFAULT_NCS_LTE_METRICS`. * ``Ncs_LteTimeToConnect`` - Time from the point when the device starts to search for an LTE network until the time when it gets registered with the network. * ``Ncs_LteConnectionLossCount`` - The number of times that the device has lost the LTE network connection after the initial network registration. * Stack usage metrics: * Shows how many bytes of unused space is left in a stack. - * Configurable using :option:`CONFIG_MEMFAULT_NCS_STACK_METRICS`. + * Configurable using :kconfig:`CONFIG_MEMFAULT_NCS_STACK_METRICS`. * ``Ncs_AtCmdUnusedStack`` - The :ref:`at_cmd_readme` library's stack. * ``Ncs_ConnectionPollUnusedStack``- Stack used by the cloud libraries for :ref:`lib_nrf_cloud`, :ref:`lib_aws_iot` and :ref:`lib_azure_iot_hub`. @@ -98,7 +98,7 @@ See `Memfault SDK`_ for more information. Minimal setup ============= -To send data to the Memfault cloud, a project key must be configured using :option:`CONFIG_MEMFAULT_NCS_PROJECT_KEY`. +To send data to the Memfault cloud, a project key must be configured using :kconfig:`CONFIG_MEMFAULT_NCS_PROJECT_KEY`. .. note:: The Memfault SDK requires certificates required for the HTTPS transport. @@ -116,25 +116,25 @@ There are two sources for Kconfig options when using Memfault SDK in |NCS|: Check and configure the following options in Memfault SDK that are used by the sample: -* :option:`CONFIG_MEMFAULT` -* :option:`CONFIG_MEMFAULT_ROOT_CERT_STORAGE_NRF9160_MODEM` -* :option:`CONFIG_MEMFAULT_SHELL` -* :option:`CONFIG_MEMFAULT_HTTP_ENABLE` -* :option:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD` -* :option:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD_INTERVAL_SECS` -* :option:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD_USE_DEDICATED_WORKQUEUE` -* :option:`CONFIG_MEMFAULT_COREDUMP_COLLECT_BSS_REGIONS` +* :kconfig:`CONFIG_MEMFAULT` +* :kconfig:`CONFIG_MEMFAULT_ROOT_CERT_STORAGE_NRF9160_MODEM` +* :kconfig:`CONFIG_MEMFAULT_SHELL` +* :kconfig:`CONFIG_MEMFAULT_HTTP_ENABLE` +* :kconfig:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD` +* :kconfig:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD_INTERVAL_SECS` +* :kconfig:`CONFIG_MEMFAULT_HTTP_PERIODIC_UPLOAD_USE_DEDICATED_WORKQUEUE` +* :kconfig:`CONFIG_MEMFAULT_COREDUMP_COLLECT_BSS_REGIONS` -If :option:`CONFIG_MEMFAULT_ROOT_CERT_STORAGE_NRF9160_MODEM` is enabled, TLS certificates used for HTTP uploads are provisioned to the nRF9160 modem when :c:func:`memfault_zephyr_port_install_root_certs` is called. +If :kconfig:`CONFIG_MEMFAULT_ROOT_CERT_STORAGE_NRF9160_MODEM` is enabled, TLS certificates used for HTTP uploads are provisioned to the nRF9160 modem when :c:func:`memfault_zephyr_port_install_root_certs` is called. Check and configure the following options for Memfault that are specific to |NCS|: -* :option:`CONFIG_MEMFAULT_NCS_PROJECT_KEY` -* :option:`CONFIG_MEMFAULT_NCS_LTE_METRICS` -* :option:`CONFIG_MEMFAULT_NCS_STACK_METRICS` -* :option:`CONFIG_MEMFAULT_NCS_INTERNAL_FLASH_BACKED_COREDUMP` +* :kconfig:`CONFIG_MEMFAULT_NCS_PROJECT_KEY` +* :kconfig:`CONFIG_MEMFAULT_NCS_LTE_METRICS` +* :kconfig:`CONFIG_MEMFAULT_NCS_STACK_METRICS` +* :kconfig:`CONFIG_MEMFAULT_NCS_INTERNAL_FLASH_BACKED_COREDUMP` -If :option:`CONFIG_MEMFAULT_NCS_INTERNAL_FLASH_BACKED_COREDUMP` is enabled, :option:`CONFIG_PM_PARTITION_SIZE_MEMFAULT_STORAGE` can be used to set the flash partition size for the flash storage. +If :kconfig:`CONFIG_MEMFAULT_NCS_INTERNAL_FLASH_BACKED_COREDUMP` is enabled, :kconfig:`CONFIG_PM_PARTITION_SIZE_MEMFAULT_STORAGE` can be used to set the flash partition size for the flash storage. Configuration files diff --git a/samples/nrf9160/mqtt_simple/README.rst b/samples/nrf9160/mqtt_simple/README.rst index 7aea2f370227..3e219244422f 100644 --- a/samples/nrf9160/mqtt_simple/README.rst +++ b/samples/nrf9160/mqtt_simple/README.rst @@ -123,10 +123,10 @@ Testing #. Observe that the sample displays the following information in the terminal:: The MQTT simple sample started -#. Observe that the development kit connects to the configured MQTT broker (:option:`CONFIG_MQTT_BROKER_HOSTNAME`) after it gets the LTE connection. - At this stage, the development kit is ready to echo the data sent to it on the configured subscribe topic (:option:`CONFIG_MQTT_SUB_TOPIC`). +#. Observe that the development kit connects to the configured MQTT broker (:kconfig:`CONFIG_MQTT_BROKER_HOSTNAME`) after it gets the LTE connection. + At this stage, the development kit is ready to echo the data sent to it on the configured subscribe topic (:kconfig:`CONFIG_MQTT_SUB_TOPIC`). #. Use an MQTT client like `Mosquitto`_ to subscribe to and publish data to the broker. - Observe that the development kit publishes all the data that you publish to :option:`CONFIG_MQTT_SUB_TOPIC` on :option:`CONFIG_MQTT_PUB_TOPIC`. + Observe that the development kit publishes all the data that you publish to :kconfig:`CONFIG_MQTT_SUB_TOPIC` on :kconfig:`CONFIG_MQTT_PUB_TOPIC`. Sample output ============= @@ -154,10 +154,10 @@ Troubleshooting =============== Public MQTT brokers might be unstable. -If you experience problems connecting to the MQTT broker, try switching to another MQTT broker by changing the value of the :option:`CONFIG_MQTT_BROKER_HOSTNAME` configuration option. +If you experience problems connecting to the MQTT broker, try switching to another MQTT broker by changing the value of the :kconfig:`CONFIG_MQTT_BROKER_HOSTNAME` configuration option. .. note:: - If the :option:`CONFIG_MQTT_BROKER_HOSTNAME` configuration option is changed and the overlay TLS configuration is used, the included CA certificate must be updated with the CA certificate for + If the :kconfig:`CONFIG_MQTT_BROKER_HOSTNAME` configuration option is changed and the overlay TLS configuration is used, the included CA certificate must be updated with the CA certificate for the newly configurated MQTT broker. diff --git a/samples/nrf9160/multicell_location/README.rst b/samples/nrf9160/multicell_location/README.rst index a5ad6d2c2e11..08ce07408e2d 100644 --- a/samples/nrf9160/multicell_location/README.rst +++ b/samples/nrf9160/multicell_location/README.rst @@ -109,15 +109,15 @@ Additional configuration Check and configure the following library options that are used by the sample: -* :option:`CONFIG_MULTICELL_LOCATION_SERVICE_NRF_CLOUD` -* :option:`CONFIG_MULTICELL_LOCATION_SERVICE_HERE` -* :option:`CONFIG_MULTICELL_LOCATION_SERVICE_SKYHOOK` +* :kconfig:`CONFIG_MULTICELL_LOCATION_SERVICE_NRF_CLOUD` +* :kconfig:`CONFIG_MULTICELL_LOCATION_SERVICE_HERE` +* :kconfig:`CONFIG_MULTICELL_LOCATION_SERVICE_SKYHOOK` For the location service that is used, the authorization method can be set with one of the following options: -* :option:`CONFIG_MULTICELL_LOCATION_NRF_CLOUD_API_KEY` -* :option:`CONFIG_MULTICELL_LOCATION_HERE_API_KEY` -* :option:`CONFIG_MULTICELL_LOCATION_SKYHOOK_API_KEY` +* :kconfig:`CONFIG_MULTICELL_LOCATION_NRF_CLOUD_API_KEY` +* :kconfig:`CONFIG_MULTICELL_LOCATION_HERE_API_KEY` +* :kconfig:`CONFIG_MULTICELL_LOCATION_SKYHOOK_API_KEY` See :ref:`lib_multicell_location` for more information on the various configuration options that exist for the services. diff --git a/samples/nrf9160/sms/README.rst b/samples/nrf9160/sms/README.rst index 9844fd4948b2..c94e45beb547 100644 --- a/samples/nrf9160/sms/README.rst +++ b/samples/nrf9160/sms/README.rst @@ -19,7 +19,7 @@ The sample requires an LTE connection. When the sample starts, it sends SMS if a recipient phone number is set in the configuration. The sample then receives all the SMS messages and displays the information about the messages including the text that is sent. -The maximum size of the AT command response defined by :option:`CONFIG_AT_CMD_RESPONSE_MAX_LEN` might limit the size of the SMS message that can be received. +The maximum size of the AT command response defined by :kconfig:`CONFIG_AT_CMD_RESPONSE_MAX_LEN` might limit the size of the SMS message that can be received. This parameter is defined in the :ref:`at_cmd_readme` module. Values over 512 bytes will not restrict the size of the received message as the maximum data length of the SMS is 140 bytes. @@ -52,17 +52,17 @@ Additional Configuration Check and configure the following mandatory library options that are used by the sample: -* :option:`CONFIG_SMS` -* :option:`CONFIG_NRF_MODEM_LIB` +* :kconfig:`CONFIG_SMS` +* :kconfig:`CONFIG_NRF_MODEM_LIB` Check and configure the following optional library options that are used by the sample: -* :option:`CONFIG_SMS_SUBSCRIBERS_MAX_CNT` -* :option:`CONFIG_AT_CMD_RESPONSE_MAX_LEN` -* :option:`CONFIG_LTE_AUTO_INIT_AND_CONNECT` -* :option:`CONFIG_LOG` -* :option:`CONFIG_ASSERT` -* :option:`CONFIG_ASSERT_VERBOSE` +* :kconfig:`CONFIG_SMS_SUBSCRIBERS_MAX_CNT` +* :kconfig:`CONFIG_AT_CMD_RESPONSE_MAX_LEN` +* :kconfig:`CONFIG_LTE_AUTO_INIT_AND_CONNECT` +* :kconfig:`CONFIG_LOG` +* :kconfig:`CONFIG_ASSERT` +* :kconfig:`CONFIG_ASSERT_VERBOSE` Building and running ******************** diff --git a/samples/nrf9160/udp/README.rst b/samples/nrf9160/udp/README.rst index 43af887d2c7e..0107dcdf6173 100644 --- a/samples/nrf9160/udp/README.rst +++ b/samples/nrf9160/udp/README.rst @@ -53,13 +53,13 @@ Configuration You can configure the following options: -* :option:`CONFIG_UDP_DATA_UPLOAD_SIZE_BYTES` -* :option:`CONFIG_UDP_DATA_UPLOAD_FREQUENCY_SECONDS` -* :option:`CONFIG_UDP_SERVER_ADDRESS_STATIC` -* :option:`CONFIG_UDP_SERVER_PORT` -* :option:`CONFIG_UDP_PSM_ENABLE` -* :option:`CONFIG_UDP_EDRX_ENABLE` -* :option:`CONFIG_UDP_RAI_ENABLE` +* :kconfig:`CONFIG_UDP_DATA_UPLOAD_SIZE_BYTES` +* :kconfig:`CONFIG_UDP_DATA_UPLOAD_FREQUENCY_SECONDS` +* :kconfig:`CONFIG_UDP_SERVER_ADDRESS_STATIC` +* :kconfig:`CONFIG_UDP_SERVER_PORT` +* :kconfig:`CONFIG_UDP_PSM_ENABLE` +* :kconfig:`CONFIG_UDP_EDRX_ENABLE` +* :kconfig:`CONFIG_UDP_RAI_ENABLE` Configuration options @@ -102,11 +102,11 @@ Additional configuration Below configurations are recommended for low power behavior: - * :option:`CONFIG_LTE_PSM_REQ_RPTAU` option set to a value greater than the value of :option:`CONFIG_UDP_DATA_UPLOAD_FREQUENCY_SECONDS`. - * :option:`CONFIG_LTE_PSM_REQ_RAT` set to 0. - * :option:`CONFIG_SERIAL` disabled in ``prj.conf`` and ``spm.conf``. - * :option:`CONFIG_UDP_EDRX_ENABLE` set to false. - * :option:`CONFIG_UDP_RAI_ENABLE` set to true for NB-IoT. It is not supported for LTE-M. + * :kconfig:`CONFIG_LTE_PSM_REQ_RPTAU` option set to a value greater than the value of :kconfig:`CONFIG_UDP_DATA_UPLOAD_FREQUENCY_SECONDS`. + * :kconfig:`CONFIG_LTE_PSM_REQ_RAT` set to 0. + * :kconfig:`CONFIG_SERIAL` disabled in ``prj.conf`` and ``spm.conf``. + * :kconfig:`CONFIG_UDP_EDRX_ENABLE` set to false. + * :kconfig:`CONFIG_UDP_RAI_ENABLE` set to true for NB-IoT. It is not supported for LTE-M. PSM and eDRX timers are set with binary strings that signify a time duration in seconds. See `Power saving mode setting section in AT commands reference document`_ for a conversion chart of these timer values. @@ -146,7 +146,7 @@ After programming the sample to your device, test it by performing the following .. note:: Logging output is disabled by default in this sample in order to produce the lowest possible amount of current consumption. - To enable logging, set the :option:`CONFIG_SERIAL` option in the ``prj.conf`` and ``spm.conf`` configuration files. + To enable logging, set the :kconfig:`CONFIG_SERIAL` option in the ``prj.conf`` and ``spm.conf`` configuration files. .. _uart_output: diff --git a/samples/openthread/cli/README.rst b/samples/openthread/cli/README.rst index 146c84607d0f..804e41f303d7 100644 --- a/samples/openthread/cli/README.rst +++ b/samples/openthread/cli/README.rst @@ -21,7 +21,7 @@ OpenThread CLI is integrated into the system shell accessible over serial connec To indicate a Thread command, the ``ot`` keyword needs to precede the command. The amount of commands you can test depends on the application configuration. -The CLI sample comes with the :ref:`full set of OpenThread functionalities ` enabled (:option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER`). +The CLI sample comes with the :ref:`full set of OpenThread functionalities ` enabled (:kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER`). If used alone, the sample allows you to test the network status. It is recommended to use at least two development kits running the same sample to be able to test communication. @@ -31,13 +31,13 @@ It is recommended to use at least two development kits running the same sample t Diagnostic module ================= -By default, the CLI sample comes with the :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER` :ref:`feature set ` enabled, which allows you to use Zephyr's diagnostic module with its ``diag`` commands. +By default, the CLI sample comes with the :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER` :ref:`feature set ` enabled, which allows you to use Zephyr's diagnostic module with its ``diag`` commands. Use these commands for manually checking hardware-related functionalities without running a Thread network. For example, when adding a new functionality or during the manufacturing process to ensure radio communication is working. See `Testing diagnostic module`_ section for an example. .. note:: - If you disable the :option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER` feature set, you can enable the diagnostic module with the :option:`CONFIG_OPENTHREAD_DIAG` Kconfig option. + If you disable the :kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER` feature set, you can enable the diagnostic module with the :kconfig:`CONFIG_OPENTHREAD_DIAG` Kconfig option. .. _ot_cli_sample_thread_v12: diff --git a/samples/openthread/coprocessor/README.rst b/samples/openthread/coprocessor/README.rst index f6e4959437c2..1e4f98c3cec3 100644 --- a/samples/openthread/coprocessor/README.rst +++ b/samples/openthread/coprocessor/README.rst @@ -28,7 +28,7 @@ The sample demonstrates using a co-processor target on the MCU to communicate wi According to the co-processor architecture, the MCU part must cooperate with user higher layer process to establish the complete full stack application. The sample shows how to set up the connection between the co-processor and wpantund. -This sample comes with the :ref:`full set of OpenThread functionalities ` enabled (:option:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER`). +This sample comes with the :ref:`full set of OpenThread functionalities ` enabled (:kconfig:`CONFIG_OPENTHREAD_NORDIC_LIBRARY_MASTER`). .. _ot_coprocessor_sample_vendor_hook_extension: @@ -48,7 +48,7 @@ Logging extension This sample by default uses :ref:`Spinel logging backend `, which allows sending log messages to the host device using the Spinel protocol. This feature is very useful, because it does not require having separate interfaces to communicate with the co-processor through the Spinel protocol and collect log messages. -Moreover, selecting the Spinel logging backend (by setting :option:`CONFIG_LOG_BACKEND_SPINEL`) does not exclude using another backend like UART or RTT at the same time. +Moreover, selecting the Spinel logging backend (by setting :kconfig:`CONFIG_LOG_BACKEND_SPINEL`) does not exclude using another backend like UART or RTT at the same time. By default, the log levels for all modules are set to critical to not engage the microprocessor in unnecessary activities. To make the solution flexible, you can change independently the log levels for your modules, for the whole Zephyr system, and for OpenThread. @@ -82,7 +82,7 @@ User interface All the interactions with the application are handled using serial communication. You can interact with the sample through :ref:`ug_thread_tools_wpantund`, using ``wpanctl`` commands. -If you use the RCP architecture (see :option:`CONFIG_OPENTHREAD_COPROCESSOR_RCP`), you can alternatively use ``ot-daemon`` or ``ot-cli`` with commands listed in `OpenThread CLI Reference`_. +If you use the RCP architecture (see :kconfig:`CONFIG_OPENTHREAD_COPROCESSOR_RCP`), you can alternatively use ``ot-daemon`` or ``ot-cli`` with commands listed in `OpenThread CLI Reference`_. See :ref:`ug_thread_tools_ot_apps` for more information. Both NCP and RCP support communication with the kit using `Pyspinel`_ commands. @@ -100,9 +100,9 @@ Configuration Check and configure the following library options that are used by the sample: -* :option:`CONFIG_OPENTHREAD_COPROCESSOR_NCP` - Selects the NCP architecture for the sample. +* :kconfig:`CONFIG_OPENTHREAD_COPROCESSOR_NCP` - Selects the NCP architecture for the sample. This is the default. -* :option:`CONFIG_OPENTHREAD_COPROCESSOR_RCP` - Selects the RCP architecture for the sample. +* :kconfig:`CONFIG_OPENTHREAD_COPROCESSOR_RCP` - Selects the RCP architecture for the sample. .. _ot_coprocessor_sample_config_files: diff --git a/samples/peripheral/radio_test/README.rst b/samples/peripheral/radio_test/README.rst index 0decdbc891c1..4b149e930cde 100644 --- a/samples/peripheral/radio_test/README.rst +++ b/samples/peripheral/radio_test/README.rst @@ -138,7 +138,7 @@ Building and running However, you must still program the application core to boot up the network core. You can use any sample for this, for example :ref:`nrf5340_empty_app_core`. The :ref:`nrf5340_empty_app_core` is built and programmed automatically by default. - If you want to program another sample for the application core, unset the :option:'CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE' option. + If you want to program another sample for the application core, unset the :kconfig:'CONFIG_NCS_SAMPLE_EMPTY_APP_CORE_CHILD_IMAGE' option. .. _radio_test_testing: diff --git a/samples/zigbee/ncp/README.rst b/samples/zigbee/ncp/README.rst index 97c8107deaa1..4407b132df39 100644 --- a/samples/zigbee/ncp/README.rst +++ b/samples/zigbee/ncp/README.rst @@ -50,7 +50,7 @@ Overview The sample demonstrates using a Nordic Semiconductor's Development Kit as Zigbee Network Co-Processor. -The sample uses the :option:`CONFIG_ZIGBEE_LIBRARY_NCP_DEV` Kconfig option, which is available as part of the :ref:`nrfxlib:zboss_configuration`. +The sample uses the :kconfig:`CONFIG_ZIGBEE_LIBRARY_NCP_DEV` Kconfig option, which is available as part of the :ref:`nrfxlib:zboss_configuration`. The NCP Kconfig option extends the compilation process with an implementation of the ZBOSS API serialization through NCP commands. It also implements the ZBOSS default signal handler function, which controls the ZBOSS and commissioning logic. @@ -70,7 +70,7 @@ Serial communication setup ========================== The communication channel uses Zephyr's :ref:`zephyr:uart_api` API. -This serial device is selected with :option:`CONFIG_ZIGBEE_UART_DEVICE_NAME`. +This serial device is selected with :kconfig:`CONFIG_ZIGBEE_UART_DEVICE_NAME`. By default, the NCP sample communicates through the UART serialization (``UART0``). As a result, Zephyr's logger is configured to use ``UART1``, which is available through GPIO pins (**P1.00** and **P1.01**). @@ -112,7 +112,7 @@ MCUboot When the `Communication through USB`_ is selected, MCUboot in this sample is built with support for single application slot, and uses the USB DFU class driver to allow uploading image over USB. -If you want to use the default UART serial communication channel, you can enable MCUboot by setting the :option:`CONFIG_BOOTLOADER_MCUBOOT` Kconfig option. +If you want to use the default UART serial communication channel, you can enable MCUboot by setting the :kconfig:`CONFIG_BOOTLOADER_MCUBOOT` Kconfig option. To use the same MCUboot configuration as in `Communication through USB`_, you need to provide MCUboot with the Kconfig options included in the :file:`child_image/mcuboot_usb.conf` file. See :ref:`ug_multi_image_variables` for how to set the required options. diff --git a/scripts/partition_manager/partition_manager.rst b/scripts/partition_manager/partition_manager.rst index eee9f76795f9..d04824c29f9d 100644 --- a/scripts/partition_manager/partition_manager.rst +++ b/scripts/partition_manager/partition_manager.rst @@ -100,7 +100,7 @@ In particular, partition definitions are global per domain, and must be identica If the same partition is defined twice with different configurations within a domain, the Partition Manager will fail. .. note:: - If Partition Manager configurations are only defined by subsystems, so that only one image is included in the build, you must set the option :option:`CONFIG_PM_SINGLE_IMAGE` to execute the Partition Manager script. + If Partition Manager configurations are only defined by subsystems, so that only one image is included in the build, you must set the option :kconfig:`CONFIG_PM_SINGLE_IMAGE` to execute the Partition Manager script. .. _pm_yaml_format: @@ -500,10 +500,10 @@ External flash regions always use the start_to_end placement strategy. To use external flash, you must provide information about the device to the Partition Manager through these Kconfig options: -* :option:`CONFIG_PM_EXTERNAL_FLASH` - enable external flash -* :option:`CONFIG_PM_EXTERNAL_FLASH_DEV_NAME` - specify the name of the flash device -* :option:`CONFIG_PM_EXTERNAL_FLASH_BASE` - specify the base address -* :option:`CONFIG_PM_EXTERNAL_FLASH_SIZE` - specify the available flash size (from the base address) +* :kconfig:`CONFIG_PM_EXTERNAL_FLASH` - enable external flash +* :kconfig:`CONFIG_PM_EXTERNAL_FLASH_DEV_NAME` - specify the name of the flash device +* :kconfig:`CONFIG_PM_EXTERNAL_FLASH_BASE` - specify the base address +* :kconfig:`CONFIG_PM_EXTERNAL_FLASH_SIZE` - specify the available flash size (from the base address) The following example assumes that the flash device has been initialized as follows in the flash driver: diff --git a/tests/crypto/README.rst b/tests/crypto/README.rst index 58a15fb02045..0978bd93dd85 100644 --- a/tests/crypto/README.rst +++ b/tests/crypto/README.rst @@ -19,7 +19,7 @@ See :ref:`crypto_test_ztest_custom` for details. The tests are executed if the cryptographic functionality is enabled in Kconfig. Make sure to configure :ref:`nrfxlib:nrf_security` and all available hardware or software backends to enable the tests. -See :option:`CONFIG_NORDIC_SECURITY_BACKEND`. +See :kconfig:`CONFIG_NORDIC_SECURITY_BACKEND`. +--------------------+-------------+----------------------------------------------------------------------------+----------------------------------------------------------------------------+ | Cryptographic mode | Sub-mode | Link to standard | Test Vector Source | @@ -158,9 +158,9 @@ Ztest custom log formatting =========================== Cryptography tests replace the standard Ztest formatting to assure more efficient reporting of running tests and test results. -Set the configuration option :option:`CONFIG_ZTEST_TC_UTIL_USER_OVERRIDE` to replace the Ztest macros ``TC_START`` and ``Z_TC_END_RESULT`` with versions more suited for reporting results of cryptographic tests. +Set the configuration option :kconfig:`CONFIG_ZTEST_TC_UTIL_USER_OVERRIDE` to replace the Ztest macros ``TC_START`` and ``Z_TC_END_RESULT`` with versions more suited for reporting results of cryptographic tests. -:option:`CONFIG_ZTEST_TC_UTIL_USER_OVERRIDE` uses :file:`tests/crypto/include_override/tc_util_user_override.h` to define the custom formatting. +:kconfig:`CONFIG_ZTEST_TC_UTIL_USER_OVERRIDE` uses :file:`tests/crypto/include_override/tc_util_user_override.h` to define the custom formatting. .. _crypto_test_testing: From 10f85a1082a372d387dbcfaceea196e690553314 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20=C3=98ye=20Amundsen?= Date: Mon, 9 Aug 2021 09:59:21 +0200 Subject: [PATCH 107/126] modules: tfm: pass ZEPHYR_BASE to TF-M build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We use this variable downstream when passing our out of tree platform to the TF-M build system. Ref: NCSDK-10706 Signed-off-by: Håkon Øye Amundsen --- modules/tfm/zephyr/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/tfm/zephyr/CMakeLists.txt b/modules/tfm/zephyr/CMakeLists.txt index 58810ce5df3e..67b2ce1a172a 100644 --- a/modules/tfm/zephyr/CMakeLists.txt +++ b/modules/tfm/zephyr/CMakeLists.txt @@ -38,6 +38,10 @@ set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS -DNRF_DIR=${ZEPHYR_NRF_MODULE_DIR} ) +set_property(TARGET zephyr_property_target + APPEND PROPERTY TFM_CMAKE_OPTIONS -DZEPHYR_BASE=${ZEPHYR_BASE} + ) + if (CONFIG_TFM_MINIMAL) set_property(TARGET zephyr_property_target APPEND PROPERTY TFM_CMAKE_OPTIONS From de7e9c1990eb45550dec0af8eece796fd74fd9f9 Mon Sep 17 00:00:00 2001 From: Emil Obalski Date: Mon, 9 Aug 2021 15:37:58 +0200 Subject: [PATCH 108/126] caf: Update leds module Use DT_DEVICE_GET to bind proper device instead of runtime device_get_binding(). This patch fix issue, when non existing device was tried to bind at caf leds initialization. Unnecessary code was removed. Jira: NCSDK-10317 Signed-off-by: Emil Obalski --- subsys/caf/modules/leds.c | 37 +++++-------------------------------- 1 file changed, 5 insertions(+), 32 deletions(-) diff --git a/subsys/caf/modules/leds.c b/subsys/caf/modules/leds.c index c135d6a814b7..52f8b3604108 100644 --- a/subsys/caf/modules/leds.c +++ b/subsys/caf/modules/leds.c @@ -20,7 +20,6 @@ LOG_MODULE_REGISTER(MODULE, CONFIG_CAF_LEDS_LOG_LEVEL); #define LED_ID(led) ((led) - &leds[0]) struct led { - const char *label; const struct device *dev; uint8_t color_count; @@ -34,15 +33,13 @@ struct led { #ifdef CONFIG_CAF_LEDS_PWM #define DT_DRV_COMPAT pwm_leds - #define DEFAULT_LABEL(id) STRINGIFY(_CONCAT(LED_PWM_, id)) #elif defined(CONFIG_CAF_LEDS_GPIO) #define DT_DRV_COMPAT gpio_leds - #define DEFAULT_LABEL(id) "leds" #else #error "LED driver must be specified in configuration" #endif -#define _LED_COLOR_ID(id) 0, +#define _LED_COLOR_ID(_unused) 0, #define _LED_COLOR_COUNT(id) \ static const uint8_t led_colors_##id[] = { \ @@ -53,7 +50,7 @@ DT_INST_FOREACH_STATUS_OKAY(_LED_COLOR_COUNT) #define _LED_INSTANCE_DEF(id) \ { \ - .label = DT_INST_PROP_OR(id, label, DEFAULT_LABEL(id)), \ + .dev = DEVICE_DT_GET(DT_DRV_INST(id)), \ .color_count = ARRAY_SIZE(led_colors_##id), \ }, @@ -177,44 +174,20 @@ static void led_update(struct led *led) } } -static void verify_labels(void) -{ - /* Zephyr boards by default define "gpio_leds" compatible DT node called "leds". CAF LEDs - * uses "leds" as a default name to get the related GPIO LED driver binding. In that case - * only one CAF led instance can use the default driver device name. Using the same driver - * device name by multiple instances would result in referring to improper driver device. - */ - if (IS_ENABLED(CONFIG_ASSERT) && IS_ENABLED(CONFIG_CAF_LEDS_GPIO)) { - size_t default_label_cnt = 0; - - for (size_t i = 0; i < ARRAY_SIZE(leds); i++) { - if (!strcmp(leds[i].label, DEFAULT_LABEL(0))) { - default_label_cnt++; - } - } - - __ASSERT_NO_MSG(default_label_cnt <= 1); - } -} - static int leds_init(void) { int err = 0; BUILD_ASSERT(DT_HAS_COMPAT_STATUS_OKAY(DT_DRV_COMPAT) > 0, "No LEDs defined"); - verify_labels(); - for (size_t i = 0; (i < ARRAY_SIZE(leds)) && !err; i++) { struct led *led = &leds[i]; __ASSERT_NO_MSG((led->color_count == 1) || (led->color_count == 3)); - led->dev = device_get_binding(led->label); - - if (!led->dev) { - LOG_ERR("Cannot bind %s", led->label); - err = -ENXIO; + if (!device_is_ready(led->dev)) { + LOG_ERR("Device %s is not ready", led->dev->name); + err = -ENODEV; } else { k_work_init_delayable(&led->work, work_handler); led_update(led); From 09fdeac839c6ae07b7407585477b13c6fddb9545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=AD=20Bol=C3=ADvar?= Date: Mon, 9 Aug 2021 13:39:23 -0700 Subject: [PATCH 109/126] CODEOWNERS: fix scripts/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use my current handle. Signed-off-by: Martí Bolívar --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 621fd30a3ee4..32290e3540c2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -121,7 +121,7 @@ Kconfig* @tejlmand /samples/CMakeLists.txt @tejlmand /samples/nrf5340/netboot/ @hakonfam /samples/nrf5340/multiprotocol_rpmsg/ @hubertmis -/scripts/ @mbolivar @tejlmand +/scripts/ @mbolivar-nordic @tejlmand /scripts/hid_configurator/ @pdunaj /scripts/tools-versions-*.txt @tejlmand @asle-nordic @grho @shanta-14 /share/zephyrbuild-package/ @tejlmand From 63cf819fc794300ae82653eb5ac2efc816ec6229 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20=C3=98ye=20Amundsen?= Date: Tue, 10 Aug 2021 12:09:25 +0200 Subject: [PATCH 110/126] modules: mbedtls: increase the heap size if building with TFM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For TF-M to work as expected we need to increase the size of the mbedtls heap. We do this in this file to ensure that the default gets priority in Kconfig. Ref: NCSDK-10020 Signed-off-by: Håkon Øye Amundsen Signed-off-by: Martí Bolívar --- modules/Kconfig | 3 ++- modules/mbedtls/Kconfig | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 modules/mbedtls/Kconfig diff --git a/modules/Kconfig b/modules/Kconfig index 79b6ebd9984d..bc3470ced166 100644 --- a/modules/Kconfig +++ b/modules/Kconfig @@ -5,6 +5,7 @@ # rsource "Kconfig.mcuboot" -rsource "tfm/zephyr/Kconfig" rsource "cddl-gen/Kconfig" +rsource "mbedtls/Kconfig" rsource "memfault/Kconfig" +rsource "tfm/zephyr/Kconfig" diff --git a/modules/mbedtls/Kconfig b/modules/mbedtls/Kconfig new file mode 100644 index 000000000000..6383b9e4ce34 --- /dev/null +++ b/modules/mbedtls/Kconfig @@ -0,0 +1,9 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Increase the heap size of mbedtls when building with TF-M. +config MBEDTLS_HEAP_SIZE + default 8320 if BUILD_WITH_TFM From ef0a7e09979314d75ef9f512a2ea5be0eab56a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5vard=20Vermeer?= Date: Fri, 13 Aug 2021 13:15:04 +0200 Subject: [PATCH 111/126] pm: adapt nrf9160 application and samples to new API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Device Power Management API has changed. Requires pm_device_state enum for set and get. Arguments removed from pm_device_state_set. Signed-off-by: Håvard Vermeer --- applications/serial_lte_modem/src/slm_at_host.c | 2 +- samples/nrf9160/modem_shell/src/uart/uart.c | 2 +- .../nrf9160/modem_shell/src/uart/uart_shell.c | 16 +++++----------- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/applications/serial_lte_modem/src/slm_at_host.c b/applications/serial_lte_modem/src/slm_at_host.c index 97f658aff189..f16a54176841 100644 --- a/applications/serial_lte_modem/src/slm_at_host.c +++ b/applications/serial_lte_modem/src/slm_at_host.c @@ -208,7 +208,7 @@ int poweroff_uart(void) int poweron_uart(void) { int err; - uint32_t current_state = 0; + enum pm_device_state current_state = PM_DEVICE_STATE_ACTIVE; err = pm_device_state_get(uart_dev, ¤t_state); if (err) { diff --git a/samples/nrf9160/modem_shell/src/uart/uart.c b/samples/nrf9160/modem_shell/src/uart/uart.c index 5b82fd9da27c..a723efe46650 100644 --- a/samples/nrf9160/modem_shell/src/uart/uart.c +++ b/samples/nrf9160/modem_shell/src/uart/uart.c @@ -28,7 +28,7 @@ void disable_uarts(void) void enable_uarts(void) { const struct device *uart_dev; - uint32_t current_state; + enum pm_device_state current_state; uart_dev = device_get_binding(DT_LABEL(DT_NODELABEL(uart0))); diff --git a/samples/nrf9160/modem_shell/src/uart/uart_shell.c b/samples/nrf9160/modem_shell/src/uart/uart_shell.c index ad4148b0bd4b..e713b008f652 100644 --- a/samples/nrf9160/modem_shell/src/uart/uart_shell.c +++ b/samples/nrf9160/modem_shell/src/uart/uart_shell.c @@ -79,7 +79,7 @@ void uart_toggle_power_state_at_event(const struct shell *shell, const struct lt void uart_toggle_power_state(const struct shell *shell) { const struct device *uart_dev; - uint32_t uart0_power_state; + enum pm_device_state uart0_power_state; int err; uart_dev = device_get_binding(DT_LABEL(DT_NODELABEL(uart0))); @@ -99,27 +99,21 @@ void uart_toggle_power_state(const struct shell *shell) k_sleep(K_MSEC(500)); /* set uart0 to low power state */ - err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_LOW_POWER, NULL, NULL); + err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_LOW_POWER); /* set uart1 to low power state */ uart_dev = device_get_binding(DT_LABEL(DT_NODELABEL(uart1))); if (uart_dev) { - pm_device_state_set(uart_dev, - PM_DEVICE_STATE_LOW_POWER, - NULL, - NULL); + pm_device_state_set(uart_dev, PM_DEVICE_STATE_LOW_POWER); } } else { /* set uart0 to active state */ - err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE, NULL, NULL); + err = pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE); /* set uart1 to active state */ uart_dev = device_get_binding(DT_LABEL(DT_NODELABEL(uart1))); if (uart_dev) { - pm_device_state_set(uart_dev, - PM_DEVICE_STATE_ACTIVE, - NULL, - NULL); + pm_device_state_set(uart_dev, PM_DEVICE_STATE_ACTIVE); } shell_print(shell, "Enabling UARTs"); From 645896964cd8b1c020ebaa4a4a418168588c5665 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Magne=20V=C3=A6rnes?= Date: Tue, 17 Aug 2021 08:37:30 +0200 Subject: [PATCH 112/126] samples: crypto: Reduced mbed TLS heap size configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [this line added by Martí to appease compliance] Signed-off-by: Magne Værnes Signed-off-by: Martí Bolívar --- samples/crypto/psa_tls/prj.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/crypto/psa_tls/prj.conf b/samples/crypto/psa_tls/prj.conf index f09b73330ad0..3069de749549 100644 --- a/samples/crypto/psa_tls/prj.conf +++ b/samples/crypto/psa_tls/prj.conf @@ -50,7 +50,7 @@ CONFIG_MBEDTLS_PK_C=y CONFIG_MBEDTLS_RSA_C=y CONFIG_MBEDTLS_PKCS1_V15=y CONFIG_MBEDTLS_ENABLE_HEAP=y -CONFIG_MBEDTLS_HEAP_SIZE=65536 +CONFIG_MBEDTLS_HEAP_SIZE=56000 CONFIG_MBEDTLS_TLS_LIBRARY=y CONFIG_MBEDTLS_X509_LIBRARY=y CONFIG_NRF_SECURITY_ADVANCED=y From 1e5bec7b23a9e6c3f81fa01051b7977841924927 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Piotr=20S=C5=82aw=C4=99cki?= Date: Tue, 17 Aug 2021 11:30:51 +0200 Subject: [PATCH 113/126] samples: peripheral: 802154_phy_test: RadioDriver compatibility fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Updated the sample to be compatible with new API function declarations. Signed-off-by: Piotr Sławęcki --- .../peripheral/802154_phy_test/src/rf_proc.c | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/samples/peripheral/802154_phy_test/src/rf_proc.c b/samples/peripheral/802154_phy_test/src/rf_proc.c index b9a3fc6aa64f..783f1491923e 100644 --- a/samples/peripheral/802154_phy_test/src/rf_proc.c +++ b/samples/peripheral/802154_phy_test/src/rf_proc.c @@ -200,18 +200,19 @@ void nrf_802154_receive_failed(nrf_802154_rx_error_t error, uint32_t id) k_work_submit(&rf_rx_failed_info.work); } -void nrf_802154_transmitted_raw(const uint8_t *frame, uint8_t *ack, int8_t power, uint8_t lqi) +void nrf_802154_transmitted_raw(uint8_t *frame, + const nrf_802154_transmit_done_metadata_t *metadata) { ARG_UNUSED(frame); - if (ack != NULL) { + if (metadata->data.transmitted.p_ack != NULL) { ack_packet = (struct rf_rx_pkt_s){ 0 }; - ack_packet.data = &ack[1]; - ack_packet.length = ack[0]; - ack_packet.rssi = power; - ack_packet.lqi = lqi; - ack_packet.rf_buf = ack; + ack_packet.data = metadata->data.transmitted.p_ack; + ack_packet.length = metadata->data.transmitted.length; + ack_packet.rssi = metadata->data.transmitted.power; + ack_packet.lqi = metadata->data.transmitted.lqi; + ack_packet.rf_buf = metadata->data.transmitted.p_ack; k_work_submit(&rf_tx_ack_received_wq); } @@ -219,7 +220,8 @@ void nrf_802154_transmitted_raw(const uint8_t *frame, uint8_t *ack, int8_t power k_work_submit(&rf_tx_finished_wq); } -void nrf_802154_transmit_failed(const uint8_t *frame, nrf_802154_tx_error_t error) +void nrf_802154_transmit_failed(uint8_t *frame, nrf_802154_tx_error_t error, + const nrf_802154_transmit_done_metadata_t *p_metadata) { ARG_UNUSED(frame); @@ -374,8 +376,10 @@ bool ptt_rf_send_packet_ext(const uint8_t *pkt, ptt_pkt_len_t len, bool cca) /* temp_tx_pkt is protected inside ptt rf by locking mechanism */ temp_tx_pkt[0] = len + RF_FCS_SIZE; memcpy(&temp_tx_pkt[RF_PSDU_START], pkt, len); - - ret = nrf_802154_transmit_raw(temp_tx_pkt, cca); + const nrf_802154_transmit_metadata_t metadata = { + .cca = cca + }; + ret = nrf_802154_transmit_raw(temp_tx_pkt, &metadata); } return ret; From 4e177ab44ab8484c967a96e6f20058c930cac71a Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Thu, 12 Aug 2021 08:27:37 +0200 Subject: [PATCH 114/126] net: openthread: make use of new API for retransmissions Remove the limitation about sending secured retransmissions after a newer OpenThread revision and proper Zephyr changes are applied. Also update documentation about this limitation. Signed-off-by: Eduardo Montoya --- doc/nrf/ug_thread_supported_features.rst | 5 +---- subsys/net/openthread/Kconfig | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/doc/nrf/ug_thread_supported_features.rst b/doc/nrf/ug_thread_supported_features.rst index 7edbe9d585fa..bef29474f786 100644 --- a/doc/nrf/ug_thread_supported_features.rst +++ b/doc/nrf/ug_thread_supported_features.rst @@ -42,9 +42,6 @@ By default, |NCS| supports Thread 1.1, but you can enable and configure Thread 1 Limitations for Thread 1.2 support ================================== -The Thread 1.2 Specification support has the following limitations: +The Thread 1.2 Specification support has the following limitation: -* The current implementation does not guarantee that all retransmitted frames will be secured when using the radio driver transmission security capabilities. - For this reason, OpenThread retransmissions are disabled by default when the :kconfig:`CONFIG_NRF_802154_ENCRYPTION` Kconfig option is enabled. - You can enable the retransmissions at your own risk. * Due to code size limitation, the combination of complete set of Thread 1.2 features with the Bluetooth LE multiprotocol support is not possible for the nRF52833 DKs. diff --git a/subsys/net/openthread/Kconfig b/subsys/net/openthread/Kconfig index 8d51e579ced1..b936ddab193e 100644 --- a/subsys/net/openthread/Kconfig +++ b/subsys/net/openthread/Kconfig @@ -63,9 +63,6 @@ config OPENTHREAD_RADIO_WORKQUEUE_STACK_SIZE default 796 if SOC_NRF5340_CPUAPP default 736 -config OPENTHREAD_CUSTOM_PARAMETERS - default "OPENTHREAD_CONFIG_MAC_DEFAULT_MAX_FRAME_RETRIES_DIRECT=0 OPENTHREAD_CONFIG_MAC_MAX_TX_ATTEMPTS_INDIRECT_POLLS=0" if NRF_802154_ENCRYPTION - endmenu endif From c8574614fea10fbfe4e0f473d9a5e5e755cdccd6 Mon Sep 17 00:00:00 2001 From: Tomasz Chyrowicz Date: Wed, 18 Aug 2021 19:16:13 +0200 Subject: [PATCH 115/126] zigbee: osif: Allocate net packet for every TX Since the IEEE 802.15.4 shim API requires the non-NULL network packet buffer for each TX operation, it is required to allocate an empty buffer in the ZBOSS transceiver layer, even if it is not used by the Zigbee logic. Signed-off-by: Tomasz Chyrowicz --- subsys/zigbee/osif/zb_nrf_transceiver.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/subsys/zigbee/osif/zb_nrf_transceiver.c b/subsys/zigbee/osif/zb_nrf_transceiver.c index 9f1833b82f90..f7a97ac69d1a 100644 --- a/subsys/zigbee/osif/zb_nrf_transceiver.c +++ b/subsys/zigbee/osif/zb_nrf_transceiver.c @@ -275,6 +275,7 @@ zb_bool_t zb_trans_is_active(void) zb_bool_t zb_trans_transmit(zb_uint8_t wait_type, zb_time_t tx_at, zb_uint8_t *tx_buf, zb_uint8_t current_channel) { + struct net_pkt *pkt = NULL; struct net_buf frag = { .frags = NULL, .b = { @@ -293,6 +294,12 @@ zb_bool_t zb_trans_transmit(zb_uint8_t wait_type, zb_time_t tx_at, ARG_UNUSED(current_channel); #endif + pkt = net_pkt_alloc(K_NO_WAIT); + if (!pkt) { + ZB_ASSERT(0); + return ZB_FALSE; + } + ack_frame = NULL; switch (wait_type) { @@ -306,22 +313,15 @@ zb_bool_t zb_trans_transmit(zb_uint8_t wait_type, zb_time_t tx_at, mode = IEEE802154_TX_MODE_CCA; } - err = radio_api->tx(radio_dev, mode, NULL, &frag); + err = radio_api->tx(radio_dev, mode, pkt, &frag); break; } #ifdef ZB_ENABLE_ZGP_DIRECT case ZB_MAC_TX_WAIT_ZGP: { - struct net_pkt *pkt = NULL; - if (!(radio_api->get_capabilities(radio_dev) & IEEE802154_HW_TXTIME)) { - return ZB_FALSE; - } - - pkt = net_pkt_alloc(K_NO_WAIT); - if (!pkt) { - ZB_ASSERT(0); + net_pkt_unref(pkt); return ZB_FALSE; } @@ -331,7 +331,6 @@ zb_bool_t zb_trans_transmit(zb_uint8_t wait_type, zb_time_t tx_at, IEEE802154_TX_MODE_TXTIME, pkt, &frag); - net_pkt_unref(pkt); break; } #endif @@ -340,15 +339,17 @@ zb_bool_t zb_trans_transmit(zb_uint8_t wait_type, zb_time_t tx_at, state_cache.radio_state = RADIO_802154_STATE_TRANSMIT; err = radio_api->tx(radio_dev, IEEE802154_TX_MODE_DIRECT, - NULL, + pkt, &frag); break; default: LOG_DBG("Illegal wait_type parameter: %d", wait_type); ZB_ASSERT(0); + net_pkt_unref(pkt); return ZB_FALSE; } + net_pkt_unref(pkt); state_cache.radio_state = RADIO_802154_STATE_RECEIVE; switch (err) { From 765975b0fb76d4bde292deb7ede0c4b509b1ce62 Mon Sep 17 00:00:00 2001 From: Kamil Kasperczyk Date: Mon, 9 Aug 2021 14:02:29 +0200 Subject: [PATCH 116/126] applications: Moved weather station from samples to applications The weather station sample should become an application, so it was moved with several changes: * Removed abilitiy to build target without DFU support * Extended application docs about using CHIPTool application to read sensor measurements * Added in Matter docs mention about new application * Replaced logging using RTT with USB * Changed device type to SED in order to save energy on RX. Signed-off-by: Kamil Kasperczyk --- .checkpatch.conf | 1 + CODEOWNERS | 1 + .../matter_weather_station}/CMakeLists.txt | 21 +- .../matter_weather_station/README.rst | 257 ++++++++++++++++++ .../multiprotocol_rpmsg_ZDebug.conf | 8 + .../multiprotocol_rpmsg_ZRelease.conf | 8 + .../mcuboot_ZDebug.conf | 1 + .../mcuboot_ZRelease.conf | 1 + .../thingy53_nrf5340_cpuapp/pm_static.yml | 0 .../thingy53_nrf5340_cpuapp/prj_ZDebug.conf | 69 ++++- .../thingy53_nrf5340_cpuapp/prj_ZRelease.conf | 40 ++- .../matter_weather_station}/sample.yaml | 4 +- .../matter_weather_station}/src/app_event.h | 0 .../matter_weather_station}/src/app_task.cpp | 0 .../matter_weather_station}/src/app_task.h | 0 .../src/chip_project_config.h | 0 .../src/gen/CHIPClientCallbacks.cpp | 0 .../src/gen/CHIPClientCallbacks.h | 0 .../src/gen/CHIPClusters.cpp | 0 .../src/gen/CHIPClusters.h | 0 .../src/gen/IMClusterCommandHandler.cpp | 0 .../src/gen/af-gen-event.h | 0 .../src/gen/attribute-size.cpp | 0 .../src/gen/callback-stub.cpp | 0 .../src/gen/callback.h | 0 .../src/gen/chip-zcl-zpro-codec-api.h | 0 .../src/gen/encoder.cpp | 0 .../src/gen/endpoint_config.h | 0 .../src/gen/gen_config.h | 0 .../src/gen/gen_tokens.h | 0 .../matter_weather_station}/src/main.cpp | 35 ++- .../src/weather-station.zap | 0 .../thingy53_nrf5340_cpuapp.overlay | 0 doc/nrf/images/chiptool_relative_humidity.gif | Bin 0 -> 633653 bytes doc/nrf/images/chiptool_sensor_cluster.gif | Bin 0 -> 46550 bytes doc/nrf/images/chiptool_temperature_read.gif | Bin 0 -> 54960 bytes doc/nrf/images/chiptool_temperature_watch.gif | Bin 0 -> 252192 bytes doc/nrf/nrf.doxyfile.in | 3 +- doc/nrf/releases/release-notes-changelog.rst | 2 +- doc/nrf/samples/samples_matter.rst | 5 + doc/nrf/ug_matter.rst | 2 +- samples/matter/weather_station/README.rst | 191 ------------- 42 files changed, 425 insertions(+), 224 deletions(-) rename {samples/matter/weather_station => applications/matter_weather_station}/CMakeLists.txt (83%) create mode 100644 applications/matter_weather_station/README.rst create mode 100644 applications/matter_weather_station/child_image/multiprotocol_rpmsg_ZDebug.conf create mode 100644 applications/matter_weather_station/child_image/multiprotocol_rpmsg_ZRelease.conf rename samples/matter/weather_station/child_image/mcuboot_debug.conf => applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/mcuboot_ZDebug.conf (98%) rename samples/matter/weather_station/child_image/mcuboot_release.conf => applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/mcuboot_ZRelease.conf (98%) rename {samples/matter/weather_station => applications/matter_weather_station}/configuration/thingy53_nrf5340_cpuapp/pm_static.yml (100%) rename samples/matter/weather_station/prj_debug.conf => applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZDebug.conf (59%) rename samples/matter/weather_station/prj_release.conf => applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZRelease.conf (68%) rename {samples/matter/weather_station => applications/matter_weather_station}/sample.yaml (67%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/app_event.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/app_task.cpp (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/app_task.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/chip_project_config.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/CHIPClientCallbacks.cpp (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/CHIPClientCallbacks.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/CHIPClusters.cpp (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/CHIPClusters.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/IMClusterCommandHandler.cpp (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/af-gen-event.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/attribute-size.cpp (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/callback-stub.cpp (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/callback.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/chip-zcl-zpro-codec-api.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/encoder.cpp (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/endpoint_config.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/gen_config.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/gen/gen_tokens.h (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/main.cpp (56%) rename {samples/matter/weather_station => applications/matter_weather_station}/src/weather-station.zap (100%) rename {samples/matter/weather_station => applications/matter_weather_station}/thingy53_nrf5340_cpuapp.overlay (100%) create mode 100644 doc/nrf/images/chiptool_relative_humidity.gif create mode 100644 doc/nrf/images/chiptool_sensor_cluster.gif create mode 100644 doc/nrf/images/chiptool_temperature_read.gif create mode 100644 doc/nrf/images/chiptool_temperature_watch.gif delete mode 100644 samples/matter/weather_station/README.rst diff --git a/.checkpatch.conf b/.checkpatch.conf index e793f667fcf3..f920c4fb0186 100644 --- a/.checkpatch.conf +++ b/.checkpatch.conf @@ -22,6 +22,7 @@ --ignore MULTISTATEMENT_MACRO_USE_DO_WHILE --exclude ext --exclude samples/matter/.*/src +--exclude applications/matter_weather_station/src --exclude samples/openthread/cli/harness --exclude modules/tfm/tfm/boards/src --exclude modules/tfm/tfm/boards/common diff --git a/CODEOWNERS b/CODEOWNERS index 32290e3540c2..063f1eb1412d 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -21,6 +21,7 @@ /applications/asset_tracker_v2/ @simensrostad @jtguggedal @jhn-nordic @coderbyheart /applications/connectivity_bridge/ @jtguggedal @nordic-auko /applications/machine_learning/ @pdunaj +/applications/matter_weather_station/ @Damian-Nordic @kkasperczyk-no /applications/nrf_desktop/ @pdunaj /applications/pelion_client/ @pdunaj /applications/serial_lte_modem/ @junqingzou @lats1980 @rlubos diff --git a/samples/matter/weather_station/CMakeLists.txt b/applications/matter_weather_station/CMakeLists.txt similarity index 83% rename from samples/matter/weather_station/CMakeLists.txt rename to applications/matter_weather_station/CMakeLists.txt index f272a6ec9832..cefa71c77354 100644 --- a/samples/matter/weather_station/CMakeLists.txt +++ b/applications/matter_weather_station/CMakeLists.txt @@ -7,24 +7,18 @@ cmake_minimum_required(VERSION 3.13.1) if (NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE release) + set(CMAKE_BUILD_TYPE ZDebug) endif() -set(CONF_FILE "prj_${CMAKE_BUILD_TYPE}.conf") - -option(BUILD_WITH_DFU "Build target with Device Firmware Upgrade support" ON) -if(BUILD_WITH_DFU) - list(INSERT OVERLAY_CONFIG 0 ${CMAKE_CURRENT_SOURCE_DIR}/../common/config/overlay-dfu_support.conf) - list(INSERT OVERLAY_CONFIG 0 ${CMAKE_CURRENT_SOURCE_DIR}/../common/config/overlay-dfu_nrf53_extension.conf) - set(mcuboot_CONF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/child_image/mcuboot_${CMAKE_BUILD_TYPE}.conf) - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/thingy53_nrf5340_cpuapp/pm_static.yml) -endif() +set(CONF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/prj_${CMAKE_BUILD_TYPE}.conf) +set(mcuboot_CONF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/mcuboot_${CMAKE_BUILD_TYPE}.conf) +set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) find_package(Zephyr HINTS $ENV{ZEPHYR_BASE}) project(matter-weather-station) -set(COMMON_ROOT ${CMAKE_CURRENT_LIST_DIR}/../common) +set(COMMON_ROOT ${CMAKE_CURRENT_LIST_DIR}/../../samples/matter/common) set(NLIO_ROOT ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/third_party/nlio/repo) include(${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/config/nrfconnect/app/enable-gnu-std.cmake) @@ -39,6 +33,7 @@ target_sources(app PRIVATE src/gen/callback-stub.cpp ${COMMON_ROOT}/src/thread_util.cpp ${COMMON_ROOT}/src/led_widget.cpp + ${COMMON_ROOT}/src/dfu_over_smp.cpp ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/util/DataModelHandler.cpp ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/reporting/reporting-default-configuration.cpp ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/reporting/reporting.cpp @@ -71,7 +66,3 @@ target_sources(app PRIVATE ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/server/Server.cpp ${ZEPHYR_CONNECTEDHOMEIP_MODULE_DIR}/src/app/server/StorablePeerConnection.cpp) # NORDIC SDK APP END - -if(BUILD_WITH_DFU) - target_sources(app PRIVATE ${COMMON_ROOT}/src/dfu_over_smp.cpp) -endif() diff --git a/applications/matter_weather_station/README.rst b/applications/matter_weather_station/README.rst new file mode 100644 index 000000000000..40a09ec5dac6 --- /dev/null +++ b/applications/matter_weather_station/README.rst @@ -0,0 +1,257 @@ +.. _matter_weather_station_app: + +Thingy:53: Matter weather station +################################# + +.. contents:: + :local: + :depth: 2 + +This Matter weather station application demonstrates the usage of the :ref:`Matter ` application layer to build a weather station device. +Such a device lets you remotely gather different kinds of data using the device sensors, such as temperature, air pressure, and relative humidity. +The device works as a Matter accessory device, meaning it can be paired and controlled remotely over a Matter network built on top of a low-power, 802.15.4 Thread network. +You can use this application as a reference for creating your own application. + +.. note:: + The Matter protocol is in an early development stage and must be treated as an experimental feature. + +Requirements +************ + +The application supports the following development kits: + +.. table-from-rows:: /includes/sample_board_rows.txt + :header: heading + :rows: thingy53_nrf5340_cpuapp + +To commission the weather station device and control it remotely through a Thread network, you also need a Matter controller device :ref:`configured on PC or smartphone ` (which requires additional hardware depending on which setup you choose). +The recommended way of getting measurement values is using the mobile Matter controller application that comes with a neat graphical interface, performs measurements automatically and visualizes the data. + +To program the Thingy:53 device, you need the external J-Link programmer. +If you own an nRF5340 DK that has an onboard J-Link programmer, you can also use it for this purpose. + +.. note:: + |matter_gn_required_note| + +Overview +******** + +The application uses a single button for controlling the device state. +The weather station device is periodically performing temperature, air pressure, and relative humidity measurements. +The measurement results are stored in the device memory and can be read using the Matter controller. +The controller communicates with the weather station device over the Matter protocol using Zigbee Cluster Library (ZCL). +The library describes data measurements within the proper clusters that correspond to the measurement type. + +The application uses MCUboot secure bootloader and SMP protocol for performing over-the-air Device Firmware Upgrade using Bluetooth LE. +For information about how to upgrade the device firmware using a PC or a mobile, see the :ref:`matter_weather_station_app_dfu` section. + +.. _matter_weather_station_network_mode: + +Remote testing in a network +=========================== + +By default, the Matter accessory device has Thread disabled, and it must be paired with the Matter controller over Bluetooth LE to get configuration from it if you want to use the device within a Thread network. +To do this, the device must be made discoverable over Bluetooth LE. + +The Bluetooth LE advertising starts automatically upon the device startup, but only for a predefined period of time (15 minutes by default). +If the Bluetooth LE advertising times out, you can re-enable it manually using **Button 1**. + +Additionally, the controller must get the commissioning information from the Matter accessory device and provision the device into the network. +For details, see the `Testing`_ section. + +.. _matter_weather_station_app_build_types: + +Matter weather station build types +================================== + +The Matter weather station application does not use a single :file:`prj.conf` file. +Configuration files are provided for different build types and they are located in the `configuration/thingy53_nrf5340_cpuapp` directory. + +.. include:: /gs_modifying.rst + :start-after: build_types_overview_start + :end-before: build_types_overview_end + +Before you start testing the application, you can select one of the build types supported by Matter weather station application, depending on the building method. +This application supports the following build types: + +* ``ZDebug`` -- Debug version of the application - can be used to enable additional features for verifying the application behavior, such as logs or command-line shell. +* ``ZRelease`` -- Release version of the application - can be used to enable only the necessary application functionalities to optimize its performance. + +.. note:: + `Selecting a build type`_ is optional. + The ``ZDebug`` build type is used by default if no build type is explicitly selected. + +Configuration +************* + +|config| + +User interface +************** + +LED 1: + Shows the overall state of the device and its connectivity. + The following states are possible: + + * Short flash on (green color, 50 ms on/950 ms off) - The device is in the unprovisioned (unpaired) state and is not advertising over Bluetooth LE. + * Short flash on (blue color, 50 ms on/950 ms off) - The device is in the unprovisioned (unpaired) state, but is advertising over Bluetooth LE. + * Rapid even flashing (blue color, 100 ms on/100 ms off) - The device is in the unprovisioned state and a commissioning application is connected through Bluetooth LE. + * Short flash on (purple color, 50 ms on/950 ms off) - The device is fully provisioned and has Thread enabled. + +Button 1: + Used during the commissioning procedure. + Depending on how long you press the button: + + * If pressed for 6 seconds, it initiates the factory reset of the device. + Releasing the button within the 6-second window cancels the factory reset procedure. + * If pressed for less than 3 seconds, it starts the NFC tag emulation, enables Bluetooth LE advertising for the predefined period of time (15 minutes by default), and makes the device discoverable over Bluetooth LE. + +USB port: + Used for getting logs from the device or communicating with it through the command-line interface. + It is enabled only for the debug configuration of a application. + See the `Selecting a build type`_ section to learn how to select the debug configuration. + +NFC port with antenna attached: + Used for obtaining the commissioning information from the Matter accessory device to start the commissioning procedure. + +Building and running +******************** + +.. |sample path| replace:: :file:`applications/matter_weather_station` + +.. include:: /includes/build_and_run.txt + +Selecting a build type +====================== + +Before you start testing the application, you can select one of the :ref:`matter_weather_station_app_build_types`, depending on your building method. + +Selecting a build type in SES +----------------------------- + +.. include:: /gs_modifying.rst + :start-after: build_types_selection_ses_start + :end-before: build_types_selection_ses_end + +Selecting a build type from command line +---------------------------------------- + +.. include:: /gs_modifying.rst + :start-after: build_types_selection_cmd_start + :end-before: For example, you can replace the + +For example, you can replace the *selected_build_type* variable to build the ``ZRelease`` firmware for PCA20053 by running the following command in the project directory: + +.. parsed-literal:: + :class: highlight + + west build -b thingy53_nrf5340_cpuapp -d build_thingy53_nrf5340_cpuapp -- -DCMAKE_BUILD_TYPE=ZRelease + +The ``build_thingy53_nrf5340_cpuapp`` parameter specifies the output directory for the build files. + +.. note:: + If the selected board does not support the selected build type, the build is interrupted. + For example, if the ``ZDebugWithShell`` build type is not supported by the selected board, the following notification appears: + + .. code-block:: console + + Configuration file for build type ZDebugWithShell is missing. + +Testing +======= + +.. note:: + The testing procedure assumes you are using the mobile Matter controller application. + You can also obtain the measurement values using the PC command-line-based Matter controller and invoking the read commands manually. + To see how to send read commands from the PC Matter controller, read the `Working with Python Controller`_ guide in the Matter documentation. + +After programming the application, perform the following steps to test the Matter weather station application on the Thingy:53 with the mobile Matter controller application: + +1. Turn on the Thingy:53. + The application starts in an unprovisioned state. + The advertising over Bluetooth LE and DFU start automatically, and **LED 1** starts blinking blue (short flash on). +#. Commission the device into a Thread network by following the guides linked on the :ref:`ug_matter_configuring` page for the mobile Matter controller. + As part of this procedure, you will complete the following steps: + + * Configure Thread Border Router. + * Build and install the mobile Matter controller. + * Commission the device. + * Send Matter commands. + + During the commissioning procedure, **LED 1** of the Matter device starts blinking blue (rapid even flashing). + This indicates that the device is connected over Bluetooth LE, but does not yet have full Thread network connectivity. + + .. note:: + To start commissioning, the controller must get the commissioning information from the Matter accessory device. + The data payload, which includes the device discriminator and setup PIN code, is encoded and shared using an NFC tag. + When using the debug configuration, you can also get this type of information from the USB interface logs. + + Once the commissioning is complete and the device has full Thread connectivity, **LED 1** starts blinking purple (short flash on). +#. Read sensor measurements in Android CHIPTool: + + a. In the Android CHIPTool application main menu, tap the :guilabel:`SENSOR CLUSTERS` button to open the sensor measurements section. + This section contains text boxes to enter :guilabel:`Device ID` and :guilabel:`Endpoint ID`, a drop-down menu with available measurements and two buttons, :guilabel:`READ` and :guilabel:`WATCH`. + + .. figure:: /images/chiptool_sensor_cluster.gif + :alt: Sensor cluster section selection + + Sensor cluster section selection + + On this image, :guilabel:`Device ID` has the value ``5`` and :guilabel:`Endpoint ID` has the value ``1``. + #. Select one of the available measurement types from the drop-down menu. + #. Enter one of the following values for :guilabel:`Endpoint ID`, depending on the selected measurement type: + + * 1 - Temperature measurement + * 2 - Relative humidity measurement + * 3 - Air pressure measurement + + #. Tap the :guilabel:`READ` button to read and display the single measurement value. + + .. figure:: /images/chiptool_temperature_read.gif + :alt: Single temperature measurement read + + Single temperature measurement read + + #. Tap the :guilabel:`WATCH` button to start watching measurement changes in a continuous way and display values on a chart. + + .. figure:: /images/chiptool_temperature_watch.gif + :alt: Continuous temperature measurement watch + + Continuous temperature measurement watch + + The vertical axis represents the measurement values and the horizontal axis represents the current time. + #. Change the displayed measurement by selecting a different measurement type from the drop-down list and entering the corresponding :guilabel:`Endpoint ID` value. + + .. figure:: /images/chiptool_relative_humidity.gif + :alt: Relative humidity measurement type selection + + Relative humidity measurement type selection + +.. _matter_weather_station_app_dfu: + +Updating the device firmware +============================ + +.. note:: + Device Firmware Upgrade feature is under development and currently it is possible to update only the application core image. + Network core image update is not yet available. + +To update the device firmware, complete the steps listed for the selected method in the `Performing Device Firmware Upgrade in Matter device`_ tutorial. + +Dependencies +************ + +This application uses the Matter library, which includes the |NCS| platform integration layer: + +* `Matter`_ + +In addition, the application uses the following |NCS| components: + +* :ref:`dk_buttons_and_leds_readme` +* :ref:`nfc_uri` +* :ref:`lib_nfc_t2t` + +The application depends on the following Zephyr libraries: + +* :ref:`zephyr:logging_api` +* :ref:`zephyr:kernel_api` diff --git a/applications/matter_weather_station/child_image/multiprotocol_rpmsg_ZDebug.conf b/applications/matter_weather_station/child_image/multiprotocol_rpmsg_ZDebug.conf new file mode 100644 index 000000000000..8b53fef45668 --- /dev/null +++ b/applications/matter_weather_station/child_image/multiprotocol_rpmsg_ZDebug.conf @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# TODO: remove increasing connection interval after fixing MPSL driver blocking issues +CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 diff --git a/applications/matter_weather_station/child_image/multiprotocol_rpmsg_ZRelease.conf b/applications/matter_weather_station/child_image/multiprotocol_rpmsg_ZRelease.conf new file mode 100644 index 000000000000..8b53fef45668 --- /dev/null +++ b/applications/matter_weather_station/child_image/multiprotocol_rpmsg_ZRelease.conf @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# TODO: remove increasing connection interval after fixing MPSL driver blocking issues +CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 diff --git a/samples/matter/weather_station/child_image/mcuboot_debug.conf b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/mcuboot_ZDebug.conf similarity index 98% rename from samples/matter/weather_station/child_image/mcuboot_debug.conf rename to applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/mcuboot_ZDebug.conf index 897427cd07be..c6dad4985b00 100644 --- a/samples/matter/weather_station/child_image/mcuboot_debug.conf +++ b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/mcuboot_ZDebug.conf @@ -13,6 +13,7 @@ CONFIG_PM=n CONFIG_MAIN_STACK_SIZE=10240 CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" +CONFIG_BOOT_UPGRADE_ONLY=y CONFIG_BOOT_MAX_IMG_SECTORS=2048 CONFIG_BOOT_SIGNATURE_TYPE_RSA=y diff --git a/samples/matter/weather_station/child_image/mcuboot_release.conf b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/mcuboot_ZRelease.conf similarity index 98% rename from samples/matter/weather_station/child_image/mcuboot_release.conf rename to applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/mcuboot_ZRelease.conf index 897427cd07be..c6dad4985b00 100644 --- a/samples/matter/weather_station/child_image/mcuboot_release.conf +++ b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/mcuboot_ZRelease.conf @@ -13,6 +13,7 @@ CONFIG_PM=n CONFIG_MAIN_STACK_SIZE=10240 CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" +CONFIG_BOOT_UPGRADE_ONLY=y CONFIG_BOOT_MAX_IMG_SECTORS=2048 CONFIG_BOOT_SIGNATURE_TYPE_RSA=y diff --git a/samples/matter/weather_station/configuration/thingy53_nrf5340_cpuapp/pm_static.yml b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/pm_static.yml similarity index 100% rename from samples/matter/weather_station/configuration/thingy53_nrf5340_cpuapp/pm_static.yml rename to applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/pm_static.yml diff --git a/samples/matter/weather_station/prj_debug.conf b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZDebug.conf similarity index 59% rename from samples/matter/weather_station/prj_debug.conf rename to applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZDebug.conf index f0ad8bf28df1..3cb1961d6eae 100644 --- a/samples/matter/weather_station/prj_debug.conf +++ b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZDebug.conf @@ -20,6 +20,7 @@ CONFIG_NET_SOCKETS_POLL_MAX=5 CONFIG_NET_L2_OPENTHREAD=y CONFIG_OPENTHREAD_MTD=y +CONFIG_OPENTHREAD_MTD_SED=y CONFIG_OPENTHREAD_FTD=n CONFIG_OPENTHREAD_SLAAC=y CONFIG_OPENTHREAD_MTD_NETDIAG=y @@ -27,6 +28,7 @@ CONFIG_OPENTHREAD_MANUAL_START=y CONFIG_OPENTHREAD_THREAD_STACK_SIZE=6144 CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS=64 +CONFIG_OPENTHREAD_POLL_PERIOD=1000 CONFIG_OPENTHREAD_PANID=4660 CONFIG_OPENTHREAD_CHANNEL=15 CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" @@ -49,7 +51,6 @@ CONFIG_BT_MAX_PAIRED=0 CONFIG_BT_BONDABLE=n CONFIG_BT_TINYCRYPT_ECC=n CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY=y -CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 # Use NFC to share commissioning information CONFIG_CHIP_NFC_COMMISSIONING=y @@ -94,19 +95,28 @@ CONFIG_OBERON_MBEDTLS_AES_C=n CONFIG_DK_LIBRARY=y CONFIG_DK_LIBRARY_INVERT_LEDS=n -# Configure RTT logging and shell -CONFIG_USE_SEGGER_RTT=y -CONFIG_UART_CONSOLE=n +# Configure UART logging and shell CONFIG_LOG=y -CONFIG_LOG_MODE_DEFERRED=y -CONFIG_LOG_BACKEND_UART=n -CONFIG_LOG_BACKEND_RTT=n -CONFIG_LOG_STRDUP_BUF_COUNT=32 +CONFIG_LOG_BACKEND_UART=y +CONFIG_LOG_STRDUP_BUF_COUNT=48 CONFIG_LOG_STRDUP_MAX_STRING=100 +CONFIG_LOG_BUFFER_SIZE=2048 CONFIG_SHELL=y -CONFIG_SHELL_LOG_BACKEND=y -CONFIG_SHELL_BACKEND_SERIAL=n -CONFIG_SHELL_BACKEND_RTT=y +CONFIG_SHELL_LOG_BACKEND=n + +# Enable USB CDC ACM +CONFIG_USB=y +CONFIG_USB_DEVICE_STACK=y +CONFIG_USB_DEVICE_PRODUCT="Thingy:53 Matter Weather" +CONFIG_USB_DEVICE_VID=0x1915 +CONFIG_USB_DEVICE_PID=0x530D +CONFIG_USB_CDC_ACM=y +CONFIG_USB_UART_CONSOLE=y +CONFIG_USB_CDC_ACM_DEVICE_NAME="CDC_ACM" +CONFIG_UART_CONSOLE_ON_DEV_NAME="CDC_ACM_0" +CONFIG_UART_LINE_CTRL=y +CONFIG_UART_SHELL_ON_DEV_NAME="CDC_ACM_0" +CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY=51 # Configure Thingy:53 sensors CONFIG_I2C=y @@ -119,3 +129,40 @@ CONFIG_INIT_STACKS=y CONFIG_HW_STACK_PROTECTION=y CONFIG_THREAD_NAME=y CONFIG_MPU_STACK_GUARD=y + +######################################################### +# Bootloader and Device Firmware Upgrade related settings + +CONFIG_BOOTLOADER_MCUBOOT=y + +# QSPI configuration +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# External flash memory configuration +CONFIG_PM_EXTERNAL_FLASH=y +CONFIG_PM_EXTERNAL_FLASH_DEV_NAME="MX25R64" +CONFIG_PM_EXTERNAL_FLASH_SIZE=0x800000 +CONFIG_PM_EXTERNAL_FLASH_BASE=0 + +# MCU Manager and SMP configuration +CONFIG_MCUMGR=y +CONFIG_MCUMGR_CMD_IMG_MGMT=y +CONFIG_MCUMGR_CMD_OS_MGMT=y +CONFIG_MCUMGR_SMP_BT=y +CONFIG_MCUMGR_SMP_BT_AUTHEN=n +CONFIG_MCUMGR_BUF_COUNT=6 + +# Increase BT MTU and RX buffer for big size DFU messages +CONFIG_BT_L2CAP_TX_MTU=260 +CONFIG_BT_BUF_ACL_RX_SIZE=264 + +# Increase system workqueue size, as SMP is processed within it +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2800 + +# TODO: Temporary fix until multi-image support allowing to update net core will be available: NCSDK-9502. +CONFIG_NRF53_UPGRADE_NETWORK_CORE=n + +# TODO: Temporary workaround to fix net core Spinel response timeout: KRKNWK-10930 +CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT=1000 diff --git a/samples/matter/weather_station/prj_release.conf b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZRelease.conf similarity index 68% rename from samples/matter/weather_station/prj_release.conf rename to applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZRelease.conf index 21de91e15c2a..e11219481f72 100644 --- a/samples/matter/weather_station/prj_release.conf +++ b/applications/matter_weather_station/configuration/thingy53_nrf5340_cpuapp/prj_ZRelease.conf @@ -20,6 +20,7 @@ CONFIG_NET_SOCKETS_POLL_MAX=5 CONFIG_NET_L2_OPENTHREAD=y CONFIG_OPENTHREAD_MTD=y +CONFIG_OPENTHREAD_MTD_SED=y CONFIG_OPENTHREAD_FTD=n CONFIG_OPENTHREAD_SLAAC=y CONFIG_OPENTHREAD_MTD_NETDIAG=y @@ -27,6 +28,7 @@ CONFIG_OPENTHREAD_MANUAL_START=y CONFIG_OPENTHREAD_THREAD_STACK_SIZE=6144 CONFIG_OPENTHREAD_NUM_MESSAGE_BUFFERS=64 +CONFIG_OPENTHREAD_POLL_PERIOD=1000 CONFIG_OPENTHREAD_PANID=4660 CONFIG_OPENTHREAD_CHANNEL=15 CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" @@ -49,7 +51,6 @@ CONFIG_BT_MAX_PAIRED=0 CONFIG_BT_BONDABLE=n CONFIG_BT_TINYCRYPT_ECC=n CONFIG_BT_SMP_OOB_LEGACY_PAIR_ONLY=y -CONFIG_SDC_MAX_CONN_EVENT_LEN_DEFAULT=3000 # Use NFC to share commissioning information CONFIG_CHIP_NFC_COMMISSIONING=y @@ -113,3 +114,40 @@ CONFIG_BME680=y CONFIG_MAIN_STACK_SIZE=8192 CONFIG_INIT_STACKS=y CONFIG_HW_STACK_PROTECTION=y + +######################################################### +# Bootloader and Device Firmware Upgrade related settings + +CONFIG_BOOTLOADER_MCUBOOT=y + +# QSPI configuration +CONFIG_NORDIC_QSPI_NOR=y +CONFIG_NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE=4096 +CONFIG_NORDIC_QSPI_NOR_STACK_WRITE_BUFFER_SIZE=16 + +# External flash memory configuration +CONFIG_PM_EXTERNAL_FLASH=y +CONFIG_PM_EXTERNAL_FLASH_DEV_NAME="MX25R64" +CONFIG_PM_EXTERNAL_FLASH_SIZE=0x800000 +CONFIG_PM_EXTERNAL_FLASH_BASE=0 + +# MCU Manager and SMP configuration +CONFIG_MCUMGR=y +CONFIG_MCUMGR_CMD_IMG_MGMT=y +CONFIG_MCUMGR_CMD_OS_MGMT=y +CONFIG_MCUMGR_SMP_BT=y +CONFIG_MCUMGR_SMP_BT_AUTHEN=n +CONFIG_MCUMGR_BUF_COUNT=6 + +# Increase BT MTU and RX buffer for big size DFU messages +CONFIG_BT_L2CAP_TX_MTU=260 +CONFIG_BT_BUF_ACL_RX_SIZE=264 + +# Increase system workqueue size, as SMP is processed within it +CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2800 + +# TODO: Temporary fix until multi-image support allowing to update net core will be available: NCSDK-9502. +CONFIG_NRF53_UPGRADE_NETWORK_CORE=n + +# TODO: Temporary workaround to fix net core Spinel response timeout: KRKNWK-10930 +CONFIG_NRF_802154_SER_DEFAULT_RESPONSE_TIMEOUT=1000 diff --git a/samples/matter/weather_station/sample.yaml b/applications/matter_weather_station/sample.yaml similarity index 67% rename from samples/matter/weather_station/sample.yaml rename to applications/matter_weather_station/sample.yaml index f83fdb6ffd95..3cf27a2fc2ef 100644 --- a/samples/matter/weather_station/sample.yaml +++ b/applications/matter_weather_station/sample.yaml @@ -1,8 +1,8 @@ sample: name: Matter Weather Station - description: Matter Weather Station example + description: Matter Weather Station application tests: - matter.weather_station: + applications.matter_weather_station: build_only: true platform_allow: thingy53_nrf5340_cpuapp integration_platforms: diff --git a/samples/matter/weather_station/src/app_event.h b/applications/matter_weather_station/src/app_event.h similarity index 100% rename from samples/matter/weather_station/src/app_event.h rename to applications/matter_weather_station/src/app_event.h diff --git a/samples/matter/weather_station/src/app_task.cpp b/applications/matter_weather_station/src/app_task.cpp similarity index 100% rename from samples/matter/weather_station/src/app_task.cpp rename to applications/matter_weather_station/src/app_task.cpp diff --git a/samples/matter/weather_station/src/app_task.h b/applications/matter_weather_station/src/app_task.h similarity index 100% rename from samples/matter/weather_station/src/app_task.h rename to applications/matter_weather_station/src/app_task.h diff --git a/samples/matter/weather_station/src/chip_project_config.h b/applications/matter_weather_station/src/chip_project_config.h similarity index 100% rename from samples/matter/weather_station/src/chip_project_config.h rename to applications/matter_weather_station/src/chip_project_config.h diff --git a/samples/matter/weather_station/src/gen/CHIPClientCallbacks.cpp b/applications/matter_weather_station/src/gen/CHIPClientCallbacks.cpp similarity index 100% rename from samples/matter/weather_station/src/gen/CHIPClientCallbacks.cpp rename to applications/matter_weather_station/src/gen/CHIPClientCallbacks.cpp diff --git a/samples/matter/weather_station/src/gen/CHIPClientCallbacks.h b/applications/matter_weather_station/src/gen/CHIPClientCallbacks.h similarity index 100% rename from samples/matter/weather_station/src/gen/CHIPClientCallbacks.h rename to applications/matter_weather_station/src/gen/CHIPClientCallbacks.h diff --git a/samples/matter/weather_station/src/gen/CHIPClusters.cpp b/applications/matter_weather_station/src/gen/CHIPClusters.cpp similarity index 100% rename from samples/matter/weather_station/src/gen/CHIPClusters.cpp rename to applications/matter_weather_station/src/gen/CHIPClusters.cpp diff --git a/samples/matter/weather_station/src/gen/CHIPClusters.h b/applications/matter_weather_station/src/gen/CHIPClusters.h similarity index 100% rename from samples/matter/weather_station/src/gen/CHIPClusters.h rename to applications/matter_weather_station/src/gen/CHIPClusters.h diff --git a/samples/matter/weather_station/src/gen/IMClusterCommandHandler.cpp b/applications/matter_weather_station/src/gen/IMClusterCommandHandler.cpp similarity index 100% rename from samples/matter/weather_station/src/gen/IMClusterCommandHandler.cpp rename to applications/matter_weather_station/src/gen/IMClusterCommandHandler.cpp diff --git a/samples/matter/weather_station/src/gen/af-gen-event.h b/applications/matter_weather_station/src/gen/af-gen-event.h similarity index 100% rename from samples/matter/weather_station/src/gen/af-gen-event.h rename to applications/matter_weather_station/src/gen/af-gen-event.h diff --git a/samples/matter/weather_station/src/gen/attribute-size.cpp b/applications/matter_weather_station/src/gen/attribute-size.cpp similarity index 100% rename from samples/matter/weather_station/src/gen/attribute-size.cpp rename to applications/matter_weather_station/src/gen/attribute-size.cpp diff --git a/samples/matter/weather_station/src/gen/callback-stub.cpp b/applications/matter_weather_station/src/gen/callback-stub.cpp similarity index 100% rename from samples/matter/weather_station/src/gen/callback-stub.cpp rename to applications/matter_weather_station/src/gen/callback-stub.cpp diff --git a/samples/matter/weather_station/src/gen/callback.h b/applications/matter_weather_station/src/gen/callback.h similarity index 100% rename from samples/matter/weather_station/src/gen/callback.h rename to applications/matter_weather_station/src/gen/callback.h diff --git a/samples/matter/weather_station/src/gen/chip-zcl-zpro-codec-api.h b/applications/matter_weather_station/src/gen/chip-zcl-zpro-codec-api.h similarity index 100% rename from samples/matter/weather_station/src/gen/chip-zcl-zpro-codec-api.h rename to applications/matter_weather_station/src/gen/chip-zcl-zpro-codec-api.h diff --git a/samples/matter/weather_station/src/gen/encoder.cpp b/applications/matter_weather_station/src/gen/encoder.cpp similarity index 100% rename from samples/matter/weather_station/src/gen/encoder.cpp rename to applications/matter_weather_station/src/gen/encoder.cpp diff --git a/samples/matter/weather_station/src/gen/endpoint_config.h b/applications/matter_weather_station/src/gen/endpoint_config.h similarity index 100% rename from samples/matter/weather_station/src/gen/endpoint_config.h rename to applications/matter_weather_station/src/gen/endpoint_config.h diff --git a/samples/matter/weather_station/src/gen/gen_config.h b/applications/matter_weather_station/src/gen/gen_config.h similarity index 100% rename from samples/matter/weather_station/src/gen/gen_config.h rename to applications/matter_weather_station/src/gen/gen_config.h diff --git a/samples/matter/weather_station/src/gen/gen_tokens.h b/applications/matter_weather_station/src/gen/gen_tokens.h similarity index 100% rename from samples/matter/weather_station/src/gen/gen_tokens.h rename to applications/matter_weather_station/src/gen/gen_tokens.h diff --git a/samples/matter/weather_station/src/main.cpp b/applications/matter_weather_station/src/main.cpp similarity index 56% rename from samples/matter/weather_station/src/main.cpp rename to applications/matter_weather_station/src/main.cpp index 4655ed9fd40d..31d522daea1c 100644 --- a/samples/matter/weather_station/src/main.cpp +++ b/applications/matter_weather_station/src/main.cpp @@ -8,8 +8,13 @@ #include +#ifdef CONFIG_USB +#include +#endif + #include #include +#include LOG_MODULE_REGISTER(app); @@ -20,6 +25,13 @@ int main() int ret = 0; CHIP_ERROR err = CHIP_NO_ERROR; +#ifdef CONFIG_USB + err = chip::System::MapErrorZephyr(usb_enable(NULL)); + if (err != CHIP_NO_ERROR) { + goto exit; + } +#endif + err = chip::Platform::MemoryInit(); if (err != CHIP_NO_ERROR) { LOG_ERR("Platform::MemoryInit() failed"); @@ -47,11 +59,32 @@ int main() goto exit; } - err = ConnectivityMgr().SetThreadDeviceType(ConnectivityManager::kThreadDeviceType_MinimalEndDevice); +#ifdef CONFIG_OPENTHREAD_MTD_SED + err = ConnectivityMgr().SetThreadDeviceType( + ConnectivityManager::kThreadDeviceType_SleepyEndDevice); + if (err != CHIP_NO_ERROR) { + LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); + goto exit; + } + + ConnectivityManager::ThreadPollingConfig pollingConfig; + pollingConfig.Clear(); + pollingConfig.ActivePollingIntervalMS = CONFIG_OPENTHREAD_POLL_PERIOD; + pollingConfig.InactivePollingIntervalMS = CONFIG_OPENTHREAD_POLL_PERIOD; + + err = ConnectivityMgr().SetThreadPollingConfig(pollingConfig); + if (err != CHIP_NO_ERROR) { + LOG_ERR("ConnectivityMgr().SetThreadPollingConfig() failed"); + goto exit; + } +#else + err = ConnectivityMgr().SetThreadDeviceType( + ConnectivityManager::kThreadDeviceType_MinimalEndDevice); if (err != CHIP_NO_ERROR) { LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); goto exit; } +#endif ret = GetAppTask().StartApp(); if (ret != 0) { diff --git a/samples/matter/weather_station/src/weather-station.zap b/applications/matter_weather_station/src/weather-station.zap similarity index 100% rename from samples/matter/weather_station/src/weather-station.zap rename to applications/matter_weather_station/src/weather-station.zap diff --git a/samples/matter/weather_station/thingy53_nrf5340_cpuapp.overlay b/applications/matter_weather_station/thingy53_nrf5340_cpuapp.overlay similarity index 100% rename from samples/matter/weather_station/thingy53_nrf5340_cpuapp.overlay rename to applications/matter_weather_station/thingy53_nrf5340_cpuapp.overlay diff --git a/doc/nrf/images/chiptool_relative_humidity.gif b/doc/nrf/images/chiptool_relative_humidity.gif new file mode 100644 index 0000000000000000000000000000000000000000..5cf1b379c74aabe790fcd0b74744b2271648227e GIT binary patch literal 633653 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%0D`+mAvVHOH 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

ZI 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%0AxCKtEy0jJ_uSO@pICb}`Kzk>xi32ug;?+1p zPbSyB!z0Zkf;ZBxB*#pkm|67bd_d^5gktWSFx%a}O!vY5*JHsFVI>=z+Lv$b=zh1%AHYF6CZh)loFV~_ZZpbdpe zmL}n3H7v6IVJ&Z>?&A6^OW8^Zp{r+Ho8$an}Dv{v=njR92~K^#H|^}VTI!o$v9W1 z9(M_o){|p)>FcSGQR51`S+T3Kw^@@Udj_&93bJUGZwW?i2Id)7g4Hy+u0m^q`I=}J zp;MK#tj+}a1mEcv(T;)SEsBmL{zd~xF2V`c^{q5Z0xHNo5+p}@jj2lIk*Qd zYf0KDNY)2iF1p+&U9H`2T?%@?{ct%>YNzerf+Dg9%B71UYJvZax)nW~rta*oU0ALDVH_?xH!Pl(%-P&a^+DQs1Ui!8 zh&e7_;NK5Dy-NK=UTqZygJHJ&PO%~P2@?pzQzgeHWqXV;7cahO8chp#ZbfSfKiOZ{ zVdzg5@SuxHK$nf5ARix6F&%+xS{%U)72(@W{+JSwRUX6sot)5{aPr=VLH9Gxh6_?d zCqnxeIo28$*sd)#_vIXWpt4aA%-^w5HkKUr_UZkpePr^uWOj&<-5GnaPh##C#n;H?< zjA3A+k9n{Kdqu_fy6=l7k_Gko)6F#Bb(px1PF0F<*BY)cd%k-z#Pj|-~C09@9%T5og zt#F-l<)7B59bP}a)O^Gr*;?gY6fz+7Oc?ux)uI@`cKHT8ij1S(*Q2$Uz#vA4&_*+* z${!(mf~sK5`I$2QKnX3yFf36st5}%NeNjmj{6d^57ou`EKGk8Cga{C1O2O(ftxiRe z14_hV-Ay!%&I_RS;0C65&ofDYo)bPY8xZ*iuo+%|)#R3P#%V zI|*dWJ%MMVVlBO9gy_<{jbcKxt{`W)dD4gUVj#EeUm{PB%|CT6e^9C6t%qH-d1m#j z<<<)WXD82zg`0eS*gpUw-@Yki>A$H{N(@mHVJ=*z{fxl(YmK7Pn6X%3Lp# z0@tmAQPcJJ0`Dii*!F+eiTH3Ys88zUE_->`YYl^-*-qkS=|MXU-Y2}f)8Ug)`J)4k z`yn4{UmnEepmx3Q;c7fzY->FyA)m=a92nbw@8#%ZK?S*>GTv$5^M*88varvWj|7TU*>b2w#NI5RiAW8rtVCi)VkSDt1al(IXP5a=&Dr; zsgO4fF0R%X2$|@7dGPe$(f6ObxMN+*)aMR+d4BB?&ULMF+&}d3w4Gv}VYa?({b1|I* zaeE+=i~~xh)SNP=Hh&H zluNS*U6ggAW;#@+%FV$8vN+@&0fT|i3EWxvU3if)vL=`mp1c$>$HN4a$1%aGK{k+K z5(`mThAQmcWDhtHei$SR`kvJbUX+K)V715A>`(1Q^f85>K7_ChLFtu2RvgHP(nK&(qYpJta>W09 z2%1<%3-3W(2w>}E*vJFOS8?7@66Dz};h0%V2DGOP8Y)hTxpQ>kie>|#g0rAs4)Wpj zrD^mijEns>8(XOCmXt$nM!X73zey{rCGQA|qM{WLE`H=tZ8V}-Nt0*Ue=#;@y#nfu zJVOt}7Hzm*SMnWR!=>qiN>_RKs}p;y2qy;tUNHPxIn;g+vbhe+iAU4;h6=L+kKM$^ zufv(J5E>N3rNNie0I0nHImr$!9u9dr8wNG-Y|RNRSJu2{W&g#%HT-hg>rbhx=GUC# zZ~RgL1<*j@ReMR_FhqK6-GSZ@38$~Qk*_ZknP<{ka;ucX2O9Racn(a z6N{tvBf>E$^q35uc93;5gR33FP*e>tJZ8fu#bKHh+p+y?7UgL>BB{nJd%hG6Z8 zcWN-J%raDO1Bz+Lm%-(U?&Xu_WA&_|0||MLYzlfL^DwBqflXNBNI@^f&pe;sZv!0{ zju5X3)7dNB<0yh1HHO_)E`nowDF66MT!yvXLoUDK{y2Mumrh`>%6NPc9 zf+I+y;&>(jS6$SC@uop6>q<#+3`{`}Xsj{5X6U6kXeZNQ%$ZnR3Dif7m;i3%NoQ zjCy}W3Aqbnl>@3+PHFk5@`Ao#&T+7&8o0Y&Bwt+q;X{%DswUsBdWQ>oTb1&z)pDE! zIb1>?#DjC?4o7JPBE3oy9sfR55Lm9tcj95_DIpvO)km+&k!r-U2%11`BX(cI)s56zyy)Exs0koE3I@#5n5>t%Xj6v$&u-()=u1Es7>gWpHSsvn2>H2}Qd3OW2?7in4TaL|vZ;n>8uyVP~B zHt%T?p{%l3HKaiFAlF;lOtqS3&Q*ve&gp7LwQWK7+-zoNdKy>}^qom?*iS(XRBWrY->XOM)tjic^Q9-teQ7Gd z;HlEX6mdl-9mQVSfV?<=ngi&KIWD125Rej}wXH0sV^(hPuu!X~ZY-yne9%e9%(k9A zVOc?XYp0CuLVRkPvXy+g$Q8C&I(#J;x!=!s_r1o9 zXKT;Ik6xSnuA#hazm|kivWchn>xRqYKGmLSp>ull*6vVBwp$JK2X0=DgS?6-UDks; zOSJSSlI|u#UW)g?{7BAjJ;-knNDmSe(!*t3!fH~72WQ??}kTFr^+j)8&=u=+7zw>0P-K5)fuz}jmN zh8d~~gs~BQS7@&~#zj+o7>clKMx^_Nhl6qI!?+{6;bT=`)HoO!_z2O*poxaP7`lU4 zv5BDq!~sQm^2qgD!dT(axLiotl11bw@JQ8~i)>ly1+rz0QVS|RdS~&-!}7oetSU&j zvoxaLVp%*pf{nH;4!@x32scsGx)h7fy)sTz1eFPB<&EB_;RJ$`wY8{XvEmb@HfyAg z%~{b}pt7rzwJdL|cl?uc{1xlXt*{NR5t+K&nQ^b|D;YCho{4c!369B^Zkh%%^R>5)9uYBQ z6}ptu4mSh1iPS3OG!-yBV66KxJEiy$lP|PB&9>)vvsc{6uC==Mh~^TFqj#WHO29&+ z*|43?U2vt(Jss`F*ie@{G47~jywuM(Dg2Lao>4pI2nhJXP>#@(#TUMR)0E>@6dhlrE`iX!-mn?aDj$gSP+u~sF1|UrV zGy)*q4G{n+tU^3JNM%Qk^=#{1_%{1&pyOF=9+esF)3-!TS@>J-3(v4Ki~TDulsAR2RN(;MXrYwt%p5Y4}ZBH`D-1=zY(Rm z5mUq@bYha~NE1Y$AHo|qu9rcEP-l_Ve`Q&7Iwsxg5-plb&Lb248v*)-5CRv0x-+;8OfcaO>&L=c2uj>|x0J zduPN2#MbN(ver)rTFQN7R^G|jIXsqLI5BSz>g*N#R4#i{3ia`^v)1#l99$l!vfcZ< zyWspW?#R{C>1U3Do{#LE6URw!J1Xw5F+tRPKW5222wTTp3haE5@gYQi3n}>gniP0C zW4ktff64iykmT-1hZNh#pWi)Aw@&+fto^g&ozELjKJ`zg@?e0gADtyRVUG`QOLFSI z+JVW-HolzO`Kl_ze8JD_`+N9#f&RoZMTQH9#bLv0 zTL*-rJ18^azQ<jLu})UrlZ+GBP*d>_X5oyBooKNW+gJ-$$_>{kr=vWfVy zINIZnRK7iqDd`i(=jJ0L4FLav3=FM zjsPLhLsVNIHJ;L1Jyg*muV@pPM9-F6Pp;}Fb170L63Hd{iHOswF$Ov!hDj*3Zy+Z? z(u#sQ=~d&V-kKJi4vd`Pa&jHyJ|iC)!ifh=Vvad6?@P`|>fE9Lnp|Xi-pwMRB@SMy zE#(&ySp7j!Ye0x2N;w>v+eUVsN;`2`&)Yq#)T)Tu2C*^9BJvV2KDm138(DZh0e0nO z3f;30ms9lp!5`!qs@nvNKoKe=>bmaJJA7A%_Zs&5hL_R4SG~0Nav6pmM@dTbj!)*i zS*pVyd^4CRy03rRa7EZ_{-gGr=>3U_mRHd|+VXkT(9*liQST+-+hfOiVmaxPG36+F z>4sx&2B07`c}()|Pl;#=sbj*-$)~<#Cq>cSf|7R5M2VpY10T+hG751Ed6d!+9ORDI zlqDO3rA()2{q=-mg{0yI)x+FTEJ&3os`%1F(twcnM+vAjh4++@1cXTTmAMtK7nsKO zWpcc)PQRdV*J6)~{FUU9MI)w9Q{tyZwd$bkQUHg;3%K)v1ZN+zuLOb27^J52Y}r6? zeyx}2tGS9osS@7Jkd&IVfNT_7NT9WliBm>R{P&$36V$JRavO@72=C0UltQslD78Ib zH?#(M50l4|n&=qM)W9n^`xyL=!j%bIPRk0U{F0x#WApAq$#;jiqlG@EbUk8mSSepvGaB&fT9Y;;lbiX-j?wNQhYn5JMd zddge?E=D}LecBP$Qi^V$i5Io@PoQOe%Xz!sL6zdZ-zdwQClTCOXo`@M;;|Fl(>mV|&b-Z%(_ z6jCwZ;Y)v$=w>@DDo|O!)sF^L4$*<7dxcR9@12LD@aM)qHYQ8FRhN044j)2x+4aQR z+S-)c1(E9bXW(?;X^ws7k6_vgvuK(Ht;29`Dg9CXxjg1{r-r=qw`h_9Ge$osrm`gd zl`IZoW3#4oVzo<4@I(g78)WAurzW05r0 zG==ZoXcAfuGghGCPUkd1oKnV(1jj|g90M`=I|?G0`%$+ZNLFgDB_f4vEn)72-O^)D z09E+j9a{S1Il7>7zhw{K8%d$5 zD0dVjSxJ^fU0fil!0{NHo0qL3Ayv@mA5V0jd9bvK4GH1lih5#@QZo)t-T7)r+`yG}+NWYO`_XzgB<0X)gaXjn9$wce(wj9D0a#XtInl>wC zfgPlb8TE3gJW*g@g={@H7^KY9#%a!Zk@Ev76}WF&?G^F;VwNwek-HO;#as;G2y}&^ zsEp6JuGuX+DENjm6?=!HYkVrOr!Y{qZ(>sexrbgT4Wb2RbdfVby6M5Lkva88i3ua6 zsV-;vWZCD39E4&;&G&?(!yrf@xT-Gqy9=oAa860z4q3FOSM zj+)ts-QhlVUElW>{js&3=ly>3d-UXN|((ET-v%1=RH3M zZ!SMuT>8O`hI}bl>*K6pE5E^xG~dsuX+Z(&Pv}_U!Zfp}S1w-Ih0J`SS{5yNH?yt44&CVhtM4wL8SmYz%(a zS_>7_W{++_Nd(`0b_D1CGEBqTBj_~((^o+;e+!jBklfo|D2OP=Z=jb%!E;_u=rsgb ziy>OY0KKoHd5(z)L=^zK6h8vlOKnt$HVmAzSX^Enjqr@T`il{Yo3cPXQnMk@xMcue zPospCu6!L8=X^=c>xtAFmeuRPt?>*W>(k7|K-O}ibU7RmECy@P@xq!(e;vCzrseB{7&AbY){iHu+F%c3n05_$L`*Rhf(edp=SrQ!;&sUU3G z?f{v3Rb=~9w<~zFe%)U8(;Jryc0(gY%3hh?w7-6d%=@^1k|p%hJ-8#z;^)jU>YOm< ze;ZsO45{9aK?0{jv!k&}qon&knve{~EBM<{FSrC1M%alVNvllNobL)bGKdZs7I3`t z)v1!@NfM~Q&qTwFWa6?uRn4kZqI|rBBl#G+bIF@S9Mgt+n|z|E6R~Er@a1Wqa%A!@ zXNSUTV*OW^4}EgcLj3Ie_ZbSzWk+|oYtLmN%6gW=WDlGf2y*U>T2(Y4dj^U~1| z*D*-eF)YwAs?#y<(lHs=Fm6z^?a9!(U zU7G@3+dAEgUAlJTy7o)D4qLjHe&{;V>pAi2IZNwZR@ZYe(Ys=&chyVJHC)dvSqL&^A@lj4cga|b%*@w($)|am7M83}9mTky$Q!tmt({pOZ z3qqLNB#;t3CF7%IF@*YX!o4NJ{WU@ZebWmSoOct@l@8%6PDwj`Dhdlk`9eIU2Bw<; znLWdcn`&(j80M3r+q>8wNJBVCkmggymRoA-?iv?s@FEg8dJ=v}1Q~lhmsf(J*G1P; z-XtEAIs`Y0B1AXBv)adjF>T$qssQRc=Vb8%dSY~%A3hJ){=TD{{2*%~OKhIU=wd?D z$$WtUR^7K+V@HEc>>*6Yc=qtjXp`Vo=zZGkX%o|6p{JfsGMfqm%Uu#I8{IcDy5GSE z-jPl0Ix1dvnxfmsnMtV(*t6GN7I1e2%`+z4+JJ*P>j$pAMo`ul@hToMeP`D2fl$ni+*u@vOzK+vJ|iVz2^eW%s*AD+K~}rK<7B$@3-*59m<} zEw?z_W}b(SEtN5zx;19VXP)3TncmRaU}rJ+u1!&ct)$%IEL9fw#yHy*Gl6QOIl(Bi z6U^)qQM5!DJeGrn7|l!`HTSkm1kKOVF*ze^qi>~|*$7tgE9Q%``FGW!_J!$GXgSp4gn1)`4i&E|7@gY54oi9#l`htt z5Pf%z<4ri0`GiG$4L;5nUwkNV?eyfrDY?$q9BjkDBq`NblzA+G5Zl7oYbI(y+1jYc5B%71I^n;x{>^1$Z9ff-u7c`E8@N6y(G{#OTxcEV6~+ zI5|Gnx>TBhR>M*VQuCN$r1Q=B0eibaZ#zm0j}q)OQfN0?Z#QP&-^ZZeKQr4wMQ5Zt zNsP6YW1FJIjqCH7^s!CSi&mdI!OZDapL%&-=rr`mWvs29P#*w!K0|o=*+?LE{HSMt z@+9B%cnf2!6pmcT^v3J?SFUk^C!?so*?!ZDRoJHtvP~+{Il?$d3P$xSrU5>T-+WQ| z?7Lk@_vA#kS=DEw-mN8=EL}`R%G!wxju31VR`pstgUkl>!N#SiIov8=-HYyQ=4w7J zfE>^1NcTpuw7^)KDoa=v4-L7L5@IG<35YWjgc*&K1h?(BbgYbIV2}=jaGf z&rF7>kmchx#%vpg&68)jNccz7j`JF9&7m(p1Sa-vUyuuV1$?2U78{+J16ahEi`&sWJxj$BNP)D)N|#I!Fc0O|+~ERw6&wvG5q+r#`cD$TnaZ3ZAv39>J>tBQtz| zlZj9!hGjIf?;Va^|C?%XZv0 zYjC6RZSti36q9MEiRRSj6eN`aL}r7V<1G34c^v45V=ewa#Jz_*T<^ZHzor^vFnVY7 z5=19RGNacRHF`w!7M+C1%;+^kL=XhgiQY*vIw4xL1PKx$f=D4fe)IjFv(MT4oOkbY z_IZEjdjA5~8rNFuSb8%EYD7ZNolk>04}eiB%c0WRDW`Eqb-J&zn;h zf9G7UjcC%spOE97?j;^F;r)j+8$`vNgW_ zN?pL#IOOQ!k*E<*hIzu7$GY@erZ47?fj#gUF+^*&`^r$#@~)Sb5F)hv#oOp<&LQIJ z{H6=YA^Xi1z<}qS2ECzobj+U^59LfAnr9F-`>5khKeSPK>w!jiwRZkIM^U-JTEMAD0_c84#YO&+x;ZSc*<{hqqBX3fdzXLap)^5~PM zx*ZKiUzq67#V5;Fnk13mgAhFN;Q%oouQn-RRP5|CQibo|Gn%f*R>BVL1QL0YK%qCi za0Qo2c25hN#+JqmzWO{9&tlaFT{*4{^y~C^n+h!U>|Dg}K1=lKEZ!a~g$CRS49Fnt zZx=c6@R_|jGt_+XUE9%G@n_%n&c5gT{S?cm&xz40gv}h}B%NqnE4CThg}$f>m8$J;~f`s@vLjUTB-4MWoYT z2;3#Bf3yA0vlYLBnC%kYU`O3m!3IPp%zyRT&UrW9sh`U=IpbM5`_c6uDM8X1CoMJ)oC!-*y*93)Hmyk2> zL(Y65o}u}Cmg94JBCL7V@ilXBuJ3~xUEW6+qj>|MEW z-XA4*t`G6tsLDvHZE3F90Hsgc%w3h7tyc**9+EO@^D)%pOp-x$2i=@+a4|hscvX)5 zS>r$9%ljKT>2GCAczrgFJe4}vHeVE*bK;pdql^ic(xvUQem$ENCiYzUD>~`#58)pF z^$_lZA72h$jo&qU^za&qcmLhXDS=bO-(I@F8Ufl(gZ(FlaFbYo`?|KV+FY#Jch51n zpzlS&st_zJ>Uyl$|AIYGV8T*v*#7kpZbh~-bC8FdI!0XEL+UlQ0Hqk9mw@%L$-xFk zxK@yWkw>YGVu5xpW3Nw{XhHi{K_4vndD|@ z&?!80LaMB;dGhfWF`S$W*ftH>+9S9Jzt&y z1)Q@DG6#dM{WV0yL%or=fZadEmwyi;`ip5!c-SOg^Iyc5S!w6~goq5C;D%jP09TJyG?tfh|yL9?as)m0TWJ2iFnMn1KT8M{(D)lJkJ z8Qb2@U06p4L-*88fS1tcKq|J8%7ehZ)v= zn$-MnD6jqnBKpravg^MhJAdK`BETmQmi4CavsBr>RcohXif_MAeXVT;%(AkjRI1_^@Gn%we<`-pPr0L&!rSFtTyax^-baYD8T0t|32XbbZ%q|X?$8>xX=+=z zRmA6cOKVTRAR6pX6f)HZTo6*!E+arSySx~Zdq}Mq!@_e z6DJA;4Wgm)!DM^ub9}l>;J$thbmLR zNl)#j#4@;kOcK5EH7a51%vptGY$4h)_`%%*!67VwYE8lRB%y#JSRa-gbg6&|rv#xo zI>&Mjc3Vb`1@6CpO1n2}Al^TU#mj?5E$DF*E<$)H!aDjRmf7t1;3V$%(Rk3KGsh;) zgM~VdEYu=ca(4`iGFhQjep?V|B5pX4(YzpYJ!TkM%p0BXs)@tx%0`sK zN&M@omKQ;rtJ*IjkKpP2;ad01%wpaxG@QkM-`Pr^{x&Hb8uhJ&ad2?zY~sqOd>wA| zJu|Zqard%^WXP!Ogv!aHat4>Ur{lK}uFA1W>6qMuXTPPH(nz~E*i35^W{O6zQOSPS z3n{}d05$R@v?~FYN#aHbH5MxGqxv+oKayfq3vb~sfMZLr$NAx?dbU8KoJ28B&YXV2 z^gZea%LUe;EoIWzy~NMW%ee3exQ8?zV^|i4O%c@NtG^$ywfs_eO$F<$wuj*vbnRmw zNGm(7#eR907Z+};L^_c50Mot*i20&>s=qes?)KnB)eM40Y#@OwQLt4s+Ng*X@|zY;`c>|8ej@MPKfqkxy%HTcrf^MigE6#lO`tu6ds6=uwDy5xqF=X zb!8$-p#6?~X|muyV*DCM89hQ)>OJsn6mSs|a*57=-RkE+U_fOGSTg zoL1a&{};e0bU_!SZb0Oa@rwiQx$aT6_trB}&WGVD4|bL7u`e`M_q!J# z?6vJ*-Sl1ID{F7oa3OF$oOW0&66_h?!}_PDt}z5gKoRHUB1(AH8PzyD*!KNsn%`ac z<-GKWD||oT(06_Jxy>N={(FYztMGQ&r>%nprC7-t5;tAhuvDOAMws6v{;f_QHeLjZ zgwhj={eaPvRmi#-?G`6zHwFVy*kBv<`Te=V!0MKMTd!G6_!a7OO*5_sWl?%HZvreB zk~>r9ArqT-{KUgq(LBlpn&5bm_I&3juKLEUGoP+tuCOES9y*dm(Sy@q`PNdJW~k1| zvYCu?tvDf>w>rZ4v$xK*T>2Sx^Ks1JQ)S6dIm)MZlv48nyF(uxTND>w_49mVMq8by z={x)7?+cxiZS@gP-Z}sHzDQwE>9O@^sTJyYB4FB%O_JG7njpl{R};@Buc==8baVcc zRZ^{IA&~do5(K*<1!2aM=CnRkaEltCkP1YE&Kj75a})}8u_D9!%D_wj!xV;QVBu<= zBVhxU=h?>sOjQyGXJPj%c6w;tXy5_{3`Kh?anj)!C|lBUee@Hg=4ZI5m#W^zX|f=m zg3&of_j6&fWWosmuDxA}V+SBvcLf=qRS;f=lI_Zo-%xApW?&@@If=0huA&A3R1Qc9 zmLU+&&RV?cEPy}^g4R!IgJT>)oNg4KA0b$Va&Cadpcrh}m`_`D+m6{Qd&|5M*LlzD zV2V4A*7o)ft^h2B0hZ2^+~bdCyL(d=P`J)F?@|y z4DBXbk4b|ywICB}SBByc8?)RL%TyM)N3q}-(0k8y9U(T>MQ9;&%!PPVoeY;0A& znxBmHaPKq|z<4<2B>%`x9;@&m8vum}PoMA==k834kAR23=%~{)dHd2 zOGGYmYIjwtCz;Umm0Gz0b=!g;M#9^^rVdK*4}47(C4+`X)4C=2ae>fL+t@=rKpX>M zt299!q_b_NygeTj5R&oI0GhxGa3z{lgh6&9Gdu|yY?T?P&vwx1j1(`H?_MUksyaMX zCLF9lW2edeToctm+=95iS!Dd=9C13%hwb3fh*ID$TNB6JSn$Ogk3WNCF&Q5HnTym@ z+OOsSaDzoCi{?W*hdvr}#Y#4rUjYj}+E!6IWzBsop0VY1gV*lH_QeQfTjuP?bjRWh zUM|?DQ3~K=Y*@M8Dw(TFRbaXR!P#qu7_ryc9p8; zXIdk4e4zdrfI4J~N(xKn2ywo`ljUUn)c4xSyfc0atiV76V|)b-OOxlbBrDFu45Ytrtn?yk|_G;hAJX$XYmD z1rPPaUxze>pRv9!&6NWoMkd2w#vgM>I#oYQm!R+eKhUQi*}PD+o*9B znhfN$GePLFcLG|#@@TM(3nakuy0TuVYGX9700|*ssDj z>~P6nuDQLn5Pt4mN6WR76jmJpZT<4yzYLj%OP;TLx! z>O>>p+j!awEsJ)$uI|RZd@21rn$y=!t^Lxeg(gf-F=n|*Ri#5gD3{u|B|Z#q$!Mn73L77nqmI~drLl!%sJw@Jc)S&&v&;bCK6P(&LCL4xIyK7U zr&6H*o6ahu6r8uuD7?F3JM@QbcSTfp)t&B|p678`&8T$R+mT1$8R~JI9l{Td+$j?%zQIfe z@s3{ii^R)e@BR|u=biQ!Ktl!bF^~`76Om>=J;S5it)|#DnZ!Xh-gv1iIL5Ie28vI26Lf%7^5Tk&N-<%HCD)tlwTqQ#-X;#JLF9WuUX7zLz627xKSPaTpI zUD$`M!e3>TjTQYYlq(!%{kB4nsAt-YxqaqGZL5`_8#D>vAc$OG;RR$SiyR1k%n@Uk zSV5Q8_kk4@F=hi$^2NtM+0V?X5>)p%VBQ4}X>lL`9Wt9s_DE7y!zUQimDpM+Z*+DCJd=&9#3)RP|l!^)!SDbc~FFxUOZoz8%Y$H}RW?2l%24xK;yGF|Dl zCGXbb^&#M5u&HJ4;zkfFDElo4A{F&4xA0khdh?y{Xb=Sm!h?9xFzgWEMhUh&T)KEi z8->=aUwz(~u6y}x%-Ky)^dXa88z+pwrifkCQ(zx9g zk;i+BEa^dT_68HFnc~<@nd?fUzu#?hFHN#=VnNs|Pvh1@uW?W+I3d zvGGd>l1x=~0D8Ms`WIz~@!x-~vi+KsLv-c!bd`-h1U)p{O-*sjS@Q~C^L&67#{&-{ zbWI_6foY;_;Q60(Fh%&I?Y&-qe9B}5CB)B>+2^H+v?}4DmpB^tlMicLFaI*LXc&>bC6&0C|xTJmlTJE z%tGPBpz5*d7Wwz#3*AY z=}#0-PyQ+sa!1qdy0a~5Xe;N~Yg-|4%X4E>=F}!!9z>JtaS8)Ep>~12EA3wtBF>@+E_!1VX$X~Oa&$^E34Ke}qdttrMp_Eq%N#4Gp_KzB(A zky!g8P8IAWv;G_Xk_Nb|9EcN3hz!YGoqIhU^`5TpJ=aC6;|#P0#m)`p9mZGTq13fg^Q@cdN$q38A?b5+N1g`eYoyqkM+y}{y(3N)*G z?Y`JJ+Gug#;}gU@n(tb#Na2SF|3_?10jF|CAVI;WFaSq=OuRmNLOOkED~+O7_2wsD{qhIenU?B??{N8tOiiI| z=s>1G$eG1Ra4~s1C;sf>kB7%U2tICwlWw+HbTkI-R$QfvfMlOOp+oqDRS{G_SVuEK zV8sz_*ME2(luI3>uZ!k;q@=zYgQr}6$!r6Zj^Lf}mk!X7viZNI(E!PF~KS4P6rZS?r2hCJ2-Sr`1W4`{1IJ z2$|B6PCjt$zbVQghLY=h{a6uZSo96Rh(Au1exir6JJKvcuoy$ftJ|Fil%~iQqs01ZcYs-Q} z3aaH;J&qF)N(hRQR%O>#?y?7*gp(yVBdP zSpEr@IEnGW6Ef|A+&*-Qxf0dmh8jFnl;9*0<80OL0bFTyPvyB- zxsNl15`@tEvB%-Iv}IZ01grb}dYr`C5(^z@y1dtqaj`rxpG?5YOx>y%Qhjy2j5bNi zKrU9oR`LdSjhhd++^E@m{=gYSI{j%9<7#}wOFglcNwjZY@|co1O4HF6twHJ_cfn?C zZnoj$mr}3x^>S0fs#bcZWpCTrO^c}!Ia+Ldk(8P%{rm6Pa7<1$tv~<)o+Or)3*40ulQ2o5Y zg#dz-GTk^nyA7gYa6>c*@0vd)VV!V1HzdZ-U;C`Y;XZj@6TqXGUQCS~`nT3=|Eu|rK=g(g% z*wrvpHA0+DEbt;RCNj8LtY@2>&QlY+;Pjq+-FqoXl9i+y@Xd{+y)>xnX>EKtqJ9m+ zOK_1Gzx2YHJydagtV&5*cosZGfn<%QnZf0?%_Fr5j0Z@I$`Fg6!3xKfbEA~leZ|q3 zfHyVsN`rCMQftnx(CQ=eJ^81gj2A~Ou^^`SP;EuKb4QA|r+L#fXjoj6?XBDL4_FPifnwyPx%hSNMl=$yTa}h>wxU7mF%^i#z>KG6d_nyWp9@}05UwZ2X>ow%L9R5*i z18NZ|M>`twLZOhsPWPofG7ng*Me#%?4%>xzh>YD{Cy9Nv?p; zp^4JX62~L>DK1W}9SiAHLb(ek@9Cz1U~qDk&R$FA7klT=al+4F3z(QaK6p*|aEP4`OPQqlPz@Y}d z!B?#7WX0wG&q&h zX=24#H)5FYaMczCUb01k#JC0kdwN|+`{20uBIh!np_jzZQu9a`p9gn9~X_|%QBGx>H()*`(JDZ^qPgoPa~o@OjjbVIa!xKz!o&^C-I$IGq&%Z-o5#Ut zuv*;!0r|QQ^N}mr+Fo?ER{Ex-VBjk}KLNrEO@^J@T;%Gc5D_NR`Cn-Ppwk7MQ*cp* zVdk!@5T%IG>U>F~=0N19;O8X>O78UWN@MYn#4D4185+SQIS5itB1Hm*Z>1jCA21Vy z@MSS}2s1I=ZEx>b^5 zAPQ}yV&r~oC?_I0nL-@;u>IYEO#GIicXc49o-IbU=t_}96Ns4(KGcpE#)|JUH@g4_tOV^3m%5;Z_6t( z?yx$puy?H87K^d882k8s^Wn=+F_&JLz5M(%B0}1^>dQMw{$V9}J==|6fBId__DlHh znI)m0sVBhFScoPTYJ!D1V&Q&RnrJK{4NF^qMb=^Ida5~W~_IaUTM`IV8uNN;z0F4 zb5wr7U^xmg;wi1~6*}xCtsiDG66Q7%9y$_{rWf3b^otu&Btsy)ZH`yFsw9b5b#RvgeTLM<_rb3V%w*uy`az52r%b^Gk7i5cwG4NnC<+WK2fPc6>EUZ@a>-%tt zS^-){p%(!jjT^06d5rlw^Mli(mN2pCHVVInTa(7{+&BM_Yayho_a{|hA-iXB@|T4i zy`?;#rNVrlWShmWL97z2@A%azR0Z0sMcVijEJs-e19QT0bW%MG#H+3a17rfh{>&L>c5QX{le| zQGG#zOmvzrW7g$F;t4Dzt#$TueiLOhVF(g0_?@GW8=di+IK7eyQCKeh=d^RC&pU)D zV)oSl_NVDVTvRlzP0uh%W)+Aya9$*fJdq?$P>WnMdoDDzBpQH{jWNccG`0zm^U zDJ`5yih`$#jxP?W#Tu~MurYlo8y@)3#okPymmqF=;dP#f*4C5>HZ7D)b4c{m_yo`J zr=JrDOR7~G7m&ewXFug|Pe}?z#D5;?9~@?PpS<2=ww7l3MrXG9(|EbH4f}n&04p03 z+YK$5lrQ}z8*^nyFXHvQsb4{ap64gaose`U#<4DptFvVerunrSB$lLEwNWFQsPv*R z^B%T7FBp5(gXgvCXr4|h#2!gJz3+P4J&2uERn>En?q~^mjw_mY?TKjBYmPnxBh^A9 zhVt1b*5}J<+j&^c)#=SSmX;)*%`>kVKV5zH!DWT^nZrzB->i(~^ZQQA51dw>IIXTa zz1VYl`OE3}<*I{Pwpq;}vc%45AznXO+I|H4qQqsk5lM=dUTHqGblfRpM`u3{H7;EP zSM5%yDNjBtwCt5Lo{!G2^cl@4%!jE#KzK8kZ}X*iV$ejHa4zU;FrwdS;g&SPR~V^a zyR6-JUz9YwH44BrT1;vHOHuH3H%99I*lgiQzV%`rY@xIYUvb+0#{{9LSYfMQOctTC zHJ>_A0<7!iLaK>oKB}vLRnB$RW>o_`?|U!iv{(anlXb zF+_qe9Gb*wa8cbGi1r_4UQ2KAIk#9&X7zfR5O=9%&+*;^7i{}8M|;9G4dSaz+00A) z71%2B3Udqh%WCt{__)U%KVLbEB9C~H>u!_xHOD5?NUkMT?f&U7PVkM->l;o&h02K9 z9g@8}f3Au3^*Oh?&Z%bUnejpML~Q;n8@K6`GAM;bs^=cYaJ5mb$ff=!t@EbINBxqZ zId+nf$*il(GiP5F7NJ~caZ&sHUvI<@XI?#9Vm8QTCm4=T0Q4>OwO7+=WL~|%=%+k+ z>B^RMjm72D=MLU5BE+149Q7E%TRcF3E6B3sYv-;<5tmADxmS=EF^~;q1CBNDaZXrL zm*YmS#0Krk{6wMU*@rjAhNK#!@zD>3FI>_iyuqf2(x-Xw9=RZO5^6QYCg8uk6o;pK zDZ>X(##4I@*gsB}2HF?!`}BIfRd4cEX7yTg@~H^$sf_Wd%J8W!@~Nr!seR~!(JTte zhSb0DS+QEEe>f7g>vKvCRmJw2R({7}KmF0`oo~`B%yGjv`Ayy9d>LX4=-c0gip)#h zfBfd~-Sf{=6OEhLhbdRwQk0*VoYD5_`+bSt-|~Cf^HIGEKL+3R2AB^QA=?)GelCq` zx|_4>Obko|Bol8QB~soSN>=n}$|u`y>D{?$U%KD#MyB!i!a+gLV-HPnJb}Z<^i^Jw z?IRx$0qgtbk2F#4Dgo@Qrt*_79l5qB3^#^iR(WJD+?6qjHGs^n__MN_mUcFK&lpSu zq|xuaaymy}^7icra9! zE*{g37Qw1bjI=M02?@SN;=8oY#>hycw!-0e;l};F2TP+@H2EC_N7br`$7RgpO^zYG z?jfpE?y9$+Z4~)K?hahGCL&!7cG4EcR}SEJ19*5xq%O{bzSxOgPHUR@D3J}^81&Kp z?5ckw)bMVoQA4QlqfnEnP}8Zw3(2?WI){?i(ytC{w-7RDzlNTDC2vjBZ7P*waWduU z*UxmF08|ZPe-;AGJv8e$w7YQFYkBB2lIkL$6%<^Fl&IJKQ1P_!7Ac9LrITQJ_ppV0 zJIUbdV_GV$Ffe{xL`)M!{!Kz=Z zXFv*GL>d{AkO7D@mwsJA(O&>%pUCgW5eZEKpax%UlL@4eLrZMV%b%fokx&ry295n@y z)*q=Gf(jG+)kX=)+CVNxWR2Xno2n_#BMGpoPNB$#LducvR+yK?)iSfIULV^Q0{T&e zihFlc?9I}f-fvb*5E8b+oM<$1G2iT8lIhUIID^O}8g;V>q#wyjc#h-2@l_Yx)Kv~J ziHX3mM4R{MD8KUX;@!ih3tycD!V9i{sR$$r%FTu;g50EkpwVZNnpl%mh+oXMHk@cp*HFEfGP zW({FhH-2n93V+iP#w2$&;C5K@-LO0kkk|PiZP%~7yAgBe#?e3`!<+Yq10CUaZv3$9 zh^f{8IdeAl-)InOU>XS^funz=LH^UEEL!+aX}6Z?zn3UDTv2~pqCgq<{V_!Tp5Z}-^bi&$zKsl%0L}$~bThT0F zW(tt}GL1TFb{`Qs8~3>?{KboI zo-@xyi#y)G8ohbq!aq%e{AGw-Bk?x?m!Q%h|I`rqtc`XGc$GYp!W0(1PS0cu6;6;X zIH0C$+$s2U<>+Z9;Ku_ppskK5CIC9@bA(JruE5faGtIU$P@8`=M1Ci5SaPc%biupQ z(Db2X*&V>@sKPrM{M@4`wx1R#@quHui&N{9tL{1I5=qxm_LJwYD=sZ=7rLLRsi;)1 z#>NqggOOsOJNY#}ISSp+c4``jkN;7L;$K=dMe*9z9t<-A4i^Zz@QA5AalA&fAG$6Z!X64JwFu>)RM*D25@lX*ioUyJ>`- z!zyT0fLa^w`p>PJoEz#z#rLop0%a}0=}){$T4yJiK?3(2rET(Xrv*it|+n5cJhDkeEpc^89E&d-p-S z-2b6fbC8Hdm7+Nk4F-j{KO`BLlrpc{P;0%kAlq3p>c3O)8x)2FK!7wB2n4!-t5p5} zF$F79Ovia+v@CecPyOz6RjAQ@`@6y$VdHyOAFVaYJFwoF+HU1G6svoA&>4NMVfp>n z-k7QPKaQz++}ODIgv6xel+?8J|MiId`-2Z3KYczt`tnai?8BI}5?F<1M@KWoZWN2; z1yiH0lGgQBl7qP^e>~$>#;BkS&D}HUgD>In;?lF{%PXrdUaqZgyn4O)W^4QH&b!^c{r|}|-k=f>ynp)~r&4|Y_8kB78t-DM z&v9yVZ04T9O(~~8nq!stdq#!S=GZ^ZhwS{(*0}wqq7%g&hoanWAUp&?za5^4M6W+0 z9!rVMEy}$b$Y2?%!~RQj><_FDoHivVJ>`b)X#EQfbSTbU|L;km>%BY#iZ>-m^l56= zx%fcCJ7*-0F{2&Nk=|arwm-v0R;eXGXHUmbl;a~~A$~@EPKDwB2KUw(Sq z|LXDX)oA-=2T-GJc?w23ep=jyQ*U$82)bLM^ITLziSuPB?ch7A-8dn1(E_iLy$^;%O^0ihiFm!K21eL)L^0N;Rnf0j-D z8|{n##h?HGb=l-^S*)lH0l>`#-A6-Y;X0#(pa3+#5Fg#~Xvj->JOKn>k?W&l#Zy3l z_-m@Qi49FDjs+Fq35=}Fn7l-mB@Wy*Xc{L7BoOCyH|8)|je4Hzh{Y$1WL0gX3bX4_ z($CCs5^z9h2{E2_n%vKH#t)BU(2g$F2BRdXv;AyjCelq>iStAqC~5{quQnK@%_J^X z454vD<8gGTMgX8^-Yy1l2^XMgfE7D~J|^=)fC4{RR~?IjudP9#D7+j5rPYgt!qfsO zVB#`$B$NxD>jHpeS>*=daypcFARi7u5cGb<{WMN)Mj)a?z%j?m0=e%11O~QKk7LMT z1|W0-jzID4?8n?gaNg)O2oNOFDZs&#O94P?el7qC3Z1T`1tORD03Zz`4G5&km8Jo^ za(z(hXyHB-DtB-%lHWN{I8FFxRl~I$JpvYxd6>(WDlnljP4j&Z3&BP1H^w$=K;;^e z7p~;u=vAS3A(Rx*c$ZOO1%ob9m{!HXb*$tzpmNz0uR;r&U9?cjjxHoX@HGfa8O} z$nAq#1`L7;3*io3Cv3|19w-B+{Ky0lO2T24=3#J&HviACl2{O1G!V<^#)|Hvb(2Ft z06CoxV1#&UAc@gg_8cFehQLD8dg%bdFdJuaKa?v=kT48bVF*aQ09q2mGu;orVy@>O zL;z0FcN^$fs~Un>;hOJHz-D|p1`td))WFAQ0&|nW#RAEvb}u4+P#9cVWA`H^z`Gl_ zKR&PMJ)n$Ukoia+5%Lny^hW7PY^+7tv!2tny0)3gJgYXhF%mZIdM;307`M>`g#Y2#1d$x z^&zJKTl5N)0PQXI*Qh3N&m&^F>f~*1jV-`L5+KOdwTL9r^EELFf%Pj5{tPX)b4^(Y zsB)oUnx2AA+#3D$tWqDYZPICEKtKfwf&g1=M=1ryjctTWE@6>Ycr`rcGpVtZ%JYB6LSWMbtPwgkpyI8LelYu(EnLfaV-Pc>kc-kgb?7B7}*B4hBL1 zEDs2Y9cY@%#wb@wGWk&Kgd$a1?(Efho~^aJ9ULxkavRLuOGy-S5p?3iuO?%4W`X0* zHJC}N7ApcnQ^9nQqce?trc?}q(;{S#HJHA55hj0KYjl8mx!lOvhB$?vh+R{+4J}WV zOIA-SfaNXrf43L-#cP6LsI?BiMgdTD?Z|T!2>UQ$^r4aJ`8Vof94G+XrzZ%Ob-}?$ zZ-GFp7`S>81*L)^Xe#Z=Xtu)7lf(3-OOWHih z4a{DR5Fre{{gA1$Sp-hNpyfcy+hCe-^qO~*8Cc^I?q!8?rNRE7i-C>J!x5nu ztI#F(I9HAQ=42PvzV;{Mac7xpbb_XpP7E06eV6jS`ORH`DZFcjZM#3Yuo0%wd*x!u zZwV1t=~KTMisPBUYI4gEk(1S@*+BtBSLZ1OX#-G$660e z+OdR&p103JpcHo^;zYftyJ!95t9`|eAVv($70wB4aMt+}TI*wjuE&=9@i`riE0>Z^ z!CkN+oSZ}u3Rt|;eb{(H$nRq53#ErLFgfmYKQLm=%Rk-L;zT~aSg70U{wrAQmkLfg zWBdZcyZd-qL#0P>$#NZ@Jr8bD#2_r$ICcOtLmz-$%s=jnD zgk8=~Q>|tWFlSpAozZXKu4MVt*PpW%-Z8>Q7c!#F8U83raqZXZNX8fz@(f`Ea%RN~ zL*n*v+2`RsL+_2?0M1v3x9AtsoY$=0!HF1nr-A4tzeN97VB2m))8geVRXQ0XsRYvj zwp2~T6Ue1N1wOmbejT~Kd^sk5`4vB-d?HQQRush())x_+G)*_U7I6<9@=_HZ;}Ia& z2w4jT7nNbZ2SbpH_6`IZR3r2>0GyWNhL(nW0A0S^EUhHxtWimdB#A2##DyV(mLl|L z0>Q_LG~whZ;q$@g8iOe`(Xv~?(QD9)1ejhi)QC({@Z#S)<85=} zJE)c<;94y@{><8SswMwp7_8}IoKhvXMz#?>tM5}b4-?VQQ&~R#mREP7fl~A5K?ian z+xT<(;Ww<%$TB`I4rkQ5;A2PqMv|Bp`&!&wi5qCb}7>eH3_rPSrPj9uT>EOj}q zr5R-T$8!A6@4?4yCoBM{X7^{KcIin3sGnbXyj^CD4>OPvX53M)!wt4|Z5{8pJb*qq z8*pgc*+{9NinW~`&);_(N)x^<3fRcFjpcTI?=9$R*_tY*CV)-5|7|t?zs=_V)7vT) zRU0YN?b{pwsdV?>2z>srt+Es^Crsm*@Na?7tD><0Q`sMZPgz(V9m}BiR$=6u>aC*a zBX1je#d+QD2u{qO8ACz%XT+Aq9!0 zK>gdTtaVHE^eHqFZQWcr#?uG@(Dh)of@xpk6*1+8UYqV~kIx%8@B>i) z(;2h)U#9(H^Hr|>%h#pYB}vEOtm2BKSc7VvKX(bCc6PjF)zg$bB#u@|XL`#(&sS%| z@$uYi$>dlDIQY5TQ|vv~s61vhpJHp>1XoF!CJ*bUEnYGfx2lW-~a!f)nM=*`)=$@XzV*P$gaj#veYO}B^L{cih`K;G<-S_pm@9Vnn-|zc9j^Doy$6*fd^ZlCh zJfF|!<5{1;b-exod30JM3f=#KU!%b4k>CD`DVW>O8nX! z3#(9!uE^71^ z;NOfdys)X6*PfPPaw&F9Qfzl7o@2&XVghW$`|_`>Xe`ZV5Y6P@W;!19eVgU{uiO%r zQKhph(r@1g*BtK?OjX>pxEXUrY5*U7S4F@)k=I3z3xN_u)Rr(~R_L^(X8w#fv@fcx71pZpq08HwN)=1f4$Q?5wdURFg32q#9^Sso^(l<$ZRLPq}cSTK;i|v5auk!62Jg|iMAs+V)h_w9IvB~VL@J^nk2I` zV4^G!B0T-Eoh^h$si)9@%2|XZ`4zr*jf&tW1aPn(W>J>_xLwx7ncSj5c>8Y6NfxOq zY`&2Q5rC+SgOhlwUyJaa=#QgNV9k=r_<7Rf7>XZcB%xS^IWUTNsuua-n+yTb9-9Om zV{9ZN@p9B=X8kb_QN;uT$J3EWMIZ#`OH$a)iH~9MqIfK#01+&hHOCRmDr~`rqFBdW z$A@Usk3b5mJ1pMOqxzF)(7jqzJ*ncGZtfMGkUs?(}Sd1yWn)PAdi%DqTTFcAyk<3`z-k(47jIP@RBwe|VI$oy!tk-3$Hg~AP zTZ_@>7q(SLW2^Krx1N5Qw^d(iTY2)(!1P3O_JQ`%JsY0olMB1@dz0|jl}^Vt>Ax^r zZ#2?BcKX^0GYL+-8 z^2Hq7WUMlKg`ay(ZR3Nvh`r&@T%$gRX~8~8qeCiPUoUs(C{D-jy|{4!4w%v_FV@Wp ze$%Pvl3Ig{U-)2h@_n^rDIUprE`fD5aTcv61*^!6em!H=$i^X677jZU6VD5eN|@?k zn|&uJgJ@#sP!eS4mQ69b-cs@{)h*~O?edvp$0K`bz2U9_nO2~lOiPoDOmz)9VVIE( zIUL__V96eIn0n|g6H}i_a*n_!irmY4+E$vqhNEs=0=<#DS#pMb=!5jP8bPxNCTAE1 zZX6ZurfsEbmICp1p`K@nK^-z2__)%4HE)a#QE`XuHK4*Y`C?G=;gPrWxO~(z9I<;z zI869?Uhy}cFu^H0I7fyRQETCnvX-~qRl;naVWaKQWi|%K#yr`35 z)U6;%xM&T!3yPg~ud3tVLR9q(c5ea=`$=b*790z0O8bxYpLZDgT`2U1u48?9zxE@dqQRS9PZBh1 z2VGBJpXw4)l9II;9_5UbH6pWV@rTvZ!zELJo%f+_>_Z@e3c%$2cC@yvi4` zBz-2V|M)CCMB3WO;Z+DDuy;J{#%gd-fiQCg1$ND7L#bbo1h;OMX~1t=ddi z;ZpMOCG6OZ-5={WFU7T}iNgT^s!f4!E5T6!gds6&Q*zZo7L+mv{~@ScBo`_Y)l1>v zw?|t)V{Px(;15(aW&~+Tw_QgH?QAoLHTvH@_C@85NEs9cx zG#xkGj>hxH7;DFvI>(rW##rRWST)7iOvUWqjv?~L9=+mKbk?86BQ`(X8D|F9=LbGa zL^)d+cbXdTZk}VVImacgEMQ{T)_@G)Gw+l+*nUob3mFYxhjMJ3g+X8qnnq0PR>~%^ zH_pNa>K&dRC)6YL-v)z7(*DBTIn{feQBoU9_=BKgEF%C*iAvBxe>`zzba4f(nx1 zs&uIA8sk_Goqv0ZZ3?jEQDw&a?_?OiuSe?8^ydm=bJZB>O)9L-x>FrA0buFsaF2a} zz_1@1-OEHXT|UN`4GUwBp$wi)w~+?NC!7Or>B|t$IPoU|bO2>>tX?~Xy;q-|8&F@v zZ51V)XgI{Z+h(Q3tjmBmpb`#oaAgj_Qm@8j5SH-fWeG}4IAdRZb7sng`b2x}zpnN> zZ_&@?UGf>{qGe!lKjU}Co26Xlz zIET8n!wxmRjqg62UGMCwBzHCbnNgB}t6^tuA5U%?vs-LpM$@<}Jl!&l(GFRiBi##h zckb7FhA^o%d}Cqz;S-Jr3}3NJM9WCu|0=*Ud<{-e_L+)WsY5DZjenL}7asFLGtRGo z31mikch%0n~hCefRA*KS)7k=EQv zc*73|55hrcJIX|t%CykE-^(j?>Hgs`9)ubIJyWW$hDdiO<>tohIhYsDj$MF8$ z2093mH2c&2mNT5dS#AhRx%Li=v~ZbmKy!7nr5kc2w>z>rny$qWp&3T^ufUrPZaur4l-y)3U~sGLt23u&tEtnCG+9 zND2j`LJt^UlUcM#_Rs(;OpzbGrGI$Vh~aB4I^+8{42PCW9w+1VKqDhZ@JyKFh+nHh zef62$r8u7xGLqEfkuhamDx`S>SKr-iJCc$58RE->DelAYH_P};XB1q05G#N`#Ocvf zqE~VaEa=1V2EpFB$mA85NbR(WC1O6wgGp61HP;4u&^F5y)%K9mfKn;2-;-?HR^ zsFPs|YkI5Jp0RZg;WX&RGKeLoKjtO4eTFD!P!Z~IyKg~`#y}IyKyt0AdpQm=3>)Dx z`c#xao^IhQZ&RO-D-CL86*7VrRC6!4G@HOIY=FGlT%Bfpww;_aF8ES7?qg9GT&4S= zEB;G;tK&+B9|d{f?R_-HKoGzQ5$&d70G1X+{HUcQxvt+;gNHpULhf&DurMvG&IPq}az9Bj1tYK+u&5jM-oZ21#O84TjFy+`p}CM6k=pJK0D<6LPLRs0`C;0cNE6kSj}=H zQ_+>HBD3C)26txBcMTuxvcYVBJ>VEI0k<1OeID1_#X%ixLY_Z>2M2-9bkGSm>4%%F z8ybS918kr$bY!^e5aj9Fr6+>~iTOcoc?v|g7@2f?B;!!st)`le=QgJf8dT?_g{=%W zq0mIj8;<)%pFdb*>DsrXdS4CF?=W=Jl1_1Q7V&p&?_l7yN|F!XzTDRoBn?_KE^x`< zIpSn+1n3PSmm{7d?GS8QV2c6LXxhV!iu^JJV8Bk6@@joN3`2)a4!|^v=VpX5sm#I+ zALb13gyY}#kzQWWa)e=4<2^}6&L=?S;kV&?Wa7)4hoh}{j^s`|yfRzczkLJLRtERu zo-aqdb;7av4YQVhpN6&Z?cr^nf!@Bq8(lE(fY=WrgInR6+z?)-Q77H|q%@4s8YJHt zgn|Z0nQ$k2m^${w-l@pf?Ld1(G=ibLrPGUkCYLHJlpZlGuy;6XIKQR^o}(}=i1heS zkjxL?=oo?*mBCVfL{P+gmUKGvI@An-;lT~&B;Y$NjaKHNd>~|0r*cW4O-sDtdog%S zsO^y!m>0PECT6wu{Oa;6rHA)dKmJ^`eK~fQ;dVW?%0y6pb5|Zmg|NN_kwoC0I#d~d z3#hhJPr!eFsn7D<rfUzJ61u zwf6?Txywpq|J5tLou|_}KkZ5`J^umeP93Vwy%qe;khf~$%lAgK5yt)jlA8!|2N4(s zLZfwD2bXM=>LNQF=SPE$aJNjUO?_;3u>)bO+=#Eu$Y*7c1ru;@iVJ_qL+~(6l{VC^ zRywFwSm|kZ=(_9Fo7e0C-5#f9&mZM#t1}YztvQ}o`0yGePrnF_fnK<5!O9JnFOAMkuv1~foGkxpA3Q*i+lk1JL(do4i8a7S^_R<#8bBYIQHzG4b?Bm<0@ z(=R_+9gSlK;ZU@j!!RjE1JcB=NE)8)i1M7k#{6FG$2lWcLt;-rPLSoC3ufZu6(>r^ zw%1^(F@g##_bo=689c419f|MaW50Tl0e!@#6tRam z2SviX+E743MVUvi9QzH3@ExKbS;IWuxtWABknjpvhR2vO>WE8A<_(&o|o zVE!5wWZxK+-Z@i#{+Z>ze0Ib^ZX163Xa;T1M6gA(x@iw6YjesqQ<*fy@qFT5#o0Z( zkiL}N)psu+%*|_vN!SdpJl{4Mu_PQdeD&h%*+*gt(XshsL9ds2GY&1hdbty_HrsVs z_UNnc=Qo$et4_Rr_2a_!`r9YBkG}pH@%`)Pj|;C~?_L66++;kIRecQ)=W-+ykU~Lg z1e9bZ*_dTd{hBdaZH#Qf&VWCgfF|4lrkvL5>!#cejsg34U4z#5@gL6&Fcb8vUpEsz zI~HIrdSP?j92?CYXd#iT{>efr!!giO=33AvOSz)VKr4mv`cGDhbz_0n$`3X_S>rmm z&)TRCsBhS)k2;>U)qEbbVXOTn^Xz`z<@$~N`Ws_s4;b!jZXCeFc!G$=tQwm{Q!c07 zAUiXm;7vOV$*drIt3CHN?QPV?gBcK``@uO5}@H$JDW3(0vX*cKgOhgJzXiFrN zCJbSti{e_7J0)3aX%9Un*EC=|-rBPM{o*wl%SB$~QxaawnkvW+*^~2bCk<;1p?o-tf19|$_3c462mfxE zxzNw91CZREylGmNxa#?tg!Sb)znxxf==8TJ?KzL?uKn9p(GCp<(tbQ{y=of%Agv~* zMz|dkry)mrVEX8-^-LUkUak$%`zE6dD|}@5d1uG-t!LQ!VKY~9vf*BVqG~pKk5nmi z6hS&fZI^oND{r;#%d>lP_R5XL%k>6x1Xwhf37v?K6`xX0`eyb)=`O3^{m5mwB!4wN@Y9g2s3*MUCZEzReh!YT;)U0xi9?KTDt z-9~M?9D$8S*N3z&oWg`ZVLL``-uZ4SC^&jE>?BI;Xt0Op3MLWVk1+X8q(Nm&F=%BA zQ7*;3%&?Xx@S)rJ6$TWv>RRsw-a=@G(+raBK^t4MasI-~crwQbq<=H(k))_fAb+F~ zd+z7Th;)kd8ioQ)kb3m4^dN024veAOA*?<#iOV`|ooS)@DnHl7y>{5auMSbd&RF<} zpWxf@b1`YN^b_Y;`QNUU7zqm#EMfD<7DA-R^qcsA%gA1}}^xUPL zxNX1K1R5qfwy`=JcPihbiz`whnYuQuzvRZiWEMp?M2{IR##Y4nFk=mM7KW5f6^~?J zza_(V$CB5uIBq7!0=IjwI~!jw{l%C?f3!}AZ-(v0dyh$GXv0W(;(-EgE?+c+I>%H|o5Yb;IxT@$hv4?_AI;W7~Jmlp^ZL>bg zT^m;+eurg;*k5}L%F0c@v6S9sSNKUi)OVmPeK}W=>)>7cxRfyD*^})oR`)9w_e+ev zZ*MUTs^{w*Gr0Wb*1jP%T*~3nIm5AT1>wiD{CIS@6 zubl|A<=ycuvyC|Ec-v*X+&j43{l`h?9+wFN=-WFlWKuOO-i+`S((fx&`|_L@cqD0@ z%$)hYNS)RzCE1DTyIU=x)3bOf)fyw}m)Yu_-H!;Bvk)Y^Q};NVOv&ddq_|Q26P#gP zXBskDi`!0R@r1@nTS2OwxYxv}u=%-3w6^z&@=O6XD4)cNZ+#vV}hm-0paj@unLlcH18SQA5-M;%2@ua zQEwm~dMION=v7etaj6d+H9B*9YR_Wax+Fv-zh5gAfLy!Tx|F4bTF7W$iIUQSjSYSc zoj)BaGBhHW|1s^A$dz~v8`|cp`v5G^9zM1!w^H#jt!^q&GV0kb3hoC)ia_WW7KHa9 zaTa)j4BvP!hu1pq)r-RiGKvOWTNlPZrdb|*5Oc+(c=fGK$YNdhCD)&<`K)p(pnm zmb3m6MK7*H(OmUk={5hEVL<@DHkzyh75`EZLXmk~l=|=Lw4B4QMF<1GG@AV8eb$Va zWq6-u+Z~1z#L>Fsj3*55GpD+h)xYX}{tNRh+0rJCi)*vUIpDTks-!jhif`@Pf!yC| z@Bag{MYu-%yWt`u1h%#L^YT=k-|PRr2%+z?98L03=Z_y>nJ^THrzb2N2;_!@L;W|e zheKH8W@ESy`pm}idza3}37=b>jmO5x%_T@>`^+WE{e{`$9LMV7oByWKV zvVH%q2;t8R3&U(-$kWC!TP!Wy{Iv)niZ?+RozPB;Dojwm6IFCsL2#)k*@{K}R`!0Y zrCYhDb>-3LAM(&k5m!#W|E&n2l%@V8Bu;d<=hsG)^0J9kUAqc!N$`CYUGpjgA{6C9 zMGGSdAV&NhxKcO#CnDXcjpm=wa?DjQ_-V2$V;%yF@5eXU+)&4JfWPR zmEzpSE-^8@-uIs~EE_}G3;)X^1pmelThGZoN?%?CO`iJlGW0ifnunoIA3uSYxQacE zD+J7Ez+*8-|MYP%Y)NvAl)@+w5BXb4AqE50i2sKqMowb#)f>O16fR%0DK7mbrI4Mt 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 z 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

-YMg0YJ|J)NK_g$O&|b^Ok=IeMT?x5XWZLci>uh@~KZ(T7)<;Z2*P zczyV2ejIv+_YZ^c@~&8xULhh9U%uX4Wt=d85vcqAwd!4^rfg=s<}9}2sX_5S=iUDq z?ml1`Lz7om(ds)ylEmd61%!gZBRO0$eTcG?yZX86vSyz`N=xpRToS@PnbgG-3)spJ zm)fM&^s_jXPb6)gaYa6RNE#cZN)Y47Cx&7>vkBhXBKB7pT4tg4MivF%Ig?WIKYX9e z7JfA(0Achso})iyy}uV?{S#cVAwdef|7#^7ZSht3Q})6y)y>!v7_X<^t?- zvV!;=uVJ{eT=3@bimLT^;a5BBPs9fKHxi`gTs9KrwyHLg6i;_Hk`aUgpHejFT|cF= zQK8DTfx-(^6pT{4pE5LN5qGsx?Ba|GbVV07vm9!WAoc6R1FC)^yr?aN95Rk3L$bYk zGe2O?b-N(=&p6uY?sgH1P;dwPH-j*LjGxwwi(2y58BmoShAk@xT7?P#fo5*ii0s?g z-OAF4(L01yguWUz+AQean)>dmr>eC~j##(4m#^Au>f75#Yo9$K6!Nf2rC_coenU~a z-!v|x=L{I3-$cDg9T5YYO$|EVEfF5RA7Q#MXa;z>l8P3I*U0%yTPcurZr1v!Pwz1Q z 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

ehboyS`^b$@|(<8D6-i4b%u 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ע(KiO8c~5s){-E-N?6| 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 z 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ⅇP9}!Ieebvb!&tT?#eLD+D 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 sample. + * :ref:`Thngy:53 Weather station ` application. * :ref:`Template ` sample with a guide about :ref:`ug_matter_creating_accessory`. * :ref:`ug_matter_tools` page with information about building options for Matter controllers. diff --git a/doc/nrf/samples/samples_matter.rst b/doc/nrf/samples/samples_matter.rst index 68945c36f5f9..c0236cae1336 100644 --- a/doc/nrf/samples/samples_matter.rst +++ b/doc/nrf/samples/samples_matter.rst @@ -3,6 +3,11 @@ Matter samples ############## +The |NCS| provides the following samples showcasing the :ref:`Matter ` protocol. +The samples can be built for various boards and can be configured for different usage scenarios. + +In addition to these samples, check also the :ref:`Thingy:53 Matter weather station ` application. + .. toctree:: :maxdepth: 1 :caption: Subpages diff --git a/doc/nrf/ug_matter.rst b/doc/nrf/ug_matter.rst index 93b3c2bfae22..1b75e0d3e27b 100644 --- a/doc/nrf/ug_matter.rst +++ b/doc/nrf/ug_matter.rst @@ -18,7 +18,7 @@ Matter is in an early development stage and must be treated as an experimental f .. matter_intro_end The |NCS| allows you to develop applications that are compatible with Matter. -See :ref:`matter_samples` for the list of available samples. +See :ref:`matter_samples` for the list of available samples or :ref:`Matter Weather Station ` for specific Matter application. If you are new to Matter, check also the tutorials on `DevZone`_. .. note:: diff --git a/samples/matter/weather_station/README.rst b/samples/matter/weather_station/README.rst deleted file mode 100644 index ef4ed54ebd40..000000000000 --- a/samples/matter/weather_station/README.rst +++ /dev/null @@ -1,191 +0,0 @@ -.. _matter_weather_station_sample: - -Matter: Weather station -####################### - -.. contents:: - :local: - :depth: 2 - -This weather station sample demonstrates the usage of the :ref:`Matter ` (formerly Project Connected Home over IP, Project CHIP) application layer to build a weather station device that lets you remotely gather different kinds of data, such as temperature, air pressure, and relative humidity, using the device sensors. -This device works as a Matter accessory device, meaning it can be paired and controlled remotely over a Matter network built on top of a low-power, 802.15.4 Thread network. -You can use this sample as a reference for creating your own application. - -.. note:: - |weather_station_wip_note| - -Requirements -************ - -The sample supports the following development kits: - -.. table-from-rows:: /includes/sample_board_rows.txt - :header: heading - :rows: thingy53_nrf5340_cpuapp - -To program and gather logs from the Thingy:53 device, you need the external J-Link programmer. -If you own an nRF5340 DK that has an onboard J-Link programmer, you can also use it for this purpose. - -To commission the weather station device and :ref:`control it remotely ` through a Thread network, you also need the following: - -* A Matter controller device :ref:`configured on PC or smartphone ` (which requires additional hardware depending on which setup you choose). - -.. note:: - |matter_gn_required_note| - -Overview -******** - -The sample uses a single button for controlling the device state. -The weather station device is periodically performing temperature, air pressure, and relative humidity measurements. -The measurement results are stored in the device memory and can be read using the Matter controller. -The controller communicates with the weather station device over the Matter protocol using Zigbee Cluster Library (ZCL). -The library describes data measurements within the proper clusters that correspond to the measurement type. - -The sample can be tested remotely over the Thread protocol, which requires an additional Matter controller device that can be configured either on PC or mobile (for remote testing in a network). -You can start testing after :ref:`building and running the sample `. - -.. _matter_weather_station_network_mode: - -Remote testing in a network -=========================== - -By default, the Matter accessory device has Thread disabled, and it must be paired with the Matter controller over Bluetooth LE to get configuration from it if you want to use the device within a Thread network. -To do this, the device must be made discoverable over Bluetooth LE that starts automatically upon the device startup but only for a predefined period of time (15 minutes by default). -If the Bluetooth LE advertising times out, you can re-enable it manually using **Button 1**. -Additionally, the controller must get the commissioning information from the Matter accessory device and provision the device into the network. -For details, see the `Commissioning the device`_ section. - -Configuration -************* - -|config| - -.. _matter_weather_station_sample_selecting_build_configuration: - -Selecting build configuration -============================= - -This sample supports the following build types: - -* Debug - This build type enables additional features for verifying the application behavior, such as logs or command-line shell. -* Release - This build type enables only the necessary application functionalities to optimize its performance. - -You can find configuration options for both build types in the corresponding :file:`prj_debug.conf` and :file:`prj_release.conf` files. -By default, the sample selects the release configuration. - -If you want to build the target with the debug configuration, you can set the following flag when building the sample: - -* ``-DCMAKE_BUILD_TYPE=debug`` - -See :ref:`cmake_options` for instructions on how to add these options to your build. -For example, when building on the command line, you can build the target with the debug configuration running the following command: - -.. parsed-literal:: - :class: highlight - - west build -b thingy53_nrf5340_cpuapp -- -DCMAKE_BUILD_TYPE=debug - -Device Firmware Upgrade support -=============================== - -This sample by default uses MCUboot for performing over-the-air Device Firmware Upgrade using Bluetooth LE. -To build the sample with both the secure bootloader and the DFU support disabled, you can use the ``-DBUILD_WITH_DFU=0`` flag in your build. - -See :ref:`cmake_options` for instructions on how to add this option to your build. -For example, when building on the command line, you can run the following command: - -.. parsed-literal:: - :class: highlight - - west build -b thingy53_nrf5340_cpuapp -- -DBUILD_WITH_DFU=0 - -User interface -************** - -LED 1: - Shows the overall state of the device and its connectivity. - The following states are possible: - - * Green color short flash on (50 ms on/950 ms off) - The device is in the unprovisioned (unpaired) state and is not advertising over Bluetooth LE. - * Blue color short flash on (50 ms on/950 ms off) - The device is in the unprovisioned (unpaired) state and is advertising over Bluetooth LE. - * Blue color rapid even flashing (100 ms on/100 ms off) - The device is in the unprovisioned state and a commissioning application is connected through Bluetooth LE. - * Purple color short flash on (50 ms on/950 ms off) - The device is fully provisioned and has Thread enabled. - -Button 1: - This button is used during the :ref:`commissioning procedure `. - Depending on how long you press the button: - - * If pressed for 6 seconds, it initiates the factory reset of the device. - Releasing the button within the 6-second window cancels the factory reset procedure. - * If pressed for less than 3 seconds, it starts the NFC tag emulation, enables Bluetooth LE advertising for the predefined period of time, and makes the device discoverable over Bluetooth LE. - -Serial Wire Debug port: - Used for getting logs from the device or communicating with it through the command-line interface. - It is enabled only for the debug configuration of a sample. - See the :ref:`build configuration ` to learn how to select debug configuration. - -NFC port with antenna attached: - Used for obtaining the commissioning information from the Matter accessory device to start the :ref:`commissioning procedure `. - -Building and running -******************** - -.. |sample path| replace:: :file:`samples/matter/weather_station` - -.. include:: /includes/build_and_run.txt - -Testing -======= - -.. note:: - |weather_station_wip_note| - -.. _matter_weather_station_sample_remote_control: - -Enabling remote control -======================= - -Remote control allows you to control the Matter weather station device from a Thread network. -The weather station sample supports `Commissioning the device`_, which allows you to set up a testing environment and remotely control the sample over a Matter-enabled Thread network. - -.. _matter_weather_station_sample_remote_control_commissioning: - -Commissioning the device ------------------------- - -.. include:: ../lock/README.rst - :start-after: matter_door_lock_sample_commissioning_start - :end-before: matter_door_lock_sample_commissioning_end - -Before starting the commissioning procedure, the device must be made discoverable over Bluetooth LE that starts automatically upon the device startup but only for a predefined period of time (15 minutes by default). -If the Bluetooth LE advertising times out, you can re-enable it manually using **Button 1**. - -To start commissioning, the controller must get the commissioning information from the Matter accessory device. -The data payload, which includes the device discriminator and setup PIN code, is encoded and shared using an NFC tag. -When using the debug configuration, you can also get this type of information from the RTT interface logs. - -Upgrading the device firmware -============================= - -To upgrade the device firmware, complete the steps listed for the selected method in the `Performing Device Firmware Upgrade in Matter device`_ tutorial. - -Dependencies -************ - -This sample uses the Matter library, which includes the |NCS| platform integration layer: - -* `Matter`_ - -In addition, the sample uses the following |NCS| components: - -* :ref:`dk_buttons_and_leds_readme` -* :ref:`nfc_uri` -* :ref:`lib_nfc_t2t` - -The sample depends on the following Zephyr libraries: - -* :ref:`zephyr:logging_api` -* :ref:`zephyr:kernel_api` - -.. |weather_station_wip_note| replace:: This sample is still in development and offers no testing scenarios at the moment. From a8e579fc3ee918354e74a81d71c906c4472c21d6 Mon Sep 17 00:00:00 2001 From: Mariusz Poslinski Date: Fri, 20 Aug 2021 16:49:46 +0200 Subject: [PATCH 117/126] manifest: update homekit revision - [X] nrfconnect/sdk-homekit#217 Signed-off-by: Mariusz Poslinski --- west.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/west.yml b/west.yml index f1a73cd7745f..ba3a98fb3d48 100644 --- a/west.yml +++ b/west.yml @@ -162,7 +162,7 @@ manifest: path: modules/lib/cddl-gen - name: homekit repo-path: sdk-homekit - revision: 56b570c249d302e3affccc43423eee3bc82f0273 + revision: 8014b7f5d3e20164d1e305cf1188ec72fab330f4 groups: - homekit - name: find-my From 6a5ae6b94d1edebfdfeffe9b014ddcf9c765c90b Mon Sep 17 00:00:00 2001 From: Kamil Gawor Date: Fri, 20 Aug 2021 11:15:12 +0200 Subject: [PATCH 118/126] boards: shields: Add nrf21540_ek shield This commit provides the nRF21540 evaluation kit shield. Signed-off-by: Kamil Gawor --- boards/shields/nrf21540_ek/Kconfig.shield | 8 +++++ .../shields/nrf21540_ek/nrf21540_ek.overlay | 29 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 boards/shields/nrf21540_ek/Kconfig.shield create mode 100644 boards/shields/nrf21540_ek/nrf21540_ek.overlay diff --git a/boards/shields/nrf21540_ek/Kconfig.shield b/boards/shields/nrf21540_ek/Kconfig.shield new file mode 100644 index 000000000000..1aa1c00ba473 --- /dev/null +++ b/boards/shields/nrf21540_ek/Kconfig.shield @@ -0,0 +1,8 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +config SHIELD_NRF21540_EK + def_bool $(shields_list_contains,nrf21540_ek) diff --git a/boards/shields/nrf21540_ek/nrf21540_ek.overlay b/boards/shields/nrf21540_ek/nrf21540_ek.overlay new file mode 100644 index 000000000000..dae59cb669cf --- /dev/null +++ b/boards/shields/nrf21540_ek/nrf21540_ek.overlay @@ -0,0 +1,29 @@ +/* Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + nrf_radio_fem: nrf21540_fem { + compatible = "nordic,nrf21540-fem"; + tx-en-gpios = <&arduino_header 11 GPIO_ACTIVE_HIGH>; /* D5 */ + rx-en-gpios = <&arduino_header 9 GPIO_ACTIVE_HIGH>; /* D3 */ + pdn-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */ + ant-sel-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 */ + mode-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ + spi-if = <&nrf_radio_fem_spi>; + }; +}; + +fem_spi: &arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 16 0>; /* D10 */ + + nrf_radio_fem_spi: nrf21540_fem_spi@0 { + compatible = "nordic,nrf21540-fem-spi"; + status = "okay"; + reg = <0>; + label = "FEM_SPI_IF"; + spi-max-frequency = <8000000>; + }; +}; From 5bf009739638c4df5b538213c3e84fc285a2350a Mon Sep 17 00:00:00 2001 From: Kamil Gawor Date: Fri, 20 Aug 2021 11:16:03 +0200 Subject: [PATCH 119/126] doc: Introducing nrf21540 ek This commit itroduces documentation for the nRF21540 EK shield. Signed-off-by: Kamil Gawor Signed-off-by: Mia Koen --- doc/nrf/app_boards.rst | 1 + doc/nrf/images/nrf21540_ek.png | Bin 0 -> 192201 bytes doc/nrf/ug_radio_fem.rst | 91 +++++++++++++++++++++++++++++++-- 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 doc/nrf/images/nrf21540_ek.png diff --git a/doc/nrf/app_boards.rst b/doc/nrf/app_boards.rst index b1aa1db44f31..878401aeba87 100644 --- a/doc/nrf/app_boards.rst +++ b/doc/nrf/app_boards.rst @@ -95,6 +95,7 @@ The following boards are defined in the :file:`nrf/boards/arm/` folder. | | | :ref:`thingy91_nrf52840 ` | ``thingy91_nrf52840`` | +-------------------+------------+----------------------------------------------------------+---------------------------------------+ +The :ref:`nRF21540 EK shield ` is defined in the :file:`nrf/boards/shields` folder. Custom boards ************* diff --git a/doc/nrf/images/nrf21540_ek.png b/doc/nrf/images/nrf21540_ek.png new file mode 100644 index 0000000000000000000000000000000000000000..99afd951901c6da71e8720c78f47df089ccdb3f6 GIT binary patch literal 192201 zcma%?Lv$uiu=X>V*iI&#SZ{3Gwr$(C-`KWo+vdc!ZG8W`{ucKxx;Itlbe~#0r|Q>F zN65>H!NXv~fPjF&ONa|Af`EXkgMj?Xf`a&Ocf7rJ`7Z!%FRtMP0)jB~KkHXAH3AL@ z=(U%Guz<3=?xha6f0D{S-;x%t)8bBKBxEFk0U~8EiC@qnMFJhg$Z^+k2?^Jt9i0ZL zG%Z}E-zQy-jexS;ysEMvZN8qZY>$Ucr&*p8j^Yp-ZZ`0yS)ZaS{?+g&P-%VQlo)k7 z{s2t&r4bEQ!)_38-Q77q7PF^}wh8aIdljt3U(KaF2z0o`o&j!tdqO`fLz->J%KQ0= zo!N^-wuMR;Ymg>>UAY);)$gcZ;9nie zAg{4C^V<$Mn{fVsK_2il;VQu~dC`i9s{>kify1Y~H@k}l8{>rd>Oz8P)1FnE_Go0u z7^aE3d)UcqBvR2N2Ok+R?5~psU0M$`Rhpf@w>=yUCtG;R?lnEUmuu<;S5M0*z`))H zHx_?ONKm?WpX2ytH0xs5%j!s-KHp9}ufh890*{2c>+J0WoU1%gZAQrlm(e0vjh;^5 zzsYc890jGvbfRx|kc?Eh1$)ym-|n%~miy+;!o=asdZKfJcPlfR=_{h;#)(+?TA>Ig zD6?T~c&$U%7RmA+QhAWD@!`23y)HTI;j%M)z#2sn?Fb0UmMufn!S6ezo!#6BUd_s% zO2dc$xZ3_)O$~{CBi1_$|MF(Kr@b#%-P@2+Q=mwt)a!Z=MnZ$Hdh@^>FDFun z5tmpToSz3ej)8bJ^T43d#)P{Q8!jZ&8QuIUQ&jYTXX=2@3BMEK%r{+Q`(8@;pb6|j zs^7Mp->_!Qn6nXPW2V3ei2{1uuK8Pex4ZWwk!ScWp%JLW2wvF95t3{Ld%5X|gAvDa zz%;HPl#7b-2K|DdrA`jT6>?>KP*E17cpLv=#zyD;DnnMS){5PNT&^pW%$qllGo|la z>yI#&DKTdhvYP#hm2!Ctg*TsTLKegi&C}r_0IWLW6vG@2G=IF*Ka36YO$zsVY{Mc? z4sDGB9rta+5s!g6mG5~cSdHub(Sf>_kLkXWYjyu@lY1AftI%k zS?Ej3h#bUP8BDG$f}}$K$Pp%G@GUMZ<}GpTK4Or?MFkO=k;MJ8UqIpd*Gb zRTH_4i;Bzh8(V{Pmk3q`Ykok5sIzI^*fHj}8(+d!Ss()q z`ZG{A3yfo=;Zay+&VI1X^9#8mi5k3c<@cyuc5n(?xzdFU2}ubN008vAv>qpqf==EkDIN6G;&5{2<41lmJi9}0I~;`xx+V~UP0 zyocSWIn-eNfI-{f7`$9DMuM;BeDba5o@Mf)gcTCZP^?r^z9?VeY!M75LKsh%l`vv* zStV#$A)t{UNQ-JFa;W!VTWEn;L2vbL?EN&Y&wl3Yeo>uK_TegXx!#C42=O#nR-b4; z%7?4@C9+hl#UfOR8Ng4wXlehktrG{+uZn&W=722℞@`-kc_8CtW4fGPdeYde$U3~2|AZmnkNP@R*>9Ija{;)h{dyn& zqCB0)OD#@^1K~>>U^hFRV4rYUhvtRE;*+ogU@>R<|FMx<_CC#6^G;2Yube7;DcdoV zx|N&z8do8Ogh|jdaD2O~r{qSo;JQeGg@6t6`$*;D2I6i5Z|@yN7Y=aT(RL$6wL7?C zbwVO>9d=h49@m6Yd!dRy_46kM(>rQrc zPZyhCPru&H7xJ(ZP*D{wsc2gmZz9JJM)&vEaG;_hL%e{3@?J%RXWQ_H zQ%BR&BpBt&!gf0z{?~YXgO4If=@V-Oh4HUh>`ZQwEKjY*j>m2FgLjJw@ny>O9G~~A z2SaavtF(KO;V*g-*kTaI$0Iz@Q}(Wy_~h>0|Me-?+Z*(!P~)<<{3HPi3LFo-DS zq1`x;-!;M%;yDaI6=mkgjh;_=PgyKe2L3p%e1=HnIX#I+{JS8QQ)cvjI25|70Cza^ z1+(31x0(OY<5K5T#9QhjI?Snq=xw8&1xvHaU6b7^p)8Zw_$XR+O=dn4~x;MW(jv2XNknt9n~#ldlP zqPA{Bp+>kJb6LIn9mcomtOcWjO+KeovcMw~HpHgP8+z(tzELU7J@YkEwA<|76$Y`x z;T&1p8#?jcmR^$V#GPM8@6t|}#Q`l)zNV<*;sGs73Vg~n< z{sgsB3w$m+GBAUMqaEiqq%vV?Y<1E>U*9B<5T&6mrM7gVY1 zS5pbLp;5)wdZ$C!2U4``>?}c74fb|A-W#^JbjU_=_Mj2}>ad!8-|W`hoMh~mW@ zG$_$x3Gz|-8iiNOa?YX>(!T8guw_2@?FdaG`4|xVat2&crgEL~lU617*tMzC zQ4n_j`rMfQQOwe287l)ohCh|RDa(XY)YvYb+}&>oaUY+dV#9^nUpUimhO89EW`%iV zVnz*q(M{?2rK_iuvJnyzYOIBBX?G)`=K4#e()Rz%6SJ?A5)!HeITvO(a3_-*$tul( z1#w0+h|1Iu29z6QjzPmn7cv>0wfVk!Y{;5tIqsh5gxNo5^xkJn*jK^rk5zMErdUyh zvRp}^Xo?8Z{MiAy61^Ne6livM^=332tQoA;_R&NNlV>i)FtY z2!OW-rxe-Xy<`l@#P*9i9}N`g`zo&8yH<H_ucrR~pkDVMe|0MFh@sxXf`WK*Ioqi;jzm*f6ZmPA z!qr$b3(lUl_`kWQ=2U{Cp-UvExLXqLQNCnZLe&y)v3UIIl9LZYHz9Z{twvKKR(><2=)_Ml>b0UU(L98Plz z{6hQBZuuzWI;ycGKNy|rP*U0X@rL5m0Zu*KOl$-44E;X zyTZc8-|Ah3WjCWO15vI!=R7Yt3}1hh{pflXAZW=KzY9OU8RH)VUPw01=S+-A{_An} zPECJX_Ub|tu;IsI+d&(?((3`clzvmeYHiU-*6}hSJ?&@!+;~%m_ zt@MUpUR6l&JAhr`!rw4@2V-YE6sO3)f@bhbWA%h|_1GRS*^s`~2zF6YZvw9P9F%q) z4{6Kt?d4+fk8`NWIeRi;8&hwDHZcCvO|`#@im3Aqv!oN1QdsNxP*iC4{r+^C1tvRN z!M4t?Ewiaz5O;0`rJg?YmMfl>cSG|JE#t8GJf3JurCqp4w;>TKJ>DYddk9W7+U+?g z(QGw43~p~t$SYT?5pS@fc^Cf@_s$L_HHrkzh)j^tu*2tx#f%nbVeR+U@lgIkw&Zq2 zJ6mpTocIP-Lnh3ZiQ;C!vj-hz$_XV`a&P-h{xQ+Zjarb6y4{ZB_x_f(jn=^gm$|fQ z;`xAW+9b(>{=V91-77ca5KFnQmYKTJ0LflxxB+-Gi3)g#Es{-j;Mp;J?qBnJn;!c&JBc^W1e!w2JS+P|A0cO=Sj$+x7((`F(ctVm9j`mS`o{BcS&I7pGp=f1TBE?LYQ{ z<{ltqlVw7@0xQ1@j?nDz|AQEL9JBu=@rNM1*>yIiS!$)mCO#{n&m9U6Sncs`o`#t> zs}%N4%}zaI?Q3-PPE5W7aR2jF0%q{ekGBq=0pW#7UKFC&U-D!X&wFeIF{_m&Kov@g zPMh{qEVTF^s`25nC~Wtf-$?5rf{GIRU{vKni_wi8G4rt_jBSMG12l?d%AFey<~Xg6 z+WXUw1TpZ2DX?L@i-Ya|_VaVv3j|L_#4>DO>hI6*?&j%k@-ygiG?dZu*mVg0dCoea z<1*NTvJ2*F5|N#@ZMw#R5c2`N$CUbU7W0(=Er*+-WS0>v?5#%EjPy^7Jaem z4UJitZ(4s5{JZNfp}{d&x!CQq4wD@W#M1Zr#U#37&=C9!wzPG?Ea;iPbRvLGR73kI z7jZj($hw@AHQ`RDTzW*i#}{_p`!nahJ2XI`ekxv8S~9pW==Y|!_TF$20D3Q}t*V!? zAx1sI)M-YxyOi&{MMm}!&kwgYRkHu{Pd9~8!n~g$H&b7e`J*dz*Ml#$^Z6DgpRXQ% zF1*iJaG9`kjx#Lhh$#y}8>XeHZjr>jlBj8S1{fm)tw;p1iGEgCD;^553%l3h-VOf>-Ba(X(jo>+2t4YK{2w`UPsXJ=6YvZ^CLhKv%#$Bo(-xC zbG&U~1rE5hAC+>WKa(LZ{mKb#Ga77kJ~m;_lJ+)VG3o8gk^$dYYAlU44Lro=nKj5F z_$^8zrWpa|&1w{MSH4`SI@I#iDIYs79frsk>;~j+bA7-XkmN$nq<4d^!|*w?%c_JYD*J!Vzm z&NnXTkWVydy=@J<7j4TlW;vln%?On3HKHhLqfQz3(Vl6q!fFO%4Ud{y=NtYxTBk3D zjvwIYFL>0U38WFJWju44NrW4^21nlAB`lHfrFT}4L{z3Z5x=pa@Nnj-sa3r?p!ymY z-HVnCJ()o#*B6d394o_{k(1-w94;7k@d(i?VFi0WKkJ~;Xn}e(vjucTuzPc)Gs=d5 z19Wa1Mx9VApEg43o&Uj?u#guR6naoWOssd$o2qB{>=Vm+<2SuO<0?lFSS?sF4aSf< z_~R0%YexGenHx)>(cd3Aws8?r1vCWZ{vr9B$r+C%nQJOP0T-Ri95#>*x-)}gA^jx- z*WG_R8Xc{=c198--Oef0mM(#eI{K<|!@cUo7%Tx1-E3?qFplzO&-WKC`<;%NE@Shp z*x}!Q7c&|KR%Fohuw^v}&qGwg+lz$i?i0i;7z1K)C|<7Fiz1|o07 z42R#h*uBqjA2RT0puz696Y?Ym%G1b*HoA@5B@5bfawFE6KSpys;GhdhWEEKcVq&KU z2z(z>tuS^HmlZVRDR`auOqZuv+K?J7e*t71$l{8BjZ29BI1y z`g?HWGE-Oum=u zaq6q>9|q^q?PIxoe7bZgsLLe?{+1IUPWI+$32-K*PS($6&`$%PzV<)0D$5x!Y`N`@ zze{Vk6&2k`@zm0U$5Z3~d4`@<-)kkn-XBfHj1s2U7nFu3pzr04(XNtGvlzjgOo#2( z)s;FHEk0qFfGNf7^5DMS4}^%C?mt++dU6gFYkLd{hZRVr&Z2uM3`Qf8=8_lI#Y<0Q zdm&B@M`5UL_4@5p6?+nKs=KQf1soNo(LDB!!aAgASLpt+!|nQ1UmLFCSolM>_A?W2 zDm!}?rN-!3L<23!xS$l0sW?|P?4{mp&ym&Lm8QPyUv~;73o_W#&fQK&k(e+Ovp4yD zFyHPYR`lmdT))9o7O^^^_f@8qZf|#gr0a}V+m~k!WwS>DTjV= z0v6S|n6f$=v;tUEO6?%#6|V^6L*#gCAZtX-dy)F#z5!Ap}GS;@gL}X}?&zGhXb`FPtTL>lZ-@CiV z|#ZUTQ38t0o`c&xcxvv5iPMplsw9Lh2>dN!pb$|_}=P~i7(dCGf%;=s1>jqiAI zX^A2KJtlewVZUQhMkyMeFW;Fg4@eAZRqH{g`sLgsK>I7#(ZgO}F@G_4WR6`yqBd)Y z{XM9(cf!=?4wm6T3;`z;GO`wgIzZ!x zDTDb7M62~uxyJR@5ej>`aykKA42@=c$ncM43hf+&*{C?^ItND`t^n@&iWe$mdX@d2 zEByjWTEmGb+Ws|q*S|7e(CfD!%B>4IhZOF|HU%FQmCWaO!C$LSJ{rtdPGZOd=Z|30 z*>mvSBU4Hhr97F$G$C%GF}V{l1^&eqzbpWbb}L=&-WsUfU6BKEjs%&pTLLyp3L+&o zYh6;m9*w25JFsSG(ay`M*yHJ?)s$VuuA?M@&YZb>4$4@vIo)tv5?I~!5n1o7L`3ja z+J&N#LIS$OKOX64E{6wbA9jss2JT^(O(8cyHGULJODw8TmfR zM>Y|$r5JG})veNNBS=rNheqs84Qq6GvOE!Dt~RdEk28tw?OsMYubiV&_W@lRrAxrp z!>1a|K+QN)OP45+nJBG*O$x636YPm2kausHO0A3Xm%~Jin-S=uigRxJkz?gMEe{?F zkzb^SGTHRX=xDg6vS!Dfv4~RqCV$Q%?ot|LvhGU5HW&QYr2Gatm#Ov~kp#FoB<&~( zj;@k}H0le2OZxIiA(AE0k_5Gy+MG?pD2w6IY_=1Qt)}Bu&vz-bCobaZUaq%<&i04P zXV~}7<4qNHvtocg6E*&=;A#IS9uZZa(sj zY9p$$NpH*uLqC}mujKN4o6q`K&Xu`S!0es(1If10X1PTLb?nI)7L?3?RVdv`6t=39 zOT`kC)5T*8dP@PDpnRg1(*>HU62h^2E?qr*mTxPzQ%suE1VozzDal3fuBuIcPm8fh zyA!TGrA8E+5`vSHd#TzQ!_X`F6bCPMfBb55egjQVTu3v`lqTY=TMxs7-p~7+0t5zY zrwQAJ>YpgG1uw6spv?Phd z=iz^+_NIV)M7D$N8zj*k!%;*h2HX^CUMtNVUPZ}mI0y2?M;UDKj-0k@>7}**M>Fc{ z>yMRDMgs1MNl3tWJ-CsP@q=P;)QBkn0U9-}Ngdvl+Pqo(W!f+l{L!kJ;y^>!o}|A> za{^#3MUPaS6akpUJ;^3h>RtGa!B&hXI?^}>6yx!xpk#Y^*^1P0|02y6I@FLkSvTiw z{rOa5r(;)$W!y_WeZ6@fshs{$>mM>RVRy5ncarI)YWxhE+6mEiQUG*W&E_$$I$b<< zE4q>D)6gdZEwRCvq%M$|E`)@HG`fu#?iK4w?a3byeW$SVBVg{FIpHsYI4Pgg`{M+? zCvzrM9NjO|G&uik^)xU-Wb;Giv za#_uvq#0JYBlS{h_5I2Y4ed+j=Ja{tXrAobMHCC3<3X_Qv39 zNYR{yo8Q6Qd*y(B`bwDjV}!sKu-oW&0GtBvI{8cQG_v0-OmZZw}9K z`*v$@zArRaU(0tC8yOy8cVg4&iV`sOeK#;v02goECoMQmj6tidk288WAJl^v7k6w; zt5<@=>Aix2*Mkd;TSY5sR2GQXH<>FHBS?dDX#1f@!sn1=yvs7lqu7wmiS1t^^{F=y zWunbh2Bd3dk%kD>ovDNQ_`B`Zn7)B?P4M{yHw;=*?3%oEJ0B0h+I;yXXVFPl?Q|Lx zipD^UxrsP>8J-VxmgzpzB3$W)*Dt2*olK9$G3ots{yf*(m(7-M$@`5TwU{WP`?LvG zTGJ&P8!L}5tPb-AMK>Sa*SYuP)V7&g;p6OsIq7cAZ!1!{u-uLbj1Vsfwi7JGFaa#x+Bl^$M3klDE#P=$H@ zXW1PD`|lvmQr3`k!)q*iFct_T(dKfKaIv3+bJ`-~QJFmP&ZY`ZFuQ$n-{UlxeK_@V zpOQMLs&ad8vd|Hc^6NI$vEJyx92d2{t0KV0anI&h5QbDnmftAO#%44ZaN&@CD4=OJC&GvPG3}0*8s?vAUB@nA>GT(Djkbb6@@hlV0zq| zCz=Ux^t{B${9p}yt~~q@hqE}J?(b;j(+NIU^F0#?R9X8?raJ%rAKVi6f5R=-VWzO) z)|K>HW0sv|G4_ijX(S39NWv3r_8?G5OIu59zGdjnoGxvGV#$Ie-DmM1^ad3{N^XIO6Ty0%VcK6 z?=dK}g&UU*Sy={;;pMt_zb#6h-+8jj&gJo3v0_2EIZLC*A2lX}6s0|xesf-ov-bVu z^YOqj`jS{+;9qq)J8p!W&F0W01(tj5-MQXA$o7rVJ>)<1RoagyLMnNs@b|@NoYLQ7 zH(3vGHT;82dmJ=qI$!%Ep>U^OXAV8`{DakV&9QfRZY!~%_|83W5#R?RWk|1)Gkv%u z-LBABndls6(ASv$r{m}J7Q*A#e+NStWw-s=vOEFuR9@?Lhnu&kKQ52#edredx$y#l zfFzK{e?-;n^Huc+RB4VtHZbvJEL19W|-D?3}=A zW{3G2{f?Gtyr_qggvyZK_{H*YHmeI|(3>h{zP68Ad>%#2g|A7xaWoGgbt%fvCFS`W zqi}_Y51z)Ot5)ReGMwzHPT&@pl znL&Z0D#uvZSe;Uz;CIC_!nDTF3s>oA3JK#g1=cbt5du!yJJ|=PW5!WUA5_1$UTYaA zqH=z64XPdpk3%p1-K@Ku4DhN5Rw&~r8O@wdgvT)MXHxd&QGG-~Xul!sr7q5QiD2Ry z9RXjk-wlo#S^0~0ZQm`tz{+9vrp9B;mA@I!Wzqu~CQ}TslvsVSHUHRzWevwub1G9L zVq)55);YKGVbptNBQqr_x2$v*=U0*ZNne$WwXnOKuwo@A(y>%!aFDP|P%T&(QfO!c zNRu8Ae&Ax;NK_z21a~@r z2QIJy9vKEZ{;=H~91LGFh-DQci#||^a<`s;KCzRK z78@PM39|dq{AZ%!(>G|a2YlCXB7EQfr}W%my46&9$_j4YBV9QNLUj3(+x!6BZ-x$p zjacCCggSFUh0i84R@ohgk*iKI^ti0?HYOm7osnBuE0g4k{uC#)r_`H_A5x1oGzAU_CjbE~l#CN7;>I0Ip9`z) z`de~*M4Ut@dTtlvf+Ak_N7o`4)Jbh@pE zNB`QI&-Ht(O$Vp5E}1RcbFCw`b+-qMYlR8Cilfo3Sk=;7U;FwWPG&nxib@T%!#1&6 z-T4L-yA?)=!FOC~f*>gg^p8Jd%)e@WH9{owOGyGVa z^Z;g(t|Wo>(U0+U4p}^X^x=e6T1vHk~M2JGcO&u%ext|f=HIDPUr?!9ZJ}K*;`q^TuoO5K zp%21&=^H=@;Rfm~rIzp663dcgi{@m_#RK!x$kRxUzL(lRJU*hV?RyLL%*$baduxD3 zrxGEe8?FA|Bv6|lO2Cv=@vkgmvC~g5=3kb21QGVdzv{k{?vFZ)J!Lc+%}0W9<$K`T zfI2}FzIhJIhXh2?d^bHWjZb3nx}j|c`>{C+D*6Ho_h$V~>%mB#)~LrT^>Ph@eE;xKRjOI9*=8OoXycnkIaf)&POUJR*`+@*bz;I^E`vU>UND_ zKcYvNinr)Ow;6+uKYXP!Y9P5Cf;%M)Z>(hmAC*^8G~1Q*H}BiXZgz;Im>Xd_C_2lo zy@k78-Ai$tn42@jGak`$sXBJ!(l>o%-QQT`aF4U?eHWs3xP!?ygu(0q{pij4x_wPi zCydwV_&a{iy?DnA*2rhAU_IolGPWm07H_zZSzqQ-=+k*SqP)jLN+G1Zkn!YiKC1p- zg%dg*7}ckP=n3Hs;ta*Zubu@oMa$ZNV!BtQ9x^3L)ZF|f-uf&?#=9f98pq$AiEP%d z7@N+b*4qv!o-uS;)A7~`8<78Qh7IrTrzIH(P#K5~1mn$#3X=k(2buu7rgA3iG}*%e zX%tjX3N(hIt8_e#+o`t(8Feg~L6BtF?p2LP93E+C`*lf2bO}?g z7%KF_!$ZVu=~B-|YnDoIoZ7HagQpCId#OwWqHqL(>nv7{Re{8)8f#))e~}3D72F#w z$R8r6qrT%6skN{w6%Jyl?7loc&e|{JdUD1>dl)T#bNU1<9fEx}IZ&fs$3R6v3t>x9 zt!CmfSX^R}`G**eFA$i(pcPPaMoDLpeksO-GIA)YiM(+eHRN>pCo$0Hi;dQlX>TJk zVN~zCo(YSJ7e_ma-XOyQq6bkAH5Dt*p$F9^qsOwREXlr{xE4NMhC6xyN6NwtY_zL$kV`a1Bf0Zg0|G7{_9#7{H>XU5sp0mJsxCH33m>~3A z-e4F?gb!(Uqp)wf0<19U>b5hOM1lArq43!Gk}>bMkB+0~%X|&%LBBumk53|Dhd-Jp z42}>3OqHlmX*Kp$a`Y;mDDiGgGR;=(>H|acpbt!7ji429{2mROlP_3v)tleEpW2#) zrL$z`r>i9=JjbG}uC_Qls50hFAMv>voJxxH%~m{ZRjDNrknkJh=z_?F1&zOD7PB@M zqgD6};_TSaXp<6MqAwke2WYlc(X2yk09{4u%HB^?k-Bn^RPY?@edpzhgTgdgC5qdk z)*=dM90pxriw#V<0+FNYMOGt$@;xYI%LUSR-2b_z>_rgGl^8(32KB{B~sb~U=)Ppb)6W|m~7qZ*cE)Zj*KH5MA>Mf4UBIm8dd zC=w*eQ!&XtIn^6)mr}e+(VCR5%zGc{a%r(5QZ$k8OlGF^$)TjlV8O~*GGw743V0eX zq#O~s^Ni95elnS?BL{QhS-d_OoGBO(7zuWZB|IxNUlIyS#e#89-X?;{Zi@%^F=DSB zI~3k*o+Qr%JTYDYvG&)te^actz#)0%4-o%*)HWoAnh7OJb5A)n;8er&S}*P2n$JO* zh10VmfWzm6GZF>%<=H_Nc-7L?ySz{`TikNG&@kGII;eqfEWilb&F=uDMMsDO)N>wY zVsKjFJRJX{DsOsI{<6rVlwYnRc&_}DN zxPF|WHN`^IjEw>9AJ1-jcqxF=W64~9b`n~xi>s5cp*5A`$z2FA`K+kMrGrpc1I$xW zoKB8zv%_Ulxq+m!@Mk#wDw=fmU%SsF=L2TdYU_31lc&U4O6Y~4^HJ%gi^j1onOIR$ zK?lWw#)@Y@TZ^rm#w|qzZ5>jsBscQihMTR^zJ-8gd$s)r&Z7(>AdLlvi*>6YQ*;oe z93by_gZmL#c1urz%){jqgc{aDe7ld~{VGek!owxHH5$K=mO`FBm42PXrdJycjHxu5 zUg-w2qpNpsL;o|at`4|;d{g@>yDV30a8gm# zRYWC3()xe(E3DrF&nOWM7&wLFsPiJwj+IDq(PS{tbYR*WDgL^YRV-5zk^n&XXw}0L z&|&ffzU1tW_kD0VUr`MgmcpZrT^PV!AQjxt-Sk?;cnMTd6ECn)HOik@E7WRBa1W%y zg{9(DE3zXR|3X$~qSHR!+t>Gs7;3zgxV_BW$bS3IJa?0S@`=+&)_)ImG^V_^XnNhZ zBE4#~yz4!M{-gpD&sQ|hl{}4La8H+H$Q#QjbRH!%Mu8!}BZx`sr8nu+ej`7z zgO1;cs`4-PPj`ZHp9NX1RPjntw-b_ZV|2b;=hGpzd7q>x*2`DXC({QKg*1sDnmuK@ z4sTCWE713nlhLh<#wCRYHz~;PqQ*-WXggY|y3*%}Ez7o0gzSK+oBSp<_*VYL$HwTt zYJ`^kbVN~`*%DqvywrF*#no(ngVRF9H9NY3OuA`+w?cYj2OA9i;Sc!{>iW3G0pM5X z&&!uvr!$%WRJW!z<x`Y@&C_|VxQQ(ZzersXu-TGyNe`&GRjmGi-^`Hjc@xtb+?!1<|YpCxOEV-(i<^_{0k~I$M zu%xhV#=LdgD}c$KeAW-7xdMgCx9H$H-xd_z!BJUj%cK!?LXwPySZ&!2vPDGsMRalC zDDh#1(_*I4GV?|+dyBy&+r-AmA@v6%d)b`L3>Npe*uQHilnN-Ww>v{$s4VM!CvBH} zI?1U2(Tp^OP}e_=I+UsJHTQ;;A9nw^jwECv5Zt;f-jL0%+rL`hlHWC9T;ZJx%a|n@ z-~MWQOA4vYWa`OF?e%V#6ql8jhgpndut4I&YYn%9kQL_4ETXXDrpCYH+BA*#P9j0T z_Fk_+RHe-hY(MbKKgmm%_iCdws|U$pJme*!+2qki-X#dO3zHqjQK>B8-($RO^TJ}d z>yJdF;|Ng4ERLo3rw)3&-uCd^J!{Pb%P&1tBxJhjQ@VF=Z>SV*=bD3H9=`Cte ze-QE`A(;nb)vBPT+9M^gq`ISHIC5d`WXg($nB&E{?R+2TpO_( zaoXp#_+sh#dUyJy&&PZRW=}?-?c@(@DuXB>RO}gRO5#F}=+}pgpGExx>=vec<&%g` z#CHdb9V$+wkS|b|D^^L*4-VY{z7SB965ErZnMf(^!92oW6jOwbiOpiV6?@_@B;>I0 z3&a(Rms;qtexQM3jWIlG%^Oag}4K?=S6jBEXb%NIE z%29mNio&|`)*AB-)f^4$7w;a0x5I3M@p-O3mIc0F>nmzg{6ph#n|<`Y*Onrw3iCH< zGbsv^G=?>{5p=1qC9A6>lK5V}GZ4l}&XiSfRv1wI!kEdROZOV?U5~N;l-Y40)aPWS z6vsWxlk$I+?l355Df@p{g?E7?xPvyTAFo-$Q{zLn7kLBp8HY>Rvl)}Ubd|0Ta$k{( zrBV+Y>xPrN(?xU^bccuPO5B=KZ4NvsT6Jqy$J< zo1I9^)ser$=MK^YX<3XIM}(N+6^xRMG{%D05-teGIdgeMa3VcS=lChz+bb?@LMDew z!hN9gP}9(aOciY=GfB0&bR2EF9#Zi98VLl4-JPCLY5UR&zyf*4#&wfCg z@7Jo{8MB9gdZ=+~$FqRY~K;!&58V{2#EU3_ALjf5Q z#UgcNpglT@xW0Y*zSo&mrk=h&PB3lK(YvHSZtqi7$wN)yf>!C7MZ4D*?>qK|N_wGV z6w73ilgA}JWc@ho&r74WSPOlnn83Fw7kHExPmo_#f|TVab!AXWIRh=Wsi6$;v9Kmh z9U3+jZ*(uylD$Z0bU}h(ckT$6-JTKD7oY0!MiG@sWE z>MzZTaJBs4@)kUm8lvixsg9isHZYs_-6MDYp~8>va}vdGij2-zxP@^gg+^=2WHLpC zBtCe4!Z-qlF#d{H+VksUkFehz7au~eSG&#Qi463bPq{&{#&KAz&Z~kStlYT7_*+U^ zT2UMM3{1V4Av&pDu9R0P*+zg?TWer;RU|rL9N1S0N+=I{#?5>l+- z3>%M}Wow{sC7GQ|RlY~n?UA4n+bRsxq+nFHs10+V*hv6up_ys}R9m4+%S<#i4PK#cv1B0G zS57P$A81_XZX2~WtbA{~HlYr>P(0`2@N}+%%jc_Y0FaZD3u!-e`qS`!Ki2Bb31PU$hnQaay zHGwqH$D}L9Fi(FXDC`aWAOp~gW{Xlh(^%dIsMeOin3{*i_E87(A7&6SvGMtU)KP?q zGy9@N#8j`O`qH!eSj;gx+o96J|E_(`!p)%IYgwG&h0H+h^8M@zp7dV)Ll-;-m)=*| zOGrARyGDaynNnnp4v1nGUh^(wow2-PX-Q~+vn2AGeZlFKb_Z9CZ@2WfWY=KAgxobS z^UwMNY(2SlYqyJ$n5k@jU(wbk0Ql@O6wuGb_1yWpC|2Qy-)O_^VnE!9*`gwn|Nc>_ z88m$$+7^;zLO}DU=jcY$BpM+hqe!B0;qlhYxZebwtG63KCPKiKsZ8MKlNi?E0s$Vr zzc{+?>4nv>8#9nm(8Z#}V^XGf`u9a9>4DWvu2-8P7Gff-db(hY!12DZ>D4y*M;z8P zc>x4c!~XQ?Slb=HKGDsY%guxWXCnqC^@-)=OiU47K|xRl3W(Kaicq)hJD~?UM9Plo zjQZhpl;Z&NthDZ}m(dqpo) zudv`d;$I|2zfr@WoznjFBZ11w5@6dt(H4pE z_I7Du&SowjF4^7o)fY;heW`IaB-iU!K6Y4sy+0kh=K7V;C$gK7u4r}rIXfdmqftz7 z5UojHKTpPKoyNap&WJ@RR&4iP^@{^L!FXq18}k*$S+g1gp?iTef0nRQuKA?7-ijGG zgx8mw-un9~ePR{3RgG#MMKD{oBy&8POgp_Z2Tz;TW z7<|M#S-0%Nx%oh~>Zp-4R9jswP&t1r;Z(ot?1QQDS8~dhDGP>Re9`WQ#RT(FOgo-P z4+QCBc5VDXxYE93wJWyljyy%Z9;v#q?sCOWKkW34X3HwRCyhq`TDHH;VJn&C3Qr*> zTH{=SPgR{M4Q^xxPmZ72k;{Pzj7-=VRdF(W8Ch<&K<>@xc%};=ZTt^UyzzcLE}o3Y zOr+B0clgoyf5pO6Oxq`{4`R!WyaHsJ_}RU8-5V>S0`+3x9K|j)d(_#=sRUi785{?Q;4akB z+c$;MH<3eByIqNDVU-TgGSZtpNec~)!0Zc(m=tT7@Uq=1z##~1{71q%xHFqfkWAV9EyFc8=4*v-84M(y(?Cz-{e7xig-jor;pqQScTUlj1#KE`#J16~ZQHi(blkDc6WdmYC${aJ*mlyfHTma$)|$(i%UXM{ zT^m)q>Z|X4pW1SL6NmxkkZoV(iI*`l z?A>wtxgf&q-!%oVI}ooFK*9@nBYGkJ;W3V?g0v~-wR*57UZXzmZiw!WK22uws3PF_Ns`BcGxPB?O*>Fl>-yxt@(M8Zs6?R{wh%=PVIO3ZdKbV6y-Q}nayAI ztTMk>kHHv4LbeGy5DzVdO_Yhtj1K&G-TO*lF~ggLB4)AL_1U=O2%8OU8O`ta59h;~ zjz{1k24O80h$&HsQ%g2mLemrHn8_jt+l96tlSvW9P7h};+PyxnoFti#Ejr%5IWE+R z^-l!x(77TANji-y;G|fsRe~BHb+ozbxYO)R3C@nQ)M<&%eGj*k^3P*)n0PzzvyDmS zTy;KU0N$Xp`lYg5k17McA-{z24>kbVJR$GZ8FWx+v`m*Hmy0+Gss#KHrBBye$d*>C zO2ZYS? zp!2pqG(PSg<~PRnp#~rm#T78GWmOxuseE9D9;N-90NSm^v#C)x*9G%A++o%6B?^5- zgsaqNK9JG6XP?Zud)*FIe)uM46tnG!2CqrZ*o;p1b>|&he$T64nRkZie>C14xF(&# zyPv7{wkDOIH|Je_ZuLxyG^8JX&x`-pPx0$H&uPKtb2#fV81nLH#fE6`SOazcGvK!Y z+;b=x0#OA>4hP4>FLhiw=&h2=j$an zC-Ao#3J0z%^-gsNDB06@+g&)=ET_f{O}^^<#iGI2)3Vf=E>VjppQ#rw%bvo=ZML%| z*DwU{#b9D$s&LVkXjJ8At!JWWUvgu}>fS!L@!n5$wfed+tMU&>hERs*gJmGXWw!z9 zteYDNza=<7j$=AmG76)agMNxor0}@>pV^p={vzRKR@#|byVFfRSck`dd>9;#W?=}2 z&#@mMJPc$jD<5N13)rayX>FCX`Fi(^XrTUX*83j4%O$Y&_B7Xxw#CDog806gu>?zL z*@eSto;82kU#U#JnlbVzxUfY7h8qqq%m)_}sG@1ra0$X~{nL^!S`NeMc}Ka(Ko|(= zCZhE-hHYERYzCCS3d-&WN%n%4l_!T}ZdM8rs^J|mq{mn6Vq)<)Qii&W4~}hJFZ=EBx6hpIWZ{Jd z{G=etmV;H7uZ&otc@jK(rRqB2@o#izlZ0xWw8H||1lRIB(R>>0lTCrFXRlN~ZLYI! zu*vUc)BM%K_4z)s`e<`IploPmMaa#=dF~#wG@c^z_0{3DsL1dRt9ja951)TG5`K|3 zzMS!Q|J1#;*}!?4z=-s5p&NS<3FpV7@rQ#LP2`YhST!WJdV`kTB*H>;OlqB0B`jH< zens`1Fj_xBwm2w6fsfPYPd{CxZ8mdi`z|1pTM!mcj-KK-E7s)jbaZ+rX+J5atdFTK zN}yT|{!JN+Q}6hXtOE9^IcXjcAJ{+~BtX53p}oKm3_<5vKO2E?+cg>H^|&6NamzQM2L#XNH?n=aqb#!gW3sx+ zsoU;=BL3LN=|clg!s}#o|0u`kr-LMYNCjqls^?zbhh#nyRebhS@xDq~vN6%Mv)Yo6 z9L<~xg+dN&x$GBs^)m1hhu?lSu4;#tg}gI}w#r?rSszDDnyD3FG|WzKzQ_j;1I>Om zswnM+!4-DKJ=gWZsW@S=0t(jF0aQDNX*CHHL;L9P6OG@ zM!{LLb>)7=)-n!$D@CN&X>pU@m$2hGAOVjMttn8OXFWT?pU7Zw=;?sN;oci5Md1a? zqPlcf*c4&WJ2!Z6j=$&neb_`ee{&+r=$^(T+&$i5i**z)i~cgLIZjr)A+Y;vxXbilczZ_EMeiy zU{Y)@&1p4F^ImSS@HEYgaa|AytAWSqd@xiM$h5;!8j8p%QKQ z2lCD&)dO8@P~xJ^Wa}O&i_--QnF#?ZimjHQ6X#ZD9Z;smCh4ySU5_$pZ&78}O30b+bHBd6b};twWLfJ{EmsET zu-8-5?)#d{g$1Bo@asT()f3HC;Cx~aWi&odl#G`$_@X&oLMYGEV_nH90G{hewQG2w z6LDRzhJU0DDz9aS>i4hXE1lP@gGKqK1?c;)gqxj5C?l^dtJTyV}Ntc|UC+&0XwoF_6b7KQN^1xc=O2 z=pNcOPca}+x~72i0ViQogq~J}ev+$mVH2jm^Y3+yY2}6nF(lrym*MXH8sf~;Jy@l_ z8!oPfU2m|ySp0B5`0tn$Lk?i<3aJwphP-{?R8VYT{|KrBOWiblyKsa3{Eu6WfBm)k z&x~Fx^t#?Xp}U5JT#M!g%?$o8@=V@0lbUH4?^n-mZiaUgQusp%zY)O_nU>>|hoyeX zM~@24CYu&SzfFw6-ORPYms91_>g1V4R>2z;$G1d9k&r87e(TQ4v0N?V^ZH)y@VXz~TXU?&xFnDR^Z=`|^)Il(B<3!%r*5 zBS&aiut+AzGum$k9#x)9r<@@@IMK}ztE4>qc!SD)-6xM=peH+Oa3}}8OvR?GyDPhcG*iG3Cc-@%NSpa22nG-T_%a^sxn4m zGDO7HlAzpMH3Dt zj)ac;yr|c@?#2;9JvM)LDGzCPo%Hq5xY@h3d0Y_SEamrk`{6IzZ-m+MxEdOL2D(>) zz2bSX4QTv?G&)>{Q4O?8m$O(yZCag7zeI)`?P^$VXxP**Eyx6fjYc#6*<@y|v=Wb< zYGgF}h}E=74ej7sIoB~6PW~69{<9jmK}Ux4PMU;#o+$~=BZ7!hAVtAg>|-{h@O!PL z5=>3ean`fwAS)_UO!6H;Ai^0LPr4{#TNSk4)8n-opFfVl5LOTZWB9S|vE0UjR<-_T zm#LXWK>@J{3$%hy7e5Jyl6{ zjStGcQw{u)K+NP{fy=oOrDEV9eBn;c2u4;U(J$_p27}oXRR_hyh|wxy$l}X_7@v|y zJpNvGC;lrMRW$oW_aOX>uN;6oFPvE-g{was`B2?6dHZ0-a^O<@q<{*D(RK)LzFY&@ zKE=x=@|nh@60E-Ud>%X#QLoc!iz36;65f+dTvkhXE`4Ktp(rPjXVqsFiBDX9_zu~= zPRoi{r;ATiwTQ!Ri)$1i@4$hK7+)lk%W$E{&5^$Wi$Kv{S{6a*nfRLXa~awML%h&B zx6dx@+zy&ryOPp^#YxdVzI zKOZ9uO>2cgo`+zy*rDq)9LQLqgi0S6^mA;injH2eOUfMhw3sPz0&`i@qas^k=6I8tEoE7pTD>G3%1 zc#XaE6(;mBgc)a|vYX@$r@}FgS)M8Fc-@1GRWiO(X`1JqsiFKNkA~+x#%cV%bZ|EI zb&rO$Ah@Z>KJN=4-*tha9Ub>6iH)Mo$=jU60Jsk_l$j@S&>0r{mO zGti?o($-T=wFz+dof`>0l?bNmO~6rMJPraBSv3DES&si=VamY-Rh~n`Yaojo+`jFF zzkCmtfsg`_J&4i8ZO{Ix+8;(wSY;tr>~ejRoH^67sq<;t<@sFYCE(uvi(a==a(8UA zC)w%}wzL5%P1yt~d3UWuH`&-to}k^AT)~b*7K=MZM^9mY9yqtSmsxvD7c}FbF<<>J zhS2RYWOWu?Zy2KII7Q(*F6vzlhHQAnRv;9Uto($xd{H3LY>EY@dB`@md=?xkSyB4Y zDg0fbqgPUddJ`>|M$EMTcUp-kX1nL|afjuTZNOe>O}{>7-`?oFE5z}WUF@<;r6f=} z{LU}9%jauU&KgX)rAh#R=6U(Vtlnwrltamblp<`jo}vVlv5EImX8l$J)GasM_y>yX zk7~^o7;6&4ormAtYo>TO-H(w1NeYr5(KCibhYb${8$Y|T#?ex}XZ1_VlWb}gK}2jY zC(e~Q&{d6gvuQOE!gaQz1@JTq*=_43wvYJ$HD=>`E_B^LXr=u5z0H5*b=takW{6QY zAPNxq;ziXR7*!w(Vo2LFHO;J&AaHij)VQ%T;Rd8oJB!Tes2^hEi|s@1w<;c2J3<69mhf6KW~KBIZL^S@qlqSe zyJgK}QT}qp?-Ej@!M2XbnokE>E#WiA%l>Lc7W<(kMRs%a{6$L2)krH-z2+UsUV?SZ zk8g3{Nid8-6-PV{PPu6B(b|(A9gH|4t4g3cD+)icQxIQpYDbHx_?Fq1mxSVqP*;o{ zC-0*a${1N#4|`a}Md}n;!r#o#&oTYf?|~7bZ&VEsBN}O==~cMC=9+moAvIa6uh~tz z{QCJkGY>S`{UYZ_Cy{^`eU4Ofygifyv13QK`&w*r`;FWpA0y_T9uQoCuw@7s+z?X# zgsQ5bv;S(;)GKPFN+F^=F*?2x`>jf=fh~b}DHh^%!03LC_9JM%zet0%^IqMc10AzY z8pG`O!HlL!3iGkyMxW>|tNkWi^zY;nmvjJn1;urOSL9qyoNNgrYmBia$sA__(*j4*(sVzgC)5Ypwt|;|-s~0DC zFVA=%{N+2A6cAu%LKlD5F@E`GJP1Y38l#Ku5z6Du-BUXQSURJWQ*OCKTmv|%3jt=Z zK9`*)VZ%=7AZ{fu21rx9JgW>Fetx`3M+OmB{;a0=*G^kTGa`3-k_#h1h zq(-oq$C0D1OrRb$p~IO4`ZZJNRGSROp>OaOjUs-K#gI*8p$(ItOwJTJ!e?>1 zg3G8A3NAHW78w5HrBq7rrz8Xt>Odjlv14R5R}TjihV3v8;o5g;p+2})Q)=Y%((AXC zv06>1HvhV5E!kPK_v#h<-E!b}#;?pOK0r1=Gi}v-@a=P3(5JVuW&PsRv#n5C1n}BszK9%)kCp^l!5hseTwMP13;vcYwF4Ot}p1pAR+(&vK>H*K>z_EqjFd zl4S<)gSNL5rIB~Q!hKVy+8$JDJ1%c|?7q85((NoM-g!cJ$ZY&9a1)m0{;f|U`5eBQ zrzdLEWm>JjXeqQAA&Ulg`Kd+}LLfYVgQThQpb~up+WBTZ{#Vx%>vTKac?hC$|LlAO zK9p8bCM>0P2^)xtLxRSN&Zx%!w6wH*9FlBwf6nL@N#<{PZ}0E#QNT*hu5 ziFHr24<$fSB`rO-Ol`J`Q)|?uV`SF(IEv|9Nu^Vs($4dkY9?F3cRphOp1Qe3JiO9^ zK=Us1>K5YkIY9Xb8Jw8jdO=n3nhvW3sigQIJ8MA{f}cL#^NSC7$O^_Thn*04T^Pw^ zY(Am#Asm7vE0A-up02YsH}QMd>)}`cXHNXFXX6!7sY0F)ZR{w7wcr}U1Wz2GpBFra z#Reg&WdE`sH00i?%?5`xLzwHci1Lbv*T1OOj%IRrm@MUx57xwxl3AVG>0T(!q#a{Q z%cS`+42UAL+Ga86^fj?-WiIZHjFhHCB_ME?`vKXBg-&#>qg|B&`0Szev|6b%`*a`V zr3m{{I5t|YbR335*H1!D0X>?v)dkYOG%|AJQVuy2Y8Kh4-B@>&I?MCe^~?rab!C2+ z1@o;~xMp&iwT!HVtS;x9G9@zd>;>*t0;<)z*qMHt)q*exG2H7NUMefDgOE_RLyc9A zOis-Jx2PDofoL8j%jIK}FTr!Z*wS|x=U)(C=*eV8mp98()&7}}+nA0Ig7d9M*arH4 zn%%ZM+>LK=|MBQ^@U<0cwl3x6|I=te%AU`UMM6vQM*)YD7%7-=$Q$>9;x(Q;9VPwN zy|lXGgN>PbRctdDcnUiiy?&eQc0|L;#S=H{ZCb(p`ts6+b~vU!l#ogjH+&l&q^Egd z${j;TpA5IZA{_@YB|p013u5NYv)Wgqd3G?dl~TjxJxlU>i8#4%PBWeia| zWi5-{-Zs?b^g!RVBM0M!>MIQEb;jo+(fe+JEqinr^u4pYr-2Y-F51N7djS>(bPBQ) zEr2SK*J#Lw3}a(_;Y-Qo+*j!#&@;6F`Re{|l3Go|$N$4(I$OM3$bjl;14JllfSXe=aV(WOCL4+<#ik5 zN!6xSWb&c3-b*jb8!LD0&fVRQM(5?_9VJQld22SYs1LhVZ4%sX@ZRRYMv7%|iEb&! zols~$5ei($@C&Cc#UFP?N_#os%~iDMUG6@Ra3&(^QRhraIY`G>Vr#pcnidTe|GB|~ z(jYZ{8^BIdN8zqiajq^U5hW`Ss+2(vumC2Q6SAgfVCp&EE>u{<$%w*26S8)!GxEL0V!v7pn9QPjab5WerrQ5k);>Q1Amnb|u(U1;@GIJgPs_ zxXATlb;KxF)MgR=jGfSkmKPq~L-M;gILJ`4u0D)I->)9$;onx!Yd~)rk46Hws0oR` z%puZ*4BZRmce4s>$`EE@Cs(|!$rZQD&5{QJH z9K*NuPrk#Buq@M2wd#AG{-H@$ zLe9jr@*jyQKGThJDWRsD3INTh!TGcP(Vd8J*W{VTQccs$|Q#?gB) zFRXXwBVgS{p+r3p1{p?PL3+tqDUm6Cwexe@!Zd z-4=OpJOu?RX91etY;XKOnzjo4L-$sVS3-ruGo$9E-pyhmC(m6K2`#eJdy$HI^(5sL z`p=sY)xUmKJy9>kYW{>QOocMFZgsyd_sHc%YwWU-@X-;y2;sBvsJ;NMukI@>ZN%u9 zHCw%1g-ciP*DVBQXC^}hxk=l6@qy%#hS%((1K~xEy@im7JKOO;%cZOH@;%+4fR3Qd+=6dQr6^Ooz%O~IT6Mq5J7of3G_S#;gZ zq#kRhhl@bK-|xLG9mxD$z5H6@^4je{C(`&;>-KQD)*PPO#% zNr@@4`i8r?)nr(qe_t7FF7-U1K8Pi&)uq_tTcP^Xj=bWxk|~|=Ru+lfyAVOzwX6Dr zY!>eb1;Z5s6~Q>qdNwoKy|XrZHHi=ybjN>pOix?<5*w6wYBZR`O)jt}3GyP|3CL9C zIAj>-%+149UL7-kwe&cVwBtt9j6lP&gful)GL%78jHs<=5QsfgvNj0Jz+~mAPOxkNtsD#>- zzY%>aqZQOQ$Z3{LCsu7Ei3=*%M=*g$|dG6|r~eie&5%>dD6kIkhmncM8xKs?D*{K zmo>cBs<^7rj_4j%jqHvATS^~@7P)bXLOWP)BSD5yYwGyU=e67JxYfH>gEfX;6CI6< zux(y*8R72L7X&=sdbkKjA79$5_-;TA5XTEd*i%)lQvH53l|AV|7~lJpsbv-hyF{3$ z(p+68kJ#h3HF-E?I+};vF?qw%|98ChpJCjx_oxbK#Vrz#*ULxC`QhX{GGV6W zfxcfSb6_D#T)iOu{BKnW=ryi-sqheN8X47z>;$|nSD{``c+bQLX_dA=s z9%pIrJSq8cJVO|dOFNi5v-W;J;;9J;pyd93fxp~oguTAbn-goua8lNt{YA$#}T1c2X-H;EOovt(g_!}X2Y{%{2^5@am!ZNBcl5M|Eu%jrm3dPiWs(z{07q*|6rY=7FnHdx~>>mPz}_LB_~$TpS(#t{sY;7l%|jIrvJx=mT*b2c@S?6<#U0N z_Q%$ZhNdalv6ImZ(LK4HM?P||rHVw<^LUKONSYlM*E>0A9F%*G?vdj=5*I*-h{v|!y=}~ks8E__Zu8pXleO>c?twXchJIThRzKvh z55u8+!pg|hKa$Nzbjp-6O%RKbEx|m$jAC-%AtE*vPpNPj$i-xN_wDWNmI$xI;inaL z-}IPf!Ngp1=+annDYhThQEaXm*7#c4bqOH?!8&49W)6}t)FmaYtzv4b981890 zIcM^pK*m9zzWA(>Dy0M|e6iuZ>nw*=OuU9M_b%fu&8JOfwDoAhTHW|?TCoF6vYbar zc{3=KX4z}D)3lX~%E!t)@FFoXexZ6+xZ}al0(uIWhmxn zJ2v#`WEz#!W?qBpFw+9SEYNafg(+N7LVVtd2lbcQ7`zl~WfCI_wCPb?8E^ZpQM_uc z#co^9z(1WPYSeza170KN15{8iaXsxzik~6U&EcpFRqi)J`xK@EOu?GbpAyyKc&#ce z3w6x!6`+9up8fz?hVyKBzr!Li8CU_rLH#ME8UPRi@!$K&_RieIf&TArH}J(MiRhF{ zyu9bh+XB`0`P9V|bK$W8s4eafSk9*cy@6q!hTADQM@5Vw6LV{r;D0=R{fY!J{>+Ip zt|y=MGYuTso2{8?)kUk84grf6ggRj)5JlFlM&y-LGP^ar=K zn94gJix9>A(YvTA7(+|mBXVaD3Yk1!6tSz`6j=%`6_o{;s2ok1l88*2WI8&!bLBM8 zV)6oy$4wV1lw|xKN%yiavvSyK(*2>6RCVOFmfAni-4@v{vZ~E}!2jpbP>)iYMvR)T zkOkWN7q?7_C{es~L$&iZhSd!k##2yfeOCcEMM9O`Nyhzh^9F&-+2UaKBu}y;Mlm;B z^bg0;@Shq@tZc<0>1*{ro0+ukxlg^#Uw8(gZGQQepKGEN4qD8sfHXaHNn?62QzBV9 zx{bXxb6G@~&17rXB(7K*5#F8+sEzV5J8on|!FLdJI>f$o= zFVRsA$C-e&)h>E$+;{zt)lREU1fYnmkHOE^tT*zHZZSupex}jkJI%0Z`@Cl{fUIb8 z=S;*P?1UsGOkc`1f+RCJ~GQ8%46F{v^j52DZ|c#{u;UfoD|X$f%D0rAp4b;%zo zxwl%Fi%}C531~D3INvq*`dVv8_LJ17XsuZNys__aTz^Qp`qo;s`8pA&QwQk`-X~$@ zl+AlFDt@lDd3~}YmoYe9V)8vCvtW>rh%~ZREe!n0f{GinR#85X`ZlYChp&r%WG`x3 zsm!{!`OY(@zy>>&Lai34i4@fjf-e~G`;#fdA(PKa{=vye)fW?7I)GfFT9FRWVSVLxIW{-`S|$_MAv_}bb= zymXCe&2sCpCSm|vO-pIS(z{ZR39sqOfaMSm6(|x#j5%~K&HalHVaBH4?VDYYeNxPA z5&8;J5Qk7@{D$ylW+H8NN=SlX$oeHU>dDS3IvYfpJ>iU?a}E(D>#?|!Jw-14mF8pe zSpkch66QPI?<@q<27g4!l$okG=NyNpTg+>8?Y|_G6sXX#qSOOuW2n|I)%)w(CQ*IK zhxr(0IVF3;F6V{&wasde#H~^kv;l~J7bU`)JZ4O`9XOfl^8LNAPSwYQa0q>(zrVlC z$dNK#iIeeHJY$;BUXnI}strlMsi$W$xi6mCRup6E5JAfpttj8)q&Btrs7hRaW2ezKSoxy2g4z(qC3`W&S~NNl zC0Cj*SuXv|05>zx9X4U<{hta_W)zQ9O%`}M88Q_v6HaKP42N`1F~^tO>{=&pA$}41 zCMhm|7o901SwsWp=N87p%GQ8G16$!og8O4IgDS}p^Ufxd_rQ`F(GcQnu8^-iIK;A- zRA%gYkRoj!4v6p@5*{t(#bK0u`S$uXLGb)B$bgj}@?WdF#@xF*1(aanmqH{e}S zrI7=ph|!5*@`W5}f^$Qp*=lEL4Pqc+*e`NM)dy*VxF>7i25{PTBwpggTehE z3G0Vc-gCe_xt01+zEdxOqxeFmkBUOlhc#i@CImk#$ zj1B?Mk;SDLl!2&}jpe4yY{Udf*@}!*EYzLq;1mj3{uw(%V|nOg2)1k_lp#XxE>^=c zTZ7U=PK!onwG%jn*bm)m7In-CBO+9MRup13JJ8*#f-zN=o6ra5lFK5*Ah&W2C6bShpoaF<1S!u4Ab__taMS zu4`8jX%fC!H->c|tfHbKibNnJ;?_?{#Lt3bcmAB}v6MFgA&^1_n+UC(TXZMSTs?+1 zDI6UGkorKAikJp?DZMBCFs{VxR5{CwoggPxCX`4Jz#4|Po}lIN95w`p))CC`vJom0 zvu;}FZlgN`M%T{N8u$uy+ssN@uEZ8+%U_7Y#o8$Uma+IpsJD;MaOLf}Ok)k2X##20 znf6=f@W0-Mc=T(tB?7~;9~p=qJvltwZG+0&Wv#Kx+mx>5wU8cPKDK1>^t$4f=p2D- zv#{y2uN31tivI>WBb(SR@)Y;nlHS)ZTC`%WENR(DoEnTp(DMR7X5x=sZKJCpdxZ zH_nNKh^|TlL*j?s32k-dFC2P`_Kyu-oD^PVN9NnZk%*b);TclgnX8~?$A<|v0(+_8 zWE^-ZS=TEUw|up=%a&*CpAJ}Mzp)@ZnDK=8K;>e2KW`nMqI6M$<^ zY@y6A%2nt!`7_{aFtUp@Po6dv8^Y7sZ2l*>dyC2qbG6OFU$ZBxe)aRsPFyzvFvG=4 zEq4bSl#H$m5sd|2X-osltiJ`W_$-U~QNo6GsNCM;Mevy7!{S@PuvN&z&WlbIq$>G` zna9@)irOVcm{I5qdea+v=(Y#>K|CBEljnE)u3z1BotWOB%}F`}uEp!9ig_{Z>GmA> z_}#~0*%r`$mD^h4zZayFA|c}k<9nrS-)89vcC!nw?Aork0K+L*T+e1>SC~X=?!Ii) z#kAGy9!2vl$^~%YMx%eAob2+<%on0X57=h*rX`y0$79T6s$mCPov--r_mffmyQQ3Miv zSD86{NyLtmg)lQGa@{#T+}w{_VjN2(?0nnme@$Ejv@u*O8&4&{4el1*Ha*U=H@Ce1 zI4pg1VohpSe>TK_E#5Jl4gt0b#OSCts$*IDbc+Zmo9RiQ4^MU~yoVX%<_^X*s?8

zI2A0Qc$IdG^9e0`RZb9dCBAmU3@%i=TL8*1^iD9%dTa9G-Dm`4DI!Z!$U)F@uMqi? ze%9!`kMn%{`I9&KuDW?j3f@``e`Fg(!HPf21ed8S`Zdr>B+BSU+#ri9JrM8tlu^0w z`-V7!X>EbhiYKPRJ5qKio<`hLdQipHJ52uGzRFYOD?}x>TKa{W`0Su@IhBzqTt+8J zE)f&lSrgw6+!Vn~q+nLh@AG%eSXdcZG#b4>Gc~FV^A-|;KDRG^I1GIEyk9oP5Eu+9 z->dCj9^&Ew0ScWw*@9dHUw0-oDhc@-*}KP=i`P9>@%~@EnN9~+LaiudNJv82L&rg; zUMw*NiHZq=WxKIPTM3&Erh1^NHCLn2F+GRzoiO9Uaq8uiZ{`1N9v4rdHYFpx!l6}4 z^2{o}9DMKGX^l2NMP$o3kUcHu%2Ay#sKc04$opf+{H?p=abMGgNCUEDBvOq!G!Rlg zHix+3wW*hJ;7$}V_B37!r-R3wQrQUNpv!en){z*aRx4V(gyHc< zxxm>!#d@n^Hk!Opm^BbaiwO(sC?qqsBgzJoHX2haM$xd;eL^F1@r=W zHwet?_rNCGHIw&g0h29;?%EzZ(&n{3XLkx<>J$P-G2LX9x9brrPBaeN zSUBCg1Z=^PZ;OptC7j;r&@F%T)MjHG6Wc*P<&;jdy&ju&A0U}VU3~kj7uSKte~d;( zKQlVUz23%g-=RCIgm6h@?h(iEtVE@<->zIct6NZttlfyM7J#IO+Lve3EDgr*;2{wUM( zhX@ZCGw#uL70C3Q5NNE+zyHt@=BNV2LOzJ1V9Z)+qLlGeIk{lZR!sbxr8cfQqpe^d zwb-c_inD@wrJgud}q>~quaq3NOHHub*6#^Q_NStcC9``+q8P+YLCGc|{U z`nuwEn4?@Sj9xJI#XKtF)-7ws=XH%K*C+)#%&G&jWzn=n5CwuRVUj7O)+71Fr8`h6 zk6O()P{3GRtsW{*o*J|;MQh$d7I7Wv@tX->FpF)Pq$`GJE{F0*F@FNRcfCgJF{9$= z4vkjB`ArScn|1iA2f2)<6fkF6_4sXcfk`pu63qIH*s6ls#uk-u7ZbWtE^i*vL>!?! zGB%jGK?zg=6Ovmn8;TlGWN1cI_CHEqEF(rg6k`3*OrVRgy*1XPuZcuLW%XK|50VHm zYKN!J?Vdtic4Rsq5GMWDU^HyP3n3Nqg*~XZ!}}#%wv3ZgMBE1&+-FZf(58#OXCTTW zpeL-ah3Fsdaqqy-%C>m>E7K{1XSkC-SjB%7{e(aezueS=rV}+DTW)*mxaE*^YzRtJ zP-A`a*IZk#U-nuBh%Eg$u8#`MxERqCNcSX(w~Z`hT@2*7HV{<&Ra`Xqm_E`Y2J}vj zL(hf=f4^C$+5e}idii&%-nKtw=95(;Lh-4z+t9&5(vMg?@vH$WZ0sOvXD6GcOl=B( z%hfKh;p4tGD1{7#i^4r zJ97w>2Mi7F89c3v=v7i(gum^N;!4Pb@Cfvg>_0$x^f}<~)Q4Ao>&>eC8IQ%UIWIS1 zJ=NW3&~>auWxNQaY&x^W>^^94tIz9l*=TVf|D4U85Ymf5P|%%~AZ*4+F0s?!fM7tJ zT$xFMJO^C@KT}WbmXjpJQ!AEVB)J?e2GM-q|LHs{Np#j!1kMTh#=%)q&_?o?PCNKc zWp5bWc^1}(?30l3-(?ZS(~{HHY_d9c-I*X!>)-Pi~R)ioekW_r`g*cwhTEj)6I3Wz!qVlGf2&k)&w)ua7K^+so`On?nRk14c8G7Cxq_BTl?Qf!tXcUKe>pstk^F&_-< z^8xPZg&j_2jXF%FcswE=&#FXrZ&3O4^>g@1 zgK=?WM}&e-v(Bnu?0^Jd)*Q-SB~YkL0Os>Ir?~lu(oqLioz@Tnwvc9$;HlP1VlgVg ziQgl_QbvqF<j`BwPJ4Uz*qJZoD?C9EKP$m+OSthyxdmIQA7FHy{ z+gEfuQ43X70yFCD?Q+r+Y9@=7z_kM$~wHkCLXnsC3BODaMqV zf~@b`79Tu`lRKlQ$oYJjhgOg)|5?-SLAdi2BggBfoRXIeI4H9}aklEEbdF;+q<3N!4cLd@vR%utP!kZ;Gw;M%-GWqx_5I z!<|g6D0!{1{@-~XLqlAiS_1ASKNUW0i%%AXO5TdwW~+yx_qNN>O_W6r3cf9~L}b z-N7vsPys3TYgPS|X$cg3THWI>ZaBqdE}T3Ek*BX4Ai?L%M@)?AMb2A4P}ciz(i9{* z((RXRZ7#r`@w(O~BVVWsTVnixEIvG4ho)~$DS@cKUb_tD)N*3-$h1mFv=Zj?Ab1j$ zt+PUb9AL;)VD_wX&yh1zzzj}-P(v<5E0wCR&tye_!Q_sxd;KVvb;a+f{;dM*_j-%t zo`CI&Q5H29O1!p2llvdNPPg0DMJ?!u@c;n{{-ztcq`#&+n&QN3huUF_`YONJ4B=b=0@zE=~7dW_X z%*m@fW0%wErmqZk2mj+F#k_Xm9=;M4&(#jovM=wTD0I7Y{9(;LUG4RWS@YYZ5}=iR z^S*xhT=AwN9-CibqkO{P&=C#%_;GDh`oRxw12Ef*vB~$32G)gCHbt#sjSu}?5&ohg zo55C)Ow>F{0MKt|FNduDUOdIv)hcwv5rd3<8yKl3P-^b`Nh6y_ea}-po7SrFyAU0J@8K=7Hd?^ z&$x(MzM=8_Z{Tv}UO-0!JU*9-`@*ld`pZxh-7)}HR9xIEYE%TuxKhsyV9cBt+rnWH zVEIX2h;9ABTG7Z@LD|4+ejM%C;(fu)f5x-cVJ^)FRKcShx*pe8Bl&X?HxRq0uQ68|d+F6Zr2y_V=Nh&5tuO)Opv|^ZaiifmhahGi6WJ1p0RH`}B{OkbAxk zVCpri-zgyR?@Ex?yWdgqR7ezgQaRctHon4P+=d74GBxXiUVs&v{F`3#bu)~08VDs0 z4clJIa z%@-bIvKZvOv(W*QY!6ys5$L5bs0nNTP2~Mz1xq?0S|FHDoW}nS36tS`U?gCv2raky ziR6kyV%%@Cb6n7WgrAvj`x=XuU#O;)5{`Wx9vRu(kq5;KLrHCx7nyR+=Vwi8P%()X z=$V6@>F@9VjiqKUlR_b9L_h+6O-qZ)5LJ`icSIcqtR!QL$D{9a9G9co7Yh$1FGfyQ zNLLpxZ>c{nCo&{4<1G_X92Izm1NLzhz5B$9$2KweSHPV-kkOvD|5GPox-h z+QEe63Inysh3>yQ3y7@dtvfX8(dMO=jGCq)DKsFh^;zM|QOlXZ(8(55g3R;91h2iZ z$*t8Q;}Q}%0pf{bC9{=D`LjxU((*A^kB^@PhP{C@b;--0i1c<}Z5ffAi$^~mmVJ7* zLdo_L63n&5b6^m=o>^fdiCCnudJDEDGw zVwCgM6sU=biEwsyMnpse?CtGo-r5mcGxB?N*F3&C7i7oW{*$k16IlP`*?C3Jb~nac z`^2eRT>~EZfATo|v0Y$r5OJ9l=(IZYZ&MQaoRbk5v=tMEuS1%BPG~g*s$-+^P1}N~ zTG|6?s#I(`5QnPocEiP+{)mf-z~CtxFn4rIXwyP4{fBO7)nz{Jg~dW`XODGz0YiKs z^1Gy=eCa&68Dv6m3^6H~u=j*NYE^Q;kRD}WZ#3XWkP0q2>Lc0giF4=9qg{_RSUUAn zm{M+H<@cYWb+45;f9C;IG|B8->`=Q}P9#LeASi+69Z_|I0PGYBCIQ>2Egin%4~j3O zCOo1=cN~Mi{RW|rLnzRQNy&d18kS&F|7)n#mhVj_BTdOC%gT^(0VhW%5Qwkw@Zm!v zHLV;;Nl6VU6hBH$F*Hd`NYu%>v2igL?T*iB#mGb(Od;(>fEg*M%=Bc+^V5ki|8Z1! zhg{w{s=p#Oc_p{C39MH__E&S$IJ4R7;<`cQYQjYdOLY^AJnNHA1h6dk~aN@YzX? z89#@jQMd!DRVe{CpCF7GJ{su;YD=1Q=rlRd>Z`37HT(nQb`8LmC2jCgyXnxo<%G#z zgEyI&$D8M=K ztbXh0>7y5rW|)|Eltv1kl$Mf?orePzVk;&bJ%D1WS>Sj1kjGP9<1JwC;*Qi5drX?K z3~gIB+OnOj6D2EyhMn&VX4)HLGU=kBhv?>u)zcs`IDML>|BO}eMSMS`jJF;Yn z5=sb#hANd{Wll~`yjB_#Q`Uk^7oH-v?Sp+La`N(e?ua>^Tg zuNs`YC`}Q8~5*8cxX;?&r>*G**t_&umaUCU^Qem%8 zL{iWW6x7^8v1(rE*mpbh+MI}``QqT{Vp)7#KrFnHYem^b!4*r~&?Y(_`4 z>b)L!9@yi?oyXX7#0VD$F0Sx>$nE6@ceM+zV~1psAMNCRfK%V%O1yfQh9y=K-_0xjHlz}m2 zHTh)m%in4Wp2SoqELgS$@7Ak|{P{g#Or_wGD=GqAqX;IesYvBV86v!_!c0s=F$v8S zhVs)yp{EEedKL{lK{O_JcX!20nUunr5bO<$S*1+Dqd-3+$Z)4|A2=ylA1T6Y zcD;Npy7~PF*E>Ia6j?1iGz#&L{o&&ngV#!X;lPDBnooMP|K>}mO?G(iH5Ux|$d}55 z8y<%GVDggVs9muN@)jzL1wY+JhY!7JK0U;Osddn%$98zT6+^#%-LduO9r(CuWAyGm z6qCQ7fE6o!@kzh4s8`7eHC}VTy6J7vvG;PM+I!GEOn|$+BSwDvKJt0#2??pN=WrU1 zT}?x9a44?bRb$w=gP1((ZMZl_BTxQ9_`LUUYAX&f>rCh{@(#3y6xiE2Bii5tduLZA zPAY|qcf;NXPtAyEP4X{|CLYMGil!toNCCf-iIa(qXZhU3FD$}@2V?{jNPLwdxH7%|S!Bt>Y5cBA5%1`#q8at<0AqNa2lID7~N3+2YUwQD0iHAxXZa$O_OlVJtj&FR#< z__u^Qh{>k1r*Ps=5kg5xiAbZsb8v7_@Fyo?QI6E4_S$PWd}KfT^5?^)%je+h>xp~!?kSqqwQJWX+^9_gPXBNgeyNXV z6Id^moG*5 zNI_1df`Dvt3SMxAit%z2!?dILc#u3&JNH_7OF^y%IL!)ES) z_Ub*xASL18aU-4_9Glpzoq&ntMJtBb30{Owz} z;6MydzL#^)oH+wKogG|UT$JmJH`UJ04oN&#G(&mbq{JjeU`ec3p@M~Y?*GQtUW_CE z`A6FXRyNEL7lqy3Ff==S`eK*+4?}Cmga$Ci=MG#QlM%vb9HZ8Y-lH^p(5ffC?NAw2 zUyp-5(y-$|GFBbBORXd)N|mXEMXS%CSL?zwODeQjudtdxEB9 zP&2T1!n~h@F>h1o6Do3n!t6lhM+Ax+O|=Y-gl}l3)}w?IPyv!gdS77LGYOIAT5 zpUH8VL$IMNp#@e!W&K{Ap+RK|BDqJF^D`{N%*#pGg4|R~!DBY3qePkV3}DXdr&olHNfP&BpV zU56P< zPoYnT66pMi2ei#RvEt`Il&{kY&Rzxa@b)c?7&8;o2i1gw=@GWhZ;EDJHbU!Lfs00q zLr3G#rA<|O#DZb;=1!f=C~dP&j2=a!u?{manIsCalL4s|EV+@UWv~KqB(0cK20NNV zB9O9bMe=tRa5~Giev8zvDhyn(B+*nnJzQ|-?roGQ^#<0QrFT(x7pf1^P_a@e+`e;% z(#DSIId|aVC39(;YxqkoM*eJ&RJiJ3qNQX3HG)6-LbZL5oJURwr!cF24 zjuRta%Qi%#%}2#hv5XJ8w=RQOi!RUwPb`E2!_&nX^T)S^KJgL% zW`O19NL;v`fRMN-j9Yjfoj%HkIbt&Jx@a+qm#?fO zKY!J|3l_|uj$?-o!h?b#2enBDR}b7IACxX#S`kc6E_vw5OI9?ZXvRzBWC~ER;)Sqn z+cv}}L?bSq!poeKDMJqs%t-fE?>9gZ3MG|*^#a4`jC6#gDY%w+`;+7YEBFvdjM5x)<=~} z)p6*21ZtJ=Ms&no%pTDYJx3ft5ItnkR4P^-h{leykCE5Y8ISzWAT^mO9J;&&VqK7K zw#O%5EWxTdAES)#6>RvSD!LEef`TRAMAcgFppah)Y+W@R)#%!c?! zO>>Oq_^MTSQ4<0;F0Po1?XgJVxHYu8tNjXo3XhecH zB_|~*L7wv7ckkZC^c4|k`EgUcNfS|HNP@=Bk$gdL-@)NQ;eyN)vW*v_z`tH#J&H9q z*n8wk*IRdQHqq*InoHL&BQ>4swAzt7St`9gYJAl8J4NM|VI=00!_5=1F^@5(XG6F- zMdHKSd9ifMLzI2915TYhhf7z^V9?~_m^ipOig`HT`$>K9RsRJza^f-L^j9^=mA!UEY`B_UUXJ5wJ*qe@0t#06*_ytyEFFEY8w(G4GV-$dnz?sZw; z#G-91peNMZODVX6z$Y%bHJz5n1Q7q9_t4jT08+yZ_%=q01(l8_w7g&%`L zMSSoUO|QepPeNd4`h12$px6k9#_AO8x0b>Mi&TbuSAI&weaK2l=h6_8f( zj__x@F8vrlsAY7uj%(P1ZfZMve8Q-u=m;*SF>HtCkddh((Lk{Li}FO#Vx{5iSsmTR z?xrTw48e&3h)&R8=A}{zt&)$`dGQcQ;4)Qs9;-kQXWR)Ezp01`!U< zNJt^Jm#)EUCG6ng5Q^(JXo5%Dp<4C#QM!CPEZcGbE);4KpY`MVBl!5e7EFw`2v^&9 zaSHq^1lIk~+edERJx5%IQOQc|G5=Y2UNWB1&I>wvZ(s<=C*>32Nv$c3JAXO@d!iZb zoS2*dEpehe%pvo2^G0Z_4sK~a_@qf=44b?aiS6xNJrroIGd*IGJ zfAkwX2{XsGhNCJJ>t?mXXG{eNgDbX#oW;%qCiLu78xbMF43JdA+0KQY9X&M&Al~eU zCcVyP2%5W81uR}76?bVPO+202SHX|uU9v7bgR;;V+eA;DL|_}Aa+wKi#Ko9J>oKdT zfk^Z=HAxvJsh>hKkgh`>%-<;hOj#ndH3ZxhP~5tpS>h=xWUisPlyz9b3Z8tTU`$UP zAi~C935aakb$}u`j4pIG@b3TynFc?gTa?dhHQ5~Pd@+CC&lomr5T;D|UUHxr!(=h3 ziWe=0`~D9pq?txT?MH@Df{6e=d-h@v5?#T&_y&Xb>dzKmxR!EPbA_Nn)K zlKZDZY*GR|7%(gM&Zss6M|W4{wA@~vc*oZVQ-7EaXL~iu`o$xLW`0n3Iy!Xw0u^8T z1S6)bL*b&OQM_0&lr38plc!9f5Uh*9MBu_M$p@svM8_~G39_eV?m+FV)mH$446`BLw+`beRZQg`!XC6_Lv13$TVYC}`5XmfM zqOv$ zAxjXXNvRU>Mj0@R@AawN!a z5t_{5<6LO8)KjSynJ6HQG)b)*k5(r&qwFwc@?>=Qq9c+buA@%PniN2GxN_+Rt_1jE z|KVS#g;?InOify7V6BQ^6=c@;QOJ?ysh_6S)Bek>FK0bJDk=)z-rjI!XoHf!M^CA> zQiHpjGpf|~!=BxT@c1(0w3w9bU}wfJ-`yo9d6#%pF4p7Yw zq;{3{u?1C1rPn8oC2j3-_O1i!cACsJYGe?fC!Dw|OI%BIVmvjiWb8N}PM)G+AZodZ zF)^a~khw-KyvBt=ZN(%zB6oB$pBN7*)IiJvT5IUi=ikI^Gl#?s8EK!XxVSX@&*I>c zRR1T(JPT$&iveX8lFPVmhDAip!XlP4B7P_gOmu4}!${%aLesZUp`s{KtT^nQym0IK zMMQ<(!`Kl6>7h!*fg>ldanoTs4V(!ui)JSpi3RI1DH_$2Wi8rT)) zV1|}v??hpkmYRtPs;qM%`E^jC5pJhv<`%fGh%I{*oV2s6b8} zI=zfl6GHiJD#k?dnHjT{xhIK0CXHoAWLTfh>V1^lz^p#XXB1MNp?&K8GSADno+xTD zafwJ~+?9`y4>el3!xL|*G0^}!-a|!gRYd?l)tt)jRjeS9Mw-%`Oh|+y3j|7H_{2#Q z(YJpe#8&b)qnFMhjGiBrENp5dvZ$4CNo&2MX95wQC9QQKJwM6+ z_mPxG%6PrPYsls83m-cp^5^wNKEGUyztQ2w^;5Ji-7#*;a@@Z804eFj=_nNP<@Lp~ z)oYa!Dd7>RaB_D;3=?S8#K?ZnGx)!rL})AEwVDz@NApauArV^Qybx?jJYp6JVoiOq zn6?sZnRPs?@mRmJ()Ypr2#ZNeY)@?`!cES9a@HStA)lA-SreBnykohCRq-?ur=urZbs4w3?t;Oe z=YF2|pf*^Y*ji_5nV%FWP{93p&iSt$^RE$DLilE_TB%n5xYleUXmR8IV*zX!$7EqV z*;x(TYTvI@3#U(=z*k>&Qc@huOt@XXVj)tQjqk*ABOkT=oI5J9i+p*pa>rIC*ix@z z5^C9UEMG!~`ncKW7&?4J=7Llh`hQ?J)@*(&V;H64L6+m0nDG?PC|cN4-#^V#Qe#{e z@P#YqP_sr&xG+8{XC5DFOQ|@t>mc3k?_=o53Dha60TQR<_OGP51coQ@-z{ED{#k^% zhWia_}LBRwik5Q7-qo@fA z*k+_<@F+Cctjd+g$xo#cXYv1=@vjnCGApgxex~|y*=n<-WZb$P!HNSE5KRA&`izYo&s7vsUS1wJbnuYEe?G2eIQkgSt$hQOEL9RYy=hV> zCsJ@)>cXqJ%St4CRP3Ygge0c;C)_3}JW8Vsn%hsH1qk{KV?sc_-KmOQHe z2jgESuw+i!wr{1HzjztJ6&5=ibT5vuw{kUMLrO*&0z%IZP1(+09SH5{#!x4Z#tJm(2 z6fDt}pN^D&nx6ErJoS7=(#D=zW5arHA~7}ssVp4m>g|KintrUL%-B0QNbLp1oK1?4 zM(2*LC{U6W?KwFy4%4R&z=TQj@GyWdfTJr~w(W~T@zA z=-ee`+LWE2k>NV2r^LCJvLZ4vy=A{Mxk@xs7Mb=N@+n){!oX*~aX$!t+?lJCE{rd~ zY>E31A7JO6H5l=2cYHrs5L5+mr6H!WTp1fDU!yqN>V)W>7N};^TQzj_EYKg7?gH=|R#j*7q%jc&o3WvJiqJzT$j9RWe16iiMSH*OsFja1}gp6P+T zCy_UgH)_{m=7cekB1S?^B#!X6Rdb0qlUTy%9g<8<=%eJLfFN`J0{Q-@zR%)+^@xMD zp>yGL*|0@>6XEFU>dI0$Nytt7PO=i@Z$4i(+78eAcE3LEUn{WWRoZoKrJ6T?rP<7I zg6mw=!ni86U?Squw=7+)Rik)D(mYvEPirGe`P?j1#qv#0p-|5XgkO85UTiY{NC4_2 z&Wa->Dh>}r!g1*0m`q`O?7~t-m{_EgJZO5xv;GfWQ?#m#A+&iGk+;$-;}DHtR>WO2 z3=lOM=s^`H2Hk%KE_5j!BVi$;sfmEFWD{tWN|}`^RYIY{g^)mp#(nk%e8~8!rcFP> z>UA5QGP&isvnE?xw8Y;ZDr!&CrprhNNsj>&FmCvl@OEc87M>SF$4W$0B+8br$dW7u zbnZTcRVC7xmzPUfjKvt>x_j3}rp8zrrD~;WD65^;s8ItaPMpBlv163FU{@|*!x;WP zp#K24I_D&wWTdv9h96gKBBrFp4~yn2?<4;(~#LL3h5S&46Yj8Hz$m#>6U z&x-K9!h>fo+`?NmUPE#m%R);ST!xJQwJ!YhyIb+AXDMQhC(~yngNn1_VPKHCV7|Og zs^)YNf?P>+DV^%5nni46C5HsP^XTC{?O7pD95JqV;0kD`!8Z zIeqwn(n%+h$;vzT?NK!D-UIp*Q)0*hB}$(@J(P%gdpj|D<1uPPZ>(IolEJX|@zoby zsZm`+i_bnohxY9-@rPNsM=k%8b_|9cJqm#V3}-lV8aJ*zU>Hma1!Nk-Yjn7D{R&3( z?}?DWM^A@sWFfqD9-h>Ymr4&b|9%s?c%sRQW+eYEUc8(v0{7<4+e)Z~cymQaN#eF> zPT~m_0nRQy42>y-3m4ccojDk~RA+KQ2yl(VxvYF2v#-d;X<%-Z2n)iNTAUNkNiI|rr} z(G1ksr6M*e6gMxO#OqZG;~ffwaK=!X8C)eswuVj+y~KJ+(K^v2Bx;{HmbD`^(BXRW5VT3<^%!PXq z>;;J9M}Hw6b%C9D=piMDt!Bo9(cn*w=`r4^UlWm!qfokRLG0YQ58+|aaPfA<4VLB^ zJ7z3KjT(i@ew9(I2sN{<2l3g*ZJGCY6hACnqy&bZx_kw$xeDOh(c?2sysmxw(b2>E zPdRu_I!i13d%%R&ir1|3W^4MiJE zB%rTl&~E-5`4wPZ%Y^uQcl}YJVi_Dgb`X^-SLV;dEWKP8M~@yxt+%RU|Ni}`Qn?B? zY+Q?GpL~XW`*)#Hqej@XXAi2sQR^gc^ZK9R&FnbmKOwM$Fkg55LN#mZJg%GExE&Cx zFwk$s@I0yY{eSFT1%Opm*Ih5>O?T4W-Jl|hBDNxmA|fh?iJ~aBqGF&ZDxe@1qJ*L# z$OkCh-8u9C)7|s(Tl?I1rvPCDC4A@q`No;|Zk>D2x;xfh`+{`Q|A~97J=g?raoNO@ z5O+ppsH9ep|Ab>DZ{s0DhEUUe3?F>0Yl{pM`D_wM*NeyVatcwqVSOAvv=1SHCR#OY z*=0#r-!9samyaO1U$3_W_=zQ30#~jDVyJ0~GwnbDaR9+FN>XbLPCQOM)tl^EHzTm zgD$FAQXM;XM11@)Dxy}WoX#O$cQlSO?k1L3Vp5_~NEKBI+2{K8>(%@+w$<(*dno_L zjxQO&l52l*$fJhQpH5IOoqb11NL1W(S$HLH@bVUx%3}S+%dA)(!9BU5x#&*IE=!oZT{G}^8mX#^V}HNF%vv#q!r&2yG~5y$%riQgLn7B zHJ3M`m3Is&ESApca2dY+elk@Ncop2mQpVVM`JsBdSngHC5F;vgMdcO2~Og3{nIGFQjov0hUbcpr;=;j2-(8m#qu? z4koHMZt0-zzsVE2kZ!boE)py^R_*imuf_eE12KDM*=cFg7SO z3tz5Ze_y8Jx$fi*97n;s$f!`&?M1mgv?h+T2)r^2hDH9$$|7tpzYO?VomfiBz*Sdu z#e1&}LB}?&@YAe~h+~{5B*Yun-+Dg*E)1*J?LZ-Q#lWu5E`qQqRLHQg$%7052niHV zo;d^lK1NgtHnVA~4;Q~T-eG)c=!eA;& z0KNSDoa}eKnEM1*TNR$O`%X5qcPwKXJ^FLJ@Y2ip<(FU3ty?#(nFgOua+R@bdpwhg z)W~8js$>SGrZJbUa{{&f*RNa8a-}#1#cQfUZ*d>x^Oh~D(t2WDBkx}>tv4gHqyl)w zS#RmqLrRDI-iW*};UvmEs?UT&B3)%EKN43tAdnOlc2$z1?V>{JbNNaVLF?Y5)qrw8 zv>+WK-*W+tOAfGPZl8GKA;UW(M!Jl~>e$7auD=>5=V6s>poX*R1f9&xE=Rv8IGFzy&>e+&J8S{{xsZc?uT`vx9tt=h3C|qYLx-=O1IxlaFda zZn_#mT=gSZ_B2D$ulLaH6XS2gjSY&O?UA7dBnm5I+BblgNyEPS0!%(+w zUF_PIfb|=<;*rM&;hXO!LIn7xl?osy6TaAVM%$h5Dp_GxP3n6pr z7hqN$X6zJC6t^ZMED%?8?ugxcHA9XVJMIM1!VQb?Rn}e_t(<}aC*x1Fo(M)lNicgERp%U;V*`n$U;QuxH+8!T z?K{+k4^3W`h;=`RLSK-7vYnz{h+dbQeJU|6aq;A5l`2(~iyaXjLkpYIgGJUwZCcmt z%l%Lf=)xVBq=ltV_cJd%X&CXrXudXTAofrq<0Nj;w^CMa`Px2~ag_x&c|1$Kl=aVb z%j|Rp*4Y;CmREZ?(?>~nZL|`Ak_Wmx^SpeP)TrnUQo7xHenHdnDhJpXkk@C+_4lS$Flp2&<9w{Swzcg?jM`!&QV;^ zz{QeBz#$l^LSP>_=PcFPO(ot|Yne!r&*8Io6323W*^O$y8PXX-XIOl(hv2Xuz^uF^t zz69j{YD?Khj+Fowi=(@eL$&x!pO=f}dzUm|$xV1+=pe(#BR^;V&M53S%=Ei*=`Jk4 z{I4FC)6pWzZ!2$8iAhP5&hW5sG^$?{HAxPX?!m&vk-mXiR?b~CuHdO;=%H#w4rMk< zvQNp$Ns6NryEhg^T#%MPAH49!`{;V*WmvU*Et1kQac{r-nO&=esWX1lVq#4Di$%~V zIv7`8){^Y}-MIX++o?!OD}jq^J$vv8vGS`aKQW}E_3jfO`+zRgph1H$ZrpfPLs!Dx z*Uqx^d`LasG+Kh4+P1+rKm3lNLmxrQ_RTQ%t0{=8C!K@h*odQSF}ivIlw#|aC+=!M zUos;u1&|`OtO2FaHU!Wtw0dL|u`W@C`1K-70+_#V3}#MWhPt&PR8_)lx7~($^X4(m z=SxLde|-Gy=XiGTt8~HnI~!HBXxmZ+`j02=#-?3+=(0%=kcCi8T-YS2@3xR6PAEZH zX?~HOk;Z$RLd!QBef!*v73-IwNwYc#@D5a#E-k2~7Yhhg>*$_PNImZ;$wl zGFmmTc9X6K%j&i49NnKhtPB)n7vY(K58~s|UsAc#pOsK9 z>_483+bcC>q53YYUHU)xF_qq}+s*8Bya`9*j^WBHy0AuXi6XB`woABL-+ucYZn)uk z%$hZef^7S2!jV>GVyF20u)lITzLHHO1k? zbR0RJh&yh*1H<2X9V17)t71(fKKcqaBMYLLU~n=hUyHIw5zMGcENRR3^$4IP)~-e% zs@JNDqbbK}MF!!ck>i+YtxK0L6Y->)tXcXSewjRu*k({Ql?3+Fk?7Cx3A?bq_MZSO znex|Oc*^kE$S+(buWBrqrU;;tG0{`fQcSAdUt?h=icP zy3SIu>qkjng>hV9q98$a8}eBwYvOKkt~2k?^<$u09^NKOqFBwCzhW&Kw`hRZ-u@U9 zK4w?vp)cT_4@Tiu*1b)iHK$y8%&E^t$}n(e>i^pFruqP zAiu~&ep4)_P5qqIlGicp&DTkg{D^w#3`sL9KK8pGRl`w#W~Q7w_hZ4b&&c1(QCY?Y z4V$6w{e8)QN+O7DW2RB=jYE+c#iBT!ORdEsUDROD;?FEvWZZ@-r;>$}fVfy`0xmir zNj6M+3yL9SqY8yt1RD7)6vu!_uaH_qZ@1o;NHoh(GCJx=nwkr__1g2|?!2tW*mRyB z>-JEO(#bZqfTNg=`tDU%U9ChTopkZ4u;1X(s`+Pozz4*|% zezY#A{rzVEOJ@D4=N>b>J7ToU$p>jW34sn~bEG@3Q65lfM!+DX%N~yp-|mUVwL+L- z%)=WWOy|SfR+a3D!l;k%g7^?RnT-jL2tqq%zB+YikIEF#Q`sW|lMpfOd?*FXM2B2j zxKI0Ssp<+-N?u)i@XNO*{+o|SF`&x+xX8q{*}Z)q8)*2T?_n}dSJMX?p*_{vZ zz@0bKm0CdePN?W*c|=khUV7+6OaXKw>*z*)^dX)j!Su6F$Er9~0o}g0KK@*}Azo4K zr~$Q@*FT>i9nO-E#ss8#*neP`DvjB(T}Ym^iAd%&8$;P?*^V`t8?c&Inm#PlJy-Lh z3>MLTa(B(qX&551D8)EDp6ZI@&e{bCCy9T{qs1XLl~SNB2|$yH!i=Si4WT1wBuzV2 zA81W6h$ok9bJHNKR8y5v;(EGcT5eNT^tu$WwYX|i12SFHLo%(}eYNu$+a<9i^>R?a zDj7r)YK;WRPM2S+NVXeREaZGtg`L!e8r35a6jcjj$4ysFcq1!S#;v#Bg*|)r>9h-FsPp!PX%!yCBZb69l`MB}p@G7Nkwy^vq zo0g48u}GZD&yNi#$nEhm1=A9-VcWJn*t&J6DwsBKk@}H+?yv>Y0wlSTfAgihOChZ@ zv4D!3Mz{~HGvED%xabB|r7+;OjD%;!zBdFPty_+RHGo2M^lo zP%Rm!y)3!t(3%11kKZRleGe8cS;h4F{rF_;x2o9pR6}Y6%M1q0WsSf64kc6+L}=Rv zg@!9pIx{H=(mT*j3&WvU^lY2PKtGHHv@op+MpY+;F1=UZX;-O!&bZU}D7{x9l zH&rwO{R{5yJ-WpuuA%^sZaB;A2zM$plrbrGlJ+K`>s!lx5v!dD&t96`h;tX>Rfzfx zW2p6&Mv^H%w`Nk~ja)V|=Y7c5_X(zx}yH?!{x zj)O@>Eow)5Z#$dk>q6W1KM7cJ6JB`kNyB?@e!vJP%M$3;2+1*kmQ)_)NMu2k3DWZW zS_fmN23DoUspLQOuM~R8a^z!6H}dY=Iw6B;{#6^cmAD+I)0a8RC&ng?GPsB>#tVMbg$1awQyN#D>T1q$D>`id8 zk_W`Vwt*I?mUs|)0)a+Zv{cJ zCo2V!ZA@+@0;jk=v{nZ6yn;t6z>*ES`4-l}?`#q}id_0qox>JtS>Kd9K_xql7Ijl)k&-I5ltt)?D zA&UB|1cQ|Lq==M`%%CkBU(Wj9+t0o;>9&tw>3cyHF`w$%PWSi!G+@c(y!OfqhFP=c zyCjPw0a-g6b^81JDOp?{jAQ|q$bM*3S}dUECiUr`m-Nlk9%Q8_rEQ>o7#Mhe{Qf(U zo%#ja*Jp#hUjNZip3!d=cP*a*YpJ{AksbU!pKaDvaGJxyIz1imBxYo1JV^B9<-a9Z zZI-|>M+q-UY7u2WS|cmFli5{uo!a$ke6JEaNX=7ejL>n$jQ}FW>|~ZOj|9^&HZyHZ zEvx1&T2Vajd-ptP`_p4}Cn*{HN9VJmJ6ALcH6MCb(ZCwPBMioiP+k&ooq)%^=?(uF-nxfb$%6dzK`J9I%q z+JD*t5OO3XhNXKnqfDwvtXMW~SMC&gf84VyB8g2g{vz_qqM=1AQ@213B5}iu^7Zwm z3`#Kj5?15C>R7va1-e|`3GLf!-HSx8JR>uk?s@^;Ap^CjZebg( zQ>X>s^&y)2rRP(!peMo0;_oY7X_*^X)&i^OS{L;R8O1L=xxehcc)rZ1-d9t#JbLn-DKBCdLI$_tQgG-psdQFVGHFI3$!)=G%v zmNQ;RZdbyw!{$35`M@=O{Lr(zpo&hwIsU!}usETNCnQ@~-youFQe-O`LwUeNFIxrO z`MXNnD{`auILiW8no{L5Y zPBQ{R+VzxJRW^IJb{IDz8Qrd%zVGs}E&cjSN`W|Mjy!hGn#{+K>-31|D66bO!>!{p|#+ShreNPJseKn3om9- zL;2ivs8<`V`Z?&(OFG87P|;WqP>9yIg(=8@Bf?%qe;> zARup7*;YzbB*-ccnOF}(Dij&v!)$(FVNg7uF$|};27G{ZO?jb32yH^D{$=>FtV2c- z+x|$PUqDdatWFgpqX?gym~AlGm_;KrDHl{?J+c)Gh}|SvyL6&G2?<(X01mgBfdtUq z2>F+bwiu}NZ@Ii_xfLNHE*^Wi$Sz|W`UGk@RZY*MdTAb#n2FuEWh=~7aJcU72RT1f z-E?Q+*6;aKv-tGk&^ z=d{qmRJ!b4^OI#wkZs$xF>TwnZQIkf-P5*h+qP|ErfqZIw|~aQ{+JONFJ9f7H!Caa zyYy0P^w^(Qbwg=74AG54aFg_aReridr+iY4XJ$uHxD zqTvGO)9DqbbK}J@`nyM zdy)!um^4+nVJ0P@DZK(oTPVL8iYGhU%S>`{MOhP|5|VX*aLHx<(r@Hz9(f~JkpL}j zXd4A>siA{(&>vN+!DsUVE7>Zk#&fu~+R)F}6Kb&D7eN`>tp2JMkp>38(*!0Q{71AH zAMGx135|wVW}|`m!p{$nzqu0@tKkw*@*BX~@I~+CQWffE2dh-#=FY2-KRNy~Qp!iw z{t$U)DQfq*4hoArnoc!z^O!raLK4ov!~^2c&4i6Au@glQ+O_ek2nK@pgQpuXgnvs; z!N+_a@FxwrAj-oIS9xDBU)leV-!rmzOJa6}0GW;K_nV;OF@nlg@CV z5L*n%GlniULS>hBW?c1{w}L!ruZF!B{jHO((b_)amq?TvDmr>efUK=Or37q|gF~#I z2?wjk3OOE0JTCQO>eMjYf;LkG0-{yxVo%Ju?W4khfoRd7GNtYcPyJf6n|TeHAnb8( zh>=iTxqCBc^;;zAIoLt*;J!UPZ7VOiJOeJ$Kf4^)z}OtCT;STTcc*J5eWz2so1lst zU-4`V^KT1Wut(qqn@a5El4-3HP>90J>$v#>)J}PoBZ%tU2{K&3aaCl$WX)6 zEdgzA8(bV83#x$M9Z=1g%je@)Rr_0QT)pj*`XZBL;6e0BnLrxxB2Px=?SaShfQ=-W z9s~$D9KuPDN5%z8DOGlUqknuaK)l5&^5V(0>xm)^!8(I@Jit)64;$xG~7I^LSqkJL_ae$ z`BSpjbp0VNC>Z&G?QS_Z$MBai_=v^Y{uyRk{K$3Dq4SMj13{Y$+;Gm$(0og9=u;pp z)7QU>`iBv-0`_mvy4liU=9UIYB`7F3F}NXgfQr+(R@#Bso0-*!d22++h;0$dlgW0< zTsE1r=-Z0nv$+bDLscJ_i?)mDaeLezb^}bhOKIC}(EF|!w5IMS1u_w;k#7NVgrOfG zFp@*b0!N>(wwhokf0D_fd?e000CbsQ<};Z_Z}%tCF$S&3uov?MBKC$(B)Dr%|Q$`NnDFW=>}%)aDH0MNpD&E*)TSl?`DH zCLgV@uA^|RQa`|`y}1$GEf>U5BwnNfcv4Qh{@U2&T9Rq!szrRk%JY{elVXyNL`SYl z?WrieOlmYopcqmD50^yNDm~NINK{Q!8@-=PIt1~PWAT^9z^R*(XDw+sC%{q|dFMQq zWR57?ecjP}X*wd4Vj#X}6-0nCA5_+FRg64jT0Q0KY#G1i*W@Du!_aIgPCaP;(k`Lft)R z6u2hIdwe`Rov!p?bhfbPJ7>LLV(*6^7*v~&)n?jaAzT9i7_>q|OhTvj`{XH>tB5zSst$ zK4^?Vq?E{}tbM5Nm;5CIq-U&wQk-Vk1H!B=Y#eHp3=J$(^OK#OrWx-0v0FD$#pvxK z@^ZZl_JckY20wIB*B3^yEN0MTP6vVLhvVRX3k(qJ{NsJ&kA#Te6XO~@V7u2W99W0f zrR@S`-*IOC+Q_M?%IK}Q8G`PS%>9j*R3<-QVGtuB)7ia9e1d6y8LO%twS_X^8Mf)B?vuQ=$iZLeg^Y- zIlFQ^q3p*)3bgXa$k&RtsSn3_?s6wEo3`S@HCh&XstkSo{9}Lmv&d`9*Pf>ezALgQ zYTsST^n9}y$M>;ePeT-zA-LIH zySm5PnUOy^uc%#_$Nh5XZ|9cU2j$%lF1u|xf%F%AZE%*RF^KL=7KeuI&A(i4`M{8X zuz;N~cpIciS^1%NIjfW_5+FwBF_>>f5bdW)rsV^3492l2;Z}V2dVJ4HYr_eS9L7#7 zbSyO|I`Cy`4dp0su2o??u5QE@lTRv(sdkW>rg7>4+Wc8z7fZ0!h6h zXO!O*7el2!Y~pO8?a{E8T@I9$&vFXzUYTqbZst3wObAB9mt0Lsf8Ld2b=i@~4Oh*o zDzl*F^L*~1OXc1P;sl<_t~-zTV=M@Jc&^)1^3VI%q4yH-CONtYcj6`TjE`Jc)a{NB z>0+Otbatx$s)o(7ELGqqb}I(Z;9Lymx^F2YwxC5zYHv&_PJky^8YQ%I+-t^7HUqz^%Gs)s0d9)9>o zgXieUy;r0v){fC))j{=~Oz^fB8;v-fo|WMVcouz+VB96-FmUXj(LGqA_XA?lp6klp z`hx>$?XQ3VhtzoOpoZV$`X!%d#)sr&?HJWym|ejPj3BcyTo0-!Ld`w0T(*M)X}R<| zw2|6I?^!8EKvrlK!_2_*&@7 zjM!?co=%EVvTFD6Xwc`lr!i57`3#ONIe06Pg$a0P@V&2?+Am4-qBPxR%guC*0Q5iS z>;to)xThX?W-4>8w$w;N_7n7Y<{b)UZtz;mIwAYFPawpoH7zk#)N}-U*HXepNzg-1ov7`I3fxb8$n`w`j-1}Q=2XfyTeAI^^*9XFBp0V zwVSh-bdZ9(qh3{5N$YiP_fEK!!Hvntk!|m1{2}$$wMj~Fp`d#d1=M`*hKV3eNgO7n zQ*19n-W}$~gmtT5vIXV3#G7ojLFnFRjhVtJDO4>1ZLZM6J3H3Y^|P(&gI^;4q8^f< z&2~E|A4yfj)e%l(<)XYk5>VD+kcV3xk=@=DWZJ<_7x`LP@3;7x&GzUB_>w_I0fhn6 z#Y`G;d{W|%e#S7R3a5cpStAFNN_z9|`=ZZ0wxRDDZ6a;-I}L`TjxJW1zyd?SF+aB$ z+Z>iK(cx7XFBZ#K2SJlK4JxiNMsU^rO3?0nUE(8Qy0b%t-hqY^ym;8n0U=WI_0Pxw zts_N@BF0kPHq@(>!2a6vV6*%El7I`=F&p*B49APBHM#cdsEb2|)^^Of)b$sdpXbg# z%Q*K15Or146N_}UE{CV{l}p{@srx@+FagIk^zq$u;iN6!hQ#LFU>3Y}fbVKBGIvd)y z#Ct<~kkIwPkyC7#i$v8RdtKv7+mZ4VC1og3G#E$dYPN0GY{k_-l(mh;z!dyl`krA_ z%^bK`U=2`JoSELr4AQTbwmFH*VFJ|zSJH&GBp?KePT{Srup^-3MiWFnu;-BNTu6Qi z$r#J63}qVb?e_SDV&;$Sycq390WM5!QIG5r4Q~gqI(ZNMNGQ=)j6twso=h&vGK+ER zRa(h5ZNX?7k9u~z^x5AH+_d?3FZU>0)wduZ9=nRzDw)ln4{!4viMZk)jzoZNkAxM5 z+L2$V-TzhuoMYX83vYkSD}pGgl|ZxEFSdDn4^Tio@<$o;dSkfr^P#;9atN=lxVjr2*ZyU!Bju}jkCNtQR|2gISR}4icw;hvpgNN`FZ&|J1 z2#1LHO+bj)mrB2)|9Shy=CY7#G*Sq_Us`|%iF`U44$E(Qics!0xk4dC8$GB?1-vr< znju0zG8QWS#pxL*rl`0gxhSoC%$8_(HhxbzG5k3^xn8Ig0vDQyLWDA}Uy*=pgo?{y z{XSwNlD9~*UxsBO9@}jRd??Iw7mZPGN&+pL04LfBRz6&k#8FJ^5h*com^_-GpL`4j z4U0WKKk00j*=8G`n7F~s%xt=3uoICUp(r9O-6;cIdKV3%E39#AHrn7^^;c7uPyDV+ z`Qc3+0YO+l0pI!WoQS0&GWWW5zJFcosiUVey{5JqwcuVT#yovU`cl2;mbz&|!sk@C z+GWhNzJCn(iRs@W{i4!lH@t|b;&dGo>79LuG4=uJ33sBfWfQ%O`J zs~z8`6%L;&NM^a*kVjt7)Gp@>KuL&~%$eoA(G$VS zObJ@i-as=dFwrb7ps$9#_;<~q~b%{XI+)u&I7a6aG9YS~qAyf2C( z)7rOmr86>u#6sIsXkoo`b;oc2R92EP>fFHsW9d6h$Fb-+r$=i^$9@V?5ZQw~<0VO( z^m>dxA2i*>hL8YgVSCN-=%#rPnn`F_*!KqgE3YDf_tPFd%+10thP*j3c+KBO>m|>! zQ*adHFA9+A??Z}I%+rpv^gAhX(V~ZVp|q%X%#e-EWN0+0^eo#x-iT>SPHd^QTA@xu zkcUz1$R1yR+yS((%+F=^1MYne;`D*E3^~mZ^cbM9r?$dQ^)`W*M0H5iva11gbokh# zBEKdh%(_dkE7{5;D~# z!&$6RLtqYo{xO!+GYSX?O`~+7j3{9<@IS;HBrz4~0rTrI-TtA{RgQ75FHgY%wH9J4 zS3za#o=~q#?Ux^Mb5o2I`ZuM`GPolwhfhjr?CUulEW1evVq!9`RIi9Sx{1n6Vb;?x>TAUpaEQ@HO;A|nQ^>D%SS%rUq>!8GyKiOv}G5+9{c zcXwMN>t|T6&flz;#iF-)um~h)<@h}A1f$)dUC^8=XOl|vbXfy_m9p$M8|lh3$-q=F z5{^h+Z^|5eO#Hw?2Ln)%$AfbT_SEvqRLq)?6pM7W%@dj%Piq1qe;$#lH5>luR%31N zSwNZp@CR$nIHp)~y3xi0DI*pr@w?>YXf|+TNX4XJW5sJIciX=QHs_+~kYy2Zo~>G z11#?_$S!1cy^YuD=UVTyhCyc5kSmu671Jj5-P}(w8ML=Bt=U+u0#gq?xLBn{OA%SZ z)!w6TXM6yG0BzpHzi>?UrX-jpm^HiW3!Pm=twwF*#Kl&;A%eVfF59_Y5rIH_rm;C# z#Y_~0Z=%+Vu@wGu`TPFzD=!xq(Jff*NRVhNc2`f|8qW`86C zUe20;w87CSRr(qfor)wfL#oZBhGs5Ow1zGDt$gl0@}x#=&z?jyC)e1iW>R^tUA(V* zRJWn!Wn3C%qX_jQPAm${sb+Y6GV&buHx%BOdl#eYY3kEUgWYjwz6Bp9``ZED$7db4 z@hWWPV(#AFn_Xa!WgocO*%9*nsdtOf>7Ic;>w!Aext=ri>ut3Ahg+ZEo=7U3tT+sk zs^`I$eMVMlVrRA^K#vnQQ89rCGpA&8(@MJ5L&s9z)Z+iF+@kG6l5Z=hP_> z)l4c~Q^Lb`&)&s$0q=stK?JA*>7e-L_PnYO_AE^uJ`_9%9qt!Xu z+Vi?CtwATSoVI>x(87(MG^6xHp>Rloy&iCM$%7;a`9l0QE$P5eT;S&@JWhdB71YSM z0D(K&gp2$1fO#?5Ndr;lUI{uetiG{!h zoMz;lcGInOxpq%xqw1wT30=|1z%YsvhS@;g#vnCa)zRy~PNjH_eGU$-(PqGGntO3Q zo>Xqki)cf_KZJAT&=t1$0|mEMu)mRl!tv<9P}F-%dJiTAoFZ?Ze%jVBps(hPL(-F> ztC=$5^i8cOAF%MyYEGO~_vrBMB_}5iPFJ$L#YEH+Ce+V92nKUPQK|yAw+X>7TiL+`vClMBc6JwkbRtVf>?+2B?A%8bGvZA*cx|*D%;% zeSv_eho}EBxZLjcSAMu&L-0R5AgGIYKb7ktpaGQ*3=C@*9NI<5z@|l`?aj{}{ZqkR4Kt=TTdKC|W1G^K+*Y3O>%3Zj?4pB(W!o!tw5WCk ziz*Tolt4mnnNvM1<7u2UE$*kB;%Qg1MIyowqK z;i9PwgVo=r)tXRc()o^*GXPu37pVJvU@srMiuvbUi{F+$V4Nki7O5tn+B9+A&co() z>ljSxMg)@Itm^lHO0*f80A&suF=3~LUAj~84g>dvV+CAsFCxKljxeE~{RTF%!MzHE*EHz)>%3}+>pbWa+ zNyH>~c}bQmln4f`U!%b-p~!)bs2U#Nvu{YNAN0J zhx%^S_kEqLvZ(Z3pmV)()yD`*(Ekoe`F6egf~D_k6;WkkvZ>U{8C4F=vmOqQ~r(=yj{KX=KY|WKezbU-@6iFY&Or}a#>t&H8Itfd~}-{ zIq%cKbEe-bMin^D`r!j+XaRmg|^K-IL|r`xc9QrPtduuJgBc-7D?fR?}OF z0N~MfKHfNm);T_=-$2F^xZMOiqCw0~{!z-CLvnab2LD$EQU#M2VgWh_m;GNg3Z=dsLT{Ac!iX8u?Gl|{bbt+IgTVwb-HysHkK|85NaXL2h1x5+-R-sKK? znfJ4RqUQm;)qG}obv*tv|5^Q)5pyYaoi*p+Jk0YC|MQNT%dmj`&)nyo0Tl7GOT*p> z7a72FaH>84Z?!wF2it@H%EAz^FNZH#NUSE*g5WFmkcK~nok$=-oq5qlxzv%yqZ~8Kn4OD_zZ>RN=^K-qG&)fU>gvY1_Jzp8Od zUWZ@BKaOILcE@(b^!52|-EgNNND=>r%vc34jQq5I2>bOPikkaDVAO4J#`JjtU2N|p zHf<&W;@tY37uP_NW&d{vEqFgZjXMEey^Y2oTLVw*es1`lgpm>Pr5jJSJddvaCN>Yg z{C6Cz+k7TU$nV=Y`tQDmh#x7M=+xA}K1w{ESS11ay?5EXSvq;w8gOv%l_ix%Z?5d; z4_%D3_uRU;5@%J-4uE>l z*>75%tY~2qPP#G@EIDz`%OJ^s8R`5(#$QuW5GgAN4#4$;Bxo3DgQr)Z!D-ODz=8Fc zT1IrTBT;4mHlOd0*7+<4`& z)CuFyg3d#nUMpn%cSFU~<*V*2P+*~-UqMUWlI592YyRY&iPgFy=Fa;^H7(9IWqY-n4A&q4CMs6@BgaDkwwa?=} zgMweAs4doOLSwBn3k7Ph=U5j%=+nURtfC>PG$V0uP! zxzj)px2Khc5re+PL22~036@SP#E2xi>u&=$8rKc0#np8u*!S16y$z+1#(ng_cwm*-~CMHQh7Z?#*lz0?HG ze0D3~S+7K&|~@xNDHUL~a^;CmmpieQlG$Z5(@Srde{APv^cw*xk9 zM1vNH-OxDj8W_fVN`B_eh4#Vk>5OJv1no3X*ji2=-9N5a-*-Rzs2H&;HmRgvAaX(wxw!8j`kq!$zn7Q~ZvKVW&ohE3BhW%nHYU0=shb65+|ftJg$i6* z^M|Ygrq_OQ1grSnm>n60B-0c>DmrrCUrxEh%1TRHqaz|Tf9m8P$-Nj64fP5+o`u`1 zebTDVTYaA)(`qz#8K~Yoa)yshx9|3G;ao5WqgNNv?QD#XW$cWm<_5P?4xla>)~R@lOG#>vT2}XLvPzz#Pb{2fP$|EFPlU7c(QsK+`i-kMxfo#P$kk7K$URUGdyuPp`46xeM}Hyc6a7<&9&-5V9qeiw9(_`X z;Q9U5a1_4q?+$rfPHJq2BYZ!T{$PA2dbmE$1lt)#uz(5?HkDSa5BHkrY9Go=cMpoE z&2F^DH!nOb5B$U3zJFFv%2Ibnvg#M24*O4xCru5jkt8>x*HOhw>flxe0w`U%whQh{ zsrkTE8#BGl8rVY`!*CJeQ&`*sPz;6vYk79K_CgAhiwr}|&$|s86NVZ4NB{8&xP%|S zax_AbvMecC8TufxZdj70CV8sr2J{*o%~zd#Df~#va^FqiiJBoD$V7z+F1zLHaK<)0 zie?|>_!|Tyug(0Z7dSk2_=(f; zwfrp>c#d>FIS4~e$7p0xle6dRG%h2fU}^yUsxBnX7qRdQuADF-#$-dkT&In@wy#sb zFSiS+O%FTlGlp~9QG|8Z@5qc3q}#|;aeMDr_-A*`aOtnzdJhk1EeWJFb7)jw9Bx427wU%i$ev9evGK3C^|t!(ei#@ z&|_OXoSL2%6%+(oTwGk{@<7&PVP;A2 z&DO7hFYlMVfAyOral@mB2@-jMD_G)d)LH$9{qev%N-T#^J`Oa+FCX0ZU)V6Jx4UtRdOtI}%V}NudIc_LJ+Oj7_aC`I1b&drPi;SO z84o_du{<>Bw%vUpFJq@h*DD%+Ij+YKUHN75g08t=MmInDo~}JG2OTrG5?w3F08IfgEj03l24%~n+L5qP~P_C7vVu!R0Mvd}Cm zYx#Lxm%U|7-rwu60m^JQG|Yx3AUp1sKw@`HdIv4=EO&yjnisgC>-C}ac6)S+8Sbdu zwRj?H8R1}SglV130lTk`c{vZ~>7V(l#!OBRL!MYNj6vb5xypkSoaTb~14pJ;f~dl6 zA6ngJ968*z(6o&|+@G;CrQioMQ4n`8;nR5|m*~!)uXj_z!os%A`}V}1PwYA4)OfYo z*?2)M43e^9E!HcJ0BNG(;o9~e%VexMMcH%K7V%1n^eH@#^Yv3E3YHD z(Uv#adn-^xf?%uBcWnha(yHBm-ZA98xKM3J(WTY^*F?ikB7p`?Uz}msf}Du68uW-i ze4#=L%UsqVuC|RgM%&efxZij%Ml5OJiCGyK232Z%d(LAa&&3GNr7!z60QkX+&8Ob^ zMn1jT{1ppiTn8plbv!*sJjUk&AIu1~+ZV*?6N|-14B67#%$v1h2`kT+8AajAq5r7# zAog1B_LwDZ2n%T_)Mo72uA}{8H9R36BOI>@AES>mh~@%hMm#7<;BT$0a&3i(E}x$P zr>1rMsv((2!moh`QqKVzARRXXp|RLBVg?>q3O|irs%m#^Hx3p3x$nrSUo8>47!GF8 zTsb&Ny`S~zthXv+E1zlEnT?C4cgiQiiB_x~vQW_QLi+St_ZXmbG>cT6X?J&HP|Dwu z3JN73HU+LJG8_wtyR1(D0m=BxWJ!>!E0v^)i?b#_B>F;pzzL6}Q_I4;GApi&eyi1L zsR%L-@7!vp^<(F0{8upx>_1~`eT;1Fm{qv$ulF7}O^3h6w8Aq1V3$%(gB)aV8t&&& zRDBLYc^8GJyC(;c67~ZZ2C`xVYn1{!SapN6E*IQTxbC(?38sw$GvJPnLW7FqjhK{| zZxG!-=X&KRC^32Fbt4WkO9@tU!X?rN>9;!?9%mEuY=(*u*g8@ps2(3iv8!lFN#w_G+sjwI|~e*4@>;n@0GWMwWqJ8MU{8+zZhzAoLJE>`e(tT z@YW_nrKHEaVk}$Yn32lVhqdY00!#}i%v&&b2ard%t1=q#Ejh7ckWc*wm!+EZUWgbB zd&8kQfjV7oqV@g=Mxrj4+Dhcw_ zC9R2nLH`gz#+I28?;R+_LmxJ1HBCFWdc9GFb+qNACg-Tb8qJDnC}^=qL1{CqF0h0r zFV5E}4?L0RBt#*bElf7BIAY`_5BNrSi69Ho!LNdxt;TAutpNnDV>kX?VcCQ9?M zr<9DOsb~x>W*d*c*}#fJS!3p4Kr}iyxINf|d4N@o*Xx%y)+{I}i1~OUBGEm{3`;Vg z_#lg`O5ZX&;Y(~!)xvuDX}H_#I+VGEXd>Y-eY!8|X}j886=0*OlS4U@e|h$m;@cO~ z9cPyyxbEv9ueG@G*6!0hXd41+de|(DL%*B~ZUjhzc z^yqm`BgEoiZcv}a4ShCLhWXoXDHF`c1OJ4}ZY*bjFfbQH!aNqb{Wg7s*st0Q;Wz!< zqGvKH=gucW9ZU#38aYQPC%Bip!1%Y6DAVTmYx)A?2e|Wqx6va9EaUyvSiSj?c(vx( zJHNe&vob^&hH}D8%(CkD?4fZDeSL)CJ}hb7n5fKnzi;$~RF)Vh^#IMcUugm*RqS&s zUsWtfoyTIrW1Y_o~`=Lt;mozniuy^Zlzbk|SD`v_8W9 z-dl3J6Ec)pgj$Q+mG*Lt2CBE)jZknHyrteqq52FrryvR~6#}QvaXm;gXQIgvw8vJf z11e+mffEYDz}S0n+A*Liyp_L^ciCz5+}aIyzu9w^;q{b%;d@8W8+}F6$YK#+~g07#2qQU2UFY z`yU(>ROsy%%R#4gY3yS?+WbBWf8JNWo1Ww9aF-D(6eac5@5h23Cw~_j`@_ z%w!gZrU0r!S}Nc5Q@6j3_DZyL4cDrId1Dx`(m*QAL2lo4ZU(dfj=4xXowh>rKbglx zb`o7~SM^p)5H6N`k%FCscAL!u1w-NS+1cB{A3ujAJ~2P5RNg=r4su(4ZA#rMD{fz_ zMPKf=Tk|}`9ltpF4zPAT4y;(Kp_l742xY$4XJvCZ)>7d4V}+L^p~KUBDK}fnBkRv5 zZsRI~O69bRtgm)ood8GUOX0!d9PAEmaF3@y8n=rw3{2i9WDECB#2kkyX?w#(aeN`r z2J*vkN&ku@(th#I_n@ZI@BJ~*FrCkt2&n6TVlkH&D=Mosgx9Aa=;=fC%SekWaba7l z`9$i~7k}(50TuRjC*|IZl+U3ya;`?KsrP}H61jc75a?HuJP&aH1p*?1J{~b8wiS%3 zGw6#FfZD4%@ylS2vM-N>(=}6v%#e6BX++pPWh|AGUjA>T|q{^8{zO=RusC3p0} zpA69N{P9-wfuJ?3cpeK2=>@zl&tG)JP4a_xdLD-b09aOG*N8I4gxec2EMc!JVRsEK zvLV7qBl+>M>03F6v!yCy?~g0=`wor>QRGn3SKTnC3hMq9W(4$}ys(fyvwhzg6P`S0 z2wd+M-7$a9&j2LW+qd`Y)xQnPy#n}EyPd$(bjwZ?`9yS3>^EBZChsP81CK4r0F8A(VFDl&Hjjg05C6B zHUg2?k_%E6D|hUko>~I;B$ZJzhQG4Js`}A#S2RXIj8oy0DC7o7K?ws_1{w+3z}A1ANqkDnO{nLS>>DOx zhIt>O6c2Mx(jd7i3ykEU7(&B5i@0jHQ@lr`IC3m$t1z>agpH&@gIp^#hBoG8OnWbRRgIgYQOH(L)(_a@|3NSM(pE*GHOWn1aQZ+SYP`x6;11>ORIJ^}~t1c2t zvIw`@IG)*ib9%0E9+@(LD=an2knFTI#-1NJFXvK;IwUiJoPTs9vUv2Ny=VQjwd@>i zk11UG&iI#W_ONu?Y{vqRkKm#R%iy9h{jy#W-0n;dcqiPQ0^{`ESHP69ssdFz6QF7<_ld7}{rY|)WYk-T1~4FwrxF)0(V z67(ZF`lh9C0>VHdPJ>saYQ^wkvS21qi9<-viG3$O?} z=fn+41g4Cm3Wt92G6AFtDk;62^`wsi(0gO!u(w@iWbLiNtFVXAGcA z8MxIiwrV+hegxWfwd3p{uI;D#87SxRup#kU`Z)4^q^nAyO&h}z3W;`5u*;E8;i_XV?CAmqXqQ;wz@LJaBv!0;h5 zFJ|OY=8ccVmC%u>$%lE&5$r6KS|Rv+b>AJ7vDBL@0QY_Y_;3BV5d^-wW9*9r;J762 zF86Ca9^c{&;j3%6`;B)Kc~VWu=X)N%rN2Akw=31^U&9)cL(7S}Db?aIRjnaHlT4Kw z@C)!HQ{`s?GKXgvFeYO5j)?)C-+S-!lc2K(q2-efRRIq!=x*0Uy?)&oGn)r58-4j& zN0|`~pzEL+gu7}w=CPHG^fq~R$vrX;lZ#I@t~Ask*8fAbP3v~BSu zjVzmk$O6~Q5v9I|+#!YF%SXnmJuTu#nxQXvEmo5!m8wcdtBI?tmo`>{4G%Y>%BcHE zt1rvtde-Pi9yS@#Twe6Q8Bn7&8 zyqHt#wq`saIyhzZ{P`*|@x-=X2N4E}=41=DG{TjS!KWurjLs%a+Dmf;8kb@Z?;y8G zm*!K*NoX=kw8ONHN#%a332n}QV*%Mmp3(fHE&*m>Aw1<3=;pZRaIrHH>EqEc9+>pi z?BL7V;O{h@R{diCvd~?~PW+bvdH0FRVYu^+gT?1X5=$^MbfBBs=5i7AE042x=E`!1 z8VmPDXMd!vuLaIQYHDqyBvD5+6s${w{5Euscz_~PYI2iGEL+t&tJ9{$x5mezE%N*q zon~e@h^6#)oVtnbw$jsHs4U6xi4uD_{cbBAj}qNq>J+8N!ja;!xntAgE@p%zEbS_D zxoeRRJ!4gIZGe1Qjb2wP2weuvflzsk4L%r?9m}RHhiG zNAfvT0vY9ItjXNDK)tsHl*vxP^sLxX&7Atd_wH4L@fE>v={w7=@XHAPK7E5*JKdX_ zu=(OPyEYyL&&5YX&td1i0d~JKZmJsReDGiN^uPWmRl;=jTd?UZEJoj-Z%~g_A+{7G zt+qP>UDxLovj^h?q+syu6}QhpeVTg8<06L0@_=JOC^*iUIxT$#IIkZqK}2nk>5WU{ zhKgd3c5~QfNtlm8Yf7Fct$FHeGTa+qQWPADA!a>FrZ_)z=>akFEyqXITuF!oZB>1J zggx9j!>b0xIS5Y#APXIa;Yqpc_4;aT2f*X1zj$4rb$#7i>ce@TSm|!nkpKO5;A=%e ziiyE~tJk+33(INmqcoFFr}OTfJHg`jLd99NiNd(56_bBAO8+D=GAs(I>SC3slh6-a z>Laefxc5Kx^x=<$0S^RUZ*``)KikY07ihdKNNN0YxlJ|@9%p>`_3^GeDqFZ|iDO$s$4fh$Y~p^?!vVq} z;6We7K5F0Vypg`gbGxDa`h+MDPMB z2~%AH4x?sMP+nU@)#CTy)L7gjePqLemb>K_(#3K`kr|>@D7qq@uq6gc#LL~&fxk?J z3Q`Ttr2ax9sv^xeLwzFad+v($PljPj)8LY0r0qU1?aQBJ<lZh3S z*vo+;P>7~FiY(-In1;$59M&3~2n&LO7-*ZnB-i%g>v0^Uc{}RAA11bpq6ky7EDs6A zQ*d^RL6-+JzuZ0BIJ5BhZ;D{=rB}2_o{-_|6 zFSgUbQJe(b&ZvgY0YK-?64e(;cp<{G_;z% zp+}9QvM4k5zfI9vG_$m`PAw?zuIDR_C|EV_*3h&@(URq|VRAGeHNjy+?&v}cQHe3# zi;J=pV9$)1a9ad#rLRrby1#YUE>#(Ww{TB~Zw&IFdR_Z+-uE~9eP&yvV=5{-gggY{ zexPBn6IvApy~}-UINOTwXRSCMhban6JE!9!knD@8O#VtRzzPxCtK zu8th+wc5c7qcy|*AC*kAhJtN0TZYf~0!GCp$r5QsC#^2kShsASBq-^Tl?v)!)I)q~ zp53~y5YjVR#OI@$hLgK-n0cqM0qMDt6Tgk#GFz5oH=}U7*!M}cB!n$pWz$*l<()yz z$8EdD4c|4~<0PSAP-Twi9K!Csg)wN6+3u?_wfhSY?#b69#DUB4ZxC?<#a?{K6 zoX+&QC?AtL*>)v0cmk6e1mzP9d}+ZL$Wsy}g!0OrXL@{HB|#5r>+}P0(_|Q&TAiPk zT@Wr04r83K@PKj$vgHC+gMsdYe-^I1Qf-c zs#U)(mM&eY_9yfL0V*ML%JC%gC~+v^RE6RCY)}KQKGU69qEy6nX@pO{+KQ`t z-ij8jufX~x^HC&fn)V%NQa2h84SoPQmL~GLg_#XKC(k&H2kxv%`a(A9)o%{U5tDK5 zjU2x1*X^Y|Fc*W_8Nw15X79Kpy?mKj685&roRR1#1{JM~@>Wbm9+toJUBzN2Ac^}F z6BU8_Rbxn4%E#mp`D@6=M zrlh1P>qr_?NMQV@Uw*|seeTDC#mmv-jvf@sOCn&=0wM=%%a$z+u*YHB?wuMqasNk; z#wmupIvzpMmjUqtvd{&T#By>nCiOpZ)9TfKkS`G%Ul;@|K2uKmzk$AiYtG4q|HpQ6 z$pO~BJXfo=>vlbI@X(Q7eBeS;jwa#l5g#zS#vm&fvzO=?F%I#``}ZQyx(+6C1UGLo zW5v!4_;}eE2da**CNIU1hnvDo$&Y6qx*a3G*@Yi}orACGKKR*kk?OdOEKVr}FhjI_;VujtLIJxf!CVYxJoUx`#*jqvB$vV3TI_-6%_@C6>Q)b0+nGVysGijpPWzQb&M!Sr;9Q2QuXW*nbN`1udk$b9-MM5Ear1>7YA?dJ%{w@sJP$8_ z5<2N#Q!Rlw$Y+T!1pdwG;I-Kqzho9sim=U6oXwb&$latQrsIFV&ti!V8@%?rALeu` zOKbAxHLO?vKgCc#SGamn0~SkJsw`TU^uU&_+xz7fWY;^Ea1@U{HH@iu67Tr%i%Nk% zIZvd<@Zsm1mK+u{gUce2HvHYs@#$+_`S4_@V%+N;t+0E49#*Yfh+{|dkzG`mq3B}> zkE+4Nv5YPiIXC72ZW~57@f$?@WTSP%U<@759`BD`3a{W8T1T`bm^q4ysLuYJI}z*` zg8uh3M|9nuSh8UaHmu!@5#v{2=;QTaPdkE#@9T=yFE1cic@tzz*tn|@Z-1Ra*CP%Y zd28Vn5JoGBR*|?(T&oU5a8Z{8u~posT#(wOx_N5ib6Nz*-F8X^i^L^7>!?uiv!~oU zcEAzWv<6f3?7v4as;Lw*w{F{lZF~1)$DV_DdGJ75v?)wNRHNl#M_TeB73{ZAEn;B* zJ{UXxD;7Qna=#_DgaVAJpqXk70=Nn=1dQFM?@#4TxfU~vwlx6LzE{L@A7P0LSyRBw zn-lkg_#6Y0#pb|opmFqa#6h!ewi_o3Jp%`S9xK>2F4GO zkB1+9NP#*@rc@R5jK4Dj7ZqSF*&g3_``*}x;}eoQr>Ewk*Te6s`Ym}-MaRg&#cHG) zqcD|y%*n{tWPecfA>DN9b&qg zZ+=h>^O?71vo9V=feDl0#|N|^FF=Xd6)?-=B!l_gcV0no(K;0$YSqYzstqnj>y8~2 z@$b_wUcqyZG$%mjpm|dh2EF_Y3jJb~b&yZJ@wB4GEN3}@b&K|qU})jFD_en!$QK(A zl4*`8k`S3+lK?S!QBrVQQY%+BGHrC5B*if(H$Z8>(*ihcf4z!5Hl_C`8Njw}TCtQU zAN6Wi#T6_Te&WU9T+}Qj5gi3)&e%FDh;84scNaM8<*u0`)31Db|)}@0Q^46kM zo*yM$J>zf9z(oOA?|io4(3S%`Yrgf#7&vptW1;)ShQaEB9ef~d1`Aviar0r8#o$at zt0qp=rsh+y7YUC{vo3&Xnbg%eu zi*$*^I>^7d`Nl4|y5pV7ZG88$pRi#Ud)ft=(Xx3HU_{r0iAwGu)j{gIgML(k2MELs*rKm1(@;dvVal=ir?gqY2erDt@q zcvu#x5-t%WyKp@RiIpu|w*`Y~IdtvV63371$IvGp#9Qx#i{;X4E^GvXY+6xX zBzuZAB*AkTdea9Dpf!;^1^)`5WL`CsOow@cxR~xC0O@eEEF`XVS(hu3PU}`0tu9}& z98rw9g@*)?bLK>q=uigbYl7`u5f`6?`7?haN!OPzLUQ6LD|6d*RWNtf*W_l|aCzJI zxb?Q{+4Le#S^8}BMUe8xs!hAmwpJu9tf1t-wOTzJUHDnTRhy1o^WOL$Yi8$)WG&5j zK7iD+cE>cdn2MREy+iR~(s5^dFZfY~AT)qoeX~e8NY6ta+a>uq{Ln0-3ik7D`r)Tv z;=bO!@bj;~;r)+(MW;q4^u4te<}cfdjYnv{Q#!=OC-{e-X0RQ4ZK2R zoXxQ$7jA+rH30|WuS8@>60M*N_QR`$b+L3wB(p@ zsx;jUe1pq+QcH=XO}9lLa=q+lB|#j@{FaLuN!=YS41H*{0QUk_#kq7%gr=b4RXhll z1Gu`&Jm%7MMGg0Yc9o057k{q4M8GIVMKAMp#rHB{7KxWDs2bX+VLj!#b?n*&vHMv} zy<#Ia88<1%)Gk28^IyAWH(q(=IXv>zYs_p?HIy!P0FxFGl_ObVl)((FWagy#sF=hA zFgL!Ky_tNFE(sS}f_#nUj8j()LS=lntbwh$R~u zO=daoMbkDdc%QeiB&s%oEd{u_GwTEG`6yrz-fW9k!h36WP;r#cT`rIF%i_bRQSCbT z(}LfY;iRI)e)d;nH)+n1or!=V-j7d5kHxfa#u0prJb?8#!S{l!Pl=k;SW3{a9~B1p~iO3ldrOB5~PNwm$a@;X{~70wCSFwhde2 z=M@|9;-G<;HGL+0N&M{Ft21lylF<5zJ1}bMKHPNcy$qP=Vc8$EaqPGQ;r>|+=Gw4$ z?r+$*kIZBr9@8fX?|m@?kM`|CrO3V5e~dwA1rD07Q@&09n--tGLfmiqk_E3VB&R6X zacCq=jX^Gv=o)5ySgx~=|f0RAby?xJ8IQ#gzTJ5r45yI zEECT^|2#%~FarK8A{N)riV!^qej4AbWVk!Z ztLI0KEqtm{pK?CguAVQo&~Se=X~u5TtCynt<@K><@qCyWuZxHd#N7j*!K)+Ykat&r z#~yuLDS`^^VdBK^c)!J^XLd3mO34^&l{Z2VB?+E#FyBp`fx!>;@VJC0K1yfwmkS=S za&yvs+E5B*)y7o5P18vo&|HDyL6DGajDZW^pAUKg6(SRl6W~k%V`HMLe_O4#PeE#8 zLY<<5gpX2_o%Nz>`647d6mPu$F`gOx6h+m%vHS3!Xk0lTMHvaOrEkHIXV$^UfVmg_ zg}s|M;JY#Xm=(;zO}E{N)wG-(eACf97~x?@}?)b!~x24&atX&)M6DVY^*A-W-h zAZfRe;UqPOe2ExDy+M{LOL^qnBuK4_lj+(?z1%a;4#LMDy-(3W7s3L4@W*eHaZ|U; zuwuh@xf*75HPsXs!9#|0QkGNIfvQ*stJE3GRFns;Q>7S`d^D{z3D!&9pmq#VL>2y; z#;1y5DO8m@&9Qbbnx#whCqqnaFz{L}?f%OUU!uN`+Q~VK*%_FdK_0 zv#JR!lHNAb3v3m?`xh0ee zhs{fYro@z-j0O2vB!TLOrSYZ{SOn;7 zQcX{FgB&iX@pChf7=Ii`5AT6jP=s1+f&p2Kmw_=T3F<3~0f9>QjHDJ&N$WDuW8gkj zOsO1CsXT-H1hoQpj77H&r1V8Fz{bTd`;#&fEpSYr5Py$yTzX!vHalkN$H#s73QtYWfaZ&^(wQPrew>*WYD9E3jG6EquIqL) zC3Gl~=M_TURzn;-c(BBh;`J+)&r(DU*`HpcD4l*vkMc1$VYQbY`gZzHp^GFYrzyD? zu>w`x&waj1tBUu#hysL^VGsdio(nUSoO36+bT0DWqyoak$iIm23H`)}f%v=v#!~O> zMHP(p82jZo7D6Y;9Z=R^VLs)M8Q=Qh*Nv~-cSjqF@q0!^X5fMcEG`WD+~5AUxpwua zRvY)H(^V)5q{w3|pdpbMA@e!8m@}+?Si9r+${vG8laMH75Uh-65Pig$AGk`y4PZ?d zfy%`NXygJC56ejqoVR$FB4|48BHvp|y-BTaeNjjdx@^!}NvOC_NpUn!66ZP78zS46 z&c3VtN=(ZA&rZg>fyC8@T+~(BoFFQuDjDMi*s@_6dXO_DO!}W@PQ!q{cPc`vB+Lw= zc**TG`h%`bb*5(|E}UjjdAqwI8!3S-q)lnaAhTq3HxQMSzYKqW?UB-f+2Pb0hN>Ze z?#9b}&i~Zuzu~GY+F`;Ezfoa=9en5>ivGE`H)#p(V7eZwJo7Uy^-aY)tH_omwU+u; z2GPZ0pj|j!su`*z0{F6%*q_iM3i8;k**ggL^}U-3g|)O2ci;~uA@01h4|Z-pKr-<0 zVl6CrQVYoT4RRG={-Q<0c?=I=Rpj>YyB9oQ$@ScD+l{R!{rH2cW!=hHx97Nen`y0{ z#66?Upu7;044Hm2`bqZ^FFyQINXiFLZ*(c{3H6PP42rr6Ngn0mkZhyy5jC2GkQ9Xx zt}QNok)4iaslWLvIPa(Yx}IhiB~2kKh6H<~euIWw$gDFYIM=CEnQ!eMaNytpssMzr z`2_hyjtm@S3#b}Z!_c~A8!TF~US&4Tq|cWRI-luzD$=I(zN3p|AsC5;q*+mXIS^Gf zW;qQHcT7ua?&L<;$oeilP7LI0pQ;vF{I_DA2oKQSp`ro%In>&>8W?Kvc@I zmA^^jh$z(yP`l&uef7fQV`gPpRS~n6HnQHmXlXTX-WpF2ehk@J`IJPCQr&Idd+$9g zW*JVW&R6q0zSLw-p_QvWOQBR26>_R}S)!2z9HUaikoTvq`{>1c+Mnxdy_ENNQ2>_Q zfQYd0jrC$|ZMGapQ4234u%(u0b*Cu-DK5-CLu&0LwxlUO zXfB=%;YZ0(B|a*Hc{+$MeJVoJ5VO*4MXGHzApEz7NDyZdR6>I#7H3dOpGE;^g4EDw zpH?h>VYRnv)eKj5?uypUK0@=BY&L81!E-}~;Km+zVaEUF;-UWc;jTOH#rW~xkbKHk z^VBSRmtdyoH=H|Grjk6$XP3#5jr$L@R!c z+r=gE`9%X*H{5VT+wZ>p-qoUJBv$NBhJ}En`rOfqQf{4EHC*saJ&T-&5ICi1b>PE~ zAK4w8u?AEKd|Kuh&#Q zCgms>!!niILHXrenkA*_PieBj+u4iGWoE&23#u|0$ONYWvv+?y)^0jZc0X`Ux9boR zSs4co9l-8AJF${_Trz|Xph|XVfeM(&HH)9>;2$NUc!Gy?(o!8keyNWPq*X`EW6Xv{ zF4X=K)q}E4BXo^)-51sgz542KmLhJQAb%{^swPyYagZ)jCJS1UbvtpjY1WG*K1z-y zn5n5Wh=n9Bz9d*oW~(a6;T6%c7D+)SM`7dz8*ggpL{x!4NUj(<-u4N&93L4e;toMF#!Mja}ln)@mlnM=n>4EH4C@i zd?OCCDEi5#2BC4|hK!Ac<1Q9bi-k4yr|Il@Nc}M-4NVs_KN|yI`%WkhWl);Wlz(P+ z_8n>IY5f@+?IQYH2M)$5PMJ5QYdBi*p9iombO;U#4qjh5!rIQqE1nh>1HV%J?mlTv zPsxdi6UJZ}fk^(<=UZ{h%4K-%`DgGMnbch=sP@+TpQ3Nyz8E=jB;6SUcJKW`)xmXS zSA z345qu&!PR;wC6AaDW9wHok)IUR~#9|Av7VG3KW!KdY_ELP#!|{@5oPS6rsiKPU%{f z2E1~G(&~Ip6GJK;>c$IV)3ih%3;K6%)Vcq)eNK2!T;_NvD zZzGm0Uq+?Zdr*r4jV1&#X>g-r++TC;RXD`1%!8hO3ggCofv(qHuS&gs{`qG`4ECWK zhm;s8@k7=N*8KxGS+Ih8x= zp6|`uw;gQNtaq zThyvmi)A%8pc(_yvu4l7e9DEa*|Zb84jojTf+tP>4&86K7Q1$C$Kc0aW1;R=?2Fxp z8?V0(TX%e}Tmn4{R>p$j;Z6|1tWZ$*%x|BRhlu>i+rviUi9rvN|3e+EM$J%z#MkW~ zjv|YilFN+G30R3Wp)=)ARXcd*M=twKI~SUY{}6ekd8j*sU;L%A^CN8jvY>cYLG!;j zY02Q_Q9_t`6ct+&E|rbSoy@T)4Xbaz8IS3|Oh?~)Z)cK#dR3H_dG`4?kt2L!Av{P@FUETg5=ws}2l+ISGXdf!N^dk%sF!_kPC5O+KU&%XE!TCf}Q_^-cV z+qH4*kW)?dBDC_DZQ8U`ptXDVZd`tOV|?}1SEOoG!Z+W1r7V2`8(%WwrR*rorx5jP zvB?N^xLP!8qL}dP*7Kgjo~N>~MediS7NZr#3UMWwfiC9LX_G>k=32Yo3KKWidw(mWNBNX`;0$|JLO(`F< z1`qb@!xrE>2x8T7<4reV&hNkDuG@QH2_;*$ZQI7S={51e$77UCiY!u{TXVi{s>D?0 zu|WHUr=Q02!$vF6h);?~&3bzf5E`tcdqv|)(Z$YMM)<_5RJ^J4b@69#Tv23*jtWEH zo;Tqzn~zEZ(zHx*WzB3V@iglcvk}b#=G;`OI8fTg$YA~pPd|pYKKKGAcFLyxg-^en zuGIz}O~);_H^$AkUyJK*zMoAXYN2i0PKs38@rs)f928AbYcCd7yAT{1!xv&5%$P9) zm1|I}aZ?x$>_3XJv17@9quMAH8&u;{B6|_JTGb;hxa_ja(7Z(pf?Ny2{;(7`smDgmKixbyF z>&UE#p|nP%&d%E_P+3`!mh`%5AG9yfJE&)aW= zJvWWT?v#^e3eLd$FQq`j6O)!%HLFG9SlmAH(`rz1sEA!^q7f5mMp_0NM=&Ei?~f&z zMptm!%*XINp9w3eFKOnhkJ-$^y~=L5ba+Fb}7?3N1EuM%g?CY>b`IYBAII(v=WO zVofL7V0tqN{pcsF@B7>HD{?yorQiT>71#S_!dIwUt(IyFFIG)ZkiQC`OBs)!Um$x3 zO4n(tYCL*v@>XF!TIGI^A28D&Xz?YbGotZuFPsQg^Yz6+?z)r~)KEN!dQ4guS(ZuzWp-bGJ zYEDb58OSmIZGaQ$oNp&iB5~7*8kNIv{f$?#-BT2Dc%ARQ`w;;v>>NH0C+j|jSh;*Xv%^k| z9rK08%VTD-N|h*$X)jqvUbB_O^kTJ#u+>+K)-71XT}6SY6mDOC!_A0}sfj&1wvxo# zkTsJDSh{2-nlx>oWRT>+(_7b{D%L2<5fvGtqI>Y*VW|k$vMv=E>FMdcIR|x^!R)|Z zi1)bPVw4VZckZabzW%MRUX*|(lM@^qxTq1r5$$h(I!PB1)LXH}rFl55zTHTG8U#g53Sb9IyoksLSpWy))@0$e5F~W?r#kG3g)LbK~tp zxtO$Uv~1Y|`}fB(CZz?@F%aCqK zqvVo+yy}5S;3jc4SLRHr7~@&@_lE2m(Kkj{*l=`_osQ{9`C*DhReVB{A*X^ z8ev!!D`gTaTM?^UFFxg4QKAARr8H%MsaV0YoW^;1mxg^M%8c^xcDl6v>E`0E;^k7k zChJIC!!N)887nt!Q?2L4N~~O~87)Vu1Tbc&A(p6;%A)%#KyX_{YT<~rd6KWY6+g9| z(jp*{LKM&)B-R>O7Uj*B^$xpGN_ZTZ>vB9UYI3TKrQnhPg^TW(v{Y}=vL%+UT!Da~ z;NmIK;O`*JqkWWMo-(`T2m~-` zei|878G(@v@cNr?vF9MWIg9Q)ONRuIa_KHgHZC$G2A_WS4F*3w7-2lun{T>VWgF+t zoQr$zy$?@5H-uJIZ6qWoVVDp?Y59sJml1!AgkMTUGehmNc5{fWq?m}GC zwG)c+s3PLNJ#wqg1nxx}OwLd54y4bD-et({R?A>j!(@I|2CxznQ)VAIaus?znM7E!Vy*V@x*t*nR%N(P zXR-uJe@EpQOO9NQN2T$|G>{V#rm)=wK;@rPrjcsMeZ{U?mo45wnTiuI$3>VGYcf z`HRw&A2)6s)~{cytWhr(p~okr!i#ei93ag~G}Jo7Na9~UIr};d;lsOY*R0t{ zHXv9HK62#n&D4)q+bfHcz)A~C{Vp#Rp@jsn)!HGJc~!0~ZOo1n$h;K?jL+ExnSs2h z0jp2nyE{+#db+DowNUIin8n**=K?65C6iuo+JY>$sPx6|e$|zaC6p#wtHBx zqBGsBbd1eRfGXCXl2a3fDe!cqG zM^)I$jL}({`4yK~k^{AC*HuC+RRd$7mMw`}caqvJK z)@@#*diDuvQYdlU-mC%EZ&=S-)xC6E*)x)5O(_hz&zU230t!$ zzP@BJeM!%dM1cU0SeRn<$vu%?i}G`C>|Ql5@^Xoaieh`SJt~_niGo(GTB&<=<%KUR-AL<-ZO96p2n&u-ot(WH0}>HCqmP+$Tx;D}L6s-LFUN?0ML-XTLhP7vFrF z)Dt6{SNNeWI|+F)z9yjsQN`W5{V;lvBX~G&x0(-ex69j2#h$o#q`JFmWl4@Q2*E=SxS<(&1Q7WU~}Ts`I`*$Vk@_xtE+2FZoE zDHheFZzn2Am*nI`ay8lVjV@>w<6M#%3}Mp@VWT&1(TsG1M)+mgFZg7_XjVczsw|E7 z-}?}~7;7t_y2lGIzk(T4C*$@Wz47U%pCK!!058&YWScIP;1ChQl^Zsx0Ja)(KBUVS z6emu55KH2q5{)!t?C0O1=Uvxwo+L4Gx{E#iBPH&<3`uYZxi>o}UB&IB!EFI6=3PvX zNa43|)xyGpDfnn3pDqtg8@E&(vRbukDA}AE)vKxbWA>d^SUk1$ed!kOJN*g#%ip*p z0PDfN_g+2j>z`dsYUE(6VyvHf=%%>VzWl#4lq3&bk>Y?aV-~`m5AYA+nz!MN7hb`O zL!ZOWt^3`DwlX(D7}e%TuU8y2=u!O6PR6mj*P(IK+8F%g03~-E7!XKmfgf76ZiGLV zEK>@wBDN?hoB}GcrVER*`8^+e_2t(H3ieUuMS7N0r#qDAap`wSTG0zh)~*y_MbT8N zuhZ2b#*7}L{ap@3tVl{H7mFuvX24r|R+`wzRGd^>ejdr6Q3$2b;PM53;EtX>S)4or zx7^wtix#eBAi9X9G*_|%P%}LD{Bs!i#0v-vjl|HGU*p#7EKNeP3^}&QMVGGgEB!S2 zGY%$0*Y*;wpqyB8Mm{YeTB4Gjq~5l)lPf(+EG#WKqQ|l%7AtPM99KX}*Y{GD2OR0_ zI3x`JToy`8XKRstmWh||W_X|smPx)tCO_qId(&RDg23A4A&lu&@UgF=?|Ctp#T z$x2Le$M#)vyhc2y-51JAxg-EfCevC}u((R7_tmi}zI>bWEidfvf1t+hLb-7jJr7y% z@^%&8jao>2!|S{oaRomc{h3m&$jhYca&bJ1Z*6y}k7SNy!F@S?5_R+I;D+m2hq+)e z7mpKx6iswF(vX>+gvAT@Qt&U3E|4f`NWflu#DanX@bVK+!c1P&_|YRV=&48X+S}u( z_^d7L(+xRSw#P!DHCI_e5;PWey2YdchyayX%etn%MkE&NQJSC9%A(rEryq^Pytxaw zs55ch^*7+Hx8CA@>S5)o#prp*on)&2$w~-6^t->mR_5g&NOzgf5xa+*$pQFj-g z)19x6#E|$>u(A`l45cL|EG^E>q=`Rc*o*yf>_`$EN&{a+Bu~B+bqh+YLjf!uxWsK& z&prPxL!Nh$u*sujjdox2)x9w?L{eCot1PfRdv~E*weGZ>j;Pw%Lx+wqVM2)_cKwlT z;?5nrQKwEl74MR)syr))427#MKY!}+`@4=C`=zT+Mi92ei&>tfsX3G* zN|m>)P8+i-ug`P>bKpFu5zmmvB&8%KwkOly-~vkW5KEn#6naZ+=arXV#9MC+Qw?eL zCLBIS##)pm!I+ej1YQ0+dLRjhVx_66@S8#@5zJO-taHrHWJWGu`VZ!*k|~3oE(lZk zR@S`bW#k~`=n(|EGSK^mT1blh6HV)dWB0LqC0gik2j|W5iwv=z_(Qi)BCRA$0M?a@sZG6QYVJ&pMbTq^216C5o>aP`ih?yzcw2Sxh`+siqw2Q4`TW(mlLI zs#HmgY8!~#C9bz9o;sbZdNXuUeg-28FN{(ax2@$ z=MYR8vmr1@Wq?7qs*B$v8erIoG}6daT+b(;euh~z9~>nG!9?DXf;ExRIms>3d2kv! z{WaOsAnqNBwbJ;aQl$VaUNjf2+jenVLA)AuK@xW}V%>(VxVCFoS~Z&#NTj8uE0EL( zp3#b9{SQ64e`~jw zj7un2|JY-XT>H@{U%Bd44#LiTqL;-{?kOxE==`Vjn*P?^_!l6B4Wfs&bVMx9((OzY>N(@OX6)pC}ZC<0FCDSI zd?J z7MLioN=C`%pk>52wk!y-RPxB0HZaEHOBYfWh%8J$x>d4J&EzrpuoE}f5M=N6ow%<1 z71*$5IXnHtV9GBGsaJN0nY!j^)w~I7`PRZeD2A@1^Z+b7MS4qmZ*rML`sE;N0ejqj z58iwGIRsIk>YLd=qh0H!*s(i~79Bz9q>|77;x_=M-Cms^y$-a-+lKf{jBS| z-&ou)(n=38H6@$YjK7ld77NQrtG9rj!Lj&cY}mL#1@-;?gB1Z(=D0zT;|P}d1xRGok*iUSNUYtRuJM5WVw^5ps3g%#4|hyUsX?gJ`f2C*pZ&rK zvczXno^#?UsSG=7LC07Vegn7E3OPn}H!*Xx!cq=7)W>b~o?ahe|mij5QT8qm_p)S9fQd_a`uV z+(Z@@-^}B!WWbyj2m{43^emW}x>GU~-GT9!`E%#twIQ#vSD-IBLwV$gHAGC+YFNE) z9DHes=tEaNEpI^yz?KX-R>|`rzv(ee{aX$<&q4=uceAEa2_0R(O!^M8XCr+pc|@|Z z3-R*n@3H~KF#I`p7P9FQ7qW?}**6T8ss|%KODlQWy7v(4`I6YXFp<^{0ZTwCAcz6+ zL`Ce(%uPm8S_ZRw;qc?%E5}4L_+G?#l&|W}BU=43%)%Lw90%i5R=SY&>aeC!8i%<1 zMhfstO{eI1nN;T1$wnL5GP68aHYrw#7AmOHrI#*JW+obfc@HBaqJ=zq!Hi1|uw-Ug zA2mPNTG-v6ok_@R{71&6nt?1L=tv!0pFa0em31zgdN2b>+QZT%%c;E;C_-k zXU;x>idmLt_tzx7GmBB`50t#g%I;5fabhbrxdIalus3Yoj7oI34(>as)Ej31_A}o3 zcr?p&lHnC*LV9W%_U$={lr+YhnD`*PkVj}nQgW&SA`uc4*E=AWXixsO^Fy=z-s81%S43}_~EX+~@@fbSf zSq8;N!^v&sUI~{-hMuJpi%FnD8n-5;r{P)BB5Vao;OVg?+OyOQ`$ZKY8%3p|)Hp$N z{%@MZy8Mg|sM`H6YhFuRut2(XQfDX%w{6;ANonOP@z{XJ5gN#B9j&De8<%k_U-G<~ zFk#_?N)eHa^X1dZ$)KLQofayAi~I2>OJ80D(g#soZ3RlSm=XwbJNLw~XuBSh9MtpB z6-?a^qWmsgG4UK!^Hc}Pf!dd$yVB$1u&69rQRbkF%%KI zK*uEsSTffZi)mi9aNq0qr?G{-o2znx-h&JBw7#GCJ(W%eW84>`6$w#P2OKQ7>D{|G zzMSwmUVZH)_DI}DuZCd87>u~cCR$vfbOEK+{6`;sgdrqeUPpPBh7B5F!J;*)0NS7X z64%khmxz)y=9(7?n<<@O;>5PD26N3CI6YvvJtx`3t zm^%}->V}gF!TF^IUt+EinUuP*GMOPH&muO&m4t@OvAhrp8AP`*IZ>O9EG&`i1XL~y zE`{475hF#;N@C~7`^|>DVI$a3sY+Xm4>8!g%XL@rb z+ogmS+{&stliZ{eiQGFXUkanQo(N?b$GSDERcVPl_^LLIBu!~4|J0DzNH0hu*T|n* z>3L||p(Xb1jbqQg>S)=PqJkSYVbSs}?CetoKh4}gB@F^qP$c6d*$j-+Jt0sT7gM!ewC0EfsaE#-UN?tB}BWRt~8m!h?#5ZbrAzp}O$+`HE}} z-8!15$C8iHx|J^51T$6*kmNuf8zsP5I zlpLhhdRYei>1qj2_xV44BXy?p->Ey3n2hvlR15wTuF#3sr+r@vY1gh@gLlaWf1CeA z0l-PtbPx+@J9KD|WD+;Sg2V6~8!=R`(;iD#9zqd|n-{PAUXc)M)wUrtygI7ZBJq@Q zsUqs08@YgNqFk!#eWc%^HhTg@CdR@(qcm}K@~e_5j;9p~mW>g~_2^A6BslyLwe5RS zGFrL_Nt)ipa+inh?}f47{={v`F%sTznHwbaj^&atWr)REAI37Hyxy35dnxzP3bC~% zq}?BBL+``5)B$B#)nm-=w%cw~eJ}^Hlh3%Zqi|o3+ZD6i!Foo zK;mKw`A?Df_J>)hQmrmyNG4_&qg0uUxP7m^^fIzC4k-rpZ!_kS(ohvwUeg6*#*QWL zDvuJyq@B1eKsjHrTv_YW1=we z$Ek=2^=DwafaN%5r3g`al$UiW|2UM_oze-dTFg^iUu}lec@W$zwCJ?o^@3*$gX;@W zgDt%}+}i=mRxHPW0T1K1-)1uF7J)He|AgLs`k^w_PksDY=f^6522C2%>f|dWE)iL~ zjx!if#=C{CGh5gd710KjjzzRO9qz8%5@=7Qpy20YzrvTFzr&0z>jwj}rDzywVEdv9C z#ovDa4FYJ@w(r!GlEe2img3ENwu5L^zYZRH@FBd%?%T&$vZE{n2@Vrrga_8GTQ{YX ze!6#y7)P^7b9i(>e_C&JgCfJwrd1&PiH}vI-8}qSZDdK)FkWwB`}iTOcsV zFbQ{ooU|f$8d~OC08CoTiJXpw=kpP-uLFA$Hf-2{ay5rBaNxrj%Z|`2Rw9SZ#hOLLuJ~W<1{13g_{NcYsv2fkd{rRcV8~Qb*|lQoVaK*u zM3Gg$dFv)tDKz1CRm?W7f|q^KeEpIKtf51myyc_M$bK(!Vhyb7ubShiCKO(H_x+K$vU3+IbTV*Gii6Bi zQfiV?(d=?rXS#5Q2#)pHlp!3_;8wJzOx`Y18q)E|ke9J_<2(!-ItYF5dl2;-cO-YJ z3TDmx4Feu}7_XA0?nhFj1cjaS;Us1!#m!Pz=SRy-zrIsh#!{F(Z{c#xr1WviR!wQ$ z`BFm0$~IoUiWEuY)Bwg^T_P)YahcVS=ZfS#D?h*au0B-xOrwY&@WeAi@!^Lbpkw<^7&H0{yff@A#^Y=# zV9@&=O6}xRen+HWT!j)vETlpN+3D6CW<@DGO}#FECMkk>vh`cGR&vG@zWoAoV%Okz zQYHMu{L!XCO|+rLd;u+2T8YOl8U(7~iC*%6CG$bP%B&z?%dMe)Oye@$EcITc;}50h zOdmuGZbN25Tc<5^> zZ2ajPa^?pjxY=1B=S8M;%hs*v3NC|>k?IP(E@5v^{^5JYhw9(wc5GO?9MM5ONFbpx zksWIMLjqWg>xWUFeU9o?yz$7BL-6IevFLt>9S!QYL=Z`d`}QAHV5M`21T+LFzWL@G zJow;)_+ipyX0`s}5mkK(4LB5cnAh46iM?}O=04kp{&Hfd294 z5(1+%evn?7EJP;pQv?RLvFpyF#S3uNm6wqinhOWP%IM9~8P;w3(L!q8tR?@Rh1&IM zW8;P;sO%kpYunXF?D1o~fAR1manwRr(qIV0jkn*5xOi${MT&Ga0gtE~5a@s4%y06= z_09hTV7)eU&}|=n_Pwi4bS}2X6*9f+Lsy2NB^f9;s1z$(O36dET`{+9bZ3Oa@>fGo z!53Qq(z=I3On7<79q#&xzY~k9$fKm~Uka7Ufc9lA+rh)w@ZoB__sURQ(di1j_U5~| z_4?~DXW>d!`*)_XJmEvhzmM2};eG~>XU+Ou1-cRv;?cHsb987+J*CBKna#4Jefx%} z+cFB{CQK#>@oZQ+!|*U}>@k1@(Rid3_+rSL&XtmHS?3QdNcnCO1X%AaVv0SII zs&(79Z@)&DIE`PZIzIE-_w9>S0OP~vsSNq>oZ0?eS^+xTayq(}zvzMygw52b_oh|k zqQxcPRxIPf$3k2%g9@fQ>3Zo|N-b8U^TL!?s92z-)FI^aV!bsUM}SbbV8hvvvj|}L6Yr1#F^gs5~joe9a^k&&kJ0+)MAaRxFaIhlJ&c*cI{{&zu0I}I-RthxT z9!rUpf;^Ex(Xxi6`^1^}@Z_f-rdb}3+)Ty|EDVf>Q+h*Jlsw&?Rp95&GV#BQnBC!f zPq`x!%+(uWoNhN~^*OIgQrv4cZ^b)rzCbDggYN|9M<48mY zh0YTEl};-`!G3Dt7D`4cyb4mXwo*qu9-nS#F|9Kl8sHG%NMd$A^m%d z{CJG38HtXocd=WviNRjQ%W_xkGXqmpkb;_(((&Esr}-AP;Gx0ea5#%*x}`n|j`>;| zUieM?52?2@FvVu%Yh2jKR(n2~!e%tCSA}Yh9h73Du$8C${43@x*-YnwHCzmemA4qq z6^ND8L@E_2rt}SL_Am`3`=IA7*Wr(OzcIeF7rlDlk6Ck#tLZH2!E`ug4x=*<>UHpv*${&!nM zQY7jkn3>F!*vMzfoD0Rtc$W{~#9q?n#3XIm`HU+;wOl@YU{?5!kv`fo%82%wQx(Cy8e@sp)D|RM-Co7f;Wc_LHyBucy-u|?1*xd zouc=V6UAV(FCTbGXq95?oU9L{{<(qfnS3tULUDV>j{Tg)xgq%G#~;=4G?hy(AREb# z{uUO^hO(B8E!z1a$Rf#9R4)HF`%lJK2qadEIzNj=Kt^PLPc6gDC4F zlGUee@4kfMBmphzjI2z>I5&wfp!!_0IixF)%v!>g+Ru1Jz@$VvGBl)b&bG%=VoJ zGV$D-?1{=k?qkVmShH>mV^ow%GDjj`UXZj}<>geKWF-QD`SinMk7nVH7EL@s_ftJm z7t`NgeBrsCBR=`s)qov#w(U!$(xscNERPc10{?(0BxL#Ht^pGXJcWEqSLJgP!OkbS zhzWKoW^ojCqN-M@&NrsF(nL3qtSH05n3zLUGTr?M)ZZkK!-uQq^;co${534S3*duW zu9fsTo2 zxNrfUe|{)NQ&KrMD_e1$!nx2IGUy#$sWO4UTNO4-@4KT%7qH=}rn>26_NP_DIyRP^ zc(W0Njq@wV*BRpadFwGjb#8RbTu#m961UBvVozEpWC0jqvlr%T0AiE2IpTmbKrJs5 z{Y7LK$r|;E_OpD&Kt*GV`uUZ&z{>w!eiuzC$u5djC%`FgtI6z3RZ$j-lVVe&ek*KP zzX6-}vZaw=^KoB=i-uy->;wA6L;#L=Mx^+riw6^ZN`FhNn zvxK$;Gi)ahdHf?!hs3hjIEBT>9q_`7Z&Ed28=}ZgKYI8e>;-IAz>BRQElUO9f1f>D zwQv{U*h(c!X>)#bCGlBLKSg8U+O*SfF|FU{)7V7n(J4- zuu8u9?>_Rg?$+lYzM;iG@=%@Uo&LLb?>t|u9R7`$p1t$k z5o28qtA}A-Y#RLeI_}cGHoA0bOUtRI(hst+Rh3;SG&)egnlBNmiwq0r;$pmtu7@aU z>Q(#F{#=GGIb0H>()5u`j9p1-#noNAV8OB-$_hJ|<77)x?O&?(`NKq>()cgGWc#kl z?27y=j_ld1*x=7R{V+y-^?h*`>s06D5?9PU*~KhiAzzqz)F5*@7_wky(_6I^Bk@#OTW%{;-VF@G|MKS_&9hyu@F0UB z?OZ-<7s9^&bATn2&J_Aj!2w>qLP-iNU^eH~p-GC$ z@b#se!Nn*hy~w7h{(NrW@j69|_tH04;y8a^;fkb+#fxsQVx7vPC7d>iLunZ| zu@LO+IwKiFZ(5|{GLz3s$r+L+3n)iZ3b6E|Z+~*RWT@l>7pYYmv?>76VrnH;l>Ab1 zK7Zq4PP$2Psi7ErXYj7kzpulhfiFE_rwd?7(^J`pnO3R<;zfNyQ6rczaN5M31tNl^ z){-e2B3lvluIz=W%nf)UI)Lo?aDOD^vVafL3teRsb!&CU;g*&$daYXBh%MO0CjN{W0n) z6&BKJlG;tx4M$cxEimaQo%U$~hN8OzD8(UM8~Q{4cGS!h`{W|x>XeBl0` zSTg7xcN2tvHu$cw{N@e@tEP%5-`2ls;1F zQKr4sNiI-ZAarBg#feV7?Ir7Hu`ol&zJF$M1yzR6y~;`U`w>Ee83g%~SC6)_Xs1&pQXsj?7hjY?3xN|g}RDaSz~Z7?m%u%J+z z$(5H{WOr1`qq}J2wkbzr(Xm}EEZxLpk0f=Ni+m!5n4o=-j*b9e0+QW+SC&CV;JOi386tt{=Ka$7;C<4MWFlJXDTg(-bB zC5IwUjCeDW@v`RQik8)|c1Ik8&}37W<3Rnr%PL#DSUS)w#}zwCwZP({|90X;^t-DE zz8F7^^?cQERhRBqxMsZy)|M_o66;45^D2;W$4A`#`Sec9x+1870OZBEpJ;{Wa}En_ zhtT$I(rE?7mS)KdLj%Q9X;=P6CXioq0kE|&FJoJ0;+To^y1yyq}^B%O^MoY%O7W z)7sfkt$?%w8D{ZQI2=MPVAji4D2s%WG_2QDfI`cvq%d3q8KqC<4iM|VmyJQmU){$o z&hVAK#?pYKB6MYEMgaB%HIA}joYU!>{nh6(m&F1QZXEopxK{bQBcK&`^e{`1s%Ue_ zB!bKzbGamw`Y?M6Y(7$C|7rZd4Fs$c?)t=U7rgq~M`OJw{rtysu(Lr3Blhxgm1k8{ zVO0UQ%rjp$ssSql_Ot)|gU`3C55fNoB5;5ELHyS?{7(bcOD_$*_pP@-=q;H(iCu{l zt<(+*URF=V&cE(AXPMFswUD(bHMj|fx_%OaH0tltx33ckmD>-bB9BkM zo5=l--S9Hn^*o1Mx?X0sVAps~^eVVWOq7eU%4*?ok>M{x>4Ed1_wg0_hAaTFBq_v4 zV3OgG^dN_qQEOZv7M7@Q=CfO}cKx!w#H`9L+tOJ$wFmby(zAZDuB0oB+PA8Clzo(q z8>;;)c^7dV|FNk%Cp*@e`f?326Z!cCs%}#2{g{ck-VGESY<&%_>ywKKgwSX0nhT_4eViaL=}3Md^EN=0baX zKtDV<=oPqpBL3amFIgpb2uTHXmCL3*=w=ccRY5Y_&g&1p1kptf-wC@3^>amRLIiNEM3-3Xe)KPF@5dlvwH5;WEUsMc9$Uhuw2^aX+#WYDi8_ zR;r-+?22tBm&_pQAe4}Cnpna_&8w7@e9F>f)IMlP{CV4sLkyxzEvnSMQaM9ntn>y# zIXC`NenjrzsfJ`_9dya}9X%fX>(axG?&wl;_rLqVo%^F*+;{&R%*XJzUcK*`XP)jO z-HgROkrcELB88=_YP8({T|P!7i&rc$$?lXMN;;QA72TGOsn8Tq@hs-?9c;5ykNQP> z4$z`2wVqXsq}(;>AD1X)YJbr!72Sd>>FT2GKrcCwU^t09w5T)}%4ndA$MX_P&|B0p z4VpD$lg^&}Zb5ztuguIvB0MJ9myfTzos>u*sQtT7RIafYlthw;i-`OoI~So`ji38_ zde+fEt4-MJ5@a`W?ra1&AD%`CNvu(kp{PM2z_73&)v>2$^{S{6Sq)9taN(VipR<}M zgr{CQCRIWXEivTEx`0|Pv1I5mCjBqv4YV>AoBHtV@{q<-7P`_RBluhS4CJxVgd{0^ zX}x;0|DeSB>O~mDcv=72h|jy z$^CT491Tv&_b}e|>#wtRo%O|(dp6IK7G6@iJ8vnRx} zM8ioHwz>hT{LParkg&BSmLo%vCWIWQ^tWAjY3Q@)`{1)M_-H&M84@EY9~3_Ep>QLB z9`$w81Z-{>Pon_v0q0v;0hA&>N<&R8zGV=AQj#w02gq)}ZoX!*GJ>C9pmx40m`reW z^Pcn)mlMwCBo>s=7u5Fdpt5Y^aK{71l`+!oiwX^5{bev(HgArc47Rl|%%`|rYnJ%b zpbIKWo;IYXWhyf2FTYMhuegYnpj+f)jcYY)A*MMkEs%L}XuJB2c zzPjwQ0>HAbIIH_P(712hPFzk}$_a@H!hnCC4EPVv=;SZZFL?lqH%3_0BC;k{i-43! zgNW%a@fUeh>DHB!9dW5P)c_QQtk&Vk3>Kp-$1@FSqH~{eT^Da zrEXQK`o3OEcS1HLZ z=2WwK4FoWowQl_?+<0R*YB<$KpsEWr;aRo>d+34tSX;Lmn>TGomC7}6EHMqfq2Y+C z+z9jLE>U%LE|Cb8`6^D+U6?CNo*Ru12io%%;K&O3(1#P}tTCj^?#GVJRx;*go=mJ^E#Q4uS=>@Xk}58~Je{n?l4HwD zR*J5jR6mvEhrEE7u2}N{H}L@0h55)-{H#h76ra&L*x(9<_9djnTE0wj=EDRx58cn{erPCIKxUMq9^0Ts@ zPcnB>dnfoJ54SGqWi-2k>ne7|+C6u1u*$e87gpy@>A+MmyTqG%V}2~v>D>NuM6p#^ zeoh)hODi%mk~&$nRUluK30!o+^D?rq@7Q51T(Sxco43Kj6y9AsY0?}fCM#C?*$w9balqh(e=H3G>tirJpYI>Zc82n4J| zA~zsdQ!5ae-SqSfRhnUN<|yk(Sr3XdsXYv0-4*e>4ukG8%B>Psy#`KBcd$iDJY?kO zYg+4a{t`a(X3d`rUGY@TTLZLGLE2L8oU&MyQK<8p%16^q{*Y>xRmmu#%U6SmizR=~ z#w*VaX1lMp3Y^7aUB7NEHf-5WS5)fb$UWkz?ARNRWU}J7ZP{6Qgw3LJ?mY0aDT6wX7>Sb8EWG5DGpp{Oov_eMgCjI&w?!Nv}J0xozZvjSa#l7fvc|Wh;~M^Ns|MKdBq<;&V~%>>g}JLk*UB<&ny|eCW%0UKplCm7z{J!yA7(v>t@EKQx|X=xAQF8f89JVv)P*V? z|4@J>F0ckbx`z3QX@I|a$R((6!SN4IvMiYKXgB%uq=(Qgy|OVpT`*5J`8!Obzvf+u{*~hM^QQ#Ar4&ZHB@(AI z6{eH0PvJfBvb~zXPL6_u^Bzoa8uaL`)Vn{1mIJ$E>FV*+SgXWm#v7eGT!pWutigS^ zM58D>3Bz9KiD%xPimabzQr?K|Wl1)>wB7&5}gO0`>Vy&D%`}D=CSW!B=qU4jN zELM*wBRE6{i6A8klagsHAn!&jHc88i>VtZ?7*tk`F~vGly7D4SCvBp@hgOSCXuSlb zI$r}S8=DTukXBC;f719~ECwbyP=;pdFsQEAK)UG)<#|x$pUmQHqbgVy0;#)(u-Nx1 zYiXTMV_hsoKmSmC^}}?uYug4p_v}VeQW6ZC_VO~h^i}M|2yXC|Ibx>BB?o|*isvjrxr?q$(J^`V)`~Dx{6{ygGl%hLpX*@AKMEi6sDcC8G=oG?2fJwd zndCaUv;#G2)c9X=Qo1Tr zFtZUuTwFXVRjTAKu_!;j-Q{OMa9|ge0kpBd8y9#aGgX01{idWQutC6n)r?bO1kxxV zB_)k+T?QK`>{8sBT-Im>QRGjry)#qAQkCWKc(P9cl|))=34FVWg(aVf1twr7v;@^Y zUe(Bn(mMs**yT8I*M6qC+0mCNZCS{9d796n3)@M9Oc^RhC8aGaqE-M_ET>XF?S6J? z__KRP#VsNoggc=jh-DP=b24t{&Gfxw4FwbR%A5 zRxxZ)S-q5;G_#H!$!4ZA1va|(y>F|A6mgird42SI z;$dVP>#7)@(G`eZPfz$id)EOUMfG)0cC*<{?>&Kp5_<1N5JgbHUa|Myd+&dH7Znvn zr3orFihva9z4xAw-pgjQ$+qv@x4W=}WgG=?Zkr$mQUdhdZxpjhRbL=+>e=J}(=sveRn z&D&Jv5P^)ktC(f=N0XSp#!LRQd*b-M`;;EAI7s#4a$~U!7ShX3YPI6y5*0cUo+vnk z#iB(8N>wbNI5sYtODYRpGTBs>{E=u}%IH5HM8tIEwb!v2wVM7*R0o^wYDrkly22{j z`^x?*xcrl4OCD43G6)H(k^!l_tVj{y!f8o{&^wSQFD)vVC6R5ZwWtbx8?!k6Oi$Nw z+2x?%PnKWp+IGd_#f!*UxwCri5*fFbx$+qI$RcX3?j@c#8z?`k;$|Px#=TVWCeS%B z*4K5ZoB7}YP52nu)Nj?_Jy|W!eRg1g`E!zTZ>^!j^FRrbw0qX2ay<2QP>0;ke^F@a z%Q?9NI{QoaKh4eE}?Yv+KPnLsJyQ{%R9{AV@atnf%r1cZ|h!7&P^hRmeyki%N*`+wI zfHSK2Wl1L-<%+5I6vgr;=fyP8NmC6b6l=<|&Po3#@AA-X&+DGuM1CO0CN*F}kp9YE zf=+6l4v@?4J7d2gocn3q|9<(G;%w^aaD4A4^>-2C9BDgbaFFGx_rdlIP=9WmI`T*S z$AFK8ME=#cuv?Nkw!?9F5+9S!f;V5d0BJF0ESn0!_4j>-VpmJ+oBt$%=`uG7cRxpRn_RwDvBh$4#Ox*_~e__RLf_D&9n4o~^ik#CHX_b;d9fVFn*+WB3(c2&zXX{97O9~pe)rj&t5 zxFaFH6?ekl<&YGY^}Y;5QhKv*-#+!TDspCL8)+1(deQL)E-TCM>m}Q!G+G|LfDB+#Kj>}TDaRw5Xt3l<1|m5IZx&8omtT;Nm`2TL zGrWe!;;y>a`?<4YGPrt)e&5??f8V=$t^(fIcy(ZZSEnQsfbe5(c|;wFVt4Vg$X(Tg z@)y@~fA#hCAC)7WhqsU9!5kc=53FXdqfM}p*N7LC)J4BMi$(Hx89xsCo{a#4QSf@T|BNEQBs|a^&9eeEto~-d?I}u4dTtFDhbRAA=({c z21v<+m?QFJ4Z=rqnHb1>GJw4V>}-ElC8Qw-(qz49%*i_>9sS5o$pK4FNtS<&8Z}Y_ zi+q=dEI&VA4LrMc?NYiQS<1^r?5fP1{d_Em|ISSnARSti+kyyR{~o-Nfm}AloBczC^>@zUZ@-5RXKf`1 zD_aQ%ej<#37S*WZXlqZOaM zaWi&i7PE^u8>EtW_oEcXp<@Y6KqPh*(ntN7OOP6`Lw1P+4?H%NYFQD4vXxwIEV2r9 zNDLzPXxoGH&u)TAzs|t8$-fZk2a&rf!QjtsKt=H~oH?KiMod^j$wRcVCp41qzxk23 zk(`=>om*C+P5WMK`PBq#*R56etT-qeq-dR^STI}7iG7b$2}tX&YM~TlMZt;ENEJPs zscbU(8%93+*dt@p)6>iUc8pK(8&AmrOQZp^MNp8qZrwT-f<~%`YcDf#(hpEBrVLmz zn8|Ae2?_F2x+gxwg1|~CL)f@+qgpD;CM3B);Zr(X7CD%$`RWLh-Awp6PJ-@ zcIY*e0~5<(K{`?nVvQ+zn(b^i3;s%26_vaT-jgjbx`5@+=d zrmP^G-e2=EV+H#Y@}Zahi*;<~;9@_(1C}>(fWW7tN8zgLZ^hdm%*5k&wkGH0hua>! z8uRb?4maNVAR?oZ6uP|b!7)tE6re|^beumR853s}um+G>VNNo3W{cyf$ah$_A~wu~ z-rYlSGjF@`0X<|Am-xSAuaIzkKZ9CqBX37$ce=6e0DN9u`=ZB zp2uq&4S#bk?zrg!ELpe!C51MG8aUWl%h`~kh~1!>AtdTGamgCMT2L3!m{dCmXXqfJ zbnyOTg2@tOGER(*3jTP+h)-AgUck{KKR&@j&OiJ3Q*yu(WF!xYEcIky5Jc6YMGN)N z2}dOlwD3cMYUI1TCMzpT5$=+~lR-@0D__d0mz!vT?3}H(JMs_`5zSfDgpBrGNs>!> zjhLfRBSV$Ajz~@#BveyJB{nE7x)cbfB}hs%RZ?WEM4bxUh#1uUgh~r08=Dcx>tujX zmcm?Oir`P0RP2`@98iwB*{=Ntah~iU-)ke9b4vkSIFBVRn>KAExqB|-z#064OL5MS zYjNAHw_y>p8W~+rDq*tLTos)h&W$-;d%0N1xRh2hVLf*NM6sPBorQV zhd*_f9k#Eb&pVHmo02nBo>M$HhhF;3%fRIsaK)*BKN=k6=+Q1xHLRUFa|80K=q)8Z z6WPXn@%%Nos9!f&xrDpphCcXh{%7dj_X;GWCSv@=nH--P3yMFzn+#;nzwr*2evPns z!*+Z)sSGz@p&}bCpXLJ7n81uzTuoNtUD=-rC7A|60O$VG#fBZqG z55)WLK92kEZpye7;nr(<UN{=qxT45y{pCqv-;pV+&(Ec6) zwo*ier=Zdt%rd1)3^{usz8EzUfzC>FZrvEOi!yP|mFHvG;#q2f@z)2Tnke5XC0HC> z4N4oLUu7~HKN&oD@PylLyUm?OZlK#KIbaDQk%7s}SIIym+?0^++o_N8BCjO!Pixk! zQKH2iv?!s(LGf2oXCMQa%%(8jdJt8$~oIoRtiCf_wtGoUGiF zsg{JoBglYdql>5vLV^_BB2YIOFUv$ZP8nRwnGo=DTf$2T&m>D&S$5h;_{)2}0#Jn} zcr1b%%ggB;L4+aiktL*LCYv{F!LBNyxap>wsMmRct=^lXODCqgM~%W$PdY3N@@~bbg6_s26RXIoDR8)~TW8@vj zeI6!XgeF9?=*a9u6GoyaiLH(XgARY`IKvt|F5w3B?SLCDh-5Co%zleQamRhXQ4C3a zl+e-93CPJ0WxMxcRF-Dp`b)cE@^71QJu|UP^6|PcsX+o-2~|Bs;wx8e#Dp)u#1&WF zfZ5Bp;=W5eqhqHY2#Zf-ar&ny$ST9DuRlk``2xm_orSB;3*$1Y1kXHl0luAS!LL(h z;=7-IMwq`1#pVPer*Z_b+TijFyWqRuONgL|qB!BbIbjtnUzRFysNNBTkN_*+Q-gAA z7E&V{VGldv=qdOzmuC}#a|KXt#;o5LQ~Vjhj@{XKf5a$^{CqSKrLLTMt8tOxbtA`o zF>#~sxHNh4zzdbo>}DQ!@LkqivNPc2@&80VaGj?zxaz$C=G^o5fF zLmn#mlGjRBQT{IbklzXFN@V?D=QeHV!bzWZYFdoJfha2}Kr~x?$tD9=5Z@z9PSL%H z^gsqf83gNR_vBdQ7-e9UfzCT%c{we~LW=K}D3pC0Sjg+1eDX<5nluTg_d5+gem4ov zJo7ZBPn)g=xJxg+6t~}T2m1Evjy!g9p0{WPdN2cJ;Zo_@|GlaPk$2yHSJ~Ty(m^#? zTA1H*3+Bw7OVo8M?zrU+y!_Hjm^o7rhaKl$IviW}>|-`-Ir^N|51)Va6#_XpKKAsJ z?m?VcP~S~5s zuLS9`;VQM@y31RlL!YOxj>`S>uet`mfB!AcyL2#1Z?@AlGz3-ovxx>%S$4x-i)$M`=@=(?N)A|7Ug#=w86QeN zb{mew(xqj5`18?`ZR5S!Eg3N6ff6oDewHsmEuzt$SDzMA)vQPe=s$jnuR>n216)Z;{_K%Sh5klJFvb5Vdju&&kduU*5hfWN{$A z;JjfhE2Domm6+GxdmHX~@GkV|(+?kiHk!r25!gh8uxR!|g#^>m8lluyjc>mALJe{^ z-FOSWo$xb4jA7{6xjSBX?nT^i^W9jnZX14Euox{`x5C4ZJ+B57d4OllU8Fh&2`6^I zw9rSmDg%-@`f*djSkX3#j6*sK@w?R4`Fq?SeJF7r9F3CS9GBT92x-=?v(3WI1diCm|RKW5uiPlO`fDBZ!b3SKjHUbFn zaxJ8Zoh*k)YTSf^)F|vNEk?A7B39~s{K*UHD)wT)1!ux(*$h+NF8I^%PFiZ3SZ*Uc zxQ+_;&qlnBP!6bm#~V?##+z8lHnB z2a^Lu%pL-R~umO~IwNPvQd~&rB>cxgqh?FqzS`TfA-$`g97xqjz;e>sIY?=c8ZX_vzI< z_YZK(%@3=4LN+;fQH;xw{P>eksjkw&Tsr^syNSG%`1=>(y;ttT9nbs*Cnq^efD_yD z0&&UhQ&7X~upu}C5q!O#ohq#4oS1=O)>#_Bx>J)zu@_<-Wl1mhB8{Y3Z^&ec@Q}Qx zf&v3v87*7>(znmBPn$MP`K_V&uK%0E>M1#3rKTo5lV6a1j%3}KWLAhqmTkh7$RH%y zK#?=ZCJ0L&92ubGMwJ1}TOa85zw+pfm}NAX2X?CKi*iMvlfNP39LE7vmXVdL#vlL9C^i}uaVjMWB#66pYk>>TzXVgK z{)X6?M5gVHxaQic@cs9b)Umz!&fAzeZ6*c`9L&P%x%l>nU)ZTS6x(<0#D>l5sKT#7 zvy&onlJ<#p0=sizuBSc$6XmCv*$sRSy_ zqhn+e-J6n{`1!S0UNNdehYr%{6f=LK1VY>XbOcVx0V^ONc-78bo2hCqB2X|wM5M{d zsho|?O4c9`jtoj7Ur=PQ+>D&neY8|2GHBoXEHrD{8sCimiK0|ykwOcUUzESNY;vEa1te;DJmKW43MzB)^y3dO z1KOH5JC~$9uH9L?aoNSgSdE|00gY67uj@fxIasrkg?&ne~eocW6t$sQn`RA}fX zr5iU~bu~%%Qd$ukk<_RuUV7zyg+|PtET-tUBxVP!mfcH1Z(>3GIuWmqJrS8T1~aL3qO4N4mM?lt1NGQ^E>a;qAZMg+O-J7 z+v6BRCRP0P!H6*N-l(nS*dt9M7*8&Nje?Y<&PaJ&%lkxr!VEGA^H4JUVWC0f4}+$4 zXwzcEbB{kY-S>%n`}J4<^aHBB@ZboXk^`1PPBDoqD$1+7iSDUWXYv^=hp>`sl1!m2 z{bW;}NjL}yN|LOV3|wYrW8BRwRT5o2T=F_DBg^>vaVd=&-z}Op1T}N^RAzAUn9Z>w*rY?Sv644vpz0>Gap!u}m2X3*{(Z4*bq{1g6@zljtu; zBzd&d_*msw>d%Mb@++=JcFt~GaZw)*M8VYTL?b4isc;hLd$?q+;fNGSMYf&EfvC86 zgjqxI;s2gRT9b6*QhDfELgHepb9y{U0>MdiM%=%+JAy_di2aun}9=*WuaQIkIQq@uXE zR4oH7H1+rOt@0uRu{0^I;0!4!OJsvwa)`H-EDuSxU)Z8Wv!8rJzG3T*h~S{0tL63L z@F;wbyLeg#$p|hr0uU3`5`p9|wr*X^S4472(v*z@{E^X;d)S1~bJ z;HN9aeb;tHnZF;TiDHuVG8pj**z6Sd12JF(L0{mwdX!#wz8&#TvrK_xvUSOR;mWc{A?>sHWOl_ zjOf=rnRHnJ9=rP-jGa-AbB5ic{Gk4r_A?f4(4hn4Zn5Mei2JW7%xC>)DCHS;mdn_% zE;kK3Hm%0Ol`~LBRk|u|QZg2@k8J!9O^4Kq3i?`cz>_eOu zV0XyK6pSk+4s6UR+{FFmG7K zxYAFH$S5XoFCM(>W;l$pWOrii+Cs+mDk9=swCj=v=Vv7EdCtU&lpKWMRVvtZI*K$o z!PGf&5vsU5mRpH}p5JRp4VZje7tzZ~y4o1XQ%P6m0Gi~9$vTrWqvN6@KV?E>>;JPc z;-os=Q+B|TC=ywL#bd<)8>hB~#d?OBdCyJ1{7C61%pnVo$))UAuLx z;Dd5h0e5a*-kltzJ{F$KZ42Wrn~}LT)D&coi3|2OWd)(6(#B<>6q=H#x8GR#5By=N0$A=@Wc~fL=-;8g+o5~WOJUsr~+vHHF%IEUf z!G}$H)_E<0MR@w@XJ6vN3$Ng3)?&bb_V}1+Ks?wbOKG>|VaoU?sS@8sekKT4-0}e% zKD1N=acDp=-uYlM?!U1umxN__dld zg&hTHSh{f?<}9H5Mr0Y@d%72#b(Oeqa98{?Wjg76E~6;|)p3b;(^J2()Tx;9WcTiP z4t(U9jN~KrvIWRwhX~+oLQ%XRUgIuFq6jqe@XF8U@pw2W=luZ#RrPs?sg7- zf;@zH7ZG7)RXGQ}DrFk@(z7pP+vY9!e-LMPMWHJMU}RPHAmVbp0k*cR-!dF#t_hDwO1l=-vV%w8baq;z!p;0Q05~~XF%}?Vo z{2V4r>@2B-PA!uRL&)=&K1Ui zm0GrvEFPmI=S1`6=Awif7hY1lxf2JkC~i_kn{?9e6hGumHKDG|S0BLh*rqzPj=v zkh~j9}Wi);O=zMq0u83nFiL1HPu9+7h6p;%{(5(B&6Brb|t9!eTRG3}*V?<&)Bu zq1crT8f4+E;%{xn3o8X9{>_#Pxk?nFw>#3{-6C3sa;DIwpzYBB4Q&!-SCrZYaA`*BGkzPoSw~$)P;&)YS-9`tC6fS(%4!99M=WVeK$1XKZ}+@yZ!@UW3AX zHa(=>xun3VkkZ<>R5>R;VFzKbwgbb!i#a%ungU5I+&X-+Ux~gDvwX_dQbq=ikwoOf zGX-u{T{LsFtu^h`Y@^ZZza3%>UlTHkHe6Fp~J^Nyor&Uo@vjZ)fC& zG0n;~cT4iUbc7Ctpg-Uy`(jO(EM|Cy`KWz^d75ybxEwQmvSo3gL_tejr>w!fGx5#C zR9ZPMFq-{7E@dMlxDE5=@;x}Mkqbqu>AV~*8rM}yVPz7LIN;sn&kem6%R#n9?H?9b zWJZBXc;N0GYKI$9z#=q~u&yQy??6-^1J)?|c=Eyh1JA)oXijkQHI#(84ucEBS{A0L zumx#P_5kVADS)~`*><8WxjxnyF*0BacUZ9=u-b%6k^ih5>k!#8kHxpDdBc+9|}*=0trJ zg_)qOs5f!v@cD3L1lDYc47Tas3t$L2{Z^GtQd7r+BZE)=Z2M@`tXlf5P8uQJ)=d5m z9){ax?Tkl(vwYO#@pK)qY2TY3#GR_TlpG9^KG*9YXuH{h>CpWO8$o9qCU4b0oA)bT zwn4jq?+nD&5U{9q(sP6qtJT>MR~mE>escDB+eb$JM^cs8rqJ%TI7x7*A!{_iGxsG$ z=C4YVed1KhJ;hpQCscj>lBxRD2!jT4->Gyblg*5c%kGz2mfd&12_Rousevu64UW0FKq!>cawvxdlIpn%JFvbq}K2*OxEN6-e< z2Q}FfIpv+m(lqPK{+Dv7TV1$_LmOAK{D}4!d)iPKA0$WIDB)65jY?JDAnqB9Z_SUw zoLZG;|9yV%qqviLj;cfveS)H{0@Yvt4gPSh^LPR>uD^h=AQIuF z232LrJmUQXrK}e_iP%p)%)B$8VN=(#Gk5lbsEMJTG&HYC0no7sEpL#^O0(#=M%E}( z@IHMc!d}G5g@!ZgZ9K4!nK7*SmFE7!>0JMm9EvZGwu~2LwD_C#wANJYhf~L- zZh5t{Rm{FKJrQMzKbiVb<~u>hc%Z_T3}CpBPLVA1t%b-Mw`aO=x9tOqP|5Z61rzYS z(d8;1y4fs5?ZIvhlbv?SDYT?h{W*)inBMPd?EHsEZIN+pqPU*uNf)YsKoIROl9PgK zQf?TwD$nf2aH*^`d|Qud4x4=@|MIKW(Th_Nd0rP~sJQKiviMM@*s7*uu~Mx$P}A&R zTNV<^KNcsqdmBMg7C}-rx^}VuADI8`;r6`TvpV>)`W)y)YS;?5G?i49FowxP18TIR za!aO*73k3HJPoEogSClFP*`1-V5D0O&98A$K^e?pr~3rD+cA!u64#qXXdF*>5~}ko z7XbKx(0|>32^$UV6AxUEq~Dk-)uPz;P^lYW%%#K*h+vak3J~@)4 z8#7Ea{INb!6u2$!lxyIVtlOZBe2g;8WnxH5RT?AObzN)(-7aWFynl0sOYSzm{KuL? zS-E;?=|XEuPBa8`unEC*f|Z`hPxdHmk_$xv&M>luP;bNNwZrvOgIkWp!p5OjEQphmx?vJ$ZpOs=}2Y^OdrIDE}*s^C@os;DGoyzmtN; z8NHZou^&ci7h&uo93`6A1POS`4W$&&(P?ROd8NK5*5NOg)1^sf6D%E|=IuIyZsx*k z28Tdnv~G4+vQWY*a9OZxRI#Mh27E=Z3-{mqZlZ%XzvDz^VA;x-;|ia^C8}=CX?zxT z5Ig-fB0`nu?hLHuCLg|?_E3WF`G`s;g!;6>xY@ipS6|mr?#3e;sMi(J5icw zVHO77hz{K^^sX8@r(w5X(0*P5U7wbH8qfe6lf@AJwKg*(JuEosmc@;bA`fY0ifTnm z8c{I4j2~i+W9uUDX-wKhYM%H4S1uuOm#c5fm2)lXHn!{al9*1Va}%80?Ahr9-Iqv7 zvo#EEM@N8$t|FNHOxnD|h4DS2F@GT*$w*8%ZlW0Kg-KyVHTG`~Z{hGzo_Ec`+~HL> zBq0UHP8nKJCTG-U`J-IZ{y!Dd#tShlP)PVHTLb%2+!hlhC--sXA?>mO1q<4(2s_f?exXpT89C7ncnsjXHzu(8I|sU zc!g}FxXw^>;Va-*(O}GpAas6|;PNi;JmUj)S0sEW>Jmm**45M67-5B8Cp40g2U#|i z!E_|L8;9)lhlIm#bR1WHXh3!uPmyrBHGl-jk3aR2o}5Gyc9;JPe1cN1#_X2H!kzR? z34>I?w1DHJVg5qA*!pFRm%F_wkw+N(0`95fyN&PFCx^pq0)1;5-J$2LjE;dF*Oy-R zVLB}Sx?ct{juNQYI1MC7zI$rTi>nh`u9#|-xaHEdu*0Gf0Ne0$&8iW$-|3N5MNin( zth2;P4LGK*-imgsUSv8yxjJ$TXd^G2sTlE(Xz-?gHrn(&Z$|i%ARkf6T_zPp9esWM zJy!JMgiL`_9zHLFY9I;^sP|!>Cs8AO@%DU%t?93WXB;7l93u-aiM&ZfNRPQraeOR- zgO^t7ic3U(6dnt_VVjR8X6J$Ecp19R399WVIlKA<0A>wxM}D*K1l4E{4Fft4?D51H0dwC`BQQD zmeQ5RhEm#rPxXZAJ58Ebqpu`V8U7r^%gRe>Ymri(M_U;JOTaP z5I&nuj&uwozT}Zt4KRK*K(Bt3u31E;O^u}9{5ZX!dUi7lTJ5O&QPi~%V1$tXLUR(_KH7Y^QO|2aP9OTo^)_fUr%H|406lD7+*QLB#ZUGAy! zUTZN!*NJg39n|1)F_-eJxvqGx&GSE=OfkZmPj0s7Om$V0`ib%@Vt9sky+zK0*4)he zuA4W0p$gpR%QZs;d4LrX1qbJ>1ceY#$a9NgPJ@`3BN$o4;s+x&ml}83SG*&$y0vq+OF3i+*HcmC z8dq0ANxbEugDz|Tp5r5|Y|jeBZ;UG03)nL}Y~pq{-=-$%d0L^gRP1^D z60Vby+&t{q@Mgm=GG4Lhe0V(({c!cp$9`JIT9S^RqtrMewRjxyByy~Z2kP)3;IhFu!roDr zBpI#M<b=ase6kLR2h@+U_k%GJ}a?a z2xYrjDgWL_bJsKBY2Oau79XzN{dou;`yR3)Mvgr?wcS${0nYo})hBd;2kwb;Lr2SN zNnE*BFEAkf!wb(Y^ueY9$%BZ&mo&LB7&~}*bM1~=!fWbW*9f|!gmCnt>gs&xf6mhR z^4Z*+KWCo&wV9StJw)#(EM!5n)ygO(3WiGwf{fW=IRBB$sar-`p4>skLYE?nCTzI# ztGhZwt`^!YR7%m$UxvoB*^rt1xeS$j(FThPi&}J8Vrrs=0?XM+vb;E&VrN(NZ}){M zGVPc!4>P!Y-H{4`)9byyuW#F1Ls_!4Gp1W3$7v{f~t_qZW3nQ(I)S#C(XrdNd zp#JClW>O#0N3Xp;17}CNfCFaxO$MdtoO4Eg$a-tF|%=Er8md&UhMs`A43*Yehi6i0pkcBE4CSk@&l{lrW+Dr-D?Lyr!>D3PL< z^B1PTFrBf@*m)kQ?eW<0m~6&M%H=In{3UIsw}R;I^AiQtK99(wx*dc)IjL-Q^CMb} z&lPh4<1nw6U(mg#_uq|!b6@rF;~6h9q4#ABmlf)b3qGye6XzP)5MXn^sM@Bxdd1AZ zy8KB{mfozX+DKfev*6#rQ&k1ECttVY;p#v@D{(GCkY0>+TKdK;33QX=p*EvBM9c1)Q!nkw;`E2B|Q(_m|)siO)Ip4yliEyZ$Jg-x_+Z>eg1j|6adecP}cX8D#rj zxpLCR)<}rx zefiT5-HB4d_U9)>3Ga99_dnxn{0TQ~?PsfAU=xFm_#hk+>LJbW(wT8j=?0 zSw_U4!K}7u8H|esgQ&;M(9yDQC`T!(chj>AMf7+Sps@qtr0ruBWaMz3hDU4XkskXv zmTw|^z1$8*q9=R)o|6=H-W%4MJDPSgFi{it+0vM^B5?RtwMwJ5-pbgbdB6-L^o|2h zP;xWDbsX<%=Ke5G6-A7Dc28rVq|qv1x(R1Kwd@eg^fotHjvp&@Tj_rG>bb3(HDD}V zU-f!DDSmNUVm%pjNI<@>D;AC7=-c5)F73+%Xf2m%qLTAakTM2FCO~}Ar?6O~i|Akg zABAfR2Ln*HjC)0h0L7jaBp&xvMqA4Q|<~0-l`}`puXnL&@7EgDSS`2J`Jd(~k4uhv{Gnv97X$6a&%9L|a%OASl zH{HoZ0v_(Ik~`S-_q!2+ExU<7{&xU+i6^-}FU^VqUN_4CWjER_=d)wR?c%kZErm$~ znvKE_zhv%5EsGmbv{4=&z^N6B#^LBC9=ke{TRn4nz_Ua!gm-$}%4sC31D_&#^*?iX zQ(3ppbTLsHMU#t2J)s=Ze(Fi7Hrw|m~E6_bEoKK$mR8@W*NwO zPy4SYg6p3fCWF>?A$5^R?th*w1DAcBMYF_m3lKH`9Sl>~R{10_Sn4xlPd6zWZ4>{- z)j)|)h^DpW@Gc|Mte-Pd?vKFYSb|_`lp;H@dr98*{ir;7&D5Y*re8+GV-WXR2nT93ct3gg z{(U??QO%#(ggPbs?{mlS55r^bA35Hy(UFldbTc%pslHzq7DV;&yZ%?D;kzG`lDE%p zKboVfu6SMg4i-|11E-|k2v`hZBPz^Mn`pQ`P=eI;On!6oF)>|#s~5d;FtFt$H#ZLv z=zGKR+3T6gVfYE1`teQV_UTVVW>7i=Ff6LiDGnG=izO(ZRnD}`(U55r#tuNjslyL} z3H9%u^LVyt#i_;j>X_}}IZjtSIBE{$EB`MBpn5vyj)#^U4<3H8|@faQKtR<0f>GeYNY*gS{#H^*^OFz3<1tU_Xv9Vzks0EFBcS`Fed6{|I*B z=PO_73@eLgacJH!lC^cJUrz{o&JmSlg@P84B?C{U7FUhW{q*Jh0Aw zLyX276z{a(1{?_9UAJLng=!gwItNu1@=Lwhd4Y6J=s(#I9|x>Ui^cOu{`&#k1NG$@ z=|~~)=@As0j>Y@KpUb7#uC*s4|NXY|9_i=ry{|z%#t`NG6sr_IsV^fl?1fKU`_->wdVr}(hHj!@twue%8Kz?^p62; z3(@Lr(9}i9Y<)?T;=sjyzrnMhM1wD%FXCSTJG1^gT(7Jzo`OjL^};eHto8PH9_QX- z&k5b?MY7MoU&Ery`ZeNt!v9H$_;zniRr)QZkZ1%*ziJxd*jn=OWrLZ8xyHQ=L4=Hq zPMjkg9WAYhx;kc!$4_!vT3RK$axfQ0E|?fobd=-L2i4tW%Djj?X)3{sEH6;Q+QWYz zFhwtP{Qa0&9x(cicisxZ8e6%t`jyVqduHX$hT{><{$&rltPUpgIHj%8*`9od)6O#V zoSCfW=jR)*&@WVwP-!ddG734r_yk2aQ@_0i-M6CNT1hLfH2%-!_ay;?P>g=LZ*k-8 zcsrXP-*0N>JpEjty8`x#(*gHe*JXe9Un!zsLG~+GO6n14QAi?!#)0!>$L#9Cz`zi{ z9}&Y-AS7iQ49N$ibm9HG>O^HkWkpqLcL~Vu(}QhN5rjW*dRxB#R0v=R?tKyTH}Oin zOah@>JB2nH23BbyHV(5`EL<`?>$;g&qDu1G5thayXqz~!z`$Tq`#K!01Z6<-w7 zE3*F#+si*ZP_PJ;NW^JaB_0%V7euzaL;_231k`UjHsXDul^qe=O%qC``_T&a$$F1z z6*dJ#(a0vDAPBX>_;KV|{T(#tlbb%p-f9Vk0%f~JGGZp7;zwII&Xu1kbjO{reZ~?F z|NfkmzEptYA&Y>d=T;(l^sMQdlEj<0)yF_|Id9vE#Xuv`!&o0tn8n{Xx3@&vtIUF#n5Hcl z82ZonNm21uQFG-r!}H?Q$T_S7D5tgaIy%tkG^$0!xfcVrytL@DjkC8hf233VLn1bG zTC1wlu`z5_A2er>NR6q!I~_zO4x=(=NmCL9SUs#p%{oPdW5IeYb#7KLjpi3#65mhDTx`w81dYWBz3izCzS->z%O zo1`pMq=;vz@d(q}B{l?MN8u#Gp4sxD=(Ax^9cTbK{kt-~=A#yqK{uOtgag#iGo2I*PN?IYvP zr;v%Xxm#{K#`bXY41!7>I5q&wG!V!r4&AHwoEd5rtR3#D;$Lg$h98_E2-7g|0=?Ce`GhHkiHO)blMhKgIE%*Rq{yLY z!pkN@f;j~}$ygP&>w_f3bkMKSD#h8Qp5 ze_H%n{s!A{vd+BqVT!k2r49b}xAEn{z&b8reKOt3)RJ@jMZnm5!k}rXx<}kxq$WAl zxL$R9y2Ffff_&j$CqxFOOBwVN!j&t4+2o5+?#qq=A^)t5o-7QFoEXH9rsJ|({MX@? zgX3y+;CzWVeT6k`nn$JRuP{va-8DRCtV`iVpeTqaMuRN;T;YwCru6iGB9+Ia&_UNVmU-1oeknH=tp-HBv2@D6TT5@Ruz zNJ^NuUMPb7dO1Yq8b^Ay=jr9q75wnZTIr;-P8+PMr~s-5@_>nRxyXHnL+Go-EIIww zEE7r`uf8*Wn;But@vqtp-x6CQ!o+-{5e8xfRBb98)m!FPi|6@3u=y2lqyOi%*ur4K zXeiN5|YXm z1;(9wr3P;K@}2flla?W;LD)ge(SK?e2fqa|pz@75pap;XD@Bq<6J$WZUkrwT%~Xe1 zGNTz<-pJV}q4YQzHQe^t;2gif25zHaPu>TX<7ojX7>uUoOf9IY60=GRh!PHi2^T$# z13A)IF*?3K=BtIPzrzj7Kj*YTj&iXYLhA~)!Gk?4Q;Rno3iTVF>|v8-*+Jh)4uQW+DqTkv zLiIfyUFYTG%#F5DOVbbP3QKeM(?A*7$TWq`KzIj_Fa$XQ(!oF@rqeMY?s)mWJqsA~ ziOLv1{|vH{F6(m4dn&FlnT5j$k}IP+3lWPSrrNbA9)+;-_E!;#J(|H&TiR<`piDtQ z#9S=c!u`sY^G%$(Z@5vpO-O@K?vy=a$^$?7=}*^a0VMs~%pM0|Q`#+IB9FuYbgh5J z#F)_c8jLQk(TK>pZaB`SB z(bQ}jhNpfrZTACB}u=+JH^9a$7hMby-7$(c;y>bgGIEU_)aw2Sx|hU$$jB?m6s_!!k`oa~QO z@*Gz65bQDC1Xsr3Qu&_efuS*Wrj(d`%IZCX{2>|F9}xjzs? zK&vy$YewQ`qQi#!pKcejH~8vL({>pW7UZaV$u%u&85Y}*?dAG8SezV;a%+7|eK#|p zh9Usrk*;x~UtY*B8OjDEzX|AAY>2_Y$$maFtQJTgy72vb+oUE3Z#Dc9846x!wl%~{ zo1~SZVD^^$Q8CFlAruKf9h>4%W+VEZ9{q(Uj%i*op!G!cj2fQLGjA9kmm}QNpb`s! ztpYqsVj7f|A_g$`A#-!{#%C>v4R6gHVlw@qOM8x3Lar@FLtpTCEB6qOd~!H5VFp5J zbNmuc`Ox+KM>=b)1>#Qkr8m_8m2TX6wV~Bua zzH?SU5<*xK7Z<0n;~gHGRzw-h4UYt1a@b?uSn9<|y_P7v;{hE;Bhzk+p#1I_@g$(F zs34RIi}JatB~1MLrpo!>*}K+eyB&SUC+9FybO1CdhKPGxf<~5SR|b08Gt(Moi=<^u zkq9~)we$0a_gztW_I_yo*dYeKAe{D`?1lNB-%S2Ng6sxHs)QdLuvD$rp%QtugK+B4gI8y=g$`;9-5QA+{$hYaya<|={4tcEzRtGcB0^*u zl>WUc3Fa(tpsu_x#D?e}K%xX$FGdE8mLOIzY@-6@@p27A3$l2OfdV8TTqxv5!$%bm zlmX*5l^lkI*hev_Jt%H?;^f#HLf?c8-|zgK8|dJ>8MHXlhCPp}Y}$42xO|&WZS3LT z00fjw>4YRS7-#t^Xh7s;2_Qpge|!jB;SHX$946M5=8pj&It6iPg%c&$@O?lv>y3y4 zKF&(b4%zqGA)zzl;xuA%_&p1Xil(mIk6TE$dtZUzIkud6mV-m%0>pj3%YW=LYi+g* zo;W3WM+OEW%o#(ye_Lu=7In?ow%pg;AG*649swucS-8lR{He4>;`Hdr(%j0dN5Z}d z8Q-0F4kJ$m>FMP@JKNec)n#QaT_J)QGkP*Ar%gFUccy8^e7E;XFHo_tTK}3xX1no? z3jTNYU(CyY%l?-?Q8IDl$Zlq;FPmG~i>D^QIddw|+R4hu;>zMyG*zj|^I&cN6fvyaDy@JJUxW~~h{Es1 zh=iR36D5t`YNKHQ6r4FEhdi2s37?k>d^yoGa`$2hYawPWDK7KeqoM=+@ffcnIR!sJ zHd(8^97sR#p^AN-(54`g*qVJpe;HxAdrwP!;J)B2bBUgY#8BBlLgxwHVn5rTtf4!i>Pp=w1Pm#c zX(js*Hmuy~rFeQ%-M?cZ+@5c_*y@87GfDQC5~#+iJhPQEWDu z@=S1+_VIzwk1*mVb+>~CnAmoR|5I&Rew0;yrLt%6mufE}z++f*{8LX`J0dL&J8oO$ z(%Q_d*tiM87IrS-Q(Qc#FylS(GweD#<{dOXKHdf{BBCZHHk#mB(YUz#`6$*8s!rj{ zridUP;Qx;vY$3wTf;r=ACw|k>KwtTpwzIl%U3;-$L>BM@41y>RnxpbZ6?X?{RA@hARV`BePx-Y(>=o4({PL_)dmpczAtP7m=3L zn>bFNw4+2LT@FLs$hu#8+-7L05fJDEhGQK)b~_Xjy4SM_y0X7j$u&Z^ajW~ zBHmz*Gjr0WjZeG?<*gwC(~$?&O5;m1#Twk3D^x$kxSS{;r&QwUq-3b-+J`LD>3LVDBspUavPA4X>!kKrrRRK zYNAlI6<>F1YHi+wU75qi%EZzw6%}v|-$8H%1Tk#h#MBgocPoY`#rtlf1@gk;A}R(( z5lEWf{E%2fNmnkU>D5j*wBwy)(>jc@kbF+;{Q?U)CArt2X7zDn!&z@k{NLaI^uFWm zr`=)gck=H_C>t0cm5#!~!7g(`MrZYD^VwxHGjVn1Tw^=!H=Q>-6<|I&%YAgxy4l_W zSB!&SX!4xxO_*CuNj^?V z&2|L+N9@4WYIa}=jnS>e+XQj7*4XWq`!-J6-6+7+g&!KoqSD#OTK^p?72J4D?baoh zcktM5u|gwnvwsiOp-{=s>zu_)fWE71AocŸ%Vh^f{F!&Gvd1J!HL5=K4KY{^HP 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 literal 0 HcmV?d00001 diff --git a/doc/nrf/ug_radio_fem.rst b/doc/nrf/ug_radio_fem.rst index 7b0b89aecce3..73804a337041 100644 --- a/doc/nrf/ug_radio_fem.rst +++ b/doc/nrf/ug_radio_fem.rst @@ -24,9 +24,6 @@ These methods are only available to protocol drivers that are using FEM features They are also valid for cases where an application uses just one protocol, but benefits from features provided by MPSL. To avoid conflicts, check the protocol documentation to see if it uses FEM support provided by MPSL. -Work is underway to make the protocols shipped with |NCS| use FEM. -At the moment, :ref:`ug_thread` and :ref:`ug_zigbee` support the :ref:`nRF21540 DK ` and the nRF21540 EK for nRF52 Series devices, but there is no multiprotocol support or support for nRF5340 yet. - |NCS| provides a friendly wrapper that configures FEM based on devicetree (DTS) and Kconfig information. To enable FEM support, you must enable FEM and MPSL, and add an ``nrf_radio_fem`` node in the devicetree file. The node can also be provided by the devicetree file of the target devkit or by an overlay file. @@ -191,3 +188,91 @@ Then there is no need to define a GPIO to control the PDN signal. The line ``pdn Generally, if pin ``X`` is not used, the ``X-gpios = < .. >;`` property can be removed. This applies to all properties with a ``-gpios`` suffix, for both nRF21540 and SKY66112-11. + +.. _ug_radio_fem_boards: + +Supported boards +**************** + +Two nRF21540 boards are available, showcasing the possibilities of the nRF21540 FEM: + +* :ref:`nRF21540 DK ` +* nRF21540 EK, described in sections below + +While the front-end module feature is supported on the nRF52 Series, it is yet not supported on the nRF53 Series. +Work is underway to make the protocols shipped with |NCS| use FEM. +At the moment, :ref:`ug_thread` and :ref:`ug_zigbee` support both the nRF21540 DK and the nRF21540 EK for the nRF52 Series devices. + +.. _ug_radio_fem_nrf21540_ek: + +nRF21540 EK +=========== + +The nRF21540 EK (Evaluation Kit) is an RF front-end module (FEM) for Bluetooth Low Energy, Bluetooth mesh, 2.4 GHz proprietary, Thread, and Zigbee range extension. +When combined with an nRF52 or nRF53 Series SoC, the nRF21540 RF FEM’s +21 dBm TX output power and 13 dB RX gain ensure a superior link budget for up to 16x range extension. + +Overview +-------- + +The nRF21540 complementary device has a 50 Ω SMA transceiver interface and 2x 50 Ω SMA antenna interfaces. +This enables connecting an SoC or a signal generator to the input. +It also enables connecting the outputs to measurement tools or to antennas directly. +The FEM can be configured through the pins available on the Arduino headers. + +The nRF21540's gain control, antenna switching, and modes are controlled via GPIO or SPI, or a combination of both. +GPIO and SPI are accessible through the Arduino Uno Rev3 compatible headers. +The shield also features two additional SMA connectors hooked to the dual antenna ports from the RF FEM, to monitor the performance of the RF FEM using any equipment desired. +The FEM SMA input can be connected to the nRF52 or nRF53 Series SoC RF output with a coaxial RF cable with SMA\SWF connectors. + +.. figure:: /images/nrf21540_ek.png + :width: 350px + :align: center + :alt: nRF21540_EK + + nRF21540 EK shield + +Pin assignment of the nRF21540 EK +--------------------------------- + ++-----------------------+----------+-----------------+ +| Shield connector pin | SIGNAL | FEM function | ++=======================+==========+=================+ +| D2 | GPIO | Mode Select | ++-----------------------+----------+-----------------+ +| D3 | GPIO | RX Enable | ++-----------------------+----------+-----------------+ +| D4 | GPIO | Antenna Select | ++-----------------------+----------+-----------------+ +| D5 | GPIO | TX Enable | ++-----------------------+----------+-----------------+ +| D9 | GPIO | Power Down | ++-----------------------+----------+-----------------+ +| D10 | SPI CS | Chip Select | ++-----------------------+----------+-----------------+ +| D11 | SPI MOSI | Serial Data In | ++-----------------------+----------+-----------------+ +| D12 | SPI MISO | Serial Data Out | ++-----------------------+----------+-----------------+ +| D13 | SPI SCK | Serial Clock | ++-----------------------+----------+-----------------+ + +Programming +----------- + +Set ``-DSHIELD=nrf21540_ek`` when you invoke ``west build`` or ``cmake`` in your Zephyr application. + +Alternatively, add the shield in the project's :file:`CMakeLists.txt` file: + +.. code-block:: none + + set(SHIELD nrf21540_ek) + +To build with SES, in the :guilabel:`Extended Settings` specify ``-DSHIELD=nrf21540_ek``. +See :ref:`cmake_options`. + +References +---------- + +* `nRF21540 DK product page`_ +* `nRF21540 Product Specification`_ +* `nRF21540`_ From 0872c94f66cd0e6ad2e56de2bee49d8790337090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Mi=C5=9B?= Date: Tue, 17 Aug 2021 16:56:40 +0200 Subject: [PATCH 120/126] samples: use nRF21540-EK shield instead of devicetree overlays MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thread and Zigbee samples used a devicetree overlay to enable nRF21540 support. This patch removes the obsolete overlay and updates documentation to properly use recently introduced nRF21540-EK shield. Signed-off-by: Hubert Miś --- doc/nrf/includes/sample_fem_support.txt | 23 ++++--------------- samples/openthread/cli/README.rst | 2 -- samples/openthread/coap_client/README.rst | 2 -- samples/openthread/coap_server/README.rst | 2 -- .../common/dts-nrf21540-fem.overlay | 14 ----------- samples/openthread/coprocessor/README.rst | 2 -- .../zigbee/common/dts-nrf21540-fem.overlay | 14 ----------- samples/zigbee/light_bulb/README.rst | 2 -- samples/zigbee/light_switch/README.rst | 2 -- samples/zigbee/ncp/README.rst | 2 -- samples/zigbee/ncp/sample.yaml | 2 +- samples/zigbee/network_coordinator/README.rst | 2 -- 12 files changed, 6 insertions(+), 63 deletions(-) delete mode 100644 samples/openthread/common/dts-nrf21540-fem.overlay delete mode 100644 samples/zigbee/common/dts-nrf21540-fem.overlay diff --git a/doc/nrf/includes/sample_fem_support.txt b/doc/nrf/includes/sample_fem_support.txt index 4458dbdb7d70..b0cf4d8a2c96 100644 --- a/doc/nrf/includes/sample_fem_support.txt +++ b/doc/nrf/includes/sample_fem_support.txt @@ -5,30 +5,17 @@ You can add support for the nRF21540 front-end module to the sample. See :ref:`ug_radio_fem` for more information. -To add support for the nRF21540 FEM, add the provided :file:`dts-nrf21540-fem.overlay` devicetree overlay file when building. -The file is located in the |fem_file_path| folder. -Make sure that the GPIOs in the file correspond to those in which your front-end module is connected. - -.. note:: - You must add the provided overlay file if you use the nRF21540 EK. - If you use the nRF21540 DK, build your application for the :ref:`nrf21540dk_nrf52840 ` board. - The devicetree for the nRF21540 DK already contains the required FEM configuration, so you do not need to add the overlay file. +To add support for the nRF21540 FEM, build the sample for a board containing nRF21540 FEM like nrf21540dk_nrf52840 or create a devicetree overlay file describing how FEM is connected to nRF5 SoC in your device. See :ref:`zephyr:set-devicetree-overlays` for different ways of adding the overlay file. -The easiest way to add the file when building is to set it in the ``DTC_OVERLAY_FILE`` variable. -However, doing so will override the default settings. -For some boards, this sample requires additional overlay files, which are automatically included when building with the default settings. -When you set the ``DTC_OVERLAY_FILE`` variable, you must specify all overlay files that are needed for building. -Check the :file:`boards` folder to see the additional overlay files. +.. note:: + If you use the nRF21540 EK, append ``nrf21540_ek`` shield to your build command instructing build system to append the appropriate devicetree overlay file. -Follow the instructions in :ref:`cmake_options` to specify the ``DTC_OVERLAY_FILE`` variable. For example, to build the sample from the command line for an nRF52833 DK with an attached nRF21540 EK, invoke the following command within the sample directory: .. code-block:: console - west build -b nrf52833dk_nrf52833 -- -DDTC_OVERLAY_FILE="boards/nrf52833dk_nrf52833.overlay;../common/dts-nrf21540-fem.overlay" - -Alternatively, you can copy the contents of :file:`dts-nrf21540-fem.overlay` to the board's overlay file. + west build -b nrf52833dk_nrf52833 -- -DSHIELD=nrf21540_ek -To add support for other front-end modules, add the respective overlay files in the same way. +To add support for other front-end modules, add the respective devicetree file entries to the board devicetree file or a devicetree overlay file. diff --git a/samples/openthread/cli/README.rst b/samples/openthread/cli/README.rst index 804e41f303d7..1c075292f48b 100644 --- a/samples/openthread/cli/README.rst +++ b/samples/openthread/cli/README.rst @@ -75,8 +75,6 @@ You can switch to USB transport by :ref:`activating the USB overlay extension ; - rx-en-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; - pdn-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; - ant-sel-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; - }; -}; diff --git a/samples/openthread/coprocessor/README.rst b/samples/openthread/coprocessor/README.rst index 1e4f98c3cec3..dc481ea792ce 100644 --- a/samples/openthread/coprocessor/README.rst +++ b/samples/openthread/coprocessor/README.rst @@ -57,8 +57,6 @@ Use the :file:`overlay-logging.conf` overlay file as reference for this purpose. FEM support =========== -.. |fem_file_path| replace:: :file:`samples/openthread/common` - .. include:: /includes/sample_fem_support.txt Requirements diff --git a/samples/zigbee/common/dts-nrf21540-fem.overlay b/samples/zigbee/common/dts-nrf21540-fem.overlay deleted file mode 100644 index 569d29f10248..000000000000 --- a/samples/zigbee/common/dts-nrf21540-fem.overlay +++ /dev/null @@ -1,14 +0,0 @@ -/* Copyright (c) 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - -/ { - nrf_radio_fem: nrf21540_fem { - compatible = "nordic,nrf21540-fem"; - tx-en-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>; - rx-en-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>; - pdn-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>; - ant-sel-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; - }; -}; diff --git a/samples/zigbee/light_bulb/README.rst b/samples/zigbee/light_bulb/README.rst index ac19449c9633..7c4c83ba39ac 100644 --- a/samples/zigbee/light_bulb/README.rst +++ b/samples/zigbee/light_bulb/README.rst @@ -41,8 +41,6 @@ Configuration FEM support =========== -.. |fem_file_path| replace:: :file:`samples/zigbee/common` - .. include:: /includes/sample_fem_support.txt User interface diff --git a/samples/zigbee/light_switch/README.rst b/samples/zigbee/light_switch/README.rst index 5c43cdeacc3a..0150f51f7ff8 100644 --- a/samples/zigbee/light_switch/README.rst +++ b/samples/zigbee/light_switch/README.rst @@ -119,8 +119,6 @@ For more information about using configuration overlay files, see :ref:`zephyr:i FEM support =========== -.. |fem_file_path| replace:: :file:`samples/zigbee/common` - .. include:: /includes/sample_fem_support.txt .. _zigbee_light_switch_user_interface: diff --git a/samples/zigbee/ncp/README.rst b/samples/zigbee/ncp/README.rst index 4407b132df39..1c9eed2bdb5b 100644 --- a/samples/zigbee/ncp/README.rst +++ b/samples/zigbee/ncp/README.rst @@ -158,8 +158,6 @@ to upgrade the dongle, you can use one of the following options: FEM support =========== -.. |fem_file_path| replace:: :file:`samples/zigbee/common` - .. include:: /includes/sample_fem_support.txt .. _zigbee_ncp_user_interface: diff --git a/samples/zigbee/ncp/sample.yaml b/samples/zigbee/ncp/sample.yaml index 45cba7c10909..7386fad4aa60 100644 --- a/samples/zigbee/ncp/sample.yaml +++ b/samples/zigbee/ncp/sample.yaml @@ -27,6 +27,6 @@ tests: build_only: true platform_allow: nrf52840dk_nrf52840 tags: ci_build - extra_args: DTC_OVERLAY_FILE=boards/nrf52840dk_nrf52840.overlay;../common/dts-nrf21540-fem.overlay + extra_args: SHIELD=nrf21540_ek integration_platforms: - nrf52840dk_nrf52840 diff --git a/samples/zigbee/network_coordinator/README.rst b/samples/zigbee/network_coordinator/README.rst index 2619e8747b6f..5c0487641ffc 100644 --- a/samples/zigbee/network_coordinator/README.rst +++ b/samples/zigbee/network_coordinator/README.rst @@ -43,8 +43,6 @@ Configuration FEM support =========== -.. |fem_file_path| replace:: :file:`samples/zigbee/common` - .. include:: /includes/sample_fem_support.txt User interface From 0da85f6c54fe0276cdf74f88613899aba2c26ae4 Mon Sep 17 00:00:00 2001 From: Kamil Gawor Date: Wed, 18 Aug 2021 10:39:58 +0200 Subject: [PATCH 121/126] samples: use nRF21540-EK shield instead of devicetree overlays Direct Test Mode and Radio Test samples used a custom devicetree overlay to enable nRF21540 support. This commit removes the obsolete overlay and updates documentation to properly use recently introduced nRF21540-EK shield. Signed-off-by: Kamil Gawor --- .../includes/sample_dtm_radio_test_fem.txt | 25 ++-------------- doc/nrf/includes/sample_fem_support.txt | 22 +++++++------- .../bluetooth/direct_test_mode/CMakeLists.txt | 13 --------- samples/bluetooth/direct_test_mode/README.rst | 2 -- .../configuration/dts-nrf21540-fem.overlay | 29 ------------------- samples/peripheral/radio_test/CMakeLists.txt | 13 --------- samples/peripheral/radio_test/README.rst | 2 -- .../configuration/dts-nrf21540-fem.overlay | 29 ------------------- 8 files changed, 15 insertions(+), 120 deletions(-) delete mode 100644 samples/bluetooth/direct_test_mode/configuration/dts-nrf21540-fem.overlay delete mode 100644 samples/peripheral/radio_test/configuration/dts-nrf21540-fem.overlay diff --git a/doc/nrf/includes/sample_dtm_radio_test_fem.txt b/doc/nrf/includes/sample_dtm_radio_test_fem.txt index 0986eef04c10..034cbd543f49 100644 --- a/doc/nrf/includes/sample_dtm_radio_test_fem.txt +++ b/doc/nrf/includes/sample_dtm_radio_test_fem.txt @@ -1,33 +1,14 @@ You can add support for the nRF21540 front-end module (FEM) to the sample. -Set ``-DNRF21540EK_FEM=y`` when you invoke ``west build`` or ``cmake`` in your sample directory. -Follow the instructions in :ref:`cmake_options`. -For example: -``west build -b nrf5340dk_nrf5340_cpunet -- -DNRF21540EK_FEM=y`` - -When you set ``NRF21540EK_FEM=y`` the :file:`dts-nrf21540-fem.overlay` devicetree overlay file is used to override the default settings. -The configuration from this file is merged with the additional development kit overlay file from the :file:`boards` folder if it exists. - -The :file:`dts-nrf21540-fem.overlay` is located in the |fem_file_path| folder. -Make sure that the GPIOs and the SPI configuration in the file correspond to those in which your front-end module is connected. +To add support for the nRF21540 FEM, build the sample for a board containing nRF21540 FEM like :ref:`nrf21540dk_nrf52840 ` or create a devicetree overlay file describing how FEM is connected to nRF5 SoC in your device. .. note:: - You must set ``NRF21540EK_FEM=y`` if you use the nRF21540 EK. + If you use the nRF21540 EK, append ``nrf21540_ek`` shield to your build command instructing build system to append the appropriate devicetree overlay file. If you use the nRF21540 DK, build your application for the :ref:`nrf21540dk_nrf52840 ` board. The devicetree for the nRF21540 DK already contains the required FEM configuration, so you do not need to set an additional build option. -Sometimes, you may need to add an extra overlay file. -The easiest way to add the file when building is to set it in the ``DTC_OVERLAY_FILE`` variable. -However, that will override the default settings. -When you set the ``DTC_OVERLAY_FILE`` variable, you must specify all overlay files that are needed for building. - -Follow the instructions in :ref:`cmake_options` to specify the ``DTC_OVERLAY_FILE`` variable. For example, to build the sample from the command line for an nRF5340 DK with an attached nRF21540 EK, invoke the following command within the sample directory: -``west build -b nrf5340dk_nrf5340_cpunet -- -DDTC_OVERLAY_FILE="boards/nrf5340dk_nrf5340_cpunet.overlay;../configuration/dts-nrf21540-fem.overlay;your_overlay_file.overlay"`` - -See :ref:`zephyr:set-devicetree-overlays` for different ways of adding the overlay file. - -Alternatively, you can copy the contents of :file:`dts-nrf21540-fem.overlay` to the board's overlay file. +``west build -b nrf5340dk_nrf5340_cpunet -- -DSHIELD=nrf21540_ek`` .. note:: The nRF5340 DK network core peripherals, like UART and SPI, share an ID and a base address. diff --git a/doc/nrf/includes/sample_fem_support.txt b/doc/nrf/includes/sample_fem_support.txt index b0cf4d8a2c96..4ff47a3a9ec1 100644 --- a/doc/nrf/includes/sample_fem_support.txt +++ b/doc/nrf/includes/sample_fem_support.txt @@ -5,17 +5,19 @@ You can add support for the nRF21540 front-end module to the sample. See :ref:`ug_radio_fem` for more information. -To add support for the nRF21540 FEM, build the sample for a board containing nRF21540 FEM like nrf21540dk_nrf52840 or create a devicetree overlay file describing how FEM is connected to nRF5 SoC in your device. +To add support for the nRF21540 FEM, the devicetree must contain the description of the nRF21540 FEM. +To include this description in your application, use one of the following options, depending on your hardware: -See :ref:`zephyr:set-devicetree-overlays` for different ways of adding the overlay file. +* Build the sample for one board that contains the nRF21540 FEM, such as :ref:`nrf21540dk_nrf52840 `. +* Manually create a devicetree overlay file that describes how FEM is connected to the nRF5 SoC in your device. + See :ref:`zephyr:set-devicetree-overlays` for different ways of adding the overlay file. +* Provide nRF21540 FEM capabilities by using a :ref:`shield `, for example the :ref:`ug_radio_fem_nrf21540_ek` shield that is available in the |NCS|. + In this case, build the project for a board connected to the shield you are using with an appropriate variable included in the build command. + This variable instructs the build system to append the appropriate devicetree overlay file. + For example, to build the sample from the command line for an nRF52833 DK with the nRF21540 EK attached, use the following command within the sample directory: -.. note:: - If you use the nRF21540 EK, append ``nrf21540_ek`` shield to your build command instructing build system to append the appropriate devicetree overlay file. - -For example, to build the sample from the command line for an nRF52833 DK with an attached nRF21540 EK, invoke the following command within the sample directory: - -.. code-block:: console + .. code-block:: console - west build -b nrf52833dk_nrf52833 -- -DSHIELD=nrf21540_ek + west build -b nrf52833dk_nrf52833 -- -DSHIELD=nrf21540_ek -To add support for other front-end modules, add the respective devicetree file entries to the board devicetree file or a devicetree overlay file. +To add support for other front-end modules, add the respective devicetree file entries to the board devicetree file or the devicetree overlay file. diff --git a/samples/bluetooth/direct_test_mode/CMakeLists.txt b/samples/bluetooth/direct_test_mode/CMakeLists.txt index 62b3bf81f0b3..c111f5ae28e4 100644 --- a/samples/bluetooth/direct_test_mode/CMakeLists.txt +++ b/samples/bluetooth/direct_test_mode/CMakeLists.txt @@ -5,19 +5,6 @@ # cmake_minimum_required(VERSION 3.8) -option(NRF21540EK_FEM "Enable support for the nRF21540-EK FEM." OFF) - -if(NRF21540EK_FEM) - set(DTC_OVERLAY_FILE - "${CMAKE_CURRENT_SOURCE_DIR}/configuration/dts-nrf21540-fem.overlay" - CACHE STRING "" FORCE) - - if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.overlay") - set(DTC_OVERLAY_FILE "${DTC_OVERLAY_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.overlay" - CACHE STRING "" FORCE) - endif() -endif() - find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(NONE) diff --git a/samples/bluetooth/direct_test_mode/README.rst b/samples/bluetooth/direct_test_mode/README.rst index 041397750e89..85035e3d84c0 100644 --- a/samples/bluetooth/direct_test_mode/README.rst +++ b/samples/bluetooth/direct_test_mode/README.rst @@ -122,8 +122,6 @@ In other words, for the first antenna, antenna pin 1 is active, for the second a nRF21540 front-end module ========================= -.. |fem_file_path| replace:: :file:`samples/bluetooth/direct_test_mode/configuration` - .. include:: /includes/sample_dtm_radio_test_fem.txt You can configure the transmitted power gain and activation delay in nRF21540 using vendor-specific commands, see `Vendor-specific packet payload`_. diff --git a/samples/bluetooth/direct_test_mode/configuration/dts-nrf21540-fem.overlay b/samples/bluetooth/direct_test_mode/configuration/dts-nrf21540-fem.overlay deleted file mode 100644 index f22bae3d2468..000000000000 --- a/samples/bluetooth/direct_test_mode/configuration/dts-nrf21540-fem.overlay +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - - / { - nrf_radio_fem: nrf21540_fem { - compatible = "nordic,nrf21540-fem"; - tx-en-gpios = <&arduino_header 11 GPIO_ACTIVE_HIGH>; /* D5 */ - rx-en-gpios = <&arduino_header 9 GPIO_ACTIVE_HIGH>; /* D3 */ - pdn-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */ - ant-sel-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 */ - mode-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ - spi-if = <&nrf_radio_fem_spi>; - }; -}; - -fem_spi: &arduino_spi { - status = "okay"; - cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ - - nrf_radio_fem_spi: nrf21540_fem_spi@0 { - compatible = "nordic,nrf21540-fem-spi"; - status = "okay"; - reg = <0>; - label = "FEM_SPI_IF"; - spi-max-frequency = <8000000>; - }; -}; diff --git a/samples/peripheral/radio_test/CMakeLists.txt b/samples/peripheral/radio_test/CMakeLists.txt index 6762a2d9667e..4cae49f86525 100644 --- a/samples/peripheral/radio_test/CMakeLists.txt +++ b/samples/peripheral/radio_test/CMakeLists.txt @@ -6,19 +6,6 @@ cmake_minimum_required(VERSION 3.13.1) -option(NRF21540EK_FEM "Enable support for the nRF21540-EK FEM." OFF) - -if(NRF21540EK_FEM) - set(DTC_OVERLAY_FILE - "${CMAKE_CURRENT_SOURCE_DIR}/configuration/dts-nrf21540-fem.overlay" - CACHE STRING "" FORCE) - - if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.overlay") - set(DTC_OVERLAY_FILE "${DTC_OVERLAY_FILE} ${CMAKE_CURRENT_SOURCE_DIR}/boards/${BOARD}.overlay" - CACHE STRING "" FORCE) - endif() -endif() - find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(NONE) diff --git a/samples/peripheral/radio_test/README.rst b/samples/peripheral/radio_test/README.rst index 4b149e930cde..f7a5bb793d56 100644 --- a/samples/peripheral/radio_test/README.rst +++ b/samples/peripheral/radio_test/README.rst @@ -59,8 +59,6 @@ The sample also requires one of the following testing devices: nRF21540 front-end module ========================= -.. |fem_file_path| replace:: :file:`samples/peripheral/radio_test/configuration` - .. include:: /includes/sample_dtm_radio_test_fem.txt The nRF21540 transmitted power gain, antenna and an activation delay can be configured using the user interface :ref:`radio_test_ui`. diff --git a/samples/peripheral/radio_test/configuration/dts-nrf21540-fem.overlay b/samples/peripheral/radio_test/configuration/dts-nrf21540-fem.overlay deleted file mode 100644 index f22bae3d2468..000000000000 --- a/samples/peripheral/radio_test/configuration/dts-nrf21540-fem.overlay +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021 Nordic Semiconductor ASA - * - * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause - */ - - / { - nrf_radio_fem: nrf21540_fem { - compatible = "nordic,nrf21540-fem"; - tx-en-gpios = <&arduino_header 11 GPIO_ACTIVE_HIGH>; /* D5 */ - rx-en-gpios = <&arduino_header 9 GPIO_ACTIVE_HIGH>; /* D3 */ - pdn-gpios = <&arduino_header 15 GPIO_ACTIVE_HIGH>; /* D9 */ - ant-sel-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 */ - mode-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ - spi-if = <&nrf_radio_fem_spi>; - }; -}; - -fem_spi: &arduino_spi { - status = "okay"; - cs-gpios = <&arduino_header 16 GPIO_ACTIVE_LOW>; /* D10 */ - - nrf_radio_fem_spi: nrf21540_fem_spi@0 { - compatible = "nordic,nrf21540-fem-spi"; - status = "okay"; - reg = <0>; - label = "FEM_SPI_IF"; - spi-max-frequency = <8000000>; - }; -}; From 0708e9759faa9a871e074fd47a8da5ec19d3fad0 Mon Sep 17 00:00:00 2001 From: Wille Backman Date: Tue, 17 Aug 2021 09:59:58 +0300 Subject: [PATCH 122/126] doc: add registered trademark to Bluetooth mentions Add several registered trademark symbols to the documentation. This is to align with the official Bluetooth branding guidelines. Also some small text fixes to the affected files. JIRA: https://projecttools.nordicsemi.no/jira/browse/NCSDK-10721 Signed-off-by: Wille Backman --- applications/connectivity_bridge/README.rst | 4 +-- applications/machine_learning/README.rst | 6 ++-- .../matter_weather_station/README.rst | 2 +- applications/nrf_desktop/README.rst | 8 +++--- applications/nrf_desktop/doc/ble_adv.rst | 2 +- applications/nrf_desktop/doc/ble_bond.rst | 2 +- .../nrf_desktop/doc/ble_conn_params.rst | 6 ++-- .../nrf_desktop/doc/ble_discovery.rst | 2 +- applications/nrf_desktop/doc/ble_latency.rst | 2 +- applications/nrf_desktop/doc/ble_qos.rst | 2 +- applications/nrf_desktop/doc/ble_scan.rst | 2 +- applications/nrf_desktop/doc/ble_state.rst | 2 +- .../nrf_desktop/doc/config_channel.rst | 6 ++-- applications/nrf_desktop/doc/hfclk_lock.rst | 2 +- applications/nrf_desktop/doc/hid_forward.rst | 2 +- applications/nrf_desktop/doc/hid_state.rst | 2 +- applications/nrf_desktop/doc/hids.rst | 4 +-- applications/nrf_desktop/doc/led_state.rst | 4 +-- applications/nrf_desktop/doc/led_stream.rst | 2 +- applications/nrf_desktop/doc/motion.rst | 2 +- applications/nrf_desktop/doc/qos.rst | 4 +-- .../nrf_desktop/doc/settings_loader.rst | 2 +- applications/nrf_desktop/doc/smp.rst | 4 +-- applications/nrf_desktop/doc/usb_state.rst | 4 +-- doc/nrf/app_bootloaders.rst | 2 +- doc/nrf/app_memory.rst | 2 +- doc/nrf/glossary.rst | 4 +-- doc/nrf/index.rst | 2 +- doc/nrf/known_issues.rst | 28 +++++++++---------- .../libraries/bluetooth_services/conn_ctx.rst | 2 +- .../libraries/bluetooth_services/enocean.rst | 2 +- .../libraries/bluetooth_services/gatt_dm.rst | 2 +- .../bluetooth_services/gatt_pool.rst | 2 +- .../libraries/bluetooth_services/index.rst | 4 +-- doc/nrf/libraries/bluetooth_services/mesh.rst | 4 +-- .../bluetooth_services/mesh/dk_prov.rst | 2 +- .../bluetooth_services/mesh/gen_prop_srv.rst | 2 +- .../bluetooth_services/mesh/light_ctl_srv.rst | 2 +- .../mesh/light_ctrl_srv.rst | 2 +- .../bluetooth_services/mesh/light_hsl.rst | 2 +- .../bluetooth_services/mesh/model_types.rst | 2 +- .../bluetooth_services/mesh/properties.rst | 2 +- .../bluetooth_services/mesh/sensor.rst | 4 +-- .../bluetooth_services/mesh/time_tai.rst | 2 +- doc/nrf/libraries/bluetooth_services/rpc.rst | 2 +- doc/nrf/libraries/bluetooth_services/scan.rst | 2 +- .../services/ancs_client.rst | 2 +- .../bluetooth_services/services/bms.rst | 2 +- .../bluetooth_services/services/gadgets.rst | 2 +- .../bluetooth_services/services/hids.rst | 2 +- .../bluetooth_services/services/nus.rst | 2 +- doc/nrf/libraries/caf/ble_adv.rst | 2 +- doc/nrf/libraries/caf/ble_smp.rst | 2 +- doc/nrf/libraries/caf/ble_state.rst | 2 +- doc/nrf/libraries/nfc/ndef/ch_msg.rst | 2 +- doc/nrf/libraries/nfc/ndef/le_oob_rec.rst | 2 +- .../libraries/nfc/ndef/le_oob_rec_parser.rst | 2 +- doc/nrf/libraries/shell/shell_bt_nus.rst | 2 +- doc/nrf/releases/release-notes-changelog.rst | 2 +- doc/nrf/templates/sample_README.rst | 4 +-- doc/nrf/ug_ble_controller.rst | 4 +-- doc/nrf/ug_bt_mesh.rst | 4 +-- doc/nrf/ug_bt_mesh_architecture.rst | 2 +- doc/nrf/ug_bt_mesh_concepts.rst | 4 +-- doc/nrf/ug_bt_mesh_configuring.rst | 2 +- doc/nrf/ug_bt_mesh_model_config_app.rst | 2 +- doc/nrf/ug_bt_mesh_reserved_ids.rst | 4 +-- doc/nrf/ug_bt_mesh_supported_features.rst | 2 +- doc/nrf/ug_bt_mesh_vendor_model.rst | 2 +- .../ug_bt_mesh_vendor_model_dev_overview.rst | 4 +-- doc/nrf/ug_matter.rst | 2 +- doc/nrf/ug_matter_architecture.rst | 2 +- doc/nrf/ug_matter_configuring.rst | 2 +- doc/nrf/ug_multiprotocol_support.rst | 2 +- doc/nrf/ug_nfc.rst | 2 +- doc/nrf/ug_nrf52.rst | 2 +- doc/nrf/ug_nrf5340.rst | 2 +- doc/nrf/ug_thingy91.rst | 2 +- doc/nrf/ug_thread.rst | 2 +- doc/nrf/ug_thread_architectures.rst | 2 +- doc/nrf/ug_thread_certification.rst | 2 +- doc/nrf/ug_thread_supported_features.rst | 2 +- doc/nrf/ug_zigbee_architectures.rst | 2 +- samples/bluetooth/alexa_gadget/README.rst | 2 +- samples/bluetooth/central_bas/README.rst | 2 +- samples/bluetooth/central_hids/README.rst | 2 +- samples/bluetooth/central_hr_coded/README.rst | 2 +- .../bluetooth/central_nfc_pairing/README.rst | 2 +- .../bluetooth/central_smp_client/README.rst | 4 +-- samples/bluetooth/central_uart/README.rst | 2 +- samples/bluetooth/direct_test_mode/README.rst | 4 +-- .../README.rst | 2 +- .../README.rst | 2 +- samples/bluetooth/enocean/README.rst | 2 +- samples/bluetooth/hci_lpuart/README.rst | 2 +- samples/bluetooth/llpm/README.rst | 4 +-- samples/bluetooth/mesh/chat/README.rst | 2 +- samples/bluetooth/mesh/light/README.rst | 2 +- samples/bluetooth/mesh/light_ctrl/README.rst | 2 +- .../bluetooth/mesh/light_switch/README.rst | 2 +- .../bluetooth/mesh/sensor_client/README.rst | 2 +- .../bluetooth/mesh/sensor_server/README.rst | 2 +- .../bluetooth/mesh/silvair_enocean/README.rst | 2 +- .../peripheral_ancs_client/README.rst | 2 +- samples/bluetooth/peripheral_bms/README.rst | 2 +- .../peripheral_cts_client/README.rst | 2 +- .../peripheral_hids_keyboard/README.rst | 2 +- .../peripheral_hids_mouse/README.rst | 2 +- .../bluetooth/peripheral_hr_coded/README.rst | 2 +- samples/bluetooth/peripheral_lbs/README.rst | 2 +- .../peripheral_nfc_pairing/README.rst | 2 +- samples/bluetooth/peripheral_uart/README.rst | 2 +- samples/bluetooth/rpc_host/README.rst | 2 +- samples/bluetooth/shell_bt_nus/README.rst | 2 +- samples/bluetooth/throughput/README.rst | 4 +-- samples/bootloader/README.rst | 2 +- samples/debug/ppi_trace/README.rst | 2 +- samples/matter/light_bulb/README.rst | 2 +- samples/matter/light_switch/README.rst | 2 +- samples/matter/lock/README.rst | 4 +-- samples/matter/template/README.rst | 2 +- .../nrf5340/multiprotocol_rpmsg/README.rst | 2 +- samples/nrf5340/netboot/README.rst | 2 +- samples/nrf9160/agps/README.rst | 2 +- samples/nrf9160/lte_ble_gateway/README.rst | 2 +- samples/openthread/cli/README.rst | 2 +- samples/openthread/coap_client/README.rst | 2 +- samples/zigbee/light_switch/README.rst | 2 +- scripts/hid_configurator/README.rst | 2 +- scripts/shell/ble_console/README.rst | 2 +- 130 files changed, 173 insertions(+), 173 deletions(-) diff --git a/applications/connectivity_bridge/README.rst b/applications/connectivity_bridge/README.rst index be407a433fbb..fc6813ff9327 100644 --- a/applications/connectivity_bridge/README.rst +++ b/applications/connectivity_bridge/README.rst @@ -9,7 +9,7 @@ Connectivity bridge The Connectivity bridge application demonstrates the bridge functionality for the Thingy:91 hardware. -Additionally, the application also provides an option of adding the bluetooth functionality by making use of the :ref:`nus_service_readme`. +Additionally, the application also provides an option of adding the Bluetooth® functionality by making use of the :ref:`nus_service_readme`. Overview ******** @@ -32,7 +32,7 @@ See :ref:`thingy91_serialports` for information on the baud rate configuration f The application adds the functionality of a USB Mass Storage device, which contains several utility files such as a :file:`README.txt` file. -The application also provides a Bluetooth LE UART Service, which can be enabled by the option ``CONFIG_BRIDGE_BLE_ENABLE``. +The application also provides a Bluetooth® LE UART Service, which can be enabled by the option ``CONFIG_BRIDGE_BLE_ENABLE``. This service can be used for a wireless connection to one of the UART interfaces in the following way: .. list-table:: diff --git a/applications/machine_learning/README.rst b/applications/machine_learning/README.rst index 1965280b584c..73b12f390395 100644 --- a/applications/machine_learning/README.rst +++ b/applications/machine_learning/README.rst @@ -89,7 +89,7 @@ The figure visualizes relations between Event Manager, modules, drivers, and lib Since the application architecture is uniform and the code is shared, the set of modules in use depends on configuration. In other words, not all of the modules need to be enabled for a given reference design. -For example, the :ref:`caf_ble_state` and :ref:`caf_ble_adv` modules are not enabled if the configuration does not use Bluetooth. +For example, the :ref:`caf_ble_state` and :ref:`caf_ble_adv` modules are not enabled if the configuration does not use Bluetooth®. See :ref:`nrf_machine_learning_app_internal_modules` for detailed information about every module used by the nRF Machine Learning application. @@ -348,10 +348,10 @@ After programming the application, perform the following steps to test the nRF M After the mode is switched, the LED color changes to red and the LED starts blinking very slowly. #. Program the :ref:`central_uart` sample to a compatible development kit, for example the nRF52840 Development Kit. Turn on the programmed device. - After a brief delay the Bluetooth connection between the sample and the Thingy:52 is established. + After a brief delay the Bluetooth® connection between the sample and the Thingy:52 is established. The Thingy:52 forwards the sensor readouts over NUS. The LED on the Thingy:52 starts to blink rapidly. -#. Connect to the Bluetooth Central UART sample with a terminal emulator (for example, PuTTY). +#. Connect to the Bluetooth® Central UART sample with a terminal emulator (for example, PuTTY). See :ref:`putty` for the required settings. #. Observe the sensor readouts represented as comma-separated values. Every line represents a single sensor readout. diff --git a/applications/matter_weather_station/README.rst b/applications/matter_weather_station/README.rst index 40a09ec5dac6..545f3d968130 100644 --- a/applications/matter_weather_station/README.rst +++ b/applications/matter_weather_station/README.rst @@ -42,7 +42,7 @@ The measurement results are stored in the device memory and can be read using th The controller communicates with the weather station device over the Matter protocol using Zigbee Cluster Library (ZCL). The library describes data measurements within the proper clusters that correspond to the measurement type. -The application uses MCUboot secure bootloader and SMP protocol for performing over-the-air Device Firmware Upgrade using Bluetooth LE. +The application uses MCUboot secure bootloader and SMP protocol for performing over-the-air Device Firmware Upgrade using Bluetooth® LE. For information about how to upgrade the device firmware using a PC or a mobile, see the :ref:`matter_weather_station_app_dfu` section. .. _matter_weather_station_network_mode: diff --git a/applications/nrf_desktop/README.rst b/applications/nrf_desktop/README.rst index 6462c0a0daaf..7d1b8050f25a 100644 --- a/applications/nrf_desktop/README.rst +++ b/applications/nrf_desktop/README.rst @@ -7,7 +7,7 @@ nRF Desktop :local: :depth: 2 -The nRF Desktop is a reference design of a Human Interface Device (HID) that is connected to a host through Bluetooth LE or USB, or both. +The nRF Desktop is a reference design of a Human Interface Device (HID) that is connected to a host through Bluetooth® Low Energy or USB, or both. Depending on the configuration, this application can work as desktop mouse, gaming mouse, keyboard, or connection dongle. .. tip:: @@ -145,11 +145,11 @@ The following threads are kept running in the application: * System workqueue thread * Logger thread (on debug :ref:`build types `) * Shell thread (on :ref:`build types ` with shell enabled) - * Threads related to Bluetooth LE (the exact number depends on the selected Link Layer) + * Threads related to Bluetooth® LE (the exact number depends on the selected Link Layer) * Application-related threads * Motion sensor thread (running only on mouse) * Settings loading thread (enabled by default only on keyboard) - * QoS data sampling thread (running only if Bluetooth LE QoS feature is enabled) + * QoS data sampling thread (running only if Bluetooth® LE QoS feature is enabled) Most of the application activity takes place in the context of the system work queue thread, either through scheduled work objects or through the event manager callbacks (executed from the system workqueue thread). Because of this, the application does not need to handle resource protection. @@ -414,7 +414,7 @@ When it is connected through USB, charging of the rechargeable batteries starts. Dongle USB ~~~~~~~~~~ -The nRF Desktop dongle works as a bridge between the devices connected through standard Bluetooth LE or Low Latency Packet Mode and the host connected through USB. +The nRF Desktop dongle works as a bridge between the devices connected through standard Bluetooth® Low Energy or Low Latency Packet Mode and the host connected through USB. It receives data wirelessly from the connected peripherals and forwards the data to the host. The nRF Desktop dongle is powered directly through USB. diff --git a/applications/nrf_desktop/doc/ble_adv.rst b/applications/nrf_desktop/doc/ble_adv.rst index 67f89c928a39..106a6e8033e5 100644 --- a/applications/nrf_desktop/doc/ble_adv.rst +++ b/applications/nrf_desktop/doc/ble_adv.rst @@ -37,4 +37,4 @@ The nRF Desktop dongle scans for peripheral devices using the Bluetooth device n -.. |ble_adv| replace:: Bluetooth LE advertising module +.. |ble_adv| replace:: Bluetooth® LE advertising module diff --git a/applications/nrf_desktop/doc/ble_bond.rst b/applications/nrf_desktop/doc/ble_bond.rst index f7a130c39b46..90455711c341 100644 --- a/applications/nrf_desktop/doc/ble_bond.rst +++ b/applications/nrf_desktop/doc/ble_bond.rst @@ -235,4 +235,4 @@ The module uses Zephyr's :ref:`zephyr:settings_api` subsystem to store the follo * Currently selected peer (application local identity) * Mapping between the application local identities and the Bluetooth local identities -.. |ble_bond| replace:: Bluetooth LE bond module +.. |ble_bond| replace:: Bluetooth® LE bond module diff --git a/applications/nrf_desktop/doc/ble_conn_params.rst b/applications/nrf_desktop/doc/ble_conn_params.rst index c6beb4dd9589..1789f27c4cd2 100644 --- a/applications/nrf_desktop/doc/ble_conn_params.rst +++ b/applications/nrf_desktop/doc/ble_conn_params.rst @@ -43,8 +43,8 @@ LLPM connections The Low Latency Packet Mode (LLPM) connection parameters are not supported by the standard Bluetooth. -The LLPM connection parameters update requires using Vendor Sprecific HCI commands. -Moreover, the peripheral cannot request the LLPM connection parameters using Zephyr Bluetooth API. +The LLPM connection parameters update requires using vendor-specific HCI commands. +Moreover, the peripheral cannot request the LLPM connection parameters using Zephyr Bluetooth® API. Connection interval update ========================== @@ -59,4 +59,4 @@ After the :ref:`nrf_desktop_ble_discovery` completes the peripheral discovery, t * **10 ms** otherwise. This is required to avoid Bluetooth Link Layer scheduling conflicts that could lead to HID report rate drop. -.. |ble_conn_params| replace:: Bluetooth LE connection parameters module +.. |ble_conn_params| replace:: Bluetooth® LE connection parameters module diff --git a/applications/nrf_desktop/doc/ble_discovery.rst b/applications/nrf_desktop/doc/ble_discovery.rst index d05f25f220e2..dd198e7ef115 100644 --- a/applications/nrf_desktop/doc/ble_discovery.rst +++ b/applications/nrf_desktop/doc/ble_discovery.rst @@ -88,4 +88,4 @@ The same actions are taken if the peripheral's VID and PID value combination is The nRF Desktop central works only with predefined subset of peripherals. The mentioned peripherals must be described in the :file:`ble_discovery_def.h` file. -.. |ble_discovery| replace:: Bluetooth LE discovery module +.. |ble_discovery| replace:: Bluetooth® LE discovery module diff --git a/applications/nrf_desktop/doc/ble_latency.rst b/applications/nrf_desktop/doc/ble_latency.rst index f7bba14d68e6..28ac045bf12b 100644 --- a/applications/nrf_desktop/doc/ble_latency.rst +++ b/applications/nrf_desktop/doc/ble_latency.rst @@ -71,4 +71,4 @@ The module does not register itself using the ``GEN_CONFIG_EVENT_HANDLERS`` macr For more detailed information, see the :ref:`nrf_desktop_ble_conn_params` documentation page. -.. |ble_latency| replace:: Bluetooth LE latency module +.. |ble_latency| replace:: Bluetooth® LE latency module diff --git a/applications/nrf_desktop/doc/ble_qos.rst b/applications/nrf_desktop/doc/ble_qos.rst index 69322df79823..a79c978e3e0b 100644 --- a/applications/nrf_desktop/doc/ble_qos.rst +++ b/applications/nrf_desktop/doc/ble_qos.rst @@ -7,7 +7,7 @@ Bluetooth LE Quality of Service module :local: :depth: 2 -Use the Bluetooth LE Quality of Service (QoS) module to achieve better connection quality and higher report rate by avoiding congested RF channels. +Use the Bluetooth® LE Quality of Service (QoS) module to achieve better connection quality and higher report rate by avoiding congested RF channels. The module can be used by both nRF Desktop peripheral and nRF Desktop central with the SoftDevice Link Layer (:kconfig:`CONFIG_BT_LL_SOFTDEVICE`). However, only the Bluetooth central can update the Bluetooth LE channel map that is in use. diff --git a/applications/nrf_desktop/doc/ble_scan.rst b/applications/nrf_desktop/doc/ble_scan.rst index fe0cf37208e3..32728abf5595 100644 --- a/applications/nrf_desktop/doc/ble_scan.rst +++ b/applications/nrf_desktop/doc/ble_scan.rst @@ -140,4 +140,4 @@ a. The scanning is stopped and the |NCS|'s :ref:`nrf_bt_scan_readme` automatical At this point, the scanning can be restarted. -.. |ble_scan| replace:: Bluetooth LE scanning module +.. |ble_scan| replace:: Bluetooth® LE scanning module diff --git a/applications/nrf_desktop/doc/ble_state.rst b/applications/nrf_desktop/doc/ble_state.rst index 67f8aaa3aafb..9144a88713cf 100644 --- a/applications/nrf_desktop/doc/ble_state.rst +++ b/applications/nrf_desktop/doc/ble_state.rst @@ -7,7 +7,7 @@ Bluetooth LE state module :local: :depth: 2 -In nRF Desktop, the Bluetooth LE state module is responsible for the following actions: +In nRF Desktop, the Bluetooth® LE state module is responsible for the following actions: * Enabling Bluetooth (:c:func:`bt_enable`). * Handling Zephyr connection callbacks (:c:struct:`bt_conn_cb`). diff --git a/applications/nrf_desktop/doc/config_channel.rst b/applications/nrf_desktop/doc/config_channel.rst index 4714a0a4dcd3..855a138ff080 100644 --- a/applications/nrf_desktop/doc/config_channel.rst +++ b/applications/nrf_desktop/doc/config_channel.rst @@ -22,7 +22,7 @@ Behavior The HID feature reports are used for transporting information between the host and the connected embedded device. The cross-platform `HIDAPI library`_ is used for exchanging the reports. -The library supports both Bluetooth LE and USB. +The library supports both Bluetooth® Low Energy and USB. The host computer can set configuration values of the embedded device. It can also request fetching a value, for example in order to display it to the user. @@ -46,7 +46,7 @@ Fetching a configuration value Host<` only and requires the :ref:`nrf_desktop_ble_qos` to be enabled. diff --git a/applications/nrf_desktop/doc/settings_loader.rst b/applications/nrf_desktop/doc/settings_loader.rst index 0d89d12a5a06..80b1716d8900 100644 --- a/applications/nrf_desktop/doc/settings_loader.rst +++ b/applications/nrf_desktop/doc/settings_loader.rst @@ -25,7 +25,7 @@ Configuration The settings loader module is enabled for every nRF Desktop device with Zephyr's :ref:`zephyr:settings_api` enabled. The :ref:`zephyr:settings_api` subsystem is enabled with the :kconfig:`CONFIG_SETTINGS` Kconfig option. -Zephyr's Bluetooth stack does not load the :ref:`zephyr:settings_api` data on its own. +Zephyr's Bluetooth® stack does not load the :ref:`zephyr:settings_api` data on its own. Zephyr assumes that the application will call :c:func:`settings_load` after completing all necessary initialization. This function is called on the settings loader module initialization. diff --git a/applications/nrf_desktop/doc/smp.rst b/applications/nrf_desktop/doc/smp.rst index cbc4df55fb82..b001e8e73b3b 100644 --- a/applications/nrf_desktop/doc/smp.rst +++ b/applications/nrf_desktop/doc/smp.rst @@ -8,10 +8,10 @@ Simple Management Protocol module :local: :depth: 2 -The |smp| is responsible for performing a Device Firmware Upgrade (DFU) over Bluetooth LE. +The |smp| is responsible for performing a Device Firmware Upgrade (DFU) over Bluetooth® LE. You can perform the DFU using for example the `nRF Connect for Mobile`_ application. -The :guilabel:`DFU` button appears in the tab with the connected Bluetooth devices. +The :guilabel:`DFU` button appears in the tab with the connected Bluetooth® devices. After pressing the button, you can select the :file:`*.bin` file that is to be used for the firmware update. Module events diff --git a/applications/nrf_desktop/doc/usb_state.rst b/applications/nrf_desktop/doc/usb_state.rst index d6786045eba7..790732e704b3 100644 --- a/applications/nrf_desktop/doc/usb_state.rst +++ b/applications/nrf_desktop/doc/usb_state.rst @@ -54,8 +54,8 @@ USB device instance configuration The nRF Desktop device can provide multiple instances of a HID-class USB device. The number of instances is controlled by :kconfig:`CONFIG_USB_HID_DEVICE_COUNT`. -* The Bluetooth Peripheral device will be able to use a single instance only. -* The Bluetooth Central device can use either a single instance or a number of instances equal to :kconfig:`CONFIG_BT_MAX_PAIRED`. +* The Bluetooth® Peripheral device will be able to use a single instance only. +* The Bluetooth® Central device can use either a single instance or a number of instances equal to :kconfig:`CONFIG_BT_MAX_PAIRED`. On the Bluetooth Central device, if only one instance is used, reports from all Peripherals connected to the Central are forwarded to the same instance. In other cases, reports from each of the bonded peripherals will be forwarded to a dedicated HID-class USB device instance. diff --git a/doc/nrf/app_bootloaders.rst b/doc/nrf/app_bootloaders.rst index 892a4e83da80..b22780afba5a 100644 --- a/doc/nrf/app_bootloaders.rst +++ b/doc/nrf/app_bootloaders.rst @@ -20,7 +20,7 @@ The bootloaders support two types of updates: You can deliver the updated images to the device in two ways: * Wired - where updates are sent through a wired connection, like UART, or delivered by connecting a flash device. -* Over-the-air (OTA) - where updates are sent through a wireless connection, like Bluetooth LE. +* Over-the-air (OTA) - where updates are sent through a wireless connection, like Bluetooth® Low Energy. You can use a second-stage bootloader only in combination with a first-stage one. Also, not all bootloaders supported by the |NCS| can be used as either first-stage or second-stage ones. diff --git a/doc/nrf/app_memory.rst b/doc/nrf/app_memory.rst index dea79c53ea3e..cbe22720fd7e 100644 --- a/doc/nrf/app_memory.rst +++ b/doc/nrf/app_memory.rst @@ -25,7 +25,7 @@ The following subsections give more information on how to optimize specific subs Bluetooth ********* -Complete the following actions to optimize the Bluetooth part of your application: +Complete the following actions to optimize the Bluetooth® part of your application: * Disable features that your application does not use. For example, disable the following features: diff --git a/doc/nrf/glossary.rst b/doc/nrf/glossary.rst index 2f601dddfe48..1e51a4433586 100644 --- a/doc/nrf/glossary.rst +++ b/doc/nrf/glossary.rst @@ -32,10 +32,10 @@ Glossary "[It] allows a device referred to as the server to expose a set of attributes and their associated values to a peer device referred to as the client." `Bluetooth Core Specification`_, Version 5.3, Vol 3, Part F, Section 1.1. - Bluetooth LE Controller layer + Bluetooth® LE Controller layer A layer of the Bluetooth LE protocol stack that implements the Link Layer (LL). - Bluetooth LE Host layer + Bluetooth® LE Host layer A layer of the Bluetooth LE protocol stack comprised of multiple (non real-time) network and transport protocols enabling applications to communicate with peer devices in a standard and interoperable way. Board diff --git a/doc/nrf/index.rst b/doc/nrf/index.rst index 3066cbd8e52b..1f44db21989b 100644 --- a/doc/nrf/index.rst +++ b/doc/nrf/index.rst @@ -5,7 +5,7 @@ Welcome to the |NCS|! The |NCS| is where you begin building low power wireless applications with Nordic Semiconductor nRF52, nRF53, and nRF91 Series devices. -The SDK contains optimized cellular IoT (LTE-M and NB-IoT), Bluetooth Low Energy, Thread, Zigbee, and Bluetooth mesh stacks, a range of applications, samples, and reference implementations, as well as a full suite of drivers for Nordic Semiconductor's devices. +The SDK contains optimized cellular IoT (LTE-M and NB-IoT), Bluetooth® Low Energy, Thread, Zigbee, and Bluetooth mesh stacks, a range of applications, samples, and reference implementations, as well as a full suite of drivers for Nordic Semiconductor's devices. The |NCS| includes the Zephyr™ real-time operating system (RTOS), which is built for connected low power products. .. note:: diff --git a/doc/nrf/known_issues.rst b/doc/nrf/known_issues.rst index c0bfb72735fc..842ae9897b5e 100644 --- a/doc/nrf/known_issues.rst +++ b/doc/nrf/known_issues.rst @@ -492,14 +492,14 @@ Matter (Project CHIP) .. rst-class:: v1-6-1 v1-6-0 KRKNWK-10589: Android CHIPTool crashes when commissioning a Matter device - In random circumstances, Android CHIPTool crashes when trying to connect to a Matter device over Bluetooth LE. + In random circumstances, Android CHIPTool crashes when trying to connect to a Matter device over Bluetooth® LE. **Workaround** Restart the application and try to commission the Matter device again. If the problem persists, clear the application data and try again. .. rst-class:: v1-6-1 v1-6-0 -KRKNWK-10387: Matter service is needlessly advertised over Bluetooth LE during DFU +KRKNWK-10387: Matter service is needlessly advertised over Bluetooth® LE during DFU The Matter samples can be configured to include the support for Device Firmware Upgrade (DFU) over Bluetooth LE. When the DFU procedure is started, the Matter Bluetooth LE service is needlessly advertised, revealing the device identifiers such as Vendor and Product IDs. The service is meant to be advertised only during the device commissioning. @@ -546,7 +546,7 @@ DESK-978: Directed advertising issues with SoftDevice Link Layer .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 v1-2-1 v1-2-0 v1-1-0 v1-0-0 -NCSDK-8304: HID configurator issues for peripherals connected over Bluetooth LE to Linux host +NCSDK-8304: HID configurator issues for peripherals connected over Bluetooth® LE to Linux host Using :ref:`nrf_desktop_config_channel_script` for peripherals connected to host directly over Bluetooth LE may result in receiving improper HID feature report ID. In such case, the device will provide HID input reports, but it cannot be configured with the HID configurator. @@ -575,7 +575,7 @@ NCSDK-9820: The :ref:`peripheral_lbs` - If **Button 1** is pushed and released w .. rst-class:: v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 v1-2-1 v1-2-0 v1-1-0 v1-0-0 -NCSDK-9106: Bluetooth ECC thread stack size too small +NCSDK-9106: Bluetooth® ECC thread stack size too small The Bluetooth ECC thread used during the pairing procedure with LE Secure Connections might overflow when an interrupt is triggered when the stack usage is at its maximum. **Workaround:** Increase the ECC stack size by setting :kconfig:`CONFIG_BT_HCI_ECC_STACK_SIZE` to ``1140``. @@ -640,14 +640,14 @@ NCSDK-5711: High-throughput transmission can deadlock the receive thread .. rst-class:: v1-2-1 v1-2-0 -Only secure applications can use Bluetooth LE +Only secure applications can use Bluetooth® LE Bluetooth LE cannot be used in a non-secure application, for example, an application built for the ``nrf5340_dk_nrf5340_cpuappns`` build target. **Workaround:** Use the ``nrf5340_dk_nrf5340_cpuapp`` build target instead. .. rst-class:: v1-2-1 v1-2-0 -Peripheral HIDS keyboard sample cannot be used with nRF Bluetooth LE Controller +Peripheral HIDS keyboard sample cannot be used with nRF Bluetooth® LE Controller The :ref:`peripheral_hids_keyboard` sample cannot be used with the :ref:`nrfxlib:softdevice_controller` because the NFC subsystem does not work with the controller library. The library uses the MPSL Clock driver, which does not provide an API for asynchronous clock operation. NFC requires this API to work correctly. @@ -655,7 +655,7 @@ Peripheral HIDS keyboard sample cannot be used with nRF Bluetooth LE Controller .. rst-class:: v1-2-1 v1-2-0 Peripheral HIDS mouse sample advertising issues - When the :ref:`peripheral_hids_mouse` sample is used with the Zephyr Bluetooth LE Controller, directed advertising does not time out and the regular advertising cannot be started. + When the :ref:`peripheral_hids_mouse` sample is used with the Zephyr Bluetooth® LE Controller, directed advertising does not time out and the regular advertising cannot be started. .. rst-class:: v1-2-1 v1-2-0 @@ -665,7 +665,7 @@ Central HIDS sample issues with directed advertising .. rst-class:: v1-1-0 Unstable samples - Bluetooth Low Energy peripheral samples are unstable in some conditions (when pairing and bonding are performed and then disconnections/re-connections happen). + Bluetooth® Low Energy peripheral samples are unstable in some conditions (when pairing and bonding are performed and then disconnections/re-connections happen). .. rst-class:: v1-2-1 v1-2-0 v1-1-0 @@ -686,13 +686,13 @@ Reconnection issues on some operating systems .. rst-class:: v1-0-0 :ref:`bluetooth_central_hids` loses UART connectivity - After programming a HEX file to the nrf52_pca10040 board, UART connectivity is lost when using the Bluetooth LE Controller. + After programming a HEX file to the nrf52_pca10040 board, UART connectivity is lost when using the Bluetooth® LE Controller. The board must be reset to get UART output. .. rst-class:: v1-1-0 v1-0-0 Samples crashing on nRF51 when using GPIO - On nRF51 devices, Bluetooth LE samples that use GPIO might crash when buttons are pressed frequently. + On nRF51 devices, Bluetooth® LE samples that use GPIO might crash when buttons are pressed frequently. In such case, the GPIO ISR introduces latency that violates real-time requirements of the Radio ISR. nRF51 is more sensitive to this issue than nRF52 (faster core). @@ -704,7 +704,7 @@ GATT Discovery Manager missing support .. rst-class:: v0-4-0 Samples do not work with SD Controller v0.1.0 - Bluetooth LE samples cannot be built with the :ref:`nrfxlib:softdevice_controller` v0.1.0. + Bluetooth® LE samples cannot be built with the :ref:`nrfxlib:softdevice_controller` v0.1.0. .. rst-class:: v1-0-0 v0-4-0 v0-3-0 @@ -733,12 +733,12 @@ Bluetooth mesh .. rst-class:: v1-6-1 v1-6-0 v1-5-1 v1-5-0 v1-4-2 v1-4-1 v1-4-0 v1-3-2 v1-3-1 v1-3-0 NCSDK-5580: nRF5340 only supports SoftDevice Controller - On nRF5340, only the :ref:`nrfxlib:softdevice_controller` is supported for Bluetooth mesh. + On nRF5340, only the :ref:`nrfxlib:softdevice_controller` is supported for Bluetooth® mesh. .. rst-class:: v1-6-1 v1-6-0 NCSDK-10200: The device stops sending Secure Network Beacons after re-provisioning - Bluetooth mesh stops sending Secure Network Beacons if the device is re-provisioned after reset through Config Node Reset message or ``bt_mesh_reset()`` call. + Bluetooth® mesh stops sending Secure Network Beacons if the device is re-provisioned after reset through Config Node Reset message or ``bt_mesh_reset()`` call. **Workaround:** Reboot the device after re-provisioning. @@ -1094,7 +1094,7 @@ SoftDevice Controller DRGN-15852: In rare cases on nRF53 Series devices, an assert can occur while scanning This only occurs when the host started scanning using HCI LE Set Scan Enable. - This is default configuration of the Bluetooth host. + This is default configuration of the Bluetooth® host. **Workaround:** Use extended scanning commands. That is, set :kconfig:`CONFIG_BT_EXT_ADV` to use HCI LE Set Extended Scan Enable instead. diff --git a/doc/nrf/libraries/bluetooth_services/conn_ctx.rst b/doc/nrf/libraries/bluetooth_services/conn_ctx.rst index b81d68f4b58f..febb8d3346d4 100644 --- a/doc/nrf/libraries/bluetooth_services/conn_ctx.rst +++ b/doc/nrf/libraries/bluetooth_services/conn_ctx.rst @@ -7,7 +7,7 @@ Bluetooth connection context :local: :depth: 2 -Data related to a Bluetooth connection can be stored in a Bluetooth connection context. +Data related to a Bluetooth® connection can be stored in a Bluetooth® connection context. The Bluetooth connection context library can be used with Bluetooth LE services that require the connection context to support multilink functionality for the GATT server role. Each instance of the library can store the contexts for a configurable number of Bluetooth connections (see :ref:`zephyr:bluetooth_connection_mgmt` in the Zephyr documentation). diff --git a/doc/nrf/libraries/bluetooth_services/enocean.rst b/doc/nrf/libraries/bluetooth_services/enocean.rst index 88c4ad199879..84aeda8642d5 100644 --- a/doc/nrf/libraries/bluetooth_services/enocean.rst +++ b/doc/nrf/libraries/bluetooth_services/enocean.rst @@ -7,7 +7,7 @@ Bluetooth EnOcean :local: :depth: 2 -The Bluetooth EnOcean library allows passive observation of wall switches and sensors based on Bluetooth LE from `EnOcean`_, such as wall switches based on the Push Button Transmitter module (PTM 215B) and the Easyfit Motion Detector with Illumination (EMDCB) sensor module. +The Bluetooth® EnOcean library allows passive observation of wall switches and sensors based on Bluetooth LE from `EnOcean`_, such as wall switches based on the Push Button Transmitter module (PTM 215B) and the Easyfit Motion Detector with Illumination (EMDCB) sensor module. The library is only capable of observing the output of the devices, and does not send anything back. NFC-based configuration is not supported. diff --git a/doc/nrf/libraries/bluetooth_services/gatt_dm.rst b/doc/nrf/libraries/bluetooth_services/gatt_dm.rst index 8d0f135714cf..ced9bd0c1c1e 100644 --- a/doc/nrf/libraries/bluetooth_services/gatt_dm.rst +++ b/doc/nrf/libraries/bluetooth_services/gatt_dm.rst @@ -10,7 +10,7 @@ GATT Discovery Manager The GATT Discovery Manager handles service discovery on GATT servers. When a client connects to a peer device that has a desired server, service discovery is necessary to ensure that the client interacts with the server's characteristics using the correct attributes handles. -Service discovery is also important because Bluetooth LE advertising does not mandate that all services are advertised. +Service discovery is also important because Bluetooth® LE advertising does not mandate that all services are advertised. To actually know if a service is present on a peer device, you must perform a service discovery. The GATT Discovery Manager simplifies the usage of :ref:`Zephyr `'s :c:func:`bt_gatt_discover` function by processing the data using predefined filters. diff --git a/doc/nrf/libraries/bluetooth_services/gatt_pool.rst b/doc/nrf/libraries/bluetooth_services/gatt_pool.rst index 3cba0d3a5f91..0efe1e5f39c4 100644 --- a/doc/nrf/libraries/bluetooth_services/gatt_pool.rst +++ b/doc/nrf/libraries/bluetooth_services/gatt_pool.rst @@ -21,7 +21,7 @@ The API of the GATT attribute pools module allows to register different types of After each registration, a part of the memory is reserved for each attribute. You can also unregister attributes that are no longer needed by using the module's API. In this case, the previously reserved memory is released. -This can be useful when you want to restructure your service by using the Service Changed feature that is supported by the Zephyr Bluetooth stack (see, for example, the :ref:`hids_readme`). +This can be useful when you want to restructure your service by using the Service Changed feature that is supported by the Zephyr Bluetooth® stack (see, for example, the :ref:`hids_readme`). Additionally, you can adjust the memory footprint of this module to your needs by changing the configuration options for the size of the module's memory pool. If you are unsure about the proper values, print the module's statistics to see how the pool utilization level is affected by the chosen configuration. diff --git a/doc/nrf/libraries/bluetooth_services/index.rst b/doc/nrf/libraries/bluetooth_services/index.rst index a0d39fe2b635..eec0e296902b 100644 --- a/doc/nrf/libraries/bluetooth_services/index.rst +++ b/doc/nrf/libraries/bluetooth_services/index.rst @@ -5,7 +5,7 @@ Bluetooth libraries and services .. toctree:: :maxdepth: 1 - :caption: Bluetooth libraries: + :caption: Bluetooth® libraries: :glob: * @@ -13,7 +13,7 @@ Bluetooth libraries and services .. toctree:: :maxdepth: 1 - :caption: Bluetooth services: + :caption: Bluetooth® services: :glob: services/* diff --git a/doc/nrf/libraries/bluetooth_services/mesh.rst b/doc/nrf/libraries/bluetooth_services/mesh.rst index ce2ac3031dfa..89a2f649be6a 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh.rst @@ -3,10 +3,10 @@ Bluetooth mesh profile ###################### -Bluetooth mesh is supported for development in |NCS|, through the Zephyr :ref:`zephyr:bluetooth_mesh` implementation. +Bluetooth® mesh is supported for development in |NCS|, through the Zephyr :ref:`zephyr:bluetooth_mesh` implementation. Nordic Semiconductor's implementation of the Bluetooth mesh allows applications to use the features provided by the Bluetooth mesh when running on supported Nordic devices. -The `Bluetooth mesh profile specification`_ is developed and published by the Bluetooth SIG. +The `Bluetooth mesh profile specification`_ is developed and published by the Bluetooth® Special Interest Group (SIG). It's a solution that allows one-to-one, one-to-many, and many-to-many communication, using the Bluetooth Low Energy protocol to exchange messages between the nodes in the network. The nodes can communicate with each other as long as they are in direct radio range of each other, or there are enough devices available that are capable of listening and forwarding these messages. See the :ref:`Bluetooth mesh user guide ` for an overview of the technology, like supported features, concepts and architecture. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst b/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst index b7c987e58f37..281431a3338b 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/dk_prov.rst @@ -9,7 +9,7 @@ Bluetooth mesh provisioning handler for Nordic DKs This application-side module is a basic implementation of the provisioning process handling for Development Kits from Nordic Semiconductor. It supports four types of out-of-band (OOB) authentication methods and uses the Hardware Information driver to generate a deterministic UUID to uniquely represent the device. -For more information about provisioning in Bluetooth mesh, see the :ref:`zephyr:bluetooth_mesh_provisioning` page in Zephyr. +For more information about provisioning in Bluetooth® mesh, see the :ref:`zephyr:bluetooth_mesh_provisioning` page in Zephyr. Used primarily in :ref:`Bluetooth mesh sample applications `, this handler acts as a reference implementation for the application-specific part of provisioning. It is enabled with the :kconfig:`CONFIG_BT_MESH_DK_PROV` option and by calling :c:func:`bt_mesh_dk_prov_init` in main. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst index 97eba2d9c0da..bf1f77c04a28 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/gen_prop_srv.rst @@ -52,7 +52,7 @@ Extended models Generic Admin Property Server and Generic Manufacturer Property Server should both extend the Generic User Property Server. This is not handled automatically by the model implementation. -For this reason, to ensure compliance with the Bluetooth mesh model specification, a Generic User Property Server must be instantiated in the same element in the device composition data as the Generic Admin or Generic Manufacturer Property Server. +For this reason, to ensure compliance with the Bluetooth® mesh model specification, a Generic User Property Server must be instantiated in the same element in the device composition data as the Generic Admin or Generic Manufacturer Property Server. Persistent storage ================== diff --git a/doc/nrf/libraries/bluetooth_services/mesh/light_ctl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctl_srv.rst index 522f18d7c801..629489c61ed7 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/light_ctl_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_ctl_srv.rst @@ -51,7 +51,7 @@ The Lightness and Light Temperature Server callbacks will pass pointers to :c:me .. note:: The Light CTL Server will verify that its internal Light Temperature Server is instantiated on a subsequent element on startup. - If the Light Temperature Server is missing or instantiated on the same or a preceding element, the Bluetooth mesh startup procedure will fail, and the device will not be responsive. + If the Light Temperature Server is missing or instantiated on the same or a preceding element, the Bluetooth® mesh startup procedure will fail, and the device will not be responsive. States ====== diff --git a/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst index 249b5b584ee5..207fd5477004 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_ctrl_srv.rst @@ -132,7 +132,7 @@ To avoid having a Lightness Server running independently forever, the Light LC S The resume timer can be configured with the :kconfig:`CONFIG_BT_MESH_LIGHT_CTRL_SRV_RESUME_DELAY` option, and is disabled by default. .. note:: - The resume timer does not exist in the Bluetooth mesh specification, and may become incompatible with future specification changes. + The resume timer does not exist in the Bluetooth® mesh specification, and may become incompatible with future specification changes. Although it does not break the specification or qualification tests in the current iteration of the Bluetooth mesh specification, its behavior may be unexpected for third party devices, and should be used with caution. State machine outputs diff --git a/doc/nrf/libraries/bluetooth_services/mesh/light_hsl.rst b/doc/nrf/libraries/bluetooth_services/mesh/light_hsl.rst index 1e42291546a1..4d048c166507 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/light_hsl.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/light_hsl.rst @@ -13,7 +13,7 @@ While easy to visualize and explain to end users, the HSL does not map well to c The HSL models are best suited for applications where the color of the light is a primary function, such as decorative lighting. For applications where illumination is the primary function of the light, and its color and temperature is secondary, the CTL and xyL models might be better alternatives. -However, neither the Bluetooth mesh model specification nor the nRF Connect SDK put any restrictions on the application areas for the different models. +However, neither the Bluetooth® mesh model specification nor the nRF Connect SDK put any restrictions on the application areas for the different models. Developers may freely use the model best suited for their application. On the light fixture side, the HSL Server models are separated into three independent models: diff --git a/doc/nrf/libraries/bluetooth_services/mesh/model_types.rst b/doc/nrf/libraries/bluetooth_services/mesh/model_types.rst index 7793ad6bc4eb..b4e749905592 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/model_types.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/model_types.rst @@ -7,7 +7,7 @@ Bluetooth mesh models overview :local: :depth: 2 -A Bluetooth mesh model is a standardized component that defines a series of states and related behaviors. +A Bluetooth® mesh model is a standardized component that defines a series of states and related behaviors. Models encapsulate a single feature of a mesh node, and expose this feature to the mesh network. Each mesh-based product implements several models. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/properties.rst b/doc/nrf/libraries/bluetooth_services/mesh/properties.rst index 4843e852fb8e..956b469d7449 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/properties.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/properties.rst @@ -7,7 +7,7 @@ Bluetooth mesh properties :local: :depth: 2 -The Bluetooth SIG defines a list of Bluetooth mesh properties in the Bluetooth mesh device properties specification. +The Bluetooth® Special Interest Group (SIG) defines a list of Bluetooth mesh properties in the Bluetooth mesh device properties specification. Each property has an assigned ID and an associated Bluetooth GATT characteristic. The properties all represent values on a format defined by the associated characteristic. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst b/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst index ea83edaf92e7..2689d6e8885d 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/sensor.rst @@ -7,7 +7,7 @@ Bluetooth mesh sensors :local: :depth: 2 -The Bluetooth mesh specification provides a common scheme for representing all sensors. +The Bluetooth® mesh specification provides a common scheme for representing all sensors. A single Bluetooth mesh sensor instance represents a single physical sensor, and a mesh device may present any number of sensors to the network through a Sensor Server model. Sensors represent their measurements as a list of sensor channels, as described by the sensor's assigned type. @@ -60,7 +60,7 @@ Each sensor type is assigned its own Device Property ID, as specified in the Blu Like the Device Properties, the Sensor types are connected to a Bluetooth GATT Characteristic, which describes the unit, range, resolution and encoding scheme of the sensor type. .. note:: - The Bluetooth mesh specification only allows sensor types that have a Device Property ID in the Bluetooth mesh device properties specification. + The Bluetooth® mesh specification only allows sensor types that have a Device Property ID in the Bluetooth mesh device properties specification. It's not possible to represent vendor specific sensor values. The sensor types may either be used as the data types of the sensor output values, or as configuration parameters for the sensors. diff --git a/doc/nrf/libraries/bluetooth_services/mesh/time_tai.rst b/doc/nrf/libraries/bluetooth_services/mesh/time_tai.rst index 16adc0546510..2e6efb4ec019 100644 --- a/doc/nrf/libraries/bluetooth_services/mesh/time_tai.rst +++ b/doc/nrf/libraries/bluetooth_services/mesh/time_tai.rst @@ -18,5 +18,5 @@ This allows applications to calculate the number of seconds between any two TAI To convert to UTC, TAI based applications keep track of the UTC leap seconds separately, as well as the time zone and time zone adjustments. -The Bluetooth mesh Time models share time as a composite state of TAI seconds, 256 subseconds, UTC offset, time zone steps and uncertainty. +The Bluetooth® mesh Time models share time as a composite state of TAI seconds, 256 subseconds, UTC offset, time zone steps and uncertainty. See :cpp:type:`bt_mesh_time_status` for details. diff --git a/doc/nrf/libraries/bluetooth_services/rpc.rst b/doc/nrf/libraries/bluetooth_services/rpc.rst index 1b5ade1253fa..06b102987620 100644 --- a/doc/nrf/libraries/bluetooth_services/rpc.rst +++ b/doc/nrf/libraries/bluetooth_services/rpc.rst @@ -7,7 +7,7 @@ Bluetooth Low Energy Remote Procedure Call :local: :depth: 2 -The nRF Connect SDK supports Bluetooth Low Energy (LE) stack serialization. +The nRF Connect SDK supports Bluetooth® Low Energy (LE) stack serialization. The full Bluetooth LE stack can run on another device or CPU, such as the nRF5340 DK network core using :ref:`nrfxlib:nrf_rpc`. .. note:: diff --git a/doc/nrf/libraries/bluetooth_services/scan.rst b/doc/nrf/libraries/bluetooth_services/scan.rst index 990071592cb0..8c6ad645b60f 100644 --- a/doc/nrf/libraries/bluetooth_services/scan.rst +++ b/doc/nrf/libraries/bluetooth_services/scan.rst @@ -7,7 +7,7 @@ Scanning module :local: :depth: 2 -The scanning module handles the Bluetooth Low Energy scanning for your application. +The scanning module handles the Bluetooth® Low Energy scanning for your application. You can use it to find advertising devices and establish connections with them. Using :ref:`filters `, you can narrow down the scan to devices of a specific type. diff --git a/doc/nrf/libraries/bluetooth_services/services/ancs_client.rst b/doc/nrf/libraries/bluetooth_services/services/ancs_client.rst index 0194a4884e30..c99b84d9a40e 100644 --- a/doc/nrf/libraries/bluetooth_services/services/ancs_client.rst +++ b/doc/nrf/libraries/bluetooth_services/services/ancs_client.rst @@ -21,7 +21,7 @@ The term "notification" is used in two different meanings: * An iOS notification is the data received from the Notification Provider. -* A GATT notification is a way to transfer data with Bluetooth Low Energy. +* A GATT notification is a way to transfer data with Bluetooth® Low Energy. In this module, iOS notifications are received through the GATT notifications. The full term (iOS notification or GATT notification) is used where required to avoid confusion. diff --git a/doc/nrf/libraries/bluetooth_services/services/bms.rst b/doc/nrf/libraries/bluetooth_services/services/bms.rst index a7763b2f48b5..52fc157404e3 100644 --- a/doc/nrf/libraries/bluetooth_services/services/bms.rst +++ b/doc/nrf/libraries/bluetooth_services/services/bms.rst @@ -32,7 +32,7 @@ You can set this callback when initializing the module. Deleting the bonds ****************** -The Server deletes bonding information on Client's request right away when there is no active Bluetooth LE connection associated with a bond. +The Server deletes bonding information on Client's request right away when there is no active Bluetooth® LE connection associated with a bond. Otherwise, the Server removes the bond for a given peer when it disconnects. API documentation diff --git a/doc/nrf/libraries/bluetooth_services/services/gadgets.rst b/doc/nrf/libraries/bluetooth_services/services/gadgets.rst index eedb2ce58f47..fe31a6c72a4b 100644 --- a/doc/nrf/libraries/bluetooth_services/services/gadgets.rst +++ b/doc/nrf/libraries/bluetooth_services/services/gadgets.rst @@ -7,7 +7,7 @@ Alexa Gadgets Service :local: :depth: 2 -The Bluetooth LE GATT Alexa Gadgets Service is a custom service that manages Alexa Gadgets stream transactions. +The Bluetooth® LE GATT Alexa Gadgets Service is a custom service that manages Alexa Gadgets stream transactions. For details about the stream format, see Alexa Gadgets Bluetooth LE Packet `Alexa Gadgets Bluetooth LE Packet Format`_. The Alexa Gadgets Service is used in the :ref:`peripheral_alexa_gadgets` sample. diff --git a/doc/nrf/libraries/bluetooth_services/services/hids.rst b/doc/nrf/libraries/bluetooth_services/services/hids.rst index dc36b9696ce3..ce383c13394b 100644 --- a/doc/nrf/libraries/bluetooth_services/services/hids.rst +++ b/doc/nrf/libraries/bluetooth_services/services/hids.rst @@ -10,7 +10,7 @@ GATT Human Interface Device (HID) Service This module implements the Human Interface Device Service with the corresponding set of characteristics. When initialized, it adds the HID Service and a set of characteristics, according to the HID Service specification and to the user -requirements, to the Zephyr Bluetooth stack database. +requirements, to the Zephyr Bluetooth® stack database. If enabled, notification of Input Report characteristics is performed when the application calls the corresponding :c:func:`bt_hids_inp_rep_send` function. diff --git a/doc/nrf/libraries/bluetooth_services/services/nus.rst b/doc/nrf/libraries/bluetooth_services/services/nus.rst index fbc4a99420d3..a71e1244e97f 100644 --- a/doc/nrf/libraries/bluetooth_services/services/nus.rst +++ b/doc/nrf/libraries/bluetooth_services/services/nus.rst @@ -7,7 +7,7 @@ Nordic UART Service (NUS) :local: :depth: 2 -The Bluetooth LE GATT Nordic UART Service is a custom service that receives and writes data and serves as a bridge to the UART interface. +The Bluetooth® LE GATT Nordic UART Service is a custom service that receives and writes data and serves as a bridge to the UART interface. The NUS Service is used in the :ref:`peripheral_uart` sample. diff --git a/doc/nrf/libraries/caf/ble_adv.rst b/doc/nrf/libraries/caf/ble_adv.rst index 72f51334b6e5..b3add384c761 100644 --- a/doc/nrf/libraries/caf/ble_adv.rst +++ b/doc/nrf/libraries/caf/ble_adv.rst @@ -139,4 +139,4 @@ Avoiding connection requests from unbonded centrals when bonded If :kconfig:`CONFIG_BT_WHITELIST` is enabled and Bluetooth local identity that is in use already has a bond, the device will whitelist incoming scan response data requests and connection requests. This is done to prevent Bluetooth Centrals other than the bonded one from connecting with the device. -.. |ble_adv| replace:: Bluetooth LE advertising module +.. |ble_adv| replace:: Bluetooth® LE advertising module diff --git a/doc/nrf/libraries/caf/ble_smp.rst b/doc/nrf/libraries/caf/ble_smp.rst index 040a7ddb88bb..c707bdb6a9ff 100644 --- a/doc/nrf/libraries/caf/ble_smp.rst +++ b/doc/nrf/libraries/caf/ble_smp.rst @@ -7,7 +7,7 @@ CAF: Simple Management Protocol module :local: :depth: 2 -The |smp| of the :ref:`lib_caf` (CAF) allows to perform the device firmware upgrade (DFU) over Bluetooth LE. +The |smp| of the :ref:`lib_caf` (CAF) allows to perform the device firmware upgrade (DFU) over Bluetooth® LE. Configuration ************* diff --git a/doc/nrf/libraries/caf/ble_state.rst b/doc/nrf/libraries/caf/ble_state.rst index d31b29e604e8..de8dfe680dda 100644 --- a/doc/nrf/libraries/caf/ble_state.rst +++ b/doc/nrf/libraries/caf/ble_state.rst @@ -93,4 +93,4 @@ If the SoftDevice Link Layer is selected, the |ble_state| also sets the TX power The TX power is set according to Zephyr's Kconfig options related to selecting the default TX power. This is necessary because the mentioned Kconfig options are not automatically applied by the Bluetooth stack if the SoftDevice Link Layer is selected. -.. |ble_state| replace:: Bluetooth LE state module +.. |ble_state| replace:: Bluetooth® LE state module diff --git a/doc/nrf/libraries/nfc/ndef/ch_msg.rst b/doc/nrf/libraries/nfc/ndef/ch_msg.rst index 4ac67937e018..44a4aac6598b 100644 --- a/doc/nrf/libraries/nfc/ndef/ch_msg.rst +++ b/doc/nrf/libraries/nfc/ndef/ch_msg.rst @@ -8,7 +8,7 @@ Connection Handover messages and records :depth: 2 Connection Handover records and the corresponding messages are used to negotiate and activate an alternative communication carrier. -The negotiated communication carrier can then be used to perform certain activities between the two devices, such as Bluetooth pairing. +The negotiated communication carrier can then be used to perform certain activities between the two devices, such as Bluetooth® pairing. Connection Handover records *************************** diff --git a/doc/nrf/libraries/nfc/ndef/le_oob_rec.rst b/doc/nrf/libraries/nfc/ndef/le_oob_rec.rst index cafb38629290..d9d076064cb0 100644 --- a/doc/nrf/libraries/nfc/ndef/le_oob_rec.rst +++ b/doc/nrf/libraries/nfc/ndef/le_oob_rec.rst @@ -7,7 +7,7 @@ Bluetooth LE OOB records :local: :depth: 2 -A Bluetooth LE device that has an NFC interface (a tag or a polling device) can use NFC to send or receive data required for connecting and pairing in the Bluetooth domain. +A Bluetooth® LE device that has an NFC interface (a tag or a polling device) can use NFC to send or receive data required for connecting and pairing in the Bluetooth domain. This data should be presented in the form of a Bluetooth LE pairing message. A Bluetooth LE pairing message that works with Android devices contains one Bluetooth LE OOB record. diff --git a/doc/nrf/libraries/nfc/ndef/le_oob_rec_parser.rst b/doc/nrf/libraries/nfc/ndef/le_oob_rec_parser.rst index 2274da4c367c..6a9d0d3dc2d8 100644 --- a/doc/nrf/libraries/nfc/ndef/le_oob_rec_parser.rst +++ b/doc/nrf/libraries/nfc/ndef/le_oob_rec_parser.rst @@ -7,7 +7,7 @@ Parser for Bluetooth LE OOB records :local: :depth: 2 -This library provides a parser for Bluetooth LE OOB records that can be used to decode NDEF records generated by the :ref:`nfc_ndef_le_oob` library. +This library provides a parser for Bluetooth® LE OOB records that can be used to decode NDEF records generated by the :ref:`nfc_ndef_le_oob` library. The output of this library is a descriptor with the same content as the one that would be used to encode the data with the :ref:`nfc_ndef_le_oob` library. This library should be used together with the :ref:`nfc_ndef_parser_readme` in the following way: diff --git a/doc/nrf/libraries/shell/shell_bt_nus.rst b/doc/nrf/libraries/shell/shell_bt_nus.rst index 08717f2c846e..9ce3221c3ba7 100644 --- a/doc/nrf/libraries/shell/shell_bt_nus.rst +++ b/doc/nrf/libraries/shell/shell_bt_nus.rst @@ -7,7 +7,7 @@ Nordic UART Service (NUS) shell transport :local: :depth: 2 -The Bluetooth LE GATT Nordic UART Service shell transport allows you to receive shell commands remotely over *Bluetooth*. +The Bluetooth® LE GATT Nordic UART Service shell transport allows you to receive shell commands remotely over *Bluetooth*. It uses the :ref:`nus_service_readme`. The NUS Service shell transport is used in the :ref:`shell_bt_nus` sample. diff --git a/doc/nrf/releases/release-notes-changelog.rst b/doc/nrf/releases/release-notes-changelog.rst index b2a5d6d4ed14..48a6a1f9485c 100644 --- a/doc/nrf/releases/release-notes-changelog.rst +++ b/doc/nrf/releases/release-notes-changelog.rst @@ -86,7 +86,7 @@ Bluetooth LE * Updated: - * :ref:`ble_samples` - Changed the Bluetooth sample Central DFU SMP name to :ref:`Central SMP Client `. + * :ref:`ble_samples` - Changed the Bluetooth® sample Central DFU SMP name to :ref:`Central SMP Client `. Matter ------ diff --git a/doc/nrf/templates/sample_README.rst b/doc/nrf/templates/sample_README.rst index ad8b11ea2fd9..532e7aee606f 100644 --- a/doc/nrf/templates/sample_README.rst +++ b/doc/nrf/templates/sample_README.rst @@ -148,7 +148,7 @@ Additional configuration* Check and configure the following library options that are used by the sample: -* :kconfig:`CONFIG_BT_DEVICE_NAME` - Defines the Bluetooth device name. +* :kconfig:`CONFIG_BT_DEVICE_NAME` - Defines the Bluetooth® device name. * :kconfig:`CONFIG_BT_LBS` - Enables the :ref:`lbs_readme`. Configuration files* @@ -226,7 +226,7 @@ If the LEDs do not start blinking, check if the music is loud enough. References* *********** -* Music chapter in the Bluetooth Spec (-> always link) +* Music chapter in the Bluetooth® Spec (-> always link) * Disco ball datasheet .. tip:: diff --git a/doc/nrf/ug_ble_controller.rst b/doc/nrf/ug_ble_controller.rst index 7fb172f1d25e..9058d7907f95 100644 --- a/doc/nrf/ug_ble_controller.rst +++ b/doc/nrf/ug_ble_controller.rst @@ -7,7 +7,7 @@ Bluetooth LE Controller :local: :depth: 2 -When you develop a Bluetooth Low Energy (LE) application, you must include a Bluetooth LE Controller. +When you develop a Bluetooth® Low Energy (LE) application, you must include a Bluetooth® LE Controller. A Bluetooth LE Controller is the layer of the Bluetooth stack that handles the physical layer packets and all associated timing. It implements the Link Layer, which is the low-level, real-time protocol that controls the Bluetooth LE communication. @@ -35,7 +35,7 @@ The SoftDevice Controller is distributed as a set of precompiled, linkable libra There are different variants of the libraries that support different feature sets. Which variant you should choose depends on the chip that you are using, the features that you need, and the amount of available memory. -Nordic's SoftDevice Controller supports an extensive standard feature set from the Bluetooth 5.2 specification and a number of extensions for high-performance applications like Low Latency Packet mode (LLPM). +Nordic's SoftDevice Controller supports an extensive standard feature set from the Bluetooth® 5.2 specification and a number of extensions for high-performance applications like Low Latency Packet mode (LLPM). See the :ref:`SoftDevice Controller documentation ` for a detailed list of supported features. diff --git a/doc/nrf/ug_bt_mesh.rst b/doc/nrf/ug_bt_mesh.rst index c67d48c3f278..4e3d6549d01b 100644 --- a/doc/nrf/ug_bt_mesh.rst +++ b/doc/nrf/ug_bt_mesh.rst @@ -3,10 +3,10 @@ Bluetooth mesh ############## -The |NCS| provides support for developing applications using the Bluetooth mesh protocol. +The |NCS| provides support for developing applications using the Bluetooth® mesh protocol. The support is based on Zephyr's :ref:`bluetooth_mesh` implementation. -The `Bluetooth mesh profile specification`_ is developed and published by the Bluetooth SIG. +The `Bluetooth mesh profile specification`_ is developed and published by the Bluetooth® Special Interest Group (SIG). It allows one-to-one, one-to-many, and many-to-many communication, using the Bluetooth LE protocol to exchange messages between the nodes on the network. All nodes in a Bluetooth mesh network can communicate with each other, as long as there's a chain of nodes between them to relay the messages. The messages are encrypted with two layers of 128-bit AES-CCM encryption, allowing secure communication between thousands of devices. diff --git a/doc/nrf/ug_bt_mesh_architecture.rst b/doc/nrf/ug_bt_mesh_architecture.rst index 6493fc7d51c1..562cf4021db7 100644 --- a/doc/nrf/ug_bt_mesh_architecture.rst +++ b/doc/nrf/ug_bt_mesh_architecture.rst @@ -7,7 +7,7 @@ Bluetooth mesh stack architecture :local: :depth: 2 -The Bluetooth mesh stack in |NCS| is an extension of the Zephyr Bluetooth mesh stack. +The Bluetooth® mesh stack in |NCS| is an extension of the Zephyr Bluetooth® mesh stack. The Zephyr Bluetooth mesh stack implements the Bluetooth mesh profile specification (see :ref:`zephyr:bluetooth_mesh`), while |NCS| provides additional model implementations from the Bluetooth mesh model specification on top of the :ref:`zephyr:bluetooth_mesh_access` API. .. figure:: /images/bt_mesh_basic_architecture.svg diff --git a/doc/nrf/ug_bt_mesh_concepts.rst b/doc/nrf/ug_bt_mesh_concepts.rst index cbb354bad5d5..5ea53cd25a4c 100644 --- a/doc/nrf/ug_bt_mesh_concepts.rst +++ b/doc/nrf/ug_bt_mesh_concepts.rst @@ -7,11 +7,11 @@ Bluetooth mesh concepts :local: :depth: 2 -Bluetooth mesh is a profile specification developed and published by the Bluetooth Special Interest Group (SIG). +Bluetooth® mesh is a profile specification developed and published by the Bluetooth® Special Interest Group (SIG). This document explains the basic concepts of the Bluetooth mesh and gives an overview of the operation and capabilities of the profile, as well as the life cycle of a mesh device. For more information about the |NCS| implementation of the Bluetooth mesh, see :ref:`Bluetooth mesh architecture documentation `. -The Bluetooth mesh is based on the Bluetooth LE part of the Bluetooth 4.0 Specification, and shares the lowest layers with this protocol. +The Bluetooth mesh is based on the Bluetooth LE part of the Bluetooth® 4.0 Specification, and shares the lowest layers with this protocol. On-air, the Bluetooth mesh physical representation is compatible with existing Bluetooth LE devices, as mesh messages are contained inside the payload of Bluetooth LE *advertisement* packets. However, Bluetooth mesh specifies a completely new host stack, and although some concepts are shared, Bluetooth mesh is incompatible with the Bluetooth Host. diff --git a/doc/nrf/ug_bt_mesh_configuring.rst b/doc/nrf/ug_bt_mesh_configuring.rst index b4c148eaa096..747439eb58c9 100644 --- a/doc/nrf/ug_bt_mesh_configuring.rst +++ b/doc/nrf/ug_bt_mesh_configuring.rst @@ -7,7 +7,7 @@ Configuring Bluetooth mesh in |NCS| :local: :depth: 2 -The Bluetooth mesh support is controlled by :kconfig:`CONFIG_BT_MESH`, which depends on the following configuration options: +The Bluetooth® mesh support is controlled by :kconfig:`CONFIG_BT_MESH`, which depends on the following configuration options: * :kconfig:`CONFIG_BT` - Enables the Bluetooth subsystem. * :kconfig:`CONFIG_BT_OBSERVER` - Enables the Bluetooth Observer role. diff --git a/doc/nrf/ug_bt_mesh_model_config_app.rst b/doc/nrf/ug_bt_mesh_model_config_app.rst index 3f5e11ed638a..08ba8653f1b6 100644 --- a/doc/nrf/ug_bt_mesh_model_config_app.rst +++ b/doc/nrf/ug_bt_mesh_model_config_app.rst @@ -7,7 +7,7 @@ Configuring mesh models using the nRF Mesh mobile app :local: :depth: 2 -The Bluetooth mesh :ref:`samples ` use the nRF Mesh mobile app to perform provisioning and configuration. +The Bluetooth® mesh :ref:`samples ` use the nRF Mesh mobile app to perform provisioning and configuration. Binding a model to an application key ************************************* diff --git a/doc/nrf/ug_bt_mesh_reserved_ids.rst b/doc/nrf/ug_bt_mesh_reserved_ids.rst index b188cd07aecc..de129645bcf4 100644 --- a/doc/nrf/ug_bt_mesh_reserved_ids.rst +++ b/doc/nrf/ug_bt_mesh_reserved_ids.rst @@ -9,7 +9,7 @@ Reserved vendor model IDs and opcodes This page contains information about vendor model IDs and opcodes allocated by Nordic Semiconductor. -As the Bluetooth SIG member, Nordic Semiconductor has been assigned the Company ID *0x0059*. +As a Bluetooth® Special Interest Group (SIG) member, Nordic Semiconductor has been assigned the Company ID *0x0059*. You can find this information on the `Bluetooth SIG company identifiers`_ page. Reserved vendor model IDs @@ -40,7 +40,7 @@ The table below lists all vendor-assigned model identifiers allocated by Nordic Reserved opcodes **************** -The table below lists the manufactor-specific opcodes allocated by Nordic Semiconductor: +The table below lists the manufacturer-specific opcodes allocated by Nordic Semiconductor: +-----------------------------------+--------+ | Message name | Opcode | diff --git a/doc/nrf/ug_bt_mesh_supported_features.rst b/doc/nrf/ug_bt_mesh_supported_features.rst index e5fe54f9685b..c879f3f55959 100644 --- a/doc/nrf/ug_bt_mesh_supported_features.rst +++ b/doc/nrf/ug_bt_mesh_supported_features.rst @@ -3,7 +3,7 @@ Supported Bluetooth mesh features ################################# -The Bluetooth mesh in |NCS| supports all mandatory features of the `Bluetooth mesh profile specification`_ and the `Bluetooth mesh model specification`_, as well as most of the optional features. +The Bluetooth® mesh in |NCS| supports all mandatory features of the `Bluetooth mesh profile specification`_ and the `Bluetooth mesh model specification`_, as well as most of the optional features. The following features are supported by Zephyr's :ref:`zephyr:bluetooth_mesh`: diff --git a/doc/nrf/ug_bt_mesh_vendor_model.rst b/doc/nrf/ug_bt_mesh_vendor_model.rst index 606bda331093..4800a1d491bf 100644 --- a/doc/nrf/ug_bt_mesh_vendor_model.rst +++ b/doc/nrf/ug_bt_mesh_vendor_model.rst @@ -3,7 +3,7 @@ Creating a new model #################### -You may create your own vendor-specific models for Bluetooth mesh. +You may create your own vendor-specific models for Bluetooth® mesh. These will enable your devices to provide custom behavior not covered by the already defined standard models. The following sections describe the basics of creating new models for the Bluetooth mesh in |NCS|, based on the concepts and principles defined in :ref:`mesh_concepts` and :ref:`Access API `. It is recommended that you have read and understood these concepts and principles, before proceeding with the model development. diff --git a/doc/nrf/ug_bt_mesh_vendor_model_dev_overview.rst b/doc/nrf/ug_bt_mesh_vendor_model_dev_overview.rst index 3f58c1e60473..cdbe992e776e 100644 --- a/doc/nrf/ug_bt_mesh_vendor_model_dev_overview.rst +++ b/doc/nrf/ug_bt_mesh_vendor_model_dev_overview.rst @@ -7,7 +7,7 @@ Vendor model development overview :local: :depth: 2 -To implement a new Bluetooth mesh model, apply the steps described in this step-by-step model development process overview. +To implement a new Bluetooth® mesh model, apply the steps described in this step-by-step model development process overview. Defining a model identifier *************************** @@ -22,7 +22,7 @@ As defined by the `Bluetooth mesh profile specification`_, the vendor model iden #define YOUR_COMPANY_ID 0x1234 #define YOUR_MODEL_ID 0x5678 -The Company ID must be registered with the Bluetooth SIG, and the vendor owning the Company ID may freely allocate the model IDs for its Company ID. +The Company ID must be registered with the Bluetooth® Special Interest Group (SIG), and the vendor owning the Company ID may freely allocate the model IDs for its Company ID. See `Bluetooth SIG company identifiers`_ for a list of Company IDs. Adding the model to the node composition data diff --git a/doc/nrf/ug_matter.rst b/doc/nrf/ug_matter.rst index 1b75e0d3e27b..12f158cb6e45 100644 --- a/doc/nrf/ug_matter.rst +++ b/doc/nrf/ug_matter.rst @@ -11,7 +11,7 @@ Matter (Project CHIP) .. matter_intro_start `Matter`_ (formerly Project Connected Home over IP or Project CHIP) is an open-source application layer that aims at creating a unified communication standard across smart home devices, mobile applications, and cloud services. -It supports a wide range of existing technologies, including Wi-Fi, Thread, and Bluetooth LE, and uses IPv6-based transport protocols like TCP and UDP to ensure connectivity between different kinds of networks. +It supports a wide range of existing technologies, including Wi-Fi, Thread, and Bluetooth® LE, and uses IPv6-based transport protocols like TCP and UDP to ensure connectivity between different kinds of networks. Matter is in an early development stage and must be treated as an experimental feature. diff --git a/doc/nrf/ug_matter_architecture.rst b/doc/nrf/ug_matter_architecture.rst index b7a5dfd26bd1..cbcb8c674561 100644 --- a/doc/nrf/ug_matter_architecture.rst +++ b/doc/nrf/ug_matter_architecture.rst @@ -23,7 +23,7 @@ That is, the code used for the |NCS| and Matter integration is stored in the Mat Both instances depend on each other, but their development is independent to ensure that they both support the latest stable version of one another. Matter is located on the top application layer of the integration model, looking from the networking point of view. -The |NCS| and Zephyr provide the Bluetooth LE and Thread stacks, which must be integrated with the Matter stack using a special intermediate layer. +The |NCS| and Zephyr provide the Bluetooth® LE and Thread stacks, which must be integrated with the Matter stack using a special intermediate layer. The |NCS|'s Multiprotocol Service Layer (MPSL) driver allows running Bluetooth LE and Thread concurrently on the same radio chip. .. figure:: images/matter_nrfconnect_overview_simplified_ncs.svg diff --git a/doc/nrf/ug_matter_configuring.rst b/doc/nrf/ug_matter_configuring.rst index 5970d41724a5..1daf59e77729 100644 --- a/doc/nrf/ug_matter_configuring.rst +++ b/doc/nrf/ug_matter_configuring.rst @@ -15,7 +15,7 @@ To pair and control the Matter accessory device remotely over such a network, yo A Matter controller is a role within the Matter environment. This controller interacts with the accessory devices using the following protocols: -* Bluetooth LE during the commissioning process - to securely pass the network credentials and provision the accessory device into the Thread network. +* Bluetooth® LE during the commissioning process - to securely pass the network credentials and provision the accessory device into the Thread network. * Regular IPv6 communication after the accessory device joins the Thread network - to interact with each other by exchanging application messages. For example, to report temperature measurements of a sensor. diff --git a/doc/nrf/ug_multiprotocol_support.rst b/doc/nrf/ug_multiprotocol_support.rst index 4ec9da3d5095..8b673a54ec3c 100644 --- a/doc/nrf/ug_multiprotocol_support.rst +++ b/doc/nrf/ug_multiprotocol_support.rst @@ -27,7 +27,7 @@ To enable the multiprotocol support for either Thread or Zigbee, set the followi This option activates the :ref:`nrfxlib:softdevice_controller`, which by default supports the multiprotocol features. Disabling the SoftDevice Controller also disables the multiprotocol support. -After enabling this option, the application can start configuring Bluetooth LE's API options alongside Thread's or Zigbee's in the respective :file:`.conf` file. +After enabling this option, the application can start configuring Bluetooth® LE's API options alongside Thread's or Zigbee's in the respective :file:`.conf` file. Multiprotocol limitations in application development **************************************************** diff --git a/doc/nrf/ug_nfc.rst b/doc/nrf/ug_nfc.rst index 635aa53bc2e0..6c97b8003433 100644 --- a/doc/nrf/ug_nfc.rst +++ b/doc/nrf/ug_nfc.rst @@ -8,7 +8,7 @@ Near Field Communication (NFC) :depth: 2 Near Field Communication (NFC) is a technology for wireless transfer of small amounts of data between two devices. -It uses very simple communication protocols and therefore allows quicker connection than Bluetooth Low Energy. +It uses very simple communication protocols and, therefore, allows quicker connection than Bluetooth® Low Energy. However, because NFC uses magnetic induction to enable communication, the devices must be very close (< 10 cm) to connect. The following image gives a simplified overview of how NFC works. diff --git a/doc/nrf/ug_nrf52.rst b/doc/nrf/ug_nrf52.rst index cda6938b6956..4ec67596fb7e 100644 --- a/doc/nrf/ug_nrf52.rst +++ b/doc/nrf/ug_nrf52.rst @@ -15,7 +15,7 @@ Introduction ************ The nRF52 Series of System-on-Chip (SoC) devices embed a powerful yet low-power Arm Cortex-M4 processor with our industry leading 2.4 GHz RF transceivers. -All of the nRF52 Series SoCs have support for Bluetooth 5 features, in addition to multiprotocol capabilities. +All of the nRF52 Series SoCs have support for Bluetooth® 5 features, in addition to multiprotocol capabilities. See `nRF52 Series`_ for the technical documentation on the nRF52 Series chips and associated kits. diff --git a/doc/nrf/ug_nrf5340.rst b/doc/nrf/ug_nrf5340.rst index 70deeacbb6fd..5f82f8b9590d 100644 --- a/doc/nrf/ug_nrf5340.rst +++ b/doc/nrf/ug_nrf5340.rst @@ -115,7 +115,7 @@ Bluetooth Low Energy * - :ref:`ble_rpc_host` (supported for development) - Some Bluetooth Low Energy samples, for example, :ref:`zephyr:bluetooth-beacon-sample` -When using Bluetooth Low Energy on the nRF5340, you have two options: +When using Bluetooth® Low Energy on the nRF5340, you have two options: * Split the Bluetooth LE Controller and the host part of the Bluetooth LE stack and run them on different cores. * Run the full Bluetooth LE stack on the network core (currently supported for development only). diff --git a/doc/nrf/ug_thingy91.rst b/doc/nrf/ug_thingy91.rst index 52ad8d634baa..4199b57abbae 100644 --- a/doc/nrf/ug_thingy91.rst +++ b/doc/nrf/ug_thingy91.rst @@ -14,7 +14,7 @@ Nordic Thingy:91 is a battery-operated prototyping platform for cellular IoT sys Thingy:91 integrates the following components: * nRF9160 SiP - supporting LTE-M, NB-IoT, and Global Positioning System (GPS) -* nRF52840 SoC - supporting Bluetooth Low Energy and Near Field Communication (NFC) +* nRF52840 SoC - supporting Bluetooth® Low Energy and Near Field Communication (NFC) You can find more information on the product in the `Thingy:91 product page`_ and in the `Nordic Thingy:91 User Guide`_. The |NCS| provides support for developing applications on the Thingy:91. diff --git a/doc/nrf/ug_thread.rst b/doc/nrf/ug_thread.rst index 08181d251d0a..ab97e8bd4478 100644 --- a/doc/nrf/ug_thread.rst +++ b/doc/nrf/ug_thread.rst @@ -14,7 +14,7 @@ The OpenThread stack is integrated into Zephyr. .. thread_intro_end -You can use Thread in parallel with Bluetooth Low Energy. +You can use Thread in parallel with Bluetooth® Low Energy. See :ref:`ug_multiprotocol_support` for more information. See :ref:`openthread_samples` for the list of available Thread samples. diff --git a/doc/nrf/ug_thread_architectures.rst b/doc/nrf/ug_thread_architectures.rst index 05319e0ef626..e0a8e24eb917 100644 --- a/doc/nrf/ug_thread_architectures.rst +++ b/doc/nrf/ug_thread_architectures.rst @@ -81,7 +81,7 @@ This platform design is suitable for the following development kits: Single-chip, multiprotocol (SoC) ================================ -nRF52 and nRF53 Series devices support multiple wireless technologies, including IEEE 802.15.4 and Bluetooth Low Energy (Bluetooth LE). +nRF52 and nRF53 Series devices support multiple wireless technologies, including IEEE 802.15.4 and Bluetooth® Low Energy (Bluetooth LE). In a single-chip, multiprotocol design, the application layer and OpenThread run on the same processor. diff --git a/doc/nrf/ug_thread_certification.rst b/doc/nrf/ug_thread_certification.rst index ea36657a36f0..a372ba3e64a8 100644 --- a/doc/nrf/ug_thread_certification.rst +++ b/doc/nrf/ug_thread_certification.rst @@ -72,7 +72,7 @@ Complete the following steps to prepare for the certification tests: .. note:: The configuration option selects the precompiled OpenThread libraries. - The overlay file enables :ref:`multiprotocol support ` with Bluetooth LE advertising. + The overlay file enables :ref:`multiprotocol support ` with Bluetooth® LE advertising. #. Prepare Thread Test Harness. diff --git a/doc/nrf/ug_thread_supported_features.rst b/doc/nrf/ug_thread_supported_features.rst index bef29474f786..14c59d08636d 100644 --- a/doc/nrf/ug_thread_supported_features.rst +++ b/doc/nrf/ug_thread_supported_features.rst @@ -44,4 +44,4 @@ Limitations for Thread 1.2 support The Thread 1.2 Specification support has the following limitation: -* Due to code size limitation, the combination of complete set of Thread 1.2 features with the Bluetooth LE multiprotocol support is not possible for the nRF52833 DKs. +* Due to code size limitation, the combination of complete set of Thread 1.2 features with the Bluetooth® LE multiprotocol support is not possible for the nRF52833 DKs. diff --git a/doc/nrf/ug_zigbee_architectures.rst b/doc/nrf/ug_zigbee_architectures.rst index 6f90c48c68ce..eb6419362966 100644 --- a/doc/nrf/ug_zigbee_architectures.rst +++ b/doc/nrf/ug_zigbee_architectures.rst @@ -59,7 +59,7 @@ This platform design is suitable for the following development kits: Single-chip, multiprotocol (SoC) ================================ -With the nRF devices supporting multiple wireless technologies, including IEEE 802.15.4 and Bluetooth Low Energy (Bluetooth LE), the application layer and the Zigbee and Bluetooth LE stack run on the same chip. +With the nRF devices supporting multiple wireless technologies, including IEEE 802.15.4 and Bluetooth® Low Energy (Bluetooth LE), the application layer and the Zigbee and Bluetooth LE stack run on the same chip. This design has the following advantages: diff --git a/samples/bluetooth/alexa_gadget/README.rst b/samples/bluetooth/alexa_gadget/README.rst index dbb354e19e75..f92233c08450 100644 --- a/samples/bluetooth/alexa_gadget/README.rst +++ b/samples/bluetooth/alexa_gadget/README.rst @@ -7,7 +7,7 @@ Bluetooth: Peripheral Alexa Gadgets :local: :depth: 2 -The Peripheral Alexa Gadgets sample demonstrates how a Bluetooth LE device can connect to an Amazon Echo device using the Alexa Gadgets Bluetooth Service and Profile. +The Peripheral Alexa Gadgets sample demonstrates how a Bluetooth® LE device can connect to an Amazon Echo device using the Alexa Gadgets Bluetooth Service and Profile. Documentation for the Gadgets Service and Profile can be found at `Alexa Gadgets Bluetooth LE`_. diff --git a/samples/bluetooth/central_bas/README.rst b/samples/bluetooth/central_bas/README.rst index 36b69296a95e..d03de34befb7 100644 --- a/samples/bluetooth/central_bas/README.rst +++ b/samples/bluetooth/central_bas/README.rst @@ -28,7 +28,7 @@ The sample supports the following development kits: :header: heading :rows: nrf5340dk_nrf5340_cpuapp_and_cpuappns , nrf52840dk_nrf52840, nrf52840dk_nrf52811, nrf52833dk_nrf52833, nrf52833dk_nrf52820, nrf52dk_nrf52832, nrf52dk_nrf52810 -The sample also requires a device running a BAS Server to connect with (for example, another development kit running the :ref:`peripheral_hids_mouse` or :ref:`peripheral_hids_keyboard` sample, or a Bluetooth Low Energy dongle and nRF Connect for Desktop) +The sample also requires a device running a BAS Server to connect with (for example, another development kit running the :ref:`peripheral_hids_mouse` or :ref:`peripheral_hids_keyboard` sample, or a Bluetooth® Low Energy dongle and nRF Connect for Desktop) User interface diff --git a/samples/bluetooth/central_hids/README.rst b/samples/bluetooth/central_hids/README.rst index 8ac4f7e2f956..f7b0df92b6dc 100644 --- a/samples/bluetooth/central_hids/README.rst +++ b/samples/bluetooth/central_hids/README.rst @@ -32,7 +32,7 @@ The sample supports the following development kits: :header: heading :rows: nrf5340dk_nrf5340_cpuapp_and_cpuappns , nrf52840dk_nrf52840, nrf52833dk_nrf52833, nrf52833dk_nrf52820, nrf52dk_nrf52832 -The sample also requires a HIDS device to connect with (for example, another development kit running the :ref:`peripheral_hids_mouse` or :ref:`peripheral_hids_keyboard` sample, or a Bluetooth Low Energy dongle and nRF Connect for Desktop). +The sample also requires a HIDS device to connect with (for example, another development kit running the :ref:`peripheral_hids_mouse` or :ref:`peripheral_hids_keyboard` sample, or a Bluetooth® Low Energy dongle and nRF Connect for Desktop). User interface ************** diff --git a/samples/bluetooth/central_hr_coded/README.rst b/samples/bluetooth/central_hr_coded/README.rst index d8cc8eb24382..67f79616e12f 100644 --- a/samples/bluetooth/central_hr_coded/README.rst +++ b/samples/bluetooth/central_hr_coded/README.rst @@ -13,7 +13,7 @@ However, this sample specifically looks for heart rate monitors using LE Coded P Overview ******** -The sample demonstrates a Bluetooth LE Central role functionality by scanning for other Bluetooth LE devices that run a Heart Rate Server with LE Coded PHY support which not available in Zephyr Bluetooth LE Controller (See :ref:`ug_ble_controller` for more information). +The sample demonstrates a Bluetooth® LE Central role functionality by scanning for other Bluetooth LE devices that run a Heart Rate Server with LE Coded PHY support, which is not available in Zephyr Bluetooth LE Controller (See :ref:`ug_ble_controller` for more information). It then establishes a connection to the first Peripheral device in range. It can be used together with the :ref:`peripheral_hr_coded` sample. diff --git a/samples/bluetooth/central_nfc_pairing/README.rst b/samples/bluetooth/central_nfc_pairing/README.rst index eba0aff9821d..bea7d7f7c221 100644 --- a/samples/bluetooth/central_nfc_pairing/README.rst +++ b/samples/bluetooth/central_nfc_pairing/README.rst @@ -7,7 +7,7 @@ Bluetooth: Central NFC pairing :local: :depth: 2 -The Central NFC pairing sample demonstrates Bluetooth LE out-of-band pairing using an :ref:`st25r3911b_nfc_readme` and the NFC TNEP protocol. +The Central NFC pairing sample demonstrates Bluetooth® LE out-of-band pairing using an :ref:`st25r3911b_nfc_readme` and the NFC TNEP protocol. You can use it to test the touch-to-pair feature between Nordic Semiconductor's devices with :ref:`st25r3911b_nfc_readme` and an NFC Tag device with Bluetooth LE support. The sample shows the usage of NFC NDEF :ref:`nfc_ch` and :ref:`tnep_poller_readme` with the :ref:`Connection Handover service`. diff --git a/samples/bluetooth/central_smp_client/README.rst b/samples/bluetooth/central_smp_client/README.rst index 27271617dd1f..1355084ca973 100644 --- a/samples/bluetooth/central_smp_client/README.rst +++ b/samples/bluetooth/central_smp_client/README.rst @@ -30,9 +30,9 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf5340dk_nrf5340_cpuapp_and_cpuappns , nrf52840dk_nrf52840, nrf52833dk_nrf52833, nrf52833dk_nrf52820, nrf52dk_nrf52832 + :rows: nrf5340dk_nrf5340_cpuapp_and_cpuappns, nrf52840dk_nrf52840, nrf52833dk_nrf52833, nrf52833dk_nrf52820, nrf52dk_nrf52832 -The sample also requires a device running `mcumgr`_ with transport protocol over Bluetooth Low Energy, for example, another development kit running the :ref:`smp_svr_sample`. +The sample also requires a device running `mcumgr`_ with transport protocol over Bluetooth® Low Energy, for example, another development kit running the :ref:`smp_svr_sample`. User interface ************** diff --git a/samples/bluetooth/central_uart/README.rst b/samples/bluetooth/central_uart/README.rst index 90a27ca69106..857fab56982c 100644 --- a/samples/bluetooth/central_uart/README.rst +++ b/samples/bluetooth/central_uart/README.rst @@ -8,7 +8,7 @@ Bluetooth: Central UART :depth: 2 The Central UART sample demonstrates how to use the :ref:`nus_client_readme`. -It uses the NUS Client to send data back and forth between a UART connection and a Bluetooth LE connection, emulating a serial port over Bluetooth LE. +It uses the NUS Client to send data back and forth between a UART connection and a Bluetooth® LE connection, emulating a serial port over Bluetooth LE. Overview diff --git a/samples/bluetooth/direct_test_mode/README.rst b/samples/bluetooth/direct_test_mode/README.rst index 85035e3d84c0..8a7207a7d82f 100644 --- a/samples/bluetooth/direct_test_mode/README.rst +++ b/samples/bluetooth/direct_test_mode/README.rst @@ -7,7 +7,7 @@ Bluetooth: Direct Test Mode :local: :depth: 2 -This sample enables the Direct Test Mode functions described in `Bluetooth Core Specification`_: Version 5.2, Vol. 6, Part F. +This sample enables the Direct Test Mode functions described in `Bluetooth® Core Specification `_: Version 5.2, Vol. 6, Part F. Overview ******** @@ -20,7 +20,7 @@ The sample uses Direct Test Mode (DTM) to test the operation of the following fe * Packet error rate * Intermodulation performance -Test procedures are defined in the document `Bluetooth Low Energy RF PHY Test Specification`_: Document number RF-PHY.TS.p15 +Test procedures are defined in the document `Bluetooth® Low Energy RF PHY Test Specification `_: Document number RF-PHY.TS.p15 You can carry out conformance tests using dedicated test equipment, such as the Anritsu MT8852 or similar, with an nRF5 running the DTM sample set as device under test (DUT). diff --git a/samples/bluetooth/direction_finding_connectionless_rx/README.rst b/samples/bluetooth/direction_finding_connectionless_rx/README.rst index 6c67fa2fda44..31c797ecb5b7 100644 --- a/samples/bluetooth/direction_finding_connectionless_rx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_rx/README.rst @@ -7,7 +7,7 @@ Bluetooth: Direction finding connectionless locator :local: :depth: 2 -The direction finding connectionless locator sample application demonstrates Bluetooth LE direction finding reception. +The direction finding connectionless locator sample application demonstrates Bluetooth® LE direction finding reception. Requirements ************ diff --git a/samples/bluetooth/direction_finding_connectionless_tx/README.rst b/samples/bluetooth/direction_finding_connectionless_tx/README.rst index a148f2977e8c..8f3249cb9bfc 100644 --- a/samples/bluetooth/direction_finding_connectionless_tx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_tx/README.rst @@ -7,7 +7,7 @@ Bluetooth: Direction finding connectionless beacon :local: :depth: 2 -The direction finding connectionless beacon sample demonstrates Bluetooth LE direction finding transmission. +The direction finding connectionless beacon sample demonstrates Bluetooth® LE direction finding transmission. Requirements ************ diff --git a/samples/bluetooth/enocean/README.rst b/samples/bluetooth/enocean/README.rst index baa93219e7e1..189b0cc64dc5 100644 --- a/samples/bluetooth/enocean/README.rst +++ b/samples/bluetooth/enocean/README.rst @@ -7,7 +7,7 @@ Bluetooth: EnOcean :local: :depth: 2 -The Bluetooth EnOcean sample demonstrates the basic usage of the :ref:`bt_enocean_readme` library. +The Bluetooth® EnOcean sample demonstrates the basic usage of the :ref:`bt_enocean_readme` library. Overview ******** diff --git a/samples/bluetooth/hci_lpuart/README.rst b/samples/bluetooth/hci_lpuart/README.rst index 98dd31c2177a..d494ab8dcd22 100644 --- a/samples/bluetooth/hci_lpuart/README.rst +++ b/samples/bluetooth/hci_lpuart/README.rst @@ -21,7 +21,7 @@ The sample supports the following development kit: Overview ******** -The sample implements the Bluetooth HCI controller using the :ref:`uart_nrf_sw_lpuart` for UART communication. +The sample implements the Bluetooth® HCI controller using the :ref:`uart_nrf_sw_lpuart` for UART communication. Building and running ******************** diff --git a/samples/bluetooth/llpm/README.rst b/samples/bluetooth/llpm/README.rst index f6189703f8f2..ef4127e38dca 100644 --- a/samples/bluetooth/llpm/README.rst +++ b/samples/bluetooth/llpm/README.rst @@ -7,7 +7,7 @@ Bluetooth: LLPM :local: :depth: 2 -The Bluetooth Low Latency Packet Mode (LLPM) sample uses the :ref:`latency_readme` and the :ref:`latency_client_readme` to showcase the LLPM proprietary Bluetooth extension from Nordic Semiconductor. +The Bluetooth® Low Latency Packet Mode (LLPM) sample uses the :ref:`latency_readme` and the :ref:`latency_client_readme` to showcase the LLPM proprietary Bluetooth extension from Nordic Semiconductor. You can use it to determine the transmission latency of LLPM-enabled connections, or to compare with different connection parameters and check their influence on the results. @@ -25,7 +25,7 @@ LLPM connection interval (1 ms) The lowest supported connection interval is 1 ms for one link. Physical layer (PHY) - Starting with Bluetooth 5, the over-the-air data rate in Bluetooth Low Energy supports 2 Ms/s (mega symbol per second), which allows for faster transmission. + Starting with Bluetooth® 5, the over-the-air data rate in Bluetooth Low Energy supports 2 Ms/s (mega symbol per second), which allows for faster transmission. The LLPM connection interval is only supported on *LE 2M PHY*. Otherwise, the SoftDevice Controller will deny the request command. diff --git a/samples/bluetooth/mesh/chat/README.rst b/samples/bluetooth/mesh/chat/README.rst index c4ea68fe26c5..7bd04d82cb99 100644 --- a/samples/bluetooth/mesh/chat/README.rst +++ b/samples/bluetooth/mesh/chat/README.rst @@ -7,7 +7,7 @@ Bluetooth: Mesh chat :local: :depth: 2 -The Bluetooth mesh chat sample demonstrates how the mesh network can be used to facilitate communication between nodes by text, using the :ref:`bt_mesh_chat_client_model`. +The Bluetooth® mesh chat sample demonstrates how the mesh network can be used to facilitate communication between nodes by text, using the :ref:`bt_mesh_chat_client_model`. .. toctree:: :maxdepth: 1 diff --git a/samples/bluetooth/mesh/light/README.rst b/samples/bluetooth/mesh/light/README.rst index 5b5af712f369..74b89807daa2 100644 --- a/samples/bluetooth/mesh/light/README.rst +++ b/samples/bluetooth/mesh/light/README.rst @@ -7,7 +7,7 @@ Bluetooth: Mesh light :local: :depth: 2 -The Bluetooth mesh light sample demonstrates how to set up a mesh server model application, and control LEDs with Bluetooth mesh using the :ref:`bt_mesh_onoff_readme`. +The Bluetooth® mesh light sample demonstrates how to set up a mesh server model application, and control LEDs with Bluetooth mesh using the :ref:`bt_mesh_onoff_readme`. .. note:: This sample is self-contained, and can be tested on its own. diff --git a/samples/bluetooth/mesh/light_ctrl/README.rst b/samples/bluetooth/mesh/light_ctrl/README.rst index 72b135fbdd23..ceca369155ab 100644 --- a/samples/bluetooth/mesh/light_ctrl/README.rst +++ b/samples/bluetooth/mesh/light_ctrl/README.rst @@ -7,7 +7,7 @@ Bluetooth: Mesh light fixture :local: :depth: 2 -The Bluetooth mesh light fixture sample demonstrates how to set up a light control mesh server model application, and control a dimmable LED with Bluetooth mesh using the :ref:`bt_mesh_onoff_readme`. +The Bluetooth® mesh light fixture sample demonstrates how to set up a light control mesh server model application, and control a dimmable LED with Bluetooth mesh using the :ref:`bt_mesh_onoff_readme`. Requirements ************ diff --git a/samples/bluetooth/mesh/light_switch/README.rst b/samples/bluetooth/mesh/light_switch/README.rst index 0a53d8e42d25..ac4e6b5443ce 100644 --- a/samples/bluetooth/mesh/light_switch/README.rst +++ b/samples/bluetooth/mesh/light_switch/README.rst @@ -8,7 +8,7 @@ Bluetooth: Mesh light switch :depth: 2 The :ref:`ug_bt_mesh` light switch sample can be used to change the state of light sources on other devices within the same mesh network. -It also demonstrates how to use Bluetooth mesh models by using the Generic OnOff Client model in an application. +It also demonstrates how to use Bluetooth® mesh models by using the Generic OnOff Client model in an application. Use the light switch sample with the :ref:`bluetooth_mesh_light` sample to demonstrate its function in a Bluetooth mesh network. diff --git a/samples/bluetooth/mesh/sensor_client/README.rst b/samples/bluetooth/mesh/sensor_client/README.rst index de6d6012a629..e746c435220a 100644 --- a/samples/bluetooth/mesh/sensor_client/README.rst +++ b/samples/bluetooth/mesh/sensor_client/README.rst @@ -7,7 +7,7 @@ Bluetooth: Mesh sensor observer :local: :depth: 2 -The Bluetooth mesh sensor observer sample demonstrates how to set up a basic Bluetooth mesh :ref:`bt_mesh_sensor_cli_readme` model application that gets sensor data from one :ref:`bt_mesh_sensor_srv_readme` model. +The Bluetooth® mesh sensor observer sample demonstrates how to set up a basic Bluetooth mesh :ref:`bt_mesh_sensor_cli_readme` model application that gets sensor data from one :ref:`bt_mesh_sensor_srv_readme` model. Four different sensor types are used to showcase different ways for the server to publish data. In addition, the samples demonstrate usage of both :ref:`single-channel sensor types and sensor series types `. diff --git a/samples/bluetooth/mesh/sensor_server/README.rst b/samples/bluetooth/mesh/sensor_server/README.rst index 228b3ed73461..8171576ecb7b 100644 --- a/samples/bluetooth/mesh/sensor_server/README.rst +++ b/samples/bluetooth/mesh/sensor_server/README.rst @@ -7,7 +7,7 @@ Bluetooth: Mesh sensor :local: :depth: 2 -The Bluetooth mesh sensor sample demonstrates how to set up a basic mesh Sensor Server model application that provides sensor data to one :ref:`bt_mesh_sensor_cli_readme` model. +The Bluetooth® mesh sensor sample demonstrates how to set up a basic mesh Sensor Server model application that provides sensor data to one :ref:`bt_mesh_sensor_cli_readme` model. Four different sensor types are used to showcase different ways for the server to publish data. In addition, the sample demonstrates usage of both :ref:`single-channel sensor types and sensor series types `. diff --git a/samples/bluetooth/mesh/silvair_enocean/README.rst b/samples/bluetooth/mesh/silvair_enocean/README.rst index 62f9f8be7fbf..10ff0d211256 100644 --- a/samples/bluetooth/mesh/silvair_enocean/README.rst +++ b/samples/bluetooth/mesh/silvair_enocean/README.rst @@ -8,7 +8,7 @@ Bluetooth: Mesh Silvair EnOcean :depth: 2 The :ref:`ug_bt_mesh` Silvair EnOcean sample can be used to change the state of light sources on other devices within the same mesh network. -It also demonstrates how to use Bluetooth mesh models by using the Silvair EnOcean Proxy Server model in an application. +It also demonstrates how to use Bluetooth® mesh models by using the Silvair EnOcean Proxy Server model in an application. Use the Silvair EnOcean sample with the :ref:`bluetooth_mesh_light_lc` sample to demonstrate its function in a Bluetooth mesh network. diff --git a/samples/bluetooth/peripheral_ancs_client/README.rst b/samples/bluetooth/peripheral_ancs_client/README.rst index d18549cc494c..f0f2a5689310 100644 --- a/samples/bluetooth/peripheral_ancs_client/README.rst +++ b/samples/bluetooth/peripheral_ancs_client/README.rst @@ -32,7 +32,7 @@ The sample supports the following development kits: :header: heading :rows: nrf5340dk_nrf5340_cpuapp_and_cpuappns, nrf52840dk_nrf52840, nrf52833dk_nrf52833, nrf52dk_nrf52832 -The sample also requires a device running an ANCS Server to connect with (for example, an iPhone which runs iOS, or a Bluetooth Low Energy dongle and nRF Connect for Desktop). +The sample also requires a device running an ANCS Server to connect with (for example, an iPhone which runs iOS, or a Bluetooth® Low Energy dongle and nRF Connect for Desktop). User interface ************** diff --git a/samples/bluetooth/peripheral_bms/README.rst b/samples/bluetooth/peripheral_bms/README.rst index 6e935f461e9b..f770b4fea8c8 100644 --- a/samples/bluetooth/peripheral_bms/README.rst +++ b/samples/bluetooth/peripheral_bms/README.rst @@ -25,7 +25,7 @@ The sample supports the following development kits: :header: heading :rows: nrf5340dk_nrf5340_cpuapp_and_cpuappns, nrf52840dk_nrf52840, nrf52dk_nrf52832, nrf52dk_nrf52810 -The sample also requires a Bluetooth Low Energy dongle and nRF Connect for Desktop. +The sample also requires a Bluetooth® Low Energy dongle and nRF Connect for Desktop. User interface ************** diff --git a/samples/bluetooth/peripheral_cts_client/README.rst b/samples/bluetooth/peripheral_cts_client/README.rst index 8199bc412731..9f054273bd06 100644 --- a/samples/bluetooth/peripheral_cts_client/README.rst +++ b/samples/bluetooth/peripheral_cts_client/README.rst @@ -23,7 +23,7 @@ The sample supports the following development kits: :header: heading :rows: nrf5340dk_nrf5340_cpuapp_and_cpuappns, nrf52840dk_nrf52840, nrf52833dk_nrf52833, nrf52dk_nrf52832 -The sample also requires a device running a CTS Server to connect with (for example, a Bluetooth Low Energy dongle and nRF Connect for Desktop) +The sample also requires a device running a CTS Server to connect with (for example, a Bluetooth® Low Energy dongle and nRF Connect for Desktop). User interface ************** diff --git a/samples/bluetooth/peripheral_hids_keyboard/README.rst b/samples/bluetooth/peripheral_hids_keyboard/README.rst index f6cc55e331b7..0969dbcfe452 100644 --- a/samples/bluetooth/peripheral_hids_keyboard/README.rst +++ b/samples/bluetooth/peripheral_hids_keyboard/README.rst @@ -95,7 +95,7 @@ After programming the sample to your development kit, you can test it either by Testing with a Microsoft Windows computer ----------------------------------------- -To test with a Microsoft Windows computer that has a Bluetooth radio, complete the following steps: +To test with a Microsoft Windows computer that has a Bluetooth® radio, complete the following steps: 1. Power on your development kit. #. Press **Button 4** on the kit if the device is not advertising. diff --git a/samples/bluetooth/peripheral_hids_mouse/README.rst b/samples/bluetooth/peripheral_hids_mouse/README.rst index a701fc585c20..988448c5f986 100644 --- a/samples/bluetooth/peripheral_hids_mouse/README.rst +++ b/samples/bluetooth/peripheral_hids_mouse/README.rst @@ -21,7 +21,7 @@ This sample exposes the HID GATT Service. It uses a report map for a generic mouse. You can also disable directed advertising feature by clearing the BT_DIRECTED_ADVERTISING flag in the application configuration. -This feature is enabled by default and it changes the way in which advertising works in comparison to the other Bluetooth LE samples. +This feature is enabled by default and it changes the way in which advertising works in comparison to the other Bluetooth® Low Energy samples. When the device wants to advertise, it starts with high duty cycle directed advertising provided that it has bonding information. If the timeout occurs, then the device starts directed advertising to the next bonded peer. If all bonding information is used and there is still no connection, then the regular advertising starts. diff --git a/samples/bluetooth/peripheral_hr_coded/README.rst b/samples/bluetooth/peripheral_hr_coded/README.rst index 9acec3bd75ad..087e1f04eb89 100644 --- a/samples/bluetooth/peripheral_hr_coded/README.rst +++ b/samples/bluetooth/peripheral_hr_coded/README.rst @@ -13,7 +13,7 @@ However, this sample supports LE Coded PHY. Overview ******** -The sample demonstrates a basic Bluetooth LE Peripheral role functionality that exposes the Heart Rate GATT Service with LE Coded PHY support which not available in Zephyr Bluetooth LE Controller (See :ref:`ug_ble_controller` for more information). +The sample demonstrates a basic Bluetooth® Low Energy Peripheral role functionality that exposes the Heart Rate GATT Service with LE Coded PHY support, which is not available in Zephyr Bluetooth LE Controller (See :ref:`ug_ble_controller` for more information). Once it connects to a Central device, it generates dummy heart rate values. It can be used together with the :ref:`bluetooth_central_hr_coded` sample. diff --git a/samples/bluetooth/peripheral_lbs/README.rst b/samples/bluetooth/peripheral_lbs/README.rst index ccae5000d605..81045d1c6a5e 100644 --- a/samples/bluetooth/peripheral_lbs/README.rst +++ b/samples/bluetooth/peripheral_lbs/README.rst @@ -27,7 +27,7 @@ The sample supports the following development kits: :rows: nrf5340dk_nrf5340_cpuapp_and_cpuappns, nrf52840dk_nrf52840, nrf52840dk_nrf52811, nrf52833dk_nrf52833, nrf52833dk_nrf52820, nrf52dk_nrf52832, nrf52dk_nrf52810, nrf52840dongle_nrf52840, thingy53_nrf5340_cpuapp .. note:: - When used with :ref:`zephyr:thingy53_nrf5340`, the sample supports the MCUboot bootloader with serial recovery and SMP DFU over Bluetooth. + When used with :ref:`zephyr:thingy53_nrf5340`, the sample supports the MCUboot bootloader with serial recovery and SMP DFU over Bluetooth®. Debug logs are provided over the USB CDC ACM class serial port. The sample also requires a smartphone or tablet running a compatible application. diff --git a/samples/bluetooth/peripheral_nfc_pairing/README.rst b/samples/bluetooth/peripheral_nfc_pairing/README.rst index 04c97d70568a..eecb6d0de453 100644 --- a/samples/bluetooth/peripheral_nfc_pairing/README.rst +++ b/samples/bluetooth/peripheral_nfc_pairing/README.rst @@ -7,7 +7,7 @@ Bluetooth: NFC pairing :local: :depth: 2 -The NFC pairing sample demonstrates Bluetooth LE out-of-band pairing using an NFC tag and the NFC TNEP protocol. +The NFC pairing sample demonstrates Bluetooth® LE out-of-band pairing using an NFC tag and the NFC TNEP protocol. You can use it to test the touch-to-pair feature between Nordic Semiconductor's devices and an NFC polling device with Bluetooth LE support, for example, a mobile phone. The sample shows the usage of NFC NDEF :ref:`nfc_ch` and :ref:`tnep_tag_readme` with the :ref:`Connection Handover service`. diff --git a/samples/bluetooth/peripheral_uart/README.rst b/samples/bluetooth/peripheral_uart/README.rst index 2bbc1bff34ff..efac416771f0 100644 --- a/samples/bluetooth/peripheral_uart/README.rst +++ b/samples/bluetooth/peripheral_uart/README.rst @@ -8,7 +8,7 @@ Bluetooth: Peripheral UART :depth: 2 The Peripheral UART sample demonstrates how to use the :ref:`nus_service_readme`. -It uses the NUS service to send data back and forth between a UART connection and a Bluetooth LE connection, emulating a serial port over Bluetooth LE. +It uses the NUS service to send data back and forth between a UART connection and a Bluetooth® LE connection, emulating a serial port over Bluetooth LE. Overview ******** diff --git a/samples/bluetooth/rpc_host/README.rst b/samples/bluetooth/rpc_host/README.rst index 86fa7c262c2d..b032ac79b446 100644 --- a/samples/bluetooth/rpc_host/README.rst +++ b/samples/bluetooth/rpc_host/README.rst @@ -3,7 +3,7 @@ Bluetooth: Host for nRF RPC Bluetooth Low Energy ################################################ -The nRF RPC Host sample demonstrates the Bluetooth Low Energy (LE) stack with the :ref:`nrfxlib:nrf_rpc` library, which exposes the stack's interface to another device or CPU using `Remote Procedure Calls (RPC)`_. +The nRF RPC Host sample demonstrates the Bluetooth® Low Energy (LE) stack with the :ref:`nrfxlib:nrf_rpc` library, which exposes the stack's interface to another device or CPU using `Remote Procedure Calls (RPC)`_. On an nRF53 device, this sample is supposed to run on the network core and it provides the Bluetooth LE functionality for the application core. Overview diff --git a/samples/bluetooth/shell_bt_nus/README.rst b/samples/bluetooth/shell_bt_nus/README.rst index 9981d35f8baf..42ff771c864f 100644 --- a/samples/bluetooth/shell_bt_nus/README.rst +++ b/samples/bluetooth/shell_bt_nus/README.rst @@ -7,7 +7,7 @@ Bluetooth: NUS shell transport :local: :depth: 2 -The Nordic UART Service (NUS) shell transport sample demonstrates how to use the :ref:`shell_bt_nus_readme` to receive shell commands from a remote device. +The Nordic UART Service (NUS) shell transport sample demonstrates how to use the :ref:`shell_bt_nus_readme` to receive shell commands from a remote device over Bluetooth®. Overview ******** diff --git a/samples/bluetooth/throughput/README.rst b/samples/bluetooth/throughput/README.rst index 9fbe665baaa1..aeeaf08d94ae 100644 --- a/samples/bluetooth/throughput/README.rst +++ b/samples/bluetooth/throughput/README.rst @@ -10,7 +10,7 @@ Bluetooth: Throughput .. note:: The implementation and usage of this sample has changed considerably with |NCS| v1.5.0. -The Bluetooth Throughput sample uses the :ref:`throughput_readme` to measure *Bluetooth* Low Energy throughput performance. +The Bluetooth® Throughput sample uses the :ref:`throughput_readme` to measure Bluetooth® Low Energy throughput performance. You can use it to determine the maximum throughput, or to experiment with different connection parameters and check their influence on the throughput. Overview @@ -39,7 +39,7 @@ Connection interval When increasing this value, more packets may be sent in one interval, but if a packet is lost, the wait until the retransmission is longer. Physical layer (PHY) data rate - Starting with Bluetooth 5, the over-the-air data rate in Bluetooth Low Energy can exceed 1 Ms/s (mega symbol per second), which allows for faster transmission. + Starting with Bluetooth® 5, the over-the-air data rate in Bluetooth Low Energy can exceed 1 Ms/s (mega symbol per second), which allows for faster transmission. In addition, it is possible to use coded PHY (available on the nRF52840 SoC only) for long-range transmission. By default, the following connection parameter values are used: diff --git a/samples/bootloader/README.rst b/samples/bootloader/README.rst index 4c2e15aab52d..b53187953572 100644 --- a/samples/bootloader/README.rst +++ b/samples/bootloader/README.rst @@ -16,7 +16,7 @@ See :ref:`ug_bootloader` for more information about the full bootloader chain. .. note:: Currently, this immutable bootloader does not support firmware updates over the SMP transport for either an upgradable bootloader or an application. - If the application using this bootloader requires SMP-based firmware updates, such as Bluetooth LE DFU, :ref:`include MCUboot as a second-stage bootloader `. + If the application using this bootloader requires SMP-based firmware updates, such as Bluetooth® LE DFU, :ref:`include MCUboot as a second-stage bootloader `. .. _bootloader_rot: diff --git a/samples/debug/ppi_trace/README.rst b/samples/debug/ppi_trace/README.rst index dfd6a4353071..422c4c7a1bd5 100644 --- a/samples/debug/ppi_trace/README.rst +++ b/samples/debug/ppi_trace/README.rst @@ -18,7 +18,7 @@ The sample initializes trace pins to observe the following hardware events: * RTC Compare event (:c:enumerator:`NRF_RTC_EVENT_COMPARE_0`) * RTC Tick event (:c:enumerator:`NRF_RTC_EVENT_TICK`) * Low frequency clock (LFCLK) Started event (:c:enumerator:`NRF_CLOCK_EVENT_LFCLKSTARTED`) -* Radio activity during *Bluetooth* advertising (available only for Bluetooth capable devices) +* Radio activity during Bluetooth® advertising (available only for Bluetooth capable devices) The sample sets up a :ref:`zephyr:counter_api` to generate an :c:enumerator:`NRF_RTC_EVENT_COMPARE_0` event every 50 ms. Initially, RTC runs on RC low frequency (lower precision) as clock source. diff --git a/samples/matter/light_bulb/README.rst b/samples/matter/light_bulb/README.rst index 8a7b07ded542..f468cf0da2e8 100644 --- a/samples/matter/light_bulb/README.rst +++ b/samples/matter/light_bulb/README.rst @@ -106,7 +106,7 @@ Button 3: If for some reason the light switch device is not able to receive messages during this predefined period of time, you can restart publishing service by pressing this button again. Button 4: - Starts the NFC tag emulation, enables Bluetooth LE advertising for the predefined period of time (15 minutes by default), and makes the device discoverable over Bluetooth LE. + Starts the NFC tag emulation, enables Bluetooth® LE advertising for the predefined period of time (15 minutes by default), and makes the device discoverable over Bluetooth LE. This button is used during the :ref:`commissioning procedure `. .. include:: ../lock/README.rst diff --git a/samples/matter/light_switch/README.rst b/samples/matter/light_switch/README.rst index 5e33bf1ed53e..dc93c12c59a1 100644 --- a/samples/matter/light_switch/README.rst +++ b/samples/matter/light_switch/README.rst @@ -36,7 +36,7 @@ The light switch must be put into the test mode and paired with a light bulb dev Test mode ========= -Unlike other samples, such as :ref:`Matter door lock `, the light switch sample does not support Matter commissioning over Bluetooth LE. +Unlike other samples, such as :ref:`Matter door lock `, the light switch sample does not support Matter commissioning over Bluetooth® LE. To make the light switch and the light bulb devices able to communicate with each other, they must be initialized with the same static Thread network parameters and static Matter cryptographic keys. Pressing **Button 3** activates the test mode before enabling the pairing phase on the device. diff --git a/samples/matter/lock/README.rst b/samples/matter/lock/README.rst index d0e448b733ec..672b44faf44c 100644 --- a/samples/matter/lock/README.rst +++ b/samples/matter/lock/README.rst @@ -46,7 +46,7 @@ Remote testing in a network .. matter_door_lock_sample_remote_testing_start By default, the Matter accessory device has Thread disabled. -You must pair it with the Matter controller over Bluetooth LE to get configuration from the controller if you want to use the device within a Thread network. +You must pair it with the Matter controller over Bluetooth® LE to get configuration from the controller if you want to use the device within a Thread network. To do this, the device must be made discoverable manually (for security reasons) and the controller must get the commissioning information from the Matter accessory device and provision the device into the network. For details, see the `Commissioning the device`_ section. @@ -77,7 +77,7 @@ Device Firmware Upgrade support .. matter_door_lock_sample_build_with_dfu_start -You can configure the sample to use the secure bootloader for performing over-the-air Device Firmware Upgrade using Bluetooth LE, using the following build flags during the build process: +You can configure the sample to use the secure bootloader for performing over-the-air Device Firmware Upgrade using Bluetooth® LE, using the following build flags during the build process: * ``-DOVERLAY_CONFIG=../common/config/overlay-dfu_support.conf`` * ``-DPM_STATIC_YML_FILE="configuration/build-target/pm_static.yml`` diff --git a/samples/matter/template/README.rst b/samples/matter/template/README.rst index 42a76be9b659..b6197f0ef937 100644 --- a/samples/matter/template/README.rst +++ b/samples/matter/template/README.rst @@ -30,7 +30,7 @@ For testing purposes, that is to commission the device and :ref:`control it remo Overview ******** -The sample starts the Bluetooth LE advertising automatically and prepares the Matter device for commissioning into a Matter-enabled Thread network. +The sample starts the Bluetooth® LE advertising automatically and prepares the Matter device for commissioning into a Matter-enabled Thread network. The sample uses an LED to show the state of the connection. You can press a button to start the factory reset when needed. diff --git a/samples/nrf5340/multiprotocol_rpmsg/README.rst b/samples/nrf5340/multiprotocol_rpmsg/README.rst index a48843242e86..958f6d74f57b 100644 --- a/samples/nrf5340/multiprotocol_rpmsg/README.rst +++ b/samples/nrf5340/multiprotocol_rpmsg/README.rst @@ -12,7 +12,7 @@ This sample exposes the :ref:`softdevice_controller` and the IEEE 802.15.4 radio Overview ******** -The sample is compatible with the HCI RPMsg driver provided by the |NCS| Bluetooth :ref:`bt_hci_drivers` core and with the nRF 802.15.4 Serialization Host module. +The sample is compatible with the HCI RPMsg driver provided by the |NCS| Bluetooth® :ref:`bt_hci_drivers` core and with the nRF 802.15.4 Serialization Host module. See the following configuration options for more information: diff --git a/samples/nrf5340/netboot/README.rst b/samples/nrf5340/netboot/README.rst index 71dde5bb4054..1bee827b4ad4 100644 --- a/samples/nrf5340/netboot/README.rst +++ b/samples/nrf5340/netboot/README.rst @@ -15,7 +15,7 @@ Overview The network core bootloader sample protects the flash memory areas allocated to both itself and the application running on the network core. You must use this sample as a child image of a :ref:`multi-image ` build, where MCUboot is enabled and there is a network core application. -MCUboot verifies and shares with the network core bootloader any new network core application image received through a device firmware update (DFU) transport layer, like a serial or a Bluetooth LE connection. +MCUboot verifies and shares with the network core bootloader any new network core application image received through a device firmware update (DFU) transport layer, like a serial or a Bluetooth® LE connection. For this reason, without MCUboot, this sample does nothing other than launching directly the application. During the boot process, the network core bootloader sample and MCUboot interact as follows: diff --git a/samples/nrf9160/agps/README.rst b/samples/nrf9160/agps/README.rst index 16067c93b4f4..ea7f4c6ddb65 100644 --- a/samples/nrf9160/agps/README.rst +++ b/samples/nrf9160/agps/README.rst @@ -140,7 +140,7 @@ Testing This is to achieve sufficient satellite coverage to get a position fix. #. Optionally, connect the nRF9160-based device to a PC with a USB cable. The kit is assigned a COM port (Windows) or ttyACM device (Linux), which is visible in the Device Manager. #. Optionally, connect to the kit with a terminal emulator (for example, PuTTY) to see log output. See How to connect with PuTTY for the required settings. - You can also use the Bluetooth LE service of Thingy:91 to see log output on a mobile device. + You can also use the Bluetooth® LE service of Thingy:91 to see log output on a mobile device. #. Log into your nRF Connect for Cloud account and select your device. #. Power on the nRF9160-based device. diff --git a/samples/nrf9160/lte_ble_gateway/README.rst b/samples/nrf9160/lte_ble_gateway/README.rst index 1764ec707ed6..83597b228985 100644 --- a/samples/nrf9160/lte_ble_gateway/README.rst +++ b/samples/nrf9160/lte_ble_gateway/README.rst @@ -9,7 +9,7 @@ nRF9160: LTE Sensor Gateway The LTE Sensor Gateway sample demonstrates how to transmit sensor data from an nRF9160 development kit to the `nRF Connect for Cloud`_. -The sensor data is collected via Bluetooth LE, unlike the :ref:`asset_tracker` sample. +The sensor data is collected via Bluetooth® Low Energy, unlike the :ref:`asset_tracker` sample. Therefore, this sample acts as a gateway between the Bluetooth LE and the LTE connections to nRF Connect for Cloud. Overview diff --git a/samples/openthread/cli/README.rst b/samples/openthread/cli/README.rst index 1c075292f48b..427e39666c66 100644 --- a/samples/openthread/cli/README.rst +++ b/samples/openthread/cli/README.rst @@ -477,7 +477,7 @@ This sample uses the following Zephyr libraries: * :ref:`zephyr:thread_protocol_interface` -The following dependencies are added by the optional multiprotocol Bluetooth LE extension: +The following dependencies are added by the optional multiprotocol Bluetooth® LE extension: * :ref:`nrfxlib:softdevice_controller` * :ref:`nus_service_readme` diff --git a/samples/openthread/coap_client/README.rst b/samples/openthread/coap_client/README.rst index 6132672e15f7..27048492077c 100644 --- a/samples/openthread/coap_client/README.rst +++ b/samples/openthread/coap_client/README.rst @@ -35,7 +35,7 @@ Multiprotocol Bluetooth LE extension ==================================== This optional extension can demonstrate the OpenThread stack and :ref:`nrfxlib:softdevice_controller` working concurrently. -It uses the :ref:`nus_service_readme` library to control the LED states over Bluetooth LE in a Thread network. +It uses the :ref:`nus_service_readme` library to control the LED states over Bluetooth® LE in a Thread network. For more information about the multiprotocol feature, see :ref:`ug_multiprotocol_support`. FEM support diff --git a/samples/zigbee/light_switch/README.rst b/samples/zigbee/light_switch/README.rst index 0150f51f7ff8..565bfc2ca2d1 100644 --- a/samples/zigbee/light_switch/README.rst +++ b/samples/zigbee/light_switch/README.rst @@ -59,7 +59,7 @@ The sleepy behavior can be enabled by pressing **Button 3** while the light swit Multiprotocol Bluetooth LE extension ==================================== -This optional extension demonstrates dynamic concurrent switching between two protocols, Bluetooth LE and Zigbee. +This optional extension demonstrates dynamic concurrent switching between two protocols, Bluetooth® LE and Zigbee. It uses :ref:`nus_service_readme` library. When this extension is enabled, you can use: diff --git a/scripts/hid_configurator/README.rst b/scripts/hid_configurator/README.rst index 453c7157fcc4..ce162918dcf2 100644 --- a/scripts/hid_configurator/README.rst +++ b/scripts/hid_configurator/README.rst @@ -22,7 +22,7 @@ It can be used for the following purposes: Overview ******** -The script looks for nRF Desktop devices connected to the host through USB, Bluetooth, or nRF Desktop dongle. +The script looks for nRF Desktop devices connected to the host through USB, Bluetooth®, or nRF Desktop dongle. The devices are identified based on Vendor ID. The script exchanges data with the device using :ref:`nrf_desktop_config_channel`. diff --git a/scripts/shell/ble_console/README.rst b/scripts/shell/ble_console/README.rst index 3f83e475cac5..3fffe20274ee 100644 --- a/scripts/shell/ble_console/README.rst +++ b/scripts/shell/ble_console/README.rst @@ -7,7 +7,7 @@ Bluetooth LE Console :local: :depth: 2 -Bluetooth LE Console (located in :file:`scripts/shell/ble_console`) is a desktop application that can be used to communicate with an nRF device over Bluetooth Low Energy using the :ref:`shell_bt_nus_readme`. +Bluetooth® LE Console (located in :file:`scripts/shell/ble_console`) is a desktop application that can be used to communicate with an nRF device over Bluetooth® Low Energy using the :ref:`shell_bt_nus_readme`. The application supports Linux only and cannot be run on Windows. You should run it on a natively installed Linux. From e091bc61d3e77daf9ea8d8f2c739caaa11f649fe Mon Sep 17 00:00:00 2001 From: Piotr Pryga Date: Wed, 9 Jun 2021 11:34:48 +0200 Subject: [PATCH 123/126] samples: bluetooth: df: rx: Move BLE ctrl conf into board spec file Move BLE controller configuration from top level prj.conf file into boards/.conf file. That change is required to allow the sample to build for nRF5340 SOC where BLE cotroller is run on network core and is not part of the sample application image. Signed-off-by: Piotr Pryga --- .../boards/nrf52833dk_nrf52833.conf | 18 ++++++++++++++++++ .../boards/nrf52833dk_nrf52833.overlay | 2 +- .../prj.conf | 11 ----------- 3 files changed, 19 insertions(+), 12 deletions(-) create mode 100644 samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.conf diff --git a/samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.conf b/samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.conf new file mode 100644 index 000000000000..96498c082021 --- /dev/null +++ b/samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.conf @@ -0,0 +1,18 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +CONFIG_BT_CTLR=y +CONFIG_BT_LL_SW_SPLIT=y + +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_SYNC_PERIODIC=y + +# Enable Direction Finding Feature including AoA and AoD +CONFIG_BT_CTLR_DF=y + +# Disable Direction Finding TX mode +CONFIG_BT_CTLR_DF_ANT_SWITCH_TX=n +CONFIG_BT_CTLR_DF_ADV_CTE_TX=n diff --git a/samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.overlay b/samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.overlay index ef18c982c91f..f3e46ad35d2b 100644 --- a/samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.overlay +++ b/samples/bluetooth/direction_finding_connectionless_rx/boards/nrf52833dk_nrf52833.overlay @@ -9,7 +9,7 @@ /* This is a number of antennas that are available on antenna matrix * designed by Nordic. For more information see README.rst. */ - dfe-antenna-num = < 12 >; + dfe-antenna-num = <12>; /* This is a setting that enables antenna 12 (in antenna matrix designed * by Nordic) for Rx PDU. For more information see README.rst. */ diff --git a/samples/bluetooth/direction_finding_connectionless_rx/prj.conf b/samples/bluetooth/direction_finding_connectionless_rx/prj.conf index ac6f129f1026..8e19efa38729 100644 --- a/samples/bluetooth/direction_finding_connectionless_rx/prj.conf +++ b/samples/bluetooth/direction_finding_connectionless_rx/prj.conf @@ -5,8 +5,6 @@ # CONFIG_BT=y -CONFIG_BT_CTLR=y -CONFIG_BT_LL_SW_SPLIT=y CONFIG_BT_DEVICE_NAME="DF Connectionless Locator App" CONFIG_BT_EXT_ADV=y @@ -16,12 +14,3 @@ CONFIG_BT_OBSERVER=y # Enable Direction Finding Feature including AoA and AoD CONFIG_BT_DF=y CONFIG_BT_DF_CONNECTIONLESS_CTE_RX=y - -CONFIG_BT_CTLR_ADV_EXT=y -CONFIG_BT_CTLR_SYNC_PERIODIC=y -# Enable Direction Finding Feature including AoA and AoD -CONFIG_BT_CTLR_DF=y -CONFIG_BT_CTLR_DF_ANT_SWITCH_TX=n - -# Disable Direction Finding Tx mode -CONFIG_BT_CTLR_DF_ADV_CTE_TX=n From 4b680ec768b35f7a89cd2a3085a49a175e3f0031 Mon Sep 17 00:00:00 2001 From: Piotr Pryga Date: Wed, 9 Jun 2021 11:49:31 +0200 Subject: [PATCH 124/126] samples: bluetooth: df: rx: Add child img conf for nRF5340 target builds Add configuration of child image for builds targeted for nRF5340 SOC. The child image is hci_rpmsg. Besides usual Kconfig overlay there is also a DTS overlay required for Radio peripheral configuration. Signed-off-by: Piotr Pryga --- .../child_image/hci_rpmsg.conf | 25 +++++++++++++++++ .../nrf5340dk_nrf5340_cpunet.overlay | 28 +++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 samples/bluetooth/direction_finding_connectionless_rx/child_image/hci_rpmsg.conf create mode 100644 samples/bluetooth/direction_finding_connectionless_rx/child_image/hci_rpmsg/nrf5340dk_nrf5340_cpunet.overlay diff --git a/samples/bluetooth/direction_finding_connectionless_rx/child_image/hci_rpmsg.conf b/samples/bluetooth/direction_finding_connectionless_rx/child_image/hci_rpmsg.conf new file mode 100644 index 000000000000..2f293097c11a --- /dev/null +++ b/samples/bluetooth/direction_finding_connectionless_rx/child_image/hci_rpmsg.conf @@ -0,0 +1,25 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Required to enable BT_BUF_CMD_TX_SIZE for LE Set Extended Advertising Data command +CONFIG_BT_EXT_ADV=y + +# Required to enable BT_PER_ADV_SYNC_MAX +CONFIG_BT_PER_ADV_SYNC=y +CONFIG_BT_OBSERVER=y + +CONFIG_BT_CTLR=y +CONFIG_BT_LL_SW_SPLIT=y + +CONFIG_BT_CTLR_ADV_EXT=y +CONFIG_BT_CTLR_SYNC_PERIODIC=y + +# Enable Direction Finding Feature including AoA and AoD +CONFIG_BT_CTLR_DF=y +CONFIG_BT_CTLR_DF_ANT_SWITCH_TX=n + +# Disable Direction Finding TX mode +CONFIG_BT_CTLR_DF_ADV_CTE_TX=n diff --git a/samples/bluetooth/direction_finding_connectionless_rx/child_image/hci_rpmsg/nrf5340dk_nrf5340_cpunet.overlay b/samples/bluetooth/direction_finding_connectionless_rx/child_image/hci_rpmsg/nrf5340dk_nrf5340_cpunet.overlay new file mode 100644 index 000000000000..d83035bf0f8b --- /dev/null +++ b/samples/bluetooth/direction_finding_connectionless_rx/child_image/hci_rpmsg/nrf5340dk_nrf5340_cpunet.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +&radio { + status = "okay"; + /* This is a number of antennas that are available on antenna matrix + * designed by Nordic. For more information see README.rst. + */ + dfe-antenna-num = <12>; + /* This is a setting that enables antenna 12 (in antenna matrix designed + * by Nordic) for Rx PDU. For more information see README.rst. + */ + dfe-pdu-antenna = <0x0>; + + /* These are GPIO pin numbers that are provided to + * Radio peripheral. The pins will be acquired by Radio to + * drive antenna switching when AoA is enabled. + * Pin numbers are selected to drive switches on antenna matrix + * desinged by Nordic. For more information see README.rst. + */ + dfegpio0-gpios = <&gpio0 4 0>; + dfegpio1-gpios = <&gpio0 5 0>; + dfegpio2-gpios = <&gpio0 6 0>; + dfegpio3-gpios = <&gpio0 7 0>; +}; From 68e74a0d749ecf39aac711c1e7df34585dddec32 Mon Sep 17 00:00:00 2001 From: Piotr Pryga Date: Wed, 9 Jun 2021 11:53:57 +0200 Subject: [PATCH 125/126] samples: Bluetooth: df: rx: Add info about nRF5340 to README.rst Extend README.rst with information about support for nRF5340. Signed-off-by: Piotr Pryga --- .../direction_finding_connectionless_rx/README.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/samples/bluetooth/direction_finding_connectionless_rx/README.rst b/samples/bluetooth/direction_finding_connectionless_rx/README.rst index 31c797ecb5b7..e51ff17a2634 100644 --- a/samples/bluetooth/direction_finding_connectionless_rx/README.rst +++ b/samples/bluetooth/direction_finding_connectionless_rx/README.rst @@ -16,7 +16,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf52833dk_nrf52833 + :rows: nrf52833dk_nrf52833, nrf5340dk_nrf5340_cpuapp_and_cpuappns The sample also requires an antenna matrix when operating in angle of arrival mode. It can be a Nordic Semiconductor design 12 patch antenna matrix, or any other antenna matrix. @@ -38,6 +38,15 @@ Configuration |config| +This sample configuration is split into the following two files: + +* generic configuration is available in :file:`prj.conf` file +* board specific configuration is available in :file:`boards/.conf` file + +Board specific configuration involves configuring the Bluetooth LE controller. +For :ref:`nRF5340 DK `, the Bluetooth LE controller is part of a ``child image`` aimed to run on the network core. +Configuration for the child image is stored in :file:`child_image/` subdirectory. + Angle of departure mode ======================= @@ -46,6 +55,8 @@ To build this sample with angle of departure mode only, set ``OVERLAY_CONFIG`` t See :ref:`cmake_options` for instructions on how to add this option. For more information about using configuration overlay files, see :ref:`zephyr:important-build-vars` in the Zephyr documentation. +To build this sample for :ref:`nRF5340 DK `, with angle of arrival mode only, add content of :file:`overlay-aod.conf` file to :file:`child_image/hci_rpmsg.conf` file. + Antenna matrix configuration for angle of arrival mode ====================================================== From 493859edfee9c41969335a708f4399638783677d Mon Sep 17 00:00:00 2001 From: Lukasz Duda Date: Sun, 8 Aug 2021 20:33:00 +0200 Subject: [PATCH 126/126] samples: matter: add support for nRF21540 This commit adds support for nRF21540 Front-End Module for Matter. Signed-off-by: Lukasz Duda --- doc/nrf/releases/release-notes-changelog.rst | 1 + samples/matter/light_bulb/CMakeLists.txt | 6 ++- samples/matter/light_bulb/README.rst | 7 +++- .../boards/nrf21540dk_nrf52840.conf | 10 +++++ .../boards/nrf21540dk_nrf52840.overlay | 41 +++++++++++++++++++ samples/matter/light_bulb/sample.yaml | 3 +- samples/matter/light_switch/README.rst | 12 +++++- .../boards/nrf21540dk_nrf52840.conf | 10 +++++ .../boards/nrf21540dk_nrf52840.overlay | 16 ++++++++ samples/matter/light_switch/sample.yaml | 3 +- samples/matter/lock/CMakeLists.txt | 6 ++- samples/matter/lock/README.rst | 10 ++++- .../lock/boards/nrf21540dk_nrf52840.conf | 10 +++++ .../lock/boards/nrf21540dk_nrf52840.overlay | 16 ++++++++ samples/matter/lock/sample.yaml | 3 +- samples/matter/template/README.rst | 12 +++++- .../template/boards/nrf21540dk_nrf52840.conf | 10 +++++ .../boards/nrf21540dk_nrf52840.overlay | 16 ++++++++ samples/matter/template/sample.yaml | 3 +- 19 files changed, 185 insertions(+), 10 deletions(-) create mode 100644 samples/matter/light_bulb/boards/nrf21540dk_nrf52840.conf create mode 100644 samples/matter/light_bulb/boards/nrf21540dk_nrf52840.overlay create mode 100644 samples/matter/light_switch/boards/nrf21540dk_nrf52840.conf create mode 100644 samples/matter/light_switch/boards/nrf21540dk_nrf52840.overlay create mode 100644 samples/matter/lock/boards/nrf21540dk_nrf52840.conf create mode 100644 samples/matter/lock/boards/nrf21540dk_nrf52840.overlay create mode 100644 samples/matter/template/boards/nrf21540dk_nrf52840.conf create mode 100644 samples/matter/template/boards/nrf21540dk_nrf52840.overlay diff --git a/doc/nrf/releases/release-notes-changelog.rst b/doc/nrf/releases/release-notes-changelog.rst index 48a6a1f9485c..ed05c4c61127 100644 --- a/doc/nrf/releases/release-notes-changelog.rst +++ b/doc/nrf/releases/release-notes-changelog.rst @@ -96,6 +96,7 @@ Matter * :ref:`Thngy:53 Weather station ` application. * :ref:`Template ` sample with a guide about :ref:`ug_matter_creating_accessory`. * :ref:`ug_matter_tools` page with information about building options for Matter controllers. + * PA/LNA GPIO interface support for RF front-end modules (FEM) in Matter. Zigbee ------ diff --git a/samples/matter/light_bulb/CMakeLists.txt b/samples/matter/light_bulb/CMakeLists.txt index 39be6d5fda84..9f84207d96fc 100644 --- a/samples/matter/light_bulb/CMakeLists.txt +++ b/samples/matter/light_bulb/CMakeLists.txt @@ -9,7 +9,11 @@ cmake_minimum_required(VERSION 3.13.1) option(BUILD_WITH_DFU "Build target with Device Firmware Upgrade support" OFF) if(BUILD_WITH_DFU) list(INSERT OVERLAY_CONFIG 0 ${CMAKE_CURRENT_SOURCE_DIR}/../common/config/overlay-dfu_support.conf) - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml") + set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) + else() + message(FATAL_ERROR "The ${BOARD} target does not support DFU") + endif() if(${BOARD} STREQUAL "nrf5340dk_nrf5340_cpuapp") list(INSERT OVERLAY_CONFIG 0 ${CMAKE_CURRENT_SOURCE_DIR}/../common/config/overlay-dfu_nrf53_extension.conf) endif() diff --git a/samples/matter/light_bulb/README.rst b/samples/matter/light_bulb/README.rst index f468cf0da2e8..8e4a4d5cd069 100644 --- a/samples/matter/light_bulb/README.rst +++ b/samples/matter/light_bulb/README.rst @@ -23,7 +23,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf52840dk_nrf52840, nrf5340dk_nrf5340_cpuapp + :rows: nrf52840dk_nrf52840, nrf5340dk_nrf5340_cpuapp, nrf21540dk_nrf52840 For remote testing scenarios, you also need the following: @@ -78,6 +78,11 @@ Device Firmware Upgrade support :start-after: matter_door_lock_sample_build_with_dfu_start :end-before: matter_door_lock_sample_build_with_dfu_end +FEM support +=========== + +.. include:: /includes/sample_fem_support.txt + User interface ************** diff --git a/samples/matter/light_bulb/boards/nrf21540dk_nrf52840.conf b/samples/matter/light_bulb/boards/nrf21540dk_nrf52840.conf new file mode 100644 index 000000000000..4cbd0e90c3af --- /dev/null +++ b/samples/matter/light_bulb/boards/nrf21540dk_nrf52840.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Enable Thread 1.2 features +CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y +CONFIG_OPENTHREAD_DUA=y +CONFIG_OPENTHREAD_MLR=y diff --git a/samples/matter/light_bulb/boards/nrf21540dk_nrf52840.overlay b/samples/matter/light_bulb/boards/nrf21540dk_nrf52840.overlay new file mode 100644 index 000000000000..a5f34bdd2657 --- /dev/null +++ b/samples/matter/light_bulb/boards/nrf21540dk_nrf52840.overlay @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + /* + * In some default configurations within the nRF Connect SDK, + * e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell. + * This devicetree overlay ensures that default is overridden wherever it + * is set, as this application uses the RNG node for entropy exclusively. + */ + + chosen { + zephyr,entropy = &rng; + }; + + /* + * By default, PWM module is only configured for led0 (LED1 on the board). + * The lighting-app, however, uses LED2 to show the state of the lighting, + * including its brightness level. + */ + aliases { + pwm-led1 = &pwm_led1; + }; + + pwmleds { + pwm_led1: pwm_led_1 { + pwms = < &pwm0 0xe >; + }; + }; + +}; + +&pwm0 { + /delete-property/ ch0-pin; + /delete-property/ ch0-inverted; + ch1-pin = < 0xe >; + ch1-inverted; +}; diff --git a/samples/matter/light_bulb/sample.yaml b/samples/matter/light_bulb/sample.yaml index da12306c0ead..2de6c5a4b230 100644 --- a/samples/matter/light_bulb/sample.yaml +++ b/samples/matter/light_bulb/sample.yaml @@ -4,8 +4,9 @@ sample: tests: matter.light_bulb: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp + platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp nrf21540dk_nrf52840 integration_platforms: - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp + - nrf21540dk_nrf52840 tags: ci_build diff --git a/samples/matter/light_switch/README.rst b/samples/matter/light_switch/README.rst index dc93c12c59a1..93bd37fa6b11 100644 --- a/samples/matter/light_switch/README.rst +++ b/samples/matter/light_switch/README.rst @@ -19,7 +19,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf52840dk_nrf52840, nrf5340dk_nrf5340_cpuapp + :rows: nrf52840dk_nrf52840, nrf5340dk_nrf5340_cpuapp, nrf21540dk_nrf52840 For this sample to work, you also need the :ref:`Matter light bulb ` sample programmed to another supported development kit. @@ -50,6 +50,16 @@ After the test mode is activated and both devices are initialized with the same During this phase, the light bulb device periodically sends multicast messages with static content. Once such a message is intercepted by the light switch device, the light switch is made aware of the IP address of the nearby light bulb device and the pairing is done. +Configuration +************* + +|config| + +FEM support +=========== + +.. include:: /includes/sample_fem_support.txt + User interface ************** diff --git a/samples/matter/light_switch/boards/nrf21540dk_nrf52840.conf b/samples/matter/light_switch/boards/nrf21540dk_nrf52840.conf new file mode 100644 index 000000000000..4cbd0e90c3af --- /dev/null +++ b/samples/matter/light_switch/boards/nrf21540dk_nrf52840.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Enable Thread 1.2 features +CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y +CONFIG_OPENTHREAD_DUA=y +CONFIG_OPENTHREAD_MLR=y diff --git a/samples/matter/light_switch/boards/nrf21540dk_nrf52840.overlay b/samples/matter/light_switch/boards/nrf21540dk_nrf52840.overlay new file mode 100644 index 000000000000..6dcf38dbaf8f --- /dev/null +++ b/samples/matter/light_switch/boards/nrf21540dk_nrf52840.overlay @@ -0,0 +1,16 @@ +/* Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + /* + * In some default configurations within the nRF Connect SDK, + * e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell. + * This devicetree overlay ensures that default is overridden wherever it + * is set, as this application uses the RNG node for entropy exclusively. + */ + chosen { + zephyr,entropy = &rng; + }; +}; diff --git a/samples/matter/light_switch/sample.yaml b/samples/matter/light_switch/sample.yaml index 81c18bdf6f7f..32186a410dfa 100644 --- a/samples/matter/light_switch/sample.yaml +++ b/samples/matter/light_switch/sample.yaml @@ -4,8 +4,9 @@ sample: tests: matter.light_switch: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp + platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp nrf21540dk_nrf52840 integration_platforms: - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp + - nrf21540dk_nrf52840 tags: ci_build diff --git a/samples/matter/lock/CMakeLists.txt b/samples/matter/lock/CMakeLists.txt index 6ff7389d779e..ecb925e6d922 100644 --- a/samples/matter/lock/CMakeLists.txt +++ b/samples/matter/lock/CMakeLists.txt @@ -9,7 +9,11 @@ cmake_minimum_required(VERSION 3.13.1) option(BUILD_WITH_DFU "Build target with Device Firmware Upgrade support" OFF) if(BUILD_WITH_DFU) list(INSERT OVERLAY_CONFIG 0 ${CMAKE_CURRENT_SOURCE_DIR}/../common/config/overlay-dfu_support.conf) - set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml") + set(PM_STATIC_YML_FILE ${CMAKE_CURRENT_SOURCE_DIR}/configuration/${BOARD}/pm_static.yml) + else() + message(FATAL_ERROR "The ${BOARD} target does not support DFU") + endif() if(${BOARD} STREQUAL "nrf5340dk_nrf5340_cpuapp") list(INSERT OVERLAY_CONFIG 0 ${CMAKE_CURRENT_SOURCE_DIR}/../common/config/overlay-dfu_nrf53_extension.conf) endif() diff --git a/samples/matter/lock/README.rst b/samples/matter/lock/README.rst index 672b44faf44c..565b043989ab 100644 --- a/samples/matter/lock/README.rst +++ b/samples/matter/lock/README.rst @@ -19,7 +19,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf52840dk_nrf52840, nrf5340dk_nrf5340_cpuapp + :rows: nrf52840dk_nrf52840, nrf5340dk_nrf5340_cpuapp, nrf21540dk_nrf52840 For remote testing scenarios, if you want to commission the lock device and :ref:`control it remotely ` through a Thread network, you also need a Matter controller device :ref:`configured on PC or smartphone ` (which requires additional hardware depending on which setup you choose). @@ -77,6 +77,9 @@ Device Firmware Upgrade support .. matter_door_lock_sample_build_with_dfu_start +.. note:: + Over-the-air Device Firmware Upgrade can be enabled only on hardware platforms containing external flash memory. + You can configure the sample to use the secure bootloader for performing over-the-air Device Firmware Upgrade using Bluetooth® LE, using the following build flags during the build process: * ``-DOVERLAY_CONFIG=../common/config/overlay-dfu_support.conf`` @@ -93,6 +96,11 @@ For example, when building on the command line, run the following command with * .. matter_door_lock_sample_build_with_dfu_end +FEM support +=========== + +.. include:: /includes/sample_fem_support.txt + User interface ************** diff --git a/samples/matter/lock/boards/nrf21540dk_nrf52840.conf b/samples/matter/lock/boards/nrf21540dk_nrf52840.conf new file mode 100644 index 000000000000..4cbd0e90c3af --- /dev/null +++ b/samples/matter/lock/boards/nrf21540dk_nrf52840.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Enable Thread 1.2 features +CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y +CONFIG_OPENTHREAD_DUA=y +CONFIG_OPENTHREAD_MLR=y diff --git a/samples/matter/lock/boards/nrf21540dk_nrf52840.overlay b/samples/matter/lock/boards/nrf21540dk_nrf52840.overlay new file mode 100644 index 000000000000..6dcf38dbaf8f --- /dev/null +++ b/samples/matter/lock/boards/nrf21540dk_nrf52840.overlay @@ -0,0 +1,16 @@ +/* Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + /* + * In some default configurations within the nRF Connect SDK, + * e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell. + * This devicetree overlay ensures that default is overridden wherever it + * is set, as this application uses the RNG node for entropy exclusively. + */ + chosen { + zephyr,entropy = &rng; + }; +}; diff --git a/samples/matter/lock/sample.yaml b/samples/matter/lock/sample.yaml index a81e3f9a5392..be1ad3e69cc3 100644 --- a/samples/matter/lock/sample.yaml +++ b/samples/matter/lock/sample.yaml @@ -4,8 +4,9 @@ sample: tests: matter.lock: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp + platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp nrf21540dk_nrf52840 integration_platforms: - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp + - nrf21540dk_nrf52840 tags: ci_build diff --git a/samples/matter/template/README.rst b/samples/matter/template/README.rst index b6197f0ef937..7a02261c66cf 100644 --- a/samples/matter/template/README.rst +++ b/samples/matter/template/README.rst @@ -20,7 +20,7 @@ The sample supports the following development kits: .. table-from-rows:: /includes/sample_board_rows.txt :header: heading - :rows: nrf52840dk_nrf52840, nrf5340dk_nrf5340_cpuapp + :rows: nrf52840dk_nrf52840, nrf5340dk_nrf5340_cpuapp, nrf21540dk_nrf52840 For testing purposes, that is to commission the device and :ref:`control it remotely ` through a Thread network, you also need a Matter controller device :ref:`configured on PC or smartphone ` (which requires additional hardware depending on which setup you choose). @@ -58,6 +58,16 @@ As a result, the device can join the Thread network and communicate with other T To start the commissioning procedure, the controller must get the commissioning information from the Matter accessory device. The data payload, which includes the device discriminator and setup PIN code, is encoded within a QR code, printed to the UART console. +Configuration +************* + +|config| + +FEM support +=========== + +.. include:: /includes/sample_fem_support.txt + User interface ************** diff --git a/samples/matter/template/boards/nrf21540dk_nrf52840.conf b/samples/matter/template/boards/nrf21540dk_nrf52840.conf new file mode 100644 index 000000000000..4cbd0e90c3af --- /dev/null +++ b/samples/matter/template/boards/nrf21540dk_nrf52840.conf @@ -0,0 +1,10 @@ +# +# Copyright (c) 2021 Nordic Semiconductor ASA +# +# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause +# + +# Enable Thread 1.2 features +CONFIG_OPENTHREAD_THREAD_VERSION_1_2=y +CONFIG_OPENTHREAD_DUA=y +CONFIG_OPENTHREAD_MLR=y diff --git a/samples/matter/template/boards/nrf21540dk_nrf52840.overlay b/samples/matter/template/boards/nrf21540dk_nrf52840.overlay new file mode 100644 index 000000000000..6dcf38dbaf8f --- /dev/null +++ b/samples/matter/template/boards/nrf21540dk_nrf52840.overlay @@ -0,0 +1,16 @@ +/* Copyright (c) 2021 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/ { + /* + * In some default configurations within the nRF Connect SDK, + * e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell. + * This devicetree overlay ensures that default is overridden wherever it + * is set, as this application uses the RNG node for entropy exclusively. + */ + chosen { + zephyr,entropy = &rng; + }; +}; diff --git a/samples/matter/template/sample.yaml b/samples/matter/template/sample.yaml index ab3a253c5a28..36c9214d16dd 100644 --- a/samples/matter/template/sample.yaml +++ b/samples/matter/template/sample.yaml @@ -4,8 +4,9 @@ sample: tests: matter.template: build_only: true - platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp + platform_allow: nrf52840dk_nrf52840 nrf5340dk_nrf5340_cpuapp nrf21540dk_nrf52840 integration_platforms: - nrf52840dk_nrf52840 - nrf5340dk_nrf5340_cpuapp + - nrf21540dk_nrf52840 tags: ci_build