初始提交
This commit is contained in:
8
application/samples/bt/ble/ble_gatt_server/CMakeLists.txt
Executable file
8
application/samples/bt/ble/ble_gatt_server/CMakeLists.txt
Executable 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)
|
91
application/samples/bt/ble/ble_gatt_server/inc/ble_gatt_server.h
Executable file
91
application/samples/bt/ble/ble_gatt_server/inc/ble_gatt_server.h
Executable 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
|
||||
|
212
application/samples/bt/ble/ble_gatt_server/inc/ble_server_adv.h
Executable file
212
application/samples/bt/ble/ble_gatt_server/inc/ble_server_adv.h
Executable 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
|
||||
|
8
application/samples/bt/ble/ble_gatt_server/src/CMakeLists.txt
Executable file
8
application/samples/bt/ble/ble_gatt_server/src/CMakeLists.txt
Executable 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)
|
335
application/samples/bt/ble/ble_gatt_server/src/ble_gatt_server.c
Executable file
335
application/samples/bt/ble/ble_gatt_server/src/ble_gatt_server.c
Executable 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, ¶m.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, ¶m);
|
||||
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, ¶m);
|
||||
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);
|
192
application/samples/bt/ble/ble_gatt_server/src/ble_server_adv.c
Executable file
192
application/samples/bt/ble/ble_gatt_server/src/ble_server_adv.c
Executable 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;
|
||||
}
|
Reference in New Issue
Block a user