Rime协议学习笔记:(十四)multihop多跳传输
2017-03-29 22:02
691 查看
十四.multihop多跳传输
multihop源码文件:contiki-3.0/core/net/rime/multihop.[c/h]multihop模块实现了多跳转发机制。使用multihop之前,必须已经用route_add函数建立了路由,路由的建立还使用到另一Rime模块route-discovery。multihop模块利用网络中每个节点的多跳转发功能将数据包发送给指定节点。应用或协议通过使用多跳原语来为选择下一跳邻居提供路由功能。如果multihop原语在发送数据包的过程中没找到合适的下一跳邻居,调用者会立即通告并可能选择发起一个路由选择进程。
14.1 multihop相关定义
multihop相关结构体:struct multihop_conn { /**多跳连接,建立在单跳单播基础上*/ struct unicast_conn c; const struct multihop_callbacks *cb; }; struct multihop_callbacks { /**用户自定义回调结构体*/ void (* recv)(struct multihop_conn *ptr, const linkaddr_t *sender, const linkaddr_t *prevhop, uint8_t hops); linkaddr_t *(* forward)(struct multihop_conn *ptr, const linkaddr_t *originator, const linkaddr_t *dest, const linkaddr_t *prevhop, uint8_t hops); };
multihop数据包相关属性:
/**multihop.c中的定义*/ static const struct packetbuf_attrlist attributes[] = {MULTIHOP_ATTRIBUTES PACKETBUF_ATTR_LAST}; /**multihop.h中的定义*/ #define MULTIHOP_ATTRIBUTES { PACKETBUF_ADDR_ESENDER, PACKETBUF_ADDRSIZE }, \ { PACKETBUF_ADDR_ERECEIVER, PACKETBUF_ADDRSIZE }, \ { PACKETBUF_ATTR_HOPS, PACKETBUF_ATTR_BIT * 5 }, \ UNICAST_ATTRIBUTES //在unicast数据包的基础上增加了发送者地址、指定接收者地址、跳数属性
14.2 主要操作
14.2.1 回调函数
(1)用户自定义回调函数:由用户在使用multihop时自己定义并调用,调用时封装在multihop_callbacks里。(2)系统回调函数为:unicast_callbacks,只定义接收回调函数。具体代码如下:
static const struct unicast_callbacks data_callbacks = { data_packet_received }; void data_packet_received(struct unicast_conn *uc, const linkaddr_t *from){ /**系统接收回调函数,处理收到的数据包,分为中间节点和指定接收节点两种情况*/ struct multihop_conn *c = (struct multihop_conn *)uc; linkaddr_t *nexthop; linkaddr_t sender, receiver; //拷贝数据包属性,避免因应用程序自身需要而将数据包属性重写或清除 linkaddr_copy(&sender, packetbuf_addr(PACKETBUF_ADDR_ESENDER)); linkaddr_copy(&receiver, packetbuf_addr(PACKETBUF_ADDR_ERECEIVER)); //打印收到数据包的信息 PRINTF("data_packet_received from %d.%d towards %d.%d len %d\n", from aecb ->u8[0], from->u8[1], packetbuf_addr(PACKETBUF_ADDR_ERECEIVER)->u8[0], packetbuf_addr(PACKETBUF_ADDR_ERECEIVER)->u8[1], packetbuf_datalen()); /*如果本节点地址和指定接收者地址相同,即数据包已到达指定接收者*/ if(linkaddr_cmp(packetbuf_addr(PACKETBUF_ADDR_ERECEIVER), &linkaddr_node_addr)) { PRINTF("for us!\n"); if(c->cb->recv) { //调用用户自定义接收回调 c->cb->recv(c, &sender, from, packetbuf_attr(PACKETBUF_ATTR_HOPS)); } } /*数据包还在中间转发节点*/ else { nexthop = NULL; if(c->cb->forward) { packetbuf_set_attr(PACKETBUF_ATTR_HOPS, packetbuf_attr(PACKETBUF_ATTR_HOPS) + 1); //将属性跳数加1 nexthop = c->cb->forward(c, &sender, &receiver, from, packetbuf_attr(PACKETBUF_ATTR_HOPS) - 1); //调用用户自定义forward回调 } if(nexthop) { PRINTF("forwarding to %d.%d\n", nexthop->u8[0], nexthop->u8[1]); unicast_send(&c->c, nexthop); //调用unicast_send转发数据包 } } }
14.2.2 multihop_open
void multihop_open(struct multihop_conn *c, uint16_t channel, const struct multihop_callbacks *callbacks) { unicast_open(&c->c, channel, &data_callbacks); channel_set_attributes(channel, attributes); c->cb = callbacks; }
14.2.3 multihop_close
void multihop_close(struct multihop_conn *c){ unicast_close(&c->c); }
14.2.4 multihop_send
int multihop_send(struct multihop_conn *c, const linkaddr_t *to){ /**用于发送节点发送数据,发送前先调用用户自定义的forward回调获取下一跳的地址*/ linkaddr_t *nexthop; if(c->cb->forward == NULL) { return 0; } packetbuf_compact(); //压缩包属性 packetbuf_set_addr(PACKETBUF_ADDR_ERECEIVER, to); //将指定的接收者地址压入包属性 packetbuf_set_addr(PACKETBUF_ADDR_ESENDER, &linkaddr_node_addr); //将发送者地址压入包属性 packetbuf_set_attr(PACKETBUF_ATTR_HOPS, 1); //设置属性跳数为1(初始化) nexthop = c->cb->forward(c, &linkaddr_node_addr, to, NULL, 0); //获取下一跳的地址 if(nexthop == NULL) { PRINTF("multihop_send: no route\n"); return 0; } else { PRINTF("multihop_send: sending data towards %d.%d\n",nexthop->u8[0], nexthop->u8[1]); unicast_send(&c->c, nexthop); //调用unicast_send向下一跳发送数据 return 1; } }
14.2.5 multihop_resend
void multihop_resend(struct multihop_conn *c, const linkaddr_t *nexthop){ /**重发数据,被mesh模块调用*/ unicast_send(&c->c, nexthop); }
相关文章推荐
- Rime协议学习笔记:(八)可靠单播块传输rucb
- FastSocket学习笔记~制定自已的传输协议~续~制定基于FastSocket的协议
- Rime协议学习笔记:(二)主要数据结构(1)
- Rime协议学习笔记:(十二)netflood洪泛技术
- 实验:传输层:UDP协议 学习笔记
- Object-c学习笔记十四-----协议
- UDP学习笔记——第二章传输层协议简介
- 本学习笔记TCP/IP传输协议
- Rime协议学习笔记:(十)polite广播
- Rime协议学习笔记:(三)匿名广播abc
- EZ-USB 68013学习笔记(二)——USB协议之传输的基本单元--包
- Rime协议学习笔记:(一)Rime协议概述
- Rime协议学习笔记:(七)可靠单播runicast
- Rime协议学习笔记:(十三)route discovery路由发现
- ATS 出现“400 Multi-Hop Cycle Detected”的原因及解决方法(Apache Traffic Server 学习笔记 3)
- Rime协议学习笔记:(六)顽固单播stunicast
- Rime协议学习笔记:(二)主要数据结构(2)
- 学习笔记:MFC实现http协议传输图片和文本
- Java学习笔记 UDP协议传输信息
- Rime协议学习笔记:(十一)ipolite广播