如何同時用一臺設備同時連接兩個RTL872X的設備?

如題, 我需要用一臺主機設備同時連接兩個RTL8721DM的芯片,但是我發現他們兩個的local BT ADDR是一樣的, 因此無法同時連接,請用我應該如何修改軟件可以使兩臺芯片的addr不一致呢,我在API文檔中沒找到.
我新建了BLEADDR的實例類,但是我發現實際輸出的LOCAL BT ADDR 並不是我設置的這個Addr, 他是不是需要一個函數初始化過去?

2 Likes

你是在用 GCC SDK 吗?

GCC SDK 应该是用
gap_get_param(GAP_PARAM_BD_ADDR, void *p_value);
gap_set_param(GAP_PARAM_BD_ADDR, uint8_t len, void *p_value);
来读取和设置 BT ADDR, 有可能还需要先把 GAP 层设置好启动了, 才能读取和更改 BT ADDR

我是用的arduino进行的调试,所以才发现底层调起来很麻烦,一开始我本以为参考官方API的文档class BLEADDR类可以进行修改,但是现在发现好像不行,我看过ble stack user manual的参考文档,上边2.5.2节描述的本地设备使用Static Random Address是不是可以解决这个问题?我还没有尝试成功,我看了下arduino平台下的代码,你所描述的gap_set_param这个函数是不是应该对应的就是le_set_gap_param这个?我来试试

update__
我试过了,应该就是直接通过gap_get_param和gap_set_param来进行操作,但是我现在发现我读取的结果也不对,我是直接修改了void BLEDevice::beginPeripheral()函数,在里边加入了以下代码:

uint8_t bt_addr[6] = {0,1,2,3,4,5};
uint8_t bt_addr1[6] ;
uint8_t i;
gap_get_param(GAP_PARAM_BD_ADDR, bt_addr1);
for(i=0;i<6;i++){
printf("%x\n", bt_addr1[i]);
}
gap_set_param(GAP_PARAM_BD_ADDR, 6, bt_addr);
for(i=0;i<6;i++){
printf("%x\n", bt_addr[i]);
}
gap_get_param(GAP_PARAM_BD_ADDR, bt_addr);
for(i=0;i<6;i++){
printf("%x\n", bt_addr[i]);
}

但是两次gap_get_param打印出来的结果都是0,所以是我放置的位置不对还是要设置GAP层启动呢?

update__
我试过了通过BLEDevice::getLocalAddr()是可以读到localaddr的,我看了下它的源码用的就是gap_get_param(), 我没有注意到注释里写的// Local address is only avaliable after peripheral or central mode is started,所以我在BLEDevice::beginPeripheral()之后就可以读到了,我现在准备仿造一个BLEDevice::setLocalAddr()加在BLEDevice::beginPeripheral()之后看一看能不能行

update_
我新建了一个BLEDevice::setLocalAddr的函数如下:
void BLEDevice::setLocalAddr(uint8_t flag) {
uint8_t btaddr_L[GAP_BD_ADDR_LEN] = {11,22,33,44,55,66};
uint8_t btaddr_R[GAP_BD_ADDR_LEN] = {22,33,44,55,66,77};
if(flag==1){
gap_set_param(GAP_PARAM_BD_ADDR, sizeof(btaddr_L), &btaddr_L[0]);
}
else{
gap_set_param(GAP_PARAM_BD_ADDR, sizeof(btaddr_R), &btaddr_R[0]);
}

}
但是我发现BLEDevice::getLocalAddr()出来的还是以前的就addr,并没有更新,这是哪里有问题呢?
arduino代码如下:
BLE.init();
BLE.configAdvert()->setAdvData(advdata);
BLE.configAdvert()->setScanRspData(scndata);
BLE.configServer(1);
BLE.addService(UartService);
BLE.setLocalAddr(1);
BLE.beginPeripheral();
uint8_t ad[6];
BLE.getLocalAddr(ad);
for(i=0;i<6;i++){
Serial.print(ad[i]);
Serial.println();
}
我尝试了无论在 BLE.beginPeripheral();之前或者之后进行 BLE.setLocalAddr(1)都未能成功

update
我看了gap.h的源码,发现上边对GAP_PARAM_BD_ADDR是这么描述的:
GAP_PARAM_BD_ADDR = 0x200,//!< Locol Device’s Address. Read Only. Size is uint8[GAP_BD_ADDR_LEN]. This item is read from the controller.
这个参数是只读的,应该不能通过gap_set_param进行修改,看样子要通过别的办法了.

请问你用的是模块还是芯片呢? 如果是芯片的话,应该是有完整SDK的,arduino的方面不方便做local addr的修改

请问一下,是否 WiFi 2.4G 和 5.8G 的 MAC address 也是两个芯片相同?

我用的芯片,自己设计的电路,那如果不改localaddr的话怎么能同时连接两个一样addr的芯片呢?
我现在再看你们的底层是怎么写的

这个我还没有试过,我用的都是Local BT addr:上电吐出来的地址

BT ADDR 和 WiFi MAC ADDR, 通常都是开发板厂商在大批生产时,同时在 EFUSE 里面给每一个芯片独特的 ADDR。
BT ADDR 如果 EFUSE 里面没有设定,就会用 hci_board 里面已经写好的默认 ADDR。如果多个芯片 EFUSE 都是空的,用的 image 都一样,就会导致 BT ADDR 一样。
hci_board 里面也同样能看到从 EFUSE 读取 ADDR 的过程。
既然能拿到芯片,也建议联系 FAE 具体了解如何在 EFUSE 写入 ADDR。

1 Like

各位,我已经解决了这个问题,我最近查阅了ble的手册和ble stack user manual,通过使用random address的方式同时连接上了两台local bt addr一样的芯片.
具体解决思路如下, 参考ble stack user manual的2.5.2节本地设备使用Static Random Address中的作为peripheral角色的参考,重新修改arrduino库中的BLEDevice.cpp,修改如下:
1.定义一个setLocalAddr的函数加入BLEDevice类,我这个因为只需要同时连接2个,所以改的相对简单了些,直接定义了两个addr,其实正常应该传参进来
uint8_t addr_data[6] = {0xe9,0x51,0x12,0x36,0x28,0x10};
void BLEDevice::setLocalAddr(uint8_t flag) {
uint8_t btaddr_L[GAP_BD_ADDR_LEN] = {0xe9,0x51,0x12,0x36,0x28,0x10};
uint8_t btaddr_R[GAP_BD_ADDR_LEN] = {0xe9,0x51,0x12,0x36,0x28,0x11};
if(flag==1){
memcpy(addr_data, btaddr_L, sizeof(btaddr_L));
}
else{
memcpy(addr_data, btaddr_R, sizeof(btaddr_R));
}

}
2.对beginPeripheral()函数作了修改,加入了如下代码:
T_APP_STATIC_RANDOM_ADDR random_addr;
uint8_t local_bd_type=GAP_LOCAL_ADDR_LE_RANDOM;
for(int i=0;i<6;i++){
random_addr.bd_addr[i]=addr_data[5-i];
//printf("%x\n",random_addr.bd_addr[i]);
}
le_cfg_local_identity_address(random_addr.bd_addr, GAP_IDENT_ADDR_RAND);
le_set_gap_param(GAP_PARAM_RANDOM_ADDR, 6, random_addr.bd_addr);
//only for peripheral,broadcaster
le_adv_set_param(GAP_PARAM_ADV_LOCAL_ADDR_TYPE, sizeof(local_bd_type), &local_bd_type);
思路就是将addr的type由public改成了random,但是random的值是预设好的
3.在连接的时候,使用ubuntu gatttool的话需要注意加入-t random的参数,手机我用app试了试好像不需要

1 Like

@desa001 谢谢你的反馈和补充! :+1:

我最近也遇到类似的问题,需要修改mac地址,我发现在安信可的网站上有个bw16的combo固件 (RTL87XX 系列模组专题 | 安信可科技 常见固件下方),烧录之后使用AT指令
AT+BLEMAC=AABBCCDDEEFF可以修改MAC地址,并且当我重新烧录Arduino编译好的自定义固件之后,模块仍然沿用了这个重新设置的MAC地址,我咨询安信可的客服,被告知combo固件源码不开放,所以内部具体怎么操作的不得而知,我猜测是不是写入在芯片BL固件中的,因为擦除Flash的时候都是从0x08000000开始擦除的,所以在这个地址之前会不会还有其他的BL数据呢

帮你 @wyy 一下,他比较了解BT

Flash 就是从 0x0800_0000 地址开始的,之前的地址是分给了其他外设,如 PSRAM / SRAM / ROM.
BLE MAC 地址是储存在 EFUSE 里面,AN0400 13.5.9 的 EFUSE 章能看到。安信可的固件 应该是在收到 AT 后更改 EFUSE。