从机广播本机的地址

转自大香瓜的博客。

一、简介:

在不连接的情况下,主机获得从机的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、修改扫描数据

[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. }  


五、实验结果


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值