1 Star 0 Fork 1

pargo/ld_ble_hal

forked from tangly/ld_ble_hal 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
bt_gatt_server.c 20.16 KB
一键复制 编辑 原始数据 按行查看 历史
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
/*
* Copyright (c) 2018-2022 Allwinner Technology Co. Ltd. All rights reserved.
* Author: BT Team
* Date: 2022.03.12
* Description: gatt-server test demo.
*/
#include <bt_manager.h>
#include <errno.h>
#include <fcntl.h>
#include <fcntl.h>
#include <getopt.h>
#include <poll.h>
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/signalfd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "bt_dev_list.h"
#include "bt_hal.h"
#include "bt_log.h"
#define SERVICE_HANDLE_START 11
static uint16_t service_handle;
static uint16_t service_handle_char;
static uint16_t service_handle_desc;
static uint8_t server_is_connected = 0;
static int is_gatt_testcase_server = 0;
char device_name[28] = "aw-ble-test-007";
static btmg_adv_data_t le_adv_data = {0};
static btmg_scan_rsp_data_t rsp_data = {0};
static uint8_t le_adv_status = 0;
static btmg_adv_data_t nonconn_le_adv_data = {0};
static btmg_scan_rsp_data_t nonconn_rsp_data = {0};
static uint8_t nonconn_le_adv_status = 0;
static int char_handle = 0;
static int dev_name_char_handle = 0;
static int notify_handle = 0;
static int indicate_handle = 0;
static ms_hal_ble_attrib_callback_t server_callback[64] = {NULL};
static void bt_test_gatt_connection_cb(char *addr,
gatts_connection_event_t event,
int err)
{
if (event == BT_GATT_CONNECTION)
{
printf("gatt server Connected: %s.\n", addr);
ms_hal_ble_stack_msg_t msg;
bzero(&msg, sizeof(msg));
msg.event_type = MS_HAL_BLE_STACK_EVENT_CONNECTION_REPORT;
msg.param.conn_hdl = SERVER_HANDLE_ID;
msg.param.connection_msg.addr;
msg.param.connection_msg.role = 1;
server_is_connected = 1;
ble_gatt_data_t device = {0};
if (strlen(addr) == 17 && addr[2] == ':')
{
for (int i = 0; i < 6; i++)
{
char buf[3] = {0};
memcpy(buf, &addr[i * 3], 2);
device.addr[i] = strtoull(buf, NULL, 16);
}
}
memcpy(msg.param.connection_msg.addr, device.addr, 6);
if (ms_hal_ble_stack_callback)
ms_hal_ble_stack_callback(msg);
device.conn_id = SERVER_HANDLE_ID;
device.is_slave = 1;
add_device_to_list(device);
}
else if (event == BT_GATT_DISCONNECT)
{
printf("gatt server Disconnected: %s (reason UNKONW)\n", addr);
server_is_connected = 0;
del_device_to_list(SERVER_HANDLE_ID);
ms_hal_ble_stack_msg_t msg;
bzero(&msg, sizeof(msg));
msg.event_type = MS_HAL_BLE_STACK_EVENT_DISCONNECTED;
msg.param.conn_hdl = SERVER_HANDLE_ID;
if (ms_hal_ble_stack_callback)
ms_hal_ble_stack_callback(msg);
}
else
{
printf("gatt server event unkown.\n");
}
}
static void bt_test_gatt_add_service_cb(gatts_add_svc_msg_t *msg)
{
if (msg != NULL)
{
service_handle = msg->svc_handle;
printf("add service handle: %d, handle max number: %d\n", service_handle,
msg->handle_num);
}
}
static void bt_test_gatts_add_char_cb(gatts_add_char_msg_t *msg)
{
if (msg != NULL)
{
service_handle_char = msg->char_handle;
printf("add char,uuid: %s,chr handle is %d\n", msg->uuid, msg->char_handle);
}
}
static void bt_test_gatt_add_desc_cb(gatts_add_desc_msg_t *msg)
{
if (msg != NULL)
{
service_handle_desc = msg->desc_handle;
printf("desc handle is %d\n", msg->desc_handle);
}
}
static void bt_test_gatt_char_read_request_cb(gatts_char_read_req_t *chr_read)
{
char value[1];
static unsigned char count = 0;
char dev_name[] = "aw_ble_test_1149";
printf("trans_id:%d,attr_handle:%d,offset:%d\n", chr_read->trans_id,
chr_read->attr_handle, chr_read->offset);
// for (int k = 0; k < sizeof(server_callback) / sizeof(ms_hal_ble_attrib_callback_t); k++)
// {
// if (server_callback[k].read_cb)
// {
// server_callback[k].read_cb(char_write->value, char_write->value_len);
// }
// }
}
static void
bt_test_gatts_send_indication_cb(gatts_send_indication_t *send_ind)
{
ms_hal_ble_stack_msg_t msg;
bzero(&msg, sizeof(msg));
msg.event_type = MS_HAL_BLE_STACK_EVENT_CMP_INDICATE;
msg.param.conn_hdl = SERVER_HANDLE_ID;
if (ms_hal_ble_stack_callback)
ms_hal_ble_stack_callback(msg);
}
static void bt_test_gatt_char_write_request_cb(gatts_char_write_req_t *char_write)
{
static unsigned char data_value[1] = {0};
int ret = 0;
if (char_write)
{
printf("\033[1;34m attr_handle: %d,tran_id: %d \033[0m\n", char_write->attr_handle,
char_write->trans_id);
for(int i =0; i < char_write->value_len; i++){
printf("\033[1;34m %x ", char_write->value[i]);
}
printf("\033[0m\n");
for (int k = 0; k < sizeof(server_callback) / sizeof(ms_hal_ble_attrib_callback_t); k++)
{
if (server_callback[k].write_cb)
{
// char value[64] = {0};
// if(char_write->value_len == 2){
// value[0] = char_write->value[1];
// value[1] = char_write->value[0];
// server_callback[k].write_cb(value, char_write->value_len);
// }else
server_callback[k].write_cb(char_write->value, char_write->value_len);
}
}
}
printf("char_write->need_rsp: %d\n", char_write->need_rsp);
if (char_write->need_rsp)
{
gatts_write_rsp_t data;
data.trans_id = char_write->trans_id;
data.attr_handle = char_write->attr_handle;
data.state = BT_GATT_SUCCESS;
ret = bt_manager_gatt_server_send_write_response(&data);
if (ret != 0)
printf("send write response failed!\n");
else
printf("send write response success!\n");
}
}
ms_hal_result_t ms_hal_ble_stack_stop_service_clean(void)
{
bzero(server_callback, sizeof(server_callback));
}
static void
bt_test_gatt_desc_read_requset_cb(gatts_desc_read_req_t *desc_read)
{
char value[1];
static unsigned char count = 0;
printf("trans_id:%d,attr_handle:%d,offset:%d\n", desc_read->trans_id,
desc_read->attr_handle, desc_read->offset);
if (desc_read)
{
gatts_send_read_rsp_t data;
data.trans_id = desc_read->trans_id;
data.attr_handle = desc_read->attr_handle;
data.status = 0x0b;
data.auth_req = 0x00;
value[0] = count;
data.value = value;
data.value_len = 1;
bt_manager_gatt_server_send_read_response(&data);
count++;
}
}
static void
bt_test_gatt_desc_write_request_cb(gatts_desc_write_req_t *desc_write)
{
int ret = 0;
printf("enter\n");
printf("desc_write->need_rsp: %d\n", desc_write->need_rsp);
printf("desc_write->attr_handle: %d\n", desc_write->attr_handle);
if (desc_write->need_rsp)
{
gatts_write_rsp_t data;
data.trans_id = desc_write->trans_id;
data.attr_handle = desc_write->attr_handle;
data.state = BT_GATT_SUCCESS;
ret = bt_manager_gatt_server_send_write_response(&data);
if (ret != 0)
printf("send write response failed!\n");
else
printf("send write response success!\n");
}
}
static void set_adv_param(void)
{
btmg_le_advertising_parameters_t adv_params;
adv_params.min_interval = 0x0020;
adv_params.max_interval = 0x01E0; /*range from 0x0020 to 0x4000*/
adv_params.own_addr_type = BTMG_LE_RANDOM_ADDRESS;
adv_params.adv_type = BTMG_LE_ADV_IND; /*ADV_IND*/
adv_params.chan_map =
BTMG_LE_ADV_CHANNEL_ALL; /*0x07, *bit0:channel 37, bit1:
channel 38, bit2: channel39*/
adv_params.filter = BTMG_LE_PROCESS_ALL_REQ;
bt_manager_le_set_adv_param(&adv_params);
}
static int le_set_adv_data(const char *ble_name, uint16_t uuid)
{
int dd;
uint8_t manuf_len;
int index;
char advdata[31] = {0};
char uuid_buf[5] = {0};
int advdata_len = 0;
index = 0;
advdata[index] = 0x02; /* flag len */
advdata[index + 1] = 0x01; /* type for flag */
advdata[index + 2] = 0x1A; // 0x05
index += advdata[index] + 1;
advdata[index] = strlen(ble_name) + 1; /* name len */
advdata[index + 1] = 0x09; /* type for local name */
int name_len;
name_len = strlen(ble_name);
strcpy(&(advdata[index + 2]), ble_name);
index += advdata[index] + 1;
advdata[index] = 0x03; /* uuid len */
advdata[index + 1] = 0x03; /* type for complete list of 16-bit uuid */
advdata[index + 2] = (char)(uuid & 0xFF);
advdata[index + 3] = (char)((uuid >> 8) & 0xFF);
index += advdata[index] + 1;
btmg_adv_data_t adv;
adv.data_len = index;
memcpy(adv.data, advdata, 31);
BTMG_INFO("ble name = [%s]", ble_name);
return bt_manager_le_set_adv_data(&adv);
}
void bt_gatt_server_register_callback(btmg_callback_t *cb)
{
cb->btmg_gatt_server_cb.gatts_add_svc_cb = bt_test_gatt_add_service_cb;
cb->btmg_gatt_server_cb.gatts_add_char_cb = bt_test_gatts_add_char_cb;
cb->btmg_gatt_server_cb.gatts_add_desc_cb = bt_test_gatt_add_desc_cb;
cb->btmg_gatt_server_cb.gatts_connection_event_cb = bt_test_gatt_connection_cb;
cb->btmg_gatt_server_cb.gatts_char_read_req_cb = bt_test_gatt_char_read_request_cb;
cb->btmg_gatt_server_cb.gatts_char_write_req_cb = bt_test_gatt_char_write_request_cb;
cb->btmg_gatt_server_cb.gatts_desc_read_req_cb = bt_test_gatt_desc_read_requset_cb;
cb->btmg_gatt_server_cb.gatts_desc_write_req_cb = bt_test_gatt_desc_write_request_cb;
cb->btmg_gatt_server_cb.gatts_send_indication_cb = bt_test_gatts_send_indication_cb;
}
ms_hal_result_t ble_gatt_service_add(ms_hal_ble_service_t *service)
{
if (!service || service->attr_count <= 0)
{
return MS_HAL_RESULT_ERROR;
}
for (int i = 0; i < service->attr_count; i++)
{
printf("\033[1;34m chenql%d %d\033[0m\n", __LINE__,service->attrs[i].att_type);
switch (service->attrs[i].att_type)
{
case ENUM_MS_HAL_BLE_ATTRIB_TYPE_SERVICE:
{
gatts_add_svc_t svc;
bzero(&svc, sizeof(gatts_add_svc_t));
svc.number = service->attr_count + SERVICE_HANDLE_START;
char uuid[128] = {0};
for (int j = 0; j < service->attrs[i].service_para.uuid_size; j++)
{
char data[16] = {0};
if( j == 4 || j == 6 || j == 8 || j == 10){
strcat(uuid, "-");
}
sprintf(data, "%02x",service->attrs[i].service_para.uuid[service->attrs[i].service_para.uuid_size-1-j]);
strcat(uuid, data);
}
svc.uuid = uuid;
svc.primary = true;
bt_manager_gatt_server_create_service(&svc);
service->attrs[i].handle = service_handle;
}
break;
case ENUM_MS_HAL_BLE_ATTRIB_TYPE_CHAR:
{
gatts_add_char_t chr1;
bzero(&chr1, sizeof(gatts_add_char_t));
chr1.permissions = service->attrs[i].charact_para.permission;
chr1.properties = service->attrs[i].charact_para.property;
int k = 0;
for (; k < sizeof(server_callback) / sizeof(ms_hal_ble_attrib_callback_t); k++)
{
if (server_callback[k].null_cb == NULL &&
server_callback[k].read_cb == NULL &&
server_callback[k].write_cb == NULL)
{
break;
}
}
server_callback[k] = service->attrs[i].charact_para.callback;
chr1.svc_handle = service_handle;
char uuid[128] = {0};
for (int j = 0; j < service->attrs[i].charact_para.uuid_size; j++)
{
char data[16] = {0};
if( j == 4 || j == 6 || j == 8 || j == 10){
strcat(uuid, "-");
}
sprintf(data, "%02x",service->attrs[i].charact_para.uuid[service->attrs[i].charact_para.uuid_size-1-j]);
strcat(uuid, data);
}
chr1.uuid = uuid;
bt_manager_gatt_server_add_characteristic(&chr1);
service->attrs[i].handle = service_handle_char;
}
break;
case ENUM_MS_HAL_BLE_ATTRIB_TYPE_CHAR_USER_DESCR:
case ENUM_MS_HAL_BLE_ATTRIB_TYPE_CHAR_CLIENT_CONFIG:
{
gatts_add_desc_t desc1;
bzero(&desc1, sizeof(gatts_add_desc_t));
desc1.permissions = service->attrs[i].user_desc_para.permission;
char uuid[5] = {0};
sprintf(uuid, "%x", service->attrs[i].att_type);
desc1.uuid = uuid;
desc1.svc_handle = service_handle;
bt_manager_gatt_server_add_descriptor(&desc1);
service->attrs[i].handle = service_handle_desc;
}
break;
}
}
gatts_star_svc_t start_svc;
bt_manager_gatt_server_start_service(&start_svc);
return MS_HAL_RESULT_SUCCESS;
}
ms_hal_result_t ble_gatt_data_send(uint16_t conn_hdl,
ms_hal_ble_gatts_attr_handle_t *handle,
uint8_t *data, uint16_t len)
{
printf("\033[1;34m chenql%d %d \033[0m\n", __LINE__,*handle);
gatts_indication_data_t pData = {0};
pData.attr_handle = *handle;
pData.value = data;
pData.value_len = len;
printf("\033[1;34m chenql%d %d %d %d \033[0m\n", __LINE__,*handle,data,len);
return bt_manager_gatt_server_send_indication(&pData);
}
ms_hal_result_t set_ble_name(char *device_name, int len)
{
char ble_device_name[4096] = {0};
memcpy(ble_device_name, device_name, len);
if (nonconn_le_adv_status)
bt_manager_le_enable_adv(false);
ms_hal_result_t ret = le_set_adv_data(ble_device_name, 0);
if (ret != 0)
{
ret = MS_HAL_RESULT_ERROR;
}
if (nonconn_le_adv_status)
bt_manager_le_enable_adv(true);
return ret;
}
uint8_t ble_adv_status(uint16_t handle)
{
return le_adv_status;
;
}
uint8_t nonconn_ble_adv_status(uint16_t handle)
{
return nonconn_le_adv_status;
;
}
ms_hal_result_t ble_legacy_adv_stop(uint16_t handle)
{
if (handle == LE_ADV_HANDLE)
{
if (bt_manager_le_enable_adv(false) == 0)
{
le_adv_status = 0;
return MS_HAL_RESULT_SUCCESS;
}
else
{
return MS_HAL_RESULT_ERROR;
}
}
else if (handle == NONNECT_LE_ADV_HANDLE)
{
if (bt_manager_le_enable_adv(false) == 0)
{
nonconn_le_adv_status = 0;
return MS_HAL_RESULT_SUCCESS;
}
else
{
return MS_HAL_RESULT_ERROR;
}
}
else
{
return MS_HAL_RESULT_ERROR;
}
}
ms_hal_result_t nonconn_ble_legacy_adv_stop(uint16_t handle)
{
if (handle == LE_ADV_HANDLE)
{
if (bt_manager_le_enable_adv(false) == 0)
{
le_adv_status = 0;
return MS_HAL_RESULT_SUCCESS;
}
else
{
return MS_HAL_RESULT_ERROR;
}
}
else if (handle == NONNECT_LE_ADV_HANDLE)
{
if (bt_manager_le_enable_adv(false) == 0)
{
nonconn_le_adv_status = 0;
return MS_HAL_RESULT_SUCCESS;
}
else
{
return MS_HAL_RESULT_ERROR;
}
}
else
{
return MS_HAL_RESULT_ERROR;
}
}
uint16_t ble_legacy_adv_start(ms_hal_ble_gap_adv_params *param,
ms_hal_ble_gap_adv_data *adv_data,
uint8_t enable)
{
if (nonconn_le_adv_status)
bt_manager_le_enable_adv(false);
if (param)
{
btmg_le_advertising_parameters_t adv_params;
bzero(&adv_params, sizeof(adv_params));
adv_params.min_interval = param->adv_intv_min;
adv_params.max_interval = param->adv_intv_max;
/*range from 0x0020 to 0x4000*/
adv_params.filter = BTMG_LE_PROCESS_ALL_REQ;
switch (param->adv_type)
{
case MS_HAL_BLE_ADV_TPYE_IND:
adv_params.adv_type = BTMG_LE_ADV_IND;
break;
case MS_HAL_BLE_ADV_TPYE_DIRECT_IND:
adv_params.adv_type = BTMG_LE_ADV_DIRECT_LOW_IND;
break;
case MS_HAL_BLE_ADV_TPYE_NONCONN_IND:
adv_params.adv_type = BTMG_LE_ADV_NONCONN_IND;
break;
case MS_HAL_BLE_ADV_TPYE_SCAN_IND:
adv_params.adv_type = BTMG_LE_ADV_SCAN_IND;
break;
case MS_HAL_BLE_ADV_TPYE_EXT_IND:
case MS_HAL_BLE_AUX_TPYE_ADV_IND:
case MS_HAL_BLE_AUX_TPYE_SYNC_IND:
case MS_HAL_BLE_AUX_TPYE_CHAIN_IND:
adv_params.adv_type = BTMG_LE_ADV_IND;
break;
}
adv_params.own_addr_type = BTMG_LE_RANDOM_ADDRESS;
adv_params.chan_map = BTMG_LE_ADV_CHANNEL_ALL; /*0x07, *bit0:channel 37,
bit1: channel 38, bit2:
channel39*/
bt_manager_le_set_adv_param(&adv_params);
bt_manager_le_set_random_address();
}
if (adv_data->adv_len > 0 && adv_data->adv_data)
{
bzero(&le_adv_data, sizeof(le_adv_data));
memcpy(le_adv_data.data, adv_data->adv_data, adv_data->adv_len);
le_adv_data.data_len = adv_data->adv_len;
bt_manager_le_set_adv_data(&le_adv_data);
}
if (adv_data->rsp_len > 0 && adv_data->rsp_data)
{
bzero(&rsp_data, sizeof(rsp_data));
memcpy(rsp_data.data, adv_data->rsp_data, adv_data->rsp_len);
rsp_data.data_len = adv_data->rsp_len;
bt_manager_le_set_scan_rsp_data(&rsp_data);
}
if (enable)
{
if (bt_manager_le_enable_adv(true) == 0)
{
le_adv_status = 1;
}
else
{
return -1;
}
}
return LE_ADV_HANDLE;
}
uint16_t nonconn_ble_legacy_adv_start(ms_hal_ble_gap_adv_params *param, ms_hal_ble_gap_adv_data *adv_data,
uint8_t enable)
{
if (nonconn_le_adv_status)
bt_manager_le_enable_adv(false);
btmg_le_advertising_parameters_t adv_params;
bzero(&adv_params, sizeof(adv_params));
adv_params.min_interval = param->adv_intv_min;
adv_params.max_interval = param->adv_intv_max; /*range from 0x0020 to 0x4000*/
adv_params.adv_type = BTMG_LE_ADV_NONCONN_IND;
switch (param->adv_type)
{
case MS_HAL_BLE_ADV_TPYE_IND:
adv_params.filter = BTMG_LE_PROCESS_ALL_REQ;
break;
case MS_HAL_BLE_ADV_TPYE_DIRECT_IND:
adv_params.filter = BTMG_LE_PROCESS_CONN_REQ;
break;
case MS_HAL_BLE_ADV_TPYE_NONCONN_IND:
break;
case MS_HAL_BLE_ADV_TPYE_SCAN_IND:
adv_params.filter = BTMG_LE_PROCESS_SCAN_REQ;
break;
case MS_HAL_BLE_ADV_TPYE_EXT_IND:
break;
case MS_HAL_BLE_AUX_TPYE_ADV_IND:
break;
case MS_HAL_BLE_AUX_TPYE_SYNC_IND:
break;
case MS_HAL_BLE_AUX_TPYE_CHAIN_IND:
break;
}
adv_params.own_addr_type = BTMG_LE_RANDOM_ADDRESS;
adv_params.chan_map =
BTMG_LE_ADV_CHANNEL_ALL; /*0x07, *bit0:channel 37, bit1:
channel 38, bit2: channel39*/
bt_manager_le_set_adv_param(&adv_params);
bt_manager_le_set_random_address();
if (adv_data->adv_len > 0 && adv_data->adv_data)
{
bzero(&nonconn_le_adv_data, sizeof(nonconn_le_adv_data));
memcpy(nonconn_le_adv_data.data, adv_data->adv_data, adv_data->adv_len);
nonconn_le_adv_data.data_len = adv_data->adv_len;
bt_manager_le_set_adv_data(&nonconn_le_adv_data);
}
if (adv_data->rsp_len > 0 && adv_data->rsp_data)
{
bzero(&nonconn_rsp_data, sizeof(nonconn_rsp_data));
memcpy(nonconn_rsp_data.data, adv_data->rsp_data, adv_data->rsp_len);
nonconn_rsp_data.data_len = adv_data->rsp_len;
bt_manager_le_set_scan_rsp_data(&nonconn_rsp_data);
}
if (enable)
{
if (bt_manager_le_enable_adv(true) == 0)
{
nonconn_le_adv_status = 1;
}
else
{
return -1;
}
}
return NONNECT_LE_ADV_HANDLE;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/pargo/ld_ble_hal.git
git@gitee.com:pargo/ld_ble_hal.git
pargo
ld_ble_hal
ld_ble_hal
master

搜索帮助