3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 * Visit http://www.olsr.org for more information.
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.
45 #include "lq_packet.h"
48 #include "two_hop_neighbor_table.h"
49 #include "common/avl.h"
51 #include "lq_plugin_default_float.h"
52 #include "lq_plugin_default_fpm.h"
54 struct avl_tree lq_handler_tree;
55 struct lq_handler *active_lq_handler = NULL;
58 avl_strcasecmp(const void *str1, const void *str2)
60 return strcasecmp(str1, str2);
65 init_lq_handler_tree(void)
67 avl_init(&lq_handler_tree, &avl_strcasecmp);
68 register_lq_handler(&lq_etx_float_handler, LQ_ALGORITHM_ETX_FLOAT_NAME);
69 register_lq_handler(&lq_etx_fpm_handler, LQ_ALGORITHM_ETX_FPM_NAME);
71 if (activate_lq_handler(olsr_cnf->lq_algorithm)) {
72 activate_lq_handler(LQ_ALGORITHM_ETX_FPM_NAME);
79 * this function is used by routing metric plugins to activate their link
82 * The name parameter is marked as "unused" to squelch a compiler warning if debug
83 * output is not active
85 * @param pointer to lq_handler structure
86 * @param name of the link quality handler for debug output
89 register_lq_handler(struct lq_handler *handler, const char *name)
91 struct lq_handler_node *node;
93 node = olsr_malloc(sizeof(*node) + strlen(name) + 1, "olsr lq handler");
95 strcpy(node->name, name);
96 node->node.key = node->name;
97 node->handler = handler;
99 avl_insert(&lq_handler_tree, &node->node, OLSR_FALSE);
103 activate_lq_handler(const char *name)
105 struct lq_handler_node *node;
110 node = (struct lq_handler_node *) avl_find(&lq_handler_tree, name);
112 OLSR_PRINTF(1, "Error, unknown lq_handler '%s'\n", name);
116 OLSR_PRINTF(1, "Using '%s' algorithm for lq calculation.\n", name);
117 active_lq_handler = node->handler;
118 active_lq_handler->initialize();
126 * this function calculates the linkcost of a tc_edge_entry
128 * @param pointer to the tc_edge_entry
132 olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
134 return active_lq_handler->calc_tc_cost(tc_edge->linkquality);
138 * olsr_is_relevant_costchange
140 * decides if the difference between two costs is relevant
141 * (for changing the route for example)
143 * @param first linkcost value
144 * @param second linkcost value
148 olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2)
150 return active_lq_handler->is_relevant_costchange(c1, c2);
154 * olsr_serialize_hello_lq_pair
156 * this function converts the lq information of a lq_hello_neighbor into binary package
159 * @param pointer to binary buffer to write into
160 * @param pointer to lq_hello_neighbor
161 * @return number of bytes that have been written
164 olsr_serialize_hello_lq_pair(unsigned char *buff,
165 struct lq_hello_neighbor *neigh)
167 return active_lq_handler->serialize_hello_lq(buff, neigh->linkquality);
171 * olsr_deserialize_hello_lq_pair
173 * this function reads the lq information of a binary package into a hello_neighbor
174 * It also initialize the cost variable of the hello_neighbor
176 * @param pointer to the current buffer pointer
177 * @param pointer to hello_neighbor
180 olsr_deserialize_hello_lq_pair(const olsr_u8_t ** curr,
181 struct hello_neighbor *neigh)
183 active_lq_handler->deserialize_hello_lq(curr, neigh->linkquality);
184 neigh->cost = active_lq_handler->calc_hello_cost(neigh->linkquality);
188 * olsr_serialize_tc_lq_pair
190 * this function converts the lq information of a olsr_serialize_tc_lq_pair
191 * into binary package format
193 * @param pointer to binary buffer to write into
194 * @param pointer to olsr_serialize_tc_lq_pair
195 * @return number of bytes that have been written
198 olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh)
200 return active_lq_handler->serialize_tc_lq(buff, neigh->linkquality);
204 * olsr_deserialize_tc_lq_pair
206 * this function reads the lq information of a binary package into a tc_edge_entry
208 * @param pointer to the current buffer pointer
209 * @param pointer to tc_edge_entry
212 olsr_deserialize_tc_lq_pair(const olsr_u8_t ** curr, struct tc_edge_entry *edge)
214 active_lq_handler->deserialize_tc_lq(curr, edge->linkquality);
218 * olsr_update_packet_loss_worker
220 * this function is called every times a hello package for a certain link_entry
221 * is lost (timeout) or received. This way the lq-plugin can update the links link
224 * @param pointer to link_entry
225 * @param OLSR_TRUE if hello package was lost
228 olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
231 lq = active_lq_handler->packet_loss_handler(entry, entry->linkquality, lost);
233 if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
234 entry->linkcost = lq;
236 if (olsr_cnf->lq_dlimit > 0) {
237 changes_neighborhood = OLSR_TRUE;
238 changes_topology = OLSR_TRUE;
242 OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
244 /* XXX - we should check whether we actually announce this neighbour */
245 signal_link_changes(OLSR_TRUE);
250 * olsr_memorize_foreign_hello_lq
252 * this function is called to copy the link quality information from a received
253 * hello package into a link_entry.
255 * @param pointer to link_entry
256 * @param pointer to hello_neighbor, if NULL the neighbor link quality information
257 * of the link entry has to be reset to "zero"
260 olsr_memorize_foreign_hello_lq(struct link_entry *local,
261 struct hello_neighbor *foreign)
264 active_lq_handler->memorize_foreign_hello(local->linkquality,
265 foreign->linkquality);
267 active_lq_handler->memorize_foreign_hello(local->linkquality, NULL);
272 * get_link_entry_text
274 * this function returns the text representation of a link_entry cost value.
275 * It's not thread save and should not be called twice with the same println
276 * value in the same context (a single printf command for example).
278 * @param pointer to link_entry
279 * @param buffer for output
280 * @return pointer to a buffer with the text representation
283 get_link_entry_text(struct link_entry *entry, struct lqtextbuffer *buffer)
285 return active_lq_handler->print_hello_lq(entry->linkquality, buffer);
289 * get_tc_edge_entry_text
291 * this function returns the text representation of a tc_edge_entry cost value.
292 * It's not thread save and should not be called twice with the same println
293 * value in the same context (a single printf command for example).
295 * @param pointer to tc_edge_entry
296 * @param pointer to buffer
297 * @return pointer to the buffer with the text representation
300 get_tc_edge_entry_text(struct tc_edge_entry *entry, struct lqtextbuffer *buffer)
302 return active_lq_handler->print_tc_lq(entry->linkquality, buffer);
308 * This function transforms an olsr_linkcost value into it's text representation and copies
309 * the result into a buffer.
311 * @param linkcost value
312 * @param true to transform the cost of a route, false for a link
313 * @param pointer to buffer
314 * @return pointer to buffer filled with text
317 get_linkcost_text(olsr_linkcost cost, olsr_bool route,
318 struct lqtextbuffer *buffer)
320 static const char *infinite = "INFINITE";
323 if (cost == ROUTE_COST_BROKEN) {
327 if (cost >= LINK_COST_BROKEN) {
331 return active_lq_handler->print_cost(cost, buffer);
337 * this function copies the link quality information from a link_entry to a
340 * @param pointer to target lq_hello_neighbor
341 * @param pointer to source link_entry
344 olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source)
346 memcpy(target->linkquality, source->linkquality,
347 active_lq_handler->hello_lq_size);
351 * olsr_copylq_link_entry_2_tc_mpr_addr
353 * this function copies the link quality information from a link_entry to a
356 * @param pointer to tc_mpr_addr
357 * @param pointer to link_entry
360 olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target,
361 struct link_entry *source)
363 active_lq_handler->copy_link_lq_into_tc(target->linkquality,
364 source->linkquality);
368 * olsr_copylq_link_entry_2_tc_edge_entry
370 * this function copies the link quality information from a link_entry to a
373 * @param pointer to tc_edge_entry
374 * @param pointer to link_entry
377 olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target,
378 struct link_entry *source)
380 active_lq_handler->copy_link_lq_into_tc(target->linkquality,
381 source->linkquality);
387 * this function resets the linkquality value of a tc_mpr_addr
389 * @param pointer to tc_mpr_addr
392 olsr_clear_tc_lq(struct tc_mpr_addr *target)
394 active_lq_handler->clear_tc(target->linkquality);
398 * olsr_malloc_hello_neighbor
400 * this function allocates memory for an hello_neighbor inclusive
403 * @param id string for memory debugging
405 * @return pointer to hello_neighbor
407 struct hello_neighbor *
408 olsr_malloc_hello_neighbor(const char *id)
410 struct hello_neighbor *h;
413 olsr_malloc(sizeof(struct hello_neighbor) +
414 active_lq_handler->hello_lq_size, id);
416 active_lq_handler->clear_hello(h->linkquality);
421 * olsr_malloc_tc_mpr_addr
423 * this function allocates memory for an tc_mpr_addr inclusive
426 * @param id string for memory debugging
428 * @return pointer to tc_mpr_addr
431 olsr_malloc_tc_mpr_addr(const char *id)
433 struct tc_mpr_addr *t;
436 olsr_malloc(sizeof(struct tc_mpr_addr) + active_lq_handler->tc_lq_size, id);
438 active_lq_handler->clear_tc(t->linkquality);
443 * olsr_malloc_lq_hello_neighbor
445 * this function allocates memory for an lq_hello_neighbor inclusive
448 * @param id string for memory debugging
450 * @return pointer to lq_hello_neighbor
452 struct lq_hello_neighbor *
453 olsr_malloc_lq_hello_neighbor(const char *id)
455 struct lq_hello_neighbor *h;
458 olsr_malloc(sizeof(struct lq_hello_neighbor) +
459 active_lq_handler->hello_lq_size, id);
461 active_lq_handler->clear_hello(h->linkquality);
466 * olsr_malloc_link_entry
468 * this function allocates memory for an link_entry inclusive
471 * @param id string for memory debugging
473 * @return pointer to link_entry
476 olsr_malloc_link_entry(const char *id)
478 struct link_entry *h;
481 olsr_malloc(sizeof(struct link_entry) + active_lq_handler->hello_lq_size,
484 active_lq_handler->clear_hello(h->linkquality);