轉自大香瓜的博客。
一、簡介:
在不連接的情況下,主機獲得從機的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、修改掃描數據
- static uint8 scanRspData[] =
- {
- // complete name
- //0x14, // length of this data
- 0x13,
- GAP_ADTYPE_LOCAL_NAME_COMPLETE,
- 0x47, //G
- 0x55, //U
- 0x41, //A
- 0x20, //空格
- 0x20, //空格
- 0x20, //空格
- 0x20, //給MAC地址預留位置
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- 0x20,
- /*
- 0x53, // 'S'
- 0x69, // 'i'
- 0x6d, // 'm'
- 0x70, // 'p'
- 0x6c, // 'l'
- 0x65, // 'e'
- 0x42, // 'B'
- 0x4c, // 'L'
- 0x45, // 'E'
- 0x50, // 'P'
- 0x65, // 'e'
- 0x72, // 'r'
- 0x69, // 'i'
- 0x70, // 'p'
- 0x68, // 'h'
- 0x65, // 'e'
- 0x72, // 'r'
- 0x61, // 'a'
- 0x6c, // 'l'
- */
- // connection interval range
- 0x05, // length of this data
- GAP_ADTYPE_SLAVE_CONN_INTERVAL_RANGE,
- LO_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ), // 100ms
- HI_UINT16( DEFAULT_DESIRED_MIN_CONN_INTERVAL ),
- LO_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ), // 1s
- HI_UINT16( DEFAULT_DESIRED_MAX_CONN_INTERVAL ),
- // Tx power level
- 0x02, // length of this data
- GAP_ADTYPE_POWER_LEVEL,
- 0 // 0dBm
- };
2、修改應用初始化
由於讀出來的數據是6字節的十六進制數,而手機端顯示的是字符串,所以我們要把6字節MAC轉爲12字節字符串。
3、寫一個讀mac的函數
- //**************************************************
- //name: Read_Mac
- //input: mac需要保存到的位置,需要6個字節大小
- //return: none
- //**************************************************
- static void Read_Mac(uint8 *ownAddress) //讀本機MAC
- {
- ownAddress[5] = *(unsigned char *)(0x780E); // 直接指向指針內容
- ownAddress[4] = *(unsigned char *)(0x780F);
- ownAddress[3] = *(unsigned char *)(0x7810);
- ownAddress[2] = XREG(0x7811); // define 函數直接讀出數據
- ownAddress[1] = XREG(0x7812);
- ownAddress[0] = XREG(0x7813);
- }
可以通過flash programmer讀取MAC地址,以此來校驗你代碼中讀出的MAC是否正確:
4、寫一個十六進制轉字符串的函數
- //**************************************************
- //name: OwnAddr2Str
- //input: 16進制地址轉字符串
- //return: 修改後的字符串
- //**************************************************
- char *OwnAddr2Str( uint8 *pAddr )
- {
- uint8 i;
- char hex[] = "0123456789ABCDEF";
- static char str[B_ADDR_STR_LEN];
- char *pStr = str;
- for ( i = B_ADDR_LEN; i > 0; i-- )
- {
- *pStr++ = hex[*pAddr >> 4];
- *pStr++ = hex[*pAddr++ & 0x0F];
- }
- return str;
- }
五、實驗結果