Contiki协议栈Rime:包属性packetbuf_attr

2024-04-08 04:32

本文主要是介绍Contiki协议栈Rime:包属性packetbuf_attr,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

更多的Contiki协议栈知识,请参考索引目录:
《Contiki协议栈:索引目录》

1 概述

  包属性其实属于下一篇博客《Contiki协议栈Rime:缓冲区管理packetbuf management》的一部分,但是它比较难以理解,所以单独抽出一篇博客对它做介绍。
  为了兼容其他协议,Rime不定义任何头部格式,而用包属性代替。一种属性是一种头部字段的抽象。当Rime协议栈中的子协议要发送一个包时,会传递一个属性链表下来。属性链表里包含了若干个属性,这些属性最终会被转换成头部的字段。
  该部分代码位于:contiki/core/net/packetbuf.[ch]

2 相关定义

packetbuf_attrs packetbuf_addrs

  Rime中定义了关于包属性的数组:

struct packetbuf_attr packetbuf_attrs[PACKETBUF_NUM_ATTRS];
struct packetbuf_addr packetbuf_addrs[PACKETBUF_NUM_ADDRS];

  其中,struct packetbuf_attr和struct packetbuf_addr分别定义为

typedef uint16_t packetbuf_attr_t;struct packetbuf_attr {packetbuf_attr_t val; // 一个16位无符号整型
};
struct packetbuf_addr {linkaddr_t addr; // 上一篇博客介绍的节点地址,16位或者64位
};

  数组的大小分别定义为:

#if NETSTACK_CONF_WITH_RIME
#define PACKETBUF_NUM_ADDRS 4
#else /* NETSTACK_CONF_WITH_RIME */
#define PACKETBUF_NUM_ADDRS 2
#endif /* NETSTACK_CONF_WITH_RIME */
#define PACKETBUF_NUM_ATTRS (PACKETBUF_ATTR_MAX - PACKETBUF_NUM_ADDRS)

  为什么PACKETBUF_NUM_ATTRS定义为PACKETBUF_ATTR_MAX - PACKETBUF_NUM_ADDRS?
  这是因为在定义属性的枚举变量时,将ADDR也当做了一种特殊属性,这样做的好处是可以将ADDR和ATTR统一处理(统一放在属性链表中,当Rime协议栈中的子协议将属性链表传递下来时,统一写到缓冲区packetbuf的头部)。请看下面

enum {PACKETBUF_ATTR_NONE,.../* Scope 2 attributes: used between end-to-end nodes. */
#if NETSTACK_CONF_WITH_RIMEPACKETBUF_ATTR_HOPS,PACKETBUF_ATTR_TTL,PACKETBUF_ATTR_EPACKET_ID,PACKETBUF_ATTR_EPACKET_TYPE,PACKETBUF_ATTR_ERELIABLE,          // 其实ATTR在这里就定义完了
#endif /* NETSTACK_CONF_WITH_RIME */    /* These must be last */PACKETBUF_ADDR_SENDER,             // 这里是ADDR的定义PACKETBUF_ADDR_RECEIVER,
#if NETSTACK_CONF_WITH_RIMEPACKETBUF_ADDR_ESENDER,PACKETBUF_ADDR_ERECEIVER,
#endif /* NETSTACK_CONF_WITH_RIME */PACKETBUF_ATTR_MAX                // 这里才是PACKETBUF_ATTR_MAX,包含ATTR+ADDR,所以ATTR=MAX-ADDR
};

struct packetbuf_attrlist

  前面说了,Rime协议栈的子协议在发送包时会传递一个属性链表下来,它的定义为:

struct packetbuf_attrlist {uint8_t type;uint8_t len;  // 单位是bit
};

  type:属性的类型。它直接对应于属性数组packetbuf_attrs或者packetbuf_addrs的下标
  len:该属性的长度。需要注意的是,此处长度的单位是位,而不是字节。属性的类型是packetbuf_attr_t,即uint16_t,因此可以推断,len的取值范围应该是0~16。(本宝宝好厉害呀,居然想到这儿了~~~)

3 相关函数

packetbuf_attr_clear

void packetbuf_attr_clear(void)
{int i;memset(packetbuf_attrs, 0, sizeof(packetbuf_attrs));//其实也可以用memset(packetbuf_addrs, 0, sizeof(packetbuf_addrs))吧?for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) {linkaddr_copy(&packetbuf_addrs[i].addr, &linkaddr_null);}
}

  很简单,清空两个属性数组packetbuf_attrs和packetbuf_addrs。

packetbuf_attr_copyto

void packetbuf_attr_copyto(struct packetbuf_attr *attrs, struct packetbuf_addr *addrs)
{memcpy(attrs, packetbuf_attrs, sizeof(packetbuf_attrs));memcpy(addrs, packetbuf_addrs, sizeof(packetbuf_addrs));
}

  很简单,将两个属性数组的内容拷贝给attrs和addrs

packetbuf_attr_copyfrom

void
packetbuf_attr_copyfrom(struct packetbuf_attr *attrs, struct packetbuf_addr *addrs)
{memcpy(packetbuf_attrs, attrs, sizeof(packetbuf_attrs));memcpy(packetbuf_addrs, addrs, sizeof(packetbuf_addrs));
}

  很简单,从attrs和addrs拷贝到两个属性数组中。

packetbuf_set_attr

int packetbuf_set_attr(uint8_t type, const packetbuf_attr_t val)
{
packetbuf_attrs[type].val = val;
return 1;
}
  很简单,设置属性数组中对应属性的值。

packetbuf_attr

packetbuf_attr_t
packetbuf_attr(uint8_t type)
{return packetbuf_attrs[type].val;
}

  很简单,返回属性数组中对于属性的值。

packetbuf_set_addr

int packetbuf_set_addr(uint8_t type, const linkaddr_t *addr)
{linkaddr_copy(&packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr, addr);return 1;
}

  很简单,设置属性数组中对应属性的值。

packetbuf_addr

const linkaddr_t *packetbuf_addr(uint8_t type)
{return &packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr;
}

  很简单,返回属性数组中对于属性的值。

4 小结

  这么抽象的东西,居然把它给阐释清楚了,我得意的笑~~
  但是说实话,初次接触时,难免会有很多地方难以理解,没关系,在继续看完我的后续几篇博客后,整个路就完全通了,然后大家都可以嘚瑟了O(∩_∩)O哈哈~

这篇关于Contiki协议栈Rime:包属性packetbuf_attr的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/884571

相关文章

滚雪球学Java(87):Java事务处理:JDBC的ACID属性与实战技巧!真有两下子!

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE啦,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好习惯,别被干货淹没了哦~ 🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!! 环境说明:Windows 10

【Linux】应用层http协议

一、HTTP协议 1.1 简要介绍一下HTTP        我们在网络的应用层中可以自己定义协议,但是,已经有大佬定义了一些现成的,非常好用的应用层协议,供我们直接使用,HTTP(超文本传输协议)就是其中之一。        在互联网世界中,HTTP(超文本传输协议)是一个至关重要的协议,他定义了客户端(如浏览器)与服务器之间如何进行通信,以交换或者传输超文本(比如HTML文档)。

【Go】go连接clickhouse使用TCP协议

离开你是傻是对是错 是看破是软弱 这结果是爱是恨或者是什么 如果是种解脱 怎么会还有眷恋在我心窝 那么爱你为什么                      🎵 黄品源/莫文蔚《那么爱你为什么》 package mainimport ("context""fmt""log""time""github.com/ClickHouse/clickhouse-go/v2")func main(

2024.9.8 TCP/IP协议学习笔记

1.所谓的层就是数据交换的深度,电脑点对点就是单层,物理层,加上集线器还是物理层,加上交换机就变成链路层了,有地址表,路由器就到了第三层网络层,每个端口都有一个mac地址 2.A 给 C 发数据包,怎么知道是否要通过路由器转发呢?答案:子网 3.将源 IP 与目的 IP 分别同这个子网掩码进行与运算****,相等则是在一个子网,不相等就是在不同子网 4.A 如何知道,哪个设备是路由器?答案:在 A

Modbus-RTU协议

一、协议概述 Modbus-RTU(Remote Terminal Unit)是一种基于主从架构的通信协议,采用二进制数据表示,消息中的每个8位字节含有两个4位十六进制字符。它主要通过RS-485、RS-232、RS-422等物理接口实现数据的传输,传输距离远、抗干扰能力强、通信效率高。 二、报文结构 一个标准的Modbus-RTU报文通常包含以下部分: 地址域:单个字节,表示从站设备

HTML5自定义属性对象Dataset

原文转自HTML5自定义属性对象Dataset简介 一、html5 自定义属性介绍 之前翻译的“你必须知道的28个HTML5特征、窍门和技术”一文中对于HTML5中自定义合法属性data-已经做过些介绍,就是在HTML5中我们可以使用data-前缀设置我们需要的自定义属性,来进行一些数据的存放,例如我们要在一个文字按钮上存放相对应的id: <a href="javascript:" d

Python中的属性装饰器:解锁更优雅的编程之道

引言 在Python的世界里,装饰器是一个强大的工具,它允许我们以一种非侵入性的方式修改函数或方法的行为。而当我们谈论“属性装饰器”时,则是在探讨如何使用装饰器来增强类中属性的功能。这不仅让我们的代码更加简洁、易读,同时也提供了强大的功能扩展能力。本文将带你深入了解属性装饰器的核心概念,并通过一系列实例展示其在不同场景下的应用,从基础到进阶,再到实际项目的实战经验分享,帮助你解锁Python编程

react笔记 8-17 属性绑定 class绑定 引入图片 循环遍历

1、绑定属性 constructor(){super()this.state={name:"张三",title:'我是一个title'}}render() {return (<div><div>aaaaaaa{this.state.name}<div title={this.state.title}>我是一个title</div></div></div>)} 绑定属性直接使用花括号{}   注

网络原理之TCP协议(万字详解!!!)

目录 前言 TCP协议段格式 TCP协议相关特性 1.确认应答 2.超时重传 3.连接管理(三次握手、四次挥手) 三次握手(建立TCP连接) 四次挥手(断开连接)  4.滑动窗口 5.流量控制 6.拥塞控制 7.延迟应答 8.捎带应答  9.基于字节流 10.异常情况的处理 小结  前言 在前面,我们已经讲解了有关UDP协议的相关知识,但是在传输层,还有

DNS协议基础笔记

1.定义 DNS(Domain Name System,域名系统)是互联网的一项核心服务,它作为将域名和 IP 地址相互映射的一个分布式数据库,能够使人更方便地访问互联网。 2.域名解析过程 当用户在浏览器中输入一个域名,浏览器首先会检查自己的缓存中是否有该域名对应的 IP 地址。本地 DNS 服务器收到查询请求后,首先会检查自己的缓存中是否有该域名对应的 IP 地址。根域名服务器收到查询请