diff --git a/tools/cooja/apps/avrora/build.xml b/tools/cooja/apps/avrora/build.xml
new file mode 100644
index 000000000..260fb5eb3
--- /dev/null
+++ b/tools/cooja/apps/avrora/build.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tools/cooja/apps/avrora/cooja.config b/tools/cooja/apps/avrora/cooja.config
new file mode 100644
index 000000000..64c829a28
--- /dev/null
+++ b/tools/cooja/apps/avrora/cooja.config
@@ -0,0 +1,2 @@
+se.sics.cooja.GUI.MOTETYPES = + se.sics.cooja.avrmote.MicaZMoteType
+se.sics.cooja.GUI.JARFILES = + cooja_avrora.jar avrora.jar
diff --git a/tools/cooja/apps/avrora/lib/avrora.jar b/tools/cooja/apps/avrora/lib/avrora.jar
new file mode 100644
index 000000000..f926a0dfd
Binary files /dev/null and b/tools/cooja/apps/avrora/lib/avrora.jar differ
diff --git a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMote.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMote.java
new file mode 100755
index 000000000..57d4bb593
--- /dev/null
+++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMote.java
@@ -0,0 +1,312 @@
+/*
+ * 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: MicaZMote.java,v 1.1 2009/02/22 16:45:01 joxe Exp $
+ */
+
+package se.sics.cooja.avrmote;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Observable;
+import java.util.Observer;
+import java.util.Random;
+import java.util.Vector;
+import org.apache.log4j.Logger;
+import org.jdom.Element;
+import se.sics.cooja.GUI;
+import se.sics.cooja.Mote;
+import se.sics.cooja.MoteInterface;
+import se.sics.cooja.MoteInterfaceHandler;
+import se.sics.cooja.MoteMemory;
+import se.sics.cooja.MoteType;
+import se.sics.cooja.Simulation;
+import se.sics.cooja.avrmote.interfaces.MicaZLED;
+import se.sics.cooja.interfaces.Position;
+import avrora.sim.*;
+import avrora.sim.platform.*;
+import avrora.sim.mcu.*;
+import avrora.core.*;
+import avrora.sim.radio.*;
+import avrora.sim.util.SimUtil;
+
+
+/**
+ * @author Joakim Eriksson
+ */
+public class MicaZMote implements Mote {
+ private static Logger logger = Logger.getLogger(MicaZMote.class);
+
+ /* 8 MHz according to Contiki config */
+ public static long NR_CYCLES_PER_MSEC = 8000;
+
+ /* Cycle counter */
+ public long cycleCounter = 0;
+ public long cycleDrift = 0;
+
+ private Simulation mySimulation = null;
+ private Microcontroller myCpu = null;
+ private MicaZ micaZ = null;
+ private LoadableProgram program = null;
+ private Interpreter interpreter = null;
+
+ private MicaZMoteType myMoteType = null;
+
+ /* Stack monitoring variables */
+ private boolean stopNextInstruction = false;
+
+ private MoteInterfaceHandler myMoteInterfaceHandler;
+
+ /**
+ * Abort current tick immediately.
+ * May for example be called by a breakpoint handler.
+ */
+ public void stopNextInstruction() {
+ stopNextInstruction = true;
+ }
+
+ public MicaZMote() {
+ mySimulation = null;
+ myCpu = null;
+ myMoteInterfaceHandler = null;
+ }
+
+ public MicaZMote(Simulation simulation, MicaZMoteType type) {
+ mySimulation = simulation;
+ myMoteType = type;
+ }
+
+ protected void initMote() {
+ if (myMoteType != null) {
+ initEmulator(myMoteType.getELFFile());
+ myMoteInterfaceHandler = createMoteInterfaceHandler();
+ }
+ }
+
+ protected boolean initEmulator(String fileELF) {
+ try {
+ prepareMote(fileELF);
+ } catch (Exception e) {
+ logger.fatal("Error when creating MicaZ mote:", e);
+ return false;
+ }
+ return true;
+ }
+
+
+ public Simulation getSimulation() {
+ return mySimulation;
+ }
+
+ public void setSimulation(Simulation simulation) {
+ mySimulation = simulation;
+ }
+
+ /**
+ * Prepares CPU, memory and ELF module.
+ *
+ * @param fileELF ELF file
+ * @param cpu MSP430 cpu
+ * @throws Exception
+ */
+ protected void prepareMote(String file) throws Exception {
+ program = new LoadableProgram(file);
+ program.load();
+ PlatformFactory factory = new MicaZ.Factory();
+ micaZ = (MicaZ) factory.newPlatform(1, program.getProgram());
+ myCpu = micaZ.getMicrocontroller();
+ Simulator sim = myCpu.getSimulator();
+ interpreter = sim.getInterpreter();
+// State state = interpreter.getState();
+ }
+
+ public void setState(State newState) {
+ logger.warn("MicaZ motes can't change state");
+ }
+
+ public State getState() {
+ return Mote.State.ACTIVE;
+ }
+
+ /* called when moteID is updated */
+ public void idUpdated(int newID) {
+ }
+
+ public MoteType getType() {
+ return myMoteType;
+ }
+
+ public void setType(MoteType type) {
+ //myMoteType = (MspMoteType) type;
+ }
+
+ public void addStateObserver(Observer newObserver) {
+ }
+
+ public void deleteStateObserver(Observer newObserver) {
+ }
+
+ public MoteInterfaceHandler getInterfaces() {
+ return myMoteInterfaceHandler;
+ }
+
+ public void setInterfaces(MoteInterfaceHandler moteInterfaceHandler) {
+ myMoteInterfaceHandler = moteInterfaceHandler;
+ }
+
+ /* return false when done - e.g. true means more work to do before finished with this tick */
+
+ private boolean firstTick = true;
+ private long cyclesExecuted = 0;
+ public boolean tick(long simTime) {
+ if (stopNextInstruction) {
+ stopNextInstruction = false;
+ throw new RuntimeException("MSPSim requested simulation stop");
+ }
+
+ /* Nodes may be added in an ongoing simulation:
+ * Update cycle drift to current simulation time */
+ if (firstTick) {
+ firstTick = false;
+ cycleDrift += (-NR_CYCLES_PER_MSEC*simTime);
+ }
+
+ long maxSimTimeCycles = NR_CYCLES_PER_MSEC * (simTime + 1) + cycleDrift;
+
+ if (maxSimTimeCycles <= cycleCounter) {
+ return false;
+ }
+
+ // Leave control to emulated CPU
+ cycleCounter += 1;
+
+ if (cyclesExecuted > cycleCounter) {
+ /* CPU already ticked too far - just wait it out */
+ return true;
+ }
+ // myMoteInterfaceHandler.doActiveActionsBeforeTick();
+
+ cyclesExecuted += interpreter.step();
+
+ //cpu.step(cycleCounter);
+
+ /* Check if radio has pending incoming bytes */
+// if (myRadio != null && myRadio.hasPendingBytes()) {
+// myRadio.tryDeliverNextByte(cpu.cycles);
+// }
+
+ return true;
+ }
+
+ public boolean setConfigXML(Simulation simulation, Collection configXML, boolean visAvailable) {
+ for (Element element: configXML) {
+ String name = element.getName();
+
+ if (name.equals("motetype_identifier")) {
+
+ setSimulation(simulation);
+ myMoteType = (MicaZMoteType) simulation.getMoteType(element.getText());
+ getType().setIdentifier(element.getText());
+
+ try {
+ prepareMote(myMoteType.getELFFile());
+ } catch (Exception e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+ }
+ myMoteInterfaceHandler = createMoteInterfaceHandler();
+
+ } 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 = getInterfaces().getInterfaceOfType(moteInterfaceClass);
+ moteInterface.setConfigXML(element.getChildren(), visAvailable);
+ }
+ }
+
+ return true;
+ }
+
+ private MoteInterfaceHandler createMoteInterfaceHandler() {
+ System.out.println("Creating mote interface handler....");
+ MoteInterfaceHandler moteInterfaceHandler = new MoteInterfaceHandler();
+
+ // Add position interface
+ Position motePosition = new Position(this);
+ Random random = new Random(); /* Do not use main random generator for positioning */
+ motePosition.setCoordinates(random.nextDouble()*100, random.nextDouble()*100, random.nextDouble()*100);
+ moteInterfaceHandler.addInterface(motePosition);
+
+ // Add LED interface
+ MicaZLED moteLED = new MicaZLED(micaZ);
+ moteInterfaceHandler.addInterface(moteLED);
+
+ return moteInterfaceHandler;
+ }
+
+ public Collection getConfigXML() {
+ Vector config = new Vector();
+
+ Element element;
+
+ // Mote type identifier
+ element = new Element("motetype_identifier");
+ element.setText(getType().getIdentifier());
+ config.add(element);
+
+ // Mote interfaces
+ for (MoteInterface moteInterface: getInterfaces().getInterfaces()) {
+ 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 MoteMemory getMemory() {
+ return null;
+ }
+
+ public void setMemory(MoteMemory memory) {
+ }
+
+}
diff --git a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMoteType.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMoteType.java
new file mode 100644
index 000000000..37f98ab2b
--- /dev/null
+++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMoteType.java
@@ -0,0 +1,1135 @@
+/*
+ * 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: MicaZMoteType.java,v 1.1 2009/02/22 16:45:01 joxe Exp $
+ */
+
+package se.sics.cooja.avrmote;
+
+import java.awt.*;
+import java.awt.Dialog.ModalityType;
+import java.awt.event.*;
+import java.io.*;
+import java.util.Collection;
+import java.util.Vector;
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.filechooser.FileFilter;
+import org.apache.log4j.Logger;
+import org.jdom.Element;
+import se.sics.cooja.*;
+import se.sics.cooja.dialogs.MessageList;
+import se.sics.cooja.dialogs.MessageList.MessageContainer;
+
+@ClassDescription("MicaZ Mote Type")
+public class MicaZMoteType implements MoteType {
+ private static Logger logger = Logger.getLogger(MicaZMoteType.class);
+
+ public static final String target = "micaz";
+ public static final String targetNice = "MicaZ";
+
+ protected static String getTargetFileExtension(String target) {
+ return "." + target;
+ }
+
+ /* Convenience: Preselecting last used directory */
+ protected static File lastParentDirectory = null;
+
+ private String identifier = null;
+ private String description = null;
+
+ /* If source file is defined, (re)compilation is performed */
+ private String fileFirmware = null;
+ private File fileSource = null;
+ private String compileCommand = null;
+
+ public String getIdentifier() {
+ return identifier;
+ }
+
+ public void setIdentifier(String identifier) {
+ this.identifier = identifier;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Set ELF file.
+ *
+ * @param file
+ * ELF file
+ */
+ public void setELFFile(File file) {
+ this.fileFirmware = file.getAbsolutePath();
+ }
+
+ /**
+ * Set compile command.
+ *
+ * @param command
+ * Compile command
+ */
+ public void setCompileCommand(String command) {
+ this.compileCommand = command;
+ }
+
+ /**
+ * @return ELF file
+ */
+ public String getELFFile() {
+ return fileFirmware;
+ }
+
+ /**
+ * @return Compile command
+ */
+ public String getCompileCommand() {
+ return compileCommand;
+ }
+
+ /**
+ * Set source file
+ *
+ * @param file Source file
+ */
+ public void setSourceFile(File file) {
+ fileSource = file;
+ }
+
+ /**
+ * @return Source file
+ */
+ public File getSourceFile() {
+ return fileSource;
+ }
+
+ public final Mote generateMote(Simulation simulation) {
+ MicaZMote mote = new MicaZMote(simulation, this);
+ mote.initMote();
+ return mote;
+ }
+
+ /**
+ * Configures and initialized MicaZ mote types.
+ * TODO: share this code with mspmote using an abstract emulated mote class...
+ *
+ * @param parentContainer Graphical parent container
+ * @param simulation Current simulation
+ * @param visAvailable Enable graphical interfaces and user input
+ * @param target Contiki target platform name
+ * @param targetNice Nicer representation of target
+ * @return True is successful
+ * @throws MoteTypeCreationException Mote type creation failed
+ */
+ protected boolean configureAndInitMicaZType(Container parentContainer, Simulation simulation,
+ boolean visAvailable, final String target, final String targetNice)
+ throws MoteTypeCreationException {
+ boolean compileFromSource = false;
+
+ if (getIdentifier() == null && !visAvailable) {
+ throw new MoteTypeCreationException("No identifier");
+ }
+
+ /* Generate unique identifier */
+ if (getIdentifier() == null) {
+ int counter = 0;
+ boolean identifierOK = false;
+ while (!identifierOK) {
+ counter++;
+ setIdentifier(target + counter);
+ identifierOK = true;
+
+ // Check if identifier is already used by some other type
+ for (MoteType existingMoteType : simulation.getMoteTypes()) {
+ if (existingMoteType != this
+ && existingMoteType.getIdentifier().equals(getIdentifier())) {
+ identifierOK = false;
+ break;
+ }
+ }
+ }
+
+ if (getDescription() == null) {
+ setDescription(targetNice + " Mote Type #" + counter);
+ }
+
+ /* Let user choose whether to compile or load existing binaries */
+ Object[] options = { "Compile", "Existing" };
+
+ String question = targetNice + " mote type loads a firmware (ELF).\n\n"
+ + "To compile a Contiki application from source: 'Compile'\n"
+ + "To use a pre-compiled existing firmware: 'Existing'.\n";
+ String title = "Compile or load existing " + targetNice + " firmware";
+
+ if (GUI.isVisualizedInApplet()) {
+ compileFromSource = false;
+ } else {
+ int answer = JOptionPane.showOptionDialog(GUI.getTopParentContainer(),
+ question, title, JOptionPane.YES_NO_OPTION,
+ JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
+
+ if (answer != JOptionPane.YES_OPTION && answer != JOptionPane.NO_OPTION) {
+ return false;
+ }
+ compileFromSource = answer == JOptionPane.YES_OPTION;
+ }
+ }
+
+ /* Description */
+ if (getDescription() == null) {
+ setDescription(targetNice + " Mote Type #" + getIdentifier());
+ }
+
+ if (getSourceFile() != null) {
+ compileFromSource = true;
+ }
+
+ if (compileFromSource) {
+ MicaELFCompiler compiler = new MicaELFCompiler(target);
+ compiler.setCompileCommand(compileCommand);
+
+ if (visAvailable) {
+ boolean success = compiler.showDialog(GUI.getTopParentContainer(), this);
+ if (success) {
+ setSourceFile(compiler.getSourceFile());
+ setELFFile(compiler.getOutputFile());
+ setCompileCommand(compiler.getLastCompileCommand());
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ MessageList compilationOutput = new MessageList();
+ try {
+ compiler.compileFirmware(getSourceFile(), null, null, compilationOutput,
+ true);
+
+ } catch (Exception e) {
+ MoteTypeCreationException newException = new MoteTypeCreationException(
+ "Mote type creation failed: " + e.getMessage());
+ newException = (MoteTypeCreationException) newException.initCause(e);
+ newException.setCompilationOutput(compilationOutput);
+
+ /* Print last 5 compilation errors */
+ MessageContainer[] messages = compilationOutput.getMessages();
+ for (int i=messages.length-5; i < messages.length; i++) {
+ if (i < 0) {
+ continue;
+ }
+ logger.fatal(">> " + messages[i]);
+ }
+
+ logger.fatal("Compilation error: " + e.getMessage());
+ throw newException;
+ }
+
+ setSourceFile(compiler.getSourceFile());
+ setELFFile(compiler.getOutputFile());
+ setCompileCommand(compiler.getLastCompileCommand());
+
+ return true;
+ }
+ }
+
+ if (GUI.isVisualizedInApplet()) {
+ return true;
+ }
+
+ // Check dependency files
+ File elfFile = null;
+ if (getELFFile() != null) {
+ elfFile = new File(getELFFile());
+ }
+ if (elfFile == null || !elfFile.exists()) {
+ if (!visAvailable) {
+ throw new MoteTypeCreationException("ELF file does not exist: " + getELFFile());
+ }
+
+ JFileChooser fc = new JFileChooser();
+
+ // Select previous directory
+ if (lastParentDirectory != null) {
+ fc.setCurrentDirectory(lastParentDirectory);
+ } else {
+ fc.setCurrentDirectory(new java.io.File(GUI.getExternalToolsSetting("PATH_CONTIKI")));
+ }
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ fc.addChoosableFileFilter(new FileFilter() {
+ public boolean accept(File f) {
+ String filename = f.getName();
+ if (f.isDirectory()) {
+ return true;
+ }
+
+ if (filename != null) {
+ if (filename.endsWith(getTargetFileExtension(target)) || filename.endsWith(".firmware")
+ || filename.endsWith(".elf")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String getDescription() {
+ return "Firmware files";
+ }
+ });
+ fc.addChoosableFileFilter(new FileFilter() {
+ public boolean accept(File f) {
+ String filename = f.getName();
+ if (f.isDirectory()) {
+ return true;
+ }
+
+ if (filename != null) {
+ if (filename.endsWith(getTargetFileExtension(target))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String getDescription() {
+ return targetNice + " firmware files";
+ }
+ });
+ fc.setDialogTitle("Select firmware file");
+
+ if (fc.showOpenDialog(parentContainer) == JFileChooser.APPROVE_OPTION) {
+ File selectedFile = fc.getSelectedFile();
+
+ if (!selectedFile.exists()) {
+ logger.fatal("Selected file \"" + selectedFile + "\" does not exist");
+ return false;
+ }
+
+ setELFFile(fc.getSelectedFile());
+ } else {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ protected static class MicaELFCompiler {
+ private static int LABEL_WIDTH = 170;
+
+ private static int LABEL_HEIGHT = 15;
+
+ private JButton cancelButton = new JButton("Cancel");
+
+ private JButton cleanButton = new JButton("Clean");
+
+ private JButton compileButton = new JButton("Compile");
+
+ private JButton createButton = new JButton("Create");
+
+ private JTextField sourceTextField = new JTextField();
+
+ private JTextField compileCommandTextField = new JTextField();
+
+ // private JFormattedTextField nodeIDTextField;
+ // private NumberFormat integerFormat = NumberFormat.getIntegerInstance();
+
+ private String lastCompileCommand = null;
+
+ private File sourceFile = null;
+
+ private File ELFFile = null;
+
+ private String target;
+
+ private JDialog myDialog;
+
+ private String customizedCompileCommand = null;
+
+ private Process compileProcess;
+
+ static enum DialogState {
+ NO_SOURCE, SELECTED_SOURCE, IS_COMPILING, COMPILED_SOURCE
+ }
+
+ public MicaELFCompiler(String target) {
+ this.target = target;
+ }
+
+ private String getCompileCommand(String filename) {
+ if (customizedCompileCommand != null) {
+ return customizedCompileCommand;
+ }
+ return GUI.getExternalToolsSetting("PATH_MAKE") + " " + filename + getTargetFileExtension(target) + " TARGET=" + target;
+ }
+
+ private void setCompileCommand(String command) {
+ if (command == null || command.isEmpty()) {
+ customizedCompileCommand = null;
+ return;
+ }
+ customizedCompileCommand = command;
+ }
+
+ /**
+ * @return Compiler output
+ */
+ public File getOutputFile() {
+ return ELFFile;
+ }
+
+ public File getSourceFile() {
+ return sourceFile;
+ }
+
+ public String getLastCompileCommand() {
+ return lastCompileCommand;
+ }
+
+ private void updateDialog(DialogState dialogState) {
+ switch (dialogState) {
+ case NO_SOURCE:
+ compileButton.setEnabled(false);
+ createButton.setEnabled(false);
+ compileCommandTextField.setText("");
+ break;
+
+ case IS_COMPILING:
+ compileButton.setEnabled(false);
+ createButton.setEnabled(false);
+ break;
+
+ case SELECTED_SOURCE:
+ File sourceFile = new File(sourceTextField.getText());
+ if (!sourceFile.exists()) {
+ updateDialog(DialogState.NO_SOURCE);
+ break;
+ }
+
+ File parentDirectory = sourceFile.getParentFile();
+ if (!parentDirectory.exists()) {
+ updateDialog(DialogState.NO_SOURCE);
+ break;
+ }
+
+ if (!sourceFile.getName().endsWith(".c")) {
+ updateDialog(DialogState.NO_SOURCE);
+ break;
+ }
+
+ String name = sourceFile.getName().substring(0,
+ sourceFile.getName().length() - 2);
+
+ compileButton.setEnabled(true);
+ createButton.setEnabled(false);
+ compileCommandTextField.setText(getCompileCommand(name));
+ compileButton.requestFocusInWindow();
+ break;
+
+ case COMPILED_SOURCE:
+ compileButton.setEnabled(true);
+ createButton.setEnabled(true);
+
+ createButton.requestFocusInWindow();
+ myDialog.getRootPane().setDefaultButton(createButton);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ protected void compileFirmware(final File sourceFile,
+ final Action successAction, final Action failAction,
+ final MessageList compilationOutput, boolean synchronous) throws Exception {
+ final File parentDirectory = sourceFile.getParentFile();
+
+ if (!sourceFile.getName().endsWith(".c")) {
+ logger.fatal("Source file does not end with '.c'");
+ return;
+ }
+
+ final String filenameNoExtension = sourceFile.getName().substring(0,
+ sourceFile.getName().length() - 2);
+
+ final String command = getCompileCommand(filenameNoExtension);
+ logger.info("-- Compiling AVR/MicaZ Firmware --");
+
+ compileFirmware(command, sourceFile, filenameNoExtension + getTargetFileExtension(target),
+ parentDirectory,
+ successAction, failAction,
+ compilationOutput, synchronous);
+ }
+
+ protected void compileFirmware(
+ final String command, final File sourceFile,
+ final String firmware, final File parentDirectory,
+ final Action successAction, final Action failAction,
+ final MessageList compilationOutput, boolean synchronous) throws Exception {
+
+ if (compilationOutput != null) {
+ compilationOutput.clearMessages();
+ }
+
+ try {
+ logger.info("Compilation command: " + command);
+ compileProcess = Runtime.getRuntime().exec(
+ new String[] {"bash", "-c", command},
+ null,
+ parentDirectory
+ );
+
+ final BufferedReader processNormal = new BufferedReader(
+ new InputStreamReader(compileProcess.getInputStream()));
+ final BufferedReader processError = new BufferedReader(
+ new InputStreamReader(compileProcess.getErrorStream()));
+
+ final File ELFFile = new File(parentDirectory, firmware);
+ if (firmware != null) {
+ if (ELFFile.exists()) {
+ ELFFile.delete();
+ if (ELFFile.exists()) {
+ if (compilationOutput != null) {
+ compilationOutput.addMessage("Error when deleting old " + ELFFile.getName(), MessageList.ERROR);
+ }
+ if (failAction != null) {
+ failAction.actionPerformed(null);
+ }
+ throw new MoteTypeCreationException("Error when deleting old "
+ + ELFFile.getName());
+ }
+ }
+ }
+
+ Thread readInput = new Thread(new Runnable() {
+ public void run() {
+ try {
+ String readLine;
+ while ((readLine = processNormal.readLine()) != null) {
+ if (compilationOutput != null) {
+ compilationOutput.addMessage(readLine, MessageList.NORMAL);
+ }
+ }
+ } catch (IOException e) {
+ logger.warn("Error while reading from process");
+ }
+ }
+ }, "read input stream thread");
+
+ Thread readError = new Thread(new Runnable() {
+ public void run() {
+ try {
+ String readLine;
+ while ((readLine = processError.readLine()) != null) {
+ if (compilationOutput != null) {
+ compilationOutput.addMessage(readLine, MessageList.ERROR);
+ }
+ }
+ } catch (IOException e) {
+ logger.warn("Error while reading from process");
+ }
+ }
+ }, "read input stream thread");
+
+ final MoteTypeCreationException syncException =
+ new MoteTypeCreationException("");
+ Thread handleCompilationResultThread = new Thread(new Runnable() {
+ public void run() {
+
+ /* Wait for compilation to end */
+ try {
+ compileProcess.waitFor();
+ } catch (Exception e) {
+ if (compilationOutput != null) {
+ compilationOutput.addMessage(e.getMessage(), MessageList.ERROR);
+ }
+ syncException.setCompilationOutput(new MessageList());
+ syncException.fillInStackTrace();
+ return;
+ }
+
+ /* Check return value */
+ if (compileProcess.exitValue() != 0) {
+ if (compilationOutput != null) {
+ compilationOutput.addMessage("Process returned error code " + compileProcess.exitValue(), MessageList.ERROR);
+ }
+ if (failAction != null) {
+ failAction.actionPerformed(null);
+ }
+ syncException.setCompilationOutput(new MessageList());
+ syncException.fillInStackTrace();
+ return;
+ }
+
+ if (firmware == null) {
+ return;
+ }
+
+ if (!ELFFile.exists()) {
+ if (compilationOutput != null) {
+ compilationOutput.addMessage("Can't locate output file " + ELFFile, MessageList.ERROR);
+ }
+ if (failAction != null) {
+ failAction.actionPerformed(null);
+ }
+ syncException.setCompilationOutput(new MessageList());
+ syncException.fillInStackTrace();
+ return;
+ }
+
+ if (compilationOutput != null) {
+ compilationOutput.addMessage("", MessageList.NORMAL);
+ compilationOutput.addMessage("Compilation succeded", MessageList.NORMAL);
+ }
+ MicaELFCompiler.this.lastCompileCommand = command;
+ MicaELFCompiler.this.sourceFile = sourceFile;
+ MicaELFCompiler.this.ELFFile = ELFFile;
+ if (successAction != null) {
+ successAction.actionPerformed(null);
+ }
+ }
+ }, "handle compilation results");
+
+ readInput.start();
+ readError.start();
+ handleCompilationResultThread.start();
+
+ if (synchronous) {
+ try {
+ handleCompilationResultThread.join();
+ } catch (Exception e) {
+ throw (MoteTypeCreationException) new MoteTypeCreationException(
+ "Compilation error: " + e.getMessage()).initCause(e);
+ }
+
+ /* Detect error manually */
+ if (syncException.hasCompilationOutput()) {
+ throw (MoteTypeCreationException) new MoteTypeCreationException(
+ "Bad return value").initCause(syncException);
+ }
+ }
+
+ else {
+ }
+ } catch (IOException ex) {
+ if (failAction != null) {
+ failAction.actionPerformed(null);
+ }
+ throw (MoteTypeCreationException) new MoteTypeCreationException(
+ "Compilation error: " + ex.getMessage()).initCause(ex);
+ }
+ }
+
+ public boolean showDialog(Container parentContainer, final MicaZMoteType moteType) {
+
+ if (parentContainer instanceof Window) {
+ myDialog = new JDialog((Window)parentContainer, "Compile firmware file", ModalityType.APPLICATION_MODAL);
+ } else if (parentContainer instanceof Dialog) {
+ myDialog = new JDialog((Dialog)parentContainer, "Compile firmware file", ModalityType.APPLICATION_MODAL);
+ } else if (parentContainer instanceof Frame) {
+ myDialog = new JDialog((Frame)parentContainer, "Compile firmware file", ModalityType.APPLICATION_MODAL);
+ } else {
+ logger.fatal("Unknown parent container type: " + parentContainer);
+ return false;
+ }
+
+ final MessageList taskOutput = new MessageList();
+
+ // BOTTOM BUTTON PART
+ Box buttonBox = Box.createHorizontalBox();
+ buttonBox.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
+
+ buttonBox.add(Box.createHorizontalGlue());
+
+ cancelButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ sourceFile = null;
+ ELFFile = null;
+
+ if (compileProcess != null) {
+ compileProcess.destroy();
+ }
+ myDialog.dispose();
+ }
+ });
+
+ cleanButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ File parentDir = new File(sourceTextField.getText()).getParentFile();
+ compileFirmware(
+ "make clean TARGET=" + target, new File(sourceTextField.getText()), null,
+ parentDir, null, null, taskOutput, true);
+ } catch (Exception e2) {
+ }
+ }
+ }).start();
+ }
+ });
+
+ compileButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ final File selectedSourceFile = new File(sourceTextField.getText());
+
+ /* Strip .c file extension */
+ if (!selectedSourceFile.getName().endsWith(".c")) {
+ logger.fatal("Source file does not end with '.c'");
+ return;
+ }
+
+ final String filenameNoExtension = selectedSourceFile.getName()
+ .substring(0, selectedSourceFile.getName().length() - 2);
+
+ final Action successAction = new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ updateDialog(DialogState.COMPILED_SOURCE);
+ File parentFile = selectedSourceFile.getParentFile();
+
+ sourceFile = selectedSourceFile;
+ ELFFile = new File(parentFile, filenameNoExtension + getTargetFileExtension(target));
+ }
+ };
+ final Action failAction = new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ updateDialog(DialogState.SELECTED_SOURCE);
+ }
+ };
+
+ updateDialog(DialogState.IS_COMPILING);
+ try {
+ new Thread(new Runnable() {
+ public void run() {
+ try {
+ compileFirmware(selectedSourceFile,
+ successAction, failAction,
+ taskOutput, false);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ } catch (Exception e2) {
+ }
+ }
+ });
+
+ createButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ myDialog.dispose();
+ }
+ });
+
+ buttonBox.add(cancelButton);
+ buttonBox.add(Box.createHorizontalStrut(5));
+ buttonBox.add(cleanButton);
+ buttonBox.add(Box.createHorizontalStrut(5));
+ buttonBox.add(compileButton);
+ buttonBox.add(Box.createHorizontalStrut(5));
+ buttonBox.add(createButton);
+
+ // MAIN DIALOG CONTENTS
+ Box horizBox;
+ JLabel label;
+ Box vertBox = Box.createVerticalBox();
+
+ // Source
+ horizBox = Box.createHorizontalBox();
+ horizBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, LABEL_HEIGHT));
+ horizBox.setAlignmentX(Component.LEFT_ALIGNMENT);
+ label = new JLabel("Contiki process sourcefile");
+ label.setPreferredSize(new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
+
+ sourceTextField.setText("");
+ if (moteType.getSourceFile() != null) {
+ sourceTextField.setText(moteType.getSourceFile().getAbsolutePath());
+ }
+ sourceTextField.setColumns(25);
+
+ sourceTextField.getDocument().addDocumentListener(new DocumentListener() {
+ public void insertUpdate(DocumentEvent e) {
+ updateDialog(DialogState.SELECTED_SOURCE);
+ }
+ public void changedUpdate(DocumentEvent e) {
+ updateDialog(DialogState.SELECTED_SOURCE);
+ }
+ public void removeUpdate(DocumentEvent e) {
+ updateDialog(DialogState.SELECTED_SOURCE);
+ }
+ });
+
+ JButton browseButton = new JButton("Browse");
+ browseButton.addActionListener(new ActionListener() {
+ public void actionPerformed(ActionEvent e) {
+ updateDialog(DialogState.NO_SOURCE);
+
+ JFileChooser fc = new JFileChooser();
+ if (lastParentDirectory != null) {
+ fc.setCurrentDirectory(lastParentDirectory);
+ } else {
+ fc.setCurrentDirectory(new java.io.File(GUI
+ .getExternalToolsSetting("PATH_CONTIKI")));
+ }
+
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ fc.addChoosableFileFilter(new FileFilter() {
+ public boolean accept(File f) {
+ if (f.isDirectory()) {
+ return true;
+ }
+
+ String filename = f.getName();
+ if (filename != null) {
+ if (filename.endsWith(".c")) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public String getDescription() {
+ return "Contiki process source";
+ }
+ });
+ fc.setDialogTitle("Select Contiki process source");
+
+ if (fc.showOpenDialog(myDialog) == JFileChooser.APPROVE_OPTION) {
+ lastParentDirectory = null;
+ sourceTextField.setText("");
+
+ File selectedFile = fc.getSelectedFile();
+ if (!selectedFile.exists()) {
+ return;
+ }
+
+ if (!selectedFile.getName().endsWith(".c")) {
+ return;
+ }
+
+ lastParentDirectory = fc.getSelectedFile().getParentFile();
+ sourceTextField.setText(fc.getSelectedFile().getAbsolutePath());
+ updateDialog(DialogState.SELECTED_SOURCE);
+ }
+ }
+ });
+
+ horizBox.add(label);
+ horizBox.add(Box.createHorizontalStrut(10));
+ horizBox.add(sourceTextField);
+ horizBox.add(browseButton);
+
+ vertBox.add(horizBox);
+ vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
+
+ // Node ID
+ /*
+ * horizBox = Box.createHorizontalBox(); horizBox.setMaximumSize(new
+ * Dimension(Integer.MAX_VALUE,LABEL_HEIGHT));
+ * horizBox.setAlignmentX(Component.LEFT_ALIGNMENT); label = new
+ * JLabel("Node ID (0=EEPROM)"); label.setPreferredSize(new
+ * Dimension(LABEL_WIDTH,LABEL_HEIGHT));
+ *
+ * nodeIDTextField = new JFormattedTextField(integerFormat);
+ * nodeIDTextField.setValue(new Integer(0));
+ * nodeIDTextField.setColumns(25);
+ * nodeIDTextField.addPropertyChangeListener("value", new
+ * PropertyChangeListener() { public void
+ * propertyChange(PropertyChangeEvent e) {
+ * updateDialog(DialogState.SELECTED_SOURCE); } });
+ *
+ * horizBox.add(label); horizBox.add(Box.createHorizontalStrut(150));
+ * horizBox.add(nodeIDTextField);
+ *
+ * vertBox.add(horizBox); vertBox.add(Box.createRigidArea(new
+ * Dimension(0,5)));
+ */
+
+ // Compile command
+ horizBox = Box.createHorizontalBox();
+ horizBox.setMaximumSize(new Dimension(Integer.MAX_VALUE, LABEL_HEIGHT));
+ horizBox.setAlignmentX(Component.LEFT_ALIGNMENT);
+ label = new JLabel("Compile command");
+ label.setPreferredSize(new Dimension(LABEL_WIDTH, LABEL_HEIGHT));
+
+ compileCommandTextField.setText("");
+ compileCommandTextField.setColumns(25);
+ compileCommandTextField.setEditable(true);
+
+ compileCommandTextField.getDocument().addDocumentListener(new DocumentListener() {
+ public void insertUpdate(DocumentEvent e) {
+ setCompileCommand(compileCommandTextField.getText());
+ }
+ public void changedUpdate(DocumentEvent e) {
+ setCompileCommand(compileCommandTextField.getText());
+ }
+ public void removeUpdate(DocumentEvent e) {
+ setCompileCommand(compileCommandTextField.getText());
+ }
+ });
+
+ horizBox.add(label);
+ horizBox.add(Box.createHorizontalStrut(10));
+ horizBox.add(compileCommandTextField);
+
+ vertBox.add(horizBox);
+ vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
+
+ vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
+ vertBox.add(new JLabel("Compilation output:"));
+ vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
+
+ vertBox.add(new JScrollPane(taskOutput));
+ vertBox.add(Box.createRigidArea(new Dimension(0, 5)));
+
+ vertBox.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
+ Container contentPane = myDialog.getContentPane();
+ contentPane.add(vertBox, BorderLayout.CENTER);
+ contentPane.add(buttonBox, BorderLayout.SOUTH);
+
+ myDialog.pack();
+ myDialog.setLocationRelativeTo(parentContainer);
+ myDialog.getRootPane().setDefaultButton(compileButton);
+
+ // Dispose on escape key
+ InputMap inputMap = myDialog.getRootPane().getInputMap(
+ JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
+ inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0, false),
+ "dispose");
+ AbstractAction cancelAction = new AbstractAction() {
+ public void actionPerformed(ActionEvent e) {
+ cancelButton.doClick();
+ }
+ };
+ myDialog.getRootPane().getActionMap().put("dispose", cancelAction);
+
+ myDialog.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
+ myDialog.addWindowListener(new WindowListener() {
+ public void windowDeactivated(WindowEvent e) {
+ }
+
+ public void windowIconified(WindowEvent e) {
+ }
+
+ public void windowDeiconified(WindowEvent e) {
+ }
+
+ public void windowOpened(WindowEvent e) {
+ }
+
+ public void windowClosed(WindowEvent e) {
+ }
+
+ public void windowActivated(WindowEvent e) {
+ }
+
+ public void windowClosing(WindowEvent e) {
+ cancelButton.doClick();
+ }
+ });
+
+ updateDialog(DialogState.NO_SOURCE);
+ if (moteType.getSourceFile() != null) {
+ updateDialog(DialogState.SELECTED_SOURCE);
+ if (customizedCompileCommand != null && !customizedCompileCommand.equals("")) {
+ compileCommandTextField.setText(customizedCompileCommand);
+ }
+ compileButton.requestFocus();
+ }
+
+ myDialog.setVisible(true);
+
+ return sourceFile != null;
+ }
+
+ }
+
+ 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(getIdentifier());
+ 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(getDescription());
+ smallPane.add(BorderLayout.EAST, label);
+ panel.add(smallPane);
+
+ // ELF Hex file
+ smallPane = new JPanel(new BorderLayout());
+ label = new JLabel("ELF file");
+ smallPane.add(BorderLayout.WEST, label);
+ File elfFile = new File(getELFFile());
+ label = new JLabel(elfFile.getName());
+ label.setToolTipText(elfFile.getPath());
+ smallPane.add(BorderLayout.EAST, label);
+ panel.add(smallPane);
+
+ // Source file
+ smallPane = new JPanel(new BorderLayout());
+ label = new JLabel("Source file");
+ smallPane.add(BorderLayout.WEST, label);
+ if (getSourceFile() != null) {
+ label = new JLabel(getSourceFile().getName());
+ label.setToolTipText(getSourceFile().getPath());
+ } else {
+ label = new JLabel("[not specified]");
+ }
+ smallPane.add(BorderLayout.EAST, label);
+ panel.add(smallPane);
+
+ // Icon (if available)
+ if (!GUI.isVisualizedInApplet()) {
+ Icon moteTypeIcon = getMoteTypeIcon();
+ if (moteTypeIcon != null) {
+ smallPane = new JPanel(new BorderLayout());
+ label = new JLabel(moteTypeIcon);
+ smallPane.add(BorderLayout.CENTER, label);
+ panel.add(smallPane);
+ }
+ } else {
+ smallPane = new JPanel(new BorderLayout());
+ label = new JLabel("No icon available in applet mode");
+ smallPane.add(BorderLayout.CENTER, label);
+ panel.add(smallPane);
+ }
+
+ panel.add(Box.createRigidArea(new Dimension(0, 5)));
+ return panel;
+ }
+
+ public Icon getMoteTypeIcon() {
+ return null;
+ }
+
+ public ProjectConfig getConfig() {
+ logger.warn("MicaZ mote type project config not implemented");
+ return null;
+ }
+
+ public Collection getConfigXML() {
+ Vector config = new Vector();
+
+ Element element;
+
+ // Identifier
+ element = new Element("identifier");
+ element.setText(getIdentifier());
+ config.add(element);
+
+ // Description
+ element = new Element("description");
+ element.setText(getDescription());
+ config.add(element);
+
+ // Source file
+ if (fileSource != null) {
+ element = new Element("source");
+ fileSource = GUI.stripAbsoluteContikiPath(fileSource);
+ element.setText(fileSource.getPath().replaceAll("\\\\", "/"));
+ config.add(element);
+ element = new Element("command");
+ element.setText(compileCommand);
+ config.add(element);
+ } else {
+ // ELF file
+ element = new Element("elf");
+ File file = new File(fileFirmware);
+ file = GUI.stripAbsoluteContikiPath(file);
+ fileFirmware = file.getAbsolutePath();
+ element.setText(file.getPath().replaceAll("\\\\", "/"));
+ config.add(element);
+ }
+
+ return config;
+ }
+
+ public boolean setConfigXML(Simulation simulation,
+ Collection configXML, boolean visAvailable)
+ throws MoteTypeCreationException {
+ for (Element element : configXML) {
+ String name = element.getName();
+
+ if (name.equals("identifier")) {
+ identifier = element.getText();
+ } else if (name.equals("description")) {
+ description = element.getText();
+ } else if (name.equals("source")) {
+ fileSource = new File(element.getText());
+ } else if (name.equals("command")) {
+ compileCommand = element.getText();
+ } else if (name.equals("elf")) {
+ fileFirmware = new File(element.getText()).getAbsolutePath();
+ } else {
+ logger.fatal("Unrecognized entry in loaded configuration: " + name);
+ throw new MoteTypeCreationException(
+ "Unrecognized entry in loaded configuration: " + name);
+ }
+ }
+
+ return configureAndInit(GUI.getTopParentContainer(), simulation, visAvailable);
+ }
+
+ @Override
+ public boolean configureAndInit(Container parentContainer,
+ Simulation simulation, boolean visAvailable)
+ throws MoteTypeCreationException {
+ if (GUI.isVisualizedInApplet()) {
+ String firmware = GUI.getExternalToolsSetting("MICAZ_FIRMWARE", "");
+ if (!firmware.equals("")) {
+ setELFFile(new File(firmware));
+ JOptionPane.showMessageDialog(GUI.getTopParentContainer(),
+ "Creating mote type from precompiled firmware: " + firmware,
+ "Compiled firmware file available", JOptionPane.INFORMATION_MESSAGE);
+ } else {
+ JOptionPane.showMessageDialog(GUI.getTopParentContainer(),
+ "No precompiled firmware found",
+ "Compiled firmware file not available", JOptionPane.ERROR_MESSAGE);
+ return false;
+ }
+ }
+ return configureAndInitMicaZType(parentContainer, simulation, visAvailable, target, targetNice);
+ }
+
+}
diff --git a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZLED.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZLED.java
new file mode 100755
index 000000000..46b9e63a1
--- /dev/null
+++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZLED.java
@@ -0,0 +1,195 @@
+/*
+ * 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: MicaZLED.java,v 1.1 2009/02/22 16:45:01 joxe Exp $
+ */
+
+package se.sics.cooja.avrmote.interfaces;
+
+import java.awt.*;
+import java.util.*;
+import javax.swing.*;
+import org.apache.log4j.Logger;
+import org.jdom.Element;
+
+import avrora.sim.FiniteStateMachine;
+import avrora.sim.platform.MicaZ;
+import se.sics.cooja.*;
+import se.sics.cooja.interfaces.LED;
+
+/**
+ * @author Joakim Eriksson
+ */
+@ClassDescription("MicaZ LED")
+public class MicaZLED extends LED {
+ private static Logger logger = Logger.getLogger(MicaZLED.class);
+
+ private boolean blueOn = false;
+ private boolean greenOn = false;
+ private boolean redOn = false;
+
+ private static final Color DARK_BLUE = new Color(0, 0, 100);
+ private static final Color DARK_GREEN = new Color(0, 100, 0);
+ private static final Color DARK_RED = new Color(100, 0, 0);
+ private static final Color BLUE = new Color(0, 0, 255);
+ private static final Color GREEN = new Color(0, 255, 0);
+ private static final Color RED = new Color(255, 0, 0);
+
+ public MicaZLED(MicaZ micaZ) {
+ avrora.sim.platform.LED.LEDGroup leds =
+ (avrora.sim.platform.LED.LEDGroup) micaZ.getDevice("leds");
+ leds.leds[0].getFSM().insertProbe(new FiniteStateMachine.Probe() {
+ public void fireAfterTransition(int old, int newstate) {
+ redOn = newstate > 0;
+ setChanged();
+ notifyObservers();
+ }
+ public void fireBeforeTransition(int arg0, int arg1) {
+ }
+ });
+ leds.leds[1].getFSM().insertProbe(new FiniteStateMachine.Probe() {
+ public void fireAfterTransition(int old, int newstate) {
+ blueOn = newstate > 0;
+ setChanged();
+ notifyObservers();
+ }
+ public void fireBeforeTransition(int arg0, int arg1) {
+ }
+ });
+ leds.leds[2].getFSM().insertProbe(new FiniteStateMachine.Probe() {
+ public void fireAfterTransition(int old, int newstate) {
+ greenOn = newstate > 0;
+ setChanged();
+ notifyObservers();
+ }
+ public void fireBeforeTransition(int arg0, int arg1) {
+ }
+ });
+ }
+
+ public boolean isAnyOn() {
+ return blueOn || greenOn || redOn;
+ }
+
+ public boolean isGreenOn() {
+ return greenOn;
+ }
+
+ public boolean isYellowOn() {
+ return blueOn; /* Returning blue */
+ }
+
+ public boolean isRedOn() {
+ return redOn;
+ }
+
+ public double energyConsumption() {
+ return 0;
+ }
+
+ public JPanel getInterfaceVisualizer() {
+ final JPanel panel = new JPanel() {
+ public void paintComponent(Graphics g) {
+ super.paintComponent(g);
+
+ int x = 20;
+ int y = 25;
+ int d = 25;
+
+ if (isGreenOn()) {
+ g.setColor(GREEN);
+ g.fillOval(x, y, d, d);
+ g.setColor(Color.BLACK);
+ g.drawOval(x, y, d, d);
+ } else {
+ g.setColor(DARK_GREEN);
+ g.fillOval(x + 5, y + 5, d-10, d-10);
+ }
+
+ x += 40;
+
+ if (isRedOn()) {
+ g.setColor(RED);
+ g.fillOval(x, y, d, d);
+ g.setColor(Color.BLACK);
+ g.drawOval(x, y, d, d);
+ } else {
+ g.setColor(DARK_RED);
+ g.fillOval(x + 5, y + 5, d-10, d-10);
+ }
+
+ x += 40;
+
+ if (isYellowOn()) {
+ g.setColor(BLUE);
+ g.fillOval(x, y, d, d);
+ g.setColor(Color.BLACK);
+ g.drawOval(x, y, d, d);
+ } else {
+ g.setColor(DARK_BLUE);
+ g.fillOval(x + 5, y + 5, d-10, d-10);
+ }
+ }
+ };
+
+ Observer observer;
+ this.addObserver(observer = new Observer() {
+ public void update(Observable obs, Object obj) {
+ panel.repaint();
+ }
+ });
+
+ // Saving observer reference for releaseInterfaceVisualizer
+ panel.putClientProperty("intf_obs", observer);
+
+ panel.setMinimumSize(new Dimension(140, 60));
+ panel.setPreferredSize(new Dimension(140, 60));
+
+ return panel;
+ }
+
+ public void releaseInterfaceVisualizer(JPanel panel) {
+ Observer observer = (Observer) panel.getClientProperty("intf_obs");
+ if (observer == null) {
+ logger.fatal("Error when releasing panel, observer is null");
+ return;
+ }
+
+ this.deleteObserver(observer);
+ }
+
+
+ public Collection getConfigXML() {
+ return null;
+ }
+
+ public void setConfigXML(Collection configXML, boolean visAvailable) {
+ }
+
+}
+
diff --git a/tools/cooja/config/external_tools_win32.config b/tools/cooja/config/external_tools_win32.config
index 3101743c4..958007bc6 100644
--- a/tools/cooja/config/external_tools_win32.config
+++ b/tools/cooja/config/external_tools_win32.config
@@ -22,7 +22,7 @@ CONTIKI_STANDARD_PROCESSES = sensors_process;etimer_process
CONTIKI_MAIN_TEMPLATE_FILENAME = contiki_template.c
CORECOMM_TEMPLATE_FILENAME = corecomm_template.java
PATH_JAVAC = javac
-DEFAULT_PROJECTDIRS = ../apps/mrm;../apps/mspsim
+DEFAULT_PROJECTDIRS = ../apps/mrm;../apps/mspsim;../apps/avrora
PARSE_WITH_COMMAND = true
PARSE_COMMAND=nm -C $(LIBFILE)