first commit
This commit is contained in:
27
application/samples/bt/ble/CMakeLists.txt
Executable file
27
application/samples/bt/ble/CMakeLists.txt
Executable file
@ -0,0 +1,27 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
#===============================================================================
|
||||
if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_GATT_CLIENT_SAMPLE)
|
||||
add_subdirectory_if_exist(ble_gatt_client)
|
||||
endif()
|
||||
|
||||
if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_GATT_SERVER_SAMPLE)
|
||||
add_subdirectory_if_exist(ble_gatt_server)
|
||||
endif()
|
||||
|
||||
if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_SPEED_SERVER_SAMPLE)
|
||||
add_subdirectory_if_exist(ble_speed_server)
|
||||
endif()
|
||||
|
||||
if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_SPEED_CLIENT_SAMPLE)
|
||||
add_subdirectory_if_exist(ble_speed_client)
|
||||
endif()
|
||||
|
||||
if(DEFINED CONFIG_SAMPLE_SUPPORT_BLE_CFG_SAMPLE)
|
||||
add_subdirectory_if_exist(ble_wifi_cfg_client)
|
||||
add_subdirectory_if_exist(ble_wifi_cfg_server)
|
||||
endif()
|
||||
|
||||
set(SOURCES "${SOURCES}" PARENT_SCOPE)
|
||||
set(PUBLIC_HEADER "${PUBLIC_HEADER}" PARENT_SCOPE)
|
24
application/samples/bt/ble/Kconfig
Executable file
24
application/samples/bt/ble/Kconfig
Executable file
@ -0,0 +1,24 @@
|
||||
#===============================================================================
|
||||
# @brief Kconfig file.
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
#===============================================================================
|
||||
|
||||
choice
|
||||
prompt "BLE Sample"
|
||||
|
||||
config SAMPLE_SUPPORT_BLE_GATT_CLIENT_SAMPLE
|
||||
bool "Support BLE GATT Client Sample."
|
||||
|
||||
config SAMPLE_SUPPORT_BLE_GATT_SERVER_SAMPLE
|
||||
bool "Support BLE GATT Server Sample."
|
||||
|
||||
config SAMPLE_SUPPORT_BLE_SPEED_SERVER_SAMPLE
|
||||
bool "Support BLE Throughput Server Sample."
|
||||
|
||||
config SAMPLE_SUPPORT_BLE_SPEED_CLIENT_SAMPLE
|
||||
bool "Support BLE Throughput Client Sample"
|
||||
|
||||
config SAMPLE_SUPPORT_BLE_CFG_SAMPLE
|
||||
bool "Support BLE WIFI CFG Sample"
|
||||
|
||||
endchoice
|
8
application/samples/bt/ble/ble_gatt_client/CMakeLists.txt
Executable file
8
application/samples/bt/ble/ble_gatt_client/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)
|
59
application/samples/bt/ble/ble_gatt_client/inc/ble_gatt_client.h
Executable file
59
application/samples/bt/ble/ble_gatt_client/inc/ble_gatt_client.h
Executable file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved.
|
||||
*
|
||||
* Description: BT GATT Client Moudle.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup bluetooth_bts_hid_server HID SERVER API
|
||||
* @ingroup
|
||||
* @{
|
||||
*/
|
||||
#ifndef BLE_GATT_CLIENT_H
|
||||
#define BLE_GATT_CLIENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @if Eng
|
||||
* @brief Use this funtion to init gatt client.
|
||||
* @par Description:init gatt client.
|
||||
* @attention NULL
|
||||
* @param NULL
|
||||
* @retval error code.
|
||||
* @else
|
||||
* @brief 初始化gatt 客户端。
|
||||
* @par 说明:初始化gatt 客户端。
|
||||
* @attention NULL
|
||||
* @param NULL
|
||||
* @retval 执行结果错误码。
|
||||
* @endif
|
||||
*/
|
||||
errcode_t ble_gatt_client_init(void);
|
||||
|
||||
/**
|
||||
* @if Eng
|
||||
* @brief discover all service, character and descriptor of remote device.
|
||||
* @par Description:discover all service of remote device.
|
||||
* @attention NULL
|
||||
* @param conn_id connection ID
|
||||
* @retval error code.
|
||||
* @else
|
||||
* @brief 发现对端设备所有服务、特征和描述符。
|
||||
* @par 说明:发现对端设备所有服务、特征和描述符。
|
||||
* @attention NULL
|
||||
* @param conn_id 连接 ID
|
||||
* @retval 执行结果错误码。
|
||||
* @endif
|
||||
*/
|
||||
errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
5
application/samples/bt/ble/ble_gatt_client/src/CMakeLists.txt
Executable file
5
application/samples/bt/ble/ble_gatt_client/src/CMakeLists.txt
Executable file
@ -0,0 +1,5 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
#===============================================================================
|
||||
set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/ble_gatt_client.c" PARENT_SCOPE)
|
277
application/samples/bt/ble/ble_gatt_client/src/ble_gatt_client.c
Executable file
277
application/samples/bt/ble/ble_gatt_client/src/ble_gatt_client.c
Executable file
@ -0,0 +1,277 @@
|
||||
#include "osal_list.h"
|
||||
#include "bts_le_gap.h"
|
||||
#include "bts_gatt_client.h"
|
||||
#include "soc_osal.h"
|
||||
#include "app_init.h"
|
||||
#include "securec.h"
|
||||
#include "common_def.h"
|
||||
|
||||
#define UUID16_LEN 2
|
||||
#define DEFAULT_SCAN_INTERVAL 0x48
|
||||
|
||||
/* client id, invalid client id is "0" */
|
||||
uint8_t g_client_id = 0;
|
||||
/* client app uuid for test */
|
||||
static bt_uuid_t g_client_app_uuid = {UUID16_LEN, {0}};
|
||||
|
||||
errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id);
|
||||
|
||||
static void ble_gatt_client_discover_service_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_service_result_t *service, errcode_t status)
|
||||
{
|
||||
gattc_discovery_character_param_t param = {0};
|
||||
osal_printk("[GATTClient]Discovery service----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" start handle:%d end handle:%d uuid_len:%d\n uuid:",
|
||||
service->start_hdl, service->end_hdl, service->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < service->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", service->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
param.service_handle = service->start_hdl;
|
||||
param.uuid.uuid_len = 0; /* uuid length is zero, discover all character */
|
||||
gattc_discovery_character(g_client_id, conn_id, ¶m);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_character_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_character_result_t *character, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery character----client:%d conn_id:%d uuid_len:%d\n uuid:",
|
||||
client_id, conn_id, character->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < character->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", character->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n declare handle:%d value handle:%d properties:%x\n", character->declare_handle,
|
||||
character->value_handle, character->properties);
|
||||
osal_printk(" status:%d\n", status);
|
||||
gattc_discovery_descriptor(g_client_id, conn_id, character->declare_handle);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_descriptor_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_descriptor_result_t *descriptor, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery descriptor----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, descriptor->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < descriptor->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", descriptor->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n descriptor handle:%d\n", descriptor->descriptor_hdl);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_service_compl_cbk(uint8_t client_id, uint16_t conn_id, bt_uuid_t *uuid,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk(
|
||||
"[GATTClient]Discovery service complete----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, uuid->uuid_len);
|
||||
for (uint8_t i = 0; i < uuid->uuid_len; i++) {
|
||||
osal_printk("%02x", uuid->uuid[i]);
|
||||
}
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_character_compl_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_character_param_t *param, errcode_t status)
|
||||
{
|
||||
osal_printk(
|
||||
"[GATTClient]Discovery character complete----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, param->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < param->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", param->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n service handle:%d\n", param->service_handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_descriptor_compl_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
uint16_t character_handle, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery descriptor complete----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" charatcer handle:%d\n", character_handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *read_result,
|
||||
gatt_status_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Read result----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" handle:%d data_len:%d\ndata:", read_result->handle, read_result->data_len);
|
||||
for (uint8_t i = 0; i < read_result->data_len; i++) {
|
||||
osal_printk("%02x", read_result->data[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_read_compl_cbk(uint8_t client_id, uint16_t conn_id, gattc_read_req_by_uuid_param_t *param,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Read by uuid complete----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk("start handle:%d end handle:%d uuid len:%d\n uuid:",
|
||||
param->start_hdl, param->end_hdl, param->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < param->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", param->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, uint16_t handle, gatt_status_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Write result----client:%d conn_id:%d handle:%d\n", client_id, conn_id, handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_mtu_changed_cbk(uint8_t client_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Mtu changed----client:%d conn_id:%d mtu size:%d\n", client_id, conn_id,
|
||||
mtu_size);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_notification_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Receive notification----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk("handle:%d data_len:%d\ndata:", data->handle, data->data_len);
|
||||
for (uint8_t i = 0; i < data->data_len; i++) {
|
||||
osal_printk("%02x", data->data[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_indication_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Receive indication----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" handle:%d data_len:%d\ndata:", data->handle, data->data_len);
|
||||
for (uint8_t i = 0; i < data->data_len; i++) {
|
||||
osal_printk("%02x", data->data[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_scan_result_cbk(gap_scan_result_data_t *scan_result_data)
|
||||
{
|
||||
uint8_t ble_mac[BD_ADDR_LEN] = {0x63, 0x38, 0xce, 0xad, 0x38, 0x63};
|
||||
if (memcmp(scan_result_data->addr.addr, ble_mac, BD_ADDR_LEN) == 0) {
|
||||
osal_printk("Find The Target Device.\n");
|
||||
gap_ble_stop_scan();
|
||||
bd_addr_t client_addr = { 0 };
|
||||
client_addr.type = scan_result_data->addr.type;
|
||||
if (memcpy_s(client_addr.addr, BD_ADDR_LEN, scan_result_data->addr.addr, BD_ADDR_LEN) != EOK) {
|
||||
osal_printk("%s add server app addr memcpy failed\r\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
gap_ble_connect_remote_device(&client_addr);
|
||||
} else {
|
||||
osal_printk("\naddr:");
|
||||
for (uint8_t i = 0; i < BD_ADDR_LEN; i++) {
|
||||
osal_printk(" %02x:", scan_result_data->addr.addr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatt_client_conn_state_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("%s connect state change conn_id: %d, status: %d, pair_status:%d, disc_reason %x\n",
|
||||
__FUNCTION__, conn_id, conn_state, pair_state, disc_reason);
|
||||
|
||||
if (conn_state == GAP_BLE_STATE_CONNECTED) {
|
||||
gap_ble_pair_remote_device(addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatt_client_pair_result_cbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status)
|
||||
{
|
||||
unused(addr);
|
||||
osal_printk("%s pair result conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status);
|
||||
|
||||
ble_gatt_client_discover_all_service(conn_id);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_conn_param_update_cbk(uint16_t conn_id, errcode_t status,
|
||||
const gap_ble_conn_param_update_t *param)
|
||||
{
|
||||
osal_printk("%s conn_param_update conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status);
|
||||
osal_printk("interval:%d latency:%d timeout:%d.\n", param->interval, param->latency, param->timeout);
|
||||
}
|
||||
|
||||
errcode_t ble_gatt_client_callback_register(void)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_UNHANDLED;
|
||||
gap_ble_callbacks_t gap_cb = {0};
|
||||
gap_cb.scan_result_cb = ble_gatt_client_scan_result_cbk;
|
||||
gap_cb.conn_state_change_cb = ble_gatt_client_conn_state_change_cbk;
|
||||
gap_cb.pair_result_cb = ble_gatt_client_pair_result_cbk;
|
||||
gap_cb.conn_param_update_cb = ble_gatt_client_conn_param_update_cbk;
|
||||
ret |= gap_ble_register_callbacks(&gap_cb);
|
||||
|
||||
gattc_callbacks_t cb = {0};
|
||||
cb.discovery_svc_cb = ble_gatt_client_discover_service_cbk;
|
||||
cb.discovery_svc_cmp_cb = ble_gatt_client_discover_service_compl_cbk;
|
||||
cb.discovery_chara_cb = ble_gatt_client_discover_character_cbk;
|
||||
cb.discovery_chara_cmp_cb = ble_gatt_client_discover_character_compl_cbk;
|
||||
cb.discovery_desc_cb = ble_gatt_client_discover_descriptor_cbk;
|
||||
cb.discovery_desc_cmp_cb = ble_gatt_client_discover_descriptor_compl_cbk;
|
||||
cb.read_cb = ble_gatt_client_read_cfm_cbk;
|
||||
cb.read_cmp_cb = ble_gatt_client_read_compl_cbk;
|
||||
cb.write_cb = ble_gatt_client_write_cfm_cbk;
|
||||
cb.mtu_changed_cb = ble_gatt_client_mtu_changed_cbk;
|
||||
cb.notification_cb = ble_gatt_client_notification_cbk;
|
||||
cb.indication_cb = ble_gatt_client_indication_cbk;
|
||||
ret |= gattc_register_callbacks(&cb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t ble_cliant_start_scan(void)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_SUCCESS;
|
||||
gap_ble_scan_params_t ble_device_scan_params = { 0 };
|
||||
ble_device_scan_params.scan_interval = DEFAULT_SCAN_INTERVAL;
|
||||
ble_device_scan_params.scan_window = DEFAULT_SCAN_INTERVAL;
|
||||
ble_device_scan_params.scan_type = 0x00;
|
||||
ble_device_scan_params.scan_phy = GAP_BLE_PHY_2M;
|
||||
ble_device_scan_params.scan_filter_policy = 0x00;
|
||||
ret |= gap_ble_set_scan_parameters(&ble_device_scan_params);
|
||||
ret |= gap_ble_start_scan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t ble_gatt_client_init(void)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_SUCCESS;
|
||||
ret |= enable_ble();
|
||||
ret |= ble_gatt_client_callback_register();
|
||||
ret |= gattc_register_client(&g_client_app_uuid, &g_client_id);
|
||||
printf("ble_gatt_client_init, ret:%x.\n", ret);
|
||||
ret |= ble_cliant_start_scan();
|
||||
printf("ble_cliant_start_scan, ret:%x.\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_SUCCESS;
|
||||
bt_uuid_t service_uuid = {0}; /* uuid length is zero, discover all service */
|
||||
ret |= gattc_discovery_service(g_client_id, conn_id, &service_uuid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define BLE_UUID_CLIENT_TASK_PRIO 24
|
||||
#define BLE_UUID_CLIENT_STACK_SIZE 0x2000
|
||||
|
||||
static void ble_uuid_client_entry(void)
|
||||
{
|
||||
osal_task *task_handle = NULL;
|
||||
osal_kthread_lock();
|
||||
task_handle= osal_kthread_create((osal_kthread_handler)ble_gatt_client_init, 0, "ble_gatt_client",
|
||||
BLE_UUID_CLIENT_STACK_SIZE);
|
||||
if (task_handle != NULL) {
|
||||
osal_kthread_set_priority(task_handle, BLE_UUID_CLIENT_TASK_PRIO);
|
||||
osal_kfree(task_handle);
|
||||
}
|
||||
osal_kthread_unlock();
|
||||
}
|
||||
|
||||
/* Run the app entry. */
|
||||
app_run(ble_uuid_client_entry);
|
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;
|
||||
}
|
8
application/samples/bt/ble/ble_speed_client/CMakeLists.txt
Executable file
8
application/samples/bt/ble/ble_speed_client/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)
|
57
application/samples/bt/ble/ble_speed_client/inc/ble_speed_client.h
Executable file
57
application/samples/bt/ble/ble_speed_client/inc/ble_speed_client.h
Executable file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved.
|
||||
*
|
||||
* Description: BLE SPEED Server module.
|
||||
*/
|
||||
|
||||
#ifndef BLE_SPEED_CLIENT_H
|
||||
#define BLE_SPEED_CLIENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define DEFAULT_SCAN_INTERVAL 0x48
|
||||
#define DEFAULT_SCAN_INTERVAL 0x48
|
||||
|
||||
/**
|
||||
* @if Eng
|
||||
* @brief Use this funtion to init gatt client.
|
||||
* @par Description:init gatt client.
|
||||
* @attention NULL
|
||||
* @param NULL
|
||||
* @retval error code.
|
||||
* @else
|
||||
* @brief 初始化gatt 客户端。
|
||||
* @par 说明:初始化gatt 客户端。
|
||||
* @attention NULL
|
||||
* @param NULL
|
||||
* @retval 执行结果错误码。
|
||||
* @endif
|
||||
*/
|
||||
errcode_t ble_gatt_client_init(void);
|
||||
|
||||
/**
|
||||
* @if Eng
|
||||
* @brief discover all service, character and descriptor of remote device.
|
||||
* @par Description:discover all service of remote device.
|
||||
* @attention NULL
|
||||
* @param conn_id connection ID
|
||||
* @retval error code.
|
||||
* @else
|
||||
* @brief 发现对端设备所有服务、特征和描述符。
|
||||
* @par 说明:发现对端设备所有服务、特征和描述符。
|
||||
* @attention NULL
|
||||
* @param conn_id 连接 ID
|
||||
* @retval 执行结果错误码。
|
||||
* @endif
|
||||
*/
|
||||
errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
5
application/samples/bt/ble/ble_speed_client/src/CMakeLists.txt
Executable file
5
application/samples/bt/ble/ble_speed_client/src/CMakeLists.txt
Executable file
@ -0,0 +1,5 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023-2023. All rights reserved.
|
||||
#===============================================================================
|
||||
set(SOURCES "${SOURCES}" "${CMAKE_CURRENT_SOURCE_DIR}/ble_speed_client.c" PARENT_SCOPE)
|
335
application/samples/bt/ble/ble_speed_client/src/ble_speed_client.c
Executable file
335
application/samples/bt/ble/ble_speed_client/src/ble_speed_client.c
Executable file
@ -0,0 +1,335 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved.
|
||||
* Description: ble speed client sample.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "securec.h"
|
||||
#include "app_init.h"
|
||||
#include "systick.h"
|
||||
#include "soc_osal.h"
|
||||
#include "osal_list.h"
|
||||
#include "common_def.h"
|
||||
|
||||
#include "bts_le_gap.h"
|
||||
#include "bts_gatt_client.h"
|
||||
#include "ble_speed_client.h"
|
||||
|
||||
#define UUID16_LEN 2
|
||||
#define TEMP_LINE_LEN 32
|
||||
static int g_recv_pkt_num = 0;
|
||||
static uint64_t g_count_before_get_us;
|
||||
static uint64_t g_count_after_get_us;
|
||||
#define RECV_PKT_CNT 100
|
||||
|
||||
/* client id, invalid client id is "0" */
|
||||
static uint8_t g_client_id = 0;
|
||||
/* client app uuid for test */
|
||||
static bt_uuid_t g_client_app_uuid = {UUID16_LEN, {0}};
|
||||
|
||||
bd_addr_t g_ble_speed_addr = {
|
||||
.type = 0,
|
||||
.addr = {0x11, 0x22, 0x33, 0x63, 0x88, 0x63},
|
||||
};
|
||||
|
||||
extern errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id);
|
||||
|
||||
static void ble_gatt_client_discover_service_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_service_result_t *service, errcode_t status)
|
||||
{
|
||||
gattc_discovery_character_param_t param = {0};
|
||||
osal_printk("[GATTClient]Discovery service----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" start handle:%d end handle:%d uuid_len:%d\n uuid:",
|
||||
service->start_hdl, service->end_hdl, service->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < service->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", service->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
param.service_handle = service->start_hdl;
|
||||
param.uuid.uuid_len = 0; /* uuid length is zero, discover all character */
|
||||
gattc_discovery_character(g_client_id, conn_id, ¶m);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_character_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_character_result_t *character, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery character----client:%d conn_id:%d uuid_len:%d\n uuid:",
|
||||
client_id, conn_id, character->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < character->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", character->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n declare handle:%d value handle:%d properties:%x\n", character->declare_handle,
|
||||
character->value_handle, character->properties);
|
||||
osal_printk(" status:%d\n", status);
|
||||
gattc_discovery_descriptor(g_client_id, conn_id, character->declare_handle);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_descriptor_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_descriptor_result_t *descriptor, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery descriptor----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, descriptor->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < descriptor->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", descriptor->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n descriptor handle:%d\n", descriptor->descriptor_hdl);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_service_compl_cbk(uint8_t client_id, uint16_t conn_id, bt_uuid_t *uuid,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk(
|
||||
"[GATTClient]Discovery service complete----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, uuid->uuid_len);
|
||||
for (uint8_t i = 0; i < uuid->uuid_len; i++) {
|
||||
osal_printk("%02x", uuid->uuid[i]);
|
||||
}
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_character_compl_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_character_param_t *param, errcode_t status)
|
||||
{
|
||||
osal_printk(
|
||||
"[GATTClient]Discovery character complete----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, param->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < param->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", param->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n service handle:%d\n", param->service_handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_discover_descriptor_compl_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
uint16_t character_handle, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery descriptor complete----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" charatcer handle:%d\n", character_handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *read_result,
|
||||
gatt_status_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Read result----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" handle:%d data_len:%d\ndata:", read_result->handle, read_result->data_len);
|
||||
for (uint8_t i = 0; i < read_result->data_len; i++) {
|
||||
osal_printk("%02x", read_result->data[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_read_compl_cbk(uint8_t client_id, uint16_t conn_id, gattc_read_req_by_uuid_param_t *param,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Read by uuid complete----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk("start handle:%d end handle:%d uuid len:%d\n uuid:",
|
||||
param->start_hdl, param->end_hdl, param->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < param->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", param->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_write_cfm_cbk(uint8_t client_id, uint16_t conn_id, uint16_t handle, gatt_status_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Write result----client:%d conn_id:%d handle:%d\n", client_id, conn_id, handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_mtu_changed_cbk(uint8_t client_id, uint16_t conn_id, uint16_t mtu_size, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Mtu changed----client:%d conn_id:%d mtu size:%d\n", client_id, conn_id,
|
||||
mtu_size);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
#define BLE_SPEED_HUNDRED 100
|
||||
static uint32_t get_float_int(float in)
|
||||
{
|
||||
return (uint32_t)(((uint64_t)(in * BLE_SPEED_HUNDRED)) / BLE_SPEED_HUNDRED);
|
||||
}
|
||||
|
||||
static uint32_t get_float_dec(float in)
|
||||
{
|
||||
return (uint32_t)(((uint64_t)(in * BLE_SPEED_HUNDRED)) % BLE_SPEED_HUNDRED);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_notification_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data,
|
||||
errcode_t status)
|
||||
{
|
||||
unused(status);
|
||||
unused(conn_id);
|
||||
unused(client_id);
|
||||
|
||||
g_recv_pkt_num++;
|
||||
if (g_recv_pkt_num == 1) {
|
||||
g_count_before_get_us = uapi_systick_get_us();
|
||||
} else if (g_recv_pkt_num == RECV_PKT_CNT) {
|
||||
g_count_after_get_us = uapi_systick_get_us();
|
||||
printf("count_us = %llu, recv %d pkt.\r\n",
|
||||
g_count_after_get_us - g_count_before_get_us, RECV_PKT_CNT);
|
||||
float time = (float)(g_count_after_get_us - g_count_before_get_us) / 1000000.0; /* 1s = 1000000.0us */
|
||||
printf("time = %d.%d s\r\n", get_float_int(time), get_float_dec(time));
|
||||
float speed = (data->data_len) * RECV_PKT_CNT * 8 / time; /* 1B = 8bits */
|
||||
printf("speed = %d.%d bps\r\n", get_float_int(speed), get_float_dec(speed));
|
||||
g_recv_pkt_num = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatt_client_indication_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Receive indication----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" handle:%d data_len:%d\ndata:", data->handle, data->data_len);
|
||||
for (uint8_t i = 0; i < data->data_len; i++) {
|
||||
osal_printk("%02x", data->data[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_enable_cbk(errcode_t status)
|
||||
{
|
||||
status = status;
|
||||
}
|
||||
|
||||
static int convert_ble_mac(uint8_t *dest_mac, uint16_t dest_len, uint8_t *src_mac, uint16_t src_len)
|
||||
{
|
||||
if (dest_len != src_len) {
|
||||
return -1;
|
||||
}
|
||||
for (uint8_t i = 0; i < src_len; i++) {
|
||||
dest_mac[i] = src_mac[src_len - 1 - i];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ble_gatt_client_scan_result_cbk(gap_scan_result_data_t *scan_result_data)
|
||||
{
|
||||
uint8_t ble_mac[BD_ADDR_LEN] = {0};
|
||||
convert_ble_mac(ble_mac, BD_ADDR_LEN, g_ble_speed_addr.addr, BD_ADDR_LEN);
|
||||
if (memcmp(scan_result_data->addr.addr, ble_mac, BD_ADDR_LEN) == 0) {
|
||||
osal_printk("Find The Target Device.\n");
|
||||
gap_ble_stop_scan();
|
||||
bd_addr_t client_addr = { 0 };
|
||||
client_addr.type = scan_result_data->addr.type;
|
||||
if (memcpy_s(client_addr.addr, BD_ADDR_LEN, scan_result_data->addr.addr, BD_ADDR_LEN) != EOK) {
|
||||
osal_printk("%s add server app addr memcpy failed\r\n", __FUNCTION__);
|
||||
return;
|
||||
}
|
||||
gap_ble_connect_remote_device(&client_addr);
|
||||
} else {
|
||||
osal_printk("\naddr:");
|
||||
for (uint8_t i = 0; i < BD_ADDR_LEN; i++) {
|
||||
osal_printk(" %02x:", scan_result_data->addr.addr[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatt_client_conn_state_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("%s connect state change conn_id: %d, status: %d, pair_status:%d, disc_reason %x\n",
|
||||
__FUNCTION__, conn_id, conn_state, pair_state, disc_reason);
|
||||
|
||||
if (conn_state == GAP_BLE_STATE_CONNECTED) {
|
||||
gap_ble_pair_remote_device(addr);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_gatt_client_pair_result_cbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status)
|
||||
{
|
||||
unused(addr);
|
||||
osal_printk("%s pair result conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status);
|
||||
|
||||
ble_gatt_client_discover_all_service(conn_id);
|
||||
}
|
||||
|
||||
static void ble_gatt_client_conn_param_update_cbk(uint16_t conn_id, errcode_t status,
|
||||
const gap_ble_conn_param_update_t *param)
|
||||
{
|
||||
osal_printk("%s conn_param_update conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status);
|
||||
osal_printk("interval:%d latency:%d timeout:%d.\n", param->interval, param->latency, param->timeout);
|
||||
}
|
||||
|
||||
errcode_t ble_gatt_client_callback_register(void)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_UNHANDLED;
|
||||
gap_ble_callbacks_t gap_cb = {0};
|
||||
gap_cb.ble_enable_cb = ble_gatt_client_enable_cbk;
|
||||
gap_cb.scan_result_cb = ble_gatt_client_scan_result_cbk;
|
||||
gap_cb.conn_state_change_cb = ble_gatt_client_conn_state_change_cbk;
|
||||
gap_cb.pair_result_cb = ble_gatt_client_pair_result_cbk;
|
||||
gap_cb.conn_param_update_cb = ble_gatt_client_conn_param_update_cbk;
|
||||
ret |= gap_ble_register_callbacks(&gap_cb);
|
||||
|
||||
gattc_callbacks_t cb = {0};
|
||||
cb.discovery_svc_cb = ble_gatt_client_discover_service_cbk;
|
||||
cb.discovery_svc_cmp_cb = ble_gatt_client_discover_service_compl_cbk;
|
||||
cb.discovery_chara_cb = ble_gatt_client_discover_character_cbk;
|
||||
cb.discovery_chara_cmp_cb = ble_gatt_client_discover_character_compl_cbk;
|
||||
cb.discovery_desc_cb = ble_gatt_client_discover_descriptor_cbk;
|
||||
cb.discovery_desc_cmp_cb = ble_gatt_client_discover_descriptor_compl_cbk;
|
||||
cb.read_cb = ble_gatt_client_read_cfm_cbk;
|
||||
cb.read_cmp_cb = ble_gatt_client_read_compl_cbk;
|
||||
cb.write_cb = ble_gatt_client_write_cfm_cbk;
|
||||
cb.mtu_changed_cb = ble_gatt_client_mtu_changed_cbk;
|
||||
cb.notification_cb = ble_gatt_client_notification_cbk;
|
||||
cb.indication_cb = ble_gatt_client_indication_cbk;
|
||||
ret |= gattc_register_callbacks(&cb);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ble_speed_start_scan(void)
|
||||
{
|
||||
gap_ble_scan_params_t ble_device_scan_params = { 0 };
|
||||
ble_device_scan_params.scan_interval = DEFAULT_SCAN_INTERVAL;
|
||||
ble_device_scan_params.scan_window = DEFAULT_SCAN_INTERVAL;
|
||||
ble_device_scan_params.scan_type = 0x00;
|
||||
ble_device_scan_params.scan_phy = GAP_BLE_PHY_2M;
|
||||
ble_device_scan_params.scan_filter_policy = 0x00;
|
||||
gap_ble_set_scan_parameters(&ble_device_scan_params);
|
||||
gap_ble_start_scan();
|
||||
}
|
||||
|
||||
errcode_t ble_gatt_client_init(void)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_SUCCESS;
|
||||
ret |= enable_ble();
|
||||
ret |= ble_gatt_client_callback_register();
|
||||
ret |= gattc_register_client(&g_client_app_uuid, &g_client_id);
|
||||
osal_printk("[BLE Client] init ok.\n");
|
||||
ble_speed_start_scan();
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t ble_gatt_client_discover_all_service(uint16_t conn_id)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_SUCCESS;
|
||||
bt_uuid_t service_uuid = {0}; /* uuid length is zero, discover all service */
|
||||
ret |= gattc_discovery_service(g_client_id, conn_id, &service_uuid);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define BLE_SPEED_TASK_PRIO 26
|
||||
#define BLE_SPEED_STACK_SIZE 0x2000
|
||||
|
||||
static void ble_speed_entry(void)
|
||||
{
|
||||
osal_task *task_handle = NULL;
|
||||
osal_kthread_lock();
|
||||
task_handle= osal_kthread_create((osal_kthread_handler)ble_gatt_client_init, 0, "ble_speed",
|
||||
BLE_SPEED_STACK_SIZE);
|
||||
if (task_handle != NULL) {
|
||||
osal_kthread_set_priority(task_handle, BLE_SPEED_TASK_PRIO);
|
||||
osal_kfree(task_handle);
|
||||
}
|
||||
osal_kthread_unlock();
|
||||
}
|
||||
|
||||
/* Run the app entry. */
|
||||
app_run(ble_speed_entry);
|
8
application/samples/bt/ble/ble_speed_server/CMakeLists.txt
Executable file
8
application/samples/bt/ble/ble_speed_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_speed_server/inc/ble_speed_server.h
Executable file
91
application/samples/bt/ble/ble_speed_server/inc/ble_speed_server.h
Executable file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved.
|
||||
*
|
||||
* Description: BLE SPEED Server module.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup bluetooth_bts_hid_server HID SERVER API
|
||||
* @ingroup
|
||||
* @{
|
||||
*/
|
||||
#ifndef BLE_SPEED_SERVER_H
|
||||
#define BLE_SPEED_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 server init.
|
||||
* @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(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 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_speed_server/inc/ble_speed_server_adv.h
Executable file
212
application/samples/bt/ble/ble_speed_server/inc/ble_speed_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_speed_server/src/CMakeLists.txt
Executable file
8
application/samples/bt/ble/ble_speed_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_speed_server_adv.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/ble_speed_server.c"
|
||||
PARENT_SCOPE)
|
426
application/samples/bt/ble/ble_speed_server/src/ble_speed_server.c
Executable file
426
application/samples/bt/ble/ble_speed_server/src/ble_speed_server.c
Executable file
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2022. All rights reserved.
|
||||
* Description: ble speed server sample.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <los_memory.h>
|
||||
#include "app_init.h"
|
||||
#include "systick.h"
|
||||
#include "soc_osal.h"
|
||||
#include "cmsis_os2.h"
|
||||
#include "securec.h"
|
||||
#include "errcode.h"
|
||||
|
||||
#include "osal_addr.h"
|
||||
#include "bts_def.h"
|
||||
#include "bts_def.h"
|
||||
#include "bts_le_gap.h"
|
||||
#include "bts_gatt_stru.h"
|
||||
#include "bts_gatt_server.h"
|
||||
#include "bts_gatt_client.h"
|
||||
#include "ble_speed_server_adv.h"
|
||||
#include "ble_speed_server.h"
|
||||
|
||||
uint8_t g_server_id = 0;
|
||||
|
||||
/* 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;
|
||||
|
||||
#define OCTET_BIT_LEN 8
|
||||
#define UUID_LEN_2 2
|
||||
|
||||
bd_addr_t g_ble_speed_addr = {
|
||||
.type = 0,
|
||||
.addr = {0x11, 0x22, 0x33, 0x63, 0x88, 0x63},
|
||||
};
|
||||
|
||||
#define DATA_LEN 236
|
||||
unsigned char data[DATA_LEN];
|
||||
uint64_t g_count_before_get_us;
|
||||
uint64_t g_count_after_get_us;
|
||||
#define SEND_PKT_TIMES 8
|
||||
#define SEND_PKT_CNT 100
|
||||
#define DEFAULT_BLE_SPEED_MTU_SIZE 250
|
||||
#define GAP_MAX_TX_OCTETS 251
|
||||
#define GAP_MAX_TX_TIME 2000
|
||||
#define SPEED_DEFAULT_CONN_INTERVAL 0xA
|
||||
#define SPPED_DEFAULT_SLAVE_LATENCY 0
|
||||
#define SPEED_DEFAULT_TIMEOUT_MULTIPLIER 0x1f4
|
||||
|
||||
#define BLE_SPEED_TASK_PRIO 26
|
||||
#define BLE_SPEED_STACK_SIZE 0x2000
|
||||
|
||||
void send_data_thread_function(void)
|
||||
{
|
||||
printf("start send notify info.\n");
|
||||
gap_le_set_phy_t phy_param = {
|
||||
.conn_handle = g_conn_hdl,
|
||||
.all_phys = 0,
|
||||
.tx_phys = 1,
|
||||
.rx_phys = 1,
|
||||
.phy_options = 0,
|
||||
};
|
||||
gap_ble_set_phy(&phy_param);
|
||||
|
||||
gap_le_set_data_length_t data_param = {
|
||||
.conn_handle = g_conn_hdl,
|
||||
.maxtxoctets = GAP_MAX_TX_OCTETS,
|
||||
.maxtxtime = GAP_MAX_TX_TIME,
|
||||
};
|
||||
gap_ble_set_data_length(&data_param);
|
||||
|
||||
int i = 0;
|
||||
g_count_before_get_us = uapi_systick_get_us();
|
||||
while (1) {
|
||||
i++;
|
||||
data[0] = (i >> 8) & 0xFF; /* offset 8bits */
|
||||
data[1] = i & 0xFF;
|
||||
ble_uuid_server_send_report_by_uuid(data, DATA_LEN);
|
||||
osal_msleep(1); /* 延时1ms 可使用BLE流控机制替换 */
|
||||
if (i == SEND_PKT_CNT) {
|
||||
i = 0;
|
||||
printf("[SYS INFO] send %d pkt: ", SEND_PKT_CNT);
|
||||
LOS_MEM_POOL_STATUS status;
|
||||
LOS_MemInfoGet(m_aucSysMem0, &status);
|
||||
osal_printk(" mem: used:%u, free:%u.\r\n", status.uwTotalUsedSize, status.uwTotalFreeSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 将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_CONNECTED) {
|
||||
gattc_exchange_mtu_req(g_server_id, conn_id, DEFAULT_BLE_SPEED_MTU_SIZE);
|
||||
|
||||
gap_conn_param_update_t conn_param = {0};
|
||||
conn_param.conn_handle = conn_id;
|
||||
conn_param.interval_min = SPEED_DEFAULT_CONN_INTERVAL;
|
||||
conn_param.interval_max = SPEED_DEFAULT_CONN_INTERVAL;
|
||||
conn_param.slave_latency = SPPED_DEFAULT_SLAVE_LATENCY;
|
||||
conn_param.timeout_multiplier = SPEED_DEFAULT_TIMEOUT_MULTIPLIER;
|
||||
gap_ble_connect_param_update(&conn_param);
|
||||
} else 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_pair_result_cbk(uint16_t conn_id, const bd_addr_t *addr, errcode_t status)
|
||||
{
|
||||
osal_printk("pair state change conn_id: %d, status: %d, addr %x \n",
|
||||
conn_id, status, addr[0]);
|
||||
|
||||
if (status == 0) {
|
||||
osal_task *task_handle = NULL;
|
||||
osal_kthread_lock();
|
||||
task_handle = osal_kthread_create((osal_kthread_handler)send_data_thread_function, 0,
|
||||
"SpeedTask", BLE_SPEED_STACK_SIZE);
|
||||
osal_kthread_set_priority(task_handle, BLE_SPEED_TASK_PRIO + 1);
|
||||
if (task_handle != NULL) {
|
||||
osal_kfree(task_handle);
|
||||
}
|
||||
osal_kthread_unlock();
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_uuid_server_conn_param_update_cbk(uint16_t conn_id, errcode_t status,
|
||||
const gap_ble_conn_param_update_t *param)
|
||||
{
|
||||
osal_printk("%s conn_param_update conn_id: %d,status: %d \n", __FUNCTION__, conn_id, status);
|
||||
osal_printk("interval:%d latency:%d timeout:%d.\n", param->interval, param->latency, param->timeout);
|
||||
}
|
||||
|
||||
static errcode_t ble_uuid_server_register_callbacks(void)
|
||||
{
|
||||
errcode_t ret = 0;
|
||||
|
||||
gap_ble_callbacks_t gap_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.pair_result_cb = ble_uuid_server_pair_result_cbk;
|
||||
gap_cb.conn_param_update_cb = ble_uuid_server_conn_param_update_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;
|
||||
}
|
||||
|
||||
gatts_callbacks_t service_cb = {0};
|
||||
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(BLE_UUID_SERVER_ID, &service_uuid, true);
|
||||
osal_printk("[uuid server] ble uuid add service out\r\n");
|
||||
return ERRCODE_BT_SUCCESS;
|
||||
}
|
||||
|
||||
static errcode_t ble_uuid_gatts_register_server(void)
|
||||
{
|
||||
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;
|
||||
}
|
||||
return gatts_register_server(&app_uuid, &g_server_id);
|
||||
}
|
||||
|
||||
/* 初始化uuid server service */
|
||||
errcode_t ble_uuid_server_init(void)
|
||||
{
|
||||
(void)osal_msleep(1000); /* 延时1000ms,等待BLE初始化完毕 */
|
||||
enable_ble();
|
||||
ble_uuid_server_register_callbacks();
|
||||
ble_uuid_gatts_register_server();
|
||||
ble_uuid_add_service();
|
||||
gap_ble_set_local_addr(&g_ble_speed_addr);
|
||||
osal_printk("[uuid server] init ok\r\n");
|
||||
ble_start_adv();
|
||||
osal_printk("[uuid server] adv ok\r\n");
|
||||
return ERRCODE_BT_SUCCESS;
|
||||
}
|
||||
|
||||
/* device通过uuid向host发送数据:report */
|
||||
errcode_t ble_uuid_server_send_report_by_uuid(uint8_t *data, uint16_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 = data;
|
||||
if (param.value == NULL) {
|
||||
osal_printk("[hid][ERROR]send report new fail\r\n");
|
||||
return ERRCODE_BT_FAIL;
|
||||
}
|
||||
gatts_notify_indicate_by_uuid(BLE_UUID_SERVER_ID, conn_id, ¶m);
|
||||
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(BLE_UUID_SERVER_ID, conn_id, ¶m);
|
||||
osal_vfree(param.value);
|
||||
return ERRCODE_BT_SUCCESS;
|
||||
}
|
||||
|
||||
static void ble_speed_entry(void)
|
||||
{
|
||||
osal_task *task_handle = NULL;
|
||||
osal_kthread_lock();
|
||||
task_handle= osal_kthread_create((osal_kthread_handler)ble_uuid_server_init, 0, "ble_speed",
|
||||
BLE_SPEED_STACK_SIZE);
|
||||
if (task_handle != NULL) {
|
||||
osal_kthread_set_priority(task_handle, BLE_SPEED_TASK_PRIO);
|
||||
osal_kfree(task_handle);
|
||||
}
|
||||
osal_kthread_unlock();
|
||||
}
|
||||
|
||||
/* Run the app entry. */
|
||||
app_run(ble_speed_entry);
|
196
application/samples/bt/ble/ble_speed_server/src/ble_speed_server_adv.c
Executable file
196
application/samples/bt/ble/ble_speed_server/src/ble_speed_server_adv.c
Executable file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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_speed_server_adv.h"
|
||||
|
||||
#define NAME_MAX_LENGTH 15
|
||||
#define EXT_ADV_OR_SCAN_RSP_DATA_LEN 251
|
||||
static uint8_t u16_low_u8(uint16_t val)
|
||||
{
|
||||
return (uint8_t)(val & 0xff);
|
||||
}
|
||||
|
||||
static uint8_t u16_high_u8(uint16_t val)
|
||||
{
|
||||
return (uint8_t)((val >> 8) & 0xff); /* offset 8bits */
|
||||
}
|
||||
|
||||
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};
|
||||
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;
|
||||
}
|
8
application/samples/bt/ble/ble_wifi_cfg_client/CMakeLists.txt
Executable file
8
application/samples/bt/ble/ble_wifi_cfg_client/CMakeLists.txt
Executable file
@ -0,0 +1,8 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 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)
|
52
application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_client.h
Executable file
52
application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_client.h
Executable file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
* Description: BT config wifi Service client module.
|
||||
*/
|
||||
#ifndef BLE_WIFI_CFG_CLIENT_H
|
||||
#define BLE_WIFI_CFG_CLIENT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @if Eng
|
||||
* @brief Use this funtion to init gatt client.
|
||||
* @par Description:init gatt client.
|
||||
* @attention NULL
|
||||
* @param NULL
|
||||
* @retval error code.
|
||||
* @else
|
||||
* @brief 初始化gatt 客户端。
|
||||
* @par 说明:初始化gatt 客户端。
|
||||
* @attention NULL
|
||||
* @param NULL
|
||||
* @retval 执行结果错误码。
|
||||
* @endif
|
||||
*/
|
||||
errcode_t ble_wifi_cfg_client_init(void);
|
||||
|
||||
/**
|
||||
* @if Eng
|
||||
* @brief discover all service, character and descriptor of remote device.
|
||||
* @par Description:discover all service of remote device.
|
||||
* @attention NULL
|
||||
* @param conn_id connection ID
|
||||
* @retval error code.
|
||||
* @else
|
||||
* @brief 发现对端设备所有服务、特征和描述符。
|
||||
* @par 说明:发现对端设备所有服务、特征和描述符。
|
||||
* @attention NULL
|
||||
* @param conn_id 连接 ID
|
||||
* @retval 执行结果错误码。
|
||||
* @endif
|
||||
*/
|
||||
errcode_t ble_wifi_cfg_client_discover_all_service(uint16_t conn_id);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
25
application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_scan.h
Executable file
25
application/samples/bt/ble/ble_wifi_cfg_client/inc/ble_wifi_cfg_scan.h
Executable file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
* Description: BLE config wifi client scan.
|
||||
*/
|
||||
#ifndef BLE_WIFI_CFG_SCAN_H
|
||||
#define BLE_WIFI_CFG_SCAN_H
|
||||
|
||||
#include "errcode.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
errcode_t ble_wifi_device_start_scan(void);
|
||||
|
||||
errcode_t ble_wifi_set_scan_parameters(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
#endif
|
11
application/samples/bt/ble/ble_wifi_cfg_client/src/CMakeLists.txt
Executable file
11
application/samples/bt/ble/ble_wifi_cfg_client/src/CMakeLists.txt
Executable file
@ -0,0 +1,11 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
#===============================================================================
|
||||
|
||||
set(
|
||||
ble_wifi_cfg_src_list
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_client.c
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_scan.c
|
||||
)
|
||||
set(SOURCES "${SOURCES}" "${ble_wifi_cfg_src_list}" PARENT_SCOPE)
|
281
application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_client.c
Executable file
281
application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_client.c
Executable file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
* Description: BT config wifi Service client module.
|
||||
*/
|
||||
#include "securec.h"
|
||||
#include "osal_list.h"
|
||||
#include "osal_debug.h"
|
||||
#include "bts_le_gap.h"
|
||||
#include "bts_gatt_client.h"
|
||||
#include "ble_wifi_cfg_scan.h"
|
||||
|
||||
#define UUID16_LEN 2
|
||||
|
||||
#define BLE_WIFI_CFG_CLIENT_LOG "[ble wifi cfg client]"
|
||||
#define BLE_WIFI_CFG_CLIENT_ERROR "[ble wifi cfg error]"
|
||||
|
||||
/* client id, invalid client id is "0" */
|
||||
uint8_t g_ble_wifi_cfg_client_id = 0;
|
||||
|
||||
static uint16_t g_ble_wifi_cfg_conn_id = 0;
|
||||
|
||||
/* max transport unit, default is 100 */
|
||||
static uint16_t g_ble_wifi_cfg_mtu = 100;
|
||||
|
||||
/* client app uuid for test */
|
||||
static bt_uuid_t g_ble_wifi_cfg_client_app = {UUID16_LEN, {0}};
|
||||
|
||||
|
||||
uint8_t ble_wifi_adv_data[31] = {0x02, 0x01, 0x02, 0x13, 0xFF, 0x7D, 0x02, 0x0E, 0x70, 0x80, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x01, 0x06, 0xCA, 0x2D, 0x28, 0xA0, 0x9D, 0xA3, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
#define HW_ADV_DATA_LEN 0x17
|
||||
|
||||
static void ble_wifi_cfg_client_discover_service_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_service_result_t *service, errcode_t status)
|
||||
{
|
||||
gattc_discovery_character_param_t param = {0};
|
||||
osal_printk("[GATTClient]Discovery service----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk("start handle:%d end handle:%d uuid_len:%d\n uuid:",
|
||||
service->start_hdl, service->end_hdl, service->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < service->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", service->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
param.service_handle = service->start_hdl;
|
||||
param.uuid.uuid_len = 0; /* uuid length is zero, discover all character */
|
||||
gattc_discovery_character(g_ble_wifi_cfg_client_id, conn_id, ¶m);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_discover_character_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_character_result_t *character, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery character----client:%d conn_id:%d uuid_len:%d\n uuid:",
|
||||
client_id, conn_id, character->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < character->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", character->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n declare handle:%d value handle:%d properties:%x\n", character->declare_handle,
|
||||
character->value_handle, character->properties);
|
||||
osal_printk(" status:%d\n", status);
|
||||
gattc_discovery_descriptor(g_ble_wifi_cfg_client_id, conn_id, character->declare_handle);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_discover_descriptor_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_descriptor_result_t *descriptor, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery descriptor----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, descriptor->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < descriptor->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", descriptor->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n descriptor handle:%d\n", descriptor->descriptor_hdl);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_discover_service_compl_cbk(uint8_t client_id, uint16_t conn_id, bt_uuid_t *uuid,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk(
|
||||
"[GATTClient]Discovery service complete----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, uuid->uuid_len);
|
||||
for (uint8_t i = 0; i < uuid->uuid_len; i++) {
|
||||
osal_printk("%02x", uuid->uuid[i]);
|
||||
}
|
||||
osal_printk("status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_discover_character_compl_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_discovery_character_param_t *param, errcode_t status)
|
||||
{
|
||||
osal_printk(
|
||||
"[GATTClient]Discovery character complete----client:%d conn_id:%d uuid len:%d\n uuid:",
|
||||
client_id, conn_id, param->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < param->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", param->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n service handle:%d\n", param->service_handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_discover_descriptor_compl_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
uint16_t character_handle, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Discovery descriptor complete----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" charatcer handle:%d\n", character_handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_read_cfm_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *read_result,
|
||||
gatt_status_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Read result----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" handle:%d data_len:%d\ndata:", read_result->handle, read_result->data_len);
|
||||
for (uint8_t i = 0; i < read_result->data_len; i++) {
|
||||
osal_printk("%02x", read_result->data[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_read_compl_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
gattc_read_req_by_uuid_param_t *param, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Read by uuid complete----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk("start handle:%d end handle:%d uuid len:%d\n uuid:",
|
||||
param->start_hdl, param->end_hdl, param->uuid.uuid_len);
|
||||
for (uint8_t i = 0; i < param->uuid.uuid_len; i++) {
|
||||
osal_printk("%02x", param->uuid.uuid[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_write_cfm_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
uint16_t handle, gatt_status_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Write result----client:%d conn_id:%d handle:%d\n", client_id, conn_id, handle);
|
||||
osal_printk(" status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_mtu_changed_cbk(uint8_t client_id, uint16_t conn_id,
|
||||
uint16_t mtu_size, errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Mtu changed----client:%d conn_id:%d mtu size:%d\n", client_id, conn_id,
|
||||
mtu_size);
|
||||
osal_printk("status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_notification_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Receive notification----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk("handle:%d data_len:%d\ndata:", data->handle, data->data_len);
|
||||
for (uint8_t i = 0; i < data->data_len; i++) {
|
||||
osal_printk("%02x", data->data[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_client_indication_cbk(uint8_t client_id, uint16_t conn_id, gattc_handle_value_t *data,
|
||||
errcode_t status)
|
||||
{
|
||||
osal_printk("[GATTClient]Receive indication----client:%d conn_id:%d\n", client_id, conn_id);
|
||||
osal_printk(" handle:%d data_len:%d\ndata:", data->handle, data->data_len);
|
||||
for (uint8_t i = 0; i < data->data_len; i++) {
|
||||
osal_printk("%02x", data->data[i]);
|
||||
}
|
||||
osal_printk("\n status:%d\n", status);
|
||||
}
|
||||
|
||||
/* ble client set scan param callback */
|
||||
void ble_wifi_cfg_set_scan_param_cbk(errcode_t status)
|
||||
{
|
||||
osal_printk("%s set scan param status: %d\n", 0, status);
|
||||
gap_ble_remove_all_pairs(); /* 配网业务无需多连接,因此扫描时需将其他设备断开, 然后扫描配对新设备 */
|
||||
ble_wifi_device_start_scan();
|
||||
}
|
||||
|
||||
/* ble client scan result callback */
|
||||
void ble_wifi_cfg_scan_result_cbk(gap_scan_result_data_t *scan_result_data)
|
||||
{
|
||||
if (memcmp(scan_result_data->adv_data, ble_wifi_adv_data, HW_ADV_DATA_LEN) == 0) {
|
||||
gap_ble_stop_scan();
|
||||
osal_printk("\naddr:");
|
||||
for (uint8_t i = 0; i < BD_ADDR_LEN; i++) {
|
||||
osal_printk(" %02x: ", scan_result_data->addr.addr[i]);
|
||||
}
|
||||
bd_addr_t client_addr = { 0 };
|
||||
client_addr.type = scan_result_data->addr.type;
|
||||
if (memcpy_s(client_addr.addr, BD_ADDR_LEN, scan_result_data->addr.addr, BD_ADDR_LEN) != EOK) {
|
||||
osal_printk("%s add server app addr memcpy failed\r\n", BLE_WIFI_CFG_CLIENT_ERROR);
|
||||
return;
|
||||
}
|
||||
gap_ble_connect_remote_device(&client_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/* ble client connect state change callback */
|
||||
void ble_wifi_cfg_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)
|
||||
{
|
||||
bd_addr_t client_addr = { 0 };
|
||||
client_addr.type = addr->type;
|
||||
g_ble_wifi_cfg_conn_id = conn_id;
|
||||
if (memcpy_s(client_addr.addr, BD_ADDR_LEN, addr->addr, BD_ADDR_LEN) != EOK) {
|
||||
osal_printk("%s add server app addr memcpy failed\r\n", BLE_WIFI_CFG_CLIENT_ERROR);
|
||||
return;
|
||||
}
|
||||
osal_printk("%s connect state change conn_id: %d, status: %d, pair_status:%d, disc_reason %x\n",
|
||||
0, conn_id, conn_state, pair_state, disc_reason);
|
||||
|
||||
if (conn_state == GAP_BLE_STATE_CONNECTED && pair_state == GAP_BLE_PAIR_NONE) {
|
||||
osal_printk("%s connect change cbk conn_id =%d \n", 0, conn_id);
|
||||
gattc_exchange_mtu_req(g_ble_wifi_cfg_client_id, g_ble_wifi_cfg_conn_id, g_ble_wifi_cfg_mtu);
|
||||
} else if (conn_state == GAP_BLE_STATE_DISCONNECTED) {
|
||||
osal_printk("%s connect change cbk conn disconnected \n", 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* ble client pair result callback */
|
||||
void ble_wifi_cfg_pair_result_cb(uint16_t conn_id, const bd_addr_t *addr, errcode_t status)
|
||||
{
|
||||
osal_printk("%s pair result conn_id: %d,status: %d \n", 0, conn_id, status);
|
||||
osal_printk("addr:\n");
|
||||
for (uint8_t i = 0; i < BD_ADDR_LEN; i++) {
|
||||
osal_printk("%2x", addr->addr[i]);
|
||||
}
|
||||
osal_printk("\n");
|
||||
gattc_exchange_mtu_req(g_ble_wifi_cfg_client_id, g_ble_wifi_cfg_conn_id,
|
||||
g_ble_wifi_cfg_mtu);
|
||||
}
|
||||
|
||||
|
||||
errcode_t ble_wifi_cfg_client_callback_register(void)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_UNHANDLED;
|
||||
gap_ble_callbacks_t gap_cb = { 0 };
|
||||
gattc_callbacks_t cb = {0};
|
||||
|
||||
gap_cb.set_scan_param_cb = ble_wifi_cfg_set_scan_param_cbk;
|
||||
gap_cb.scan_result_cb = ble_wifi_cfg_scan_result_cbk;
|
||||
gap_cb.conn_state_change_cb = ble_wifi_cfg_connect_change_cbk;
|
||||
gap_cb.pair_result_cb = ble_wifi_cfg_pair_result_cb;
|
||||
ret = gap_ble_register_callbacks(&gap_cb);
|
||||
if (ret != ERRCODE_BT_SUCCESS) {
|
||||
osal_printk("%s reg gap cbk failed ret = %d\n", 0, ret);
|
||||
}
|
||||
|
||||
cb.discovery_svc_cb = ble_wifi_cfg_client_discover_service_cbk;
|
||||
cb.discovery_svc_cmp_cb = ble_wifi_cfg_client_discover_service_compl_cbk;
|
||||
cb.discovery_chara_cb = ble_wifi_cfg_client_discover_character_cbk;
|
||||
cb.discovery_chara_cmp_cb = ble_wifi_cfg_client_discover_character_compl_cbk;
|
||||
cb.discovery_desc_cb = ble_wifi_cfg_client_discover_descriptor_cbk;
|
||||
cb.discovery_desc_cmp_cb = ble_wifi_cfg_client_discover_descriptor_compl_cbk;
|
||||
cb.read_cb = ble_wifi_cfg_client_read_cfm_cbk;
|
||||
cb.read_cmp_cb = ble_wifi_cfg_client_read_compl_cbk;
|
||||
cb.write_cb = ble_wifi_cfg_client_write_cfm_cbk;
|
||||
cb.mtu_changed_cb = ble_wifi_cfg_client_mtu_changed_cbk;
|
||||
cb.notification_cb = ble_wifi_cfg_client_notification_cbk;
|
||||
cb.indication_cb = ble_wifi_cfg_client_indication_cbk;
|
||||
ret = gattc_register_callbacks(&cb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t ble_wifi_cfg_client_init(void)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_SUCCESS;
|
||||
ret |= enable_ble();
|
||||
ret |= ble_wifi_cfg_client_callback_register();
|
||||
ret |= gattc_register_client(&g_ble_wifi_cfg_client_app, &g_ble_wifi_cfg_client_id);
|
||||
return ret;
|
||||
}
|
||||
|
||||
errcode_t ble_wifi_cfg_client_discover_all_service(uint16_t conn_id)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_SUCCESS;
|
||||
bt_uuid_t service_uuid = {0}; /* uuid length is zero, discover all service */
|
||||
ret |= gattc_discovery_service(g_ble_wifi_cfg_client_id, conn_id, &service_uuid);
|
||||
return ret;
|
||||
}
|
||||
|
31
application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_scan.c
Executable file
31
application/samples/bt/ble/ble_wifi_cfg_client/src/ble_wifi_cfg_scan.c
Executable file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
* Description: BLE config wifi client scan
|
||||
*/
|
||||
|
||||
#include "errcode.h"
|
||||
#include "bts_def.h"
|
||||
#include "bts_le_gap.h"
|
||||
#include "ble_wifi_cfg_scan.h"
|
||||
|
||||
static uint16_t scan_interval = 0x48;
|
||||
static uint16_t scan_window = 0x48;
|
||||
static uint8_t scan_type = 0x00;
|
||||
static uint8_t scan_phy = 0x01;
|
||||
static uint8_t scan_filter_policy = 0x00;
|
||||
|
||||
errcode_t ble_wifi_set_scan_parameters(void)
|
||||
{
|
||||
gap_ble_scan_params_t ble_device_scan_params = { 0 };
|
||||
ble_device_scan_params.scan_interval = scan_interval;
|
||||
ble_device_scan_params.scan_window = scan_window;
|
||||
ble_device_scan_params.scan_type = scan_type;
|
||||
ble_device_scan_params.scan_phy = scan_phy;
|
||||
ble_device_scan_params.scan_filter_policy = scan_filter_policy;
|
||||
return gap_ble_set_scan_parameters(&ble_device_scan_params);
|
||||
}
|
||||
|
||||
errcode_t ble_wifi_device_start_scan(void)
|
||||
{
|
||||
return gap_ble_start_scan();
|
||||
}
|
8
application/samples/bt/ble/ble_wifi_cfg_server/CMakeLists.txt
Executable file
8
application/samples/bt/ble/ble_wifi_cfg_server/CMakeLists.txt
Executable file
@ -0,0 +1,8 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 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)
|
171
application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_adv.h
Executable file
171
application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_adv.h
Executable file
@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
* Description: BLE ADV Config.
|
||||
*/
|
||||
#ifndef BLE_WIFI_CFG_ADV_H
|
||||
#define BLE_WIFI_CFG_ADV_H
|
||||
|
||||
#include "bts_def.h"
|
||||
|
||||
/* Ble keyboard categorylength */
|
||||
#define BLE_ADV_CATEGORY_LEN 2
|
||||
|
||||
/**
|
||||
* @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 0x20
|
||||
/* 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);
|
||||
|
||||
uint8_t ble_wifi_cfg_start_adv(void);
|
||||
#endif
|
||||
|
77
application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_server.h
Executable file
77
application/samples/bt/ble/ble_wifi_cfg_server/inc/ble_wifi_cfg_server.h
Executable file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
* Description: BLE UUID Server module.
|
||||
*/
|
||||
#ifndef BLE_WIFI_CFG_SERVER_H
|
||||
#define BLE_WIFI_CFG_SERVER_H
|
||||
|
||||
#include "bts_def.h"
|
||||
|
||||
/* Characteristic Property */
|
||||
#define BLE_WIFI_CFG_PROPERTIES (GATT_CHARACTER_PROPERTY_BIT_NOTIFY | GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP)
|
||||
|
||||
/* Characteristic Property */
|
||||
#define UUID_SERVER_IND_PROPERTIES (GATT_CHARACTER_PROPERTY_BIT_INDICATE | GATT_CHARACTER_PROPERTY_BIT_WRITE_NO_RSP)
|
||||
|
||||
/**
|
||||
* @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_wifi_cfg_server_init(void);
|
||||
|
||||
/**
|
||||
* @if Eng
|
||||
* @brief send data to peer device by wifi 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 通过wifi server 发送数据给对端。
|
||||
* @attention NULL
|
||||
* @retval BT_STATUS_SUCCESS 执行成功
|
||||
* @retval BT_STATUS_FAIL 执行失败
|
||||
* @par 依赖:
|
||||
* @li bts_def.h
|
||||
* @endif
|
||||
*/
|
||||
errcode_t ble_wifi_cfg_server_send_report_by_uuid(const uint8_t *data, uint32_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 通过wifi server 发送数据给对端。
|
||||
* @attention NULL
|
||||
* @retval BT_STATUS_SUCCESS 执行成功
|
||||
* @retval BT_STATUS_FAIL 执行失败
|
||||
* @par 依赖:
|
||||
* @li bts_def.h
|
||||
* @endif
|
||||
*/
|
||||
errcode_t ble_wifi_cfg_server_send_report_by_handle(uint16_t attr_handle, const uint8_t *data, uint8_t len);
|
||||
|
||||
#endif
|
9
application/samples/bt/ble/ble_wifi_cfg_server/src/CMakeLists.txt
Executable file
9
application/samples/bt/ble/ble_wifi_cfg_server/src/CMakeLists.txt
Executable file
@ -0,0 +1,9 @@
|
||||
#===============================================================================
|
||||
# @brief cmake file
|
||||
# Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
#===============================================================================
|
||||
|
||||
set(SOURCES "${SOURCES}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_adv.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/ble_wifi_cfg_server.c"
|
||||
PARENT_SCOPE)
|
136
application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_adv.c
Executable file
136
application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_adv.c
Executable file
@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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 "osal_debug.h"
|
||||
#include "securec.h"
|
||||
#include "errcode.h"
|
||||
#include "bts_def.h"
|
||||
#include "bts_le_gap.h"
|
||||
#include "ble_wifi_cfg_adv.h"
|
||||
|
||||
#define NAME_MAX_LENGTH 15
|
||||
#define EXT_ADV_OR_SCAN_RSP_DATA_LEN 251
|
||||
#define HW_ADV_DATA_LEN 0x17
|
||||
|
||||
/* Ble Adv data length */
|
||||
#define BLE_GENERAL_BYTE_1 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
|
||||
|
||||
uint8_t g_device_name[ NAME_MAX_LENGTH] = { 'b', 'l', 'e', '_', 'w', 'i', 'f', 'i', '_', 'c',
|
||||
'o', 'n', 'f', 'i', 'g' };
|
||||
|
||||
uint8_t g_adv_data[31] = {0x02, 0x01, 0x02, 0x13, 0xFF, 0x7D, 0x02, 0x0E, 0x70, 0x80, 0x00, 0x00,
|
||||
0x00, 0x01, 0x00, 0x01, 0x06, 0xCA, 0x2D, 0x28, 0xA0, 0x9D, 0xA3, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
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_device_name) + BLE_GENERAL_BYTE_1;
|
||||
scan_rsp_data[idx++] = BLE_ADV_LOCAL_NAME_DATA_TYPE;
|
||||
if ((idx + sizeof(g_device_name)) > scan_rsp_data_max_len) {
|
||||
return 0;
|
||||
}
|
||||
n_ret = memcpy_s(&scan_rsp_data[idx], scan_rsp_data_max_len - idx, g_device_name, sizeof(g_device_name));
|
||||
if (n_ret != EOK) {
|
||||
return 0;
|
||||
}
|
||||
idx += sizeof(g_device_name);
|
||||
return idx;
|
||||
}
|
||||
|
||||
uint8_t ble_wifi_cfg_set_adv_data(void)
|
||||
{
|
||||
errcode_t n_ret = 0;
|
||||
uint16_t scan_rsp_data_len;
|
||||
uint8_t set_scan_rsp_data[EXT_ADV_OR_SCAN_RSP_DATA_LEN] = { 0 };
|
||||
gap_ble_config_adv_data_t cfg_adv_data;
|
||||
|
||||
/* 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 = g_adv_data;
|
||||
cfg_adv_data.adv_length = HW_ADV_DATA_LEN;
|
||||
|
||||
cfg_adv_data.scan_rsp_data = set_scan_rsp_data;
|
||||
cfg_adv_data.scan_rsp_length = scan_rsp_data_len;
|
||||
|
||||
osal_printk("[uplus][debug] uplus_ble_gap_adv_data_set adv_length=%x, adv_data=",
|
||||
cfg_adv_data.adv_length);
|
||||
for (int i = 0; i < cfg_adv_data.adv_length; i++) {
|
||||
osal_printk(" %02x", cfg_adv_data.adv_data[i]);
|
||||
}
|
||||
osal_printk("\n[uplus][debug] uplus_ble_gap_adv_data_set scan_rsp_length=%x, scan_rsp_data=",
|
||||
cfg_adv_data.scan_rsp_length);
|
||||
for (int i = 0; i < cfg_adv_data.scan_rsp_length; i++) {
|
||||
osal_printk(" %02x", cfg_adv_data.scan_rsp_data[i]);
|
||||
}
|
||||
osal_printk("\n");
|
||||
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_wifi_cfg_start_adv(void)
|
||||
{
|
||||
errcode_t n_ret = 0;
|
||||
gap_ble_adv_params_t adv_para = {0};
|
||||
|
||||
ble_wifi_cfg_set_adv_data();
|
||||
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(BTH_GAP_BLE_ADV_HANDLE_DEFAULT, &adv_para);
|
||||
if (n_ret != 0) {
|
||||
return 0;
|
||||
}
|
||||
n_ret = gap_ble_start_adv(BTH_GAP_BLE_ADV_HANDLE_DEFAULT);
|
||||
if (n_ret != 0) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
367
application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_server.c
Executable file
367
application/samples/bt/ble/ble_wifi_cfg_server/src/ble_wifi_cfg_server.c
Executable file
@ -0,0 +1,367 @@
|
||||
/*
|
||||
* Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2023. All rights reserved.
|
||||
* Description: ble wifi config server sample.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "osal_addr.h"
|
||||
#include "osal_debug.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 "ble_wifi_cfg_server.h"
|
||||
|
||||
/* server app uuid for test */
|
||||
char g_app_uuid[] = {0x0, 0x0};
|
||||
|
||||
/* ble service att handle */
|
||||
uint16_t g_service_hdl;
|
||||
|
||||
/* ble chara handle trans wifi cfg info */
|
||||
uint16_t g_chara_cfg_hdl = 0;
|
||||
|
||||
/* ble chara handle trans wifi list req&resp */
|
||||
uint16_t g_chara_wifi_list_hdl = 0;
|
||||
|
||||
/* ble indication att handle */
|
||||
uint16_t g_ind_crt_att_hdl = 0;
|
||||
|
||||
/* ble notification att handle */
|
||||
uint16_t g_ntf_crt_att_hdl = 0;
|
||||
|
||||
uint16_t g_descriptor_report_hdl = 0;
|
||||
uint16_t g_descriptor_ctrl_hdl = 0;
|
||||
uint16_t g_descriptor_cfg_hdl = 0;
|
||||
|
||||
/* ble connect handle */
|
||||
uint16_t g_conn_handle = 0;
|
||||
|
||||
#define OCTET_BIT_LEN 8
|
||||
#define UUID_LEN_2 2
|
||||
#define CCC_UUID 0x2902
|
||||
|
||||
/* Service UUID */
|
||||
#define BLE_WIFI_CFG_SERVICE 0xfd5c
|
||||
/* Characteristic Control Information UUID */
|
||||
#define BLE_WIFI_CFG_CONTROL_INFO 0xfd5d
|
||||
/* Client Characteristic Configuration Wi-Fi Information UUID */
|
||||
#define BLE_WIFI_CFG_INFORMATION 0xfd5e
|
||||
/* Client AP Lists Req/Resp Configuration UUID */
|
||||
#define BLE_WIFI_CFG_REQ_REPORT 0xfd5f
|
||||
|
||||
/* Client Characteristic Configuration UUID */
|
||||
#define BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION 0x2902
|
||||
|
||||
/* Server ID */
|
||||
#define BLE_WIFI_CFG_SERVER_ID 1
|
||||
/* Wifi Configure Write Characteristic */
|
||||
#define BLE_WIFI_CFG_CHARACTER_VALUE_1 0x12
|
||||
#define BLE_WIFI_CFG_CHARACTER_VALUE_2 0x34
|
||||
#define BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_0 0X00
|
||||
#define BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_2 0X02
|
||||
|
||||
extern void set_wifi_cfg_info(uint8_t *info, uint16_t info_len);
|
||||
extern int bgwc_wifi_list_resp_send(uint16_t handle);
|
||||
|
||||
/* 将uint16的uuid数字转化为bt_uuid_t */
|
||||
void streams_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 service_uuid_compare(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_wifi_cfg_server_service_start_cbk(uint8_t server_id, uint16_t handle, errcode_t status)
|
||||
{
|
||||
osal_printk("[wifi_cfg_server] start service cbk : server: %d status: %d srv_hdl: %d\n", server_id, status,
|
||||
handle);
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_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("[wifi_cfg_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);
|
||||
|
||||
if (write_cb_para->handle == g_chara_cfg_hdl) {
|
||||
set_wifi_cfg_info(write_cb_para->value, write_cb_para->length);
|
||||
}
|
||||
if (write_cb_para->handle == g_chara_wifi_list_hdl) {
|
||||
bgwc_wifi_list_resp_send(write_cb_para->handle);
|
||||
}
|
||||
}
|
||||
|
||||
static void ble_wifi_cfg_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("[wifi_cfg_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_wifi_cfg_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_wifi_cfg_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_wifi_cfg_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_handle = conn_id;
|
||||
}
|
||||
|
||||
void ble_wifi_cfg_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_wifi_cfg_server_enable_cbk(errcode_t status)
|
||||
{
|
||||
osal_printk("enable status: %d\n", status);
|
||||
}
|
||||
|
||||
static errcode_t ble_wifi_cfg_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_wifi_cfg_server_adv_enable_cbk;
|
||||
gap_cb.stop_adv_cb = ble_wifi_cfg_server_adv_disable_cbk;
|
||||
gap_cb.conn_state_change_cb = ble_wifi_cfg_server_connect_change_cbk;
|
||||
gap_cb.ble_enable_cb = ble_wifi_cfg_server_enable_cbk;
|
||||
ret = gap_ble_register_callbacks(&gap_cb);
|
||||
if (ret != ERRCODE_BT_SUCCESS) {
|
||||
osal_printk("[wifi_cfg_server] reg gap cbk failed\r\n");
|
||||
return ERRCODE_BT_FAIL;
|
||||
}
|
||||
|
||||
service_cb.start_service_cb = ble_wifi_cfg_server_service_start_cbk;
|
||||
service_cb.read_request_cb = ble_wifi_cfg_server_receive_read_req_cbk;
|
||||
service_cb.write_request_cb = ble_wifi_cfg_server_receive_write_req_cbk;
|
||||
service_cb.mtu_changed_cb = ble_wifi_cfg_server_mtu_changed_cbk;
|
||||
ret = gatts_register_callbacks(&service_cb);
|
||||
if (ret != ERRCODE_BT_SUCCESS) {
|
||||
osal_printk("[wifi_cfg_server] reg service cbk failed\r\n");
|
||||
return ERRCODE_BT_FAIL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wifi_cfg_add_character_control_point(uint8_t server_id, uint16_t srvc_handle)
|
||||
{
|
||||
gatts_add_chara_info_t character = { 0 };
|
||||
gatts_add_character_result_t add_character_result = { 0 };
|
||||
uint8_t character_value[] = {BLE_WIFI_CFG_CHARACTER_VALUE_1, BLE_WIFI_CFG_CHARACTER_VALUE_2};
|
||||
uint8_t ccc_value_indicate[UUID_LEN_2] = {BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_2,
|
||||
BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_0};
|
||||
gatts_add_desc_info_t ccc = { { UUID_LEN_2, { 0 } },
|
||||
GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE,
|
||||
UUID_LEN_2,
|
||||
NULL };
|
||||
streams_data_to_uuid(BLE_WIFI_CFG_CONTROL_INFO, &character.chara_uuid);
|
||||
character.properties = BLE_WIFI_CFG_PROPERTIES;
|
||||
character.permissions = 0;
|
||||
character.value_len = sizeof(character_value);
|
||||
character.value = character_value;
|
||||
gatts_add_characteristic_sync(server_id, srvc_handle, &character, &add_character_result);
|
||||
|
||||
ccc.desc_uuid.uuid[0] = BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION >> 8; /* 8: octet bit num */
|
||||
ccc.desc_uuid.uuid[1] = (uint8_t)BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION;
|
||||
ccc.value = ccc_value_indicate;
|
||||
gatts_add_descriptor_sync(server_id, srvc_handle, &ccc, &g_descriptor_ctrl_hdl);
|
||||
}
|
||||
|
||||
static void wifi_cfg_add_character_cfg_info(uint8_t server_id, uint16_t srvc_handle)
|
||||
{
|
||||
gatts_add_chara_info_t character = { 0 };
|
||||
gatts_add_character_result_t add_character_result = { 0 };
|
||||
uint8_t character_value[] = {BLE_WIFI_CFG_CHARACTER_VALUE_1, BLE_WIFI_CFG_CHARACTER_VALUE_2};
|
||||
uint8_t ccc_value_indicate[UUID_LEN_2] = {BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_2,
|
||||
BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_0};
|
||||
gatts_add_desc_info_t ccc = { { UUID_LEN_2, { 0 } },
|
||||
GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE,
|
||||
UUID_LEN_2,
|
||||
NULL };
|
||||
|
||||
streams_data_to_uuid(BLE_WIFI_CFG_INFORMATION, &character.chara_uuid);
|
||||
character.properties = UUID_SERVER_IND_PROPERTIES;
|
||||
character.permissions = 0;
|
||||
character.value_len = sizeof(character_value);
|
||||
character.value = character_value;
|
||||
gatts_add_characteristic_sync(server_id, srvc_handle, &character, &add_character_result);
|
||||
g_chara_cfg_hdl = add_character_result.value_handle;
|
||||
|
||||
ccc.desc_uuid.uuid[0] = BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION >> 8; /* 8: octet bit num */
|
||||
ccc.desc_uuid.uuid[1] = (uint8_t)BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION;
|
||||
ccc.value = ccc_value_indicate;
|
||||
gatts_add_descriptor_sync(server_id, srvc_handle, &ccc, &g_descriptor_cfg_hdl);
|
||||
}
|
||||
|
||||
static void wifi_cfg_add_character_req_report(uint8_t server_id, uint16_t srvc_handle)
|
||||
{
|
||||
gatts_add_chara_info_t character = { 0 };
|
||||
gatts_add_character_result_t add_character_result = { 0 };
|
||||
uint8_t character_value[] = {BLE_WIFI_CFG_CHARACTER_VALUE_1, BLE_WIFI_CFG_CHARACTER_VALUE_2};
|
||||
uint8_t ccc_value_indicate[UUID_LEN_2] = {BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_2,
|
||||
BLE_WIFI_CFG_CHARACTER_VALUE_INDICATE_0};
|
||||
gatts_add_desc_info_t ccc = { { UUID_LEN_2, { 0 } },
|
||||
GATT_ATTRIBUTE_PERMISSION_READ | GATT_ATTRIBUTE_PERMISSION_WRITE,
|
||||
UUID_LEN_2,
|
||||
NULL };
|
||||
streams_data_to_uuid(BLE_WIFI_CFG_REQ_REPORT, &character.chara_uuid);
|
||||
character.properties = BLE_WIFI_CFG_PROPERTIES;
|
||||
character.permissions = 0;
|
||||
character.value_len = sizeof(character_value);
|
||||
character.value = character_value;
|
||||
gatts_add_characteristic_sync(server_id, srvc_handle, &character, &add_character_result);
|
||||
g_chara_wifi_list_hdl = add_character_result.value_handle;
|
||||
|
||||
ccc.desc_uuid.uuid[0] = BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION >> 8; /* 8: octet bit num */
|
||||
ccc.desc_uuid.uuid[1] = (uint8_t)BLE_UUID_CLIENT_CHARACTERISTIC_CONFIGURATION;
|
||||
ccc.value = ccc_value_indicate;
|
||||
gatts_add_descriptor_sync(server_id, srvc_handle, &ccc, &g_descriptor_report_hdl);
|
||||
}
|
||||
|
||||
errcode_t wifi_cfg_server_service(void)
|
||||
{
|
||||
errcode_t ret;
|
||||
osal_printk("[wifi_cfg_server] ble uuid add service in\r\n");
|
||||
|
||||
/* Add Wifi Configure Service */
|
||||
bt_uuid_t service_uuid = { 0 };
|
||||
streams_data_to_uuid(BLE_WIFI_CFG_SERVICE, &service_uuid);
|
||||
ret = gatts_add_service_sync(BLE_WIFI_CFG_SERVER_ID, &service_uuid, true, &g_service_hdl);
|
||||
if (ret != ERRCODE_BT_SUCCESS) {
|
||||
osal_printk("[wifi_cfg_server_service] reg service failed, ret=%x\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Configure Trans Control Info Characteristic */
|
||||
wifi_cfg_add_character_control_point(BLE_WIFI_CFG_SERVER_ID, g_service_hdl);
|
||||
/* Configure Trans Wi-Fi Info Characteristic */
|
||||
wifi_cfg_add_character_cfg_info(BLE_WIFI_CFG_SERVER_ID, g_service_hdl);
|
||||
/* Configure Trans Wi-Fi Req/Resp info Characteristic */
|
||||
wifi_cfg_add_character_req_report(BLE_WIFI_CFG_SERVER_ID, g_service_hdl);
|
||||
|
||||
gatts_start_service(BLE_WIFI_CFG_SERVER_ID, g_service_hdl);
|
||||
osal_printk("[wifi_cfg_server] ble uuid add service out\r\n");
|
||||
return ERRCODE_BT_SUCCESS;
|
||||
}
|
||||
|
||||
errcode_t ble_wifi_gatts_register_server(void)
|
||||
{
|
||||
uint8_t server_handle;
|
||||
bt_uuid_t app_uuid = { 0 };
|
||||
app_uuid.uuid_len = sizeof(g_app_uuid);
|
||||
if (memcpy_s(app_uuid.uuid, app_uuid.uuid_len, g_app_uuid, sizeof(g_app_uuid)) != EOK) {
|
||||
return ERRCODE_BT_FAIL;
|
||||
}
|
||||
|
||||
osal_printk("[wifi_cfg_server] gatts_register_server begin\r\n");
|
||||
return gatts_register_server(&app_uuid, &server_handle);
|
||||
}
|
||||
|
||||
/* 初始化ble wifi cfg server service */
|
||||
errcode_t ble_wifi_cfg_server_init(void)
|
||||
{
|
||||
errcode_t ret = ERRCODE_BT_SUCCESS;
|
||||
ret |= enable_ble();
|
||||
ret |= ble_wifi_cfg_server_register_callbacks();
|
||||
ret |= ble_wifi_gatts_register_server();
|
||||
ret |= wifi_cfg_server_service();
|
||||
if (ret != ERRCODE_BT_SUCCESS) {
|
||||
osal_printk("[wifi_cfg_server] init fail.\r\n");
|
||||
} else {
|
||||
osal_printk("[wifi_cfg_server] init ok\r\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* device通过uuid向host发送数据:report */
|
||||
errcode_t ble_wifi_cfg_server_send_report_by_uuid(const uint8_t *data, uint32_t len)
|
||||
{
|
||||
gatts_ntf_ind_by_uuid_t param = { 0 };
|
||||
uint16_t conn_id = g_conn_handle;
|
||||
param.start_handle = 0;
|
||||
param.end_handle = 0xffff;
|
||||
streams_data_to_uuid(BLE_WIFI_CFG_CONTROL_INFO, ¶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(BLE_WIFI_CFG_SERVER_ID, conn_id, ¶m);
|
||||
osal_vfree(param.value);
|
||||
return ERRCODE_BT_SUCCESS;
|
||||
}
|
||||
|
||||
/* device通过handle向host发送数据:report */
|
||||
errcode_t ble_wifi_cfg_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_handle;
|
||||
|
||||
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(BLE_WIFI_CFG_SERVER_ID, conn_id, ¶m);
|
||||
osal_vfree(param.value);
|
||||
return ERRCODE_BT_SUCCESS;
|
||||
}
|
Reference in New Issue
Block a user