Once we setting bluetooth low energy(BLE) advertising, we would want to setting this beacon being connectable. The clients (like phone, computer) could read/upload data to/from that.
That applying is very wide: for example, the all-day heartbeat measurer in current, the sensors and recorder are connected physicallly as one device. The patient will feel it is not comfortable when he carry it (Just like carry urine bag but smaller) . If the manufacturer of heartbeat measurer introduce BLE technology, the recorder could be indenpendent device.
The connection between recorder and sensors is wireless. It is not necessary to carry recorder like shoulder bag all day, it could be put in desk.
Why not apply classical bluetooth for that goal ? For classical bluetooth spends too much energy, mercury battery could not afford such costing.
Ok, for our major issue: setting gatt service in linux.
In my environment, I use fedora 21 + bluez 5.
If dbus version of your linux distribution is lower than 1.6, you should use bluez 4.
DO NOT force upgrading your dbus version to 1.6, unless you know what you do.
The gatt service warm-up be the follow steps:
0. Download and untar the bluez package from bluez
(Use tar Jxvf XXX.tar.xz to uncompress file)
1. Build bluez on your computer.
For me, the configure parameters of bluez are:
./configure CFLAGS="$CFLAGS -Wno-sign-compare" --disable-udev --prefix=$PWD/built --enable-experimental --enable-maintainer-mode
The --enable-experimental and --enable-maintainer-mode set gatt-service example being included into compilation. and --disable-udev is for avoiding configuration error(and the udev module is useless for me). CFLAGS="$CFLAGS -Wno-sign-compare" set compiler to ignore sign/unsigned warning (the Makefile of Bluez set compiler to treat warning as error!).
2. Run the bluetoothd program, which is under src folder of bluez
The bluetoothd is a daemon program to manage all bluetooth device and (maybe all) service.
Once we have built this bluez, we could run the sbluetoothd as test.
But before the running, we should stop the one bluetoothd which has been run:
sudo killall -9 bluetoothd
we could read the help of bluetoothd.
[gaiger@localhost src]$ ./bluetoothd -h Usage: bluetoothd [OPTION...] Help Options: -h, --help Show help options Application Options: -d, --debug=DEBUG Specify debug options to enable -p, --plugin=NAME,.., Specify plugins to load -P, --noplugin=NAME,... Specify plugins not to load -C, --compat Provide deprecated command line interfaces -E, --experimental Enable experimental interfaces -n, --nodetach Run with logging in foreground -v, --version Show version information and exit
I note here : the -d argument would make the output be tedeious, and the -n argument would make the programming running on the front-end.
What is plugin? those are gatt service (example) which have been included in bluez.
Check the files under profiles and plugin, we could watch what service bluez have done:
[gaiger@localhost src]$ ls ../profiles/ alert cyclingspeed health input sap time audio deviceinfo heartrate network scanparam cups gap iap proximity thermometer
[gaiger@localhost src]$ ls ../plugins/*.c ../plugins/autopair.c ../plugins/hostname.c ../plugins/sixaxis.c ../plugins/external-dummy.c ../plugins/neard.c ../plugins/wiimote.c ../plugins/gatt-example.c ../plugins/policy.c
Now we try to enable the timer service in bluetoothd:
[gaiger@localhost src]$ sudo ./bluetoothd --plugin=time -n bluetoothd: Bluetooth daemon 5.27 bluetoothd: Starting SDP server bluetoothd: Ignoring (cli) hostname bluetoothd: Ignoring (cli) wiimote bluetoothd: Ignoring (cli) autopair bluetoothd: Ignoring (cli) policy bluetoothd: Ignoring (cli) gatt_example bluetoothd: Ignoring (cli) neard bluetoothd: Ignoring (cli) sap bluetoothd: Ignoring (cli) a2dp bluetoothd: Ignoring (cli) avrcp bluetoothd: Ignoring (cli) network bluetoothd: Ignoring (cli) input bluetoothd: Ignoring (cli) hog bluetoothd: Ignoring (cli) health bluetoothd: Ignoring (cli) gap bluetoothd: Ignoring (cli) scanparam bluetoothd: Ignoring (cli) deviceinfo bluetoothd: Ignoring (cli) alert bluetoothd: Ignoring (cli) proximity bluetoothd: Ignoring (cli) thermometer bluetoothd: Ignoring (cli) heartrate bluetoothd: Ignoring (cli) cyclingspeed bluetoothd: Ignoring (cli) external_dummy bluetoothd: Bluetooth management interface 1.7 initialized
Then run the script I have provided in the last article, we could use BLE scanner (android's app) to detect this service.
Now we know that is a good example for us to set a gatt service.
Take look at the time service code, in profiles/time/server.c (buttom):
The declaration of macro BLUETOOTH_PLUGIN_DEFINE be
(in src/plugin.h). it is , to define what function is for initialization(entrance), what is for exit. As this example, the entrance and exit are just for setting/un-setting structure btd_profile, the structure are for customizing gatt service distinctly.
The structure btd_profile has 3 member, are name, service_init and service_exit, respectively.
Now look at the function time_server_init , time_server_exit and relative functions in the same file:
That is very obvious:
The function time_server_init register 2 service : register_current_time_service and register_ref_time_update_service. In the function register_current_time_service, the code call the function bt_uuid16_create with uuid REF_TIME_UPDATE_SVC_UUID to create a service, and add 2 characteristic CT_TIME_CHR_UUID and LOCAL_TIME_INFO_CHR_UUID by calling function gatt_service_add which be added function local_time_info_read and current_time_read. In these pointed function, the data be sent by calling function attrib_db_update.
bt_uuid16_create : create service.
gatt_service_add: set characteristic and set function pointer corresponding the characteristic.
attrib_db_update: sent data to client.
The functions are declared in src/plugin.h and attrib/gatt-service.h:
You could refer to the other gatt service example, I recommend plugins/gatt-example.c.
If you want to customize your gatt service, It is complicated to create a whole new one but without changing original example: it is hard to modify Makefile files! Just backup and modify the plugins/wiimote.c file, It maybe be the most useless one for being refered.
NOTE : If you want to know more detailedly about how to implement or modify a gatt-server ( peripheral) as yours, please read the article written by me, which is the sequel of this one.