目录

一、RPL拓扑建立

主要可以分成两个部分拓扑创建+填充路由表

上行路由的建立(为了让节点给DODAG Root发送消息也即拓扑创建)

例子

下行路由建立(为了DODAG Root给节点发送消息也即路由表创建)

二、仿真文件的制作

三、仿真结果的分析

udp-server.c分析

udp-client.c分析

附录:关于RPL专业术语



一、RPL拓扑建立

RPL的核心思想是构建DAG拓扑,DODAG的构建基于邻居发现ND过程

  • 主要可以分成两个部分拓扑创建+填充路由表

    • 上行路由的建立(为了让节点给DODAG Root发送消息也即拓扑创建

      • DODAG根节点会首先广播DIO消息,(消息中包含DODAG ID、Rank值、所选择的OF等信息。)收到DIO消息的节点会按照以下流程图运行,加入拓扑的节点向DODAG Root发送包含自己路由信息的DAO控制消息,从而构建上行路由。

    • 上行路由的建立需要考虑的因素
      • 候选的邻居节点集合必须是Link-Local多播能到达的节点的子集。
      • 父节点的集合需要是候选邻居节点集合满足一定限制条件的子集。
      • 最优父节点集合是在上行路由中,考虑父节点集合中最佳下一跳节点的集合。通常来说,最优父节点是一个单独的父节点,不过若有些父节点都具有相同的优先级以及相同的Rank值,它们也可以作为一组最优父节点
    • 例子

    • 上层为节点分布图
      • 第一个图

        • 为最开始的时候,节点0和节点1为根节点,节点2和节点3在节点0的通信范围内,节点3和节点4在节点1的通信范围内。
      • 第二个图
        • 根节点开始向周围的节点发送DIO。

          • 节点2收到节点0的DIO,同时节点3收到节点0和节点1的DIO,
          • 节点4收到节点1的DIO。显然节点2和节点4分别选择了节点0和节点1作为自己的父节点,因为它们只收到了一个DIO。
          • 节点3通过OF计算选择了节点0作为自己的父节点。
      • 第三个图
        • 此时RPL Instance的状态就到了下层第三个图,节点2、节点3和节点4修改路由代价及Rank值信息后再向自己的周围节点转发DIO,

          • 节点2给节点5和节点6发送了DIO

            • 最后节点5将节点2当作父节点
          • 节点3和节点4都给节点6发送了DIO。,
            • 节点6通过目标函数选择节点4作为父节点,到此时整个拓扑结构都建立起来了。
        • 当节点5要向节点0发送数据时,会将数据默认发给其父节点2,然后通过节点2转发给节点0。但是此时如果节点0要给节点5发送数据,节点0还不知道发送的路径,因为此时向下路由还没有建立。
  • 下行路由建立(为了DODAG Root给节点发送消息也即路由表创建

    • 加入DODAG的节点会定时地向父节点发送包含自身前缀信息的DAO消息,父节点收到DAO消息之后,缓存子节点的前缀信息,在路由表中加上相应的路由信息,并回应DAO-ACK消息。这样在进行通信时,通过前缀匹配就可以将数据包发送到目的节点
    • 针对下行路由的建立,RPL定义了两种模式
      • 存储模式(Storing Mode)

意思是对于普通父节点,存储路由表

    • 一个节点收到DIO消息选择好父节点后,会向父节点发送DAO。DAO消息中包含了通过该节点可以到达的地址或者地址前缀信息。当父节点收到DAO后会处理DAO消息中的地址前缀,然后在路由表中加入相应的路由项。当父节点做完这些后就会向它的父节点发送DAO数据包。如此重复,直到整个向下的路由建立起来。
  • 非存储模式(Non-Storing Mode)

意思是对于普通父节点,不存储路由表

  • 一个节点收到DIO消息后不是向父节点发送DAO,而是向DODAG根节点发送 DAO。当然必须要通过父节点转发,当根节点收到所有节点发送过来的DAO消息后,就会建立到所有节点的路由表。当根节点要向下面的节点发送数据包时,根节点根据路由表构建源路由。

二、仿真文件的制作

  • 进入instantcontiki3.0
  • cd contiki/tools/cooja
  • ant run
  • 点击motes 
      • 点击sky mote
    • 文件目录examples/ipv6/rpl-udp/下
    • 选择文件 udp-server.c 编译,并点击create节点
  • 再一次点击motes,同样步骤选择文件为udp-client.c 编译 并创建create节点
  • simulation start
  • 注意:也可以直接打开rpl-udp.csc文件,进行仿真

三、仿真结果的分析

network:

udp-server.c分析

  • 功能

    • RPL-UDP Server负责建立UDP服务器端的连接,程序的主要功能是RPL网络的建立、UDP服务器端的建立和监听并接收客户端发送的信息。
  • 流程图

    • 程序流程

      • 初始化RPL DAG

        • uip_ds6_addr_add(&ipaddr, 0, ADDR_MANUAL);root_if = uip_ds6_addr_lookup(&ipaddr);if(root_if != NULL) {rpl_dag_t *dag;dag = rpl_set_root(RPL_DEFAULT_INSTANCE,(uip_ip6addr_t *)&ipaddr);uip_ip6addr(&ipaddr, UIP_DS6_DEFAULT_PREFIX, 0, 0, 0, 0, 0, 0, 0);rpl_set_prefix(dag, &ipaddr, 64);PRINTF("created a new RPL dag\n");} else {PRINTF("failed to create a new RPL DAG\n");}print_local_addresses();/* 数据接收器以 100% 的占空比运行,以确保高数据包接收率。*/NETSTACK_MAC.off(1);
          static void
          print_local_addresses(void)
          {int i;uint8_t state;PRINTF("Server IPv6 addresses: ");for(i = 0; i < UIP_DS6_ADDR_NB; i++) {state = uip_ds6_if.addr_list[i].state;if(state == ADDR_TENTATIVE || state == ADDR_PREFERRED) {PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr);PRINTF("\n");/* hack to make address "final" */if (state == ADDR_TENTATIVE) {uip_ds6_if.addr_list[i].state = ADDR_PREFERRED;}}}
          }
          
      • 建立UDP连接

        • server_conn = udp_new(NULL, UIP_HTONS(UDP_CLIENT_PORT), NULL);if(server_conn == NULL) {PRINTF("No UDP connection available, exiting the process!\n");PROCESS_EXIT();}udp_bind(server_conn, UIP_HTONS(UDP_SERVER_PORT));PRINTF("Created a server connection with remote address ");PRINT6ADDR(&server_conn->ripaddr);PRINTF(" local/remote port %u/%u\n", UIP_HTONS(server_conn->lport),UIP_HTONS(server_conn->rport));
          
      • 等待事件的到来,如果是tcpip事件就调用tcpip_handle函数

        • while(1) {PROCESS_YIELD();if(ev == tcpip_event) {tcpip_handler();} else if (ev == sensors_event && data == &button_sensor) {PRINTF("Initiaing global repair\n");rpl_repair_root(RPL_DEFAULT_INSTANCE);}}
          
      • tcpip_handler函数处理到来的tcpip事件,打印输出接收到的信息,并向客户端返还发送的数据信息

        • static void
          tcpip_handler(void)
          {char *appdata;if(uip_newdata()) {appdata = (char *)uip_appdata;appdata[uip_datalen()] = 0;PRINTF("DATA recv '%s' from ", appdata);PRINTF("%d",UIP_IP_BUF->srcipaddr.u8[sizeof(UIP_IP_BUF->srcipaddr.u8) - 1]);PRINTF("\n");
          #if SERVER_REPLYPRINTF("DATA sending reply\n");uip_ipaddr_copy(&server_conn->ripaddr, &UIP_IP_BUF->srcipaddr);uip_udp_packet_send(server_conn, "Reply", sizeof("Reply"));uip_create_unspecified(&server_conn->ripaddr);
          #endif}
          }
          

udp-client.c分析

  • 流程图

  • 程序流程
    • 建立UDP连接

      /* new connection with remote host */client_conn = udp_new(NULL, UIP_HTONS(UDP_SERVER_PORT), NULL); if(client_conn == NULL) {PRINTF("No UDP connection available, exiting the process!\n");PROCESS_EXIT();}udp_bind(client_conn, UIP_HTONS(UDP_CLIENT_PORT)); PRINTF("Created a connection with the server ");PRINT6ADDR(&client_conn->ripaddr);PRINTF(" local/remote port %u/%u\n",UIP_HTONS(client_conn->lport), UIP_HTONS(client_conn->rport));
      
    • 等待事件的到来
      • 如果是tcpip_event事件,

        • 通过调用tcpip_event函数处理
      • 如果是定时器超时事件

        if(etimer_expired(&periodic)) {etimer_reset(&periodic);ctimer_set(&backoff_timer, SEND_TIME, send_packet, NULL);
        
        • 则通过send_packet函数向服务器端发送数据,

          static void
          send_packet(void *ptr)
          {char buf[MAX_PAYLOAD_LEN];#ifdef SERVER_REPLYuint8_t num_used = 0;uip_ds6_nbr_t *nbr;nbr = nbr_table_head(ds6_neighbors);while(nbr != NULL) {nbr = nbr_table_next(ds6_neighbors, nbr);num_used++;}if(seq_id > 0){ANNOTATE("#A r=%d/%d,color=%s,n=%d %d\n", reply, seq_id,reply == seq_id ? "GREEN" : "RED", uip_ds6_route_num_routes(), num_used);}
          #endif /* SERVER_REPLY */seq_id++;PRINTF("DATA send to %d 'Hello %d'\n",server_ipaddr.u8[sizeof(server_ipaddr.u8) - 1], seq_id);sprintf(buf, "Hello %d from the client", seq_id);uip_udp_packet_sendto(client_conn, buf, strlen(buf),&server_ipaddr, UIP_HTONS(UDP_SERVER_PORT));
          }
  • motes output分析

ID:2即client节点

00:00.508    ID:2Rime 从地址 0.18.116.2.0.2.2.2 开始
00:00.517   ID:2MAC 00:12:74:02:00:02:02:02 Contiki-2.6-2450-geaa8760 已启动。节点 ID 设置为 2。
00:00.526   ID:2nullsec CSMA nullrdc,通道检查速率 128 Hz,无线电通道 26,CCA 阈值 -45
00:00.537   ID:2 暂定链路本地 IPv6 地址 fe80:0000:0000:0000:0212:7402:0002:0202
00:00.539   ID:2Starting 'UDP 客户端进程'
00:00.543   ID:2UDP 客户端进程启动 nbr:10 路由:10
00:00.547   ID:2Client IPv6 地址:fd00::212:7402:2:202
00:00.550   ID:2fe80::212:7402:2:202
00:00.555   ID:2与服务器建立连接::本地/远程端口8765/5678

ID:1即server节点  与client节点建立udp连接

00:00.654    ID:1Rime 从地址 0.18.116.1.0.1.1.1 开始
00:00.663   ID:1MAC 00:12:74:01:00:01:01:01 Contiki-2.6-2450-geaa8760 已启动。节点 ID 设置为 1。
00:00.672   ID:1nullsec CSMA nullrdc,信道检查率 128 Hz,无线电信道 26,CCA 阈值 -45
00:00.683   ID:1 暂定链路本地 IPv6 地址 fe80:0000:0000:0000:0212:7401:0001:0101
00:00.685   ID:1 开始 'UDP 服务器进程'
00:00.688   ID:1UDP 服务器已启动。编号:10 路线:10
00:00.692   ID:1创建了一个新的 RPL dag
00:00.696   ID:1 服务器 IPv6 地址:fd00::212:7401:1:101
00:00.698   ID:1fd00::ff:fe00:1
00:00.701   ID:1fe80::212:7401:1:101
00:00.707   ID:1使用远程地址::本地/远程端口5678/8765创建服务器连接

发送数据包

00:01.527    ID:2上层校验和 len: 6 from: 40
00:01.543   ID:1uip6:从 fe80::212:7402:2:202 到 ff02::1a 收到 IPv6 数据包
00:01.546    ID:1icmp6_input:长度 46 类型:155
00:01.548   ID:1上层校验和 len: 6 from: 40
00:01.550   ID:1 在 uip 中丢弃数据包

附录:关于RPL专业术语

  • RPL是一个距离向量路由协议,其设计高度模块化

    • 为了使RPL在LLN应用领域有广泛的应用,RPL将数据处理和数据转发从路由优化目标中分离出来。RPL支持很多不同形式的链路层,包括但不限于有损链路和用在主机或路由设备中资源有限的链路层。
    • RPL的核心思想是构建DAG拓扑。DAG拓扑是一个类似于树状拓扑的结构,用它来规定LLN节点之间的默认路由。但与典型树状拓扑中节点只允许有一个父节点的情况不同,DAG结构中节点可以与多个父节点连接。具体来说,一个DAG由一个或多个RPL实例组成,一个RPL实例中又包含一个或多个DODAG。每个DODAG有唯一的DODAG ID。DODAG ID的范围是一个RPL Instance。一个RPL Instance ID和一个DODAG ID唯一地确定了一个DODAG。在DODAG中,目的地节点往往是DAG的根节点,根节点通过骨干网连接到路由器,再由路由器连接到传统的有线网络中。在同一个网络中可以同时运行多个RPL实例,这些RPL实例的操作在逻辑上互相独立。
  • RPL的基本术语
    • DAG (有向无环图(Directed Acyclic Graph))

      • 概念

        • DAG是对RPL形成的拓扑的一种描述。拓扑中所有的路径为边,这些边构成了一个有向无环图,即这些边不会形成环路,有效防止路由环路问题,
      • DAG Root (DAG 根节点)

        • 各个边汇聚于一点,这个点被称作DAG Root,即Sink节点或网关。DAG Root有构建DAG的能力,同时担任着连接LLN和Internet的网关(或边界路由器)角色。DAG的根节点通过广播路由限制条件来过滤网络中一些不满足条件的节点,然后节点通过路由度量来选择最优的路径,(从而消除传统路由协议可能存在的瓶颈问题,解决由网络路由所带来的巨大开销、所引发的网络生存周期缩短等技术难题。)
      • DODAG 面向目的地的DAG(Destination-Oriented Directed Acyclic Graph)

        • 概念

          • DODAG是RPL拓扑的基本单元,一个DAG可以由一个或多个DODAG组成
        • DODAG Root (DODAG根节点)

          • 一个DODAG有且只有一个根节点,称作 DODAG Root,通常为Sink节点或处理能力比较强的普通节点。DODAG Root最后全部汇聚于目的地节点,即DAG Root。DODAG Root 能起到边界路由器的作用,有构建DODAG的能力,并负责本地DODAG的路由聚集和信息收集。特别地,在需要的情况下,DODAG Root可以更新DODAG拓扑。
    • 向上路由

      • 是节点沿着DODAG(或DAG)边朝向根节点方向的路由。
    • 向下路由

      • 向下路由是节点沿着DODAG(或DAG)边与向上路由方向相反的路由
    • 最佳父节点

      • 指DODAG拓扑中节点向上路由的默认下一跳节点。最佳父节点的选择规则由目标函数(Object Function,OF)定义
    • 等级(Rank)

      • 可以看作RPL路由协议的路由“梯度”,表征单个节点相对DODAG根节点的距离,其本质是将节点到DODAG根节点的距离以量化的形式表示出来,Rank值由OF计算得到,可以用来避免路由回环和进行路由回环检测。为了保证环路探测机制,沿着节点到DODAG根节点的方向,节点的Rank值减小,DODAG根节点的Rank值为0,父节点的Rank值大于子节点的Rank值
    • 目标函数(Object Function,OF)

      • 功能

        • 定义了路由度量、路由优化目标和Rank值的计算方式
        • 定义了DODAG中选取最佳父节点的方式
        • 定义了DODAG的构建方式
      • RPL旨在使用OF功能使节点到达DODAG根节点的路径成本最小化。OF可以根据网络应用场景的不同来灵活定义。
    • RPL实例(RPL Instance)

      • 一个DAG可以包含多个RPL实例,同一个RPL实例由一个或多个DODAG组成。一个节点可以属于多个RPL实例,并根据DODAG特点标记数据流量,但在所属的每个RPL实例中只能属于其中一个DODAG
      • 一个节点可以有多个目标函数OF,同一个DODAG使用相同的OF,也就是说即使在同一个网络中,也可以根据不同的区域或不同的要求,定义不同的OF来满足目标
    • RPL实例号(RPL Instance ID)

      • 由DAG Root设定。RPL实例由RPL实例号唯一表征
    • DODAG号(DODAG ID)

      • DODAG ID由DODAG Root设定。DODAG由RPL实例号和DODAG号唯一表征。
    • DODAG版本号(DODAG Version Number)

      • 由DODAG Root设定。节点通常会因为自身的原因(如节点电池耗尽)或者环境原因而失去作用,结果导致DODAG的拓扑结构发生变化,因此路由协议必须维护DODAG的拓扑。RPL路由协议通过DODAG版本号来定义不同DODAG的拓扑版本,当DODAG因为某种原因重新建立而变成另外一个拓扑版本时,DODAG版本号都会加1。一个DODAG版本号由RPL实例号、DODAG号和DODAG版本号共同唯一表征

RPL-UDP的cooja仿真过程相关推荐

  1. Linux下Verilog仿真过程(二)

    上一篇Linux下Verilog仿真过程(一)已经介绍了Verilog基本仿真问题 只不过仿真结果输出只是简单输出,不是很形象. 下面看一下"gui(图形用户界面)"的仿真结果. ...

  2. ISE中使用DDR3例程的生成步骤与仿真过程

    DDR3的IP核是FPGA编程中常用的一的IP,今天我们来聊聊DDR3的IP怎么仿真. 使用环境:ISE 调用IP:MIG 7 Series / MIG Virtex-6 and Spartan-6 ...

  3. contiki cooja仿真

    最近在做contiki平台上的一些cooja仿真的东西,发现现在网上能学到的东西实在是很有限,现在在这里将我最近学到的一些东西做一下总结. 一. 关于运行的一般步骤: https://www.zhih ...

  4. Proteus仿真过程中External model DLL “***.DLL” not found

    一.问题 在Proteus仿真过程中出现External model DLL "***.DLL" not found的错误,这种情况一般是元件的模型找不到 方法一 Proteus中 ...

  5. Modelsim仿真过程(完整版)

    Modelsim仿真没有想象的那么难,我一直没想着仔细研究一下,本来想着请教别人的,但是最后还是决定找资料,自己好好做一下. 我原先都是调试C语言程序,然后直接用硬件验证的,没有注意到仿真的重要性.在 ...

  6. SLM—仿真过程与数据管理平台

    SLM-仿真过程与数据管理平台 近年来,企业通过将仿真纳入产品研发过程,来减少对试验的依赖,缩短研发周期.利用仿真分析手段能够更加深入地开展产品特性研究,通过设计 - 仿真 - 优化迭代,实现产品创新 ...

  7. OFDM完整仿真过程及解释(MATLAB)

    因为是复制过来,如果出现图片显示不完整以及需要源程序请点击下面链接查看原文: OFDM完整仿真过程及解释(MATLAB) - 子木的文章 - 知乎 点击这里访问原文 后面的更新没有同步,点上面链接可以 ...

  8. 状态机控制移位寄存器multisim仿真过程中出现的状态变量和状态转移条件不匹配的问题

    问题如下: 当我们在进行到0000001时,状态变量应该取值为s1s0=10 但在实际仿真过程中出现了s1s0依旧在0000001时保持01不变,在0000001结束到1000000复位时才发生01到 ...

  9. Step7V5.6版本PLC编写的程序与博图V14编写的面板的仿真过程

    博图V14面板的仿真过程不再过多叙述,详见上一篇文章. 1.博图中的硬件连接准备,新建一个PLC代理与KP700通过以太网的方式连接 2.为验证仿真的正确性在面板中新建一个IO域连接PLC中的变量.在 ...

  10. 使用SIM4LIFE light对人体电磁场仿真过程1

    使用SIM4LIFE light对人体电磁场仿真过程1 关于S4L软件 我的研究课题以及使用体验 EM FDTD 关于EM FDTD模块 模块使用 关于S4L软件 S4L软件全名SIM4LIFE,由瑞 ...

最新文章

  1. 重要通知 | WanaCrypt0r 2.0及Onion等勒索软件安全建议
  2. 《幸福资本论》读书笔记
  3. oracle 日期 extract,ORACLE——EXTRACT() 截取日期时间的函数使用
  4. 苹果8如何设置锁屏无线网连接服务器,iPhone8屏幕解锁怎么设置?苹果iPhone8与8 Plus解锁四种方法...
  5. R语言应用实战-基于R的C4.5算法和C5.0算法原理解析及应用案例
  6. 腾讯2019暑期实习生提前批CV岗笔试题
  7. 「雕爷学编程」Arduino动手做(20)—水银开关模块
  8. (六)为时装设计生成训练和运行GAN
  9. NoSQL——MongoDB
  10. S3存储服务间数据同步工具Rclone介绍
  11. 山地车中轴进水表现_你一定不知道的自行车中轴知识
  12. php 翻转180度,如何翻转视频—将视频翻转90或180度
  13. mySQL mainxml汉化包下载
  14. Android SeekBar控件详解
  15. Excel数据可视化竟可以如此惊艳!数据可视化大屏制作
  16. 【PHP发送邮件】PHP实现发送邮件
  17. Windows11 系统打开IE浏览器的方式(完整版)
  18. 梯度提升树(GBDT)
  19. 安凯AK3918E加载mtk7601驱动不能ifconfig wlan0 down
  20. js将文本转成语言播放

热门文章

  1. python--22 类和对象
  2. 举头望明月打计算机术语,与月亮有关的谜语
  3. U盘不显示文件但有内存
  4. Git:rebase 是什么
  5. 如何下载网吧电影服务器上的电影
  6. The <Router /> component appears to be a function component that returns报错解决方式
  7. DFU u-boot搭建
  8. 惯导标定国内外研究现状小结(删减版)
  9. authorized_keys与known_hosts
  10. 生活中常见的计算机网络知识