2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
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.
33 * Visit http://www.olsr.org for more information.
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.
44 #include "lq_packet.h"
47 #include "two_hop_neighbor_table.h"
49 #include "lq_plugin_default.h"
50 #include "lq_plugin.h"
52 /* Default lq plugin settings */
53 struct lq_handler default_lq_handler = {
57 &default_olsr_is_relevant_costchange,
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,
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,
70 &default_olsr_print_lq,
71 &default_olsr_print_lq,
72 &default_olsr_print_cost,
74 sizeof(struct default_lq),
75 sizeof(struct default_lq)
78 struct lq_handler *active_lq_handler = &default_lq_handler;
83 * this function is used by routing metric plugins to activate their link
86 * @param pointer to lq_handler structure
87 * @param name of the link quality handler for debug output
89 void set_lq_handler(struct lq_handler *handler, const char *name) {
91 OLSR_PRINTF(1, "Activated lq_handler: %s\n", name);
92 active_lq_handler = handler;
94 OLSR_PRINTF(1, "Activated lq_handler: default\n");
95 active_lq_handler = &default_lq_handler;
98 name = NULL; /* squelch compiler warning */
104 * this function calculates the linkcost of a tc_edge_entry
106 * @param pointer to the tc_edge_entry
109 olsr_linkcost olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
111 return active_lq_handler->calc_tc_cost(tc_edge->linkquality);
115 * olsr_is_relevant_costchange
117 * decides if the difference between two costs is relevant
118 * (for changing the route for example)
120 * @param first linkcost value
121 * @param second linkcost value
124 olsr_bool olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2) {
125 return active_lq_handler->is_relevant_costchange(c1, c2);
129 * olsr_serialize_hello_lq_pair
131 * this function converts the lq information of a lq_hello_neighbor into binary package
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
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);
143 * olsr_deserialize_hello_lq_pair
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
148 * @param pointer to the current buffer pointer
149 * @param pointer to hello_neighbor
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);
157 * olsr_serialize_tc_lq_pair
159 * this function converts the lq information of a olsr_serialize_tc_lq_pair
160 * into binary package format
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
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);
171 * olsr_deserialize_tc_lq_pair
173 * this function reads the lq information of a binary package into a tc_edge_entry
175 * @param pointer to the current buffer pointer
176 * @param pointer to tc_edge_entry
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);
183 * olsr_update_packet_loss_worker
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
189 * @param pointer to link_entry
190 * @param OLSR_TRUE if hello package was lost
192 void olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
195 lq = active_lq_handler->packet_loss_handler(entry->linkquality, lost);
197 if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
198 entry->linkcost = lq;
200 if (olsr_cnf->lq_dlimit > 0) {
201 changes_neighborhood = OLSR_TRUE;
202 changes_topology = OLSR_TRUE;
206 OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
208 // XXX - we should check whether we actually
209 // announce this neighbour
210 signal_link_changes(OLSR_TRUE);
215 * olsr_memorize_foreign_hello_lq
217 * this function is called to copy the link quality information from a received
218 * hello package into a link_entry.
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"
224 void olsr_memorize_foreign_hello_lq(struct link_entry *local, struct hello_neighbor *foreign) {
226 active_lq_handler->memorize_foreign_hello(local->linkquality, foreign->linkquality);
229 active_lq_handler->memorize_foreign_hello(local->linkquality, NULL);
234 * get_link_entry_text
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).
240 * @param pointer to link_entry
241 * @param buffer for output
242 * @return pointer to a buffer with the text representation
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);
249 * get_tc_edge_entry_text
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).
255 * @param pointer to tc_edge_entry
256 * @param pointer to buffer
257 * @return pointer to the buffer with the text representation
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);
266 * This function transforms an olsr_linkcost value into it's text representation and copies
267 * the result into a buffer.
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
274 const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route, struct lqtextbuffer *buffer) {
275 static const char *infinite = "INFINITE";
278 if (cost == ROUTE_COST_BROKEN) {
283 if (cost >= LINK_COST_BROKEN) {
287 return active_lq_handler->print_cost(cost, buffer);
293 * this function copies the link quality information from a link_entry to a
296 * @param pointer to target lq_hello_neighbor
297 * @param pointer to source link_entry
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);
304 * olsr_copylq_link_entry_2_tc_mpr_addr
306 * this function copies the link quality information from a link_entry to a
309 * @param pointer to tc_mpr_addr
310 * @param pointer to link_entry
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);
317 * olsr_copylq_link_entry_2_tc_edge_entry
319 * this function copies the link quality information from a link_entry to a
322 * @param pointer to tc_edge_entry
323 * @param pointer to link_entry
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);
332 * this function resets the linkquality value of a tc_mpr_addr
334 * @param pointer to tc_mpr_addr
336 void olsr_clear_tc_lq(struct tc_mpr_addr *target) {
337 active_lq_handler->clear_tc(target->linkquality);
341 * olsr_malloc_hello_neighbor
343 * this function allocates memory for an hello_neighbor inclusive
346 * @param id string for memory debugging
348 * @return pointer to hello_neighbor
350 struct hello_neighbor *olsr_malloc_hello_neighbor(const char *id) {
351 struct hello_neighbor *h;
353 h = olsr_malloc(sizeof(struct hello_neighbor) + active_lq_handler->hello_lq_size, id);
355 active_lq_handler->clear_hello(h->linkquality);
360 * olsr_malloc_tc_mpr_addr
362 * this function allocates memory for an tc_mpr_addr inclusive
365 * @param id string for memory debugging
367 * @return pointer to tc_mpr_addr
369 struct tc_mpr_addr *olsr_malloc_tc_mpr_addr(const char *id) {
370 struct tc_mpr_addr *t;
372 t = olsr_malloc(sizeof(struct tc_mpr_addr) + active_lq_handler->tc_lq_size, id);
374 active_lq_handler->clear_tc(t->linkquality);
379 * olsr_malloc_lq_hello_neighbor
381 * this function allocates memory for an lq_hello_neighbor inclusive
384 * @param id string for memory debugging
386 * @return pointer to lq_hello_neighbor
388 struct lq_hello_neighbor *olsr_malloc_lq_hello_neighbor(const char *id) {
389 struct lq_hello_neighbor *h;
391 h = olsr_malloc(sizeof(struct lq_hello_neighbor) + active_lq_handler->hello_lq_size, id);
393 active_lq_handler->clear_hello(h->linkquality);
398 * olsr_malloc_link_entry
400 * this function allocates memory for an link_entry inclusive
403 * @param id string for memory debugging
405 * @return pointer to link_entry
407 struct link_entry *olsr_malloc_link_entry(const char *id) {
408 struct link_entry *h;
410 h = olsr_malloc(sizeof(struct link_entry) + active_lq_handler->hello_lq_size, id);
412 active_lq_handler->clear_hello(h->linkquality);
417 * olsr_malloc_tc_edge_entry
419 * this function allocates memory for an tc_edge_entry inclusive
422 * @param id string for memory debugging
424 * @return pointer to tc_edge_entry
426 struct tc_edge_entry *olsr_malloc_tc_edge_entry(const char *id) {
427 struct tc_edge_entry *t;
429 t = olsr_malloc(sizeof(struct tc_edge_entry) + active_lq_handler->tc_lq_size, id);
431 active_lq_handler->clear_tc(t);