This is my first shot working with bluetooth and I'm confused about which channel I should be sending my write packet to enable notifications. I'm working with the Fitness Machine 0x1826 service and I'm trying to get the data from the 0x2AD2 characteristic, specifically the 0x0030 handle.
When I run "sudo gatttool -t random -b [MAC ADDRESS] -I --char-write-req -a 0x0030 - 0300 --listen" I get no response so I'm led to believe that I'm sending the packet to the wrong handle, as the device should be sending notifications with my actions.
Thanks for any help!
You should send your write packet to Client Characteristic Configuration Descriptor (CCCD), which has a UUID 0x2902. You first need to find the handle of that CCCD within the fitness machine service. You can find more information here:-
Reading Thermometer Data with BlueZ
Bluetooth Low Energy: listening for notifications/indications in linux
However, as ukBaz mentioned, gatttool is deprecated so you should look into using bluetoothctl instead. More information on using bluetoothctl as a gatt client is found here:-
bluetoothctl write on descriptor to enable notification
Using acquire-write and acquire-notify in bluetoothctl
Related
I see its adding a file to /var/lib/bluetooth/hci MAC/cache/ for each discovered device with its name as the address. Documentation says its creating device objects. Where and what are they, virtual dbus objects? ( ex: /dev_F8:41:1B:6B:95:2A). I know the device is removed after 3 minutes if not connected. And what else is it doing to make a device available for connecting with the bluez dbus interface. Thanks.
Bluetoothctl uses the Bluez DBus apis to do everything it does. When you do 'scan on' in bluetoothctl, it will call the StartDiscovery method of the Adapter object. Internally the Dbus will use the HCI interface to start a lescan. Once advertisement come in, Bluez will create objects for them on the Dbus and will send an InterfaceAdded or PropertiesChanged signals on the Dbus. Your application can listen to those signals which contain the address of the objects they are about.
I am running a BLE beacon in bluez5.52 on a linux machine(ubuntu 14.04) using the default gatt-service and the beacon using the btmgmt provided in the tools folder. Following are the commands I run to setup the beacon:
Terminal 1:
./gatt-service
Terminal 2
sudo ./btmgmt
add-adv -u 180d -u 180f -d 080954657374204C45 1
I am easily able to connect and disconnect with the beacon using BLE scanner app in android.
What I would like to do is setup a password for the beacon so that I am the only one who can connect to it. So far I have been unable to find any resources online that could help set that up. I have a decent understanding of the btmgmt and gatt-service code. I am looking for direction on what part of bluez code to look for to set up the password protection. Any leads, pseudo-code or partial code would help a lot.
Emil already mentioned pairing and bonding in the comments. This would definetly serve your purpose as you would be able to control who could connect to your peripheral.
A BLE characteristic can ask a connected device to authenticate before reading or writing which would result in a 'insufficient authentication error' if the device is not paired to your peripheral. A Android app is able to handle this error by displaying a pairing popup depending on the used pairing method.
So it is possible to have characteristics without security right next to one's that require pairing.
In case you still want to implement something like your mentioned password safety you should look into a 'authorized read'.
A characteristic which requires authorization first receives a read request and you can allow or deny it based on your own requirements. That means you can authorize yourself by sending a password to one characteristic and afterwards allow a read request on another characteristic. This would be even easier if you only accept one connection at a time.
I'm using BlueZ 5.49 and trying to connect, pair, and pass information between two different bluetooth devices.
It's seems like i have problem with enforcing security and authentication between the two.
I'm configuring each hci device with:
hciconfig hci0 pscan auth encrypt which as i read, is setting the device to security mode 3.
In addition i'm creating manualy this path in both sides: /var/lib/bluetooth/<local_bdaddr>/<remote_bdaddr>/info with LinkKey.
I've noticed that if i'm creating the path for only one device, and then trying to connect using rfcomm connect from the device without the infofile, the connection succeed, even though the device is lacking the info file which containts the LinkKey.
If i'm trying rfcomm connect from the device with the info file i'm getting Key Exchange Error, which is acceptable since the other device doesn't have the key.
My base line is that it seems that security and authentication are not enforced.
Many Thanks,
Liad
Apparently hci device is by default set to work in Secure Simple Pairing also known
as sspmode. Simple Pairing originaly generated to support devices that can't insert pin code during pairing process (such as headset).
Hence when a device is in sspmode enabled, it use a default pin key - say 0000, and then based on the pin, generating LinkKey to encrypt and authenticate, and thus not truely enforcing authentication as i mentioned before.
The line hciconfig hci0 sspmode disable is disabling the Secure Simple Pairing mode, and finally enforce authentication using the static LinkKey you supply
in the info file which located in /var/lib/bluetooth/<your_mac>/<remote_mac>/info.
Description:
I have a small in-house device with bluetooth capabilities.
At the moment , other devices connect to that box.
Requirement:
Now we have to make it slave so that it get connected with other devices. I am wondering how to do it ? I don't need source code or anything just your views.
Additional Information:
The application uses Bluez libraires to send command to firmware/hardware and we extensively use HCItool.
Operating system :
Fedora.
I am also wondering , do I need to change chipset? From google it doesnt look like we need to change it.
Any help will be beneficial to us.
Thanks
From the command line, the way to achieve what you want is to use the #hcitool. However, you must first be connected. Try this sequence:
hcitool cc AA:BB:CC:DD:EE:FF #Connect to the device
hcitool con #To make sure you are in a connection
hcitool sr AA:BB:CC:DD:EE:FF <role> #switch master/slave role
If the output of "hcitool con" indicates that you are not in a connection, try the following sequence:
hciconfig hci0 sspmode 1
hciconfig hci0 piscan
sdptool add SP
rfcomm connect /dev/rfcomm0 AA:BB:CC:DD:EE:FF 1 &
hcitool con
hcitool sr AA:BB:CC:DD:EE:FF <role>
The above code is specifically for the serial profile, but it has worked for me on several occasions when 'hcitool cc' failed.
If you want to see the source code for this, open the tools/hcitool.c source file in the bluez directory and navigate to the function:
static void cmd_sr(int dev_id, int argc, char **argv)
This is the function that fires up the sequence for switching between master and slave role. Following this function you can see what exactly happens through the bluez stack.
I hope this helps.
I'm trying to set up a connection to a Bluetooth 4.0 LE device on Linux using the BlueZ 4.X DBus interface.
To test this I use the following command:
dbus-send --system --dest=org.bluez --print-reply /org/bluez/<PID of bluetoothd>/hci0 org.bluez.Adapter.CreateDevice string:<MAC of BT device>
This command seems to work most times, giving a result like:
method return sender=:1.238 -> dest=:1.262 reply_serial=2
object path "/org/bluez/9652/hci1/dev_BC_6A_29_26_C2_1C"
and enabling me to interact with the device DBus object.
However, starting from yesterday, this seems to fail very frequently returning the following error:
Error org.bluez.Error.Failed: Operation canceled
When debugging the bluetooth daemon, (using bluetoothd -n -d) I notice the following things when executing the method call:
bluetoothd[340]: src/adapter.c:create_device() BC:6A:29:26:C2:1C
bluetoothd[340]: src/adapter.c:adapter_create_device() BC:6A:29:26:C2:1C
bluetoothd[340]: src/device.c:device_create() Creating device /org/bluez/340/hci0/dev_BC_6A_29_26_C2_1C
bluetoothd[340]: src/device.c:btd_device_ref() 0xb7ad8: ref=1
bluetoothd[340]: src/device.c:device_set_temporary() temporary 1
bluetoothd[340]: src/device.c:btd_device_ref() 0xb7ad8: ref=2
bluetoothd[340]: plugins/mgmtops.c:mgmt_event() cond 1
bluetoothd[340]: plugins/mgmtops.c:mgmt_event() Received 14 bytes from management socket
bluetoothd[340]: plugins/mgmtops.c:mgmt_connect_failed() hci0 BC:6A:29:26:C2:1C status 4
bluetoothd[340]: src/event.c:btd_event_conn_failed() status 0x04
bluetoothd[340]: src/device.c:device_remove() Removing device /org/bluez/340/hci0/dev_BC_6A_29_26_C2_1C
bluetoothd[340]: src/device.c:device_set_temporary() temporary 1
bluetoothd[340]: src/device.c:btd_device_unref() 0xb7ad8: ref=1
bluetoothd[340]: src/device.c:btd_device_unref() 0xb7ad8: ref=0
bluetoothd[340]: src/device.c:device_free() 0xb7ad8
As far as I can see, my Bluetooth dongle sends me an error event (status 4) when I try to connect to the device.
However, when I use hcitool ot gatttool to connect to the device, everything works perfectly.
I found that this happens mostly after I try to connect to the device using a different program (i.e cinnamon-settings), and cancel the connection prematurely. I also noticed this with other programs like bluetooth-properties on Angstrom.
My guess is that Bluez sends the wrong HCI commands to my bluetooth dongle in certain conditions. I think this is because the gui programs try to pair with the device instead of just connecting to it, which may cause BlueZ to think my device is a Bluetooth 2.0 device.
Thus far I seemed to be able to resolve this problem by connecting to my BT device using a gui application, waiting till it fails, and restarting my computer. However, the problem seems to reoccur occasionally, making this very painful.
I have seen this problem on systems running both BlueZ version 4.99 and 4.101.
Does anyone know how I can solve this correctly?
It seems like my predictions where more or less correct. After many hours of debugging the Bluetooth daemon I discovered that connecting to BT LE devices without a preliminary scan causes the daemon to try to connect to the device as a BR/EDR device. This is because the daemon's "internal cache" is filled with the EIR information at the time the device is discovered. If this information is not available when connecting to a LE device the CreateDevice method will fail.
A simple solution is to always make sure to discover devices before connecting to them.
The BlueZ 5 API introduction and porting guide also describes this problem, and how it is solved in BlueZ 5:
Bluetooth Low Energy essentially extended Bluetooth addresses with one extra bit, requiring one to always know whether an address is “random” or “public”. This caused issues with the BlueZ 4 API where the address was given to BlueZ in the CreateDevice and CreatePairedDevice calls. Since the parameter didn’t contain any of this extra random/public information bluetoothd had to maintain an internal cache to look up the necessary info. Another complication to the matter is that the BlueZ D-Bus API doesn’t differentiate between traditional BR/EDR devices and LE devices so there are essentially three possible address types: BR/EDR, LE public and LE random.