1.nordic藍牙地址獲取 代碼
官方工程默認都是使用靜態隨機地址,地址的最高兩位必須要是 1 1,原因下面會有解釋
void ble_get_mac(void)
{
// uint8_t i;
// ble_gap_addr_t ble_mac;
//#if (NRF_SD_BLE_API_VERSION >= 3)
// sd_ble_gap_addr_get(&ble_mac);
//#else
// sd_ble_gap_address_get(&ble_mac);
//#endif
// for(i=0; i<6; i++)
// {
// mac[i]=ble_mac.addr[5-i];
// }
mac[0]=*((uint8_t*)(0x10000000+0xa9))|0x40|0x80;
mac[1]=*((uint8_t*)(0x10000000+0x0a8));
mac[2]=*((uint8_t*)(0x10000000+0x0a7));
mac[3]=*((uint8_t*)(0x10000000+0x0a6));
mac[4]=*((uint8_t*)(0x10000000+0x0a5));
mac[5]=*((uint8_t*)(0x10000000+0x0a4));
}
2.藍牙地址規則
2.1BLE地址主要分爲類
兩類:
公共地址和隨機地址。
而隨機地址細分又有 靜態隨機地址和隱私地址(Private address)
而隱私地址又分爲:可解析隱私地址,不可解析隱私地址。
2.2 如何區分各種地址類型
有那麼多類型的地址,那麼如何區分各種地址類型的呢。
廣播通道PDU數據前面有2字節的頭 格式如下
其中的TxAdd表示發送方的地址類型 (0爲public,1爲random)
RxAdd表示接收方的地址類型。
PS:這兩個域並不是一直都有效的。比如對於普通廣播來說,只有TxAdd的指示是有效的,表示廣播發送者的第一類型。 而對於定向廣播來說。TxAdd和RxAdd都是有效的,TxAdd表示廣播發送者的地址類型,RxAdd表示廣播接受者的地址類型。
所以 對於是 public類型地址還是Random類型地址,直接通過 廣播通道PDU中的的 數據頭 中的 TxAdd或者RxAdd來判斷就可以了。
2.3 靜態隨機地址,還是可解析的隱私地址
但是這裏有個問題,只是區分出了 Random地址後,又怎麼知道是靜態隨機地址,還是可解析的隱私地址,或者不可解析的隱私地址呢。
這就要了解 各種地址類型的格式。
Public地址的格式比較簡單,高24位是公司標示,低24位公司內部自己賦值。
靜態隨機地址的格式如下圖所示,需要滿足
1:最高2位爲1
2:隨機部分不能全0或者全1
另外對於靜態隨機地址,地址的設置是在設備上電初始化時進行的,一旦設置後本次運行過程中 自己的靜態隨機地址都不能再改變,除非重新上電。
不可解析的隱私地址格式如下圖所示:需要滿足
1:最高2位爲0
2:隨機部分不能爲全1或全0
可解析的隱私地址格式如下圖所示:需要滿足
1:最高位0次高位爲1
2:隨機部分不能爲全0或全1
可解析的隨機地址的生成需要使用到 IRK, 地址由兩部分組成,
hansh和prand(包含最高固定2位和22位隨機部分)。
其中 hash = ah(IRK, prand) ah就是產生隨機地址的函數。
既然是可解析地址,那麼如何解析呢? 解析的過程也是一樣的。接收方可能存在多個IRK,接收方收到一個地址類型是 隨機地址,並且最高2位是01那麼,接收方就會 用他有的IRK對接收到的地址的高24位做ah(IRK, prand)運算,得到localHash,然後將localHash和接收到地址的低24位的hash對比,如果相同則認爲這個地址 和 該IRK是相關連的。
如果不同則繼續 用下一個IRK做上面的過程,知道找到一個關聯的IRK或者一個沒找到。
2.4 總結一下
當一方收到一個地址後,對於地址的解析過程如下:
1:首先根據 收到的廣播信道PDU中的數據頭中的指示來判斷是public類型地址還是Random類型地址。
2:如果是public那麼地址類型就是確定的了,
3:如果是Random,則查看地址的最高兩位,
如果是11就是靜態隨機地址,地址類型確定
如果是00表示爲不可解析隱私地址,類型確定
如果是01表示爲可解析的私有地址,並執行上面說過的ah方法,找到與該可 解析地址相關的IRK(可能找不到)。
最後 介紹一下 51822中怎麼設置各種類型的地址。
uint32_t sd_ble_gap_address_set (uint8_t addr_cycle_mode, const ble_gap_addr_t * p_addr )
addr_cycle_mode 參數爲:BLE_GAP_ADDR_CYCLE_MODE_AUTO:
該模式下,會忽略第二個地址參數p_addr 中給的地址addr。協議棧內部會自動週期性根據 p_addr中addr_type指定的地址類型來 生成可解析的或者不可解析的地址。
addr_cycle_mode 參數爲:BLE_GAP_ADDR_CYCLE_MODE_NONE:
該模式下,可以使用public地址和自己設置的 static random地址。
如果第二個參數P_addr中的addr_type爲staic random類型,則addr中存放的地址的最高2位必須爲1,不然這個地址會被認爲無效並自動替換,51822會自動替換爲藍牙mac地址。(跟沒有調用sd_ble_gap_address_set函數的效果是一樣的,看教程最上面的說明)
static random address 只有在每次 重新上電後纔可改變。
可解析和不可解析的地址可在正常運行過程中週期性改變
其他使用該函數需要注意的地方看 sdk中該函數的說明就行了