【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地址给打印出来

  在配对绑定过程中,会进行密钥验证,默认的密钥是000000,在程序中,可以通过手机发送数据的方式来修改这个密钥。

  在获取手机静态地址的同时,判断手机的静态地址是否与程序中自定义的MAC地址匹配,如果成功匹配,标志位为1,否则匹配失败,标志位为0。

   通过手机绑定从机设备后,在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,才能进行正确的配对绑定连接。

 

posted on 2024-11-12 19:19  凡仕  阅读(7)  评论(0编辑  收藏  举报