Remove some unused code and move some funtions to other files to make them static.
[olsrd.git] / src / olsr.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
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
16  *   distribution.
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.
20  *
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.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
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.
39  *
40  */
41
42 /**
43  * All these functions are global
44  */
45
46 #include "defs.h"
47 #include "olsr.h"
48 #include "link_set.h"
49 #include "tc_set.h"
50 #include "duplicate_set.h"
51 #include "mid_set.h"
52 #include "lq_mpr.h"
53 #include "olsr_spf.h"
54 #include "scheduler.h"
55 #include "neighbor_table.h"
56 #include "lq_packet.h"
57 #include "common/avl.h"
58 #include "net_olsr.h"
59 #include "lq_plugin.h"
60 #include "olsr_logging.h"
61 #include "os_system.h"
62 #include "os_apm.h"
63
64 #include <assert.h>
65 #include <stdarg.h>
66 #include <unistd.h>
67 #include <stdlib.h>
68
69 static void olsr_update_willingness(void *);
70 static void olsr_trigger_forced_update(void *);
71
72 bool changes_topology;
73 bool changes_neighborhood;
74 bool changes_hna;
75 bool changes_force;
76
77 static uint16_t message_seqno;
78
79 /**
80  *Initialize the message sequence number as a random value
81  */
82 void
83 init_msg_seqno(void)
84 {
85   message_seqno = random() & 0xFFFF;
86   OLSR_DEBUG(LOG_MAIN, "Settings initial message sequence number to %u\n", message_seqno);
87 }
88
89 /**
90  * Get and increment the message sequence number
91  *
92  *@return the seqno
93  */
94 uint16_t
95 get_msg_seqno(void)
96 {
97   return message_seqno++;
98 }
99
100 /**
101  *Process changes in neighborhood or/and topology.
102  *Re-calculates the neighborhood/topology if there
103  *are any updates - then calls the right functions to
104  *update the routing table.
105  *@return 0
106  */
107 void
108 olsr_process_changes(void)
109 {
110   if (changes_neighborhood)
111     OLSR_DEBUG(LOG_MAIN, "CHANGES IN NEIGHBORHOOD\n");
112   if (changes_topology)
113     OLSR_DEBUG(LOG_MAIN, "CHANGES IN TOPOLOGY\n");
114   if (changes_hna)
115     OLSR_DEBUG(LOG_MAIN, "CHANGES IN HNA\n");
116
117   if (!changes_force && 0 >= olsr_cnf->lq_dlimit)
118     return;
119
120   if (!changes_neighborhood && !changes_topology && !changes_hna)
121     return;
122
123   if (olsr_cnf->log_target_stderr && olsr_cnf->clear_screen && isatty(STDOUT_FILENO)) {
124     os_clear_console();
125     printf("       *** %s (%s on %s) ***\n", olsrd_version, build_date, build_host);
126   }
127
128   if (changes_neighborhood) {
129     olsr_calculate_lq_mpr();
130   }
131
132   /* calculate the routing table */
133   if (changes_neighborhood || changes_topology || changes_hna) {
134     olsr_calculate_routing_table(false);
135   }
136
137   olsr_print_link_set();
138   olsr_print_neighbor_table();
139   olsr_print_tc_table();
140   olsr_print_mid_set();
141   olsr_print_duplicate_table();
142   olsr_print_hna_set();
143
144   changes_neighborhood = false;
145   changes_topology = false;
146   changes_hna = false;
147   changes_force = false;
148 }
149
150 /*
151  * Callback for the periodic route calculation.
152  */
153 static void
154 olsr_trigger_forced_update(void *unused __attribute__ ((unused)))
155 {
156
157   changes_force = true;
158   changes_neighborhood = true;
159   changes_topology = true;
160   changes_hna = true;
161
162   olsr_process_changes();
163 }
164
165 /**
166  *Initialize all the tables used(neighbor,
167  *topology, MID,  HNA, MPR, dup).
168  *Also initalizes other variables
169  */
170 void
171 olsr_init_tables(void)
172 {
173   /* Some cookies for stats keeping */
174   static struct olsr_timer_info *periodic_spf_timer_info = NULL;
175
176   changes_topology = false;
177   changes_neighborhood = false;
178   changes_hna = false;
179
180   /* Initialize link set */
181   olsr_init_link_set();
182
183   /* Initialize duplicate table */
184   olsr_init_duplicate_set();
185
186   /* Initialize neighbor table */
187   olsr_init_neighbor_table();
188
189   /* Initialize routing table */
190   olsr_init_routing_table();
191
192   /* Initialize topology */
193   olsr_init_tc();
194
195   /* Initialize MID set */
196   olsr_init_mid_set();
197
198   /* Initialize HNA set */
199   olsr_init_hna_set();
200
201   /* Start periodic SPF and RIB recalculation */
202   if (olsr_cnf->lq_dinter > 0) {
203     periodic_spf_timer_info = olsr_alloc_timerinfo("Periodic SPF", &olsr_trigger_forced_update, true);
204     olsr_start_timer(olsr_cnf->lq_dinter, 5,
205                      NULL, periodic_spf_timer_info);
206   }
207 }
208
209 /**
210  * Shared code to write the message header
211  */
212 uint8_t *
213 olsr_put_msg_hdr(uint8_t **curr, struct olsr_message *msg)
214 {
215   uint8_t *sizeptr;
216
217   assert(msg);
218   assert(curr);
219
220   pkt_put_u8(curr, msg->type);
221   pkt_put_reltime(curr, msg->vtime);
222   sizeptr = *curr;
223   pkt_put_u16(curr, msg->size);
224   pkt_put_ipaddress(curr, &msg->originator);
225   pkt_put_u8(curr, msg->ttl);
226   pkt_put_u8(curr, msg->hopcnt);
227   pkt_put_u16(curr, msg->seqno);
228
229   return sizeptr;
230 }
231
232 static void
233 olsr_update_willingness(void *foo __attribute__ ((unused)))
234 {
235   int tmp_will = olsr_cnf->willingness;
236
237   /* Re-calculate willingness */
238   olsr_calculate_willingness();
239
240   if (tmp_will != olsr_cnf->willingness) {
241     OLSR_INFO(LOG_MAIN, "Local willingness updated: old %d new %d\n", tmp_will, olsr_cnf->willingness);
242   }
243 }
244
245 void
246 olsr_init_willingness(void)
247 {
248   /* Some cookies for stats keeping */
249   static struct olsr_timer_info *willingness_timer_info = NULL;
250
251   if (olsr_cnf->willingness_auto) {
252     OLSR_INFO(LOG_MAIN, "Initialize automatic willingness...\n");
253     /* Run it first and then periodic. */
254     olsr_update_willingness(NULL);
255
256     willingness_timer_info = olsr_alloc_timerinfo("Update Willingness", &olsr_update_willingness, true);
257     olsr_start_timer(olsr_cnf->will_int, 5, NULL, willingness_timer_info);
258   }
259 }
260
261 /**
262  *Calculate this nodes willingness to act as a MPR
263  *based on either a fixed value or the power status
264  *of the node using APM
265  *
266  *@return a 8bit value from 0-7 representing the willingness
267  */
268
269 void
270 olsr_calculate_willingness(void)
271 {
272   struct olsr_apm_info ainfo;
273 #if !defined(REMOVE_LOG_INFO)
274   struct millitxt_buf tbuf;
275 #endif
276
277   /* If fixed willingness */
278   if (!olsr_cnf->willingness_auto)
279     return;
280
281   if (os_apm_read(&ainfo) < 1) {
282     olsr_cnf->willingness = WILL_DEFAULT;
283     olsr_cnf->willingness_auto = false;
284     OLSR_WARN(LOG_MAIN, "Cannot read APM info, setting willingness to default value (%d)", olsr_cnf->willingness);
285     return;
286   }
287
288   os_apm_printinfo(&ainfo);
289
290   /* If AC powered */
291   if (ainfo.ac_line_status == OLSR_AC_POWERED) {
292     olsr_cnf->willingness = 6;
293   }
294   else {
295   /* If battery powered
296    *
297    * juice > 78% will: 3
298    * 78% > juice > 26% will: 2
299    * 26% > juice will: 1
300    */
301     olsr_cnf->willingness = (ainfo.battery_percentage / 26);
302   }
303   OLSR_INFO(LOG_MAIN, "Willingness set to %d - next update in %s secs\n",
304       olsr_cnf->willingness, olsr_milli_to_txt(&tbuf, olsr_cnf->will_int));
305 }
306
307 /**
308  *Termination function to be called whenever a error occures
309  *that requires the daemon to terminate
310  *
311  *@param val the exit code for OLSR
312  */
313
314 void
315 olsr_exit(int val)
316 {
317   fflush(stdout);
318   olsr_cnf->exit_value = val;
319   if (app_state == STATE_INIT) {
320     os_exit(val);
321   }
322   app_state = STATE_SHUTDOWN;
323 }
324
325
326 /**
327  * Wrapper for malloc(3) that does error-checking
328  *
329  * @param size the number of bytes to allocalte
330  * @param caller a string identifying the caller for
331  * use in error messaging
332  *
333  * @return a void pointer to the memory allocated
334  */
335 void *
336 olsr_malloc(size_t size, const char *id __attribute__ ((unused)))
337 {
338   void *ptr;
339
340   /*
341    * Not all the callers do a proper cleaning of memory.
342    * Clean it on behalf of those.
343    */
344   ptr = calloc(1, size);
345
346   if (!ptr) {
347     OLSR_ERROR(LOG_MAIN, "Out of memory for id '%s': %s\n", id, strerror(errno));
348     olsr_exit(EXIT_FAILURE);
349   }
350   return ptr;
351 }
352
353 /*
354  * Same as strdup but works with olsr_malloc
355  */
356 char *
357 olsr_strdup(const char *s)
358 {
359   char *ret = olsr_malloc(1 + strlen(s), "olsr_strdup");
360   strcpy(ret, s);
361   return ret;
362 }
363
364 /*
365  * Same as strndup but works with olsr_malloc
366  */
367 char *
368 olsr_strndup(const char *s, size_t n)
369 {
370   size_t len = n < strlen(s) ? n : strlen(s);
371   char *ret = olsr_malloc(1 + len, "olsr_strndup");
372   strncpy(ret, s, len);
373   ret[len] = 0;
374   return ret;
375 }
376
377 /*
378  * Local Variables:
379  * c-basic-offset: 2
380  * indent-tabs-mode: nil
381  * End:
382  */