瑞芯微Rockchip开发者社区
直播中

哈哈哈

10年用户 872经验值
擅长:可编程逻辑
私信 关注
[问答]

如何去解决wifi与bt地址无法写到机器里去的问题呢

wifi地址与bt地址为什么无法写到机器里面去呢?
如何去解决wifi与bt地址无法写到机器里去的问题呢?

回帖(1)

张嘉

2022-2-17 15:05:31
背景


  
最近在做RK平台的项目,遇到了写号的问题;最开始是SN、wifi地址、bt地址无法写到机器里面去;更新了写号工具之后,可以写入机器,但是并没有使用到写号工具写入的数据,即写入的数据并没有生效。

  平台:RK3326,Android 8.1;
工具:RKDevInfoWriteTool_Setup_V1.0.4_0422
出现问题

  
最开始是SN、wifi地址、bt地址无法写到机器里面去;更新了写号工具之后,可以写入机器,但是并没有使用到我们使用写号工具写入的信息,即写入的数据并没有生效。
分析问题

  
我觉得想要解决这个问题,需要弄清楚2个问题:

  1、工具写入的数据是存放在哪里的?
2、蓝牙和wifi分别是在哪里去获取工具写入的数据?
解决问题

存放位置

  根据RK文档可得知:vendor storage,用于存储SN, MAC, LAN,BT等数据,主要特性是不会丢失以及系统启动各个阶段都可以访问,包括uboot, kernel, linux用户空间以及pc端。
获取地址

1、WIFI Mac

WIFI Mac是在wifi驱动里面去获取的;

  路径:
kernel/drivers/net/wireless/rockchip_wlan/rtlxxxx/core/rtw_ieee80211.c
在函数rtw_macaddr_cfg()中,添加如下:

void rtw_macaddr_cfg(u8 *out, const u8 *hw_mac_addr)
{
   
    …………
   
err_chk:


    /*添加代码 start*/
    if (!rockchip_wifi_mac_addr(mac)) {
        RTW_ERR("get mac address from flash=[%02x:%02x:%02x:%02x:%02x:%02x]n", mac[0], mac[1],
        mac[2], mac[3], mac[4], mac[5]);
    }
   
/*添加代码 end*/


    if (rtw_check_invalid_mac_address(mac, _TRUE) == _TRUE) {


简单的去跟踪一下rockchip_wifi_mac_addr()函数,可以发现是从vendor分区里面把数据读出来的,其实有一个值得注意得地方,如下:

int rockchip_wifi_mac_addr(unsigned char *buf)
{
    char mac_buf[20] = {0};


    LOG("%s: enter.n", __func__);


    // from vendor storage
    if (is_zero_ether_addr(wifi_custom_mac_addr)) {
        if (get_wifi_addr_vendor(wifi_custom_mac_addr) != 0)
            return -1;
    }


    sprintf(mac_buf, "%02x:%02x:%02x:%02x:%02x:%02x",
        wifi_custom_mac_addr[0], wifi_custom_mac_addr[1],
        wifi_custom_mac_addr[2], wifi_custom_mac_addr[3],
        wifi_custom_mac_addr[4], wifi_custom_mac_addr[5]);
    LOG("falsh wifi_custom_mac_addr=[%s]n", mac_buf);


    if (is_valid_ether_addr(wifi_custom_mac_addr)) {
        /*如果是rtl开头的芯片,这里会对第一个字节进行一些处理(一共6个字节),导致写入的值和实际呈现的值有偏差*/
        if (!strncmp(wifi_chip_type_string, "rtl", 3))
            wifi_custom_mac_addr[0] &= ~0x2; // for p2p
    } else {
        LOG("This mac address is not valid, ignored...n");
        return -1;
    }


    memcpy(buf, wifi_custom_mac_addr, 6);


    return 0;
}                                                           


  get_wifi_addr_vendor(wifi_custom_mac_addr) -> rk_vendor_read(WIFI_MAC_ID, addr, 6) -> return _vendor_read(id, pbuf, size);
  wifi地址的获取比较简单,但是我在解决这个问题的过程中,遇到了驱动模块加载的问题,因为wifi驱动是以模块的方式编进内核的,在重新编译了kernel之后一定要将模块卸载之后再重新加载,不然不会生效!
2、蓝牙地址

蓝牙地址的获取是在HAL层;

  相关路径:
hardware/realtek/rtkbt/code/libbt-vendor/src/hardware.c
hardware/interfaces/bluetooth/1.0/default/vendor_interface.cc
hardware/interfaces/bluetooth/1.0/default/bluetooth_address.cc
  hardware/下面有很多厂商,若所想要自己添加的东西被编译进系统,需要在build/make/core/product.mk文件里面做如下添加,如宏:BOARD_HAVE_BLUETOOTH_RTK,在Android.mk文件里面可以提现这个宏的作用;

product_stash_var_list +=
    BOARD_WPA_SUPPLICANT_DRIVER
    BOARD_WLAN_DEVICE
    BOARD_USES_GENERIC_AUDIO
    BOARD_KERNEL_CMDLINE
    BOARD_KERNEL_BASE
    BOARD_HAVE_BLUETOOTH
    BOARD_HAVE_BLUETOOTH_RTK     


在vendor_interface.cc文件中:




static const char* VENDOR_LIBRARY_SYMBOL_NAME =
    "BLUETOOTH_VENDOR_LIB_INTERFACE"; //和后面调用init函数有关


bool VendorInterface::Open(InitializeCompleteCallback initialize_complete_cb,
                           PacketReadCallback event_cb,
                           PacketReadCallback acl_cb,
                           PacketReadCallback sco_cb) {
   
    /*省略部分代码*/
   
    uint8_t local_bda[BluetoothAddress::kBytes];
    /*从vendor分区获取BT地址*/
    if (!BluetoothAddress::get_local_address(local_bda)) {
        LOG_ALWAYS_FATAL("%s: No Bluetooth Address!", __func__);
    }
   
    /*调用init函数,位于realtek下面,后面详细说*/
    int status = lib_interface_->init(&lib_callbacks, (unsigned char*)local_bda);
    if (status) {
        ALOGE("%s unable to initialize vendor library: %d", __func__, status);
        return false;
    }


    /*省略部分代码*/            
        
}
  在bluetooth_address.cc文件中,定义了get_local_address()函数,将获取到的蓝牙地址放在形参local_addr里面,即VendorInterface::Open函数中的local_bda数组里面;



bool BluetoothAddress::get_local_address(uint8_t* local_addr) {
     
     /*省略部分代码*/
     
    ret = bt_addr_vendor_storage_read_or_write(0, bd_addr, 6);
    if (ret == 0) {
        memcpy(local_addr, bd_addr, 6);


        valid_bda = true;
        ALOGE("Got local bdaddr for vendor storage %02X:%02X:%02X:%02X:%02X:%02X",
                local_addr[0], local_addr[1], local_addr[2],
                local_addr[3], local_addr[4], local_addr[5]);
    }
   
    /*省略部分代码*/
   
}


上面提到的init函数,其实定义在bt_vendor_rtk.c文件中,在该文件中,有如下定义:


/*可用于interfaces下面的调用(我现在也不知道为什么,是凭着直觉找到的[捂脸])*/
const bt_vendor_interface_t BLUETOOTH_VENDOR_LIB_INTERFACE = {
    sizeof(bt_vendor_interface_t),
    init,
    op,
    cleanup
};


//在init函数中将local_bdaddr数组里面的地址(即上面所获取到的蓝牙地址)放在vnd_local_bd_addr数组里
static int init(const bt_vendor_callbacks_t* p_cb, unsigned char *local_bdaddr)
{


    /*省略部分代码*/


    /* This is handed over from the stack */
    memcpy(vnd_local_bd_addr, local_bdaddr, 6);
    byte_reverse(vnd_local_bd_addr, 6);
   
    /*省略部分代码*/
}


在hardware.c文件里,定义了getmacaddr()函数,是一个一看名字就知道干什么的函数;


int getmacaddr(unsigned char * addr)
{


    /*省略部分代码*/
   
    char property[100] = {0};
    if (property_get("persist.vendor.rtkbt.bdaddr_path", property, "none")) {
        if(strcmp(property, "none") == 0) {
            return -1;
        }
        else if(strcmp(property, "default") == 0) {
            memcpy(addr, vnd_local_bd_addr, BD_ADDR_LEN);
            return 0;
        }
    }


    /*省略部分代码*/
}


  可以从上面代码段中看出来,通过persist.vendor.rtkbt.bdaddr_path属性的值来决定采用哪个蓝牙地址,如果persist.vendor.rtkbt.bdaddr_path的值为default,那么就使用vendor分区里面我们写入的值;那么如何修改persist.vendor.rtkbt.bdaddr_path的值呢?通过查找代码,我们就可以看到这个属性值定义在hardware/realtek/rtkbt/rtkbt.mk文件中,如下,将none改为default就可以,刷机验证OK;


PRODUCT_PROPERTY_OVERRIDES +=
                    persist.vendor.bluetooth.rtkcoex=true
                    persist.vendor.rtkbt.bdaddr_path=default
                    persist.vendor.bluetooth.prefferedrole=master
                    persist.vendor.rtkbtadvdisable=false //由none改为default


总结

  BT/Wifi这个模块,以前做MTK平台基本上没接触过;这次RK平台,Android 8.1,刚好公司采用的是RK那边也没做过的某芯片,问题比较多,接触到的东西也比较多,等有时间再写一篇蓝牙7.1升级到8.1的记录。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分