Contiki协议栈Rime:匿名广播abc

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_ATTRIBUTESPACKETBUF_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匿名广播消息,其实很简单,参考引子博客。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值