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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18973098/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:37:24  来源:igfitidea点击:

Get MAC address of bluetooth low energy peripheral

iosbluetoothbluetooth-lowenergy

提问by Feby Sam

I am currently working on an iOS application based on bluetooth low energy devices. In order to get a unique identifier to compare the peripherals got, I have to get the MAC address of the peripherals.

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

It is observed that the UUID property of a peripheral device varies across iOS devices and also for the peripheral device to get a UUID, it will have to get connected to a master device at least once. Since I have to deal with check-in's I don't want to establish a connection. As I went through the bluetooth services portal, I found that the device information itself is a service, which couldn't be retrieved unless a connection has been established between the master iOS device and the peripheral bluetooth low energy device.

据观察,外围设备的 UUID 属性因 iOS 设备而异,而且外围设备要获得 UUID,必须至少连接到主设备一次。由于我必须处理签到,我不想建立连接。在浏览蓝牙服务入口时,我发现设备信息本身是一个服务,除非主iOS设备和外围蓝牙低功耗设备之间建立了连接,否则无法检索。

I found that in Android we get the entire information of the device, including its MAC address (using getAddress()) when we get the response from the device on scanning itself.

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

I didn't find any properties in CBPeripheral class related to the device address. Another way to get a unique parameter would be to customize the advertisement data to send additional information regarding the device, which requires more work on firmware side.

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

So is there any way in iOS that I could get the MAC address of the bluetooth low energy peripheral without establishing a connection?

那么在iOS中有什么方法可以在不建立连接的情况下获得蓝牙低功耗外设的MAC地址吗?

Any help would be greatly appreciated.

任何帮助将不胜感激。

采纳答案by Jogendra.Com

There is no public API to get this information.

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

If this is an internal or jailbreak application you can get the value of the kLockdownBluetoothAddressKey key via liblockdown.dylib

如果这是一个内部或越狱应用程序,您可以通过liblockdown.dylib获取 kLockdownBluetoothAddressKey 密钥的值

回答by Taryn

CBPeripheral's identifier property will serve your purpose, available from a still-unconnected device in CBCentralManager's didDiscoverPeripheral delegate method:

CBPeripheral 的 identifier 属性将用于您的目的,可从 CBCentralManager 的 didDiscoverPeripheral 委托方法中仍然未连接的设备获得:

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

CBPeripheral *peripheral ...

NSUUID* serverId = [peripheral identifier];

I have a half dozen LE devices I'm experimenting with, including multiple sets of identical devices. I just confirmed that across two iOS devices, the identifiers for all of these LE widgets were different, but for EACH iOS device, the identifier for each widget was retained across application launches and even across app deletes and reinstalls. I would say this definitively proves that the OS is storing enough info internally that for a given iThing, you'll be able to distinguish between, and re-identify, all the peripherals your app encounters, without actually connecting to them. Also note that the advertisementData, also available before connecting, is full of useful info like CBAdvertisementDataLocalNameKey, CBAdvertisementDataManufacturerDataKey, CBAdvertisementDataServiceUUIDsKey, CBAdvertisementDataSolicitedServiceUUIDsKey, and others, although none as certain to uniquely identify the device as [peripheral identifier] is.

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

I didn't try doing a device backup and restore to prove the UUIDs were retained, but I'd wager they are, and if they're not, it's something Apple would consider a bug.

我没有尝试进行设备备份和恢复来证明保留了 UUID,但我敢打赌它们是,如果不是,Apple 会认为这是一个错误。

回答by makkara

Low energy peripherals may use privacy feature which hides the MAC address, so it is not necessarily even possible to get the address before connection or bonding. If you somehow get the MAC address which goes over the air, you need to handle privacy or you have interoperability problems.

低功耗外围设备可能使用隐藏 MAC 地址的隐私功能,因此在连接或绑定之前甚至不一定可以获得地址。如果您以某种方式获得了通过无线传输的 MAC 地址,则您需要处理隐私或存在互操作性问题。

Apple uses UUIDs to abstract these privacy features out so users do not need to worry about those.

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

Correct way to do that like you wrote is to either add some vendor specific data to advertisement packet or use the Device Information service.

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

回答by Mohit G.

On-behalf of the discussion of the other professionals I've found some facts which says -

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

iOS hides the MAC address of the device and generates a UUID. The UUID on iOS is generated by the iOS device. Different iOS devices will get different UUIDs for the same peripheral. The MAC address is usually based on the hardware. If we both have iPhones and scan the same peripheral, we'll see different UUIDs. iOS generates the UUID on the device and hides the MAC address.??Summary - iOS doesn't let you get the MAC address of a device, it gives you a random UUID instead.“?

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

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

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

As per above study I've found that there's not such a unique way to get connect to the board so far, Every board has a MAC address, which Doesn't changes and easy to access in (only) Android, while iOS doesn't allow to access MAC Address of the peripheral, however iOS use this MAC address to create a peripheral identifier (UUID), which is unique on (unique) device only. The peripheral identifier for a single Board is different for different iPhones devices (but unique on single device).

根据上述研究,我发现到目前为止还没有这样一种独特的方式来连接到电路板,每个电路板都有一个 MAC 地址,它不会改变并且在(仅)Android 中易于访问,而 iOS 则没有t 允许访问外设的 MAC 地址,但是 iOS 使用此 MAC 地址来创建外设标识符 (UUID),该标识符仅在(唯一)设备上是唯一的。对于不同的 iPhone 设备,单个 Board 的外设标识符是不同的(但在单个设备上是唯一的)。

However we can connect to a board by searching with Peripheral's Bluetooth Service UUID, but this service UUID is same for all the boards of a kind say- “Adafruit Feather M0”. It means the App will look around the BLE boards of the same type (“Adafruit Feather M0”) and will get connect to ANY one of them. In order to connect to a particular user to a specific Board doesn't seems to be possible so far due to the inaccessibility of MAC and giving the random UUID in iOS.

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

回答by jlandyr

You can access to the MAC ADDRESS without problem in iOS 12. To get the mac address you have to follow the next steps.

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

  1. Parse the Data received by the BLE device to String.
  1. 将 BLE 设备接收到的 Data 解析为 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. Add a separator ":" to the address.
  1. 在地址中添加一个分隔符“:”。
extension String {
    func separate(every stride: Int = 4, with separator: Character = " ") -> String {
        return String(enumerated().map { 
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)")
        }
}
> 0 && ##代码## % stride == 0 ? [separator, ] : []}.joined()) } }
  1. In didReadValueForCharacteristic( characteristic: CBCharacteritic) you can use the previous 2 functions to get the mac address.
  1. 在 didReadValueForCharacteristic(characteristic: CBCharacteristic) 中,你可以使用前面的 2 个函数来获取 mac 地址。
##代码##
  1. enjoy your mac address: "MAC_ADDRESS: 00:0A:57:4E:86:F2"
  1. 享受你的mac地址:“MAC_ADDRESS:00:0A:57:4E:86:F2”