h2zero / NimBLE-Arduino

A fork of the NimBLE library structured for compilation with Arduino, for use with ESP32, nRF5x.
https://h2zero.github.io/NimBLE-Arduino/
Apache License 2.0
703 stars 147 forks source link

Getting status code 6 after 16-17th notify when sending files in chunks #730

Open ctaskin opened 3 days ago

ctaskin commented 3 days ago

I am trying to send large text files to iPhone using notify (tried indicate also). Even if I added from 100 to 10.000 ms delay between chunks, I am starting to get "Notification/Indication status code: 4, return code: 6, " error from ESP side and iPhone client disconnets at that time (ESP continues to send notifications)

I tried dirrent MTU sizes (from 20 to 200), diffent delays between chunks (100 to 10.000) but I am getting the error after simiar number of (around 16-17) messages sent successfully. I was trying to solve this for 3 days but could not find any solution. help please!

Device has been bonded and authenticated. Some code and logs are below...

#define BLE_MTU_SIZE 50

NimBLEDevice::setPower(ESP_PWR_LVL_P9); /** +9db */
  NimBLEDevice::setSecurityAuth(true, true, false);
  NimBLEDevice::setSecurityIOCap(BLE_HS_IO_DISPLAY_ONLY);
  NimBLEDevice::setMTU((BLE_MTU_SIZE + 3));

  logFileCharacteristic = bleService->createCharacteristic(
      LOG_FILE_UUID,
      NIMBLE_PROPERTY::READ_AUTHEN |
          NIMBLE_PROPERTY::READ_ENC |
          NIMBLE_PROPERTY::NOTIFY |
          NIMBLE_PROPERTY::WRITE_AUTHEN |
          NIMBLE_PROPERTY::WRITE_ENC);
  logFileCharacteristic->setCallbacks(&chrCallbacks);

void sendLogFileToBLE(const char* filename) {
    size_t fileSize;
    char* fileData = getLogFileData(filename, &fileSize);

    size_t offset = 0;

    // Loop through the buffer, sending it in chunks over BLE
    while (offset < fileSize) {
        // Determine the chunk size (either MTU size or the remaining bytes in the buffer)
        size_t chunkSize = min(size_t(BLE_MTU_SIZE), fileSize - offset);

        debugPrint("[BLE] Sending File Chunk: " + String(offset) + " to " + String(offset + chunkSize));

        // Send the chunk over BLE
        logFileCharacteristic->setValue((uint8_t*)(fileData + offset), chunkSize);
        logFileCharacteristic->notify();

        // Advance the offset by the chunk size
        offset += chunkSize;

        delay(1000);
    }

        logFileCharacteristic->setValue("*EOF*");
        logFileCharacteristic->notify();
         debugPrint("[BLE] Log file successfully sent.");
}

Here is a log:

17:04:50.572 > [BLE] Sending File Chunk: 0 to 50 17:04:50.572 > Sending notification to clients 17:04:50.572 > Notification/Indication status code: 1, return code: 0, 17:04:51.572 > [BLE] Sending File Chunk: 50 to 100 17:04:51.572 > Sending notification to clients 17:04:51.572 > Notification/Indication status code: 1, return code: 0, 17:04:52.572 > [BLE] Sending File Chunk: 100 to 150 17:04:52.573 > Sending notification to clients 17:04:52.573 > Notification/Indication status code: 1, return code: 0, 17:04:53.572 > [BLE] Sending File Chunk: 150 to 200 17:04:53.577 > Sending notification to clients 17:04:53.577 > Notification/Indication status code: 1, return code: 0, 17:04:54.572 > [BLE] Sending File Chunk: 200 to 250 17:04:54.572 > Sending notification to clients 17:04:54.572 > Notification/Indication status code: 1, return code: 0, 17:04:55.575 > [BLE] Sending File Chunk: 250 to 300 17:04:55.575 > Sending notification to clients 17:04:55.575 > Notification/Indication status code: 1, return code: 0, 17:04:56.572 > [BLE] Sending File Chunk: 300 to 350 17:04:56.572 > Sending notification to clients 17:04:56.574 > Notification/Indication status code: 1, return code: 0, 17:04:57.572 > [BLE] Sending File Chunk: 350 to 400 17:04:57.573 > Sending notification to clients 17:04:57.573 > Notification/Indication status code: 1, return code: 0, 17:04:58.573 > [BLE] Sending File Chunk: 400 to 450 17:04:58.573 > Sending notification to clients 17:04:58.573 > Notification/Indication status code: 1, return code: 0, 17:04:59.573 > [BLE] Sending File Chunk: 450 to 500 17:04:59.573 > Sending notification to clients 17:04:59.573 > Notification/Indication status code: 1, return code: 0, 17:05:00.572 > [BLE] Sending File Chunk: 500 to 550 17:05:00.573 > Sending notification to clients 17:05:00.574 > Notification/Indication status code: 1, return code: 0, 17:05:01.573 > [BLE] Sending File Chunk: 550 to 600 17:05:01.573 > Sending notification to clients 17:05:01.573 > Notification/Indication status code: 1, return code: 0, 17:05:02.573 > [BLE] Sending File Chunk: 600 to 650 17:05:02.573 > Sending notification to clients 17:05:02.573 > Notification/Indication status code: 1, return code: 0, 17:05:03.572 > [BLE] Sending File Chunk: 650 to 700 17:05:03.573 > Sending notification to clients 17:05:03.573 > Notification/Indication status code: 1, return code: 0, 17:05:04.573 > [BLE] Sending File Chunk: 700 to 750 17:05:04.573 > Sending notification to clients 17:05:04.573 > Notification/Indication status code: 1, return code: 0, 17:05:05.572 > [BLE] Sending File Chunk: 750 to 800 17:05:05.573 > Sending notification to clients 17:05:05.573 > Notification/Indication status code: 1, return code: 0, 17:05:06.575 > [BLE] Sending File Chunk: 800 to 850 17:05:06.575 > Sending notification to clients 17:05:06.575 > Notification/Indication status code: 1, return code: 0, 17:05:07.573 > [BLE] Sending File Chunk: 850 to 900 17:05:07.573 > Sending notification to clients 17:05:07.573 > Notification/Indication status code: 4, return code: 6, 17:05:08.572 > [BLE] Sending File Chunk: 900 to 950 17:05:08.572 > Sending notification to clients 17:05:08.572 > Notification/Indication status code: 4, return code: 6, 17:05:09.573 > [BLE] Sending File Chunk: 950 to 1000 17:05:09.573 > Sending notification to clients 17:05:09.573 > Notification/Indication status code: 4, return code: 6, 17:05:10.573 > [BLE] Sending File Chunk: 1000 to 1050 17:05:10.573 > Sending notification to clients 17:05:10.573 > Notification/Indication status code: 4, return code: 6, 17:05:11.573 > [BLE] Sending File Chunk: 1050 to 1100 17:05:11.573 > Sending notification to clients 17:05:11.573 > Notification/Indication status code: 4, return code: 6, 17:05:12.573 > [BLE] Sending File Chunk: 1100 to 1150 17:05:12.573 > Sending notification to clients 17:05:12.573 > Notification/Indication status code: 4, return code: 6, 17:05:13.573 > [BLE] Sending File Chunk: 1150 to 1200 17:05:13.573 > Sending notification to clients 17:05:13.573 > Notification/Indication status code: 4, return code: 6, 17:05:14.573 > [BLE] Sending File Chunk: 1200 to 1250 17:05:14.573 > Sending notification to clients 17:05:14.573 > Notification/Indication status code: 4, return code: 6

h2zero commented 2 days ago

The stack is running out of buffers, which shouldn't happen if the data is actually sent. From where are you calling the sendLogFileToBLE function?

ctaskin commented 1 day ago

It is called from the callback function which is triggered by the client via BT with the requested filename.

  logFileRequestCharacteristic = bleService->createCharacteristic(
                        LOG_FILE_REQUEST_UUID,
                        NIMBLE_PROPERTY::WRITE);

    // Set callback to handle acknowledgment write
  logFileRequestCharacteristic->setCallbacks(new LogFileRequestCallback());
class LogFileRequestCallback : public NimBLECharacteristicCallbacks {
    void onWrite(NimBLECharacteristic* pCharacteristic) {
        std::string fileName = pCharacteristic->getValue();
        sendLogFileToBLE(fileName.c_str());

    }
};
h2zero commented 1 day ago

That's the error then, the stack is not able to continue until you return from the callback. You should ether set a flag or start a task in the callback that calls that function.