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