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