fix(modem): Minor cleanup of pppos example

* Use CONFIG_EXAMPLE_DETECT_MODE_BEFORE_CONNECT to demonstrate mode
detect
* Use disconnection flag to indicate conneciton issue and gracefully
degrade to command mode
* Remove IDF-verion < v5.0 code
This commit is contained in:
David Cermak
2024-12-06 10:56:06 +01:00
parent c989c6adae
commit 5e929902c7
6 changed files with 48 additions and 17 deletions

View File

@ -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

View File

@ -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);

View File

@ -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')

View File

@ -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

View File

@ -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"

View File

@ -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());
}