
分类
其他
杰理AC63_BT_SDK 学习笔记 (11 Central)
简介
基于杰理官方的通用蓝牙软件包 fw-AC63_BT_SDK-master,学习和了解AC695/6系列芯片的功能和应用。主要从SPP_BLE、MASH、HID三个方面学习和了解相关的协议和应用。
简介: 基于杰理官方的通用蓝牙软件包 fw-AC63_BT_SDK-master,学习和了解AC695/6系列芯片的功能和应用。主要从SPP_BLE、MASH、HID三个方面学习和了解相关的协议和应用。
.filter_pdu_bitmap = 0,
.create_conn_mode = BIT(CLI_CREAT_BY_NAME),
.compare_data_len = sizeof(cetl_test_remoter_name2) - 1,
.compare_data = cetl_test_remoter_name2,
.filter_pdu_bitmap = 0,
功能:按设备名称匹配,匹配到 "AC897N_MX(BLE)" 或 "AC632N_MX(BLE)" 时自动连接。
- 搜索匹配设备会发聩事件处理
case GATT_COMM_EVENT_SCAN_DEV_MATCH:
log_info("match_dev:addr_type= %d\n", packet[0]);
put_buf(&packet[1], 6);
if (packet[8] == 2) log_info("is TEST_BOX\n");
client_match_cfg_t *match_cfg = ext_param;
if (match_cfg)
{ log_info("match_mode: %d\n", match_cfg->create_conn_mode);
if (match_cfg->compare_data_len)
put_buf(match_cfg->compare_data, match_cfg->compare_data_len);
}
break;
- 配置连上后搜索的uuid
*//指定搜索uuid*
static const target_uuid_t jl_cetl_search_uuid_table[] = {
*// for uuid16*
*// PRIMARY_SERVICE, ae30*
*// CHARACTERISTIC, ae01, WRITE_WITHOUT_RESPONSE | DYNAMIC,*
*// CHARACTERISTIC, ae02, NOTIFY,*
.services_uuid16 = 0xae30,
.characteristic_uuid16 = 0xae01,
.opt_type = ATT_PROPERTY_WRITE_WITHOUT_RESPONSE,
.services_uuid16 = 0xae30,
.characteristic_uuid16 = 0xae02,
.opt_type = ATT_PROPERTY_NOTIFY,
- 查找到匹配的UUID和handle,处理事件,并且可以记录操作handle。
case GATT_COMM_EVENT_GATT_SEARCH_MATCH_UUID:
opt_handle_t *opt_hdl = packet;
log_info("match:server_uuid= %04x,charactc_uuid= %04x,value_handle= %04x\n",
opt_hdl->search_uuid->services_uuid16,
opt_hdl->search_uuid->characteristic_uuid16,
opt_hdl->value_handle);
#if cetl_TEST_WRITE_SEND_DATA
*//for test*
if (opt_hdl->search_uuid->characteristic_uuid16 == 0xae01)
cetl_ble_client_write_handle = opt_hdl->value_handle;
#endif
break;
- 配置扫描和连接参数:扫描参数以625ms为单位,设置如下所示:
#define SET_SCAN_TYPE SCAN_ACTIVE // 主动扫描(可获取扫描响应)
#define SET_SCAN_INTERVAL ADV_SCAN_MS(24) // 扫描周期 15ms
#define SET_SCAN_WINDOW ADV_SCAN_MS(8) // 扫描窗口 5ms
// ATT MTU大小 (最大传输单元)
#define ATT_LOCAL_MTU_SIZE (517) // 517字节
#define ATT_SEND_CBUF_SIZE (512 * 2) // 发送缓冲区大小
- 连接参数interval是以25ms为单位,timeout是以10ms为单位,如下图:
#define SET_CONN_INTERVAL (BASE_INTERVAL_MIN*4) // 连接间隔 30ms
#define SET_CONN_LATENCY 0 // 从设备延迟
#define SET_CONN_TIMEOUT 400 // 连接超时 4秒
// 连接建立超时
#define SET_CREAT_CONN_TIMEOUT 8000 // 8秒
- 以上两组参数请慎重修改,必须按照蓝牙的协议规范来定义修改。
- 核心函数分析
- cetl_client_init() - 初始化
void cetl_client_init(void)
log_info("%s", __FUNCTION__);
// 如果使用本地名称匹配
#if MATCH_CONFIG_NAME
cetl_match_device_table[0].compare_data = bt_get_local_name();
cetl_match_device_table[0].compare_data_len = strlen(bt_get_local_name());
#endif
// 设置搜索配置
ble_gatt_client_set_search_config(&cetl_client_search_config);
// 设置扫描配置
cetl_scan_conn_config_set();
// 启动数据发送测试定时器
#if CETL_TEST_WRITE_SEND_DATA
if (TEST_TIMER_MS < 10)
sys_s_hi_timer_add(0, cetl_client_test_write, TEST_TIMER_MS);
else
sys_timer_add(0, cetl_client_test_write, TEST_TIMER_MS);
#endif
- 2 cetl_client_event_packet_handler() - 事件处理
这是最核心的回调函数,处理所有GATT客户端事件:
static int cetl_client_event_packet_handler(int event, u8 *packet, u16 size, u8 *ext_param)
switch (event)
// 1. 收到数据报告 (Notify/Indicate/Read)
case GATT_COMM_EVENT_GATT_DATA_REPORT: {
att_data_report_t *report_data = (void *)packet;
// 打印接收数据
log_info("data_report:hdl=%04x,pk_type=%02x,size=%d",report_data->conn_handle,
report_data->packet_type,report_data->blob_length);
put_buf(report_data->blob, report_data->blob_length);
// 统计接收速率
i = ble_comm_dev_get_index(report_data->conn_handle, SUPPORT_MAX_GATT_CLIENT);
if (i != INVAIL_INDEX)
recieve_test_count[i] += report_data->blob_length;
break;
// 2. 扫描到广播数据 (未匹配)
case GATT_COMM_EVENT_SCAN_ADV_REPORT:
putchar('V'); // 打印 'V' 表示收到广播
break;
// 3. 连接完成
case GATT_COMM_EVENT_CONNECTION_COMPLETE:
cetl_con_handle = little_endian_read_16(packet, 0);
log_info("connection_handle:%04x, rssi= %d", cetl_con_handle,
ble_vendor_get_peer_rssi(cetl_con_handle));
break;
// 4. 断开连接
case GATT_COMM_EVENT_DISCONNECT_COMPLETE:
log_info("disconnect_handle:%04x,reason= %02x",
little_endian_read_16(packet, 0), packet[2]);
cetl_con_handle = 0;
// 清除搜索完成标志
i = ble_comm_dev_get_index(..., SUPPORT_MAX_GATT_CLIENT);
if (i != INVAIL_INDEX)
search_profile_complete_flag[i] = 0;
break;
// 5. 加密完成 (配对)
case GATT_COMM_EVENT_ENCRYPTION_CHANGE:
log_info("ENCRYPTION_CHANGE:handle=%04x,state=%d,process=%d",
little_endian_read_16(packet, 0), packet[2], packet[3]);
break;
// 6. 扫描到匹配设备
case GATT_COMM_EVENT_SCAN_DEV_MATCH:
log_info("match_dev:addr_type= %d", packet[0]);
put_buf(&packet[1], 6);
break;
// 7. 搜索到匹配的UUID
case GATT_COMM_EVENT_GATT_SEARCH_MATCH_UUID:
opt_handle_t *opt_hdl = packet;
log_info("match:server_uuid=%04x,charactc_uuid=%04x,value_handle=%04x",
opt_hdl->search_uuid->services_uuid16,
opt_hdl->search_uuid->characteristic_uuid16,
opt_hdl->value_handle);
// 保存写句柄用于发送数据
if (opt_hdl->search_uuid->characteristic_uuid16 == 0xae01)
cetl_ble_client_write_handle = opt_hdl->value_handle;
break;
// 8. 搜索完成
case GATT_COMM_EVENT_GATT_SEARCH_PROFILE_COMPLETE:
log_info("GATT_SEARCH_PROFILE_COMPLETE:%04x",
little_endian_read_16(packet, 0));
// 设置搜索完成标志
i = ble_comm_dev_get_index(...);
if (i != INVAIL_INDEX)
search_profile_complete_flag[i] = 1;
break;
// 9. MTU交换完成
case GATT_COMM_EVENT_MTU_EXCHANGE_COMPLETE:
log_info("con_handle= %02x, ATT MTU = %u",
little_endian_read_16(packet, 0), little_endian_read_16(packet, 2));
break;
// 10. 输入Passkey (配对)
case GATT_COMM_EVENT_SM_PASSKEY_INPUT:
u32 *key = little_endian_read_32(packet, 2);
*key = 888888; // 固定Passkey
log_info("input_key:%6u", *key);
break;
- 3 cetl_client_test_write() - 数据发送测试
static void cetl_client_test_write(void)
{ static u32 count = 0;
static u32 send_index[SUPPORT_MAX_GATT_CLIENT];
count++;
for (i = 0; i < SUPPORT_MAX_GATT_CLIENT; i++)
{send_index[i]++;
tmp_handle = ble_comm_dev_get_handle(i, GATT_ROLE_CLIENT);
// 检查连接有效且搜索完成
if (tmp_handle && cetl_ble_client_write_handle && search_profile_complete_flag[i])
{// 发送数据
ret = ble_comm_att_send_data(tmp_handle, cetl_ble_client_write_handle,
&count, send_len, ATT_OP_WRITE_WITHOUT_RESPOND);
if (!ret) send_test_count[i] += send_len;
}
// 每秒统计一次速率
if (send_index[i] >= time_index_max)
log_info("conn_handle:%04x,send_rate= %d byte/s",tmp_handle, send_test_count[i]);
send_test_count[i] = 0;
- 工作流程图
- 系统启动
app_main() 选择 central 应用
- 应用启动 (app_central.c)
→ 调用 bt_ble_init()
- BLE初始化 (ble_central.c)
├── bt_ble_before_start_init() → ble_comm_init()
├── bt_ble_init()
│ ├── ble_comm_set_config_name() // 设置设备名称
│ ├── cetl_client_init() // 客户端初始化
│ │ ├── 设置搜索配置 (设备匹配表 + UUID表)
│ │ ├── 设置扫描配置 (间隔/窗口)
│ │ └── 启动测试定时器 (数据发送)
│ └── ble_module_enable(1) // 使能BLE模块
└── (可选) central_server_init() // 同时作为从机
- 扫描阶段
├── 主动扫描 (SCAN_ACTIVE)
├── 扫描到设备 → GATT_COMM_EVENT_SCAN_ADV_REPORT
├── 检查设备名称是否匹配 (cetl_match_device_table)
└── 匹配成功 → GATT_COMM_EVENT_SCAN_DEV_MATCH
- 连接阶段
├── 自动发起连接 (creat_auto_do = 1)
├── 连接完成 → GATT_COMM_EVENT_CONNECTION_COMPLETE
├── 保存连接句柄 (cetl_con_handle)
└── 可选: 加密配对 (SM)
- 服务搜索阶段
├── 搜索指定服务 (0xAE30)
├── 匹配特征值 (0xAE01 写, 0xAE02 通知)
├── 保存写句柄 (cetl_ble_client_write_handle)
├── 自动使能通知 (auto_enable_ccc = 1)
└── 搜索完成 → GATT_COMM_EVENT_GATT_SEARCH_PROFILE_COMPLETE
- 数据通信阶段
发送数据 (定时器)
├── cetl_client_test_write() 定时调用
├── ble_comm_att_send_data() 发送到 0xAE01
└── 统计发送速率
接收数据 (Notify)
├── GATT_COMM_EVENT_GATT_DATA_REPORT 收到数据
├── put_buf() 打印数据
└── 统计接收速率
- 测试功能说明
6.1 数据发送测试
|
宏 |
值 |
说明 |
|
CETL_TEST_WRITE_SEND_DATA |
1 |
使能自动发送 |
|
CETL_TEST_SEND_EN |
1 |
允许发送数据 |
|
CETL_TEST_PAYLOAD_LEN |
244 |
每包数据长度 |
|
TEST_TIMER_MS |
5/500 |
发送间隔(高速/普通) |
6.2 速率统计
// 每秒统计一次
if (send_index[i] >= time_index_max)
{ log_info("send_rate= %d byte/s", send_test_count[i]);
send_test_count[i] = 0;
log_info("recieve_rate= %d byte/s", recieve_test_count[i]);
recieve_test_count[i] = 0;
}







评论