转自大香瓜的博客。
一、简介:
在不连接的情况下,主机获得从机的MAC地址的方法。
二、版权声明
博主:甜甜的大香瓜
声明:喝水不忘挖井人,转载请注明出处。
原文地址:http://blog.csdn.net/feilusia
联系方式:897503845@qq.com
技术交流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;
- }
五、实验结果