昨天大体上熟悉了TIMAC自带的CC2530的示范例程,今天先从演示抓包入手,分析四种不同的配置工程在空中传输的差异。随后,会按照扫描、组网、入网等MAC层接口函数入手,结合IEEE 802.15.4标准规范和能够看到的函数接口代码,来学习MAC的一些操作处理。
前面提到了,例程有四种网络组建方式,分为非信标直接模式,非信标间接模式,信标直接模式,信标间接模式。以下分别来抓包,结合具体代码分析,安全传输模式最后另作分析。
1. 非信标直接模式
对于非信标网络的建立,设备上电开机后,会扫描默认信道,如果此信道上没有其他协调器存在,它会将自己设定为协调器。
先通过 MSA_ScanReq(MAC_SCAN_ACTIVE, 3) 命令MAC层执行主动扫描过程,扫描结果以MAC_MLME_SCAN_CNF消息反馈给应用层,在应用层执行 MSA_CoordinatorStartup(),设置协调器的MAC层相关参数,例如协调器扩展地址、短地址、Beacon帧的内容、接收机空闲时保持打开状态、是否允许入网等一系列参数,设置完成后,调用MAC_MlmeStartReq()来启动协调器网络,MAC层完成此操作后,以MAC_MLME_START_CNF消息通知应用层。
注意,协调器的扩展地址、短地址和PAN ID都是固定写在程序中的,终端设备的扩展地址前6个字节是固定的,后两个字节随机生成,短地址由协调器为其分配,PAN ID是写死的。
协调器建立网络请求:
因为是非信标模式,建立网络的前提是周围没有其他网络,发出一个信标探测即可。
终端先发起扫描,发现扫描里面有Beacon的响应,产生MAC_MLME_BEACON_NOTIFY_IND消息,然后通过MAC层的回调函数,向应用层发起MAC_MLME_BEACON_NOTIFY_IND消息。终端在解析超帧结构时,会获取超帧结构中的BO和SO,将其设置为自身的BO和SO值,这样,就可以加入任何不同类型的网络了。在随后的MAC层的扫描确认响应MAC_MLME_SCAN_CNF中,通过一些条件判断,然后发送请求连接指令,MAC_MlmeAssociateReq,当MAC层完成了此动作,以MAC_MLME_ASSOCIATE_CNF通知应用层。
终端扫描过程的抓包如下:
终端请求加入网络的抓包如下:
至此,协调器和终端之间已经建立好联系。接下来就是双发收发数据。
协调器向终端发送数据,由于是直接模式,协调器无需等待终端的poll请求,想发就发。
实际的数据发送很简单,就不截图了。收发双方通过预先设定好的发送数据内容来相互确认发送的正确性与否。唯一要注意的是,协调器发送数据,会向所有已经连接的设备发送数据。终端设备收到数据后,会将数据原封不动的回显给协调器。
以上就是非信标直接模式的整个过程。
2. 非信标间接模式
有了上面非信标直接模式的经验,现在分析非信标间接模式就清楚明白多了。这个模式与第一种模式的区别就在终端设备是以间接模式接入网络,也就是说,终端设备会定时向协调器发送poll轮询,已获知协调器是否有发给自己的数据,协调器那边发送数据,也只有等到对于终端发来数据请求,才会真正给终端发送数据,再次之前,都是缓存着的。
从程序上来看,间接模式下,终端在于协调器建立联系后开启了一个MSA_POLL_EVENT定时事件,核心是执行MAC_MlmePollReq接口函数。当MAC层完成Poll操作时,会反馈给应用层MAC_MLME_POLL_CNF事件。如果协调器有数据要发送给终端,则MAC_MLME_POLL_CNF事件的状态结果为SUCCESS,同时向终端发送对于的数据,终端的MAC层收到此数据后,向应用层发送MAC_MCPS_DATA_IND事件通知。
终端发送poll请求数据的抓包:
这里,让人奇怪的一点是,poll操作会反馈MAC_MLME_POLL_CNF消息给应用层,但是在应用层,switch的条件判断也判断到该信号的产生,但是单步的时候进不去,设置断点无效,怀疑可能被编译器优化了,在响应语句里面操作一些全局变量,果然又可以进去了。
3. 信标模式直接模式
在信标模式下,整个网络自己会维护同步关系,因此不需要轮训,终端设备只会有直接模式接入网络这一种情况。
设置方法见学习笔记(一).在这里要注意一点,信标模式下,协调器的BO和SO数值要和终端的BO、SO数值一致,否则无法接入网络,因为信标网络的标识就是SO和BO,不同的SO和BO代表不同的信标网络,要入网,肯定要在同一信标网络下才行的。
信标模式下,协调器建立网络的扫描方式改为被动扫描,顾名思义,被动用于监听信道上的beacon帧。信标网络相比于非信标网络来说,除了网络的自动同步外,允许协调器设备进入低功耗模式,但能否真正进入,还要看其他相关设置。
信标模式协调器建网抓包:
在没有其他终端入网之前,协调器是不用发送信标同步信号的,信标是用来同步的,既然网络目前只有一个节点,那也就没有必要同步啦。
在允许协调器进入代码中,TI的代码有一处写的不好,
#define MSA_PWR_MGMT_ENABLED FALSE /* Enable or Disable power saving */
明明是使能宏,数值却是FALSE. 调试了一会儿就发现了这个问题,TI这份代码估计是不想让协调器进入省电模式。像这种定义宏含义与实际设定的值不符合的情况,就是个大坑,自己别挖坑,也要提防着代码里面这样的坑。
经过初步的测试,发现信标网络的建网和入网时间都很长,可能是需要扫描每一个信道上是否有信标响应,16个信道依次等待超时造成的。对于信标网络的终端设备,有如下额外的处理流程:
设置好相关的BO和SO的值就,然后开启同步请求,如果MAC层发现失步了,则会向应用层发送MAC_MLME_SYNC_LOSS_IND事件通知。协调器发现自己有子节点后,开始定时发送信标帧,默认时间为15s。现有的代码,没有对同步帧进行进一步的处理。
信标模式下,协调器主动向终端发送数据的抓包:
信标模式下,终端主动向协调器发送数据的抓包:
好了,以上就是三种不同方式的网络建立和收发数据的总体流程。下面,要开始介绍安全相关的东西。
4. 安全传输
安全传输,就是开启MAC层的加密功能,以非信标模式下的为例子,安全模式,只不过是多加了两个宏,一个是FEATURE_MAC_SECURITY,另一个是HAL_AES宏。在代码中的体现,就是添加了很多有关安全的初始化。
MAC层有四种传输帧,信标帧、数据帧、ACK帧、命令帧。PHY层的PIB数据库,对于输出帧和输入帧,定义了不同的安全属性。主要有四个比较重要的参数,下面一一来介绍。
uint8 msa_securityLevel = MAC_SEC_LEVEL_NONE; //这个参数用于实际传输过程中的加密等级
uint8 msa_keyIdMode = MAC_KEY_ID_MODE_NONE; //密钥索引的模式
uint8 msa_keySource[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8 msa_keyIndex = 0; //密钥索引值
这样来介绍吧,MAC为了加密,肯定要用到AES硬件加密引擎,有引擎就肯定有密钥,有密钥就肯定不止一个密钥,很多个密钥怎么组织呢?那就把他们放在一个表里,取个名字叫做msa_KeyTable,有keyTableEntries个这样的表。这么多密钥,如果不指定,肯定要用一个默认的密钥,这个默认的密钥叫做msa_keyDefaultSource,实际使用的key为msa_keySource。对不同类型的帧,有着不同的安全级别要求,MAC层有4种帧,因此,也要个对于的表,叫做msa_securityLevelTable
下面是终端设备发送加密内容的抓包图:
在安全控制域中,Level为加密强度,密钥模式为1,密钥索引为3.后面的为加密的MAC负载信息。需要注意的一点是,在加密通讯中,扫描网络、请求入网是不用加密的。在接收方,当传递到应用层时,已经是解密后的数据了,无需做其他的处理。
总结一下:以上就是TIMAC基本的应用和大概的入网流程的解释,还有很多地方没有深入去理解,希望能够帮助到大家。
能够分享的技术,才能让别人看到你的不足。我有很多不足,希望能够不断改进自己。