Show idr_conf.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.
*
*/
/* IDR configuration functions */
#include <stdio.h>
#include <stdlib.h>
#include "idr_i.h"
char *idr_command_usage(void *data)
{
return "See idr_conf.h for the struct that's to be used\n";
}
static int idr_command_handler(char *command, size_t size, void *data)
{
idr_state_t *s = (idr_state_t *) data;
int n=0;
if (command==NULL) {
elog(LOG_ERR, "NULL pointer in command argument\n");
exit(1);
}
// copy command argument to state struct
memcpy(&(s->conf), command, sizeof(idr_conf));
// reset the status nodelist, since a new request came in through
// the command iface
memset(s->status.nodelist, 0, sizeof(s->status.nodelist));
// put the conf info in the status struct
n=sync_conf_status(s->conf.nodelist, s->status.nodelist, MAX_NEIGHBORS);
elog(LOG_NOTICE, "%d elements in status nodelist updated\n", n);
// sync the status neighborlist with the linkstats
n=sync_neighb_status(s->nb_list, s->status.nodelist,
MAX_NEIGHBORS, s->nb_count);
elog(LOG_NOTICE, "%d elements in status nodelist updated\n", n);
// now update the static elements
s->status.deadline=s->conf.deadline;
s->status.max_nack=s->conf.max_nack;
s->constr.nacks_remaining=s->status.max_nack;
// Calculate the value of min_accuracy that should go in the constraints
// struct
if (s->conf.min_accuracy!=0) {
int i=0;
int sum=0;
for (i=0; i<MAX_NEIGHBORS;i++) {
if (s->conf.nodelist[i].id != 0) {
sum+=s->conf.nodelist[i].importance;
}
}
sum=MAX_ACCURACY-sum; // this is the value of accuracy the
// application got
//
// So our required contribution is what the app requires minus
// what the app got
// Perhaps the app should set that value?
s->constr.min_accuracy=s->conf.min_accuracy - sum;
if (s->constr.min_accuracy < 0) {
// this CAN happen, if the app sent us a command
s->constr.min_accuracy=0;
s->nackmethod=NO_NACKS;
// NOTICE: setting remaining nacks to 0
// Energy-saving mode:)
s->constr.nacks_remaining=0;
} else {
// TODO: make this part of the config
s->nackmethod=COMBINATORIAL;
}
}
if (s->nackmethod==0) {
s->nackmethod=BEST_SCORE;
}
elog(LOG_NOTICE, "Using NACK method %d\n", s->nackmethod);
s->status.round_nacks=0;
if (s->status.deadline!=0) {
// Run the selection algorithm
select_source_to_nack(s);
// Set the deadline
s->constr.time_remaining=s->status.deadline;
// Initiate the check timer
g_timer_add(NACK_CHECK_INTERVAL, nack_timer, s, NULL, NULL);
} else {
elog(LOG_NOTICE, "Deadline expired\n");
}
return EVENT_RENEW;
}
static int idr_status_binary(status_info_t *info, buf_t *buf)
{
idr_state_t *s = (idr_state_t *)info->device_info;
bufcpy(buf, &s->status, sizeof(s->status));
return STATUS_MSG_COMPLETE;
}
static int idr_status_printable(status_info_t *info, buf_t *buf)
{
idr_state_t *s = (idr_state_t *)info->device_info;
uint16_t i, n=0;
bufprintf(buf, "IDR status:\n"
" Node ID Importance Conn_to Conn_from Retx"
" NACKs Score\n");
for (i=0; i<MAX_NEIGHBORS; i++) {
if (s->status.nodelist[i].id != 0) {
bufprintf(buf," %4d %5d %6.2f%% %6.2f%% %2d"
" %3d %6.2f\n",
s->status.nodelist[i].id,
s->status.nodelist[i].importance,
s->status.nodelist[i].conn_to,
s->status.nodelist[i].conn_from,
s->status.nodelist[i].retx_count,
s->status.nodelist[i].nack_count,
s->status.nodelist[i].score);
n++;
}
}
if (n==0) {
bufprintf(buf, " (null)\n");
}
bufprintf(buf, " Number of monitored nodes: %d (max=%d)\n"
" Deadline: %d (ms)\n"
" Number of NACKs sent this round: %d (max=%d)\n"
" Total number of NACKs sent: %d\n"
" Number of packets retransmitted (sender only): %d\n",
n, MAX_NEIGHBORS,
s->status.deadline,
s->status.round_nacks,
s->status.max_nack,
s->status.total_nacks,
s->status.retno);
return STATUS_MSG_COMPLETE;
}
void idr_conf_init(idr_state_t *s)
{
// status device options
status_dev_opts_t s_opts = {
device: {
device_info: s,
devname: IDR_STATUS_DEV
},
printable: idr_status_printable,
binary: idr_status_binary,
eof_after_each: 1
};
// command device options
cmd_dev_opts_t c_opts = {
device: {
device_info: s,
devname: IDR_COMMAND_DEV
},
command: idr_command_handler,
usage: idr_command_usage
};
// create the status device
if (g_status_dev(&s_opts, &s->status_ev) < 0) {
elog(LOG_CRIT, "can't create status dev %s: %m",
s_opts.device.devname);
exit(1);
}
/* Create the command device */
if (g_command_dev(&c_opts, &s->command_ev) < 0) {
elog(LOG_CRIT, "can't create command dev %s: %m",
c_opts.device.devname);
exit(1);
}
}
See more files for this project here