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
700 stars 145 forks source link

Cannot pair to sony camera but works when using Bluedroid #572

Open Lemin2 opened 1 year ago

Lemin2 commented 1 year ago

Hi h2zero,

Hello, I encountered a problem with connecting esp32 and Sony ZV-1 camera, and I would like to ask you for advice.

I modified the example program of Nimble-Arduino library a bit, and I wanted to use esp32 to control my ZV-1 camera, but when esp32 and the camera paired, the program got stuck at D NimBLEClient: >> secureConnection(), and then reported an error E NimBLEClient: secureConnection: failed rc=13.

I know that ZV-1 would pop up a confirm pairing window, when it's in pairing mode, and the connected device has sent any requests to it. I can successfully simulate this process with the nrf connect app on Android.

I saw on GitHub that someone was also testing how to use Nimble or Bluedroid to control Sony cameras. I tried his program and found that, using nimble-arduino would also get stuck at D NimBLEClient: >> secureConnection(), and disconnect after 10 seconds; However, using Bluedroid can pair and control normally. And after pairing successfully with Bluedroid, I changed to flash the Nimble-Arduino program,and this time esp32 could also pair with the camera, but the device name displayed on the camera was Bluedroid program's.

I tried changing the settings of NimBLEDevice::setSecurityAuth() or NimBLEDevice::setSecurityIOCap(), but it didn't work. Am I doing anything wrong or is there a bug in the Nimble-Arduino library?

Thank you for your time and help.

Lemin2 commented 1 year ago

Logs when using Nimble-Arduino:

Starting NimBLE Client
I NimBLEDevice: BLE Host Task Started
I NimBLEDevice: NimBle host synced.
D NimBLEDevice: Setting bonding: 1, mitm: 0, sc: 0
D NimBLEScan: >> start: duration=30
D NimBLEScan: << start()
I NimBLEScan: New advertiser: 42:12:62:1d:61:3e
I NimBLEScan: New advertiser: 9c:50:d1:c3:52:80
I NimBLEScan: Updated advertiser: 9c:50:d1:c3:52:80
Found Sony Camera
D NimBLEScan: >> stop()
Scan Ended
D NimBLEScan: << stop()
New client created
D NimBLEClient: >> connect(9c:50:d1:c3:52:80)
D NimBLEClient: Got Client event
I NimBLEClient: Connected event
D NimBLEClient: Got Client event 
I NimBLEClient: mtu update event; conn_handle=0 mtu=255
I NimBLEClient: Connection established
D NimBLEClient: >> deleteServices
D NimBLEClient: << deleteServices
Connected -------------   on connection
D NimBLEClient: << connect()
D NimBLEClient: >> getService: uuid: 8000ff00-ff00-ffff-ffff-ffffffffffff
D NimBLEClient: >> retrieveServices
D NimBLEClient: Service Discovered >> status: 0 handle: 66
D NimBLERemoteService: >> NimBLERemoteService()
D NimBLERemoteService: << NimBLERemoteService(): 8000ff00-ff00-ffff-ffff-ffffffffffff
D NimBLEClient: Service Discovered >> status: 14 handle: -1
D NimBLEClient: << Service Discovered
D NimBLEClient: << retrieveServices
D NimBLERemoteService: >> getCharacteristic: uuid: 0xff02
D NimBLERemoteService: >> retrieveCharacteristics() for service: 8000ff00-ff00-ffff-ffff-ffffffffffff
D NimBLERemoteService: Characteristic Discovered >> status: 0 handle: 68
D NimBLERemoteCharacteristic: >> NimBLERemoteCharacteristic()
D NimBLERemoteCharacteristic: << NimBLERemoteCharacteristic(): 0xff02
D NimBLERemoteService: Characteristic Discovered >> status: 14 handle: -1
D NimBLERemoteService: << Characteristic Discovered
D NimBLERemoteService: << retrieveCharacteristics()
D NimBLERemoteCharacteristic: >> setNotify(): Characteristic: uuid: 0xff02, handle: 68 0x0044, props:  0x10, 01
D NimBLERemoteCharacteristic: >> getDescriptor: uuid: 0x2902
D NimBLERemoteCharacteristic: >> retrieveDescriptors() for characteristic: 0xff02
D NimBLERemoteCharacteristic: Next Characteristic >> status: 0 handle: 71
D NimBLERemoteCharacteristic: Descriptor Discovered >> status: 0 handle: 69
D NimBLERemoteDescriptor: >> NimBLERemoteDescriptor()
D NimBLERemoteDescriptor: << NimBLERemoteDescriptor(): 0x2902
D NimBLERemoteCharacteristic: << Descriptor Discovered. status: 0
D NimBLERemoteCharacteristic: << retrieveDescriptors(): Found 1 descriptors.
D NimBLERemoteCharacteristic: << setNotify()
D NimBLERemoteDescriptor: >> Descriptor writeValue: Descriptor: uuid: 0x2902, handle: 69
D NimBLERemoteService: >> getCharacteristic: uuid: 0xff01
D NimBLERemoteService: >> retrieveCharacteristics() for service: 8000ff00-ff00-ffff-ffff-ffffffffffff
D NimBLERemoteService: Characteristic Discovered >> status: 0 handle: 71
D NimBLERemoteCharacteristic: >> NimBLERemoteCharacteristic()
D NimBLERemoteCharacteristic: << NimBLERemoteCharacteristic(): 0xff01
D NimBLERemoteService: Characteristic Discovered >> status: 14 handle: -1
D NimBLERemoteService: << Characteristic Discovered
D NimBLERemoteService: << retrieveCharacteristics()
D NimBLERemoteCharacteristic: >> writeValue(), length: 6
I NimBLERemoteCharacteristic: Write complete; status=271 conn_handle=0
D NimBLEClient: >> secureConnection()
D NimBLEClient: Got Client event 
E NimBLEClient: secureConnection: failed rc=13
E NimBLERemoteCharacteristic: << writeValue, rc: 271
D NimBLERemoteCharacteristic: >> writeValue(), length: 2
I NimBLERemoteCharacteristic: Write complete; status=7 conn_handle=0
E NimBLERemoteCharacteristic: << writeValue, rc: 7
D NimBLEClient: Got Client event 
I NimBLEClient: disconnect; reason=531, 
9c:50:d1:c3:52:80 Disconnected - not Starting scan
D NimBLERemoteCharacteristic: >> writeValue(), length: 4
E NimBLERemoteCharacteristic: Disconnected
D NimBLERemoteCharacteristic: >> writeValue(), length: 8
E NimBLERemoteCharacteristic: Disconnected
Wrote new value to: 0xff01
Done with this device!
Success! we should now be getting notifications, scanning for more!

I think the program got stuck when the first command was sent.

And here is the log when using Bluedroid:

Starting Arduino BLE Client application...
[   682][I][BLEDevice.cpp:194] gapEventHandler(): ESP_GAP_BLE_LOCAL_IR_EVT
[   693][I][BLEDevice.cpp:197] gapEventHandler(): ESP_GAP_BLE_LOCAL_ER_EVT
[   890][D][BLEAdvertisedDevice.cpp:472] setRSSI(): - setRSSI(): rssi: -42
[   890][D][BLEAdvertisedDevice.cpp:292] parseAdvertisement(): Type: 0x01 (ESP_BLE_AD_TYPE_FLAG), length: 1, data: 07
[   896][D][BLEAdvertisedDevice.cpp:292] parseAdvertisement(): Type: 0xff (ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE), length: 22, data: 2d0103006400433422ef002160000000000000000000
[   911][D][BLEAdvertisedDevice.cpp:449] setManufacturerData(): - manufacturer data: 2d0103006400433422ef002160000000000000000000
[   923][D][BLEAdvertisedDevice.cpp:292] parseAdvertisement(): Type: 0x03 (ESP_BLE_AD_TYPE_16SRV_CMPL), length: 2, data: 0018
[   934][D][BLEAdvertisedDevice.cpp:500] setServiceUUID(): - addServiceUUID(): serviceUUID: 00001800-0000-1000-8000-00805f9b34fb
[   945][D][BLEAdvertisedDevice.cpp:292] parseAdvertisement(): Type: 0x09 (ESP_BLE_AD_TYPE_NAME_CMPL), length: 4, data: 5a562d31
[   956][D][BLEAdvertisedDevice.cpp:461] setName(): - setName(): name: ZV-1
BLE Advertised Device found: Name: ZV-1, Address: 9c:50:d1:c3:52:80, manufacturer data: 2d0103006400433422ef002160000000000000000000, serviceUUID: 00001800-0000-1000-8000-00805f9b34fb
Found Sony Camera
Forming a connection to 9c:50:d1:c3:52:80
 - Created client
[   986][I][BLEDevice.cpp:622] addPeerDevice(): add conn_id: 0, GATT role: client
[   988][D][BLEClient.cpp:493] handleGAPEvent(): BLEClient ... handling GAP event!
[  1001][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_REG_EVT
[  1011][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_REG_EVT
[  1092][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CONNECT_EVT
[  1094][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CONNECT_EVT
[  1105][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_OPEN_EVT
[  1115][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_OPEN_EVT
 - Connected to server
[  2154][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown
[  2155][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... Unknown
[  2162][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2173][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2185][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2195][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2207][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2217][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2229][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2239][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2252][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2262][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2273][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2284][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
[  2295][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_CMPL_EVT
[  2306][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_CMPL_EVT
 - Found our service
[  2328][D][BLERemoteService.cpp:193] retrieveCharacteristics(): Found a characteristic: Handle: 68, UUID: 0000ff02-0000-1000-8000-00805f9b34fb
[  2332][D][BLERemoteCharacteristic.cpp:293] retrieveDescriptors(): Found a descriptor: Handle: 69, UUID: 00002902-0000-1000-8000-00805f9b34fb
[  2344][D][BLERemoteService.cpp:193] retrieveCharacteristics(): Found a characteristic: Handle: 71, UUID: 0000ff01-0000-1000-8000-00805f9b34fb
[  2356][E][BLERemoteCharacteristic.cpp:287] retrieveDescriptors(): esp_ble_gattc_get_all_descr: ESP_GATT_NOT_FOUND
 - Found our command interafce
[  2378][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_REG_FOR_NOTIFY_EVT
[  2381][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_REG_FOR_NOTIFY_EVT
[  2423][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_DESCR_EVT
[  2424][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_DESCR_EVT
 - subscribe to status notification
We are now connected to the Camera.
[  2468][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[  2469][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[  2512][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[  2514][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[  2557][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[  2559][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[  2602][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[  2604][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
completed a full shutter travel[  4160][D][BLEDevice.cpp:247] gapEventHandler(): ESP_GAP_BLE_KEY_EVT
[  4164][I][BLEDevice.cpp:249] gapEventHandler(): key type = ESP_LE_KEY_PENC
[  4164][D][BLEClient.cpp:493] handleGAPEvent(): BLEClient ... handling GAP event!
[  4172][D][BLEDevice.cpp:247] gapEventHandler(): ESP_GAP_BLE_KEY_EVT
[  4178][I][BLEDevice.cpp:249] gapEventHandler(): key type = ESP_LE_KEY_PID
[  4184][D][BLEClient.cpp:493] handleGAPEvent(): BLEClient ... handling GAP event!
[  4192][D][BLEDevice.cpp:247] gapEventHandler(): ESP_GAP_BLE_KEY_EVT
[  4198][I][BLEDevice.cpp:249] gapEventHandler(): key type = ESP_LE_KEY_PCSRK
[  4205][D][BLEClient.cpp:493] handleGAPEvent(): BLEClient ... handling GAP event!
[  4212][D][BLEDevice.cpp:247] gapEventHandler(): ESP_GAP_BLE_KEY_EVT
[  4218][I][BLEDevice.cpp:249] gapEventHandler(): key type = ESP_LE_KEY_LENC
[  4225][D][BLEClient.cpp:493] handleGAPEvent(): BLEClient ... handling GAP event!
[  4232][D][BLEDevice.cpp:247] gapEventHandler(): ESP_GAP_BLE_KEY_EVT
[  4238][I][BLEDevice.cpp:249] gapEventHandler(): key type = ESP_LE_KEY_LID
[  4245][D][BLEClient.cpp:493] handleGAPEvent(): BLEClient ... handling GAP event!
[  4253][D][BLEDevice.cpp:247] gapEventHandler(): ESP_GAP_BLE_KEY_EVT
[  4259][I][BLEDevice.cpp:249] gapEventHandler(): key type = ESP_LE_KEY_LCSRK
[  4265][D][BLEClient.cpp:493] handleGAPEvent(): BLEClient ... handling GAP event!
[  4363][I][BLEDevice.cpp:253] gapEventHandler(): ESP_GAP_BLE_AUTH_CMPL_EVT
[  4364][D][BLEClient.cpp:493] handleGAPEvent(): BLEClient ... handling GAP event!
[ 12654][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[ 12655][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[ 12699][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[ 12700][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[ 12744][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[ 12745][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[ 12789][D][BLEDevice.cpp:148] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[ 12790][D][BLEClient.cpp:178] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
completed a full shutter travel

pairing window is showing up and the camera is able to take pictures every 10 seconds.

h2zero commented 1 year ago

All I can see in the log is this:

secureConnection: failed rc=13

Which is

0x0d BLE_HS_ETIMEOUT Operation timed out.

This may be due to the configuration of the security settings in NimBLEDevice::setSecurityIOCap() and NimBLEDevice::setSecurityAuth().

Lemin2 commented 1 year ago

All I can see in the log is this:

secureConnection: failed rc=13

Which is

0x0d BLE_HS_ETIMEOUT Operation timed out. This may be due to the configuration of the security settings in NimBLEDevice::setSecurityIOCap() and NimBLEDevice::setSecurityAuth().

Hi h2zero, It seems that the camera only requires no io capacity and bonding to be functional. so I've tried to set my esp32 with:

NimBLEDevice::setSecurityIOCap(BLE_HS_IO_NO_INPUT_OUTPUT);
NimBLEDevice::setSecurityAuth(BLE_SM_PAIR_AUTHREQ_BOND |  BLE_SM_PAIR_AUTHREQ_SC);

but this doesn't help. I'm still getting the same error. I also tried other combinations and they don't help too. Then I found another one using NRF52840 the chip and bluefruit library to control a sony camera. seems in the code he is able to manually issue an SMP Pairing Request or an SMP Security Request. I don't know how to achieve this with an esp32 so I'm just assuming ble libraries would do this automatically. so I just tried to duplicate the default GAP security parameters of the bluefruit library:

// default is Just Work
static const ble_gap_sec_params_t _sec_param_default =
{
  .bond         = 1,
  .mitm         = 0,
  .lesc         = LESC_SUPPORTED,
  .keypress     = 0,
  .io_caps      = BLE_GAP_IO_CAPS_NONE,
  .oob          = 0,
  .min_key_size = 7,
  .max_key_size = 16,
  .kdist_own    = { .enc = 1, .id = 1},
  .kdist_peer   = { .enc = 1, .id = 1}
};

And I'm doing like this:

  ble_hs_cfg.sm_bonding=1;
  ble_hs_cfg.sm_mitm=0;
  ble_hs_cfg.sm_sc=1;
  ble_hs_cfg.sm_keypress=0;
  ble_hs_cfg.sm_io_cap=BLE_SM_IO_CAP_NO_IO;
  ble_hs_cfg.sm_oob_data_flag=0;
  ble_hs_cfg.sm_our_key_dist=BLE_SM_PAIR_KEY_DIST_ENC|BLE_SM_PAIR_KEY_DIST_ID;
  ble_hs_cfg.sm_their_key_dist=BLE_SM_PAIR_KEY_DIST_ENC|BLE_SM_PAIR_KEY_DIST_ID;

Unfortunately this doesn't make a difference either. I'm still getting the same error. I'm still new to ble, and don't know why Nimble and Bluedroid behave differently, although they seem to be using similar interfaces. the Bluedroid code just sets encryption level with BLEDevice::setEncryptionLevel(ESP_BLE_SEC_ENCRYPT); and all the thing goes flawlessly; but I just don't know what kind of magic is happening here, and what to do to get Nimble working like that. Could you please give me some more advice on that? Best reguards

h2zero commented 1 year ago

I think this may have something to do with BLE_SM_PAIR_AUTHREQ_SC or ble_hs_cfg.sm_sc=1; being enabled. Try removing this, by setting ble_hs_cfg.sm_sc=0;

h2zero commented 4 months ago

@Lemin2 Any updates?