Page 1 of 1

checking status of writeValue-response

Posted: Mon Jul 31, 2023 12:18 pm
by nicolaus
Hi,
I have a little project where my code is running on an esp32-c3, and I want to write values to a third party device.

BLERemoteCharacteristic::writeValue(...) has the option to request a response from the server. With the help of a sniffer I can see that a response is being sent. However, I cannot find a way to react to the response, or check the status of the response.

Is there a way to wait for a positive response, or check if a positive response has been received such that I could resend the write request after some time if there hasn't? In some cases I can also see (in the sniffed traffic) that there is no positive response, but an error sent by the slave (= ble-server); is there a way for me to receive that?

cheers, nicolaus

Re: checking status of writeValue-response

Posted: Sat Dec 14, 2024 12:40 pm
by AlwaysLearning
Sorry for resurrecting a dead thread, but I hope this might help you and others...

The responses to writeValue() requests are asynchronous notifications. After establishing your client, remote service and remote characteristic you need to register a callback function for notifications, e.g.:

Code: Select all

static void ApiCharacteristicCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic, uint8_t *pData, size_t length, bool isNotify) {
  Serial.print(">> ApiCharacteristicCallback, UUID: ");
  Serial.println(pBLERemoteCharacteristic->getUUID().toString().c_str());
  Serial.print("  data:");
  Serial.print(String(pData, length));
  Serial.println();
  //packet rebuilding not shown
  Serial.println("<< ApiCharacteristicCallback");
}

static void pokeSphero(BLEClient *client) {
  BLERemoteService *apiService = client->getService(BLEUUID("00010001-574f-4f20-5370-6865726f2121"));
  BLERemoteCharacteristic *apiCharacteristic = apiService->getCharacteristic(BLEUUID("00010002-574f-4f20-5370-6865726f2121"));
  apiCharacteristic->registerForNotify(ApiCharacteristicCallback, true);

  Serial.println("Wake up!");
  uint8_t wakePacket[] = { 0x8d, 0x0a, 0x13, 0x0d, 0x00, 0xd5, 0xd8 };
  apiCharacteristic->writeValue(wakePacket, sizeof wakePacket, true);

  delay(5000);

  Serial.println("Go to sleep!");
  uint8_t sleepPacket[] = { 0x8d, 0x0a, 0x13, 0x01, 0x07, 0xda, 0xd8 };
  apiCharacteristic->writeValue(sleepPacket, sizeof sleepPacket, true);
}
The responses can be delayed anywhere from tens of milliseconds to a handful of seconds, depending on what the device is doing, communications latency/interference, etc.. Due to the limitations of small packets in BLE you may also receive the response across several callback events, e.g.: the Sphero I was experimenting with here could have returned single packets with eight or nine byte payloads but, instead, chose to send all of its packets with single byte payloads (this was also seen in Wireshark)...

Code: Select all

22:10:41.157 -> Wake up!
22:10:41.221 ->   data: 8d
22:10:41.221 ->   data: 29
22:10:41.221 ->   data: 01
22:10:41.221 ->   data: 13
22:10:41.221 ->   data: 0d
22:10:41.221 ->   data: 00
22:10:41.221 ->   data: 00
22:10:41.221 ->   data: b5
22:10:41.221 ->   data: d8
22:10:41.221 -> PACKET COMPLETE: 8d 29 01 13 0d 00 00 b5 d8
22:10:41.323 ->   data: 8d
22:10:41.323 ->   data: 28
22:10:41.323 ->   data: 01
22:10:41.323 ->   data: 13
22:10:41.323 ->   data: 11
22:10:41.323 ->   data: ff
22:10:41.323 ->   data: b3
22:10:41.323 ->   data: d8
22:10:41.323 -> PACKET COMPLETE: 8d 28 01 13 11 ff b3 d8
22:10:46.200 -> Go to sleep!
22:10:46.240 ->   data: 8d
22:10:46.240 ->   data: 29
22:10:46.240 ->   data: 01
22:10:46.240 ->   data: 13
22:10:46.240 ->   data: 01
22:10:46.240 ->   data: 07
22:10:46.240 ->   data: 00
22:10:46.240 ->   data: ba
22:10:46.240 ->   data: d8
22:10:46.240 -> PACKET COMPLETE: 8d 29 01 13 01 07 00 ba d8
22:10:48.242 ->   data: 8d
22:10:48.242 ->   data: 28
22:10:48.242 ->   data: 01
22:10:48.242 ->   data: 13
22:10:48.242 ->   data: 1a
22:10:48.242 ->   data: ff
22:10:48.242 ->   data: aa
22:10:48.242 ->   data: d8
22:10:48.242 -> PACKET COMPLETE: 8d 28 01 13 1a ff aa d8