您的位置:首页 > 理论基础 > 数据结构算法

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();//即包头长度加上已使用的数据段长度
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: