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匿名广播消息,其实很简单,参考引子博客。相关文章推荐
- 关于简历不得不说的那些事儿
- C语言应用初步感受
- 数塔python
- 读书笔记和sprint总结
- PostgreSQL索引分类及使用
- 计算结果总是100的程序
- 使用HashMap,如果key是自定义的类,就必须重写hashcode()和equals()。
- JAVA反射机制(二)
- Spring Data JPA 1.10.1 详解一之Spring Data JPA介绍
- 一个屌丝程序猿的人生(十八)
- Mapreduce参数调节
- java中创建线程主要有三种方式
- 1005. 继续(3n+1)猜想 (25)
- qt中绘图事件paintEvent 的用法
- java bean
- POJ3169-Layout
- gson和bson4jackson 的简单记录
- 从零开始配置Ubuntu Server 14.04 图形界面、Caffe安装及远程连接
- 利用DOM进行评论的发表与删除
- mysql 笔记分享