removed references to unused mantis files
This commit is contained in:
parent
716932544b
commit
c447f5e6c0
|
@ -35,5 +35,3 @@ se.sics.cooja.GUI.PLUGINS = se.sics.cooja.plugins.VisState se.sics.cooja.plugins
|
||||||
se.sics.cooja.GUI.IP_DISTRIBUTORS = se.sics.cooja.ipdistributors.RandomIPDistributor se.sics.cooja.ipdistributors.SpatialIPDistributor se.sics.cooja.ipdistributors.IdIPDistributor
|
se.sics.cooja.GUI.IP_DISTRIBUTORS = se.sics.cooja.ipdistributors.RandomIPDistributor se.sics.cooja.ipdistributors.SpatialIPDistributor se.sics.cooja.ipdistributors.IdIPDistributor
|
||||||
se.sics.cooja.GUI.POSITIONERS = se.sics.cooja.positioners.RandomPositioner se.sics.cooja.positioners.LinearPositioner se.sics.cooja.positioners.EllipsePositioner
|
se.sics.cooja.GUI.POSITIONERS = se.sics.cooja.positioners.RandomPositioner se.sics.cooja.positioners.LinearPositioner se.sics.cooja.positioners.EllipsePositioner
|
||||||
se.sics.cooja.GUI.RADIOMEDIUMS = se.sics.cooja.radiomediums.UDGM se.sics.cooja.radiomediums.SilentRadioMedium
|
se.sics.cooja.GUI.RADIOMEDIUMS = se.sics.cooja.radiomediums.UDGM se.sics.cooja.radiomediums.SilentRadioMedium
|
||||||
|
|
||||||
se.sics.cooja.mantismote.MantisMoteType.MOTE_INTERFACES = se.sics.cooja.interfaces.Position
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ AR_COMMAND_1 = ar rcf $(ARFILE)
|
||||||
AR_COMMAND_2 =
|
AR_COMMAND_2 =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
||||||
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
||||||
MANTIS_MAIN_TEMPLATE_FILENAME = mantis_template.c
|
|
||||||
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
PATH_JAVAC = javac
|
PATH_JAVAC = javac
|
||||||
DEFAULT_PROJECTDIRS = ../apps/mrm
|
DEFAULT_PROJECTDIRS = ../apps/mrm
|
||||||
|
|
|
@ -20,7 +20,6 @@ AR_COMMAND_1 = ar rc $(ARFILE)
|
||||||
AR_COMMAND_2 =
|
AR_COMMAND_2 =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
||||||
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
||||||
MANTIS_MAIN_TEMPLATE_FILENAME = mantis_template.c
|
|
||||||
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
PATH_JAVAC = javac
|
PATH_JAVAC = javac
|
||||||
DEFAULT_PROJECTDIRS = ../apps/mrm
|
DEFAULT_PROJECTDIRS = ../apps/mrm
|
||||||
|
|
|
@ -20,7 +20,6 @@ AR_COMMAND_1 = ar rcf $(ARFILE)
|
||||||
AR_COMMAND_2 =
|
AR_COMMAND_2 =
|
||||||
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
|
||||||
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
|
||||||
MANTIS_MAIN_TEMPLATE_FILENAME = mantis_template.c
|
|
||||||
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
|
||||||
PATH_JAVAC = javac
|
PATH_JAVAC = javac
|
||||||
DEFAULT_PROJECTDIRS = ../apps/mrm
|
DEFAULT_PROJECTDIRS = ../apps/mrm
|
||||||
|
|
|
@ -1,178 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id: mantis_template.c,v 1.1 2006/11/09 19:32:53 fros4943 Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file
|
|
||||||
* C code template for generating Mantis source code files from COOJA
|
|
||||||
* Simulator. This file should not be compiled directly.
|
|
||||||
* \author
|
|
||||||
* Fredrik Osterlind <fros@sics.se>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <jni.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include "mos.h"
|
|
||||||
#include "sem.h"
|
|
||||||
#include "msched.h"
|
|
||||||
|
|
||||||
extern int main(); /* in mantis/src/mos/sys/main.c */
|
|
||||||
extern uint32_t cooja_time; /* in mantis/src/mos/sys/main.c */
|
|
||||||
extern pthread_cond_t cooja_cv; /* in mantis/src/mos/sys/main.c */
|
|
||||||
extern mos_thread_t threads[MAX_THREADS]; /* in mantis/src/mos/sys/main.c */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* referenceVar is used for comparing absolute and process relative memory.
|
|
||||||
* (this must not be static due to memory locations)
|
|
||||||
*/
|
|
||||||
int referenceVar;
|
|
||||||
|
|
||||||
int dataVar = 1;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \brief Initialize a mote by starting processes etc.
|
|
||||||
*
|
|
||||||
* This function initializes a mote by starting certain
|
|
||||||
* processes and setting up the environment.
|
|
||||||
*
|
|
||||||
* This is a JNI function and should only be called via the
|
|
||||||
* responsible Java part (MoteType.java).
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_se_sics_cooja_corecomm_[CLASS_NAME]_init(JNIEnv *env, jobject obj)
|
|
||||||
{
|
|
||||||
main();
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \brief Get a segment from the process memory.
|
|
||||||
* \param start Start address of segment
|
|
||||||
* \param length Size of memory segment
|
|
||||||
* \return Java byte array containing a copy of memory segment.
|
|
||||||
*
|
|
||||||
* Fetches a memory segment from the process memory starting at
|
|
||||||
* (start), with size (length). This function does not perform
|
|
||||||
* ANY error checking, and the process may crash if addresses are
|
|
||||||
* not available/readable.
|
|
||||||
*
|
|
||||||
* This is a JNI function and should only be called via the
|
|
||||||
* responsible Java part (MoteType.java).
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_se_sics_cooja_corecomm_[CLASS_NAME]_getMemory(JNIEnv *env, jobject obj, jint start, jint length, jbyteArray mem_arr)
|
|
||||||
{
|
|
||||||
(*env)->SetByteArrayRegion(env, mem_arr, 0, (size_t) length, (jbyte *) start);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \brief Replace a segment of the process memory with given byte array.
|
|
||||||
* \param start Start address of segment
|
|
||||||
* \param length Size of memory segment
|
|
||||||
* \param mem_arr Byte array contaning new memory
|
|
||||||
*
|
|
||||||
* Replaces a process memory segment with given byte array.
|
|
||||||
* This function does not perform ANY error checking, and the
|
|
||||||
* process may crash if addresses are not available/writable.
|
|
||||||
*
|
|
||||||
* This is a JNI function and should only be called via the
|
|
||||||
* responsible Java part (MoteType.java).
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_se_sics_cooja_corecomm_[CLASS_NAME]_setMemory(JNIEnv *env, jobject obj, jint start, jint length, jbyteArray mem_arr)
|
|
||||||
{
|
|
||||||
jbyte *mem = (*env)->GetByteArrayElements(env, mem_arr, 0);
|
|
||||||
memcpy((void *) start, mem, length);
|
|
||||||
(*env)->ReleaseByteArrayElements(env, mem_arr, mem, 0);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \brief Let mote execute one "block" of code (tick mote).
|
|
||||||
*
|
|
||||||
* This is a JNI function and should only be called via the
|
|
||||||
* responsible Java part (MoteType.java).
|
|
||||||
*/
|
|
||||||
JNIEXPORT void JNICALL
|
|
||||||
Java_se_sics_cooja_corecomm_[CLASS_NAME]_tick(JNIEnv *env, jobject obj)
|
|
||||||
{
|
|
||||||
int readyexist = 0;
|
|
||||||
|
|
||||||
/* Ugly hack, setting all ready threads to BLOCKED just to discover which ones wake up */
|
|
||||||
for(i=0; i<MAX_THREADS; i++) {
|
|
||||||
if (threads[i].state == READY) {
|
|
||||||
threads[i].state = BLOCKED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cooja_time += 1; // increase time
|
|
||||||
//printf("CORE> tick, time is now %i\n", cooja_time);
|
|
||||||
|
|
||||||
/* Signal all threads to start working again */
|
|
||||||
for(i=0; i<MAX_THREADS; i++) {
|
|
||||||
if (threads[i].state == BLOCKED) {
|
|
||||||
mos_thread_resume(&threads[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait until all threads are blocked again. ??!?!!
|
|
||||||
* For now we just assume all threads will be done within 1ms. */
|
|
||||||
do {
|
|
||||||
readyexist=0;
|
|
||||||
for(i=0; i<MAX_THREADS; i++) {
|
|
||||||
if (threads[i].state == READY) {
|
|
||||||
readyexist = 1;
|
|
||||||
//printf("waiting until thread finished...: %p\n", &threads[i]);
|
|
||||||
//fflush(stdout);
|
|
||||||
usleep(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (readyexist);
|
|
||||||
}
|
|
||||||
/*---------------------------------------------------------------------------*/
|
|
||||||
/**
|
|
||||||
* \brief Get the absolute memory address of a special variable.
|
|
||||||
* \return Absolute memory address.
|
|
||||||
*
|
|
||||||
* Returns the absolute memory address of a special variable
|
|
||||||
* "referenceVar". By comparing this address with the relative
|
|
||||||
* address (from the map file) for referenceVar, an runtime offset
|
|
||||||
* can be calculated.
|
|
||||||
*
|
|
||||||
* This is a JNI function and should only be called via the
|
|
||||||
* responsible Java part (MoteType.java).
|
|
||||||
*/
|
|
||||||
JNIEXPORT jint JNICALL
|
|
||||||
Java_se_sics_cooja_corecomm_[CLASS_NAME]_getReferenceAbsAddr(JNIEnv *env, jobject obj)
|
|
||||||
{
|
|
||||||
return (jint) &referenceVar;
|
|
||||||
}
|
|
|
@ -1,234 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id: MantisMote.java,v 1.2 2007/01/09 10:02:16 fros4943 Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
package se.sics.cooja.mantismote;
|
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.jdom.Element;
|
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A Mantis mote simulation works the same way as the native Contiki mote. The
|
|
||||||
* Mantis OS is compiled and linked together with a JNI-enabled object file
|
|
||||||
* generated from COOJA.
|
|
||||||
*
|
|
||||||
* Each tick the all interfaces are polled, the memory is copied and the tick is
|
|
||||||
* forwarded to the core Mantis system.
|
|
||||||
*
|
|
||||||
* A Mantis mote is always active.
|
|
||||||
*
|
|
||||||
* @author Fredrik Osterlind
|
|
||||||
*/
|
|
||||||
public class MantisMote implements Mote {
|
|
||||||
private static Logger logger = Logger.getLogger(MantisMote.class);
|
|
||||||
|
|
||||||
private MantisMoteType myType = null;
|
|
||||||
|
|
||||||
private SectionMoteMemory myMemory = null;
|
|
||||||
|
|
||||||
private MoteInterfaceHandler myInterfaceHandler = null;
|
|
||||||
|
|
||||||
private Simulation mySimulation = null;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new uninitialized Mantis mote.
|
|
||||||
*
|
|
||||||
* This mote needs at least a type, a memory, a mote interface handler and to
|
|
||||||
* be connected to a simulation.
|
|
||||||
*/
|
|
||||||
public MantisMote() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new mote of given type. Both the initial mote memory and the
|
|
||||||
* interface handler are supplied from the mote type.
|
|
||||||
*
|
|
||||||
* @param moteType
|
|
||||||
* Mote type
|
|
||||||
* @param sim
|
|
||||||
* Mote's simulation
|
|
||||||
*/
|
|
||||||
public MantisMote(MantisMoteType moteType, Simulation sim) {
|
|
||||||
this.mySimulation = sim;
|
|
||||||
this.myType = moteType;
|
|
||||||
this.myMemory = moteType.createInitialMemory();
|
|
||||||
this.myInterfaceHandler = new MoteInterfaceHandler((Mote) this, moteType
|
|
||||||
.getMoteInterfaces());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setState(State newState) {
|
|
||||||
logger.fatal("Mantis motes can't change state");
|
|
||||||
}
|
|
||||||
|
|
||||||
public State getState() {
|
|
||||||
return State.ACTIVE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addStateObserver(Observer newObserver) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void deleteStateObserver(Observer newObserver) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public MoteInterfaceHandler getInterfaces() {
|
|
||||||
return myInterfaceHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setInterfaces(MoteInterfaceHandler moteInterfaceHandler) {
|
|
||||||
myInterfaceHandler = moteInterfaceHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MoteMemory getMemory() {
|
|
||||||
return myMemory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMemory(MoteMemory memory) {
|
|
||||||
myMemory = (SectionMoteMemory) memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MoteType getType() {
|
|
||||||
return myType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setType(MoteType type) {
|
|
||||||
myType = (MantisMoteType) type;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Simulation getSimulation() {
|
|
||||||
return mySimulation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSimulation(Simulation simulation) {
|
|
||||||
mySimulation = simulation;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void tick(int simTime) {
|
|
||||||
// Poll all interfaces before tick
|
|
||||||
myInterfaceHandler.doActiveActionsBeforeTick();
|
|
||||||
myInterfaceHandler.doPassiveActionsBeforeTick();
|
|
||||||
|
|
||||||
// Copy memory to core
|
|
||||||
myType.setCoreMemory(myMemory);
|
|
||||||
|
|
||||||
// Tick node
|
|
||||||
myType.tick();
|
|
||||||
|
|
||||||
// Fetch new updated memory from core
|
|
||||||
myType.getCoreMemory(myMemory);
|
|
||||||
|
|
||||||
// Poll all interfaces after tick
|
|
||||||
myInterfaceHandler.doActiveActionsBeforeTick();
|
|
||||||
myInterfaceHandler.doPassiveActionsBeforeTick();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Element> getConfigXML() {
|
|
||||||
Vector<Element> config = new Vector<Element>();
|
|
||||||
|
|
||||||
Element element;
|
|
||||||
|
|
||||||
// Mote type identifier
|
|
||||||
element = new Element("motetype_identifier");
|
|
||||||
element.setText(getType().getIdentifier());
|
|
||||||
config.add(element);
|
|
||||||
|
|
||||||
// Active interface configs (if any)
|
|
||||||
for (MoteInterface moteInterface : getInterfaces().getAllActiveInterfaces()) {
|
|
||||||
element = new Element("interface_config");
|
|
||||||
element.setText(moteInterface.getClass().getName());
|
|
||||||
|
|
||||||
Collection interfaceXML = moteInterface.getConfigXML();
|
|
||||||
if (interfaceXML != null) {
|
|
||||||
element.addContent(interfaceXML);
|
|
||||||
config.add(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Passive interface configs (if any)
|
|
||||||
for (MoteInterface moteInterface : getInterfaces()
|
|
||||||
.getAllPassiveInterfaces()) {
|
|
||||||
element = new Element("interface_config");
|
|
||||||
element.setText(moteInterface.getClass().getName());
|
|
||||||
|
|
||||||
Collection interfaceXML = moteInterface.getConfigXML();
|
|
||||||
if (interfaceXML != null) {
|
|
||||||
element.addContent(interfaceXML);
|
|
||||||
config.add(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setConfigXML(Simulation simulation,
|
|
||||||
Collection<Element> configXML, boolean visAvailable) {
|
|
||||||
mySimulation = simulation;
|
|
||||||
|
|
||||||
for (Element element : configXML) {
|
|
||||||
String name = element.getName();
|
|
||||||
|
|
||||||
if (name.equals("motetype_identifier")) {
|
|
||||||
myType = (MantisMoteType) simulation.getMoteType(element.getText());
|
|
||||||
myMemory = myType.createInitialMemory();
|
|
||||||
myInterfaceHandler = new MoteInterfaceHandler((Mote) this, myType
|
|
||||||
.getMoteInterfaces());
|
|
||||||
|
|
||||||
} else if (name.equals("interface_config")) {
|
|
||||||
Class<? extends MoteInterface> moteInterfaceClass = simulation.getGUI()
|
|
||||||
.tryLoadClass(this, MoteInterface.class, element.getText().trim());
|
|
||||||
|
|
||||||
if (moteInterfaceClass == null) {
|
|
||||||
logger.fatal("Could not load mote interface class: "
|
|
||||||
+ element.getText().trim());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MoteInterface moteInterface = myInterfaceHandler
|
|
||||||
.getInterfaceOfType(moteInterfaceClass);
|
|
||||||
if (moteInterface != null)
|
|
||||||
moteInterface.setConfigXML(element.getChildren(), visAvailable);
|
|
||||||
else
|
|
||||||
logger
|
|
||||||
.warn("Can't restore configuration for non-existing interface: "
|
|
||||||
+ moteInterfaceClass.getName());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
if (getInterfaces().getMoteID() != null) {
|
|
||||||
return "Mantis Mote, ID=" + getInterfaces().getMoteID().getMoteID();
|
|
||||||
} else
|
|
||||||
return "Mantis Mote, ID=null";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,416 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id: MantisMoteType.java,v 1.6 2008/02/12 15:10:49 fros4943 Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
package se.sics.cooja.mantismote;
|
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Container;
|
|
||||||
import java.awt.Dimension;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.swing.Box;
|
|
||||||
import javax.swing.BoxLayout;
|
|
||||||
import javax.swing.JLabel;
|
|
||||||
import javax.swing.JPanel;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.jdom.Element;
|
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
|
||||||
import se.sics.cooja.contikimote.ContikiMoteType;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The Mantis mote type holds the native library used to communicate with an
|
|
||||||
* underlying Mantis system. All communication with that system should always
|
|
||||||
* pass through this mote type.
|
|
||||||
* <p>
|
|
||||||
* All core communication with the Mantis mote should be via this class. When a
|
|
||||||
* mote type is created it allocates a CoreComm to be used with this type.
|
|
||||||
* <p>
|
|
||||||
* When a new mote type is created an initialization function is run on the
|
|
||||||
* Mantis system in order to create the initial memory. When a new mote is
|
|
||||||
* created the createInitialMemory() method should be called to get this initial
|
|
||||||
* memory for the mote.
|
|
||||||
*
|
|
||||||
* @author Fredrik Osterlind
|
|
||||||
*/
|
|
||||||
@ClassDescription("Mantis Mote Type")
|
|
||||||
public class MantisMoteType implements MoteType {
|
|
||||||
private static Logger logger = Logger.getLogger(MantisMoteType.class);
|
|
||||||
private Simulation mySimulation = null;
|
|
||||||
|
|
||||||
// Mote type specific information
|
|
||||||
private String myIdentifier = null;
|
|
||||||
private String myDescription = null;
|
|
||||||
private String myObjectFilename = null;
|
|
||||||
private SectionMoteMemory myInitialMemory = null;
|
|
||||||
private Vector<Class<? extends MoteInterface>> moteInterfaceClasses = null;
|
|
||||||
|
|
||||||
// Core communication variables
|
|
||||||
private String libraryClassName = null;
|
|
||||||
private int offsetRelToAbs = 0;
|
|
||||||
private CoreComm myCoreComm = null;
|
|
||||||
|
|
||||||
// Variable name to address mappings
|
|
||||||
private Properties varAddresses = new Properties();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new uninitialized Mantis mote type. This mote type's doInit
|
|
||||||
* method must be called and succeed before it can be used.
|
|
||||||
*/
|
|
||||||
public MantisMoteType() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a new initialized Mantis mote type. The given library file is
|
|
||||||
* loaded by the first available CoreComm. Each mote generated from this mote
|
|
||||||
* type will have the interfaces specified in the given mote interface class
|
|
||||||
* list.
|
|
||||||
*
|
|
||||||
* @param libFile
|
|
||||||
* Library file to load
|
|
||||||
* @param objFile
|
|
||||||
* Object file
|
|
||||||
* @param moteInterfaceClasses
|
|
||||||
* List of mote interfaces
|
|
||||||
*/
|
|
||||||
public MantisMoteType(File libFile, File objFile,
|
|
||||||
Vector<Class<? extends MoteInterface>> moteInterfaceClasses) {
|
|
||||||
if (!doInit(libFile, objFile, moteInterfaceClasses)) {
|
|
||||||
logger.fatal("Mantis mote type creation failed!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is an mote type initialization method and should normally never be
|
|
||||||
* called by any other part than the mote type constructor. It is called from
|
|
||||||
* the constructor with an identifier argument, but not from the standard
|
|
||||||
* constructor. This method may be called from the simulator when loading
|
|
||||||
* configuration files, and the libraries must be recompiled.
|
|
||||||
*
|
|
||||||
* This method allocates a core communicator, loads the Mantis library file,
|
|
||||||
* creates variable name to address mappings and finally creates the Mantis
|
|
||||||
* mote initial memory.
|
|
||||||
*
|
|
||||||
* @param libFile Library file
|
|
||||||
* @param objFile Object file
|
|
||||||
* @param moteInterfaceClasses Mote interface classes
|
|
||||||
* @return True if initialization ok, false otherwise
|
|
||||||
*/
|
|
||||||
protected boolean doInit(File libFile, File objFile,
|
|
||||||
Vector<Class<? extends MoteInterface>> moteInterfaceClasses) {
|
|
||||||
myObjectFilename = objFile.getAbsolutePath();
|
|
||||||
myIdentifier = libFile.getName();
|
|
||||||
myDescription = libFile.getAbsolutePath();
|
|
||||||
|
|
||||||
// Allocate core communicator class
|
|
||||||
libraryClassName = CoreComm.getAvailableClassName();
|
|
||||||
try {
|
|
||||||
myCoreComm = CoreComm.createCoreComm(libraryClassName, libFile);
|
|
||||||
} catch (MoteTypeCreationException e) {
|
|
||||||
logger.fatal("Library creation failed: " + e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse variable name to addresses mappings using nm
|
|
||||||
varAddresses.clear();
|
|
||||||
Vector<String> nmData = ContikiMoteType.loadCommandData(libFile);
|
|
||||||
if (nmData == null || !ContikiMoteType.parseCommandData(nmData, varAddresses)) {
|
|
||||||
logger.fatal("Nm response parsing failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Bug. Both sections sizes must be > 0!
|
|
||||||
|
|
||||||
// Parse section offsets and sizes using objdump
|
|
||||||
Vector<String> objdumpData = ContikiMoteType.loadObjdumpData(libFile);
|
|
||||||
int relDataSectionAddr = -1;
|
|
||||||
int dataSectionSize = -1;
|
|
||||||
int relBssSectionAddr = -1;
|
|
||||||
int bssSectionSize = -1;
|
|
||||||
String dataRegExp = "^[ \t]*[0-9]*[ \t]*.data[ \t]*([0-9A-Fa-f]*)[ \t]*[0-9A-Fa-f]*[ \t]*([0-9A-Fa-f]*)[ \t]*[0-9A-Fa-f]*[ \t]*";
|
|
||||||
String bssRegExp = "^[ \t]*[0-9]*[ \t]*.bss[ \t]*([0-9A-Fa-f]*)[ \t]*[0-9A-Fa-f]*[ \t]*([0-9A-Fa-f]*)[ \t]*[0-9A-Fa-f]*[ \t]*";
|
|
||||||
Pattern dataPattern = Pattern.compile(dataRegExp);
|
|
||||||
Pattern bssPattern = Pattern.compile(bssRegExp);
|
|
||||||
Matcher matcher;
|
|
||||||
for (String objdumpLine: objdumpData) {
|
|
||||||
matcher = dataPattern.matcher(objdumpLine);
|
|
||||||
if (matcher.find()) {
|
|
||||||
String size = matcher.group(1);
|
|
||||||
String offset = matcher.group(2);
|
|
||||||
dataSectionSize = Integer.parseInt(size, 16);
|
|
||||||
relDataSectionAddr = Integer.parseInt(offset, 16);
|
|
||||||
}
|
|
||||||
matcher = bssPattern.matcher(objdumpLine);
|
|
||||||
if (matcher.find()) {
|
|
||||||
String size = matcher.group(1);
|
|
||||||
String offset = matcher.group(2);
|
|
||||||
bssSectionSize = Integer.parseInt(size, 16);
|
|
||||||
relBssSectionAddr = Integer.parseInt(offset, 16);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (relDataSectionAddr == -1) {
|
|
||||||
logger.fatal("Data section address parsing failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (dataSectionSize == -1) {
|
|
||||||
logger.fatal("Data section size parsing failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (relBssSectionAddr == -1) {
|
|
||||||
logger.fatal("BSS section address parsing failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (bssSectionSize == -1) {
|
|
||||||
logger.fatal("BSS section size parsing failed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get offset between relative and absolute addresses
|
|
||||||
offsetRelToAbs = myCoreComm.getReferenceAbsAddr() - (Integer) varAddresses.get("referenceVar");
|
|
||||||
|
|
||||||
// Read initial memory from Mantis system
|
|
||||||
byte[] initialDataSection = new byte[dataSectionSize];
|
|
||||||
myCoreComm.getMemory(relDataSectionAddr + offsetRelToAbs, dataSectionSize, initialDataSection);
|
|
||||||
byte[] initialBssSection = new byte[bssSectionSize];
|
|
||||||
myCoreComm.getMemory(relBssSectionAddr + offsetRelToAbs, bssSectionSize, initialBssSection);
|
|
||||||
|
|
||||||
// Store initial memory for later use
|
|
||||||
myInitialMemory = new SectionMoteMemory(varAddresses);
|
|
||||||
myInitialMemory.setMemorySegment(relDataSectionAddr, initialDataSection);
|
|
||||||
myInitialMemory.setMemorySegment(relBssSectionAddr, initialBssSection);
|
|
||||||
|
|
||||||
this.moteInterfaceClasses = moteInterfaceClasses;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and returns a copy of this mote type's initial memory (just after
|
|
||||||
* the init function has been run). When a new mote is created it should get
|
|
||||||
* it's memory from here.
|
|
||||||
*
|
|
||||||
* @return Initial memory of a mote type
|
|
||||||
*/
|
|
||||||
public SectionMoteMemory createInitialMemory() {
|
|
||||||
return myInitialMemory.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ticks the currently loaded mote. This should not be used directly, but
|
|
||||||
* rather via MantisMote.tick().
|
|
||||||
*/
|
|
||||||
public void tick() {
|
|
||||||
myCoreComm.tick();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy core memory to given memory. This should not be used directly, but
|
|
||||||
* instead via MantisMote.getMemory().
|
|
||||||
*
|
|
||||||
* @param mem
|
|
||||||
* Memory to set
|
|
||||||
*/
|
|
||||||
public void getCoreMemory(SectionMoteMemory mem) {
|
|
||||||
for (int i = 0; i < mem.getNumberOfSections(); i++) {
|
|
||||||
int startAddr = mem.getStartAddrOfSection(i);
|
|
||||||
int size = mem.getSizeOfSection(i);
|
|
||||||
byte[] data = mem.getDataOfSection(i);
|
|
||||||
|
|
||||||
getCoreMemory(startAddr + offsetRelToAbs,
|
|
||||||
size, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy given memory to the Mantis system. This should not be used directly,
|
|
||||||
* but instead via MantisMote.setMemory().
|
|
||||||
*
|
|
||||||
* @param mem
|
|
||||||
* New memory
|
|
||||||
*/
|
|
||||||
public void setCoreMemory(SectionMoteMemory mem) {
|
|
||||||
for (int i = 0; i < mem.getNumberOfSections(); i++) {
|
|
||||||
setCoreMemory(mem.getStartAddrOfSection(i) + offsetRelToAbs, mem
|
|
||||||
.getSizeOfSection(i), mem.getDataOfSection(i));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void getCoreMemory(int start, int length, byte[] data) {
|
|
||||||
myCoreComm.getMemory(start, length, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setCoreMemory(int start, int length, byte[] mem) {
|
|
||||||
myCoreComm.setMemory(start, length, mem);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns all mote interfaces of this mote type
|
|
||||||
*
|
|
||||||
* @return All mote interfaces
|
|
||||||
*/
|
|
||||||
public Vector<Class<? extends MoteInterface>> getMoteInterfaces() {
|
|
||||||
return moteInterfaceClasses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getDescription() {
|
|
||||||
return myDescription;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDescription(String description) {
|
|
||||||
myDescription = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIdentifier() {
|
|
||||||
return myIdentifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIdentifier(String identifier) {
|
|
||||||
myIdentifier = identifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getObjectFilename() {
|
|
||||||
return myObjectFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setObjectFilename(String objectFilename) {
|
|
||||||
myObjectFilename = objectFilename;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JPanel getTypeVisualizer() {
|
|
||||||
JPanel panel = new JPanel();
|
|
||||||
JLabel label = new JLabel();
|
|
||||||
JPanel smallPane;
|
|
||||||
|
|
||||||
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
|
||||||
|
|
||||||
// Identifier
|
|
||||||
smallPane = new JPanel(new BorderLayout());
|
|
||||||
label = new JLabel("Identifier");
|
|
||||||
smallPane.add(BorderLayout.WEST, label);
|
|
||||||
label = new JLabel(myIdentifier);
|
|
||||||
smallPane.add(BorderLayout.EAST, label);
|
|
||||||
panel.add(smallPane);
|
|
||||||
|
|
||||||
// Description
|
|
||||||
smallPane = new JPanel(new BorderLayout());
|
|
||||||
label = new JLabel("Description");
|
|
||||||
smallPane.add(BorderLayout.WEST, label);
|
|
||||||
label = new JLabel(myDescription);
|
|
||||||
smallPane.add(BorderLayout.EAST, label);
|
|
||||||
panel.add(smallPane);
|
|
||||||
|
|
||||||
// Object file
|
|
||||||
smallPane = new JPanel(new BorderLayout());
|
|
||||||
label = new JLabel("Object file");
|
|
||||||
smallPane.add(BorderLayout.WEST, label);
|
|
||||||
label = new JLabel(myObjectFilename);
|
|
||||||
smallPane.add(BorderLayout.EAST, label);
|
|
||||||
panel.add(smallPane);
|
|
||||||
|
|
||||||
// Library class name
|
|
||||||
smallPane = new JPanel(new BorderLayout());
|
|
||||||
label = new JLabel("JNI Class");
|
|
||||||
smallPane.add(BorderLayout.WEST, label);
|
|
||||||
label = new JLabel(libraryClassName);
|
|
||||||
smallPane.add(BorderLayout.EAST, label);
|
|
||||||
panel.add(smallPane);
|
|
||||||
|
|
||||||
panel.add(Box.createRigidArea(new Dimension(0, 5)));
|
|
||||||
return panel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProjectConfig getConfig() {
|
|
||||||
logger.debug("MantisMoteType::getConfig");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Mote generateMote(Simulation simulation) {
|
|
||||||
return new MantisMote(this, mySimulation);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable) {
|
|
||||||
if (!visAvailable) {
|
|
||||||
logger.fatal(">>>>>>> NOT IMPLEMENTED");
|
|
||||||
}
|
|
||||||
return MantisMoteTypeDialog.showDialog(parentContainer, simulation, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Collection<Element> getConfigXML() {
|
|
||||||
Vector<Element> config = new Vector<Element>();
|
|
||||||
|
|
||||||
Element element;
|
|
||||||
|
|
||||||
// Identifier
|
|
||||||
element = new Element("identifier");
|
|
||||||
element.setText(getIdentifier());
|
|
||||||
config.add(element);
|
|
||||||
|
|
||||||
// Description
|
|
||||||
element = new Element("description");
|
|
||||||
element.setText(getDescription());
|
|
||||||
config.add(element);
|
|
||||||
|
|
||||||
// Object file
|
|
||||||
element = new Element("objectfile");
|
|
||||||
element.setText(getObjectFilename());
|
|
||||||
config.add(element);
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean setConfigXML(Simulation simulation,
|
|
||||||
Collection<Element> configXML, boolean visAvailable) {
|
|
||||||
mySimulation = simulation;
|
|
||||||
|
|
||||||
for (Element element : configXML) {
|
|
||||||
String name = element.getName();
|
|
||||||
|
|
||||||
if (name.equals("identifier")) {
|
|
||||||
myIdentifier = element.getText();
|
|
||||||
} else if (name.equals("description")) {
|
|
||||||
myDescription = element.getText();
|
|
||||||
} else if (name.equals("objectfile")) {
|
|
||||||
myObjectFilename = element.getText();
|
|
||||||
} else {
|
|
||||||
logger.fatal("Unrecognized entry in loaded configuration: " + name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean createdOK = configureAndInit(GUI.getTopParentContainer(), simulation, visAvailable);
|
|
||||||
return createdOK;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,831 +0,0 @@
|
||||||
/*
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id: MantisMoteTypeDialog.java,v 1.7 2008/02/12 15:25:42 fros4943 Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
package se.sics.cooja.mantismote;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.awt.event.*;
|
|
||||||
import java.io.*;
|
|
||||||
import java.util.*;
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.event.*;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
|
||||||
import se.sics.cooja.dialogs.MessageList;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A dialog for configuring Mantis mote types and compiling KMantis mote type
|
|
||||||
* libraries.
|
|
||||||
*
|
|
||||||
* The dialog takes a Mantis mote type as argument and pre-selects the values
|
|
||||||
* already set in that mote type before showing the dialog. Any changes made to
|
|
||||||
* the settings are written to the mote type if the compilation is successful
|
|
||||||
* and the user presses OK.
|
|
||||||
*
|
|
||||||
* This dialog uses external tools to scan for sources and compile libraries.
|
|
||||||
*
|
|
||||||
* @author Fredrik Osterlind
|
|
||||||
*/
|
|
||||||
public class MantisMoteTypeDialog extends JDialog {
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
private static Logger logger = Logger.getLogger(MantisMoteTypeDialog.class);
|
|
||||||
|
|
||||||
private MoteTypeEventHandler myEventHandler = new MoteTypeEventHandler();
|
|
||||||
private Thread compilationThread;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Suggested mote type identifier prefix
|
|
||||||
*/
|
|
||||||
public static final String ID_PREFIX = "mtype";
|
|
||||||
|
|
||||||
private final static int LABEL_WIDTH = 170;
|
|
||||||
private final static int LABEL_HEIGHT = 15;
|
|
||||||
|
|
||||||
private MantisMoteType myMoteType = null;
|
|
||||||
|
|
||||||
private JTextField textID, textOutputFiles, textDescription, textMantisBinary;
|
|
||||||
private JButton createButton, compileButton;
|
|
||||||
|
|
||||||
private File objFile = null;
|
|
||||||
private File workingDir = null;
|
|
||||||
private File libFile = null;
|
|
||||||
private File srcFile = null;
|
|
||||||
|
|
||||||
private Vector<Class<? extends MoteInterface>> moteInterfaceClasses = null;
|
|
||||||
|
|
||||||
private boolean settingsOK = false; // Do all settings seem correct?
|
|
||||||
private boolean compilationSucceded = false; // Did compilation succeed?
|
|
||||||
private boolean libraryCreatedOK = false; // Was a library created?
|
|
||||||
|
|
||||||
private Vector<MoteType> allOtherTypes = null; // Used to check for conflicting parameters
|
|
||||||
|
|
||||||
private MantisMoteTypeDialog myDialog;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows a dialog for configuring a Mantis mote type.
|
|
||||||
*
|
|
||||||
* @param parentContainer
|
|
||||||
* Parent container for dialog
|
|
||||||
* @param simulation
|
|
||||||
* Simulation holding (or that will hold) mote type
|
|
||||||
* @param moteTypeToConfigure
|
|
||||||
* Mote type to configure
|
|
||||||
* @return True if mote type configuration succeded and library is ready to be loaded
|
|
||||||
*/
|
|
||||||
public static boolean showDialog(Container parentContainer, Simulation simulation,
|
|
||||||
MantisMoteType moteTypeToConfigure) {
|
|
||||||
|
|
||||||
MantisMoteTypeDialog myDialog = null;
|
|
||||||
if (parentContainer instanceof Window) {
|
|
||||||
myDialog = new MantisMoteTypeDialog((Window) parentContainer);
|
|
||||||
} else if (parentContainer instanceof Dialog) {
|
|
||||||
myDialog = new MantisMoteTypeDialog((Dialog) parentContainer);
|
|
||||||
} else if (parentContainer instanceof Frame) {
|
|
||||||
myDialog = new MantisMoteTypeDialog((Frame) parentContainer);
|
|
||||||
} else {
|
|
||||||
logger.fatal("Unknown parent container type: " + parentContainer);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
myDialog.myMoteType = moteTypeToConfigure;
|
|
||||||
myDialog.allOtherTypes = simulation.getMoteTypes();
|
|
||||||
|
|
||||||
// Set identifier of mote type
|
|
||||||
if (moteTypeToConfigure.getIdentifier() != null) {
|
|
||||||
// Identifier already preset, assuming recompilation of mote type library
|
|
||||||
// Use preset identifier (read-only)
|
|
||||||
myDialog.textID.setText(moteTypeToConfigure.getIdentifier());
|
|
||||||
myDialog.textID.setEditable(false);
|
|
||||||
myDialog.textID.setEnabled(false);
|
|
||||||
|
|
||||||
// Change title to indicate this is a recompilation
|
|
||||||
myDialog.setTitle("Recompile Mote Type");
|
|
||||||
} else {
|
|
||||||
// Suggest new identifier
|
|
||||||
int counter = 0;
|
|
||||||
String testIdentifier = "";
|
|
||||||
boolean identifierOK = false;
|
|
||||||
while (!identifierOK) {
|
|
||||||
counter++;
|
|
||||||
testIdentifier = ID_PREFIX + counter;
|
|
||||||
identifierOK = true;
|
|
||||||
|
|
||||||
// Check if identifier is already used by some other type
|
|
||||||
for (MoteType existingMoteType : myDialog.allOtherTypes) {
|
|
||||||
if (existingMoteType != myDialog.myMoteType
|
|
||||||
&& existingMoteType.getIdentifier().equals(testIdentifier)) {
|
|
||||||
identifierOK = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
myDialog.textID.setText(testIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set preset description of mote type
|
|
||||||
if (moteTypeToConfigure.getDescription() != null) {
|
|
||||||
myDialog.textDescription.setText(moteTypeToConfigure.getDescription());
|
|
||||||
} else {
|
|
||||||
myDialog.textDescription.setText("mantis type, id=" + myDialog.textID.getText());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set preset object file of mote type
|
|
||||||
if (moteTypeToConfigure.getObjectFilename() != null) {
|
|
||||||
myDialog.textMantisBinary.setText(moteTypeToConfigure.getObjectFilename());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load all mote interface classes
|
|
||||||
String[] moteInterfaces = simulation.getGUI().getProjectConfig().getStringArrayValue(MantisMoteType.class, "MOTE_INTERFACES");
|
|
||||||
myDialog.moteInterfaceClasses = new Vector<Class<? extends MoteInterface>>();
|
|
||||||
for (String moteInterface : moteInterfaces) {
|
|
||||||
try {
|
|
||||||
Class<? extends MoteInterface> newMoteInterfaceClass =
|
|
||||||
simulation.getGUI().tryLoadClass(simulation.getGUI(), MoteInterface.class, moteInterface);
|
|
||||||
myDialog.moteInterfaceClasses.add(newMoteInterfaceClass);
|
|
||||||
/*logger.info("Loaded Mantis mote interface: " + newMoteInterfaceClass);*/
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.fatal("Failed to load mote interface, aborting: " + moteInterface + ", " + e.getMessage());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set position and focus of dialog
|
|
||||||
myDialog.pack();
|
|
||||||
myDialog.setLocationRelativeTo(parentContainer);
|
|
||||||
myDialog.textDescription.requestFocus();
|
|
||||||
myDialog.textDescription.select(0, myDialog.textDescription.getText().length());
|
|
||||||
myDialog.pathsWereUpdated();
|
|
||||||
myDialog.setVisible(true);
|
|
||||||
|
|
||||||
if (myDialog.myMoteType != null) {
|
|
||||||
// Library was compiled and loaded
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private MantisMoteTypeDialog(Dialog dialog) {
|
|
||||||
super(dialog, "Configure Mantis Mote Type", ModalityType.APPLICATION_MODAL);
|
|
||||||
setupDialog();
|
|
||||||
}
|
|
||||||
private MantisMoteTypeDialog(Window window) {
|
|
||||||
super(window, "Configure Mantis Mote Type", ModalityType.APPLICATION_MODAL);
|
|
||||||
setupDialog();
|
|
||||||
}
|
|
||||||
private MantisMoteTypeDialog(Frame frame) {
|
|
||||||
super(frame, "Configure Mantis Mote Type", ModalityType.APPLICATION_MODAL);
|
|
||||||
setupDialog();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupDialog() {
|
|
||||||
myDialog = this;
|
|
||||||
|
|
||||||
JLabel label;
|
|
||||||
JPanel mainPane = new JPanel();
|
|
||||||
mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
|
|
||||||
JPanel smallPane;
|
|
||||||
JTextField textField;
|
|
||||||
JButton button;
|
|
||||||
|
|
||||||
// BOTTOM BUTTON PART
|
|
||||||
JPanel buttonPane = new JPanel();
|
|
||||||
buttonPane.setLayout(new BoxLayout(buttonPane, BoxLayout.X_AXIS));
|
|
||||||
buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
|
|
||||||
|
|
||||||
button = new JButton("Compile");
|
|
||||||
button.setActionCommand("compile");
|
|
||||||
button.addActionListener(myEventHandler);
|
|
||||||
compileButton = button;
|
|
||||||
this.getRootPane().setDefaultButton(button);
|
|
||||||
buttonPane.add(button);
|
|
||||||
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
|
|
||||||
|
|
||||||
buttonPane.add(Box.createHorizontalGlue());
|
|
||||||
|
|
||||||
button = new JButton("Clean");
|
|
||||||
button.setActionCommand("clean");
|
|
||||||
button.addActionListener(myEventHandler);
|
|
||||||
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
|
|
||||||
buttonPane.add(button);
|
|
||||||
|
|
||||||
button = new JButton("Cancel");
|
|
||||||
button.setActionCommand("cancel");
|
|
||||||
button.addActionListener(myEventHandler);
|
|
||||||
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
|
|
||||||
buttonPane.add(button);
|
|
||||||
|
|
||||||
button = new JButton("Create");
|
|
||||||
button.setEnabled(libraryCreatedOK);
|
|
||||||
button.setActionCommand("create");
|
|
||||||
button.addActionListener(myEventHandler);
|
|
||||||
createButton = button;
|
|
||||||
buttonPane.add(Box.createRigidArea(new Dimension(10, 0)));
|
|
||||||
buttonPane.add(button);
|
|
||||||
|
|
||||||
// MAIN PART
|
|
||||||
|
|
||||||
// Identifier
|
|
||||||
smallPane = new JPanel();
|
|
||||||
smallPane.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
||||||
smallPane.setLayout(new BoxLayout(smallPane, BoxLayout.X_AXIS));
|
|
||||||
label = new JLabel("Identifier");
|
|
||||||
label.setPreferredSize(new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
|
|
||||||
|
|
||||||
textField = new JTextField();
|
|
||||||
|
|
||||||
textField.setText("");
|
|
||||||
|
|
||||||
textField.getDocument().addDocumentListener(myEventHandler);
|
|
||||||
textID = textField;
|
|
||||||
label.setLabelFor(textField);
|
|
||||||
smallPane.add(label);
|
|
||||||
smallPane.add(Box.createHorizontalStrut(10));
|
|
||||||
smallPane.add(Box.createHorizontalGlue());
|
|
||||||
smallPane.add(textField);
|
|
||||||
|
|
||||||
mainPane.add(smallPane);
|
|
||||||
|
|
||||||
mainPane.add(Box.createRigidArea(new Dimension(0, 5)));
|
|
||||||
|
|
||||||
// Output filenames
|
|
||||||
smallPane = new JPanel();
|
|
||||||
smallPane.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
||||||
smallPane.setLayout(new BoxLayout(smallPane, BoxLayout.X_AXIS));
|
|
||||||
label = new JLabel("Output files");
|
|
||||||
label.setPreferredSize(new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
|
|
||||||
|
|
||||||
textField = new JTextField();
|
|
||||||
textField.setText("");
|
|
||||||
textField.setEnabled(false);
|
|
||||||
textOutputFiles = textField;
|
|
||||||
label.setLabelFor(textField);
|
|
||||||
smallPane.add(label);
|
|
||||||
smallPane.add(Box.createHorizontalStrut(10));
|
|
||||||
smallPane.add(Box.createHorizontalGlue());
|
|
||||||
smallPane.add(textField);
|
|
||||||
|
|
||||||
mainPane.add(smallPane);
|
|
||||||
|
|
||||||
mainPane.add(Box.createRigidArea(new Dimension(0, 5)));
|
|
||||||
|
|
||||||
// Description
|
|
||||||
smallPane = new JPanel();
|
|
||||||
smallPane.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
||||||
smallPane.setLayout(new BoxLayout(smallPane, BoxLayout.X_AXIS));
|
|
||||||
label = new JLabel("Description");
|
|
||||||
label.setPreferredSize(new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
|
|
||||||
|
|
||||||
textField = new JTextField();
|
|
||||||
textField.setBackground(Color.GREEN);
|
|
||||||
textField.setText("");
|
|
||||||
textField.getDocument().addDocumentListener(myEventHandler);
|
|
||||||
textDescription = textField;
|
|
||||||
label.setLabelFor(textField);
|
|
||||||
smallPane.add(label);
|
|
||||||
smallPane.add(Box.createHorizontalStrut(10));
|
|
||||||
smallPane.add(Box.createHorizontalGlue());
|
|
||||||
smallPane.add(textField);
|
|
||||||
|
|
||||||
mainPane.add(smallPane);
|
|
||||||
|
|
||||||
mainPane.add(Box.createRigidArea(new Dimension(0, 5)));
|
|
||||||
|
|
||||||
// Mantis binary
|
|
||||||
smallPane = new JPanel();
|
|
||||||
smallPane.setAlignmentX(Component.LEFT_ALIGNMENT);
|
|
||||||
smallPane.setLayout(new BoxLayout(smallPane, BoxLayout.X_AXIS));
|
|
||||||
label = new JLabel("Mantis x86 object");
|
|
||||||
label.setPreferredSize(new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
|
|
||||||
|
|
||||||
textField = new JTextField();
|
|
||||||
textField.setText("");
|
|
||||||
textField.getDocument().addDocumentListener(myEventHandler);
|
|
||||||
textMantisBinary = textField;
|
|
||||||
label.setLabelFor(textField);
|
|
||||||
|
|
||||||
button = new JButton("Browse");
|
|
||||||
button.setActionCommand("browsemantis");
|
|
||||||
button.addActionListener(myEventHandler);
|
|
||||||
|
|
||||||
smallPane.add(label);
|
|
||||||
smallPane.add(Box.createHorizontalStrut(10));
|
|
||||||
smallPane.add(Box.createHorizontalGlue());
|
|
||||||
smallPane.add(textField);
|
|
||||||
smallPane.add(button);
|
|
||||||
mainPane.add(smallPane);
|
|
||||||
|
|
||||||
mainPane.add(Box.createRigidArea(new Dimension(0, 5)));
|
|
||||||
mainPane.add(Box.createVerticalGlue());
|
|
||||||
|
|
||||||
// Add everything!
|
|
||||||
mainPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
|
||||||
|
|
||||||
Container contentPane = getContentPane();
|
|
||||||
contentPane.add(mainPane, BorderLayout.NORTH);
|
|
||||||
contentPane.add(buttonPane, BorderLayout.SOUTH);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Tries to compile library using current settings.
|
|
||||||
*/
|
|
||||||
public void doCompileCurrentSettings() {
|
|
||||||
libraryCreatedOK = false;
|
|
||||||
|
|
||||||
JPanel progressPanel = new JPanel(new BorderLayout());
|
|
||||||
final JDialog progressDialog = new JDialog(myDialog, (String) null);
|
|
||||||
JProgressBar progressBar;
|
|
||||||
JButton button;
|
|
||||||
final MessageList taskOutput;
|
|
||||||
progressDialog.setLocationRelativeTo(myDialog);
|
|
||||||
|
|
||||||
progressBar = new JProgressBar(0, 100);
|
|
||||||
progressBar.setValue(0);
|
|
||||||
progressBar.setStringPainted(true);
|
|
||||||
progressBar.setIndeterminate(true);
|
|
||||||
|
|
||||||
taskOutput = new MessageList();
|
|
||||||
|
|
||||||
button = new JButton("Close/Abort");
|
|
||||||
button.addActionListener(new ActionListener() {
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
if (compilationThread != null && compilationThread.isAlive()) {
|
|
||||||
compilationThread.interrupt();
|
|
||||||
}
|
|
||||||
if (progressDialog != null && progressDialog.isDisplayable()) {
|
|
||||||
progressDialog.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
progressPanel.add(BorderLayout.CENTER, new JScrollPane(taskOutput));
|
|
||||||
progressPanel.add(BorderLayout.NORTH, progressBar);
|
|
||||||
progressPanel.add(BorderLayout.SOUTH, button);
|
|
||||||
progressPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
|
||||||
progressPanel.setVisible(true);
|
|
||||||
|
|
||||||
progressDialog.getContentPane().add(progressPanel);
|
|
||||||
progressDialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
|
|
||||||
progressDialog.pack();
|
|
||||||
|
|
||||||
progressDialog.getRootPane().setDefaultButton(button);
|
|
||||||
progressDialog.setVisible(true);
|
|
||||||
|
|
||||||
// Generate main mantis source file
|
|
||||||
try {
|
|
||||||
// Remove old file is existing
|
|
||||||
if (srcFile.exists()) {
|
|
||||||
srcFile.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (srcFile.exists()) {
|
|
||||||
throw new Exception("could not remove old source file");
|
|
||||||
}
|
|
||||||
|
|
||||||
generateSourceFile(srcFile);
|
|
||||||
|
|
||||||
if (!srcFile.exists()) {
|
|
||||||
throw new Exception("source file not created");
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
libraryCreatedOK = false;
|
|
||||||
progressBar.setBackground(Color.ORANGE);
|
|
||||||
if (e.getMessage() != null) {
|
|
||||||
progressBar.setString("source file generation failed: " + e.getMessage());
|
|
||||||
} else {
|
|
||||||
progressBar.setString("source file generation failed");
|
|
||||||
}
|
|
||||||
|
|
||||||
progressBar.setIndeterminate(false);
|
|
||||||
progressBar.setValue(0);
|
|
||||||
createButton.setEnabled(libraryCreatedOK);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test compile shared library
|
|
||||||
progressBar.setString("..compiling..");
|
|
||||||
|
|
||||||
if (libFile.exists()) {
|
|
||||||
libFile.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
compilationThread = new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
compilationSucceded =
|
|
||||||
MantisMoteTypeDialog.compileLibrary(
|
|
||||||
libFile,
|
|
||||||
objFile,
|
|
||||||
srcFile,
|
|
||||||
workingDir,
|
|
||||||
taskOutput.getInputStream(MessageList.NORMAL),
|
|
||||||
taskOutput.getInputStream(MessageList.ERROR));
|
|
||||||
}
|
|
||||||
}, "compilation thread");
|
|
||||||
compilationThread.start();
|
|
||||||
|
|
||||||
while (compilationThread.isAlive()) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// NOP
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!compilationSucceded) {
|
|
||||||
if (libFile.exists()) {
|
|
||||||
libFile.delete();
|
|
||||||
}
|
|
||||||
libraryCreatedOK = false;
|
|
||||||
} else {
|
|
||||||
libraryCreatedOK = true;
|
|
||||||
if (!libFile.exists()) {
|
|
||||||
libraryCreatedOK = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (libraryCreatedOK) {
|
|
||||||
progressBar.setBackground(Color.GREEN);
|
|
||||||
progressBar.setString("compilation succeded");
|
|
||||||
button.grabFocus();
|
|
||||||
myDialog.getRootPane().setDefaultButton(createButton);
|
|
||||||
} else {
|
|
||||||
progressBar.setBackground(Color.ORANGE);
|
|
||||||
progressBar.setString("compilation failed");
|
|
||||||
myDialog.getRootPane().setDefaultButton(compileButton);
|
|
||||||
}
|
|
||||||
progressBar.setIndeterminate(false);
|
|
||||||
progressBar.setValue(0);
|
|
||||||
createButton.setEnabled(libraryCreatedOK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates new source file by reading default source template and replacing
|
|
||||||
* certain field in order to be loadable from given Java class.
|
|
||||||
*
|
|
||||||
* @param outputFile Source file to create
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public static void generateSourceFile(File outputFile)
|
|
||||||
throws Exception {
|
|
||||||
|
|
||||||
// CHECK JNI CLASS AVAILABILITY
|
|
||||||
String libString = CoreComm.getAvailableClassName();
|
|
||||||
if (libString == null) {
|
|
||||||
logger.fatal("No more libraries can be loaded!");
|
|
||||||
throw new Exception("Maximum number of mote types already exist");
|
|
||||||
}
|
|
||||||
|
|
||||||
// GENERATE NEW FILE
|
|
||||||
BufferedWriter destFile = null;
|
|
||||||
BufferedReader sourceFile = null;
|
|
||||||
try {
|
|
||||||
Reader reader;
|
|
||||||
String mainTemplate = GUI
|
|
||||||
.getExternalToolsSetting("MANTIS_MAIN_TEMPLATE_FILENAME");
|
|
||||||
if ((new File(mainTemplate)).exists()) {
|
|
||||||
reader = new FileReader(mainTemplate);
|
|
||||||
} else {
|
|
||||||
InputStream input = MantisMoteTypeDialog.class
|
|
||||||
.getResourceAsStream('/' + mainTemplate);
|
|
||||||
if (input == null) {
|
|
||||||
throw new FileNotFoundException(mainTemplate + " not found");
|
|
||||||
}
|
|
||||||
reader = new InputStreamReader(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceFile = new BufferedReader(reader);
|
|
||||||
|
|
||||||
destFile = new BufferedWriter(new OutputStreamWriter(
|
|
||||||
new FileOutputStream(outputFile)));
|
|
||||||
|
|
||||||
// Replace fields in template
|
|
||||||
String line;
|
|
||||||
while ((line = sourceFile.readLine()) != null) {
|
|
||||||
line = line.replaceFirst("\\[CLASS_NAME\\]", libString);
|
|
||||||
destFile.write(line + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
destFile.close();
|
|
||||||
sourceFile.close();
|
|
||||||
} catch (Exception e) {
|
|
||||||
try {
|
|
||||||
if (destFile != null) {
|
|
||||||
destFile.close();
|
|
||||||
}
|
|
||||||
if (sourceFile != null) {
|
|
||||||
sourceFile.close();
|
|
||||||
}
|
|
||||||
} catch (Exception e2) {
|
|
||||||
}
|
|
||||||
|
|
||||||
// Forward exception
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Compiles a mote type shared library using the standard Mantis makefile.
|
|
||||||
*
|
|
||||||
* @param libFile Library file to create
|
|
||||||
* @param binFile Binary file to link against
|
|
||||||
* @param sourceFile Source file to compile
|
|
||||||
* @param workingDir Working directory
|
|
||||||
* @param outputStream
|
|
||||||
* Output stream from compilation (optional)
|
|
||||||
* @param errorStream
|
|
||||||
* Error stream from compilation (optional)
|
|
||||||
* @return True if compilation succeeded, false otherwise
|
|
||||||
*/
|
|
||||||
public static boolean compileLibrary(File libFile, File binFile, File sourceFile, File workingDir,
|
|
||||||
final PrintStream outputStream, final PrintStream errorStream) {
|
|
||||||
|
|
||||||
// Check needed files
|
|
||||||
if (!workingDir.exists()) {
|
|
||||||
if (errorStream != null) {
|
|
||||||
errorStream.println("Bad paths");
|
|
||||||
}
|
|
||||||
logger.fatal("Working directory does not exist");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!workingDir.isDirectory()) {
|
|
||||||
if (errorStream != null) {
|
|
||||||
errorStream.println("Bad paths");
|
|
||||||
}
|
|
||||||
logger.fatal("Working directory is not a directory");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (libFile.exists()) {
|
|
||||||
if (errorStream != null) {
|
|
||||||
errorStream.println("Bad output filenames");
|
|
||||||
}
|
|
||||||
logger.fatal("Library already exists");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sourceFile.exists()) {
|
|
||||||
if (errorStream != null) {
|
|
||||||
errorStream.println("Bad dependency files");
|
|
||||||
}
|
|
||||||
logger.fatal("Source file not found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!binFile.exists()) {
|
|
||||||
if (errorStream != null) {
|
|
||||||
errorStream.println("Bad dependency files");
|
|
||||||
}
|
|
||||||
logger.fatal("Link object file not found");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (CoreComm.hasLibraryFileBeenLoaded(libFile)) {
|
|
||||||
if (errorStream != null) {
|
|
||||||
errorStream.println("Bad output filenames");
|
|
||||||
}
|
|
||||||
logger.fatal("A library has already been loaded with the same name before");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Call make file
|
|
||||||
String[] cmd = new String[]{
|
|
||||||
GUI.getExternalToolsSetting("PATH_MAKE"),
|
|
||||||
libFile.getName()};
|
|
||||||
|
|
||||||
String[] env = new String[]{
|
|
||||||
"COOJA_LINKFILE=" + binFile.getName(),
|
|
||||||
"COOJA_SOURCE=" + sourceFile.getName(),
|
|
||||||
"PATH=" + System.getenv("PATH")};
|
|
||||||
|
|
||||||
Process p = Runtime.getRuntime().exec(cmd, env, workingDir);
|
|
||||||
|
|
||||||
final BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
|
|
||||||
final BufferedReader err = new BufferedReader(new InputStreamReader(p.getErrorStream()));
|
|
||||||
|
|
||||||
Thread readInput = new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
String readLine;
|
|
||||||
try {
|
|
||||||
while ((readLine = input.readLine()) != null) {
|
|
||||||
if (outputStream != null && readLine != null) {
|
|
||||||
outputStream.println(readLine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.warn("Error while reading from process");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "read input stream thread");
|
|
||||||
|
|
||||||
Thread readError = new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
String readLine;
|
|
||||||
try {
|
|
||||||
while ((readLine = err.readLine()) != null) {
|
|
||||||
if (errorStream != null && readLine != null) {
|
|
||||||
errorStream.println(readLine);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.warn("Error while reading from process");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "read input stream thread");
|
|
||||||
|
|
||||||
readInput.start();
|
|
||||||
readError.start();
|
|
||||||
|
|
||||||
while (readInput.isAlive() || readError.isAlive()) {
|
|
||||||
Thread.sleep(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
input.close();
|
|
||||||
err.close();
|
|
||||||
|
|
||||||
p.waitFor();
|
|
||||||
if (p.exitValue() != 0) {
|
|
||||||
logger.fatal("Make file returned error: " + p.exitValue());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
logger.fatal("Error while compiling library: " + e);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void pathsWereUpdated() {
|
|
||||||
updateVisualFields();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateVisualFields() {
|
|
||||||
settingsOK = true;
|
|
||||||
|
|
||||||
// Check for non-unique identifier
|
|
||||||
textID.setBackground(Color.WHITE);
|
|
||||||
textID.setToolTipText(null);
|
|
||||||
|
|
||||||
for (MoteType otherType : allOtherTypes) {
|
|
||||||
if (otherType != myMoteType
|
|
||||||
&& otherType.getIdentifier().equalsIgnoreCase(textID.getText())) {
|
|
||||||
textID.setBackground(Color.RED);
|
|
||||||
textID.setToolTipText("Conflicting name - must be unique");
|
|
||||||
settingsOK = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check for non-unique description
|
|
||||||
textDescription.setBackground(Color.WHITE);
|
|
||||||
textDescription.setToolTipText(null);
|
|
||||||
|
|
||||||
for (MoteType otherType : allOtherTypes) {
|
|
||||||
if (otherType != myMoteType
|
|
||||||
&& otherType.getDescription().equals(textDescription.getText())) {
|
|
||||||
textDescription.setBackground(Color.RED);
|
|
||||||
textDescription.setToolTipText("Conflicting name - must be unique");
|
|
||||||
settingsOK = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check that binary exists
|
|
||||||
textMantisBinary.setBackground(Color.WHITE);
|
|
||||||
textMantisBinary.setToolTipText(null);
|
|
||||||
|
|
||||||
objFile = new File(textMantisBinary.getText());
|
|
||||||
workingDir = objFile.getParentFile();
|
|
||||||
libFile = new File(workingDir, textID.getText() + ".library");
|
|
||||||
srcFile = new File(workingDir, textID.getText() + ".c");
|
|
||||||
// TODO Check that file is correct type (.o or something)
|
|
||||||
if (objFile == null || !objFile.exists()) {
|
|
||||||
textMantisBinary.setBackground(Color.RED);
|
|
||||||
textMantisBinary.setToolTipText("Incorrect object file");
|
|
||||||
objFile = null;
|
|
||||||
libFile = null;
|
|
||||||
srcFile = null;
|
|
||||||
workingDir = null;
|
|
||||||
settingsOK = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update output text field
|
|
||||||
if (settingsOK) {
|
|
||||||
textOutputFiles.setText(libFile.getName() + ", " + srcFile.getName() + ", " + textID.getText() + ".o");
|
|
||||||
} else {
|
|
||||||
textOutputFiles.setText("");
|
|
||||||
}
|
|
||||||
|
|
||||||
createButton.setEnabled(libraryCreatedOK = false);
|
|
||||||
compileButton.setEnabled(settingsOK);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private class MoteTypeEventHandler
|
|
||||||
implements
|
|
||||||
ActionListener,
|
|
||||||
DocumentListener {
|
|
||||||
public void insertUpdate(DocumentEvent e) {
|
|
||||||
if (myDialog.isVisible()) {
|
|
||||||
javax.swing.SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
pathsWereUpdated();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void removeUpdate(DocumentEvent e) {
|
|
||||||
if (myDialog.isVisible()) {
|
|
||||||
javax.swing.SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
pathsWereUpdated();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void changedUpdate(DocumentEvent e) {
|
|
||||||
if (myDialog.isVisible()) {
|
|
||||||
javax.swing.SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
pathsWereUpdated();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public void actionPerformed(ActionEvent e) {
|
|
||||||
if (e.getActionCommand().equals("cancel")) {
|
|
||||||
// Cancel creation of mote type
|
|
||||||
myMoteType = null;
|
|
||||||
dispose();
|
|
||||||
} else if (e.getActionCommand().equals("clean")) {
|
|
||||||
// Delete any created intermediate files
|
|
||||||
// TODO Not implemented
|
|
||||||
logger.fatal("Clean functionality not implemented");
|
|
||||||
} else if (e.getActionCommand().equals("create")) {
|
|
||||||
// Create mote type and set related fields
|
|
||||||
boolean ret = myMoteType.doInit(libFile, objFile, moteInterfaceClasses);
|
|
||||||
myMoteType.setDescription(textDescription.getText());
|
|
||||||
myMoteType.setIdentifier(textID.getText());
|
|
||||||
if (ret) {
|
|
||||||
dispose();
|
|
||||||
} else {
|
|
||||||
logger.fatal("Mote type creation failed.");
|
|
||||||
}
|
|
||||||
} else if (e.getActionCommand().equals("compile")) {
|
|
||||||
compileButton.requestFocus();
|
|
||||||
Thread testSettingsThread = new Thread(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
doCompileCurrentSettings();
|
|
||||||
}
|
|
||||||
}, "test settings thread");
|
|
||||||
testSettingsThread.start();
|
|
||||||
} else if (e.getActionCommand().equals("browsemantis")) {
|
|
||||||
JFileChooser fc = new JFileChooser();
|
|
||||||
fc.setCurrentDirectory(new java.io.File("."));
|
|
||||||
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
|
|
||||||
fc.setDialogTitle("Mantis binary to link against");
|
|
||||||
|
|
||||||
if (fc.showOpenDialog(myDialog) == JFileChooser.APPROVE_OPTION) {
|
|
||||||
textMantisBinary.setText(fc.getSelectedFile().getPath());
|
|
||||||
}
|
|
||||||
createButton.setEnabled(libraryCreatedOK = false);
|
|
||||||
pathsWereUpdated();
|
|
||||||
} else {
|
|
||||||
logger.warn("Unhandled action: " + e.getActionCommand());
|
|
||||||
}
|
|
||||||
|
|
||||||
createButton.setEnabled(libraryCreatedOK = false);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in a new issue