From 0ec736346af5828c7ae7257385c36f62d5a9a2ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A2=81=E6=9D=B0?= <15582361+Gu___Lian@user.noreply.gitee.com> Date: Sun, 17 Aug 2025 16:01:24 +0800 Subject: [PATCH 1/4] sle_tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 梁杰 <15582361+Gu___Lian@user.noreply.gitee.com> --- vendor/developers/demo/sle_tag/CMakeLists.txt | 10 + vendor/developers/demo/sle_tag/README.md | 9 + vendor/developers/demo/sle_tag/sle_client.c | 379 +++++++++++ vendor/developers/demo/sle_tag/sle_server.c | 643 ++++++++++++++++++ vendor/developers/demo/sle_tag/sle_server.h | 162 +++++ 5 files changed, 1203 insertions(+) create mode 100644 vendor/developers/demo/sle_tag/CMakeLists.txt create mode 100644 vendor/developers/demo/sle_tag/README.md create mode 100644 vendor/developers/demo/sle_tag/sle_client.c create mode 100644 vendor/developers/demo/sle_tag/sle_server.c create mode 100644 vendor/developers/demo/sle_tag/sle_server.h diff --git a/vendor/developers/demo/sle_tag/CMakeLists.txt b/vendor/developers/demo/sle_tag/CMakeLists.txt new file mode 100644 index 00000000..3cf2b2de --- /dev/null +++ b/vendor/developers/demo/sle_tag/CMakeLists.txt @@ -0,0 +1,10 @@ +list(APPEND SOURCES + "${CMAKE_CURRENT_SOURCE_DIR}/sle_client.c" +) + +# 将当前目录添加到PUBLIC_HEADER变量 +list(APPEND PUBLIC_HEADER "${CMAKE_CURRENT_SOURCE_DIR}") + +# 传递给父级作用域 +set(SOURCES ${SOURCES} PARENT_SCOPE) +set(PUBLIC_HEADER ${PUBLIC_HEADER} PARENT_SCOPE) \ No newline at end of file diff --git a/vendor/developers/demo/sle_tag/README.md b/vendor/developers/demo/sle_tag/README.md new file mode 100644 index 00000000..bb72bf0f --- /dev/null +++ b/vendor/developers/demo/sle_tag/README.md @@ -0,0 +1,9 @@ +sle_tag是一个基于 Hispark ws63 开发板的测距报警器项目,通过星闪通信和RSSI值的测量与后处理,实现测距和警报。 + +# 项目概述 + +本项目实现了基于星闪通信的测距警报系统,通过采集星闪通信的RSSI值,判定信号强度,间接得到两块Hispark ws63 开发板间的距离。同时,为了使测距更加准确,本项目对得到的RSSI值进行了一系列处理,包括通过标定以得到RSSI值与实际距离的数学关系式,通过一阶高斯滤波得到更准确的RSSI值。 + +# 其他细节 + +需要通过修改CMakeLists.txt来决定烧录的是server端还是client端代码。 \ No newline at end of file diff --git a/vendor/developers/demo/sle_tag/sle_client.c b/vendor/developers/demo/sle_tag/sle_client.c new file mode 100644 index 00000000..676dee6f --- /dev/null +++ b/vendor/developers/demo/sle_tag/sle_client.c @@ -0,0 +1,379 @@ + #include + #include + #include + + #include "app_init.h" + #include "soc_osal.h" + #include "common_def.h" + #include "systick.h" + #include "securec.h" + #include "tcxo.h" + + + #include "sle_common.h" + #include "sle_device_discovery.h" + #include "sle_connection_manager.h" + #include "sle_ssap_client.h" + + +#include "pinctrl.h" +#include "gpio.h" + + + //线程参数 + #define SLE_DISTANCE_CLIENT_TASK_PRIO 26 //线程优先级 + #define SLE_DISTANCE_CLIENT_TASK_STACK_SIZE 0x2000 //线程的栈大小 + + //本地设备参数 + static uint8_t local_addr[SLE_ADDR_LEN] = {0x13, 0x67, 0x5c, 0x07, 0x00, 0x51}; //自身 mac 地址 + static uint64_t g_conn_id; //地址 + + //对端设备参数 + static uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; //待匹配的 server 端的 mac + static sle_addr_t g_remote_addr = {0}; //创建设备地址结构体,初始化为0 + + //设备发现 + #define SLE_SEEK_INTERVAL_DEFAULT 100 //扫描间隔 + #define SLE_SEEK_WINDOW_DEFAULT 100 //扫描窗口 + + //设备连接 + #define DISTANCE_DEFAULT_CONN_INTERVAL 0x14 //连接时间 + #define DISTANCE_DEFAULT_SCAN_INTERVAL 400 //扫描间隔 + #define DISTANCE_DEFAULT_SCAN_WINDOW 20 //扫描时间 + #define DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 //超时时间 + + //设备匹配 + #define SLE_MTU_SIZE_DEFAULT 1500 //链路最大传输单元 + + // SSAP 参数 + #define UUID_16BIT_LEN 2 //UUID 长度为 16 位 + #define UUID_128BIT_LEN 16 //UUID 长度为 128 位 + static ssapc_find_service_result_t g_find_service_result = {0}; //存储服务信息的全局变量 + + // 卡尔曼滤波 + static double P = 0.1; // 估算协方差 + static double G = 0; // 卡尔曼增益 + static double Q = 0.001; // 过程噪声协方差,Q增大,动态响应变快,收敛稳定性变坏 + static double R = 3; // 测量噪声协方差,R增大,动态响应变慢,收敛稳定性变好 + static double Output = -20; // 卡尔曼滤波器输出 + + //卡尔曼滤波 + static double KalmanFilter(int32_t input) + { + P = P + Q; // 估算协方差方程:当前 估算协方差 = 上次更新 协方差 + 过程噪声协方差 + G = P / (P + R); // 卡尔曼增益方程:当前 卡尔曼增益 = 当前 估算协方差 / (当前 估算协方差 + 测量噪声协方差) + Output = Output + G * (input - Output); // 更新最优值方程:当前 最优值 = 当前 估算值 + 卡尔曼增益 * (当前 测量值 - 当前 估算值) + P = (1 - G) * P; // 更新 协方差 = (1 - 卡尔曼增益) * 当前 估算协方差 + return Output; + } + + /* 设备发现 */ + + //设备发现参数初始化 + void sle_start_scan(void){ + sle_seek_param_t param = {0}; + param.own_addr_type = 0; + param.filter_duplicates = 0; + param.seek_filter_policy = 0; + param.seek_phys = 1; //扫描设备所使用的PHY,1M + param.seek_type[0] = 0; //被动扫描 + param.seek_interval[0] = SLE_SEEK_INTERVAL_DEFAULT; //扫描间隔,time = N * 0.125ms + param.seek_window[0] = SLE_SEEK_WINDOW_DEFAULT; //扫描窗口,time = N * 0.125ms + sle_set_seek_param(¶m); //公开扫描参数 + sle_start_seek(); //开始公开扫描 + } + + void sle_sample_sle_enable_cbk(errcode_t status){ + if (status == 0) { + sle_start_scan(); + } + } + + void sle_sample_seek_enable_cbk(errcode_t status){ + if (status == 0) { + return; + } + } + + //检验是否是目标对象,是则将其地址存入外部变量 g_remote_addr 中 + void sle_sample_seek_result_info_cbk(sle_seek_result_info_t *seek_result_data){ //传入一个指向扫描结果的指针 + if (seek_result_data != NULL) { + if (memcmp(seek_result_data->addr.addr, mac, SLE_ADDR_LEN) == 0) { // mac 地址比较 + (void)memcpy_s(&g_remote_addr, sizeof(sle_addr_t), &seek_result_data->addr, sizeof(sle_addr_t)); //将 mac 地址存储到 addr 中 + sle_stop_seek(); //停止扫描 + } + } + } + + void sle_sample_seek_disable_cbk(errcode_t status){ + if (status == 0) { + sle_connect_remote_device(&g_remote_addr); //发送连接请求 + } + } + + //注册设备发现回调函数 + static void sle_init(void){ + static sle_announce_seek_callbacks_t g_seek_cbk = {0}; + g_seek_cbk.sle_enable_cb = sle_sample_sle_enable_cbk; // sle 协议栈回调函数使能 + g_seek_cbk.seek_enable_cb = sle_sample_seek_enable_cbk; //扫描回调函数使能 + g_seek_cbk.seek_result_cb = sle_sample_seek_result_info_cbk; //根据结果关闭回调函数 + g_seek_cbk.seek_disable_cb = sle_sample_seek_disable_cbk; //关闭扫描回调函数 + sle_announce_seek_register_callbacks(&g_seek_cbk); + } + + + + /* 设备连接 */ + + //连接参数 + void sle_distance_connect_param_init(void) + { + sle_default_connect_param_t param = {0}; + param.enable_filter_policy = 0; //不过滤 + param.gt_negotiate = 0; //gt交互 + param.initiate_phys = 1; //通信带宽 + param.max_interval = DISTANCE_DEFAULT_CONN_INTERVAL; //最大连接间隔 + param.min_interval = DISTANCE_DEFAULT_CONN_INTERVAL; //最小连接间隔 + param.scan_interval = DISTANCE_DEFAULT_SCAN_INTERVAL; //扫描时间间隔 + param.scan_window = DISTANCE_DEFAULT_SCAN_WINDOW; //扫描时间 + param.timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; //超时时间 + sle_default_connection_param_set(¶m); + } + + void sle_sample_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr,sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) + { + osal_printk("[ssap client] conn state changed conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0],addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + osal_printk("[ssap client] conn state changed disc_reason:0x%x\n", disc_reason); + if (conn_state == SLE_ACB_STATE_CONNECTED) { //设备已连接 + if (pair_state == SLE_PAIR_NONE) { //未匹配则发起匹配 + sle_pair_remote_device(&g_remote_addr); + } + g_conn_id = conn_id; + } + } + + void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) + { + unused(conn_id); + unused(status); + osal_printk("[ssap client] sle_sample_update_req_cbk interval_min = %02x, interval_max = %02x\n",param->interval_min, param->interval_max); + } + + void sle_sample_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) + { + osal_printk("[ssap client] pair complete conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0],addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + if (status == 0) { //是否配对成功 + ssap_exchange_info_t info = {0}; + info.mtu_size = SLE_MTU_SIZE_DEFAULT; + info.version = 1; + ssapc_exchange_info_req(1, g_conn_id, &info); //发送链路连接请求,配置连接参数 + } + } + + void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) + { + unused(status); + osal_printk("[ssap client] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); + } + + //回调函数内容,每次调用读取rssi的函数之后会挑战到该回调函数 +void sle_sample_read_rssi_cbk(uint16_t conn_id, int8_t rssi, errcode_t status) +{ + unused(conn_id); + unused(status); + int32_t rssi_k; + double distance; + rssi_k = (int32_t)KalmanFilter(rssi*100); + distance = 1.0933 - 1.0933 * 0.001 * rssi_k + 1.0933 * (0.001 * 0.001 * rssi_k * rssi_k) / 2 - 1.0933 * (0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k) / 6 + 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k) / 24- 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k* rssi_k * rssi_k) / 120 + 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k) / 720 - 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k) / 5040; + osal_printk("rssi: %d rssi_k:%d distance:%d\r\n",rssi*100,(int32_t)rssi_k,(int32_t)distance); + if(distance > 5) + { + uapi_gpio_set_val(2, GPIO_LEVEL_HIGH); // 超过5cm,蜂鸣器发出警报 + } + else + { + uapi_gpio_set_val(2, GPIO_LEVEL_LOW); + } +} + + //连接设备连接回调函数 + void sle_sample_connect_cbk_register(void) + { + static sle_connection_callbacks_t g_connect_cbk = {0}; + g_connect_cbk.connect_state_changed_cb = sle_sample_connect_state_changed_cbk; //连接状态改变 + g_connect_cbk.connect_param_update_req_cb = sle_sample_update_req_cbk; //请求连接参数更新 + g_connect_cbk.pair_complete_cb = sle_sample_pair_complete_cbk; //配对完成 + g_connect_cbk.connect_param_update_cb = sle_sample_update_cbk; //更新连接参数(已完成) + g_connect_cbk.read_rssi_cb = sle_sample_read_rssi_cbk; //读取rssi回调函数 + sle_connection_register_callbacks(&g_connect_cbk); + } + + + /* SSAP client */ + + //更新mtu大小,启动服务发现 + void sle_sample_exchange_info_cbk(uint8_t client_id, uint16_t conn_id, ssap_exchange_info_t *param,errcode_t status) + { + osal_printk("[ssap client] pair complete client id:%d status:%d\n", client_id, status); + osal_printk("[ssap client] exchange mtu, mtu size: %d, version: %d.\n",param->mtu_size, param->version); + + //服务发现 + ssapc_find_structure_param_t find_param = {0}; + find_param.type = SSAP_FIND_TYPE_PRIMARY_SERVICE; //寻找指定的服务 + find_param.start_hdl = 1; //起始句柄 + find_param.end_hdl = 0xFFFF; //结束句柄 + + //调用服务发现函数 + ssapc_find_structure(0, conn_id, &find_param); + } + + //为应用层提供信息 + void sle_sample_find_structure_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_service_result_t *service,errcode_t status) + { + osal_printk("[ssap client] find structure cbk client: %d conn_id:%d status: %d \n",client_id, conn_id, status); + osal_printk("[ssap client] find structure start_hdl:[0x%02x], end_hdl:[0x%02x], uuid len:%d\r\n",service->start_hdl, service->end_hdl, service->uuid.len); + if (service->uuid.len == UUID_16BIT_LEN) {osal_printk("[ssap client] structure uuid:[0x%02x][0x%02x]\r\n",service->uuid.uuid[14], service->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] structure uuid[%d]:[0x%02x]\r\n", idx, service->uuid.uuid[idx]); + } + } + + //保存服务信息到全局变量 + g_find_service_result.start_hdl = service->start_hdl; + g_find_service_result.end_hdl = service->end_hdl; + memcpy_s(&g_find_service_result.uuid, sizeof(sle_uuid_t), &service->uuid, sizeof(sle_uuid_t)); + } + + //处理服务或特征发现完成的事件,发送数据到对端设备 + void sle_sample_find_structure_cmp_cbk(uint8_t client_id, uint16_t conn_id,ssapc_find_structure_result_t *structure_result, errcode_t status) + { + osal_printk("[ssap client] find structure cmp cbk client id:%d status:%d type:%d uuid len:%d \r\n",client_id, status, structure_result->type, structure_result->uuid.len); + if (structure_result->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] find structure cmp cbk structure uuid:[0x%02x][0x%02x]\r\n",structure_result->uuid.uuid[14], structure_result->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] find structure cmp cbk structure uuid[%d]:[0x%02x]\r\n", idx,structure_result->uuid.uuid[idx]); + } + } + + //构造一个写操作(发送操作) + uint8_t data[] = {0x11, 0x22, 0x33, 0x44}; + uint8_t len = sizeof(data); + ssapc_write_param_t param = {0}; + param.handle = g_find_service_result.start_hdl; //写操作的目标句柄 + param.type = SSAP_PROPERTY_TYPE_VALUE; //写类型 + param.data_len = len; //数据长度 + param.data = data; //写入数据 + ssapc_write_req(0, conn_id, ¶m); //发起写申请 + } + + //写操作完成确认函数 + void sle_sample_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_write_result_t *write_result,errcode_t status) + { + osal_printk("[ssap client] write cfm cbk, client id: %d status:%d.\n", client_id, status); + ssapc_read_req(0, conn_id, write_result->handle, write_result->type); + } + + //发现特征回调函数 + void sle_sample_find_property_cbk(uint8_t client_id, uint16_t conn_id,ssapc_find_property_result_t *property, errcode_t status) + { + osal_printk("[ssap client] find property cbk, client id: %d, conn id: %d, operate ind: %d, ""descriptors count: %d status:%d.\n", client_id, conn_id, property->operate_indication,property->descriptors_count, status); + for (uint16_t idx = 0; idx < property->descriptors_count; idx++) { + osal_printk("[ssap client] find property cbk, descriptors type [%d]: 0x%02x.\n",idx, property->descriptors_type[idx]); + } + if (property->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] find property cbk, uuid: %02x %02x.\n",property->uuid.uuid[14], property->uuid.uuid[15]); /* 14 15: uuid index */ + } else if (property->uuid.len == UUID_128BIT_LEN) { + for (uint16_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] find property cbk, uuid [%d]: %02x.\n",idx, property->uuid.uuid[idx]); + } + } + } + + //解析读取数据并打印 + void sle_sample_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *read_data,errcode_t status) + { + osal_printk("[ssap client] read cfm cbk client id: %d conn id: %d status: %d\n",client_id, conn_id, status); + osal_printk("[ssap client] read cfm cbk handle: %d, type: %d , len: %d\n",read_data->handle, read_data->type, read_data->data_len); + for (uint16_t idx = 0; idx < read_data->data_len; idx++) { + osal_printk("[ssap client] read cfm cbk[%d] 0x%02x\r\n", idx, read_data->data[idx]); + } + } + + static void sle_distance_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, + errcode_t status) + { + unused(status); + unused(conn_id); + unused(client_id); + osal_printk("\n sle_distance_indication_cb sle uart recived data : %s\r\n", data->data); + } + + //ssap client回调函数 + void sle_sample_ssapc_cbk_register(ssapc_notification_callback indication_cb) + { + static ssapc_callbacks_t g_ssapc_cbk = {0}; + g_ssapc_cbk.exchange_info_cb = sle_sample_exchange_info_cbk; //更新mtu大小回调钩子,启动服务发现 + g_ssapc_cbk.find_structure_cb = sle_sample_find_structure_cbk; //发现服务回调函数,为应用层提供信息 + g_ssapc_cbk.find_structure_cmp_cb = sle_sample_find_structure_cmp_cbk; //发现特征完成回调函数,完成写操作 + g_ssapc_cbk.write_cfm_cb = sle_sample_write_cfm_cbk; //写操作完成确认函数 + g_ssapc_cbk.ssapc_find_property_cbk = sle_sample_find_property_cbk; //发现特征回调函数. + g_ssapc_cbk.read_cfm_cb = sle_sample_read_cfm_cbk; //解析读取数据并打印 + g_ssapc_cbk.indication_cb = indication_cb; //指示事件上报钩子 + ssapc_register_callbacks(&g_ssapc_cbk); + } + + + + /* 主函数 */ + static int sle_distance_client_task(const char *arg) + { + unused(arg); + + sle_addr_t local_address; + local_address.type = 0; + (void)memcpy_s(local_address.addr, SLE_ADDR_LEN, local_addr, SLE_ADDR_LEN); + + sle_init(); + sle_distance_connect_param_init(); + sle_sample_connect_cbk_register(); + sle_sample_ssapc_cbk_register(sle_distance_indication_cb); + enable_sle(); + sle_set_local_addr(&local_address); + uapi_pin_set_mode(2, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir(2, GPIO_DIRECTION_OUTPUT); // 蜂鸣器的正极连接到微控制器的数字输出引脚,蜂鸣器的负极连接到微控制器的GND引脚 + uapi_gpio_set_val(2, GPIO_LEVEL_LOW); + osal_msleep(1000); + //主函数中调用读取rssi的函数 + while (1) + { + sle_read_remote_device_rssi(g_conn_id); + osal_msleep(1000); + } + + return 0; + } + + + + //创建运行任务的线程并进行初始化 + static void sle_distance_client_entry(void) + { + osal_task *task_handle = NULL; + osal_kthread_lock(); //加锁 + + //创建线程 + task_handle = osal_kthread_create((osal_kthread_handler)sle_distance_client_task, 0, "Sle_Distance_Task", SLE_DISTANCE_CLIENT_TASK_STACK_SIZE); + + if (task_handle != NULL) { + //设置优先级 + osal_kthread_set_priority(task_handle, SLE_DISTANCE_CLIENT_TASK_PRIO);// + osal_kfree(task_handle); //释放内存 + } + + osal_kthread_unlock(); //解锁 + } + + //运行该app + app_run(sle_distance_client_entry); diff --git a/vendor/developers/demo/sle_tag/sle_server.c b/vendor/developers/demo/sle_tag/sle_server.c new file mode 100644 index 00000000..bc903417 --- /dev/null +++ b/vendor/developers/demo/sle_tag/sle_server.c @@ -0,0 +1,643 @@ + #include "app_init.h" + #include "watchdog.h" + #include "tcxo.h" + #include "systick.h" + #include "los_memory.h" + #include "securec.h" + #include "errcode.h" + #include "osal_addr.h" + #include "soc_osal.h" + #include "common_def.h" + + #include "sle_common.h" + #include "sle_errcode.h" + #include "sle_ssap_server.h" + #include "sle_connection_manager.h" + #include "sle_device_discovery.h" + #include "sle_transmition_manager.h" + #include "nv.h" + + #include "sle_server.h" + + //线程参数 + #define DISTANCE_DEFAULT_KTHREAD_SIZE 0x2000 + #define DISTANCE_DEFAULT_KTHREAD_PROI 26 + + //本地设备参数 + #define NAME_MAX_LENGTH 30 + static uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; + static uint8_t sle_local_name[NAME_MAX_LENGTH] = "sle_connect_server"; + //数据包长度 + #define PKT_DATA_LEN 600 + static unsigned char data[PKT_DATA_LEN]; + //确保为小端格式存储 + #define encode2byte_little(_ptr, data) \ + do { \ + *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \ + *(uint8_t *)(_ptr) = (uint8_t)(data); \ + } while (0) + + //设备公开 + #define SLE_CONN_INTV_MIN_DEFAULT 0xA //连接最小调度间隔12.5ms,单位125us + #define SLE_CONN_INTV_MAX_DEFAULT 0xA //连接最大调度间隔12.5ms,单位125us + #define SLE_ADV_INTERVAL_MIN_DEFAULT 0xC8 //连接调度间隔25ms,单位125us + #define SLE_ADV_INTERVAL_MAX_DEFAULT 0xC8 //超时时间5000ms,单位10ms + #define SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT 0x1F4 //超时时间4990ms,单位10ms + #define SLE_CONN_MAX_LATENCY 0x1F3 //广播发送功率 + #define SLE_ADV_TX_POWER 20 //最大广播数据长度 + #define SLE_ADV_DATA_LEN_MAX 251 + + //设备连接 + + #define DISTANCE_DEFAULT_CONN_INTERVAL 0xA0 + #define DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 + #define DISTANCE_DEFAULT_SCAN_INTERVAL 400 + #define DISTANCE_DEFAULT_SCAN_WINDOW 20 + //蓝牙地址索引 + #define BT_INDEX_4 4 + #define BT_INDEX_5 5 + #define BT_INDEX_0 0 + + static uint16_t g_conn_id = 0; + + // SSAP 参数 + #define OCTET_BIT_LEN 8 //8比特长度 + #define UUID_LEN_2 2 //两个字节 + static char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0}; + static char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + + //传输参数 + #define DEFAULT_SLE_DISTANCE_DATA_LEN 1500 + #define DEFAULT_SLE_DISTANCE_MTU_SIZE 1500 + static uint8_t g_server_id = 0; + static uint16_t g_service_handle = 0; + static uint16_t g_property_handle = 0; + static uint8_t sle_uuid_base[] = { 0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + extern uint8_t gle_tx_acb_data_num_get(void); + + + + /* 检查 BTC 功率档位 */ + + void sle_distance_server_set_nv(void) + { + uint16_t nv_value_len = 0; + uint8_t nv_value = 0; + + //读取指定NV数据项的值 + uapi_nv_read(0x20A0, sizeof(uint16_t), &nv_value_len, &nv_value); + if (nv_value != 7) { // 7:btc功率档位 + nv_value = 7; // 7:btc功率档位 + + //写入NV数据项 + uapi_nv_write(0x20A0, (uint8_t *)&(nv_value), sizeof(nv_value)); + } + osal_printk("[distance server] The value of nv is set to %d.\r\n", nv_value); + } + + + + /* 本地设备参数 */ + + //设置本端 MAC 地址 + void sle_set_local_addr_init(void) + { + sle_addr_t addr = {0}; + addr.type = 0; + memcpy_s(addr.addr, SLE_ADDR_LEN, mac, SLE_ADDR_LEN); + sle_set_local_addr(&addr); + } + + //设置本端名称 + static uint16_t sle_set_adv_local_name(uint8_t *adv_data, uint16_t max_len) + { + errno_t ret; + uint8_t index = 0; + + uint8_t *local_name = sle_local_name; + uint8_t local_name_len = (uint8_t)strlen((char *)local_name); + for (uint8_t i = 0; i < local_name_len; i++) { + osal_printk("local_name[%d] = 0x%02x\r\n", i, local_name[i]); + } + + adv_data[index++] = local_name_len + 1; + adv_data[index++] = SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME; + ret = memcpy_s(&adv_data[index], max_len - index, local_name, local_name_len); + if (ret != EOK) { + osal_printk("memcpy fail\r\n"); + return 0; + } + return (uint16_t)index + local_name_len; + } + + + + /* 设备公开 */ + + //设备公开参数 + static int sle_set_default_announce_param(void) + { + //初始化 + sle_announce_param_t param = {0}; + param.announce_mode = SLE_ANNOUNCE_MODE_CONNECTABLE_SCANABLE; //公开类型 + param.announce_handle = SLE_ADV_HANDLE_DEFAULT; //公开句柄 + param.announce_gt_role = SLE_ANNOUNCE_ROLE_T_CAN_NEGO; //gt角色协商指示 + param.announce_level = SLE_ANNOUNCE_LEVEL_NORMAL; //发现等级 + param.announce_channel_map = SLE_ADV_CHANNEL_MAP_DEFAULT; //设备公开信道 + param.announce_interval_min = SLE_ADV_INTERVAL_MIN_DEFAULT; //最小设备公开周期 + param.announce_interval_max = SLE_ADV_INTERVAL_MAX_DEFAULT; //最大设备公开周期 + param.conn_interval_min = SLE_CONN_INTV_MIN_DEFAULT; //连接间隔最小取值 + param.conn_interval_max = SLE_CONN_INTV_MAX_DEFAULT; //连接间隔最大取值 + param.conn_max_latency = SLE_CONN_MAX_LATENCY; //最大休眠连接间隔 + param.conn_supervision_timeout = SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT; //最大超时时间 + param.announce_tx_power = SLE_ADV_TX_POWER; //广播发射攻略 + param.own_addr.type = 0; //本端地址 + memcpy_s(param.own_addr.addr, SLE_ADDR_LEN, mac, SLE_ADDR_LEN); + + //设置参数 + return sle_set_announce_param(param.announce_handle, ¶m); + } + + void sle_enable_cbk(errcode_t status) + { + osal_printk("sle enable status:%02x\r\n", status); + } + + void sle_announce_enable_cbk(uint32_t announce_id, errcode_t status) + { + osal_printk("sle announce enable id:%02x, state:%02x\r\n", announce_id, status); + } + + void sle_announce_terminal_cbk(uint32_t announce_id) + { + osal_printk("sle announce terminal id:%02x\r\n", announce_id); + } + + void sle_announce_disable_cbk(uint32_t announce_id, errcode_t status) + { + osal_printk("sle announce disable id:%02x, state:%02x\r\n", announce_id, status); + } + + //设备公开回调函数 + void sle_announce_register_cbks(void) + { + sle_announce_seek_callbacks_t seek_cbks = {0}; + seek_cbks.sle_enable_cb = sle_enable_cbk; //SLE协议栈使能回调函数 + seek_cbks.announce_enable_cb = sle_announce_enable_cbk; //设备公开使能回调函数 + seek_cbks.announce_terminal_cb = sle_announce_terminal_cbk; //设备公开停止回调函数 + seek_cbks.announce_disable_cb = sle_announce_disable_cbk; //设备公开关闭回调函数 + sle_announce_seek_register_callbacks(&seek_cbks); //将回调函数注册到协议层 + } + + //设置广播数据 + static uint16_t sle_set_adv_data(uint8_t *adv_data) + { + size_t len = 0; + uint16_t idx = 0; + errno_t ret = 0; + + //填充设备发现级别 + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_disc_level = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL, + .value = SLE_ANNOUNCE_LEVEL_NORMAL, + }; + + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_disc_level, len); + if (ret != EOK) { + osal_printk("adv_disc_level memcpy fail\r\n"); + return 0; + } + idx += len; + + //填充访问模式 + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_access_mode = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_ACCESS_MODE, + .value = 0, + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_access_mode, len); + if (ret != EOK) { + osal_printk("memcpy fail\r\n"); + return 0; + } + idx += len; + return idx; + } + + + static uint16_t sle_set_scan_response_data(uint8_t *scan_rsp_data) + { + uint16_t idx = 0; + errno_t ret; + size_t scan_rsp_data_len = sizeof(struct sle_adv_common_value); + + struct sle_adv_common_value tx_power_level = { + .length = scan_rsp_data_len - 1, + .type = SLE_ADV_DATA_TYPE_TX_POWER_LEVEL, + .value = SLE_ADV_TX_POWER, + }; + ret = memcpy_s(scan_rsp_data, SLE_ADV_DATA_LEN_MAX, &tx_power_level, scan_rsp_data_len); + if (ret != EOK) { + osal_printk("sle scan response data memcpy fail\r\n"); + return 0; + } + idx += scan_rsp_data_len; + + /* set local name */ + idx += sle_set_adv_local_name(&scan_rsp_data[idx], SLE_ADV_DATA_LEN_MAX - idx); + return idx; + } + + static int sle_set_default_announce_data(void) + { + errcode_t ret; + uint8_t announce_data_len = 0; + uint8_t seek_data_len = 0; + sle_announce_data_t data = {0}; + uint8_t adv_handle = SLE_ADV_HANDLE_DEFAULT; + uint8_t announce_data[SLE_ADV_DATA_LEN_MAX] = {0}; + uint8_t seek_rsp_data[SLE_ADV_DATA_LEN_MAX] = {0}; + + osal_printk("set adv data default\r\n"); + + //设置广播数据 + announce_data_len = sle_set_adv_data(announce_data); + data.announce_data = announce_data; + data.announce_data_len = announce_data_len; + //设置扫描相应数据 + seek_data_len = sle_set_scan_response_data(seek_rsp_data); + data.seek_rsp_data = seek_rsp_data; + data.seek_rsp_data_len = seek_data_len; + //设置参数 + ret = sle_set_announce_data(adv_handle, &data); + if (ret == ERRCODE_SLE_SUCCESS) { + osal_printk("[SLE DD SDK] set announce data success."); + } else { + osal_printk("[SLE DD SDK] set adv param fail."); + } + return ERRCODE_SLE_SUCCESS; + } + + static errcode_t sle_uuid_server_adv_init(void) + { + osal_printk("sle_uuid_server_adv_init in\r\n"); + + sle_announce_register_cbks(); + sle_set_default_announce_param(); + sle_set_default_announce_data(); + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); //开始设备公开 + osal_printk("sle_uuid_server_adv_init out\r\n"); + return ERRCODE_SLE_SUCCESS; + } + + // ssap 信息交换设置 + void sle_ssaps_set_info(void) + { + ssap_exchange_info_t info = {0}; + info.mtu_size = DEFAULT_SLE_DISTANCE_MTU_SIZE; + info.version = 1; + ssaps_set_info(g_server_id, &info); + } + + /* 设备连接 */ + + //连接参数 + void sle_distance_connect_param_init(void) + { + sle_default_connect_param_t param = {0}; + param.enable_filter_policy = 0; //过滤功能 + param.gt_negotiate = 0; + param.initiate_phys = 1; + param.max_interval = DISTANCE_DEFAULT_CONN_INTERVAL; + param.min_interval = DISTANCE_DEFAULT_CONN_INTERVAL; + param.scan_interval = DISTANCE_DEFAULT_SCAN_INTERVAL; + param.scan_window = DISTANCE_DEFAULT_SCAN_WINDOW; + param.timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; + sle_default_connection_param_set(¶m); + } + + //连接状态改变回调函数 + static void sle_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, + sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) + { + osal_printk("[distance server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \ + disc_reason:0x%x\r\n", conn_id, conn_state, pair_state, disc_reason); + osal_printk("[distance server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", + addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); + g_conn_id = conn_id; + sle_connection_param_update_t parame = {0}; + parame.conn_id = conn_id; + parame.interval_min = DISTANCE_DEFAULT_CONN_INTERVAL; + parame.interval_max = DISTANCE_DEFAULT_CONN_INTERVAL; + parame.max_latency = 0; + parame.supervision_timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; + if (conn_state == SLE_ACB_STATE_CONNECTED) { + sle_update_connect_param(¶me); + } else if (conn_state == SLE_ACB_STATE_DISCONNECTED) { + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); + } + } + + //连接参数请求更新回调函数 + void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) + { + unused(conn_id); + unused(status); + osal_printk("[ssap server] sle_sample_update_req_cbk interval_min:%02x, interval_max:%02x\n", + param->interval_min, param->interval_max); + } + + //连接参数更新完成回调函数 + void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) + { + unused(status); + osal_printk("[ssap server] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); + } + + //配对完成回调函数 + static void sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) + { + osal_printk("[distance server] pair complete conn_id:%02x, status:%x\r\n", + conn_id, status); + osal_printk("[distance server] pair complete addr:%02x:**:**:**:%02x:%02x\r\n", + addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); + } + + static void sle_conn_register_cbks(void) + { + sle_connection_callbacks_t conn_cbks = {0}; + conn_cbks.connect_state_changed_cb = sle_connect_state_changed_cbk; //连接状态改变回调函数 + conn_cbks.connect_param_update_req_cb = sle_sample_update_req_cbk; //连接参数请求更新回调函数 + conn_cbks.connect_param_update_cb = sle_sample_update_cbk; //连接参数更新完成回调函数 + conn_cbks.pair_complete_cb = sle_pair_complete_cbk; //配对完成回调函数 + sle_connection_register_callbacks(&conn_cbks); //将回调函数结构体注册到协议层 + } + + + + /* SSAP server */ + + //启动服务回调函数 + static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status) + { + osal_printk("[distance server] start service cbk server_id:%d, handle:%d, status:%d\r\n", + server_id, handle, status); + } + + //mtu 大小更新回调函数 + static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, ssap_exchange_info_t *mtu_size, + errcode_t status) + { + osal_printk("[distance server] ssaps write request cbk server_id:%d, conn_id:%d, mtu_size:%d, status:%d\r\n", + server_id, conn_id, mtu_size->mtu_size, status); + } + + //发送信息 + static errcode_t sle_uuid_server_send_report_by_handle_id(uint8_t *data, uint16_t len, uint16_t connect_id) + { + ssaps_ntf_ind_t param = {0}; + param.handle = g_property_handle; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.value = data; + param.value_len = len; + + //向对端发送通知 + ssaps_notify_indicate(g_server_id, connect_id, ¶m); + return ERRCODE_SLE_SUCCESS; + } + + static uint8_t sle_flow_ctrl_flag(void) + { + return gle_tx_acb_data_num_get(); + } + + static void send_data_thread_function(void) + { + //设置最大传输长度 + sle_set_data_len(g_conn_id, DEFAULT_SLE_DISTANCE_DATA_LEN); + + osal_printk("code: GFSK, PHY 1MHZ, power: 20dbm \r\n"); + int i = 0; + while (1) { + if (sle_flow_ctrl_flag() > 0) { + i++; + //填充数据 + data[0] = (i >> 8) & 0xFF; + data[1] = i & 0xFF; + + //发送数据包 + sle_uuid_server_send_report_by_handle_id(data, PKT_DATA_LEN, g_conn_id); + } + + } + } + + //收到远端读请求回调函数 + static void ssaps_read_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para, + errcode_t status) + { + osal_printk("[distance server] ssaps read request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n",server_id, conn_id, read_cb_para->handle, status); + + //创建新线程完成发送任务 + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)send_data_thread_function,0, "RadarTask", DISTANCE_DEFAULT_KTHREAD_SIZE); + osal_kthread_set_priority(task_handle, DISTANCE_DEFAULT_KTHREAD_PROI + 1); + if (task_handle != NULL) { + osal_kfree(task_handle); + } + osal_kthread_unlock(); + printf("kthread success\r\n"); + } + + //收到远端写请求回调函数 + static void ssaps_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para, + errcode_t status) + { + osal_printk("[distance server] ssaps write request cbk server_id:%d, conn_id:%d, handle:%d, status:%d\r\n", + server_id, conn_id, write_cb_para->handle, status); + } + + //注册 ssap server 回调 + static void sle_ssaps_register_cbks(void) + { + ssaps_callbacks_t ssaps_cbk = {0}; + ssaps_cbk.start_service_cb = ssaps_start_service_cbk; //启动服务回调函数 + ssaps_cbk.mtu_changed_cb = ssaps_mtu_changed_cbk; //mtu 大小更新回调函数 + ssaps_cbk.read_request_cb = ssaps_read_request_cbk; //收到远端读请求回调函数 + ssaps_cbk.write_request_cb = ssaps_write_request_cbk; //收到远端写请求回调函数 + ssaps_register_callbacks(&ssaps_cbk); + } + + //复制128-bit UUID 到结构体 + static void sle_uuid_set_base(sle_uuid_t *out) + { + (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN); + out->len = UUID_LEN_2; + } + + //将 uuid 转换为小端格式 + static void sle_uuid_setu2(uint16_t u2, sle_uuid_t *out) + { + sle_uuid_set_base(out); + out->len = UUID_LEN_2; + encode2byte_little(&out->uuid[14], u2); + } + + static errcode_t sle_uuid_server_service_add(void) + { + errcode_t ret; + sle_uuid_t service_uuid = {0}; + sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid); + //添加一个ssap服务 + ret = ssaps_add_service_sync(g_server_id, &service_uuid, 1, &g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[distance server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + return ERRCODE_SLE_SUCCESS; + } + + static errcode_t sle_uuid_server_property_add(void) + { + errcode_t ret; + ssaps_property_info_t property = {0}; + ssaps_desc_info_t descriptor = {0}; + uint8_t ntf_value[] = {0x01, 0x0}; + + //添加特征信息 + property.permissions = SLE_UUID_TEST_PROPERTIES; //特征权限 + sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid); //SSAP 特征 UUID + property.value = osal_vmalloc(sizeof(g_sle_property_value)); //响应的数据 + property.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_NOTIFY; //操作指示 + if (property.value == NULL) { + osal_printk("[distance server] sle property mem fail\r\n"); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, + sizeof(g_sle_property_value)) != EOK) { + osal_vfree(property.value); + osal_printk("[distance server] sle property mem cpy fail\r\n"); + return ERRCODE_SLE_FAIL; + } + + //添加一个ssap特征 + ret = ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[distance server] sle uuid add property fail, ret:%x\r\n", ret); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + + descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR; //特征权限 + descriptor.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_WRITE; //操作指示 + descriptor.type = SSAP_DESCRIPTOR_USER_DESCRIPTION; //描述符类型 + descriptor.value = ntf_value; //数据 + descriptor.value_len = sizeof(ntf_value); + + //添加一个ssap特征描述符 + ret = ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[distance server] sle uuid add descriptor fail, ret:%x\r\n", ret); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + osal_vfree(property.value); + return ERRCODE_SLE_SUCCESS; + } + + //创建 server 实体 + static errcode_t sle_uuid_server_add(void) + { + errcode_t ret; + sle_uuid_t app_uuid = {0}; + + osal_printk("[distance server] sle uuid add service in\r\n"); + app_uuid.len = sizeof(g_sle_uuid_app_uuid); //设置 uuid 长度 + if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK) { + return ERRCODE_SLE_FAIL; + } + //注册ssap服务端 + ssaps_register_server(&app_uuid, &g_server_id); + + //若添加服务失败则注销服务端 + if (sle_uuid_server_service_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + + //若添加特征失败则注销服务端 + if (sle_uuid_server_property_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + + osal_printk("[distance server] sle uuid add service, server_id:%x, service_handle:%x, property_handle:%x\r\n", + g_server_id, g_service_handle, g_property_handle); + + //开始一个SSAP服务 + ret = ssaps_start_service(g_server_id, g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[distance server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + osal_printk("[distance server] sle uuid add service out\r\n"); + return ERRCODE_SLE_SUCCESS; + } + + + + + /* 初始化distance server */ + + errcode_t sle_distance_server_init(void) + { + uapi_watchdog_disable(); + enable_sle(); + printf("sle enable\r\n"); + sle_distance_server_set_nv(); + sle_conn_register_cbks(); + sle_ssaps_register_cbks(); + sle_uuid_server_add(); + sle_uuid_server_adv_init(); + sle_ssaps_set_info(); + sle_distance_connect_param_init(); + sle_set_local_addr_init(); + osal_printk("[distance server] init ok\r\n"); + return ERRCODE_SLE_SUCCESS; + } + + + + /* 函数入口 */ + int sle_distance_init(void) + { + //初始化全局变量 data + for (int i = 0; i < PKT_DATA_LEN; i++) { + data[i] = 'A'; + data[PKT_DATA_LEN - 1] = '\0'; //最后一个字节填充空字符,作为字符串的结尾标识 + } + osal_msleep(1000); //休眠1s + sle_distance_server_init(); + + + return 0; + } + + /* 线程与优先级设置 */ + static void sle_distance_entry(void) + { + osal_task *task_handle1 = NULL; + osal_kthread_lock(); + task_handle1= osal_kthread_create((osal_kthread_handler)sle_distance_init, 0, "distance", DISTANCE_DEFAULT_KTHREAD_SIZE); + if (task_handle1 != NULL) { + osal_kthread_set_priority(task_handle1, DISTANCE_DEFAULT_KTHREAD_PROI); + osal_kfree(task_handle1); + } + osal_kthread_unlock(); + } + + app_run(sle_distance_entry); diff --git a/vendor/developers/demo/sle_tag/sle_server.h b/vendor/developers/demo/sle_tag/sle_server.h new file mode 100644 index 00000000..0a0a9b25 --- /dev/null +++ b/vendor/developers/demo/sle_tag/sle_server.h @@ -0,0 +1,162 @@ + /** + * @defgroup bluetooth_sle_adv API + * @ingroup + * @{ + */ + + #ifndef SLE_SERVER_ADV_H + #define SLE_SERVER_ADV_H + + #include "sle_ssap_server.h" + + /* 广播ID */ + #define SLE_ADV_HANDLE_DEFAULT 1 + + /** + * @if Eng + * @brief Definitaion of BLE ADV 通用广播结构. + * @else + * @brief SLE 广播普通数据结构。 + * @endif + */ + struct sle_adv_common_value { + uint8_t length; + uint8_t type; + uint8_t value; + }; + + /** + * @if Eng + * @brief Definitaion of BLE ADV Channel mapping. + * @else + * @brief SLE 广播信道映射。 + * @endif + */ + typedef enum { + SLE_ADV_CHANNEL_MAP_77 = 0x01, + SLE_ADV_CHANNEL_MAP_78 = 0x02, + SLE_ADV_CHANNEL_MAP_79 = 0x04, + SLE_ADV_CHANNEL_MAP_DEFAULT = 0x07 + } sle_adv_channel_map; + + /** + * @if Eng + * @brief Definitaion of SLE ADV Data Type. + * @else + * @brief SLE 广播数据类型 + * @endif + */ + typedef enum { + SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL = 0x01, /*!< 发现等级 */ + SLE_ADV_DATA_TYPE_ACCESS_MODE = 0x02, /*!< 接入层能力 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_16BIT_UUID = 0x03, /*!< 标准服务数据信息 */ + SLE_ADV_DATA_TYPE_SERVICE_DATA_128BIT_UUID = 0x04, /*!< 自定义服务数据信息 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x05, /*!< 完整标准服务标识列表 */ + SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x06, /*!< 完整自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x07, /*!< 部分标准服务标识列表 */ + SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x08, /*!< 部分自定义服务标识列表 */ + SLE_ADV_DATA_TYPE_SERVICE_STRUCTURE_HASH_VALUE = 0x09, /*!< 服务结构散列值 */ + SLE_ADV_DATA_TYPE_SHORTENED_LOCAL_NAME = 0x0A, /*!< 设备缩写本地名称 */ + SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME = 0x0B, /*!< 设备完整本地名称 */ + SLE_ADV_DATA_TYPE_TX_POWER_LEVEL = 0x0C, /*!< 广播发送功率 */ + SLE_ADV_DATA_TYPE_SLB_COMMUNICATION_DOMAIN = 0x0D, /*!< SLB通信域域名 */ + SLE_ADV_DATA_TYPE_SLB_MEDIA_ACCESS_LAYER_ID = 0x0E, /*!< SLB媒体接入层标识 */ + SLE_ADV_DATA_TYPE_EXTENDED = 0xFE, /*!< 数据类型扩展 */ + SLE_ADV_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF /*!< 厂商自定义信息 */ + } sle_adv_data_type; + + + /** + * @if Eng + * @brief sle adv data config. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle广播数据配置。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ + static errcode_t sle_uuid_server_adv_init(void); + + + + /* Service UUID */ + #define SLE_UUID_SERVER_SERVICE 0xABCD + + /* Property UUID */ + #define SLE_UUID_SERVER_NTF_REPORT 0x1122 + + /* Property Property */ + #define SLE_UUID_TEST_PROPERTIES (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + + /* Descriptor Property */ + #define SLE_UUID_TEST_DESCRIPTOR (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + + /** + * @if Eng + * @brief SLE uuid server inir. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief SLE UUID服务器初始化。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ + errcode_t sle_uuid_server_init(void); + + /** + * @if Eng + * @brief send data to peer device by uuid on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ + errcode_t sle_uuid_server_send_report_by_uuid(uint8_t *data, uint16_t len); + + /** + * @if Eng + * @brief send data to peer device by handle on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ + errcode_t sle_uuid_server_send_report_by_handle(const uint8_t *data, uint8_t len); + #endif -- Gitee From 53c481f26c91c6099039c76e1e8e7612e40fe5c9 Mon Sep 17 00:00:00 2001 From: Kid <3548263564@qq.com> Date: Sun, 17 Aug 2025 09:03:27 +0000 Subject: [PATCH 2/4] update vendor/developers/demo/sle_tag/sle_client.c. Signed-off-by: Kid <3548263564@qq.com> --- vendor/developers/demo/sle_tag/sle_client.c | 763 ++++++++++---------- 1 file changed, 400 insertions(+), 363 deletions(-) diff --git a/vendor/developers/demo/sle_tag/sle_client.c b/vendor/developers/demo/sle_tag/sle_client.c index 676dee6f..cf634e09 100644 --- a/vendor/developers/demo/sle_tag/sle_client.c +++ b/vendor/developers/demo/sle_tag/sle_client.c @@ -1,379 +1,416 @@ - #include - #include - #include - - #include "app_init.h" - #include "soc_osal.h" - #include "common_def.h" - #include "systick.h" - #include "securec.h" - #include "tcxo.h" - - - #include "sle_common.h" - #include "sle_device_discovery.h" - #include "sle_connection_manager.h" - #include "sle_ssap_client.h" - - +#include +#include +#include + +#include "app_init.h" +#include "soc_osal.h" +#include "common_def.h" +#include "systick.h" +#include "securec.h" +#include "tcxo.h" + +#include "sle_common.h" +#include "sle_device_discovery.h" +#include "sle_connection_manager.h" +#include "sle_ssap_client.h" + #include "pinctrl.h" #include "gpio.h" - - - //线程参数 - #define SLE_DISTANCE_CLIENT_TASK_PRIO 26 //线程优先级 - #define SLE_DISTANCE_CLIENT_TASK_STACK_SIZE 0x2000 //线程的栈大小 - - //本地设备参数 - static uint8_t local_addr[SLE_ADDR_LEN] = {0x13, 0x67, 0x5c, 0x07, 0x00, 0x51}; //自身 mac 地址 - static uint64_t g_conn_id; //地址 - - //对端设备参数 - static uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; //待匹配的 server 端的 mac - static sle_addr_t g_remote_addr = {0}; //创建设备地址结构体,初始化为0 - - //设备发现 - #define SLE_SEEK_INTERVAL_DEFAULT 100 //扫描间隔 - #define SLE_SEEK_WINDOW_DEFAULT 100 //扫描窗口 - - //设备连接 - #define DISTANCE_DEFAULT_CONN_INTERVAL 0x14 //连接时间 - #define DISTANCE_DEFAULT_SCAN_INTERVAL 400 //扫描间隔 - #define DISTANCE_DEFAULT_SCAN_WINDOW 20 //扫描时间 - #define DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 //超时时间 - - //设备匹配 - #define SLE_MTU_SIZE_DEFAULT 1500 //链路最大传输单元 - - // SSAP 参数 - #define UUID_16BIT_LEN 2 //UUID 长度为 16 位 - #define UUID_128BIT_LEN 16 //UUID 长度为 128 位 - static ssapc_find_service_result_t g_find_service_result = {0}; //存储服务信息的全局变量 - - // 卡尔曼滤波 - static double P = 0.1; // 估算协方差 - static double G = 0; // 卡尔曼增益 - static double Q = 0.001; // 过程噪声协方差,Q增大,动态响应变快,收敛稳定性变坏 - static double R = 3; // 测量噪声协方差,R增大,动态响应变慢,收敛稳定性变好 - static double Output = -20; // 卡尔曼滤波器输出 - - //卡尔曼滤波 - static double KalmanFilter(int32_t input) - { - P = P + Q; // 估算协方差方程:当前 估算协方差 = 上次更新 协方差 + 过程噪声协方差 - G = P / (P + R); // 卡尔曼增益方程:当前 卡尔曼增益 = 当前 估算协方差 / (当前 估算协方差 + 测量噪声协方差) - Output = Output + G * (input - Output); // 更新最优值方程:当前 最优值 = 当前 估算值 + 卡尔曼增益 * (当前 测量值 - 当前 估算值) - P = (1 - G) * P; // 更新 协方差 = (1 - 卡尔曼增益) * 当前 估算协方差 - return Output; - } - - /* 设备发现 */ - - //设备发现参数初始化 - void sle_start_scan(void){ - sle_seek_param_t param = {0}; - param.own_addr_type = 0; - param.filter_duplicates = 0; - param.seek_filter_policy = 0; - param.seek_phys = 1; //扫描设备所使用的PHY,1M - param.seek_type[0] = 0; //被动扫描 - param.seek_interval[0] = SLE_SEEK_INTERVAL_DEFAULT; //扫描间隔,time = N * 0.125ms - param.seek_window[0] = SLE_SEEK_WINDOW_DEFAULT; //扫描窗口,time = N * 0.125ms - sle_set_seek_param(¶m); //公开扫描参数 - sle_start_seek(); //开始公开扫描 - } - - void sle_sample_sle_enable_cbk(errcode_t status){ - if (status == 0) { - sle_start_scan(); - } - } - - void sle_sample_seek_enable_cbk(errcode_t status){ - if (status == 0) { - return; - } - } - - //检验是否是目标对象,是则将其地址存入外部变量 g_remote_addr 中 - void sle_sample_seek_result_info_cbk(sle_seek_result_info_t *seek_result_data){ //传入一个指向扫描结果的指针 - if (seek_result_data != NULL) { - if (memcmp(seek_result_data->addr.addr, mac, SLE_ADDR_LEN) == 0) { // mac 地址比较 - (void)memcpy_s(&g_remote_addr, sizeof(sle_addr_t), &seek_result_data->addr, sizeof(sle_addr_t)); //将 mac 地址存储到 addr 中 - sle_stop_seek(); //停止扫描 - } - } - } - - void sle_sample_seek_disable_cbk(errcode_t status){ - if (status == 0) { - sle_connect_remote_device(&g_remote_addr); //发送连接请求 - } - } - - //注册设备发现回调函数 - static void sle_init(void){ - static sle_announce_seek_callbacks_t g_seek_cbk = {0}; - g_seek_cbk.sle_enable_cb = sle_sample_sle_enable_cbk; // sle 协议栈回调函数使能 - g_seek_cbk.seek_enable_cb = sle_sample_seek_enable_cbk; //扫描回调函数使能 - g_seek_cbk.seek_result_cb = sle_sample_seek_result_info_cbk; //根据结果关闭回调函数 - g_seek_cbk.seek_disable_cb = sle_sample_seek_disable_cbk; //关闭扫描回调函数 - sle_announce_seek_register_callbacks(&g_seek_cbk); - } - - - - /* 设备连接 */ - - //连接参数 - void sle_distance_connect_param_init(void) - { - sle_default_connect_param_t param = {0}; - param.enable_filter_policy = 0; //不过滤 - param.gt_negotiate = 0; //gt交互 - param.initiate_phys = 1; //通信带宽 - param.max_interval = DISTANCE_DEFAULT_CONN_INTERVAL; //最大连接间隔 - param.min_interval = DISTANCE_DEFAULT_CONN_INTERVAL; //最小连接间隔 - param.scan_interval = DISTANCE_DEFAULT_SCAN_INTERVAL; //扫描时间间隔 - param.scan_window = DISTANCE_DEFAULT_SCAN_WINDOW; //扫描时间 - param.timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; //超时时间 - sle_default_connection_param_set(¶m); - } - - void sle_sample_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr,sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) - { - osal_printk("[ssap client] conn state changed conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0],addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ - osal_printk("[ssap client] conn state changed disc_reason:0x%x\n", disc_reason); - if (conn_state == SLE_ACB_STATE_CONNECTED) { //设备已连接 - if (pair_state == SLE_PAIR_NONE) { //未匹配则发起匹配 - sle_pair_remote_device(&g_remote_addr); - } - g_conn_id = conn_id; - } - } - - void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) - { - unused(conn_id); - unused(status); - osal_printk("[ssap client] sle_sample_update_req_cbk interval_min = %02x, interval_max = %02x\n",param->interval_min, param->interval_max); - } - - void sle_sample_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) - { - osal_printk("[ssap client] pair complete conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0],addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ - if (status == 0) { //是否配对成功 - ssap_exchange_info_t info = {0}; - info.mtu_size = SLE_MTU_SIZE_DEFAULT; - info.version = 1; - ssapc_exchange_info_req(1, g_conn_id, &info); //发送链路连接请求,配置连接参数 - } - } - - void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) - { - unused(status); - osal_printk("[ssap client] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); - } - - //回调函数内容,每次调用读取rssi的函数之后会挑战到该回调函数 + +// 线程参数 +#define SLE_DISTANCE_CLIENT_TASK_PRIO 26 // 线程优先级 +#define SLE_DISTANCE_CLIENT_TASK_STACK_SIZE 0x2000 // 线程的栈大小 + +// 本地设备参数 +static uint8_t local_addr[SLE_ADDR_LEN] = {0x13, 0x67, 0x5c, 0x07, 0x00, 0x51}; // 自身 mac 地址 +static uint64_t g_conn_id; // 地址 + +// 对端设备参数 +static uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; // 待匹配的 server 端的 mac +static sle_addr_t g_remote_addr = {0}; // 创建设备地址结构体,初始化为0 + +// 设备发现 +#define SLE_SEEK_INTERVAL_DEFAULT 100 // 扫描间隔 +#define SLE_SEEK_WINDOW_DEFAULT 100 // 扫描窗口 + +// 设备连接 +#define DISTANCE_DEFAULT_CONN_INTERVAL 0x14 // 连接时间 +#define DISTANCE_DEFAULT_SCAN_INTERVAL 400 // 扫描间隔 +#define DISTANCE_DEFAULT_SCAN_WINDOW 20 // 扫描时间 +#define DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 // 超时时间 + +// 设备匹配 +#define SLE_MTU_SIZE_DEFAULT 1500 // 链路最大传输单元 + +// SSAP 参数 +#define UUID_16BIT_LEN 2 // UUID 长度为 16 位 +#define UUID_128BIT_LEN 16 // UUID 长度为 128 位 +static ssapc_find_service_result_t g_find_service_result = {0}; // 存储服务信息的全局变量 + +// 卡尔曼滤波 +static double P = 0.1; // 估算协方差 +static double G = 0; // 卡尔曼增益 +static double Q = 0.001; // 过程噪声协方差,Q增大,动态响应变快,收敛稳定性变坏 +static double R = 3; // 测量噪声协方差,R增大,动态响应变慢,收敛稳定性变好 +static double Output = -20; // 卡尔曼滤波器输出 + +// 卡尔曼滤波 +static double KalmanFilter(int32_t input) +{ + P = P + Q; // 估算协方差方程:当前 估算协方差 = 上次更新 协方差 + 过程噪声协方差 + G = P / (P + R); // 卡尔曼增益方程:当前 卡尔曼增益 = 当前 估算协方差 / (当前 估算协方差 + 测量噪声协方差) + Output = + Output + + G * (input - Output); // 更新最优值方程:当前 最优值 = 当前 估算值 + 卡尔曼增益 * (当前 测量值 - 当前 估算值) + P = (1 - G) * P; // 更新 协方差 = (1 - 卡尔曼增益) * 当前 估算协方差 + return Output; +} + +/* 设备发现 */ + +// 设备发现参数初始化 +void sle_start_scan(void) +{ + sle_seek_param_t param = {0}; + param.own_addr_type = 0; + param.filter_duplicates = 0; + param.seek_filter_policy = 0; + param.seek_phys = 1; // 扫描设备所使用的PHY,1M + param.seek_type[0] = 0; // 被动扫描 + param.seek_interval[0] = SLE_SEEK_INTERVAL_DEFAULT; // 扫描间隔,time = N * 0.125ms + param.seek_window[0] = SLE_SEEK_WINDOW_DEFAULT; // 扫描窗口,time = N * 0.125ms + sle_set_seek_param(¶m); // 公开扫描参数 + sle_start_seek(); // 开始公开扫描 +} + +void sle_sample_sle_enable_cbk(errcode_t status) +{ + if (status == 0) { + sle_start_scan(); + } +} + +void sle_sample_seek_enable_cbk(errcode_t status) +{ + if (status == 0) { + return; + } +} + +// 检验是否是目标对象,是则将其地址存入外部变量 g_remote_addr 中 +void sle_sample_seek_result_info_cbk(sle_seek_result_info_t *seek_result_data) +{ // 传入一个指向扫描结果的指针 + if (seek_result_data != NULL) { + if (memcmp(seek_result_data->addr.addr, mac, SLE_ADDR_LEN) == 0) { // mac 地址比较 + (void)memcpy_s(&g_remote_addr, sizeof(sle_addr_t), &seek_result_data->addr, + sizeof(sle_addr_t)); // 将 mac 地址存储到 addr 中 + sle_stop_seek(); // 停止扫描 + } + } +} + +void sle_sample_seek_disable_cbk(errcode_t status) +{ + if (status == 0) { + sle_connect_remote_device(&g_remote_addr); // 发送连接请求 + } +} + +// 注册设备发现回调函数 +static void sle_init(void) +{ + static sle_announce_seek_callbacks_t g_seek_cbk = {0}; + g_seek_cbk.sle_enable_cb = sle_sample_sle_enable_cbk; // sle 协议栈回调函数使能 + g_seek_cbk.seek_enable_cb = sle_sample_seek_enable_cbk; // 扫描回调函数使能 + g_seek_cbk.seek_result_cb = sle_sample_seek_result_info_cbk; // 根据结果关闭回调函数 + g_seek_cbk.seek_disable_cb = sle_sample_seek_disable_cbk; // 关闭扫描回调函数 + sle_announce_seek_register_callbacks(&g_seek_cbk); +} + +/* 设备连接 */ + +// 连接参数 +void sle_distance_connect_param_init(void) +{ + sle_default_connect_param_t param = {0}; + param.enable_filter_policy = 0; // 不过滤 + param.gt_negotiate = 0; // gt交互 + param.initiate_phys = 1; // 通信带宽 + param.max_interval = DISTANCE_DEFAULT_CONN_INTERVAL; // 最大连接间隔 + param.min_interval = DISTANCE_DEFAULT_CONN_INTERVAL; // 最小连接间隔 + param.scan_interval = DISTANCE_DEFAULT_SCAN_INTERVAL; // 扫描时间间隔 + param.scan_window = DISTANCE_DEFAULT_SCAN_WINDOW; // 扫描时间 + param.timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; // 超时时间 + sle_default_connection_param_set(¶m); +} + +void sle_sample_connect_state_changed_cbk(uint16_t conn_id, + const sle_addr_t *addr, + sle_acb_state_t conn_state, + sle_pair_state_t pair_state, + sle_disc_reason_t disc_reason) +{ + osal_printk("[ssap client] conn state changed conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], + addr->addr[4], addr->addr[5]); /* 0 4 5: addr index */ + osal_printk("[ssap client] conn state changed disc_reason:0x%x\n", disc_reason); + if (conn_state == SLE_ACB_STATE_CONNECTED) { // 设备已连接 + if (pair_state == SLE_PAIR_NONE) { // 未匹配则发起匹配 + sle_pair_remote_device(&g_remote_addr); + } + g_conn_id = conn_id; + } +} + +void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) +{ + unused(conn_id); + unused(status); + osal_printk("[ssap client] sle_sample_update_req_cbk interval_min = %02x, interval_max = %02x\n", + param->interval_min, param->interval_max); +} + +void sle_sample_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + osal_printk("[ssap client] pair complete conn_id:%d, addr:%02x***%02x%02x\n", conn_id, addr->addr[0], addr->addr[4], + addr->addr[5]); /* 0 4 5: addr index */ + if (status == 0) { // 是否配对成功 + ssap_exchange_info_t info = {0}; + info.mtu_size = SLE_MTU_SIZE_DEFAULT; + info.version = 1; + ssapc_exchange_info_req(1, g_conn_id, &info); // 发送链路连接请求,配置连接参数 + } +} + +void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) +{ + unused(status); + osal_printk("[ssap client] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); +} + +// 回调函数内容,每次调用读取rssi的函数之后会挑战到该回调函数 void sle_sample_read_rssi_cbk(uint16_t conn_id, int8_t rssi, errcode_t status) { unused(conn_id); unused(status); int32_t rssi_k; double distance; - rssi_k = (int32_t)KalmanFilter(rssi*100); - distance = 1.0933 - 1.0933 * 0.001 * rssi_k + 1.0933 * (0.001 * 0.001 * rssi_k * rssi_k) / 2 - 1.0933 * (0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k) / 6 + 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k) / 24- 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k* rssi_k * rssi_k) / 120 + 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k) / 720 - 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k) / 5040; - osal_printk("rssi: %d rssi_k:%d distance:%d\r\n",rssi*100,(int32_t)rssi_k,(int32_t)distance); - if(distance > 5) - { + rssi_k = (int32_t)KalmanFilter(rssi * 100); + distance = + 1.0933 - 1.0933 * 0.001 * rssi_k + 1.0933 * (0.001 * 0.001 * rssi_k * rssi_k) / 2 - + 1.0933 * (0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k) / 6 + + 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k) / 24 - + 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k) / 120 + + 1.0933 * (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k) / + 720 - + 1.0933 * + (0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * 0.001 * rssi_k * rssi_k * rssi_k * rssi_k * rssi_k * + rssi_k * rssi_k) / + 5040; + osal_printk("rssi: %d rssi_k:%d distance:%d\r\n", rssi * 100, (int32_t)rssi_k, (int32_t)distance); + if (distance > 5) { uapi_gpio_set_val(2, GPIO_LEVEL_HIGH); // 超过5cm,蜂鸣器发出警报 - } - else - { + } else { uapi_gpio_set_val(2, GPIO_LEVEL_LOW); } } - //连接设备连接回调函数 - void sle_sample_connect_cbk_register(void) - { - static sle_connection_callbacks_t g_connect_cbk = {0}; - g_connect_cbk.connect_state_changed_cb = sle_sample_connect_state_changed_cbk; //连接状态改变 - g_connect_cbk.connect_param_update_req_cb = sle_sample_update_req_cbk; //请求连接参数更新 - g_connect_cbk.pair_complete_cb = sle_sample_pair_complete_cbk; //配对完成 - g_connect_cbk.connect_param_update_cb = sle_sample_update_cbk; //更新连接参数(已完成) - g_connect_cbk.read_rssi_cb = sle_sample_read_rssi_cbk; //读取rssi回调函数 - sle_connection_register_callbacks(&g_connect_cbk); - } - - - /* SSAP client */ - - //更新mtu大小,启动服务发现 - void sle_sample_exchange_info_cbk(uint8_t client_id, uint16_t conn_id, ssap_exchange_info_t *param,errcode_t status) - { - osal_printk("[ssap client] pair complete client id:%d status:%d\n", client_id, status); - osal_printk("[ssap client] exchange mtu, mtu size: %d, version: %d.\n",param->mtu_size, param->version); - - //服务发现 - ssapc_find_structure_param_t find_param = {0}; - find_param.type = SSAP_FIND_TYPE_PRIMARY_SERVICE; //寻找指定的服务 - find_param.start_hdl = 1; //起始句柄 - find_param.end_hdl = 0xFFFF; //结束句柄 - - //调用服务发现函数 - ssapc_find_structure(0, conn_id, &find_param); - } - - //为应用层提供信息 - void sle_sample_find_structure_cbk(uint8_t client_id, uint16_t conn_id, ssapc_find_service_result_t *service,errcode_t status) - { - osal_printk("[ssap client] find structure cbk client: %d conn_id:%d status: %d \n",client_id, conn_id, status); - osal_printk("[ssap client] find structure start_hdl:[0x%02x], end_hdl:[0x%02x], uuid len:%d\r\n",service->start_hdl, service->end_hdl, service->uuid.len); - if (service->uuid.len == UUID_16BIT_LEN) {osal_printk("[ssap client] structure uuid:[0x%02x][0x%02x]\r\n",service->uuid.uuid[14], service->uuid.uuid[15]); /* 14 15: uuid index */ - } else { - for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { - osal_printk("[ssap client] structure uuid[%d]:[0x%02x]\r\n", idx, service->uuid.uuid[idx]); - } - } - - //保存服务信息到全局变量 - g_find_service_result.start_hdl = service->start_hdl; - g_find_service_result.end_hdl = service->end_hdl; - memcpy_s(&g_find_service_result.uuid, sizeof(sle_uuid_t), &service->uuid, sizeof(sle_uuid_t)); - } - - //处理服务或特征发现完成的事件,发送数据到对端设备 - void sle_sample_find_structure_cmp_cbk(uint8_t client_id, uint16_t conn_id,ssapc_find_structure_result_t *structure_result, errcode_t status) - { - osal_printk("[ssap client] find structure cmp cbk client id:%d status:%d type:%d uuid len:%d \r\n",client_id, status, structure_result->type, structure_result->uuid.len); - if (structure_result->uuid.len == UUID_16BIT_LEN) { - osal_printk("[ssap client] find structure cmp cbk structure uuid:[0x%02x][0x%02x]\r\n",structure_result->uuid.uuid[14], structure_result->uuid.uuid[15]); /* 14 15: uuid index */ - } else { - for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { - osal_printk("[ssap client] find structure cmp cbk structure uuid[%d]:[0x%02x]\r\n", idx,structure_result->uuid.uuid[idx]); - } - } - - //构造一个写操作(发送操作) - uint8_t data[] = {0x11, 0x22, 0x33, 0x44}; - uint8_t len = sizeof(data); - ssapc_write_param_t param = {0}; - param.handle = g_find_service_result.start_hdl; //写操作的目标句柄 - param.type = SSAP_PROPERTY_TYPE_VALUE; //写类型 - param.data_len = len; //数据长度 - param.data = data; //写入数据 - ssapc_write_req(0, conn_id, ¶m); //发起写申请 - } - - //写操作完成确认函数 - void sle_sample_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_write_result_t *write_result,errcode_t status) - { - osal_printk("[ssap client] write cfm cbk, client id: %d status:%d.\n", client_id, status); - ssapc_read_req(0, conn_id, write_result->handle, write_result->type); - } - - //发现特征回调函数 - void sle_sample_find_property_cbk(uint8_t client_id, uint16_t conn_id,ssapc_find_property_result_t *property, errcode_t status) - { - osal_printk("[ssap client] find property cbk, client id: %d, conn id: %d, operate ind: %d, ""descriptors count: %d status:%d.\n", client_id, conn_id, property->operate_indication,property->descriptors_count, status); - for (uint16_t idx = 0; idx < property->descriptors_count; idx++) { - osal_printk("[ssap client] find property cbk, descriptors type [%d]: 0x%02x.\n",idx, property->descriptors_type[idx]); - } - if (property->uuid.len == UUID_16BIT_LEN) { - osal_printk("[ssap client] find property cbk, uuid: %02x %02x.\n",property->uuid.uuid[14], property->uuid.uuid[15]); /* 14 15: uuid index */ - } else if (property->uuid.len == UUID_128BIT_LEN) { - for (uint16_t idx = 0; idx < UUID_128BIT_LEN; idx++) { - osal_printk("[ssap client] find property cbk, uuid [%d]: %02x.\n",idx, property->uuid.uuid[idx]); - } - } - } - - //解析读取数据并打印 - void sle_sample_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *read_data,errcode_t status) - { - osal_printk("[ssap client] read cfm cbk client id: %d conn id: %d status: %d\n",client_id, conn_id, status); - osal_printk("[ssap client] read cfm cbk handle: %d, type: %d , len: %d\n",read_data->handle, read_data->type, read_data->data_len); - for (uint16_t idx = 0; idx < read_data->data_len; idx++) { - osal_printk("[ssap client] read cfm cbk[%d] 0x%02x\r\n", idx, read_data->data[idx]); - } - } - - static void sle_distance_indication_cb(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *data, - errcode_t status) - { - unused(status); - unused(conn_id); - unused(client_id); - osal_printk("\n sle_distance_indication_cb sle uart recived data : %s\r\n", data->data); - } - - //ssap client回调函数 - void sle_sample_ssapc_cbk_register(ssapc_notification_callback indication_cb) - { - static ssapc_callbacks_t g_ssapc_cbk = {0}; - g_ssapc_cbk.exchange_info_cb = sle_sample_exchange_info_cbk; //更新mtu大小回调钩子,启动服务发现 - g_ssapc_cbk.find_structure_cb = sle_sample_find_structure_cbk; //发现服务回调函数,为应用层提供信息 - g_ssapc_cbk.find_structure_cmp_cb = sle_sample_find_structure_cmp_cbk; //发现特征完成回调函数,完成写操作 - g_ssapc_cbk.write_cfm_cb = sle_sample_write_cfm_cbk; //写操作完成确认函数 - g_ssapc_cbk.ssapc_find_property_cbk = sle_sample_find_property_cbk; //发现特征回调函数. - g_ssapc_cbk.read_cfm_cb = sle_sample_read_cfm_cbk; //解析读取数据并打印 - g_ssapc_cbk.indication_cb = indication_cb; //指示事件上报钩子 - ssapc_register_callbacks(&g_ssapc_cbk); - } - - - - /* 主函数 */ - static int sle_distance_client_task(const char *arg) - { - unused(arg); - - sle_addr_t local_address; - local_address.type = 0; - (void)memcpy_s(local_address.addr, SLE_ADDR_LEN, local_addr, SLE_ADDR_LEN); - - sle_init(); - sle_distance_connect_param_init(); - sle_sample_connect_cbk_register(); - sle_sample_ssapc_cbk_register(sle_distance_indication_cb); - enable_sle(); - sle_set_local_addr(&local_address); - uapi_pin_set_mode(2, HAL_PIO_FUNC_GPIO); - uapi_gpio_set_dir(2, GPIO_DIRECTION_OUTPUT); // 蜂鸣器的正极连接到微控制器的数字输出引脚,蜂鸣器的负极连接到微控制器的GND引脚 - uapi_gpio_set_val(2, GPIO_LEVEL_LOW); - osal_msleep(1000); - //主函数中调用读取rssi的函数 - while (1) - { +// 连接设备连接回调函数 +void sle_sample_connect_cbk_register(void) +{ + static sle_connection_callbacks_t g_connect_cbk = {0}; + g_connect_cbk.connect_state_changed_cb = sle_sample_connect_state_changed_cbk; // 连接状态改变 + g_connect_cbk.connect_param_update_req_cb = sle_sample_update_req_cbk; // 请求连接参数更新 + g_connect_cbk.pair_complete_cb = sle_sample_pair_complete_cbk; // 配对完成 + g_connect_cbk.connect_param_update_cb = sle_sample_update_cbk; // 更新连接参数(已完成) + g_connect_cbk.read_rssi_cb = sle_sample_read_rssi_cbk; // 读取rssi回调函数 + sle_connection_register_callbacks(&g_connect_cbk); +} + +/* SSAP client */ + +// 更新mtu大小,启动服务发现 +void sle_sample_exchange_info_cbk(uint8_t client_id, uint16_t conn_id, ssap_exchange_info_t *param, errcode_t status) +{ + osal_printk("[ssap client] pair complete client id:%d status:%d\n", client_id, status); + osal_printk("[ssap client] exchange mtu, mtu size: %d, version: %d.\n", param->mtu_size, param->version); + + // 服务发现 + ssapc_find_structure_param_t find_param = {0}; + find_param.type = SSAP_FIND_TYPE_PRIMARY_SERVICE; // 寻找指定的服务 + find_param.start_hdl = 1; // 起始句柄 + find_param.end_hdl = 0xFFFF; // 结束句柄 + + // 调用服务发现函数 + ssapc_find_structure(0, conn_id, &find_param); +} + +// 为应用层提供信息 +void sle_sample_find_structure_cbk(uint8_t client_id, + uint16_t conn_id, + ssapc_find_service_result_t *service, + errcode_t status) +{ + osal_printk("[ssap client] find structure cbk client: %d conn_id:%d status: %d \n", client_id, conn_id, status); + osal_printk("[ssap client] find structure start_hdl:[0x%02x], end_hdl:[0x%02x], uuid len:%d\r\n", + service->start_hdl, service->end_hdl, service->uuid.len); + if (service->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] structure uuid:[0x%02x][0x%02x]\r\n", service->uuid.uuid[14], + service->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] structure uuid[%d]:[0x%02x]\r\n", idx, service->uuid.uuid[idx]); + } + } + + // 保存服务信息到全局变量 + g_find_service_result.start_hdl = service->start_hdl; + g_find_service_result.end_hdl = service->end_hdl; + memcpy_s(&g_find_service_result.uuid, sizeof(sle_uuid_t), &service->uuid, sizeof(sle_uuid_t)); +} + +// 处理服务或特征发现完成的事件,发送数据到对端设备 +void sle_sample_find_structure_cmp_cbk(uint8_t client_id, + uint16_t conn_id, + ssapc_find_structure_result_t *structure_result, + errcode_t status) +{ + osal_printk("[ssap client] find structure cmp cbk client id:%d status:%d type:%d uuid len:%d \r\n", client_id, + status, structure_result->type, structure_result->uuid.len); + if (structure_result->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] find structure cmp cbk structure uuid:[0x%02x][0x%02x]\r\n", + structure_result->uuid.uuid[14], structure_result->uuid.uuid[15]); /* 14 15: uuid index */ + } else { + for (uint8_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] find structure cmp cbk structure uuid[%d]:[0x%02x]\r\n", idx, + structure_result->uuid.uuid[idx]); + } + } + + // 构造一个写操作(发送操作) + uint8_t data[] = {0x11, 0x22, 0x33, 0x44}; + uint8_t len = sizeof(data); + ssapc_write_param_t param = {0}; + param.handle = g_find_service_result.start_hdl; // 写操作的目标句柄 + param.type = SSAP_PROPERTY_TYPE_VALUE; // 写类型 + param.data_len = len; // 数据长度 + param.data = data; // 写入数据 + ssapc_write_req(0, conn_id, ¶m); // 发起写申请 +} + +// 写操作完成确认函数 +void sle_sample_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_write_result_t *write_result, errcode_t status) +{ + osal_printk("[ssap client] write cfm cbk, client id: %d status:%d.\n", client_id, status); + ssapc_read_req(0, conn_id, write_result->handle, write_result->type); +} + +// 发现特征回调函数 +void sle_sample_find_property_cbk(uint8_t client_id, + uint16_t conn_id, + ssapc_find_property_result_t *property, + errcode_t status) +{ + osal_printk( + "[ssap client] find property cbk, client id: %d, conn id: %d, operate ind: %d, " + "descriptors count: %d status:%d.\n", + client_id, conn_id, property->operate_indication, property->descriptors_count, status); + for (uint16_t idx = 0; idx < property->descriptors_count; idx++) { + osal_printk("[ssap client] find property cbk, descriptors type [%d]: 0x%02x.\n", idx, + property->descriptors_type[idx]); + } + if (property->uuid.len == UUID_16BIT_LEN) { + osal_printk("[ssap client] find property cbk, uuid: %02x %02x.\n", property->uuid.uuid[14], + property->uuid.uuid[15]); /* 14 15: uuid index */ + } else if (property->uuid.len == UUID_128BIT_LEN) { + for (uint16_t idx = 0; idx < UUID_128BIT_LEN; idx++) { + osal_printk("[ssap client] find property cbk, uuid [%d]: %02x.\n", idx, property->uuid.uuid[idx]); + } + } +} + +// 解析读取数据并打印 +void sle_sample_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, ssapc_handle_value_t *read_data, errcode_t status) +{ + osal_printk("[ssap client] read cfm cbk client id: %d conn id: %d status: %d\n", client_id, conn_id, status); + osal_printk("[ssap client] read cfm cbk handle: %d, type: %d , len: %d\n", read_data->handle, read_data->type, + read_data->data_len); + for (uint16_t idx = 0; idx < read_data->data_len; idx++) { + osal_printk("[ssap client] read cfm cbk[%d] 0x%02x\r\n", idx, read_data->data[idx]); + } +} + +static void sle_distance_indication_cb(uint8_t client_id, + uint16_t conn_id, + ssapc_handle_value_t *data, + errcode_t status) +{ + unused(status); + unused(conn_id); + unused(client_id); + osal_printk("\n sle_distance_indication_cb sle uart recived data : %s\r\n", data->data); +} + +// ssap client回调函数 +void sle_sample_ssapc_cbk_register(ssapc_notification_callback indication_cb) +{ + static ssapc_callbacks_t g_ssapc_cbk = {0}; + g_ssapc_cbk.exchange_info_cb = sle_sample_exchange_info_cbk; // 更新mtu大小回调钩子,启动服务发现 + g_ssapc_cbk.find_structure_cb = sle_sample_find_structure_cbk; // 发现服务回调函数,为应用层提供信息 + g_ssapc_cbk.find_structure_cmp_cb = sle_sample_find_structure_cmp_cbk; // 发现特征完成回调函数,完成写操作 + g_ssapc_cbk.write_cfm_cb = sle_sample_write_cfm_cbk; // 写操作完成确认函数 + g_ssapc_cbk.ssapc_find_property_cbk = sle_sample_find_property_cbk; // 发现特征回调函数. + g_ssapc_cbk.read_cfm_cb = sle_sample_read_cfm_cbk; // 解析读取数据并打印 + g_ssapc_cbk.indication_cb = indication_cb; // 指示事件上报钩子 + ssapc_register_callbacks(&g_ssapc_cbk); +} + +/* 主函数 */ +static int sle_distance_client_task(const char *arg) +{ + unused(arg); + + sle_addr_t local_address; + local_address.type = 0; + (void)memcpy_s(local_address.addr, SLE_ADDR_LEN, local_addr, SLE_ADDR_LEN); + + sle_init(); + sle_distance_connect_param_init(); + sle_sample_connect_cbk_register(); + sle_sample_ssapc_cbk_register(sle_distance_indication_cb); + enable_sle(); + sle_set_local_addr(&local_address); + uapi_pin_set_mode(2, HAL_PIO_FUNC_GPIO); + uapi_gpio_set_dir( + 2, GPIO_DIRECTION_OUTPUT); // 蜂鸣器的正极连接到微控制器的数字输出引脚,蜂鸣器的负极连接到微控制器的GND引脚 + uapi_gpio_set_val(2, GPIO_LEVEL_LOW); + osal_msleep(1000); + // 主函数中调用读取rssi的函数 + while (1) { sle_read_remote_device_rssi(g_conn_id); osal_msleep(1000); } - - return 0; - } - - - - //创建运行任务的线程并进行初始化 - static void sle_distance_client_entry(void) - { - osal_task *task_handle = NULL; - osal_kthread_lock(); //加锁 - - //创建线程 - task_handle = osal_kthread_create((osal_kthread_handler)sle_distance_client_task, 0, "Sle_Distance_Task", SLE_DISTANCE_CLIENT_TASK_STACK_SIZE); - - if (task_handle != NULL) { - //设置优先级 - osal_kthread_set_priority(task_handle, SLE_DISTANCE_CLIENT_TASK_PRIO);// - osal_kfree(task_handle); //释放内存 - } - - osal_kthread_unlock(); //解锁 - } - - //运行该app - app_run(sle_distance_client_entry); + + return 0; +} + +// 创建运行任务的线程并进行初始化 +static void sle_distance_client_entry(void) +{ + osal_task *task_handle = NULL; + osal_kthread_lock(); // 加锁 + + // 创建线程 + task_handle = osal_kthread_create((osal_kthread_handler)sle_distance_client_task, 0, "Sle_Distance_Task", + SLE_DISTANCE_CLIENT_TASK_STACK_SIZE); + + if (task_handle != NULL) { + // 设置优先级 + osal_kthread_set_priority(task_handle, SLE_DISTANCE_CLIENT_TASK_PRIO); // + osal_kfree(task_handle); // 释放内存 + } + + osal_kthread_unlock(); // 解锁 +} + +// 运行该app +app_run(sle_distance_client_entry); -- Gitee From 272cbe86e26f8c2c5dd27044cc2fdfc400309130 Mon Sep 17 00:00:00 2001 From: Kid <3548263564@qq.com> Date: Sun, 17 Aug 2025 09:03:53 +0000 Subject: [PATCH 3/4] update vendor/developers/demo/sle_tag/sle_server.c. Signed-off-by: Kid <3548263564@qq.com> --- vendor/developers/demo/sle_tag/sle_server.c | 1281 +++++++++---------- 1 file changed, 638 insertions(+), 643 deletions(-) diff --git a/vendor/developers/demo/sle_tag/sle_server.c b/vendor/developers/demo/sle_tag/sle_server.c index bc903417..6dc31848 100644 --- a/vendor/developers/demo/sle_tag/sle_server.c +++ b/vendor/developers/demo/sle_tag/sle_server.c @@ -1,643 +1,638 @@ - #include "app_init.h" - #include "watchdog.h" - #include "tcxo.h" - #include "systick.h" - #include "los_memory.h" - #include "securec.h" - #include "errcode.h" - #include "osal_addr.h" - #include "soc_osal.h" - #include "common_def.h" - - #include "sle_common.h" - #include "sle_errcode.h" - #include "sle_ssap_server.h" - #include "sle_connection_manager.h" - #include "sle_device_discovery.h" - #include "sle_transmition_manager.h" - #include "nv.h" - - #include "sle_server.h" - - //线程参数 - #define DISTANCE_DEFAULT_KTHREAD_SIZE 0x2000 - #define DISTANCE_DEFAULT_KTHREAD_PROI 26 - - //本地设备参数 - #define NAME_MAX_LENGTH 30 - static uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; - static uint8_t sle_local_name[NAME_MAX_LENGTH] = "sle_connect_server"; - //数据包长度 - #define PKT_DATA_LEN 600 - static unsigned char data[PKT_DATA_LEN]; - //确保为小端格式存储 - #define encode2byte_little(_ptr, data) \ - do { \ - *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \ - *(uint8_t *)(_ptr) = (uint8_t)(data); \ - } while (0) - - //设备公开 - #define SLE_CONN_INTV_MIN_DEFAULT 0xA //连接最小调度间隔12.5ms,单位125us - #define SLE_CONN_INTV_MAX_DEFAULT 0xA //连接最大调度间隔12.5ms,单位125us - #define SLE_ADV_INTERVAL_MIN_DEFAULT 0xC8 //连接调度间隔25ms,单位125us - #define SLE_ADV_INTERVAL_MAX_DEFAULT 0xC8 //超时时间5000ms,单位10ms - #define SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT 0x1F4 //超时时间4990ms,单位10ms - #define SLE_CONN_MAX_LATENCY 0x1F3 //广播发送功率 - #define SLE_ADV_TX_POWER 20 //最大广播数据长度 - #define SLE_ADV_DATA_LEN_MAX 251 - - //设备连接 - - #define DISTANCE_DEFAULT_CONN_INTERVAL 0xA0 - #define DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 - #define DISTANCE_DEFAULT_SCAN_INTERVAL 400 - #define DISTANCE_DEFAULT_SCAN_WINDOW 20 - //蓝牙地址索引 - #define BT_INDEX_4 4 - #define BT_INDEX_5 5 - #define BT_INDEX_0 0 - - static uint16_t g_conn_id = 0; - - // SSAP 参数 - #define OCTET_BIT_LEN 8 //8比特长度 - #define UUID_LEN_2 2 //两个字节 - static char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0}; - static char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; - - //传输参数 - #define DEFAULT_SLE_DISTANCE_DATA_LEN 1500 - #define DEFAULT_SLE_DISTANCE_MTU_SIZE 1500 - static uint8_t g_server_id = 0; - static uint16_t g_service_handle = 0; - static uint16_t g_property_handle = 0; - static uint8_t sle_uuid_base[] = { 0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; - extern uint8_t gle_tx_acb_data_num_get(void); - - - - /* 检查 BTC 功率档位 */ - - void sle_distance_server_set_nv(void) - { - uint16_t nv_value_len = 0; - uint8_t nv_value = 0; - - //读取指定NV数据项的值 - uapi_nv_read(0x20A0, sizeof(uint16_t), &nv_value_len, &nv_value); - if (nv_value != 7) { // 7:btc功率档位 - nv_value = 7; // 7:btc功率档位 - - //写入NV数据项 - uapi_nv_write(0x20A0, (uint8_t *)&(nv_value), sizeof(nv_value)); - } - osal_printk("[distance server] The value of nv is set to %d.\r\n", nv_value); - } - - - - /* 本地设备参数 */ - - //设置本端 MAC 地址 - void sle_set_local_addr_init(void) - { - sle_addr_t addr = {0}; - addr.type = 0; - memcpy_s(addr.addr, SLE_ADDR_LEN, mac, SLE_ADDR_LEN); - sle_set_local_addr(&addr); - } - - //设置本端名称 - static uint16_t sle_set_adv_local_name(uint8_t *adv_data, uint16_t max_len) - { - errno_t ret; - uint8_t index = 0; - - uint8_t *local_name = sle_local_name; - uint8_t local_name_len = (uint8_t)strlen((char *)local_name); - for (uint8_t i = 0; i < local_name_len; i++) { - osal_printk("local_name[%d] = 0x%02x\r\n", i, local_name[i]); - } - - adv_data[index++] = local_name_len + 1; - adv_data[index++] = SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME; - ret = memcpy_s(&adv_data[index], max_len - index, local_name, local_name_len); - if (ret != EOK) { - osal_printk("memcpy fail\r\n"); - return 0; - } - return (uint16_t)index + local_name_len; - } - - - - /* 设备公开 */ - - //设备公开参数 - static int sle_set_default_announce_param(void) - { - //初始化 - sle_announce_param_t param = {0}; - param.announce_mode = SLE_ANNOUNCE_MODE_CONNECTABLE_SCANABLE; //公开类型 - param.announce_handle = SLE_ADV_HANDLE_DEFAULT; //公开句柄 - param.announce_gt_role = SLE_ANNOUNCE_ROLE_T_CAN_NEGO; //gt角色协商指示 - param.announce_level = SLE_ANNOUNCE_LEVEL_NORMAL; //发现等级 - param.announce_channel_map = SLE_ADV_CHANNEL_MAP_DEFAULT; //设备公开信道 - param.announce_interval_min = SLE_ADV_INTERVAL_MIN_DEFAULT; //最小设备公开周期 - param.announce_interval_max = SLE_ADV_INTERVAL_MAX_DEFAULT; //最大设备公开周期 - param.conn_interval_min = SLE_CONN_INTV_MIN_DEFAULT; //连接间隔最小取值 - param.conn_interval_max = SLE_CONN_INTV_MAX_DEFAULT; //连接间隔最大取值 - param.conn_max_latency = SLE_CONN_MAX_LATENCY; //最大休眠连接间隔 - param.conn_supervision_timeout = SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT; //最大超时时间 - param.announce_tx_power = SLE_ADV_TX_POWER; //广播发射攻略 - param.own_addr.type = 0; //本端地址 - memcpy_s(param.own_addr.addr, SLE_ADDR_LEN, mac, SLE_ADDR_LEN); - - //设置参数 - return sle_set_announce_param(param.announce_handle, ¶m); - } - - void sle_enable_cbk(errcode_t status) - { - osal_printk("sle enable status:%02x\r\n", status); - } - - void sle_announce_enable_cbk(uint32_t announce_id, errcode_t status) - { - osal_printk("sle announce enable id:%02x, state:%02x\r\n", announce_id, status); - } - - void sle_announce_terminal_cbk(uint32_t announce_id) - { - osal_printk("sle announce terminal id:%02x\r\n", announce_id); - } - - void sle_announce_disable_cbk(uint32_t announce_id, errcode_t status) - { - osal_printk("sle announce disable id:%02x, state:%02x\r\n", announce_id, status); - } - - //设备公开回调函数 - void sle_announce_register_cbks(void) - { - sle_announce_seek_callbacks_t seek_cbks = {0}; - seek_cbks.sle_enable_cb = sle_enable_cbk; //SLE协议栈使能回调函数 - seek_cbks.announce_enable_cb = sle_announce_enable_cbk; //设备公开使能回调函数 - seek_cbks.announce_terminal_cb = sle_announce_terminal_cbk; //设备公开停止回调函数 - seek_cbks.announce_disable_cb = sle_announce_disable_cbk; //设备公开关闭回调函数 - sle_announce_seek_register_callbacks(&seek_cbks); //将回调函数注册到协议层 - } - - //设置广播数据 - static uint16_t sle_set_adv_data(uint8_t *adv_data) - { - size_t len = 0; - uint16_t idx = 0; - errno_t ret = 0; - - //填充设备发现级别 - len = sizeof(struct sle_adv_common_value); - struct sle_adv_common_value adv_disc_level = { - .length = len - 1, - .type = SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL, - .value = SLE_ANNOUNCE_LEVEL_NORMAL, - }; - - ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_disc_level, len); - if (ret != EOK) { - osal_printk("adv_disc_level memcpy fail\r\n"); - return 0; - } - idx += len; - - //填充访问模式 - len = sizeof(struct sle_adv_common_value); - struct sle_adv_common_value adv_access_mode = { - .length = len - 1, - .type = SLE_ADV_DATA_TYPE_ACCESS_MODE, - .value = 0, - }; - ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_access_mode, len); - if (ret != EOK) { - osal_printk("memcpy fail\r\n"); - return 0; - } - idx += len; - return idx; - } - - - static uint16_t sle_set_scan_response_data(uint8_t *scan_rsp_data) - { - uint16_t idx = 0; - errno_t ret; - size_t scan_rsp_data_len = sizeof(struct sle_adv_common_value); - - struct sle_adv_common_value tx_power_level = { - .length = scan_rsp_data_len - 1, - .type = SLE_ADV_DATA_TYPE_TX_POWER_LEVEL, - .value = SLE_ADV_TX_POWER, - }; - ret = memcpy_s(scan_rsp_data, SLE_ADV_DATA_LEN_MAX, &tx_power_level, scan_rsp_data_len); - if (ret != EOK) { - osal_printk("sle scan response data memcpy fail\r\n"); - return 0; - } - idx += scan_rsp_data_len; - - /* set local name */ - idx += sle_set_adv_local_name(&scan_rsp_data[idx], SLE_ADV_DATA_LEN_MAX - idx); - return idx; - } - - static int sle_set_default_announce_data(void) - { - errcode_t ret; - uint8_t announce_data_len = 0; - uint8_t seek_data_len = 0; - sle_announce_data_t data = {0}; - uint8_t adv_handle = SLE_ADV_HANDLE_DEFAULT; - uint8_t announce_data[SLE_ADV_DATA_LEN_MAX] = {0}; - uint8_t seek_rsp_data[SLE_ADV_DATA_LEN_MAX] = {0}; - - osal_printk("set adv data default\r\n"); - - //设置广播数据 - announce_data_len = sle_set_adv_data(announce_data); - data.announce_data = announce_data; - data.announce_data_len = announce_data_len; - //设置扫描相应数据 - seek_data_len = sle_set_scan_response_data(seek_rsp_data); - data.seek_rsp_data = seek_rsp_data; - data.seek_rsp_data_len = seek_data_len; - //设置参数 - ret = sle_set_announce_data(adv_handle, &data); - if (ret == ERRCODE_SLE_SUCCESS) { - osal_printk("[SLE DD SDK] set announce data success."); - } else { - osal_printk("[SLE DD SDK] set adv param fail."); - } - return ERRCODE_SLE_SUCCESS; - } - - static errcode_t sle_uuid_server_adv_init(void) - { - osal_printk("sle_uuid_server_adv_init in\r\n"); - - sle_announce_register_cbks(); - sle_set_default_announce_param(); - sle_set_default_announce_data(); - sle_start_announce(SLE_ADV_HANDLE_DEFAULT); //开始设备公开 - osal_printk("sle_uuid_server_adv_init out\r\n"); - return ERRCODE_SLE_SUCCESS; - } - - // ssap 信息交换设置 - void sle_ssaps_set_info(void) - { - ssap_exchange_info_t info = {0}; - info.mtu_size = DEFAULT_SLE_DISTANCE_MTU_SIZE; - info.version = 1; - ssaps_set_info(g_server_id, &info); - } - - /* 设备连接 */ - - //连接参数 - void sle_distance_connect_param_init(void) - { - sle_default_connect_param_t param = {0}; - param.enable_filter_policy = 0; //过滤功能 - param.gt_negotiate = 0; - param.initiate_phys = 1; - param.max_interval = DISTANCE_DEFAULT_CONN_INTERVAL; - param.min_interval = DISTANCE_DEFAULT_CONN_INTERVAL; - param.scan_interval = DISTANCE_DEFAULT_SCAN_INTERVAL; - param.scan_window = DISTANCE_DEFAULT_SCAN_WINDOW; - param.timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; - sle_default_connection_param_set(¶m); - } - - //连接状态改变回调函数 - static void sle_connect_state_changed_cbk(uint16_t conn_id, const sle_addr_t *addr, - sle_acb_state_t conn_state, sle_pair_state_t pair_state, sle_disc_reason_t disc_reason) - { - osal_printk("[distance server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \ - disc_reason:0x%x\r\n", conn_id, conn_state, pair_state, disc_reason); - osal_printk("[distance server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", - addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); - g_conn_id = conn_id; - sle_connection_param_update_t parame = {0}; - parame.conn_id = conn_id; - parame.interval_min = DISTANCE_DEFAULT_CONN_INTERVAL; - parame.interval_max = DISTANCE_DEFAULT_CONN_INTERVAL; - parame.max_latency = 0; - parame.supervision_timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; - if (conn_state == SLE_ACB_STATE_CONNECTED) { - sle_update_connect_param(¶me); - } else if (conn_state == SLE_ACB_STATE_DISCONNECTED) { - sle_start_announce(SLE_ADV_HANDLE_DEFAULT); - } - } - - //连接参数请求更新回调函数 - void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) - { - unused(conn_id); - unused(status); - osal_printk("[ssap server] sle_sample_update_req_cbk interval_min:%02x, interval_max:%02x\n", - param->interval_min, param->interval_max); - } - - //连接参数更新完成回调函数 - void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) - { - unused(status); - osal_printk("[ssap server] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); - } - - //配对完成回调函数 - static void sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) - { - osal_printk("[distance server] pair complete conn_id:%02x, status:%x\r\n", - conn_id, status); - osal_printk("[distance server] pair complete addr:%02x:**:**:**:%02x:%02x\r\n", - addr->addr[BT_INDEX_0], addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); - } - - static void sle_conn_register_cbks(void) - { - sle_connection_callbacks_t conn_cbks = {0}; - conn_cbks.connect_state_changed_cb = sle_connect_state_changed_cbk; //连接状态改变回调函数 - conn_cbks.connect_param_update_req_cb = sle_sample_update_req_cbk; //连接参数请求更新回调函数 - conn_cbks.connect_param_update_cb = sle_sample_update_cbk; //连接参数更新完成回调函数 - conn_cbks.pair_complete_cb = sle_pair_complete_cbk; //配对完成回调函数 - sle_connection_register_callbacks(&conn_cbks); //将回调函数结构体注册到协议层 - } - - - - /* SSAP server */ - - //启动服务回调函数 - static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status) - { - osal_printk("[distance server] start service cbk server_id:%d, handle:%d, status:%d\r\n", - server_id, handle, status); - } - - //mtu 大小更新回调函数 - static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, ssap_exchange_info_t *mtu_size, - errcode_t status) - { - osal_printk("[distance server] ssaps write request cbk server_id:%d, conn_id:%d, mtu_size:%d, status:%d\r\n", - server_id, conn_id, mtu_size->mtu_size, status); - } - - //发送信息 - static errcode_t sle_uuid_server_send_report_by_handle_id(uint8_t *data, uint16_t len, uint16_t connect_id) - { - ssaps_ntf_ind_t param = {0}; - param.handle = g_property_handle; - param.type = SSAP_PROPERTY_TYPE_VALUE; - param.value = data; - param.value_len = len; - - //向对端发送通知 - ssaps_notify_indicate(g_server_id, connect_id, ¶m); - return ERRCODE_SLE_SUCCESS; - } - - static uint8_t sle_flow_ctrl_flag(void) - { - return gle_tx_acb_data_num_get(); - } - - static void send_data_thread_function(void) - { - //设置最大传输长度 - sle_set_data_len(g_conn_id, DEFAULT_SLE_DISTANCE_DATA_LEN); - - osal_printk("code: GFSK, PHY 1MHZ, power: 20dbm \r\n"); - int i = 0; - while (1) { - if (sle_flow_ctrl_flag() > 0) { - i++; - //填充数据 - data[0] = (i >> 8) & 0xFF; - data[1] = i & 0xFF; - - //发送数据包 - sle_uuid_server_send_report_by_handle_id(data, PKT_DATA_LEN, g_conn_id); - } - - } - } - - //收到远端读请求回调函数 - static void ssaps_read_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_read_cb_t *read_cb_para, - errcode_t status) - { - osal_printk("[distance server] ssaps read request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n",server_id, conn_id, read_cb_para->handle, status); - - //创建新线程完成发送任务 - osal_task *task_handle = NULL; - osal_kthread_lock(); - task_handle = osal_kthread_create((osal_kthread_handler)send_data_thread_function,0, "RadarTask", DISTANCE_DEFAULT_KTHREAD_SIZE); - osal_kthread_set_priority(task_handle, DISTANCE_DEFAULT_KTHREAD_PROI + 1); - if (task_handle != NULL) { - osal_kfree(task_handle); - } - osal_kthread_unlock(); - printf("kthread success\r\n"); - } - - //收到远端写请求回调函数 - static void ssaps_write_request_cbk(uint8_t server_id, uint16_t conn_id, ssaps_req_write_cb_t *write_cb_para, - errcode_t status) - { - osal_printk("[distance server] ssaps write request cbk server_id:%d, conn_id:%d, handle:%d, status:%d\r\n", - server_id, conn_id, write_cb_para->handle, status); - } - - //注册 ssap server 回调 - static void sle_ssaps_register_cbks(void) - { - ssaps_callbacks_t ssaps_cbk = {0}; - ssaps_cbk.start_service_cb = ssaps_start_service_cbk; //启动服务回调函数 - ssaps_cbk.mtu_changed_cb = ssaps_mtu_changed_cbk; //mtu 大小更新回调函数 - ssaps_cbk.read_request_cb = ssaps_read_request_cbk; //收到远端读请求回调函数 - ssaps_cbk.write_request_cb = ssaps_write_request_cbk; //收到远端写请求回调函数 - ssaps_register_callbacks(&ssaps_cbk); - } - - //复制128-bit UUID 到结构体 - static void sle_uuid_set_base(sle_uuid_t *out) - { - (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN); - out->len = UUID_LEN_2; - } - - //将 uuid 转换为小端格式 - static void sle_uuid_setu2(uint16_t u2, sle_uuid_t *out) - { - sle_uuid_set_base(out); - out->len = UUID_LEN_2; - encode2byte_little(&out->uuid[14], u2); - } - - static errcode_t sle_uuid_server_service_add(void) - { - errcode_t ret; - sle_uuid_t service_uuid = {0}; - sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid); - //添加一个ssap服务 - ret = ssaps_add_service_sync(g_server_id, &service_uuid, 1, &g_service_handle); - if (ret != ERRCODE_SLE_SUCCESS) { - osal_printk("[distance server] sle uuid add service fail, ret:%x\r\n", ret); - return ERRCODE_SLE_FAIL; - } - return ERRCODE_SLE_SUCCESS; - } - - static errcode_t sle_uuid_server_property_add(void) - { - errcode_t ret; - ssaps_property_info_t property = {0}; - ssaps_desc_info_t descriptor = {0}; - uint8_t ntf_value[] = {0x01, 0x0}; - - //添加特征信息 - property.permissions = SLE_UUID_TEST_PROPERTIES; //特征权限 - sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid); //SSAP 特征 UUID - property.value = osal_vmalloc(sizeof(g_sle_property_value)); //响应的数据 - property.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_NOTIFY; //操作指示 - if (property.value == NULL) { - osal_printk("[distance server] sle property mem fail\r\n"); - return ERRCODE_SLE_FAIL; - } - if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, - sizeof(g_sle_property_value)) != EOK) { - osal_vfree(property.value); - osal_printk("[distance server] sle property mem cpy fail\r\n"); - return ERRCODE_SLE_FAIL; - } - - //添加一个ssap特征 - ret = ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle); - if (ret != ERRCODE_SLE_SUCCESS) { - osal_printk("[distance server] sle uuid add property fail, ret:%x\r\n", ret); - osal_vfree(property.value); - return ERRCODE_SLE_FAIL; - } - - descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR; //特征权限 - descriptor.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_WRITE; //操作指示 - descriptor.type = SSAP_DESCRIPTOR_USER_DESCRIPTION; //描述符类型 - descriptor.value = ntf_value; //数据 - descriptor.value_len = sizeof(ntf_value); - - //添加一个ssap特征描述符 - ret = ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor); - if (ret != ERRCODE_SLE_SUCCESS) { - osal_printk("[distance server] sle uuid add descriptor fail, ret:%x\r\n", ret); - osal_vfree(property.value); - return ERRCODE_SLE_FAIL; - } - osal_vfree(property.value); - return ERRCODE_SLE_SUCCESS; - } - - //创建 server 实体 - static errcode_t sle_uuid_server_add(void) - { - errcode_t ret; - sle_uuid_t app_uuid = {0}; - - osal_printk("[distance server] sle uuid add service in\r\n"); - app_uuid.len = sizeof(g_sle_uuid_app_uuid); //设置 uuid 长度 - if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK) { - return ERRCODE_SLE_FAIL; - } - //注册ssap服务端 - ssaps_register_server(&app_uuid, &g_server_id); - - //若添加服务失败则注销服务端 - if (sle_uuid_server_service_add() != ERRCODE_SLE_SUCCESS) { - ssaps_unregister_server(g_server_id); - return ERRCODE_SLE_FAIL; - } - - //若添加特征失败则注销服务端 - if (sle_uuid_server_property_add() != ERRCODE_SLE_SUCCESS) { - ssaps_unregister_server(g_server_id); - return ERRCODE_SLE_FAIL; - } - - osal_printk("[distance server] sle uuid add service, server_id:%x, service_handle:%x, property_handle:%x\r\n", - g_server_id, g_service_handle, g_property_handle); - - //开始一个SSAP服务 - ret = ssaps_start_service(g_server_id, g_service_handle); - if (ret != ERRCODE_SLE_SUCCESS) { - osal_printk("[distance server] sle uuid add service fail, ret:%x\r\n", ret); - return ERRCODE_SLE_FAIL; - } - osal_printk("[distance server] sle uuid add service out\r\n"); - return ERRCODE_SLE_SUCCESS; - } - - - - - /* 初始化distance server */ - - errcode_t sle_distance_server_init(void) - { - uapi_watchdog_disable(); - enable_sle(); - printf("sle enable\r\n"); - sle_distance_server_set_nv(); - sle_conn_register_cbks(); - sle_ssaps_register_cbks(); - sle_uuid_server_add(); - sle_uuid_server_adv_init(); - sle_ssaps_set_info(); - sle_distance_connect_param_init(); - sle_set_local_addr_init(); - osal_printk("[distance server] init ok\r\n"); - return ERRCODE_SLE_SUCCESS; - } - - - - /* 函数入口 */ - int sle_distance_init(void) - { - //初始化全局变量 data - for (int i = 0; i < PKT_DATA_LEN; i++) { - data[i] = 'A'; - data[PKT_DATA_LEN - 1] = '\0'; //最后一个字节填充空字符,作为字符串的结尾标识 - } - osal_msleep(1000); //休眠1s - sle_distance_server_init(); - - - return 0; - } - - /* 线程与优先级设置 */ - static void sle_distance_entry(void) - { - osal_task *task_handle1 = NULL; - osal_kthread_lock(); - task_handle1= osal_kthread_create((osal_kthread_handler)sle_distance_init, 0, "distance", DISTANCE_DEFAULT_KTHREAD_SIZE); - if (task_handle1 != NULL) { - osal_kthread_set_priority(task_handle1, DISTANCE_DEFAULT_KTHREAD_PROI); - osal_kfree(task_handle1); - } - osal_kthread_unlock(); - } - - app_run(sle_distance_entry); +#include "app_init.h" +#include "watchdog.h" +#include "tcxo.h" +#include "systick.h" +#include "los_memory.h" +#include "securec.h" +#include "errcode.h" +#include "osal_addr.h" +#include "soc_osal.h" +#include "common_def.h" + +#include "sle_common.h" +#include "sle_errcode.h" +#include "sle_ssap_server.h" +#include "sle_connection_manager.h" +#include "sle_device_discovery.h" +#include "sle_transmition_manager.h" +#include "nv.h" + +#include "sle_server.h" + +// 线程参数 +#define DISTANCE_DEFAULT_KTHREAD_SIZE 0x2000 +#define DISTANCE_DEFAULT_KTHREAD_PROI 26 + +// 本地设备参数 +#define NAME_MAX_LENGTH 30 +static uint8_t mac[SLE_ADDR_LEN] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; +static uint8_t sle_local_name[NAME_MAX_LENGTH] = "sle_connect_server"; +// 数据包长度 +#define PKT_DATA_LEN 600 +static unsigned char data[PKT_DATA_LEN]; +// 确保为小端格式存储 +#define encode2byte_little(_ptr, data) \ + do { \ + *(uint8_t *)((_ptr) + 1) = (uint8_t)((data) >> 8); \ + *(uint8_t *)(_ptr) = (uint8_t)(data); \ + } while (0) + +// 设备公开 +#define SLE_CONN_INTV_MIN_DEFAULT 0xA // 连接最小调度间隔12.5ms,单位125us +#define SLE_CONN_INTV_MAX_DEFAULT 0xA // 连接最大调度间隔12.5ms,单位125us +#define SLE_ADV_INTERVAL_MIN_DEFAULT 0xC8 // 连接调度间隔25ms,单位125us +#define SLE_ADV_INTERVAL_MAX_DEFAULT 0xC8 // 超时时间5000ms,单位10ms +#define SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT 0x1F4 // 超时时间4990ms,单位10ms +#define SLE_CONN_MAX_LATENCY 0x1F3 // 广播发送功率 +#define SLE_ADV_TX_POWER 20 // 最大广播数据长度 +#define SLE_ADV_DATA_LEN_MAX 251 + +// 设备连接 + +#define DISTANCE_DEFAULT_CONN_INTERVAL 0xA0 +#define DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4 +#define DISTANCE_DEFAULT_SCAN_INTERVAL 400 +#define DISTANCE_DEFAULT_SCAN_WINDOW 20 +// 蓝牙地址索引 +#define BT_INDEX_4 4 +#define BT_INDEX_5 5 +#define BT_INDEX_0 0 + +static uint16_t g_conn_id = 0; + +// SSAP 参数 +#define OCTET_BIT_LEN 8 // 8比特长度 +#define UUID_LEN_2 2 // 两个字节 +static char g_sle_uuid_app_uuid[UUID_LEN_2] = {0x0, 0x0}; +static char g_sle_property_value[OCTET_BIT_LEN] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; + +// 传输参数 +#define DEFAULT_SLE_DISTANCE_DATA_LEN 1500 +#define DEFAULT_SLE_DISTANCE_MTU_SIZE 1500 +static uint8_t g_server_id = 0; +static uint16_t g_service_handle = 0; +static uint16_t g_property_handle = 0; +static uint8_t sle_uuid_base[] = {0x37, 0xBE, 0xA8, 0x80, 0xFC, 0x70, 0x11, 0xEA, + 0xB7, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; +extern uint8_t gle_tx_acb_data_num_get(void); + +/* 检查 BTC 功率档位 */ + +void sle_distance_server_set_nv(void) +{ + uint16_t nv_value_len = 0; + uint8_t nv_value = 0; + + // 读取指定NV数据项的值 + uapi_nv_read(0x20A0, sizeof(uint16_t), &nv_value_len, &nv_value); + if (nv_value != 7) { // 7:btc功率档位 + nv_value = 7; // 7:btc功率档位 + + // 写入NV数据项 + uapi_nv_write(0x20A0, (uint8_t *)&(nv_value), sizeof(nv_value)); + } + osal_printk("[distance server] The value of nv is set to %d.\r\n", nv_value); +} + +/* 本地设备参数 */ + +// 设置本端 MAC 地址 +void sle_set_local_addr_init(void) +{ + sle_addr_t addr = {0}; + addr.type = 0; + memcpy_s(addr.addr, SLE_ADDR_LEN, mac, SLE_ADDR_LEN); + sle_set_local_addr(&addr); +} + +// 设置本端名称 +static uint16_t sle_set_adv_local_name(uint8_t *adv_data, uint16_t max_len) +{ + errno_t ret; + uint8_t index = 0; + + uint8_t *local_name = sle_local_name; + uint8_t local_name_len = (uint8_t)strlen((char *)local_name); + for (uint8_t i = 0; i < local_name_len; i++) { + osal_printk("local_name[%d] = 0x%02x\r\n", i, local_name[i]); + } + + adv_data[index++] = local_name_len + 1; + adv_data[index++] = SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME; + ret = memcpy_s(&adv_data[index], max_len - index, local_name, local_name_len); + if (ret != EOK) { + osal_printk("memcpy fail\r\n"); + return 0; + } + return (uint16_t)index + local_name_len; +} + +/* 设备公开 */ + +// 设备公开参数 +static int sle_set_default_announce_param(void) +{ + // 初始化 + sle_announce_param_t param = {0}; + param.announce_mode = SLE_ANNOUNCE_MODE_CONNECTABLE_SCANABLE; // 公开类型 + param.announce_handle = SLE_ADV_HANDLE_DEFAULT; // 公开句柄 + param.announce_gt_role = SLE_ANNOUNCE_ROLE_T_CAN_NEGO; // gt角色协商指示 + param.announce_level = SLE_ANNOUNCE_LEVEL_NORMAL; // 发现等级 + param.announce_channel_map = SLE_ADV_CHANNEL_MAP_DEFAULT; // 设备公开信道 + param.announce_interval_min = SLE_ADV_INTERVAL_MIN_DEFAULT; // 最小设备公开周期 + param.announce_interval_max = SLE_ADV_INTERVAL_MAX_DEFAULT; // 最大设备公开周期 + param.conn_interval_min = SLE_CONN_INTV_MIN_DEFAULT; // 连接间隔最小取值 + param.conn_interval_max = SLE_CONN_INTV_MAX_DEFAULT; // 连接间隔最大取值 + param.conn_max_latency = SLE_CONN_MAX_LATENCY; // 最大休眠连接间隔 + param.conn_supervision_timeout = SLE_CONN_SUPERVISION_TIMEOUT_DEFAULT; // 最大超时时间 + param.announce_tx_power = SLE_ADV_TX_POWER; // 广播发射攻略 + param.own_addr.type = 0; // 本端地址 + memcpy_s(param.own_addr.addr, SLE_ADDR_LEN, mac, SLE_ADDR_LEN); + + // 设置参数 + return sle_set_announce_param(param.announce_handle, ¶m); +} + +void sle_enable_cbk(errcode_t status) +{ + osal_printk("sle enable status:%02x\r\n", status); +} + +void sle_announce_enable_cbk(uint32_t announce_id, errcode_t status) +{ + osal_printk("sle announce enable id:%02x, state:%02x\r\n", announce_id, status); +} + +void sle_announce_terminal_cbk(uint32_t announce_id) +{ + osal_printk("sle announce terminal id:%02x\r\n", announce_id); +} + +void sle_announce_disable_cbk(uint32_t announce_id, errcode_t status) +{ + osal_printk("sle announce disable id:%02x, state:%02x\r\n", announce_id, status); +} + +// 设备公开回调函数 +void sle_announce_register_cbks(void) +{ + sle_announce_seek_callbacks_t seek_cbks = {0}; + seek_cbks.sle_enable_cb = sle_enable_cbk; // SLE协议栈使能回调函数 + seek_cbks.announce_enable_cb = sle_announce_enable_cbk; // 设备公开使能回调函数 + seek_cbks.announce_terminal_cb = sle_announce_terminal_cbk; // 设备公开停止回调函数 + seek_cbks.announce_disable_cb = sle_announce_disable_cbk; // 设备公开关闭回调函数 + sle_announce_seek_register_callbacks(&seek_cbks); // 将回调函数注册到协议层 +} + +// 设置广播数据 +static uint16_t sle_set_adv_data(uint8_t *adv_data) +{ + size_t len = 0; + uint16_t idx = 0; + errno_t ret = 0; + + // 填充设备发现级别 + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_disc_level = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL, + .value = SLE_ANNOUNCE_LEVEL_NORMAL, + }; + + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_disc_level, len); + if (ret != EOK) { + osal_printk("adv_disc_level memcpy fail\r\n"); + return 0; + } + idx += len; + + // 填充访问模式 + len = sizeof(struct sle_adv_common_value); + struct sle_adv_common_value adv_access_mode = { + .length = len - 1, + .type = SLE_ADV_DATA_TYPE_ACCESS_MODE, + .value = 0, + }; + ret = memcpy_s(&adv_data[idx], SLE_ADV_DATA_LEN_MAX - idx, &adv_access_mode, len); + if (ret != EOK) { + osal_printk("memcpy fail\r\n"); + return 0; + } + idx += len; + return idx; +} + +static uint16_t sle_set_scan_response_data(uint8_t *scan_rsp_data) +{ + uint16_t idx = 0; + errno_t ret; + size_t scan_rsp_data_len = sizeof(struct sle_adv_common_value); + + struct sle_adv_common_value tx_power_level = { + .length = scan_rsp_data_len - 1, + .type = SLE_ADV_DATA_TYPE_TX_POWER_LEVEL, + .value = SLE_ADV_TX_POWER, + }; + ret = memcpy_s(scan_rsp_data, SLE_ADV_DATA_LEN_MAX, &tx_power_level, scan_rsp_data_len); + if (ret != EOK) { + osal_printk("sle scan response data memcpy fail\r\n"); + return 0; + } + idx += scan_rsp_data_len; + + /* set local name */ + idx += sle_set_adv_local_name(&scan_rsp_data[idx], SLE_ADV_DATA_LEN_MAX - idx); + return idx; +} + +static int sle_set_default_announce_data(void) +{ + errcode_t ret; + uint8_t announce_data_len = 0; + uint8_t seek_data_len = 0; + sle_announce_data_t data = {0}; + uint8_t adv_handle = SLE_ADV_HANDLE_DEFAULT; + uint8_t announce_data[SLE_ADV_DATA_LEN_MAX] = {0}; + uint8_t seek_rsp_data[SLE_ADV_DATA_LEN_MAX] = {0}; + + osal_printk("set adv data default\r\n"); + + // 设置广播数据 + announce_data_len = sle_set_adv_data(announce_data); + data.announce_data = announce_data; + data.announce_data_len = announce_data_len; + // 设置扫描相应数据 + seek_data_len = sle_set_scan_response_data(seek_rsp_data); + data.seek_rsp_data = seek_rsp_data; + data.seek_rsp_data_len = seek_data_len; + // 设置参数 + ret = sle_set_announce_data(adv_handle, &data); + if (ret == ERRCODE_SLE_SUCCESS) { + osal_printk("[SLE DD SDK] set announce data success."); + } else { + osal_printk("[SLE DD SDK] set adv param fail."); + } + return ERRCODE_SLE_SUCCESS; +} + +static errcode_t sle_uuid_server_adv_init(void) +{ + osal_printk("sle_uuid_server_adv_init in\r\n"); + + sle_announce_register_cbks(); + sle_set_default_announce_param(); + sle_set_default_announce_data(); + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); // 开始设备公开 + osal_printk("sle_uuid_server_adv_init out\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +// ssap 信息交换设置 +void sle_ssaps_set_info(void) +{ + ssap_exchange_info_t info = {0}; + info.mtu_size = DEFAULT_SLE_DISTANCE_MTU_SIZE; + info.version = 1; + ssaps_set_info(g_server_id, &info); +} + +/* 设备连接 */ + +// 连接参数 +void sle_distance_connect_param_init(void) +{ + sle_default_connect_param_t param = {0}; + param.enable_filter_policy = 0; // 过滤功能 + param.gt_negotiate = 0; + param.initiate_phys = 1; + param.max_interval = DISTANCE_DEFAULT_CONN_INTERVAL; + param.min_interval = DISTANCE_DEFAULT_CONN_INTERVAL; + param.scan_interval = DISTANCE_DEFAULT_SCAN_INTERVAL; + param.scan_window = DISTANCE_DEFAULT_SCAN_WINDOW; + param.timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; + sle_default_connection_param_set(¶m); +} + +// 连接状态改变回调函数 +static void sle_connect_state_changed_cbk(uint16_t conn_id, + const sle_addr_t *addr, + sle_acb_state_t conn_state, + sle_pair_state_t pair_state, + sle_disc_reason_t disc_reason) +{ + osal_printk( + "[distance server] connect state changed conn_id:0x%02x, conn_state:0x%x, pair_state:0x%x, \ + disc_reason:0x%x\r\n", + conn_id, conn_state, pair_state, disc_reason); + osal_printk("[distance server] connect state changed addr:%02x:**:**:**:%02x:%02x\r\n", addr->addr[BT_INDEX_0], + addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); + g_conn_id = conn_id; + sle_connection_param_update_t parame = {0}; + parame.conn_id = conn_id; + parame.interval_min = DISTANCE_DEFAULT_CONN_INTERVAL; + parame.interval_max = DISTANCE_DEFAULT_CONN_INTERVAL; + parame.max_latency = 0; + parame.supervision_timeout = DISTANCE_DEFAULT_TIMEOUT_MULTIPLIER; + if (conn_state == SLE_ACB_STATE_CONNECTED) { + sle_update_connect_param(¶me); + } else if (conn_state == SLE_ACB_STATE_DISCONNECTED) { + sle_start_announce(SLE_ADV_HANDLE_DEFAULT); + } +} + +// 连接参数请求更新回调函数 +void sle_sample_update_req_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_req_t *param) +{ + unused(conn_id); + unused(status); + osal_printk("[ssap server] sle_sample_update_req_cbk interval_min:%02x, interval_max:%02x\n", param->interval_min, + param->interval_max); +} + +// 连接参数更新完成回调函数 +void sle_sample_update_cbk(uint16_t conn_id, errcode_t status, const sle_connection_param_update_evt_t *param) +{ + unused(status); + osal_printk("[ssap server] updat state changed conn_id:%d, interval = %02x\n", conn_id, param->interval); +} + +// 配对完成回调函数 +static void sle_pair_complete_cbk(uint16_t conn_id, const sle_addr_t *addr, errcode_t status) +{ + osal_printk("[distance server] pair complete conn_id:%02x, status:%x\r\n", conn_id, status); + osal_printk("[distance server] pair complete addr:%02x:**:**:**:%02x:%02x\r\n", addr->addr[BT_INDEX_0], + addr->addr[BT_INDEX_4], addr->addr[BT_INDEX_5]); +} + +static void sle_conn_register_cbks(void) +{ + sle_connection_callbacks_t conn_cbks = {0}; + conn_cbks.connect_state_changed_cb = sle_connect_state_changed_cbk; // 连接状态改变回调函数 + conn_cbks.connect_param_update_req_cb = sle_sample_update_req_cbk; // 连接参数请求更新回调函数 + conn_cbks.connect_param_update_cb = sle_sample_update_cbk; // 连接参数更新完成回调函数 + conn_cbks.pair_complete_cb = sle_pair_complete_cbk; // 配对完成回调函数 + sle_connection_register_callbacks(&conn_cbks); // 将回调函数结构体注册到协议层 +} + +/* SSAP server */ + +// 启动服务回调函数 +static void ssaps_start_service_cbk(uint8_t server_id, uint16_t handle, errcode_t status) +{ + osal_printk("[distance server] start service cbk server_id:%d, handle:%d, status:%d\r\n", server_id, handle, + status); +} + +// mtu 大小更新回调函数 +static void ssaps_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, ssap_exchange_info_t *mtu_size, errcode_t status) +{ + osal_printk("[distance server] ssaps write request cbk server_id:%d, conn_id:%d, mtu_size:%d, status:%d\r\n", + server_id, conn_id, mtu_size->mtu_size, status); +} + +// 发送信息 +static errcode_t sle_uuid_server_send_report_by_handle_id(uint8_t *data, uint16_t len, uint16_t connect_id) +{ + ssaps_ntf_ind_t param = {0}; + param.handle = g_property_handle; + param.type = SSAP_PROPERTY_TYPE_VALUE; + param.value = data; + param.value_len = len; + + // 向对端发送通知 + ssaps_notify_indicate(g_server_id, connect_id, ¶m); + return ERRCODE_SLE_SUCCESS; +} + +static uint8_t sle_flow_ctrl_flag(void) +{ + return gle_tx_acb_data_num_get(); +} + +static void send_data_thread_function(void) +{ + // 设置最大传输长度 + sle_set_data_len(g_conn_id, DEFAULT_SLE_DISTANCE_DATA_LEN); + + osal_printk("code: GFSK, PHY 1MHZ, power: 20dbm \r\n"); + int i = 0; + while (1) { + if (sle_flow_ctrl_flag() > 0) { + i++; + // 填充数据 + data[0] = (i >> 8) & 0xFF; + data[1] = i & 0xFF; + + // 发送数据包 + sle_uuid_server_send_report_by_handle_id(data, PKT_DATA_LEN, g_conn_id); + } + } +} + +// 收到远端读请求回调函数 +static void ssaps_read_request_cbk(uint8_t server_id, + uint16_t conn_id, + ssaps_req_read_cb_t *read_cb_para, + errcode_t status) +{ + osal_printk("[distance server] ssaps read request cbk server_id:%x, conn_id:%x, handle:%x, status:%x\r\n", + server_id, conn_id, read_cb_para->handle, status); + + // 创建新线程完成发送任务 + osal_task *task_handle = NULL; + osal_kthread_lock(); + task_handle = osal_kthread_create((osal_kthread_handler)send_data_thread_function, 0, "RadarTask", + DISTANCE_DEFAULT_KTHREAD_SIZE); + osal_kthread_set_priority(task_handle, DISTANCE_DEFAULT_KTHREAD_PROI + 1); + if (task_handle != NULL) { + osal_kfree(task_handle); + } + osal_kthread_unlock(); + printf("kthread success\r\n"); +} + +// 收到远端写请求回调函数 +static void ssaps_write_request_cbk(uint8_t server_id, + uint16_t conn_id, + ssaps_req_write_cb_t *write_cb_para, + errcode_t status) +{ + osal_printk("[distance server] ssaps write request cbk server_id:%d, conn_id:%d, handle:%d, status:%d\r\n", + server_id, conn_id, write_cb_para->handle, status); +} + +// 注册 ssap server 回调 +static void sle_ssaps_register_cbks(void) +{ + ssaps_callbacks_t ssaps_cbk = {0}; + ssaps_cbk.start_service_cb = ssaps_start_service_cbk; // 启动服务回调函数 + ssaps_cbk.mtu_changed_cb = ssaps_mtu_changed_cbk; // mtu 大小更新回调函数 + ssaps_cbk.read_request_cb = ssaps_read_request_cbk; // 收到远端读请求回调函数 + ssaps_cbk.write_request_cb = ssaps_write_request_cbk; // 收到远端写请求回调函数 + ssaps_register_callbacks(&ssaps_cbk); +} + +// 复制128-bit UUID 到结构体 +static void sle_uuid_set_base(sle_uuid_t *out) +{ + (void)memcpy_s(out->uuid, SLE_UUID_LEN, sle_uuid_base, SLE_UUID_LEN); + out->len = UUID_LEN_2; +} + +// 将 uuid 转换为小端格式 +static void sle_uuid_setu2(uint16_t u2, sle_uuid_t *out) +{ + sle_uuid_set_base(out); + out->len = UUID_LEN_2; + encode2byte_little(&out->uuid[14], u2); +} + +static errcode_t sle_uuid_server_service_add(void) +{ + errcode_t ret; + sle_uuid_t service_uuid = {0}; + sle_uuid_setu2(SLE_UUID_SERVER_SERVICE, &service_uuid); + // 添加一个ssap服务 + ret = ssaps_add_service_sync(g_server_id, &service_uuid, 1, &g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[distance server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + return ERRCODE_SLE_SUCCESS; +} + +static errcode_t sle_uuid_server_property_add(void) +{ + errcode_t ret; + ssaps_property_info_t property = {0}; + ssaps_desc_info_t descriptor = {0}; + uint8_t ntf_value[] = {0x01, 0x0}; + + // 添加特征信息 + property.permissions = SLE_UUID_TEST_PROPERTIES; // 特征权限 + sle_uuid_setu2(SLE_UUID_SERVER_NTF_REPORT, &property.uuid); // SSAP 特征 UUID + property.value = osal_vmalloc(sizeof(g_sle_property_value)); // 响应的数据 + property.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_NOTIFY; // 操作指示 + if (property.value == NULL) { + osal_printk("[distance server] sle property mem fail\r\n"); + return ERRCODE_SLE_FAIL; + } + if (memcpy_s(property.value, sizeof(g_sle_property_value), g_sle_property_value, sizeof(g_sle_property_value)) != + EOK) { + osal_vfree(property.value); + osal_printk("[distance server] sle property mem cpy fail\r\n"); + return ERRCODE_SLE_FAIL; + } + + // 添加一个ssap特征 + ret = ssaps_add_property_sync(g_server_id, g_service_handle, &property, &g_property_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[distance server] sle uuid add property fail, ret:%x\r\n", ret); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + + descriptor.permissions = SLE_UUID_TEST_DESCRIPTOR; // 特征权限 + descriptor.operate_indication = SSAP_OPERATE_INDICATION_BIT_READ | SSAP_OPERATE_INDICATION_BIT_WRITE; // 操作指示 + descriptor.type = SSAP_DESCRIPTOR_USER_DESCRIPTION; // 描述符类型 + descriptor.value = ntf_value; // 数据 + descriptor.value_len = sizeof(ntf_value); + + // 添加一个ssap特征描述符 + ret = ssaps_add_descriptor_sync(g_server_id, g_service_handle, g_property_handle, &descriptor); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[distance server] sle uuid add descriptor fail, ret:%x\r\n", ret); + osal_vfree(property.value); + return ERRCODE_SLE_FAIL; + } + osal_vfree(property.value); + return ERRCODE_SLE_SUCCESS; +} + +// 创建 server 实体 +static errcode_t sle_uuid_server_add(void) +{ + errcode_t ret; + sle_uuid_t app_uuid = {0}; + + osal_printk("[distance server] sle uuid add service in\r\n"); + app_uuid.len = sizeof(g_sle_uuid_app_uuid); // 设置 uuid 长度 + if (memcpy_s(app_uuid.uuid, app_uuid.len, g_sle_uuid_app_uuid, sizeof(g_sle_uuid_app_uuid)) != EOK) { + return ERRCODE_SLE_FAIL; + } + // 注册ssap服务端 + ssaps_register_server(&app_uuid, &g_server_id); + + // 若添加服务失败则注销服务端 + if (sle_uuid_server_service_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + + // 若添加特征失败则注销服务端 + if (sle_uuid_server_property_add() != ERRCODE_SLE_SUCCESS) { + ssaps_unregister_server(g_server_id); + return ERRCODE_SLE_FAIL; + } + + osal_printk("[distance server] sle uuid add service, server_id:%x, service_handle:%x, property_handle:%x\r\n", + g_server_id, g_service_handle, g_property_handle); + + // 开始一个SSAP服务 + ret = ssaps_start_service(g_server_id, g_service_handle); + if (ret != ERRCODE_SLE_SUCCESS) { + osal_printk("[distance server] sle uuid add service fail, ret:%x\r\n", ret); + return ERRCODE_SLE_FAIL; + } + osal_printk("[distance server] sle uuid add service out\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +/* 初始化distance server */ + +errcode_t sle_distance_server_init(void) +{ + uapi_watchdog_disable(); + enable_sle(); + printf("sle enable\r\n"); + sle_distance_server_set_nv(); + sle_conn_register_cbks(); + sle_ssaps_register_cbks(); + sle_uuid_server_add(); + sle_uuid_server_adv_init(); + sle_ssaps_set_info(); + sle_distance_connect_param_init(); + sle_set_local_addr_init(); + osal_printk("[distance server] init ok\r\n"); + return ERRCODE_SLE_SUCCESS; +} + +/* 函数入口 */ +int sle_distance_init(void) +{ + // 初始化全局变量 data + for (int i = 0; i < PKT_DATA_LEN; i++) { + data[i] = 'A'; + data[PKT_DATA_LEN - 1] = '\0'; // 最后一个字节填充空字符,作为字符串的结尾标识 + } + osal_msleep(1000); // 休眠1s + sle_distance_server_init(); + + return 0; +} + +/* 线程与优先级设置 */ +static void sle_distance_entry(void) +{ + osal_task *task_handle1 = NULL; + osal_kthread_lock(); + task_handle1 = + osal_kthread_create((osal_kthread_handler)sle_distance_init, 0, "distance", DISTANCE_DEFAULT_KTHREAD_SIZE); + if (task_handle1 != NULL) { + osal_kthread_set_priority(task_handle1, DISTANCE_DEFAULT_KTHREAD_PROI); + osal_kfree(task_handle1); + } + osal_kthread_unlock(); +} + +app_run(sle_distance_entry); -- Gitee From 5e7f412619df47251994245b796bfd224488d6ee Mon Sep 17 00:00:00 2001 From: Kid <3548263564@qq.com> Date: Sun, 17 Aug 2025 09:04:16 +0000 Subject: [PATCH 4/4] update vendor/developers/demo/sle_tag/sle_server.h. Signed-off-by: Kid <3548263564@qq.com> --- vendor/developers/demo/sle_tag/sle_server.h | 321 ++++++++++---------- 1 file changed, 159 insertions(+), 162 deletions(-) diff --git a/vendor/developers/demo/sle_tag/sle_server.h b/vendor/developers/demo/sle_tag/sle_server.h index 0a0a9b25..3fa7420b 100644 --- a/vendor/developers/demo/sle_tag/sle_server.h +++ b/vendor/developers/demo/sle_tag/sle_server.h @@ -1,162 +1,159 @@ - /** - * @defgroup bluetooth_sle_adv API - * @ingroup - * @{ - */ - - #ifndef SLE_SERVER_ADV_H - #define SLE_SERVER_ADV_H - - #include "sle_ssap_server.h" - - /* 广播ID */ - #define SLE_ADV_HANDLE_DEFAULT 1 - - /** - * @if Eng - * @brief Definitaion of BLE ADV 通用广播结构. - * @else - * @brief SLE 广播普通数据结构。 - * @endif - */ - struct sle_adv_common_value { - uint8_t length; - uint8_t type; - uint8_t value; - }; - - /** - * @if Eng - * @brief Definitaion of BLE ADV Channel mapping. - * @else - * @brief SLE 广播信道映射。 - * @endif - */ - typedef enum { - SLE_ADV_CHANNEL_MAP_77 = 0x01, - SLE_ADV_CHANNEL_MAP_78 = 0x02, - SLE_ADV_CHANNEL_MAP_79 = 0x04, - SLE_ADV_CHANNEL_MAP_DEFAULT = 0x07 - } sle_adv_channel_map; - - /** - * @if Eng - * @brief Definitaion of SLE ADV Data Type. - * @else - * @brief SLE 广播数据类型 - * @endif - */ - typedef enum { - SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL = 0x01, /*!< 发现等级 */ - SLE_ADV_DATA_TYPE_ACCESS_MODE = 0x02, /*!< 接入层能力 */ - SLE_ADV_DATA_TYPE_SERVICE_DATA_16BIT_UUID = 0x03, /*!< 标准服务数据信息 */ - SLE_ADV_DATA_TYPE_SERVICE_DATA_128BIT_UUID = 0x04, /*!< 自定义服务数据信息 */ - SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x05, /*!< 完整标准服务标识列表 */ - SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x06, /*!< 完整自定义服务标识列表 */ - SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x07, /*!< 部分标准服务标识列表 */ - SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x08, /*!< 部分自定义服务标识列表 */ - SLE_ADV_DATA_TYPE_SERVICE_STRUCTURE_HASH_VALUE = 0x09, /*!< 服务结构散列值 */ - SLE_ADV_DATA_TYPE_SHORTENED_LOCAL_NAME = 0x0A, /*!< 设备缩写本地名称 */ - SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME = 0x0B, /*!< 设备完整本地名称 */ - SLE_ADV_DATA_TYPE_TX_POWER_LEVEL = 0x0C, /*!< 广播发送功率 */ - SLE_ADV_DATA_TYPE_SLB_COMMUNICATION_DOMAIN = 0x0D, /*!< SLB通信域域名 */ - SLE_ADV_DATA_TYPE_SLB_MEDIA_ACCESS_LAYER_ID = 0x0E, /*!< SLB媒体接入层标识 */ - SLE_ADV_DATA_TYPE_EXTENDED = 0xFE, /*!< 数据类型扩展 */ - SLE_ADV_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF /*!< 厂商自定义信息 */ - } sle_adv_data_type; - - - /** - * @if Eng - * @brief sle adv data config. - * @attention NULL - * @retval ERRCODE_SLE_SUCCESS Excute successfully - * @retval ERRCODE_SLE_FAIL Execute fail - * @par Dependency: - * @li NULL - * @else - * @brief sle广播数据配置。 - * @attention NULL - * @retval ERRCODE_SLE_SUCCESS 执行成功 - * @retval ERRCODE_SLE_FAIL 执行失败 - * @par 依赖: - * @li NULL - * @endif - */ - static errcode_t sle_uuid_server_adv_init(void); - - - - /* Service UUID */ - #define SLE_UUID_SERVER_SERVICE 0xABCD - - /* Property UUID */ - #define SLE_UUID_SERVER_NTF_REPORT 0x1122 - - /* Property Property */ - #define SLE_UUID_TEST_PROPERTIES (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) - - /* Descriptor Property */ - #define SLE_UUID_TEST_DESCRIPTOR (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) - - /** - * @if Eng - * @brief SLE uuid server inir. - * @attention NULL - * @retval ERRCODE_SLE_SUCCESS Excute successfully - * @retval ERRCODE_SLE_FAIL Execute fail - * @par Dependency: - * @li sle_ssap_server.h - * @else - * @brief SLE UUID服务器初始化。 - * @attention NULL - * @retval ERRCODE_SLE_SUCCESS 执行成功 - * @retval ERRCODE_SLE_FAIL 执行失败 - * @par 依赖: - * @li sle_ssap_server.h - * @endif - */ - errcode_t sle_uuid_server_init(void); - - /** - * @if Eng - * @brief send data to peer device by uuid on uuid server. - * @attention NULL - * @param [in] value send value. - * @param [in] len Length of send value。 - * @retval ERRCODE_SLE_SUCCESS Excute successfully - * @retval ERRCODE_SLE_FAIL Execute fail - * @par Dependency: - * @li sle_ssap_server.h - * @else - * @brief 通过uuid server 发送数据给对端。 - * @attention NULL - * @retval ERRCODE_SLE_SUCCESS 执行成功 - * @retval ERRCODE_SLE_FAIL 执行失败 - * @par 依赖: - * @li sle_ssap_server.h - * @endif - */ - errcode_t sle_uuid_server_send_report_by_uuid(uint8_t *data, uint16_t len); - - /** - * @if Eng - * @brief send data to peer device by handle on uuid server. - * @attention NULL - * @param [in] value send value. - * @param [in] len Length of send value。 - * @retval ERRCODE_SLE_SUCCESS Excute successfully - * @retval ERRCODE_SLE_FAIL Execute fail - * @par Dependency: - * @li sle_ssap_server.h - * @else - * @brief 通过uuid server 发送数据给对端。 - * @attention NULL - * @retval ERRCODE_SLE_SUCCESS 执行成功 - * @retval ERRCODE_SLE_FAIL 执行失败 - * @par 依赖: - * @li sle_ssap_server.h - * @endif - */ - errcode_t sle_uuid_server_send_report_by_handle(const uint8_t *data, uint8_t len); - #endif +/** + * @defgroup bluetooth_sle_adv API + * @ingroup + * @{ + */ + +#ifndef SLE_SERVER_ADV_H +#define SLE_SERVER_ADV_H + +#include "sle_ssap_server.h" + +/* 广播ID */ +#define SLE_ADV_HANDLE_DEFAULT 1 + +/** + * @if Eng + * @brief Definitaion of BLE ADV 通用广播结构. + * @else + * @brief SLE 广播普通数据结构。 + * @endif + */ +struct sle_adv_common_value { +uint8_t length; +uint8_t type; +uint8_t value; +}; + +/** + * @if Eng + * @brief Definitaion of BLE ADV Channel mapping. + * @else + * @brief SLE 广播信道映射。 + * @endif + */ +typedef enum { +SLE_ADV_CHANNEL_MAP_77 = 0x01, +SLE_ADV_CHANNEL_MAP_78 = 0x02, +SLE_ADV_CHANNEL_MAP_79 = 0x04, +SLE_ADV_CHANNEL_MAP_DEFAULT = 0x07 +} sle_adv_channel_map; + +/** + * @if Eng + * @brief Definitaion of SLE ADV Data Type. + * @else + * @brief SLE 广播数据类型 + * @endif + */ +typedef enum { +SLE_ADV_DATA_TYPE_DISCOVERY_LEVEL = 0x01, /*!< 发现等级 */ +SLE_ADV_DATA_TYPE_ACCESS_MODE = 0x02, /*!< 接入层能力 */ +SLE_ADV_DATA_TYPE_SERVICE_DATA_16BIT_UUID = 0x03, /*!< 标准服务数据信息 */ +SLE_ADV_DATA_TYPE_SERVICE_DATA_128BIT_UUID = 0x04, /*!< 自定义服务数据信息 */ +SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x05, /*!< 完整标准服务标识列表 */ +SLE_ADV_DATA_TYPE_COMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x06, /*!< 完整自定义服务标识列表 */ +SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_16BIT_SERVICE_UUIDS = 0x07, /*!< 部分标准服务标识列表 */ +SLE_ADV_DATA_TYPE_INCOMPLETE_LIST_OF_128BIT_SERVICE_UUIDS = 0x08, /*!< 部分自定义服务标识列表 */ +SLE_ADV_DATA_TYPE_SERVICE_STRUCTURE_HASH_VALUE = 0x09, /*!< 服务结构散列值 */ +SLE_ADV_DATA_TYPE_SHORTENED_LOCAL_NAME = 0x0A, /*!< 设备缩写本地名称 */ +SLE_ADV_DATA_TYPE_COMPLETE_LOCAL_NAME = 0x0B, /*!< 设备完整本地名称 */ +SLE_ADV_DATA_TYPE_TX_POWER_LEVEL = 0x0C, /*!< 广播发送功率 */ +SLE_ADV_DATA_TYPE_SLB_COMMUNICATION_DOMAIN = 0x0D, /*!< SLB通信域域名 */ +SLE_ADV_DATA_TYPE_SLB_MEDIA_ACCESS_LAYER_ID = 0x0E, /*!< SLB媒体接入层标识 */ +SLE_ADV_DATA_TYPE_EXTENDED = 0xFE, /*!< 数据类型扩展 */ +SLE_ADV_DATA_TYPE_MANUFACTURER_SPECIFIC_DATA = 0xFF /*!< 厂商自定义信息 */ +} sle_adv_data_type; + +/** + * @if Eng + * @brief sle adv data config. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li NULL + * @else + * @brief sle广播数据配置。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li NULL + * @endif + */ +static errcode_t sle_uuid_server_adv_init(void); + +/* Service UUID */ +#define SLE_UUID_SERVER_SERVICE 0xABCD + +/* Property UUID */ +#define SLE_UUID_SERVER_NTF_REPORT 0x1122 + +/* Property Property */ +#define SLE_UUID_TEST_PROPERTIES (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + +/* Descriptor Property */ +#define SLE_UUID_TEST_DESCRIPTOR (SSAP_PERMISSION_READ | SSAP_PERMISSION_WRITE) + +/** + * @if Eng + * @brief SLE uuid server inir. + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief SLE UUID服务器初始化。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_init(void); + +/** + * @if Eng + * @brief send data to peer device by uuid on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_send_report_by_uuid(uint8_t *data, uint16_t len); + +/** + * @if Eng + * @brief send data to peer device by handle on uuid server. + * @attention NULL + * @param [in] value send value. + * @param [in] len Length of send value。 + * @retval ERRCODE_SLE_SUCCESS Excute successfully + * @retval ERRCODE_SLE_FAIL Execute fail + * @par Dependency: + * @li sle_ssap_server.h + * @else + * @brief 通过uuid server 发送数据给对端。 + * @attention NULL + * @retval ERRCODE_SLE_SUCCESS 执行成功 + * @retval ERRCODE_SLE_FAIL 执行失败 + * @par 依赖: + * @li sle_ssap_server.h + * @endif + */ +errcode_t sle_uuid_server_send_report_by_handle(const uint8_t *data, uint8_t len); +#endif -- Gitee