From 8d42faba6e4850d863110a5c9d51d19b4ba8010b Mon Sep 17 00:00:00 2001 From: Jun Qing Zou Date: Wed, 25 Oct 2023 14:25:20 +0900 Subject: [PATCH] application: serial_lte_modem: Automatic LTE connection Move the lte auto-connect from SLM LwM2M client to full SLM scope. Support lte auto-connnect by new Kconfig CONFIG_SLM_AUTO_CONNECT. Default behavior is no automatic LTE connection, same as before. When auto-connect is enabled, need to customize network-specific PDN configuration in code. Default is Non-IP in NB-IoT for NIDD. Impact on LwM2M client: .Operation "auto_connect" is removed from LwM2M command. .No more dynamic config of auto_connect (and auto_register). .CONFIG_SLM_AUTO_CONNECT is enabled by default in overlay. Change CONFIG_SLM_CUSTOMIZED to CONFIG_SLM_CUSTOMER_VERSION to allow reporting customer version of SLM after customization. Remove unused CONFIG_SLM_AT_MODE and CONFIG_SLM_SOCKET_RX_MAX. Signed-off-by: Jun Qing Zou --- applications/serial_lte_modem/Kconfig | 23 +++----- .../doc/Generic_AT_commands.rst | 14 +++-- .../serial_lte_modem/doc/slm_description.rst | 35 ++++++++---- .../serial_lte_modem/overlay-carrier.conf | 9 +--- applications/serial_lte_modem/prj.conf | 6 ++- .../src/lwm2m_carrier/slm_at_carrier.c | 35 ------------ .../src/lwm2m_carrier/slm_at_carrier.h | 4 -- applications/serial_lte_modem/src/main.c | 53 ++++++++++++++----- .../serial_lte_modem/src/slm_at_commands.c | 9 +++- .../serial_lte_modem/src/slm_auto_connect.h | 22 ++++++++ .../serial_lte_modem/src/slm_settings.c | 34 ------------ .../serial_lte_modem/src/twi/slm_at_twi.c | 4 -- .../releases/release-notes-changelog.rst | 7 +++ 13 files changed, 125 insertions(+), 130 deletions(-) create mode 100644 applications/serial_lte_modem/src/slm_auto_connect.h diff --git a/applications/serial_lte_modem/Kconfig b/applications/serial_lte_modem/Kconfig index 0bafdac98cf5..d3fbbe0cb073 100644 --- a/applications/serial_lte_modem/Kconfig +++ b/applications/serial_lte_modem/Kconfig @@ -8,16 +8,10 @@ source "Kconfig.zephyr" menu "Nordic Serial LTE Modem" -config SLM_CUSTOMIZED - bool "Flag for customized functionality" +config SLM_CUSTOMER_VERSION + string "Customer version string" help - Enable this flag to include customized logic. - -config SLM_AT_MODE - bool "Serial LTE Modem by raw AT mode" - default y - select AT_CMD_PARSER - select AT_MONITOR + This version is reported together with baseline versions by AT command "#XSLMVER". config SLM_AT_MAX_PARAM int "Maximum number of parameters in AT command" @@ -104,15 +98,12 @@ config SLM_INDICATE_TIME GPIO active indication time in milliseconds. This setting specify the period length for the pin to be active # -# Socket +# LTE network automatic attach # -config SLM_SOCKET_RX_MAX - int "Maximum RX buffer size for receiving socket data" - range 576 708 - default 576 +config SLM_AUTO_CONNECT + bool "Automatically connect to the LTE network on start-up or after a reset" help - Default: NET_IPV4_MTU (576) - Maximum: MSS setting in modem (708) + Enables automatic connection to the LTE network using the PDN configuration defined in 'slm_auto_connect.h'. # # TCP/TLS proxy diff --git a/applications/serial_lte_modem/doc/Generic_AT_commands.rst b/applications/serial_lte_modem/doc/Generic_AT_commands.rst index 6acc64543b35..15773123d425 100644 --- a/applications/serial_lte_modem/doc/Generic_AT_commands.rst +++ b/applications/serial_lte_modem/doc/Generic_AT_commands.rst @@ -32,11 +32,13 @@ Response syntax :: - #XSLMVER: , + #XSLMVER: ,[,] -The ```` value returns a string containing the version of the |NCS|. +The ```` value is a string containing the version of the |NCS|. -The ```` value returns a string containing the version of the modem library. +The ```` value is a string containing the version of the modem library. + +The ```` value is the :ref:`CONFIG_SLM_CUSTOMER_VERSION ` string, if defined. Example ~~~~~~~ @@ -46,7 +48,11 @@ The following command example reads the versions: :: AT#XSLMVER - #XSLMVER: "2.3.0","2.3.0" + #XSLMVER: "2.5.0","2.5.0-lte-5ccd2d4dd54c" + OK + + AT#XSLMVER + #XSLMVER: "2.5.99","2.5.0-lte-5ccd2d4dd54c","Onomondo 2.1.0" OK Read command diff --git a/applications/serial_lte_modem/doc/slm_description.rst b/applications/serial_lte_modem/doc/slm_description.rst index c120ab5c4b82..0d1250fb8eda 100644 --- a/applications/serial_lte_modem/doc/slm_description.rst +++ b/applications/serial_lte_modem/doc/slm_description.rst @@ -43,11 +43,11 @@ Configuration options Check and configure the following configuration options for the sample: -.. _CONFIG_SLM_CUSTOMIZED: +.. _CONFIG_SLM_CUSTOMER_VERSION: -CONFIG_SLM_CUSTOMIZED - Flag for customized functionality - This flag can be used to enable customized functionality. - To add your own custom logic, enclose the code by ``#if defined(CONFIG_SLM_CUSTOMIZED)`` and enable this flag. +CONFIG_SLM_CUSTOMER_VERSION - Customer version string + Version string defined by the customer after customizing the application. + When defined, this version is reported with the baseline versions by the ``#XSLMVER`` AT command. .. _CONFIG_SLM_AT_MAX_PARAM: @@ -124,14 +124,29 @@ CONFIG_SLM_INDICATE_TIME - Indicate GPIO active time This option specifies the length, in milliseconds, of the time interval during which the indicate GPIO must stay active. The default value is 100 milliseconds. -.. _CONFIG_SLM_SOCKET_RX_MAX: +.. _CONFIG_SLM_AUTO_CONNECT: -CONFIG_SLM_SOCKET_RX_MAX - Maximum RX buffer size for receiving socket data - This option specifies the maximum buffer size for receiving data through the socket interface. - By default, this size is set to :c:enumerator:`NET_IPV4_MTU` (576), which is defined in Zephyr. - The maximum value is 708, which is the maximum segment size (MSS) defined for the modem. +CONFIG_SLM_AUTO_CONNECT - Connect to LTE network at start-up or reset + This option enables connecting to the LTE network at start-up or reset using a defined PDN configuration. + This option is enabled by the LwM2M Carrier overlay, but is otherwise disabled by default. - This option impacts the total RAM usage. + .. note:: + This option requires network-specific configuration in the ``slm_auto_connect.h`` file. + + Here is a sample configuration for NIDD connection in the :file:`slm_auto_connect.h` file:: + + /* Network-specific default system mode configured by %XSYSTEMMODE (refer to AT command manual) */ + 0, /* LTE support */ + 1, /* NB-IoT support */ + 0, /* GNSS support, also define CONFIG_MODEM_ANTENNA if not Nordic DK */ + 0, /* LTE preference */ + /* Network-specific default PDN configured by +CGDCONT and +CGAUTH (refer to AT command manual) */ + true, /* PDP context definition required or not */ + "Non-IP", /* PDP type: "IP", "IPV6", "IPV4V6", "Non-IP" */ + "", /* Access point name */ + 0, /* PDP authentication protocol: 0(None), 1(PAP), 2(CHAP) */ + "", /* PDN connection authentication username */ + "" /* PDN connection authentication password */ .. _CONFIG_SLM_CR_TERMINATION: diff --git a/applications/serial_lte_modem/overlay-carrier.conf b/applications/serial_lte_modem/overlay-carrier.conf index 46646bbc3a75..6d16d54dfadb 100644 --- a/applications/serial_lte_modem/overlay-carrier.conf +++ b/applications/serial_lte_modem/overlay-carrier.conf @@ -25,12 +25,7 @@ CONFIG_AT_HOST_LIBRARY=n # Credential management CONFIG_MODEM_KEY_MGMT=y -# Non-volatile Storage -CONFIG_NVS=y -CONFIG_MPU_ALLOW_FLASH_WRITE=y - -# Default partition for NVS is unused -CONFIG_PM_PARTITION_SIZE_NVS_STORAGE=0 - # Enable LwM2M carrier support in SLM CONFIG_SLM_CARRIER=y +CONFIG_SLM_AUTO_CONNECT=y +CONFIG_SLM_CUSTOMER_VERSION="lwm2m_carrier" diff --git a/applications/serial_lte_modem/prj.conf b/applications/serial_lte_modem/prj.conf index cfa7ce4e161d..8a364158ac8c 100644 --- a/applications/serial_lte_modem/prj.conf +++ b/applications/serial_lte_modem/prj.conf @@ -98,10 +98,14 @@ CONFIG_MODEM_JWT=y #CONFIG_MQTT_KEEPALIVE=60 CONFIG_MQTT_CLEAN_SESSION=y +# AT command helper libraries +CONFIG_AT_CMD_PARSER=y +CONFIG_AT_MONITOR=y + # # SLM-specific configurations # -CONFIG_SLM_CUSTOMIZED=n +CONFIG_SLM_CUSTOMER_VERSION="" CONFIG_SLM_EXTERNAL_XTAL=n CONFIG_SLM_START_SLEEP=n CONFIG_SLM_DATAMODE_URC=n diff --git a/applications/serial_lte_modem/src/lwm2m_carrier/slm_at_carrier.c b/applications/serial_lte_modem/src/lwm2m_carrier/slm_at_carrier.c index 0b46459ded4a..81aa33a09420 100644 --- a/applications/serial_lte_modem/src/lwm2m_carrier/slm_at_carrier.c +++ b/applications/serial_lte_modem/src/lwm2m_carrier/slm_at_carrier.c @@ -18,8 +18,6 @@ LOG_MODULE_REGISTER(slm_carrier, CONFIG_SLM_LOG_LEVEL); /**@brief LwM2M Carrier operations. */ enum slm_carrier_operation { - /* LTE auto-connect operation for LwM2M Carrier */ - CARRIER_OP_AUTO_CONNECT, /* Carrier AppData Operation */ CARRIER_OP_APPDATA_SEND, /* Carrier Device Operation */ @@ -60,7 +58,6 @@ struct carrier_op_list { static int m_mem_free; /** forward declaration of cmd handlers **/ -static int do_carrier_auto_connect(void); static int do_carrier_appdata_send(void); static int do_carrier_device_battery_level(void); static int do_carrier_device_battery_status(void); @@ -84,7 +81,6 @@ static int do_carrier_request_link_up(void); /**@brief SLM AT Command list type. */ static struct carrier_op_list op_list[CARRIER_OP_MAX] = { - {CARRIER_OP_AUTO_CONNECT, "auto_connect", do_carrier_auto_connect}, {CARRIER_OP_APPDATA_SEND, "app_data", do_carrier_appdata_send}, {CARRIER_OP_DEVICE_BATTERY_LEVEL, "battery_level", do_carrier_device_battery_level}, {CARRIER_OP_DEVICE_BATTERY_STATUS, "battery_status", do_carrier_device_battery_status}, @@ -839,37 +835,6 @@ static int do_carrier_request_link_up(void) return lwm2m_carrier_request(LWM2M_CARRIER_REQUEST_LINK_UP); } -/* AT#XCARRIER="auto_connect","read|write"[,] */ -static int do_carrier_auto_connect(void) -{ - int ret = 0; - int flag; - char operation[6]; - size_t size = sizeof(operation); - - ret = util_string_get(&slm_at_param_list, 2, operation, &size); - if (ret) { - return ret; - } - - if (slm_util_cmd_casecmp(operation, "READ")) { - rsp_send("\r\n#XCARRIER: auto_connect %d\r\n", slm_carrier_auto_connect); - } else if (slm_util_cmd_casecmp(operation, "WRITE")) { - ret = at_params_int_get(&slm_at_param_list, 3, &flag); - if (ret) { - return ret; - } - if (flag == 0 || flag == 1) { - slm_carrier_auto_connect = flag; - (void)slm_settings_auto_connect_save(); - } else { - ret = -EINVAL; - } - } - - return ret; -} - /**@brief API to handle Carrier AT command */ int handle_at_carrier(enum at_cmd_type cmd_type) diff --git a/applications/serial_lte_modem/src/lwm2m_carrier/slm_at_carrier.h b/applications/serial_lte_modem/src/lwm2m_carrier/slm_at_carrier.h index f3a2cb126ab8..3dfb7d732b4f 100644 --- a/applications/serial_lte_modem/src/lwm2m_carrier/slm_at_carrier.h +++ b/applications/serial_lte_modem/src/lwm2m_carrier/slm_at_carrier.h @@ -14,10 +14,6 @@ * @brief Vendor-specific AT command for LwM2M Carrier service. * @{ */ - -/* Whether to auto-connect to the network at startup or after a FOTA update. */ -extern int32_t slm_carrier_auto_connect; - /** * @brief Initialize Carrier AT command parser. * diff --git a/applications/serial_lte_modem/src/main.c b/applications/serial_lte_modem/src/main.c index db9ed8165867..bf7a18ec0b08 100644 --- a/applications/serial_lte_modem/src/main.c +++ b/applications/serial_lte_modem/src/main.c @@ -26,9 +26,7 @@ #include "slm_at_fota.h" #include "slm_settings.h" #include "slm_uart_handler.h" -#if defined(CONFIG_SLM_CARRIER) -#include "slm_at_carrier.h" -#endif +#include "slm_util.h" LOG_MODULE_REGISTER(slm, CONFIG_SLM_LOG_LEVEL); @@ -338,32 +336,59 @@ static void check_app_fota_status(void) int lte_auto_connect(void) { int err = 0; - -#if defined(CONFIG_SLM_CARRIER) +#if defined(CONFIG_SLM_AUTO_CONNECT) int stat; + struct network_config { + /* Refer to AT command manual of %XSYSTEMMODE for system mode settings */ + int lte_m_support; /* 0 ~ 1 */ + int nb_iot_support; /* 0 ~ 1 */ + int gnss_support; /* 0 ~ 1 */ + int lte_preference; /* 0 ~ 4 */ + /* Refer to AT command manual of +CGDCONT and +CGAUTH for PDN configuration */ + bool pdp_config; /* PDP context definition required or not */ + char *pdn_fam; /* PDP type: "IP", "IPV6", "IPV4V6", "Non-IP" */ + char *pdn_apn; /* Access point name */ + int pdn_auth; /* PDN authentication protocol 0(None), 1(PAP), 2(CHAP) */ + char *pdn_username; /* PDN connection authentication username */ + char *pdn_password; /* PDN connection authentication password */ + }; + const struct network_config cfg = { +#include "slm_auto_connect.h" + }; - if (!slm_carrier_auto_connect) { - return 0; - } err = nrf_modem_at_scanf("AT+CEREG?", "+CEREG: %d", &stat); if (err != 1 || (stat == 1 || stat == 5)) { return 0; } - LOG_INF("auto connect"); -#if defined(CONFIG_LWM2M_CARRIER_SERVER_BINDING_N) - err = nrf_modem_at_printf("AT%%XSYSTEMMODE=0,1,0,0"); + LOG_INF("lte auto connect"); + err = nrf_modem_at_printf("AT%%XSYSTEMMODE=%d,%d,%d,%d", cfg.lte_m_support, + cfg.nb_iot_support, cfg.gnss_support, cfg.lte_preference); if (err) { - LOG_ERR("Failed to configure RAT: %d", err); + LOG_ERR("Failed to configure system mode: %d", err); return err; } -#endif /* CONFIG_LWM2M_CARRIER_SERVER_BINDING_N */ + if (cfg.pdp_config) { + err = nrf_modem_at_printf("AT+CGDCONT=0,%s,%s", cfg.pdn_fam, cfg.pdn_apn); + if (err) { + LOG_ERR("Failed to configure PDN: %d", err); + return err; + } + } + if (cfg.pdp_config && cfg.pdn_auth != 0) { + err = nrf_modem_at_printf("AT+CGAUTH=0,%d,%s,%s", cfg.pdn_auth, + cfg.pdn_username, cfg.pdn_password); + if (err) { + LOG_ERR("Failed to configure AUTH: %d", err); + return err; + } + } err = nrf_modem_at_printf("AT+CFUN=1"); if (err) { LOG_ERR("Failed to turn on radio: %d", err); return err; } -#endif /* CONFIG_SLM_CARRIER */ +#endif /* CONFIG_SLM_AUTO_CONNECT */ return err; } diff --git a/applications/serial_lte_modem/src/slm_at_commands.c b/applications/serial_lte_modem/src/slm_at_commands.c index 7cac684e0de0..dcbfe10a5a0e 100644 --- a/applications/serial_lte_modem/src/slm_at_commands.c +++ b/applications/serial_lte_modem/src/slm_at_commands.c @@ -116,7 +116,14 @@ static int handle_at_slmver(enum at_cmd_type type) if (type == AT_CMD_TYPE_SET_COMMAND) { char *libmodem = nrf_modem_build_version(); - rsp_send("\r\n#XSLMVER: %s,\"%s\"\r\n", STRINGIFY(NCS_VERSION_STRING), libmodem); + if (strlen(CONFIG_SLM_CUSTOMER_VERSION) > 0) { + rsp_send("\r\n#XSLMVER: %s,\"%s\",\"%s\"\r\n", + STRINGIFY(NCS_VERSION_STRING), libmodem, + CONFIG_SLM_CUSTOMER_VERSION); + } else { + rsp_send("\r\n#XSLMVER: %s,\"%s\"\r\n", + STRINGIFY(NCS_VERSION_STRING), libmodem); + } ret = 0; } diff --git a/applications/serial_lte_modem/src/slm_auto_connect.h b/applications/serial_lte_modem/src/slm_auto_connect.h new file mode 100644 index 000000000000..03296e8e58a7 --- /dev/null +++ b/applications/serial_lte_modem/src/slm_auto_connect.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause + */ + +/* + * This file defines the network configuration when CONFIG_SLM_AUTO_CONNECT is enabled. + */ + +/* Network-specific default system mode configured by %XSYSTEMMODE (refer to AT command manual) */ +1, /* LTE support */ +1, /* NB-IoT support */ +1, /* GNSS support, also define CONFIG_MODEM_ANTENNA if not Nordic DK */ +0, /* LTE preference */ +/* Network-specific default PDN configured by +CGDCONT and +CGAUTH (refer to AT command manual) */ +false, /* PDP context definition required or not */ +"", /* PDP type: "IP", "IPV6", "IPV4V6", "Non-IP" */ +"", /* Access point name */ +0, /* PDP authentication protocol: 0(None), 1(PAP), 2(CHAP) */ +"", /* PDN connection authentication username */ +"" /* PDN connection authentication password */ diff --git a/applications/serial_lte_modem/src/slm_settings.c b/applications/serial_lte_modem/src/slm_settings.c index f711d253932a..5d5a8ae4fc5a 100644 --- a/applications/serial_lte_modem/src/slm_settings.c +++ b/applications/serial_lte_modem/src/slm_settings.c @@ -11,19 +11,9 @@ #include #include "slm_at_fota.h" #include "slm_settings.h" -#include "lwm2m_carrier/slm_at_carrier.h" LOG_MODULE_REGISTER(slm_settings, CONFIG_SLM_LOG_LEVEL); -/** - * Serial LTE Modem setting page for persistent data - */ - -#if defined(CONFIG_SLM_CARRIER) -#include "slm_at_carrier.h" -int32_t slm_carrier_auto_connect = 1; -#endif - static int settings_set(const char *name, size_t len, settings_read_cb read_cb, void *cb_arg) { if (!strcmp(name, "modem_full_fota")) { @@ -31,13 +21,6 @@ static int settings_set(const char *name, size_t len, settings_read_cb read_cb, return -EINVAL; if (read_cb(cb_arg, &slm_modem_full_fota, len) > 0) return 0; -#if defined(CONFIG_SLM_CARRIER) - } else if (!strcmp(name, "auto_connect")) { - if (len != sizeof(slm_carrier_auto_connect)) - return -EINVAL; - if (read_cb(cb_arg, &slm_carrier_auto_connect, len) > 0) - return 0; -#endif } /* Simply ignore obsolete settings that are not in use anymore. * settings_delete() does not completely remove settings. @@ -77,20 +60,3 @@ int slm_settings_fota_save(void) return settings_save_one("slm/modem_full_fota", &slm_modem_full_fota, sizeof(slm_modem_full_fota)); } - -#if defined(CONFIG_SLM_CARRIER) -int slm_settings_auto_connect_save(void) -{ - int ret; - - /* Write a single serialized value to persisted storage (if it has changed value). */ - ret = settings_save_one("slm/auto_connect", - &(slm_carrier_auto_connect), sizeof(slm_carrier_auto_connect)); - if (ret) { - LOG_ERR("save slm/auto_connect failed: %d", ret); - return ret; - } - - return 0; -} -#endif diff --git a/applications/serial_lte_modem/src/twi/slm_at_twi.c b/applications/serial_lte_modem/src/twi/slm_at_twi.c index a7993c320d36..d6a434f91853 100644 --- a/applications/serial_lte_modem/src/twi/slm_at_twi.c +++ b/applications/serial_lte_modem/src/twi/slm_at_twi.c @@ -17,10 +17,6 @@ LOG_MODULE_REGISTER(slm_twi, CONFIG_SLM_LOG_LEVEL); #define TWI_ADDR_LEN 2 #define TWI_DATA_LEN 255 -#if (TWI_DATA_LEN * 2) > (CONFIG_SLM_SOCKET_RX_MAX * 2) -# error "Please specify smaller TWI_DATA_LEN" -#endif - static const struct device *slm_twi_dev[] = { DEVICE_DT_GET_OR_NULL(DT_NODELABEL(i2c0)), DEVICE_DT_GET_OR_NULL(DT_NODELABEL(i2c1)), diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 11ef2af785d2..e924c0b220ab 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -169,10 +169,17 @@ Serial LTE modem * Added: * ``#XMQTTCFG`` AT command to configure MQTT client before connecting to the broker. + * The :ref:`CONFIG_SLM_AUTO_CONNECT ` Kconfig option to support automatic LTE connection at start-up or reset. + * The :ref:`CONFIG_SLM_CUSTOMER_VERSION ` Kconfig option for customers to define their own version string after customization. * Updated: * ``#XMQTTCON`` AT command to exclude MQTT client ID from the parameter list. + * ``#XSLMVER`` AT command to report CONFIG_SLM_CUSTOMER_VERSION if it is defined. + +* Removed: + * The ``CONFIG_SLM_CUSTOMIZED`` Kconfig option due to it no longer being used. + * The ``CONFIG_SLM_SOCKET_RX_MAX`` Kconfig option due to it no longer being used. nRF5340 Audio -------------