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.多机通讯:支持多个主机和从机角色同时运行。设备当从机时候,主机连接成功设备以后要开启通知notify之后,设备才会打开新的广播让额外设备进行连接。
    多机通讯从机模式: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操作如下:

../../_images/111.gif ../../_images/222.gif

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;
    }
}