1/*********************************************************************
2   PicoTCP. Copyright (c) 2015-2017 Altran Intelligent Systems. Some rights reserved.
3   See COPYING, LICENSE.GPLv2 and LICENSE.GPLv3 for usage.
4
5   .
6
7   Author: Daniele Lacamera <daniele.lacamera@altran.com>
8 *********************************************************************/
9#ifndef PICO_AODV_H_
10#define PICO_AODV_H_
11
12/* RFC3561 */
13#define PICO_AODV_PORT (654)
14
15/* RFC3561 $10 */
16#define AODV_ACTIVE_ROUTE_TIMEOUT     (8000u) /* Conservative value for link breakage detection */
17#define AODV_DELETE_PERIOD            (5 * AODV_ACTIVE_ROUTE_TIMEOUT) /* Recommended value K = 5 */
18#define AODV_ALLOWED_HELLO_LOSS       (4) /* conservative */
19#define AODV_NET_DIAMETER             ((uint8_t)(35))
20#define AODV_RREQ_RETRIES             (2)
21#define AODV_NODE_TRAVERSAL_TIME      (40)
22#define AODV_HELLO_INTERVAL           (1000)
23#define AODV_LOCAL_ADD_TTL            2
24#define AODV_RREQ_RATELIMIT           (10)
25#define AODV_TIMEOUT_BUFFER           (2)
26#define AODV_TTL_START                ((uint8_t)(1))
27#define AODV_TTL_INCREMENT            2
28#define AODV_TTL_THRESHOLD            ((uint8_t)(7))
29#define AODV_RERR_RATELIMIT           (10)
30#define AODV_MAX_REPAIR_TTL           ((uint8_t)(AODV_NET_DIAMETER / 3))
31#define AODV_MY_ROUTE_TIMEOUT         (2 * AODV_ACTIVE_ROUTE_TIMEOUT)
32#define AODV_NET_TRAVERSAL_TIME       (2 * AODV_NODE_TRAVERSAL_TIME * AODV_NET_DIAMETER)
33#define AODV_BLACKLIST_TIMEOUT        (AODV_RREQ_RETRIES * AODV_NET_TRAVERSAL_TIME)
34#define AODV_NEXT_HOP_WAIT            (AODV_NODE_TRAVERSAL_TIME + 10)
35#define AODV_PATH_DISCOVERY_TIME      (2 * AODV_NET_TRAVERSAL_TIME)
36#define AODV_RING_TRAVERSAL_TIME(ttl)   (2 * AODV_NODE_TRAVERSAL_TIME * (ttl + AODV_TIMEOUT_BUFFER))
37/* End section RFC3561 $10 */
38
39
40#define AODV_TYPE_RREQ 1
41#define AODV_TYPE_RREP 2
42#define AODV_TYPE_RERR 3
43#define AODV_TYPE_RACK 4
44
45PACKED_STRUCT_DEF pico_aodv_rreq
46{
47    uint8_t type;
48    uint16_t req_flags;
49    uint8_t hop_count;
50    uint32_t rreq_id;
51    uint32_t dest;
52    uint32_t dseq;
53    uint32_t orig;
54    uint32_t oseq;
55};
56
57#define AODV_RREQ_FLAG_J 0x8000
58#define AODV_RREQ_FLAG_R 0x4000
59#define AODV_RREQ_FLAG_G 0x2000
60#define AODV_RREQ_FLAG_D 0x1000
61#define AODV_RREQ_FLAG_U 0x0800
62#define AODV_RREQ_FLAG_RESERVED 0x07FF
63
64PACKED_STRUCT_DEF pico_aodv_rrep
65{
66    uint8_t type;
67    uint8_t rep_flags;
68    uint8_t prefix_sz;
69    uint8_t hop_count;
70    uint32_t dest;
71    uint32_t dseq;
72    uint32_t orig;
73    uint32_t lifetime;
74};
75
76#define AODV_RREP_MAX_PREFIX 0x1F
77#define AODV_RREP_FLAG_R 0x80
78#define AODV_RREP_FLAG_A 0x40
79#define AODV_RREP_FLAG_RESERVED 0x3F
80
81#define PICO_AODV_NODE_NEW          0x0000
82#define PICO_AODV_NODE_SYNC         0x0001
83#define PICO_AODV_NODE_REQUESTING   0x0002
84#define PICO_AODV_NODE_ROUTE_UP     0x0004
85#define PICO_AODV_NODE_ROUTE_DOWN   0x0008
86#define PICO_AODV_NODE_IDLING       0x0010
87#define PICO_AODV_NODE_UNREACH      0x0020
88
89#define PICO_AODV_ACTIVE(node) ((node->flags & PICO_AODV_NODE_ROUTE_UP) && (node->flags & PICO_AODV_NODE_ROUTE_DOWN))
90
91
92struct pico_aodv_node
93{
94    union pico_address dest;
95    pico_time last_seen;
96    pico_time fwd_time;
97    uint32_t dseq;
98    uint16_t flags;
99    uint8_t metric;
100    uint8_t ring_ttl;
101    uint8_t rreq_retry;
102};
103
104PACKED_STRUCT_DEF pico_aodv_unreachable
105{
106    uint32_t addr;
107    uint32_t dseq;
108};
109
110PACKED_STRUCT_DEF pico_aodv_rerr
111{
112    uint8_t type;
113    uint16_t rerr_flags;
114    uint8_t dst_count;
115    uint32_t unreach_addr;
116    uint32_t unreach_dseq;
117    struct pico_aodv_unreachable unreach[1]; /* unrechable nodes: must be at least 1. See dst_count field above */
118};
119
120PACKED_STRUCT_DEF pico_aodv_rack
121{
122    uint8_t type;
123    uint8_t reserved;
124};
125
126int pico_aodv_init(void);
127int pico_aodv_add(struct pico_device *dev);
128int pico_aodv_lookup(const union pico_address *addr);
129void pico_aodv_refresh(const union pico_address *addr);
130#endif
131