2.5. DEMO_BLE工程说明
概述
本工程展示了使用蓝牙BLE分别充当主从机进行数据传输测试功能和mesh功能。
1.从机 数传
2.主机 client角色
3.多机通讯
4.mesh测试demo
具体的示例工程代码详见 apps/demo/demo_ble
。
2.5.1. 工程配置说明
apps/demo/demo_ble/include/app_config.h
A)打开宏 #define TCFG_USER_BLE_ENABLE BLE功能使能
B)BLE DEMO模式选择:选择需要打开的测试用例置1,同时只能选择一项
打开宏 #define TRANS_DATA_EN 1 从机模式 数传打开宏 #define BT_NET_CENTRAL_EN 1 主机模式 client角色 搜寻连接其它BLE从机打开宏 #define TRANS_MULTI_BLE_EN 1 多机通讯(支持多个主机和从机同时运行)打开宏 #define CONFIG_BLE_MESH_ENABLE 1 mesh组网测试demo
//*********************************************************************************//
// BT_BLE配置 //
//*********************************************************************************//
#ifdef CONFIG_BT_ENABLE
#define CONFIG_BT_RX_BUFF_SIZE 0
#define CONFIG_BT_TX_BUFF_SIZE 0
#define TCFG_USER_BLE_ENABLE 1 //BLE功能使能
#define TCFG_USER_BT_CLASSIC_ENABLE 0 //经典蓝牙功能
#if TCFG_USER_BLE_ENABLE
//BLE DEMO选择
#define BT_NET_HID_EN 0 //从机 hid
#define TRANS_DATA_EN 1 //从机 传输数据
#define BT_NET_CENTRAL_EN 0 //主机 client角色
#define TRANS_MULTI_BLE_EN 0 //多机通讯
#define CONFIG_BLE_MESH_ENABLE 0 //mesh测试demo
#if (TRANS_MULTI_BLE_EN + BT_NET_HID_EN + BT_NET_CENTRAL_EN + TRANS_DATA_EN + CONFIG_BLE_MESH_ENABLE > 1)
#error "they can not enable at the same time,just select one!!!"
#endif
2.5.2. 操作说明:
- 1.从机模式
- 通过手机app(nrf connect)(扫描、发现、连接低功耗蓝牙设备的应用)连接到设备BLE的JL-AC79XXble
- 对已经连接的蓝牙ble设备进行trans_data传输数据,进行写write,读read,通知notify等操作。
- 2.主机模式:主动通过搜索去连接其它BLE从机设备
- 用户需要填写以下过滤规则,填写不匹配会出现一直连接不上或者通讯失败的情况,需要指定搜索对应profile的uuid。
//ble.c
#if BT_NET_CENTRAL_EN || TRANS_MULTI_BLE_MASTER_NUMS
//用户需要填写以下过滤规则,填写错误会出现一直连接不上的情况
//指定搜索uuid
static const target_uuid_t search_uuid_table[] = {
// for uuid16
// PRIMARY_SERVICE, ae80
// CHARACTERISTIC, ae81, WRITE_WITHOUT_RESPONSE | DYNAMIC,
// CHARACTERISTIC, ae82, NOTIFY,
{
.services_uuid16 = 0xae80,
.characteristic_uuid16 = 0xae81,
.opt_type = ATT_PROPERTY_WRITE_WITHOUT_RESPONSE,
},
{
.services_uuid16 = 0xae80,
.characteristic_uuid16 = 0xae82,
.opt_type = ATT_PROPERTY_NOTIFY,
},
{
.services_uuid16 = 0xae00, // 6901A
.characteristic_uuid16 = 0xae01,
.opt_type = ATT_PROPERTY_WRITE_WITHOUT_RESPONSE,
},
{
.services_uuid16 = 0xae00, // 6901A
.characteristic_uuid16 = 0xae01,
.opt_type = ATT_PROPERTY_NOTIFY,
},
//for uuid128,sample
// PRIMARY_SERVICE, 0000F530-1212-EFDE-1523-785FEABCD123
// CHARACTERISTIC, 0000F531-1212-EFDE-1523-785FEABCD123, NOTIFY,
// CHARACTERISTIC, 0000F532-1212-EFDE-1523-785FEABCD123, WRITE_WITHOUT_RESPONSE | DYNAMIC,
/*
{
.services_uuid16 = 0,
.services_uuid128 = {0x00,0x00,0xF5,0x30 ,0x12,0x12 ,0xEF, 0xDE ,0x15,0x23 ,0x78,0x5F,0xEA ,0xBC,0xD1,0x23} ,
.characteristic_uuid16 = 0,
.characteristic_uuid128 = {0x00,0x00,0xF5,0x31 ,0x12,0x12 ,0xEF, 0xDE ,0x15,0x23 ,0x78,0x5F,0xEA ,0xBC,0xD1,0x23},
.opt_type = ATT_PROPERTY_NOTIFY,
},
{
.services_uuid16 = 0,
.services_uuid128 = {0x00,0x00,0xF5,0x30 ,0x12,0x12 ,0xEF, 0xDE ,0x15,0x23 ,0x78,0x5F,0xEA ,0xBC,0xD1,0x23} ,
.characteristic_uuid16 = 0,
.characteristic_uuid128 = {0x00,0x00,0xF5,0x32 ,0x12,0x12 ,0xEF, 0xDE ,0x15,0x23 ,0x78,0x5F,0xEA ,0xBC,0xD1,0x23},
.opt_type = ATT_PROPERTY_WRITE_WITHOUT_RESPONSE,
},
*/
};
- 3.多机通讯:支持多个主机和从机角色同时运行
- 多机通讯从机模式:bt_multi_trans_init(); ble多机从机数传多机通讯主机模式:bt_multi_client_init(); ble多机主机数传
//app_config.h
#if TRANS_MULTI_BLE_EN
#define TRANS_MULTI_BLE_SLAVE_NUMS 2 //最大从机数
#define TRANS_MULTI_BLE_MASTER_NUMS 2 //最大主机数
#endif
//le_multi_common.h
#define SUPPORT_MAX_SERVER TRANS_MULTI_BLE_SLAVE_NUMS
#define SUPPORT_MAX_CLIENT TRANS_MULTI_BLE_MASTER_NUMS
//le_multi_common.c
void bt_ble_init(void)
{
int error_reset = 0;
//log_info("%s,%d\n", __FUNCTION__, __LINE__);
//log_info("ble_file: %s", __FILE__);
/*确认配置是否ok*/
if (config_le_hci_connection_num && att_send_check_multi_dev(config_le_gatt_server_num, config_le_gatt_client_num)) {
log_info("no support more device!!!\n");
error_reset = 1;
}
if (error_reset) {
printf("======error config!!!\n");
ASSERT(0);
while (1);
}
#if SUPPORT_MAX_SERVER
bt_multi_trans_init();
#endif
#if SUPPORT_MAX_CLIENT
bt_multi_client_init();
#endif
}
- 4.mesh组网测试demo:蓝牙Mesh网络是用于建立多对多(many:many)设备通信的低能耗蓝牙(Bluetooth Low Energy,也称为Bluetooth LE)的网络拓扑,网络中包含的蓝牙设备之间可以相互进行信息的传递。
- 在
apps/common/ble/mesh/model_api.h
选择对应的mesh测试用例
测试APP操作如下:
2.5.3. 代码流程
1.app_main(),调用bt_ble_module_init()进行蓝牙BLE协议栈初始化
//app_main.c
/*
* 应用程序主函数
*/
void app_main()
{
puts("------------- demo_ble app main-------------\n");
extern void bt_ble_module_init(void);
bt_ble_module_init();
}
2.bt_ble_module_init()
A) 调用bt_max_pwr_set()函数设置蓝牙最大发射功率(0-11)。B) 调用bt_get_mac_addr()函数获取蓝牙mac地址。C) 调用lib_make_ble_address()函数根据提供的edr地址生成唯一对应ble地址。D) 调用le_controller_set_mac()函数设置ble的public地址。E) 调用btstack_init()函数进行蓝牙协议栈初始化。
//ble.c
void bt_ble_module_init(void)
{
void lmp_set_sniff_disable(void);
lmp_set_sniff_disable();
#if TCFG_USER_BLE_ENABLE
u8 tmp_ble_addr[6];
extern const u8 *bt_get_mac_addr(void);
extern void lib_make_ble_address(u8 * ble_address, u8 * edr_address);
extern int le_controller_set_mac(void *addr);
lib_make_ble_address(tmp_ble_addr, (u8 *)bt_get_mac_addr());
le_controller_set_mac((void *)tmp_ble_addr);
printf("\n-----edr + ble 's address-----");
put_buf((void *)bt_get_mac_addr(), 6);
put_buf((void *)tmp_ble_addr, 6);
#if BT_NET_CENTRAL_EN || TRANS_MULTI_BLE_MASTER_NUMS
extern void ble_client_config_init(void);
ble_client_config_init();
#endif
#endif
btstack_init();
}
3.BLE各个测试用例的初始化入口
//ble.c
static int bt_connction_status_event_handler(struct bt_event *bt)
{
switch (bt->event) {
case BT_STATUS_INIT_OK:
#if TRANS_MULTI_BLE_EN //多机通讯
bt_ble_init();
#else
#if BT_NET_CENTRAL_EN //主机模式
extern void bt_master_ble_init(void);
bt_master_ble_init();
#endif
#if TRANS_DATA_EN //从机模式
bt_ble_init();
#endif
#if BT_NET_HID_EN //从机hid
extern void ble_module_enable(u8 en);
extern void ble_hid_set_config(void);
ble_hid_set_config();
bt_ble_init();
#endif
#if CONFIG_BLE_MESH_ENABLE //mesh组网
extern void bt_ble_mesh_init(void);
bt_ble_mesh_init();
#endif
#endif
break;
}
return 0;
}
4.ble_report_data_deal(),主机模式下处理接收到的数据
//ble.c
static void ble_report_data_deal(att_data_report_t *report_data, const target_uuid_t *search_uuid)
{
log_i("report_data:%02x,%02x,%d,len(%d)", report_data->packet_type,
report_data->value_handle, report_data->value_offset, report_data->blob_length);
put_buf(report_data->blob, report_data->blob_length);
//处理接收数据
switch (report_data->packet_type) {
case GATT_EVENT_NOTIFICATION: //notify
break;
case GATT_EVENT_INDICATION://indicate
case GATT_EVENT_CHARACTERISTIC_VALUE_QUERY_RESULT://read
break;
case GATT_EVENT_LONG_CHARACTERISTIC_VALUE_QUERY_RESULT://read long
break;
default:
break;
}
}
5.主机模式下发送测试数据
//ble.c
static void client_event_callback(le_client_event_e event, u8 *packet, int size)
{
switch (event) {
case CLI_EVENT_MATCH_DEV:
log_i("match_name:%s\n", ((client_match_cfg_t *)packet)->compare_data);
break;
case CLI_EVENT_MATCH_UUID:
;
opt_handle_t *opt_hdl = (opt_handle_t *)packet;
if (opt_hdl->search_uuid == &search_uuid_table[0]) {
ble_client_write_handle = opt_hdl->value_handle;
log_i("match_uuid\n");
}
break;
case CLI_EVENT_SEARCH_PROFILE_COMPLETE:
log_i("CLI_EVENT_SEARCH_PROFILE_COMPLETE\n");
//可以开始发送数据
#if TRANS_MULTI_BLE_MASTER_NUMS
for (int i = 0; i < TRANS_MULTI_BLE_MASTER_NUMS; i++) {
u16 tmp_handle = mul_dev_get_conn_handle(i, MULTI_ROLE_CLIENT);
if (tmp_handle) {
ble_client_api->opt_comm_send_ext(tmp_handle, ble_client_write_handle, (u8 *)test_data, sizeof(test_data), ATT_OP_WRITE_WITHOUT_RESPOND);
}
}
#else
//发送测试数据
if (ble_client_write_handle) {
ble_client_api->opt_comm_send(ble_client_write_handle, (u8 *)test_data, sizeof(test_data), ATT_OP_WRITE_WITHOUT_RESPOND);
}
#endif
break;
case CLI_EVENT_CONNECTED:
break;
case CLI_EVENT_DISCONNECT:
ble_client_write_handle = 0;
break;
default:
break;
}
}