facb38a53ae1b39827612a0dc5b5b6182687cac5
[olsrd.git] / src / lq_plugin.c
1 #include "tc_set.h"
2 #include "link_set.h"
3 #include "lq_route.h"
4 #include "lq_packet.h"
5 #include "packet.h"
6 #include "olsr.h"
7
8 #include "lq_plugin_default.h"
9 #include "lq_plugin.h"
10
11 /* Default lq plugin settings */
12 struct lq_handler default_lq_handler = {
13                 &default_calc_cost,
14                 &default_calc_cost,
15                 
16                 &default_olsr_is_relevant_costchange,
17                 
18                 &default_packet_loss_worker,
19                 &default_olsr_memorize_foreign_hello_lq,
20                 &default_olsr_copy_link_lq_into_tc,
21     &default_olsr_clear_lq,
22     &default_olsr_clear_lq,
23                 
24                 &default_olsr_serialize_hello_lq_pair,
25                 &default_olsr_serialize_tc_lq_pair,
26                 &default_olsr_deserialize_hello_lq_pair,
27                 &default_olsr_deserialize_tc_lq_pair,
28                 
29                 &default_olsr_print_lq,
30                 &default_olsr_print_lq,
31                 &default_olsr_print_cost, 
32                 
33                 sizeof(struct default_lq),
34                 sizeof(struct default_lq)
35 };
36
37 struct lq_handler *active_lq_handler = &default_lq_handler;
38
39 /*
40  * set_lq_handler
41  * 
42  * this function is used by routing metric plugins to activate their link
43  * quality handler
44  * 
45  * @param pointer to lq_handler structure
46  * @param name of the link quality handler for debug output
47  */
48 void set_lq_handler(struct lq_handler *handler, char *name) {
49   if (handler) {
50     OLSR_PRINTF(1, "Activated lq_handler: %s\n", name);
51     active_lq_handler = handler;
52   }
53   else {
54     OLSR_PRINTF(1, "Activated lq_handler: default\n");
55     active_lq_handler = &default_lq_handler;
56   }
57 }
58
59 /*
60  * olsr_calc_tc_cost
61  * 
62  * this function calculates the linkcost of a tc_edge_entry
63  * 
64  * @param pointer to the tc_edge_entry
65  * @return linkcost
66  */
67 olsr_linkcost olsr_calc_tc_cost(const struct tc_edge_entry *tc_edge)
68 {
69   return active_lq_handler->calc_tc_cost(tc_edge->linkquality);
70 }
71
72 /*
73  * olsr_is_relevant_costchange
74  * 
75  * decides if the difference between two costs is relevant
76  * (for changing the route for example)
77  * 
78  * @param first linkcost value
79  * @param second linkcost value
80  * @return boolean
81  */
82 olsr_bool olsr_is_relevant_costchange(olsr_linkcost c1, olsr_linkcost c2) {
83   return active_lq_handler->is_relevant_costchange(c1, c2);
84 }
85
86 /*
87  * olsr_serialize_hello_lq_pair
88  * 
89  * this function converts the lq information of a lq_hello_neighbor into binary package
90  * format
91  * 
92  * @param pointer to binary buffer to write into
93  * @param pointer to lq_hello_neighbor
94  * @return number of bytes that have been written
95  */
96 int olsr_serialize_hello_lq_pair(unsigned char *buff, struct lq_hello_neighbor *neigh) {
97         return active_lq_handler->serialize_hello_lq(buff, neigh->linkquality);
98 }
99
100 /*
101  * olsr_deserialize_hello_lq_pair
102  * 
103  * this function reads the lq information of a binary package into a hello_neighbor
104  * It also initialize the cost variable of the hello_neighbor
105  * 
106  * @param pointer to the current buffer pointer
107  * @param pointer to hello_neighbor
108  */
109 void olsr_deserialize_hello_lq_pair(const olsr_u8_t **curr, struct hello_neighbor *neigh) {
110         active_lq_handler->deserialize_hello_lq(curr, neigh->linkquality);
111         neigh->cost = active_lq_handler->calc_hello_cost(neigh->linkquality);
112 }
113
114 /*
115  * olsr_serialize_tc_lq_pair
116  * 
117  * this function converts the lq information of a olsr_serialize_tc_lq_pair
118  * into binary package format
119  * 
120  * @param pointer to binary buffer to write into
121  * @param pointer to olsr_serialize_tc_lq_pair
122  * @return number of bytes that have been written
123  */
124 int olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh) {
125         return active_lq_handler->serialize_tc_lq(buff, neigh->linkquality);
126 }
127
128 /*
129  * olsr_deserialize_tc_lq_pair
130  * 
131  * this function reads the lq information of a binary package into a tc_edge_entry
132  * 
133  * @param pointer to the current buffer pointer
134  * @param pointer to tc_edge_entry
135  */
136 void olsr_deserialize_tc_lq_pair(const olsr_u8_t **curr, struct tc_edge_entry *edge) {
137         active_lq_handler->deserialize_tc_lq(curr, edge->linkquality);
138 }
139
140 /*
141  * olsr_update_packet_loss_worker
142  * 
143  * this function is called every times a hello package for a certain link_entry
144  * is lost (timeout) or received. This way the lq-plugin can update the links link
145  * quality value.
146  * 
147  * @param pointer to link_entry
148  * @param OLSR_TRUE if hello package was lost
149  */
150 void olsr_update_packet_loss_worker(struct link_entry *entry, olsr_bool lost)
151 {
152         olsr_linkcost lq;
153         lq = active_lq_handler->packet_loss_handler(entry->linkquality, lost);
154   
155         if (olsr_is_relevant_costchange(lq, entry->linkcost)) {
156     entry->linkcost = lq;
157     
158     if (olsr_cnf->lq_dlimit > 0) {
159       changes_neighborhood = OLSR_TRUE;
160       changes_topology = OLSR_TRUE;
161     }
162
163     else
164       OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
165     
166     // XXX - we should check whether we actually
167     // announce this neighbour
168     signal_link_changes(OLSR_TRUE);
169   }
170 }
171
172 /*
173  * olsr_memorize_foreign_hello_lq
174  * 
175  * this function is called to copy the link quality information from a received
176  * hello package into a link_entry.
177  * 
178  * @param pointer to link_entry
179  * @param pointer to hello_neighbor, if NULL the neighbor link quality information
180  * of the link entry has to be reset to "zero"
181  */
182 void olsr_memorize_foreign_hello_lq(struct link_entry *local, struct hello_neighbor *foreign) {
183   if (foreign) {
184     active_lq_handler->memorize_foreign_hello(local->linkquality, foreign->linkquality);
185   }
186   else {
187     active_lq_handler->memorize_foreign_hello(local->linkquality, NULL);
188   }
189 }
190
191 /*
192  * get_link_entry_text
193  * 
194  * this function returns the text representation of a link_entry cost value.
195  * It's not thread save and should not be called twice with the same println
196  * value in the same context (a single printf command for example).
197  * 
198  * @param pointer to link_entry
199  * @return pointer to a buffer with the text representation
200  */
201 char *get_link_entry_text(struct link_entry *entry) {
202   return active_lq_handler->print_hello_lq(entry->linkquality);
203 }
204
205 /*
206  * get_tc_edge_entry_text
207  * 
208  * this function returns the text representation of a tc_edge_entry cost value.
209  * It's not thread save and should not be called twice with the same println
210  * value in the same context (a single printf command for example).
211  * 
212  * @param pointer to tc_edge_entry
213  * @return pointer to a buffer with the text representation
214  */
215 char *get_tc_edge_entry_text(struct tc_edge_entry *entry) {
216   return active_lq_handler->print_tc_lq(entry->linkquality);
217 }
218
219 const char *get_linkcost_text(olsr_linkcost cost, olsr_bool route) {
220   static const char *infinite = "INFINITE";
221   
222   if (route) {
223     if (cost == ROUTE_COST_BROKEN) {
224       return infinite;
225     }
226   }
227   else {
228     if (cost >= LINK_COST_BROKEN) {
229       return infinite;
230     }
231   }
232   return active_lq_handler->print_cost(cost);
233 }
234
235 /*
236  * olsr_copy_hello_lq
237  * 
238  * this function copies the link quality information from a link_entry to a
239  * lq_hello_neighbor.
240  * 
241  * @param pointer to target lq_hello_neighbor
242  * @param pointer to source link_entry
243  */
244 void olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source) {
245   memcpy(target->linkquality, source->linkquality, active_lq_handler->hello_lq_size);
246 }
247
248 /*
249  * olsr_copylq_link_entry_2_tc_mpr_addr
250  * 
251  * this function copies the link quality information from a link_entry to a
252  * tc_mpr_addr.
253  * 
254  * @param pointer to tc_mpr_addr
255  * @param pointer to link_entry
256  */
257 void olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target, struct link_entry *source) {
258   active_lq_handler->copy_link_lq_into_tc(target->linkquality, source->linkquality);
259 }
260
261 /*
262  * olsr_copylq_link_entry_2_tc_edge_entry
263  * 
264  * this function copies the link quality information from a link_entry to a
265  * tc_edge_entry.
266  * 
267  * @param pointer to tc_edge_entry
268  * @param pointer to link_entry
269  */
270 void olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source) {
271   active_lq_handler->copy_link_lq_into_tc(target->linkquality, source->linkquality);
272 }
273
274 /*
275  * olsr_clear_tc_lq
276  * 
277  * this function resets the linkquality value of a tc_mpr_addr
278  * 
279  * @param pointer to tc_mpr_addr
280  */
281 void olsr_clear_tc_lq(struct tc_mpr_addr *target) {
282   active_lq_handler->clear_tc(target->linkquality);
283 }
284
285 /*
286  * olsr_malloc_hello_neighbor
287  * 
288  * this function allocates memory for an hello_neighbor inclusive
289  * linkquality data.
290  * 
291  * @param id string for memory debugging
292  * 
293  * @return pointer to hello_neighbor
294  */
295 struct hello_neighbor *olsr_malloc_hello_neighbor(const char *id) {
296         struct hello_neighbor *h;
297         
298         h = olsr_malloc(sizeof(struct hello_neighbor) + active_lq_handler->hello_lq_size, id);
299         
300         active_lq_handler->clear_hello(h->linkquality);
301         return h;
302 }
303
304 /*
305  * olsr_malloc_tc_mpr_addr
306  * 
307  * this function allocates memory for an tc_mpr_addr inclusive
308  * linkquality data.
309  * 
310  * @param id string for memory debugging
311  * 
312  * @return pointer to tc_mpr_addr
313  */
314 struct tc_mpr_addr *olsr_malloc_tc_mpr_addr(const char *id) {
315   struct tc_mpr_addr *t;
316   
317    t = olsr_malloc(sizeof(struct tc_mpr_addr) + active_lq_handler->tc_lq_size, id);
318   
319   active_lq_handler->clear_tc(t->linkquality);
320   return t;
321 }
322
323 /*
324  * olsr_malloc_lq_hello_neighbor
325  * 
326  * this function allocates memory for an lq_hello_neighbor inclusive
327  * linkquality data.
328  * 
329  * @param id string for memory debugging
330  * 
331  * @return pointer to lq_hello_neighbor
332  */
333 struct lq_hello_neighbor *olsr_malloc_lq_hello_neighbor(const char *id) {
334   struct lq_hello_neighbor *h;
335   
336   h = olsr_malloc(sizeof(struct lq_hello_neighbor) + active_lq_handler->hello_lq_size, id);
337   
338   active_lq_handler->clear_hello(h->linkquality);
339   return h;
340 }
341
342 /*
343  * olsr_malloc_link_entry
344  * 
345  * this function allocates memory for an link_entry inclusive
346  * linkquality data.
347  * 
348  * @param id string for memory debugging
349  * 
350  * @return pointer to link_entry
351  */
352 struct link_entry *olsr_malloc_link_entry(const char *id) {
353   struct link_entry *h;
354   
355   h =  olsr_malloc(sizeof(struct link_entry) + active_lq_handler->hello_lq_size, id);
356   
357   active_lq_handler->clear_hello(h->linkquality);
358   return h;
359 }
360
361 /*
362  * olsr_malloc_tc_edge_entry
363  * 
364  * this function allocates memory for an tc_edge_entry inclusive
365  * linkquality data.
366  * 
367  * @param id string for memory debugging
368  * 
369  * @return pointer to tc_edge_entry
370  */
371 struct tc_edge_entry *olsr_malloc_tc_edge_entry(const char *id) {
372   struct tc_edge_entry *t;
373   
374   t = olsr_malloc(sizeof(struct tc_edge_entry) + active_lq_handler->tc_lq_size, id);
375   
376   active_lq_handler->clear_tc(t);
377   return t;
378 }