/*
* The olsr.org Optimized Link-State Routing daemon(olsrd)
* Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* * Neither the name of olsr.org, olsrd nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Visit http://www.olsr.org for more information.
*
* If you find this software useful feel free to make a donation
* to the project. For more information see the website or contact
* the copyright holders.
*
* $Id: mpr_selector_set.c,v 1.18 2007/09/17 22:24:22 bernd67 Exp $
*/
#include "defs.h"
#include "mpr_selector_set.h"
#include "olsr.h"
#include "scheduler.h"
static olsr_u16_t ansn;
/* MPR selector list */
static struct mpr_selector mprs_list;
/**
*Initialize MPR selector set
*/
int
olsr_init_mprs_set(void)
{
OLSR_PRINTF(5, "MPRS: Init\n");
/* Initial values */
ansn = 0;
olsr_register_timeout_function(&olsr_time_out_mprs_set, OLSR_TRUE);
mprs_list.next = &mprs_list;
mprs_list.prev = &mprs_list;
return 1;
}
olsr_u16_t
get_local_ansn(void)
{
return ansn;
}
void
increase_local_ansn(void)
{
ansn++;
}
/**
* Check if we(this node) is selected as a MPR by any
* neighbors. If the list is empty we are not MPR.
*/
olsr_bool
olsr_is_mpr(void)
{
return ((mprs_list.next == &mprs_list) ? OLSR_FALSE : OLSR_TRUE);
}
/**
*Add a MPR selector to the MPR selector set
*
*@param add address of the MPR selector
*@param vtime validity time for the new entry
*
*@return a pointer to the new entry
*/
struct mpr_selector *
olsr_add_mpr_selector(union olsr_ip_addr *addr, float vtime)
{
struct mpr_selector *new_entry;
OLSR_PRINTF(1, "MPRS: adding %s\n", olsr_ip_to_string(addr));
new_entry = olsr_malloc(sizeof(struct mpr_selector), "Add MPR selector");
/* Fill struct */
COPY_IP(&new_entry->MS_main_addr, addr);
new_entry->MS_time = GET_TIMESTAMP(vtime*1000);
/* Queue */
QUEUE_ELEM(mprs_list, new_entry);
/*
new_entry->prev = &mprs_list;
new_entry->next = mprs_list.next;
mprs_list.next->prev = new_entry;
mprs_list.next = new_entry;
*/
return new_entry;
}
/**
*Lookup an entry in the MPR selector table
*based on address
*
*@param addr the addres to check for
*
*@return a pointer to the entry or NULL
*/
struct mpr_selector *
olsr_lookup_mprs_set(union olsr_ip_addr *addr)
{
struct mpr_selector *mprs;
if(addr == NULL)
return NULL;
//OLSR_PRINTF(1, "MPRS: Lookup....");
mprs = mprs_list.next;
while(mprs != &mprs_list)
{
if(COMP_IP(&mprs->MS_main_addr, addr))
{
//OLSR_PRINTF(1, "MATCH\n");
return mprs;
}
mprs = mprs->next;
}
//OLSR_PRINTF(1, "NO MACH\n");
return NULL;
}
/**
*Update a MPR selector entry or create an new
*one if it does not exist
*
*@param addr the address of the MPR selector
*@param vtime tha validity time of the entry
*
*@return 1 if a new entry was added 0 if not
*/
int
olsr_update_mprs_set(union olsr_ip_addr *addr, float vtime)
{
struct mpr_selector *mprs;
int retval;
OLSR_PRINTF(5, "MPRS: Update %s\n", olsr_ip_to_string(addr));
retval = 0;
if(NULL == (mprs = olsr_lookup_mprs_set(addr)))
{
olsr_add_mpr_selector(addr, vtime);
retval = 1;
signal_link_changes(OLSR_TRUE);
}
else
{
mprs->MS_time = GET_TIMESTAMP(vtime*1000);
}
return retval;
}
/**
*Time out MPR selector entries
*
*@return nada
*/
void
olsr_time_out_mprs_set(void)
{
struct mpr_selector *mprs = mprs_list.next;
while(mprs != &mprs_list)
{
if(TIMED_OUT(mprs->MS_time))
{
/* Dequeue */
struct mpr_selector *mprs_to_delete = mprs;
mprs = mprs->next;
OLSR_PRINTF(1, "MPRS: Timing out %s\n", olsr_ip_to_string(&mprs_to_delete->MS_main_addr));
DEQUEUE_ELEM(mprs_to_delete);
/* Delete entry */
free(mprs_to_delete);
signal_link_changes(OLSR_TRUE);
}
else
mprs = mprs->next;
}
}
/**
*Print the current MPR selector set to STDOUT
*/
void
olsr_print_mprs_set(void)
{
struct mpr_selector *mprs;
OLSR_PRINTF(1, "MPR SELECTORS: ");
for(mprs = mprs_list.next; mprs != &mprs_list; mprs = mprs->next)
{
OLSR_PRINTF(1, "%s ", olsr_ip_to_string(&mprs->MS_main_addr));
}
OLSR_PRINTF(1, "\n");
}
syntax highlighted by Code2HTML, v. 0.9.1