I implemented the org.bluez.Agent1 interface using QDbus and I would like to set a fixed pin (that I will provide to the users) in order to authenticate all the pairing request and reject them if the pin is wrong. The agent capabilities should be "NoInputNoOutput" because the project will be deployed on the RaspberryPi 3 without keyboard or display. Is there a way to deal with this? Thank you
You should not initialize the capability as "NoInputOutput" for fixed key pairing. NoInputOutput means there is not display and there is no keyboard/UI possible for this device. Mentioning this capability for your Agent when registering with BlueZ means, instructing BlueZ (bluetoothd) not to call any Agent API for authentication.
This is typically useful to autopair without any manual intervention. You can see this sample code, which uses NoInputOutput capability to connect the device without any intervention.
What you need is "DisplayOnly" capability to instruct BlueZ to call "DisplayPinCode" or "DisplayPasskey" based on SSP support of your device.
You can implement DisplayPinCode/DisplayPasskey in your Agent to reply constant PIN always. So the Bluetooth device which tries to connect can use the same constant PIN for pairing.
Here Display Pin /Passkey is just the naming convention or hint to Agent developers to write wizard/UI or any form of display operations. But you can completely ignore the displaying operation and reply with static/constant 6 digit key for pairing.
Typically this Agent API is called by Bluez (in rasperry pi) when the device (iPhone/Android mobile/any bluetooth capable device) trying pair calls "RequestPasskey" or "RequestPinCode" from the device end.
We had the same issue in a project, and i moved on LE device do to the fact that apple device are only capable to connect to LE device for "safety" reasons.
I don't have that much ref to that but if this could help you in your researches.
Related
When connection to a custom BLE device from an app (android and ios) I have two options
a) first pair the device on the phone (like a headset or other devices) and then use it from the app to read and write data
b) without pairing on the phone, go inside the app, search for a device with a specific name or address, and just connect to it and read and write data.
when is one preferred over the other one ?
Its just when it needs to interact in the background or am I missing something?
The devices you see in your phones Bluetooth settings are Bluetooth Classic devices. There are some devices using both BLE and Bluetooth Classic which show up in the settings too, but the settings page is only for the Bluetooth Classic part of the device. Headphones for example are streaming music trough the Bluetooth Classic profile A2DP but might offer BLE services for additional features.
You always have to use a special app to communicate with the BLE part of a device. This could be an app provided by a manufacturer or a generic BLE scanner app such as nRF Connect.
As alexander.cpp already told you in his answer pairing (the exchange of keys) and bonding (saving of said keys) is not required for the communication with BLE devices and only needed if the device requires a secured connection.
Bonding (technically correct term for BLE, often called Pairing in non-technical speech) is mostly for security, we can send sensitive information because the receiver is verified and data is transferred in encrypted form.
Prefer to use bonding if the data is sensitive (means users feel uncomfortable if somebody they don't know receive their data). For example, I consider "current temperature = 25" as NOT sensitive. For detailed explanation, find "Bonding with a BLE device" in BLE guide by PunchThrough.
Also this is a good answer to a similar question: https://stackoverflow.com/a/42916081/10380092.
Your second question about background - no, bonding is not related to interaction in background.
I'm trying to establish a connection between my PC running Ubuntu and my iPhone via Bluetooth automatically when it becomes available, after being manually paired beforehand. I've seen this to be possible with certain peripherals, mainly audio. For example, my phone will automatically connect to a Bluetooth speaker when it is turned on and Bluetooth is active on my phone; another example is my phone automatically connects to my car's radio system via Bluetooth when I turn the car on.
I'm not able to connect my phone to my PC without first initiating the connection from the smartphone's Bluetooth menu. I'm thinking that I could possibly write an application for the PC to attempt to connect to the device every few minutes or something, but it seems that the phone needs to be the device to initiate the connection.
The only information that I need for what I'm trying to do ultimately is that the devices can pair successfully. Essentially I'm trying to build a sort of proximity trigger between my phone and my PC without using Wi-Fi and GPS - I can't use these for some specific reasons.
Is there any way to make this happen?
Yes this should be doable as long as you use the Background Processing feature for iOS apps. In the example I'll give below, we'll have the PC be the peripheral and the phone be the central, but you can really have it working either way. You will need to do the following:-
First initial connection needs to be performed in the foreground (this is due to iOS's background limitations).
On the iOS side, you need an application that acts as a central that scans and connects to the remove device (check this example as a starting point).
Upon connection, you need to bond with the PC. Bonding is important as it will prevent you from having to do the pairing again in the future. However, pairing/bonding is managed by the iPhone's OS so you cannot write it in your application, so the workaround is to have an encrypted characteristic on the PC side that will force the iPhone to bond (this is covered later).
On the PC side, you need to have a BlueZ script that acts as a peripheral that is always advertising. You can do this using bluetoothctl (check the examples here and here).
Before you start advertising, you need to have a GATT server on the PC side (to do this, check this example).
When registering characteristics, ensure that one of them has the encrypt-read property (you can find a full list of the properties here).
Now when you attempt to read this characteristic from the iOS side, the two devices should bond (make sure that your PC is bondable which you can do this via these commands).
Once the devices are paired, your iOS app needs to be working in the background constantly scanning and attempting to connect to the same peripheral (have a look at this and this example).
You can find more useful information at the links below:-
Getting started with Bluetooth Low Energy
The Ultimate Guide to CoreBluetooth Development
How to manage Bluetooth devices on Linux using bluetoothctl
I have an android app that connects to a few classic Bluetooth and BLE devices. Starting from one of the security patch releases of Android 10 I am getting pairing requests on my Android device. Is there a way to automatically accept these requests in code? The BLE devices do not have a pin and only need a certain flow of read and write operations to pair. Right now my write operations are failing unless I wait for the bond state to change to BONDED which happens on accepting the pairing request on the Android device.
So far I've tried setPairingConfirmation(true) which does not seem to be working.
I guess the idea of pairing is that the user must accept that an "unknown" device being paired to his system. Otherwise different shady apps could just pair devices in the background without the user's consent.
A peripheral that is not meant to be paired to a user should hence not require pairing in the first place, to perform various operations.
We've got a use case in which a BLE connection is used to do the basic configuration of an embedded device via an Android app (later also via an iPhone app). The embedded device runs Linux and thus uses BlueZ as Bluetooth stack.
Using the DBus-API of BlueZ, bonding is made possible by making the device pairable, discoverable, and activating advertising. After bonding the apps can access the GATT services and characteristics
(which require bonding to be read/written) on the embedded device.
After the setup is done the bonding of the device (running the app) that managed the setup process, is supposed to be removed. In order to do that we call RemoveDevice() of org.bluez.Adapter1.
The BlueZ documentation states the following
void RemoveDevice(object device)
This removes the remote device object at the given
path. It will remove also the pairing information.
Still the app is able to access the GATT characteristics afterwards.
If bluetoothctl is used to check the list of paired devices, the list is not containing that device anymore though. Before calling RemoveDevice() the bonded device was visible there.
If bluetootd is stopped and restarted the app is no longer able to read/write the GATT characteristics, but needs to re-bonded before doing so.
I can neither find any further information in the BlueZ documentation nor can I find anything about this topic searching anywhere else.
Is this intended behavior or is this a bug? Does "remove pairing information" also mean "remove bonding information"? If this is intended behavior, how do we properly terminate bonding with a device?
Should I use the BlueZ Management API instead of the BlueZ API? I'm not sure about this as multiple source state that the DBus-API is the way to go.
RemoveDevice() indeed removes the bonding information as well. So you have to disconnect first and then call RemoveDevice(). The next time you connect the bonding information will be gone.
However, note that if you only make use of encrypted characteristics, you can still connect and discover services. Only once you start reading/writing the encrypted characteristics will Bluez check if you are bonded.
We have bought BLED112 to interface our target via BT.
An android app interacting with target via BT & USB (HID).
We have used some Bluetooth communication to write a program and send data to dongle.
Now can somebody here having any experince in converting that BT data to a HID signal.
Have anybody tried that?
Is there any BGScript code which we need to write to achieve that?
Please let me know if the thought is completely wrong.
Referring to a comment above which states,
We are writing an Android App which can send data to BLED112 over BLE interface or GATT. My question is how can I convert that data (basically a command) to an HID (key event), correct me if my understanding is wrong?
If I understand the use-case correctly, I think, in the initial stages of the development, you will need to use the BLE-GUI utility that BlueGiga provides.
With that utility you can see the communication between the BLED112 Dongle and the BLE112 Module. BLED112 shall be simulating what the android app would do?
First, you will need to know the GATT structure stored in BLED112 to write to or read from the BLED112.
Secondly, the way BLE112 works is an event-based implementation. Going through the API reference document for BLE112 shall help you understand the events generation conditions and codes that are generated modified when a characteristic value is updated by the android application, or read by android application. You get events for connection, disconnection, read from, write to, notification enabled for, indication enabled for, etc.
On the BLE112 side, depending upon what service and what characteristics in that service is going to be used for data transfer between Client (Android App) and Server (BLE112), you need to write suitable implementation in event callback handlers.
There is a standard service called Human Interface Device which has a reserved UUID: 0x1812.
Once you configure your BLE112 as a HID over GATT device, your android app shall see a service with UUID: 0x1812. Parse the service descriptor and get the characteristics bundled up into the service. You can read from or write to that service depending upon access parameters set in gatt.xml
As an example, say, if it is a Keyboard, you can send the scancode for (make and break) of the key depending upon what key is pressed. How to get a scancode is out of the scope of this question anyway, and sadly I had worked on PS2 keyboards, so I don't really know how to get the scancode from a USB keyboard.
So, you have the scancode for the key pressed, and you know the characteristics to write that into. Write it, the application should enable the Notifications for that characteristics, so that it is notified whenever the key is pressed and value is written into the characteristics. To let application enable notifications or indications for the characteristics, study the developer guide that talks about how to write a gatt.xml for Bluegiga-based BLE devices. I'll give you a hint: in xml, in the characteristics configuration you have to write notify="true".
About parsing of the service and characteristics in Android, Unfortunately I am not an android developer, but an embedded developer, I know how the BLE112 module part is to be implemented, while I have no insight of how android parses the data. But, there are plenty of question and discussions about it online, which you might understand better than me since you have an android background.