[Android P] 蓝牙mac地址的读取与修改

1、蓝牙mac地址格式

蓝牙设备地址(BD_ADDR)是一个48bit的唯一标识符,由LAP(24位地址低端部分)、UAP(8位地址高端部分)和NAP(16位无意义地址部分)组成,其格式如下所示:

          LSB                                                       MSB
          |0000 0001 0000 0000 0000 0000|0001 0010|0111 1011 0011 0101|
          |<----------(24bit)---------->|<( 8bit)>|<----+(16bit)+---->|
          |             LAP             |   UAP   |        NAP        |

NAP和UAP是蓝牙设备生产厂商的唯一标识码,由SIG分配给各个厂商;LAP则由厂商自行分配。

其中,bit40为组播地址标志位,其值为0:unicast(单播),其值为1:multicast(组播);bit41为地址类型标志位,其值为0:universal addr,其值为1:local addr。

2、读取蓝牙mac地址

在函数BluetoothAddress::GetLocalAddress()中展示了数种方式读取蓝牙BD_ADDR。
首先函数fetch_vendor_addr(local_addr)读取存储在vendor下bt_nv.bin文件中的蓝牙地址:

vendor/qcom/proprietary/bluetooth/hidl_transport/bt/1.0/default/bluetooth_address.cpp
bool fetch_vendor_addr(uint8_t * addr ){
  cmd_result = (nv_persist_stat_enum_type)bt_nv_cmd(NV_READ_F,NV_BD_ADDR_I, &my_nv_item); 
}

vendor/qcom/proprietary/bt/hci_qcomm_init/bt_nv.cpp
int bt_nv_cmd(nv_persist_func_enum_type nvReadWriteFunc, nv_persist_items_enum_type
nvitem,nv_persist_item_type *my_nv_item, int bIsRandom){
 numitems = bt_nv_read(params_temp)
 switch(nvReadWriteFunc){
   case NV_READ_F:                        //read from file
   ......
   if(nvitem == NV_BD_ADDR_I){
     memcpy((*my_nv_item).bd_addr, params_temp[item].pCmdBuffer, NV_BD_ADDR_SIZE );
   ......
 }
 
#define PERSISTENCE_PATH "/vendor/factory"
#define BT_NV_FILE_NAME "bt_nv.bin"
int bt_nv_read (nv_persist_params *params_read) {
 snprintf(filename, NAME_MAX, "%s/%s",PERSISTENCE_PATH,BT_NV_FILE_NAME);}

其次是从system property中获取本地蓝牙地址路径:

static constexpr char PROPERTY_BT_BDADDR_PATH[] = "ro.vendor.bt.bdaddr_path";
static constexpr char PROPERTY_BT_BDADDR_PATH[] = "ro.bt.bdaddr_path";
property_get(PROPERTY_BT_BDADDR_PATH, property, NULL)
const uint8_t zero_bdaddr[kBytes] = { 0, 0, 0, 0, 0, 0 };
if ((StringToBytes(property, local_addr)) && (memcmp(local_addr, zero_bdaddr, kBytes) != 0)) {
  valid_bda = true;
  le2bd(local_addr);
  ALOGD("%s: Got Factory BDA %s", __func__, property)
}

若以上两种方法均不能获得BD_ADDR,则尝试从factory property中获取:

static constexpr char FACTORY_BDADDR_PROPERTY[] = "ro.boot.btmacaddr";
static constexpr char FACTORY_BDADDR_PROPERTY[] = "ro.vendor.bt.boot.macaddr";if (!valid_bda && property_get(FACTORY_BDADDR_PROPERTY, property, NULL) &&
StringToBytes(property, local_addr)) {
  valid_bda = true;
  le2bd(local_addr); 
}

再者,若从factory property中也无法获取到BD_ADDR,可以从之前保存的BDA中查找:

static constexpr char PERSIST_BDADDR_PROPERTY[] = "persist.service.bdroid.bdaddr";
static constexpr char PERSIST_BDADDR_PROPERTY[] = "persist.vendor.service.bdroid.bdaddr";

if (!valid_bda && property_get(PERSIST_BDADDR_PROPERTY, property, NULL) &&
StringToBytes(property, local_addr)) {
  valid_bda = true;
  le2bd(local_addr);
}

以上方法均无法获取到固定地址时,则生成随机地址,其形式为0x22:22:xx:xx:xx:xx,然后将之保存在property之中,每次重新开关机后会生成新的随机地址:

  /* No autogen BDA. Generate one now. */
  local_addr[0] = 0x22;
  local_addr[1] = 0x22;
  local_addr[2] = (uint8_t)rand();
  local_addr[3] = (uint8_t)rand();
  local_addr[4] = (uint8_t)rand();
  local_addr[5] = (uint8_t)rand();
  
  /* Convert to ascii, and store as a persistent property */
  BytesToString(local_addr, bdstr);
  
  if (property_set(PERSIST_BDADDR_PROPERTY, (char*)bdstr) < 0) {
    ALOGE("%s: Failed to set random BDA in prop %s",__func__,PERSIST_BDADDR_PROPERTY);
    valid_bda = false;
  }
   else {
    valid_bda = true;
    le2bd(local_addr);
  }

3、修改蓝牙mac地址

  • 使用bluedroid中提供的btnvtool修改蓝牙地址,具体过程如下:
#adb shell
#btnvtool -p                    // display bt address
#btnvtool -b aa:bb:cc:dd:ee:ff  // change bt address to be aa:bb:cc:dd:ee:ff
  • 使用高通QXDM工具修改蓝牙地址,在nv工具中ID:00447对应的BT地址中可以直接修改。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,383评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,522评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,852评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,621评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,741评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,929评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,076评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,803评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,265评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,582评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,716评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,395评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,039评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,027评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,488评论 2 361
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,612评论 2 350