osd-contiki/tools/chakana/cooja_plugin/java/se/sics/chakana/XMLCommandHandler.java

1159 lines
40 KiB
Java

/*
* Copyright (c) 2007, 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: XMLCommandHandler.java,v 1.1 2007/08/21 14:39:58 fros4943 Exp $
*/
package se.sics.chakana;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Collection;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import org.apache.log4j.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import se.sics.chakana.EventpointEvaluator.EventpointException;
import se.sics.chakana.eventpoints.*;
import se.sics.cooja.AddressMemory;
import se.sics.cooja.CoreComm;
import se.sics.cooja.GUI;
import se.sics.cooja.Mote;
import se.sics.cooja.MoteMemory;
import se.sics.cooja.RadioMedium;
import se.sics.cooja.Simulation;
import se.sics.cooja.Mote.State;
import se.sics.cooja.MoteType.MoteTypeCreationException;
import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.plugins.VisState;
import se.sics.cooja.plugins.Visualizer2D;
import se.sics.cooja.radiomediums.UDGM;
/**
* Handles incoming XML commands.
* Each command handling call blocks during handling and returns a reply to the client.
*
* A command must always be of the form:
* <command>...</command>
*
* @author Fredrik Osterlind
*/
public class XMLCommandHandler {
public static final boolean DEBUG_OUTPUT = true;
private static Logger logger = Logger.getLogger(XMLCommandHandler.class);
public static final String XML_OK = "<ok/>";
public static final String XML_OK_START = "<ok>";
public static final String XML_OK_END = "</ok>";
public static final String XML_INFO_START = "<info>";
public static final String XML_INFO_END = "</info>";
public static final String XML_ERROR_START = "<error>";
public static final String XML_ERROR_END = "</error>";
public static final String XML_COMMAND_NAME = "command";
public static final String XML_COMMAND_END = "</command>";
public static final String XML_EVENTPOINT_START = "<eventpoint>";
public static final String XML_EVENTPOINT_END = "</eventpoint>";
public static final String XML_ID_NAME = "id";
public static final String XML_TYPE_NAME = "type";
public static final String XML_MOTE_NAME = "mote";
public static final String XML_VARIABLE_NAME = "variable";
public static final String XML_MOTECOUNT_NAME = "motecount";
public static final String XML_VALUE_NAME = "value";
public static final String XML_TIME_NAME = "time";
public static final String XML_SIZE_NAME = "size";
public static final String XML_ADDRESS_NAME = "address";
public static final String XML_VISIBLE_NAME = "visible";
public static final String XML_TRIGGERON_NAME = "triggeron";
public static final String XML_WATCHPOINT_INT = "int";
public static final String XML_WATCHPOINT_VARIABLE = "variable";
public static final String XML_WATCHPOINT_ADDRESS = "address";
public static final String XML_TIMEPOINT_SIMULATION = "time";
public static final String XML_TIMEPOINT_REAL = "realtime";
public static final String XML_EVENTPOINT_RADIOMEDIUM = "radiomedium";
private GUI myGUI;
private EventpointEvaluator myEvaluator;
private ChakanaPlugin myParent;
public enum Command {
CREATE_SIM,
CONF_SIM,
CONF_PLUGINS,
CONTROL_SIM,
SET_GUI,
ADD_EVENTPOINT,
READ_MEMORY,
WRITE_MEMORY,
CLEAR_EVENTPOINTS,
DELETE_EVENTPOINT,
KILL_NODES,
GET_INFO,
CUSTOM_COMMAND,
EXIT_COOJA;
}
public enum ControlSimulationCommand {
RESUME;
}
/**
* TODO Document
*
* @param gui
* @param parent
* @param evaluator
*/
public XMLCommandHandler(GUI gui, ChakanaPlugin parent, EventpointEvaluator evaluator) {
myGUI = gui;
myEvaluator = evaluator;
myParent = parent;
}
/**
* @param command
* @return
*/
public boolean containsEntireCommand(String command) {
return command.contains(XMLCommandHandler.XML_COMMAND_END); // TODO Ugly trick
}
/**
* Handle given command (XML format).
* Method blocks until given command has been handled.
*
* @param command
* Command to handle
* @return Reply to client in XML format
*/
public String handleCommand(String command) {
try {
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new StringReader(command));
Element root = doc.getRootElement();
if (!root.getName().equals(XML_COMMAND_NAME)) {
return createErrorMessage("Malformed command: " + root.getName());
}
String cmdTypeString = root.getAttributeValue("value");
Command cmdType;
try {
cmdType = Command.valueOf(cmdTypeString);
} catch (IllegalArgumentException e) {
return createErrorMessage("Unknown command: " + cmdTypeString);
}
Collection<Element> cmdInfo = root.getChildren();
logger.debug("Command type: " + cmdType);
switch (cmdType) {
case CREATE_SIM:
return createSimulation(cmdInfo);
case CONF_SIM:
return configureSimulation(cmdInfo);
case CONF_PLUGINS:
return configurePlugins(cmdInfo);
case CONTROL_SIM:
return controlSimulation(cmdInfo);
case ADD_EVENTPOINT:
return addEventpoint(cmdInfo);
case SET_GUI:
return configureGUI(cmdInfo);
case READ_MEMORY:
return readMemory(cmdInfo);
case WRITE_MEMORY:
return writeMemory(cmdInfo);
case CLEAR_EVENTPOINTS:
return clearEventpoints();
case DELETE_EVENTPOINT:
return deleteEventpoint(cmdInfo);
case KILL_NODES:
return killNodes(cmdInfo);
case GET_INFO:
return getInfo(cmdInfo);
case CUSTOM_COMMAND:
return handleCustomCommand(cmdInfo);
case EXIT_COOJA:
return shutdownCOOJA(cmdInfo);
default:
return createErrorMessage("Unknown command: " + cmdType);
}
} catch (JDOMException e) {
logger.fatal("Command parsing exception: " + e);
return createErrorMessage("Invalid command syntax: " + e.getMessage());
} catch (IOException e) {
logger.fatal("Command parsing exception: " + e);
return createErrorMessage("Invalid command syntax: " + e.getMessage());
}
}
/**
* Handle create new simulation command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String createSimulation(Collection<Element> arguments) {
Simulation simulation = new Simulation(myGUI);
simulation.setTitle("[chakana - no title]");
simulation.setDelayTime(0);
simulation.setSimulationTime(0);
simulation.setTickTime(1);
try {
RadioMedium radioMedium = RadioMedium.generateRadioMedium(UDGM.class,
simulation);
simulation.setRadioMedium(radioMedium);
} catch (Exception e) {
return createErrorMessage("Create simulation: Could not create radio medium: " + e.getMessage());
}
// Let simulation parse command arguments
myGUI.setSimulation(simulation);
try {
boolean success = simulation.setConfigXML(arguments, false);
} catch (Exception e) {
logger.fatal("Error when configuring simulation: " + e);
if (DEBUG_OUTPUT) {
if (e instanceof MoteTypeCreationException) {
MessageList compilationOutput = ((MoteTypeCreationException) e).getCompilationOutput();
if (compilationOutput != null) {
logger.info("Compilation output:");
for(int i = 0; i < compilationOutput.getModel().getSize(); i++) {
logger.info(compilationOutput.getModel().getElementAt(i));
}
}
StackTraceElement[] stackTrace = e.getStackTrace();
if (stackTrace != null) {
logger.info("Stack trace:");
for(StackTraceElement element: stackTrace) {
logger.info(element);
}
}
GUI.showErrorDialog(new JFrame(""), "Set DEBUG_OUTPUT to false to disable this frame", e, false); // XXX Graphical component
}
}
return createErrorMessage("Create simulation: Could not configure simulation: " + e.getMessage());
}
return XML_OK;
}
/**
* Handle configure simulation command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String configureSimulation(Collection<Element> arguments) {
Simulation simulation = myGUI.getSimulation();
// Let simulation parse command arguments
try {
simulation.setConfigXML(arguments, false);
} catch (Exception e) {
logger.fatal("Error when configuring simulation: " + e);
e.printStackTrace();
return createErrorMessage("Could not configure simulation: " + e.getMessage());
}
return XML_OK;
}
/**
* Handle configure plugins command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String configurePlugins(Collection<Element> arguments) {
Simulation simulation = myGUI.getSimulation();
// Let GUI parse command arguments
try {
myGUI.setPluginsConfigXML(arguments, simulation, false);
} catch (Exception e) {
logger.fatal("Error when configuring plugins: " + e);
return createErrorMessage("Could not configure plugins: " + e.getMessage());
}
return XML_OK;
}
/**
* Handle control simulation command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String controlSimulation(Collection<Element> arguments) {
String reply = "";
for (Element element : arguments) {
ControlSimulationCommand cmdType;
try {
cmdType = ControlSimulationCommand.valueOf(element.getName());
} catch (IllegalArgumentException e) {
return createErrorMessage("Unknown simulation control command: " + element.getName());
}
switch (cmdType) {
case RESUME:
// TODO Check performance degradation using try-blocks
try {
myEvaluator.resumeSimulation();
reply += createEventpointMessage(myEvaluator);
} catch (EventpointException e) {
return createErrorMessage("Exception during simulation: " + e);
}
break;
default:
return createErrorMessage("Unknown simulation control command");
}
}
return reply;
}
/**
* Handle exit COOJA command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String shutdownCOOJA(Collection<Element> arguments) {
myParent.performCOOJAShutdown();
logger.info("Shutdown requested");
return XML_OK;
}
/**
* Fetch mote variable value as specified by arguments.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String readMemory(Collection<Element> arguments) {
Simulation simulation = myGUI.getSimulation();
String type = null;
String mote = null;
String variable = null;
String size = null;
String address = null;
for (Element element : arguments) {
if (element.getName().equals(XML_TYPE_NAME)) {
type = element.getText();
} else if (element.getName().equals(XML_MOTE_NAME)) {
mote = element.getText();
} else if (element.getName().equals(XML_VARIABLE_NAME)) {
variable = element.getText();
} else if (element.getName().equals(XML_SIZE_NAME)) {
size = element.getText();
} else if (element.getName().equals(XML_ADDRESS_NAME)) {
address = element.getText();
} else {
return createErrorMessage("Unknown read memory parameter: " + element.getName());
}
}
if (type == null)
return createErrorMessage("No read memory type specified");
if (mote == null)
return createErrorMessage("No mote specified");
if (mote == null)
return createErrorMessage("No mote ID specified");
int moteNr = Integer.parseInt(mote);
if (moteNr < 0 || simulation.getMotesCount() <= moteNr) {
return createErrorMessage("Bad mote ID specified: " + moteNr);
}
MoteMemory memory = simulation.getMote(moteNr).getMemory();
// Read integer variable
if (type.equals("int")) {
if (variable == null)
return createErrorMessage("No variable name specified");
if (variable.contains(" "))
return createErrorMessage("Variable name must not contain spaces: " + variable);
if (!(memory instanceof AddressMemory))
return createErrorMessage("Can't read mote memory variables (not address memory)");
if (!((AddressMemory) memory).variableExists(variable)) {
return createErrorMessage("Variable does not exist: " + variable);
}
int val = ((AddressMemory) memory).getIntValueOf(variable);
return XML_OK_START + val + XML_OK_END;
} else if (type.equals("variable")) {
if (variable == null)
return createErrorMessage("No variable name specified");
if (variable.contains(" "))
return createErrorMessage("Variable name must not contain spaces: " + variable);
if (!(memory instanceof AddressMemory))
return createErrorMessage("Can't read mote memory variables (not address memory)");
if (!((AddressMemory) memory).variableExists(variable)) {
return createErrorMessage("Variable does not exist: " + variable);
}
if (size == null)
return createErrorMessage("No size specified");
int sizeParsed = Integer.parseInt(size);
if (sizeParsed < 0) {
return createErrorMessage("Bad size specified: " + sizeParsed);
}
byte[] val = ((AddressMemory) memory).getByteArray(variable, sizeParsed);
String ret = "";
for (byte b: val)
ret += (int) (0xff&b) + " ";
ret = ret.trim();
return XML_OK_START + ret + XML_OK_END;
} else if (type.equals("address")) {
if (size == null)
return createErrorMessage("No size specified");
int sizeParsed = Integer.parseInt(size);
if (sizeParsed < 0) {
return createErrorMessage("Bad size specified: " + sizeParsed);
}
int addressParsed = Integer.parseInt(address);
if (addressParsed < 0) {
return createErrorMessage("Bad start address specified: " + addressParsed);
}
byte[] val = memory.getMemorySegment(addressParsed, sizeParsed);
String ret = "";
for (byte b: val)
ret += (int) (0xff&b) + " ";
ret = ret.trim();
return XML_OK_START + ret + XML_OK_END;
}
return createErrorMessage("Bad read memory type specified: " + type);
}
/**
* Write mote variable value as specified by arguments.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String writeMemory(Collection<Element> arguments) {
Simulation simulation = myGUI.getSimulation();
String type = null;
String mote = null;
String variable = null;
String size = null;
String address = null;
String value = null;
for (Element element : arguments) {
if (element.getName().equals(XML_TYPE_NAME)) {
type = element.getText();
} else if (element.getName().equals(XML_MOTE_NAME)) {
mote = element.getText();
} else if (element.getName().equals(XML_VARIABLE_NAME)) {
variable = element.getText();
} else if (element.getName().equals(XML_SIZE_NAME)) {
size = element.getText();
} else if (element.getName().equals(XML_ADDRESS_NAME)) {
address = element.getText();
} else if (element.getName().equals(XML_VALUE_NAME)) {
value = element.getText();
} else {
return createErrorMessage("Unknown write memory parameter: " + element.getName());
}
}
if (type == null)
return createErrorMessage("No write memory type specified");
if (mote == null)
return createErrorMessage("No mote specified");
if (mote == null)
return createErrorMessage("No mote ID specified");
int moteNr = Integer.parseInt(mote);
if (moteNr < 0 || simulation.getMotesCount() <= moteNr) {
return createErrorMessage("Bad mote ID specified: " + moteNr);
}
MoteMemory memory = simulation.getMote(moteNr).getMemory();
// Write integer variable
if (type.equals("int")) {
if (variable == null)
return createErrorMessage("No variable name specified");
if (variable.contains(" "))
return createErrorMessage("Variable name must not contain spaces: " + variable);
if (!(memory instanceof AddressMemory))
return createErrorMessage("Can't read mote memory variables (not address memory)");
if (!((AddressMemory) memory).variableExists(variable)) {
return createErrorMessage("Variable does not exist: " + variable);
}
if (value == null)
return createErrorMessage("No value specified");
if (value.contains(" "))
return createErrorMessage("Integer value must not contain spaces: " + value);
int val;
try {
val = Integer.parseInt(value);
} catch (NumberFormatException e) {
return createErrorMessage("Bad integer value specified: " + e);
}
((AddressMemory) memory).setIntValueOf(variable, val);
return XML_OK;
} else if (type.equals("variable")) {
if (variable == null)
return createErrorMessage("No variable name specified");
if (variable.contains(" "))
return createErrorMessage("Variable name must not contain spaces: " + variable);
if (!(memory instanceof AddressMemory))
return createErrorMessage("Can't read mote memory variables (not address memory)");
if (!((AddressMemory) memory).variableExists(variable)) {
return createErrorMessage("Variable does not exist: " + variable);
}
if (size == null)
return createErrorMessage("No size specified");
int sizeParsed = Integer.parseInt(size);
if (sizeParsed < 0) {
return createErrorMessage("Bad size specified: " + sizeParsed);
}
if (value == null)
return createErrorMessage("No value specified");
String[] bytesParsed = value.split(" ");
if (bytesParsed.length != sizeParsed)
return createErrorMessage("Number of bytes and specified size does not match: " + bytesParsed.length + "!=" + sizeParsed);
byte[] val = new byte[bytesParsed.length];
for (int i=0; i < sizeParsed; i++) {
val[i] = Byte.parseByte(bytesParsed[i]);
}
((AddressMemory) memory).setByteArray(variable, val);
return XML_OK;
} else if (type.equals("address")) {
if (size == null)
return createErrorMessage("No size specified");
int sizeParsed = Integer.parseInt(size);
if (sizeParsed < 0) {
return createErrorMessage("Bad size specified: " + sizeParsed);
}
int addressParsed = Integer.parseInt(address);
if (addressParsed < 0) {
return createErrorMessage("Bad start address specified: " + addressParsed);
}
if (value == null)
return createErrorMessage("No value specified");
String[] bytesParsed = value.split(" ");
if (bytesParsed.length != sizeParsed)
return createErrorMessage("Number of bytes and specified size does not match: " + bytesParsed.length + "!=" + sizeParsed);
byte[] val = new byte[bytesParsed.length];
for (int i=0; i < sizeParsed; i++) {
val[i] = Byte.parseByte(bytesParsed[i]);
}
memory.setMemorySegment(addressParsed, val);
return XML_OK;
}
return createErrorMessage("Bad write memory type specified: " + type);
}
/**
* Handle add new eventpoint command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String addEventpoint(Collection<Element> arguments) {
Simulation simulation = myGUI.getSimulation();
String type = null;
String mote = null;
String variable = null;
String time = null;
String size = null;
String triggeron = null;
String address = null;
String count = null;
for (Element element : arguments) {
if (element.getName().equals(XML_TYPE_NAME)) {
type = element.getText();
} else if (element.getName().equals(XML_MOTE_NAME)) {
mote = element.getText();
} else if (element.getName().equals(XML_VARIABLE_NAME)) {
variable = element.getText();
} else if (element.getName().equals(XML_TIME_NAME)) {
time = element.getText();
} else if (element.getName().equals(XML_SIZE_NAME)) {
size = element.getText();
} else if (element.getName().equals(XML_ADDRESS_NAME)) {
address = element.getText();
} else if (element.getName().equals(XML_TRIGGERON_NAME)) {
triggeron = element.getText();
} else if (element.getName().equals("count")) {
count = element.getText();
} else {
return createErrorMessage("Unknown eventpoint parameter: " + element.getName());
}
}
logger.debug("Eventpoint type: " + type);
if (type == null)
return createErrorMessage("No eventpoint type specified");
// Integer variable watchpoint
if (type.equals(XML_WATCHPOINT_INT)) {
if (variable == null)
return createErrorMessage("No variable name specified");
if (variable.contains(" "))
return createErrorMessage("Variable name must not contain spaces: " + variable);
if (mote == null)
return createErrorMessage("No mote ID specified");
int moteNr = Integer.parseInt(mote);
if (moteNr < 0 || simulation.getMotesCount() <= moteNr) {
return createErrorMessage("Bad mote ID specified: " + moteNr);
}
Mote moteObject = simulation.getMote(moteNr);
MoteMemory memory = simulation.getMote(moteNr).getMemory();
if (!(memory instanceof AddressMemory))
return createErrorMessage("Can't write mote memory variables (not address memory)");
if (!((AddressMemory) memory).variableExists(variable)) {
return createErrorMessage("Variable does not exist: " + variable);
}
Eventpoint newEventpoint = new IntegerWatchpoint(moteObject, variable);
myEvaluator.addEventpoint(newEventpoint);
return createOkMessage(newEventpoint, simulation.getSimulationTime());
}
// Variable watchpoint
if (type.equals(XML_WATCHPOINT_VARIABLE)) {
if (variable == null)
return createErrorMessage("No variable name specified");
if (variable.contains(" "))
return createErrorMessage("Variable name must not contain spaces: " + variable);
if (mote == null)
return createErrorMessage("No mote ID specified");
if (size == null)
return createErrorMessage("No size specified");
int sizeParsed = Integer.parseInt(size);
if (sizeParsed < 0) {
return createErrorMessage("Bad size specified: " + sizeParsed);
}
int moteNr = Integer.parseInt(mote);
if (moteNr < 0 || simulation.getMotesCount() <= moteNr) {
return createErrorMessage("Bad mote ID specified: " + moteNr);
}
Mote moteObject = simulation.getMote(moteNr);
MoteMemory memory = simulation.getMote(moteNr).getMemory();
if (!(memory instanceof AddressMemory))
return createErrorMessage("Can't write mote memory variables (not address memory)");
if (!((AddressMemory) memory).variableExists(variable)) {
return createErrorMessage("Variable does not exist: " + variable);
}
Eventpoint newEventpoint = new VariableWatchpoint(moteObject, variable, sizeParsed);
myEvaluator.addEventpoint(newEventpoint);
return createOkMessage(newEventpoint, simulation.getSimulationTime());
}
// Memory area watchpoint
if (type.equals(XML_WATCHPOINT_ADDRESS)) {
if (mote == null)
return createErrorMessage("No mote ID specified");
if (size == null)
return createErrorMessage("No size specified");
int sizeParsed = Integer.parseInt(size);
if (sizeParsed < 0) {
return createErrorMessage("Bad size specified: " + sizeParsed);
}
int addressParsed = Integer.parseInt(address);
if (addressParsed < 0) {
return createErrorMessage("Bad start address specified: " + addressParsed);
}
int moteNr = Integer.parseInt(mote);
if (moteNr < 0 || simulation.getMotesCount() <= moteNr) {
return createErrorMessage("Bad mote ID specified: " + moteNr);
}
Mote moteObject = simulation.getMote(moteNr);
MoteMemory memory = simulation.getMote(moteNr).getMemory();
Eventpoint newEventpoint = new Watchpoint(moteObject, addressParsed, sizeParsed);
myEvaluator.addEventpoint(newEventpoint);
return createOkMessage(newEventpoint, simulation.getSimulationTime());
}
// Simulation timepoint
if (type.equals(XML_TIMEPOINT_SIMULATION)) {
if (time == null)
return createErrorMessage("No time specified");
int timeParsed = Integer.parseInt(time);
if (timeParsed < 0) {
return createErrorMessage("Bad time specified: " + timeParsed);
}
Eventpoint newEventpoint = new SimulationTimepoint(simulation, timeParsed);
myEvaluator.addEventpoint(newEventpoint);
return createOkMessage(newEventpoint, simulation.getSimulationTime());
}
// Real timepoint
if (type.equals(XML_TIMEPOINT_REAL)) {
if (time == null)
return createErrorMessage("No time specified");
long timeParsed = Long.parseLong(time);
if (timeParsed < 0) {
return createErrorMessage("Bad time specified: " + timeParsed);
}
Eventpoint newEventpoint = new RealTimepoint(timeParsed);
myEvaluator.addEventpoint(newEventpoint);
return createOkMessage(newEventpoint, simulation.getSimulationTime());
}
// Radio medium event point
if (type.equals(XML_EVENTPOINT_RADIOMEDIUM)) {
int countInt;
try {
countInt = Integer.parseInt(count);
} catch (NumberFormatException e) {
return createErrorMessage("Bad count specified: " + e);
}
if (triggeron == null || triggeron.equals("all")) {
Eventpoint newEventpoint = new RadioMediumEventpoint(simulation.getRadioMedium(), countInt);
myEvaluator.addEventpoint(newEventpoint);
return createOkMessage(newEventpoint, simulation.getSimulationTime());
} else if (triggeron.equals("completed")) {
Eventpoint newEventpoint = new TransmissionRadioMediumEventpoint(simulation.getRadioMedium(), countInt);
myEvaluator.addEventpoint(newEventpoint);
return createOkMessage(newEventpoint, simulation.getSimulationTime());
} else {
return createErrorMessage("Bad trigger on parameter: " + triggeron);
}
}
return createErrorMessage("Bad eventpoint type specified: " + type);
}
/**
* Handle configure GUI command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String configureGUI(Collection<Element> arguments) {
String visible = null;
for (Element element : arguments) {
if (element.getName().equals(XML_VISIBLE_NAME)) {
visible = element.getText();
} else {
return createErrorMessage("Unknown GUI configure parameter: " + element.getName());
}
}
boolean shouldBeVisible = Boolean.parseBoolean(visible);
if (myGUI.isVisualized() != shouldBeVisible) {
myGUI.setVisualized(shouldBeVisible);
}
return XML_OK;
}
/**
* Handle delete eventpoint command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String deleteEventpoint(Collection<Element> arguments) {
String id = null;
for (Element element : arguments) {
if (element.getName().equals(XML_ID_NAME)) {
id = element.getText();
} else {
return createErrorMessage("Unknown eventpoint parameter: " + element.getName());
}
}
int idInt;
try {
idInt = Integer.parseInt(id);
} catch (NumberFormatException e) {
return createErrorMessage("Bad eventpoint ID specified: " + e);
}
Eventpoint eventpoint = myEvaluator.getEventpoint(idInt);
if (eventpoint == null)
return createErrorMessage("No eventpoint with ID " + idInt + " exists");
myEvaluator.deleteEventpoint(idInt);
return XML_OK;
}
/**
* Handle kill nodes command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String killNodes(Collection<Element> arguments) {
String lowId = null;
String highId = null;
for (Element element : arguments) {
if (element.getName().equals("lowmote")) {
lowId = element.getText();
} else if (element.getName().equals("highmote")) {
highId = element.getText();
} else {
return createErrorMessage("Unknown eventpoint parameter: " + element.getName());
}
}
int lowIdInt;
int highIdInt;
try {
lowIdInt = Integer.parseInt(lowId);
highIdInt = Integer.parseInt(highId);
} catch (NumberFormatException e) {
return createErrorMessage("Bad mote interval specified: " + e);
}
if (lowIdInt > highIdInt)
return createErrorMessage("Bad mote interval specified: Low ID must be <= than high ID");
if (lowIdInt < 0)
return createErrorMessage("Bad mote interval specified: Low ID >= 0");
if (myGUI.getSimulation() == null)
return createErrorMessage("No simulation exists");
if (myGUI.getSimulation().getMotesCount() < highIdInt)
return createErrorMessage("Bad mote interval specified: Only " + myGUI.getSimulation().getMotesCount() + " motes exist");
for (int pos=lowIdInt; pos <= highIdInt; pos++) {
Mote mote = myGUI.getSimulation().getMote(pos);
mote.setState(State.DEAD);
}
return XML_OK;
}
/**
* Handle get info command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String getInfo(Collection<Element> arguments) {
Simulation simulation = myGUI.getSimulation();
String type = null;
String mote = null;
String variable = null;
for (Element element : arguments) {
if (element.getName().equals(XML_TYPE_NAME)) {
type = element.getText();
} else if (element.getName().equals(XML_MOTE_NAME)) {
mote = element.getText();
} else if (element.getName().equals(XML_VARIABLE_NAME)) {
variable = element.getText();
} else {
return createErrorMessage("Unknown info parameter: " + element.getName());
}
}
if (type.equals("motestate")) {
if (mote == null)
return createErrorMessage("No mote ID specified");
int moteNr = Integer.parseInt(mote);
if (moteNr < 0 || simulation.getMotesCount() <= moteNr) {
return createErrorMessage("Bad mote ID specified: " + moteNr);
}
State state = simulation.getMote(moteNr).getState();
if (state == State.DEAD)
return XML_OK_START + 0 + XML_OK_END;
return XML_OK_START + 1 + XML_OK_END;
} else if (type.equals("time")) {
return XML_OK_START + myGUI.getSimulation().getSimulationTime() + XML_OK_END;
} else if (type.equals(XML_MOTECOUNT_NAME)) {
return XML_OK_START + myGUI.getSimulation().getMotesCount() + XML_OK_END;
} else if (type.equals("var_address")) {
if (variable == null)
return createErrorMessage("No variable name specified");
if (variable.contains(" "))
return createErrorMessage("Variable name must not contain spaces: " + variable);
if (mote == null)
return createErrorMessage("No mote ID specified");
int moteNr = Integer.parseInt(mote);
if (moteNr < 0 || simulation.getMotesCount() <= moteNr) {
return createErrorMessage("Bad mote ID specified: " + moteNr);
}
Mote moteObject = simulation.getMote(moteNr);
MoteMemory memory = simulation.getMote(moteNr).getMemory();
if (!(memory instanceof AddressMemory))
return createErrorMessage("Can't read mote memory variable address (not address memory)");
if (!((AddressMemory) memory).variableExists(variable)) {
return createErrorMessage("Variable does not exist: " + variable);
}
int address = ((AddressMemory) memory).getVariableAddress(variable);
return XML_OK_START + address + XML_OK_END;
}
return createErrorMessage("Unknown type: " + type);
}
/**
* Handle custom command.
*
* @param arguments Command arguments
* @return Reply to client (XML format)
*/
private String handleCustomCommand(Collection<Element> arguments) {
Simulation simulation = myGUI.getSimulation();
String action = null;
int id = -1;
int visible = -1;
int hide = -1;
for (Element element : arguments) {
if (element.getName().equals("action")) {
action = element.getText();
} else if (element.getName().equals("id")) {
String idString = element.getText();
id = Integer.parseInt(idString);
} else if (element.getName().equals("hide")) {
String hideString = element.getText();
hide = Integer.parseInt(hideString);
} else if (element.getName().equals("visible")) {
String visibleString = element.getText();
visible = Integer.parseInt(visibleString);
} else {
return createErrorMessage("Unknown info parameter: " + element.getName());
}
}
if (action.equals("CLICK_SINK")) {
simulation.getMote(0).getInterfaces().getButton().clickButton();
return XML_OK;
}
if (action.equals("SHOW_FIRE")) {
if (!simulation.getGUI().isVisualized())
return XML_OK;
JInternalFrame[] allPlugins = simulation.getGUI().getDesktopPane().getAllFrames();
try {
Class<Visualizer2D> pluginClass = (Class<Visualizer2D>) simulation.getGUI().tryLoadClass(this, Visualizer2D.class, "se.sics.runes.RunesVis");
Class[] parameterTypes = new Class[1];
parameterTypes[0] = Boolean.TYPE;
Method method = pluginClass.getMethod("showFire", parameterTypes);
Object[] parameterArguments = new Object[1];
parameterArguments[0] = new Boolean(visible==1?true:false);
for (JInternalFrame plugin: allPlugins) {
if (plugin.getClass() == pluginClass) {
method.invoke(plugin, parameterArguments);
}
}
} catch (Exception e) {
return createErrorMessage("Exception: " + e.getMessage());
}
return XML_OK;
}
if (action.equals("RESET_COLORS")) {
if (!simulation.getGUI().isVisualized())
return XML_OK;
JInternalFrame[] allPlugins = simulation.getGUI().getDesktopPane().getAllFrames();
try {
Class<Visualizer2D> pluginClass = (Class<Visualizer2D>) simulation.getGUI().tryLoadClass(this, Visualizer2D.class, "se.sics.runes.RunesVis");
Class[] parameterTypes = new Class[0];
Method method = pluginClass.getMethod("resetColors", parameterTypes);
Object[] parameterArguments = new Object[0];
for (JInternalFrame plugin: allPlugins) {
if (plugin.getClass() == pluginClass) {
method.invoke(plugin, parameterArguments);
}
}
} catch (Exception e) {
return createErrorMessage("Exception: " + e.getMessage());
}
return XML_OK;
}
if (action.equals("SHOW_TRUCK")) {
if (!simulation.getGUI().isVisualized())
return XML_OK;
JInternalFrame[] allPlugins = simulation.getGUI().getDesktopPane().getAllFrames();
try {
Class<Visualizer2D> pluginClass = (Class<Visualizer2D>) simulation.getGUI().tryLoadClass(this, Visualizer2D.class, "se.sics.runes.RunesVis");
if (hide == 0) {
Class[] parameterTypes = new Class[0];
Method method = pluginClass.getMethod("showTruck", parameterTypes);
Object[] parameterArguments = new Object[0];
for (JInternalFrame plugin: allPlugins) {
if (plugin.getClass() == pluginClass) {
method.invoke(plugin, parameterArguments);
}
}
} else {
Class[] parameterTypes = new Class[0];
Method method = pluginClass.getMethod("hideTruck", parameterTypes);
Object[] parameterArguments = new Object[0];
for (JInternalFrame plugin: allPlugins) {
if (plugin.getClass() == pluginClass) {
method.invoke(plugin, parameterArguments);
}
}
}
} catch (Exception e) {
return createErrorMessage("Exception: " + e.getMessage());
}
return XML_OK;
}
if (action.equals("INDICATE_MOTE")) {
if (!simulation.getGUI().isVisualized())
return XML_OK;
JInternalFrame[] allPlugins = simulation.getGUI().getDesktopPane().getAllFrames();
try {
Class<Visualizer2D> pluginClass = (Class<Visualizer2D>) simulation.getGUI().tryLoadClass(this, Visualizer2D.class, "se.sics.runes.RunesVis");
Class[] parameterTypes = new Class[1];
parameterTypes[0] = Integer.TYPE;
Method method = pluginClass.getMethod("indicateMote", parameterTypes);
Object[] parameterArguments = new Object[1];
parameterArguments[0] = new Integer(id);
for (JInternalFrame plugin: allPlugins) {
if (plugin.getClass() == pluginClass) {
method.invoke(plugin, parameterArguments);
}
}
} catch (Exception e) {
return createErrorMessage("Exception: " + e.getMessage());
}
return XML_OK;
}
return createErrorMessage("Unknown action: " + action);
}
/**
* Handle clear eventpoints command.
*
* @return Reply to client (XML format)
*/
private String clearEventpoints() {
myEvaluator.clearAllEventpoints();
return XML_OK;
}
public static String createErrorMessage(String message) {
return XML_ERROR_START + message + XML_ERROR_END;
}
public static String createInfoMessage(String message) {
return XML_INFO_START + message + XML_INFO_END;
}
public static String createOkMessage(Eventpoint eventpoint, int time) {
return XML_OK_START + eventpoint.getID() + XML_OK_END;
}
public static String createEventpointMessage(EventpointEvaluator evaluator) {
return XML_EVENTPOINT_START +
evaluator.getLastTriggeredEventpointID() +
XML_INFO_START +
evaluator.getTriggeredEventpoint().getMessage() +
XML_INFO_END +
XML_EVENTPOINT_END;
}
}