初始提交

This commit is contained in:
2025-05-13 22:00:58 +08:00
commit e4c030b0c0
564 changed files with 78858 additions and 0 deletions

View File

@ -0,0 +1,8 @@
#===============================================================================
# @brief cmake file
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
#===============================================================================
add_subdirectory_if_exist(src)
set(SOURCES "${SOURCES}" PARENT_SCOPE)
set(PUBLIC_HEADER "${PUBLIC_HEADER}" "${CMAKE_CURRENT_SOURCE_DIR}/inc" PARENT_SCOPE)

View File

@ -0,0 +1,91 @@
/*
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved.
*
* Description: BLE UUID Server module.
*/
/**
* @defgroup bluetooth_bts_hid_server HID SERVER API
* @ingroup
* @{
*/
#ifndef BLE_UUID_SERVER_H
#define BLE_UUID_SERVER_H
#include "bts_def.h"
/* Service UUID */
#define BLE_UUID_UUID_SERVER_SERVICE 0xABCD
/* Characteristic UUID */
#define BLE_UUID_UUID_SERVER_REPORT 0xCDEF
/* Client Characteristic Configuration UUID */
#define BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION 0x2902
/* Server ID */
#define BLE_UUID_SERVER_ID 1
/* Characteristic Property */
#define UUID_SERVER_PROPERTIES (GATT_CHARACTER_PROPERTY_BIT_READ | GATT_CHARACTER_PROPERTY_BIT_NOTIFY)
/**
* @if Eng
* @brief BLE uuid server inir.
* @attention NULL
* @retval BT_STATUS_SUCCESS Excute successfully
* @retval BT_STATUS_FAIL Execute fail
* @par Dependency:
* @li bts_def.h
* @else
* @brief BLE UUID服务器初始化。
* @attention NULL
* @retval BT_STATUS_SUCCESS 执行成功
* @retval BT_STATUS_FAIL 执行失败
* @par 依赖:
* @li bts_def.h
* @endif
*/
errcode_t ble_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 BT_STATUS_SUCCESS Excute successfully
* @retval BT_STATUS_FAIL Execute fail
* @par Dependency:
* @li bts_def.h
* @else
* @brief 通过uuid server 发送数据给对端。
* @attention NULL
* @retval BT_STATUS_SUCCESS 执行成功
* @retval BT_STATUS_FAIL 执行失败
* @par 依赖:
* @li bts_def.h
* @endif
*/
errcode_t ble_uuid_server_send_report_by_uuid(const uint8_t *data, uint8_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 BT_STATUS_SUCCESS Excute successfully
* @retval BT_STATUS_FAIL Execute fail
* @par Dependency:
* @li bts_def.h
* @else
* @brief 通过uuid server 发送数据给对端。
* @attention NULL
* @retval BT_STATUS_SUCCESS 执行成功
* @retval BT_STATUS_FAIL 执行失败
* @par 依赖:
* @li bts_def.h
* @endif
*/
errcode_t ble_uuid_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len);
#endif

View File

@ -0,0 +1,212 @@
/*
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
*
* Description: BLE ADV Config.
*/
/**
* @defgroup bluetooth_bts_ble_adv API
* @ingroup
* @{
*/
#ifndef BLE_SERVER_ADV_H
#define BLE_SERVER_ADV_H
#include "bts_def.h"
/* Ble Adv type Flag length */
#define BLE_ADV_FLAG_LEN 0x03
/* Ble Adv data length */
#define BLE_GENERAL_BYTE_1 1
/* Ble Adv appearance length */
#define BLE_ADV_APPEARANCE_LENGTH 4
/* Ble Adv appearance type */
#define BLE_ADV_APPEARANCE_DATA_TYPE 0x19
/* Ble keyboard appearance type */
#define BLE_ADV_CATEGORY_KEYBOARD_VALUE 0x0080
/* Ble keyboard categorylength */
#define BLE_ADV_CATEGORY_LEN 2
/* Ble name adv param type length */
#define BLE_ADV_PARAM_DATATYPE_LENGTH 1
/* Ble name adv name type */
#define BLE_ADV_LOCAL_NAME_DATA_TYPE 0x09
/* Ble name adv tx power type */
#define BLE_ADV_TX_POWER_LEVEL 0x0A
/* Ble name adv tx power response type */
#define BLE_SCAN_RSP_TX_POWER_LEVEL_LEN 0x03
/* Ble adv flag data */
#define BLE_ADV_FLAG_DATA 0x05
/**
* @if Eng
* @brief Definitaion of BLE ADV data flag.
* @else
* @brief BLE 广播数据类型定义。
* @endif
*/
typedef struct {
uint8_t length; /*!< @if Eng adv data flag length.
@else 广播数据类型长度 */
uint8_t adv_data_type; /*!< @if Eng adv data type.
@else 广播数据类型 */
uint8_t flags; /*!< @if Eng adv data flag.
@else 广播数据标志 */
} ble_adv_flag;
/**
* @if Eng
* @brief Definitaion of BLE device appearance struct.
* @else
* @brief BLE 广播设备外观结构。
* @endif
*/
typedef struct {
uint8_t length; /*!< @if Eng adv appearance data length.
@else 设备外观数据类型长度 */
uint8_t adv_data_type; /*!< @if Eng adv appearance data type.
@else 设备外观数据类型 */
uint8_t catogory_id[BLE_ADV_CATEGORY_LEN]; /*!< @if Eng adv appearance data.
@else 设备外观数据 */
} ble_appearance_st;
/**
* @if Eng
* @brief Definitaion of BLE device name.
* @else
* @brief BLE 广播设备名称。
* @endif
*/
typedef struct {
uint8_t length; /*!< @if Eng adv device name length.
@else 广播设备名称类型长度 */
uint8_t adv_data_type; /*!< @if Eng adv name data type.
@else 设备名称类型 */
int8_t *name; /*!< @if Eng adv name data.
@else 设备名称数据指针 */
} ble_local_name_st;
/**
* @if Eng
* @brief Definitaion of BLE Tx power.
* @else
* @brief BLE 广播发送功率。
* @endif
*/
typedef struct {
uint8_t length; /*!< @if Eng adv tx power length.
@else 广播发送功率长度 */
uint8_t adv_data_type; /*!< @if Eng adv tx power type.
@else 广播发送数据类型 */
uint8_t tx_power_value; /*!< @if Eng adv tx power value.
@else 广播发送数据 */
} ble_tx_power_level_st;
/**
* @if Eng
* @brief Definitaion value range for typedef struct ble_adv_para.adv_filter_policy.
* @else
* @brief Ble adv filter policy定义值范围。
* @endif
*/
typedef enum ble_adv_filter_policy {
BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_ANY = 0x00,
BLE_ADV_FILTER_POLICY_SCAN_WHITE_LIST_CONNECT_ANY = 0x01,
BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_WHITE_LIST = 0x02,
BLE_ADV_FILTER_POLICY_SCAN_WHITE_LIST_CONNECT_WHITE_LIST = 0x03
} ble_adv_filter_policy_t;
/**
* @if Eng
* @brief Definitaion value range for adv type.
* @else
* @brief Ble adv 类型范围。
* @endif
*/
typedef enum ble_adverting_type {
BLE_ADV_TYPE_CONNECTABLE_UNDIRECTED = 0x00,
BLE_ADV_TYPE_CONNECTABLE_HIGH_DUTY_CYCLE_DIRECTED = 0x01,
BLE_ADV_TYPE_SCANNABLE_UNDIRECTED = 0x02,
BLE_ADV_TYPE_NON_CONNECTABLE_UNDIRECTED = 0x03,
BLE_ADV_TYPE_CONNECTABLE_LOW_DUTY_CYCLE_DIRECTED = 0x04
} ble_adverting_type_t;
/**
* @if Eng
* @brief Definitaion value range for adv channel map.
* @else
* @brief Ble 广播信道范围。
* @endif
*/
typedef enum ble_adv_channel_map {
BLE_ADV_CHANNEL_MAP_CH_37 = 0x01,
BLE_ADV_CHANNEL_MAP_CH_38 = 0x02,
BLE_ADV_CHANNEL_MAP_CH_39 = 0x04,
BLE_ADV_CHANNEL_MAP_CH_37_CH_38 = 0x03,
BLE_ADV_CHANNEL_MAP_CH_37_CH_39 = 0x05,
BLE_ADV_CHANNEL_MAP_CH_38_CH_39 = 0x06,
BLE_ADV_CHANNEL_MAP_CH_DEFAULT = 0x07
} ble_adv_channel_map_t;
/**
* @if Eng
* @brief Definitaion value range for adv addr type.
* @else
* @brief Ble 广播地址类型。
* @endif
*/
typedef enum {
BLE_PUBLIC_DEVICE_ADDRESS = 0x00,
BLE_RANDOM_DEVICE_ADDRESS = 0x01,
BLE_PUBLIC_IDENTITY_ADDRESS = 0x02,
BLE_RANDOM_STATIC_IDENTITY_ADDRESS = 0x03
} ble_address_type;
/* Ble adv min interval */
#define BLE_ADV_MIN_INTERVAL 0x30
/* Ble adv max interval */
#define BLE_ADV_MAX_INTERVAL 0x60
/* Ble adv handle */
#define BTH_GAP_BLE_ADV_HANDLE_DEFAULT 0x01
/* Ble adv duration */
#define BTH_GAP_BLE_ADV_FOREVER_DURATION 0
/**
* @if Eng
* @brief Enable BLE adv.
* @attention NULL
* @retval BT_STATUS_SUCCESS Excute successfully
* @retval BT_STATUS_FAIL Execute fail
* @par Dependency:
* @li bts_def.h
* @else
* @brief 使能BLE广播。
* @attention NULL
* @retval BT_STATUS_SUCCESS 执行成功
* @retval BT_STATUS_FAIL 执行失败
* @par 依赖:
* @li bts_def.h
* @endif
*/
uint8_t ble_start_adv(void);
/**
* @if Eng
* @brief BLE adv data config.
* @attention NULL
* @retval BT_STATUS_SUCCESS Excute successfully
* @retval BT_STATUS_FAIL Execute fail
* @par Dependency:
* @li bts_def.h
* @else
* @brief BLE广播数据配置。
* @attention NULL
* @retval BT_STATUS_SUCCESS 执行成功
* @retval BT_STATUS_FAIL 执行失败
* @par 依赖:
* @li bts_def.h
* @endif
*/
uint8_t ble_set_adv_data(void);
#endif

View File

@ -0,0 +1,8 @@
#===============================================================================
# @brief cmake file
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
#===============================================================================
set(SOURCES "${SOURCES}"
"${CMAKE_CURRENT_SOURCE_DIR}/ble_server_adv.c"
"${CMAKE_CURRENT_SOURCE_DIR}/ble_gatt_server.c"
PARENT_SCOPE)

View File

@ -0,0 +1,335 @@
/*
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved.
* Description: ble uuid server sample.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "osal_addr.h"
#include "bts_def.h"
#include "securec.h"
#include "errcode.h"
#include "bts_def.h"
#include "bts_le_gap.h"
#include "bts_gatt_stru.h"
#include "bts_gatt_server.h"
#include "soc_osal.h"
#include "app_init.h"
#include "ble_server_adv.h"
#include "ble_gatt_server.h"
/* server app uuid for test */
char g_uuid_app_uuid[] = {0x0, 0x0};
/* ble indication att handle */
uint16_t g_indication_characteristic_att_hdl = 0;
/* ble notification att handle */
uint16_t g_notification_characteristic_att_hdl = 0;
/* ble connect handle */
uint16_t g_conn_hdl = 0;
/* ble server id */
uint8_t g_server_id = 0;
#define OCTET_BIT_LEN 8
#define UUID_LEN_2 2
/* 将uint16的uuid数字转化为bt_uuid_t */
void stream_data_to_uuid(uint16_t uuid_data, bt_uuid_t *out_uuid)
{
char uuid[] = {(uint8_t)(uuid_data >> OCTET_BIT_LEN), (uint8_t)uuid_data};
out_uuid->uuid_len = UUID_LEN_2;
if (memcpy_s(out_uuid->uuid, out_uuid->uuid_len, uuid, UUID_LEN_2) != EOK) {
return;
}
}
errcode_t compare_service_uuid(bt_uuid_t *uuid1, bt_uuid_t *uuid2)
{
if (uuid1->uuid_len != uuid2->uuid_len) {
return ERRCODE_BT_FAIL;
}
if (memcmp(uuid1->uuid, uuid2->uuid, uuid1->uuid_len) != 0) {
return ERRCODE_BT_FAIL;
}
return ERRCODE_BT_SUCCESS;
}
/* 添加描述符:客户端特性配置 */
static void ble_uuid_server_add_descriptor_ccc(uint32_t server_id, uint32_t srvc_handle)
{
bt_uuid_t ccc_uuid = {0};
uint8_t ccc_data_val[] = {0x00, 0x00};
osal_printk("[uuid server] beginning add descriptors\r\n");
stream_data_to_uuid(BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION, &ccc_uuid);
gatts_add_desc_info_t descriptor;
descriptor.desc_uuid = ccc_uuid;
descriptor.permissions = GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE;
descriptor.value_len = sizeof(ccc_data_val);
descriptor.value = ccc_data_val;
gatts_add_descriptor(server_id, srvc_handle, &descriptor);
osal_vfree(ccc_uuid.uuid);
}
/* 添加HID服务的所有特征和描述符 */
static void ble_uuid_server_add_characters_and_descriptors(uint32_t server_id, uint32_t srvc_handle)
{
bt_uuid_t server_uuid = {0};
uint8_t server_value[] = {0x12, 0x34};
osal_printk("[uuid server] beginning add characteristic\r\n");
stream_data_to_uuid(BLE_UUID_UUID_SERVER_REPORT, &server_uuid);
gatts_add_chara_info_t character;
character.chara_uuid = server_uuid;
character.properties = UUID_SERVER_PROPERTIES;
character.permissions = 0;
character.value_len = sizeof(server_value);
character.value = server_value;
gatts_add_characteristic(server_id, srvc_handle, &character);
ble_uuid_server_add_descriptor_ccc(server_id, srvc_handle);
}
/* 服务添加回调 */
static void ble_uuid_server_service_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t handle, errcode_t status)
{
bt_uuid_t service_uuid = {0};
osal_printk("[uuid server] add service cbk: server: %d, status: %d, srv_handle: %d, uuid_len: %d,uuid:",
server_id, status, handle, uuid->uuid_len);
for (int8_t i = 0; i < uuid->uuid_len ; i++) {
osal_printk("%02x", (uint8_t)uuid->uuid[i]);
}
osal_printk("\n");
stream_data_to_uuid(BLE_UUID_UUID_SERVER_SERVICE, &service_uuid);
if (compare_service_uuid(uuid, &service_uuid) == ERRCODE_BT_SUCCESS) {
ble_uuid_server_add_characters_and_descriptors(server_id, handle);
osal_printk("[uuid server] start service\r\n");
gatts_start_service(server_id, handle);
} else {
osal_printk("[uuid server] unknown service uuid\r\n");
return;
}
}
/* 特征添加回调 */
static void ble_uuid_server_characteristic_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle,
gatts_add_character_result_t *result, errcode_t status)
{
int8_t i = 0;
osal_printk("[uuid server] add characteristic cbk: server: %d, status: %d, srv_hdl: %d "\
"char_hdl: %x, char_val_hdl: %x, uuid_len: %d, uuid: ",
server_id, status, service_handle, result->handle, result->value_handle, uuid->uuid_len);
for (i = 0; i < uuid->uuid_len ; i++) {
osal_printk("%02x", (uint8_t)uuid->uuid[i]);
}
osal_printk("\n");
g_notification_characteristic_att_hdl = result->value_handle;
}
/* 描述符添加回调 */
static void ble_uuid_server_descriptor_add_cbk(uint8_t server_id, bt_uuid_t *uuid, uint16_t service_handle,
uint16_t handle, errcode_t status)
{
int8_t i = 0;
osal_printk("[uuid server] add descriptor cbk : server: %d, status: %d, srv_hdl: %d, desc_hdl: %x ,"\
"uuid_len:%d, uuid: ", server_id, status, service_handle, handle, uuid->uuid_len);
for (i = 0; i < uuid->uuid_len ; i++) {
osal_printk("%02x", (uint8_t)uuid->uuid[i]);
}
osal_printk("\n");
}
/* 开始服务回调 */
static void ble_uuid_server_service_start_cbk(uint8_t server_id, uint16_t handle, errcode_t status)
{
osal_printk("[uuid server] start service cbk : server: %d status: %d srv_hdl: %d\n",
server_id, status, handle);
}
static void ble_uuid_server_receive_write_req_cbk(uint8_t server_id, uint16_t conn_id,
gatts_req_write_cb_t *write_cb_para, errcode_t status)
{
osal_printk("[uuid server]ReceiveWriteReqCallback--server_id:%d conn_id:%d\n", server_id, conn_id);
osal_printk("request_id:%d att_handle:%d offset:%d need_rsp:%d need_authorize:%d is_prep:%d\n",
write_cb_para->request_id, write_cb_para->handle, write_cb_para->offset, write_cb_para->need_rsp,
write_cb_para->need_authorize, write_cb_para->is_prep);
osal_printk("data_len:%d data:\n", write_cb_para->length);
for (uint8_t i = 0; i < write_cb_para->length; i++) {
osal_printk("%02x ", write_cb_para->value[i]);
}
osal_printk("\n");
osal_printk("status:%d\n", status);
}
static void ble_uuid_server_receive_read_req_cbk(uint8_t server_id, uint16_t conn_id,
gatts_req_read_cb_t *read_cb_para, errcode_t status)
{
osal_printk("[uuid server]ReceiveReadReq--server_id:%d conn_id:%d\n", server_id, conn_id);
osal_printk("request_id:%d att_handle:%d offset:%d need_rsp:%d need_authorize:%d is_long:%d\n",
read_cb_para->request_id, read_cb_para->handle, read_cb_para->offset, read_cb_para->need_rsp,
read_cb_para->need_authorize, read_cb_para->is_long);
osal_printk("status:%d\n", status);
}
static void ble_uuid_server_adv_enable_cbk(uint8_t adv_id, adv_status_t status)
{
osal_printk("adv enable adv_id: %d, status:%d\n", adv_id, status);
}
static void ble_uuid_server_adv_disable_cbk(uint8_t adv_id, adv_status_t status)
{
osal_printk("adv disable adv_id: %d, status:%d\n",
adv_id, status);
}
void ble_uuid_server_connect_change_cbk(uint16_t conn_id, bd_addr_t *addr, gap_ble_conn_state_t conn_state,
gap_ble_pair_state_t pair_state, gap_ble_disc_reason_t disc_reason)
{
osal_printk("connect state change conn_id: %d, status: %d, pair_status:%d, addr %x disc_reason %x\n",
conn_id, conn_state, pair_state, addr[0], disc_reason);
g_conn_hdl = conn_id;
if (conn_state == GAP_BLE_STATE_DISCONNECTED) {
gap_ble_start_adv(BTH_GAP_BLE_ADV_HANDLE_DEFAULT);
}
}
void ble_uuid_server_mtu_changed_cbk(uint8_t server_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status)
{
osal_printk("mtu change change server_id: %d, conn_id: %d, mtu_size: %d, status:%d \n",
server_id, conn_id, mtu_size, status);
}
void ble_uuid_server_enable_cbk(errcode_t status)
{
osal_printk("enable status: %d\n", status);
}
static errcode_t ble_uuid_server_register_callbacks(void)
{
errcode_t ret;
gap_ble_callbacks_t gap_cb = {0};
gatts_callbacks_t service_cb = {0};
gap_cb.start_adv_cb = ble_uuid_server_adv_enable_cbk;
gap_cb.stop_adv_cb = ble_uuid_server_adv_disable_cbk;
gap_cb.conn_state_change_cb = ble_uuid_server_connect_change_cbk;
gap_cb.ble_enable_cb = ble_uuid_server_enable_cbk;
ret = gap_ble_register_callbacks(&gap_cb);
if (ret != ERRCODE_BT_SUCCESS) {
osal_printk("[uuid server] reg gap cbk failed\r\n");
return ERRCODE_BT_FAIL;
}
service_cb.add_service_cb = ble_uuid_server_service_add_cbk;
service_cb.add_characteristic_cb = ble_uuid_server_characteristic_add_cbk;
service_cb.add_descriptor_cb = ble_uuid_server_descriptor_add_cbk;
service_cb.start_service_cb = ble_uuid_server_service_start_cbk;
service_cb.read_request_cb = ble_uuid_server_receive_read_req_cbk;
service_cb.write_request_cb = ble_uuid_server_receive_write_req_cbk;
service_cb.mtu_changed_cb = ble_uuid_server_mtu_changed_cbk;
ret = gatts_register_callbacks(&service_cb);
if (ret != ERRCODE_BT_SUCCESS) {
osal_printk("[uuid server] reg service cbk failed\r\n");
return ERRCODE_BT_FAIL;
}
return ret;
}
uint8_t ble_uuid_add_service(void)
{
osal_printk("[uuid server] ble uuid add service in\r\n");
bt_uuid_t service_uuid = {0};
stream_data_to_uuid(BLE_UUID_UUID_SERVER_SERVICE, &service_uuid);
gatts_add_service(g_server_id, &service_uuid, true);
osal_printk("[uuid server] ble uuid add service out\r\n");
return ERRCODE_BT_SUCCESS;
}
/* 初始化uuid server service */
errcode_t ble_uuid_server_init(void)
{
enable_ble();
ble_uuid_server_register_callbacks();
bt_uuid_t app_uuid = {0};
app_uuid.uuid_len = sizeof(g_uuid_app_uuid);
if (memcpy_s(app_uuid.uuid, app_uuid.uuid_len, g_uuid_app_uuid, sizeof(g_uuid_app_uuid)) != EOK) {
return ERRCODE_BT_FAIL;
}
gatts_register_server(&app_uuid, &g_server_id);
ble_uuid_add_service();
osal_printk("[uuid server] init ok\r\n");
ble_start_adv();
return ERRCODE_BT_SUCCESS;
}
/* device通过uuid向host发送数据report */
errcode_t ble_uuid_server_send_report_by_uuid(const uint8_t *data, uint8_t len)
{
gatts_ntf_ind_by_uuid_t param = {0};
uint16_t conn_id = g_conn_hdl;
param.start_handle = 0;
param.end_handle = 0xffff;
stream_data_to_uuid(BLE_UUID_UUID_SERVER_REPORT, &param.chara_uuid);
param.value_len = len;
param.value = osal_vmalloc(len);
if (param.value == NULL) {
osal_printk("[hid][ERROR]send report new fail\r\n");
return ERRCODE_BT_FAIL;
}
if (memcpy_s(param.value, param.value_len, data, len) != EOK) {
osal_printk("[hid][ERROR]send input report memcpy fail\r\n");
osal_vfree(param.value);
return ERRCODE_BT_FAIL;
}
gatts_notify_indicate_by_uuid(g_server_id, conn_id, &param);
osal_vfree(param.value);
return ERRCODE_BT_SUCCESS;
}
/* device通过handle向host发送数据report */
errcode_t ble_uuid_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len)
{
gatts_ntf_ind_t param = {0};
uint16_t conn_id = g_conn_hdl;
param.attr_handle = attr_handle;
param.value = osal_vmalloc(len);
param.value_len = len;
if (param.value == NULL) {
osal_printk("[hid][ERROR]send report new fail\r\n");
return ERRCODE_BT_FAIL;
}
if (memcpy_s(param.value, param.value_len, data, len) != EOK) {
osal_printk("[hid][ERROR]send input report memcpy fail\r\n");
osal_vfree(param.value);
return ERRCODE_BT_FAIL;
}
gatts_notify_indicate(g_server_id, conn_id, &param);
osal_vfree(param.value);
return ERRCODE_BT_SUCCESS;
}
#define BLE_UUID_SERVER_TASK_PRIO 24
#define BLE_UUID_SERVER_STACK_SIZE 0x2000
static void ble_uuid_server_entry(void)
{
osal_task *task_handle = NULL;
osal_kthread_lock();
task_handle= osal_kthread_create((osal_kthread_handler)ble_uuid_server_init, 0, "ble_uuid_server",
BLE_UUID_SERVER_STACK_SIZE);
if (task_handle != NULL) {
osal_kthread_set_priority(task_handle, BLE_UUID_SERVER_TASK_PRIO);
osal_kfree(task_handle);
}
osal_kthread_unlock();
}
/* Run the app entry. */
app_run(ble_uuid_server_entry);

View File

@ -0,0 +1,192 @@
/*
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
* Description: adv config for ble uuid server.
*/
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include "osal_addr.h"
#include "securec.h"
#include "errcode.h"
#include "bts_def.h"
#include "bts_le_gap.h"
#include "ble_server_adv.h"
#define NAME_MAX_LENGTH 15
#define EXT_ADV_OR_SCAN_RSP_DATA_LEN 251
#define u16_low_u8(val) ((uint8_t)((uint16_t)(val) & 0xff))
#define u16_high_u8(val) ((uint8_t)(((uint16_t)(val) >> 8) & 0xff))
uint8_t g_local_name[ NAME_MAX_LENGTH] = { 'b', 'l', 'e', '_', 'u', 'u', 'i', 'd', '_', 's',
'e', 'r', 'v', 'e', 'r' };
static uint8_t ble_set_adv_flag_data(uint8_t *set_adv_data_position, uint8_t max_len)
{
errno_t n_ret;
ble_adv_flag adv_flags = {
.length = BLE_ADV_FLAG_LEN - BLE_GENERAL_BYTE_1,
.adv_data_type = 1,
.flags = BLE_ADV_FLAG_DATA,
};
n_ret = memcpy_s(set_adv_data_position, max_len, &adv_flags, BLE_ADV_FLAG_LEN);
if (n_ret != EOK) {
return 0;
}
return BLE_ADV_FLAG_LEN;
}
static uint8_t ble_set_adv_appearance(uint8_t *set_adv_data_position, uint8_t max_len)
{
errno_t n_ret;
ble_appearance_st adv_appearance_data = {
.length = BLE_ADV_APPEARANCE_LENGTH - BLE_GENERAL_BYTE_1,
.adv_data_type = BLE_ADV_APPEARANCE_DATA_TYPE,
.catogory_id = { u16_low_u8(BLE_ADV_CATEGORY_KEYBOARD_VALUE), u16_high_u8(BLE_ADV_CATEGORY_KEYBOARD_VALUE) },
};
n_ret = memcpy_s(set_adv_data_position, max_len, &adv_appearance_data, BLE_ADV_APPEARANCE_LENGTH);
if (n_ret != EOK) {
return 0;
}
return BLE_ADV_APPEARANCE_LENGTH;
}
static uint8_t ble_set_adv_name(uint8_t *set_adv_data_position, uint8_t max_len)
{
errno_t n_ret;
uint8_t len;
ble_local_name_st adv_local_name_data = { 0 };
adv_local_name_data.length = (uint8_t)(BLE_ADV_PARAM_DATATYPE_LENGTH + sizeof(g_local_name));
adv_local_name_data.adv_data_type = BLE_ADV_LOCAL_NAME_DATA_TYPE;
len = BLE_ADV_PARAM_DATATYPE_LENGTH + BLE_ADV_PARAM_DATATYPE_LENGTH;
n_ret = memcpy_s(set_adv_data_position, max_len, &adv_local_name_data, len);
if (n_ret != EOK) {
return 0;
}
n_ret = memcpy_s((set_adv_data_position + len), (size_t)(max_len - len), g_local_name, sizeof(g_local_name));
if (n_ret != EOK) {
return 0;
}
len = (uint8_t)(len + sizeof(g_local_name));
return len;
}
static uint8_t ble_set_adv_appearance_data(uint8_t *set_adv_data_position, uint8_t max_len)
{
uint8_t idx = 0;
idx += ble_set_adv_appearance(set_adv_data_position, max_len);
idx += ble_set_adv_name(set_adv_data_position + idx, (max_len - idx));
return idx;
}
static uint16_t ble_uuid_server_set_adv_data(uint8_t *set_adv_data, uint8_t adv_data_max_len)
{
uint8_t idx = 0;
if ((set_adv_data == NULL) || (adv_data_max_len == 0)) {
return 0;
}
idx += ble_set_adv_flag_data(set_adv_data, adv_data_max_len);
idx += ble_set_adv_appearance_data(&set_adv_data[idx], adv_data_max_len - idx);
return idx;
}
static uint16_t ble_set_scan_response_data(uint8_t *scan_rsp_data, uint8_t scan_rsp_data_max_len)
{
uint8_t idx = 0;
errno_t n_ret;
if (scan_rsp_data == NULL) {
return 0;
}
if (scan_rsp_data_max_len == 0) {
return 0;
}
/* tx power level */
ble_tx_power_level_st tx_power_level = {
.length = BLE_SCAN_RSP_TX_POWER_LEVEL_LEN - BLE_GENERAL_BYTE_1,
.adv_data_type = BLE_ADV_TX_POWER_LEVEL,
.tx_power_value = 0,
};
n_ret = memcpy_s(scan_rsp_data, scan_rsp_data_max_len, &tx_power_level, sizeof(ble_tx_power_level_st));
if (n_ret != EOK) {
return 0;
}
idx += BLE_SCAN_RSP_TX_POWER_LEVEL_LEN;
/* set local name */
scan_rsp_data[idx++] = sizeof(g_local_name) + BLE_GENERAL_BYTE_1;
scan_rsp_data[idx++] = BLE_ADV_LOCAL_NAME_DATA_TYPE;
if ((idx + sizeof(g_local_name)) > scan_rsp_data_max_len) {
return 0;
}
n_ret = memcpy_s(&scan_rsp_data[idx], scan_rsp_data_max_len - idx, g_local_name, sizeof(g_local_name));
if (n_ret != EOK) {
return 0;
}
idx += sizeof(g_local_name);
return idx;
}
uint8_t ble_set_adv_data(void)
{
errcode_t n_ret = 0;
uint16_t adv_data_len;
uint16_t scan_rsp_data_len;
uint8_t set_adv_data[EXT_ADV_OR_SCAN_RSP_DATA_LEN] = { 0 };
uint8_t set_scan_rsp_data[EXT_ADV_OR_SCAN_RSP_DATA_LEN] = { 0 };
gap_ble_config_adv_data_t cfg_adv_data;
/* set adv data */
adv_data_len = ble_uuid_server_set_adv_data(set_adv_data, EXT_ADV_OR_SCAN_RSP_DATA_LEN);
if ((adv_data_len > EXT_ADV_OR_SCAN_RSP_DATA_LEN) || (adv_data_len == 0)) {
return 0;
}
/* set scan response data */
scan_rsp_data_len = ble_set_scan_response_data(set_scan_rsp_data, EXT_ADV_OR_SCAN_RSP_DATA_LEN);
if ((scan_rsp_data_len > EXT_ADV_OR_SCAN_RSP_DATA_LEN) || (scan_rsp_data_len == 0)) {
return 0;
}
cfg_adv_data.adv_data = set_adv_data;
cfg_adv_data.adv_length = adv_data_len;
cfg_adv_data.scan_rsp_data = set_scan_rsp_data;
cfg_adv_data.scan_rsp_length = scan_rsp_data_len;
n_ret = gap_ble_set_adv_data(BTH_GAP_BLE_ADV_HANDLE_DEFAULT, &cfg_adv_data);
if (n_ret != 0) {
return 0;
}
return 0;
}
uint8_t ble_start_adv(void)
{
errcode_t n_ret = 0;
gap_ble_adv_params_t adv_para = {0};
ble_set_adv_data();
int adv_id = BTH_GAP_BLE_ADV_HANDLE_DEFAULT;
adv_para.min_interval = BLE_ADV_MIN_INTERVAL;
adv_para.max_interval = BLE_ADV_MAX_INTERVAL;
adv_para.duration = BTH_GAP_BLE_ADV_FOREVER_DURATION;
adv_para.peer_addr.type = BLE_PUBLIC_DEVICE_ADDRESS;
/* 广播通道选择bitMap, 可参考BleAdvChannelMap */
adv_para.channel_map = BLE_ADV_CHANNEL_MAP_CH_DEFAULT;
adv_para.adv_type = BLE_ADV_TYPE_CONNECTABLE_UNDIRECTED;
adv_para.adv_filter_policy = BLE_ADV_FILTER_POLICY_SCAN_ANY_CONNECT_ANY;
(void)memset_s(&adv_para.peer_addr.addr, BD_ADDR_LEN, 0, BD_ADDR_LEN);
n_ret = gap_ble_set_adv_param(adv_id, &adv_para);
if (n_ret != 0) {
return 0;
}
n_ret = gap_ble_start_adv(adv_id);
if (n_ret != 0) {
return 0;
}
return 0;
}