indent the lq_plugin
[olsrd.git] / src / lq_plugin.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
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 #include "tc_set.h"
43 #include "link_set.h"
44 #include "olsr_spf.h"
45 #include "lq_packet.h"
46 #include "packet.h"
47 #include "olsr.h"
48 #include "two_hop_neighbor_table.h"
49
50 #include "lq_plugin_default.h"
51 #include "lq_plugin.h"
52
53 /* Default lq plugin settings */
54 struct lq_handler default_lq_handler = {
55   &default_calc_cost,
56   &default_calc_cost,
57
58   &default_olsr_is_relevant_costchange,
59
60   &default_packet_loss_worker,
61   &default_olsr_memorize_foreign_hello_lq,
62   &default_olsr_copy_link_lq_into_tc,
63   &default_olsr_clear_lq,
64   &default_olsr_clear_lq,
65
66   &default_olsr_serialize_hello_lq_pair,
67   &default_olsr_serialize_tc_lq_pair,
68   &default_olsr_deserialize_hello_lq_pair,
69   &default_olsr_deserialize_tc_lq_pair,
70
71   &default_olsr_print_lq,
72   &default_olsr_print_lq,
73   &default_olsr_print_cost,
74
75   sizeof(struct default_lq),
76   sizeof(struct default_lq)
77 };
78
79 struct lq_handler *active_lq_handler = &default_lq_handler;
80
81 /*
82  * set_lq_handler
83  * 
84  * this function is used by routing metric plugins to activate their link
85  * quality handler
86  * 
87  * @param pointer to lq_handler structure
88  * @param name of the link quality handler for debug output
89  */
90 void
91 set_lq_handler(struct lq_handler *handler, const char *name)
92 {
93   if (handler) {
94     OLSR_PRINTF(1, "Activated lq_handler: %s\n", name);
95     active_lq_handler = handler;
96   } else {
97     OLSR_PRINTF(1, "Activated lq_handler: default\n");
98     active_lq_handler = &default_lq_handler;
99   }
100
101   name = NULL;                  /* squelch compiler warning */
102 }
103
104 /*
105  * olsr_calc_tc_cost
106  * 
107  * this function calculates the linkcost of a tc_edge_entry
108  * 
109  * @param pointer to the tc_edge_entry
110  * @return linkcost
111  */
112 olsr_linkcost
113 olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
114 {
115   return active_lq_handler->calc_tc_cost(tc_edge->linkquality);
116 }
117
118 /*
119  * olsr_is_relevant_costchange
120  * 
121  * decides if the difference between two costs is relevant
122  * (for changing the route for example)
123  * 
124  * @param first linkcost value
125  * @param second linkcost value
126  * @return boolean
127  */
128 olsr_bool
129 olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2)
130 {
131   return active_lq_handler->is_relevant_costchange(c1, c2);
132 }
133
134 /*
135  * olsr_serialize_hello_lq_pair
136  * 
137  * this function converts the lq information of a lq_hello_neighbor into binary package
138  * format
139  * 
140  * @param pointer to binary buffer to write into
141  * @param pointer to lq_hello_neighbor
142  * @return number of bytes that have been written
143  */
144 int
145 olsr_serialize_hello_lq_pair(unsigned char *buff,
146                              struct lq_hello_neighbor *neigh)
147 {
148   return active_lq_handler->serialize_hello_lq(buff, neigh->linkquality);
149 }
150
151 /*
152  * olsr_deserialize_hello_lq_pair
153  * 
154  * this function reads the lq information of a binary package into a hello_neighbor
155  * It also initialize the cost variable of the hello_neighbor
156  * 
157  * @param pointer to the current buffer pointer
158  * @param pointer to hello_neighbor
159  */
160 void
161 olsr_deserialize_hello_lq_pair(const olsr_u8_t ** curr,
162                                struct hello_neighbor *neigh)
163 {
164   active_lq_handler->deserialize_hello_lq(curr, neigh->linkquality);
165   neigh->cost = active_lq_handler->calc_hello_cost(neigh->linkquality);
166 }
167
168 /*
169  * olsr_serialize_tc_lq_pair
170  * 
171  * this function converts the lq information of a olsr_serialize_tc_lq_pair
172  * into binary package format
173  * 
174  * @param pointer to binary buffer to write into
175  * @param pointer to olsr_serialize_tc_lq_pair
176  * @return number of bytes that have been written
177  */
178 int
179 olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh)
180 {
181   return active_lq_handler->serialize_tc_lq(buff, neigh->linkquality);
182 }
183
184 /*
185  * olsr_deserialize_tc_lq_pair
186  * 
187  * this function reads the lq information of a binary package into a tc_edge_entry
188  * 
189  * @param pointer to the current buffer pointer
190  * @param pointer to tc_edge_entry
191  */
192 void
193 olsr_deserialize_tc_lq_pair(const olsr_u8_t ** curr, struct tc_edge_entry *edge)
194 {
195   active_lq_handler->deserialize_tc_lq(curr, edge->linkquality);
196 }
197
198 /*
199  * olsr_update_packet_loss_worker
200  * 
201  * this function is called every times a hello package for a certain link_entry
202  * is lost (timeout) or received. This way the lq-plugin can update the links link
203  * quality value.
204  * 
205  * @param pointer to link_entry
206  * @param OLSR_TRUE if hello package was lost
207  */
208 void
209 olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
210 {
211   olsr_linkcost lq;
212   lq = active_lq_handler->packet_loss_handler(entry, entry->linkquality, lost);
213
214   if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
215     entry->linkcost = lq;
216
217     if (olsr_cnf->lq_dlimit > 0) {
218       changes_neighborhood = OLSR_TRUE;
219       changes_topology = OLSR_TRUE;
220     }
221
222     else
223       OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
224
225     /* XXX - we should check whether we actually announce this neighbour */
226     signal_link_changes(OLSR_TRUE);
227   }
228 }
229
230 /*
231  * olsr_memorize_foreign_hello_lq
232  * 
233  * this function is called to copy the link quality information from a received
234  * hello package into a link_entry.
235  * 
236  * @param pointer to link_entry
237  * @param pointer to hello_neighbor, if NULL the neighbor link quality information
238  * of the link entry has to be reset to "zero"
239  */
240 void
241 olsr_memorize_foreign_hello_lq(struct link_entry *local,
242                                struct hello_neighbor *foreign)
243 {
244   if (foreign) {
245     active_lq_handler->memorize_foreign_hello(local->linkquality,
246                                               foreign->linkquality);
247   } else {
248     active_lq_handler->memorize_foreign_hello(local->linkquality, NULL);
249   }
250 }
251
252 /*
253  * get_link_entry_text
254  * 
255  * this function returns the text representation of a link_entry cost value.
256  * It's not thread save and should not be called twice with the same println
257  * value in the same context (a single printf command for example).
258  * 
259  * @param pointer to link_entry
260  * @param buffer for output
261  * @return pointer to a buffer with the text representation
262  */
263 const char *
264 get_link_entry_text(struct link_entry *entry, struct lqtextbuffer *buffer)
265 {
266   return active_lq_handler->print_hello_lq(entry->linkquality, buffer);
267 }
268
269 /*
270  * get_tc_edge_entry_text
271  * 
272  * this function returns the text representation of a tc_edge_entry cost value.
273  * It's not thread save and should not be called twice with the same println
274  * value in the same context (a single printf command for example).
275  * 
276  * @param pointer to tc_edge_entry
277  * @param pointer to buffer
278  * @return pointer to the buffer with the text representation
279  */
280 const char *
281 get_tc_edge_entry_text(struct tc_edge_entry *entry, struct lqtextbuffer *buffer)
282 {
283   return active_lq_handler->print_tc_lq(entry->linkquality, buffer);
284 }
285
286 /*
287  * get_linkcost_text
288  * 
289  * This function transforms an olsr_linkcost value into it's text representation and copies
290  * the result into a buffer.
291  * 
292  * @param linkcost value
293  * @param true to transform the cost of a route, false for a link
294  * @param pointer to buffer
295  * @return pointer to buffer filled with text
296  */
297 const char *
298 get_linkcost_text(olsr_linkcost cost, olsr_bool route,
299                   struct lqtextbuffer *buffer)
300 {
301   static const char *infinite = "INFINITE";
302
303   if (route) {
304     if (cost == ROUTE_COST_BROKEN) {
305       return infinite;
306     }
307   } else {
308     if (cost >= LINK_COST_BROKEN) {
309       return infinite;
310     }
311   }
312   return active_lq_handler->print_cost(cost, buffer);
313 }
314
315 /*
316  * olsr_copy_hello_lq
317  * 
318  * this function copies the link quality information from a link_entry to a
319  * lq_hello_neighbor.
320  * 
321  * @param pointer to target lq_hello_neighbor
322  * @param pointer to source link_entry
323  */
324 void
325 olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source)
326 {
327   memcpy(target->linkquality, source->linkquality,
328          active_lq_handler->hello_lq_size);
329 }
330
331 /*
332  * olsr_copylq_link_entry_2_tc_mpr_addr
333  * 
334  * this function copies the link quality information from a link_entry to a
335  * tc_mpr_addr.
336  * 
337  * @param pointer to tc_mpr_addr
338  * @param pointer to link_entry
339  */
340 void
341 olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target,
342                                      struct link_entry *source)
343 {
344   active_lq_handler->copy_link_lq_into_tc(target->linkquality,
345                                           source->linkquality);
346 }
347
348 /*
349  * olsr_copylq_link_entry_2_tc_edge_entry
350  * 
351  * this function copies the link quality information from a link_entry to a
352  * tc_edge_entry.
353  * 
354  * @param pointer to tc_edge_entry
355  * @param pointer to link_entry
356  */
357 void
358 olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target,
359                                        struct link_entry *source)
360 {
361   active_lq_handler->copy_link_lq_into_tc(target->linkquality,
362                                           source->linkquality);
363 }
364
365 /*
366  * olsr_clear_tc_lq
367  * 
368  * this function resets the linkquality value of a tc_mpr_addr
369  * 
370  * @param pointer to tc_mpr_addr
371  */
372 void
373 olsr_clear_tc_lq(struct tc_mpr_addr *target)
374 {
375   active_lq_handler->clear_tc(target->linkquality);
376 }
377
378 /*
379  * olsr_malloc_hello_neighbor
380  * 
381  * this function allocates memory for an hello_neighbor inclusive
382  * linkquality data.
383  * 
384  * @param id string for memory debugging
385  * 
386  * @return pointer to hello_neighbor
387  */
388 struct hello_neighbor *
389 olsr_malloc_hello_neighbor(const char *id)
390 {
391   struct hello_neighbor *h;
392
393   h =
394     olsr_malloc(sizeof(struct hello_neighbor) +
395                 active_lq_handler->hello_lq_size, id);
396
397   active_lq_handler->clear_hello(h->linkquality);
398   return h;
399 }
400
401 /*
402  * olsr_malloc_tc_mpr_addr
403  * 
404  * this function allocates memory for an tc_mpr_addr inclusive
405  * linkquality data.
406  * 
407  * @param id string for memory debugging
408  * 
409  * @return pointer to tc_mpr_addr
410  */
411 struct tc_mpr_addr *
412 olsr_malloc_tc_mpr_addr(const char *id)
413 {
414   struct tc_mpr_addr *t;
415
416   t =
417     olsr_malloc(sizeof(struct tc_mpr_addr) + active_lq_handler->tc_lq_size, id);
418
419   active_lq_handler->clear_tc(t->linkquality);
420   return t;
421 }
422
423 /*
424  * olsr_malloc_lq_hello_neighbor
425  * 
426  * this function allocates memory for an lq_hello_neighbor inclusive
427  * linkquality data.
428  * 
429  * @param id string for memory debugging
430  * 
431  * @return pointer to lq_hello_neighbor
432  */
433 struct lq_hello_neighbor *
434 olsr_malloc_lq_hello_neighbor(const char *id)
435 {
436   struct lq_hello_neighbor *h;
437
438   h =
439     olsr_malloc(sizeof(struct lq_hello_neighbor) +
440                 active_lq_handler->hello_lq_size, id);
441
442   active_lq_handler->clear_hello(h->linkquality);
443   return h;
444 }
445
446 /*
447  * olsr_malloc_link_entry
448  * 
449  * this function allocates memory for an link_entry inclusive
450  * linkquality data.
451  * 
452  * @param id string for memory debugging
453  * 
454  * @return pointer to link_entry
455  */
456 struct link_entry *
457 olsr_malloc_link_entry(const char *id)
458 {
459   struct link_entry *h;
460
461   h =
462     olsr_malloc(sizeof(struct link_entry) + active_lq_handler->hello_lq_size,
463                 id);
464
465   active_lq_handler->clear_hello(h->linkquality);
466   return h;
467 }
468
469 /*
470  * olsr_malloc_tc_edge_entry
471  * 
472  * this function allocates memory for an tc_edge_entry inclusive
473  * linkquality data.
474  * 
475  * @param id string for memory debugging
476  * 
477  * @return pointer to tc_edge_entry
478  */
479 struct tc_edge_entry *
480 olsr_malloc_tc_edge_entry(const char *id)
481 {
482   struct tc_edge_entry *t;
483
484   t =
485     olsr_malloc(sizeof(struct tc_edge_entry) + active_lq_handler->tc_lq_size,
486                 id);
487
488   active_lq_handler->clear_tc(t);
489   return t;
490 }
491
492 /*
493  * Local Variables:
494  * c-basic-offset: 2
495  * End:
496  */