]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/lib/tossim/tossim.i
Merge devel code into the trunk.
[tinyos-2.x.git] / tos / lib / tossim / tossim.i
diff --git a/tos/lib/tossim/tossim.i b/tos/lib/tossim/tossim.i
new file mode 100644 (file)
index 0000000..e819846
--- /dev/null
@@ -0,0 +1,377 @@
+/*
+ * "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 <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
+
+%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);
+
+};
+
+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);
+
+  bool runNextEvent();
+  MAC* mac();
+  Radio* radio();
+  Packet* newPacket();
+};
+
+