Show mdtn.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 <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <ctype.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include "emrun/emrun.h"
#include "link/link.h"
#include <link/link_headers.h>
#include <libmisc/misc.h>
#include <libdev/status_dev.h>
#include <libdev/command_dev.h>
#include <libdev/query_dev.h>
#include <libdev/packet_client.h>
#include <libdev/packet_dev.h>
#include <libdev/em_sched.h>
#include <libdev/command_dev.h>
#include "tos-contrib/mDTN/tos/lib/mDTN.h"
#include "tos-contrib/mDTN/apps/em_mDTN/data_payload.h"
//#include "tos-contrib/herd/tos/system/RegMsg.h"
#ifndef SECOND
#define SECOND 1000
#endif
#define DUMPFILE ("/scratch/mdtn.dat")
#define LOCKFILE ("/scratch/lock.mdtn")
typedef struct _mdtn_state {
status_context_t *mdtn_status_ev;
lu_context_t *mdtn_data_link;
int dumpfd;
int lockfd;
int is_master;
} mdtn_state_t;
#define MDTN_CMD_DEV ("/dev/link/mdtn/command")
void mdtn_shutdown(void *data);
int mdtn_pkt_rcvd(lu_context_t *link, link_pkt_t *link_pkt, ssize_t data_len);
int64_t get_time()
{
struct timeval now = {0};
int64_t retval=0;
gettimeofday(&now, NULL);
retval = misc_timeval_to_int64(&now);
return retval;
}
int mdtn_pkt_rcvd(lu_context_t *link, link_pkt_t *link_pkt, ssize_t data_len)
{
mdtn_state_t *mstate = (mdtn_state_t *)(lu_data(link));
mDTN_pkt_t *mpkt = (mDTN_pkt_t *)(link_pkt->data);
data_payload_t *payload = (data_payload_t *)(mpkt->data);
char buf[1024]={0};
int len=0;
int64_t latency=0;
latency = (get_time() - payload->timestamp)/1000;
elog(LOG_NOTICE, "Got DATA pkt from node %u, tx=%u, stored=%u,"
" sink=%u, count=%u, latency(ms)=%lld\n",
link_pkt->src.id,
mpkt->num_tx,
mpkt->num_stored,
payload->sink,
payload->count,
latency);
// node_id:rcv_sink:dst_sink:count:latency:tx:retx:stored:deferred:dups
len = sprintf(buf, "%u %u %u %u %lld %u %u %u %u %u\n",
link_pkt->src.id,
my_node_id,
payload->sink,
payload->count,
latency,
mpkt->num_tx,
mpkt->num_retx,
mpkt->num_stored,
payload->deferred,
0);
if (write(mstate->dumpfd, buf, len) < 0) {
elog(LOG_ERR, "Could not write to dumpfile: %m");
exit(1);
}
return EVENT_RENEW;
}
void mdtn_shutdown(void *data)
{
mdtn_state_t *mstate = (mdtn_state_t *)data;
close(mstate->dumpfd);
if (mstate->is_master==1) {
/*
if (remove(LOCKFILE) < 0) {
elog(LOG_ERR, "Could not unlink %s: %m",
LOCKFILE);
} else {
elog(LOG_NOTICE, "Lock file deleted");
}
*/
}
exit(0);
}
int open_data_link_dev(char *uses_link, mdtn_state_t *mstate)
{
lu_opts_t lu_opts = {
opts: {
name: uses_link,
data: mstate,
},
receive: mdtn_pkt_rcvd,
};
if (lu_open(&lu_opts, &mstate->mdtn_data_link) < 0) {
elog(LOG_ERR, "Can't open %s: %m", link_name(&lu_opts.opts, NULL));
exit(1);
} else {
elog(LOG_NOTICE, "Link device %s opened successfully\n",
link_name(&lu_opts.opts, NULL));
}
return 0;
}
int main(int argc, char **argv)
{
mdtn_state_t *mstate=NULL;
char *link_name_str=NULL;
emrun_opts_t emrun_opts = {
shutdown: mdtn_shutdown,
data: mstate,
silent: 1,
};
misc_init(&argc, argv, CVSTAG);
// malloc mstate
mstate = malloc(sizeof(mdtn_state_t));
// zero-out everything
memset(mstate, 0, sizeof(mdtn_state_t));
emrun_opts.data = mstate;
link_name_str = link_parse_uses(&argc, argv, "mdtn");
open_data_link_dev(link_name_str, mstate);
printf_to_file(sim_path(MDTN_CMD_DEV), "root");
// if lock doesn't exist
// 1. create it
// 2. set self as lockmaster
// 3. delete DUMPFILE if it exists
// 4. set open flags to WRONLY, CREAT, TRUNC
// if lock exists
// set dumpfile open flags to O_APPEND
#if 0
// try to open the lockfile. First process that tries will win
if ((mstate->lockfd = open(LOCKFILE, O_RDONLY)) < 0) {
if (errno==ENOENT) {
// file does not exist, create
if ((mstate->lockfd ==
open(LOCKFILE, O_RDONLY | O_CREAT, S_IRWXU)) < 0) {
elog(LOG_ERR, "Could not create lock file %s: %m",
LOCKFILE);
exit(1);
} else {
mstate->is_master = 1;
elog(LOG_NOTICE, "I am the LOCKMASTER\n");
}
} else {
elog(LOG_ERR, "Could not open lock file %s: %m",
LOCKFILE);
exit(1);
}
} else {
elog(LOG_NOTICE, "I am NOT the master\n");
}
close(mstate->lockfd);
#endif
mstate->is_master=1;
if (mstate->is_master==1) {
if ((mstate->dumpfd =
open(DUMPFILE, O_WRONLY | O_CREAT | O_APPEND, S_IWUSR)) < 0) {
elog(LOG_ERR, "(Master) Could not open dump file %s: %m",
DUMPFILE);
exit(1);
}
} else {
if ((mstate->dumpfd =
open(DUMPFILE, O_WRONLY | O_APPEND)) < 0) {
elog(LOG_ERR, "Could not open dump file %s: %m",
DUMPFILE);
exit(1);
}
}
if (chmod(DUMPFILE, S_IWUSR | S_IWGRP | S_IWOTH | S_IREAD) < 0) {
elog(LOG_ERR, "Could not chmod %s: %m",
DUMPFILE);
}
// Ok now it's time to start emrun
emrun_init(&emrun_opts);
g_main();
elog(LOG_CRIT, "event loop terminated abnormally!");
return 0;
}
See more files for this project here