BLE配对与绑定三(杂谈)
前言:
针对HID设备配对绑定获取信息常用代码做汇总。
一、获取已绑定的所有主机/手机MAC地址(需先绑定)
{
gapBondRec_t bond_info;
uint8_t adv_event_type = GAP_ADTYPE_ADV_HDC_DIRECT_IND;
uint8_t Adv_Direct_Addr[B_ADDR_LEN];
uint8_t Adv_Direct_Type = adv_direct.advtype;
tmos_snv_read(mainRecordNvID(0), sizeof(gapBondRec_t), &bond_info);
tmos_memcpy(Adv_Direct_Addr, bond_info.publicAddr, 6);
PRINT("Adv Direct type:%#x (", Adv_Direct_Type);
for (int i = 0; i < 6; i++) {
PRINT("%#x ", Adv_Direct_Addr[i]);
} PRINT(")\n");
}
二、获取已绑定的当前连接手机静态MAC(需先绑定)
手机会使用不同的随机MAC,避免被获取到真实的MAC地址,防止个人信息泄露。
如果直接获取手机的MAC,则获取的是动态的MAC。
获取静态MAC需要先绑定,然后根据连接识别的信息解析出静态的MAC地址。
操作如下:
①添加绑定操作:
uint8_t bonding = 1; //初始化bonding置1即可
GAPBondMgr_SetParameter(GAPBOND_PERI_BONDING_ENABLED, sizeof(uint8_t), &bonding);
②在建立连接的地方先获取到动态的MAC。
uint8_t peer_addr[6];
uint8_t peer_addr_type;
tmos_memcpy(peer_addr, event->devAddr, 6);
peer_addr_type = event->devAddrType;
PRINT("Connected..\n");
③根据动态MAC解析出对应的静态MAC。建议在回调函数中进行添加。
// Bond Manager Callbacks
static gapBondCBs_t hidDevBondCB = {
hidDevPasscodeCB,
hidDevPairStateCB, //绑定后即可进入该函数
NULL // oob callback
};
void GetStaticMAC(){
uint8_t addr[6];
uint8_t result;
result = GAPBondMgr_ResolveAddr(peer_addr_type,peer_addr,addr);
PRINT("result:%d\r\n",result);
printf("static MAC = ");
for(uint8_t i = 0; i < 6; i++){
printf("%x ", addr[i]);
}printf("\n");
}
static void hidDevPairStateCB(uint16_t connHandle, uint8_t state, uint8_t status)
{
printf("state = %d, status = %d\n", state, status);
if(state == GAPBOND_PAIRING_STATE_BONDED) //蓝牙回连进入
{
GetStaticMAC();
}
if(state == GAPBOND_PAIRING_STATE_BOND_SAVED) //蓝牙初次绑定进入
{
GetStaticMAC();
}
}
三、获取当前绑定数目
uint16_t bonding = 0;
if(events & BONDNUM_EVT)
{
GAPBondMgr_GetParameter(GAPBOND_BOND_COUNT, &bonding); //2022/7/21
printf("BondNum = %x\n", bonding);
tmos_start_task(hidEmuTaskId, BONDNUM_EVT, 6400);
return (events ^ BONDNUM_EVT);
}
四、主机获取从机MAC地址和设备名称
static uint8_t WaitPeerAddrDef[7] = {0x99, 0x02, 0x03, 0xE4, 0xC2, 0x84,'\0'} ;
char *pbuf;
case GAP_DEVICE_INFO_EVENT:
{
tmos_memcpy(WaitPeerAddrDef, pEvent->deviceInfo.addr, 6);
pbuf = strstr(WaitPeerAddrDef, PeerAddrDef);
if(pbuf != 0)
{
printf("Addr = ");
for(i = 0; i < 6; i++){
printf("%02x ", pEvent->deviceInfo.addr[i]);
}printf("\n");
printf("pEvtData = %s\r\n", pEvent->deviceInfo.pEvtData); //设备名称包含在广播包中
}
}
break;
五、添加绑定设备数量
单个BLE_SNV占用256字节。默认将DataFlash的最后区域(77FFF - 77E00)即512字节。因此默认提供两个绑定数量的地址大小,但是只提供了1个绑定num。
举例:绑定三个设备
#ifndef BLE_SNV_NUM //config.h中添加配置
#define BLE_SNV_NUM 3 // - 如果配置了SNVNum参数,则需要对应修改Lib_Write_Flash函数内擦除的flash大小,大小为SNVBlock*SNVNum
#endif
cfg.SNVNum = (uint32_t)BLE_SNV_NUM; //MCU.c中添加配置
#ifndef BLE_SNV_ADDR //config.h中修改
#define BLE_SNV_ADDR 0x77D00-FLASH_ROM_MAX_SIZE
#endif
六、读已绑定MAC地址
uint8_t buf[6];
tmos_snv_read(mainRecordNvID(0), sizeof(gapBondRec_t), buf); //获取第一个绑定MAC
printf("MAC 1 = ");
for(uint8 i = 0; i < sizeof(gapBondRec_t); i++){
printf("%02x ", buf[i]);
}printf("\r\n");
tmos_memset(buf,0,6); //清空buf
tmos_snv_read(mainRecordNvID(1), sizeof(gapBondRec_t), buf); //获取第二个绑定MAC
printf("MAC 2 = ");
for(uint8 i = 0; i < sizeof(gapBondRec_t); i++){
printf("%02x ", buf[i]);
}printf("\r\n");
七、删除绑定
①删除单个绑定
- 获取当前绑定数目(见第二点),如绑定的个数为0,则进行删除无意义;
- 获取绑定的MAC地址(见第五点);
- 获取连接MAC地址对应的地址类型:devAddrType
- 将上面获取到的MAC地址和类型组成新数组BUF(共7个字节):,第一个字节为地址类型,后六个字节为MAC地址(注意大小端);
- 调用函数 GAPBondMgr_SetParameter(GAPBOND_ERASE_SINGLEBOND, 6 + 1, BUF);
②删除所有绑定
// Erase bonding info
GAPBondMgr_SetParameter( GAPBOND_ERASE_ALLBONDS, 0, NULL );
八、获取snv
gapBondLTK_t DeviceLTK;
tmos_snv_read(localLTKNvID(0),sizeof(gapBondLTK_t),&DeviceLTK);
PRINT("Device LTK:");
for(uint8_t i=0;i<16;i++)
{
PRINT(" %02x",DeviceLTK.LTK[i]);
}PRINT("\n");
PRINT("Device ediv:%04x\n",DeviceLTK.div);
PRINT("Device Radom:");
for(uint8_t i=0;i<8;i++)
{
PRINT(" %02x",DeviceLTK.rand[i]);
}PRINT("\n");
gapBondRec_t DeviceBondInfo;
tmos_snv_read(mainRecordNvID(0),sizeof(gapBondRec_t),&DeviceBondInfo);
PRINT("Peer Addr:");
for(uint8_t i=0;i<6;i++)
{
PRINT(" %02x",DeviceBondInfo.publicAddr[i]);
}PRINT("\n");
uint8_t IRK[16]={0};
tmos_snv_read(BLE_NVID_IRK,16,IRK);
PRINT("Peer IRK:");
for(uint8_t i=0;i<16;i++)
{
PRINT(" %02x",IRK[i]);
}PRINT("\n\r\n");