Skip to content

Commit 513507d

Browse files
authored
fix(ppp): Fix PPP.end() causing exception (#11987)
* fix(ppp): Fix PPP.end() causing exception * fix(periman): Return NULL if deinit callback is cleared
1 parent c64da25 commit 513507d

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

cores/esp32/esp32-hal-periman.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,11 +236,30 @@ bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t
236236
return true;
237237
}
238238

239+
// This no-op callback is used by perimanClearBusDeinit() to effectively disable bus deinit functionality
240+
// without setting the callback to NULL, which would cause errors in perimanSetPinBus() at line 146.
241+
static bool empty_bus_deinit_cb(void *bus) {
242+
return true;
243+
}
244+
245+
bool perimanClearBusDeinit(peripheral_bus_type_t type) {
246+
if (type >= ESP32_BUS_TYPE_MAX || type == ESP32_BUS_TYPE_INIT) {
247+
log_e("Invalid type: %s (%u)", perimanGetTypeName(type), (unsigned int)type);
248+
return false;
249+
}
250+
deinit_functions[type] = empty_bus_deinit_cb;
251+
log_v("Deinit function for type %s (%u) cleared", perimanGetTypeName(type), (unsigned int)type);
252+
return true;
253+
}
254+
239255
peripheral_bus_deinit_cb_t perimanGetBusDeinit(peripheral_bus_type_t type) {
240256
if (type >= ESP32_BUS_TYPE_MAX || type == ESP32_BUS_TYPE_INIT) {
241257
log_e("Invalid type: %s (%u)", perimanGetTypeName(type), (unsigned int)type);
242258
return NULL;
243259
}
260+
if (deinit_functions[type] == empty_bus_deinit_cb) {
261+
return NULL;
262+
}
244263
return deinit_functions[type];
245264
}
246265

cores/esp32/esp32-hal-periman.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ int8_t perimanGetPinBusChannel(uint8_t pin);
134134
// Sets the peripheral destructor callback. Used to destroy bus when pin is assigned another function
135135
bool perimanSetBusDeinit(peripheral_bus_type_t type, peripheral_bus_deinit_cb_t cb);
136136

137+
// Clears the peripheral destructor callback
138+
bool perimanClearBusDeinit(peripheral_bus_type_t type);
139+
137140
// Get the peripheral destructor callback. It allows changing/restoring the peripheral pin function detaching, if necessary
138141
// returns NULL if none is set
139142
peripheral_bus_deinit_cb_t perimanGetBusDeinit(peripheral_bus_type_t type);

libraries/PPP/src/PPP.cpp

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,11 @@ void PPPClass::end(void) {
394394
Network.postEvent(&arduino_event);
395395
}
396396

397+
if (_dce != NULL) {
398+
esp_modem_destroy(_dce);
399+
_dce = NULL;
400+
}
401+
397402
destroyNetif();
398403

399404
if (_ppp_ev_instance != NULL) {
@@ -406,10 +411,10 @@ void PPPClass::end(void) {
406411
Network.removeEvent(_ppp_event_handle);
407412
_ppp_event_handle = 0;
408413

409-
if (_dce != NULL) {
410-
esp_modem_destroy(_dce);
411-
_dce = NULL;
412-
}
414+
perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_TX);
415+
perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_RX);
416+
perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_RTS);
417+
perimanClearBusDeinit(ESP32_BUS_TYPE_PPP_CTS);
413418

414419
int8_t pin = -1;
415420
if (_pin_tx != -1) {
@@ -438,6 +443,11 @@ void PPPClass::end(void) {
438443
perimanClearPinBus(pin);
439444
}
440445

446+
perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_TX, PPPClass::pppDetachBus);
447+
perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RX, PPPClass::pppDetachBus);
448+
perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_RTS, PPPClass::pppDetachBus);
449+
perimanSetBusDeinit(ESP32_BUS_TYPE_PPP_CTS, PPPClass::pppDetachBus);
450+
441451
_mode = ESP_MODEM_MODE_COMMAND;
442452
}
443453

0 commit comments

Comments
 (0)