Rime协议学习笔记:(二)主要数据结构(1)
2016-11-21 22:52
477 查看
1.节点地址linkaddr
contiki3.0版本之前用rimeaddr(/core/rime/rimeaddr.[c/h])来表示节点的地址,3.0开始改用linkaddr表示所有节点地址,linkaddr不仅在rime协议栈中用到,还被其它很多模块用到。表示节点地址的库:linkaddr;位置:/core/net/linkaddr.[c/h]
1.1 linkaddr相关定义
typedef union { unsigned char u8[LINKADDR_SIZE]; #if LINKADDR_SIZE == 2 uint16_t u16; #endif /* LINKADDR_SIZE == 2 */ } linkaddr_t;//表示网络地址 typedef union { uint8_t u8[8]; uint16_t u16[4]; } linkaddr_extended_t;//表示网络扩展地址
1.2 linaddr主要操作
主要有三个操作,较为简单,现给出源码中的官方注释:voidlinkaddr_copy(linkaddr_t *dest, const linkaddr_t *from):
intlinkaddr_cmp(const linkaddr_t *addr1, const linkaddr_t *addr2):
voidlinkaddr_set_node_addr(linkaddr_t *addr):
2.数据包缓冲区
表示数据包缓冲区的库:packetbuf;位置:/core/net/packetbuf.[c/h]。packetbuf.[c/h]中代码可以分为两部分:packetbuf_attr(数据包属性)和packetbuf(数据包)。
2.1 packetbuf_attr
(1)相关结构体定义如下:typedef uint16_t packetbuf_attr_t; /*packetbuf_attr定义包属性*/ struct packetbuf_attr { packetbuf_attr_t val; }; /*packetbuf_addr定义包地址*/ struct packetbuf_addr { linkaddr_t addr; }; struct packetbuf_attr packetbuf_attrs[PACKETBUF_NUM_ATTRS]; struct packetbuf_addr packetbuf_addrs[PACKETBUF_NUM_ADDRS];
(2)属性的分类如
4000
下:
#define PACKETBUF_ATTR_PACKET_TYPE_DATA 0 #define PACKETBUF_ATTR_PACKET_TYPE_ACK 1 #define PACKETBUF_ATTR_PACKET_TYPE_STREAM 2 #define PACKETBUF_ATTR_PACKET_TYPE_STREAM_END 3 #define PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP 4
(3)属性值如下:每个部分适用于不同的节点通信
/*定义在一个枚举中*/ enum { PACKETBUF_ATTR_NONE, /* Scope 0 attributes: used only on the local node. */ PACKETBUF_ATTR_CHANNEL,//开始定义ATTR 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, PACKETBUF_ATTR_IS_CREATED_AND_SECURED, /* Scope 1 attributes: used between two neighbors only. */ #if PACKETBUF_WITH_PACKET_TYPE PACKETBUF_ATTR_PACKET_TYPE, #endif #if NETSTACK_CONF_WITH_RIME PACKETBUF_ATTR_PACKET_ID, PACKETBUF_ATTR_RELIABLE, PACKETBUF_ATTR_REXMIT, PACKETBUF_ATTR_MAX_REXMIT, PACKETBUF_ATTR_NUM_REXMIT, #endif /* NETSTACK_CONF_WITH_RIME */ PACKETBUF_ATTR_PENDING, PACKETBUF_ATTR_FRAME_TYPE, #if LLSEC802154_SECURITY_LEVEL PACKETBUF_ATTR_SECURITY_LEVEL, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_0_1, PACKETBUF_ATTR_FRAME_COUNTER_BYTES_2_3, #if LLSEC802154_USES_EXPLICIT_KEYS PACKETBUF_ATTR_KEY_ID_MODE, PACKETBUF_ATTR_KEY_INDEX, PACKETBUF_ATTR_KEY_SOURCE_BYTES_0_1, #endif /* LLSEC802154_USES_EXPLICIT_KEYS */ #endif /* LLSEC802154_SECURITY_LEVEL */ /* Scope 2 attributes: used between end-to-end nodes. */ #if NETSTACK_CONF_WITH_RIME PACKETBUF_ATTR_HOPS, PACKETBUF_ATTR_TTL, PACKETBUF_ATTR_EPACKET_ID, PACKETBUF_ATTR_EPACKET_TYPE, PACKETBUF_ATTR_ERELIABLE, #endif /* NETSTACK_CONF_WITH_RIME */ /* These must be last */ PACKETBUF_ADDR_SENDER,//开始定义ADDR PACKETBUF_ADDR_RECEIVER, #if NETSTACK_CONF_WITH_RIME PACKETBUF_ADDR_ESENDER, PACKETBUF_ADDR_ERECEIVER, #endif /* NETSTACK_CONF_WITH_RIME */ PACKETBUF_ATTR_MAX };
(4)数据包属性相关操作如下:
/*①packetbuf_attr_clear:将两个数组(packetbuf_attrs、packetbuf_addrs)清零*/ void packetbuf_attr_clear(void) { int i; for(i = 0; i < PACKETBUF_NUM_ATTRS; ++i) { packetbuf_attrs[i].val = 0; } for(i = 0; i < PACKETBUF_NUM_ADDRS; ++i) { linkaddr_copy(&packetbuf_addrs[i].addr, &linkaddr_null); } }
/* ②packetbuf_attr_copyto:将数组packetbuf_attrs、packetbuf_addrs分别拷贝给attrs、addrs*/ 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)); }
/*③packetbuf_attr_copyfrom:从attrs、addrs拷贝数据到packetbuf_attrs、packetbuf_addrs*/ 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)); }
/*④packetbuf_set_attr:设置属性数组中对应属性的值*/ #if !PACKETBUF_CONF_ATTRS_INLINE 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);// PACKETBUF_ADDR_SENDER代表接收者的地址 return 1; }
/* ⑦packetbuf_addr:返回目的地址*/ const linkaddr_t * packetbuf_addr(uint8_t type) { return &packetbuf_addrs[type - PACKETBUF_ADDR_FIRST].addr; }
/* ⑧packetbuf_holds_broadcast:判断packetbuf中是否包含广播地址*/ #endif /* PACKETBUF_CONF_ATTRS_INLINE */ int packetbuf_holds_broadcast(void) { return linkaddr_cmp(&packetbuf_addrs[PACKETBUF_ADDR_RECEIVER - PACKETBUF_ADDR_FIRST].addr, &linkaddr_null);//比较PACKETBUF_ADDR_ RECEIVER和linkaddr_null的值是否相等 }
2.2 packetbuf
(1)数据包长度相关定义如下:/* PACKETBUF_SIZE定义数据包缓冲区数据部分大小为128字节*/ #ifdef PACKETBUF_CONF_SIZE #define PACKETBUF_SIZE PACKETBUF_CONF_SIZE #else #define PACKETBUF_SIZE 128 #endif /* PACKETBUF_HDR_SIZE定义数据包缓冲区头部大小为48字节*/ #ifdef PACKETBUF_CONF_HDR_SIZE #define PACKETBUF_HDR_SIZE PACKETBUF_CONF_HDR_SIZE #else #define PACKETBUF_HDR_SIZE 48 #endif
(2)相关变量定义:
static uint16_t buflen, bufptr;//buflen代表数据包缓冲区已使用的长度;bufptr是数据包缓冲区指针 static uint8_t hdrptr;// 数据包缓冲区包头指针 static uint8_t *packetbufptr;//数据包缓冲区数据部分指针 static uint32_t packetbuf_aligned[(PACKETBUF_SIZE + PACKETBUF_HDR_SIZE + 3) / 4]; static uint8_t *packetbuf = (uint8_t *)packetbuf_aligned;
(3)数据包相关操作:
/* ①packetbuf_clear :清空数据包缓冲区*/ void packetbuf_clear(void){ buflen = bufptr = 0; hdrptr = PACKETBUF_HDR_SIZE;//将指针hdrptr指向缓冲区包头空间的末尾 packetbufptr = &packetbuf[PACKETBUF_HDR_SIZE];//将指针packetbufptr指向数据包缓冲区数据部分 packetbuf_attr_clear();//调用packetbuf_attr_clear,即清空两个数组 }
/*② packetbuf_clear_hdr:将头部空间清空,以备数据包的继续发送*/ void packetbuf_clear_hdr(void){ hdrptr = PACKETBUF_HDR_SIZE; }
/*③packetbuf_copyfrom:从from中拷贝长度为len的数据到缓冲区数据部分中*/ int packetbuf_copyfrom(const void *from, uint16_t len){ uint16_t l; packetbuf_clear();//先将缓冲区清空 l = len > PACKETBUF_SIZE? PACKETBUF_SIZE: len;//将PACKETBUF_SIZE和len中较小者传递给l memcpy(packetbufptr, from, l);//c/c++拷贝函数从源from所指的内存地址的起始位置开始拷贝l个字节到目标packetbufptr所指的内存地址的起始位置中 buflen = l; return l; }
/*④packetbuf_compact:*/ void packetbuf_compact(void){ int i, len; if(bufptr > 0) { len = packetbuf_datalen() + PACKETBUF_HDR_SIZE;// for(i = PACKETBUF_HDR_SIZE; i < len; i++) { packetbuf[i] = packetbuf[bufptr + i]; } bufptr = 0; } }
/*⑤packetbuf_copyto_hdr:将包头数据拷贝到to里*/ int packetbuf_copyto_hdr(uint8_t *to){ memcpy(to, packetbuf + hdrptr, PACKETBUF_HDR_SIZE - hdrptr); return PACKETBUF_HDR_SIZE - hdrptr; }
/*⑥packetbuf_copyto:将包头和数据部分拷贝到to里*/ int packetbuf_copyto(void *to){ if(PACKETBUF_HDR_SIZE - hdrptr + buflen > PACKETBUF_SIZE) { return 0; }//数据包过大 memcpy(to, packetbuf + hdrptr, PACKETBUF_HDR_SIZE - hdrptr);//将包头数据拷贝到to里(同packetbuf_copyto_hdr) memcpy((uint8_t *)to + PACKETBUF_HDR_SIZE - hdrptr, packetbufptr + bufptr, buflen);//将数据段中的数据拷贝到to里 return PACKETBUF_HDR_SIZE - hdrptr + buflen; }
/*⑦packetbuf_datalen:获取数据包缓冲区已使用的长度*/ uint16_t packetbuf_datalen(void){ return buflen; }
/*⑧packetbuf_hdrlen:获取缓冲区包头的长度*/ uint8_t packetbuf_hdrlen(void){ uint8_t hdrlen; hdrlen = PACKETBUF_HDR_SIZE - hdrptr; }
/*⑨packetbuf_totlen:获取整个缓冲区当前长度*/ uint16_t packetbuf_totlen(void){ return packetbuf_hdrlen() + packetbuf_datalen();//即包头长度加上已使用的数据段长度 }
相关文章推荐
- Rime协议学习笔记:(二)主要数据结构(2)
- Rime协议学习笔记:(八)可靠单播块传输rucb
- Rime协议学习笔记:(六)顽固单播stunicast
- Rime协议学习笔记:(七)可靠单播runicast
- Rime协议学习笔记:(十四)multihop多跳传输
- Rime协议学习笔记:(十一)ipolite广播
- Linux邻居协议 学习笔记 之二 通用邻居处理函数对应的数据结构的分析
- Rime协议学习笔记:(十二)netflood洪泛技术
- c#学习笔记之五 C与C#在几种主要数据结构在上区别 数组和枚举
- Rime协议学习笔记:(一)Rime协议概述
- Rime协议学习笔记:(十三)route discovery路由发现
- Rime协议学习笔记:(十)polite广播
- Rime协议学习笔记:(三)匿名广播abc
- LTE学习笔记(1)-LTE各层协议的主要作用
- 黑马程序员_网络编程学习笔记-->代码主要是对UDP协议的讲解
- 数据结构习题学习笔记(The Fourth Day)
- 数据结构学习笔记--二叉表达式树
- 数据结构习题学习笔记(The Third Day)
- 数据结构习题学习笔记(The Sixth Day)
- 数据结构习题学习笔记(The Fifth Day)