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;
 
                    
                 
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号