從機廣播本機的地址

轉自大香瓜的博客。

一、簡介:

在不連接的情況下,主機獲得從機的MAC地址的方法。


二、版權聲明

博主:甜甜的大香瓜

聲明:喝水不忘挖井人,轉載請註明出處。

原文地址:http://blog.csdn.net/feilusia

聯繫方式:[email protected]

技術交流QQ羣:127442605


三、思路

1、理清廣播、掃描、連接的流程


簡述一下流程:

從機廣播本機的UUID,主機接收到後利用該UUID發送掃描請求,從機接收到掃描請求後回覆掃描應答(掃描應答的數據主要包括:設備名、連接參數、發射功率)。


2、在哪裏添加MAC地址?

從上圖可以看出,在主從機連接之前,從機發了一個廣播數據和一個掃描應答數據、主機發了一個掃描應答數據。

我們可以將MAC添加進從機的掃描應答數據的“設備名”,也就是說原來的設備名可能是“GUA”,修改後爲“GUA 9059AF0E6362”。

注:也可以把MAC放在廣播數據中。


3、將MAC寫在設備名稱上有什麼用?

1)用戶直觀:

在lightblue中,手機掃描到很多叫“GUA”的從機,我們並不曉得用哪一個。而MAC是唯一的,所以名稱中加入MAC可以直觀地判斷我們需要哪個從機。


2)不連接即可獲得MAC:

有些項目並不需要連接主從機(比如只用來測距),此時獲得MAC用來確認從機。


3)蘋果手機無法在連接中獲得MAC:

蘋果手機沒有提供讀取底層MAC的API,所以只能通過廣播MAC的方式傳給蘋果手機。

但是將MAC放在廣播中,同時也會導致數據的不安全。


4、主機如何從設備名稱中獲取到MAC?

主機先獲得廣播數據各個字段的數據(參考《CC2541之主機端獲取廣播包數據》),

再根據自己定義的協議(比如主從機約定好從從第9個字節~21個字節都是MAC)提取MAC。


四、修改

1、修改掃描數據

[cpp] view plain copy
  1. static uint8 scanRspData[] =  
  2. {  
  3.   // complete name  
  4.   //0x14,   // length of this data  
  5.   0x13,  
  6.   GAP_ADTYPE_LOCAL_NAME_COMPLETE,  
  7.     
  8.   0x47, //G  
  9.   0x55, //U         
  10.   0x41, //A    
  11.   0x20, //空格  
  12.   0x20, //空格  
  13.   0x20, //空格  
  14.     
  15.   0x20, //給MAC地址預留位置  
  16.   0x20,  
  17.   0x20,  
  18.   0x20,  
  19.   0x20,  
  20.   0x20,  
  21.   0x20,  
  22.   0x20,  
  23.   0x20,  
  24.   0x20,  
  25.   0x20,  
  26.   0x20,     
  27. /*   
  28.   0x53,   // 'S' 
  29.   0x69,   // 'i' 
  30.   0x6d,   // 'm' 
  31.   0x70,   // 'p' 
  32.   0x6c,   // 'l' 
  33.   0x65,   // 'e' 
  34.   0x42,   // 'B' 
  35.   0x4c,   // 'L' 
  36.   0x45,   // 'E' 
  37.   0x50,   // 'P' 
  38.   0x65,   // 'e' 
  39.   0x72,   // 'r' 
  40.   0x69,   // 'i' 
  41.   0x70,   // 'p' 
  42.   0x68,   // 'h' 
  43.   0x65,   // 'e' 
  44.   0x72,   // 'r' 
  45.   0x61,   // 'a' 
  46.   0x6c,   // 'l' 
  47. */  
  48.   // connection interval range  
  49.   0x05,   // length of this data  
  50.   GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,  
  51.   LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),   // 100ms  
  52.   HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),  
  53.   LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),   // 1s  
  54.   HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),  
  55.   
  56.   // Tx power level  
  57.   0x02,   // length of this data  
  58.   GAP_ADTYPE_POWER_LEVEL,  
  59.   0       // 0dBm  
  60. };  
這裏我只給設備名預留了6個字節,而給MAC地址12個字節。


2、修改應用初始化

由於讀出來的數據是6字節的十六進制數,而手機端顯示的是字符串,所以我們要把6字節MAC轉爲12字節字符串。


3、寫一個讀mac的函數

[cpp] view plain copy
  1. //**************************************************  
  2. //name:         Read_Mac  
  3. //input:        mac需要保存到的位置,需要6個字節大小  
  4. //return:       none  
  5. //**************************************************  
  6. static void Read_Mac(uint8 *ownAddress)     //讀本機MAC  
  7. {  
  8.   ownAddress[5] = *(unsigned char *)(0x780E); // 直接指向指針內容     
  9.   ownAddress[4] = *(unsigned char *)(0x780F);    
  10.   ownAddress[3] = *(unsigned char *)(0x7810);    
  11.   ownAddress[2] = XREG(0x7811);                // define 函數直接讀出數據     
  12.   ownAddress[1] = XREG(0x7812);    
  13.   ownAddress[0] = XREG(0x7813);   
  14. }    
注意:在初始化時不能通過GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);去讀取MAC,因爲此時MAC還沒有寫入到該變量中。所以此時只能直接從寄存器中讀出芯片的MAC地址。


可以通過flash programmer讀取MAC地址,以此來校驗你代碼中讀出的MAC是否正確:



4、寫一個十六進制轉字符串的函數

[cpp] view plain copy
  1. //**************************************************  
  2. //name:         OwnAddr2Str  
  3. //input:        16進制地址轉字符串  
  4. //return:       修改後的字符串  
  5. //**************************************************  
  6. char *OwnAddr2Str( uint8 *pAddr )  
  7. {  
  8.   uint8       i;  
  9.   char        hex[] = "0123456789ABCDEF";  
  10.   static char str[B_ADDR_STR_LEN];  
  11.   char        *pStr = str;  
  12.   
  13.   for ( i = B_ADDR_LEN; i > 0; i-- )  
  14.   {  
  15.     *pStr++ = hex[*pAddr >> 4];  
  16.     *pStr++ = hex[*pAddr++ & 0x0F];  
  17.   }  
  18.   
  19.   return str;  
  20. }  


五、實驗結果


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章