Code Search for Developers
 
 
  

scaled_net.c from EmStar at Krugle


Show scaled_net.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.
 *
 */
 

/*
 * scaled_net.c: Functions that generate data packets to probe the 
 * network.
 *
 * $Id: scaled_net.c,v 1.4 2005/10/31 09:25:51 cerpa Exp $
 */

char scaled_net_c_id[] = "$Id: scaled_net.c,v 1.4 2005/10/31 09:25:51 cerpa Exp $";

#include "scaled_i.h"


/*
 * Construct a scale packet, which contains our outgoing sequence
 * number.
 */
static void packet_send(neighbor_list_t *nl)
{
  /* Allocate a small buffer for the packet */
  buf_t *buf = buf_new();
  uint16_t mtu=0;
  int space_left;
  int pkt_len;
  int i;

  link_pkt_t link_pkt = {
    dst: {
      id: LINK_BROADCAST,
    },
    type: PKT_TYPE_SCALE,
  };

  scale_pkt_t sc_pkt = {
    src_id: my_node_id,
  };
  
    
  if (buf == NULL) {
    elog(LOG_CRIT, "out of memory!");
    return;
  }

  /* get the mtu */
  if (lu_get_mtu(nl->link, &mtu) < 0) {
    elog(LOG_WARNING, "Can't get the mtu for link %s: %m",
         lu_name(nl->link, NULL));
  }
        
  /* construct the packet: the outer (link) header and sc pkt */
  bufcpy(buf, &link_pkt, sizeof(link_pkt));
  bufcpy(buf, &sc_pkt, sizeof(sc_pkt));

  /* we have this much room left */
  space_left = mtu - buf->len;

  /* truncate pkt size limit if larger than available space */
  if (nl->pkt_size > space_left)
    pkt_len = space_left;
  else
    pkt_len = nl->pkt_size;
  
  /* send random characters as payload */
  for (i = buf->len; i < pkt_len; i++)
    bufprintf(buf, "%c", (rand() % 26) + 'a');
  
  /* increase tx counter */
  nl->seqno++;
  
  elog(LOG_DEBUG(10), "Sending test packet: %llu", nl->seqno);

  
  /* launch the packet! */
  if (lu_send(nl->link, (link_pkt_t *) buf->buf, 
	      buf->len - sizeof(link_pkt_t)) < 0) {
    elog(LOG_ERR, "can't send on %s: %m", lu_name(nl->link, NULL));
    elog(LOG_ERR, "our MTU was %d", mtu);
  }
  else
    elog(LOG_DEBUG(1), "sending probe packet seqno %lld, len %d", nl->seqno,
	 buf->len - sizeof(link_pkt_t));
  
  /* and free it */
  buf_free(buf);
}


int scaled_gps_to_cpu_time(struct timeval *src_tv, struct timeval *dest_tv)
{
  sync_id_t src = {
    node: my_node_id,
    comp: GPS
  };
    
  sync_id_t dest = {
    node: my_node_id,
    comp: CPU
  };

  if (sync_convert_tv(&src, src_tv, &dest, dest_tv) < 0) {
    elog(LOG_ERR, "couldn't convert from GPS to CPU time: %m\n");
    return -1;
  }
  
  return 0;
}


int scaled_cpu_to_gps_time(struct timeval *src_tv, struct timeval *dest_tv)
{
  sync_id_t src = {
    node: my_node_id,
    comp: CPU
  };
    
  sync_id_t dest = {
    node: my_node_id,
    comp: GPS
  };

  if (sync_convert_tv(&src, src_tv, &dest, dest_tv) < 0) {
    elog(LOG_DEBUG(0), "couldn't convert from CPU to GPS time: %m\n");
    return -1;
  }
  
  return 0;
}

void scaled_net_start(neighbor_list_t *nl)
{
  struct timeval gtime;
  struct timeval ctime;
  struct timeval log_gtime;
  struct timeval log_ctime;
  int i,j, start;
  
  /* convert (gpstime + safe guard band + timeshift (depends on each
   * node) to CPU time.
   */
  gtime = nl->gps_time;
  start = (1000*TIME_GUARD_BAND) + 
          (nl->tx_window*(my_node_id - nl->root_node_id));
  misc_tv_addms(&gtime, start);
  elog(LOG_DEBUG(5), "My node id is: %d, my start time is: %d", 
       my_node_id, start);
  
  if(scaled_gps_to_cpu_time(&gtime, &ctime) < 0) {
    elog(LOG_CRIT, "Time conversion failed, cannot continue!!\n");
    exit(1);
  }

  elog(LOG_DEBUG(10), "Busy waiting until: %s", misc_print_date(&ctime));
  
  /* busy wait until ctime */
  misc_busy_wait_until(&ctime);
  
  /* loop forever */
  for (i=0; ; i++) {
    
    /* convert current CPU time to GPS for logging purposes */
    gettimeofday(&log_ctime, NULL);
    scaled_cpu_to_gps_time(&log_ctime, &log_gtime);
       
    /* send n packets */
    for (j=0; j < nl->total_pkts; j++)
      packet_send(nl);
    
    elog (LOG_NOTICE, "%s - %s - [%d] SENT %d packets of size: %d, with"
          " cycle period of %d ms, and tx window of %d ms", 
          misc_print_date(&log_gtime), misc_tv_to_str(&log_gtime), i, 
          nl->total_pkts, nl->pkt_size, nl->period, nl->tx_window);
    
    if (nl->use_logging) {
      fprintf (nl->fp, "%s - %s - [%d] SENT %d packets of size: %d, "
          "with cycle period of %d ms, and tx window of %d ms\n", 
          misc_print_date(&log_gtime), misc_tv_to_str(&log_gtime), i, 
          nl->total_pkts, nl->pkt_size, nl->period, nl->tx_window); 
      fflush(nl->fp);   
    }

    /* convert (gpstime + i*period) to CPU time */
    misc_tv_addms(&gtime, nl->period);
    
    if(scaled_gps_to_cpu_time(&gtime, &ctime) < 0) {
      elog(LOG_CRIT, "Time conversion failed, cannot continue!!\n");
      exit(1);
    }
    
    elog(LOG_DEBUG(10), "Busy waiting until: %s", misc_print_date(&ctime));

    /* busy wait until ctime */
    misc_busy_wait_until(&ctime);

    elog(LOG_DEBUG(5), "Completed cycle: %d\n", i);
  } 
}


void scaled_net_init(neighbor_list_t *nl)
{
  lu_opts_t link_opts = {
    opts: {
      pkt_type: PKT_TYPE_SCALE,
      data: nl,
      name: nl->link_name
    },
    blocking_writes: 1,  /* block on back to back writes and full queue */
  };

  /* Open the link to the underlying network interface */
  if (lu_open(&link_opts, &nl->link) < 0) {
    elog(LOG_CRIT, "can't open %s: %m", link_name(&link_opts.opts, NULL));
    exit(1);
  }

  /* Get link status to get our if id, if available */
  if (lu_status(nl->link, &nl->link_status) < 0) {
    elog(LOG_WARNING, "couldn't get status from %s: %m", 
         lu_name(nl->link, NULL));
  }

}




See more files for this project here

EmStar

EmStar is a software system for developing and deploying wireless sensor networks involving Linux-based platforms. As the wireless sensor network community has attempted to deploy more complex designs---large-scale, long-lived systems that need self-organization and adaptivity---a number of difficult software design issues have arisen. Advances in software design have not kept pace with the capabilities of hardware. This is because designing for an adaptive, efficient, and useful sensor network has turned out to be surprisingly complex and difficult. EmStar is a Linux-based software framework, whose goal is to dramatically reduce this complexity, enabling work to be shared and reused, and simplifying and speeding the design of new sensor network applications.

Project homepage: http://cvs.cens.ucla.edu/emstar/
Programming language(s): C,Shell Script
License: other

  scaled_i.h
  scaled_main.c
  scaled_net.c