[Tinyos-2-commits] CVS: tinyos-2.x/tos/lib/tossim/sf SerialForwarder.c, NONE, 1.1 SerialForwarder.h, NONE, 1.1 SerialForwarder.i, NONE, 1.1 SerialPacket.c, NONE, 1.1 SerialPacket.h, NONE, 1.1 SerialPacket.i, NONE, 1.1 TOSSIM.py, NONE, 1.1 Throttle.cpp, NONE, 1.1 Throttle.h, NONE, 1.1 Throttle.i, NONE, 1.1 generate-swig.bash, NONE, 1.1 sim_serial_forwarder.c, NONE, 1.1 sim_serial_forwarder.h, NONE, 1.1 sim_serial_packet.c, NONE, 1.1 sim_serial_packet.h, NONE, 1.1 tossim.c, NONE, 1.1 tossim.h, NONE, 1.1 tossim.i, NONE, 1.1 tossim_wrap.cxx, NONE, 1.1

Chad Metcalf hiro at users.sourceforge.net
Tue Oct 2 18:50:22 PDT 2007


Update of /cvsroot/tinyos/tinyos-2.x/tos/lib/tossim/sf
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv27579/tos/lib/tossim/sf

Added Files:
	SerialForwarder.c SerialForwarder.h SerialForwarder.i 
	SerialPacket.c SerialPacket.h SerialPacket.i TOSSIM.py 
	Throttle.cpp Throttle.h Throttle.i generate-swig.bash 
	sim_serial_forwarder.c sim_serial_forwarder.h 
	sim_serial_packet.c sim_serial_packet.h tossim.c tossim.h 
	tossim.i tossim_wrap.cxx 
Log Message:
The initial commit of the TOSSIM Live extensions. TOSSIM Live primary
function is to enable SF communications with a TOSSIM instance.
Examples are included to show how to use TOSSIM Live with the
TestSerial application.


--- NEW FILE: SerialForwarder.c ---
/*
 * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
 * 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.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Toilers Research Group - Colorado School of 
 *   Mines  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 COPYRIGHT HOLDERS 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/**
 * Author: Chad Metcalf
 * Date: July 9, 2007
 *
 * A simple C++ wrapper around the serial forwarder for TOSSIM
 *
 */

#include "SerialForwarder.h"
#include "sim_serial_forwarder.h"

SerialForwarder::SerialForwarder(const int port) 
{ 
    openServerSocket(port);
}

SerialForwarder::~SerialForwarder() 
{
}

void SerialForwarder::openServerSocket(const int port)
{
     sim_sf_open_server_socket(port);
}

void SerialForwarder::dispatchPacket(const void *packet, const int len)
{
    sim_sf_dispatch_packet(packet, len);
}

void SerialForwarder::forwardPacket(const void *packet, const int len)
{
    sim_sf_forward_packet(packet, len);
}

void SerialForwarder::process ()
{
    sim_sf_process();
}

--- NEW FILE: SerialForwarder.h ---
/*
 * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
 * 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.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Toilers Research Group - Colorado School of 
 *   Mines  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 COPYRIGHT HOLDERS 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/**
 * Author: Chad Metcalf
 * Date: July 9, 2007
 *
 * A simple C++ wrapper around the serial forwarder for TOSSIM
 *
 */

#ifndef  _SERIALFORWARDER_H_
#define  _SERIALFORWARDER_H_

class SerialForwarder {

    public: 
    
    SerialForwarder(const int port);
    ~SerialForwarder();

    void process ();
    void dispatchPacket(const void *packet, const int len);
    void forwardPacket(const void *packet, const int len);
    void openServerSocket(const int port);

};
#endif   // ----- #ifndef _SERIALFORWARDER_H_  ----- 

--- NEW FILE: SerialForwarder.i ---
/*
 * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
 * 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.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Toilers Research Group - Colorado School of 
 *   Mines  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 COPYRIGHT HOLDERS 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/**
 * SWIG interface specification for the serial forwarder.
 *
 * @author Chad Metcalf
 * @date   July 9, 2007
 */


%{
#include <SerialForwarder.h>
%}

%apply (char *STRING, int LENGTH) { (char *data, int len) };

class SerialForwarder {

    public:
        SerialForwarder(const int port);
        ~SerialForwarder();

        void process ();
        void dispatchPacket(const void *packet, const int len);
        void forwardPacket(const void *packet, const int len);

};

--- NEW FILE: SerialPacket.c ---
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 *
 * Injecting packets into TOSSIM.
 *
 * @author Philip Levis
 * @author Chad Metcalf
 * @date   July 15 2007
 */

#include <SerialPacket.h>
#include <sim_serial_packet.h>

SerialPacket::SerialPacket() {
  msgPtr = sim_serial_packet_allocate();
  allocated = 1;
}

SerialPacket::SerialPacket(sim_serial_packet_t* m) {
  if (m != NULL) {
    msgPtr = m;
    allocated = 0;
  }
  else {
    msgPtr = sim_serial_packet_allocate();
    allocated = 1;
  }
}

SerialPacket::~SerialPacket() {
  if (allocated) {
    sim_serial_packet_free(msgPtr);
  }
}

void SerialPacket::setDestination(int dest) {
  sim_serial_packet_set_destination(msgPtr, (uint16_t)dest);
}
int SerialPacket::destination() {
  return sim_serial_packet_destination(msgPtr);
}

void SerialPacket::setLength(int len) {
  sim_serial_packet_set_length(msgPtr, (uint8_t)len);
}
int SerialPacket::length() {
  return sim_serial_packet_length(msgPtr);
}

void SerialPacket::setType(int type) {
  sim_serial_packet_set_type(msgPtr, (uint8_t)type);
}
int SerialPacket::type() {
  return sim_serial_packet_type(msgPtr);
}

char* SerialPacket::data() {
  char* val =  (char*)sim_serial_packet_data(msgPtr);
  return val;
}

void SerialPacket::setData(char* data, int len) {
  len = (len > maxLength())? maxLength():len;
  memcpy(sim_serial_packet_data(msgPtr), data, len);
  setLength(len);
}

int SerialPacket::maxLength() {
  return (int)sim_serial_packet_max_length(msgPtr);
}

sim_serial_packet_t* SerialPacket::getPacket() {
  return msgPtr;
}

void SerialPacket::deliver(int node, long long int t) {
  sim_serial_packet_deliver(node, msgPtr, t);
}

void SerialPacket::deliverNow(int node) {
  deliver(node, 0);
}

--- NEW FILE: SerialPacket.h ---
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 *
 * Injecting packets into TOSSIM.
 *
 * @author Philip Levis
 * @author Chad Metcalf
 * @date   July 15 2007
 */

#ifndef SERIAL_PACKET_H_INCLUDED
#define SERIAL_PACKET_H_INCLUDED

#include <sim_serial_packet.h>

class SerialPacket {
  public:
    SerialPacket();
    SerialPacket(sim_serial_packet_t* msg);
    ~SerialPacket();

    void setDestination(int dest);
    int destination();

    void setLength(int len);
    int length();

    void setType(int type);
    int type();

    char* data();
    void setData(char* data, int len);
    int maxLength();

    sim_serial_packet_t* getPacket();

    void deliver(int node, long long int t);
    void deliverNow(int node);
    
 private:
    int allocated;
    sim_serial_packet_t* msgPtr;
};

#endif

--- NEW FILE: SerialPacket.i ---
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 * SWIG interface specification for delivering packets to a node
 * (injecting traffic).
 *
 * Note that changing this file only changes the Python interface:
 * you must also change the underlying TOSSIM code so Python
 * has the proper functions to call. Look at mac.h, mac.c, and
 * sim_mac.c.
 *
 * @author Philip Levis
 * @author Chad Metcalf
 * @date   July 17 2007
 */


%{
#include <SerialPacket.h>
%}

%apply (char *STRING, int LENGTH) { (char *data, int len) };

class SerialPacket {
  public:
    SerialPacket();
    ~SerialPacket();

    void setDestination(int dest);
    int destination();

    void setLength(int len);
    int length();

    void setType(int type);
    int type();

    char* data();

    void setData(char* data, int len);
    int maxLength();
    
    void deliver(int node, long long int time);
    void deliverNow(int node);
};

--- NEW FILE: TOSSIM.py ---
# This file was automatically generated by SWIG (http://www.swig.org).
# Version 1.3.31
#
# Don't modify this file, modify the SWIG interface instead.
# This file is compatible with both classic and new-style classes.

import _TOSSIM
import new
new_instancemethod = new.instancemethod
try:
    _swig_property = property
except NameError:
    pass # Python < 2.2 doesn't have 'property'.
def _swig_setattr_nondynamic(self,class_type,name,value,static=1):
    if (name == "thisown"): return self.this.own(value)
    if (name == "this"):
        if type(value).__name__ == 'PySwigObject':
            self.__dict__[name] = value
            return
    method = class_type.__swig_setmethods__.get(name,None)
    if method: return method(self,value)
    if (not static) or hasattr(self,name):
        self.__dict__[name] = value
    else:
        raise AttributeError("You cannot add attributes to %s" % self)

def _swig_setattr(self,class_type,name,value):
    return _swig_setattr_nondynamic(self,class_type,name,value,0)

def _swig_getattr(self,class_type,name):
    if (name == "thisown"): return self.this.own()
    method = class_type.__swig_getmethods__.get(name,None)
    if method: return method(self)
    raise AttributeError,name

def _swig_repr(self):
    try: strthis = "proxy of " + self.this.__repr__()
    except: strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)

import types
try:
    _object = types.ObjectType
    _newclass = 1
except AttributeError:
    class _object : pass
    _newclass = 0
del types


class MAC(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, MAC, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, MAC, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_MAC(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_MAC
    __del__ = lambda self : None;
    def initHigh(*args): return _TOSSIM.MAC_initHigh(*args)
    def initLow(*args): return _TOSSIM.MAC_initLow(*args)
    def high(*args): return _TOSSIM.MAC_high(*args)
    def low(*args): return _TOSSIM.MAC_low(*args)
    def symbolsPerSec(*args): return _TOSSIM.MAC_symbolsPerSec(*args)
    def bitsPerSymbol(*args): return _TOSSIM.MAC_bitsPerSymbol(*args)
    def preambleLength(*args): return _TOSSIM.MAC_preambleLength(*args)
    def exponentBase(*args): return _TOSSIM.MAC_exponentBase(*args)
    def maxIterations(*args): return _TOSSIM.MAC_maxIterations(*args)
    def minFreeSamples(*args): return _TOSSIM.MAC_minFreeSamples(*args)
    def rxtxDelay(*args): return _TOSSIM.MAC_rxtxDelay(*args)
    def ackTime(*args): return _TOSSIM.MAC_ackTime(*args)
    def setInitHigh(*args): return _TOSSIM.MAC_setInitHigh(*args)
    def setInitLow(*args): return _TOSSIM.MAC_setInitLow(*args)
    def setHigh(*args): return _TOSSIM.MAC_setHigh(*args)
    def setLow(*args): return _TOSSIM.MAC_setLow(*args)
    def setSymbolsPerSec(*args): return _TOSSIM.MAC_setSymbolsPerSec(*args)
    def setBitsBerSymbol(*args): return _TOSSIM.MAC_setBitsBerSymbol(*args)
    def setPreambleLength(*args): return _TOSSIM.MAC_setPreambleLength(*args)
    def setExponentBase(*args): return _TOSSIM.MAC_setExponentBase(*args)
    def setMaxIterations(*args): return _TOSSIM.MAC_setMaxIterations(*args)
    def setMinFreeSamples(*args): return _TOSSIM.MAC_setMinFreeSamples(*args)
    def setRxtxDelay(*args): return _TOSSIM.MAC_setRxtxDelay(*args)
    def setAckTime(*args): return _TOSSIM.MAC_setAckTime(*args)
MAC_swigregister = _TOSSIM.MAC_swigregister
MAC_swigregister(MAC)

class Radio(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Radio, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Radio, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_Radio(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_Radio
    __del__ = lambda self : None;
    def add(*args): return _TOSSIM.Radio_add(*args)
    def gain(*args): return _TOSSIM.Radio_gain(*args)
    def connected(*args): return _TOSSIM.Radio_connected(*args)
    def remove(*args): return _TOSSIM.Radio_remove(*args)
    def setNoise(*args): return _TOSSIM.Radio_setNoise(*args)
    def setSensitivity(*args): return _TOSSIM.Radio_setSensitivity(*args)
Radio_swigregister = _TOSSIM.Radio_swigregister
Radio_swigregister(Radio)

class Packet(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Packet, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Packet, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_Packet(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_Packet
    __del__ = lambda self : None;
    def setSource(*args): return _TOSSIM.Packet_setSource(*args)
    def source(*args): return _TOSSIM.Packet_source(*args)
    def setDestination(*args): return _TOSSIM.Packet_setDestination(*args)
    def destination(*args): return _TOSSIM.Packet_destination(*args)
    def setLength(*args): return _TOSSIM.Packet_setLength(*args)
    def length(*args): return _TOSSIM.Packet_length(*args)
    def setType(*args): return _TOSSIM.Packet_setType(*args)
    def type(*args): return _TOSSIM.Packet_type(*args)
    def data(*args): return _TOSSIM.Packet_data(*args)
    def setData(*args): return _TOSSIM.Packet_setData(*args)
    def maxLength(*args): return _TOSSIM.Packet_maxLength(*args)
    def setStrength(*args): return _TOSSIM.Packet_setStrength(*args)
    def deliver(*args): return _TOSSIM.Packet_deliver(*args)
    def deliverNow(*args): return _TOSSIM.Packet_deliverNow(*args)
Packet_swigregister = _TOSSIM.Packet_swigregister
Packet_swigregister(Packet)

class SerialPacket(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, SerialPacket, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, SerialPacket, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_SerialPacket(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_SerialPacket
    __del__ = lambda self : None;
    def setDestination(*args): return _TOSSIM.SerialPacket_setDestination(*args)
    def destination(*args): return _TOSSIM.SerialPacket_destination(*args)
    def setLength(*args): return _TOSSIM.SerialPacket_setLength(*args)
    def length(*args): return _TOSSIM.SerialPacket_length(*args)
    def setType(*args): return _TOSSIM.SerialPacket_setType(*args)
    def type(*args): return _TOSSIM.SerialPacket_type(*args)
    def data(*args): return _TOSSIM.SerialPacket_data(*args)
    def setData(*args): return _TOSSIM.SerialPacket_setData(*args)
    def maxLength(*args): return _TOSSIM.SerialPacket_maxLength(*args)
    def deliver(*args): return _TOSSIM.SerialPacket_deliver(*args)
    def deliverNow(*args): return _TOSSIM.SerialPacket_deliverNow(*args)
SerialPacket_swigregister = _TOSSIM.SerialPacket_swigregister
SerialPacket_swigregister(SerialPacket)

class SerialForwarder(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, SerialForwarder, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, SerialForwarder, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_SerialForwarder(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_SerialForwarder
    __del__ = lambda self : None;
    def process(*args): return _TOSSIM.SerialForwarder_process(*args)
    def dispatchPacket(*args): return _TOSSIM.SerialForwarder_dispatchPacket(*args)
    def forwardPacket(*args): return _TOSSIM.SerialForwarder_forwardPacket(*args)
SerialForwarder_swigregister = _TOSSIM.SerialForwarder_swigregister
SerialForwarder_swigregister(SerialForwarder)

class Throttle(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Throttle, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Throttle, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_Throttle(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_Throttle
    __del__ = lambda self : None;
    def initialize(*args): return _TOSSIM.Throttle_initialize(*args)
    def finalize(*args): return _TOSSIM.Throttle_finalize(*args)
    def checkThrottle(*args): return _TOSSIM.Throttle_checkThrottle(*args)
    def printStatistics(*args): return _TOSSIM.Throttle_printStatistics(*args)
Throttle_swigregister = _TOSSIM.Throttle_swigregister
Throttle_swigregister(Throttle)

class variable_string_t(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, variable_string_t, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, variable_string_t, name)
    __repr__ = _swig_repr
    __swig_setmethods__["type"] = _TOSSIM.variable_string_t_type_set
    __swig_getmethods__["type"] = _TOSSIM.variable_string_t_type_get
    if _newclass:type = _swig_property(_TOSSIM.variable_string_t_type_get, _TOSSIM.variable_string_t_type_set)
    __swig_setmethods__["ptr"] = _TOSSIM.variable_string_t_ptr_set
    __swig_getmethods__["ptr"] = _TOSSIM.variable_string_t_ptr_get
    if _newclass:ptr = _swig_property(_TOSSIM.variable_string_t_ptr_get, _TOSSIM.variable_string_t_ptr_set)
    __swig_setmethods__["len"] = _TOSSIM.variable_string_t_len_set
    __swig_getmethods__["len"] = _TOSSIM.variable_string_t_len_get
    if _newclass:len = _swig_property(_TOSSIM.variable_string_t_len_get, _TOSSIM.variable_string_t_len_set)
    __swig_setmethods__["isArray"] = _TOSSIM.variable_string_t_isArray_set
    __swig_getmethods__["isArray"] = _TOSSIM.variable_string_t_isArray_get
    if _newclass:isArray = _swig_property(_TOSSIM.variable_string_t_isArray_get, _TOSSIM.variable_string_t_isArray_set)
    def __init__(self, *args): 
        this = _TOSSIM.new_variable_string_t(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_variable_string_t
    __del__ = lambda self : None;
variable_string_t_swigregister = _TOSSIM.variable_string_t_swigregister
variable_string_t_swigregister(variable_string_t)

class nesc_app_t(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, nesc_app_t, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, nesc_app_t, name)
    __repr__ = _swig_repr
    __swig_setmethods__["numVariables"] = _TOSSIM.nesc_app_t_numVariables_set
    __swig_getmethods__["numVariables"] = _TOSSIM.nesc_app_t_numVariables_get
    if _newclass:numVariables = _swig_property(_TOSSIM.nesc_app_t_numVariables_get, _TOSSIM.nesc_app_t_numVariables_set)
    __swig_setmethods__["variableNames"] = _TOSSIM.nesc_app_t_variableNames_set
    __swig_getmethods__["variableNames"] = _TOSSIM.nesc_app_t_variableNames_get
    if _newclass:variableNames = _swig_property(_TOSSIM.nesc_app_t_variableNames_get, _TOSSIM.nesc_app_t_variableNames_set)
    __swig_setmethods__["variableTypes"] = _TOSSIM.nesc_app_t_variableTypes_set
    __swig_getmethods__["variableTypes"] = _TOSSIM.nesc_app_t_variableTypes_get
    if _newclass:variableTypes = _swig_property(_TOSSIM.nesc_app_t_variableTypes_get, _TOSSIM.nesc_app_t_variableTypes_set)
    __swig_setmethods__["variableArray"] = _TOSSIM.nesc_app_t_variableArray_set
    __swig_getmethods__["variableArray"] = _TOSSIM.nesc_app_t_variableArray_get
    if _newclass:variableArray = _swig_property(_TOSSIM.nesc_app_t_variableArray_get, _TOSSIM.nesc_app_t_variableArray_set)
    def __init__(self, *args): 
        this = _TOSSIM.new_nesc_app_t(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_nesc_app_t
    __del__ = lambda self : None;
nesc_app_t_swigregister = _TOSSIM.nesc_app_t_swigregister
nesc_app_t_swigregister(nesc_app_t)

class Variable(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Variable, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Variable, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_Variable(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_Variable
    __del__ = lambda self : None;
    def getData(*args): return _TOSSIM.Variable_getData(*args)
Variable_swigregister = _TOSSIM.Variable_swigregister
Variable_swigregister(Variable)

class Mote(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Mote, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Mote, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_Mote(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_Mote
    __del__ = lambda self : None;
    def id(*args): return _TOSSIM.Mote_id(*args)
    def euid(*args): return _TOSSIM.Mote_euid(*args)
    def setEuid(*args): return _TOSSIM.Mote_setEuid(*args)
    def bootTime(*args): return _TOSSIM.Mote_bootTime(*args)
    def bootAtTime(*args): return _TOSSIM.Mote_bootAtTime(*args)
    def isOn(*args): return _TOSSIM.Mote_isOn(*args)
    def turnOff(*args): return _TOSSIM.Mote_turnOff(*args)
    def turnOn(*args): return _TOSSIM.Mote_turnOn(*args)
    def getVariable(*args): return _TOSSIM.Mote_getVariable(*args)
    def addNoiseTraceReading(*args): return _TOSSIM.Mote_addNoiseTraceReading(*args)
    def createNoiseModel(*args): return _TOSSIM.Mote_createNoiseModel(*args)
    def generateNoise(*args): return _TOSSIM.Mote_generateNoise(*args)
Mote_swigregister = _TOSSIM.Mote_swigregister
Mote_swigregister(Mote)

class Tossim(_object):
    __swig_setmethods__ = {}
    __setattr__ = lambda self, name, value: _swig_setattr(self, Tossim, name, value)
    __swig_getmethods__ = {}
    __getattr__ = lambda self, name: _swig_getattr(self, Tossim, name)
    __repr__ = _swig_repr
    def __init__(self, *args): 
        this = _TOSSIM.new_Tossim(*args)
        try: self.this.append(this)
        except: self.this = this
    __swig_destroy__ = _TOSSIM.delete_Tossim
    __del__ = lambda self : None;
    def init(*args): return _TOSSIM.Tossim_init(*args)
    def time(*args): return _TOSSIM.Tossim_time(*args)
    def ticksPerSecond(*args): return _TOSSIM.Tossim_ticksPerSecond(*args)
    def setTime(*args): return _TOSSIM.Tossim_setTime(*args)
    def timeStr(*args): return _TOSSIM.Tossim_timeStr(*args)
    def currentNode(*args): return _TOSSIM.Tossim_currentNode(*args)
    def getNode(*args): return _TOSSIM.Tossim_getNode(*args)
    def setCurrentNode(*args): return _TOSSIM.Tossim_setCurrentNode(*args)
    def addChannel(*args): return _TOSSIM.Tossim_addChannel(*args)
    def removeChannel(*args): return _TOSSIM.Tossim_removeChannel(*args)
    def randomSeed(*args): return _TOSSIM.Tossim_randomSeed(*args)
    def runNextEvent(*args): return _TOSSIM.Tossim_runNextEvent(*args)
    def mac(*args): return _TOSSIM.Tossim_mac(*args)
    def radio(*args): return _TOSSIM.Tossim_radio(*args)
    def newPacket(*args): return _TOSSIM.Tossim_newPacket(*args)
    def newSerialPacket(*args): return _TOSSIM.Tossim_newSerialPacket(*args)
Tossim_swigregister = _TOSSIM.Tossim_swigregister
Tossim_swigregister(Tossim)




--- NEW FILE: Throttle.cpp ---
/*
 * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
 * 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.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Toilers Research Group - Colorado School of 
 *   Mines  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 COPYRIGHT HOLDERS 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/**
 * Author: Chad Metcalf
 * Date: July 9, 2007
 *
 * A simple Throttle to slow a simulation to near real time.
 *
 */

#include "Throttle.h"

Throttle::Throttle(Tossim* tossim, const int ms = 10) : 
    sim(tossim), simStartTime(0.0), simEndTime(0.0), simPace(0), throttleCount(0) {

        // Convert milliseconds to sim_time_t 
        simPace =  ms * 10000000ULL;
}

Throttle::~Throttle() {}

void Throttle::initialize() {
    simStartTime = getTime();
}

void Throttle::finalize() {
    simEndTime = getTime();
}

void Throttle::checkThrottle() {
    
    double secondsElasped = getTime() - simStartTime;
    sim_time_t ticksElasped = secondsElasped*sim->ticksPerSecond();

    sim_time_t difference = sim->time() - ticksElasped;

    if (difference > simPace) {
        throttleCount++;
        double sleepDifference = (double) difference / sim->ticksPerSecond();
        simSleep(sleepDifference);
    }

}

inline double Throttle::toDouble(struct timeval* tv) {
    return tv->tv_sec + tv->tv_usec/1e6;
}

double Throttle::getTime() {
    struct timeval tv;
    gettimeofday (&tv, NULL);
    return toDouble(&tv);  
}

int Throttle::simSleep(double seconds) {

     struct timespec tv;
     /* Construct the timespec from the number of whole seconds... */
     tv.tv_sec = (time_t) seconds;
     /* ... and the remainder in nanoseconds. */
     tv.tv_nsec = (long) ((seconds - tv.tv_sec) * 1e+9);

     while (1)
     {
         /* Sleep for the time specified in tv. If interrupted by a
         signal, place the remaining time left to sleep back into tv. */
         int rval = nanosleep (&tv, &tv);

         if (rval == 0)
             /* Completed the entire sleep time; all done. */
             return 0;
         else if (errno == EINTR)
             /* Interrupted by a signal. Try again. */
             continue;
         else 
             /* Some other error; bail out. */
             return rval;
     }

     return 0;
}

void Throttle::printStatistics() {

    printf("Number of throttle events %d\n", throttleCount);

    if (simEndTime > 0.0) {
        printf("Total Sim Time: %.6f\n", simEndTime - simStartTime);
    }

}

--- NEW FILE: Throttle.h ---
/*
 * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
 * 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.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Toilers Research Group - Colorado School of 
 *   Mines  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 COPYRIGHT HOLDERS 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/**
 * Author: Chad Metcalf
 * Date: July 9, 2007
 *
 * A simple Throttle to slow a simulation to near real time.
 *
 */
#ifndef  _THROTTLE_H_
#define  _THROTTLE_H_


#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include "tossim.h"

class Throttle {

    public:

        Throttle(Tossim* tossim, const int ms);
        ~Throttle();

        void initialize();
        void finalize();

        void checkThrottle();
        void printStatistics();

    private:

        double simStartTime;
        double simEndTime;
        sim_time_t simPace;

        Tossim* sim;

        long throttleCount;

        double getTime();
        double toDouble(struct timeval* tv);
        int simSleep(double seconds);
};
#endif   // ----- #ifndef _THROTTLE_H_  ----- 

--- NEW FILE: Throttle.i ---
/*
 * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
 * 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.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Toilers Research Group - Colorado School of 
 *   Mines  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 COPYRIGHT HOLDERS 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/**
 * Author: Chad Metcalf
 * Date: July 9, 2007
 *
 * SWIG interface specification for the Throttle object.
 */


%{
#include <Throttle.h>
%}

%apply (char *STRING, int LENGTH) { (char *data, int len) };


class Throttle {

    public:

        Throttle(Tossim* tossim, const int ms);
        ~Throttle();

        void initialize();
        void finalize();

        void checkThrottle();
        void printStatistics();

};

--- NEW FILE: generate-swig.bash ---
#!/bin/bash
# "Copyright (c) 2005 Stanford University. All rights reserved.
#
# Permission to use, copy, modify, and distribute this software and
# its documentation for any purpose, without fee, and without written
# agreement is hereby granted, provided that the above copyright
# notice, the following two paragraphs and the author appear in all
# copies of this software.
# 
# IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
# DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
# ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
# IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
# DAMAGE.
# 
# STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
# PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
# HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
# ENHANCEMENTS, OR MODIFICATIONS."
#
# Simple script that generates the Python interfaces to TOSSIM.
#
# Author: Philip Levis
# Author: Chad Metcalf
#
# $Id: generate-swig.bash,v 1.1 2007/10/03 01:50:20 hiro Exp $

swig -shadow -python -c++ -I$TOSROOT/tos/lib/tossim tossim.i


--- NEW FILE: sim_serial_forwarder.c ---
/*
 * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
 * 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.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Toilers Research Group - Colorado School of 
 *   Mines  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 COPYRIGHT HOLDERS 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/**
 * Author: Chad Metcalf
 * Date: July 9, 2007
 *
 * The serial forwarder for TOSSIM
 *
 */

#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>

#include "sim_serial_forwarder.h"
#include "sim_serial_packet.h"
#include "sim_tossim.h"

struct sim_sf_client_list *sim_sf_clients;
int sim_sf_server_socket;
int sim_sf_packets_read, sim_sf_packets_written, sim_sf_num_clients;

int sim_sf_unix_check(const char *msg, int result)
{
    if (result < 0)
    {
        perror(msg);
        exit(2);
    }

    return result;
}

void *sim_sf_xmalloc(size_t s)
{
    void *p = malloc(s);

    if (!p)
    {
        fprintf(stderr, "out of memory\n");
        exit(2);
    }
    return p;
}

void sim_sf_fd_wait(fd_set *fds, int *maxfd, int fd)
{
    if (fd > *maxfd)
        *maxfd = fd;
    FD_SET(fd, fds);
}

void sim_sf_pstatus(void)
{
    printf("clients %d, read %d, wrote %d\n", sim_sf_num_clients, sim_sf_packets_read,
           sim_sf_packets_written);
}

void sim_sf_add_client(int fd)
{
    struct sim_sf_client_list *c = (struct sim_sf_client_list*)sim_sf_xmalloc(sizeof *c);

    c->next = sim_sf_clients;
    sim_sf_clients = c;
    sim_sf_num_clients++;
    sim_sf_pstatus();

    c->fd = fd;
}

void sim_sf_rem_client(struct sim_sf_client_list **c)
{
    struct sim_sf_client_list *dead = *c;

    *c = dead->next;
    sim_sf_num_clients--;
    sim_sf_pstatus();
    close(dead->fd);
    free(dead);
}

void sim_sf_new_client(int fd)
{
    fcntl(fd, F_SETFL, 0);
    if (sim_sf_init_source(fd) < 0)
        close(fd);
    else
        sim_sf_add_client(fd);
}

void sim_sf_check_clients(fd_set *fds)
{
    struct sim_sf_client_list **c;

    for (c = &sim_sf_clients; *c; )
    {
        int isNext = 1;

        if (FD_ISSET((*c)->fd, fds))
        {
            int len;
            const void *packet = sim_sf_read_packet((*c)->fd, &len);

            if (packet)
            {
                sim_sf_forward_packet(packet, len);
                free((void *)packet);
            }
            else
            {
                sim_sf_rem_client(c);
                isNext = 0;
            }
        }
        if (isNext)
            c = &(*c)->next;
    }
}

void sim_sf_wait_clients(fd_set *fds, int *maxfd)
{
    struct sim_sf_client_list *c;

    for (c = sim_sf_clients; c; c = c->next)
        sim_sf_fd_wait(fds, maxfd, c->fd);
}

void sim_sf_dispatch_packet(const void *packet, int len)
{
    struct sim_sf_client_list **c;

    char* dispatchPacket = (char*) sim_sf_xmalloc(len+1);
    
    memset(dispatchPacket, 0, len+1);
    memcpy(dispatchPacket+1, packet, len);

    for (c = &sim_sf_clients; *c; )
        if (sim_sf_write_packet((*c)->fd, dispatchPacket, len+1) >= 0)
        {
            sim_sf_packets_written++;
            c = &(*c)->next;
        }
        else
            sim_sf_rem_client(c);

    free(dispatchPacket);
}

void sim_sf_open_server_socket(int port)
{
    struct sockaddr_in me;
    int opt;

    sim_sf_server_socket = sim_sf_unix_check("socket", socket(AF_INET, SOCK_STREAM, 0));
    sim_sf_unix_check("socket", fcntl(sim_sf_server_socket, F_SETFL, O_NONBLOCK));
    memset(&me, 0, sizeof me);
    me.sin_family = AF_INET;
    me.sin_port = htons(port);

    opt = 1;
    sim_sf_unix_check("setsockopt", setsockopt(sim_sf_server_socket, SOL_SOCKET, SO_REUSEADDR,
                                        (char *)&opt, sizeof(opt)));

    sim_sf_unix_check("bind", bind(sim_sf_server_socket, (struct sockaddr *)&me, sizeof me));
    sim_sf_unix_check("listen", listen(sim_sf_server_socket, 5));
}

void sim_sf_check_new_client(void)
{
    int clientfd = accept(sim_sf_server_socket, NULL, NULL);

    if (clientfd >= 0)
        sim_sf_new_client(clientfd);
}

void sim_sf_forward_packet(const void *packet, int len)
{
    char* forwardPacket = (char*)packet + 1;

    uint16_t addr = sim_serial_packet_destination((struct sim_serial_packet*)forwardPacket);

    sim_serial_packet_deliver(addr, 
                             (struct sim_serial_packet*)forwardPacket,
                             sim_time());
    sim_sf_packets_read++;
}

void sim_sf_process ()
{

        fd_set rfds;
        int maxfd = -1;
        struct timeval zero;
        int ret;

        zero.tv_sec = zero.tv_usec = 0;

        FD_ZERO(&rfds);
        sim_sf_fd_wait(&rfds, &maxfd, sim_sf_server_socket);
        sim_sf_wait_clients(&rfds, &maxfd);

        ret = select(maxfd + 1, &rfds, NULL, NULL, &zero);
        if (ret >= 0)
        {
            if (FD_ISSET(sim_sf_server_socket, &rfds))
                sim_sf_check_new_client();

            sim_sf_check_clients(&rfds);
        }
}

int sim_sf_saferead(int fd, void *buffer, int count)
{
  int actual = 0;

  while (count > 0)
    {
      int n = read(fd, buffer, count);

      if (n == -1 && errno == EINTR)
        continue;
      if (n == -1)
        return -1;
      if (n == 0)
        return actual;

      count -= n;
      actual += n;
      buffer = (char*)buffer + n;
    }
  return actual;
}

int sim_sf_safewrite(int fd, const void *buffer, int count)
{
  int actual = 0;

  while (count > 0)
    {
      int n = write(fd, buffer, count);

      if (n == -1 && errno == EINTR)
        continue;
      if (n == -1)
        return -1;

      count -= n;
      actual += n;
      buffer = (char*)buffer + n;
    }
  return actual;
}

int sim_sf_open_source(const char *host, int port)
/* Returns: file descriptor for serial forwarder at host:port
 */
{
  int fd = socket(AF_INET, SOCK_STREAM, 0);
  struct hostent *entry;
  struct sockaddr_in addr;

  if (fd < 0)
    return fd;

  entry = gethostbyname(host);
  if (!entry)
    {
      close(fd);
      return -1;
    }      

  addr.sin_family = entry->h_addrtype;
  memcpy(&addr.sin_addr, entry->h_addr, entry->h_length);
  addr.sin_port = htons(port);
  if (connect(fd, (struct sockaddr *)&addr, sizeof addr) < 0)
    {
      close(fd);
      return -1;
    }

  if (sim_sf_init_source(fd) < 0)
    {
      close(fd);
      return -1;
    }

  return fd;
}

int sim_sf_init_source(int fd)
/* Effects: Checks that fd is following the TinyOS 2.0 serial forwarder 
     protocol. Use this if you obtain your file descriptor from some other
     source than open_sf_source (e.g., you're a server)
   Returns: 0 if it is, -1 otherwise
 */
{
  char check[2], us[2];
  int version;

  /* Indicate version and check if a TinyOS 2.0 serial forwarder on the
     other end */
  us[0] = 'U'; us[1] = ' ';
  if (sim_sf_safewrite(fd, us, 2) != 2 ||
      sim_sf_saferead(fd, check, 2) != 2 ||
      check[0] != 'U')
    return -1;

  version = check[1];
  if (us[1] < version)
    version = us[1];

  /* Add other cases here for later protocol versions */
  switch (version)
    {
    case ' ': break;
    default: return -1; /* not a valid version */
    }

  return 0;
}

void *sim_sf_read_packet(int fd, int *len)
/* Effects: reads packet from serial forwarder on file descriptor fd
   Returns: the packet read (in newly allocated memory), and *len is
     set to the packet length, or NULL for failure
*/
{
  unsigned char l;
  void *packet;

  if (sim_sf_saferead(fd, &l, 1) != 1)
    return NULL;

  packet = malloc(l);
  if (!packet)
    return NULL;

  if (sim_sf_saferead(fd, packet, l) != l)
    {
      free(packet);
      return NULL;
    }
  *len = l;
  
  return packet;
}

int sim_sf_write_packet(int fd, const void *packet, int len)
/* Effects: writes len byte packet to serial forwarder on file descriptor
     fd
   Returns: 0 if packet successfully written, -1 otherwise
*/
{
  unsigned char l = len;

  if (sim_sf_safewrite(fd, &l, 1) != 1 ||
      sim_sf_safewrite(fd, packet, l) != l)
    return -1;

  return 0;
}


--- NEW FILE: sim_serial_forwarder.h ---
/*
 * Copyright (c) 2007 Toilers Research Group - Colorado School of Mines
 * 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.
 * - Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the
 *   distribution.
 * - Neither the name of Toilers Research Group - Colorado School of 
 *   Mines  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 COPYRIGHT HOLDERS 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 STANFORD
 * UNIVERSITY OR ITS 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.
 */
/**
 * Author: Chad Metcalf
 * Date: July 9, 2007
 *
 * The serial forwarder for TOSSIM
 *
 */

#ifndef  _SIM_SERIAL_FORWARDER_H_
#define  _SIM_SERIAL_FORWARDER_H_
#include <sys/types.h>

#ifdef __cplusplus
extern "C" {
#endif

struct sim_sf_client_list
{
    struct sim_sf_client_list *next;
    int fd;
};

void sim_sf_forward_packet(const void *packet, int len);
void sim_sf_dispatch_packet(const void *packet, int len);
void sim_sf_open_server_socket(int port);
void sim_sf_process ();

int sim_sf_unix_check(const char *msg, int result);
void *sim_sf_xmalloc(size_t s);
void sim_sf_fd_wait(fd_set *fds, int *maxfd, int fd);
void sim_sf_pstatus(void);
void sim_sf_add_client(int fd);
void sim_sf_rem_client(struct sim_sf_client_list **c);
void sim_sf_new_client(int fd);
void sim_sf_check_clients(fd_set *fds);
void sim_sf_wait_clients(fd_set *fds, int *maxfd);
void sim_sf_check_new_client(void);
void sim_sf_forward_packet(const void *packet, int len);
int sim_sf_saferead(int fd, void *buffer, int count);
int sim_sf_safewrite(int fd, const void *buffer, int count);
int sim_sf_open_source(const char *host, int port);
int sim_sf_init_source(int fd);
void *sim_sf_read_packet(int fd, int *len);
int sim_sf_write_packet(int fd, const void *packet, int len);

#ifdef __cplusplus
}
#endif

#endif   // ----- #ifndef _SIM_SERIAL_FORWARDER_H_  ----- 

--- NEW FILE: sim_serial_packet.c ---
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 *
 * TOSSIM packet abstract data type, so C++ code can call into nesC
 * code that does the native-to-network type translation.
 *
 * @author Philip Levis
 * @author Chad Metcalf
 * @date   July 15 2007
 */

// $Id: sim_serial_packet.c,v 1.1 2007/10/03 01:50:20 hiro Exp $

#include <sim_serial_packet.h>
#include <message.h>
#include <platform_message.h>

// NOTE: This function is defined in lib/tossim/ActiveMessageC. It
// has to be predeclared here because it is defined within that component.
void serial_active_message_deliver(int node, message_t* m, sim_time_t t);

static serial_header_t* getSerialHeader(message_t* msg) {
    return (serial_header_t*)(msg->data - sizeof(serial_header_t));
}

void sim_serial_packet_set_destination(sim_serial_packet_t* msg, uint16_t dest)__attribute__ ((C, spontaneous)) {
    serial_header_t* hdr = getSerialHeader((message_t*)msg);
    hdr->dest = dest;
}__attribute__ ((C, spontaneous))

uint16_t sim_serial_packet_destination(sim_serial_packet_t* msg)__attribute__ ((C, spontaneous)) {
    serial_header_t* hdr = getSerialHeader((message_t*)msg);
    return hdr->dest;
}

void sim_serial_packet_set_source(sim_serial_packet_t* msg, uint16_t src)__attribute__ ((C, spontaneous)) {
    serial_header_t* hdr = getSerialHeader((message_t*)msg);
    hdr->src = src;
}__attribute__ ((C, spontaneous))

uint16_t sim_serial_packet_source(sim_serial_packet_t* msg)__attribute__ ((C, spontaneous)) {
    serial_header_t* hdr = getSerialHeader((message_t*)msg);
    return hdr->src;
}

void sim_serial_packet_set_length(sim_serial_packet_t* msg, uint8_t length)__attribute__ ((C, spontaneous)) {
    serial_header_t* hdr = getSerialHeader((message_t*)msg);
    hdr->length = length;
}
uint16_t sim_serial_packet_length(sim_serial_packet_t* msg)__attribute__ ((C, spontaneous)) {
    serial_header_t* hdr = getSerialHeader((message_t*)msg);
    return hdr->length;
}

void sim_serial_packet_set_type(sim_serial_packet_t* msg, uint8_t type) __attribute__ ((C, spontaneous)){
    serial_header_t* hdr = getSerialHeader((message_t*)msg);
    hdr->type = type;
}

uint8_t sim_serial_packet_type(sim_serial_packet_t* msg) __attribute__ ((C, spontaneous)){
    serial_header_t* hdr = getSerialHeader((message_t*)msg);
    return hdr->type;
}

uint8_t* sim_serial_packet_data(sim_serial_packet_t* p) __attribute__ ((C, spontaneous)){
    message_t* msg = (message_t*)p;
    return (uint8_t*)&msg->data;
}

void sim_serial_packet_deliver(int node, sim_serial_packet_t* msg, sim_time_t t) __attribute__ ((C, spontaneous)){
    if (t < sim_time()) {
        t = sim_time();
    }
    dbg("Packet", "sim_serial_packet.c: Delivering packet %p to %i at %llu\n", msg, node, t);
    serial_active_message_deliver(node, (message_t*)msg, t);
}

uint8_t sim_serial_packet_max_length(sim_serial_packet_t* msg) __attribute__ ((C, spontaneous)){
    return TOSH_DATA_LENGTH;
}

sim_serial_packet_t* sim_serial_packet_allocate () __attribute__ ((C, spontaneous)){
    return (sim_serial_packet_t*)malloc(sizeof(message_t));
}

void sim_serial_packet_free(sim_serial_packet_t* p) __attribute__ ((C, spontaneous)) {
    printf("sim_serial_packet.c: Freeing packet %p\n", p);
    free(p);
}

--- NEW FILE: sim_serial_packet.h ---
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 *
 * TOSSIM packet abstract data type, so C++ code can call into nesC
 * code that does the native-to-network type translation.
 *
 * @author Philip Levis
 * @author Chad Metcalf
 * @date   July 15 2007
 */

// $Id: sim_serial_packet.h,v 1.1 2007/10/03 01:50:20 hiro Exp $

#ifndef SIM_SERIAL_PACKET_H_INCLUDED
#define SIM_SERIAL_PACKET_H_INCLUDED

#include "sim_tossim.h"
#include <stdint.h>

#ifdef __cplusplus
extern "C" {
#endif

    /*
     * sim_serial_packet_t is a weird beast. It's a dummy type that can stand
     * in for message_t. We need to use sim_serial_packet_t because gcc can't
     * understand message_t, due to its network types (nx). So the shim
     * code between Python and TOSSIM can't mention message_t.  Rather
     * than use a void*, the shim uses sim_serial_packet_t in order to provide
     * some type checking. A sim_serial_packet_t* is essentially a Python
     * friendly pointer to a message_t.
     */
    typedef struct sim_serial_packet {} sim_serial_packet_t;

    void sim_serial_packet_set_destination(sim_serial_packet_t* msg, uint16_t dest);
    uint16_t sim_serial_packet_destination(sim_serial_packet_t* msg);

    void sim_serial_packet_set_source(sim_serial_packet_t* msg, uint16_t src);
    uint16_t sim_serial_packet_source(sim_serial_packet_t* msg);

    void sim_serial_packet_set_length(sim_serial_packet_t* msg, uint8_t len);
    uint16_t sim_serial_packet_length(sim_serial_packet_t* msg);

    void sim_serial_packet_set_type(sim_serial_packet_t* msg, uint8_t type);
    uint8_t sim_serial_packet_type(sim_serial_packet_t* msg);

    uint8_t* sim_serial_packet_data(sim_serial_packet_t* msg);

    void sim_serial_packet_deliver(int node, sim_serial_packet_t* msg, sim_time_t t);
    uint8_t sim_serial_packet_max_length(sim_serial_packet_t* msg);

    sim_serial_packet_t* sim_serial_packet_allocate();
    void sim_serial_packet_free(sim_serial_packet_t* m);

#ifdef __cplusplus
}
#endif

#endif // SIM_SERIAL_PACKET_H_INCLUDED

--- NEW FILE: tossim.c ---
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 * Implementation of TOSSIM C++ classes. Generally just directly
 * call their C analogues.
 *
 * @author Philip Levis
 * @author Chad Metcalf
 * @date   July 15 2007
 */

// $Id: tossim.c,v 1.1 2007/10/03 01:50:20 hiro Exp $


#include <stdint.h>
#include <tossim.h>
#include <sim_tossim.h>
#include <sim_mote.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <hashtable.h>

#include <mac.c>
#include <radio.c>
#include <packet.c>
#include <SerialPacket.c>
#include <sim_noise.h>

uint16_t TOS_NODE_ID = 1;

Variable::Variable(char* str, char* formatStr, int array, int which) {
  name = str;
  format = formatStr;
  isArray = array;
  mote = which;
  
  int sLen = strlen(name);
  realName = (char*)malloc(sLen + 1);
  memcpy(realName, name, sLen + 1);
  realName[sLen] = 0;

  for (int i = 0; i < sLen; i++) {
    if (realName[i] == '.') {
      realName[i] = '$';
    }
  }

  //  printf("Creating %s realName: %s format: %s %s\n", name, realName, formatStr, array? "[]":"");

  if (sim_mote_get_variable_info(mote, realName, &ptr, &len) == 0) {
    data = (char*)malloc(len + 1);
    data[len] = 0;
  }
  else {
    printf("Could not find variable %s\n", realName);
    data = NULL;
    ptr = NULL;
  }
  printf("Allocated variable %s\n", realName);
}

Variable::~Variable() {
  printf("Freeing variable %s\n", realName);
  free(data);
  free(realName);
}

/* This is the sdbm algorithm, taken from
   http://www.cs.yorku.ca/~oz/hash.html -pal */
static unsigned int tossim_hash(void* key) {
  char* str = (char*)key;
  unsigned int hashVal = 0;
  int c;
  
  while ((c = *str++))
    hashVal = c + (hashVal << 6) + (hashVal << 16) - hashVal;
  
  return hashVal;
}

static int tossim_hash_eq(void* key1, void* key2) {
  return strcmp((char*)key1, (char*)key2) == 0;
}


variable_string_t Variable::getData() {
  if (data != NULL && ptr != NULL) {
    str.ptr = data;
    str.type = format;
    str.len = len;
    str.isArray = isArray;
    //    printf("Getting %s %s %s\n", format, isArray? "[]":"", name);
    memcpy(data, ptr, len);
  }
  else {
    str.ptr = "<no such variable>";
    str.type = "<no such variable>";
    str.len = strlen("<no such variable>");
    str.isArray = 0;
  }
  return str;
}

Mote::Mote(nesc_app_t* n) {
  app = n;
  varTable = create_hashtable(128, tossim_hash, tossim_hash_eq);
}

Mote::~Mote(){}

unsigned long Mote::id() {
  return nodeID;
}

long long int Mote::euid() {
  return sim_mote_euid(nodeID);
}

void Mote::setEuid(long long int val) {
  sim_mote_set_euid(nodeID, val);
}

long long int Mote::bootTime() {
  return sim_mote_start_time(nodeID);
}

void Mote::bootAtTime(long long int time) {
  sim_mote_set_start_time(nodeID, time);
  sim_mote_enqueue_boot_event(nodeID);
}

bool Mote::isOn() {
  return sim_mote_is_on(nodeID);
}

void Mote::turnOff() {
  sim_mote_turn_off(nodeID);
}

void Mote::turnOn() {
  sim_mote_turn_on(nodeID);
}

void Mote::setID(unsigned long val) {
  nodeID = val;
}

Variable* Mote::getVariable(char* name) {
  char* typeStr = "";
  int isArray;
  Variable* var;
  
  var = (Variable*)hashtable_search(varTable, name);
  if (var == NULL) {
    // Could hash this for greater efficiency,
    // but that would either require transformation
    // in Tossim class or a more complex typemap.
    if (app != NULL) {
      for (int i = 0; i < app->numVariables; i++) {
	if(strcmp(name, app->variableNames[i]) == 0) {
	  typeStr = app->variableTypes[i];
	  isArray = app->variableArray[i];
	  break;
	}
      }
    }
    //  printf("Getting variable %s of type %s %s\n", name, typeStr, isArray? "[]" : "");
    var = new Variable(name, typeStr, isArray, nodeID);
    hashtable_insert(varTable, name, var);
  }
  return var;
}

void Mote::addNoiseTraceReading(int val) {
  sim_noise_trace_add(id(), (char)val);
}

void Mote::createNoiseModel() {
  sim_noise_create_model(id());
}

int Mote::generateNoise(int when) {
  return (int)sim_noise_generate(id(), when);
}

Tossim::Tossim(nesc_app_t* n) {
  app = n;
  init();
}

Tossim::~Tossim() {
  sim_end();
}

void Tossim::init() {
  sim_init();
  motes = (Mote**)malloc(sizeof(Mote*) * (TOSSIM_MAX_NODES + 1));
  memset(motes, 0, sizeof(Mote*) * TOSSIM_MAX_NODES);
}

long long int Tossim::time() {
  return sim_time();
}

long long int Tossim::ticksPerSecond() {
  return sim_ticks_per_sec();
}

char* Tossim::timeStr() {
  sim_print_now(timeBuf, 256);
  return timeBuf;
}

void Tossim::setTime(long long int val) {
  sim_set_time(val);
}

Mote* Tossim::currentNode() {
  return getNode(sim_node());
}

Mote* Tossim::getNode(unsigned long nodeID) {
  if (nodeID > TOSSIM_MAX_NODES) {
    nodeID = TOSSIM_MAX_NODES;
    // log an error, asked for an invalid node
  }
  else {
    if (motes[nodeID] == NULL) {
      motes[nodeID] = new Mote(app);
      if (nodeID == TOSSIM_MAX_NODES) {
	motes[nodeID]->setID(0xffff);
      }
      else {
	motes[nodeID]->setID(nodeID);
      }
    }
    return motes[nodeID];
  }
}

void Tossim::setCurrentNode(unsigned long nodeID) {
  sim_set_node(nodeID);
}

void Tossim::addChannel(char* channel, FILE* file) {
  sim_add_channel(channel, file);
}

bool Tossim::removeChannel(char* channel, FILE* file) {
  return sim_remove_channel(channel, file);
}

void Tossim::randomSeed(int seed) {
  return sim_random_seed(seed);
}

bool Tossim::runNextEvent() {
  return sim_run_next_event();
}

MAC* Tossim::mac() {
  return new MAC();
}

Radio* Tossim::radio() {
  return new Radio();
}

Packet* Tossim::newPacket() {
  return new Packet();
}

SerialPacket* Tossim::newSerialPacket() {
  return new SerialPacket();
}

--- NEW FILE: tossim.h ---
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 * Declaration of C++ objects representing TOSSIM abstractions.
 * Used to generate Python objects.
 *
 * @author Philip Levis
 * @author Chad Metcalf
 * @date   July 15 2007
 */

// $Id: tossim.h,v 1.1 2007/10/03 01:50:20 hiro Exp $

#ifndef TOSSIM_H_INCLUDED
#define TOSSIM_H_INCLUDED

//#include <stdint.h>
#include <memory.h>
#include <tos.h>
#include <mac.h>
#include <radio.h>
#include <packet.h>
#include <SerialPacket.h>
#include <hashtable.h>

typedef struct variable_string {
  char* type;
  char* ptr;
  int len;
  int isArray;
} variable_string_t;

typedef struct nesc_app {
  int numVariables;
  char** variableNames;
  char** variableTypes;
  int* variableArray;
} nesc_app_t;

class Variable {
 public:
  Variable(char* name, char* format, int array, int mote);
  ~Variable();
  variable_string_t getData();
  
 private:
  char* name;
  char* realName;
  char* format;
  int mote;
  void* ptr;
  char* data;
  size_t len;
  int isArray;
  variable_string_t str;
};

class Mote {
 public:
  Mote(nesc_app_t* app);
  ~Mote();

  unsigned long id();
  
  long long int euid();
  void setEuid(long long int id);

  long long int bootTime();
  void bootAtTime(long long int time);

  bool isOn();
  void turnOff();
  void turnOn();
  void setID(unsigned long id);  

  void addNoiseTraceReading(int val);
  void createNoiseModel();
  int generateNoise(int when);
  
  Variable* getVariable(char* name);
  
 private:
  unsigned long nodeID;
  nesc_app_t* app;
  struct hashtable* varTable;
};

class Tossim {
 public:
  Tossim(nesc_app_t* app);
  ~Tossim();
  
  void init();
  
  long long int time();
  long long int ticksPerSecond();
  char* timeStr();
  void setTime(long long int time);
  
  Mote* currentNode();
  Mote* getNode(unsigned long nodeID);
  void setCurrentNode(unsigned long nodeID);

  void addChannel(char* channel, FILE* file);
  bool removeChannel(char* channel, FILE* file);
  void randomSeed(int seed);
  
  bool runNextEvent();

  MAC* mac();
  Radio* radio();
  Packet* newPacket();
  SerialPacket* newSerialPacket();

 private:
  char timeBuf[256];
  nesc_app_t* app;
  Mote** motes;
};



#endif // TOSSIM_H_INCLUDED

--- NEW FILE: tossim.i ---
/*
 * "Copyright (c) 2005 Stanford University. All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose, without fee, and without written
 * agreement is hereby granted, provided that the above copyright
 * notice, the following two paragraphs and the author appear in all
 * copies of this software.
 * 
 * IN NO EVENT SHALL STANFORD UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF STANFORD UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 * 
 * STANFORD UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE
 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND STANFORD UNIVERSITY
 * HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
 * ENHANCEMENTS, OR MODIFICATIONS."
 */

/**
 * SWIG interface specification for TOSSIM. This file defines
 * the top-level TOSSIM and Mote objects which are exported to
 * Python. The typemap at the beginning allows a script to
 * use Python files as a parameter to a function that takes a
 * FILE* as a parameter (e.g., the logging system in sim_log.h).
 *
 * With updates to include SerialForwarder and Throttle
 *
 * @author Philip Levis
 * @author Chad Metcalf
 * @date   July 9, 2007
 */

%module TOSSIM

%{
#include <memory.h>
#include <tossim.h>

enum {
  PRIMITIVE_INTEGER      = 0,
  PRIMITIVE_FLOAT   = 1,
  PRIMITIVE_UNKNOWN = 2
};

int lengthOfType(char* type) {
  if (strcmp(type, "uint8_t") == 0) {
    return sizeof(uint8_t);
  }
  else if (strcmp(type, "uint16_t") == 0) {
    return sizeof(uint16_t);
  }
  else if (strcmp(type, "uint32_t") == 0) {
    return sizeof(uint32_t);
  }
  else if (strcmp(type, "int8_t") == 0) {
    return sizeof(int8_t);
  }
  else if (strcmp(type, "int16_t") == 0) {
    return sizeof(int16_t);
  }
  else if (strcmp(type, "int32_t") == 0) {
    return sizeof(int32_t);
  }
  else if (strcmp(type, "char") == 0) {
    return sizeof(char);
  }
  else if (strcmp(type, "short") == 0) {
    return sizeof(short);
  }
  else if (strcmp(type, "int") == 0) {
    return sizeof(int);
  }
  else if (strcmp(type, "long") == 0) {
    return sizeof(long);
  }
  else if (strcmp(type, "unsigned char") == 0) {
    return sizeof(unsigned char);
  }
  else if (strcmp(type, "unsigned short") == 0) {
    return sizeof(unsigned short);
  }
  else if (strcmp(type, "unsigned int") == 0) {
    return sizeof(unsigned int);
  }
  else if (strcmp(type, "unsigned long") == 0) {
    return sizeof(unsigned long);
  }
  else if (strcmp(type, "float") == 0) {
    return sizeof(float);
  }
  else if (strcmp(type, "double") == 0) {
    return sizeof(double);
  }
  else {
    return 1;
  }
}

int memoryToPrimitive(char* type, char* ptr, long* lval, double* dval) {
  if (strcmp(type, "uint8_t") == 0) {
    uint8_t val;
    memcpy(&val, ptr, sizeof(uint8_t));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "uint16_t") == 0) {
    uint16_t val;
    memcpy(&val, ptr, sizeof(uint16_t));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "uint32_t") == 0) {
    uint32_t val;
    memcpy(&val, ptr, sizeof(uint32_t));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "int8_t") == 0) {
    int8_t val;
    memcpy(&val, ptr, sizeof(int8_t));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "int16_t") == 0) {
    int16_t val;
    memcpy(&val, ptr, sizeof(int16_t));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "int32_t") == 0) {
    int32_t val;
    memcpy(&val, ptr, sizeof(int32_t));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "char") == 0) {
    long val;
    memcpy(&val, ptr, sizeof(char));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "short") == 0) {
    short val;
    memcpy(&val, ptr, sizeof(short));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "int") == 0) {
    int val;
    memcpy(&val, ptr, sizeof(int));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "long") == 0) {
    long val;
    memcpy(&val, ptr, sizeof(long));
    *lval = val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "unsigned char") == 0) {
    unsigned char val;
    memcpy(&val, ptr, sizeof(unsigned char));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "unsigned short") == 0) {
    unsigned short val;
    memcpy(&val, ptr, sizeof(unsigned short));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "unsigned int") == 0) {
    unsigned int val;
    memcpy(&val, ptr, sizeof(unsigned int));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "unsigned long") == 0) {
    unsigned long val;
    memcpy(&val, ptr, sizeof(unsigned long));
    *lval = (long)val;
    return PRIMITIVE_INTEGER;
  }
  else if (strcmp(type, "float") == 0) {
    float val;
    memcpy(&val, ptr, sizeof(float));
    *dval = (double)val;
    return PRIMITIVE_FLOAT;
  }
  else if (strcmp(type, "double") == 0) {
    double val;
    memcpy(&val, ptr, sizeof(double));
    *dval = val;
    return PRIMITIVE_FLOAT;
  }
  else {
    return PRIMITIVE_UNKNOWN;
  }
}

PyObject* valueFromScalar(char* type, char* ptr, int len) {
  long lval;
  double dval;
  int rval = memoryToPrimitive(type, ptr, &lval, &dval);
  switch(rval) {
    case PRIMITIVE_INTEGER:
      return PyInt_FromLong(lval);
    case PRIMITIVE_FLOAT:
      return PyFloat_FromDouble(dval);
    case PRIMITIVE_UNKNOWN:
    default:
      return PyString_FromStringAndSize(ptr, len);
  }
}

PyObject* listFromArray(char* type, char* ptr, int len) {
  long lval;
  double dval;
  int elementLen = lengthOfType(type);
  PyObject* list = PyList_New(0);
  //printf("Generating list of %s\n", type);
  for (char* tmpPtr = ptr; tmpPtr < ptr + len; tmpPtr += elementLen) {
    PyList_Append(list, valueFromScalar(type, tmpPtr, elementLen));    
  }
  return list;
}
%}

%include mac.i
%include radio.i
%include packet.i
%include SerialPacket.i
%include SerialForwarder.i
%include Throttle.i

%typemap(python,in) FILE * {
  if (!PyFile_Check($input)) {
    PyErr_SetString(PyExc_TypeError, "Requires a file as a parameter.");
    return NULL;
  }
  $1 = PyFile_AsFile($input);
}

%typemap(python,out) variable_string_t {
  if ($1.isArray) {
    //printf("Generating array %s\n", $1.type);
    $result = listFromArray  ($1.type, $1.ptr, $1.len);
  }
  else {
    //printf("Generating scalar %s\n", $1.type);
    $result = valueFromScalar($1.type, $1.ptr, $1.len);
  }
  if ($result == NULL) {
    PyErr_SetString(PyExc_RuntimeError, "Error generating Python type from TinyOS variable.");
  }
}


%typemap(python,in) nesc_app_t* {
  if (!PyList_Check($input)) {
    PyErr_SetString(PyExc_TypeError, "Requires a list as a parameter.");
    return NULL;
  }
  else {
    int size = PyList_Size($input);
    int i = 0;
    nesc_app_t* app;

    if (size % 3 != 0) {
      PyErr_SetString(PyExc_RuntimeError, "List must have 2*N elements.");
      return NULL;
    }

    app = (nesc_app_t*)malloc(sizeof(nesc_app_t));

    app->numVariables = size / 3;
    app->variableNames = (char**)malloc(sizeof(char*) * app->numVariables);
    app->variableTypes = (char**)malloc(sizeof(char*) * app->numVariables);
    app->variableArray = (int*)malloc(sizeof(int) * app->numVariables);

    memset(app->variableNames, 0, sizeof(char*) * app->numVariables);
    memset(app->variableTypes, 0, sizeof(char*) * app->numVariables);
    memset(app->variableArray, 0, sizeof(int) * app->numVariables);

    for (i = 0; i < app->numVariables; i++) {
      PyObject* name = PyList_GetItem($input, 3 * i);
      PyObject* array = PyList_GetItem($input, (3 * i) + 1);
      PyObject* format = PyList_GetItem($input, (3 * i) + 2);
      if (PyString_Check(name) && PyString_Check(format)) {
        app->variableNames[i] = PyString_AsString(name);
        app->variableTypes[i] = PyString_AsString(format);
        if (strcmp(PyString_AsString(array), "array") == 0) {
          app->variableArray[i] = 1;
          //printf("%s is an array\n", PyString_AsString(name));
        }
        else {
          app->variableArray[i] = 0;
          //printf("%s is a scalar\n", PyString_AsString(name));
        }
      }
      else {
        app->variableNames[i] = "<bad string>";
        app->variableTypes[i] = "<bad string>";
      }
    }

    $1 = app;
  }
}

typedef struct var_string {
  char* type;
  char* ptr;
  int len;
  int isArray;
} variable_string_t;

typedef struct nesc_app {
  int numVariables;
  char** variableNames;
  char** variableTypes;
  int* variableArray;
} nesc_app_t;

class Variable {
 public:
  Variable(char* name, char* format, int array, int mote);
  ~Variable();
  variable_string_t getData();  
};

class Mote {
 public:
  Mote(nesc_app_t* app);
  ~Mote();

  unsigned long id();
  
  long long int euid();
  void setEuid(long long int id);

  
  long long int bootTime();
  void bootAtTime(long long int time);

  bool isOn();
  void turnOff();
  void turnOn();
  Variable* getVariable(char* name);

  void addNoiseTraceReading(int val);
  void createNoiseModel();
  int generateNoise(int when);
};

class Tossim {
 public:
  Tossim(nesc_app_t* app);
  ~Tossim();
  
  void init();
  
  long long int time();
  long long int ticksPerSecond(); 
  void setTime(long long int time);
  char* timeStr();

  Mote* currentNode();
  Mote* getNode(unsigned long nodeID);
  void setCurrentNode(unsigned long nodeID);

  void addChannel(char* channel, FILE* file);
  bool removeChannel(char* channel, FILE* file);
  void randomSeed(int seed);

  bool runNextEvent();
  MAC* mac();
  Radio* radio();
  Packet* newPacket();
  SerialPacket* newSerialPacket();
};



--- NEW FILE: tossim_wrap.cxx ---
/* ----------------------------------------------------------------------------
 * This file was automatically generated by SWIG (http://www.swig.org).
 * Version 1.3.31
 * 
 * This file is not intended to be easily readable and contains a number of 
 * coding conventions designed to improve portability and efficiency. Do not make
 * changes to this file unless you know what you are doing--modify the SWIG 
 * interface file instead. 
 * ----------------------------------------------------------------------------- */

#define SWIGPYTHON
#define SWIG_PYTHON_DIRECTOR_NO_VTABLE

#ifdef __cplusplus
template<class T> class SwigValueWrapper {
    T *tt;
public:
    SwigValueWrapper() : tt(0) { }
    SwigValueWrapper(const SwigValueWrapper<T>& rhs) : tt(new T(*rhs.tt)) { }
[...7816 lines suppressed...]
 * -----------------------------------------------------------------------------*/

#ifdef __cplusplus
extern "C"
#endif
SWIGEXPORT void SWIG_init(void) {
  PyObject *m, *d;
  
  /* Fix SwigMethods to carry the callback ptrs when needed */
  SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial);
  
  m = Py_InitModule((char *) SWIG_name, SwigMethods);
  d = PyModule_GetDict(m);
  
  SWIG_InitializeModule(0);
  SWIG_InstallConstants(d,swig_const_table);
  
  
}




More information about the Tinyos-2-commits mailing list