diff --git a/drivers/modem/gsm_ppp.c b/drivers/modem/gsm_ppp.c index c1f8fde938b..30884249efa 100644 --- a/drivers/modem/gsm_ppp.c +++ b/drivers/modem/gsm_ppp.c @@ -317,6 +317,30 @@ static void gsm_finalize_connection(struct gsm_modem *gsm) } set_ppp_carrier_on(gsm); + + if (IS_ENABLED(CONFIG_GSM_MUX) && gsm->mux_enabled) { + /* Re-use the original iface for AT channel */ + ret = modem_iface_uart_init_dev(&gsm->context.iface, + gsm->at_dev->config->name); + if (ret < 0) { + LOG_DBG("iface %suart error %d", "AT ", ret); + } else { + /* Do a test and try to send AT command to modem */ + ret = modem_cmd_send(&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 setup returned %d, %s", + ret, "AT cmds failed"); + } else { + LOG_INF("AT channel %d connected to %s", + DLCI_AT, gsm->at_dev->config->name); + } + } + } } static int mux_enable(struct gsm_modem *gsm) @@ -455,16 +479,23 @@ static void mux_setup(struct k_work *work) break; case STATE_DONE: - /* Re-use the original iface for AT channel */ - ret = modem_iface_uart_init(&gsm->context.iface, - &gsm->gsm_data, - gsm->at_dev->config->name); + /* 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->config->name); if (ret < 0) { - LOG_DBG("iface %suart error %d", "mux ", ret); + LOG_DBG("iface %suart error %d", "PPP ", ret); gsm->mux_enabled = false; goto fail; } + LOG_INF("PPP channel %d connected to %s", + DLCI_PPP, gsm->ppp_dev->config->name); + gsm_finalize_connection(gsm); break; } diff --git a/drivers/modem/modem_iface_uart.c b/drivers/modem/modem_iface_uart.c index 15d731f81b4..8b57cb3f30c 100644 --- a/drivers/modem/modem_iface_uart.c +++ b/drivers/modem/modem_iface_uart.c @@ -121,27 +121,15 @@ static int modem_iface_uart_write(struct modem_iface *iface, return 0; } -int modem_iface_uart_init(struct modem_iface *iface, - struct modem_iface_uart_data *data, - const char *dev_name) +int modem_iface_uart_init_dev(struct modem_iface *iface, + const char *dev_name) { - if (!iface || !data) { - return -EINVAL; - } - /* get UART device */ iface->dev = device_get_binding(dev_name); if (!iface->dev) { return -ENODEV; } - iface->iface_data = data; - iface->read = modem_iface_uart_read; - iface->write = modem_iface_uart_write; - - ring_buf_init(&data->rx_rb, data->rx_rb_buf_len, data->rx_rb_buf); - k_sem_init(&data->rx_sem, 0, 1); - uart_irq_rx_disable(iface->dev); uart_irq_tx_disable(iface->dev); modem_iface_uart_flush(iface); @@ -150,3 +138,33 @@ int modem_iface_uart_init(struct modem_iface *iface, return 0; } + +int modem_iface_uart_init(struct modem_iface *iface, + struct modem_iface_uart_data *data, + const char *dev_name) +{ + int ret; + + if (!iface || !data) { + return -EINVAL; + } + + iface->iface_data = data; + iface->read = modem_iface_uart_read; + iface->write = modem_iface_uart_write; + + ring_buf_init(&data->rx_rb, data->rx_rb_buf_len, data->rx_rb_buf); + k_sem_init(&data->rx_sem, 0, 1); + + /* get UART device */ + ret = modem_iface_uart_init_dev(iface, dev_name); + if (ret < 0) { + iface->iface_data = NULL; + iface->read = NULL; + iface->write = NULL; + + return ret; + } + + return 0; +} diff --git a/drivers/modem/modem_iface_uart.h b/drivers/modem/modem_iface_uart.h index 40cf4439e7a..d0b918ab016 100644 --- a/drivers/modem/modem_iface_uart.h +++ b/drivers/modem/modem_iface_uart.h @@ -35,6 +35,19 @@ struct modem_iface_uart_data { struct k_sem rx_sem; }; +/** + * @brief Init modem interface device for UART + * + * @details This can be called after the init if the UART is changed. + * + * @param *iface: modem interface to initialize. + * @param *dev_name: name of the UART device to use + * + * @retval 0 if ok, < 0 if error. + */ +int modem_iface_uart_init_dev(struct modem_iface *iface, + const char *dev_name); + /** * @brief Init modem interface for UART *