当前位置: 首页 > news >正文

自定义杰理AC63系列BLE数据发送函数

自定义BLE数据发送函数,就是将数据发送、数据发送前的检查、以及conn_handle查询等封装在一起,脱离SDK中的相关回调函数,在程序任意位置实现发送数据功能。

1. SDK中的BLE数据发送函数

BLE的数据发送函数定义在apps\common\third_party_profile\jieli\gatt_common\le_gatt_common.c文件里。

int ble_comm_att_send_data(u16 conn_handle, u16 att_handle, u8 *data, u16 len, att_op_type_e op_type)
{gatt_op_ret_e ret = GATT_OP_RET_SUCESS;u16 tmp_16;if (!conn_handle) {return GATT_CMD_PARAM_ERROR;}switch (op_type) {case ATT_OP_READ:tmp_16  = 0x55A1;//fixedret = ble_op_multi_att_send_data(conn_handle, att_handle, &tmp_16, 2, op_type);break;case ATT_OP_READ_LONG:tmp_16  = 0x55A2;//fixedret = ble_op_multi_att_send_data(conn_handle, att_handle, &tmp_16, 2, op_type);break;default:ret = ble_op_multi_att_send_data(conn_handle, att_handle, data, len, op_type);break;}if (ret) {const char *err_string;int error_id = (int)0 - (int)GATT_CMD_RET_BUSY + (int)ret;if (error_id >= 0 && error_id < sizeof(gatt_op_error_string) / sizeof(char *)) {err_string = gatt_op_error_string[error_id];} else {err_string = "UNKNOW GATT_ERROR";}log_error("att_send_fail: %d!!!,%s", ret, err_string);log_error("param:%04x, %04x, %02x,len= %d", conn_handle, att_handle, op_type, len);/* put_buf(data,len); */}return ret;
}

该数据发送函数出现在apps\spp_and_le\examples\trans_data\ble_trans.c文件下的write_callback 回调函数里。写入回调函数如下,注意,无关代码已经省略。

2. ATT写入回调函数

在手机或其他设备(Client角色)发送数据到AC63时,会进入注册过的回调函数trans_att_write_callback( );SDK例程中在该回调函数里执行了自动收发测试代码。

static int trans_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)
{int result = 0;u16 tmp16;u16 handle = att_handle;switch (handle) {//...此处省略1万字case ATT_CHARACTERISTIC_ae01_01_VALUE_HANDLE:log_info("\n-ae01_rx(%d):", buffer_size);put_buf(buffer, buffer_size);        //收发测试,自动发送收到的数据;for testif (ble_comm_att_check_send(connection_handle, buffer_size) &&ble_gatt_server_characteristic_ccc_get(trans_con_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE)) {log_info("-loop send1\n");ble_comm_att_send_data(connection_handle, ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, buffer, buffer_size, ATT_OP_AUTO_READ_CCC);}break;//...此处省略1万字default:break;}return 0;
}

自动收发测试代码里使用ble_comm_att_check_send( )函数检查发送缓存够不够用,同时使用ble_gatt_server_characteristic_ccc_get( )函数检查特征的NOTIFY属性是否得到了Client端的许可。如果任意一个条件不满足,均不会发送数据。

3. 发送缓存检查

为了避免内存溢出,导致不可预见的异常发生,必须检查数组长度是否超出了可用缓存大小。

/********************************************************************/
/*!*  \brief      检查预备发送的数据包长度是否能填入
/*******************************************************/
bool ble_comm_att_check_send(u16 conn_handle, u16 pre_send_len)
{if (ble_comm_cbuffer_vaild_len(conn_handle) >= pre_send_len) {return true;} else {return false;}
}/******************************************************************/
/*!*  \brief       获取配置的cbuffer 可以填入数据长度*/
/**************************************************************/
u32 ble_comm_cbuffer_vaild_len(u16 conn_handle)
{u32 vaild_len = 0;ble_op_multi_att_get_remain(conn_handle, &vaild_len);return vaild_len;
}

4. NOTIFY属性是否得到许可检查

NOTIFY属性是需要在建立连接后,由手机端写入1许可通知的。该函数用于检查是否得到Client许可。

/*************************************************************************************************/
/*!*  \brief      获取 notify or indicate 通知使能值**  \param      [in]**  \return     returnGATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NONEGATT_CLIENT_CHARACTERISTICS_CONFIGURATION_NOTIFICATIONGATT_CLIENT_CHARACTERISTICS_CONFIGURATION_INDICATION**  \note*/
/*************************************************************************************************/
u16 ble_gatt_server_characteristic_ccc_get(u16 conn_handle, u16 att_ccc_handle)
{return multi_att_get_ccc_config(conn_handle, att_ccc_handle);
}

5. 查询当前连接的handle

该函数返回值为连接的句柄。如果当前没有连接,则返回0。index是句柄在数组里的序号,默认从0开始。如果只有一个连接,则index为0。role是连接状态下的角色,分为server和client两种。

/*************************************************************************************************/
/*!-  \brief      获取index对应的连接 handle*/
/*************************************************************************************************/
u16 ble_comm_dev_get_handle(u8 index, u8 role)
{u16 *group_handle;u8 count;if (GATT_ROLE_SERVER == role) {group_handle = gatt_server_conn_handle;count = SUPPORT_MAX_GATT_SERVER;} else {group_handle = gatt_client_conn_handle;count = SUPPORT_MAX_GATT_CLIENT;}if (index < count) {return group_handle[index];} else {return 0;}
}

6. 自定义BLE发送数据函数

  • 先查询当前是否建立了BLE连接,如果无连接,则直接返回。
  • 检查发送缓存是否够用,如果不够,则直接返回。
  • 检查NOTIFY值是否被Client开启,如未开启,则直接返回。
/*****************************************************************************/
/*!-  \brief      user defined ble data send fun- u8* sdata	point of data to be send - u8 len		the size of data to be send */
/***************************************************************************/void my_ble_send_data(u8* sdata,u8 len)
{//先查明当前连接的conn_handleu16 connection_handle = ble_comm_dev_get_handle(0, GATT_ROLE_SERVER);printf("connection_handle: %04x\n",connection_handle);if(connection_handle==0)//无连接{return;}//检查预备发送的数据包长度是否能填入,并且获取 notify or indicate 通知使能值if (ble_comm_att_check_send(connection_handle, len) &&ble_gatt_server_characteristic_ccc_get(connection_handle, ATT_CHARACTERISTIC_ae02_01_CLIENT_CONFIGURATION_HANDLE)){printf("permit send...\n");//使用notify方式发送ble_comm_att_send_data(connection_handle, ATT_CHARACTERISTIC_ae02_01_VALUE_HANDLE, sdata, len, ATT_OP_NOTIFY);}
}

7. 小结

自定义BLE数据发送函数是将原来SDK中分散的几个函数集合到一起,完成独立的数据发送功能。其中 ble_comm_att_send_data( )函数是最主要的,其他几个是辅助该函数完成任务的。
BLE发送函数里,有个需要注意的地方是ATT的handle,这个值是由BLEprofile里的服务特征表里的数值决定的,如果该值不一致,数据发送会失败。
BLE的profile文件在:apps\spp_and_le\examples\trans_data\ble_trans_profile.h。服务特征表如下:

static const uint8_t trans_profile_data[] = {////// 0x0001 PRIMARY_SERVICE  1800////0x0a, 0x00, 0x02, 0x00, 0x01, 0x00, 0x00, 0x28, 0x00, 0x18,/* CHARACTERISTIC,  2a00, READ | WRITE | DYNAMIC, */// 0x0002 CHARACTERISTIC 2a00 READ | WRITE | DYNAMIC0x0d, 0x00, 0x02, 0x00, 0x02, 0x00, 0x03, 0x28, 0x0a, 0x03, 0x00, 0x00, 0x2a,// 0x0003 VALUE 2a00 READ | WRITE | DYNAMIC0x08, 0x00, 0x0a, 0x01, 0x03, 0x00, 0x00, 0x2a,////// 0x0004 PRIMARY_SERVICE  1801////0x0a, 0x00, 0x02, 0x00, 0x04, 0x00, 0x00, 0x28, 0x01, 0x18,/* CHARACTERISTIC,  2a05, INDICATE, */// 0x0005 CHARACTERISTIC 2a05 INDICATE0x0d, 0x00, 0x02, 0x00, 0x05, 0x00, 0x03, 0x28, 0x20, 0x06, 0x00, 0x05, 0x2a,// 0x0006 VALUE 2a05 INDICATE0x08, 0x00, 0x20, 0x00, 0x06, 0x00, 0x05, 0x2a,// 0x0007 CLIENT_CHARACTERISTIC_CONFIGURATION0x0a, 0x00, 0x0a, 0x01, 0x07, 0x00, 0x02, 0x29, 0x00, 0x00,////// 0x0008 PRIMARY_SERVICE  ae30////0x0a, 0x00, 0x02, 0x00, 0x08, 0x00, 0x00, 0x28, 0x30, 0xae,/* CHARACTERISTIC,  ae01, WRITE_WITHOUT_RESPONSE | DYNAMIC, */// 0x0009 CHARACTERISTIC ae01 WRITE_WITHOUT_RESPONSE | DYNAMIC0x0d, 0x00, 0x02, 0x00, 0x09, 0x00, 0x03, 0x28, 0x04, 0x0a, 0x00, 0x31, 0xae,// 0x000a VALUE ae01 WRITE_WITHOUT_RESPONSE | DYNAMIC0x08, 0x00, 0x04, 0x01, 0x0a, 0x00, 0x31, 0xae,/* CHARACTERISTIC,  ae02, NOTIFY, */// 0x000b CHARACTERISTIC ae02 NOTIFY0x0d, 0x00, 0x02, 0x00, 0x0b, 0x00, 0x03, 0x28, 0x10, 0x0c, 0x00, 0x32, 0xae,// 0x000c VALUE ae02 NOTIFY0x08, 0x00, 0x10, 0x00, 0x0c, 0x00, 0x32, 0xae,// 0x000d CLIENT_CHARACTERISTIC_CONFIGURATION0x0a, 0x00, 0x0a, 0x01, 0x0d, 0x00, 0x02, 0x29, 0x00, 0x00,//...此处省略1万字// END0x00, 0x00,
};

相关文章:

自定义杰理AC63系列BLE数据发送函数

自定义BLE数据发送函数&#xff0c;就是将数据发送、数据发送前的检查、以及conn_handle查询等封装在一起&#xff0c;脱离SDK中的相关回调函数&#xff0c;在程序任意位置实现发送数据功能。 1. SDK中的BLE数据发送函数 BLE的数据发送函数定义在apps\common\third_party_pro…...

Jenkins结合gitee自动化部署SpringBoot项目

安装 安装教程 插件选择 Gitee Plugin 配置 源码管理 填写源码地址 注意&#xff1a;请确保genkins所在的服务器有权限git拉取远程仓库代码&#xff0c;如果不可以请参考ssh配置centos 配置ssh拉取远程git代码 源码管理 构建触发器 1.勾选Gitee webhook 触发构建 2.生成we…...

声强级和声压级之间的转换举例

声强级和声压级之间的转换举例 在学习声学时候&#xff0c;经常会遇到声强级和声压级的概念&#xff0c;而且它们的单位都是分贝(dB),很容易混淆这两个概念。而且&#xff0c;更容易在计算时候&#xff0c;不知如何转换&#xff0c;如何使用&#xff0c;本文将举例说明两者之间…...

16 粒子滤波

文章目录 16 粒子滤波16.1 背景介绍16.1.1 Particle Filter是什么&#xff1f;16.1.2 Patricle Filter的状态如何转移&#xff1f;16.1.3 如何通过采样求解Particle Filter 16.2 重要性采样16.2.1 重要性采样方法16.2.2 Sequential Importance Sampling16.2.3 Resampling16.2.4…...

【appium】appium自动化入门之API(下)——两万字API长文,建议收藏

目录 Appium API 前言 1.contexts &#xff08;返回当前会话中的上下文&#xff0c;使用后可以识别 H5 页面的控件&#xff09; 2.current_context &#xff08;返回当前会话的当前上下文 &#xff09; 3. context &#xff08;返回当前会话的当前上下文&#xff09; 4.find_e…...

开发改了接口,经常忘通知测试的解决方案!

目录 前言&#xff1a; Apifox解决方案 Apifox对此给出的解决方案是&#xff1a; 用Apifox怎么处理接口变更 接口代码实现逻辑修改 接口参数修改 前言&#xff1a; 在开发过程中&#xff0c;接口变动十分频繁&#xff0c;测试人员没有及时获得相关通知的情况也很普遍。这…...

Beyond Compare 4 无法打开

解决办法&#xff1a; 1.修改注册表。WINR呼出开始菜单&#xff0c;在搜索栏中输入 regedit&#xff0c;点击确定。 2.删除项目&#xff1a;\HKEY_CURRENT_USER\Software\ScooterSoftware\Beyond Compare 4\CacheId 根据这个路径找到cacheid 右击删除掉就可以...

MySQL高级数据操作

✅作者简介&#xff1a;热爱Java后端开发的一名学习者&#xff0c;大家可以跟我一起讨论各种问题喔。 &#x1f34e;个人主页&#xff1a;Hhzzy99 &#x1f34a;个人信条&#xff1a;坚持就是胜利&#xff01; &#x1f49e;当前专栏&#xff1a;MySQL &#x1f96d;本文内容&a…...

硬件设计电源系列文章-DCDC转换器基础知识

文章目录 概要整体架构流程技术名词解释技术细节小结 概要 提示&#xff1a;这里可以添加技术概要 本文主要接着上篇&#xff0c;上篇文章主要讲述了LDO的相关基础知识&#xff0c;本节开始分享DCDC基础知识 整体架构流程 提示&#xff1a;这里可以添加技术整体架构 以下是…...

XdsObjects .NET 8.45.1001.0 Crack

XdsObjects 是一个工具包&#xff0c;允许开发人员使用 IHE XDS 和 XDS-I 配置文件开发应用程序&#xff0c;只需花费最少的时间和精力&#xff0c;因为遵守配置文件和 ebXML 规则的所有艰苦工作都由该工具包处理。 它为所有角色提供客户端和服务器支持&#xff0c;包括&#…...

数据安全--17--数据安全管理之数据传输

本博客地址&#xff1a;https://security.blog.csdn.net/article/details/131061729 一、数据传输概述 数据传输有两个主体&#xff0c;一个是数据发送方&#xff0c;另一个是数据接收方。数据在通过不可信或者较低安全性的网络进行传输时&#xff0c;容易发生数据被窃取、伪…...

SpringSecurity实现前后端分离登录token认证详解

目录 1. SpringSecurity概述 1.1 权限框架 1.1.1 Apache Shiro 1.1.2 SpringSecurity 1.1.3 权限框架的选择 1.2 授权和认证 1.3 SpringSecurity的功能 2.SpringSecurity 实战 2.1 引入SpringSecurity 2.2 认证 2.2.1 登录校验流程 2.2.2 SpringSecurity完整流程 2.2.…...

Vue3_ElementPlus_简单增删改查(2023)

Vue3&#xff0c;Element Plus简单增删改查 代码&#xff1a;https://github.com/xiaoming12318/Vue3_ElementPlus_CRUD.git 环境&#xff1a; Visual Studio Code Node.js 16.0或更高版本&#xff0c;https://nodejs.org/en axios 快速上手&#xff1a; 如果已经有16.0及…...

vue中重写并自定义console.log

0. 背景 在vue2项目中自定义console.log并输出文件名及行、列号 1. 实现 1.1 自定义console.log export default {// 输出等级: 0-no, 1-error, 2-warning, 3-info, 4-debug, 5-loglevel: 5,// 输出模式: 0-default, 1-normal, 2-randommode: 1,// 是否输出图标hasIcon: fal…...

基于OpenCV 和 Dlib 进行头部姿态估计

写在前面 工作中遇到&#xff0c;简单整理博文内容涉及基于 OpenCV 和 Dlib头部姿态评估的简单Demo理解不足小伙伴帮忙指正 庐山烟雨浙江潮&#xff0c;未到千般恨不消。到得还来别无事&#xff0c;庐山烟雨浙江潮。 ----《庐山烟雨浙江潮》苏轼 https://github.com/LIRUILONGS…...

24个Jvm面试题总结及答案

1.什么是Java虚拟机&#xff1f;为什么Java被称作是“平台无关的编程语言”&#xff1f; Java虚拟机是一个可以执行Java字节码的虚拟机进程。Java源文件被编译成能被Java虚拟机执行的字节码文件。 Java被设计成允许应用程序可以运行在任意的平台&#xff0c;而不需要程序员为每…...

freemarker 生成前端文件

Freemarker是一种模板引擎&#xff0c;它允许我们在Java应用程序中分离视图和业务逻辑。在Freemarker中&#xff0c;List是一种非常有用的数据结构&#xff0c;它允许我们存储一组有序的元素。有时候&#xff0c;我们需要判断一个List是否为空&#xff0c;这在程序设计中有许多…...

Pycharm+pytest+allure打造高逼格的测试报告

目录 前言&#xff1a; 1、安装allure 2、安装allure-pytest 3、一个简单的用例test_simpe.py 4、在pycharm底部打开terminal 5、用allure美化报告 6、查看报告 总结&#xff1a; 前言&#xff1a; 今天分享的内容&#xff1a;在Pycharmpytest基础上使用allure打造高逼格…...

Mybatis-Plus中update更新操作用法

目录 一、前言二、update1、关于修改的4个条件构造器2、UpdateWrapper【用法示例】3、LambdaUpdateWrapper【用法示例】4、UpdateChainWrapper【 用法示例】5、LambdaUpdateChainWrapper【 用法示例】6、updateById 和 updateBatchById7、Mybatis-plus设置某个字段值为null的方…...

16道JVM面试题

1.jvm内存布局 1.程序计数器&#xff1a;当前线程正在执行的字节码的行号指示器&#xff0c;线程私有&#xff0c;唯一一个没有规定任何内存溢出错误的情况的区域。 2.Java虚拟机栈&#xff1a;线程私有&#xff0c;描述Java方法执行的内存模型&#xff0c;每个方法运行时都会…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

Vue2 第一节_Vue2上手_插值表达式{{}}_访问数据和修改数据_Vue开发者工具

文章目录 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染2. 插值表达式{{}}3. 访问数据和修改数据4. vue响应式5. Vue开发者工具--方便调试 1.Vue2上手-如何创建一个Vue实例,进行初始化渲染 准备容器引包创建Vue实例 new Vue()指定配置项 ->渲染数据 准备一个容器,例如: …...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

MySQL 知识小结(一)

一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库&#xff0c;分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷&#xff0c;但是文件存放起来数据比较冗余&#xff0c;用二进制能够更好管理咱们M…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...