I am developing an Android app which behaves as Bluetooth peripheral role with a service.
When I start advertising, other Android devices searching for devices offering this service, can see my device (and can pair to it without pin) - ok.
But how to enable PIN pairing?
You can force the device has to be paired, when using specific characteristics by protecting them with PERMISSION_READ_ENCRYPTED_MITM or PERMISSION_WRITE_ENCRYPTED_MITM.
The client/central side can force pairing by calling BluetoothDevice.creteBond().
The pairing method itself is determinated by the bluetooth protocol (see this thread)
You dont actually require pairing to be done to transmit/receive data via ble, take a look into this tutorial
Related
I am working on a Flutter app that connects to a bluetooth IOT device. I am using the flutter_blue library. This library allows for the scanning of nearby bluetooth devices. Based on that scan you can "connect" to a device. There is no concept of pairing to a device.
From my previous experience using bluetooth on my phone (when connecting to my car and my bluetooth speaker), I have to pair the device at the Android OS.
I am curious, from a high level, what are the differences between pairing a device vs connecting to a device. In addition, more specifically, what is the difference between pairing a device within the OS, vs scanning and connecting to the device from an app?
At a high level, you will always use "connect" to connect to a device, but you may have to "pair" the devices first. Bluetooth pairing is a security procedure. A one-off provisioning step that equips the two devices in a pairing with a series of shared security keys which allow communication to be encrypted.
A Bluetooth Low Energy device can have three levels of security, the lowest of which pairing is not required, and then two levels that require pairing.
A device opting to use No Pairing provides the greatest simplicity but obviously, no security. Communication is not encrypted and any other device can connect.
The two pairing method that can be used provide the same level of security when connected. However, during the pairing procedure itself, one of the two methods is more secure than the other.
Passkey Pairing is the most secure of the two procedures and requires a 6 digit number to be entered. This offers protection against machine-in-the-middle (MITM) attacks.
Just Works Pairing is not as secure but it does not require you to enter anything and therefore is very simple to use.
Once a pairing is established, then connection can happen without the need to establish pairing every time.
More detailed explanation of the pairing options are available at:
https://www.bluetooth.com/blog/bluetooth-pairing-part-1-pairing-feature-exchange/
According to the Bluetooth Core Specification Version 5.2 | Vol. 1, Part A, Chapter 5.1 pairing is defined as
the process for creating one or more shared secret keys
The keys themselves are not shared but established using a procedure called Diffie-Hellman key exchange. This means that pairing is only necessary if a connection is encrypted. If you connect to a device that requires security measures on one of its characteristics Android will prompt the user of your app with a pairing request automatically.
Another term you might have heard is bonding, which is defined as:
the act of storing the keys created during pairing for use in subsequent connections in order to form a trusted device pair
Bonding allows a reconnection of your devices without another pairing process since the keys have been established before.
When using Bluetooth Low Energy (BLE) pairing a Device manually within the OS is not needed. You can always scan for a device that advertises its presence. As I said before: Pairing is handled by the OS automatically if needed.
We have a BLE device and android/ios app for communication with the device.
The requirement is to have an android/ios app connect to the device without any pairing request. No security is required on the device.
Hereafter a few questions around this:
Q1. Is it possible at all to have an android/ios app connect to a BLE
device without a pairing request?
Q2. Does the bonding required for
the BLE communication?
Q3. What is the downside of having the device
with no bonding? Is it going to drop the connection while the app is
running?
Q4. Who is the initiator or pairing dialog, the app, or the
device?
Q5. When having the device with Just Works security protocol,
with no bonding and no MITM protection, should we see a pairing
dialog?
Please see answers to your questions below:-
A1. Yes it is possible to do this because pairing and connection are two separate actions. Connection is when you establish a communication channel with a remote device, while pairing is when you exchange security keys with the device and have the option of encrypting that connection.
A2. No, pairing/bonding is not required for BLE communication but it is preferred in order to have extra features and extra security on that connection.
A3. No, having no bonding does not affect the stability of your connection/communication. There are a few downsides which include less security on the connection and also potential inability to find the device if privacy is implemented. More details are provided in the link below.
A4. The app is the initiator of the pairing dialog. Specifically, the central device (the one that initiates the connection) is the one that is responsible for initiating pairing. When this central device requests to pair to the remote device, the pairing dialog is shown.
A5. I believe this is dependent on the OS type (Android/iOS) and the version number of that OS, but generally speaking the pairing dialog should not pop up because as the name suggests, it should just work. Pairing dialog pops up when MITM protection is requested.
You can find more details about pairing/bonding and general BLE communication is the answer below:-
Should one create a bond with a Bluetooth LE device
I would also recommend trying the nRF Connect app on both iOS and Android to see the difference between connection and bonding and to verify that you can have normal connections without pairing.
Based on what we got working and based on the answers to this question.
A1: Yes, it's possible if no MITM is set and the Security scheme is set to Just Works, which means no security at all.
A2: Bonding is not required for BLE communication. If the BLE device can't store the Bond information, it may lead to some issues as we got in our case. If the BLE device is able to store and use Bond information then it's recommended to Bond.
A3: The Connection will not be closed. The only downside we got is that now it takes a little more time to reconnect.
A4: The app is initiating the connection, but the dialog is shown only if the BLE device requests some type of security, it can be MITM, encryption, pin. Short answer, the pairing dialog can be avoided by changing the settings on the BLE device.
A5: When having the device with Just Works security protocol, with no bonding and no MITM protection the pairing dialog should not be presented. We got no pairing dialog experience on both iOS and Android.
To add to Youssif's answer:
A3: one difference is that connection setup will be faster since bonding allows the GATT db cache to be used. Otherwise service rediscovery must be done on every connection (if the service changed characteristic is present).
A4: on Android you can call createBond to start pairing, but on iOS there is no API for the security, so either you need to interact with a characteristic that sends an error that pairing is needed, or the remote device can send a Security Request to initiate pairing.
A5: iOS shows a dialog "accept / abort" for just works, Android doesn't.
I have a raspi3 with android things on it and I want to connect to a BLE device that requires a user authentication for bounding.
On a phone, after having set a characteristic on the BLE device, I am able to receive the Broadcast event
BluetoothDevice.ACTION_PAIRING_REQUEST
and in the meantime a dialog from android system opens asking me to accept the bluetooth connection (it has pairing variant = 3 (PAIRING_VARIANT_CONSENT)). When I accept it on the dialog everything goes nice and I connect to the device.
In my android things device I don't receive any ACTION_PAIRING_REQUEST event and my connection drops as soon as I write the characteristic on the BLE device.
Is there any way to have the accept process on android things?
You can use the Android Things BluetoothConnectionManager to initiate device pairing or respond to incoming pairing requests with a BluetoothPairingCallback. See the Bluetooth API guide for more details on device pairing.
I've built a dual mode Bluetooth device using the BT 121 from Silicon Labs. The device implements SPP over the classic connection. The device name of the classic node is "XYZ Classic". It also implements a custom service (128-bit UUID) in BLE. The device name of the BLE node is "XYZ_BLE". Both nodes have the same MAC address.
When pairing under 'Bluetooth' settings, sometimes I will see 'XYZ Classic' and sometimes I will see 'XYZ_BLE'. It seems random which one it will pair to but many Android devices I've tested have a tendency to want to pair to the classic node. After pairing, a connection over classic/SPP ALWAYS works. However, I can only connect to the custom service if paired to the BLE node. If paired to classic I can see non-custom BLE services but not my custom service. To summarize:
Function Classic Pairing BLE Pairing
Spp Works Works
Cust BLE Doesn't Work Works
When I pair in code (Android) the problem also happens despite the fact that I search for the devices named 'XYZ_BLE' and then pair to the device returned. I've looked but I can't see a way to force Android to pair to the BLE node.
My only workaround thus far has been to modify my BT 121 firmware to not allow bonding in classic mode. This is not an ideal solution has any Bluetooth Classic only devices will not be able to bond with my device (In reality this might not be too big of a problem but I have one tablet in my possession that only has Bluetooth Classic).
It should be noted that I've used 'BLE Scanner' from the play store to verify that my custom service works/doesn't work depending on the pairing mode. In other words, it's not just my code. :)
So, does anybody have any ideas on how to force Android to pair to the BLE node?
I see similar issues. Some hints:
Android behaviour differs dependent on the bit flags you set in the BLE advertising. There is for example a bit called "no br/edr support" or so. There are also bits telling explicitly that br/edr dual role is supported.
Also ble pairing may be enforced if you access a characteristic which returns a "not authenticated error" from a ble app. At least on iohone, the os will initiate the ble pairing automatically.
I am writing an android app to connect with BLE heart rate monitor devices.
All works well until another application tries to connect to the same service on the BLE device.
Only one application seems to be able to connect at a time.
Is it possible to connect the same BLE service to multple apps at once?
I set up my Bluetooth service in accordance with Link :
You can use BluetoothManager.getConnectedDevices() to get a list of Bluetooth devices, even ones not connected by your app. Unfortunately, you don't also get the service information for those devices.
What you can do then, is connect to the ones not already connected by your app and perform service discovery on them (BluetoothDevice.connectGatt() / BluetoothGatt.discoverServices()), then disconnect those that you aren't interested in. It's a bit cumbersome, but it seems to work for us.
No you can not do that, this is something is not supported in BLE.