iOS 藍牙開發 Mac地址問題


在藍牙開發中,經常會遇到藍牙Mac地址物理地址-->唯一標記)鏈接的問題,

對於安卓來說,可以通過Mac地址來鏈接,因為他們可以獲取到外設的Mac地址。

對於蘋果而言,是不可以通過Mac地址鏈接的,因為我們無法獲取外設的Mac地址。

雖然蘋果給我們提供了一個外設的UUID,但是這個UUID是通過外設的Mac地址手機的Mac地址進行加密計算得來的。

換言之,不同手機鏈接同一外設這個值是不同的,所以這個值並不能取代Mac地址作為唯一標記,況且安卓是沒有這個UUID的。

peripheral.identifier.UUIDString;
*!
 *  @property identifier
 *
 *  @discussion The unique, persistent identifier associated with the peer.
 */
@property(readonly, nonatomic) NSUUID *identifier NS_AVAILABLE(10_13, 7_0);
/* Return a string description of the UUID, such as "E621E1F8-C36C-495A-93FC-0C247A3E6E5F" */
@property (readonly, copy) NSString *UUIDString;

 

那iOS如何獲取Mac地址呢?

方案A:

硬件工程師將Mac地址寫到廠商數據中,然后我們獲取(掃描階段就可以獲取到)

 

方案B:(本質就是讀取固定指令獲取)

讀取外設的180A服務里的2A23特征值,再去進行剪切和拼接來獲取(必須先鏈接上外設)

 

詳情參考:https://www.jianshu.com/p/1d6a8fc8134f 

但這個方案有大弊端

1、就是我必須先鏈接上然后再去獲取這個Mac地址,太消耗成本,且效率不高。

假如有很多設備的話,我必須一一驗證,不是再斷開,遠沒有在掃描階段(掃描的過程是很快的,可以在短短幾秒鍾內就可以找到周圍的上百台設備),確認是再鏈接高效。

2、這樣會有莫名其妙的問題

3、從鏈接的角度來講有點本末倒置,本來我是用Mac地址來鏈接的,但現在變成了,先鏈接再獲取Mac地址,驗證是否正確。

4、僅限某些設備,如果你的藍牙設備不支持這樣獲取,你需要跟硬件工程師溝通,說白了並不通用

 

iOS如何鏈接呢?

一般我們可以通過名稱、廠商數據來鏈接。

當手機藍牙(此地將手機藍牙作為中心設備)掃描到外設(譬如手環之類的)后,會進入這個方法

/*!
 *  @method centralManager:didDiscoverPeripheral:advertisementData:RSSI:
 *
 *  @param central              The central manager providing this update.
 *  @param peripheral           A <code>CBPeripheral</code> object.
 *  @param advertisementData    A dictionary containing any advertisement and scan response data.
 *  @param RSSI                 The current RSSI of <i>peripheral</i>, in dBm. A value of <code>127</code> is reserved and indicates the RSSI
 *                                was not available.
 *
 *  @discussion                 This method is invoked while scanning, upon the discovery of <i>peripheral</i> by <i>central</i>. A discovered peripheral must
 *                              be retained in order to use it; otherwise, it is assumed to not be of interest and will be cleaned up by the central manager. For
 *                              a list of <i>advertisementData</i> keys, see {@link CBAdvertisementDataLocalNameKey} and other similar constants.
 *
 *  @seealso                    CBAdvertisementData.h
 *
 */
- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *, id> *)advertisementData RSSI:(NSNumber *)RSSI;

名稱、廠商數據可以從advertisementData(廣告數據)中讀取

/*!
 *  @constant CBAdvertisementDataLocalNameKey
 *
 *  @discussion A <code>NSString</code> containing the local name of a peripheral.
 *
 */
CB_EXTERN NSString * const CBAdvertisementDataLocalNameKey;
/*!
 *  @constant CBAdvertisementDataManufacturerDataKey
 *
 *  @discussion A <code>NSData</code> object containing the manufacturer data of a peripheral.
 *
 */
CB_EXTERN NSString * const CBAdvertisementDataManufacturerDataKey;

 

//advertisementData中可以發送的數據有約定 如下
17 /*
18 對應設置NSString類型的廣播名
19 NSString *const CBAdvertisementDataLocalNameKey;
20 外設制造商的NSData數據
21 NSString *const CBAdvertisementDataManufacturerDataKey;
22 外設制造商的CBUUID數據
23 NSString *const CBAdvertisementDataServiceDataKey;
24 服務的UUID與其對應的服務數據字典數組
25 NSString *const CBAdvertisementDataServiceUUIDsKey;
26 附加服務的UUID數組
27 NSString *const CBAdvertisementDataOverflowServiceUUIDsKey;
28 外設的發送功率 NSNumber類型
29 NSString *const CBAdvertisementDataTxPowerLevelKey;
30 外設是否可以連接
31 NSString *const CBAdvertisementDataIsConnectable;
32 服務的UUID數組
33 NSString *const CBAdvertisementDataSolicitedServiceUUIDsKey;
34 */

 

具體如何保證唯一性,這個就需要和藍牙硬件工程師約定了。

1、如果名稱是唯一的,我們就可以用名稱來約定唯一性。

2、如果名稱相同,又要確定唯一性,那我們就需要通過廠商數據來約定了。

具體這個規則要怎么來約定唯一性,就靠彼此約定了,這個規則隨意,只要彼此雙方約定好就可以。

 

綜上:

比較好的鏈接方案就是,蘋果、安卓、硬件大家約定好一個規則,不論是通過名稱或者廠商數據都可以確定唯一性通用性

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM