分类: 嵌入式
2013-01-22 17:34:47
摘要:
本文讲述Rime协议栈单跳单播的连接建立过程,即rucb_open --> runicast_open --> stunicast_open --> unicast_open --> broadcast_open --> abc_open --> channel_open。
一、概述
1.1 讨论范围
使用Rime协议栈进行通信,需要先建立连接。Rime协议栈提供单跳单播、单跳广播、多跳三种功能,本文仅介绍单跳单播(Single-hop unicast)连接建立过程,如下图红色箭头所示:
图1 Rime协议栈系统框图
图1蓝色下划线suc、stuc是两篇不同论文的名称,事实上是同一个意思。因源代码用的也是stuc,故在以后讨论使用stuc。关于图1各名词解释,详见博文《Contiki学习笔记:Rime协议栈概述及学习资料》。
1.2 连接建立概述
Rime是层次型协议栈,整个连接过程是通过上层调用下层服务来完成的,具体如下:
rucb_open --> runicast_open --> stunicast_open --> unicast_open --> broadcast_open --> abc_open --> channel_open
1.3 几点说明
使用Rime协议栈进行通信之前,需要建立连接,也就需要保存该连接一些信息(如发送者、接收者),Rime协议栈用一系列结构体保存这些链接状态信息。Rime每一层都有相应的连接结构体(以_conn结尾),上层嵌套下层,如下:
rucb_conn --> runicast_conn --> stunicast_conn --> unicast_conn --> broadcast_conn --> abc_conn
每个连接结构体都有相应的回调结构体(以_callbacks后缀结尾),该结构体的成员变量实为发送、接收函数指针。当接收到一个数据报,会调用该结构体相应的函数。回调结构体层次如下:
rucb_callbacks --> runicast_callbacks --> stunicast_callbacks --> unicast_callbacks --> broadcast_callbacks --> abc_callbacks
综上,连接建立_open、连接结构体_conn、回调结构体_callbacks间的关系如下图:
open、coon、callbacks对应关系源文件 open、coon、callbacks对应关系.rar
图2 open、coon、callbacks对应关系
为了便于叙述,将连接结构体_conn、回调结构体_callbacks分别单列成文,阅读本文后续内容,请结合如下博文:
博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之结构体rucb_conn》
博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之callbacks》
事实上,整个连接过程,就是设置相应的连接结构体成员变量,所以建立先阅读下博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之结构体rucb_conn》。
1.4 一个实例
文件contiki/examples/rime/example-rucb.c给出一个使用rucb实例,建立连接部分源代码如下:
定义连接结构体rucb,实现回调结构体中的函数并定义回调结构体rucb_call,指定一个通道号调用rucb_open建立连接。
二、rucb_open
rucb是块传输(Bulk transfer)层[1],可以理解成传输层,rucb_open源代码如下:
rimeaddr_copy
将Rime地址rimeaddr_null拷贝到sender,即将sender设为0.0(当Rime地址长度为2)。关于Rime地址rimeaddr_t及函数rimeaddr_copy相关介绍见博文《Contiki学习笔记:Rime协议栈之Rime地址rimeaddr_t》。
runicast_open
见第三部分。
c->u = u
结构体rucb_callbacks有3个函数指针成员变量写数据块write_chunk、读数据块read_chunk、超时timedout,这三个函数由用户自己实现,建立连接时作为参数传给rucb_open(见1.4例子)。
c->last_seqno = -1
一次数据发送多个片段的最后一个序列号,当接收端接收到数据时,判断其序列号是否等于最后一个序列号,若等于则不接收(即接收到最后一个数据块,停止接收)。last_seqno 初始化为-1。
三、runicast_open
ruc是可靠通信的另一层,该层主要实现确认和序列功能(acknowledgments and sequencing)[1],runicast_open源代码如下:
stunicast_open
见第四部分。
channel_set_attributes
设置通道channel属性,关于结构体通道channel及函数channel_set_attributes介绍见博文《Contiki学习笔记:Rime协议栈通道channel》。这里的参数attributes是数组指针,具体展开比较繁琐,遂单独成文《Contiki学习笔记:Rime协议栈Rime协议栈单跳单播头部》。
c->u = u
结构体runicast_callbacks有3个函数指针成员变量接收recv、发送sent、超时timedout,分别映射到接收recv、确认acked、超时timedout函数(在contiki/core/net/rime/rucb.c实现),详情见博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之callbacks》。
is_tx、rxmit、max_rxmit
is_tx、rxmit、max_rxmit是结构体runicast_conn的成员变量,均初始化为0,关于is_tx、rxmit、max_rxmit介绍见博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之结构体rucb_conn》。
四、stunicast_open
stuc是可靠通信的另一层,该层在给定的时间间隔不断地重发数据包,直到上层让其停止。为了防止无限重发,需要指定最大重发次数(maximum retransmission number)[1],stunicast_open源代码如下:
unicast_open
见本文第五部分。
c->u = u
结构体stunicast_callbacks有2个函数指针成员变量接收recv、发送sent,分别映射到接收recv_from_stunicast、发送sent_by_stunicast函数(在contiki/core/net/rime/runicast.c实现),详情见博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之callbacks》。
五、unicast_open
uc(unicast abstraction)将上层的数据包添加一个接收者头部(adds a receiver header field)[1],unicast_open源代码如下:
broadcast_open
见本文第六部分。
c->u = u
结构体unicast_callbacks有2个函数指针成员变量接收recv、发送sent,分别映射到接收recv_from_uc、发送sent_by_uc函数(在contiki/core/net/rime/stunicast.c实现),详情见博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之callbacks》。
channel_set_attributes
设置通道channel属性,关于结构体通道channel及函数channel_set_attributes介绍见博文《Contiki学习笔记:Rime协议栈通道channel》。这里的参数attributes是数组指针,具体展开比较繁琐,遂单独成文《Contiki学习笔记:Rime协议栈Rime协议栈单跳单播头部》。
六、broadcast_open
ibc(identified sender best-effort broadcast)将上层的数据包添加一个发送者身份(sender identity)头部[1],broadcast_open源代码如下:
abc_open
见本文第七部分。
c->u = u
结构体broadcast_callbacks有2个函数指针成员变量接收recv、发送sent,分别映射到接收recv_from_broadcast、发送sent_by_broadcast函数(在contiki/core/net/rime/unicast.c实现),详情见博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之callbacks》。
channel_set_attributes
设置通道channel属性,关于结构体通道channel及函数channel_set_attributes介绍见博文《Contiki学习笔记:Rime协议栈通道channel》。这里的参数attributes是数组指针,具体展开比较繁琐,遂单独成文《Contiki学习笔记:Rime协议栈Rime协议栈单跳单播头部》。
七、abc_open
abc(anonymous broadcast,匿名广播)将数据包通过无线射频驱动(radio driver)发出去,接收来自无线射频驱动所有的包并交给上层[1],abc_open源码如下:
channel_open
见本文第八部分。
c->u = callbacks
结构体abc_callbacks有2个函数指针成员变量接收recv、发送sent,分别映射到接收recv_from_abc、发送sent_by_abc函数(在contiki/core/net/rime/broadcast.c实现),详情见博文《Contiki学习笔记:Rime协议栈单跳单播建立连接之callbacks》。
channel_set_attributes
设置通道channel属性,关于结构体通道channel及函数channel_set_attributes介绍见博文《Contiki学习笔记:Rime协议栈通道channel》。这里的参数attributes是数组指针,具体展开比较繁琐,遂单独成文《Contiki学习笔记:Rime协议栈Rime协议栈单跳单播头部》。
八、channel_open
channel_open用于打开一个通道,实际上是设置通道号并将通道c加到channel链表中,详情见博文《Contiki学习笔记:Rime协议栈通道channel》,channel_open源代码如下:
至此,单跳单播连接整个过程介绍完毕:-)
参考资料:
[1] 博文《Contiki学习笔记:Rime协议栈概述及学习资料》
[2] Adam Dunkels,Fredrik Osterlind,Zhitao He. An Adaptive Communication Architecture for Wireless Sensor Networks[J]