本帖最后由 N32BLE 于 2022-10-29 20:25 编辑
#技术资源# 本文档介绍 N32WB031系列 32 位 蓝牙芯片(以下简称 N32WB031)自定义服务特征值操作流程,包括修改服务特征值的UUID、权限等参数以及添加自定义服务和自定义特征值的方法步骤。本文档目的在于让使用者能够快速熟悉自定义蓝牙服务修改或添加的方式,以减少开发前期的准备时间,降低开发难度。 1 修改服务和特征值UUID、权限 1.1 定义/修改UUID 本文档以RDTSS例程为说明对象,服务/和特征值的UUID值定义位于
注意: 1、一般在手机APP上看到的UUID与程序中配置的顺序是相反的,比如服务手机APP上UUID一般显示为:0x0000276008C211E190730E8AC72E1001。用户如果想改变UUID的值,修改如上宏定义的值即可实现UUID变更。 2、16bit UUID数传例程的宏定义在app_rdtss_16bit.h,修改方式也是修改宏定义的值即可完成修改。 1.2 修改特征值权限 本文档以RDTSS例程为说明对象,数传例程蓝牙服务的权限定义位于app_rdtss.c的结构体struct attm_desc_128rdtss_att_db里面。通过结构体struct attm_desc_128的定义的代码可知各项的意义 说明:第一项是uuid;第二项perm是属性表权限,主要用于定义属性表本身的权限,比如读/写/通知;第三项ext_perm是扩展权限,主要用于定义特征值属性,比如长度。例程里通过如下代码给UUID 为ATT_CHAR_AM_SPEED_WRITE_128的特征值定义了写权限,和这个特征值是128bit的长度。 [2] = {ATT_CHAR_AM_SPEED_WRITE_128,PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE)| PERM_VAL(UUID_LEN, 0x02),0x200}, l 例程里通过如下代码给UUID ATT_CHAR_AM_SPEED_NTF_128定义了通知权限,和这个特征值是128bit的。 [5] = {ATT_CHAR_AM_SPEED_NTF_128, PERM(NTF,ENABLE), PERM(RI, ENABLE)| PERM_VAL(UUID_LEN, 0x02), 0x200 }, l 如果我们希望把上面的特征值在原有的通知选项加上读写选项,我们应该按如下修改: [5] = {ATT_CHAR_AM_SPEED_NTF_128, PERM(NTF,ENABLE)|PERM(RD, ENABLE)|PERM(WRITE_COMMAND, ENABLE), PERM(RI, ENABLE)|PERM_VAL(UUID_LEN, 0x02), 0x200},比如PERM(RD, ENABLE),RD说明就是读权限,我们可以使用的参数有:RD(读),WRITE_COMMAND(不带回应写),WRITE_REQ(带回应写),NTF(通知),IND(带回应通知)。16bit UUID的特征值权限定义和128bit的基本一致,具体参考结构体struct attm_desc的定义。 2 添加新的特征值 RDTSS数传例程蓝牙服务的权限定义位于app_rdtss.c的结构体struct attm_desc_128rdtss_att_db里面。比如我们就在这个服务里添加一个16bit UUID为0xFFF1的特征值,有读、写和通知三种权限。 2.1 添加特征值的枚举声明 2.2 添加特征值到DB 说明: 1、例程中使用RDTSS_IDX_WRITE_VAL当作UUID为 ATT_CHAR_AM_SPEED_WRITE_128的特征值标号,接收数据时判断handle句柄为此标号时即为手机app(主机)向(从机)此特征值写入数据,即下发的数据。 2、通过定义RDTSS_IDX_NTF_VAL当作UUID为ATT_CHAR_AM_SPEED_NTF_128的特征值标号,通过通知操作上发数据时,在handle填入RDTSS_IDX_NTF_VAL即可识别为向此特征值上发数据。 2.3 发送数据操作 2.4 接收数据回调函数 说明:标号RDTSS_IDX_USER_VAL为UUID 0xFFF1的特征值标号,我们将可以通过它执行读,写和通知操作。 新增接收数据回调添加在app_rdtss.c的rdtss_val_write_ind_handler函数内: 3 添加自定义服务 以rdtss服务为模板,添加一个命名为rdtss2的新服务。在此之前我们可以通过全局搜索BLE_RDTSS_SERVER这个宏来了解这一个服务所包含的文件和代码。 1) 在app_user_config.h定义宏CFG_PRF_RDTSS2的值为1使能这个新的服务; #define CFG_PRF_RDTSS2 1 2) 在rwprf_config.h文件添加frofile层的宏控制代码,并且修改BLE_RDTS_ENABLE宏的值; #if defined(CFG_PRF_RDTSS2) #define BLE_RDTSS2_SERVER 1 #else #define BLE_RDTSS2_SERVER 0 #endif // defined(CFG_PRF_RDTSS2) #define BLE_RDTS_ENABLE (BLE_RDTSS_SERVER|| BLE_RDTSS_16BIT_SERVER || BLE_RDTSS2_SERVER) 3) 在rdts_common.c 参照#if (BLE_RDTSS_SERVER)使能内容添加头文件; #if (BLE_RDTSS2_SERVER) #include "rdtss2.h" #endif 4) 在rdts_common.c 参照#if (BLE_RDTSS_SERVER)使能内容添加两个函数实现。 #if (BLE_RDTSS2_SERVER) uint16_t rdtss2_get_att_handle(uint8_tatt_idx) { struct rdtss2_env_tag *rdtss2_env =PRF_ENV_GET(RDTSS2, rdtss2); uint16_t handle = ATT_INVALID_HDL; if (att_idx < rdtss2_env->max_nb_att) {handle = rdtss2_env->shdl + att_idx;} return handle; } uint8_t rdtss2_get_att_idx(uint16_t handle,uint8_t *att_idx) { struct rdtss2_env_tag *rdtss2_env =PRF_ENV_GET(RDTSS2, rdtss2); uint8_t status = PRF_APP_ERROR; if ((handle >= rdtss2_env->shdl)&& (handle < rdtss2_env->shdl + rdtss2_env->max_nb_att)) { *att_idx = handle -rdtss2_env->shdl; status = ATT_ERR_NO_ERROR; } return status; } #endif 5) 在rdts_common.h 参照#if (BLE_RDTSS_SERVER)使能,声明两个函数。 #if (BLE_RDTSS2_SERVER) uint16_t rdtss2_get_att_handle(uint8_tatt_idx); uint8_t rdtss2_get_att_idx(uint16_t handle,uint8_t *att_idx); #endif // (BLE_RDTSS2_SERVER) 6) 在rwip_task.h添加这个服务的任务号,注意应不要重复,这个例程最小的任务号为74。 TASK_ID_RDTSS2 = 74, // NEW USER servertask 7)添加profile层库文件,middlewares\Nationstech\ble_library\ns_ble_profile\rdts\rdtss目录下,复制rdtss.c,rdtss.h,rdtss_task.c, rdtss_task.h 四个文件为rdtss2.c,rdtss2.h,rdtss2_task.c, rdtss2_task.h,修改里面RDTSS/rdtss相关字段为RDTSS2/rdtss2,避免重名声明。(注意检查是否替换彻底) 8) 添加profile应用层代码,在例程的app_profile目录下复制app_rdtss.c和app_rdtss.h为app_rdtss2.c和app_rdtss2.h,改里面RDTSS/rdtss相关字段为RDTSS2/rdtss2,避免重名声明。(注意检查是否替换彻底) 9) 把profile层库文件和应用层的.c源文件添加到工程相应的目录,即BLE_PROFILE和BLE_APP目录。 10) 请参考第1节的内容修改UUID,如需更改权限请参考第2节的内容。 11) 在app_ble_prf_init 函数里调用ns_ble_add_prf_func_register注册新增服务。 ns_ble_add_prf_func_register(app_rdtss2_add_rdts); 12) 至此服务已经添加完成,后续可以在rdtss2_val_write_ind_handler的RDTSS2_IDX_WRITE_VAL事件回调获取接收到的数据和通过rdtss2_send_notify函数发送数据。
|