Show debug_logger.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.
*
*/
#include <link/link.h>
#include <mote.h>
#include <emrun/emrun.h>
#include "debug_logger_i.h"
static
int mote_debug_printable(status_context_t *ctx, buf_t *buf)
{
type_handler_t *t = (type_handler_t *)sd_data(ctx);
if (t->curr_print)
bufcpy(buf, t->curr_print->buf, t->curr_print->len);
else if (t->curr_bin)
bufcpy(buf, t->curr_bin->buf, t->curr_bin->len);
return STATUS_MSG_COMPLETE;
}
static
int mote_debug_binary(status_context_t *ctx, buf_t *buf)
{
type_handler_t *t = (type_handler_t *)sd_data(ctx);
if (t->curr_bin)
bufcpy(buf, t->curr_bin->buf, t->curr_bin->len);
else if (t->curr_print)
bufcpy(buf, t->curr_print->buf, t->curr_print->len);
return STATUS_MSG_COMPLETE;
}
int mote_debug_install(logger_t *log, type_handler_t *type)
{
type_handler_t *new_type;
if (log->types[type->type].type) {
elog(LOG_WARNING, "Duplicate plugin registered for type %d", type->type);
return -1;
}
new_type = &(log->types[type->type]);
*new_type = *type;
if (type->proxy_path) {
status_dev_opts_t opts = {
device: {
devname: type->proxy_path,
device_info: new_type
},
printable:mote_debug_printable,
binary:mote_debug_binary
};
if (g_status_dev(&opts, &(new_type->status_ctx)) < 0) {
elog(LOG_WARNING, "Unable to create status device %s",
opts.device.devname);
}
}
new_type->proxy_path = NULL;
return 0;
}
/*
* Basic receive handler
*/
int receive_handler(void *pkt, ssize_t len, pd_client_context_t *pd_client)
{
logger_t *l = (logger_t *)pdc_data(pd_client);
mote_debug_blob_t *bhdr = (mote_debug_blob_t *)pkt;
int size=sizeof(mote_debug_blob_t);
buf_t *print = buf_new();
buf_t *bin = buf_new();
buf_t *log_buf = buf_new();
struct timeval now;
int pre_len;
int log_me = l->log;
gettimeofday(&now, NULL);
bufprintf(log_buf, "%s: %d bytes\n", misc_tv_to_str(&now), len);
pre_len = log_buf->len;
if (len < size)
goto short_read;
size += bhdr->length;
if (len < size)
goto short_read;
/* ok, now process */
/* ok, maybe output non-raw? */
if ((l->proxy || !l->raw) && l->types[bhdr->type].handler) {
type_handler_t *type = &(l->types[bhdr->type]);
/* plugin cb */
l->types[bhdr->type].handler(bhdr, type, l, bin, print);
/* save new responses */
if (type->curr_print) buf_free(type->curr_print);
if (type->curr_bin) buf_free(type->curr_bin);
type->curr_print = print;
type->curr_bin = bin;
bin = NULL;
print = NULL;
/* if proxy requested, try to proxy */
if (l->proxy)
g_status_dev_notify(type->status_ctx);
/* if pretty logging requested */
if (l->log && !(l->raw))
bufcpy(log_buf, type->curr_print->buf, type->curr_print->len);
}
else {
if (l->proxy)
log_me = 1;
}
/* ok, output raw if no printable */
if (log_buf->len == pre_len) {
/* output raw */
bufprintf(log_buf, "Mote %s:%d, type=%d, len=%d\n",
print_if_id(l->node_id), l->mote_index, bhdr->type, bhdr->length);
misc_hexdump_to_buf(log_buf, bhdr->data, bhdr->length, " ");
}
goto done;
short_read:
bufprintf(log_buf, " *** Short packet rec'd: %d/%d\n", len, size);
log_me = 1;
done:
/* log the printable */
if (log_me)
elog(LOG_NOTICE, "%s\n", log_buf->buf);
if (print) buf_free(print);
if (bin) buf_free(bin);
if (log_buf) buf_free(log_buf);
return EVENT_RENEW;
}
/* Callback when we are asked (by emrun) to shut down */
static void log_shutdown(void *data)
{
elog(LOG_NOTICE, "logger shutting down");
exit(0);
}
/*
* Usage
*/
void usage()
{
fprintf(stderr,
"debug_logger: \n"
" usage: [-n node_id] [-m mote_index] [-r] [-p] [-P]\n"
"\n"
"-n uses that node ID if you don't have SIM_ID set.\n"
"-m logs debug info from the specified mote index, default 0\n"
"-r raw: suspends all parsing\n"
"-p enables proxying for visualization\n"
"-P enables proxying, but log as well\n"
);
exit(1);
}
int main(int argc, char **argv)
{
logger_t log = {};
int proxy_log = 0;
emrun_opts_t emrun_opts = {
shutdown: log_shutdown
};
/* generic init */
misc_init(&argc, argv, CVSTAG);
/* parse options */
misc_parse_option_as_uint(&argc, argv, "node_id", 'n', &log.node_id);
misc_parse_option_as_int(&argc, argv, "mote_index", 'm', &log.mote_index);
log.raw = misc_parse_out_switch(&argc, argv, "raw", 'r');
log.proxy = misc_parse_out_switch(&argc, argv, "proxy", 'p');
proxy_log = misc_parse_out_switch(&argc, argv, "proxy_log", 'P');
if (log.proxy && proxy_log) {
elog(LOG_CRIT, "can't set both proxy modes!");
usage();
}
/* proxy and logging requested */
if (proxy_log) {
log.proxy = 1;
log.log = 1;
}
/* proxy only requested, no logging */
else if (log.proxy) {
log.log = 0;
}
/* logging by default */
else log.log = 1;
/* set node id? */
if (log.node_id == 0)
log.node_id = my_node_id;
else
my_node_id = log.node_id;
if (!update_mote_id(&(log.mote_index), NULL))
goto skip_init;
/* open the mote */
{
pd_client_opts_t opts = {
devname: mote_name(log.mote_index, MOTE_DEBUG_DEV),
receive: receive_handler,
data: &log
};
if (pd_client_open(&opts, &log.debug_ctx) < 0) {
elog(LOG_CRIT, "Unable to open mote debug device '%s': %m",
opts.devname);
usage();
}
}
/* init the plugins */
mote_debug_neighbors_init(&log, &argc, argv);
mote_debug_smac_dbg_init(&log, &argc, argv);
mote_debug_gradient_init(&log, &argc, argv);
mote_debug_msrv_init(&log, &argc, argv);
mote_debug_radio_status_init(&log, &argc, argv);
mote_debug_ts_init(&log, &argc, argv);
mote_debug_ping_init(&log, &argc, argv);
mote_debug_retx_init(&log, &argc, argv);
mote_debug_timesync_init(&log, &argc, argv);
/* unparsed args? */
if (misc_args_remain(&argc, argv))
usage();
/* Register with emrun and start the event loop */
skip_init:
emrun_init(&emrun_opts); /* this should be the last initialization */
/* enter loop */
g_main();
elog(LOG_ERR, "Loop terminated: %m");
return 1;
}
See more files for this project here