本文介绍了Rime协议栈单跳单播连接建立过程的连接结构体,包括rucb_conn --> runicast_conn --> stunicast_conn --> unicast_conn --> broadcast_conn --> abc_conn。 PS:为了叙述方便,将连接建立过程的连接结构体单独成文,阅读时,请结合以下博文:

1. 概述

1.1 讨论范围

Rime协议栈提供单跳单播、单跳广播、多跳三种功能,本文仅介绍单跳单播(Single-hop unicast)连接相关的结构体,如下图红色箭头所示:

img

图1 Rime协议栈系统框图

图1蓝色下划线sucstuc是两篇不同论文的名称,事实上是同一个意思。因源代码用的也是stuc,故在以后讨论使用stuc。关于图1各名词解释,详见博文《概述及学习资料》。

1.2 连接结构体概述

使用Rime协议栈进行通信之前,需要建立连接,也就需要保存该连接一些信息(如发送者、接收者),Rime协议栈用一系列结构体保存这些链接状态信息。而建立连接过程说白了就是设置这些结构体相应的成员变量,所以有必要了解下连接结构体各成员变量的含义。Rime是层次型协议栈,上层的连接结构体嵌套着下层的结构体,自顶向下的连接结构体如下:

rucb_conn-->runicast_conn-->stunicast_conn-->unicast_conn-->broadcast_conn-->abc_conn

连接结构体与连接建立、回调结构体间对应关系如下图:

open、coon、callbacks对应关系源文件:open、coon、callbacks对应关系.vsd

img

图1 open、coon、callbacks对应关系二、rucb_conn

2. rucb_conn

rucb是块传输(Bulk transfer)层[1],可以理解成传输层。结构体rucb_conn源码如下:

struct rucb_conn
{
  struct runicast_conn c;
  const struct rucb_callbacks *u;
  rimeaddr_t receiver, sender;
  uint16_t chunk;
  uint8_t last_seqno;
};

结构体rucb_conn各成员变量含义如下:

c

详情见第三部分。

u

结构体rucb_callbacks有3个函数指针成员变量写数据块write_chunk、读数据块read_chunk、超时timedout,由用户自己实现,详情见博文《Rime协议栈单跳单播建立连接之callbacks》。

receiver、sender

用于标识接收者和发送者。这里的receiver是指目的节点的接收地址。

chunk

数据块数目。

last_seqno

一次数据发送多个片段的最后一个序列号,当接收端接收到数据时,判断其序列号是否等于最后一个序列号,若等于则不接收(即接收到最后一个数据块,停止接收)。

3. runicast_conn

ruc是可靠通信的另一层,该层主要实现确认和序列功能(acknowledgments and sequencing)[1]。结构体runicast_conn源代码如下:

struct runicast_conn
{
  struct stunicast_conn c;
  const struct runicast_callbacks *u;
  uint8_t sndnxt;
  uint8_t is_tx;
  uint8_t rxmit;
  uint8_t max_rxmit;
};

结构体runicast_conn各成员变量含义如下:

c

详情见第四部分。

u

结构体runicast_callbacks有3个函数指针成员变量接收recv、发送sent、超时timedout,分别映射到接收recv、确认acked、超时timedout函数(在contiki/core/net/rime/rucb.c实现),详情见博文《Rime协议栈单跳单播建立连接之callbacks》。

sndnxt

sndnxt表示Send Next,想想报文分片的时候,sndnxt为下一个待发送数据片在整个报文的偏移量,即下一个待发送数据片的序列号。(这点需阅读源代码加以验证)

is_tx

is_tx表示is transmitting,用来标记连接线路上是否有数据在传输(0表示无数据传输,1表示有数据在传输)。

rxmit

rxmit表示retransmissions,记录重传次数。

max_rxmit

max_rxmit表示maximum retransmissions,最大重传次数。当重传次数大于等于最大重传次数时,取消传输。

4. stunicast_conn

stuc是可靠通信的另一层,该层在给定的时间间隔不断地重发数据包,直到上层让其停止。为了防止无限重发,需要指定最大重发次数(maximum retransmission number)[1],结构体stunicast_conn源代码如下:

struct stunicast_conn
{
  struct unicast_conn c;
  struct ctimer t;
  struct queuebuf *buf;
  const struct stunicast_callbacks *u;
  rimeaddr_t receiver;
};

结构体stunicast_conn各成员变量含义如下:

c

详情见第五部分。

u

结构体stunicast_callbacks有2个函数指针成员变量接收recv、发送sent,分别映射到接收recv_from_stunicast、发送sent_by_stunicast函数(在contiki/core/net/rime/runicast.c实现),详情见博文《Rime协议栈单跳单播建立连接之callbacks》。

t

Contiki提供5个定时器模型,即timerstimerctimeretimerrtimerctimer由Rime使用,计时器到期调用某函数(Active timer, calls a function when it expires, Used by Rime)。正如上面所说,stuc层在给定的时间间隔不断地重发数据包,t表示该时间间隔(待读源码验证)。

buf

queuebuf表示queue buffer,队列缓冲区。所有发出和收到的数据包都被存储在一个缓冲区Rime buffer,Rime缓冲区包含应用程序数据和数据包属性(packet attributes)。一些需要数据包队列(queue packets)协议能够从队列缓冲池(a pool of Queue buffers)动态分配队列缓冲区(queue buffer),被分配后,Rime缓冲区的内容被拷贝到队列缓冲区[2]。

receiver

这里的receiver不同于rucb_conn->receiver,数据包从源到目的地传输,需要经过若干节点,rucb_conn->receiver指的是目的节点的地址,而stunicast_conn->receiver指的是直接接收者地址(从源到目的路径上中间节点地址)。(待读源码验证)

4.1 queuebuf

queuebuf结构体定义如下:

struct queuebuf {
#if QUEUEBUF_DEBUG
    struct queuebuf *next;
    const char    *file;
    int        line;
    clock_time_t    time;
#endif
    uint16_t        len;
    uint8_t            data[PACKETBUF_SIZE];
    struct packetbuf_attr    attrs[PACKETBUF_NUM_ATTRS];
    struct packetbuf_addr    addrs[PACKETBUF_NUM_ADDRS];
};

#ifdef PACKETBUF_CONF_SIZE
    #define PACKETBUF_SIZE PACKETBUF_CONF_SIZE
#else
    #define PACKETBUF_SIZE 128
#endif
#define PACKETBUF_NUM_ATTRS    (PACKETBUF_ATTR_MAX - PACKETBUF_NUM_ADDRS)
#define PACKETBUF_NUM_ADDRS    4

PACKETBUF_ATTR_MAX包含在一个枚举enum类型中,如 :

enum {
    PACKETBUF_ATTR_NONE,
    /* Scope 0 attributes: used only on the local node. */
    PACKETBUF_ATTR_CHANNEL,
    PACKETBUF_ATTR_NETWORK_ID,
    PACKETBUF_ATTR_LINK_QUALITY,
    PACKETBUF_ATTR_RSSI,
    PACKETBUF_ATTR_TIMESTAMP,
    PACKETBUF_ATTR_RADIO_TXPOWER,
    PACKETBUF_ATTR_LISTEN_TIME,
    PACKETBUF_ATTR_TRANSMIT_TIME,
    PACKETBUF_ATTR_MAX_MAC_TRANSMISSIONS,
    PACKETBUF_ATTR_MAC_SEQNO,
    PACKETBUF_ATTR_MAC_ACK,
    /* Scope 1 attributes: used between two neighbors only. */
    PACKETBUF_ATTR_RELIABLE,
    PACKETBUF_ATTR_PACKET_ID,
    PACKETBUF_ATTR_PACKET_TYPE,
    PACKETBUF_ATTR_REXMIT,
    PACKETBUF_ATTR_MAX_REXMIT,
    PACKETBUF_ATTR_NUM_REXMIT,
    PACKETBUF_ATTR_PENDING,

    /* Scope 2 attributes: used between end-to-end nodes. */
    PACKETBUF_ATTR_HOPS,
    PACKETBUF_ATTR_TTL,
    PACKETBUF_ATTR_EPACKET_ID,
    PACKETBUF_ATTR_EPACKET_TYPE,
    PACKETBUF_ATTR_ERELIABLE,
    /* These must be last */
    PACKETBUF_ADDR_SENDER,
    PACKETBUF_ADDR_RECEIVER,
    PACKETBUF_ADDR_ESENDER,
    PACKETBUF_ADDR_ERECEIVER,

    PACKETBUF_ATTR_MAX
};

5. unicast_conn

uc(unicast abstraction)将上层的数据包添加一个接收者头部(adds a receiver header field)[1],结构体unicast_conn源代码如下:

struct unicast_conn
{
  struct broadcast_conn c;
  const struct unicast_callbacks *u;
};

结构体unicast_conn各成员变量含义如下:

c

详情见第六部分。

u

结构体unicast_callbacks有2个函数指针成员变量接收recv、发送sent,分别映射到接收recv_from_uc、发送sent_by_uc函数(在contiki/core/net/rime/stunicast.c实现),详情见博文《Rime协议栈单跳单播建立连接之callbacks》。

6. broadcast_conn

ibc(identified sender best-effort broadcast)将上层的数据包添加一个发送者身份(sender identity)头部[1],结构体broadcast_conn源代码如下:

struct broadcast_conn
{
  struct abc_conn c;
  const struct broadcast_callbacks *u;
};

结构体broadcast_conn各成员变量含义如下:

c

详情见第七部分。

u

结构体broadcast_callbacks有2个函数指针成员变量接收recv、发送sent,分别映射到接收recv_from_broadcast、发送sent_by_broadcast函数(在contiki/core/net/rime/unicast.c实现),详情见博文《Rime协议栈单跳单播建立连接之callbacks》。

7. abc_conn

abc(anonymous broadcast,匿名广播)将数据包通过无线射频驱动(radio driver)发出去,接收来自无线射频驱动所有的包并交给上层[1]。结构体abc_conn源代码如下:

struct abc_conn
{
  struct channel channel;
  const struct abc_callbacks *u;
};

结构体abc_conn各成员变量含义如下:

channel

Rime协议栈所有通信都是通过通道channel标识的,即两个应用进程通信需要相同的channel,关于channel介绍见博文《通道channel》。

u

结构体abc_callbacks有2个函数指针成员变量接收recv、发送sent,分别映射到接收recv_from_abc、发送sent_by_abc函数(在contiki/core/net/rime/broadcast.c实现),详情见博文《Rime协议栈单跳单播建立连接之callbacks》。

参考资料:

[1] 博文《概述及学习资料

[2] Adam Dunkels,Fredrik Osterlind,Zhitao He. An Adaptive Communication Architecture for Wireless Sensor Networks[J]

本文系Spark & Shine原创,转载需注明出处本文最近一次修改时间 2022-03-22 22:48

results matching ""

    No results matching ""