diff --git a/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild b/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild index d5d6381b08..2bb3e4c551 100644 --- a/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild +++ b/components/esp_modem/examples/pppos_client/main/Kconfig.projbuild @@ -211,4 +211,13 @@ menu "Example Configuration" publishes another MQTT message. Connection to the MQTT broker should be kept. + config EXAMPLE_DETECT_MODE_BEFORE_CONNECT + bool "Detect mode before connect" + default n + help + Set this to true to demonstrate mode auto-detection. + If enabled, the example tries to recognize the actual mode. + If mode is detected correctly and it is not a command mode, + then the example switches to command mode. + endmenu diff --git a/components/esp_modem/examples/pppos_client/main/pppos_client_main.c b/components/esp_modem/examples/pppos_client/main/pppos_client_main.c index 7c0212eefb..457a8ebf1e 100644 --- a/components/esp_modem/examples/pppos_client/main/pppos_client_main.c +++ b/components/esp_modem/examples/pppos_client/main/pppos_client_main.c @@ -34,6 +34,7 @@ static const char *TAG = "pppos_example"; static EventGroupHandle_t event_group = NULL; static const int CONNECT_BIT = BIT0; +static const int DISCONNECT_BIT = BIT1; static const int GOT_DATA_BIT = BIT2; static const int USB_DISCONNECTED_BIT = BIT3; // Used only with USB DTE but we define it unconditionally, to avoid too many #ifdefs in the code @@ -55,6 +56,7 @@ static void usb_terminal_error_handler(esp_modem_terminal_error_t err) } #define CHECK_USB_DISCONNECTION(event_group) \ if ((xEventGroupGetBits(event_group) & USB_DISCONNECTED_BIT) == USB_DISCONNECTED_BIT) { \ + ESP_LOGE(TAG, "USB_DISCONNECTED_BIT destroying modem dce"); \ esp_modem_destroy(dce); \ continue; \ } @@ -140,6 +142,7 @@ static void on_ip_event(void *arg, esp_event_base_t event_base, ESP_LOGI(TAG, "GOT ip event!!!"); } else if (event_id == IP_EVENT_PPP_LOST_IP) { ESP_LOGI(TAG, "Modem Disconnect from PPP Server"); + xEventGroupSetBits(event_group, DISCONNECT_BIT); } else if (event_id == IP_EVENT_GOT_IP6) { ESP_LOGI(TAG, "GOT IPv6 event!"); @@ -158,6 +161,7 @@ void app_main(void) ESP_ERROR_CHECK(esp_event_handler_register(NETIF_PPP_STATUS, ESP_EVENT_ANY_ID, &on_ppp_changed, NULL)); /* Configure the PPP netif */ + esp_err_t err; esp_modem_dce_config_t dce_config = ESP_MODEM_DCE_DEFAULT_CONFIG(CONFIG_EXAMPLE_MODEM_PPP_APN); esp_netif_config_t netif_ppp_config = ESP_NETIF_DEFAULT_PPP(); esp_netif_t *esp_netif = esp_netif_new(&netif_ppp_config); @@ -177,7 +181,7 @@ void app_main(void) dte_config.uart_config.rx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE; dte_config.uart_config.tx_buffer_size = CONFIG_EXAMPLE_MODEM_UART_TX_BUFFER_SIZE; dte_config.uart_config.event_queue_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_QUEUE_SIZE; - dte_config.task_stack_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE * 2; + dte_config.task_stack_size = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_STACK_SIZE; dte_config.task_priority = CONFIG_EXAMPLE_MODEM_UART_EVENT_TASK_PRIORITY; dte_config.dte_buffer_size = CONFIG_EXAMPLE_MODEM_UART_RX_BUFFER_SIZE / 2; @@ -205,7 +209,7 @@ void app_main(void) #endif assert(dce); if (dte_config.uart_config.flow_control == ESP_MODEM_FLOW_CONTROL_HW) { - esp_err_t err = esp_modem_set_flow_control(dce, 2, 2); //2/2 means HW Flow Control. + err = esp_modem_set_flow_control(dce, 2, 2); //2/2 means HW Flow Control. if (err != ESP_OK) { ESP_LOGE(TAG, "Failed to set the set_flow_control mode"); return; @@ -246,23 +250,27 @@ void app_main(void) #error Invalid serial connection to modem. #endif - xEventGroupClearBits(event_group, CONNECT_BIT | GOT_DATA_BIT | USB_DISCONNECTED_BIT); +#if CONFIG_EXAMPLE_DETECT_MODE_BEFORE_CONNECT + xEventGroupClearBits(event_group, CONNECT_BIT | GOT_DATA_BIT | USB_DISCONNECTED_BIT | DISCONNECT_BIT); - esp_err_t err = esp_modem_set_mode(dce, ESP_MODEM_MODE_DETECT); + err = esp_modem_set_mode(dce, ESP_MODEM_MODE_DETECT); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_modem_set_mode(ESP_MODEM_MODE_DETECT) failed with %d", err); return; } - ESP_LOGI(TAG, "Mode detected!"); esp_modem_dce_mode_t mode = esp_modem_get_mode(dce); - ESP_LOGI(TAG, "Current mode is : %d", mode); - if (mode != ESP_MODEM_MODE_COMMAND) { + ESP_LOGI(TAG, "Mode detection completed: current mode is: %d", mode); + if (mode == ESP_MODEM_MODE_DATA) { // set back to command mode err = esp_modem_set_mode(dce, ESP_MODEM_MODE_COMMAND); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_modem_set_mode(ESP_MODEM_MODE_COMMAND) failed with %d", err); return; } + ESP_LOGI(TAG, "Command mode restored"); } +#endif // CONFIG_EXAMPLE_DETECT_MODE_BEFORE_CONNECT + + xEventGroupClearBits(event_group, CONNECT_BIT | GOT_DATA_BIT | USB_DISCONNECTED_BIT | DISCONNECT_BIT); /* Run the modem demo app */ #if CONFIG_EXAMPLE_NEED_SIM_PIN == 1 @@ -317,19 +325,24 @@ void app_main(void) } /* Wait for IP address */ ESP_LOGI(TAG, "Waiting for IP address"); - xEventGroupWaitBits(event_group, CONNECT_BIT | USB_DISCONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY); + xEventGroupWaitBits(event_group, CONNECT_BIT | USB_DISCONNECTED_BIT | DISCONNECT_BIT, pdFALSE, pdFALSE, + pdMS_TO_TICKS(60000)); CHECK_USB_DISCONNECTION(event_group); + if ((xEventGroupGetBits(event_group) & CONNECT_BIT) != CONNECT_BIT) { + ESP_LOGW(TAG, "Modem not connected, switching back to the command mode"); + err = esp_modem_set_mode(dce, ESP_MODEM_MODE_COMMAND); + if (err != ESP_OK) { + ESP_LOGE(TAG, "esp_modem_set_mode(ESP_MODEM_MODE_COMMAND) failed with %d", err); + return; + } + ESP_LOGI(TAG, "Command mode restored"); + return; + } /* Config MQTT */ -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0) esp_mqtt_client_config_t mqtt_config = { .broker.address.uri = CONFIG_EXAMPLE_MQTT_BROKER_URI, }; -#else - esp_mqtt_client_config_t mqtt_config = { - .uri = CONFIG_EXAMPLE_MQTT_BROKER_URI, - }; -#endif esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config); esp_mqtt_client_register_event(mqtt_client, ESP_EVENT_ANY_ID, mqtt_event_handler, NULL); esp_mqtt_client_start(mqtt_client); @@ -345,7 +358,7 @@ void app_main(void) ESP_LOGI(TAG, "Signal quality: rssi=%d, ber=%d", rssi, ber); esp_modem_pause_net(dce, false); esp_mqtt_client_publish(mqtt_client, CONFIG_EXAMPLE_MQTT_TEST_TOPIC, CONFIG_EXAMPLE_MQTT_TEST_DATA, 0, 0, 0); -#endif +#endif // CONFIG_EXAMPLE_PAUSE_NETIF_TO_CHECK_SIGNAL ESP_LOGI(TAG, "Waiting for MQTT data"); xEventGroupWaitBits(event_group, GOT_DATA_BIT | USB_DISCONNECTED_BIT, pdFALSE, pdFALSE, portMAX_DELAY); diff --git a/components/esp_modem/examples/pppos_client/pytest_pppos_client.py b/components/esp_modem/examples/pppos_client/pytest_pppos_client.py index 2ffb42cabc..6c823c5aa9 100644 --- a/components/esp_modem/examples/pppos_client/pytest_pppos_client.py +++ b/components/esp_modem/examples/pppos_client/pytest_pppos_client.py @@ -12,7 +12,7 @@ def test_pppos_connect(dut): 4. checks that the client cleanly disconnects """ # Check the sequence of connecting, publishing, disconnecting - dut.expect('Modem Connect to PPP Server') + dut.expect('Modem Connect to PPP Server', timeout=90) # Check for MQTT connection and the data event dut.expect('MQTT_EVENT_CONNECTED') dut.expect('MQTT_EVENT_DATA') diff --git a/components/esp_modem/examples/pppos_client/sdkconfig.ci.sim800_c3 b/components/esp_modem/examples/pppos_client/sdkconfig.ci.sim800_c3 index a537afeb22..23b0fc200f 100644 --- a/components/esp_modem/examples/pppos_client/sdkconfig.ci.sim800_c3 +++ b/components/esp_modem/examples/pppos_client/sdkconfig.ci.sim800_c3 @@ -14,4 +14,4 @@ CONFIG_EXAMPLE_MQTT_TEST_TOPIC="/ci/esp-modem/pppos-client" CONFIG_EXAMPLE_PAUSE_NETIF_TO_CHECK_SIGNAL=y CONFIG_ESP_SYSTEM_PANIC_PRINT_HALT=y CONFIG_ESP32_PANIC_PRINT_HALT=y -CONFIG_LOG_DEFAULT_LEVEL_DEBUG=y +CONFIG_EXAMPLE_DETECT_MODE_BEFORE_CONNECT=y diff --git a/components/esp_modem/examples/simple_cmux_client/sdkconfig.ci.sim800_cmux b/components/esp_modem/examples/simple_cmux_client/sdkconfig.ci.sim800_cmux index 6bf623113c..6a22a89f12 100644 --- a/components/esp_modem/examples/simple_cmux_client/sdkconfig.ci.sim800_cmux +++ b/components/esp_modem/examples/simple_cmux_client/sdkconfig.ci.sim800_cmux @@ -16,3 +16,4 @@ CONFIG_COMPILER_CXX_EXCEPTIONS=y CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192 CONFIG_EXAMPLE_CLOSE_CMUX_AT_END=y CONFIG_EXAMPLE_MQTT_TEST_TOPIC="/ci/esp-modem/pppos-client" +CONFIG_BROKER_URI="mqtt://mqtt.eclipseprojects.io" diff --git a/components/esp_modem/src/esp_modem_c_api.cpp b/components/esp_modem/src/esp_modem_c_api.cpp index 036e013630..e9698995e1 100644 --- a/components/esp_modem/src/esp_modem_c_api.cpp +++ b/components/esp_modem/src/esp_modem_c_api.cpp @@ -516,3 +516,11 @@ extern "C" esp_err_t esp_modem_pause_net(esp_modem_dce_t *dce_wrap, bool pause) } return command_response_to_esp_err(dce_wrap->dce->pause_netif(pause)); } + +extern "C" esp_err_t esp_modem_hang_up(esp_modem_dce_t *dce_wrap) +{ + if (dce_wrap == nullptr || dce_wrap->dce == nullptr) { + return ESP_ERR_INVALID_ARG; + } + return command_response_to_esp_err(dce_wrap->dce->hang_up()); +}