注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
dan158185的个人空间 https://home.eeworld.com.cn/space-uid-349284.html [收藏] [复制] [分享] [RSS]
日志

CC2538之TinyOS例程实验:9-Ppprouter边界路由实验

已有 1040 次阅读2016-1-5 16:10 |个人分类:CC2538之TinyOS例程

前面我们已经打下了BLIP+RPL的基础,本次例程将全部使用 并添加UART的pppd拨号实现边界路由器;这个例程是核心中的核心;使用它我们可以查看网络路由表而不是再只是通过抓包来自己分析;使用它访问其他的zigbee节点,如下一篇带来的实验CoAPServer;


例程目录:tinyos-main-release_tinyos_2_1_2\apps\cc2538_Test\PppRouter

Makefile文件:前面的介绍大家应该已经清楚了写法,现在开始省略


PppRouterC.nc文件:

  1. #include <iprouting.h>  
  2.   
  3. #include "ppp.h"  
  4.   
  5. configuration PppRouterC {  
  6. } implementation {  
  7.   components PppRouterP;  
  8.   
  9.   components MainC;  
  10.   PppRouterP.Boot -> MainC;  
  11.   
  12.   components LedsC as LedsC;  
  13.   PppRouterP.Leds -> LedsC;  
  14.   
  15.   components PppDaemonC;  
  16.   PppRouterP.PppControl -> PppDaemonC;  
  17.   
  18.   components PppIpv6C;  
  19.   PppDaemonC.PppProtocol[PppIpv6C.ControlProtocol] -> PppIpv6C.PppControlProtocol;  
  20.   PppDaemonC.PppProtocol[PppIpv6C.Protocol] -> PppIpv6C.PppProtocol;  
  21.   PppIpv6C.Ppp -> PppDaemonC;  
  22.   PppIpv6C.LowerLcpAutomaton -> PppDaemonC;  
  23.   
  24.   PppRouterP.Ipv6LcpAutomaton -> PppIpv6C;  
  25.   PppRouterP.PppIpv6 -> PppIpv6C;  
  26.   PppRouterP.Ppp -> PppDaemonC;  
  27.   
  28. #if defined(PLATFORM_TELOSB) || defined(PLATFORM_EPIC)  
  29.   components PlatformHdlcUartC as HdlcUartC;  
  30. #else  
  31.   components DefaultHdlcUartC as HdlcUartC;  
  32. #endif  
  33.   PppDaemonC.HdlcUart -> HdlcUartC;  
  34.   PppDaemonC.UartControl -> HdlcUartC;  
  35.   
  36.   // SDH : don't bother including the PppPrintfC by default  
  37.   // components PppPrintfC, PppC;;  
  38.   // PppPrintfC.Ppp -> PppDaemonC;  
  39.   // PppDaemonC.PppProtocol[PppPrintfC.Protocol] -> PppPrintfC;  
  40.   // PppPrintfC.Ppp -> PppC;  
  41.   
  42.   components IPStackC, IPForwardingEngineP, IPPacketC;  
  43.   IPForwardingEngineP.IPForward[ROUTE_IFACE_PPP] -> PppRouterP.IPForward;  
  44.   PppRouterP.IPControl -> IPStackC;  
  45.   PppRouterP.ForwardingTable -> IPStackC;  
  46.   PppRouterP.IPPacket -> IPPacketC;  
  47.   
  48. #ifdef RPL_ROUTING  
  49.   components RPLRoutingC, RplBorderRouterP;  
  50.   PppRouterP.RootControl -> RPLRoutingC;  
  51.   RplBorderRouterP.ForwardingEvents -> IPStackC.ForwardingEvents[ROUTE_IFACE_PPP];  
  52.   RplBorderRouterP.IPPacket -> IPPacketC;  
  53. #endif  
  54.   
  55.   // UDP shell on port 2000  
  56.   components UDPShellC;  
  57.   
  58.   // prints the routing table  
  59.    components RouteCmdC;  
  60.   
  61. #ifdef IN6_PREFIX  
  62.   components StaticIPAddressTosIdC; // Use TOS_NODE_ID in address  
  63.   //components StaticIPAddressC; // Use LocalIeee154 in address  
  64. #else  
  65.   components Dhcp6C;  
  66.   components Dhcp6ClientC;  
  67.   PppRouterP.Dhcp6Info -> Dhcp6ClientC;  
  68. #endif  
  69. }  

 注意 components UDPShellC;
         components RouteCmdC;这两个组件,自行去查看底层代码,原来测试命令中的route,heip等是他们定义的,参考他们的写法自己可以定义其他命令,如温度等

PppRouterP.nc文件:

  1.  <span style="font-family: Arial, Helvetica, sans-serif;">/*********************************************************************************************************************************************************</span>  
  1.  *实验7----zigbee 边界路由实验  
  2.  *节点需求数 >= 2  
  3.  *编译命令make cc2538cb blip id.xx (xx为1~65533)  
  4.  *测试命令:  
  5.  *1,sudo /usr/bin/pppd-hack/sbin/pppd debug passive noauth nodetach 115200 /dev/ttyUSB0 nocrtscts nocdtrcts lcp-echo-interval 0 noccp noip ipv6 ::23,::24 连接边界路由  
  6.  *2,新打开shell,执行sudo ifconfig ppp0 add fec0::100/64  
  7.  *3,3.1和3.2为两种测试方法,采取一种即可   
  8.  * 3.1执行nc6 -u fec0::1 2000  
  9.  *       route  
  10.  *       ping6 ff02::xx(xx为1~65533,且为烧写的测试节点号  
  11.  * 3.2  
  12.  *       ping6 ff02::xx(xx为1~65533,且为烧写的测试节点号  
  13.  * 也可以参考\apps\cc2538_Test\PppRouter下的README.blip进行测试,但是注意第一步命令pppd的区别  
  14.  * 更多命令支持请参考tinyos-main-release_tinyos_2_1_2\tos\lib\net\blip\shell的UDPShellP.nc文件,如help等,也可以自己添加入传感器等等  
  15.  ********************************************************************************************************************************************************/  
  16.   
  17. #include <stdio.h>  
  18. #include <lib6lowpan/ip.h>  
  19. #include <lib6lowpan/nwbyte.h>  
  20. #include <lib6lowpan/ip_malloc.h>  
  21. #include <dhcp6.h>  
  22.   
  23. #include "pppipv6.h"  
  24. #include "blip_printf.h"  
  25.   
  26. module PppRouterP {  
  27.   provides {   
  28.     interface IPForward;  
  29.   }  
  30.   uses {  
  31.     interface Boot;  
  32.     interface Leds;  
  33.     interface SplitControl as IPControl;  
  34.     interface SplitControl as PppControl;  
  35.     interface LcpAutomaton as Ipv6LcpAutomaton;  
  36.     interface PppIpv6;  
  37.     interface Ppp;  
  38.   
  39.     interface ForwardingTable;  
  40.     interface RootControl;  
  41.     interface Dhcp6Info;  
  42.     interface IPPacket;  
  43.   }  
  44.     
  45. } implementation {  
  46.   
  47.   event void PppIpv6.linkUp() {}  
  48.   event void PppIpv6.linkDown() {}  
  49.   
  50.   event void Ipv6LcpAutomaton.transitionCompleted (LcpAutomatonState_e state) { }  
  51.   event void Ipv6LcpAutomaton.thisLayerUp () { }  
  52.   event void Ipv6LcpAutomaton.thisLayerDown () { }  
  53.   event void Ipv6LcpAutomaton.thisLayerStarted () { }  
  54.   event void Ipv6LcpAutomaton.thisLayerFinished () { }  
  55.   
  56.   event void PppControl.startDone (error_t error) {  }  
  57.   event void PppControl.stopDone (error_t error) { }  
  58.   
  59.   event void IPControl.startDone (error_t error) {  
  60.     struct in6_addr dhcp6_group;  
  61.   
  62.     // add a route to the dhcp group on PPP, not the radio (which is the default)  
  63.     inet_pton6(DH6ADDR_ALLAGENT, &dhcp6_group);  
  64.     call ForwardingTable.addRoute(dhcp6_group.s6_addr, 128, NULL, ROUTE_IFACE_PPP);  
  65.   
  66.     // add a default route through the PPP link  
  67.     call ForwardingTable.addRoute(NULL, 0, NULL, ROUTE_IFACE_PPP);  
  68.   }  
  69.   event void IPControl.stopDone (error_t error) { }  
  70.   
  71.   event void Boot.booted() {  
  72.     error_t rc;  
  73.   
  74. #ifndef PRINTFUART_ENABLED  
  75.     rc = call Ipv6LcpAutomaton.open();  
  76.     rc = call PppControl.start();  
  77. #endif  
  78. #ifdef RPL_ROUTING  
  79.     call RootControl.setRoot();  
  80. #endif  
  81. #ifndef IN6_PREFIX  
  82.     call Dhcp6Info.useUnicast(FALSE);  
  83. #endif  
  84.   
  85.     call IPControl.start();  
  86.   }  
  87.   
  88.   event error_t PppIpv6.receive(const uint8_t* data,  
  89.                                 unsigned int len) {  
  90.     struct ip6_hdr *iph = (struct ip6_hdr *)data;  
  91.     void *payload = (iph + 1);  
  92.     call Leds.led0Toggle();  
  93.     signal IPForward.recv(iph, payload, NULL);  
  94.     return SUCCESS;  
  95.   }  
  96.   
  97.   command error_t IPForward.send(struct in6_addr *next_hop,  
  98.                                  struct ip6_packet *msg,  
  99.                                  void *data) {  
  100.     size_t len = iov_len(msg->ip6_data) + sizeof(struct ip6_hdr);  
  101.     error_t rc;  
  102.     frame_key_t key;  
  103.     const uint8_t* fpe;  
  104.     uint8_t* fp;  
  105.       
  106.     if (!call PppIpv6.linkIsUp())   
  107.       return EOFF;  
  108.   
  109.     // get an output frame  
  110.     fp = call Ppp.getOutputFrame(PppProtocol_Ipv6, &fpe, FALSE, &key);  
  111.     if ((! fp) || ((fpe - fp) < len)) {  
  112.       if (fp) {  
  113.     call Ppp.releaseOutputFrame(key);  
  114.       }  
  115.       call Leds.led2Toggle();  
  116.       return ENOMEM;  
  117.     }  
  118.   
  119.     // copy the header and body into the frame  
  120.     memcpy(fp, &msg->ip6_hdr, sizeof(struct ip6_hdr));  
  121.     iov_read(msg->ip6_data, 0, len, fp + sizeof(struct ip6_hdr));  
  122.     rc = call Ppp.fixOutputFrameLength(key, fp + len);  
  123.     if (SUCCESS == rc) {  
  124.       rc = call Ppp.sendOutputFrame(key);  
  125.     }  
  126.   
  127.     call Leds.led1Toggle();  
  128.   
  129.     return rc;  
  130.   }  
  131.   
  132.   event void Ppp.outputFrameTransmitted (frame_key_t key,  
  133.                                          error_t err) { }  
  134.   
  135. }  
阅读代码可以发现PRINTFUART_ENABLED不要开启,不然ppp模块是编译去除的;

源码是pppd的例程部分和发送数据接收数据的处理

RplBorderRouterP.nc文件:

  1. #include <lib6lowpan/ip.h>  
  2. #include <iprouting.h>  
  3. #include <RPL.h>  
  4.   
  5. module RplBorderRouterP {  
  6.   uses {  
  7.     interface ForwardingEvents;  
  8.     interface IPPacket;  
  9.   }  
  10. } implementation {  
  11.   
  12.   event bool ForwardingEvents.initiate(struct ip6_packet *pkt,  
  13.                                        struct in6_addr *next_hop) {  
  14.     return TRUE;  
  15.   }  
  16.   
  17.   event bool ForwardingEvents.approve(struct ip6_packet *pkt,  
  18.                                       struct in6_addr *next_hop) {  
  19.     int off;  
  20.     uint8_t nxt = IPV6_HOP;  
  21.     if (pkt->ip6_inputif == ROUTE_IFACE_PPP)  
  22.       return FALSE;  
  23.   
  24.     /* remove any RPL options in the hop-by-hop header by converting  
  25.        them to a PadN option */  
  26.     off = call IPPacket.findHeader(pkt->ip6_data, pkt->ip6_hdr.ip6_nxt, &nxt);  
  27.     if (off < 0) return TRUE;  
  28.     call IPPacket.delTLV(pkt->ip6_data, off, RPL_HBH_RANK_TYPE);  
  29.   
  30.     return TRUE;  
  31.   }  
  32.   
  33.   event void ForwardingEvents.linkResult(struct in6_addr *dest, struct send_info *info) {  
  34.   
  35.   }  
  36. }  

这个components是缺省写法,大家以后可以学习他的写法来偷懒,没有编写configuration和interface文件;

文件中的事件是网络路由事件;


本例程带有测试视频;截图神马的就忽略了,其中的pppd命令使用自己安装的pppd_hack的原因是因为当主机是XP的时候,虚拟机使用pppd命令,出现假死,当主机是WIN8的时候,虚拟机同样的使用pppd时正常的;于是我干脆自己安装了pppd_hack,这样主机XP或WIN8就都可以了;pppd_hack虚拟机已经安装好,参考的lab11的blip测试网页安装,百度网盘也有安装包;


可以先烧写一个Ppprouter节点连接PC,按照视频启动pppd连接,可以输入路由表查看命令,查看本机路由;

再准备一个UDPECHO节点,编译烧写,再在虚拟机查看Ppprouter节点路由表或者登陆UDPECHO节点,查看一下它的路由表;


当然你也可以先跳过UDPECHO;我自己就基本不测试他,可以pppd连接后,直接跳过测试,进入下一部CoAPServer节点实验实行ping6测试,coap的led控制!

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章