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

Hang when trying to connect to a device that is not present #880

Open ASL07 opened 5 years ago

ASL07 commented 5 years ago

Hi,

I am using the latest code from arduino-esp32. When trying to connect to a device which is not available, the application hangs.

Is there a way to pass a timeout to the connect function or something like that?

Here is a capture of the logs:

.[0;32m[I][bleESP32.cpp:558] esp_ble_gap_cb(): Stop scan successfully.[0m
Connecting
.[0;32m[I][BLEDevice.cpp:600] addPeerDevice(): add conn_id: 0, GATT role: client.[0m
.[0;36m[D][FreeRTOS.cpp:158] take(): Semaphore taking: name: RegEvt (0x3ffe39d0), owner: <N/A> for connect.[0m
.[0;36m[D][FreeRTOS.cpp:167] take(): Semaphore taken:  name: RegEvt (0x3ffe39d0), owner: connect.[0m
.[0;36m[D][BLEDevice.cpp:154] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;36m[D][BLEClient.cpp:158] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;36m[D][FreeRTOS.cpp:158] take(): Semaphore taking: name: OpenEvt (0x3fff3e4c), owner: <N/A> for connect.[0m
.[0;36m[D][FreeRTOS.cpp:167] take(): Semaphore taken:  name: OpenEvt (0x3fff3e4c), owner: connect.[0m
.[0;36m[D][BLEDevice.cpp:154] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;36m[D][BLEClient.cpp:158] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;32m[I][BLEDevice.cpp:611] removePeerDevice(): remove: 0, GATT role client.[0m
.[0;36m[D][BLEDevice.cpp:154] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;36m[D][BLEDevice.cpp:154] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m

Thanks!

chegewara commented 5 years ago

I would suggest to change this line: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEClient.cpp#L127 and use this instead with some values that will satisfy your needs: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/FreeRTOS.cpp#L188

EDIT you will need to change some more code here too to return false when semaphore timeout: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/BLEClient.cpp#L127-L141

ASL07 commented 5 years ago

Hi, I tried your suggestion and it does not work. I think I must change something else The connect semaphore is taken even if the connection has not been made, so bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) never returns false.

Here is my code in case you want to have a loook:

bool FreeRTOS::Semaphore::take(uint32_t timeoutMs, std::string owner) {
    ESP_LOGV(LOG_TAG, "Semaphore taking: %s for %s", toString().c_str(), owner.c_str());
    bool rc = false;
    if (m_usePthreads) {
        assert(false);  // We apparently don't have a timed wait for pthreads.
    } else {
        rc = ::xSemaphoreTake(m_semaphore, timeoutMs / portTICK_PERIOD_MS) == pdTRUE;
    }
    m_owner = owner;
    if (rc) {
        ESP_LOGV(LOG_TAG, "Semaphore taken:  %s", toString().c_str());
    } else {
        ESP_LOGE(LOG_TAG, "Semaphore NOT taken:  %s", toString().c_str());
    }
    return rc;
} // Semaphore::take

bool BLEClient::connect(BLEAddress address, esp_ble_addr_type_t type) {
    ESP_LOGD(LOG_TAG, ">> connect(%s)", address.toString().c_str());

    m_peerAddress = address;

    // Perform the open connection request against the target BLE Server.
    bool semaphoreTaken = m_semaphoreOpenEvt.take(2000, "connect");
    if (!semaphoreTaken) 
    {
        ESP_LOGE(LOG_TAG, "connect failed");
        return false;
    }
    esp_err_t errRc = ::esp_ble_gattc_open(
        m_gattc_if,
        *getPeerAddress().getNative(), // address
        type,          // Note: This was added on 2018-04-03 when the latest ESP-IDF was detected to have changed the signature.
        1                              // direct connection <-- maybe needs to be changed in case of direct indirect connection???
    );
    if (errRc != ESP_OK) {
        ESP_LOGE(LOG_TAG, "esp_ble_gattc_open: rc=%d %s", errRc, GeneralUtils::errorToString(errRc));
        return false;
    }

    uint32_t rc = m_semaphoreOpenEvt.wait("connect");   // Wait for the connection to complete.
    ESP_LOGD(LOG_TAG, "<< connect(), rc=%d", rc==ESP_GATT_OK);
    return rc == ESP_GATT_OK;
} // connect

Logs:

.[0;36m[D][BLEClient.cpp:120] connect(): >> connect(4c:65:a8:d4:13:78).[0m
.[0;37m[V][FreeRTOS.cpp:189] take(): Semaphore taking: name: OpenEvt (0x3ffdfd10), owner: <N/A> for connect.[0m
.[0;37m[V][FreeRTOS.cpp:198] take(): Semaphore taken:  name: OpenEvt (0x3ffdfd10), owner: connect.[0m
.[0;37m[V][FreeRTOS.cpp:69] wait(): >> wait: Semaphore waiting: name: OpenEvt (0x3ffdfd10), owner: connect for connect.[0m
.[0;37m[V][BLEUtils.cpp:952] gattClientEventTypeToString(): Unknown GATT Client event type: 41.[0m
.[0;36m[D][BLEDevice.cpp:150] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;37m[V][BLEUtils.cpp:952] gattClientEventTypeToString(): Unknown GATT Client event type: 41.[0m
.[0;37m[V][BLEUtils.cpp:1284] dumpGattClientEvent(): GATT Event: Unknown.[0m
.[0;37m[V][BLEUtils.cpp:952] gattClientEventTypeToString(): Unknown GATT Client event type: 41.[0m
.[0;36m[D][BLEClient.cpp:173] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;37m[V][BLEUtils.cpp:952] gattClientEventTypeToString(): Unknown GATT Client event type: 2.[0m
.[0;36m[D][BLEDevice.cpp:150] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;37m[V][BLEUtils.cpp:952] gattClientEventTypeToString(): Unknown GATT Client event type: 2.[0m
.[0;37m[V][BLEUtils.cpp:1284] dumpGattClientEvent(): GATT Event: Unknown.[0m
.[0;37m[V][BLEUtils.cpp:952] gattClientEventTypeToString(): Unknown GATT Client event type: 2.[0m
.[0;36m[D][BLEClient.cpp:173] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown.[0m
.[0;37m[V][FreeRTOS.cpp:119] give(): Semaphore giving: name: OpenEvt (0x3ffdfd10), owner: connect.[0m
.[0;37m[V][FreeRTOS.cpp:85] wait(): << wait: Semaphore released: name: OpenEvt (0x3ffdfd10), owner: <N/A>.[0m
.[0;36m[D][BLEClient.cpp:143] connect(): << connect(), rc=0.[0m
.[0;36m[D][BLEClient.cpp:153] disconnect(): >> disconnect().[0m
.[0;33m[W][BLEClient.cpp:154] disconnect(): gattIf: 4, connId: 0.[0m
.[0;36m[D][BLEClient.cpp:160] disconnect(): << disconnect().[0m
chegewara commented 5 years ago

Then its not problem with hang when connect.

.[0;36m[D][BLEClient.cpp:153] disconnect(): >> disconnect().[0m
.[0;33m[W][BLEClient.cpp:154] disconnect(): gattIf: 4, connId: 0.[0m
.[0;36m[D][BLEClient.cpp:160] disconnect(): << disconnect()

Maybe the same change should be applied somewhere else, but i dont know where. Not enough data and im too lazy to test where it should be.

ASL07 commented 5 years ago

Thanks anyway :) I'll try to patch it or work around it. I will let you know if I make any progress. If not , hopefully you get some time to look at it further on.