目前的adk中只有电池,心率等几个固定的gatt服务,所以如果要实现自定义的数据收发,需要再自定义一个gatt服务
首先要在config中使能gatt,如下图所示:
csr adk通过gatt_custom_server_db.dbi文件,然后利用工具生成对应的gatt服务数据表,在将该服务添加一个gatt服务列表中。通常来说嵌入式设备都是作为服务器(外设设备)存在,向客户端(中心设备)提供数据,.dbi文件如下:
primary_service {
uuid : UUID_CUSTOM_SERVICE,
name : "CUSTOM_FIRST_SERVICE",
characteristic {
uuid : UUID_CUSTOM_CHARA_WRITE,
name : "WRITE",
flags : [ FLAG_IRQ ],
properties : [ write_cmd ],
size_value : 0x14
},
characteristic {
uuid : UUID_CUSTOM_CHARA_READ,
name : "READ",
flags : [ FLAG_IRQ ],
properties : [ notify ],
size_value : 0x14,
client_config{
name : "CUSTOM_CCC",
flags : [ FLAG_IRQ , FLAG_DYNLEN ]
}
},
characteristic {
uuid : UUID_CUSTOM_CHARA_FLOW_CTL,
name : "FLOW_CTL",
flags : [ FLAG_IRQ ],
properties : [ notify ],
value : 0x0
}
},
.dbi文件在编译中会转成相应的.c与.h文件,具体可以参考battery与heartrate对应的dbi文件。上面的dbi中,我定义了一个custom 服务,服务中包含三个character,第一个用于从手机读取,第二个用于向手机发送数据,第三个是流控。
因为我们使用的数据发送的模型是notify,所以数据的发送需要调用一下接口GattNotificationRequest()。需要注意的是cid(channel id)参数,在这里我选择的是第一个gatt连接的cid,theSink.rundata->ble.gatt[0].cid,当有多个连接时,需要注意参数选择;还有handle参数,一定要与我们custom服务中相应的handle的UUID匹配
下面是我通过串口工具发送的指令到开发板,指令解析之后,将我要发送的数据通过蓝牙发送出去
void handleGattSendData(Task t, const struct GattSendData *send_data)
{
uint16 index = 0;
uint16 custom_cid = theSink.rundata->ble.gatt[index].cid;
if(stateManagerGetState() > deviceConnDiscoverable){
GattNotificationRequest(sinkGetBleTask(), custom_cid, HANDLE_READ, send_data->data.length, send_data->data.data);
UartSendStr("OK\r\n");
}else{
UartSendStr("ERROR\r\n");
}
}
当底层收到数据之后,会发送给sinkGattManagerMsgHandler()进行消息处理,我们的server的消息将会包含在GATT_MANAGER_SERVER_ACCESS_IND中,原始的adk没有关于这块的数据处理,这里我参加了一个接口去打印gatt的数据
static gatt_status_t custom_gatt_data_handle(void *msg)
{
uint16 flags,handle;
gatt_status_t status = gatt_status_success;
GATT_MANAGER_SERVER_ACCESS_IND_T *pMsg = (GATT_MANAGER_SERVER_ACCESS_IND_T *)msg;
flags = pMsg->flags;
handle = pMsg->handle;
if (flags == (ATT_ACCESS_PERMISSION | ATT_ACCESS_WRITE_COMPLETE | ATT_ACCESS_WRITE)) {
if (handle == HANDLE_WRITE) {
UartSendStr("+GATTDATA:");
UartSendData(pMsg->value, pMsg->size_value);
UartSendStr("\r\n");
} else if (handle == HANDLE_CUSTOM_CCC) {
} else{
status = gatt_status_write_not_permitted;
}
} else if (flags == (ATT_ACCESS_PERMISSION | ATT_ACCESS_READ)) {
}
return status;
}
如果想要在广播数据中包含自定义的服务的uuid等信息,需要在这里添加ble的服务数据
static void updateServicesAdData(uint8* ad_data_ptr, uint16 *counter_ptr , uint16 num_services)
{
if (num_services){
BLE_AD_INFO(("Custom Service"));
ad_data_ptr[*counter_ptr] = (0x00 & 0xFF);
(*counter_ptr)++;
ad_data_ptr[*counter_ptr] = (0xFF >> 8);
(*counter_ptr)++;
num_services--;
}
}
上面我只贴出了部分代码,详细源码及相关的工具资料等,请到我的博客