【WCH蓝牙系列芯片】-基于CH592开发板—从机获取当前已绑定的主机(手机)MAC地址
-------------------------------------------------------------------------------------------------------------------------------------
当使用CH592作为蓝牙从机,可以被手机或者蓝牙主机设备去连接。想要获取当前连接的手机MAC地址,手机会使用不同的随机MAC地址,避免被获取到真实的MAC地址,以防止个人信息泄露。如果直接获取手机MAC地址则是动态的MAC,想要获取到静态MAC需要先进行绑定操作,根据连接的信息中解析出静态的MAC地址。
第一步:在从机初始化中,进行绑定操作
将pairMode改为pairMode = GAPBOND_PAIRING_MODE_INITIATE,从机与主机连接时,会发起配对请求进行绑定操作
第二步:在建立连接的地方获取动态MA
第三步:根据动态MAC地址信息解析出对应的静态MAC
uint8_t peer_addr[6]; uint8_t peer_addr_type; uint8_t macAddressFlag = 0; uint32_t password = 000000; //配对的密钥 uint32_t storedPasskey = 0; uint8_t GAPBondMgr_ResolveAddr(uint8_t, uint8_t*, uint8_t*); //将BLE设备的私有地址解析为公共地址或静态地址。这个函数的返回值通常用来表示操作是否成功,以及如果失败,失败的原因 void GetStaticMAC() { uint8_t addr[6]; uint8_t result; result = GAPBondMgr_ResolveAddr(peer_addr_type, peer_addr, addr); //需要获取到不变的MAC地址 PRINT("result:%02d\r\n",result); printf("static MAC = "); for(uint8_t i = 0; i < 6; i++) { printf("%02x ", addr[i]); //打印出静态地址 } printf("\n"); if (result == SUCCESS && addr[0] == 0x9c && addr[1] == 0x33 && addr[2] == 0x07 && addr[3] == 0x09 && addr[4] == 0x59 && addr[5] == 0x74) { macAddressFlag = 1; // 匹配成功,设置标志位为1 } else { macAddressFlag = 0; // 匹配失败,设置标志位为0 } printf("macAddressFlag = %d\r\n",macAddressFlag); } //state:连接绑定的状态 static void Pair_StateCB(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(); } }
通过串口工具可以看出,当手机连接从机设备后,就会将当前的手机的静态MAC地址给打印出来
通过手机绑定从机设备后,在char1通过发送数据,先会判断第一个数据是否为十六进制数(0x00),而且静态地址也匹配成功。才会进入修改密钥环节。会先将发送的数据,以十六进制打印出每个字节的值。
1、将十六进制的密码以hexArrayToDecimalString函数转化成十进制,
2、然后再把数据转化为uint32_t类型的数组,
3、通过GAPBondMgr_SetParameter函数,将newPasskeyValue(新的密钥)传入进去更新密钥。
4、在将这个新的密钥再传入到EEPROM中,下次启动设备,其他设备进行绑定的时候,就会用新的密码进行配对绑定。
static void simpleProfileChangeCB(uint8_t paramID, uint8_t *pValue, uint16_t len) { switch(paramID) { case SIMPLEPROFILE_CHAR1: { uint8_t newValue[SIMPLEPROFILE_CHAR1_LEN]; tmos_memcpy(newValue, pValue, len); PRINT("profile ChangeCB CHAR1.. \n"); for (int i = 0; i < SIMPLEPROFILE_CHAR1_LEN; i++) { PRINT("char1: 0x%02X\r\n", newValue[i]); //以十六进制格式打印每个字节的值 PRINT("char1: %02d\r\n", newValue[i]); } if (newValue[0] == 0x00 && macAddressFlag == 1) { printf("OK! Please change your password.\r\n"); uint8_t newPasskey[3]; tmos_memcpy(newPasskey, &newValue[1], sizeof(newPasskey)); for (int i = 0; i < 3; i++) { PRINT("char1: 0x%02X\r\n", newPasskey[i]); //以十六进制格式打印每个字节的值 } char newPasskeyStr[6]; // 需要8个字节来存储十进制数和终止符 hexArrayToDecimalString(newPasskey, sizeof(newPasskey), newPasskeyStr); printf("newPasskeyStr = %s\r\n",newPasskeyStr); // 将字符串转换为uint32_t类型的数值 uint32_t newPasskeyValue = strtoul(newPasskeyStr, NULL, 10); printf("newPasskeyValue = %06d\r\n",newPasskeyValue); // 更新密码 GAPBondMgr_SetParameter(GAPBOND_PERI_DEFAULT_PASSCODE, sizeof(uint32_t), &newPasskeyValue); EEPROM_ERASE(0, EEPROM_BLOCK_SIZE); //擦除EEPROM uint8_t s = EEPROM_WRITE(0, (uint8_t *)&newPasskeyValue, sizeof(newPasskeyValue)); //写EEPROM if (s == 0) { printf("EEPROM_WRITE success\r\n"); } else { printf("EEPROM_WRITE failed\r\n"); } } else { printf("Write error???????\r\n"); } break; } case SIMPLEPROFILE_CHAR3: { uint8_t newValue[SIMPLEPROFILE_CHAR3_LEN]; tmos_memcpy(newValue, pValue, len); PRINT("profile ChangeCB CHAR3..\n"); break; } default: // should not reach here! break; } } void hexArrayToDecimalString(uint8_t *hexArray, uint32_t hexArrayLen, char *decimalStr) { for (uint32_t i = 0; i < hexArrayLen; ++i) { // 将每个字节的十六进制值转换为两个十进制数字,并存储到字符串中 sprintf(&decimalStr[2 * i], "%02X", hexArray[i]); } decimalStr[2 * hexArrayLen] = '\0'; // 确保字符串以NULL结尾 }
通过手机成功绑定从机设备之后,在CHAR1中,发送十六进制数据:00123456
可以从串口打印观察,先是会吧接收到的数据一个一个打印出来,然后入更改密钥流程中,将0x12,0x34,0x56转化为十进制的123456,最后在存入到EEPROM中。
最后在通过其他手机去配对绑定这个蓝牙从机,此时的密钥就从原来的000000改为123456,才能进行正确的配对绑定连接。