iBeacon Dynamic Minor Value - bluetooth

I am using a Raspberry Pi as an iBeacon by creating a LaunchService that runs on startup executing the following (using BlueZ):
sudo hciconfig hci0 up
sudo hcitool -i hci0 cmd 0x08 0x0006 40 [...] 00
sudo hcitool -i hci0 cmd 0x08 0x000A 01
sudo hcitool -i hci0 cmd 0x08 0x0008 1E [...] 02 C0 00 00 00 00 C5 00
So far this has worked beautifully. The service runs and as long as the Pi is powered, the iBeacon is advertised.
Now I would like to send some Information with the advertising data. I have a brightness sensor wired up to the Pi that simply returns true if a certain threshold of brightness has been exceeded.
My idea is to use the Minor identifier and use 1 to represent "it is bright" and 0to represent "it is dark". My app can then interpret this without having to poll the Pi via a network request what the current sensor status is.
But since I set the advertisement package statically, I won't be able to use this approach going forward I believe.
I have no idea how else to do this however, so I was hoping someone might have some insight and could point me in the right direction.
Thanks for your time!

Easy. You can simply re-issue those commands, specifically the last one:
sudo hcitool -i hci0 cmd 0x08 0x0008 1E [...] 02 C0 00 00 00 00 C5 00
Just change the last byte before the C5 above to be 01 if you want to send out a minor of 1, and change it back to 00 if you want to send out a minor of 0.

Related

Send HCI ACL Data packets with hcitool

History:
I used BlueZ 5.43 to communicate with a bluetooth device:
connect FF:FF:FF:FF:FF:FF
select-attribute /org/bluez/hci/dev_ ...
write 0x54
It takes some time, but it works.
Current issue:
Now I'm using the HCI commands defined in the Bluetooth Specification to connect to my device via hcitool cmd .... Works fine.
But: I can't write an ACL Data packet via hcitool cmd to my connected device:
The ACL packet (see BT Core Spec Vol 2, Part E, 5.2.4) is sent with sudo hcitool cmd 02 40 00 08 00 04 00 04 00 12 0D 00 54
The btmon shows the error: Unknown HCI Command
Using sudo hcidump --r I see that the ACL packet is modified to 01 40 08 0B 00 08 00 04 00 04 00 12 0D 00 54.
How can I send a ACL Data packet via hcitool cmd?
Thank you,
Tom

advertise custom service uuid with bluez 5.4x

I am writing a custom service over BLE to transmit custom characteristics. It has it's own UUID such as '8E400001-B5A3-F393-E0A9-E50E24DCCA9E'.
I have found that a particular android app (BLE client) I wish to support requires that a custom service UUID is included in the advertising packet.
However our peripheral is running via bluez 5.43 on debian and I cannot figure out how to put this UUID in the advertising packet.
I think it will be something like:
hcitool -i hci0 cmd 0x08 0x0008 .... ?
I verified the following commands to be working (BlueZ ver 5.43, Linux 4.9.0-2-amd64 (x86_64)):
hcitool -i hci0 cmd 0x08 0x0008 12 11 07 9E CA DC 24 0E E5 A9 E0 93 F3 A3 B5 01 00 40 8E 00 00 00 00 00 00 00 00 00 00 00 00 00
Explanation:
I assume everything until 0x0008 is clear, if not let me know or look at the description of the LE Set Advertising Data Command in the spec. 0x12 is Advertising_Data_Length, i.e., the number of useful bytes that comes after (until the padding bytes). Now you have to insert the Advertising_Data, which is formatted as in Vol 3 Part C, Section 11, Fig. 11.1 of the spec. So, 0x11 is the length of the AD Structure. Then, 0x07 is the AD Type "Complete List of 128-bit Service Class UUIDs" (see here). Finally comes the UUID. Notice that everything is little endian.
Then send the LE Set Advertising Parameters Commands, for example:
hcitool -i hci0 cmd 0x08 0x0006 00 08 00 08 00 00 00 00 00 00 00 00 00 07 00
Then enable advertising by sending the LE Advertising Enable command:
hcitool -i hci0 cmd 0x08 0x000A 01
See btmon output here.

BlueZ, How to turn off br/edr without using btmgmt?

I'm new to Bluetooth and BlueZ, I was working on a BLE project using BlueZ, for some reason I cannot use btmgmt -i hci0 bredr off command to turn off br/edr. I was wondering how to turn of br/edr using hcitool or any other util provided by BlueZ. Thanks in advance.
After a few days reading some question on Stackoverflow and reading Bluetooth specification. I finally found a way to use hcitool to do it. The command is
hcitool -i hci0 cmd 0x08 0x0008 12 02 01 04 02 0A 0C 0B
where 01 04 is the key 01 referred to the flag, 04 referred to bredr not supported. Thank u all.

How do we get RSSI values from Bluetooth beacons (estimote to be specific) in Linux?

I need to get distances from multiple bluetooth beacons for triangulation so that I can do indoor positioning.
I have tried to give as many relevant details as possible. This project is for an RPi, but I am currently trying to test it through my laptop first. I have tried most of what I can find on the internet about this:
The best way I could find to get the rssi values was hcitool rssi <address of beacon>
From here Bluetooth LE Signal Strength Linux
To test this, I tried to get it for my mobile first. It showed "Not Connected". I thought I need to connect first, so I tried many ways to connect my mobile:
a) hcittol cc <address of mobile>
b) gatttool -b <address of mobile> -t random --interactive
c) rfcomm connect 0 <address of mobile> 10
In each case, when I clicked pair in my mobile, connection terminated.
Then, I paired my mobile the usual way from bluetooth menu, and then tried hcitool rssi <Address of mobile> which then finally returned a value -8.
Now that I had it for my mobile, I now moved to beacons.
Then, I tried the same for my beacons. This time I had to
first do hcitool lescan to get addresses of available beacons
then connect to one of the beacons using the command hcitool lecc <address of beacon> which returned the error Could not create connection: Connection timed out
So next, I again tried connecting with the other two ways:
rfcomm connect 0 <address of beacon> 10 which returned the error Can't connect RFCOMM socket: Host is down when I can be sure hci0 was up.
Then I tried with sudo gatttool -b F1:15:A7:E3:17:63 --interactive after which interactive mode opened up and I gave the command connect. This gave different errors after Attempting to connect to <address of beacon>,
mainly connect error : Connection timed out
and Error: connect error: Connection refused (111)
Then I read I need to use -t random from Bluetooth LE on Raspbian , https://ubuntuforums.org/showthread.php?t=2204808 and one another source which I can't find right now.
So I entered sudo gatttool -b F1:15:A7:E3:17:63 -t random --interactive in which when I gave the connect command, I got error Error: connect error: Device or resource busy (16) and also sometimes Error: connect error: Input/Output Error
then I read that I perhaps need to restart my hci0 by hciconfig hci0 down and then hciconfig hci0 up which did the trick, the beacon now got connected.
But then, it quickly got disconnected after saying `GLib-WARNING **: Invalid file descriptor.
`
I read here https://raspberrypi.stackexchange.com/questions/53982/how-to-fix-gatttools-glib-warning-invalid-file-descriptor that this is because of poor connections. I tried keeping the beacons closer, but it did the same.
So I tried to anyway at least get one rssi value during the short duration it is connected. But, even when it was thus connected, I did hcitool rssi <address of beacon> the error came like this:
hcitool rssi F1:15:A7:E3:17:63
Get connection info failed: No such file or directory
To which I haven't yet found a proper solution.
I tried another way of reading the rssi value, which gave the following :
hcidump -R
HCI sniffer - Bluetooth packet analyzer ver 5.37
device: hci0 snap_len: 1500 filter: 0xffffffffffffffff
> 04 0E 04 01 0B 20 00
> 04 0E 04 01 0C 20 00
> 04 0E 04 01 0C 20 00
> 04 0F 04 00 01 0D 20
> 04 0F 04 00 01 16 20
> 04 0F 04 00 01 13 20
This was before it got disconnected.
I read here Obtain RSSI with hcidump which said to read the 14th byte. since all these seemed to be hex numbers, this would mean that each number is 1 byte. But this way, I only have 7 numbers per line, how can I read the 14th byte?
Getting distance from beacons has been troubling me a lot, and has used up a a lot of my time. Please help me out on this issue. If you can help me find a resource to help me do so, I'd appreciate the help.
You don't need to connect to a device to get the signal strength RSSI values, just use the following code and pipe that to a script that extracts values from the devices you are after:
btmon &
hcitool lescan --duplicates

Using hcitool to set ad packets

There is a well known blog post going around on how to set a usb bluetooth 4 dongle to be an iBeacon. It boils down to this magical command:
sudo hcitool -i hci0 cmd 0x08 0x0008 1e 02 01 1a 1a ff 4c 00 02 15 e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 00 00 00 00 c5 00 00 00 00 00 00 00 00 00 00 00 00 00
The issue with this example is that it is so opaque it's hard to use it in any more general format. I've been able to break it apart a bit:
sudo hcitool -i hci0 cmd
sends an hci command to the hci0 device
0x08 0x0008
is just magic to set the ad package, other stackoverflow commands have said "just use it, don't ask
1e
is the length of the ENTIRE following data packet in bytes
02 01 1a 1a
Are flags to set up the ad packet (details on request)
ff 4c 00 ...
is the 'company specific data' that encodes the iBeacon info
What I've tried to do is replace the "FF ..." bytes with the opcodes for setting the NAME parameter "04 09 41 42 43" (which should set it to ABC) but that doesn't work.
I'm surprised the hcitool doesn't give us some examples on how to set the ad packet as this would be very useful in setting all sorts of other params (like TEMP or POWER). Has anyone else had any experience in using hcitool to set things like NAME?
Late reply, but somebody might find this useful. I found it as I was looking around for solutions myself when using hcitool.
If you use hcitool cmd --help it will tell you something like this cmd <ogf> <ocf> .... It helps to look at the Bluetooth Core Specification to find out what 0x08 and 0x0008 would be for OGF and OCF. Specifically Vol. 2, Part E, 7.8
For the LE Controller Commands, the OGF code is defined as 0x08
and for the OCF of 0x0008
Advertising_Data_Length, Advertising_Data
So basically, with 0x08 0x0008 you say you are setting (in the LE Controller) the length of the data that is sent. As for the name, since the length of the BLE advertisement packet is 31 bytes (1E), you need to send the whole 31 bytes. So if you only have ABC as the name, setting 04 09 41 42 43 is correct, but that's only five bytes. For 31 you need to add 00 26 times. Just be careful you don't add too much or too little.
Also, I wasn't under the impression that BLE ad. packets are of fixed 31 byte size, but they are at least for hcitool. It doesn't work when you specifically set the outgoing size to something smaller than 1E.
No. None of this answers is correct and clean.
1) BLE have a separate command set. "LE Set Advertising Data" command must be used (see 7.8.7 vol 2 part E).
2) LE Set Advertising Data is much complex than what explained above. There are at least 2 1-octet length fields, packet must be 32 bytes length, zero padded, but the first length byte must not be 0x1e (31) but the length of the significant used part, containing one or more headers. Each header still contains a length, one AS Type byte (0x09 for set local name) and the name.
SET LE LOCAL NAME:
hciconfig hci0 down
hciconfig hci0 up
hcitool -i hci0 cmd 0x08 0x0008 0c 0b 09 6c 69 6e 6b 6d 6f 74 69 6f 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
hciconfig hci0 leadv 0
0x0c : length of the following group of headers
0x0b : length of this header
0x09 : AD Type for complete name
rest 0x0a length is the name
Check out this answer to a similar question. It basically describes how you can download the giant Bluetooth Core Spec document, and read through all the commands that it offers you. You can use the hcitool command to execute any of these commands if you can just figure out the right format (and figure out what the commands actually do!)
Major caveat: I have not tried setting the name myself, but glancing at the spec, it looks like this is described on page 482 of the spec in section "7.3.11 Write Local Name Command". According to this the command consists of:
OCF: 0x0013
Name (up to 248 bytes)
So I would try a command like this:
hcitool -i hci0 cmd 0x08 0x0013 41 42 43
One other tip: When you issue commands like this, try running hcidump & so the command executes in the background. Then, you can enter experimental hcitool commands (or even hciconfig commands) and see annotated details about what (human readable) commands executed and what errors occurred, if any.
Using the above tip, you can also try executing hciconfig name abc to set the local name using that command line tool, while you are executing a hcidump & in the background. This should show you the proper hcitool command values to use.
It would appear you need to use two commands rather than one. The iBeacon data is contained in the "LE Set Advertising Data" data and has been mentioned elsewhere in this post. To see a BLE friendly name you can use an additional command "LE Set Scan Response Data", this requires the receiver to scan your device (rather than passively read the advertising packet). So you can combine Angelo's example with this one to set the device as an iBeacon and set the "friendly name" which is the Scan Response data
sudo hcitool -i hci0 cmd 0x08 0x0008 1E 02 01 1A 1A FF 4C 00 02 15 E2 0A 39 F4 73 F5 4B C4 A1 2F 17 D1 AD 07 A9 61 00 00 00 00 C8 00
sudo hcitool -i hci0 cmd 0x08 0x0009 0c 0b 09 6c 69 6e 6b 6d 6f 74 69 6f 6e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
This worked for me using an Ubuntu box with a BLE dongle and then scanning for the beacon using this android BLE scanning app

Resources