ArthurFDLR/BR-M5

Connection interrupted

Closed this issue · 7 comments

I´ve managed it to run on the M5Stick-Cplus.

But after about 2 minutes of intervall shooting the conection betwen the m50 and the stick are lost.

I've started doing some research into this.

It appears that pretty much exactly after 3 minutes after the initial pairing (as in, the first time you pair it with the m50) the connection is dropped and cannot be reopened, regardless of any Shutter BLE Characteristic usage. I wrote a quick test and I see the same behavior in a connect/disconnect loop - it all works fine until we hit that 180s mark, at which point something in the camera starts refusing our connection messages.

I have a hunch that there's some sort of re-up on the connection that needs to be sent over either a different BLE Service, or as some sort of modification of the 0x03 control byte (I found a write-up here: https://iandouglasscott.com/2018/07/04/canon-dslr-bluetooth-remote-protocol/ for the likely origin of this reverse-engineering).

Also quick note if you start digging into the ESP32 BLE libraries - the first Serial.begin must be removed for the ESP32 logging to properly work (or the M5Stick initialization EnableSerial set to false), since opening it twice appears to nuke the device for the ESPlogging.

I'm going to keep working on this (I've added a connect / disconnect callback among some control flow changes and should have a fork up at some point) but here's some interesting logs around this issue:

When trying to connect on an already-paired device after 3 minutes:

Start BLE scan
Canon device found: 10:98:c3:46:6a:3f
Trying to connect.
[I][BLEDevice.cpp:614] addPeerDevice(): add conn_id: 0, GATT role: client
lld_pdu_get_tx_flush_nb HCI packet count mismatch (0, 1)
[E][BLEClient.cpp:238] gattClientEventHandler(): Failed to connect, status=Unknown ESP_ERR error
[I][BLEDevice.cpp:625] removePeerDevice(): remove: 0, GATT role client
Failed to connect.

When disconnected while connected after 3 minutes: (this one is.... not helpful)

Single shot
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown
[D][BLEClient.cpp:177] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown
[I][BLEDevice.cpp:625] removePeerDevice(): remove: 0, GATT role client
Connection state switched to false.
[D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown

edit - had some more time to dig into this. It appears the actual BLEClient.connect is failing 😬 without digging into the specifics of the whole GATT call stack, based on the lack of any meaningful error logs out of the esp logs I'm assuming it's this part here.

Might keep digging or give into despair and/or capitalism and just buy the TetherMonkey app (or - maybe try to make my own), haha.

edit 2 A final update for now -
Modified the BLEClient library (log_e("GATT return code is %d"); @ 144) to actually give us back the GATT code (yup, figured out it's the same as the debug code above, but I figure it should probably be an error log because it's the cause for connection failure).

[I][main.cpp:77] connect_loop(): Canon device found: 
10:98:c3:46:6a:3f
[I][main.cpp:79] connect_loop(): Trying to connect.
[I][BLEDevice.cpp:614] addPeerDevice(): add conn_id: 13, GATT role: client
-----> [E][BLEClient.cpp:144] connect(): GATT return code is 4
[I][BLEDevice.cpp:625] removePeerDevice(): remove: 13, GATT role client
[E][CanonBLE.cpp:106] connect_to_device(): Couldn't connect the BLEClient to the device

It appears to be 0x04, or ESP_GATT_INVALID_PDU. PDU stands for Protocol Data Unit, whatever that means :). Sounds like there'd have to be some blind digging around in the BLEClient to figure out what's going on.

I've also tested Android application called CB Remote which imitates the Canon Bluetooth remote.
https://github.com/iebyt/cbremote

It also has a disconnection issue as well after 3 minutes. After that, the pairing process must be done again in order to control the camera again. Moreover, the camera is not broadcast BLE signal anymore (I scanned with nRF connect application).

I've ordered a nRF52840 BLE sniffer and BR-E1 remote, waiting for them to arrive. I hope seeing raw packets might help us make it work.

After some trial and error, I've created an Arduino library based on this repository.

Key improvements

  • Persistent connection, no disconnect after 3 minutes.
  • Pair and remember. (Paring is only required for initial connection)
  • Auto re-connect.

Feel free to try it out
https://github.com/maxmacstn/ESP32-Canon-BLE-Remote

Awesome! Good work! What's the mechanism for keeping it connected past 3 minutes?

I've added BLEDevice::setEncryptionLevel() section into my code.

This is totally just from my recent experiment since my nRF52840 BLE sniffer still has not arrived yet. 😅

My assumption from the links below is that setting BLE security is required in BLE bounding process.

GATT Security Client Example Walkthrough
Arduino BLE Client Encrypted demo

After some trial and error, I've created an Arduino library based on this repository.

Key improvements

  • Persistent connection, no disconnect after 3 minutes.
  • Pair and remember. (Paring is only required for initial connection)
  • Auto re-connect.

Feel free to try it out https://github.com/maxmacstn/ESP32-Canon-BLE-Remote

Thanks guys for all your afford.
Is anyone of you able to implement these improvements into the BR-M5 remote?
I have almost no programming skills (I can barely understand the code) and I'm failing to do this.

Just made a github account for this, because I'm so desperate...

Hey, thank you all for your help on this project. My last commit (02b158d) includes the fix proposed in @maxmacstn's library. The BR-M5 is now working as expected.