Cleanup for lq_plugin system, preparation for default fpm
[olsrd.git] / src / lq_plugin_default.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
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 
15  *   distribution.
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.
19  *
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.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
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.
38  *
39  */
40
41 #include "tc_set.h"
42 #include "link_set.h"
43 #include "olsr_spf.h"
44 #include "lq_packet.h"
45 #include "packet.h"
46 #include "olsr.h"
47 #include "lq_plugin_default.h"
48
49 /* Default lq plugin settings */
50 struct lq_handler default_lq_float_handler = {
51   &default_lq_initialize_float,
52   
53   &default_lq_calc_cost_float,
54   &default_lq_calc_cost_float,
55
56   &default_lq_is_relevant_costchange_float,
57
58   &default_lq_packet_loss_worker_float,
59   &default_lq_memorize_foreign_hello_float,
60   &default_lq_copy_link2tc_float,
61   &default_lq_clear_float,
62   &default_lq_clear_float,
63
64   &default_lq_serialize_hello_lq_pair_float,
65   &default_lq_serialize_tc_lq_pair_float,
66   &default_lq_deserialize_hello_lq_pair_float,
67   &default_lq_deserialize_tc_lq_pair_float,
68
69   &default_lq_print_float,
70   &default_lq_print_float,
71   &default_lq_print_cost_float,
72
73   sizeof(struct default_lq_float),
74   sizeof(struct default_lq_float)
75 };
76
77 void default_lq_initialize_float(void) {
78   return;
79 }
80
81 olsr_linkcost default_lq_calc_cost_float(const void *ptr) {
82   const struct default_lq_float *lq = ptr;
83   olsr_linkcost cost;
84   
85   if (lq->lq < MINIMAL_USEFUL_LQ || lq->nlq < MINIMAL_USEFUL_LQ) {
86     return LINK_COST_BROKEN;
87   }
88   
89   cost = (olsr_linkcost)(1.0/(lq->lq * lq->nlq) * LQ_PLUGIN_LC_MULTIPLIER);
90   
91   if (cost > LINK_COST_BROKEN)
92     return LINK_COST_BROKEN;
93   if (cost == 0) {
94     return 1;
95   }
96   return cost;
97 }
98
99 int default_lq_serialize_hello_lq_pair_float(unsigned char *buff, void *ptr) {
100   struct default_lq_float *lq = ptr;
101   
102   olsr_u16_t lq_value = (olsr_u16_t)(lq->lq * 65535);
103   olsr_u16_t nlq_value = (olsr_u16_t)(lq->nlq * 65535);
104   
105   buff[0] = (unsigned char)(lq_value / 256);
106   buff[1] = (unsigned char)(nlq_value / 256);
107   buff[2] = (unsigned char)(lq_value & 255);
108   buff[3] = (unsigned char)(nlq_value & 255);
109   
110   return 4;
111 }
112
113 void default_lq_deserialize_hello_lq_pair_float(const olsr_u8_t **curr, void *ptr) {
114   struct default_lq_float *lq = ptr;
115   
116   olsr_u8_t lq_high, lq_low, nlq_high, nlq_low;
117   olsr_u16_t lq_value, nlq_value;
118   
119   pkt_get_u8(curr, &lq_high);
120   pkt_get_u8(curr, &nlq_high);
121   pkt_get_u8(curr, &lq_low);
122   pkt_get_u8(curr, &nlq_low);
123   
124   lq_value = 256 * (olsr_u16_t)lq_high + (olsr_u16_t)lq_low;
125   nlq_value = 256 * (olsr_u16_t)nlq_high + (olsr_u16_t)nlq_low;
126   
127   lq->lq = (float)lq_value / 65535.0;
128   lq->nlq = (float)nlq_value / 65535.0;
129 }
130
131 olsr_bool default_lq_is_relevant_costchange_float(olsr_linkcost c1, olsr_linkcost c2) {
132   if (c1 > c2) {
133     return c2 - c1 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
134   }
135   return c1 - c2 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
136 }
137
138 int default_lq_serialize_tc_lq_pair_float(unsigned char *buff, void *ptr) {
139   struct default_lq_float *lq = ptr;
140   
141   olsr_u16_t lq_value = (olsr_u16_t)(lq->lq * 65535);
142   olsr_u16_t nlq_value = (olsr_u16_t)(lq->nlq * 65535);
143   
144   buff[0] = (unsigned char)(lq_value / 256);
145   buff[1] = (unsigned char)(nlq_value / 256);
146   buff[2] = (unsigned char)(lq_value & 255);
147   buff[3] = (unsigned char)(nlq_value & 255);
148   
149   return 4;
150 }
151
152 void default_lq_deserialize_tc_lq_pair_float(const olsr_u8_t **curr, void *ptr) {
153   struct default_lq_float *lq = ptr;
154   
155   olsr_u8_t lq_high, lq_low, nlq_high, nlq_low;
156   olsr_u16_t lq_value, nlq_value;
157   
158   pkt_get_u8(curr, &lq_high);
159   pkt_get_u8(curr, &nlq_high);
160   pkt_get_u8(curr, &lq_low);
161   pkt_get_u8(curr, &nlq_low);
162   
163   lq_value = 256 * (olsr_u16_t)lq_high + (olsr_u16_t)lq_low;
164   nlq_value = 256 * (olsr_u16_t)nlq_high + (olsr_u16_t)nlq_low;
165   
166   lq->lq = (float)lq_value / 65535.0;
167   lq->nlq = (float)nlq_value / 65535.0;
168 }
169
170 olsr_linkcost default_lq_packet_loss_worker_float(struct link_entry *link, void *ptr, olsr_bool lost) {
171   struct default_lq_float *tlq = ptr;
172   float alpha = olsr_cnf->lq_aging;
173   
174   if (tlq->quickstart < LQ_QUICKSTART_STEPS) {
175     alpha = LQ_QUICKSTART_AGING; /* fast enough to get the LQ value within 6 Hellos up to 0.9 */
176     tlq->quickstart++;
177   }
178   // exponential moving average
179   tlq->lq *= (1 - alpha);
180   if (lost == 0) {
181     tlq->lq += (alpha * link->loss_link_multiplier / 65536);
182   }
183   return default_lq_calc_cost_float(ptr);
184 }
185
186 void default_lq_memorize_foreign_hello_float(void *ptrLocal, void *ptrForeign) {
187   struct default_lq_float *local = ptrLocal;
188   struct default_lq_float *foreign = ptrForeign;
189   
190   if (foreign) {
191     local->nlq = foreign->lq;
192   }
193   else {
194     local->nlq = 0;
195   }
196 }
197
198 void default_lq_copy_link2tc_float(void *target, void *source) {
199   memcpy(target, source, sizeof(struct default_lq_float));
200 }
201
202 void default_lq_clear_float(void *target) {
203   memset(target, 0, sizeof(struct default_lq_float));
204 }
205
206 const char *default_lq_print_float(void *ptr, struct lqtextbuffer *buffer) {
207   struct default_lq_float *lq = ptr;
208   
209   sprintf(buffer->buf, "%2.3f/%2.3f", lq->lq, lq->nlq);
210   return buffer->buf;
211 }
212
213 const char *default_lq_print_cost_float(olsr_linkcost cost, struct lqtextbuffer *buffer) {
214   sprintf(buffer->buf, "%2.3f", ((float)cost)/LQ_PLUGIN_LC_MULTIPLIER);
215   return buffer->buf;
216 }