Cleanup for lq_plugin system, preparation for default fpm
[olsrd.git] / lib / lq_etx_fpm / src / lq_etx_fpm.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 "lq_plugin.h"
44 #include "olsr_spf.h"
45 #include "lq_packet.h"
46 #include "packet.h"
47 #include "olsr.h"
48 #include "lq_etx_fpm.h"
49 #include "fpm.h"
50
51 /* etx lq plugin (fpm version) settings */
52 struct lq_handler lq_etx_fpm_handler = {
53     &default_lq_initialize_fpm,
54     
55     &default_lq_calc_cost_fpm,
56     &default_lq_calc_cost_fpm,
57     
58     &default_lq_is_relevant_costchange_fpm,
59     
60     &default_lq_packet_loss_worker_fpm,
61     &default_lq_memorize_foreign_hello_fpm,
62     &default_lq_copy_link2tc_fpm,
63     &default_lq_clear_fpm,
64     &default_lq_clear_fpm,
65     
66     &default_lq_serialize_hello_lq_pair_fpm,
67     &default_lq_serialize_tc_lq_pair_fpm,
68     &default_lq_deserialize_hello_lq_pair_fpm,
69     &default_lq_deserialize_tc_lq_pair_fpm,
70     
71     &default_lq_print_fpm,
72     &default_lq_print_fpm,
73     &default_lq_print_cost_fpm, 
74     
75     sizeof(struct default_lq_fpm),
76     sizeof(struct default_lq_fpm)
77 };
78
79 fpm minimal_lq;
80 fpm aging_factor_new, aging_factor_old;
81 fpm aging_quickstart_new, aging_quickstart_old;
82
83 void default_lq_initialize_fpm(void) {
84   aging_factor_new = ftofpm(olsr_cnf->lq_aging);
85   aging_factor_old = fpmsub(itofpm(1), aging_factor_new);
86   
87   aging_quickstart_new = ftofpm(LQ_QUICKSTART_AGING);
88   aging_quickstart_old = fpmsub(itofpm(1), aging_quickstart_new);
89   
90   minimal_lq = ftofpm(MINIMAL_USEFUL_LQ);
91 }
92
93 olsr_linkcost default_lq_calc_cost_fpm(const void *ptr) {
94   const struct default_lq_fpm *lq = ptr;
95   olsr_linkcost cost;
96   
97   if (lq->lq < minimal_lq || lq->nlq < minimal_lq) {
98     return LINK_COST_BROKEN;
99   }
100   
101   cost = fpmdiv(itofpm(1), fpmmul(lq->lq, lq->nlq));
102
103   if (cost > LINK_COST_BROKEN)
104     return LINK_COST_BROKEN;
105   if (cost == 0)
106     return 1;
107   return cost;
108 }
109
110 int default_lq_serialize_hello_lq_pair_fpm(unsigned char *buff, void *ptr) {
111   struct default_lq_fpm *lq = ptr;
112   
113   buff[0] = (unsigned char)fpmtoi(fpmmuli(lq->lq, 255));
114   buff[1] = (unsigned char)fpmtoi(fpmmuli(lq->nlq, 255));
115   buff[2] = (unsigned char)(0);
116   buff[3] = (unsigned char)(0);
117   
118   return 4;
119 }
120
121 void default_lq_deserialize_hello_lq_pair_fpm(const olsr_u8_t **curr, void *ptr) {
122   struct default_lq_fpm *lq = ptr;
123   olsr_u8_t valueLq, valueNlq;
124   
125   pkt_get_u8(curr, &valueLq);
126   pkt_get_u8(curr, &valueNlq);
127   pkt_ignore_u16(curr);
128   
129   lq->lq = fpmidiv(itofpm((int)valueLq), 255);
130   lq->nlq = fpmidiv(itofpm((int)valueNlq), 255);
131 }
132
133 olsr_bool default_lq_is_relevant_costchange_fpm(olsr_linkcost c1, olsr_linkcost c2) {
134   if (c1 > c2) {
135     return c2 - c1 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
136   }
137   return c1 - c2 > LQ_PLUGIN_RELEVANT_COSTCHANGE;
138 }
139
140 int default_lq_serialize_tc_lq_pair_fpm(unsigned char *buff, void *ptr) {
141   struct default_lq_fpm *lq = ptr;
142   
143   buff[0] = (unsigned char)fpmtoi(fpmmuli(lq->lq, 255));
144   buff[1] = (unsigned char)fpmtoi(fpmmuli(lq->nlq, 255));
145   buff[2] = (unsigned char)(0);
146   buff[3] = (unsigned char)(0);
147   
148   return 4;
149 }
150
151 void default_lq_deserialize_tc_lq_pair_fpm(const olsr_u8_t **curr, void *ptr) {
152   struct default_lq_fpm *lq = ptr;
153   olsr_u8_t valueLq, valueNlq;
154   
155   pkt_get_u8(curr, &valueLq);
156   pkt_get_u8(curr, &valueNlq);
157   pkt_ignore_u16(curr);
158   
159   lq->lq = fpmidiv(itofpm(valueLq), 255);
160   lq->nlq = fpmidiv(itofpm(valueNlq), 255);
161 }
162
163 olsr_linkcost default_lq_packet_loss_worker_fpm(struct link_entry *link, void *ptr, olsr_bool lost) {
164   struct default_lq_fpm *tlq = ptr;
165   fpm alpha_old = aging_factor_old;
166   fpm alpha_new = aging_factor_new;
167   
168   fpm link_loss_factor = fpmidiv(itofpm(link->loss_link_multiplier), 65536);
169   
170   if (tlq->quickstart < LQ_QUICKSTART_STEPS) {
171     alpha_new = aging_quickstart_new;
172     alpha_old = aging_quickstart_old;
173     tlq->quickstart++;
174   }
175   
176   // exponential moving average
177   tlq->lq = fpmmul(tlq->lq, alpha_old);
178   if (lost == 0) {
179     tlq->lq = fpmadd(tlq->lq, fpmmul(alpha_new, link_loss_factor));
180   }
181   return default_lq_calc_cost_fpm(ptr);
182 }
183
184 void default_lq_memorize_foreign_hello_fpm(void *ptrLocal, void *ptrForeign) {
185   struct default_lq_fpm *local = ptrLocal;
186   struct default_lq_fpm *foreign = ptrForeign;
187   
188   if (foreign) {
189     local->nlq = foreign->lq;
190   }
191   else {
192     local->nlq = itofpm(0);
193   }
194 }
195
196 void default_lq_copy_link2tc_fpm(void *target, void *source) {
197   memcpy(target, source, sizeof(struct default_lq_fpm));
198 }
199
200 void default_lq_clear_fpm(void *target) {
201   memset(target, 0, sizeof(struct default_lq_fpm));
202 }
203
204 const char *default_lq_print_fpm(void *ptr, struct lqtextbuffer *buffer) {
205   struct default_lq_fpm *lq = ptr;
206   
207   sprintf(buffer->buf, "%s/%s", fpmtoa(lq->lq), fpmtoa(lq->nlq));
208   return buffer->buf;
209 }
210
211 const char *default_lq_print_cost_fpm(olsr_linkcost cost, struct lqtextbuffer *buffer) {
212   sprintf(buffer->buf, "%s", fpmtoa(cost));
213   return buffer->buf;
214 }