6621E如何添加主机读取特性值时,从机增加对应的回调接口

徽信管理团队 · 246次点击 · 2023-11-14

当某个特性具有写、读、通知等多个功能时,目前我们6621E的服务以及接口是每次写数据的时候,会更新底层该特性的有效值的长度信息,也就是这次主机写100字节,下次主机读取的时候,从机就会回100字节。如果主机写50字节,那么主机再读的时候,从机就会回50字节。但是考虑到有些客户的需求是,假设当主机写100字节的时候,主机调用读特性的时候,从机可以回1字节,也可以回17字节,而不是回100字节。那么这种不定长数据应该怎么修改呢?


具体的修改方法如下:


1、新增读接口回调函数:
void ble_set_read_calblack(void (*callback)(co_msg_id_t id, co_layer_id_t dst, co_layer_id_t src, void *param))
{
co_msg_register(LAYER_L2CAP, callback);
}

2、main函数注册读接口回调函数:
ble_set_read_calblack(l2cap_msg_process_handle_wrapper);
该函数在softdevice_ble_evt_handler_set(on_ble_evt);后面执行就可以

3、读接口回调函数如下:
void l2cap_msg_process_handle_wrapper(co_msg_id_t id, co_layer_id_t dst, co_layer_id_t src, void * param)
{
if ((dst == LAYER_L2CAP) && (src == LAYER_LL) && (id == MSG_ACL_DATA) && param) {
msg_acl_t* acl_data = (msg_acl_t*)param;
uint8_t pb = ((acl_data->conhdl & 0x3000) >> 12);
if (pb == 0x02) { // First packet
uint8_t* p = acl_data->pdata;
p += sizeof(uint16_t);
uint16_t cid = p[0] + (p[1] << 8);
if(cid == 0x04) {
uint8_t * data = acl_data->pdata;
uint8_t att_opcode = data[4];
if (att_opcode == 0xA) { // read request
uint16_t att_handle = data[5] + (data[6] << 8);
log_debug("Read ATT handle: 0x%02X\n", att_handle);
// TODO: do something
if (att_handle == 0x17)
{
att_db_t* att_db = ((att_db_t*(*)(uint16_t, uint16_t))0x001096cd)(att_handle, 0x0A);
att_db->value_len = 2;//user define
}
}
}
}
}
void l2cap_msg_process_handle(co_msg_id_t id, co_layer_id_t dst, co_layer_id_t src, void * param);
l2cap_msg_process_handle(id, dst, src, param);
}

注意:上文中的if (att_handle == 0x17)只是做举例,实际使用应该根据客户需求,修改对应的句柄值,也就是if (att_handle == 0xxxxx),这个0xxxxx就是用户实际需要的句柄。这个0xxxxx应该是我们在注册蓝牙服务,添加特性时,会返回一个存储句柄信息的结构体handles,而我们想要操作的句柄是:handles.value_handle。om_ble_gatts_characteristic_add(m_start_handle, &char_md, &attr_char_value, &handles); 。把自己想传的字节长度赋值给att_db->value_len。

4973bc62024850a6b3c89d9dff614132.pngimage.png

image.png




被收藏 0  ∙  0 赞  
加入收藏
点赞
1 回复  
善言善语 (您需要 登录 后才能回复 没有账号 ?)

请先登录网站