ukBaz / python-bluezero

A simple Python interface to Bluez
MIT License
395 stars 112 forks source link

Pairing Request for cpu_temperature.py example despite no secure characteristics #331

Closed camm73 closed 3 years ago

camm73 commented 3 years ago

When running the cpu_temperature.py example, I try to connect to the BLE peripheral from my iPhone and upon connection I receive a pairing request. From looking at the cpu_temperature.py code, I do not see any secure characteristics which is why I'm confused why a pairing request would be generated. Is there something I'm missing here?

I've been running this example on a Raspberry Pi 4 Model B Rev 1.4 4GB. I've tested this on both the onboard Bluetooth module and a Plugable USB bluetooth dongle.

Upon looking at hcidump during this exchange I see the following "Insufficient Authentication" message followed by the pairing request due to the automatic security level upgrade:

> HCI Event: LE Meta Event (0x3e) plen 19
    LE Connection Complete
      status 0x00 handle 64, role slave
      bdaddr 60:42:E6:80:09:4F (Random)
< ACL data: handle 64 flags 0x00 dlen 6
    SMP: Security Request (0x0b)
      auth req 0x29
> ACL data: handle 64 flags 0x02 dlen 11
    L2CAP(d): cid 0x003a len 7 [psm 0]
> ACL data: handle 64 flags 0x02 dlen 7
    ATT: MTU req (0x02)
      client rx mtu 185
< ACL data: handle 64 flags 0x00 dlen 7
    ATT: MTU resp (0x03)
      server rx mtu 517
< ACL data: handle 64 flags 0x00 dlen 7
    ATT: MTU req (0x02)
      client rx mtu 517
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 7
    ATT: MTU resp (0x03)
      server rx mtu 185
< ACL data: handle 64 flags 0x00 dlen 7
    ATT: Read req (0x0a)
      handle 0x0016
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read By Group req (0x10)
      start 0x0001, end 0xffff
      type-uuid 0x2800
< ACL data: handle 64 flags 0x00 dlen 18
    ATT: Read By Group resp (0x11)
      attr handle 0x0001, end group handle 0x0005
      value 0x00 0x18
      attr handle 0x0006, end group handle 0x0009
      value 0x01 0x18
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 9
    ATT: Error (0x01)
      Error: Insufficient authentication (5)
      Read req (0x0a) on handle 0x0016
< ACL data: handle 64 flags 0x00 dlen 7
    ATT: Read req (0x0a)
      handle 0x0003
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read By Group req (0x10)
      start 0x000a, end 0xffff
      type-uuid 0x2800
< ACL data: handle 64 flags 0x00 dlen 26
    ATT: Read By Group resp (0x11)
      attr handle 0x000a, end group handle 0x000e
      value 0xbc 0x9a 0x78 0x56 0x34 0x12 0x34 0x12 0x34 0x12 0x34 0x12 0x00 0x10 0x34 0x12
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read By Group req (0x10)
      start 0x000f, end 0xffff
      type-uuid 0x2800
< ACL data: handle 64 flags 0x00 dlen 9
    ATT: Error (0x01)
      Error: Attribute not found (10)
      Read By Group req (0x10) on handle 0x000f
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read resp (0x0b)
< ACL data: handle 64 flags 0x00 dlen 7
    ATT: Read req (0x0a)
      handle 0x0005
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read By Type req (0x08)
      start 0x0006, end 0x0009
      type-uuid 0x2803
< ACL data: handle 64 flags 0x00 dlen 13
    ATT: Read By Type resp (0x09)
      length: 7
        handle 0x0007, value 0x20 0x08 0x00 0x05 0x2a 
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 7
    ATT: Read resp (0x0b)
< ACL data: handle 64 flags 0x00 dlen 11
    ATT: Read By Group req (0x10)
      start 0x0001, end 0xffff
      type-uuid 0x2800
> ACL data: handle 64 flags 0x02 dlen 9
    ATT: Find Information req (0x04)
      start 0x0009, end 0x0009
< ACL data: handle 64 flags 0x00 dlen 10
    ATT: Find Information resp (0x05)
      format: uuid-16
        handle 0x0009, uuid 0x2902 (GATT(desc) Client Characteristic Configuration)
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 18
    ATT: Read By Group resp (0x11)
      attr handle 0x0001, end group handle 0x0005
      value 0x00 0x18
      attr handle 0x0006, end group handle 0x0009
      value 0x01 0x18
< ACL data: handle 64 flags 0x00 dlen 11
    ATT: Read By Group req (0x10)
      start 0x000a, end 0xffff
      type-uuid 0x2800
> ACL data: handle 64 flags 0x02 dlen 9
    ATT: Write req (0x12)
      handle 0x0009 value  0x02 0x00
< ACL data: handle 64 flags 0x00 dlen 5
    ATT: Write resp (0x13)
> ACL data: handle 64 flags 0x02 dlen 11
    SMP: Pairing Request (0x01)
      capability 0x04 oob 0x00 auth req 0x29
      max key size 0x10 init key dist 0x0b resp key dist 0x0b
      Capability: KeyboardDisplay (OOB data not present)
      Authentication: Bonding (No MITM Protection)
      Initiator Key Distribution:  LTK IRK 
      Responder Key Distribution:  LTK IRK 
< ACL data: handle 64 flags 0x00 dlen 11
    SMP: Pairing Response (0x02)
      capability 0x03 oob 0x00 auth req 0x29
      max key size 0x10 init key dist 0x0b resp key dist 0x09
      Capability: NoInputNoOutput (OOB data not present)
      Authentication: Bonding (No MITM Protection)
      Initiator Key Distribution:  LTK IRK 
      Responder Key Distribution:  LTK  
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 27
> ACL data: handle 64 flags 0x01 dlen 19
    ATT: Read By Group resp (0x11)
      attr handle 0x000a, end group handle 0x000e
      value 0x66 0x43 0xae 0x10 0x79 0x48 0xf8 0xa5 0x91 0x45 0xb4 0xbb 0x78 0x1e 0x61 0xd0
      attr handle 0x000f, end group handle 0x0013
      value 0xae 0x04 0x5d 0xdc 0x43 0xd3 0x90 0x93 0x42 0x45 0x67 0x49 0xe0 0x80 0xa4 0x9f
< ACL data: handle 64 flags 0x00 dlen 11
    ATT: Read By Group req (0x10)
      start 0x0014, end 0xffff
      type-uuid 0x2800
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read By Type req (0x08)
      start 0x000a, end 0x000e
      type-uuid 0x2802
< ACL data: handle 64 flags 0x00 dlen 9
    ATT: Error (0x01)
      Error: Attribute not found (10)
      Read By Type req (0x08) on handle 0x000a
> ACL data: handle 64 flags 0x02 dlen 24
    ATT: Read By Group resp (0x11)
      attr handle 0x0014, end group handle 0x0017
      value 0x0f 0x18
      attr handle 0x0018, end group handle 0x001d
      value 0x05 0x18
      attr handle 0x001e, end group handle 0x0022
      value 0x0a 0x18
< ACL data: handle 64 flags 0x00 dlen 11
    ATT: Read By Group req (0x10)
      start 0x0023, end 0xffff
      type-uuid 0x2800
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read By Type req (0x08)
      start 0x000a, end 0x000e
      type-uuid 0x2803
< ACL data: handle 64 flags 0x00 dlen 13
    ATT: Read By Type resp (0x09)
      length: 7
        handle 0x000b, value 0x12 0x0c 0x00 0x6e 0x2a 
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 27
> ACL data: handle 64 flags 0x01 dlen 19
    ATT: Read By Group resp (0x11)
      attr handle 0x0023, end group handle 0x002c
      value 0xd0 0x00 0x2d 0x12 0x1e 0x4b 0x0f 0xa4 0x99 0x4e 0xce 0xb5 0x31 0xf4 0x05 0x79
      attr handle 0x002d, end group handle 0x0038
      value 0xdc 0xf8 0x55 0xad 0x02 0xc5 0xf4 0x8e 0x3a 0x43 0x36 0x0f 0x2b 0x50 0xd3 0x89
< ACL data: handle 64 flags 0x00 dlen 11
    ATT: Read By Group req (0x10)
      start 0x0039, end 0xffff
      type-uuid 0x2800
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read By Type req (0x08)
      start 0x000d, end 0x000e
      type-uuid 0x2803
< ACL data: handle 64 flags 0x00 dlen 9
    ATT: Error (0x01)
      Error: Attribute not found (10)
      Read By Type req (0x08) on handle 0x000d
> ACL data: handle 64 flags 0x02 dlen 9
    ATT: Error (0x01)
      Error: Attribute not found (10)
      Read By Group req (0x10) on handle 0x0039
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
< ACL data: handle 64 flags 0x00 dlen 9
    ATT: Write req (0x12)
      handle 0x0009 value  0x02 0x00
> ACL data: handle 64 flags 0x02 dlen 9
    ATT: Find Information req (0x04)
      start 0x000d, end 0x000e
< ACL data: handle 64 flags 0x00 dlen 14
    ATT: Find Information resp (0x05)
      format: uuid-16
        handle 0x000d, uuid 0x2902 (GATT(desc) Client Characteristic Configuration)
        handle 0x000e, uuid 0x2904 (GATT(desc) Format)
> ACL data: handle 64 flags 0x02 dlen 5
    ATT: Write resp (0x13)
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
> ACL data: handle 64 flags 0x02 dlen 7
    ATT: Read req (0x0a)
      handle 0x000d
< ACL data: handle 64 flags 0x00 dlen 7
    ATT: Read resp (0x0b)
> ACL data: handle 64 flags 0x02 dlen 7
    ATT: Read req (0x0a)
      handle 0x000e
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
< ACL data: handle 64 flags 0x00 dlen 12
    ATT: Read resp (0x0b)
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 1
> ACL data: handle 64 flags 0x02 dlen 11
    ATT: Read By Type req (0x08)
      start 0x0001, end 0x0005
      type-uuid 0x2a00
< ACL data: handle 64 flags 0x00 dlen 27
< ACL data: handle 64 flags 0x01 dlen 11
    ATT: Read By Type resp (0x09)
      length: 32
        handle 0x0003, value 0x48 0x4f 0x4d 0x45 0x41 0x57 0x41 0x52 0x45 0x5f 0x53 0x45 0x4e 0x53 0x4f 0x52 0x5f 0x53 0x45 0x54 0x55 0x50 0x5f 0x53 0x45 0x52 0x56 0x49 0x43 0x45 
> HCI Event: Number of Completed Packets (0x13) plen 5
    handle 64 packets 2
ukBaz commented 3 years ago

What app are you using for connecting to the Raspberry Pi from your iPhone? Are you using the functionality in settings? As that will probably not work as the iPhone will not know what to do with the custom CPU Temperature Service.

I would recommend using a generic Bluetooth Low Energy scanning and exploration tool like nRF Connect to initially connect and prove it works.

I have found to get reliable connection to Android phones it is best to put the controller into le only mode. This is done in the /etc/bluetooth/main.conf file. Ensure that it contains the following:

ControllerMode = le

The following explanation of this is from /etc/bluetooth/main.conf:

Restricts all controllers to the specified transport. Default value is "dual", i.e. both BR/EDR and LE enabled (when supported by the HW).` Possible values: "dual", "bredr", "le"

You can also do this from the command line with:

sudo btmgmt power off
sudo btmgmt le on
sudo btmgmt bredr off
sudo btmgmt power on
camm73 commented 3 years ago

Thanks for the quick reply! So I've been testing this via a few apps including nRF Connect and still get a pairing request shortly after connecting to the BLE peripheral running on the Pi. This is also the case if I use non-Apple devices, so it doesn't seem to be client related.

What makes me think it is something related to a secure characteristic is that I modified Bluez running on the Pi so that the static bool change_security(struct bt_att_chan *chan, uint8_t ecode) function found in https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/shared/att.c always rejects automatic security level escalation (similar to the new config option that they added to the newest Bluez version), and this successfully stops pairing requests while allowing the peripheral to operate as expected.

This is a fine temporary fix, but I thought I'd share this in case it is a bug related to how bluezero is creating characteristics.

ukBaz commented 3 years ago

Thanks for the update although I am struggling to understand why you are seeing the issue.

Are you using a stock image on the Raspberry Pi? What version of Bluez do you have installed?

The code you linked to was changed a couple of years ago to add EATT support. This would seem to link to the 5.54 release:

http://www.bluez.org/release-of-bluez-5-54-and-5-53/ https://www.phoronix.com/scan.php?page=news_item&px=BlueZ-5.54-Released

I think the stock RPi OS is still shipping with 5.50. I've just done a full upgrade on one of my old RPi 3+ and it has 5.50 and is working fine.

camm73 commented 3 years ago

So it's a stock Raspbian buster image (kernel version: 4.19.97-v71+) (haven't upgraded to RPi OS yet) with Bluez 5.50 running on a Raspberry Pi 4. However, I've also noticed this issue running on a Pi 3+ in the past.

ukBaz commented 3 years ago

I just double checked and it is actually an older 3B that I'm running on. There have been some firmware issues on the latest Raspberry Pi's. Have you checked service bluetooth status for errors? Also journalctl -u bluetooth.

Another thing to help debug is try running sudo btmon in a different window to see what is reported there when you have the error. You can write the btmon output to a file and take it into wireshark. Sometime this helps filter the information.

I've included the full details of the machine I've run the test on.

pi@raspberry:~ $ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
pi@raspberry:~ $ uname -a
Linux SensePi 5.4.79-v7+ #1373 SMP Mon Nov 23 13:22:33 GMT 2020 armv7l GNU/Linux
pi@SensePi:~ $ dpkg -l | grep bluez
ii  bluez                                5.50-1.2~deb10u1+rpt2                   armhf        Bluetooth tools and daemons
ii  bluez-firmware                       1.2-4+rpt8                              all          Firmware for Bluetooth devices
ii  bluez-obexd                          5.50-1.2~deb10u1+rpt2                   armhf        bluez obex daemon
ii  bluez-test-tools                     5.50-1.2~deb10u1+rpt2                   armhf        test tools of bluez
pi@raspberry:~ $ pinout 
,--------------------------------.
| oooooooooooooooooooo J8     +====
| 1ooooooooooooooooooo        | USB
|                             +====
|      Pi Model 3B  V1.2         |
|      +----+                 +====
| |D|  |SoC |                 | USB
| |S|  |    |                 +====
| |I|  +----+                    |
|                   |C|     +======
|                   |S|     |   Net
| pwr        |HDMI| |I||A|  +======
`-| |--------|    |----|V|-------'

Revision           : a02082
SoC                : BCM2837
RAM                : 1024Mb
Storage            : MicroSD
USB ports          : 4 (excluding power)
Ethernet ports     : 1
Wi-fi              : True
Bluetooth          : True
Camera ports (CSI) : 1
Display ports (DSI): 1
tnarik commented 3 years ago

I just started playing around with BLE, this library and the Raspberry Pi and I find a similar (or the same?) issue:

Both the project cpu_temperature.py or a modified version were I was playing around with characteristics and units (0x2A1C characteristic) behave the same way. Event completely removing the service (so just advertising data) seems to trigger "something" (not sure what) against the nRF Connect iOS which makes it respond with a:

> ACL Data RX: Handle 64 flags 0x02 dlen 9                                                                                                                 
      ATT: Error Response (0x01) len 4
        Read Request (0x0a)
        Handle: 0x0016
        Error: Insufficient Authentication (0x05)

, and then make the PI request authentication (which would fail if not set beforehand, of course)

ukBaz commented 3 years ago

I have borrowed an iPhone to do some testing. I ran btmon while I connected, read the characteristic, started notify, and disconnected. I wrote the output to a file. i.e. sudo btmon -w cpu_ios.log and then opened the output in wireshark to do some packet analysis.

image

I am an inexperienced wireshark user but it seems to be complaining about not being able to read the battery service: battery level which is something not part of the custom CPU service of the example. The error response does not prevent me from connecting to the CPU monitor service and reading the temperature value.

I did see different behaviour when I also had bluetoothctl open as that would cause the pop-up on the iPhone and in bluetoothctl. My assumption is that because there is an agent registered it tries to get authentication for the battery service: battery level

image

I repeated the example with Android and can confirm that I don't see the issue reported with Android.

The next area of investigation is to understand why the iOS devices are asking for battery level information that is not part of the service being connected to. I suspect it is one of the other profiles that are available on the iOS devices

tnarik commented 3 years ago

I'll try to find out, it is puzzling and I raised a ticket to the nFR Connect app as well. Thanks for the quick check, Barry.

cojo commented 3 years ago

@ukBaz For whatever it is worth, I am trying to use this library for Peripheral purposes and experiencing the same thing when connecting from an iOS device. It is only the following code:

# Create peripheral
    cpu_monitor = peripheral.Peripheral(adapter_address, local_name='RPi')
    # Add service
    cpu_monitor.add_service(srv_id=1, uuid=SRVC, primary=True)
    # Add characteristic
    cpu_monitor.add_characteristic(srv_id=1, chr_id=1, uuid=COMMAND_CHRC,
                                   value=[], notifying=False,
                                   flags=['write', 'write-without-response'],
                                   write_callback=write_value,
                                   read_callback=None,
                                   notify_callback=None)
    # Publish peripheral and start event loop
    cpu_monitor.publish()

And disabling br/edr, secure-conn, bondable all fail to make a difference. btmon seems to indicate that, as you noted, it requires pairing / authentication regardless:

< ACL Data TX: Handle 64 flags 0x00 dlen 7                                                                   #127 [hci0] 18.053612
      ATT: Read Request (0x0a) len 2
        Handle: 0x000c
> ACL Data RX: Handle 64 flags 0x02 dlen 9                                                                   #128 [hci0] 18.112663
      ATT: Error Response (0x01) len 4
        Read Request (0x0a)
        Handle: 0x000c
        Error: Insufficient Authentication (0x05)
< ACL Data TX: Handle 64 flags 0x00 dlen 6                                                                   #129 [hci0] 18.113607
      SMP: Security Request (0x0b) len 1
        Authentication requirement: Bonding, No MITM, Legacy, No Keypresses (0x01)
> HCI Event: Number of Completed Packets (0x13) plen 5                                                       #130 [hci0] 18.114406
        Num handles: 1
        Handle: 64
        Count: 2
> ACL Data RX: Handle 64 flags 0x02 dlen 11                                                                  #131 [hci0] 18.114428
      ATT: Read By Type Request (0x08) len 6
        Handle range: 0x0001-0x0005
        Attribute type: Device Name (0x2a00)
> ACL Data RX: Handle 64 flags 0x02 dlen 11                                                                  #132 [hci0] 18.172625
      SMP: Pairing Request (0x01) len 6
        IO capability: KeyboardDisplay (0x04)
        OOB data: Authentication data not present (0x00)
        Authentication requirement: Bonding, No MITM, Legacy, No Keypresses (0x01)
        Max encryption key size: 16
        Initiator key distribution: EncKey IdKey (0x03)
        Responder key distribution: EncKey IdKey (0x03)
@ MGMT Event: Authentication Failed (0x0011) plen 8                                                      {0x0002} [hci0] 18.172761
        LE Address: 5B:9B:23:6F:DF:EB (Resolvable)
        Status: Authentication Failed (0x05)
@ MGMT Event: Authentication Failed (0x0011) plen 8                                                      {0x0001} [hci0] 18.172761
        LE Address: 5B:9B:23:6F:DF:EB (Resolvable)
        Status: Authentication Failed (0x05)
< ACL Data TX: Handle 64 flags 0x00 dlen 6                                                                   #133 [hci0] 18.172854
      SMP: Pairing Failed (0x05) len 1

Do you have any suggestions on how we might be able to workaround this at least in the meantime? In another issue, https://github.com/ukBaz/python-bluezero/issues/291 (which coincidentally I believe was running into this problem as well, but misunderstanding it) you mentioned that the example doesn't handle pairing, which implied that maybe there is a way to handle it via additional python code? Is that the case? We would prefer for our use case to not have to manually intervene and pair via bluetoothctl if possible.

Thanks!

cojo commented 3 years ago

Also, I'm not sure if this might be related or not, but I've also noticed that while the local_name worked / was used the very first time, ever since then I can't get it to work and the device name instead shows up as "raspberrypi". Is this a known issue / is there a way to get the local_name to show instead? If this is unrelated to the other issue let me know and I can open a separate issue if needed.

tnarik commented 3 years ago

I usually set both name and alias. Not sure, but I think the name is considered ephemeral and doesn’t get linked to the mac addresses by the scanner (or most probably by the Bluez core).

ukBaz commented 3 years ago

My best guess on why the Battery Service is causing the pairing is one of the other profiles. If I list the default state of the Bluetooth on my RPi I get:

[bluetooth]# show
Controller B8:27:EB:22:57:E0 (public)
        Name: SensePi
        Alias: RPi_UART
        Class: 0x000c0000
        Powered: yes
        Discoverable: yes
        Pairable: yes
        UUID: Headset AG                (00001112-0000-1000-8000-00805f9b34fb)
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
        UUID: Audio Source              (0000110a-0000-1000-8000-00805f9b34fb)
        UUID: Audio Sink                (0000110b-0000-1000-8000-00805f9b34fb)
        UUID: Headset                   (00001108-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v1D6Bp0246d0532
        Discovering: no

If I do a pulseaudio -k it removes quite a few:

Controller B8:27:EB:22:57:E0 (public)
        Name: SensePi
        Alias: RPi_UART
        Class: 0x00000000
        Powered: yes
        Discoverable: yes
        Pairable: yes
        UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control        (0000110e-0000-1000-8000-00805f9b34fb)
        UUID: PnP Information           (00001200-0000-1000-8000-00805f9b34fb)
        UUID: A/V Remote Control Target (0000110c-0000-1000-8000-00805f9b34fb)
        UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
        Modalias: usb:v1D6Bp0246d0532
        Discovering: no

Some of the newer versions of audio gateway profiles have added indicator support to report such things as headset battery level.

I don't have access to an iOS device currently so if you can test that to see if it makes any difference.

With the local_name, I wonder if this is linked to the underlying BlueZ API changing. This could be related to #333

cojo commented 3 years ago

@tnarik thanks for the tip - will try that.

One last update on my side for now; I think I was able to (temporarily?) workaround this pairing issue by adding one more btmgmt command to the list:

sudo btmgmt io-cap 3

I say temporarily because I believe this is representing it as "NoInputNoOutput" which I think is basically just a hack workaround for now. Let me know if there is anything else I can help with investigating here.

Thanks!

cojo commented 3 years ago

Thanks @ukBaz - will try that as well and see if it makes a difference. Will keep you all posted.

tnarik commented 3 years ago

I didn’t try any of this yet ( https://stackoverflow.com/questions/59214524/since-bluez-5-48-iphones-require-pairing-when-connecting-on-a-ble-gap-periphera ) but I think the reason is the version of Bluez.

ukBaz commented 3 years ago

Thanks @tnarik . I remember reading about this on the BlueZ mailing list a few years ago. https://marc.info/?l=linux-bluetooth&m=152154683807490&w=2

It looks like modifying /lib/systemd/system/bluetooth.service to remove the unwanted plugins is the best way forward.

tnarik commented 3 years ago

Just for a bit of completeness:

>bluetoothctl
[tnarikPhone]# info AA:AA:AA:BB:BB:BB
Device AA:AA:AA:BB:BB:BB(public)
    Name: tnarikPhone
    Alias: tnarikPhone
    Appearance: 0x0040
    Icon: phone
    Paired: yes
    Trusted: no
    Blocked: no
    Connected: yes
    LegacyPairing: no
    UUID: Generic Access Profile    (00001800-0000-1000-8000-00805f9b34fb)
    UUID: Generic Attribute Profile (00001801-0000-1000-8000-00805f9b34fb)
    UUID: Current Time Service      (00001805-0000-1000-8000-00805f9b34fb)
    UUID: Device Information        (0000180a-0000-1000-8000-00805f9b34fb)
    UUID: Battery Service           (0000180f-0000-1000-8000-00805f9b34fb)
    UUID: Vendor specific           (7905f431-b5ce-4e99-a40f-4b1e122d00d0)
    UUID: Vendor specific           (89d3502b-0f36-433a-8ef4-c502ad55f8dc)
    UUID: Vendor specific           (9fa480e0-4967-4542-9390-d343dc5d04ae)
    UUID: Vendor specific           (d0611e78-bbb4-4591-a5f8-487910ae4366)

So we can see UUID: Device Information (0000180a-0000-1000-8000-00805f9b34fb)

Then, on my RPi (called picake):

1668:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:plugin_init() Loading builtin plugins
1669:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading hostname plugin
1670:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading wiimote plugin
1671:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading autopair plugin
1672:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading policy plugin
1673:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading neard plugin
1674:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading sap plugin
1675:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading a2dp plugin
1676:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading avrcp plugin
1677:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading network plugin
1678:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading input plugin
1679:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading hog plugin
1680:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading health plugin
1681:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading gap plugin
1682:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading scanparam plugin
1683:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading deviceinfo plugin
1684:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading midi plugin
1685:May 31 09:26:55 picake bluetoothd[4572]: src/plugin.c:add_plugin() Loading battery plugin

The battery plugin is the one trying to get information from a Central (the iPhone), which triggers the reverse pairing (and also explains why my sample agent was prompting for input unexpectedly on the originator). The hostname plugin is the one that sets the name and alias (I think if it gets skipped, then the alias would be left alone by Bluez and there wouldn't be any need to overwrite).

Plugins can be disabled by either recompiling, or via the -P flag in either the default configuration or a drop-in (what I did):

sudo mkdir -p /etc/systemd/system/bluetooth.service.d
sudo bash -c 'cat > /etc/systemd/system/bluetooth.service.d/bluetooth.conf <<EOF
[Service]
ExecStart=
ExecStart=/usr/lib/bluetooth/bluetoothd -P battery   
EOF'
sudo systemctl daemon-reload
sudo systemctl restart bluetooth.service

(I was messing around with files and the service so I might have missed something here).

In my case, I can now see the picake in the list of devices only while connected to the app, with no pairing requests, and disappearing when disconnecting.

You can also add -d to the ExecStart to check what is being loaded.

PS: Just run the code on a PiZero and fixed it to run properly.

ukBaz commented 3 years ago

I think this has been resolved now so I'm going to go ahead and close it. Happy to re-open if it isn't resolved.