3e1ab2bc5411706d1a84bca6b3b49718f779e030
[oonf.git] / src-api / subsystems / oonf_layer2.h
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004-2013, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 #ifndef OONF_LAYER2_H_
43 #define OONF_LAYER2_H_
44
45 #include "common/avl.h"
46 #include "common/common_types.h"
47 #include "common/netaddr.h"
48
49 #include "subsystems/oonf_clock.h"
50 #include "subsystems/oonf_timer.h"
51
52 /* both callbacks support ADD and REMOVE events */
53 #define LAYER2_CLASS_NEIGHBOR           "layer2_neighbor"
54 #define LAYER2_CLASS_NETWORK            "layer2_neighbor"
55
56 enum oonf_layer2_neighbor_data {
57   OONF_L2NEIGH_SIGNAL = 1<<0,
58   OONF_L2NEIGH_LAST_SEEN = 1<<1,
59   OONF_L2NEIGH_RX_BITRATE = 1<<2,
60   OONF_L2NEIGH_RX_BYTES = 1<<3,
61   OONF_L2NEIGH_RX_PACKETS = 1<<4,
62   OONF_L2NEIGH_TX_BITRATE = 1<<5,
63   OONF_L2NEIGH_TX_BYTES = 1<<6,
64   OONF_L2NEIGH_TX_PACKETS = 1<<7,
65   OONF_L2NEIGH_TX_RETRIES = 1<<8,
66   OONF_L2NEIGH_TX_FAILED = 1<<9,
67 };
68
69 struct oonf_layer2_neighbor_key {
70   struct netaddr neighbor_mac;
71   struct netaddr radio_mac;
72 };
73
74 struct oonf_layer2_neighbor {
75   struct avl_node _node;
76   struct oonf_layer2_neighbor_key key;
77   uint32_t if_index;
78
79   bool active;
80
81   struct oonf_timer_entry _valitity_timer;
82   enum oonf_layer2_neighbor_data _available_data;
83
84   int16_t signal_dbm;
85   uint64_t last_seen;
86
87   uint64_t tx_bitrate, rx_bitrate;
88   uint32_t tx_bytes, tx_packets;
89   uint32_t rx_bytes, rx_packets;
90
91   uint32_t tx_retries, tx_failed;
92 };
93
94 enum oonf_layer2_network_data {
95   OONF_L2NET_SSID = 1<<0,
96   OONF_L2NET_LAST_SEEN = 1<<1,
97   OONF_L2NET_FREQUENCY = 1<<2,
98   OONF_L2NET_SUPPORTED_RATES = 1<<3,
99 };
100
101 struct oonf_layer2_network {
102   struct avl_node _id_node;
103
104   struct netaddr radio_id;
105   uint32_t if_index;
106
107   bool active;
108
109   struct oonf_timer_entry _valitity_timer;
110   enum oonf_layer2_network_data _available_data;
111
112   /* 0-terminated ssid string */
113   char ssid[33];
114
115   uint64_t last_seen;
116
117   uint64_t frequency;
118
119   uint64_t *supported_rates;
120   size_t rate_count;
121 };
122
123 struct oonf_layer2_network_config {
124   struct avl_node _name_node;
125
126   const char *if_name;
127
128   uint64_t tx_bitrate;
129 };
130
131 #define LOG_LAYER2 oonf_layer2_subsystem.logging
132 EXPORT extern struct oonf_subsystem oonf_layer2_subsystem;
133
134 EXPORT extern struct avl_tree oonf_layer2_network_id_tree;
135 EXPORT extern struct avl_tree oonf_layer2_network_name_tree;
136 EXPORT extern struct avl_tree oonf_layer2_neighbor_tree;
137
138 EXPORT struct oonf_layer2_network *oonf_layer2_add_network(
139     struct netaddr *ssid, uint32_t if_index, uint64_t vtime);
140 EXPORT void oonf_layer2_remove_network(struct oonf_layer2_network *);
141
142 EXPORT struct oonf_layer2_neighbor *oonf_layer2_get_neighbor(
143     struct netaddr *radio_id, struct netaddr *neigh_mac);
144 EXPORT struct oonf_layer2_neighbor *oonf_layer2_add_neighbor(
145     struct netaddr *radio_id, struct netaddr *neigh_mac,
146     uint32_t if_index, uint64_t vtime);
147 EXPORT void oonf_layer2_remove_neighbor(struct oonf_layer2_neighbor *);
148
149 EXPORT int oonf_layer2_network_set_supported_rates(
150     struct oonf_layer2_network *net,
151     uint64_t *rate_array, size_t rate_count);
152
153 EXPORT void oonf_layer2_neighbor_commit(struct oonf_layer2_neighbor *);
154 EXPORT void oonf_layer2_network_commit(struct oonf_layer2_network *);
155
156 /**
157  * Retrieve a layer2 network entry from the database
158  * @param radio mac address of the local interface
159  * @return pointer to layer2 network, NULL if not found
160  */
161 static INLINE struct oonf_layer2_network *
162 oonf_layer2_get_network_by_id(struct netaddr *radio) {
163   struct oonf_layer2_network *net;
164   return avl_find_element(&oonf_layer2_network_id_tree, radio, net, _id_node);
165 }
166
167 /*
168  * The following inline functions should be used to set and test for
169  * data in the layer 2 neighbor and network data. Reading can be done
170  * by directly accessing the data fields (after testing if they contain
171  * data at all).
172  */
173
174 /**
175  * @param neigh pointer to layer2 neighbor data
176  * @return true if data contains signal strength, false otherwise
177  */
178 static INLINE bool
179 oonf_layer2_neighbor_has_signal(struct oonf_layer2_neighbor *neigh) {
180   return (neigh->_available_data & OONF_L2NEIGH_SIGNAL) != 0;
181 }
182
183 /**
184  * @param neigh pointer to layer2 neighbor data
185  * @return true if data contains timestamp
186  *    when station has been seen last, false otherwise
187  */
188 static INLINE bool
189 oonf_layer2_neighbor_has_last_seen(struct oonf_layer2_neighbor *neigh) {
190   return (neigh->_available_data & OONF_L2NEIGH_LAST_SEEN) != 0;
191 }
192
193 /**
194  * @param neigh pointer to layer2 neighbor data
195  * @return true if data contains rx bitrate, false otherwise
196  */
197 static INLINE bool
198 oonf_layer2_neighbor_has_rx_bitrate(struct oonf_layer2_neighbor *neigh) {
199   return (neigh->_available_data & OONF_L2NEIGH_RX_BITRATE) != 0;
200 }
201
202 /**
203  * @param neigh pointer to layer2 neighbor data
204  * @return true if data contains rx bytes, false otherwise
205  */
206 static INLINE bool
207 oonf_layer2_neighbor_has_rx_bytes(struct oonf_layer2_neighbor *neigh) {
208   return (neigh->_available_data & OONF_L2NEIGH_RX_BYTES) != 0;
209 }
210
211 /**
212  * @param neigh pointer to layer2 neighbor data
213  * @return true if data contains rx packets, false otherwise
214  */
215 static INLINE bool
216 oonf_layer2_neighbor_has_rx_packets(struct oonf_layer2_neighbor *neigh) {
217   return (neigh->_available_data & OONF_L2NEIGH_RX_PACKETS) != 0;
218 }
219
220 /**
221  * @param neigh pointer to layer2 neighbor data
222  * @return true if data contains tx bitrate, false otherwise
223  */
224 static INLINE bool
225 oonf_layer2_neighbor_has_tx_bitrate(struct oonf_layer2_neighbor *neigh) {
226   return (neigh->_available_data & OONF_L2NEIGH_TX_BITRATE) != 0;
227 }
228
229 /**
230  * @param neigh pointer to layer2 neighbor data
231  * @return true if data contains tx bytes, false otherwise
232  */
233 static INLINE bool
234 oonf_layer2_neighbor_has_tx_bytes(struct oonf_layer2_neighbor *neigh) {
235   return (neigh->_available_data & OONF_L2NEIGH_TX_BYTES) != 0;
236 }
237
238 /**
239  * @param neigh pointer to layer2 neighbor data
240  * @return true if data contains tx packets, false otherwise
241  */
242 static INLINE bool
243 oonf_layer2_neighbor_has_tx_packets(struct oonf_layer2_neighbor *neigh) {
244   return (neigh->_available_data & OONF_L2NEIGH_TX_PACKETS) != 0;
245 }
246
247 /**
248  * @param neigh pointer to layer2 neighbor data
249  * @return true if data contains tx retries, false otherwise
250  */
251 static INLINE bool
252 oonf_layer2_neighbor_has_tx_retries(struct oonf_layer2_neighbor *neigh) {
253   return (neigh->_available_data & OONF_L2NEIGH_TX_RETRIES) != 0;
254 }
255
256 /**
257  * @param neigh pointer to layer2 neighbor data
258  * @return true if data contains tx failed, false otherwise
259  */
260 static INLINE bool
261 oonf_layer2_neighbor_has_tx_failed(struct oonf_layer2_neighbor *neigh) {
262   return (neigh->_available_data & OONF_L2NEIGH_TX_FAILED) != 0;
263 }
264
265 /**
266  * Clear all optional data from a layer2 neighbor
267  * @param neigh pointer to layer2 neighbor data
268  */
269 static INLINE void
270 oonf_layer2_neighbor_clear(struct oonf_layer2_neighbor *neigh) {
271   neigh->_available_data = 0;
272 }
273
274 /**
275  * @param neigh pointer to layer2 neighbor data
276  * @param signal_dbm signal strength to store in layer2 neighbor data
277  */
278 static INLINE void
279 oonf_layer2_neighbor_set_signal(struct oonf_layer2_neighbor *neigh, int16_t signal_dbm) {
280   neigh->_available_data |= OONF_L2NEIGH_SIGNAL;
281   neigh->signal_dbm = signal_dbm;
282 }
283
284 /**
285  * @param neigh pointer to layer2 neighbor data
286  * @param relative relative time since station was last seen
287  *   to store in layer2 neighbor data
288  */
289 static INLINE void
290 oonf_layer2_neighbor_set_last_seen(struct oonf_layer2_neighbor *neigh, int64_t relative) {
291   neigh->_available_data |= OONF_L2NEIGH_LAST_SEEN;
292   neigh->last_seen = oonf_clock_get_absolute(-relative);
293 }
294
295 /**
296  * @param neigh pointer to layer2 neighbor data
297  * @param bitrate incoming bitrate of station to store in layer2 neighbor data
298  */
299 static INLINE void
300 oonf_layer2_neighbor_set_rx_bitrate(struct oonf_layer2_neighbor *neigh, uint64_t bitrate) {
301   neigh->_available_data |= OONF_L2NEIGH_RX_BITRATE;
302   neigh->rx_bitrate = bitrate;
303 }
304
305 /**
306  * @param neigh pointer to layer2 neighbor data
307  * @param bytes total number of bytes received by station
308  *    to store in layer2 neighbor data
309  */
310 static INLINE void
311 oonf_layer2_neighbor_set_rx_bytes(struct oonf_layer2_neighbor *neigh, uint32_t bytes) {
312   neigh->_available_data |= OONF_L2NEIGH_RX_BYTES;
313   neigh->rx_bytes = bytes;
314 }
315
316 /**
317  * @param neigh pointer to layer2 neighbor data
318  * @param packets total number of packets received by station
319  *    to store in layer2 neighbor data
320  */
321 static INLINE void
322 oonf_layer2_neighbor_set_rx_packets(struct oonf_layer2_neighbor *neigh, uint32_t packets) {
323   neigh->_available_data |= OONF_L2NEIGH_RX_PACKETS;
324   neigh->rx_packets = packets;
325 }
326
327 /**
328  * @param neigh pointer to layer2 neighbor data
329  * @param bytes outgoing bitrate of station
330  *    to store in layer2 neighbor data
331  */
332 static INLINE void
333 oonf_layer2_neighbor_set_tx_bitrate(struct oonf_layer2_neighbor *neigh, uint64_t bitrate) {
334   neigh->_available_data |= OONF_L2NEIGH_TX_BITRATE;
335   neigh->tx_bitrate = bitrate;
336 }
337
338 /**
339  * @param neigh pointer to layer2 neighbor data
340  * @param bytes total number of bytes sent to station
341  *    to store in layer2 neighbor data
342  */
343 static INLINE void
344 oonf_layer2_neighbor_set_tx_bytes(struct oonf_layer2_neighbor *neigh, uint32_t bytes) {
345   neigh->_available_data |= OONF_L2NEIGH_TX_BYTES;
346   neigh->tx_bytes = bytes;
347 }
348
349 /**
350  * @param neigh pointer to layer2 neighbor data
351  * @param packets total number of packwets sent to station
352  *    to store in layer2 neighbor data
353  */
354 static INLINE void
355 oonf_layer2_neighbor_set_tx_packets(struct oonf_layer2_neighbor *neigh, uint32_t packets) {
356   neigh->_available_data |= OONF_L2NEIGH_TX_PACKETS;
357   neigh->tx_packets = packets;
358 }
359
360 /**
361  * @param neigh pointer to layer2 neighbor data
362  * @param retries total number of transmission retries to station
363  *   to store in layer2 neighbor data
364  */
365 static INLINE void
366 oonf_layer2_neighbor_set_tx_retries(struct oonf_layer2_neighbor *neigh, uint32_t retries) {
367   neigh->_available_data |= OONF_L2NEIGH_TX_PACKETS;
368   neigh->tx_retries = retries;
369 }
370
371 /**
372  * @param neigh pointer to layer2 neighbor data
373  * @param signal_dbm signal strength to store in layer2 neighbor data
374  */
375 static INLINE void
376 oonf_layer2_neighbor_set_tx_fails(struct oonf_layer2_neighbor *neigh, uint32_t failed) {
377   neigh->_available_data |= OONF_L2NEIGH_TX_PACKETS;
378   neigh->tx_failed = failed;
379 }
380
381 /**
382  * @param neigh pointer to layer2 network data
383  * @return true if data contains bssid of network, false otherwise
384  */
385 static INLINE bool
386 oonf_layer2_network_has_ssid(struct oonf_layer2_network *net) {
387   return (net->_available_data & OONF_L2NET_SSID) != 0;
388 }
389
390 /**
391  * @param neigh pointer to layer2 network data
392  * @return true if data contains timestamp when network
393  *    has been seen last, false otherwise
394  */
395 static INLINE bool
396 oonf_layer2_network_has_last_seen(struct oonf_layer2_network *net) {
397   return (net->_available_data & OONF_L2NET_LAST_SEEN) != 0;
398 }
399
400 /**
401  * @param neigh pointer to layer2 network data
402  * @return true if data contains signal strength, false otherwise
403  */
404 static INLINE bool
405 oonf_layer2_network_has_frequency(struct oonf_layer2_network *net) {
406   return (net->_available_data & OONF_L2NET_FREQUENCY) != 0;
407 }
408
409 /**
410  * @param neigh pointer to layer2 network data
411  * @return true if data contains supported data-rates, false otherwise
412  */
413 static INLINE bool
414 oonf_layer2_network_has_supported_rates(struct oonf_layer2_network *net) {
415   return (net->_available_data & OONF_L2NET_SUPPORTED_RATES) != 0;
416 }
417
418 /**
419  * Clear all optional data from a layer2 neighbor
420  * @param neigh pointer to layer2 neighbor data
421  */
422 static INLINE void
423 oonf_layer2_network_clear(struct oonf_layer2_network *net) {
424   net->_available_data = 0;
425 }
426
427 /**
428  * @param neigh pointer to layer2 network data
429  * @param bssid bssid to store in layer2 network data
430  */
431 static INLINE void
432 oonf_layer2_network_set_ssid(struct oonf_layer2_network *net, char *ssid) {
433   net->_available_data |= OONF_L2NET_SSID;
434   strscpy(net->ssid, ssid, sizeof(net->ssid));
435 }
436
437 /**
438  * @param neigh pointer to layer2 network data
439  * @param relative relative timestamp when network has been seen last
440  *    to store in layer2 network data
441  */
442 static INLINE void
443 oonf_layer2_network_set_last_seen(struct oonf_layer2_network *net, uint64_t relative) {
444   net->_available_data |= OONF_L2NET_LAST_SEEN;
445   net->last_seen = oonf_clock_get_absolute(-relative);
446 }
447
448 /**
449  * @param neigh pointer to layer2 network data
450  * @param frequency frequency of network to store in layer2 network data
451  */
452 static INLINE void
453 oonf_layer2_network_set_frequency(struct oonf_layer2_network *net, uint64_t frequency) {
454   net->_available_data |= OONF_L2NET_FREQUENCY;
455   net->frequency = frequency;
456 }
457
458 #endif /* OONF_LAYER2_H_ */