google / bumble

Apache License 2.0
255 stars 73 forks source link

JUST_WORKS bonding #124

Closed cbout22 closed 5 months ago

cbout22 commented 1 year ago

Hi,

I need help understanding how pairing works from apps/pair.py. While using this app, I got an error message when I try to connect with an iPhone: (except for first connection)

Failed to Connect: Peer removed pairing information

Furthermore, when I disconnect and reconnect an Android, I have to redo pairing.

I configure it as follows :

So my questions are: How to store and use pairing information with Bumble for a Just_Works pairing method ? And how can we use or are we supposed to use PairingDelegate to create a device with a just works bonding?

I really appreciate any help you can provide.

uael commented 1 year ago

You may need a persistent storage, do your config file passed to the app include a keystore entry? Do you see this log when starting the app ?

@@@ Pairing Keys:...
cbout22 commented 1 year ago

I passed device1.json form examples files as config file. It contains the following field :

"keystore":"JsonKeyStore"

Which refers to 'bumble.keys.JsonKeyStore', if I understand it well. But no @@@ Pairing keys: appears when I start 'pair.py'.

I've try to pass a file with the following field :

"keystore":"JsonKeyStore:<absolutePath>/foo.json"

but the following error appends (I think I don't understand syntax for keystore field😄 ) :

File "/home/cbout/Documents/bumble/keys.py", line 220, in from_device_config
    filename = params[1]

IndexError: list index out of range

Furthermore, I passed foo.json as parameter using --keystore-file <absolutePath>/foo.json and pairing keys are saved into this file with peer_adress, irk and ltk.

I tried to toggle/untoggle sc and mtim fields but nothing seems changed

barbibulle commented 1 year ago

Hi. LE pairing with Android should work. The error you're seeing when specifying a keystore file name in a device config is a bug :-( (I'll send a PR shortly for that). If you just use "keystore": "JsonKeyStore" you'll get a keystore file in a default location. The debug logs will show you where that it. It is platform-dependent. For exampe, on a mac, that's ~/Library/Application Support/Bumble/Pairing/<xxx>.json. As you found out, you can also use --keystore-file and pass a path to your keystore file.

To find out more where things fail for you, could you run the app with the env var BUMBLE_LOGLEVEL set to debug. Ex: BUMBLE_LOGLEVEL=debug python apps/pair.py examples/device1.json usb:0 XX:XX:XX:XX:XX:XX

cbout22 commented 1 year ago

Hi,

First of all, thanks for fixing keystore's file name :+1:

Then, sorry for the lateness. For both Android and iOs, I use nRFConnect to trigger connection.

I've tried pairing it on Android, and it works. Bonding doesn't, but may pair.py isn't done for bonding.

Using the following cmd : BUMBLE_LOGLEVEL=debug python apps/pair.py examples/device1.json usb:0 --request

When I connect an Android :

  1. First connection + pairing : is ok
  2. Second connection: failed, and bonding is lost
  3. Third connection: redo previous steps

With an iPhone :

  1. First connection : pairing + bonding done with success
  2. Second connection: got `Failed to Connect: Peer removed pairing information on iPhone and the following suit of cmd :
    DEBUG:bumble.host:### CONTROLLER -> HOST: HCI_LE_ENHANCED_CONNECTION_COMPLETE_EVENT:
    status:                           HCI_SUCCESS
    connection_handle:                24
    role:                             PERIPHERAL
    peer_address_type:                RANDOM_DEVICE_ADDRESS
    peer_address:                     7E:14:0D:38:AE:FF
    local_resolvable_private_address: 00:00:00:00:00:00/P
    peer_resolvable_private_address:  00:00:00:00:00:00/P
    connection_interval:              24
    peripheral_latency:               0
    supervision_timeout:              100
    central_clock_accuracy:           1
    DEBUG:bumble.host:### CONNECTION: [0x0018] 7E:14:0D:38:AE:FF as PERIPHERAL
    DEBUG:bumble.device:*** Connection: [0x0018] 7E:14:0D:38:AE:FF as PERIPHERAL
    DEBUG:bumble.host:### HOST -> CONTROLLER: HCI_LE_READ_PHY_COMMAND:
    connection_handle: 24
    DEBUG:bumble.transport.usb:submit COMMAND
    DEBUG:bumble.host:### CONTROLLER -> HOST: HCI_COMMAND_COMPLETE_EVENT:
    num_hci_command_packets: 2
    command_opcode:          HCI_LE_READ_PHY_COMMAND
    return_parameters:       
    status:            HCI_SUCCESS
    connection_handle: 24
    tx_phy:            LE 1M
    rx_phy:            LE 1M
    <<< Connection: Connection(handle=0x0018, role=PERIPHERAL, address=7E:14:0D:38:AE:FF)
    >>> Requesting pairing
    DEBUG:bumble.smp:>>> Sending SMP Command on connection [0x0018] 7E:14:0D:38:AE:FF: SMP_SECURITY_REQUEST_COMMAND:
    auth_req: bonding_flags=1, MITM=1, sc=1, keypress=0, ct2=0
    DEBUG:bumble.host:### HOST -> CONTROLLER: (CID=6) ACL: handle=0x0018pb=0, bc=0, data_total_length=6, data=020006000b0d
    DEBUG:bumble.transport.usb:submit ACL
    DEBUG:bumble.host:### CONTROLLER -> HOST: HCI_NUMBER_OF_COMPLETED_PACKETS_EVENT:
    number_of_handles:         1
    connection_handle[0]:     24
    num_completed_packets[0]: 1
    DEBUG:bumble.host:### CONTROLLER -> HOST: HCI_LE_LONG_TERM_KEY_REQUEST_EVENT:
    connection_handle:      24
    random_number:          0000000000000000
    encryption_diversifier: 0
    DEBUG:bumble.host:### HOST -> CONTROLLER: HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND:
    connection_handle: 24
    DEBUG:bumble.transport.usb:submit COMMAND
    DEBUG:bumble.host:### CONTROLLER -> HOST: HCI_COMMAND_COMPLETE_EVENT:
    num_hci_command_packets: 2
    command_opcode:          HCI_LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY_COMMAND
    return_parameters:       001800
    DEBUG:bumble.host:### CONTROLLER -> HOST: HCI_DISCONNECTION_COMPLETE_EVENT:
    status:            HCI_SUCCESS
    connection_handle: 24
    reason:            HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR
    DEBUG:bumble.host:### DISCONNECTION: [0x0018] 7E:14:0D:38:AE:FF as PERIPHERAL, reason=19
    DEBUG:bumble.device:*** Disconnection: [0x0018] 7E:14:0D:38:AE:FF as PERIPHERAL, reason=19
    DEBUG:bumble.device: restarting advertising
    DEBUG:bumble.l2cap:disconnection from 24, cleaning up channels

    Then, the device restarts and advertise.

barbibulle commented 1 year ago

I think the problem here is that you are not completing the pairing/bonding with the pair app. When you pair, the app will prompt you to check that the 6 digit code matches the code shown on the phone (the phone also asks you to check and confirm). If you only confirm of the phone, the pair app won’t finish, and the key won’t be stored in the key store. Without the key in the key store, it explains why iOS is telling you that the ‘peer has removed pairing information’, because the phone has completed its side and stored the key, but not the bumble side. I ran a quick pairing test with the same setup as yours, with nRF Connect to connect to the virtual device, using the —request option. It works as expected on Android and iOS, and if you run it a second time, you will see a message in the pair app showing that the connection gets encrypted. Now, keep in mind that unfortunately, on Android, pairing with a code verification step (which is what you get when the I/O capability indicate the device can display a code and has a keyboard or a yes/no button), you will likely have to tap 4 times! The first time is the pairing request notification, the second time to accept the pairing request, the third time is for the code verification notification and the 4th time for the actual Ok to the code verification… on iOS that’s a single step.

pymenow commented 1 year ago

The pairing app works well with Andorid . With IOS I get encryption insufficient error any clues as to what I may be missing. Using the app as is no modifications.

barbibulle commented 1 year ago

@pymenow which app parameters/mode are you using? (are you connecting from iOS to to iOS?) If connecting to iOS, are you triggering the pairing from iOS or from the pairing app? (--request)

pymenow commented 1 year ago

@barbibulle - This issue is specific to the mac address being used - https://github.com/google/bumble/issues/182 . After i changed the MAC address as mentioned in my comments in issue 182 the pairing on IOS also went through fine without issues .