added support for dynamic corecomms (generated and compiled on demand)
This commit is contained in:
parent
5b35ae82c7
commit
24735fb776
5 changed files with 218 additions and 80 deletions
58
tools/cooja/config/corecomm_template.java
Normal file
58
tools/cooja/config/corecomm_template.java
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2006, Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. 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.
|
||||||
|
* 3. Neither the name of the Institute 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 INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package se.sics.cooja.corecomm;
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import se.sics.cooja.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see CoreComm
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
public class [CLASSNAME] extends CoreComm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads library libFile.
|
||||||
|
*
|
||||||
|
* @see CoreComm
|
||||||
|
* @param libFile Library file
|
||||||
|
*/
|
||||||
|
public [CLASSNAME](File libFile) {
|
||||||
|
System.load(libFile.getAbsolutePath());
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public native void tick();
|
||||||
|
public native void init();
|
||||||
|
public native int getReferenceAbsAddr();
|
||||||
|
public native void getMemory(int start, int length, byte[] mem);
|
||||||
|
public native void setMemory(int start, int length, byte[] mem);
|
||||||
|
}
|
|
@ -20,4 +20,6 @@ COMPILER_ARGS =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process;tcpip_process;uip_fw_process;cfs_cooja_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process;tcpip_process;uip_fw_process;cfs_cooja_process
|
||||||
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
||||||
MANTIS_MAIN_TEMPLATE_FILENAME = mantis_template.c
|
MANTIS_MAIN_TEMPLATE_FILENAME = mantis_template.c
|
||||||
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
|
PATH_JAVAC = javac
|
||||||
DEFAULT_USERPLATFORMS = ../apps/mrm
|
DEFAULT_USERPLATFORMS = ../apps/mrm
|
||||||
|
|
|
@ -20,4 +20,6 @@ COMPILER_ARGS = -mno-cygwin -I'C:/Program Files/Java/jdk1.5.0_06/include' -I'C:/
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process;tcpip_process;uip_fw_process;cfs_cooja_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process;tcpip_process;uip_fw_process;cfs_cooja_process
|
||||||
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
||||||
MANTIS_MAIN_TEMPLATE_FILENAME = mantis_template.c
|
MANTIS_MAIN_TEMPLATE_FILENAME = mantis_template.c
|
||||||
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
|
PATH_JAVAC = javac
|
||||||
DEFAULT_USERPLATFORMS = ../apps/mrm
|
DEFAULT_USERPLATFORMS = ../apps/mrm
|
||||||
|
|
|
@ -24,17 +24,19 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: CoreComm.java,v 1.3 2007/01/10 14:57:42 fros4943 Exp $
|
* $Id: CoreComm.java,v 1.4 2007/03/23 14:36:27 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import se.sics.cooja.corecomm.*;
|
import java.lang.reflect.*;
|
||||||
|
import java.net.*;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The purpose of corecomm's is communicating with a compiled Contiki system
|
* The purpose of corecomm's is communicating with a compiled Contiki system
|
||||||
* using Java Native Interface (JNI). Each implemented class (named Lib[1-MAX]),
|
* using Java Native Interface (JNI). Each implemented class (named Lib[number]),
|
||||||
* loads a shared library which belongs to one mote type. The reason for this
|
* loads a shared library which belongs to one mote type. The reason for this
|
||||||
* somewhat strange design is that once loaded, a native library cannot be
|
* somewhat strange design is that once loaded, a native library cannot be
|
||||||
* unloaded in Java (in the current versions available). Therefore if we wish to
|
* unloaded in Java (in the current versions available). Therefore if we wish to
|
||||||
|
@ -63,16 +65,12 @@ import se.sics.cooja.corecomm.*;
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
public abstract class CoreComm {
|
public abstract class CoreComm {
|
||||||
/**
|
|
||||||
* Maximum supported core communicators in a simulator.
|
|
||||||
*/
|
|
||||||
private final static int MAX_LIBRARIES = 8;
|
|
||||||
|
|
||||||
// Static pointers to current libraries
|
// Static pointers to current libraries
|
||||||
private final static CoreComm[] coreComms = new CoreComm[MAX_LIBRARIES];
|
private final static Vector<CoreComm> coreComms = new Vector<CoreComm>();
|
||||||
|
private final static Vector<File> coreCommFiles = new Vector<File>();
|
||||||
private final static File[] coreCommFiles = new File[MAX_LIBRARIES];
|
private static int fileCounter = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has any library been loaded? Since libraries can't be unloaded the entire
|
* Has any library been loaded? Since libraries can't be unloaded the entire
|
||||||
* simulator may have to be restarted.
|
* simulator may have to be restarted.
|
||||||
|
@ -80,10 +78,7 @@ public abstract class CoreComm {
|
||||||
* @return True if any library has been loaded this session
|
* @return True if any library has been loaded this session
|
||||||
*/
|
*/
|
||||||
public static boolean hasLibraryBeenLoaded() {
|
public static boolean hasLibraryBeenLoaded() {
|
||||||
for (int i = 0; i < coreComms.length; i++)
|
return coreComms.size() > 0;
|
||||||
if (coreComms[i] != null)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,8 +93,8 @@ public abstract class CoreComm {
|
||||||
* filename
|
* filename
|
||||||
*/
|
*/
|
||||||
public static boolean hasLibraryFileBeenLoaded(File libraryFile) {
|
public static boolean hasLibraryFileBeenLoaded(File libraryFile) {
|
||||||
for (File libFile : coreCommFiles)
|
for (File loadedFile : coreCommFiles)
|
||||||
if (libFile != null && libFile.getName().equals(libraryFile.getName()))
|
if (loadedFile != null && loadedFile.getName().equals(libraryFile.getName()))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -111,26 +106,120 @@ public abstract class CoreComm {
|
||||||
* @return Class name
|
* @return Class name
|
||||||
*/
|
*/
|
||||||
public static String getAvailableClassName() {
|
public static String getAvailableClassName() {
|
||||||
if (coreComms[0] == null)
|
return "Lib" + fileCounter;
|
||||||
return "Lib1";
|
|
||||||
if (coreComms[1] == null)
|
|
||||||
return "Lib2";
|
|
||||||
if (coreComms[2] == null)
|
|
||||||
return "Lib3";
|
|
||||||
if (coreComms[3] == null)
|
|
||||||
return "Lib4";
|
|
||||||
if (coreComms[4] == null)
|
|
||||||
return "Lib5";
|
|
||||||
if (coreComms[5] == null)
|
|
||||||
return "Lib6";
|
|
||||||
if (coreComms[6] == null)
|
|
||||||
return "Lib7";
|
|
||||||
if (coreComms[7] == null)
|
|
||||||
return "Lib8";
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates new source file by reading default source template and replacing
|
||||||
|
* the class name field.
|
||||||
|
*
|
||||||
|
* @param className
|
||||||
|
* Wanted class name
|
||||||
|
* @return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
public static boolean generateLibSourceFile(String className) {
|
||||||
|
BufferedWriter sourceFileWriter = null;
|
||||||
|
BufferedReader templateFileReader = null;
|
||||||
|
String destFilename = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Reader reader;
|
||||||
|
String mainTemplate = GUI
|
||||||
|
.getExternalToolsSetting("CORECOMM_TEMPLATE_FILENAME");
|
||||||
|
|
||||||
|
if ((new File(mainTemplate)).exists()) {
|
||||||
|
reader = new FileReader(mainTemplate);
|
||||||
|
} else {
|
||||||
|
InputStream input = CoreComm.class
|
||||||
|
.getResourceAsStream('/' + mainTemplate);
|
||||||
|
if (input == null) {
|
||||||
|
throw new FileNotFoundException(mainTemplate + " not found");
|
||||||
|
}
|
||||||
|
reader = new InputStreamReader(input);
|
||||||
|
}
|
||||||
|
|
||||||
|
templateFileReader = new BufferedReader(reader);
|
||||||
|
destFilename = className + ".java";
|
||||||
|
sourceFileWriter = new BufferedWriter(new OutputStreamWriter(
|
||||||
|
new FileOutputStream("se/sics/cooja/corecomm/" + destFilename)));
|
||||||
|
|
||||||
|
// Replace special fields in template
|
||||||
|
String line;
|
||||||
|
while ((line = templateFileReader.readLine()) != null) {
|
||||||
|
line = line.replaceFirst("\\[CLASSNAME\\]", className);
|
||||||
|
sourceFileWriter.write(line + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceFileWriter.close();
|
||||||
|
templateFileReader.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
try {
|
||||||
|
if (sourceFileWriter != null)
|
||||||
|
sourceFileWriter.close();
|
||||||
|
if (templateFileReader != null)
|
||||||
|
templateFileReader.close();
|
||||||
|
} catch (Exception e2) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File genFile = new File("se/sics/cooja/corecomm/" + destFilename);
|
||||||
|
if (genFile.exists())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile given Java source file.
|
||||||
|
*
|
||||||
|
* @param className Class name
|
||||||
|
* @return True if success, false otherwise
|
||||||
|
*/
|
||||||
|
private static boolean compileSourceFile(String className) {
|
||||||
|
try {
|
||||||
|
String[] cmd = new String[]{
|
||||||
|
GUI.getExternalToolsSetting("PATH_JAVAC"),
|
||||||
|
"se/sics/cooja/corecomm/" + className + ".java" };
|
||||||
|
|
||||||
|
Process p = Runtime.getRuntime().exec(cmd, null, null);
|
||||||
|
p.waitFor();
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
File classFile = new File("se/sics/cooja/corecomm/" + className + ".class");
|
||||||
|
if (classFile.exists())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load given Java class file, making it ready to be used.
|
||||||
|
*
|
||||||
|
* @param classFile Class file
|
||||||
|
* @return Loaded class, or null
|
||||||
|
*/
|
||||||
|
private static Class loadClassFile(String className) {
|
||||||
|
Class loadedClass = null;
|
||||||
|
try {
|
||||||
|
ClassLoader urlClassLoader = new URLClassLoader(
|
||||||
|
new URL[] { new File(".").toURL() },
|
||||||
|
CoreComm.class.getClassLoader());
|
||||||
|
loadedClass = urlClassLoader.loadClass("se.sics.cooja.corecomm." + className);
|
||||||
|
} catch (MalformedURLException e) {
|
||||||
|
return null;
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return loadedClass;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create and return an instance of the core communicator identified by
|
* Create and return an instance of the core communicator identified by
|
||||||
* className. This core communicator will load the native library libFile.
|
* className. This core communicator will load the native library libFile.
|
||||||
|
@ -142,50 +231,36 @@ public abstract class CoreComm {
|
||||||
* @return Core Communicator
|
* @return Core Communicator
|
||||||
*/
|
*/
|
||||||
public static CoreComm createCoreComm(String className, File libFile) {
|
public static CoreComm createCoreComm(String className, File libFile) {
|
||||||
if (className.equals("Lib1") && coreComms[0] == null) {
|
if (!generateLibSourceFile(className))
|
||||||
coreComms[0] = new Lib1(libFile);
|
return null;
|
||||||
coreCommFiles[0] = libFile;
|
|
||||||
return coreComms[0];
|
if (!compileSourceFile(className))
|
||||||
}
|
return null;
|
||||||
if (className.equals("Lib2") && coreComms[1] == null) {
|
|
||||||
coreComms[1] = new Lib2(libFile);
|
|
||||||
coreCommFiles[1] = libFile;
|
|
||||||
return coreComms[1];
|
|
||||||
}
|
|
||||||
if (className.equals("Lib3") && coreComms[2] == null) {
|
|
||||||
coreComms[2] = new Lib3(libFile);
|
|
||||||
coreCommFiles[2] = libFile;
|
|
||||||
return coreComms[2];
|
|
||||||
}
|
|
||||||
if (className.equals("Lib4") && coreComms[3] == null) {
|
|
||||||
coreComms[3] = new Lib4(libFile);
|
|
||||||
coreCommFiles[3] = libFile;
|
|
||||||
return coreComms[3];
|
|
||||||
}
|
|
||||||
if (className.equals("Lib5") && coreComms[4] == null) {
|
|
||||||
coreComms[4] = new Lib5(libFile);
|
|
||||||
coreCommFiles[4] = libFile;
|
|
||||||
return coreComms[4];
|
|
||||||
}
|
|
||||||
if (className.equals("Lib6") && coreComms[5] == null) {
|
|
||||||
coreComms[5] = new Lib6(libFile);
|
|
||||||
coreCommFiles[5] = libFile;
|
|
||||||
return coreComms[5];
|
|
||||||
}
|
|
||||||
if (className.equals("Lib7") && coreComms[6] == null) {
|
|
||||||
coreComms[6] = new Lib7(libFile);
|
|
||||||
coreCommFiles[6] = libFile;
|
|
||||||
return coreComms[6];
|
|
||||||
}
|
|
||||||
if (className.equals("Lib8") && coreComms[7] == null) {
|
|
||||||
coreComms[7] = new Lib8(libFile);
|
|
||||||
coreCommFiles[7] = libFile;
|
|
||||||
return coreComms[7];
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
Class newCoreCommClass = loadClassFile(className);
|
||||||
|
if (newCoreCommClass == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Constructor constr = newCoreCommClass.getConstructor(new Class[] { File.class });
|
||||||
|
CoreComm newCoreComm = (CoreComm) constr.newInstance(new Object[] { libFile });
|
||||||
|
|
||||||
|
coreComms.add(newCoreComm);
|
||||||
|
coreCommFiles.add(libFile);
|
||||||
|
fileCounter++;
|
||||||
|
|
||||||
|
return newCoreComm;
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
return null;
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
return null;
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
return null;
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ticks a mote once. This should not be used directly, but instead via
|
* Ticks a mote once. This should not be used directly, but instead via
|
||||||
* Mote.tick().
|
* Mote.tick().
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: GUI.java,v 1.30 2007/03/23 11:25:19 fros4943 Exp $
|
* $Id: GUI.java,v 1.31 2007/03/23 14:36:27 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
@ -140,7 +140,8 @@ public class GUI {
|
||||||
"CONTIKI_STANDARD_PROCESSES", "CMD_GREP_PROCESSES",
|
"CONTIKI_STANDARD_PROCESSES", "CMD_GREP_PROCESSES",
|
||||||
"REGEXP_PARSE_PROCESSES", "CMD_GREP_INTERFACES",
|
"REGEXP_PARSE_PROCESSES", "CMD_GREP_INTERFACES",
|
||||||
"REGEXP_PARSE_INTERFACES", "CMD_GREP_SENSORS", "REGEXP_PARSE_SENSORS",
|
"REGEXP_PARSE_INTERFACES", "CMD_GREP_SENSORS", "REGEXP_PARSE_SENSORS",
|
||||||
"CONTIKI_MAIN_TEMPLATE_FILENAME", "DEFAULT_USERPLATFORMS" };
|
"CONTIKI_MAIN_TEMPLATE_FILENAME", "DEFAULT_USERPLATFORMS",
|
||||||
|
"CORECOMM_TEMPLATE_FILENAME", "PATH_JAVAC"};
|
||||||
|
|
||||||
private static final int FRAME_NEW_OFFSET = 30;
|
private static final int FRAME_NEW_OFFSET = 30;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue