Android-BLE-Library icon indicating copy to clipboard operation
Android-BLE-Library copied to clipboard

Why does BleServerManager require connecting back to the client device?

Open usikder opened this issue 5 years ago • 2 comments

In this library's documentation, it's suggested to call BleManager#connect(BluetoothDevice device) from ServerObserver#onDeviceConnectedToServer(BluetoothDevice device). This confuses me for a few reasons.

(1) AIUI, BleManager#connect leads to a BluetoothDevice#connectGatt call, which treats the caller as a GATT client. Is it expected that a GATT server would have to do this too? In practice, this call does seem necessary for my code to work, so I'm more asking than calling it out as an issue.

(2) BleManagerGattCallback#onServerReady(BluetoothGattServer server) is called from BluetoothGattCallback#onServicesDiscovered, which also seems odd because why does a GattServer need to discover the services of its client? This issue actually is affecting me, because my BleManager can't set up callbacks on my server's characteristics until this method is called. The simplest fix would be to add GattServer as a parameter to ServerObserver#onServerReady, which actually does get called once the BluetoothGattServer is done advertising.

Overall, I'm confused by how server mode still involves a lot of client role calls. Any info explaining this or larger code samples demonstrating a working server would be much appreciated.

usikder avatar Aug 20 '20 19:08 usikder

Hello, The main intention for this was to be able to use the connecting device also as a server. Very often both sides have some devices for the other side to use. Even if you didn't define any, there should be Generic Attribute and Generic Access services. But you're right, that if you intend only to use the device as client, and your phone as the server, this service discovery isn't required. However, the whole Ble Manager was initially design as client, with server features added recently, and many features require BluetoothGatt to be open. Did you try adding server instance as a parameter toonServerReady callback? Does everything else work for you? I'll most probably release a bug fixing version today, so I could add this parameter. Could you create a PR?

philips77 avatar Aug 21 '20 07:08 philips77

I added a PR to address this issue, but I think the we need to do at least a bit more for proper standalone server support. For instance, BleManager holds onto the BluetoothDevice it's currently connected to.

https://github.com/NordicSemiconductor/Android-BLE-Library/blob/1b836ad846ef86fed35fc93807ff8e1056afd57f/ble/src/main/java/no/nordicsemi/android/ble/BleManager.java#L306-L308

The only way to set this device is by connecting as a client, i.e. through a ConnectRequest. Not having this device breaks things like notification/indication sending

https://github.com/NordicSemiconductor/Android-BLE-Library/blob/1b836ad846ef86fed35fc93807ff8e1056afd57f/ble/src/main/java/no/nordicsemi/android/ble/BleManagerHandler.java#L2930-L2933

and figuring out what BleManager should handle a GattServerCallback call.

https://github.com/NordicSemiconductor/Android-BLE-Library/blob/a447ade444d12eca587044785b54bce39c5f9fd2/ble/src/main/java/no/nordicsemi/android/ble/BleServerManager.java#L164-L171

Would you be open to PRs improving standalone server support? My initial thought is to create a BleManagerGattServerCallback class that serves as a counterpart for BleManagerGattCallback. Then, a BleServerManager could create a ServerBasedBleManager (which instead returns a BleManagerGattServerCallback in its getGattCallback function) for each device it connects to.

usikder avatar Aug 25 '20 17:08 usikder