From e79428cda814d126eae53436c2a0dcf6d32c0e2c Mon Sep 17 00:00:00 2001 From: Bjarki Arge Andreasen Date: Fri, 24 May 2024 17:19:32 +0200 Subject: [PATCH] drivers: modem: remove gsm_ppp.c device driver Remove the deprecated gsm_ppp.c device driver and associated dts compatible. Signed-off-by: Bjarki Arge Andreasen --- doc/connectivity/networking/api/gsm_modem.rst | 22 - doc/connectivity/networking/api/index.rst | 1 - drivers/modem/CMakeLists.txt | 4 - drivers/modem/Kconfig | 1 - drivers/modem/Kconfig.gsm | 141 -- drivers/modem/gsm_ppp.c | 1362 ----------------- dts/bindings/modem/zephyr,gsm-ppp.yaml | 8 - include/zephyr/drivers/modem/gsm_ppp.h | 69 - 8 files changed, 1608 deletions(-) delete mode 100644 doc/connectivity/networking/api/gsm_modem.rst delete mode 100644 drivers/modem/Kconfig.gsm delete mode 100644 drivers/modem/gsm_ppp.c delete mode 100644 dts/bindings/modem/zephyr,gsm-ppp.yaml delete mode 100644 include/zephyr/drivers/modem/gsm_ppp.h diff --git a/doc/connectivity/networking/api/gsm_modem.rst b/doc/connectivity/networking/api/gsm_modem.rst deleted file mode 100644 index cf15e429796..00000000000 --- a/doc/connectivity/networking/api/gsm_modem.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. _gsm_modem: - -Generic GSM Modem -################# - -Overview -******** - -The generic GSM modem driver allows the user to connect Zephyr to a GSM modem -which provides a data connection to cellular operator's network. -The Zephyr uses :ref:`PPP (Point-to-Point Protocol) ` to connect -to the GSM modem using UART. Note that some cellular modems have proprietary -offloading support using AT commands, but usually those modems also support -3GPP standards and provide PPP connection to them. -See :zephyr:code-sample:`GSM modem sample application ` how to setup Zephyr -to use the GSM modem. - -The GSM muxing, that is defined in -`GSM 07.10 `__, -and which allows mixing of AT commands and PPP traffic, is also supported in -this version of Zephyr. One needs to enable :kconfig:option:`CONFIG_GSM_MUX` and -:kconfig:option:`CONFIG_UART_MUX` configuration options to enable muxing. diff --git a/doc/connectivity/networking/api/index.rst b/doc/connectivity/networking/api/index.rst index 1264ff2aafb..fd362492b3c 100644 --- a/doc/connectivity/networking/api/index.rst +++ b/doc/connectivity/networking/api/index.rst @@ -23,5 +23,4 @@ libraries for the application to use. See the list below for details. protocols.rst system_mgmt.rst tsn.rst - gsm_modem.rst zperf.rst diff --git a/drivers/modem/CMakeLists.txt b/drivers/modem/CMakeLists.txt index a97568dfc65..665dd961acd 100644 --- a/drivers/modem/CMakeLists.txt +++ b/drivers/modem/CMakeLists.txt @@ -27,10 +27,6 @@ if(CONFIG_MODEM_WNCM14A2A) zephyr_library_sources(wncm14a2a.c) endif() -if(CONFIG_MODEM_GSM_PPP) - zephyr_library_sources(gsm_ppp.c) -endif() - if (CONFIG_MODEM_HL7800) zephyr_library_sources(hl7800.c) endif() diff --git a/drivers/modem/Kconfig b/drivers/modem/Kconfig index 02e3557918f..dbc78f067d7 100644 --- a/drivers/modem/Kconfig +++ b/drivers/modem/Kconfig @@ -189,7 +189,6 @@ config MODEM_CELL_INFO source "drivers/modem/Kconfig.ublox-sara-r4" source "drivers/modem/Kconfig.quectel-bg9x" source "drivers/modem/Kconfig.wncm14a2a" -source "drivers/modem/Kconfig.gsm" source "drivers/modem/Kconfig.cellular" source "drivers/modem/Kconfig.hl7800" diff --git a/drivers/modem/Kconfig.gsm b/drivers/modem/Kconfig.gsm deleted file mode 100644 index 101c1e2ece4..00000000000 --- a/drivers/modem/Kconfig.gsm +++ /dev/null @@ -1,141 +0,0 @@ -# Copyright (c) 2020 Intel Corporation -# SPDX-License-Identifier: Apache-2.0 - -config MODEM_GSM_PPP - bool "[DEPRECATED] Support GSM modems" - select MODEM_CONTEXT - select MODEM_CMD_HANDLER - select MODEM_IFACE_UART - select NET_MGMT - select NET_MGMT_EVENT - select DEPRECATED - help - This driver is deprecated, use the MODEM_CELLULAR driver instead. - -if MODEM_GSM_PPP - -choice MODEM_GSM_TYPE - prompt "Modem type" - default MODEM_GSM_GENERIC - help - Type/manufacturer of the GSM modem - -config MODEM_GSM_GENERIC - bool "Generic GSM modem" - help - The modem does not need any special handling etc. - -config MODEM_GSM_SIMCOM - bool "SIMCOM modem" - help - Use this if you have SIMCOM based modem like SIM800 etc. - -config MODEM_GSM_QUECTEL - bool "Quectel modem" - help - Use this if you have Quectel based modem like EC2X etc. - -endchoice - -choice MODEM_GSM_STATUS_COMMAND - prompt "Select status command Type" - default MODEM_GSM_STATUS_CMD_USE_CREG - help - Use particular type of AT command for cell tower registration status. - -config MODEM_GSM_STATUS_CMD_USE_CREG - bool "CREG command" - -config MODEM_GSM_STATUS_CMD_USE_CEREG - bool "CEREG command" - -endchoice - -config MODEM_GSM_STATUS_COMMAND - string "Status Command" - default "CREG" if MODEM_GSM_STATUS_CMD_USE_CREG - default "CEREG" if MODEM_GSM_STATUS_CMD_USE_CEREG - -config MODEM_GSM_RX_STACK_SIZE - int "Size of the stack allocated for receiving data from modem" - default 512 - help - Sets the stack size which will be used by the GSM RX thread. - -config MODEM_GSM_WORKQ_STACK_SIZE - int "Size of the stack allocated for the dedicated gsm workqueue" - default 768 - help - Sets the stack size which will be used by the dedicated GSM workqueue - thread. - -config MODEM_GSM_INIT_PRIORITY - int "Init priority for the GSM modem driver" - default 60 - range 0 99 - help - The GSM modem is initialized in POST_KERNEL using priority in - the range 0-99. - -config MODEM_GSM_APN - string "Access Point Name" - default "internet" - help - Specify Access Point Name, i.e. the name to identify Internet IP - GPRS cellular data context. - -config GSM_PPP_AUTOSTART - bool "Auto-start PPP at boot" - default y - help - This setting lets driver connect to network and initialize PPP at - boot. Unselect this if you want to run application code before - modem connects to network. See contents of "drivers/gsm_ppp.h" - to get an idea of the API. - -config MODEM_GSM_ATTACH_TIMEOUT - int "Timeout for attaching to packet service" - default 30 - help - Before activating PPP, attachment to packet service is checked - using AT+CGATT. This setting dictates how much time in seconds - we give the modem before giving up. - -config MODEM_GSM_REGISTER_TIMEOUT - int "Timeout for registering to cellular tower" - default 300 - help - Before attachment to packet service, modem is checked if it is - connected to the cellular tower. This setting dictates how much - time in seconds we give the modem before giving up. - -config MODEM_GSM_MANUAL_MCCMNO - string "MCC/MNO for establishing network connection" - help - This setting is used in the AT+COPS command to set the MCC/MNO - for the network connection context. This value is specific to - the network provider and may need to be changed if auto is not - selected. - -config MODEM_GSM_RSSI_POLLING_PERIOD - int "Configure RSSI polling period (in seconds)" - default 30 - help - This settings is used to configure the period of RSSI polling - -config MODEM_GSM_ENABLE_CESQ_RSSI - bool "+CESQ RSSI measurement" - help - If this is enabled, RSRP, RSCP and RXREL values are read from the - modem with +CESQ. Otherwise only RSSI value is read with +CSQ - from the modem. - -config MODEM_GSM_FACTORY_RESET_AT_BOOT - bool "Factory reset modem at boot" - help - If this is enabled, the modem will be reset to factory default - settings first thing in the initialization sequence. This is - helpful if your modem has a tendency to get stuck due to cached - state. - -endif diff --git a/drivers/modem/gsm_ppp.c b/drivers/modem/gsm_ppp.c deleted file mode 100644 index 88ea47b832a..00000000000 --- a/drivers/modem/gsm_ppp.c +++ /dev/null @@ -1,1362 +0,0 @@ -/* - * Copyright (c) 2020 Intel Corporation - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#define DT_DRV_COMPAT zephyr_gsm_ppp - -#include -LOG_MODULE_REGISTER(modem_gsm, CONFIG_MODEM_LOG_LEVEL); - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "modem_context.h" -#include "modem_iface_uart.h" -#include "modem_cmd_handler.h" -#include "../console/gsm_mux.h" - -#include - -#define GSM_UART_NODE DT_INST_BUS(0) -#define GSM_CMD_READ_BUF 128 -#define GSM_CMD_AT_TIMEOUT K_SECONDS(2) -#define GSM_CMD_SETUP_TIMEOUT K_SECONDS(6) -/* GSM_CMD_LOCK_TIMEOUT should be longer than GSM_CMD_AT_TIMEOUT & GSM_CMD_SETUP_TIMEOUT, - * otherwise the gsm_ppp_stop might fail to lock tx. - */ -#define GSM_CMD_LOCK_TIMEOUT K_SECONDS(10) -#define GSM_RECV_MAX_BUF 30 -#define GSM_RECV_BUF_SIZE 128 -#define GSM_ATTACH_RETRY_DELAY_MSEC 1000 -#define GSM_REGISTER_DELAY_MSEC 1000 -#define GSM_RETRY_DELAY K_SECONDS(1) - -#define GSM_RSSI_RETRY_DELAY_MSEC 2000 -#define GSM_RSSI_RETRIES 10 -#define GSM_RSSI_INVALID -1000 - -#if defined(CONFIG_MODEM_GSM_ENABLE_CESQ_RSSI) - #define GSM_RSSI_MAXVAL 0 -#else - #define GSM_RSSI_MAXVAL -51 -#endif - -/* Modem network registration state */ -enum network_state { - GSM_NET_INIT = -1, - GSM_NET_NOT_REGISTERED, - GSM_NET_HOME_NETWORK, - GSM_NET_SEARCHING, - GSM_NET_REGISTRATION_DENIED, - GSM_NET_UNKNOWN, - GSM_NET_ROAMING, -}; - -static struct gsm_modem { - struct k_mutex lock; - const struct device *dev; - struct modem_context context; - - struct modem_cmd_handler_data cmd_handler_data; - uint8_t cmd_match_buf[GSM_CMD_READ_BUF]; - struct k_sem sem_response; - struct k_sem sem_if_down; - - struct modem_iface_uart_data gsm_data; - struct k_work_delayable gsm_configure_work; - char gsm_rx_rb_buf[PPP_MRU * 3]; - - uint8_t *ppp_recv_buf; - size_t ppp_recv_buf_len; - - enum gsm_ppp_state { - GSM_PPP_START, - GSM_PPP_WAIT_AT, - GSM_PPP_AT_RDY, - GSM_PPP_STATE_INIT, - GSM_PPP_STATE_CONTROL_CHANNEL = GSM_PPP_STATE_INIT, - GSM_PPP_STATE_PPP_CHANNEL, - GSM_PPP_STATE_AT_CHANNEL, - GSM_PPP_STATE_DONE, - GSM_PPP_SETUP = GSM_PPP_STATE_DONE, - GSM_PPP_REGISTERING, - GSM_PPP_ATTACHING, - GSM_PPP_ATTACHED, - GSM_PPP_SETUP_DONE, - GSM_PPP_STOP, - GSM_PPP_STATE_ERROR, - } state; - - const struct device *ppp_dev; - const struct device *at_dev; - const struct device *control_dev; - - struct net_if *iface; - - struct k_thread rx_thread; - struct k_work_q workq; - struct k_work_delayable rssi_work_handle; - struct gsm_ppp_modem_info minfo; - - enum network_state net_state; - - int retries; - bool modem_info_queried : 1; - - void *user_data; - - gsm_modem_power_cb modem_on_cb; - gsm_modem_power_cb modem_off_cb; - struct net_mgmt_event_callback gsm_mgmt_cb; -} modem; - -NET_BUF_POOL_DEFINE(gsm_recv_pool, GSM_RECV_MAX_BUF, GSM_RECV_BUF_SIZE, 0, NULL); -K_KERNEL_STACK_DEFINE(gsm_rx_stack, CONFIG_MODEM_GSM_RX_STACK_SIZE); -K_KERNEL_STACK_DEFINE(gsm_workq_stack, CONFIG_MODEM_GSM_WORKQ_STACK_SIZE); - -static inline void gsm_ppp_lock(struct gsm_modem *gsm) -{ - (void)k_mutex_lock(&gsm->lock, K_FOREVER); -} - -static inline void gsm_ppp_unlock(struct gsm_modem *gsm) -{ - (void)k_mutex_unlock(&gsm->lock); -} - -static inline int gsm_work_reschedule(struct k_work_delayable *dwork, k_timeout_t delay) -{ - return k_work_reschedule_for_queue(&modem.workq, dwork, delay); -} - -#if defined(CONFIG_MODEM_GSM_ENABLE_CESQ_RSSI) - /* helper macro to keep readability */ -#define ATOI(s_, value_, desc_) modem_atoi(s_, value_, desc_, __func__) - -/** - * @brief Convert string to long integer, but handle errors - * - * @param s: string with representation of integer number - * @param err_value: on error return this value instead - * @param desc: name the string being converted - * @param func: function where this is called (typically __func__) - * - * @retval return integer conversion on success, or err_value on error - */ -static int modem_atoi(const char *s, const int err_value, - const char *desc, const char *func) -{ - int ret; - char *endptr; - - ret = (int)strtol(s, &endptr, 10); - if ((endptr == NULL) || (*endptr != '\0')) { - LOG_ERR("bad %s '%s' in %s", s, - desc, func); - return err_value; - } - - return ret; -} -#endif - -static void gsm_rx(void *p1, void *p2, void *p3) -{ - ARG_UNUSED(p2); - ARG_UNUSED(p3); - - struct gsm_modem *gsm = p1; - LOG_DBG("starting"); - - while (true) { - modem_iface_uart_rx_wait(&gsm->context.iface, K_FOREVER); - - /* The handler will listen AT channel */ - modem_cmd_handler_process(&gsm->context.cmd_handler, &gsm->context.iface); - } -} - -MODEM_CMD_DEFINE(gsm_cmd_ok) -{ - (void)modem_cmd_handler_set_error(data, 0); - LOG_DBG("ok"); - k_sem_give(&modem.sem_response); - return 0; -} - -MODEM_CMD_DEFINE(gsm_cmd_error) -{ - (void)modem_cmd_handler_set_error(data, -EINVAL); - LOG_DBG("error"); - k_sem_give(&modem.sem_response); - return 0; -} - -/* Handler: +CME Error: [0] */ -MODEM_CMD_DEFINE(gsm_cmd_exterror) -{ - /* TODO: map extended error codes to values */ - (void)modem_cmd_handler_set_error(data, -EIO); - k_sem_give(&modem.sem_response); - return 0; -} - -static const struct modem_cmd response_cmds[] = { - MODEM_CMD("OK", gsm_cmd_ok, 0U, ""), - MODEM_CMD("ERROR", gsm_cmd_error, 0U, ""), - MODEM_CMD("+CME ERROR: ", gsm_cmd_exterror, 1U, ""), - MODEM_CMD("CONNECT", gsm_cmd_ok, 0U, ""), -}; - -static int unquoted_atoi(const char *s, int base) -{ - if (*s == '"') { - s++; - } - - return strtol(s, NULL, base); -} - -/* - * Handler: +COPS: [0],[1],[2] - */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_cops) -{ - if (argc >= 1) { -#if defined(CONFIG_MODEM_CELL_INFO) - if (argc >= 3) { - modem.context.data_operator = unquoted_atoi(argv[2], 10); - LOG_INF("operator: %u", - modem.context.data_operator); - } -#endif - if (unquoted_atoi(argv[0], 10) == 0) { - modem.context.is_automatic_oper = true; - } else { - modem.context.is_automatic_oper = false; - } - } - - return 0; -} - -/* - * Provide modem info if modem shell is enabled. This can be shown with - * "modem list" shell command. - */ - -/* Handler: */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_manufacturer) -{ - size_t out_len; - - out_len = net_buf_linearize(modem.minfo.mdm_manufacturer, - sizeof(modem.minfo.mdm_manufacturer) - 1, - data->rx_buf, 0, len); - modem.minfo.mdm_manufacturer[out_len] = '\0'; - LOG_INF("Manufacturer: %s", modem.minfo.mdm_manufacturer); - - return 0; -} - -/* Handler: */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_model) -{ - size_t out_len; - - out_len = net_buf_linearize(modem.minfo.mdm_model, - sizeof(modem.minfo.mdm_model) - 1, - data->rx_buf, 0, len); - modem.minfo.mdm_model[out_len] = '\0'; - LOG_INF("Model: %s", modem.minfo.mdm_model); - - return 0; -} - -/* Handler: */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_revision) -{ - size_t out_len; - - out_len = net_buf_linearize(modem.minfo.mdm_revision, - sizeof(modem.minfo.mdm_revision) - 1, - data->rx_buf, 0, len); - modem.minfo.mdm_revision[out_len] = '\0'; - LOG_INF("Revision: %s", modem.minfo.mdm_revision); - - return 0; -} - -/* Handler: */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_imei) -{ - size_t out_len; - - out_len = net_buf_linearize(modem.minfo.mdm_imei, sizeof(modem.minfo.mdm_imei) - 1, - data->rx_buf, 0, len); - modem.minfo.mdm_imei[out_len] = '\0'; - LOG_INF("IMEI: %s", modem.minfo.mdm_imei); - - return 0; -} - -#if defined(CONFIG_MODEM_SIM_NUMBERS) -/* Handler: */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_imsi) -{ - size_t out_len; - - out_len = net_buf_linearize(modem.minfo.mdm_imsi, sizeof(modem.minfo.mdm_imsi) - 1, - data->rx_buf, 0, len); - modem.minfo.mdm_imsi[out_len] = '\0'; - LOG_INF("IMSI: %s", modem.minfo.mdm_imsi); - - return 0; -} - -/* Handler: */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_iccid) -{ - size_t out_len; - - out_len = net_buf_linearize(modem.minfo.mdm_iccid, sizeof(modem.minfo.mdm_iccid) - 1, - data->rx_buf, 0, len); - modem.minfo.mdm_iccid[out_len] = '\0'; - if (modem.minfo.mdm_iccid[0] == '+') { - /* Seen on U-blox SARA: "+CCID: nnnnnnnnnnnnnnnnnnnn". - * Skip over the +CCID bit, which other modems omit. - */ - char *p = strchr(modem.minfo.mdm_iccid, ' '); - - if (p) { - size_t iccid_len = strlen(p+1); - - (void)memmove(modem.minfo.mdm_iccid, p+1, iccid_len+1); - } - } - LOG_INF("ICCID: %s", modem.minfo.mdm_iccid); - - return 0; -} -#endif /* CONFIG_MODEM_SIM_NUMBERS */ - -MODEM_CMD_DEFINE(on_cmd_net_reg_sts) -{ - modem.net_state = (enum network_state)atoi(argv[1]); - - switch (modem.net_state) { - case GSM_NET_NOT_REGISTERED: - LOG_DBG("Network %s.", "not registered"); - break; - case GSM_NET_HOME_NETWORK: - LOG_DBG("Network %s.", "registered, home network"); - break; - case GSM_NET_SEARCHING: - LOG_DBG("Searching for network..."); - break; - case GSM_NET_REGISTRATION_DENIED: - LOG_DBG("Network %s.", "registration denied"); - break; - case GSM_NET_UNKNOWN: - LOG_DBG("Network %s.", "unknown"); - break; - case GSM_NET_ROAMING: - LOG_DBG("Network %s.", "registered, roaming"); - break; - default: - break; - } - - return 0; -} - -#if defined(CONFIG_MODEM_CELL_INFO) - -/* - * Handler: +CEREG: [0],[1],[2],[3],[4] - */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_cereg) -{ - if (argc >= 4) { - modem.context.data_lac = unquoted_atoi(argv[2], 16); - modem.context.data_cellid = unquoted_atoi(argv[3], 16); - LOG_INF("lac: %u, cellid: %u", - modem.context.data_lac, - modem.context.data_cellid); - } - - if (argc >= 5) { - modem.context.data_act = unquoted_atoi(argv[4], 10); - LOG_INF("act: %u", modem.context.data_act); - } - - return 0; -} - -static const struct setup_cmd query_cellinfo_cmds[] = { - SETUP_CMD_NOHANDLE("AT+CEREG=2"), - SETUP_CMD("AT+CEREG?", "", on_cmd_atcmdinfo_cereg, 5U, ","), - SETUP_CMD_NOHANDLE("AT+COPS=3,2"), - SETUP_CMD("AT+COPS?", "", on_cmd_atcmdinfo_cops, 3U, ","), -}; - -static int gsm_query_cellinfo(struct gsm_modem *gsm) -{ - int ret; - - ret = modem_cmd_handler_setup_cmds_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - query_cellinfo_cmds, - ARRAY_SIZE(query_cellinfo_cmds), - &gsm->sem_response, - GSM_CMD_SETUP_TIMEOUT); - if (ret < 0) { - LOG_WRN("modem query for cell info returned %d", ret); - } - - return ret; -} -#endif /* CONFIG_MODEM_CELL_INFO */ - -#if defined(CONFIG_MODEM_GSM_ENABLE_CESQ_RSSI) -/* - * Handler: +CESQ: [0],[1],[2],[3],[4],[5] - */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_rssi_cesq) -{ - int rsrp, rscp, rxlev; - - rsrp = ATOI(argv[5], 0, "rsrp"); - rscp = ATOI(argv[2], 0, "rscp"); - rxlev = ATOI(argv[0], 0, "rxlev"); - - if ((rsrp >= 0) && (rsrp <= 97)) { - modem.minfo.mdm_rssi = -140 + (rsrp - 1); - LOG_DBG("RSRP: %d", modem.minfo.mdm_rssi); - } else if ((rscp >= 0) && (rscp <= 96)) { - modem.minfo.mdm_rssi = -120 + (rscp - 1); - LOG_DBG("RSCP: %d", modem.minfo.mdm_rssi); - } else if ((rxlev >= 0) && (rxlev <= 63)) { - modem.minfo.mdm_rssi = -110 + (rxlev - 1); - LOG_DBG("RSSI: %d", modem.minfo.mdm_rssi); - } else { - modem.minfo.mdm_rssi = GSM_RSSI_INVALID; - LOG_DBG("RSRP/RSCP/RSSI not known"); - } - - return 0; -} -#else -/* Handler: +CSQ: [0],[1] */ -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_rssi_csq) -{ - /* Expected response is "+CSQ: ," */ - if (argc > 0) { - int rssi = atoi(argv[0]); - - if ((rssi >= 0) && (rssi <= 31)) { - rssi = -113 + (rssi * 2); - } else { - rssi = GSM_RSSI_INVALID; - } - - modem.minfo.mdm_rssi = rssi; - LOG_DBG("RSSI: %d", rssi); - } - - return 0; -} -#endif - -#if defined(CONFIG_MODEM_GSM_ENABLE_CESQ_RSSI) -static const struct modem_cmd read_rssi_cmd = - MODEM_CMD("+CESQ:", on_cmd_atcmdinfo_rssi_cesq, 6U, ","); -#else -static const struct modem_cmd read_rssi_cmd = - MODEM_CMD("+CSQ:", on_cmd_atcmdinfo_rssi_csq, 2U, ","); -#endif - -static const struct setup_cmd setup_modem_info_cmds[] = { - /* query modem info */ - SETUP_CMD("AT+CGMI", "", on_cmd_atcmdinfo_manufacturer, 0U, ""), - SETUP_CMD("AT+CGMM", "", on_cmd_atcmdinfo_model, 0U, ""), - SETUP_CMD("AT+CGMR", "", on_cmd_atcmdinfo_revision, 0U, ""), - SETUP_CMD("AT+CGSN", "", on_cmd_atcmdinfo_imei, 0U, ""), -#if defined(CONFIG_MODEM_SIM_NUMBERS) - SETUP_CMD("AT+CIMI", "", on_cmd_atcmdinfo_imsi, 0U, ""), - SETUP_CMD("AT+CCID", "", on_cmd_atcmdinfo_iccid, 0U, ""), -#endif -}; - -static const struct setup_cmd setup_cmds[] = { - /* no echo */ - SETUP_CMD_NOHANDLE("ATE0"), - /* hang up */ - SETUP_CMD_NOHANDLE("ATH"), - /* extended errors in numeric form */ - SETUP_CMD_NOHANDLE("AT+CMEE=1"), - /* disable unsolicited network registration codes */ - SETUP_CMD_NOHANDLE("AT+CREG=0"), - /* create PDP context */ - SETUP_CMD_NOHANDLE("AT+CGDCONT=1,\"IP\",\"" CONFIG_MODEM_GSM_APN "\""), -#if IS_ENABLED(DT_PROP(GSM_UART_NODE, hw_flow_control)) - /* enable hardware flow control */ - SETUP_CMD_NOHANDLE("AT+IFC=2,2"), -#endif -}; - -MODEM_CMD_DEFINE(on_cmd_atcmdinfo_attached) -{ - /* Expected response is "+CGATT: 0|1" so simply look for '1' */ - if ((argc > 0) && (atoi(argv[0]) == 1)) { - LOG_INF("Attached to packet service!"); - } - - return 0; -} - - -static const struct modem_cmd read_cops_cmd = - MODEM_CMD_ARGS_MAX("+COPS:", on_cmd_atcmdinfo_cops, 1U, 4U, ","); - -static const struct modem_cmd check_net_reg_cmd = - MODEM_CMD("+" CONFIG_MODEM_GSM_STATUS_COMMAND, on_cmd_net_reg_sts, 2U, ","); - -static const struct modem_cmd check_attached_cmd = - MODEM_CMD("+CGATT:", on_cmd_atcmdinfo_attached, 1U, ","); - -static const struct setup_cmd connect_cmds[] = { - /* connect to network */ - SETUP_CMD_NOHANDLE("ATD*99#"), -}; - -static int gsm_query_modem_info(struct gsm_modem *gsm) -{ - int ret; - - if (gsm->modem_info_queried) { - return 0; - } - - ret = modem_cmd_handler_setup_cmds_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - setup_modem_info_cmds, - ARRAY_SIZE(setup_modem_info_cmds), - &gsm->sem_response, - GSM_CMD_SETUP_TIMEOUT); - - if (ret < 0) { - return ret; - } - - gsm->modem_info_queried = true; - - return 0; -} - -static int gsm_setup_mccmno(struct gsm_modem *gsm) -{ - int ret = 0; - - if (CONFIG_MODEM_GSM_MANUAL_MCCMNO[0] != '\0') { - /* use manual MCC/MNO entry */ - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - NULL, 0, - "AT+COPS=1,2,\"" - CONFIG_MODEM_GSM_MANUAL_MCCMNO - "\"", - &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - } else { - -/* First AT+COPS? is sent to check if automatic selection for operator - * is already enabled, if yes we do not send the command AT+COPS= 0,0. - */ - - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - &read_cops_cmd, - 1, "AT+COPS?", - &gsm->sem_response, - GSM_CMD_SETUP_TIMEOUT); - - if (ret < 0) { - return ret; - } - - if (!gsm->context.is_automatic_oper) { - /* register operator automatically */ - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - NULL, 0, "AT+COPS=0,0", - &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - } - } - - if (ret < 0) { - LOG_ERR("AT+COPS ret:%d", ret); - } - - return ret; -} - -static struct net_if *ppp_net_if(void) -{ - return net_if_get_first_by_type(&NET_L2_GET_NAME(PPP)); -} - -static void set_ppp_carrier_on(struct gsm_modem *gsm) -{ - const struct device *ppp_dev = device_get_binding(CONFIG_NET_PPP_DRV_NAME); - struct net_if *iface = gsm->iface; - - if (ppp_dev == NULL) { - LOG_ERR("Cannot find PPP %s!", CONFIG_NET_PPP_DRV_NAME); - return; - } - - net_if_up(iface); -} - -static void query_rssi(struct gsm_modem *gsm, bool lock) -{ - int ret; - -#if defined(CONFIG_MODEM_GSM_ENABLE_CESQ_RSSI) - ret = modem_cmd_send_ext(&gsm->context.iface, &gsm->context.cmd_handler, &read_rssi_cmd, 1, - "AT+CESQ", &gsm->sem_response, GSM_CMD_SETUP_TIMEOUT, - lock ? 0 : MODEM_NO_TX_LOCK); -#else - ret = modem_cmd_send_ext(&gsm->context.iface, &gsm->context.cmd_handler, &read_rssi_cmd, 1, - "AT+CSQ", &gsm->sem_response, GSM_CMD_SETUP_TIMEOUT, - lock ? 0 : MODEM_NO_TX_LOCK); -#endif - - if (ret < 0) { - LOG_DBG("No answer to RSSI readout, %s", "ignoring..."); - } -} - -static inline void query_rssi_lock(struct gsm_modem *gsm) -{ - query_rssi(gsm, true); -} - -static inline void query_rssi_nolock(struct gsm_modem *gsm) -{ - query_rssi(gsm, false); -} - -static void rssi_handler(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct gsm_modem *gsm = CONTAINER_OF(dwork, struct gsm_modem, rssi_work_handle); - - gsm_ppp_lock(gsm); - query_rssi_lock(gsm); - -#if defined(CONFIG_MODEM_CELL_INFO) - (void)gsm_query_cellinfo(gsm); -#endif - (void)gsm_work_reschedule(&gsm->rssi_work_handle, - K_SECONDS(CONFIG_MODEM_GSM_RSSI_POLLING_PERIOD)); - gsm_ppp_unlock(gsm); -} - -static void gsm_finalize_connection(struct k_work *work) -{ - int ret = 0; - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct gsm_modem *gsm = CONTAINER_OF(dwork, struct gsm_modem, gsm_configure_work); - - gsm_ppp_lock(gsm); - - /* If already attached, jump right to RSSI readout */ - if (gsm->state == GSM_PPP_ATTACHED) { - goto attached; - } - - /* If attach check failed, we should not redo every setup step */ - if (gsm->state == GSM_PPP_ATTACHING) { - goto attaching; - } - - /* If modem is searching for network, we should skip the setup step */ - if (gsm->state == GSM_PPP_REGISTERING) { - goto registering; - } - - if (IS_ENABLED(CONFIG_GSM_MUX)) { - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - &response_cmds[0], - ARRAY_SIZE(response_cmds), - "AT", &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - if (ret < 0) { - LOG_ERR("%s returned %d, %s", "AT", ret, "retrying..."); - (void)gsm_work_reschedule(&gsm->gsm_configure_work, GSM_RETRY_DELAY); - goto unlock; - } - } - gsm->state = GSM_PPP_SETUP; - - if (IS_ENABLED(CONFIG_MODEM_GSM_FACTORY_RESET_AT_BOOT)) { - (void)modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - &response_cmds[0], - ARRAY_SIZE(response_cmds), - "AT&F", &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - (void)k_sleep(K_SECONDS(1)); - } - - ret = gsm_setup_mccmno(gsm); - if (ret < 0) { - LOG_ERR("%s returned %d, %s", "gsm_setup_mccmno", ret, "retrying..."); - - (void)gsm_work_reschedule(&gsm->gsm_configure_work, GSM_RETRY_DELAY); - goto unlock; - } - - ret = modem_cmd_handler_setup_cmds_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - setup_cmds, - ARRAY_SIZE(setup_cmds), - &gsm->sem_response, - GSM_CMD_SETUP_TIMEOUT); - if (ret < 0) { - LOG_DBG("%s returned %d, %s", "setup_cmds", ret, "retrying..."); - (void)gsm_work_reschedule(&gsm->gsm_configure_work, GSM_RETRY_DELAY); - goto unlock; - } - - ret = gsm_query_modem_info(gsm); - if (ret < 0) { - LOG_DBG("Unable to query modem information %d", ret); - (void)gsm_work_reschedule(&gsm->gsm_configure_work, GSM_RETRY_DELAY); - goto unlock; - } - - gsm->state = GSM_PPP_REGISTERING; -registering: - /* Wait for cell tower registration */ - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - &check_net_reg_cmd, 1, - "AT+" CONFIG_MODEM_GSM_STATUS_COMMAND "?", - &gsm->sem_response, - GSM_CMD_SETUP_TIMEOUT); - if ((ret < 0) || ((gsm->net_state != GSM_NET_ROAMING) && - (gsm->net_state != GSM_NET_HOME_NETWORK))) { - if (gsm->retries == 0) { - gsm->retries = CONFIG_MODEM_GSM_REGISTER_TIMEOUT * - (MSEC_PER_SEC / GSM_REGISTER_DELAY_MSEC); - } else { - gsm->retries--; - } - - (void)gsm_work_reschedule(&gsm->gsm_configure_work, - K_MSEC(GSM_REGISTER_DELAY_MSEC)); - goto unlock; - } - - gsm->retries = 0; - gsm->state = GSM_PPP_ATTACHING; -attaching: - /* Don't initialize PPP until we're attached to packet service */ - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - &check_attached_cmd, 1, - "AT+CGATT?", - &gsm->sem_response, - GSM_CMD_SETUP_TIMEOUT); - if (ret < 0) { - /* - * retries not set -> trigger N attach retries - * retries set -> decrement and retry - * retries set, becomes 0 -> trigger full retry - */ - if (gsm->retries == 0) { - gsm->retries = CONFIG_MODEM_GSM_ATTACH_TIMEOUT * - (MSEC_PER_SEC / GSM_ATTACH_RETRY_DELAY_MSEC); - } else { - gsm->retries--; - } - - LOG_DBG("Not attached, %s", "retrying..."); - - (void)gsm_work_reschedule(&gsm->gsm_configure_work, - K_MSEC(GSM_ATTACH_RETRY_DELAY_MSEC)); - goto unlock; - } - - /* Attached, clear retry counter */ - LOG_DBG("modem attach returned %d, %s", ret, "read RSSI"); - gsm->state = GSM_PPP_ATTACHED; - gsm->retries = GSM_RSSI_RETRIES; - - attached: - - if (!IS_ENABLED(CONFIG_GSM_MUX)) { - /* Read connection quality (RSSI) before PPP carrier is ON */ - query_rssi_nolock(gsm); - - if (!((gsm->minfo.mdm_rssi) && (gsm->minfo.mdm_rssi != GSM_RSSI_INVALID) && - (gsm->minfo.mdm_rssi <= GSM_RSSI_MAXVAL))) { - - LOG_DBG("Not valid RSSI, %s", "retrying..."); - if (gsm->retries-- > 0) { - (void)gsm_work_reschedule(&gsm->gsm_configure_work, - K_MSEC(GSM_RSSI_RETRY_DELAY_MSEC)); - goto unlock; - } - } -#if defined(CONFIG_MODEM_CELL_INFO) - (void)gsm_query_cellinfo(gsm); -#endif - } - - LOG_DBG("modem RSSI: %d, %s", gsm->minfo.mdm_rssi, "enable PPP"); - - ret = modem_cmd_handler_setup_cmds_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - connect_cmds, - ARRAY_SIZE(connect_cmds), - &gsm->sem_response, - GSM_CMD_SETUP_TIMEOUT); - if (ret < 0) { - LOG_DBG("%s returned %d, %s", "connect_cmds", ret, "retrying..."); - (void)gsm_work_reschedule(&gsm->gsm_configure_work, GSM_RETRY_DELAY); - goto unlock; - } - - gsm->state = GSM_PPP_SETUP_DONE; - set_ppp_carrier_on(gsm); - - if (IS_ENABLED(CONFIG_GSM_MUX)) { - /* Re-use the original iface for AT channel */ - ret = modem_iface_uart_init_dev(&gsm->context.iface, - gsm->at_dev); - if (ret < 0) { - LOG_DBG("iface %suart error %d", "AT ", ret); - gsm->state = GSM_PPP_STATE_ERROR; - } else { - /* Do a test and try to send AT command to modem */ - ret = modem_cmd_send_nolock( - &gsm->context.iface, - &gsm->context.cmd_handler, - &response_cmds[0], - ARRAY_SIZE(response_cmds), - "AT", &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - if (ret < 0) { - LOG_WRN("%s returned %d, %s", "AT", ret, "iface failed"); - gsm->state = GSM_PPP_STATE_ERROR; - } else { - LOG_INF("AT channel %d connected to %s", - DLCI_AT, gsm->at_dev->name); - } - } - - modem_cmd_handler_tx_unlock(&gsm->context.cmd_handler); - if (gsm->state != GSM_PPP_STATE_ERROR) { - (void)gsm_work_reschedule(&gsm->rssi_work_handle, - K_SECONDS(CONFIG_MODEM_GSM_RSSI_POLLING_PERIOD)); - } - } - -unlock: - gsm_ppp_unlock(gsm); -} - -static int mux_enable(struct gsm_modem *gsm) -{ - int ret; - - /* Turn on muxing */ - if (IS_ENABLED(CONFIG_MODEM_GSM_SIMCOM)) { - ret = modem_cmd_send_nolock( - &gsm->context.iface, - &gsm->context.cmd_handler, - &response_cmds[0], - ARRAY_SIZE(response_cmds), -#if defined(SIMCOM_LTE) - /* FIXME */ - /* Some SIMCOM modems can set the channels */ - /* Control channel always at DLCI 0 */ - "AT+CMUXSRVPORT=0,0;" - /* PPP should be at DLCI 1 */ - "+CMUXSRVPORT=" STRINGIFY(DLCI_PPP) ",1;" - /* AT should be at DLCI 2 */ - "+CMUXSRVPORT=" STRINGIFY(DLCI_AT) ",1;" -#else - "AT" -#endif - "+CMUX=0,0,5," - STRINGIFY(CONFIG_GSM_MUX_MRU_DEFAULT_LEN), - &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - } else if (IS_ENABLED(CONFIG_MODEM_GSM_QUECTEL)) { - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - &response_cmds[0], - ARRAY_SIZE(response_cmds), - "AT+CMUX=0,0,5," - STRINGIFY(CONFIG_GSM_MUX_MRU_DEFAULT_LEN), - &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - - /* Arbitrary delay for Quectel modems to initialize the CMUX, - * without this the AT cmd will fail. - */ - (void)k_sleep(K_SECONDS(1)); - } else { - /* Generic GSM modem */ - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - &response_cmds[0], - ARRAY_SIZE(response_cmds), - "AT+CMUX=0", &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - } - - if (ret < 0) { - LOG_ERR("AT+CMUX ret:%d", ret); - } - - return ret; -} - -static void mux_setup_next(struct gsm_modem *gsm) -{ - (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_MSEC(1)); -} - -static void mux_attach_cb(const struct device *mux, int dlci_address, - bool connected, void *user_data) -{ - LOG_DBG("DLCI %d to %s %s", dlci_address, mux->name, - connected ? "connected" : "disconnected"); - - if (connected) { - uart_irq_rx_enable(mux); - uart_irq_tx_enable(mux); - } - - mux_setup_next(user_data); -} - -static int mux_attach(const struct device *mux, const struct device *uart, - int dlci_address, void *user_data) -{ - int ret = uart_mux_attach(mux, uart, dlci_address, mux_attach_cb, - user_data); - if (ret < 0) { - LOG_ERR("Cannot attach DLCI %d (%s) to %s (%d)", dlci_address, - mux->name, uart->name, ret); - return ret; - } - - return 0; -} - -static void mux_setup(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct gsm_modem *gsm = CONTAINER_OF(dwork, struct gsm_modem, - gsm_configure_work); - const struct device *const uart = DEVICE_DT_GET(GSM_UART_NODE); - int ret; - - gsm_ppp_lock(gsm); - - switch (gsm->state) { - case GSM_PPP_STATE_CONTROL_CHANNEL: - /* We need to call this to reactivate mux ISR. Note: This is only called - * after re-initing gsm_ppp. - */ - if (gsm->ppp_dev != NULL) { - uart_mux_enable(gsm->ppp_dev); - } - - /* Get UART device. There is one dev / DLCI */ - if (gsm->control_dev == NULL) { - gsm->control_dev = uart_mux_alloc(); - if (gsm->control_dev == NULL) { - LOG_DBG("Cannot get UART mux for %s channel", - "control"); - goto fail; - } - } - - ret = mux_attach(gsm->control_dev, uart, DLCI_CONTROL, gsm); - if (ret < 0) { - goto fail; - } - - gsm->state = GSM_PPP_STATE_PPP_CHANNEL; - goto unlock; - - case GSM_PPP_STATE_PPP_CHANNEL: - if (gsm->ppp_dev == NULL) { - gsm->ppp_dev = uart_mux_alloc(); - if (gsm->ppp_dev == NULL) { - LOG_DBG("Cannot get UART mux for %s channel", - "PPP"); - goto fail; - } - } - - ret = mux_attach(gsm->ppp_dev, uart, DLCI_PPP, gsm); - if (ret < 0) { - goto fail; - } - - gsm->state = GSM_PPP_STATE_AT_CHANNEL; - goto unlock; - - case GSM_PPP_STATE_AT_CHANNEL: - if (gsm->at_dev == NULL) { - gsm->at_dev = uart_mux_alloc(); - if (gsm->at_dev == NULL) { - LOG_DBG("Cannot get UART mux for %s channel", - "AT"); - goto fail; - } - } - - ret = mux_attach(gsm->at_dev, uart, DLCI_AT, gsm); - if (ret < 0) { - goto fail; - } - - gsm->state = GSM_PPP_STATE_DONE; - goto unlock; - - case GSM_PPP_STATE_DONE: - /* At least the SIMCOM modem expects that the Internet - * connection is created in PPP channel. We will need - * to attach the AT channel to context iface after the - * PPP connection is established in order to give AT commands - * to the modem. - */ - ret = modem_iface_uart_init_dev(&gsm->context.iface, - gsm->ppp_dev); - if (ret < 0) { - LOG_DBG("iface %suart error %d", "PPP ", ret); - goto fail; - } - - LOG_INF("PPP channel %d connected to %s", - DLCI_PPP, gsm->ppp_dev->name); - - k_work_init_delayable(&gsm->gsm_configure_work, gsm_finalize_connection); - (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); - goto unlock; - default: - __ASSERT(0, "%s while in state: %d", "mux_setup", gsm->state); - /* In case CONFIG_ASSERT is off, goto fail */ - goto fail; - } - -fail: - gsm->state = GSM_PPP_STATE_ERROR; -unlock: - gsm_ppp_unlock(gsm); -} - -static void gsm_configure(struct k_work *work) -{ - struct k_work_delayable *dwork = k_work_delayable_from_work(work); - struct gsm_modem *gsm = CONTAINER_OF(dwork, struct gsm_modem, - gsm_configure_work); - int ret = -1; - - gsm_ppp_lock(gsm); - - if (gsm->state == GSM_PPP_WAIT_AT) { - goto wait_at; - } - - if (gsm->state == GSM_PPP_START) { - LOG_DBG("Starting modem %p configuration", gsm); - - if (gsm->modem_on_cb != NULL) { - gsm->modem_on_cb(gsm->dev, gsm->user_data); - } - - gsm->state = GSM_PPP_WAIT_AT; - } - -wait_at: - ret = modem_cmd_send_nolock(&gsm->context.iface, - &gsm->context.cmd_handler, - &response_cmds[0], - ARRAY_SIZE(response_cmds), - "AT", &gsm->sem_response, - GSM_CMD_AT_TIMEOUT); - if (ret < 0) { - LOG_DBG("modem not ready %d", ret); - goto retry; - } - - gsm->state = GSM_PPP_AT_RDY; - - if (IS_ENABLED(CONFIG_GSM_MUX)) { - if (mux_enable(gsm) == 0) { - LOG_DBG("GSM muxing %s", "enabled"); - } else { - LOG_DBG("GSM muxing %s", "disabled"); - goto retry; - } - - gsm->state = GSM_PPP_STATE_INIT; - - k_work_init_delayable(&gsm->gsm_configure_work, mux_setup); - } else { - k_work_init_delayable(&gsm->gsm_configure_work, gsm_finalize_connection); - } - -retry: - (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); - gsm_ppp_unlock(gsm); -} - -void gsm_ppp_start(const struct device *dev) -{ - int ret; - struct gsm_modem *gsm = dev->data; - - gsm_ppp_lock(gsm); - - if (gsm->state != GSM_PPP_STOP) { - LOG_ERR("gsm_ppp is already %s", "started"); - goto unlock; - } - - gsm->state = GSM_PPP_START; - - /* Re-init underlying UART comms */ - ret = modem_iface_uart_init_dev(&gsm->context.iface, DEVICE_DT_GET(GSM_UART_NODE)); - if (ret < 0) { - LOG_ERR("modem_iface_uart_init returned %d", ret); - gsm->state = GSM_PPP_STATE_ERROR; - goto unlock; - } - - k_work_init_delayable(&gsm->gsm_configure_work, gsm_configure); - (void)gsm_work_reschedule(&gsm->gsm_configure_work, K_NO_WAIT); - -unlock: - gsm_ppp_unlock(gsm); -} - -void gsm_ppp_stop(const struct device *dev) -{ - struct gsm_modem *gsm = dev->data; - struct net_if *iface = gsm->iface; - struct k_work_sync work_sync; - - if (gsm->state == GSM_PPP_STOP) { - LOG_ERR("gsm_ppp is already %s", "stopped"); - return; - } - - (void)k_work_cancel_delayable_sync(&gsm->gsm_configure_work, &work_sync); - if (IS_ENABLED(CONFIG_GSM_MUX)) { - (void)k_work_cancel_delayable_sync(&gsm->rssi_work_handle, &work_sync); - } - - gsm_ppp_lock(gsm); - - /* wait for the interface to be properly down */ - if (net_if_is_up(iface)) { - net_if_down(ppp_net_if()); - (void)k_sem_take(&gsm->sem_if_down, K_FOREVER); - } - - if (IS_ENABLED(CONFIG_GSM_MUX)) { - if (gsm->ppp_dev != NULL) { - uart_mux_disable(gsm->ppp_dev); - } - - if (modem_cmd_handler_tx_lock(&gsm->context.cmd_handler, - GSM_CMD_LOCK_TIMEOUT) < 0) { - LOG_WRN("Failed locking modem cmds!"); - } - } - - if (gsm->modem_off_cb != NULL) { - gsm->modem_off_cb(gsm->dev, gsm->user_data); - } - - gsm->state = GSM_PPP_STOP; - gsm->net_state = GSM_NET_INIT; - gsm_ppp_unlock(gsm); -} - -void gsm_ppp_register_modem_power_callback(const struct device *dev, - gsm_modem_power_cb modem_on, - gsm_modem_power_cb modem_off, - void *user_data) -{ - struct gsm_modem *gsm = dev->data; - - gsm_ppp_lock(gsm); - - gsm->modem_on_cb = modem_on; - gsm->modem_off_cb = modem_off; - - gsm->user_data = user_data; - gsm_ppp_unlock(gsm); -} - -const struct gsm_ppp_modem_info *gsm_ppp_modem_info(const struct device *dev) -{ - struct gsm_modem *gsm = dev->data; - - return &gsm->minfo; -} - -static void gsm_mgmt_event_handler(struct net_mgmt_event_callback *cb, - uint32_t mgmt_event, struct net_if *iface) -{ - if ((mgmt_event & NET_EVENT_IF_DOWN) != mgmt_event) { - return; - } - - /* Right now we only support 1 GSM instance */ - if (iface != modem.iface) { - return; - } - - if (mgmt_event == NET_EVENT_IF_DOWN) { - LOG_INF("GSM network interface down"); - /* raise semaphore to indicate the interface is down */ - k_sem_give(&modem.sem_if_down); - return; - } -} - -static int gsm_init(const struct device *dev) -{ - struct gsm_modem *gsm = dev->data; - int ret; - - LOG_DBG("Generic GSM modem (%p)", gsm); - - (void)k_mutex_init(&gsm->lock); - gsm->dev = dev; - - const struct modem_cmd_handler_config cmd_handler_config = { - .match_buf = &gsm->cmd_match_buf[0], - .match_buf_len = sizeof(gsm->cmd_match_buf), - .buf_pool = &gsm_recv_pool, - .alloc_timeout = K_NO_WAIT, - .eol = "\r", - .user_data = NULL, - .response_cmds = response_cmds, - .response_cmds_len = ARRAY_SIZE(response_cmds), - .unsol_cmds = NULL, - .unsol_cmds_len = 0, - }; - - (void)k_sem_init(&gsm->sem_response, 0, 1); - (void)k_sem_init(&gsm->sem_if_down, 0, 1); - - ret = modem_cmd_handler_init(&gsm->context.cmd_handler, &gsm->cmd_handler_data, - &cmd_handler_config); - if (ret < 0) { - LOG_DBG("cmd handler error %d", ret); - return ret; - } - -#if defined(CONFIG_MODEM_SHELL) - /* modem information storage */ - gsm->context.data_manufacturer = gsm->minfo.mdm_manufacturer; - gsm->context.data_model = gsm->minfo.mdm_model; - gsm->context.data_revision = gsm->minfo.mdm_revision; - gsm->context.data_imei = gsm->minfo.mdm_imei; -#if defined(CONFIG_MODEM_SIM_NUMBERS) - gsm->context.data_imsi = gsm->minfo.mdm_imsi; - gsm->context.data_iccid = gsm->minfo.mdm_iccid; -#endif /* CONFIG_MODEM_SIM_NUMBERS */ - gsm->context.data_rssi = &gsm->minfo.mdm_rssi; -#endif /* CONFIG_MODEM_SHELL */ - - gsm->context.is_automatic_oper = false; - - const struct modem_iface_uart_config uart_config = { - .rx_rb_buf = &gsm->gsm_rx_rb_buf[0], - .rx_rb_buf_len = sizeof(gsm->gsm_rx_rb_buf), - .hw_flow_control = DT_PROP(GSM_UART_NODE, hw_flow_control), - .dev = DEVICE_DT_GET(GSM_UART_NODE), - }; - - ret = modem_iface_uart_init(&gsm->context.iface, &gsm->gsm_data, &uart_config); - if (ret < 0) { - LOG_DBG("iface uart error %d", ret); - return ret; - } - - ret = modem_context_register(&gsm->context); - if (ret < 0) { - LOG_DBG("context error %d", ret); - return ret; - } - - /* Initialize to stop state so that it can be started later */ - gsm->state = GSM_PPP_STOP; - - gsm->net_state = GSM_NET_INIT; - - LOG_DBG("iface->read %p iface->write %p", - gsm->context.iface.read, gsm->context.iface.write); - - (void)k_thread_create(&gsm->rx_thread, gsm_rx_stack, - K_KERNEL_STACK_SIZEOF(gsm_rx_stack), - gsm_rx, - gsm, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); - (void)k_thread_name_set(&gsm->rx_thread, "gsm_rx"); - - /* initialize the work queue */ - k_work_queue_init(&gsm->workq); - k_work_queue_start(&gsm->workq, gsm_workq_stack, K_KERNEL_STACK_SIZEOF(gsm_workq_stack), - K_PRIO_COOP(7), NULL); - (void)k_thread_name_set(&gsm->workq.thread, "gsm_workq"); - - if (IS_ENABLED(CONFIG_GSM_MUX)) { - k_work_init_delayable(&gsm->rssi_work_handle, rssi_handler); - } - - gsm->iface = ppp_net_if(); - if (gsm->iface == NULL) { - LOG_ERR("Couldn't find ppp net_if!"); - return -ENODEV; - } - - net_mgmt_init_event_callback(&gsm->gsm_mgmt_cb, gsm_mgmt_event_handler, - NET_EVENT_IF_DOWN); - net_mgmt_add_event_callback(&gsm->gsm_mgmt_cb); - - if (IS_ENABLED(CONFIG_GSM_PPP_AUTOSTART)) { - gsm_ppp_start(dev); - } - - return 0; -} - -DEVICE_DT_DEFINE(DT_DRV_INST(0), gsm_init, NULL, &modem, NULL, - POST_KERNEL, CONFIG_MODEM_GSM_INIT_PRIORITY, NULL); diff --git a/dts/bindings/modem/zephyr,gsm-ppp.yaml b/dts/bindings/modem/zephyr,gsm-ppp.yaml deleted file mode 100644 index 768173d6270..00000000000 --- a/dts/bindings/modem/zephyr,gsm-ppp.yaml +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2021 G-Technologies Sdn. Bhd. -# SPDX-License-Identifier: Apache-2.0 - -description: GSM PPP modem - -compatible: "zephyr,gsm-ppp" - -include: uart-device.yaml diff --git a/include/zephyr/drivers/modem/gsm_ppp.h b/include/zephyr/drivers/modem/gsm_ppp.h deleted file mode 100644 index 606752806a2..00000000000 --- a/include/zephyr/drivers/modem/gsm_ppp.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2020 Endian Technologies AB - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef ZEPHYR_INCLUDE_DRIVERS_MODEM_GSM_PPP_H_ -#define ZEPHYR_INCLUDE_DRIVERS_MODEM_GSM_PPP_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#define GSM_PPP_MDM_MANUFACTURER_LENGTH 10 -#define GSM_PPP_MDM_MODEL_LENGTH 16 -#define GSM_PPP_MDM_REVISION_LENGTH 64 -#define GSM_PPP_MDM_IMEI_LENGTH 16 -#define GSM_PPP_MDM_IMSI_LENGTH 16 -#define GSM_PPP_MDM_ICCID_LENGTH 32 - -struct gsm_ppp_modem_info { - char mdm_manufacturer[GSM_PPP_MDM_MANUFACTURER_LENGTH]; - char mdm_model[GSM_PPP_MDM_MODEL_LENGTH]; - char mdm_revision[GSM_PPP_MDM_REVISION_LENGTH]; - char mdm_imei[GSM_PPP_MDM_IMEI_LENGTH]; -#if defined(CONFIG_MODEM_SIM_NUMBERS) - char mdm_imsi[GSM_PPP_MDM_IMSI_LENGTH]; - char mdm_iccid[GSM_PPP_MDM_ICCID_LENGTH]; -#endif - int mdm_rssi; -}; - -/** @cond INTERNAL_HIDDEN */ -struct device; -typedef void (*gsm_modem_power_cb)(const struct device *, void *); - -void gsm_ppp_start(const struct device *dev); -void gsm_ppp_stop(const struct device *dev); -/** @endcond */ - -/** - * @brief Register functions callbacks for power modem on/off. - * - * @param dev: gsm modem device - * @param modem_on: callback function to - * execute during gsm ppp configuring. - * @param modem_off: callback function to - * execute during gsm ppp stopping. - * @param user_data: user specified data - */ -void gsm_ppp_register_modem_power_callback(const struct device *dev, - gsm_modem_power_cb modem_on, - gsm_modem_power_cb modem_off, - void *user_data); - -/** - * @brief Get GSM modem information. - * - * @param dev: GSM modem device. - * - * @retval struct gsm_ppp_modem_info * pointer to modem information structure. - */ -const struct gsm_ppp_modem_info *gsm_ppp_modem_info(const struct device *dev); - -#ifdef __cplusplus -} -#endif - -#endif /* ZEPHYR_INCLUDE_DRIVERS_MODEM_GSM_PPP_H_ */