获取蓝牙低功耗外设的MAC地址

时间:2013-09-24 04:44:42

标签: ios bluetooth bluetooth-lowenergy

我目前正在开发基于蓝牙低功耗设备的iOS应用程序。为了获得唯一的标识符来比较外设,我必须得到外设的MAC地址。

据观察,外围设备的UUID属性因iOS设备而异,并且外围设备获取UUID,因此必须至少连接一次主设备。由于我必须处理登记入住,我不想建立连接。当我浏览蓝牙服务门户时,发现设备信息本身就是一项服务,除非在主iOS设备和外围蓝牙低功耗设备之间建立了连接,否则无法检索该设备。

我发现在Android中我们获取设备的全部信息,包括其MAC地址(使用getAddress()),当我们在扫描时从设备获得响应。

我没有在CBPeripheral类中找到与设备地址相关的任何属性。 获取唯一参数的另一种方法是自定义广告数据以发送有关设备的其他信息,这需要在固件方面进行更多工作。

那么在iOS中有什么办法可以在没有建立连接的情况下获得蓝牙低能量外设的MAC地址吗?

非常感谢任何帮助。

5 个答案:

答案 0 :(得分:27)

CBPeripheral的标识符属性将满足您的目的,可通过CBCentralManager的didDiscoverPeripheral委托方法从仍未连接的设备获得:

- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI

CBPeripheral *peripheral ...

NSUUID* serverId = [peripheral identifier];

我正在试验半打的LE设备,包括多套相同的设备。我刚刚确认,在两个iOS设备上,所有这些LE小部件的标识符都不同,但对于每个iOS设备,每个小部件的标识符在应用程序启动时保留,甚至跨应用程序删除和重新安装。我想说这最终证明操作系统在内部存储了足够的信息,对于给定的iThing,您将能够区分并重新识别您的应用程序遇到的所有外围设备,而无需实际连接到它们。 另请注意,advertisementData(在连接之前也可用)充满了有用的信息,例如CBAdvertisementDataLocalNameKeyCBAdvertisementDataManufacturerDataKeyCBAdvertisementDataServiceUUIDsKeyCBAdvertisementDataSolicitedServiceUUIDsKey和其他信息,但没有一定要将设备唯一地标识为[外围设备标识符]。

我没有尝试进行设备备份和恢复以证明UUID被保留,但是我打赌他们是,如果不是,那就是Apple会认为是一个bug。

答案 1 :(得分:14)

没有公共API来获取此信息。

如果这是内部或越狱应用程序,您可以通过liblockdown.dylib

获取kLockdownBluetoothAddressKey键的值

答案 2 :(得分:10)

低能耗外设可能会使用隐藏MAC地址的隐私功能,因此在连接或绑定之前甚至无法获取地址。如果你以某种方式获得无线传输的MAC地址,你需要处理隐私或者你有互操作性问题。

Apple使用UUID来抽象出这些隐私功能,因此用户无需担心这些。

像你所写的那样正确的方法是将一些特定于供应商的数据添加到广告包中或使用设备信息服务。

答案 3 :(得分:5)

代表其他专业人士的讨论,我发现了一些事实 -

iOS隐藏设备的MAC地址并生成UUID。 iOS上的UUID由iOS设备生成。不同的iOS设备将为同一外设获得不同的UUID。 MAC地址通常基于硬件。如果我们都有iPhone并扫描相同的外设,我们会看到不同的UUID。 iOS在设备上生成UUID并隐藏MAC地址。总结 - iOS不允许您获取设备的MAC地址,而是为您提供随机UUID。

  

来源 - https://github.com/don/cordova-plugin-ble-central/issues/77

根据上述研究,我发现到目前为止还没有一种独特的方式可以连接到主板,每个主板都有一个MAC地址,不会改变,也很容易在(只)Android中访问虽然iOS不允许访问外围设备的MAC地址,但是iOS使用此MAC地址来创建外围设备标识符(UUID),该标识符仅在(唯一)设备上是唯一的。对于不同的iPhone设备,单个主板的外设标识符是不同的(但在单个设备上是唯一的)。

然而,我们可以通过使用Peripheral的蓝牙服务UUID进行搜索来连接到主板,但是这种服务UUID对于所有类型的主板都是相同的 - “Adafruit Feather M0”。这意味着应用程序将环顾相同类型的BLE板(“Adafruit Feather M0”)并将连接到其中任何一个。到目前为止,由于MAC无法访问并在iOS中提供随机UUID,目前似乎无法连接到特定用户。

答案 4 :(得分:1)

您可以在iOS 12中毫无问题地访问MAC地址。 要获取mac地址,您必须执行以下步骤。

  1. 将BLE设备接收的数据解析为String。
extension Data{
func hexEncodedString() -> String {
        let hexDigits = Array("0123456789abcdef".utf16)
        var hexChars = [UTF16.CodeUnit]()
        hexChars.reserveCapacity(count * 2)

        for byte in self {
            let (index1, index2) = Int(byte).quotientAndRemainder(dividingBy: 16)
            hexChars.insert(hexDigits[index2], at: 0)
            hexChars.insert(hexDigits[index1], at: 0)
        }
        return String(utf16CodeUnits: hexChars, count: hexChars.count)
    }
}

  1. 在地址中添加分隔符“:”。
extension String {
    func separate(every stride: Int = 4, with separator: Character = " ") -> String {
        return String(enumerated().map { $0 > 0 && $0 % stride == 0 ? [separator, $1] : [$1]}.joined())
    }
}
  1. 在didReadValueForCharacteristic(特征:CBCharacteritic)中,您可以使用前面的2个函数来获取mac地址。
func didReadValueForCharacteristic(_ characteristic: CBCharacteristic) {
if characteristic.uuid == BleDeviceProfile.MAC_ADDRESS, let mac_address = characteristic.value?.hexEncodedString().uppercased(){
            let macAddress = mac_address.separate(every: 2, with: ":")
            print("MAC_ADDRESS: \(macAddress)")
        }
}
  1. 享受您的Mac地址: “ MAC_ADDRESS:00:0A:57:4E:86:F2”