最近有一个CSDN的好友给我留言,询问如何设置主服务uuid和特性uuid不一样,如下图:
我以为这个问题很简单,网上应该一大堆,但是搜索一下,却发现没有这样的文章,于是,把自己的代码给分享出来,供大家学习。
废话就少说,这里直接把代码复制下来。大家可以通过对比软件对比一下就行。使用的是SDK11的,串口服务ble_char,
uint32_t ble_char_init(ble_char_t * p_char, const ble_char_init_t * p_char_init)
{
uint32_t err_code;
ble_uuid_t ble_uuid,rx_uuid,tx_uuid;
#if 1 //add lvyapeng 20210126
ble_uuid128_t char_base_uuid = BLE_UUID_CHAR_BASE;
#endif //add end
if ((p_char == NULL) || (p_char_init == NULL))
{
return NRF_ERROR_NULL;
}
// Initialize service structure.
p_char->conn_handle = BLE_CONN_HANDLE_INVALID;
p_char->data_handler = p_char_init->data_handler;
// p_char->is_notification_enabled = false;
/**@snippet [Adding proprietary Service to S110 SoftDevice] */
// Add custom base UUID.
#if 1 //add lvyapeng 20210126
err_code = sd_ble_uuid_vs_add(&char_base_uuid, &p_char->uuid_type);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
ble_uuid.type = p_char->uuid_type;
ble_uuid.uuid = BLE_UUID_STRING_SERVICE;
#else
BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_STRING_SERVICE);
#endif //add end 20210126
// Add service.
err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
&ble_uuid,
&p_char->service_handle);
/**@snippet [Adding proprietary Service to S110 SoftDevice] */
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// Add TX Characteristic.
err_code = tx_char_add(p_char, p_char_init);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// Add RX Characteristic.
err_code = rx_char_add(p_char, p_char_init);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
// Add test Characteristic.
err_code = test_char_add(p_char, p_char_init);
if (err_code != NRF_SUCCESS)
{
return err_code;
}
return NRF_SUCCESS;
}
static uint32_t tx_char_add(ble_char_t * p_char, const ble_char_init_t * p_char_init)
{
ble_gatts_char_md_t char_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t ble_uuid;
ble_gatts_attr_md_t attr_md;
#if 1 //add 20210126 lvyapeng
ble_uuid128_t tx_char_base_uuid = BLE_UUID_TX_CHAR_BASE;
BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_TX_STRING_CHAR);
ble_uuid.type=BLE_UUID_TYPE_VENDOR_BEGIN;
sd_ble_uuid_vs_add(&tx_char_base_uuid, &ble_uuid.type);
#endif //add end
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.write = 1;
char_md.char_props.write_wo_resp = 1;
char_md.p_char_user_desc = NULL;
char_md.p_char_pf = NULL;
char_md.p_user_desc_md = NULL;
char_md.p_cccd_md = NULL;
char_md.p_sccd_md = NULL;
memset(&attr_md, 0, sizeof(attr_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = 0;
attr_md.wr_auth = 0;
attr_md.vlen = 1;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = 1;
attr_char_value.init_offs = 0;
attr_char_value.max_len = BLE_CHAR_MAX_TX_CHAR_LEN;
return sd_ble_gatts_characteristic_add(p_char->service_handle,
&char_md,
&attr_char_value,
&p_char->tx_handles);
}
static uint32_t rx_char_add(ble_char_t * p_char, const ble_char_init_t * p_char_init)
{
/**@snippet [Adding proprietary characteristic to S110 SoftDevice] */
ble_gatts_char_md_t char_md;
ble_gatts_attr_md_t cccd_md;
ble_gatts_attr_t attr_char_value;
ble_uuid_t ble_uuid;
ble_gatts_attr_md_t attr_md;
uint32_t err_code;
#if 1 //add 20210126 lvyapeng
ble_uuid128_t rx_char_base_uuid = BLE_UUID_RX_CHAR_BASE;
BLE_UUID_BLE_ASSIGN(ble_uuid, BLE_UUID_RX_STRING_CHAR);
ble_uuid.type=BLE_UUID_TYPE_VENDOR_BEGIN;
sd_ble_uuid_vs_add(&rx_char_base_uuid, &ble_uuid.type);
#endif //addend
memset(&cccd_md, 0, sizeof(cccd_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&cccd_md.write_perm);
cccd_md.vloc = BLE_GATTS_VLOC_STACK;
memset(&char_md, 0, sizeof(char_md));
char_md.char_props.notify = 1;
char_md.p_char_user_desc = NULL;
char_md.p_char_pf = NULL;
char_md.p_user_desc_md = NULL;
char_md.p_cccd_md = &cccd_md;
char_md.p_sccd_md = NULL;
memset(&attr_md, 0, sizeof(attr_md));
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.read_perm);
BLE_GAP_CONN_SEC_MODE_SET_OPEN(&attr_md.write_perm);
attr_md.vloc = BLE_GATTS_VLOC_STACK;
attr_md.rd_auth = 0;
attr_md.wr_auth = 0;
attr_md.vlen = 1;
memset(&attr_char_value, 0, sizeof(attr_char_value));
attr_char_value.p_uuid = &ble_uuid;
attr_char_value.p_attr_md = &attr_md;
attr_char_value.init_len = sizeof(uint8_t);
attr_char_value.init_offs = 0;
attr_char_value.max_len = BLE_CHAR_MAX_RX_CHAR_LEN;
return sd_ble_gatts_characteristic_add(p_char->service_handle,
&char_md,
&attr_char_value,
&p_char->rx_handles);
/**@snippet [Adding proprietary characteristic to S110 SoftDevice] */
}
下面是ble_char.h里面自己的宏定义
#define BLE_UUID_CHAR_BASE {0x3H, 0x23, 0xcf, 0x40, 0x73, 0x16, 0x42, 0x9A,\
0x5C, 0x41, 0x7E, 0x7D, 0x00, 0x00, 0x83, 0x14}
#define BLE_UUID_TX_CHAR_BASE {0xah, 0xe1, 0x26, 0x0a, 0xee, 0x9a, 0xe9, 0xbb,\
0xb0, 0x49, 0x0b, 0xeb, 0x00, 0x00, 0x00, 0x8b}
#define BLE_UUID_RX_CHAR_BASE {0x5h, 0x9a, 0x05, 0x43, 0x52, 0xcd, 0xb1, 0xa6,\
0x1a, 0x4b, 0xe7, 0xa8, 0x00, 0x00, 0x34, 0x07}
//#define BLE_UUID_STRING_SERVICE 0xA8A0 /**< The UUID of the Nordic UART Service. */
//#define BLE_UUID_TX_STRING_CHAR 0xa8a3 /**< The UUID of the TX Characteristic. */
//#define BLE_UUID_RX_STRING_CHAR 0xa8a4 /**< The UUID of the RX Characteristic. */
//#define BLE_UUID_TEST_STRING_CHAR 0xa8a5
#define BLE_UUID_STRING_SERVICE 0x9ac4 /**< The UUID of the Nordic UART Service. */
#define BLE_UUID_TX_STRING_CHAR 0xace7 /**< The UUID of the TX Characteristic. */
#define BLE_UUID_RX_STRING_CHAR 0x594a /**< The UUID of the RX Characteristic. */
下面是协议栈初始化的vs_uuid_count更改由2增加到4,注意更改以后,会增加rom消耗,确保剩余rom能够使用
uint32_t softdevice_enable_get_default_config(uint8_t central_links_count,
uint8_t periph_links_count,
ble_enable_params_t * p_ble_enable_params)
{
memset(p_ble_enable_params, 0, sizeof(ble_enable_params_t));
p_ble_enable_params->common_enable_params.vs_uuid_count = 4;
p_ble_enable_params->gatts_enable_params.attr_tab_size = SOFTDEVICE_GATTS_ATTR_TAB_SIZE;
p_ble_enable_params->gatts_enable_params.service_changed = SOFTDEVICE_GATTS_SRV_CHANGED;
p_ble_enable_params->gap_enable_params.periph_conn_count = periph_links_count;
p_ble_enable_params->gap_enable_params.central_conn_count = central_links_count;
if (p_ble_enable_params->gap_enable_params.central_conn_count != 0)
{
p_ble_enable_params->gap_enable_params.central_sec_count = SOFTDEVICE_CENTRAL_SEC_COUNT;
}
return NRF_SUCCESS;
}
详细解释:(这里就添加几个图片,相信经常玩nordic能够清楚)
下面就是更改以后,烧录进去的成果,这样就更该完成:
文章浏览阅读229次。目录一、数据库基本操作1.1 登录数据库1.2 查看数据库结构查看数据库信查看数据库中包含的表结构显示数据表的结构1.3 常用的数据库类型1.4 char和varchar的区别二、MySQL数据文件2.1 MYD文件2.2 MYI文件2.3 MyISAM存储引擎三、SQL语句3.1DDL数据定义语言创建新的数据库创建新的表删除指定的数据表删除指定的数据库3.2 DML数据操控语言向数据表中插入新的数据记录查询数据记录_myi
文章浏览阅读1.3k次,点赞23次,收藏21次。70 个小朋友参加夏令营活动,老师们组织小朋友做游戏,让他们站成一排,从 1 开始顺序报数,报奇数的 小朋友出局;剩下的小朋友位置不变,再次从 1 开始报数,报奇数的出局......按照这个规则继续下去,直 到剩一个小朋友为止。维维坐在第 1 列火车的 10 号车厢,奇奇坐在第 2 列火车的 10 号车厢。当维维和奇奇正好相遇时,第 1 列 火车的 14 号车厢,与第 2 列火车的( )号车厢相遇。下图中每个圆圈代表一个小朋友。将一个表面涂有颜色的正方体,分割成同样大小的 27 个小正方体,如下图所示。_计算思维u8省赛
文章浏览阅读2.1k次,点赞3次,收藏7次。作者:奇版权:本作品采用「」许可协议进行许可。_未找到文件nmake
文章浏览阅读3.9k次,点赞2次,收藏5次。索引是一种用来快速查询数据的数据结构。B+Tree就是一种常用的数据库索引数据结构,MongoDB采用B+Tree 做索引,索引创建在colletions上。MongoDB不使用索引的查询,先扫描所有的文档,再匹配符合条件的文档。使用索引的查询,通过索引找到文档,使用索引能够极大的提升查询效率。按照索引包含的字段数量,可以分为单键索引和组合索引(或复合索引)。按照索引字段的类型,可以分为主键索引和非主键索引。按照索引节点与物理记录的对应方式来分,可以分为聚簇索引和非聚簇索引,其。_mongodb索引
文章浏览阅读190次。请注意,在实际操作前,请确保你已经正确备份了要删除的数据,因为删除索引操作不可逆。此外,如果需要删除所有索引(这是一项非常危险的操作,应当极其谨慎),可以使用。例如,如果你想要删除名为。_elasticsearch删除索引数据
文章浏览阅读285次。要用“作为一个用户(As a user),我希望(I want)什么功能,以(so that)满足什么商业价值“的标准格式描述,以讲清楚该需求的目标用户、功能和价值。一个功能设计是否合理,能否被设计和开发团队读懂,设计、开发出满足用户需求和业务需求的产品,都要依赖需求描述的合理性。如果有专业的交互设计师,这反而是对他设计的一种限制,以你的不专业影响了他的专业。上回讲到PRD撰写前的准备工作,包括摸清PRD的目标用户的习惯,深入了解本次用户的需求,根据INVEST和MVP原则、按照业务流程做功能拆分。_在线教育prd文档
文章浏览阅读353次,点赞8次,收藏12次。博主介绍:全网粉丝10W+,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战精彩专栏 推荐订阅2023-2024年最值得选的微信小程序毕业设计选题大全:100个热门选题推荐2023-2024年最值得选的Java毕业设计选题大全:500个热门选题推荐Java精品实战案例《500套》微信小程序项目精品案例《500套》文末获取源码+数据库。
文章浏览阅读1.1k次。前几天看了Python的一些基础知识,然后又了解了一下相关的web框架,比较主流的有Django和Flask,比较了一下之后决定学Django,基础供能比较完善,对于初学者应该更友好一些。一边跟着大神的博客做,一边整理了这篇博客,没什么新的东西,只是我个人的学习笔记,其中一些部分我专门修改成不太一样的东西,以免学习过程中不求甚解的忽略。总的来说大神这篇博客非常不错,如果你是刚学习了Python的基础_通过什么语句把我们新定义的app加到settings.py中的install_apps中
文章浏览阅读424次。Zuul请求处理流程zuul框架在处理http请求时,由springmvc所管理,一起看下具体流程:请求由DispatchServlet分发,查找HandlerMapping,zuul框架定义了ZuulHandlerMapping,它是将路由规则绑定到了ZuulController上面; 查找HandlerMappingAdapter映射器处理器,由SimpleControllerH..._zuulhandlermapping
文章浏览阅读658次。今天呢先说下packetfence部署的环境; 关于使用方法之前的帖子有介绍,一定要看哦 https://blog.csdn.net/qq_18204953/article/details/80708303 官网部署参考网址 https://packetfence.org/doc/PacketFence_Installation_Guide.html 一、准备工作(服务器、设备) 需求: 1、ce..._packetfence 部署
文章浏览阅读51次。Following on/off features are defined inDeserializationConfig.Feature(Jackson 1.x) orDeserializationFeature(Jackson 2.x):ACCEPT_EMPTY_STRING_AS_NULL_OBJECT (default: false) (since1.8)Deter..._fail_on_invalid_subtype
文章浏览阅读4.6k次,点赞2次,收藏2次。转自http://hi.baidu.com/fillysky/item/a579d20f2350afca74cd3c19笛卡尔说过:“最有价值的知识是方法的知识。”一、研究生与大学生的区别大学生基本上是来接受学问、接受知识的,然而不管是对于硕士时期或是博士时期的研究而言,都应该准备要开始制造新的知识,所以第一个我们必须要很用心、很深刻的思考,大学生和研究生是不同的。(一_课题题目要有延展性对一个课题来说,如果选错了题目,就是失败,题目选对了,还有