3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
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.
42 #include "lq_plugin.h"
46 #include "lq_packet.h"
48 #include "olsr_cookie.h"
49 #include "common/avl.h"
50 #include "common/string.h"
51 #include "olsr_logging.h"
53 struct lq_handler *active_lq_handler = NULL;
55 static struct olsr_cookie_info *tc_mpr_addr_mem_cookie = NULL;
56 static struct olsr_cookie_info *tc_edge_mem_cookie = NULL;
57 static struct olsr_cookie_info *lq_hello_neighbor_mem_cookie = NULL;
58 static struct olsr_cookie_info *link_entry_mem_cookie = NULL;
63 if (NULL == active_lq_handler) {
64 OLSR_ERROR(LOG_LQ_PLUGINS, "You removed the static linked LQ plugin and don't provide another one.\n");
68 OLSR_INFO(LOG_LQ_PLUGINS, "Initializing LQ handler %s...\n", active_lq_handler->name);
70 tc_edge_mem_cookie = olsr_alloc_cookie("tc_edge", OLSR_COOKIE_TYPE_MEMORY);
71 olsr_cookie_set_memory_size(tc_edge_mem_cookie, active_lq_handler->size_tc_edge);
73 tc_mpr_addr_mem_cookie = olsr_alloc_cookie("tc_mpr_addr", OLSR_COOKIE_TYPE_MEMORY);
74 olsr_cookie_set_memory_size(tc_mpr_addr_mem_cookie, active_lq_handler->size_tc_mpr_addr);
76 lq_hello_neighbor_mem_cookie = olsr_alloc_cookie("lq_hello_neighbor", OLSR_COOKIE_TYPE_MEMORY);
77 olsr_cookie_set_memory_size(lq_hello_neighbor_mem_cookie, active_lq_handler->size_lq_hello_neighbor);
79 link_entry_mem_cookie = olsr_alloc_cookie("link_entry", OLSR_COOKIE_TYPE_MEMORY);
80 olsr_cookie_set_memory_size(link_entry_mem_cookie, active_lq_handler->size_link_entry);
82 if (active_lq_handler->initialize) {
83 active_lq_handler->initialize();
88 deinit_lq_handler(void)
90 if (NULL != active_lq_handler) {
91 if (active_lq_handler->deinitialize) {
92 active_lq_handler->deinitialize();
94 active_lq_handler = NULL;
101 * this function calculates the linkcost of a tc_edge_entry
103 * @param pointer to the tc_edge_entry
107 olsr_calc_tc_cost(struct tc_edge_entry *tc_edge)
109 return active_lq_handler->calc_tc_edge_entry_cost(tc_edge);
113 * olsr_is_relevant_costchange
115 * decides if the difference between two costs is relevant
116 * (for changing the route for example)
118 * @param first linkcost value
119 * @param second linkcost value
123 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
139 olsr_serialize_hello_lq_pair(unsigned char *buff, struct lq_hello_neighbor *neigh)
141 return active_lq_handler->serialize_hello_lq(buff, neigh);
145 * olsr_deserialize_hello_lq_pair
147 * this function reads the lq information of a binary package into a hello_neighbor
148 * It also initialize the cost variable of the hello_neighbor
150 * @param pointer to the current buffer pointer
151 * @param pointer to hello_neighbor
154 olsr_deserialize_hello_lq_pair(const uint8_t ** curr, struct lq_hello_neighbor *neigh)
156 active_lq_handler->deserialize_hello_lq(curr, neigh);
157 neigh->cost = active_lq_handler->calc_lq_hello_neighbor_cost(neigh);
161 * olsr_serialize_tc_lq_pair
163 * this function converts the lq information of a olsr_serialize_tc_lq_pair
164 * into binary package format
166 * @param pointer to binary buffer to write into
167 * @param pointer to olsr_serialize_tc_lq_pair
168 * @return number of bytes that have been written
171 olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh)
173 return active_lq_handler->serialize_tc_lq(buff, neigh);
177 * olsr_deserialize_tc_lq_pair
179 * this function reads the lq information of a binary package into a tc_edge_entry
181 * @param pointer to the current buffer pointer
182 * @param pointer to tc_edge_entry
185 olsr_deserialize_tc_lq_pair(const uint8_t ** curr, struct tc_edge_entry *edge)
187 active_lq_handler->deserialize_tc_lq(curr, edge);
191 * olsr_update_packet_loss_worker
193 * this function is called every times a hello package for a certain link_entry
194 * is lost (timeout) or received. This way the lq-plugin can update the links link
197 * @param pointer to link_entry
198 * @param true if hello package was lost
201 olsr_update_packet_loss_worker(struct link_entry *entry, bool lost)
204 lq = active_lq_handler->packet_loss_handler(entry, lost);
206 if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
207 entry->linkcost = lq;
209 if (olsr_cnf->lq_dlimit > 0) {
210 changes_neighborhood = true;
211 changes_topology = true;
215 OLSR_DEBUG(LOG_LQ_PLUGINS, "Skipping Dijkstra (1)\n");
217 /* XXX - we should check whether we actually announce this neighbour */
218 signal_link_changes(true);
223 * olsr_memorize_foreign_hello_lq
225 * this function is called to copy the link quality information from a received
226 * hello package into a link_entry.
228 * @param pointer to link_entry
229 * @param pointer to hello_neighbor, if NULL the neighbor link quality information
230 * of the link entry has to be reset to "zero"
233 olsr_memorize_foreign_hello_lq(struct link_entry *local, struct lq_hello_neighbor *foreign)
236 active_lq_handler->memorize_foreign_hello(local, foreign);
238 active_lq_handler->memorize_foreign_hello(local, NULL);
243 * get_link_entry_text
245 * this function returns the text representation of a link_entry cost value.
246 * It's not thread save and should not be called twice with the same println
247 * value in the same context (a single printf command for example).
249 * @param pointer to link_entry
250 * @param char separator between LQ and NLQ
251 * @param buffer for output
252 * @return pointer to a buffer with the text representation
255 get_link_entry_text(struct link_entry *entry, char separator, struct lqtextbuffer *buffer)
257 return active_lq_handler->print_link_entry_lq(entry, separator, buffer);
261 * get_tc_edge_entry_text
263 * this function returns the text representation of a tc_edge_entry cost value.
264 * It's not thread save and should not be called twice with the same println
265 * value in the same context (a single printf command for example).
267 * @param pointer to tc_edge_entry
268 * @param char separator between LQ and NLQ
269 * @param pointer to buffer
270 * @return pointer to the buffer with the text representation
273 get_tc_edge_entry_text(struct tc_edge_entry *entry, char separator, struct lqtextbuffer *buffer)
275 return active_lq_handler->print_tc_edge_entry_lq(entry, separator, buffer);
281 * This function transforms an olsr_linkcost value into it's text representation and copies
282 * the result into a buffer.
284 * @param linkcost value
285 * @param true to transform the cost of a route, false for a link
286 * @param pointer to buffer
287 * @return pointer to buffer filled with text
290 get_linkcost_text(olsr_linkcost cost, bool route, struct lqtextbuffer *buffer)
292 static const char *infinite = "INFINITE";
295 if (cost == ROUTE_COST_BROKEN) {
299 if (cost >= LINK_COST_BROKEN) {
303 return active_lq_handler->print_cost(cost, buffer);
309 * this function copies the link quality information from a link_entry to a
312 * @param pointer to target lq_hello_neighbor
313 * @param pointer to source link_entry
316 olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source)
318 active_lq_handler->copy_link_lq_into_neighbor(target, source);
322 * olsr_copylq_link_entry_2_tc_mpr_addr
324 * this function copies the link quality information from a link_entry to a
327 * @param pointer to tc_mpr_addr
328 * @param pointer to link_entry
331 olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target, struct link_entry *source)
333 active_lq_handler->copy_link_entry_lq_into_tc_mpr_addr(target, source);
337 * olsr_copylq_link_entry_2_tc_edge_entry
339 * this function copies the link quality information from a link_entry to a
342 * @param pointer to tc_edge_entry
343 * @param pointer to link_entry
346 olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source)
348 active_lq_handler->copy_link_entry_lq_into_tc_edge_entry(target, source);
352 * olsr_malloc_tc_edge_entry
354 * this function allocates memory for an tc_mpr_addr inclusive
357 * @return pointer to tc_mpr_addr
359 struct tc_edge_entry *
360 olsr_malloc_tc_edge_entry(void)
362 struct tc_edge_entry *t;
364 t = olsr_cookie_malloc(tc_edge_mem_cookie);
365 if (active_lq_handler->clear_tc_edge_entry)
366 active_lq_handler->clear_tc_edge_entry(t);
371 * olsr_malloc_tc_mpr_addr
373 * this function allocates memory for an tc_mpr_addr inclusive
376 * @return pointer to tc_mpr_addr
379 olsr_malloc_tc_mpr_addr(void)
381 struct tc_mpr_addr *t;
383 t = olsr_cookie_malloc(tc_mpr_addr_mem_cookie);
384 if (active_lq_handler->clear_tc_mpr_addr)
385 active_lq_handler->clear_tc_mpr_addr(t);
390 * olsr_malloc_lq_hello_neighbor
392 * this function allocates memory for an lq_hello_neighbor inclusive
395 * @return pointer to lq_hello_neighbor
397 struct lq_hello_neighbor *
398 olsr_malloc_lq_hello_neighbor(void)
400 struct lq_hello_neighbor *h;
402 h = olsr_cookie_malloc(lq_hello_neighbor_mem_cookie);
403 if (active_lq_handler->clear_lq_hello_neighbor)
404 active_lq_handler->clear_lq_hello_neighbor(h);
409 * olsr_malloc_link_entry
411 * this function allocates memory for an link_entry inclusive
414 * @return pointer to link_entry
417 olsr_malloc_link_entry(void)
419 struct link_entry *h;
421 h = olsr_cookie_malloc(link_entry_mem_cookie);
422 if (active_lq_handler->clear_link_entry)
423 active_lq_handler->clear_link_entry(h);
428 * olsr_free_link_entry
430 * this functions free a link_entry inclusive linkquality data
432 * @param pointer to link_entry
435 olsr_free_link_entry(struct link_entry *link)
437 olsr_cookie_free(link_entry_mem_cookie, link);
441 * olsr_free_lq_hello_neighbor
443 * this functions free a lq_hello_neighbor inclusive linkquality data
445 * @param pointer to lq_hello_neighbor
448 olsr_free_lq_hello_neighbor(struct lq_hello_neighbor *neigh)
450 olsr_cookie_free(lq_hello_neighbor_mem_cookie, neigh);
454 * olsr_free_tc_edge_entry
456 * this functions free a tc_edge_entry inclusive linkquality data
458 * @param pointer to tc_edge_entry
461 olsr_free_tc_edge_entry(struct tc_edge_entry *edge)
463 olsr_cookie_free(tc_edge_mem_cookie, edge);
467 * olsr_free_tc_mpr_addr
469 * this functions free a tc_mpr_addr inclusive linkquality data
471 * @param pointer to tc_mpr_addr
474 olsr_free_tc_mpr_addr(struct tc_mpr_addr *mpr)
476 olsr_cookie_free(tc_mpr_addr_mem_cookie, mpr);
480 * olsr_get_Hello_MessageId
482 * @return olsr id of hello message
485 olsr_get_Hello_MessageId(void)
487 return active_lq_handler->messageid_hello;
491 * olsr_get_TC_MessageId
493 * @return olsr id of tc message
496 olsr_get_TC_MessageId(void)
498 return active_lq_handler->messageid_tc;
502 * olsr_sizeof_HelloLQ
504 * @return number of bytes necessary to store HelloLQ data
507 olsr_sizeof_HelloLQ(void) {
508 return active_lq_handler->serialized_lqhello_size;
514 * @return number of bytes necessary to store TCLQ data
517 olsr_sizeof_TCLQ(void) {
518 return active_lq_handler->serialized_lqtc_size;
524 * indent-tabs-mode: nil