Show lqe_util.c syntax highlighted
/*
*
* Copyright (c) 2003 The Regents of the University of California. 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.
*
* - Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
*/
/*
* lqe_util.c: Some utilities for lqe, e.g. updating the
* statistical information on a neighbor.
*
* $Id: lqe_util.c,v 1.2 2005/01/31 22:43:49 mlukac Exp $
*/
char lqe_util_c_cvsid[] = "$Id: lqe_util.c,v 1.2 2005/01/31 22:43:49 mlukac Exp $";
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "link/link.h"
#include "lqe_i.h"
/*******************************************************************/
/* Get the neighbor from the neighbor queue */
static neighbor_el_t * get_neighbor(neighbor_list_t *nl,
const link_pkt_t *lpkt,
lqe_pkt_t *spkt)
{
neighbor_el_t *ne;
elog(LOG_DEBUG(10), "get neighbor called!");
/* first see if this neighbor already exists */
for (ne = neighbor_list_top(nl); ne; ne = neighbor_list_next(ne)) {
elog(LOG_DEBUG(10), "Iterating list neigh: %d", ne->info.if_id);
if (ne->info.if_id == lpkt->src.id) {
elog(LOG_DEBUG(10), "Found neighbor %d in list", lpkt->src.id);
return ne;
}
}
/* not found - create a new neighbor */
if ((ne = malloc(sizeof(neighbor_el_t))) == NULL) {
elog(LOG_CRIT, "cannot allocate memory for neighbor elem: %m");
return NULL;
}
memset(ne, 0, sizeof(neighbor_el_t));
/* initialize neighbor element fields */
ne->info.if_id = lpkt->src.id;
/* set the initial connectivity */
ne->info.conn_in[spkt->sender_id] = nl->init_rnp[spkt->src_id];
/* init to (seqno - 1) so the new rnp equal to one */
ne->last_seqno_heard[spkt->sender_id] = spkt->seqno - 1;
/* add the new neighbor to the queue */
neighbor_list_push(nl, ne);
return ne;
}
/*
* Update the link statistics for this neighbor.
*/
void update_stats(neighbor_list_t *nl, link_pkt_t *lpkt,
lqe_pkt_t *spkt)
{
neighbor_el_t *ne;
conn_t rnp;
struct timeval now;
elog(LOG_DEBUG(0), "updating stats for neighbor: %d, source: %d, "
"with seqno: %llu", spkt->src_id, spkt->sender_id, spkt->seqno);
/* Find out if neighbor exists in our list */
if ((ne = get_neighbor(nl, lpkt, spkt)) == NULL)
return;
/* find out the current rnp */
rnp = (int) (spkt->seqno - ne->last_seqno_heard[spkt->sender_id]);
elog(LOG_DEBUG(1), "Current RNP: %f -- neigh: %d -- source: %d",
rnp, spkt->src_id, spkt->sender_id);
/* update the current rnp for this packet (used by routing) */
lpkt->rnp = rnp;
/* if the rnp is negative (neighbor reboot?) we clear the state and
start again */
if (rnp < 0) {
elog(LOG_NOTICE, "Possible neighbor reboot, clearing stats state "
"and restarting...");
memset(ne, 0, sizeof(neighbor_el_t));
ne->info.conn_in[spkt->sender_id] = nl->init_rnp[spkt->src_id];
rnp = 1;
}
/* if we receive a packet with the same seqno, we ignore it */
if (rnp == 0) {
elog(LOG_WARNING, "Received duplicate seqno: %llu from neighbor "
"[%d] and source[%d], alas ignoring it...", spkt->seqno,
spkt->src_id, spkt->sender_id);
return;
}
/* update rnp estimate for this src/neigh pair */
/* his is equivalent to (1 - alpha) * oldrnp + alpha * newrnp */
ne->info.conn_in[spkt->sender_id] +=
nl->alpha * (rnp - ne->info.conn_in[spkt->sender_id]);
elog(LOG_DEBUG(1), "New RNP estimate: %f -- neigh: %d -- source: %d",
ne->info.conn_in[spkt->sender_id], spkt->src_id,
spkt->sender_id);
/* update the seqno */
ne->last_seqno_heard[spkt->sender_id] = spkt->seqno;
/* update the time */
/* NOTE: we should use lpkt->rcv_time, but it is not set!! **FIX** */
gettimeofday(&now, NULL);
//ne->info.last_heard = now;
ne->info.last_heard = lpkt->rcv_time;
}
void init_state(neighbor_list_t *nl)
{
neighbor_el_t *ne;
int i, j;
/* for each available neighbor */
for (i = 0; i < MAX_SRC; i++) {
if (nl->init_rnp[i] != 0) {
/* create a new neighbor */
if ((ne = malloc(sizeof(neighbor_el_t))) == NULL) {
elog(LOG_CRIT, "cannot allocate memory for neighbor elem: %m");
return;
}
memset(ne, 0, sizeof(neighbor_el_t));
/* initialize neighbor element fields */
ne->info.if_id = i;
/* set the initial connectivity coming from any source */
for (j = 0; j < MAX_SRC; j++) {
ne->info.conn_in[j] = nl->init_rnp[i];
ne->last_seqno_heard[j] = 0;
}
/* add the new neighbor to the queue */
neighbor_list_push(nl, ne);
}
}
}
void lqe_util_init(neighbor_list_t *nl)
{
buf_t *buf;
parser_state_t *ps;
elog(LOG_NOTICE, "Loading initialization file from file %s",
nl->init_file);
buf = buf_new();
if (file_to_buf(buf, nl->init_file) < 0) {
elog(LOG_CRIT, "Unable to open initialization file: %m");
exit(1);
}
/* ok now we parse the file to look for our data */
ps = misc_parse_init(buf->buf, MISC_PARSE_LF_SCHEME);
while (misc_parse_next_kvp(ps) >= 0) {
uint src, dst;
float quality;
if (ps->key[0] == '#') continue;
if (sscanf(ps->key, "%d %d %f", &src, &dst, &quality) == 3) {
elog(LOG_DEBUG(4), "Read src=%d dst=%d q=%f", src, dst, quality);
if(src != my_node_id) continue;
/*
* NOTE: update init array for this neighbor, assuming quality is
* the RR value, and the initial rnp is 1/RR
*/
nl->init_rnp[dst] = 1.0/quality;
}
}
init_state(nl);
}
See more files for this project here