Resuming from last article , I modify the bluez code to be a simple peripheral (GATT server).
Step 0.
download the last bluez .
and
Step 1.
use the parameters to configurate it.
[email protected]:~/sandbox/bluez-5.32/src$./configure --enable-experimental --enable-maintainer-mode --prefix=$PWD/built CFLAGS="$CFLAGS -Wno-sign-compare -Wno-unused-function"
If you encounter some error like that :
configure: error: libical is required
or
checking for UDEV... no configure: error: libudev >= 172 is required
just install those libraries. I note here, in fedora, the libudev has been included in systemd package, you should use that command line:
[email protected]:~/sandbox/bluez-5.32/src$sudo yum install systemd-devel
To install libudev-dev.
After configuration has been done, the building should be passed without error.
Step2.
Stop current bluetoothd program:
In fedora :
[email protected]:~/sandbox/bluez-5.32/src$sudo killall -p bluetoothd
In Ubuntu :
[email protected]:~/sandbox/bluez-5.32/src$sudo service bluetooth status bluetooth start/running, process 2619 [email protected]:~/sandbox/bluez-5.32/src$ sudo service bluetooth stop bluetooth stop/waiting
Then, goto the src folder under your bluez package, and execute that:
[[email protected] src]$ sudo ./bluetoothd -p xx -n
If the output log be :
bluetoothd[12465]: Bluetooth daemon 5.30 bluetoothd[12465]: Starting SDP server bluetoothd[12465]: Bluetooth management interface 1.7 initialized bluetoothd[12465]: Failed to obtain handles for "Service Changed" characteristic bluetoothd[12465]: Failed to register org.bluez.LEAdvertisingManager1 bluetoothd[12465]: Failed to register LEAdvertisingManager1 interface for adapter bluetoothd[12465]: Not enough free handles to register service bluetoothd[12465]: gatt-example-adapter-driver: Input/output error (5) bluetoothd[12465]: Not enough free handles to register service bluetoothd[12465]: Error adding Link Loss service bluetoothd[12465]: Not enough free handles to register service bluetoothd[12465]: Not enough free handles to register service bluetoothd[12465]: Not enough free handles to register service bluetoothd[12465]: Current Time Service could not be registered bluetoothd[12465]: gatt-time-server: Input/output error (5) bluetoothd[12465]: Not enough free handles to register service bluetoothd[12465]: Not enough free handles to register service bluetoothd[12465]: Sap driver initialization failed. bluetoothd[12465]: sap-server: Operation not permitted (1) bluetoothd[12465]: Endpoint registered: sender=:1.122 path=/MediaEndpoint/A2DPSource bluetoothd[12465]: Endpoint registered: sender=:1.122 path=/MediaEndpoint/A2DPSink
That is, the gatt-server start fall. The only solution I know currently, is to use the Bluez version which is not later than
5.28. please back to Step 0, use version 5.28 and do all again.
if your result be :
[[email protected] src]$ sudo ./bluetoothd -p xx -n bluetoothd[31541]: Bluetooth daemon 5.28 bluetoothd[31541]: Starting SDP server bluetoothd[31541]: Ignoring (cli) hostname bluetoothd[31541]: Ignoring (cli) wiimote bluetoothd[31541]: Ignoring (cli) autopair bluetoothd[31541]: Ignoring (cli) policy bluetoothd[31541]: Ignoring (cli) gatt_example bluetoothd[31541]: Ignoring (cli) neard bluetoothd[31541]: Ignoring (cli) sap bluetoothd[31541]: Ignoring (cli) a2dp bluetoothd[31541]: Ignoring (cli) avrcp bluetoothd[31541]: Ignoring (cli) network bluetoothd[31541]: Ignoring (cli) input bluetoothd[31541]: Ignoring (cli) hog bluetoothd[31541]: Ignoring (cli) health bluetoothd[31541]: Ignoring (cli) gap bluetoothd[31541]: Ignoring (cli) scanparam bluetoothd[31541]: Ignoring (cli) deviceinfo bluetoothd[31541]: Ignoring (cli) alert bluetoothd[31541]: Ignoring (cli) time bluetoothd[31541]: Ignoring (cli) proximity bluetoothd[31541]: Ignoring (cli) thermometer bluetoothd[31541]: Ignoring (cli) heartrate bluetoothd[31541]: Ignoring (cli) cyclingspeed bluetoothd[31541]: Ignoring (cli) external_dummy bluetoothd[31541]: Bluetooth management interface 1.7 initialized
Congratulation, you could go below.
Step 3.
Excute the command :
[[email protected] src]$ sudo ./bluetoothd -p gatt_example -n
And run this script, bleAdvertise:
#!/bin/bash # ref: http://www.theregister.co.uk/Print/2013/11/29/feature_diy_apple_ibeacons/ set -x # inquiry local bluetooth device #hcitool dev export BLUETOOTH_DEVICE=hci0 #sudo hcitool -i hcix cmd <OGF> <OCF> <No. Significant Data Octets> <iBeacon Prefix> <UUID> <Major> <Minor> <Tx Power> <Placeholder Octets> #OGF = Operation Group Field = Bluetooth Command Group = 0x08 #OCF = Operation Command Field = HCI_LE_Set_Advertising_Data = 0x0008 #No. Significant Data Octets (Max of 31) = 1E (Decimal 30) #iBeacon Prefix (Always Fixed) = 02 01 1A 1A FF 4C 00 02 15 export OGF="0x08" export OCF="0x0008" #export IBEACONPROFIX="1E 02 01 1A 1A FF 4C 00 02 15" export IBEACONPROFIX="1E 02 01 16 1A FF 4C 00 02 15" #uuidgen could gerenate uuid export UUID="4a 4e ce 60 7e b0 11 e4 b4 a9 08 00 20 0c 9a 66" #export UUID="B9 40 7F 30 F5 F8 46 6E AF F9 25 55 6B 57 FE 6D" #export UUID="76 E8 B4 E0 7E B5 11 E4 B4 A9 08 00 20 0C 9A 66" export MAJOR="00 01" export MINOR="00 00" export POWER="C5 00" initialize device sudo hciconfig $BLUETOOTH_DEVICE up # disable advertising sudo hciconfig $BLUETOOTH_DEVICE noleadv # stop the dongle looking for other Bluetooth devices sudo hciconfig $BLUETOOTH_DEVICE noscan sudo hciconfig $BLUETOOTH_DEVICE pscan #hciconfig $BLUETOOTH_DEVICE iscan #sudo hciconfig $BLUETOOTH_DEVICE name "i5-3210M "$BLUETOOTH_DEVICE sudo hciconfig $BLUETOOTH_DEVICE leadv # advertise sudo hcitool -i $BLUETOOTH_DEVICE cmd 0x08 0x0008 $IBEACONPROFIX $UUID $MAJOR $MINOR $POWER #sudo hcitool -i $BLUETOOTH_DEVICE cmd 0x08 0x0006 A0 00 A0 00 00 00 00 00 00 00 00 00 00 07 00 #sudo hcitool -i $BLUETOOTH_DEVICE cmd 0x08 0x000a 01 #sudo hciconfig $BLUETOOTH_DEVICE leadv #sudo hciconfig $BLUETOOTH_DEVICE pscan echo "complete"
You should be able to use your moblie appication (BLE scanner for android, LightBlue for iOS)
to scan and connect to this Bluez peripheral.
That Shows the bluez gatt-server works.
Step 4.
Backup the plugin/wiimote.c , and replace that as below code completely:
/* * * BlueZ - Bluetooth protocol stack for Linux * * Copyright (C) 2011-2012 David Herrmann <[email protected]> * * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifdef HAVE_CONFIG_H #include <config.h> #endif #include <unistd.h> #include <stdbool.h> #include <bluetooth/bluetooth.h> #include <glib.h> #include "lib/uuid.h" #include "src/plugin.h" #include "src/adapter.h" #include "src/shared/util.h" #include "src/log.h" #include "attrib/gattrib.h" #include "attrib/gatt-service.h" #include "attrib/att.h" #include "attrib/gatt.h" #include "attrib/att-database.h" #include "src/attrib-server.h" #define MAX_STR_LEN (256) #define SIMPLE_SVC_UUID 0xfff0 #define SIMPLE_READ1_CHAR_UUID 0xfff1 #define SIMPLE_READ2_CHAR_UUID 0xfff2 #define SIMPLE_WRITE_CHAR_UUID 0xfff3 #define SIMPLE_NOTIFY_CHAR_UUID 0xfff4 static char read1Data[MAX_STR_LEN]; static char read2Data[MAX_STR_LEN]; static int notifyData; static uint8_t SimpleCharacteristic1Read(struct attribute *a, struct btd_device *device, gpointer user_data) { struct btd_adapter *adapter; printf("__FILE__ = %s, __FUNCTION__ = %s, __LINE__ =%d\n", __FILE__, __FUNCTION__, __LINE__); adapter = user_data; attrib_db_update(adapter, a->handle, NULL, (uint8_t*)&read1Data[0], strlen(&read1Data[0]), NULL); return 0; }/*Characteristic1Read*/ static uint8_t SimpleCharacteristic2Read(struct attribute *a, struct btd_device *device, gpointer user_data) { struct btd_adapter *adapter; printf("__FILE__ = %s, __FUNCTION__ = %s, __LINE__ =%d\n", __FILE__, __FUNCTION__, __LINE__); adapter = user_data; attrib_db_update(adapter, a->handle, NULL, (uint8_t*)&read2Data[0], strlen(&read2Data[0]), NULL); return 0; }/*Characteristic2Read*/ static uint8_t SimpleCharacteristicWrite(struct attribute *a, struct btd_device *device, gpointer user_data) { unsigned char data[MAX_STR_LEN]; int i; printf("__FILE__ = %s, __FUNCTION__ = %s, __LINE__ =%d\n", __FILE__, __FUNCTION__, __LINE__); memset(&data[0], 0, MAX_STR_LEN); memcpy(&data[0], a->data, a->len); printf("written data : %s \n", &data[0]); for(i = 0; i< a->len;i++) printf("%#1x ", (unsigned char)(data[i])); printf("\n"); return 0; }/*CharacteristicWrite*/ static uint8_t SimpleCharacteristicNotify(struct attribute *a, struct btd_device *device, gpointer user_data) { struct btd_adapter *adapter; adapter = user_data; printf("__FILE__ = %s, __FUNCTION__ = %s, __LINE__ =%d\n", __FILE__, __FUNCTION__, __LINE__); do { attrib_db_update(adapter, a->handle, NULL, (uint8_t*)¬ifyData, sizeof(notifyData), NULL); //usleep(1*1000*1000); notifyData++; }while(0); return 0; }/*CharacteristicNotify*/ static void RegisterSimpleService(struct btd_adapter *adapter) { bt_uuid_t uuid; printf("__FILE__ = %s, __FUNCTION__ = %s, __LINE__ =%d\n", __FILE__, __FUNCTION__, __LINE__); bt_uuid16_create(&uuid, SIMPLE_SVC_UUID); gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid, /* characteristic register*/ /*read 1*/ GATT_OPT_CHR_UUID16, SIMPLE_READ1_CHAR_UUID, GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ , GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, SimpleCharacteristic1Read, adapter, /*read 2*/ GATT_OPT_CHR_UUID16, SIMPLE_READ1_CHAR_UUID, GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ , GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, SimpleCharacteristic2Read, adapter, /*write*/ GATT_OPT_CHR_UUID16, SIMPLE_WRITE_CHAR_UUID, GATT_OPT_CHR_PROPS, GATT_CHR_PROP_WRITE_WITHOUT_RESP, GATT_OPT_CHR_VALUE_CB, ATTRIB_WRITE, SimpleCharacteristicWrite, adapter, /*NOTIFY*/ GATT_OPT_CHR_UUID16, SIMPLE_NOTIFY_CHAR_UUID, GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ|GATT_CHR_PROP_NOTIFY, GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, SimpleCharacteristicNotify, adapter, /*end*/ GATT_OPT_INVALID); return ; }/*RegisterSimpleService*/ #define DEVICEINFO_SVC_UUID 0x180a char versionStr[MAX_STR_LEN] = "0.0.0"; char manufacturerStr[MAX_STR_LEN] = "Gaiger"; static uint8_t SoftwareRevisionStringRead(struct attribute *a, struct btd_device *device, gpointer user_data) { struct btd_adapter *adapter; printf("__FILE__ = %s, __FUNCTION__ = %s, __LINE__ =%d\n", __FILE__, __FUNCTION__, __LINE__); adapter = user_data; attrib_db_update(adapter, a->handle, NULL, (uint8_t*)&versionStr[0], strlen(&versionStr[0]), NULL); return 0; }/*SoftwareRevisionStringRead*/ static uint8_t ManufacturerStringRead(struct attribute *a, struct btd_device *device, gpointer user_data) { struct btd_adapter *adapter; printf("__FILE__ = %s, __FUNCTION__ = %s, __LINE__ =%d\n", __FILE__, __FUNCTION__, __LINE__); adapter = user_data; attrib_db_update(adapter, a->handle, NULL, (uint8_t*)&manufacturerStr[0], strlen(&manufacturerStr[0]), NULL); return 0; }/*ManufacturerStringRead*/ static void RegisterDeviceInfo(struct btd_adapter *adapter) { bt_uuid_t uuid; printf("__FILE__ = %s, __FUNCTION__ = %s, __LINE__ =%d\n", __FILE__, __FUNCTION__, __LINE__); bt_uuid16_create(&uuid, DEVICEINFO_SVC_UUID); gatt_service_add(adapter, GATT_PRIM_SVC_UUID, &uuid, /* characteristic register*/ /*GATT_CHARAC_SOFTWARE_REVISION_STRING*/ GATT_OPT_CHR_UUID16, GATT_CHARAC_SOFTWARE_REVISION_STRING, GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ , GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, SoftwareRevisionStringRead, adapter, /*GATT_CHARAC_MANUFACTURER_NAME_STRING*/ GATT_OPT_CHR_UUID16, GATT_CHARAC_MANUFACTURER_NAME_STRING, GATT_OPT_CHR_PROPS, GATT_CHR_PROP_READ , GATT_OPT_CHR_VALUE_CB, ATTRIB_READ, ManufacturerStringRead, adapter, /*end*/ GATT_OPT_INVALID); return ; }/*RegisterSimpleService*/ static void update_name(struct btd_adapter *adapter, gpointer user_data) { adapter_set_name(adapter, (char*)user_data); }/*update_name*/ static int wii_probe(struct btd_adapter *adapter) { update_name(adapter, "SimplePeripherial"); RegisterDeviceInfo(adapter); RegisterSimpleService(adapter); return 0; }/*wii_probe*/ static void wii_remove(struct btd_adapter *adapter) { }/*wii_remove*/ /*function pointers*/ static struct btd_adapter_driver wii_driver = { .name = "wiimote", .probe = wii_probe, .remove = wii_remove, }; static int wii_init(void) { printf("__FUNCTION__ = %s\n", __FUNCTION__); memset(&read1Data[0], 0, MAX_STR_LEN); memset(&read2Data[0], 0, MAX_STR_LEN); notifyData = 0; snprintf(&read1Data[0], MAX_STR_LEN, "it is read 1"); snprintf(&read2Data[0], MAX_STR_LEN, "it is read 2"); return btd_register_adapter_driver(&wii_driver); } static void wii_exit(void) { printf("__FUNCTION__ = %s\n", __FUNCTION__); btd_unregister_adapter_driver(&wii_driver); } BLUETOOTH_PLUGIN_DEFINE(wiimote, VERSION, BLUETOOTH_PLUGIN_PRIORITY_LOW, wii_init, wii_exit)
And re-compiler the bluez library (you could just delete plugins/bluetoothd-wiimote.o and
type make again to boost the compilation time).
Step 5.
Similar with Step 3
Execute the command line under src folder:
[[email protected] src]$ sudo ./bluetoothd -p wiimote -n
And Run the BleAdvertise script again : you may need to run it twice, to ensure that has
been executed indeedly.
Now you could use your BLE Scanner or LightBlue to confirm your Pheripheral has been run:
Known Insuffiecient :
If a central device (moblie) access the Notify characteristic, the bluez peripheral would be led to crash.
After the disconneciton event occurs, the Bluez perihpheral would not start again, it is,
You need to run the BleAdvertise script again.
版权声明:本文为博主原创文章,未经博主允许不得转载。