/*
* "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).
*
* @author Philip Levis
* @date Nov 22 2005
*/
%module TOSSIM
%{
#include
#include
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
%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] = (char*)"";
app->variableTypes[i] = (char*)"";
}
}
$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();
};