1.2. 蓝牙协议简介
1.2.1. GATT 简介
- 本章主要介绍基于完整GATT服务的主从收发接口(GATT_completion),该服务有以下特点:
基于标准的GATT协议,具有完整的GATT profile
从机支持HOGP协议,可连接手机或者其他主机设备
支持私有协议,支持修改广播包内容以及参数
支持多通道收发数据,通道由profile决定
1.2.2. GATT从机相关参数配置
- 以ble_hogp.c为例,其中参数:
ATT_LOCAL_MTU_SIZE:ATT发送包长
ADV_INTERVAL_MIN:未连接广播周期(unit:0.625ms)
hogp_connection_update_enable:从机使能参数请求更新控制
- Peripheral_Preferred_Connection_Parameters:连接参数表,可选择修改:
conn_interval:连接间隔(unit:1.25ms)
latency:连接延迟(unit:interval)
timeout:连接超时时间(unit:10ms)
#define ATT_LOCAL_MTU_SIZE (64)//mtu设置 #define ADV_INTERVAL_MIN (160 * 5)//普通未连接广播周期 (unit:0.625ms) static uint8_t hogp_connection_update_enable = 1;//是否使能参数请求更新,0--disable, 1--enable //从机连接主机参数表,当连接主机设备后打开参数请求更新后会按照此处连接参数更新 static const struct conn_update_param_t Peripheral_Preferred_Connection_Parameters[] = { //对应的参数为conn_interval_min,conn_interval_max,latency,timeout {6, 9, 100, 600}, //android /* {7, 7, 20, 300}, //mosue */ /* {20, 20, 20, 300}, //kb */ {12, 12, 30, 300}, //ios {6, 12, 30, 400},// ios fast };
- 值得注意的是:
对于
数据量大的场景:需要将ATT_LOCAL_MTU_SIZE设置为255,同时ATT_PACKET_NUMS_MAX也可以设置为>2。若还是报错GATT_BUFFER_FULL(buffer满了),需要确定蓝牙实际速率是否大于预期发数速率。对于需要
很快被手机/PC搜索到的场景,ADV_INTERVAL_MIN应该被调小,但是调小后功耗会提高,用户应该考虑此问题。对于
低功耗的场景,未连接:ADV_INTERVAL_MIN应该被调大,同时主机也较难搜索/连接较慢。连接:将hogp_connection_update_enable设置为1保证从机使用自己的连接参数,同时将conn_interval,latency,timeout调大。对于
数据量和低功耗均要的场景,可以适当调大latency,这样在发数时不进入latency,结束时进入latency节约功耗。Note:参数调节应该合理,不然会导致无法连接,无法更新连接参数等问题(连接参数是否更新成功,查看log最后的连接参数是多少即可)。
1.2.3. GATT主机相关参数配置
- 以ble_dg_central.c为例,其中参数:
ATT_LOCAL_MTU_SIZE:ATT发送包长
SET_SCAN_INTERVAL:搜索周期大小(unit:0.625ms)
SET_SCAN_WINDOW:搜索窗口大小(unit:0.625ms)
SET_CONN_INTERVAL:连接周期大小(unit:1.25ms)
SET_CONN_LATENCY:连接延迟
SET_CONN_TIMEOUT:连接超时时间(unit:10ms)
dg_test_remoter_name:搜索的设备名,
客户可以通过此处设置需要连接设备的名字进行连接
1.2.4. GATT Profile设置
profile配置参考make_gatt_services工具相关文档说明。但是要注意以下问题:
Note
AW30N SDK的配置文件以及函数路径和读写回调函数位置与工具文档描述有差异:
工具文档中描述的profile文件为ble_trans_profile.h,SDK配置profile的文件路径为apps/demo/hid/modules/bt/ble_hogp_profile.h att_read_callback函数和att_write_callback函数位于apps/demo/hid/modules/bt/ble_hogp.c
1.2.5. GATT从机主要api说明
1.2.5.1. 函数int get_buffer_vaild_len(void *priv)
Note
该函数实现查询蓝牙当前可写入缓存的发送数据长度
priv:传0即可;
返回值:当前可发送的数据长度;
1.2.5.2. 函数int ble_comm_att_send_data(u16 conn_handle, u16 att_handle, u8 *data, u16 len, att_op_type_e op_type)
Note
该函数实现从机选择att_handle发送数据给远端,att_handle由profile定义;
conn_handle:蓝牙连接handle;
att_handle:发送的att通道;
data:发送的数据buff;
len:发送的数据长度;
返回值:0:成功 非0:失败原因 出现发数失败时应该优先查是什么失败原因 见下;
app应用一般不会直接调用此API发送,会再封装一层,eg:int ble_slave_data_send()
GATT_OP_RET_SUCESS = 0, //执行成功 //对应ble_api接口返回的错误 GATT_CMD_RET_BUSY = -100, //命令处理忙 GATT_CMD_PARAM_OVERFLOW, //传参数溢出 GATT_CMD_OPT_FAIL, //操作失败 GATT_BUFFER_FULL, //缓存满了 GATT_BUFFER_ERROR, //缓存出错 GATT_CMD_PARAM_ERROR, //传参出错 GATT_CMD_STACK_NOT_RUN, //协议栈没有运行 GATT_CMD_USE_CCC_FAIL, //没有使能通知,导致NOTIFY或INDICATE发送失败, GATT_OP_ROLE_ERR = -200, //命令处理忙 //比如ble_hogp的发数接口会再封装一层,方便客户使用 int ble_slave_data_send(u16 att_handle, u8 *data, u16 len) { return ble_comm_att_send_data(hogp_con_handle, att_handle, data, len, ATT_OP_AUTO_READ_CCC); }
1.2.5.3. 函数int hogp_att_write_callback(hci_con_handle_t connection_handle, uint16_t att_handle, uint16_t transaction_mode, uint16_t offset, uint8_t *buffer, uint16_t buffer_size)
Note
该函数实现主机操作ATT write时的协议栈回调处理;主机发送给从机的数据,由此函数接收
att_handle:主机write用到的att通道;
buffer:数据接收buff;
buffer_size:数据接收长度;
返回值:0:成功 非0:失败;
1.2.5.4. 函数ble_cmd_ret_e ble_op_conn_param_request(con_handle, con_param)
Note
该函数实现从机请求更新连接参数,该函数在ble_slave.c已封到应用层,用户可参考该方法进行使用。
con_handle:hid从机应用下的con_handle, 传hogp_con_handle;
con_parm:连接参数;
返回值:0 失败 1更新成功
1.2.6. GATT主机主要api说明
1.2.6.1. 参考 函数int ble_comm_att_send_data(u16 conn_handle, u16 att_handle, u8 *data, u16 len, att_op_type_e op_type) 。
1.2.6.2. 函数int dg_central_event_packet_handler(int event, u8 *packet, u16 size, u8 *ext_param)
Note
该函数为主机接收从机数据回调处理。
report_data->value_handle:从机发送用到的att通道;
report_data->blob:接收数据buff;
report_data->blob_length:接收数据长度;
返回值:0:成功 非0:失败;
不同APP应用此回调函数不一样,此函数是APP应用初始化是注册回调实现,eg: 蓝牙初始化 里面hogp_event_packet_handler。
1.2.6.3. 函数ble_cmd_ret_e ble_op_conn_param_update(con_handle, con_param)
Note
该函数实现主机更新连接参数
con_handle:连接handle号, 可使用ble_comm_dev_get_handle()获取;
con_parm:连接参数;
返回值:0 失败 1更新成功