目录
- LBS服务介绍
- 实现过程
以创建LBS服务为例,在蓝牙标准里面没有这个服务,但是nordic有定制这个服务。
LBS服务介绍
实现过程
- 定义 GATT 服务及其特性的 128 位 UUID。包括服务UUID,特征的UUID。
#define BT_UUID_LBS_VAL BT_UUID_128_ENCODE(0X00001523,0X1212,0XEFDE,0x1523,0x785feabcd123)
/** @brief Button Characteristic UUID. */
#define BT_UUID_LBS_BUTTON_VAL \
BT_UUID_128_ENCODE(0x00001524, 0x1212, 0xefde, 0x1523, 0x785feabcd123)
/** @brief LED Characteristic UUID. */
#define BT_UUID_LBS_LED_VAL \
BT_UUID_128_ENCODE(0x00001525, 0x1212, 0xefde, 0x1523, 0x785feabcd123)
- 创建服务并将其添加到蓝牙 LE 堆栈。
通过宏BT_GATT_SERVICE_DEFINE()静态创建和添加服务
BT_GATT_SERVICE_DEFINE(my_lbs_svc,
BT_GATT_PRIMARY_SERVICE(BT_UUID_LBS),
);
创建并添加自定义按钮特征。
BT_GATT_CHARACTERISTIC(BT_UUID_LBS_BUTTON,
BT_GATT_CHRC_READ,
BT_GATT_PERM_READ, read_button, NULL,
&button_state),
创建自定义LED特征
BT_GATT_CHARACTERISTIC(BT_UUID_LBS_LED,
BT_GATT_CHRC_WRITE,
BT_GATT_PERM_WRITE,
NULL, write_led, NULL),
实现上面的read_button和write_led函数。
回调函数的函数签名是有固定格式的。bt_gatt_attr_read_func_t协议栈收到读取请求,会调用我们自己写的回调函数,回调函数会调用bt_gatt_attr_read ()返回数据给协议栈,然后协议栈发送数据出去。
static ssize_t read_button(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
void *buf,
uint16_t len,
uint16_t offset)
{
//get a pointer to button_state which is passed in the BT_GATT_CHARACTERISTIC() and stored in attr->user_data
const char *value = attr->user_data;
LOG_DBG("Attribute read, handle: %u, conn: %p", attr->handle,
(void *)conn);
if (lbs_cb.button_cb) {
// Call the application callback function to update the get the current value of the button
button_state = lbs_cb.button_cb();
return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
sizeof(*value));
}
return 0;
}
写LED的回调函数
static ssize_t write_led(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
const void *buf,
uint16_t len, uint16_t offset, uint8_t flags)
{
LOG_DBG("Attribute write, handle: %u, conn: %p", attr->handle,
(void *)conn);
if (len != 1U) {
LOG_DBG("Write led: Incorrect data length");
return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
}
if (offset != 0) {
LOG_DBG("Write led: Incorrect data offset");
return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
}
if (lbs_cb.led_cb) {
//Read the received value
uint8_t val = *((uint8_t *)buf);
if (val == 0x00 || val == 0x01) {
//Call the application callback function to update the LED state
lbs_cb.led_cb(val ? true : false);
} else {
LOG_DBG("Write led: Incorrect value");
return BT_GATT_ERR(BT_ATT_ERR_VALUE_NOT_ALLOWED);
}
}
return len;
}
完整代码
运行测试