I have two peripheral devices, say device1 & device2 and one Android device for central role. Android can connect to both by BluetoothDevice.connectGatt() method with autoConnect = false.
Problem is - While autoConnect functionalities work well for device1, device2 even does not connect for once with autoConnect = true.
onConnectionStateChange callback is not called in either side (android & device2).
Advertisement and scan-response packets been customized in device2, is that causing the problem? Though we know that, settings for autonomous connection is to be provided entirely at central side, peripheral side has nothing to do with it, change in peripheral device also changing auto-connect behavior at central side.
any insight? Thanks in advance.
Related
I have to write a BLE application on an embedded device and there are some features where I'm not sure if BLE supports that or whether I've to create some wrapper around everything or if it's maybe not possible at all. The gerenal descriptions of Bluetooth and BLE I found around the internet usually only cover the overall functionality but don't go in too much detail. If this post gets too complex I'll split it up into different smaller ones.
I use the STM32 BlueNRG-MS chip
1. Discoverability (resolved)
The user has to be able to disable the BLE function in case there are several devices in reach. I see that there are functions aci_gap_set_discoverable() or aci_gap_set_non_discoverable() but altough I set it to not discoverable I can still see it in the LightBlue App on my mobile. How would I correctly disable the BLE functionality of a device to make sure no one can see it or connect to it?
Update: Okay that has been a mistake from my end, if I call the aci_gap_set_non_discoverable() function it is actually undiscoverable. So that's fine.
2. Only accept connections of paired devices
I'd like to achieve a behavior such that, if you have an unpaired phone you have to set the BLE device into a pairing mode in order to connect. If the phone has already been paired, the BLE device shall accept the connection request regardless of whether it's currently in pairing mode or not. Is this what the whitelist should be there for or do I have to do this manually by saving the address of the device after successful pairing? If whitelist is the right approach, I read that newer phones cause issues with whitelisting because they change their address on a regular basis, how can I handle this? That's actually where I thought I'm gonna work with the "discoverability".
3. Automatically reconnect
I'm not sure if this topic has to be handled on the BLE device or on the mobile phone. E.g. my phone is paired with my car's radio, so whenever the phone is in the car it automatically connects - how is this done? It's still the phone that acts as central device I assume?
I'm using Android Things 1.0.4 in a prototype where it acts as BLE peripheral device: advertising services and running a GATT server.
I encounter an issue in the BLE pairing process when trying to bond the Android Things board (Raspberry Pi 3) and a smartphone.
Since the device has no display, I set using BluetoothConfigManager:
IoCapability = BluetoothConfigManager.IO_CAPABILITY_NONE
which results in the error AUTH_FAILED every time.
Instead,
IoCapability = BluetoothConfigManager.IO_CAPABILITY_OUT
logs the pairing key and prompts the smartphone to enter it during pairing, but it results in the REMOVED error.
Questions:
Is Android Things in peripheral role capable of handling BLE pairing or not yet?
Are there more things that need to be implemented in the app's code to replicate the full-fledged Android logic?
Here's the source code of the Android Things app to test BLE pairing and bonding
The same code stripped from Android Things specific elements completes BLE pairing and bonding successfully when running on an Android phone as Peripheral (server), and an Android device or iPhone as Central (client).
Generally speaking, if you attempt to read an encrypted GATT characteristic before pairing (which triggers the pairing logic automatically), this results in GATT error 137 returned from the read request (AUTH_FAIL). This is because the device doesn't have enough time to finish setting up the bond before a response is sent by the Bluetooth stack. Retying the read request again generally succeeds.
I have not tested this with an iOS client device, but it certainly holds true with an Android client connecting to an Android (Things) peripheral. As such, I would recommend a few things:
Have the client (mobile) device explicitly initiate pairing, and Android Things should simply react to these incoming requests in the BluetoothPairingCallback. This lets the mobile device decide the pairing type based on the reported capabilities of the IoT device.
Separate the pairing flow from the GATT flow. Pair to the discovered device separately from making any attempts to read the characteristics. This tends to be the best way to avoid timing problems.
Regarding capability choices, this depends on your device. In my experience, if you choose IO_CAPABILITY_NONE this results in PAIRING_VARIANT_CONSENT inside of onPairingInitiated() and the pairing operation succeeds once finishPairing() is called. If you adjust your capabilities, you should be prepared for any number of the variants requiring you to display a PIN for the mobile device to enter. I have not not personally tested these paths.
I'm trying to develop an app that connects via BLE to my CC2650 sensor tag from Texas.
I'm able to connect to my tag using GATT protocol the problem is that if when I'm connected the connection fails it is not restored. But if I reconnect the phone to the device and I repeat the procedure (turn off and on the tag) it automatically reconnects to the phone.
I just don't understand the difference between the first behavior and the one after a reconnection...
Any idea?
Alex
Android should be documented better. Anyway, here is the explanation:
When you call connectGatt (https://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback)) with autoConnect set to false, that will only make a one-shot connection to the device. When it disconnects, it doesn't reconnect.
When you instead connect using the .connect() method on the BluetoothGatt object, that is the same thing as closing the current BluetoothGatt object and then connect again with connectGatt and the autoConnect parameter set to true.
When the autoConnect parameter is set to true, that means that you would like to keep the device connected forever, i.e. for whatever reason it disconnects, Android will always try to attempt to reconnect to the device.
You can check out my list of differences for autoConnect here: https://stackoverflow.com/a/40187086/556495.
Not sure if to posted this on SO.
I'm looking at pretty simple BLE Device. It has a two LEDS (to simplify) that can be switched on or off.
While browsing the GATT profiles, i can't find which profile i should use. Most of them send something back (like a temerature) to the client (upon request).
I need the opposite: switch something on/off of the BLE decive (server). In my case, the client (a iPhone) would send a command to switch on/off LED-1 or LED -2.
What service profile i should use?
Thanks.
I'm using the nRF8001 development kit & nRF Studio for making the services.h
If the LED's are just to be turned on/off there probably isn't any specific profile that they belong to. You probably need to know the handle and write directly to the attribute some value that maps to on or off. Maybe you can figure it out by listing all attribute characteristics. (unfortunately I don't know how to do that specifically on the iPhone)
I noticed that you are using the nRF8001 development kit. So, first thing you need to check is whether the LEDs are connected to IO port of the micro-controller on the kit or directly connected to IO port on BLE chip.
If it connected to micro-controller on the kit then you need to program the kit to handle the received bluetooth data to control led. (It would have a high chance it is in this situation)
If it connected to BLE chip, it means you need to program the ble chip first.
Usually, useful GATT profiles are user specified. It means you need to define the profile yourself. And, I believe some part of the kit or the studio would allow you to do modifications to the profile.
There is only one default GATT profile you should use -- GAP which is to define the defaults like name of the ble device. The others usually are user self-defined profiles.
I've got a problem that we are hoping there is a simple solution for.
We have a need to allow a push notification to appear on a device when it enters into a certain space. The space is only going to be about 1500 sq ft. So my thought is to set up a wifi network in this area... I'm curious if anyone is aware if it is possible to notify anyone with our app installed on their device when they enter into this wifi space if they want to take a certain action... for instance to open the app?
Create an Android service that is launched when the intent WIFI connected is triggered.
The service will check if the bssid of the wifi connection is the same of the wifi area you want to monitor and then it could either launch the app/show popup/show notification.