From e8da66b9965cec5ab76ccd574e192ef693ac4aaf Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 6 Nov 2025 01:44:57 +0200 Subject: [PATCH 1/2] fix(ppp): Fix PPP.end() causing exception --- cores/esp32/esp32-hal-periman.c | 14 ++++++++++++++ cores/esp32/esp32-hal-periman.h | 3 +++ libraries/PPP/src/PPP.cpp | 18 ++++++++++++++---- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/cores/esp32/esp32-hal-periman.c b/cores/esp32/esp32-hal-periman.c index 2ba8ffde5f7..64c7ac90f5e 100644 --- a/cores/esp32/esp32-hal-periman.c +++ b/cores/esp32/esp32-hal-periman.c @@ -236,6 +236,20 @@ bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t return true; } +static bool empty_bus_deinit_cb(void *bus) { + return true; +} + +bool perimanClearBusDeinit(peripheral_bus_type_t type) { + if (type >= ESP32_BUS_TYPE_MAX || type == ESP32_BUS_TYPE_INIT) { + log_e("Invalid type: %s (%u)", perimanGetTypeName(type), (unsigned int)type); + return false; + } + deinit_functions[type] = empty_bus_deinit_cb; + log_v("Deinit function for type %s (%u) cleared", perimanGetTypeName(type), (unsigned int)type); + return true; +} + peripheral_bus_deinit_cb_t perimanGetBusDeinit(peripheral_bus_type_t type) { if (type >= ESP32_BUS_TYPE_MAX || type == ESP32_BUS_TYPE_INIT) { log_e("Invalid type: %s (%u)", perimanGetTypeName(type), (unsigned int)type); diff --git a/cores/esp32/esp32-hal-periman.h b/cores/esp32/esp32-hal-periman.h index 08b8c791ea7..12563718e19 100644 --- a/cores/esp32/esp32-hal-periman.h +++ b/cores/esp32/esp32-hal-periman.h @@ -134,6 +134,9 @@ int8_t perimanGetPinBusChannel(uint8_t pin); // Sets the peripheral destructor callback. Used to destroy bus when pin is assigned another function bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t cb); +// Clears the peripheral destructor callback +bool perimanClearBusDeinit(peripheral_bus_type_t type); + // Get the peripheral destructor callback. It allows changing/restoring the peripheral pin function detaching, if necessary // returns NULL if none is set peripheral_bus_deinit_cb_t perimanGetBusDeinit(peripheral_bus_type_t type); diff --git a/libraries/PPP/src/PPP.cpp b/libraries/PPP/src/PPP.cpp index 5e713bc84b0..76c5fad0d78 100644 --- a/libraries/PPP/src/PPP.cpp +++ b/libraries/PPP/src/PPP.cpp @@ -394,6 +394,11 @@ void PPPClass::end(void) { Network.postEvent(&arduino_event); } + if (_dce != NULL) { + esp_modem_destroy(_dce); + _dce = NULL; + } + destroyNetif(); if (_ppp_ev_instance != NULL) { @@ -406,10 +411,10 @@ void PPPClass::end(void) { Network.removeEvent(_ppp_event_handle); _ppp_event_handle = 0; - if (_dce != NULL) { - esp_modem_destroy(_dce); - _dce = NULL; - } + perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_TX); + perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_RX); + perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_RTS); + perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_CTS); int8_t pin = -1; if (_pin_tx != -1) { @@ -438,6 +443,11 @@ void PPPClass::end(void) { perimanClearPinBus(pin); } + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_TX, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RX, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RTS, PPPClass::pppDetachBus); + perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_CTS, PPPClass::pppDetachBus); + _mode = ESP_MODEM_MODE_COMMAND; } From 87a834513a1c15e68a356ef3bab1d5414245acbb Mon Sep 17 00:00:00 2001 From: me-no-dev Date: Thu, 6 Nov 2025 01:55:15 +0200 Subject: [PATCH 2/2] fix(periman): Return NULL if deinit callback is cleared --- cores/esp32/esp32-hal-periman.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cores/esp32/esp32-hal-periman.c b/cores/esp32/esp32-hal-periman.c index 64c7ac90f5e..bec88b0fdeb 100644 --- a/cores/esp32/esp32-hal-periman.c +++ b/cores/esp32/esp32-hal-periman.c @@ -236,6 +236,8 @@ bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t return true; } +// This no-op callback is used by perimanClearBusDeinit() to effectively disable bus deinit functionality +// without setting the callback to NULL, which would cause errors in perimanSetPinBus() at line 146. static bool empty_bus_deinit_cb(void *bus) { return true; } @@ -255,6 +257,9 @@ peripheral_bus_deinit_cb_t perimanGetBusDeinit(peripheral_bus_type_t type) { log_e("Invalid type: %s (%u)", perimanGetTypeName(type), (unsigned int)type); return NULL; } + if (deinit_functions[type] == empty_bus_deinit_cb) { + return NULL; + } return deinit_functions[type]; }