1.蓝牙地址获取
android P:
获取方法是bluetooth_address.cpp里面
vendor/qcom/proprietary/bluetooth/hidl_transport/bt/1.0/default/bluetooth_address.cpp
bool BluetoothAddress::GetLocalAddress(uint8_t *local_addr)
  {
    char property[PROPERTY_VALUE_MAX] = { 0 };
    bool valid_bda = false;

    // Get addr from vendor location
    if (fetch_vendor_addr(local_addr)) {
      valid_bda = true;
    }
    // Get local bdaddr storage path from a system property.
    if (!valid_bda && property_get(PROPERTY_BT_BDADDR_PATH, property, NULL)) {
      int addr_fd;

      ALOGV("%s: Trying %s", __func__, property);

      addr_fd = open(property, O_RDONLY);
      if (addr_fd != -1) {
        int bytes_read = read(addr_fd, property, kStringLength);
        CHECK(bytes_read == kStringLength);
        close(addr_fd);

        // Null terminate the string.
        property[kStringLength] = '\0';

        // If the address is not all zeros, then use it.
        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);
          }
       }
    }

    // No BDADDR found in the file. Look for BDA in a factory property.
    if (!valid_bda && property_get(FACTORY_BDADDR_PROPERTY, property, NULL) &&
        StringToBytes(property, local_addr)) {
      valid_bda = true;
      le2bd(local_addr);
    }

    // Check if address is stored @ Modem NV
    if ((!valid_bda)&& property_get("persist.vendor.bluetooth.modem_nv_support",
                     property, "false") && (strcmp(property, "true") == 0))
   {
      ALOGV("%s: QMI initialization START ",__func__);
      if(!tried_reading_modemnv_) {
        int retry = 0;
        while (retry < QMI_INIT_MAX_TRY) {
          if (retry > 0)
            sleep(QMI_INIT_RETRY_INTERVAL_SEC);
          if (QmiDmsInit() == true) {
            if (QmiDmsGetAddress(modem_bdaddr_) == true) {
              char bdstr[kStringLength + 1];
              ALOGE("Read MODEM_NV_BD_ADDR 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n",
              modem_bdaddr_[0], modem_bdaddr_[1], modem_bdaddr_[2], modem_bdaddr_[3],
                  modem_bdaddr_[4], modem_bdaddr_[5]);
              valid_bda = true;
              read_addr_from_modemnv_ = true;
              memcpy(local_addr, modem_bdaddr_, kBytes);

              /* 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 MODEM_NV_BD_ADDR in prop %s", __func__,
                  PERSIST_BDADDR_PROPERTY);
               }
            }
            QmiDmsCleanup();
            break;
          }
           ++retry;
          ALOGE("%s: QMI initialization failed in %d try...", __func__, retry);
        }
        tried_reading_modemnv_ = true;
      } else if(read_addr_from_modemnv_) {
         memcpy(local_addr, modem_bdaddr_, kBytes);
         valid_bda = true;
       }
    }

    // No factory BDADDR found. Look for a previously stored BDA.
    if (!valid_bda && property_get(PERSIST_BDADDR_PROPERTY, property, NULL) &&
        StringToBytes(property, local_addr)) {
      valid_bda = true;
      le2bd(local_addr);
    }

    /* Generate new BDA if necessary */
    if (!valid_bda) {
      char bdstr[kStringLength + 1];
      struct timespec cur_time;

      if (-1 == clock_gettime (CLOCK_MONOTONIC, &cur_time))
      {
        ALOGE("%s: clock_gettime failed\n", __func__);
      }

      srand((unsigned int)cur_time.tv_nsec);

      /* 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);

      ALOGE("%s: No preset BDA! Generating BDA: %s for prop %s", __func__,
            (char*)bdstr, PERSIST_BDADDR_PROPERTY);
      ALOGE("%s: This is a bug in the platform!  Please fix!", __func__);

      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);
        }
    }

    return valid_bda;
  }

在上面的代码中,一共有下面的 6 种获取mac地址的方法:

// Get addr from vendor location
// Get local bdaddr storage path from a system property.
// No BDADDR found in the file. Look for BDA in a factory property.
// Check if address is stored @ Modem NV
// No factory BDADDR found. Look for a previously stored BDA.
/* Generate new BDA if necessary */

其中,当需要从NV去读取Bluetooth的mac地址时,代码走// Check if address is stored @ Modem NV里面;
因为高通并没有在代码中做配置,所以需要我们去在device/qcom/common/common64.mk中添加
persist.vendor.bluetooth.modem_nv_support=true \

diff --git a/common64.mk b/common64.mk
--- a/common64.mk
+++ b/common64.mk
@@ -22,6 +22,7 @@ PRODUCT_PROPERTY_OVERRIDES += \
persist.vendor.radio.custom_ecc=1 \
persist.vendor.radio.rat_on=combine \
persist.backup.ntpServer=0.pool.ntp.org \
+ persist.vendor.bluetooth.modem_nv_support=true \
sys.vendor.shutdown.waittime=500 \

2.btnvtool工具

adb root
adb shell

向nv里写入mac地址:
btnvtool -b 11.11.11.11.11.11  或者,
btnvtool -b 22:22:22:22:22:22

读nv的mac地址:
btnvtool -p

代码就是生活的一部分。 坚持每天积累一点,时间久了,你就牛b了!