1.基础用法:

主机获取从机设备信息,包含以下信息内容:

 1 typedef struct
 2 {
 3     tmos_event_hdr_t hdr;             //!< GAP_MSG_EVENT and status
 4     uint8_t opcode;                   //!< GAP_DEVICE_INFO_EVENT                                           事件
 5     uint8_t eventType;                //!< Advertisement Type: @ref GAP_ADVERTISEMENT_REPORT_TYPE_DEFINES  广播类型,一般用以区分是广播包和应答包
 6     uint8_t addrType;                 //!< address type: @ref GAP_ADDR_TYPE_DEFINES                        地址类型
 7     uint8_t addr[B_ADDR_LEN];         //!< Address of the advertisement or SCAN_RSP                        地址
 8     int8_t rssi;                      //!< Advertisement or SCAN_RSP RSSI                                  信号强度
 9     uint8_t dataLen;                  //!< Length (in bytes) of the data field (evtData)                   数据长度
10     uint8_t *pEvtData;                //!< Data field of advertisement or SCAN_RSP                         广播包或应答包数据
11 } gapDeviceInfoEvent_t;

简单展示下打印获取程序:

 1         case GAP_DEVICE_INFO_EVENT:
 2         {
 3             PRINT("start——————————————————————————\n");
 4             PRINT("eventType=%x\n",pEvent->deviceInfo.eventType);
 5             PRINT("addrType=%x\n",pEvent->deviceInfo.addrType);
 6             for(uint8_t i=0;i<6;i++){
 7               PRINT("%x ",pEvent->deviceInfo.addr[i]);
 8             }
 9             PRINT("\n");
10             PRINT("rssi=%d\n",pEvent->deviceInfo.rssi);
11             PRINT("datalen=%d\n",pEvent->deviceInfo.dataLen);
12             for(uint8_t i=0;i<pEvent->deviceInfo.dataLen;i++){
13               PRINT("%x ",pEvent->deviceInfo.pEvtData[i]);
14             }
15             PRINT("\n");
16         }
17         break;

注意点:此结构体gapDeviceInfoEvent_t获取数据只可以在GAP_DEVICE_INFO_EVENT这个case中获取,若需要在别处使用需要在此case中做保存。

 2.进阶用法

有时候我们需要对广播包或应答包数据做解析,然后根据UUID,蓝牙名称,厂商自定义信息进行过滤连接,下面提供一个简单的解析参考:

解析源文件:

  1 #include "central_parse_advdata.h"
  2 #include "CONFIG.h"
  3 
  4 // Number of scan results
  5 uint8_t centralScanRes;
  6 
  7 ble_device_info_t ble_device_info[max_devices];
  8 ble_adv_parse_t ble_adv_parse;
  9 
 10 void insert_flag_data(uint8_t flag){
 11   ble_device_info[centralScanRes].ble_adv_parse.ad_flags=flag;
 12 }
 13 
 14 void insert_16bit_uuid_data(uint16_t uuid){
 15   ble_device_info[centralScanRes].ble_adv_parse.ad_16bit_service_uuid=uuid;
 16 }
 17 
 18 void insert_local_name_data(uint8_t len,uint8_t *data){
 19   ble_device_info[centralScanRes].ble_adv_parse.ad_local_name_len=len;
 20   tmos_memcpy(ble_device_info[centralScanRes].ble_adv_parse.ad_local_name, data, len);
 21 }
 22 
 23 void insert_manufacture_specific_data(uint8_t len,uint8_t *data){
 24   ble_device_info[centralScanRes].ble_adv_parse.ad_specific_data_len=len;
 25   tmos_memcpy(ble_device_info[centralScanRes].ble_adv_parse.ad_specific_data, data, len);
 26 }
 27 
 28 void central_add_device_info(uint8_t eventType, uint8_t addrType, uint8_t *pAddr, int rssi,uint8_t dataLen,uint8_t *pEvtData)
 29 {
 30     uint8_t i;
 31 
 32     // If result count not at max
 33     if(centralScanRes < max_devices)
 34     {
 35         // Check if device is already in scan results
 36         for(i = 0; i < centralScanRes; i++)
 37         {
 38             if(tmos_memcmp(pAddr, ble_device_info[i].addr, B_ADDR_LEN))
 39             {
 40                 return;
 41             }
 42         }
 43         // Add addr to scan result list
 44         tmos_memcpy(ble_device_info[centralScanRes].addr, pAddr, B_ADDR_LEN);
 45         ble_device_info[centralScanRes].addrType = addrType;
 46         ble_device_info[centralScanRes].rssi = rssi;
 47         // Display device addr
 48         PRINT("Device %d - rssi %d  Addr %x %x %x %x %x %x \n", centralScanRes,ble_device_info[centralScanRes].rssi,
 49                       ble_device_info[centralScanRes].addr[0],
 50                       ble_device_info[centralScanRes].addr[1],
 51                       ble_device_info[centralScanRes].addr[2],
 52                       ble_device_info[centralScanRes].addr[3],
 53                       ble_device_info[centralScanRes].addr[4],
 54                       ble_device_info[centralScanRes].addr[5]);
 55         parse_advertising_data(pEvtData,dataLen);
 56 
 57           printf("########Manufacturer Data Len:%d\n",ble_device_info[centralScanRes].ble_adv_parse.ad_specific_data_len);
 58                    for (int i=0; i<ble_device_info[centralScanRes].ble_adv_parse.ad_specific_data_len; i++) {
 59                        printf("%02X ", ble_device_info[centralScanRes].ble_adv_parse.ad_specific_data[i]);
 60                    }
 61                    printf("\n");
 62         centralScanRes++;
 63 
 64         // Increment scan result count
 65 
 66 
 67     }
 68 }
 69 // 广播包解析函数
 70 void parse_advertising_data(uint8_t *adv_data, uint8_t adv_len) {
 71     uint8_t index = 0;
 72     while (index < adv_len) {
 73         // 1. 读取当前AD结构的长度
 74         uint8_t field_len = adv_data[index];
 75         if (field_len == 0 || (index + field_len) > adv_len) break; // 安全校验
 76 
 77         // 2. 提取AD Type和Data起始位置
 78         uint8_t ad_type = adv_data[index + 1];
 79         uint8_t *ad_data = &adv_data[index + 2];
 80         uint8_t ad_data_len = field_len - 1; // 减去AD Type占用的1字节
 81 
 82         // 3. 根据AD Type处理数据
 83         switch (ad_type) {
 84 
 85             case GAP_ADTYPE_FLAGS:{
 86               uint8_t flag=0;
 87               PRINT("Flag=%x\n",flag);
 88               insert_flag_data(ad_data[0]);
 89               break;
 90             }
 91             // --- 设备名称 ---
 92             case GAP_ADTYPE_LOCAL_NAME_SHORT:
 93             case GAP_ADTYPE_LOCAL_NAME_COMPLETE: {
 94                 char name[32];
 95                 memcpy(name, ad_data, ad_data_len);
 96                 name[ad_data_len] = '\0'; // 确保字符串终止
 97                 printf("Device Name: %s\n", name);
 98                 insert_local_name_data(ad_data_len,ad_data);
 99                 break;
100             }
101 
102             // --- 16位UUID ---
103             case GAP_ADTYPE_16BIT_MORE:
104             case GAP_ADTYPE_16BIT_COMPLETE: {
105               uint16_t uuid=0;
106                 for (int i=0; i<ad_data_len; i+=2) {
107                     uuid = (ad_data[i+1] << 8) | ad_data[i]; // 小端转大端
108                     printf("16-bit UUID: 0x%04X\n", uuid);
109                 }
110                 insert_16bit_uuid_data(uuid);
111                 break;
112             }
113 
114             // --- 厂商数据 ---
115             case GAP_ADTYPE_MANUFACTURER_SPECIFIC: {
116                 if (ad_data_len >= 2) {
117 //                    uint16_t company_id = (ad_data[1] << 8) | ad_data[0]; // 注意字节序
118 //                    printf("Manufacturer ID: 0x%04X\n", company_id);
119 
120                     // 处理自定义数据(假设剩余字节是厂商自定义内容)
121                     if (ad_data_len > 2) {
122                         printf("Manufacturer Data Len:%d\n",ad_data_len);
123                         for (int i=0; i<ad_data_len; i++) {
124                             printf("%02X ", ad_data[i]);
125                         }
126                         printf("\n");
127                         insert_manufacture_specific_data(ad_data_len,ad_data);
128                     }
129                 }
130                 break;
131             }
132 
133             default:
134                 // 可扩展其他AD类型
135                 break;
136         }
137 
138         // 4. 移动到下一个AD结构
139         index += (field_len + 1); // +1是因为Length字段自身占1字节
140     }
141 }

解析头文件:

 1 #ifndef CENTRAL__PARSE_ADVDATA_H
 2 #define CENTRAL__PARSE_ADVDATA_H
 3 #include "CONFIG.h"
 4 
 5 #define max_devices 50
 6 
 7 extern void parse_advertising_data(uint8_t *adv_data, uint8_t adv_len);
 8 
 9 extern void central_add_device_info(uint8_t eventType, uint8_t addrType, uint8_t *pAddr,int rssi,uint8_t dataLen,uint8_t *pEvtData);
10 
11 
12 
13 typedef struct
14 {
15     uint8_t ad_flags;
16     uint16_t ad_16bit_service_uuid;
17     uint8_t ad_local_name_len;
18     uint8_t ad_local_name[31];
19     uint8_t ad_specific_data_len;
20     uint8_t ad_specific_data[31];
21 } ble_adv_parse_t;
22 
23 
24 typedef struct
25 {
26     uint8_t eventType;                //!< Advertisement Type: @ref GAP_ADVERTISEMENT_REPORT_TYPE_DEFINES
27     uint8_t addrType;                 //!< address type: @ref GAP_ADDR_TYPE_DEFINES
28     uint8_t addr[B_ADDR_LEN];         //!< Address of the advertisement or SCAN_RSP
29     int8_t rssi;                      //!< Advertisement or SCAN_RSP RSSI
30     ble_adv_parse_t ble_adv_parse;
31 } ble_device_info_t;
32 
33 
34 extern ble_device_info_t ble_device_info[max_devices];
35 extern ble_adv_parse_t ble_adv_parse;
36 extern uint8_t centralScanRes;
37 
38 #endif

central.c中调用解析:

 case GAP_DEVICE_INFO_EVENT:
        {
            // Add device to list
            central_add_device_info(pEvent->deviceInfo.eventType,
                                    pEvent->deviceInfo.addrType,
                                    pEvent->deviceInfo.addr,
                                    pEvent->deviceInfo.rssi,
                                    pEvent->deviceInfo.dataLen,
                                    pEvent->deviceInfo.pEvtData);
        }
        break;

        case GAP_DEVICE_DISCOVERY_EVENT:
        {
            uint8_t i;
            uint8_t name_data[31]="XF-BLE-CTRL";
            // See if peer device has been discovered
            for(i = 0; i < centralScanRes; i++)
            {
                if(tmos_memcmp(name_data,ble_device_info[i].ble_adv_parse.ad_local_name, ble_device_info[i].ble_adv_parse.ad_local_name_len)){
                    break;
                }
            }

            // Peer device not found
            if(i == centralScanRes)
            {
                PRINT("Device not found...\n");
                centralScanRes = 0;
                GAPRole_CentralStartDiscovery(DEFAULT_DISCOVERY_MODE,
                                              DEFAULT_DISCOVERY_ACTIVE_SCAN,
                                              DEFAULT_DISCOVERY_WHITE_LIST);
                PRINT("Discovering...\n");
            }

            // Peer device found
            else
            {
                PRINT("Device found...\n");

                GAPRole_CentralEstablishLink(DEFAULT_LINK_HIGH_DUTY_CYCLE,
                                             DEFAULT_LINK_WHITE_LIST,
                                             ble_device_info[i].addrType,
                                             ble_device_info[i].addr);

                // Start establish link timeout event
                tmos_start_task(centralTaskId, ESTABLISH_LINK_TIMEOUT_EVT, ESTABLISH_LINK_TIMEOUT);
                PRINT("Connecting...\n");
            }
        }
        break;

 

posted on 2025-05-10 13:51  WCH蓝牙应用分享  阅读(398)  评论(1)    收藏  举报