您的位置:首页 > 其它

Contiki协议栈Rime:匿名广播abc

2016-05-27 22:45 239 查看

1 概述

终于再次看到引子博客了,兴奋~

匿名广播的英文是Anonymous Broad Cast,简称abc。匿名广播是Rime协议栈最基础的协议,它会向节点覆盖范围内的所有节点发送消息,并接收从其它节点发送过来的匿名广播消息。

相关代码位于contiki/core/net/rime/abc.[ch]。

2 相关定义

attributes

static const struct packetbuf_attrlist attributes[] =
{ ABC_ATTRIBUTES PACKETBUF_ATTR_LAST };


定义了包属性链表attributes,且用
ABC_ATTRIBUTES
PACKETBUF_ATTR_LAST
对其进行赋初值。

#define ABC_ATTRIBUTES
#define PACKETBUF_ATTR_LAST { PACKETBUF_ATTR_NONE, 0 }


ABC_ATTRIBUTES
的定义为空,
PACKETBUF_ATTR_LAST
的属性类型是
PACKETBUF_ATTR_NONE
,它用于判断一个属性链表是否到达结尾。

struct abc_callbacks

struct abc_callbacks {
/** Called when a packet has been received by the abc module. */
void (* recv)(struct abc_conn *ptr);
void (* sent)(struct abc_conn *ptr, int status, int num_tx);
};


定义了abc的回调函数结构体。当节点接收到另一个节点发送的匿名广播时,会调用结构体中的recv函数。

struct abc_conn

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


定义一个abc连接的结构体,其中:

channel:所绑定的通道

u:所绑定的回调函数的结构体

3 相关函数

abc_open

void abc_open(struct abc_conn *c, uint16_t channelno, const struct abc_callbacks *callbacks)
{
channel_open(&c->channel, channelno);
c->u = callbacks;
channel_set_attributes(channelno, attributes);
}


打开一个abc连接,其实就是打开一个通道,并设置通道的属性。

abc_close

void abc_close(struct abc_conn *c)
{
channel_close(&c->channel);
}


关闭abc连接,其实就是关闭打开的通道

abc_send

int abc_send(struct abc_conn *c)
{
return rime_output(&c->channel);
}


发送一个abc消息。

需要注意两点:

第一,发送消息前,我们需要将待发送的消息存放到packetbuf中。

第二,参数c必须指向一个之前进行abc_open()时所设置的abc连接。

rime_output()是Rime协议栈的一个接口,我们今后会讲到,可以先简单看一下其实现内容。

int rime_output(struct channel *c)
{
RIMESTATS_ADD(tx); //将发送统计状态+1
if(chameleon_create(c)) { // 创建包头
packetbuf_compact();    // 发送前对包进行紧凑处理

NETSTACK_LLSEC.send(packet_sent, c); //发送
return 1;
}
return 0;
}


abc_input

void abc_input(struct channel *channel)
{
struct abc_conn *c = (struct abc_conn *)channel;

if(c->u->recv) {
c->u->recv(c);
}
}


当本节点接收到其它节点的匿名广播时,会调用abc_input()函数,而该函数内部又会调用abc结构体中绑定的回调函数结构体中的recv函数。

这里有一点很奇怪,为啥可以将
struct channel *
类型的channel转变为
struct abc_conn *
类型的c,并调用
c->u->recv
呢?这个咋一眼看上去访问越界了呀,访问到未知的内存了。这涉及到MAC的回调机制,我们将在今后讲解。我们目前只需要知道,其实传入的
channel
指针所指向的地址存放了一个
struct abc_conn
的变量。

abc_sent

void abc_sent(struct channel *channel, int status, int num_tx)
{
struct abc_conn *c = (struct abc_conn *)channel;

if(c->u->sent) {
c->u->sent(c, status, num_tx);
}
}


当本节点发送了一个匿名广播消息时,无论发送成功或者失败,都会回调本函数。关于struct channel 到struct abc_conn 的转换的原因,与abc_input相同。

4 小结

关于如何编写程序,发送一个abc匿名广播消息,其实很简单,参考引子博客。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: