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.
45 #include "lq_packet.h"
47 #include "plugin_util.h"
48 #include "olsr_logging.h"
49 #include "lq_plugin_rfc.h"
51 #define PLUGIN_DESCR "RFC 3626 based hopcount metric. Does not work well, use ETX !"
52 #define PLUGIN_AUTHOR "Henning Rogge"
54 #define DEF_USE_HYST false
55 #define HYST_THRESHOLD_HIGH 0.8
56 #define HYST_THRESHOLD_LOW 0.3
57 #define HYST_SCALING 0.5
59 #define LQ_PLUGIN_LC_MULTIPLIER 1024
61 static int set_plugin_float(const char *, void *, set_plugin_parameter_addon);
63 static olsr_linkcost lq_rfc_calc_link_entry_cost(struct link_entry *);
64 static olsr_linkcost lq_rfc_calc_lq_hello_neighbor_cost(struct lq_hello_neighbor *);
65 static olsr_linkcost lq_rfc_calc_tc_mpr_addr_cost(struct tc_mpr_addr *);
66 static olsr_linkcost lq_rfc_calc_tc_edge_entry_cost(struct tc_edge_entry *);
68 static bool lq_rfc_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2);
70 static olsr_linkcost lq_rfc_packet_loss_handler(struct link_entry *, bool);
72 static void lq_rfc_memorize_foreign_hello(struct link_entry *, struct lq_hello_neighbor *);
73 static void lq_rfc_copy_link_entry_lq_into_tc_mpr_addr(struct tc_mpr_addr *target, struct link_entry *source);
74 static void lq_rfc_copy_link_entry_lq_into_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source);
75 static void lq_rfc_copy_link_lq_into_neighbor(struct lq_hello_neighbor *target, struct link_entry *source);
77 static int lq_rfc_serialize_hello_lq(unsigned char *buff, struct lq_hello_neighbor *lq);
78 static int lq_rfc_serialize_tc_lq(unsigned char *buff, struct tc_mpr_addr *lq);
79 static void lq_rfc_deserialize_hello_lq(uint8_t const **curr, struct lq_hello_neighbor *lq);
80 static void lq_rfc_deserialize_tc_lq(uint8_t const **curr, struct tc_edge_entry *lq);
82 static char *lq_rfc_print_link_entry_lq(struct link_entry *entry, char separator, struct lqtextbuffer *buffer);
83 static char *lq_rfc_print_tc_edge_entry_lq(struct tc_edge_entry *ptr, char separator, struct lqtextbuffer *buffer);
84 static char *lq_rfc_print_cost(olsr_linkcost cost, struct lqtextbuffer *buffer);
86 /* RFC "lq" handler (hopcount metric with hysteresis) */
87 struct lq_handler lq_rfc_handler = {
93 &lq_rfc_calc_link_entry_cost,
94 &lq_rfc_calc_lq_hello_neighbor_cost,
95 &lq_rfc_calc_tc_mpr_addr_cost,
96 &lq_rfc_calc_tc_edge_entry_cost,
98 &lq_rfc_is_relevant_costchange,
100 &lq_rfc_packet_loss_handler,
102 &lq_rfc_memorize_foreign_hello,
103 &lq_rfc_copy_link_entry_lq_into_tc_mpr_addr,
104 &lq_rfc_copy_link_entry_lq_into_tc_edge_entry,
105 &lq_rfc_copy_link_lq_into_neighbor,
112 &lq_rfc_serialize_hello_lq,
113 &lq_rfc_serialize_tc_lq,
114 &lq_rfc_deserialize_hello_lq,
115 &lq_rfc_deserialize_tc_lq,
117 &lq_rfc_print_link_entry_lq,
118 &lq_rfc_print_tc_edge_entry_lq,
121 sizeof(struct tc_edge_entry),
122 sizeof(struct tc_mpr_addr),
123 sizeof(struct lq_hello_neighbor),
124 sizeof(struct lq_rfc_link_entry),
132 static bool use_hysteresis = DEF_USE_HYST;
133 static float scaling = HYST_SCALING;
134 static float thr_high = HYST_THRESHOLD_HIGH;
135 static float thr_low = HYST_THRESHOLD_LOW;
137 static const struct olsrd_plugin_parameters plugin_parameters[] = {
138 {.name = "UseHysteresis",.set_plugin_parameter = &set_plugin_boolean,.data = &use_hysteresis},
139 {.name = "HystScaling",.set_plugin_parameter = &set_plugin_float,.data = &scaling},
140 {.name = "HystThrHigh",.set_plugin_parameter = &set_plugin_float,.data = &thr_high},
141 {.name = "HystThrLow",.set_plugin_parameter = &set_plugin_float,.data = &thr_low},
144 DEFINE_PLUGIN6(PLUGIN_DESCR, PLUGIN_AUTHOR, NULL, NULL, NULL, NULL, false, plugin_parameters)
147 set_plugin_float(const char *value, void *data, set_plugin_parameter_addon addon __attribute__ ((unused)))
150 sscanf(value, "%f", (float *)data);
151 OLSR_INFO(LOG_LQ_PLUGINS, "%s float %f\n", "Got", *(float *)data);
153 OLSR_INFO(LOG_LQ_PLUGINS, "%s float %s\n", "Ignored", value);
159 lq_rfc_calc_link_entry_cost(struct link_entry __attribute__ ((unused)) * link)
165 lq_rfc_calc_lq_hello_neighbor_cost(struct lq_hello_neighbor __attribute__ ((unused)) * neigh)
171 lq_rfc_calc_tc_mpr_addr_cost(struct tc_mpr_addr __attribute__ ((unused)) * mpr)
177 lq_rfc_calc_tc_edge_entry_cost(struct tc_edge_entry __attribute__ ((unused)) * edge)
183 lq_rfc_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2)
189 lq_rfc_packet_loss_handler(struct link_entry *link, bool loss)
191 struct lq_rfc_link_entry *link_entry = (struct lq_rfc_link_entry *)link;
196 link_entry->hysteresis *= (1 - scaling);
198 link_entry->hysteresis += scaling;
201 if (link_entry->active && link_entry->hysteresis < thr_low) {
202 link_entry->active = false;
203 } else if (!link_entry->active && link_entry->hysteresis > thr_high) {
204 link_entry->active = true;
207 return link_entry->active ? 1 : LINK_COST_BROKEN;
211 lq_rfc_memorize_foreign_hello(struct link_entry __attribute__ ((unused)) * target,
212 struct lq_hello_neighbor __attribute__ ((unused)) * source)
217 lq_rfc_copy_link_entry_lq_into_tc_mpr_addr(struct tc_mpr_addr __attribute__ ((unused)) * target, struct link_entry
218 __attribute__ ((unused)) * source)
223 lq_rfc_copy_link_entry_lq_into_tc_edge_entry(struct tc_edge_entry __attribute__ ((unused)) * target, struct link_entry
224 __attribute__ ((unused)) * source)
229 lq_rfc_copy_link_lq_into_neighbor(struct lq_hello_neighbor __attribute__ ((unused)) * target,
230 struct link_entry __attribute__ ((unused)) * source)
235 lq_rfc_serialize_hello_lq(unsigned char __attribute__ ((unused)) * buff, struct lq_hello_neighbor __attribute__ ((unused)) * neigh)
240 lq_rfc_serialize_tc_lq(unsigned char __attribute__ ((unused)) * buff, struct tc_mpr_addr __attribute__ ((unused)) * mpr)
246 lq_rfc_deserialize_hello_lq(uint8_t const __attribute__ ((unused)) ** curr,
247 struct lq_hello_neighbor __attribute__ ((unused)) * neigh)
252 lq_rfc_deserialize_tc_lq(uint8_t const __attribute__ ((unused)) ** curr, struct tc_edge_entry __attribute__ ((unused)) * edge)
257 lq_rfc_print_link_entry_lq(struct link_entry __attribute__ ((unused)) * link, char __attribute__ ((unused)) separator,
258 struct lqtextbuffer *buffer)
260 strcpy(buffer->buf, "");
265 lq_rfc_print_tc_edge_entry_lq(struct tc_edge_entry __attribute__ ((unused)) * edge,
266 char __attribute__ ((unused)) separator, struct lqtextbuffer *buffer)
268 strcpy(buffer->buf, "");
273 lq_rfc_print_cost(olsr_linkcost cost, struct lqtextbuffer *buffer)
275 sprintf(buffer->buf, "%d", cost);
282 * indent-tabs-mode: nil