File: PppRouterP.nc

package info (click to toggle)
tinyos 2.1.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster, jessie, jessie-kfreebsd, stretch
  • size: 47,476 kB
  • ctags: 36,607
  • sloc: ansic: 63,646; cpp: 14,974; java: 10,358; python: 5,215; makefile: 1,724; sh: 902; asm: 597; xml: 392; perl: 74; awk: 46
file content (120 lines) | stat: -rw-r--r-- 3,224 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120

#include <stdio.h>
#include <lib6lowpan/ip.h>
#include <lib6lowpan/nwbyte.h>
#include <lib6lowpan/ip_malloc.h>
#include <dhcp6.h>

#include "pppipv6.h"
#include "blip_printf.h"

module PppRouterP {
  provides { 
    interface IPForward;
  }
  uses {
    interface Boot;
    interface Leds;
    interface SplitControl as IPControl;
    interface SplitControl as PppControl;
    interface LcpAutomaton as Ipv6LcpAutomaton;
    interface PppIpv6;
    interface Ppp;

    interface ForwardingTable;
    interface RootControl;
    interface Dhcp6Info;
    interface IPPacket;
  }
  
} implementation {

  event void PppIpv6.linkUp() {}
  event void PppIpv6.linkDown() {}

  event void Ipv6LcpAutomaton.transitionCompleted (LcpAutomatonState_e state) { }
  event void Ipv6LcpAutomaton.thisLayerUp () { }
  event void Ipv6LcpAutomaton.thisLayerDown () { }
  event void Ipv6LcpAutomaton.thisLayerStarted () { }
  event void Ipv6LcpAutomaton.thisLayerFinished () { }

  event void PppControl.startDone (error_t error) {  }
  event void PppControl.stopDone (error_t error) { }

  event void IPControl.startDone (error_t error) {
    struct in6_addr dhcp6_group;

    // add a route to the dhcp group on PPP, not the radio (which is the default)
    inet_pton6(DH6ADDR_ALLAGENT, &dhcp6_group);
    call ForwardingTable.addRoute(dhcp6_group.s6_addr, 128, NULL, ROUTE_IFACE_PPP);

    // add a default route through the PPP link
    call ForwardingTable.addRoute(NULL, 0, NULL, ROUTE_IFACE_PPP);
  }
  event void IPControl.stopDone (error_t error) { }

  event void Boot.booted() {
    error_t rc;

#ifndef PRINTFUART_ENABLED
    rc = call Ipv6LcpAutomaton.open();
    rc = call PppControl.start();
#endif
#ifdef RPL_ROUTING
    call RootControl.setRoot();
#endif
#ifndef IN6_PREFIX
    call Dhcp6Info.useUnicast(FALSE);
#endif

    call IPControl.start();
  }

  event error_t PppIpv6.receive(const uint8_t* data,
                                unsigned int len) {
    struct ip6_hdr *iph = (struct ip6_hdr *)data;
    void *payload = (iph + 1);
    call Leds.led0Toggle();
    signal IPForward.recv(iph, payload, NULL);
    return SUCCESS;
  }

  command error_t IPForward.send(struct in6_addr *next_hop,
                                 struct ip6_packet *msg,
                                 void *data) {
    size_t len = iov_len(msg->ip6_data) + sizeof(struct ip6_hdr);
    error_t rc;
    frame_key_t key;
    const uint8_t* fpe;
    uint8_t* fp;
    
    if (!call PppIpv6.linkIsUp()) 
      return EOFF;

    // get an output frame
    fp = call Ppp.getOutputFrame(PppProtocol_Ipv6, &fpe, FALSE, &key);
    if ((! fp) || ((fpe - fp) < len)) {
      if (fp) {
	call Ppp.releaseOutputFrame(key);
      }
      call Leds.led2Toggle();
      return ENOMEM;
    }

    // copy the header and body into the frame
    memcpy(fp, &msg->ip6_hdr, sizeof(struct ip6_hdr));
    iov_read(msg->ip6_data, 0, len, fp + sizeof(struct ip6_hdr));
    rc = call Ppp.fixOutputFrameLength(key, fp + len);
    if (SUCCESS == rc) {
      rc = call Ppp.sendOutputFrame(key);
    }

    call Leds.led1Toggle();

    return rc;
  }

  event void Ppp.outputFrameTransmitted (frame_key_t key,
                                         error_t err) { }

}