nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.37k stars 710 forks source link

ESP32 semaphore client writeValue lockup #1034

Closed tonton81 closed 3 years ago

tonton81 commented 3 years ago

I am writing using writeValue in my loop. I test killing power on my BT device and re-applying it. The disconnect callback works but the loop freezes up. I checked into the BLERemoteCharacteristic.cpp file and commented out one line:

`void BLERemoteCharacteristic::writeValue(uint8_t data, size_t length, bool response) { // writeValue(std::string((char)data, length), response); log_v(">> writeValue(), length: %d", length);

// Check to see that we are connected.
if (!getRemoteService()->getClient()->isConnected()) {
    log_e("Disconnected");
    return;
}

//m_semaphoreWriteCharEvt.take("writeValue"); // <-- THIS IS COMMENTED OUT
// Invoke the ESP-IDF API to perform the write.
esp_err_t errRc = ::esp_ble_gattc_write_char(
    m_pRemoteService->getClient()->getGattcIf(),
    m_pRemoteService->getClient()->getConnId(),
    getHandle(),
    length,
    data,
    response?ESP_GATT_WRITE_TYPE_RSP:ESP_GATT_WRITE_TYPE_NO_RSP,
    m_auth
);

if (errRc != ESP_OK) {
    log_e("esp_ble_gattc_write_char: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
    return;
}

m_semaphoreWriteCharEvt.wait("writeValue");

log_v("<< writeValue");

} // writeValue `

Is there any reprocussions or side effects by disabling this? Now the code never freezes up and continues working despite me unplugging and plugging in the BT device's power source! :)

EDIT: while killing the device power and waiting for disconnected callback, loop never stops working, great! However, if i cut power and re-apply before the disconnected callback fires, then the loop() locks up again :(

tonton81 commented 3 years ago

looks like I figured out the lockup issue. I wrote a multiple connection utility which connects X amount of devices (i set 4) where each slot is a MAC address. So if the non-blocking scan picks up the MAC it auto connects to the proper array index. There were 2 issues, the semaphore needs to be commented out in above I posted to prevent writeValue from locking up during reconnections, and that if the MAC address was picked up in the scan BEFORE it had a chance to disconnect, the code would process a:

new BLEAdvertisedDevice(device);

in this case, it was a simple ONE line fix: `

    if ( _client[j]->isConnected() ) return; //  (prevents lockup by not reconnecting until the disconnection occurs)
    _controller[j] = new BLEAdvertisedDevice(device);

`

now it is surviving disconnects and preventing reconnects until an actual disconnection occurs :)