If I pair a bluetooth device to my PC but I don't trust it, any time I power on the bluetooth device I will get a prompt like this in bluetoothctl:
Authorize service
[agent] Authorize service 0000111f-0000-1000-8000-00805f9b34fb (yes/no):
If I type yes, the device is allowed to connect.
I would like to write a small Python script that watches for new services and prompts me to authorize them using inotify-send, and pybluez seems like the tool for the job. However, after reading the documentation, I can't figure out if this is even possible. (Probably in large part because I'm not familiar with technical Bluetooth terminology.)
Is it possible to watch for- and authorize services using pybluez, and if so, how?
Related
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
In previous iOS versions you could detect if the user had bluetooth enabled or not without actually prompting the user's permission to access bluetooth. In iOS13, CBCentralManager now prompts bluetooth permission just to check if they have bluetooth turned on or not, regardless of if the app is actually going to use bluetooth directly.
Our app uses Apple's multipeer connectivity framework to communicate between devices (peer to peer) which uses a combination of wifi and bluetooth, or just wifi if bluetooth is disabled, but that is slower, so we like to remind our users to turn on bluetooth for a faster connection. Using this framework does not actually require a permission prompt for the app to use bluetooth because Apple manages all of that in a closed box so our app itself doesn't use bluetooth or require a permission prompt to work, but Apple's multipeer framework works better if the user has bluetooth enabled.
We want to simply remind the user to enable bluetooth for a faster connection, but only if they don't already have it on. However just checking if it is enabled the old way now requires a bluetooth permission prompt even though we won't be using bluetooth in the app.
In iOS13 is there a new method for just checking if bluetooth is enabled or not that doesn't require a bluetooth permission prompt.
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.
I was wondering if there's any way that I can control BLE device pairing specific to my app running on mobile device?
I do not want to write my own bluetooth profile so that only my app can talk to the BLE device instead i want to standard profiles available in BLE device but when it's paired to my phone, only my app should be able to communicate to it and none of the other apps should be able to communicate.
No don't do that.
If you MUST then you should encrypt your data with a key only your app knows.
Bluetooth Low Energy is supposed to be open and free for all.
What is the purpose for you to block others? Preventing them to block your service?
Then use some pre-shared key to verify that it's your app in both sides and close the connection if it's not.
I'm currently looking for a way to list the services exposed by a remote bluetooth device and to enable them.
Normally I would be using the WindowsAPI-functions (or more likely one of the known wrappers) to list the services and to enable them by GUID (SetServiceEnable).
The problem is, that the device is exposing two Services with the same GUID!
Thus using the windowsAPI-functions only enables one of these services. The other service can't be enabled.
I thought perhaps WMI could do the trick, but I'm still new to WMI and couldn't find any
Windows itself is able to enable both, none or a specific service over the servicemenu.
UPDATE
The problem I want to solve is to be able to enable either the first or the second service. By now only the first service (which is usually the service I need), but I couldn't find a solution to enable the second service (except by using the Windows UI).
If both services are enabled I have two Commports in devicemanager (SPP).
Since I can't add comment/questions (don't have the privilege on stackoverflow yet). Here's my best take.
If I understand correctly, it's invalid to have the service available more than once in the service record, right? Can you right click on the device in Bluetooth Pairing UI and see if you see two services and that you can enable them through the Windows UI? And once you enable them do you see two PNP devnodes under that device in device manager (view by connection) with the corresponding opposite role of the two service you enabled? (I can't try this because I don't know of a device I have with two identical UUIDs.)
As you might already know, when you enable service on a remote device, you are not actually enabling the service on the remote device through the Windows Bluetooth API. What you are doing is telling the core bluetooth component in Windows to generate the corresponding opposite role of the service. (This is what BluetoothSetLocalServiceInfo does.) For example, if the remote device supports A2DP sink, by enabling that service the Bluetooth service on desktop would then register a A2DP source service for that device, which generates a PNP devnode for matching A2DP source drivers to install on that devnode. By disabling that service, the Bluetooth service would then unregister the A2DP source devnode and the PNP devnode would be removed (sort of like unplugging a USB device).
Depending on what profile you are seeing being duplicated, it might not make sense to have two instances of device objects and driver objects that matches on the same mac address of the remote device.
My answer (which is actually not answering your question) is to check if it's even valid for the two services to be enabled in that case on the desktop with the drivers on the desktop that you will be working with. For example, a bundle of A2DP plus HFP would require A2DP and HFP to synchronize certain behavior, such as AVDTP suspend. Depending on the implementation and the drivers, they might not be expecting there are two instances of A2DP driver installed, hence causing the unexpected state of the local drivers.