espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.89k stars 7.33k forks source link

How to restart pppos client? (IDFGH-2105) (IDFGH-2106) #4268

Closed sim-pixel closed 4 years ago

sim-pixel commented 5 years ago

Environment

Problem Description

I'm trying to develop a function that restart the pppos client every X seconds.

I take the code from you repo (https://github.com/espressif/esp-idf/blob/master/examples/protocols/pppos_client/main/pppos_client_main.c). I just changed the function name from "app_main()" to "pppos_init()", so this is my function (in pppos.c): void pppos_init() { tcpip_adapter_init(); event_group = xEventGroupCreate(); /* create dte object */ esp_modem_dte_config_t config = ESP_MODEM_DTE_DEFAULT_CONFIG(); modem_dte_t *dte = esp_modem_dte_init(&config); // Register event handler // ESP_ERROR_CHECK(esp_modem_add_event_handler(dte, modem_event_handler, NULL)); // create dce object // #if CONFIG_ESP_MODEM_DEVICE_SIM800 modem_dce_t *dce = sim800_init(dte); #elif CONFIG_ESP_MODEM_DEVICE_BG96 modem_dce_t *dce = bg96_init(dte); #else #error "Unsupported DCE" #endif ESP_ERROR_CHECK(dce->set_flow_ctrl(dce, MODEM_FLOW_CONTROL_NONE)); ESP_ERROR_CHECK(dce->store_profile(dce)); // Print Module ID, Operator, IMEI, IMSI // ESP_LOGI(TAG, "Module: %s", dce->name); ESP_LOGI(TAG, "Operator: %s", dce->oper); ESP_LOGI(TAG, "IMEI: %s", dce->imei); ESP_LOGI(TAG, "IMSI: %s", dce->imsi); // Get signal quality // uint32_t rssi = 0, ber = 0; ESP_ERROR_CHECK(dce->get_signal_quality(dce, &rssi, &ber)); ESP_LOGI(TAG, "rssi: %d, ber: %d", rssi, ber); // Get battery voltage // uint32_t voltage = 0, bcs = 0, bcl = 0; ESP_ERROR_CHECK(dce->get_battery_status(dce, &bcs, &bcl, &voltage)); ESP_LOGI(TAG, "Battery voltage: %d mV", voltage); // Setup PPP environment // esp_modem_setup_ppp(dte, configuration_get(CONF_APN)); // Wait for IP address // xEventGroupWaitBits(event_group, CONNECT_BIT, pdTRUE, pdTRUE, portMAX_DELAY); // Config MQTT // esp_mqtt_client_config_t mqtt_config = { .uri = BROKER_URL, .event_handle = mqtt_event_handler, }; esp_mqtt_client_handle_t mqtt_client = esp_mqtt_client_init(&mqtt_config); esp_mqtt_client_start(mqtt_client); xEventGroupWaitBits(event_group, GOT_DATA_BIT, pdTRUE, pdTRUE, portMAX_DELAY); esp_mqtt_client_destroy(mqtt_client); // Exit PPP mode // ESP_ERROR_CHECK(esp_modem_exit_ppp(dte)); xEventGroupWaitBits(event_group, STOP_BIT, pdTRUE, pdTRUE, portMAX_DELAY); #if CONFIG_EXAMPLE_SEND_MSG const char *message = "Welcome to ESP32!"; ESP_ERROR_CHECK(example_send_message_text(dce, CONFIG_EXAMPLE_SEND_MSG_PEER_PHONE_NUMBER, message)); ESP_LOGI(TAG, "Send send message [%s] ok", message); #endif // Power down module // ESP_ERROR_CHECK(dce->power_down(dce)); ESP_LOGI(TAG, "Power down"); ESP_ERROR_CHECK(dce->deinit(dce)); ESP_ERROR_CHECK(dte->deinit(dte)); }

In my main function (main.c) I run the following function: void app_main() { for(int i=0; i<5; i++){ vTaskDelay( 20000 / portTICK_PERIOD_MS ); pppos_init(); } }

The first time (i=0) i can see "Modem PPP Started" and all data are sent via MQTT. At the second time (i=1) it stucks.

Any guidance will be helpful. Thanks

sim-pixel commented 5 years ago

Any suggestions?

AshUK commented 5 years ago

Having issues with this too

I see that once MODEM_EVENT_PPP_DISCONNECT has been raised, esp_modem_exit_ppp causes the the task to wait

MrCurio commented 4 years ago

Having similiar issues to restart ppos client. Particularly, using trying to reinit the client causes crashing, anyway, i also posted a similar issue on github called: "PppoS: Uart Resync Problems". Hope they will fix this soon :)

MrCurio commented 4 years ago

Found some interesting info in #3506 ! It may not be thread safe but some people made it work, i will give it a try!

vinifr commented 4 years ago

During the ppp setup call _pppapi_ppposcreate and _pppapi_setdefault only 1 time. So when it is reconnecting skip these functions and call only _pppapiconnect.

In exit it must call only _pppapiclose. Do not call _pppapifree! That will solve the issue.

Example:

// Dont create ppp instance twice!!
if (!pppReconnect) {
    ppp = pppapi_pppos_create(&ppp_netif,
                            ppp_output_callback, ppp_status_cb, NULL);
    pppapi_set_default(ppp);
}
pppapi_connect(ppp, 0);
diogoviannaaraujo commented 4 years ago

Ive been trying to reconnect the ppp connection after a connection drop.

For my test I get a proper connection and then cover the modem with foil, after receiving PPPERR_PEERDEAD err_code on ppp_status_cb from missed LCP echo packages I remove foil cover, wait some seconds, and call only pppapi_connect(ppp, 0)

but it always just return PPPERR_PEERDEAD err_code again on ppp_status_cb.

Should I do all the chat script again after a connection drop?

Alvin1Zhang commented 4 years ago

@diogoviannaaraujo Thanks for reporting. Would you please help file a new ticket for the new issue? Thanks.