Chinaunix首页 | 论坛 | 博客
  • 博客访问: 601637
  • 博文数量: 165
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1554
  • 用 户 组: 普通用户
  • 注册时间: 2013-10-23 22:57
个人简介

我本仁慈,奈何苍天不许

文章分类

全部博文(165)

文章存档

2018年(1)

2016年(33)

2015年(5)

2014年(34)

2013年(92)

分类: 嵌入式

2016-07-21 14:13:03

原文地址:51822模拟ble广播-理论 作者:ifndef

 
转载请注明出处,谢谢!

这讲教程介绍如何使用51822的radio部分来模拟实现ble广播功能,并使手机能够搜索到该设备。这里先介绍相关理论,实战部分见 实战教程。

既然是模拟ble广播,那么首先就需要知道 ble的广播包在空中传输的 格式。

整体的 空中包数据 分如下几个字段


前导1字节,为固定序列,8bit为01010101 或者10101010.到底使用哪个由其后的接入地址(access address)的第一个bit决定,如果是1则使用10101010,如果是0使用01010101,这样做的目的就是使 任意报文的前9个Bit都是交替的。 前导序列存在的目的是接收机可以用它来配置自动增益控制。

 

接入地址(access address)4字节分两种,广播接入地址和数据接入地址。 数据接入地址是在建立连接后两个设备之间使用的,由一定的规则产生。 我们这里因为是模拟广播,所以使用的是广播接入地址,为固定值是0x8E89BED6, 因为数据是LSB先发送,所以接入地址的第一个bit就是0 所以preamble的序列就是01010101.

 

PS:这里的接入地址 并不是 我们所说的ble的设备地址(6字节),这个接入地址是对 发射和接收端的物理radio而言的, 而ble的设备地址其实更像是应用层的地址。因为我们可以自行修改它。在广播数据包中,ble的设备地址是放在PDU中的,即负载数据中的,后面介绍具体的广播数据时会有说明。 这里这个接入地址可能不好理解,可能需要多看看规范才能渐渐明白。

 

PDU即 协议数据单元。即包中的真正应用数据就是放在这里面的。

CRC: 3字节对PDU部分进行校验,不包括接入地址和前导。 Crc生成多项式为固定的x24 + x10 + x9 + x6 + x4 + x3 + x + 1


从以上了解到我们要广播的数据就是在PDU部分中。下面看一下PDU部分中包含了哪些内容。

PDU部分 在广播信道的数据包 和数据信道的数据包中格式是不一样的。这里我们只需要知道广播信道中的格式就可以了



即广播信道中的数据包,其中的PDU部分 中包含 了2字节的头 和不超过37字节的负载数据(因为PDU本身长度最大为39字节)

也就是说 负载数据Payload本身是可以变长的,那么如何知道负载数据有多少呢。这就是 PDU里前面两字节的header起作用了。

再看下header的格式


PDU TYPE:因为这里是广信道的数据包格式,所以这个type指示的是广播信道的包类型。

RFU:为目前没有使用

TxAdd:为发送者的 地址类型0表示公共地址,1表示随机地址

RxAdd:为接收者的地址类型。

Ps: 广播信道中并不是所有 类型的包 这两个指示地址类型的 bit都是有效的。比如对于普通广播包,只使用了TxAdd,因为就是一个广播向外广播数据,所以指示一下自己的地址类型就行了,RxAdd忽略就行了。 而定向广播包中TxAdd和RxAdd都使用了。因为需要指示自己的地址类型和接收方的地址类型。

Length:指示其后的负载(payload)的长度。

 

再介绍如何设置广播数据之前先小结一下:

ble空中包有自己的数据格式。整体分为4部分。前导,接入地址,PDU,CRC。

应用数据就是在PDU部分中。而PDU由2字节的头和变长负载组成。而应用数据就是这个变长负载。


我们要模拟的广播,其中的广播数据也就是放在这个 变长负载payload中。

前面说过,这个包格式是广播信道中的数据包的格式。而广播信道中不是只会发广播包还包括,扫描包,连接请求包等。如下图所示。



我们这里需要模拟的就是  不可连接广播包。即上图中的 ADV_NONCONN_IND。

那么如何区分这些不同的数据包呢。  这就是前面说的 PDU中的2字节头中的PDU TYPE起作用了。由上图可知PDU TYPE的4bit为0010 时就代表这个 包的类型是普通广播包。

PS:之所以模拟这个广播包,而不是模拟 第一个普通广播包ADV_IND,是因为普通广播包,是可以被扫描和连接的,而对于可扫描的设备,手机可能会发一个扫描请求过来,如果设备没有回复扫描请求可能导致手机直接过滤掉设备导致搜不到这个设备。所以这里设置成 ADV_NONCONN_IND类型广播,改广播是不可连接也不可被扫描的。所以手机只要收到广播包就会将该设备显示在设备列表上了。

 

 

普通广播包就是向外广播数据,所以只有自己的ble地址,所以2字节头中的Txadd字段需要设置,我们使用静态随机地址,因为是随机地址,所以需要设置TxAdd为1,RxAdd忽略就行了(关于ble地址参考的教程 ble地址)。最后还剩一个Length,这个Length是只是2字节头后的payload的长度的。

这个payload也就是我们需要设置 广播什么数据的地方。

 

我们是模拟ADV_NONCONN_IND类型的广播,所以需要看一下该类型的广播包的payload的格式。

如下图所示:



即 负载payload部分中的数据由两部分组成 6字节广播设备地址和 广播数据。(这里的地址才是ble的设备地址,要和最前面说的那个4字节的接入地址区分开)

所以我们只要设置6字节的ble地址和一些广播数据 就完成了所有的格式要求了。

对于AdvData BLE同样也有自己的格式要求 如下图所示



广播数据中通常包含好几个类型数据,比如 设备名字,uuid,厂商自定义数据等。那么手机收到AdvData后如何将里面的数据解析成 设备名字,uuid,厂商自定义数据等呢。 就是根据上图中的 LTV结构来解析的。 也就是说广播数据的中的各个部分,像是设备名字,uuid,厂商字段什么的,都是按照LTV结构来组织的,即Length(1字节)表示后面的type(1字节)和data的长度和,type表示后面的data是什么,设备名字还是Uuid什么的。

 

Type的值有如下这些



我们需要用到的有 0x01 BLE_GAP_AD_TYPE_FLAGS,用来指示发现模式,和是否支持经典蓝牙。 我们设置flag为不支持经典蓝牙。

即 0x02 0x01 0x04           l为2  t为0x01   v为0x04 表示不知道经典蓝牙

然后使用到0x09 BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME 来设置名字。

即 0x07 0x09 0x64 0x65 0x76 0x69 0x63 0x65 

 

关于具体的广播数据方面 参考教程  BLE广播数据解析。


具体51822代码实现 在教程  广播模拟实践中。

最后由一个图来总结下具体的包组成和格式:



阅读(844) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~