Bluetooth Implementation
Initialization
Initialize the Bluetooth subsystem using bt_init()
. Caller shall
be either task or a fiber. Caller must ensure that function succeeds by
checking return code for errors.
APIs
The following Bluetooth APIs are provided:
bt_enable()
- Enables the Bluetooth subsystem.
bt_le_adv_start()
- Sets up advertisement, scans for data, and starts advertising.
Bluetooth Application Example
A simple Bluetooth beacon application is shown below. The application initializes a Bluetooth Subsystem and enables non-connectable advertising. It acts as a Bluetooth Low Energy broadcaster.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | #include <stdint.h>
#include <stddef.h>
#include <misc/printk.h>
#include <misc/util.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#define DEVICE_NAME "Test beacon"
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
/*
* Set Advertisement data. Based on the Eddystone specification:
* https://github.com/google/eddystone/blob/master/protocol-specification.md
* https://github.com/google/eddystone/tree/master/eddystone-url
*/
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0xaa, 0xfe),
BT_DATA_BYTES(BT_DATA_SVC_DATA16,
0xaa, 0xfe, /* Eddystone UUID */
0x10, /* Eddystone-URL frame type */
0x00, /* Calibrated Tx power at 0m */
0x00, /* URL Scheme Prefix http://www. */
'z', 'e', 'p', 'h', 'y', 'r',
'p', 'r', 'o', 'j', 'e', 'c', 't',
0x08) /* .org */
};
/* Set Scan Response data */
static const struct bt_data sd[] = {
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};
static void bt_ready(int err)
{
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return;
}
printk("Bluetooth initialized\n");
/* Start advertising */
err = bt_le_adv_start(BT_LE_ADV_PARAM(BT_LE_ADV_SCAN_IND,
BT_LE_ADV_ADDR_NRPA,
BT_GAP_ADV_FAST_INT_MIN_2,
BT_GAP_ADV_FAST_INT_MAX_2),
ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (err) {
printk("Advertising failed to start (err %d)\n", err);
return;
}
printk("Beacon started\n");
}
#ifdef CONFIG_MICROKERNEL
void mainloop(void)
#else
void main(void)
#endif
{
int err;
/* Initialize the Bluetooth Subsystem */
err = bt_enable(bt_ready);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
}
}
|
Testing with QEMU
A Bluetooth application might be tested with QEMU. In order to do so, a Bluetooth controller needs to be connected to the emulator.
Using Host System Bluetooth Controller in QEMU
The host system’s Bluetooth controller is connected to the second QEMU
serial line using a UNIX socket. This socket employs the QEMU option
-serial unix:/tmp/bt-server-bredr
. This option is already
added to QEMU through QEMU_EXTRA_FLAGS in the Makefile.
On the Host side, BlueZ allows to “connect” Bluetooth controller through a so-called user channel.
Use the btproxy tool to open the listening UNIX socket, type:
$ sudo tools/btproxy -u Listening on /tmp/bt-server-bredr
Note
Ensure that the Bluetooth controller is down before using the btproxy command.
To run Bluetooth application in the QEMU, go to application folder and type:
$ make qemu
Note
Bluetooth sample applications are located in
samples/bluetooth
folder.
Running QEMU now results in a connection with the second serial line to
bt-server-bredr
UNIX socket.
Now, an application can use the Bluetooth device.