54
  • Goal: Use BlueZ and an Bluetooth 4LE dongle to create a peripheral that advertises the bluetooth equivalent of "Hello World".

  • Where I'm At: I've currently got the BlueZ stack setup and downloaded, I can use the hci tool to recognize and see the Bluetooth dongle. I've tinkered with hciconfig leadv but I'm just not quite getting it/understanding what's going on.

  • What Help I Think I Need: I need to get it to the next step. If anyone can either point me towards a good resource, walk me through this, or anything, It would be much appreciated. If I need to do additional leg(search)work I can but I've scoured Google and SO with as many different derivatives of this question as I can think of.

*I tagged this as CoreBluetooth as well in hopes that maybe an iOS dev has tinkered with this at some point.

EDIT: In response to a comment, It seems prudent to state what my end goal is. I'd ultimately like to advertise via the dongle the simplest of simple messages/signals and pick that up on an iOS device (CoreBluetooth). I've been able to get the iOS side of things working well (tons of documentation compared to the Linux side of things) but that hard part for me is getting this adapter setup as a peripheral. The BlueZ stack is a terrible enigma for me.

EDIT: After more digging, I eventually stumbled upon this post: Raspberry Pi Bluetooth 4.0 Connection. This has led me toward the topic of a GATT server, I'll continue pursuing this topic.

EDIT: Alright so my quest for learning goes on. Over the past couple of days I've dived deeper into the hci*, sdptool, and gatttool tools. I've gotten to the point of being able to set the adapter to advertise, "hciconfig hci0 leadv". At this point, I can successfully "see" the adapter, but I cannot actually read anything off of it. I'm not even seeing the friendly name. I'll keep trucking on but as always, any help/suggestions are more than welcome.

EDIT: Relevant Link, solid overview of Bluetooth LE pertaining to iOS. https://developer.apple.com/library/content/documentation/NetworkingInternetWeb/Conceptual/CoreBluetooth_concepts/AboutCoreBluetooth/Introduction.html#//apple_ref/doc/uid/TP40013257-CH1-SW1

LAST EDIT: Hey all, this link covers how to create an iBeacon using a Raspberry Pi + BlueZ... http://www.wadewegner.com/2014/05/create-an-ibeacon-transmitter-with-the-raspberry-pi/

Cœur
  • 37,241
  • 25
  • 195
  • 267
Ceryni
  • 704
  • 1
  • 7
  • 14
  • How are you managing the other side (receiving advertisements)? If you have two dongles, then you'd do `hciconfig leadv` on slave device and `hcitool lescan` on the master device. – TJD Apr 22 '13 at 18:26
  • Ultimately, I want to manage central through an iOS device. The end game would be to have the dongle advertising some basic message and the iOS device picking it up and displaying it. Hopefully this adds clarification. – Ceryni Apr 23 '13 at 14:32
  • 1
    @Fitzeryni have you made any further progress on this? I am similarly trying to use BlueZ 5 on a Raspberry Pi to advertise a Bluetooth LE service for iOS devices to leverage. – Matt Jun 01 '13 at 18:39
  • @Matt, Unfortunately, I haven't made anymore progress on this and I'm currently no longer pursuing it. As far as advertising for an iOS device to leverage, this was the exact use case I was aiming at. I was able to get to the point of having my iOS device "see" the Pi's adapter, but I was unable to connect or retrieve any data from the signal. I wish you the best of luck, BlueZ is not for the faint of heart. I'll leave this link here as well though: http://www.ti.com/ww/en/wireless_connectivity/sensortag/index.shtml?DCMP=sensortag&HQS=sensortag-bn I've had great success using this device. – Ceryni Jul 01 '13 at 17:43
  • 1
    Last link is dead ;) – vanthome Sep 23 '14 at 06:19
  • Thanks @vanthome. Found a new link that I put in its place. – Ceryni Sep 15 '15 at 17:41

2 Answers2

43

With your Bluetooth dongle plugged in, running the following command will tell you the device name and give its state:

$ hciconfig

The output should look something like this:

hci0:    Type: BR/EDR  Bus: USB
     BD Address: 00:01:02:aa:bb:cc  ACL MTU: 1021:8  SCO MTU: 64:1
     DOWN
     RX bytes:1000 acl:0 sco:0 events:47 errors:0
     TX bytes:1072 acl:0 sco:0 commands:47 errors:0

This indicates the device is called hci0 is in a down state. Issue the following command to bring it up:

$ sudo hciconfig hci0 up

Now it should look like:

$ hciconfig
hci0:   Type: BR/EDR  Bus: USB
     BD Address: 00:01:02:aa:bb:cc  ACL MTU: 1021:8  SCO MTU: 64:1
     UP RUNNING
     RX bytes:1000 acl:0 sco:0 events:47 errors:0
     TX bytes:1072 acl:0 sco:0 commands:47 errors:0

Next, execute the following example command to configure the advertising data to be sent.

$ 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

You can change the hex bytes (starting with 1e) to send different byte sequences for your advertisement. One that literally sends the ASCII codes for "HELLO WORLD" would use: 48 45 4c 4c 4f 57 4f 52 4c 44 (EDIT: But you will also have to prefix this message with a valid header, see here.)

Now, use the following command to activate advertising on the dongle, this will start sending "Helo World" packets.

$ sudo hciconfig hci0 leadv 0

EDIT: the above command makes the advertised service connectable. If you don't want to allow connections, change it to $ sudo hciconfig hci0 leadv 3

You can also disable advertising using the following command:

$ sudo hciconfig hci0 noleadv

Community
  • 1
  • 1
davidgyoung
  • 63,876
  • 14
  • 121
  • 204
  • 2
    This is a really good break down of how to start advertising. I'm accepting this as it answers the original question. But for sake of completeness, Could you outline how to then pick up the advertising message using another device/dongle pair? – Ceryni Oct 03 '13 at 17:14
  • Sorry, I actually have never done this, so I do not know the details. All my reading of advertisements has been with iOS and Android bluetooth APIs. – davidgyoung Oct 27 '13 at 02:05
  • Potentially dumb question: What is the meaning of the "1e 02 01 1a 1a ff"? – Mark Peterson Nov 12 '13 at 20:39
  • That's the preamble to Apple's iBeacon advertisement, which is what I was trying to build when I figured out how to do this. – davidgyoung Nov 13 '13 at 00:15
  • I am a little confused with the iBeacon protocol and what you have said here...you said that `you can change the hex bytes (starting with 1e)`, but by doing this, wouldnt that break the iBeacon protocol since you are removing the Apple iBeacon preamble? Im just confused about where exactly your custom text, like "hello world" would sit in that set of advertising data. – Mark Dec 18 '13 at 02:39
  • 3
    @Mark, yes, you are absolutely right that this would break the iBeacon preamble. The question above was asking how to send a Bluetooth LE advertisement (NOT an iBeacon advertisement) of "Hello World". So I showed him my code that creates an iBeacon advertisement and explained how he could change it to advertise "Hello World" instead. Make sense? – davidgyoung Dec 18 '13 at 04:14
  • @davidgyoung I don't know if this is a dumb question but, would then be possible to advertise the "Hello World" data as an iBeacon advertisement? Does any of the implementations have any pros or cons to look for said data on an iOS app? – jonathanwiesel Jan 14 '14 at 21:16
  • 2
    Well, I suppose you *could* embed the "Hello World" string inside the iBeacon identifiers, but this wouldn't be very useful on iOS. In order to "see" an iBeacon, an iOS app needs to first tell the OS the ProximityUUID (16 bytes) of the iBeacons that should be visible. So you really can't embed an unknown string in that field. This only leaves four bytes left in the major and minor fields. With 8-bit character encoding, this is enough for "Hell" but not enough for "Hello World" – davidgyoung Jan 14 '14 at 21:49
  • Thanks for the answer @davidgyoung, so in this case, how can I receive the BLE advertisement the way you demonstrated (not iBeacon one) with an iOS app without needing to pair or anything? – jonathanwiesel Jan 16 '14 at 22:18
  • 1
    Sorry, but you can't. Apple's CoreBluetooth APIs disallow access to the raw advertisement body. – davidgyoung Jan 16 '14 at 22:45
  • Tried to do exactly what you suggested, but when reading out the data (from another device) with a simple `hcidump --raw` I'm getting a 4 byte payload like `b2 0 0a 02` where the first byte changes about every second, instead of the one specified via `cmd`. Bluez 5.26, ideas? – marce Jan 31 '15 at 18:21
  • @marce, it is probably worth opening a new question on this, and show the exact commands you are using to start advertising. – davidgyoung Jan 31 '15 at 20:28
  • @davidgyoung [I did](http://stackoverflow.com/questions/28261029/wrong-payload-when-using-bluez-stack-as-peripheral) and found a/realized the difference to your approach as well. – marce Feb 01 '15 at 08:55
6

adding some more information here (ref BlueZ5.x):

  • bluez is not exposing DBUS api for gatt server registeration; you have some profile implementation available but you need to configure and compile it with --enable-experimental option or enable gatt-example under plugin folder tha tregister some gatt server as example

  • when you advertise doing hciconfig hci0 leadv pay attention to advertised data. in the example below for iBeacon

    sudo hcitool -i hci0 cmd 0x08 0x0008 1e **02 01 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 bolded part is for an AD structure that is releated to flags field (check under bluetooth spec for advertisgin data format). With this flags settings the device is advertising itself as simultaneous LE and BR-EDR.

    In my experience when advertising in this way an android device that scan the bluez device acting as BLE peripheral will trigger a connection over Classic bluetooth (due to flag settings) and not over BLE (note that connection procedures are different for LE and Classic). Not sure how Apple central device act in this case. Anyway to avoid it you may set 06 instead of 1A so that BR-EDR support isnot advertised. In this way you will see a connection over BLE.

If you want to test it using a central Android device there is a free Nordic app for that.

VMAtm
  • 27,943
  • 17
  • 79
  • 125
user3891941
  • 61
  • 1
  • 1