BLE with Android 5.0 : How to get a device to act as Central AND Server?
Asked Answered
K

2

7

I'm using two Android 5.0 devices to communicate through Bluetooth Low Energy and I wan't :

  • Device 1 to act as Central and Server.

  • Device 2 to act as Peripheral and Client.


This is the behavior I'd like to achieve :

1) Device 2 starts advertising (peripheral role).

2) Device 1 starts scanning (central role), and gets the advertising device (BluetoothDevice object) through the ScanCallback's onScanResult method.

3) I now want the advertising device (Device 2) to be notified that it has been scanned and be able to get the BluetoothDevice associated with Device 1.

4) Device 1 has an instance of BluetoothGattServer. Device 2 would now call connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) on Device 1 to get an instance of BluetoothGatt.

5) In the end, Device 1 is Server and Device 2 is Client.


So far I've found that in step 2, once Device 1 holds the BluetoothDevice for Device 2, it can only connect as client like in step 4 using connectGatt.

I might be able to use the BluetoothGattServer defined in Device 1, and call : gattServer.connect(BluetoothDevice device, boolean autoConnect) with device being Device 2.

But how will Device 2 be notified it's been connected to ?

And how will I get an instance of BluetoothGatt in Device 2 if I can't call connectGatt(Context, boolean, BluetoothGattCallback) on a BluetoothDevice?

Thank you in advance for your help !

Some documentation :

BluetoothGattServer

BluetoothDevice

Kunstlied answered 24/5, 2015 at 17:11 Comment(2)
Hi Thomas, have you found any solution to your problem?Aery
Hi Hollerweger, unfortunately I never found the solution. It was for a project at university, I ended up demonstrating my work with two phones and explained why it couldn't work with that specific microcontroller. I graduated since and haven't given it any more of my time. However it might be worth checking if anything changed with Android 6. Please let me know if you figure something out! ;)Kunstlied
S
1

1) Device 2 starts advertising (peripheral role).

Peripheral role will advertise, make sure to add CONNECTABLE

     AdvertiseSettings.Builder settingBuilder = new AdvertiseSettings.Builder();
     settingBuilder.setConnectable(true);

And start advertisement accordingly.

2) Device 1 starts scanning (central role), and gets the advertising device (BluetoothDevice object) through the ScanCallback's onScanResult method.

Perfect, now call connectGatt on this device(peripheral), make sure you stops the advertisement after you gets required device, otherwise you will end up sending multiple connect commands.

3) I now want the advertising device (Device 2) to be notified that it has been scanned and be able to get the BluetoothDevice associated with Device 1.

When you calls connectGatt from Central/client role, your peripheral will get a notification in its BluetoothGattServerCallback'onConnectionStateChange.

there you will know that connection has been made. though you have to register gatt Service with characteristics at peripheral side.

4) Device 1 has an instance of BluetoothGattServer. Device 2 would now call connectGatt(Context context, boolean autoConnect, BluetoothGattCallback callback) on Device 1 to get an instance of BluetoothGatt.

Wrong, Device 1 will initiate connection as I have stated in point 3. both device's onConnectionStateChange will be called to know that connection has been made.

5) In the end, Device 1 is Server and Device 2 is Client.

Wrong, Device 2 is peripheral(Server), Device 1 is Monitor(Client)

Spectrograph answered 27/5, 2015 at 4:31 Comment(3)
I have already implemented this solution and my app works fine on both sides. The problem is it doesn't correspond to the behavior I am trying to achieve. What I am trying to do with Device 2 is to emulate a specific micro-controller that can NOT scan for devices but can only advertise. (Therefore Device 2 has to be GAP peripheral and Device 1 has to be GAP central). However, my phone (device 1) is sending the data to the micro-controller (device 2), that makes device 1 a Gatt server and device 2 a Gatt client.Kunstlied
The above is according to the definitions found under Roles and Responsabilities here : BLE Android What use do you think the following method can be? BluetoothGattServer.connect(BluetoothDevice device, boolean autoConnect)Kunstlied
BluetoothGattServer.connect can be use for connection, if autoConnection is true, and server/monitor role sees disconnected event.Spectrograph
A
0

You must turn it around a bit. The scanner is the one connecting to the advertiser. Dev1 scans dev2 adv and scan response. then dev1 should connect. Dev2 will get callback on connect. There is no callback when someone hear your adv or request scan response on android. Check instead 0x14 «List of 16-bit Service Solicitation UUIDs» from btsig if You want to advertise request for servers with a certain service to connect to You. It is a bit unusual ti see this used.

Alphabetical answered 25/5, 2015 at 6:58 Comment(1)
Do you mean dev1 should open a BluetoothGattServer and then call gattServer.connect(device2,boolean) ? The connection works while debugging dev1 when I do so. The problem is : the only way to get and instance of BluetoothGatt in dev2 and implementing the callback is through BluetoothDevice.connectGatt(contect,boolean,callback). And I can't do so in dev2 whithout knowing who dev1 is.Kunstlied

© 2022 - 2024 — McMap. All rights reserved.