Small change in comments
[olsrd.git] / src / lq_plugin.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  */
40
41 #include "tc_set.h"
42 #include "link_set.h"
43 #include "lq_route.h"
44 #include "lq_packet.h"
45 #include "packet.h"
46 #include "olsr.h"
47 #include "two_hop_neighbor_table.h"
48
49 #include "lq_plugin_default.h"
50 #include "lq_plugin.h"
51
52 /* Default lq plugin settings */
53 struct lq_handler default_lq_handler = {
54                 &default_calc_cost,
55                 &default_calc_cost,
56                 
57                 &default_olsr_is_relevant_costchange,
58                 
59                 &default_packet_loss_worker,
60                 &default_olsr_memorize_foreign_hello_lq,
61                 &default_olsr_copy_link_lq_into_tc,
62     &default_olsr_clear_lq,
63     &default_olsr_clear_lq,
64                 
65                 &default_olsr_serialize_hello_lq_pair,
66                 &default_olsr_serialize_tc_lq_pair,
67                 &default_olsr_deserialize_hello_lq_pair,
68                 &default_olsr_deserialize_tc_lq_pair,
69                 
70                 &default_olsr_print_lq,
71                 &default_olsr_print_lq,
72                 &default_olsr_print_cost, 
73                 
74                 sizeof(struct default_lq),
75                 sizeof(struct default_lq)
76 };
77
78 struct lq_handler *active_lq_handler = &default_lq_handler;
79
80 /*
81  * set_lq_handler
82  * 
83  * this function is used by routing metric plugins to activate their link
84  * quality handler
85  * 
86  * @param pointer to lq_handler structure
87  * @param name of the link quality handler for debug output
88  */
89 void set_lq_handler(struct lq_handler *handler, const char *name) {
90   if (handler) {
91     OLSR_PRINTF(1, "Activated lq_handler: %s\n", name);
92     active_lq_handler = handler;
93   }
94   else {
95     OLSR_PRINTF(1, "Activated lq_handler: default\n");
96     active_lq_handler = &default_lq_handler;
97   }
98 }
99
100 /*
101  * olsr_calc_tc_cost
102  * 
103  * this function calculates the linkcost of a tc_edge_entry
104  * 
105  * @param pointer to the tc_edge_entry
106  * @return linkcost
107  */
108 olsr_linkcost olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
109 {
110   return active_lq_handler->calc_tc_cost(tc_edge->linkquality);
111 }
112
113 /*
114  * olsr_is_relevant_costchange
115  * 
116  * decides if the difference between two costs is relevant
117  * (for changing the route for example)
118  * 
119  * @param first linkcost value
120  * @param second linkcost value
121  * @return boolean
122  */
123 olsr_bool olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2) {
124   return active_lq_handler->is_relevant_costchange(c1, c2);
125 }
126
127 /*
128  * olsr_serialize_hello_lq_pair
129  * 
130  * this function converts the lq information of a lq_hello_neighbor into binary package
131  * format
132  * 
133  * @param pointer to binary buffer to write into
134  * @param pointer to lq_hello_neighbor
135  * @return number of bytes that have been written
136  */
137 int olsr_serialize_hello_lq_pair(unsigned char *buff, struct lq_hello_neighbor *neigh) {
138         return active_lq_handler->serialize_hello_lq(buff, neigh->linkquality);
139 }
140
141 /*
142  * olsr_deserialize_hello_lq_pair
143  * 
144  * this function reads the lq information of a binary package into a hello_neighbor
145  * It also initialize the cost variable of the hello_neighbor
146  * 
147  * @param pointer to the current buffer pointer
148  * @param pointer to hello_neighbor
149  */
150 void olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, struct hello_neighbor *neigh) {
151         active_lq_handler->deserialize_hello_lq(curr, neigh->linkquality);
152         neigh->cost = active_lq_handler->calc_hello_cost(neigh->linkquality);
153 }
154
155 /*
156  * olsr_serialize_tc_lq_pair
157  * 
158  * this function converts the lq information of a olsr_serialize_tc_lq_pair
159  * into binary package format
160  * 
161  * @param pointer to binary buffer to write into
162  * @param pointer to olsr_serialize_tc_lq_pair
163  * @return number of bytes that have been written
164  */
165 int olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh) {
166         return active_lq_handler->serialize_tc_lq(buff, neigh->linkquality);
167 }
168
169 /*
170  * olsr_deserialize_tc_lq_pair
171  * 
172  * this function reads the lq information of a binary package into a tc_edge_entry
173  * 
174  * @param pointer to the current buffer pointer
175  * @param pointer to tc_edge_entry
176  */
177 void olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, struct tc_edge_entry *edge) {
178         active_lq_handler->deserialize_tc_lq(curr, edge->linkquality);
179 }
180
181 /*
182  * olsr_update_packet_loss_worker
183  * 
184  * this function is called every times a hello package for a certain link_entry
185  * is lost (timeout) or received. This way the lq-plugin can update the links link
186  * quality value.
187  * 
188  * @param pointer to link_entry
189  * @param OLSR_TRUE if hello package was lost
190  */
191 void olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
192 {
193         olsr_linkcost lq;
194         lq = active_lq_handler->packet_loss_handler(entry->linkquality, lost);
195   
196         if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
197     entry->linkcost = lq;
198     
199     if (olsr_cnf->lq_dlimit > 0) {
200       changes_neighborhood = OLSR_TRUE;
201       changes_topology = OLSR_TRUE;
202     }
203
204     else
205       OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
206     
207     // XXX - we should check whether we actually
208     // announce this neighbour
209     signal_link_changes(OLSR_TRUE);
210   }
211 }
212
213 /*
214  * olsr_memorize_foreign_hello_lq
215  * 
216  * this function is called to copy the link quality information from a received
217  * hello package into a link_entry.
218  * 
219  * @param pointer to link_entry
220  * @param pointer to hello_neighbor, if NULL the neighbor link quality information
221  * of the link entry has to be reset to "zero"
222  */
223 void olsr_memorize_foreign_hello_lq(struct link_entry *local, struct hello_neighbor *foreign) {
224   if (foreign) {
225     active_lq_handler->memorize_foreign_hello(local->linkquality, foreign->linkquality);
226   }
227   else {
228     active_lq_handler->memorize_foreign_hello(local->linkquality, NULL);
229   }
230 }
231
232 /*
233  * get_link_entry_text
234  * 
235  * this function returns the text representation of a link_entry cost value.
236  * It's not thread save and should not be called twice with the same println
237  * value in the same context (a single printf command for example).
238  * 
239  * @param pointer to link_entry
240  * @param buffer for output
241  * @return pointer to a buffer with the text representation
242  */
243 const char *get_link_entry_text(struct link_entry *entry, struct lqtextbuffer *buffer) {
244   return active_lq_handler->print_hello_lq(entry->linkquality, buffer);
245 }
246
247 /*
248  * get_tc_edge_entry_text
249  * 
250  * this function returns the text representation of a tc_edge_entry cost value.
251  * It's not thread save and should not be called twice with the same println
252  * value in the same context (a single printf command for example).
253  * 
254  * @param pointer to tc_edge_entry
255  * @param pointer to buffer
256  * @return pointer to the buffer with the text representation
257  */
258 const char *get_tc_edge_entry_text(struct tc_edge_entry *entry, struct lqtextbuffer *buffer) {
259   return active_lq_handler->print_tc_lq(entry->linkquality, buffer);
260 }
261
262 /*
263  * get_linkcost_text
264  * 
265  * This function transforms an olsr_linkcost value into it's text representation and copies
266  * the result into a buffer.
267  * 
268  * @param linkcost value
269  * @param true to transform the cost of a route, false for a link
270  * @param pointer to buffer
271  * @return pointer to buffer filled with text
272  */
273 const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route, struct lqtextbuffer *buffer) {
274   static const char *infinite = "INFINITE";
275   
276   if (route) {
277     if (cost == ROUTE_COST_BROKEN) {
278       return infinite;
279     }
280   }
281   else {
282     if (cost >= LINK_COST_BROKEN) {
283       return infinite;
284     }
285   }
286   return active_lq_handler->print_cost(cost, buffer);
287 }
288
289 /*
290  * olsr_copy_hello_lq
291  * 
292  * this function copies the link quality information from a link_entry to a
293  * lq_hello_neighbor.
294  * 
295  * @param pointer to target lq_hello_neighbor
296  * @param pointer to source link_entry
297  */
298 void olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source) {
299   memcpy(target->linkquality, source->linkquality, active_lq_handler->hello_lq_size);
300 }
301
302 /*
303  * olsr_copylq_link_entry_2_tc_mpr_addr
304  * 
305  * this function copies the link quality information from a link_entry to a
306  * tc_mpr_addr.
307  * 
308  * @param pointer to tc_mpr_addr
309  * @param pointer to link_entry
310  */
311 void olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target, struct link_entry *source) {
312   active_lq_handler->copy_link_lq_into_tc(target->linkquality, source->linkquality);
313 }
314
315 /*
316  * olsr_copylq_link_entry_2_tc_edge_entry
317  * 
318  * this function copies the link quality information from a link_entry to a
319  * tc_edge_entry.
320  * 
321  * @param pointer to tc_edge_entry
322  * @param pointer to link_entry
323  */
324 void olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source) {
325   active_lq_handler->copy_link_lq_into_tc(target->linkquality, source->linkquality);
326 }
327
328 /*
329  * olsr_clear_tc_lq
330  * 
331  * this function resets the linkquality value of a tc_mpr_addr
332  * 
333  * @param pointer to tc_mpr_addr
334  */
335 void olsr_clear_tc_lq(struct tc_mpr_addr *target) {
336   active_lq_handler->clear_tc(target->linkquality);
337 }
338
339 /*
340  * olsr_malloc_hello_neighbor
341  * 
342  * this function allocates memory for an hello_neighbor inclusive
343  * linkquality data.
344  * 
345  * @param id string for memory debugging
346  * 
347  * @return pointer to hello_neighbor
348  */
349 struct hello_neighbor *olsr_malloc_hello_neighbor(const char *id) {
350         struct hello_neighbor *h;
351         
352         h = olsr_malloc(sizeof(struct hello_neighbor) + active_lq_handler->hello_lq_size, id);
353         
354         active_lq_handler->clear_hello(h->linkquality);
355         return h;
356 }
357
358 /*
359  * olsr_malloc_tc_mpr_addr
360  * 
361  * this function allocates memory for an tc_mpr_addr inclusive
362  * linkquality data.
363  * 
364  * @param id string for memory debugging
365  * 
366  * @return pointer to tc_mpr_addr
367  */
368 struct tc_mpr_addr *olsr_malloc_tc_mpr_addr(const char *id) {
369   struct tc_mpr_addr *t;
370   
371    t = olsr_malloc(sizeof(struct tc_mpr_addr) + active_lq_handler->tc_lq_size, id);
372   
373   active_lq_handler->clear_tc(t->linkquality);
374   return t;
375 }
376
377 /*
378  * olsr_malloc_lq_hello_neighbor
379  * 
380  * this function allocates memory for an lq_hello_neighbor inclusive
381  * linkquality data.
382  * 
383  * @param id string for memory debugging
384  * 
385  * @return pointer to lq_hello_neighbor
386  */
387 struct lq_hello_neighbor *olsr_malloc_lq_hello_neighbor(const char *id) {
388   struct lq_hello_neighbor *h;
389   
390   h = olsr_malloc(sizeof(struct lq_hello_neighbor) + active_lq_handler->hello_lq_size, id);
391   
392   active_lq_handler->clear_hello(h->linkquality);
393   return h;
394 }
395
396 /*
397  * olsr_malloc_link_entry
398  * 
399  * this function allocates memory for an link_entry inclusive
400  * linkquality data.
401  * 
402  * @param id string for memory debugging
403  * 
404  * @return pointer to link_entry
405  */
406 struct link_entry *olsr_malloc_link_entry(const char *id) {
407   struct link_entry *h;
408   
409   h =  olsr_malloc(sizeof(struct link_entry) + active_lq_handler->hello_lq_size, id);
410   
411   active_lq_handler->clear_hello(h->linkquality);
412   return h;
413 }
414
415 /*
416  * olsr_malloc_tc_edge_entry
417  * 
418  * this function allocates memory for an tc_edge_entry inclusive
419  * linkquality data.
420  * 
421  * @param id string for memory debugging
422  * 
423  * @return pointer to tc_edge_entry
424  */
425 struct tc_edge_entry *olsr_malloc_tc_edge_entry(const char *id) {
426   struct tc_edge_entry *t;
427   
428   t = olsr_malloc(sizeof(struct tc_edge_entry) + active_lq_handler->tc_lq_size, id);
429   
430   active_lq_handler->clear_tc(t);
431   return t;
432 }