From 969154c6f0b1c4e53181c190d3f8846ac44cf8ea Mon Sep 17 00:00:00 2001 From: fros4943 Date: Thu, 17 Sep 2009 10:45:13 +0000 Subject: [PATCH] added some basic functionality for cooja motes like save/load support, compile dialog, and configurable mote interfaces. some parts are still missing (memory r/w access and mote IDs) + code restructuring preparing for a generic emulated mote type layer in cooja (made avrora-based motes look more like mspsim-based motes) --- .../cooja/avrmote/MicaZCompileDialog.java | 101 ++ .../src/se/sics/cooja/avrmote/MicaZMote.java | 155 +-- .../se/sics/cooja/avrmote/MicaZMoteType.java | 1163 ++++------------- .../cooja/avrmote/interfaces/MicaClock.java | 13 +- .../cooja/avrmote/interfaces/MicaSerial.java | 94 +- .../cooja/avrmote/interfaces/MicaZID.java | 92 ++ .../cooja/avrmote/interfaces/MicaZLED.java | 403 +++--- .../cooja/avrmote/interfaces/MicaZRadio.java | 8 +- 8 files changed, 750 insertions(+), 1279 deletions(-) create mode 100644 tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZCompileDialog.java create mode 100644 tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZID.java diff --git a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZCompileDialog.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZCompileDialog.java new file mode 100644 index 000000000..498a59dc7 --- /dev/null +++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZCompileDialog.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2009, 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: MicaZCompileDialog.java,v 1.1 2009/09/17 10:45:14 fros4943 Exp $ + */ + +package se.sics.cooja.avrmote; + +import java.awt.Container; +import java.io.File; + +import org.apache.log4j.Logger; + +import se.sics.cooja.GUI; +import se.sics.cooja.MoteInterface; +import se.sics.cooja.MoteType; +import se.sics.cooja.Simulation; +import se.sics.cooja.dialogs.AbstractCompileDialog; + +public class MicaZCompileDialog extends AbstractCompileDialog { + private static Logger logger = Logger.getLogger(MicaZCompileDialog.class); + + public static boolean showDialog( + Container parent, + Simulation simulation, + MoteType moteType) { + + final AbstractCompileDialog dialog = new MicaZCompileDialog(parent, simulation, moteType); + + /* Show dialog and wait for user */ + dialog.setVisible(true); /* BLOCKS */ + if (!dialog.createdOK()) { + return false; + } + + /* Assume that if a firmware exists, compilation was ok */ + return true; + } + + private MicaZCompileDialog(Container parent, Simulation simulation, MoteType moteType) { + super(parent, simulation, moteType); + + /* Add all available MicaZ mote interfaces + * Selected by default unless interfaces already configured */ + boolean selected = true; + if (moteIntfBox.getComponentCount() > 0) { + selected = false; + } + + for (Class intfClass: ((MicaZMoteType)moteType).getAllMoteInterfaceClasses()) { + addMoteInterface(intfClass, selected); + } + } + + public boolean canLoadFirmware(File file) { + if (file.getName().endsWith(".elf")) { + return true; + } + return false; + } + + public String getDefaultCompileCommands(File source) { + /* TODO Split into String[] */ + return + /*"make clean TARGET=micaz\n" + */ + GUI.getExternalToolsSetting("PATH_MAKE") + " " + getExpectedFirmwareFile(source).getName() + " TARGET=micaz"; + } + + public File getExpectedFirmwareFile(File source) { + return ((MicaZMoteType)moteType).getExpectedFirmwareFile(source); + } + + public void writeSettingsToMoteType() { + /* Nothing to do */ + } +} 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 index 1d6659bef..96edadc78 100755 --- a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMote.java +++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMote.java @@ -26,16 +26,19 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: MicaZMote.java,v 1.6 2009/03/19 18:58:19 joxe Exp $ + * $Id: MicaZMote.java,v 1.7 2009/09/17 10:45:14 fros4943 Exp $ */ package se.sics.cooja.avrmote; + +import java.io.File; import java.util.Collection; -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.Mote; import se.sics.cooja.MoteInterface; import se.sics.cooja.MoteInterfaceHandler; @@ -46,15 +49,18 @@ import se.sics.cooja.avrmote.interfaces.MicaClock; import se.sics.cooja.avrmote.interfaces.MicaSerial; import se.sics.cooja.avrmote.interfaces.MicaZLED; import se.sics.cooja.avrmote.interfaces.MicaZRadio; +import se.sics.cooja.interfaces.MoteID; import se.sics.cooja.interfaces.Position; -import avrora.sim.*; -import avrora.sim.platform.*; -import avrora.sim.mcu.*; -import avrora.core.*; - +import avrora.core.LoadableProgram; +import avrora.sim.Interpreter; +import avrora.sim.Simulator; +import avrora.sim.State; +import avrora.sim.mcu.Microcontroller; +import avrora.sim.platform.MicaZ; +import avrora.sim.platform.PlatformFactory; /** - * @author Joakim Eriksson + * @author Joakim Eriksson, Fredrik Osterlind */ public class MicaZMote implements Mote { private static Logger logger = Logger.getLogger(MicaZMote.class); @@ -64,9 +70,10 @@ public class MicaZMote implements Mote { /* Cycle counter */ public long cycleCounter = 0; - public long cycleDrift = 0; + public long usDrift = 0; /* us */ private Simulation mySimulation = null; + private MoteInterfaceHandler myMoteInterfaceHandler; private Microcontroller myCpu = null; private MicaZ micaZ = null; private LoadableProgram program = null; @@ -77,7 +84,29 @@ public class MicaZMote implements Mote { /* Stack monitoring variables */ private boolean stopNextInstruction = false; - private MoteInterfaceHandler myMoteInterfaceHandler; + + public MicaZMote() { + myMoteType = null; + mySimulation = null; + myCpu = null; + /* TODO myMemory = null; */ + myMoteInterfaceHandler = null; + } + + public MicaZMote(Simulation simulation, MicaZMoteType type) { + mySimulation = simulation; + myMoteType = type; + } + + protected boolean initEmulator(File fileELF) { + try { + prepareMote(fileELF); + } catch (Exception e) { + logger.fatal("Error when creating MicaZ mote: ", e); + return false; + } + return true; + } /** * Abort current tick immediately. @@ -87,40 +116,21 @@ public class MicaZMote implements Mote { stopNextInstruction = true; } + private MoteInterfaceHandler createMoteInterfaceHandler() { + return new MoteInterfaceHandler(this, getType().getMoteInterfaceClasses()); + } + public MicaZ getMicaZ() { return micaZ; } - 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.getContikiFirmwareFile().getAbsolutePath()); + initEmulator(myMoteType.getContikiFirmwareFile()); myMoteInterfaceHandler = createMoteInterfaceHandler(); } } - protected boolean initEmulator(String fileELF) { - //System.out.println("Loading elf file: " + fileELF); - try { - prepareMote(fileELF); - } catch (Exception e) { - logger.fatal("Error when creating MicaZ mote:", e); - return false; - } - return true; - } - - public Simulation getSimulation() { return mySimulation; } @@ -136,7 +146,7 @@ public class MicaZMote implements Mote { * @param cpu MSP430 cpu * @throws Exception */ - protected void prepareMote(String file) throws Exception { + protected void prepareMote(File file) throws Exception { program = new LoadableProgram(file); program.load(); PlatformFactory factory = new MicaZ.Factory(); @@ -151,8 +161,8 @@ public class MicaZMote implements Mote { logger.warn("MicaZ motes can't change state"); } - public State getState() { - return Mote.State.ACTIVE; + public int getID() { + return getInterfaces().getMoteID().getMoteID(); } /* called when moteID is updated */ @@ -164,13 +174,6 @@ public class MicaZMote implements Mote { } public void setType(MoteType type) { - //myMoteType = (MspMoteType) type; - } - - public void addStateObserver(Observer newObserver) { - } - - public void deleteStateObserver(Observer newObserver) { } public MoteInterfaceHandler getInterfaces() { @@ -182,24 +185,18 @@ public class MicaZMote implements Mote { } /* 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"); + throw new RuntimeException("Avrora 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); + if (simTime + usDrift < 0) { + return false; } - long maxSimTimeCycles = NR_CYCLES_PER_MSEC * (simTime + 1) + cycleDrift; - + long maxSimTimeCycles = (long)(NR_CYCLES_PER_MSEC * ((simTime+usDrift+Simulation.MILLISECOND)/(double)Simulation.MILLISECOND)); if (maxSimTimeCycles <= cycleCounter) { return false; } @@ -211,17 +208,10 @@ public class MicaZMote implements Mote { /* CPU already ticked too far - just wait it out */ return true; } - // myMoteInterfaceHandler.doActiveActionsBeforeTick(); + 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; } @@ -235,12 +225,7 @@ public class MicaZMote implements Mote { myMoteType = (MicaZMoteType) simulation.getMoteType(element.getText()); getType().setIdentifier(element.getText()); - try { - prepareMote(myMoteType.getContikiFirmwareFile().getAbsolutePath()); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } + initEmulator(myMoteType.getContikiFirmwareFile()); myMoteInterfaceHandler = createMoteInterfaceHandler(); } else if (name.equals("interface_config")) { @@ -260,29 +245,6 @@ public class MicaZMote implements Mote { 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 - moteInterfaceHandler.addInterface(new MicaZLED(micaZ)); - // Add Radio interface - moteInterfaceHandler.addInterface(new MicaZRadio(this)); - // Add Clock interface - moteInterfaceHandler.addInterface(new MicaClock(this)); - // Add Serial interface - moteInterfaceHandler.addInterface(new MicaSerial(this)); - - - return moteInterfaceHandler; - } - public Collection getConfigXML() { Vector config = new Vector(); @@ -309,10 +271,21 @@ public class MicaZMote implements Mote { } public MoteMemory getMemory() { + /* TODO Implement */ return null; } public void setMemory(MoteMemory memory) { + /* TODO Implement */ + } + + public String toString() { + MoteID moteID = getInterfaces() != null ? getInterfaces().getMoteID() : null; + if (moteID != null) { + return "MicaZ Mote, ID=" + moteID.getMoteID(); + } else { + return "MicaZ Mote, ID=null"; + } } } 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 index dcb38b1d6..19a4956a0 100644 --- a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMoteType.java +++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/MicaZMoteType.java @@ -26,51 +26,69 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: MicaZMoteType.java,v 1.5 2009/03/21 14:51:03 fros4943 Exp $ + * $Id: MicaZMoteType.java,v 1.6 2009/09/17 10:45:14 fros4943 Exp $ */ package se.sics.cooja.avrmote; -import java.awt.*; -import java.awt.Dialog.ModalityType; -import java.awt.event.*; -import java.io.*; +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Dimension; +import java.io.File; +import java.util.ArrayList; 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 javax.swing.BorderFactory; +import javax.swing.Box; +import javax.swing.BoxLayout; +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextArea; + import org.apache.log4j.Logger; import org.jdom.Element; -import se.sics.cooja.*; + +import se.sics.cooja.AbstractionLevelDescription; +import se.sics.cooja.ClassDescription; +import se.sics.cooja.GUI; +import se.sics.cooja.Mote; +import se.sics.cooja.MoteInterface; +import se.sics.cooja.MoteType; +import se.sics.cooja.ProjectConfig; +import se.sics.cooja.Simulation; +import se.sics.cooja.avrmote.interfaces.MicaClock; +import se.sics.cooja.avrmote.interfaces.MicaSerial; +import se.sics.cooja.avrmote.interfaces.MicaZID; +import se.sics.cooja.avrmote.interfaces.MicaZLED; +import se.sics.cooja.avrmote.interfaces.MicaZRadio; +import se.sics.cooja.dialogs.CompileContiki; import se.sics.cooja.dialogs.MessageList; import se.sics.cooja.dialogs.MessageList.MessageContainer; +import se.sics.cooja.interfaces.Position; -@AbstractionLevelDescription("Emulated level") +/** + * AVR-based MicaZ mote types emulated in Avrora. + * + * @author Joakim Eriksson, Fredrik Osterlind + */ @ClassDescription("MicaZ Mote Type") +@AbstractionLevelDescription("Emulated level") public class MicaZMoteType implements MoteType { private static Logger logger = Logger.getLogger(MicaZMoteType.class); - private Simulation simulation; - - 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 */ + protected Simulation simulation; + + /* If source file is defined, the firmware is recompiled when loading simulations */ private File fileFirmware = null; private File fileSource = null; - private String compileCommand = null; + private String compileCommands = null; + + private Class[] moteInterfaceClasses = null; public String getIdentifier() { return identifier; @@ -88,48 +106,36 @@ public class MicaZMoteType implements MoteType { this.description = description; } - public Class[] getMoteInterfaceClasses() { - logger.fatal("Not implemented"); - return null; - } - - public void setMoteInterfaceClasses(Class[] classes) { - logger.fatal("Not implemented"); - } - - public void setContikiFirmwareFile(File file) { - this.fileFirmware = file; + public String getCompileCommands() { + return compileCommands; } public void setCompileCommands(String command) { - this.compileCommand = command; + this.compileCommands = command; + } + + public File getContikiSourceFile() { + return fileSource; } public File getContikiFirmwareFile() { return fileFirmware; } - /** - * @return Compile command - */ - public String getCompileCommands() { - return compileCommand; - } - - /** - * Set source file - * - * @param file Source file - */ public void setContikiSourceFile(File file) { fileSource = file; } - /** - * @return Source file - */ - public File getContikiSourceFile() { - return fileSource; + public void setContikiFirmwareFile(File file) { + this.fileFirmware = file; + } + + public Class[] getMoteInterfaceClasses() { + return moteInterfaceClasses; + } + + public void setMoteInterfaceClasses(Class[] classes) { + moteInterfaceClasses = classes; } public final Mote generateMote(Simulation simulation) { @@ -138,841 +144,8 @@ public class MicaZMoteType implements MoteType { 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 { - this.simulation = simulation; - - 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 (getContikiSourceFile() != null) { - compileFromSource = true; - } - - if (compileFromSource) { - MicaELFCompiler compiler = new MicaELFCompiler(target); - compiler.setCompileCommand(compileCommand); - - if (visAvailable) { - boolean success = compiler.showDialog(GUI.getTopParentContainer(), this); - if (success) { - setContikiSourceFile(compiler.getSourceFile()); - setContikiFirmwareFile(compiler.getOutputFile()); - setCompileCommands(compiler.getLastCompileCommand()); - return true; - } else { - return false; - } - } else { - MessageList compilationOutput = new MessageList(); - try { - compiler.compileFirmware(getContikiSourceFile(), 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; - } - - setContikiSourceFile(compiler.getSourceFile()); - setContikiFirmwareFile(compiler.getOutputFile()); - setCompileCommands(compiler.getLastCompileCommand()); - - return true; - } - } - - if (GUI.isVisualizedInApplet()) { - return true; - } - - // Check dependency files - File elfFile = getContikiFirmwareFile(); -// if (getContikiFirmwareFile() != null) { -// elfFile = new File(getContikiFirmwareFile().getName()); -// } - if (elfFile == null || !elfFile.exists()) { - if (!visAvailable) { - throw new MoteTypeCreationException("ELF file does not exist: " + getContikiFirmwareFile()); - } - - 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; - } - - setContikiFirmwareFile(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 getCompileCommands(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(getCompileCommands(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 = getCompileCommands(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.getContikiSourceFile() != null) { - sourceTextField.setText(moteType.getContikiSourceFile().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.getContikiSourceFile() != null) { - updateDialog(DialogState.SELECTED_SOURCE); - if (customizedCompileCommand != null && !customizedCompileCommand.equals("")) { - compileCommandTextField.setText(customizedCompileCommand); - } - compileButton.requestFocus(); - } - - myDialog.setVisible(true); - - return sourceFile != null; - } - - } - public JPanel getTypeVisualizer() { + /* TODO Move to emulated layer */ JPanel panel = new JPanel(); JLabel label = new JLabel(); JPanel smallPane; @@ -995,19 +168,9 @@ public class MicaZMoteType implements MoteType { smallPane.add(BorderLayout.EAST, label); panel.add(smallPane); - // ELF Hex file + /* Contiki source */ smallPane = new JPanel(new BorderLayout()); - label = new JLabel("ELF file"); - smallPane.add(BorderLayout.WEST, label); - File elfFile = getContikiFirmwareFile(); - 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"); + label = new JLabel("Contiki source"); smallPane.add(BorderLayout.WEST, label); if (getContikiSourceFile() != null) { label = new JLabel(getContikiSourceFile().getName()); @@ -1018,7 +181,26 @@ public class MicaZMoteType implements MoteType { smallPane.add(BorderLayout.EAST, label); panel.add(smallPane); - // Icon (if available) + /* Contiki firmware */ + smallPane = new JPanel(new BorderLayout()); + label = new JLabel("Contiki firmware"); + smallPane.add(BorderLayout.WEST, label); + label = new JLabel(getContikiFirmwareFile().getName()); + label.setToolTipText(getContikiFirmwareFile().getPath()); + smallPane.add(BorderLayout.EAST, label); + panel.add(smallPane); + + /* Compile commands */ + smallPane = new JPanel(new BorderLayout()); + label = new JLabel("Compile commands"); + smallPane.add(BorderLayout.WEST, label); + JTextArea textArea = new JTextArea(getCompileCommands()); + textArea.setEditable(false); + textArea.setBorder(BorderFactory.createEmptyBorder()); + smallPane.add(BorderLayout.EAST, textArea); + panel.add(smallPane); + + /* Icon (if available) */ if (!GUI.isVisualizedInApplet()) { Icon moteTypeIcon = getMoteTypeIcon(); if (moteTypeIcon != null) { @@ -1027,11 +209,6 @@ public class MicaZMoteType implements MoteType { 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))); @@ -1039,6 +216,7 @@ public class MicaZMoteType implements MoteType { } public Icon getMoteTypeIcon() { + /* TODO Add MicaZ icon */ return null; } @@ -1068,14 +246,21 @@ public class MicaZMoteType implements MoteType { File file = simulation.getGUI().createPortablePath(fileSource); element.setText(file.getPath().replaceAll("\\\\", "/")); config.add(element); - element = new Element("command"); - element.setText(compileCommand); + element = new Element("commands"); + element.setText(compileCommands); config.add(element); - } else { - // ELF file - element = new Element("elf"); - File file = simulation.getGUI().createPortablePath(fileFirmware); - element.setText(file.getPath().replaceAll("\\\\", "/")); + } + + // Firmware file + element = new Element("firmware"); + File file = simulation.getGUI().createPortablePath(fileFirmware); + element.setText(file.getPath().replaceAll("\\\\", "/")); + config.add(element); + + // Mote interfaces + for (Class moteInterface : getMoteInterfaceClasses()) { + element = new Element("moteinterface"); + element.setText(moteInterface.getName()); config.add(element); } @@ -1084,7 +269,10 @@ public class MicaZMoteType implements MoteType { public boolean setConfigXML(Simulation simulation, Collection configXML, boolean visAvailable) - throws MoteTypeCreationException { + throws MoteTypeCreationException { + this.simulation = simulation; + + ArrayList> intfClassList = new ArrayList>(); for (Element element : configXML) { String name = element.getName(); @@ -1097,13 +285,24 @@ public class MicaZMoteType implements MoteType { if (!fileSource.exists()) { fileSource = simulation.getGUI().restorePortablePath(fileSource); } - } else if (name.equals("command")) { - compileCommand = element.getText(); - } else if (name.equals("elf")) { + } else if (name.equals("commands")) { + compileCommands = element.getText(); + } else if (name.equals("firmware")) { fileFirmware = new File(element.getText()); if (!fileFirmware.exists()) { fileFirmware = simulation.getGUI().restorePortablePath(fileSource); } + } else if (name.equals("moteinterface")) { + String intfClass = element.getText().trim(); + + Class moteInterfaceClass = + simulation.getGUI().tryLoadClass(this, MoteInterface.class, intfClass); + + if (moteInterfaceClass == null) { + logger.warn("Can't find mote interface class: " + intfClass); + } else { + intfClassList.add(moteInterfaceClass); + } } else { logger.fatal("Unrecognized entry in loaded configuration: " + name); throw new MoteTypeCreationException( @@ -1111,28 +310,124 @@ public class MicaZMoteType implements MoteType { } } + Class[] intfClasses = intfClassList.toArray(new Class[0]); + + setMoteInterfaceClasses(intfClasses); + + if (fileFirmware == null || fileSource == null) { + throw new MoteTypeCreationException("Either source or firmware not specified"); + } + 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("")) { - setContikiFirmwareFile(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; + public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable) + throws MoteTypeCreationException { + this.simulation = simulation; + + /* If visualized, show compile dialog and let user configure */ + if (visAvailable) { + + /* Create unique identifier */ + if (getIdentifier() == null) { + int counter = 0; + boolean identifierOK = false; + while (!identifierOK) { + identifierOK = true; + + counter++; + setIdentifier("micaz" + counter); + + for (MoteType existingMoteType : simulation.getMoteTypes()) { + if (existingMoteType == this) { + continue; + } + if (existingMoteType.getIdentifier().equals(getIdentifier())) { + identifierOK = false; + break; + } + } + } + } + + /* Create initial description */ + if (getDescription() == null) { + setDescription("MicaZ Mote Type #" + getIdentifier()); + } + + return MicaZCompileDialog.showDialog(parentContainer, simulation, this); + } + + /* Not visualized: Compile Contiki immediately */ + if (getIdentifier() == null) { + throw new MoteTypeCreationException("No identifier"); + } + + final MessageList compilationOutput = new MessageList(); + + if (getCompileCommands() != null) { + /* Handle multiple compilation commands one by one */ + String[] arr = getCompileCommands().split("\n"); + for (String cmd: arr) { + if (cmd.trim().isEmpty()) { + continue; + } + + try { + CompileContiki.compile( + cmd, + null, + null /* Do not observe output firmware file */, + getContikiSourceFile().getParentFile(), + 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 10 compilation errors to console */ + MessageContainer[] messages = compilationOutput.getMessages(); + for (int i=messages.length-10; i < messages.length; i++) { + if (i < 0) { + continue; + } + logger.fatal(">> " + messages[i]); + } + + logger.fatal("Compilation error: " + e.getMessage()); + throw newException; + } } } - return configureAndInitMicaZType(parentContainer, simulation, visAvailable, target, targetNice); + + if (getContikiFirmwareFile() == null || + !getContikiFirmwareFile().exists()) { + throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile()); + } + return true; + } + + public Class[] getAllMoteInterfaceClasses() { + return new Class[] { + Position.class, + MicaZID.class, + MicaZLED.class, + MicaZRadio.class, + MicaClock.class, + MicaSerial.class + }; + } + + public File getExpectedFirmwareFile(File source) { + File parentDir = source.getParentFile(); + String sourceNoExtension = source.getName().substring(0, source.getName().length()-2); + + return new File(parentDir, sourceNoExtension + ".elf"); } } diff --git a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaClock.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaClock.java index 46f720c58..bcd5dc1c5 100644 --- a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaClock.java +++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaClock.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: MicaClock.java,v 1.3 2009/05/26 14:35:52 fros4943 Exp $ + * $Id: MicaClock.java,v 1.4 2009/09/17 10:45:13 fros4943 Exp $ */ package se.sics.cooja.avrmote.interfaces; @@ -39,6 +39,7 @@ import org.jdom.Element; import se.sics.cooja.*; import se.sics.cooja.avrmote.MicaZMote; import se.sics.cooja.interfaces.Clock; +import se.sics.cooja.mspmote.MspMote; /** @@ -50,8 +51,8 @@ public class MicaClock extends Clock { private MicaZMote myMote; - public MicaClock(MicaZMote mote) { - myMote = mote; + public MicaClock(Mote mote) { + myMote = (MicaZMote) mote; } public void setTime(long newTime) { @@ -59,16 +60,16 @@ public class MicaClock extends Clock { } public long getTime() { - int time = (int) ((myMote.cycleCounter) / MicaZMote.NR_CYCLES_PER_MSEC); + long time = (long) ((double)myMote.cycleCounter * Simulation.MILLISECOND / MspMote.NR_CYCLES_PER_MSEC); return time > 0 ? time : 0; } public void setDrift(long drift) { - myMote.cycleDrift = Simulation.MILLISECOND * MicaZMote.NR_CYCLES_PER_MSEC * drift; + myMote.usDrift = drift; } public long getDrift() { - return (long) ((double)myMote.cycleDrift / MicaZMote.NR_CYCLES_PER_MSEC / Simulation.MILLISECOND); + return myMote.usDrift; } public JPanel getInterfaceVisualizer() { diff --git a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaSerial.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaSerial.java index f15afdf60..3334dc5bf 100644 --- a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaSerial.java +++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaSerial.java @@ -1,47 +1,47 @@ -package se.sics.cooja.avrmote.interfaces; - -import avrora.sim.mcu.AtmelMicrocontroller; -import avrora.sim.platform.MicaZ; -import se.sics.cooja.Mote; -import se.sics.cooja.avrmote.MicaZMote; -import se.sics.cooja.dialogs.SerialUI; - -public class MicaSerial extends SerialUI { - - Mote mote; - - public MicaSerial(MicaZMote micaZMote) { - mote = micaZMote; - MicaZ micaZ = micaZMote.getMicaZ(); - /* this should go into some other piece of code for serial data */ - AtmelMicrocontroller mcu = (AtmelMicrocontroller) micaZ.getMicrocontroller(); - avrora.sim.mcu.USART usart = (avrora.sim.mcu.USART) mcu.getDevice("usart0"); - if (usart != null) { - usart.connect( new avrora.sim.mcu.USART.USARTDevice() { - public avrora.sim.mcu.USART.Frame transmitFrame() { - return null; - // return new avrora.sim.mcu.USART.Frame((byte)'a', false, 8); - } - public void receiveFrame(avrora.sim.mcu.USART.Frame frame) { - dataReceived(frame.value); - } - }); - } else { - System.out.println("*** Warning MicaZ: could not find usart1 interface..."); - } - } - - public Mote getMote() { - return mote; - } - - /* not yet implemented ...*/ - public void writeArray(byte[] s) { - } - - public void writeByte(byte b) { - } - - public void writeString(String s) { - } -} +package se.sics.cooja.avrmote.interfaces; + +import avrora.sim.mcu.AtmelMicrocontroller; +import avrora.sim.platform.MicaZ; +import se.sics.cooja.Mote; +import se.sics.cooja.avrmote.MicaZMote; +import se.sics.cooja.dialogs.SerialUI; + +public class MicaSerial extends SerialUI { + + MicaZMote mote; + + public MicaSerial(Mote micaZMote) { + mote = (MicaZMote) micaZMote; + MicaZ micaZ = mote.getMicaZ(); + /* this should go into some other piece of code for serial data */ + AtmelMicrocontroller mcu = (AtmelMicrocontroller) micaZ.getMicrocontroller(); + avrora.sim.mcu.USART usart = (avrora.sim.mcu.USART) mcu.getDevice("usart0"); + if (usart != null) { + usart.connect( new avrora.sim.mcu.USART.USARTDevice() { + public avrora.sim.mcu.USART.Frame transmitFrame() { + return null; + // return new avrora.sim.mcu.USART.Frame((byte)'a', false, 8); + } + public void receiveFrame(avrora.sim.mcu.USART.Frame frame) { + dataReceived(frame.value); + } + }); + } else { + System.out.println("*** Warning MicaZ: could not find usart1 interface..."); + } + } + + public Mote getMote() { + return mote; + } + + /* not yet implemented ...*/ + public void writeArray(byte[] s) { + } + + public void writeByte(byte b) { + } + + public void writeString(String s) { + } +} diff --git a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZID.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZID.java new file mode 100644 index 000000000..dca4c35b7 --- /dev/null +++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZID.java @@ -0,0 +1,92 @@ +/* + * 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: MicaZID.java,v 1.1 2009/09/17 10:45:13 fros4943 Exp $ + */ + +package se.sics.cooja.avrmote.interfaces; + +import java.util.Collection; +import java.util.Vector; + +import javax.swing.JPanel; + +import org.apache.log4j.Logger; +import org.jdom.Element; + +import se.sics.cooja.Mote; +import se.sics.cooja.interfaces.MoteID; + +public class MicaZID extends MoteID { + private static Logger logger = Logger.getLogger(MicaZID.class); + + private int moteID = -1; /* TODO Implement */ + + public MicaZID(Mote mote) { + } + + public int getMoteID() { + return moteID; + } + + public void setMoteID(int newID) { + moteID = newID; + } + + public JPanel getInterfaceVisualizer() { + return null; + } + + public void releaseInterfaceVisualizer(JPanel panel) { + } + + public double energyConsumption() { + return 0; + } + + public Collection getConfigXML() { + Vector config = new Vector(); + Element element; + + // Infinite boolean + element = new Element("id"); + element.setText(Integer.toString(getMoteID())); + config.add(element); + + return config; + } + + public void setConfigXML(Collection configXML, boolean visAvailable) { + for (Element element : configXML) { + if (element.getName().equals("id")) { + setMoteID(Integer.parseInt(element.getText())); + } + } + } + +} 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 index 78dd1d03c..9286e597f 100755 --- 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 @@ -1,197 +1,206 @@ -/* - * 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.3 2009/03/19 18:58:19 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.mcu.AtmelMicrocontroller; -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) { - } - -} - +/* + * 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.4 2009/09/17 10:45:13 fros4943 Exp $ + */ + +package se.sics.cooja.avrmote.interfaces; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.util.Collection; +import java.util.Observable; +import java.util.Observer; + +import javax.swing.JPanel; + +import org.apache.log4j.Logger; +import org.jdom.Element; + +import se.sics.cooja.ClassDescription; +import se.sics.cooja.Mote; +import se.sics.cooja.avrmote.MicaZMote; +import se.sics.cooja.interfaces.LED; +import avrora.sim.FiniteStateMachine; +import avrora.sim.platform.MicaZ; + +/** + * @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(Mote mote) { + MicaZ micaZ = ((MicaZMote) mote).getMicaZ(); + + 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/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZRadio.java b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZRadio.java index eba3bb146..2375d1863 100644 --- a/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZRadio.java +++ b/tools/cooja/apps/avrora/src/se/sics/cooja/avrmote/interfaces/MicaZRadio.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: MicaZRadio.java,v 1.3 2009/04/16 14:28:12 fros4943 Exp $ + * $Id: MicaZRadio.java,v 1.4 2009/09/17 10:45:13 fros4943 Exp $ */ package se.sics.cooja.avrmote.interfaces; @@ -89,9 +89,9 @@ public class MicaZRadio extends Radio implements CustomDataRadio { Medium.Transmitter trans; CC2420Radio.Receiver recv; - public MicaZRadio(MicaZMote mote) { - this.mote = mote; - micaz = mote.getMicaZ(); + public MicaZRadio(Mote mote) { + this.mote = (MicaZMote) mote; + micaz = this.mote.getMicaZ(); cc2420 = (CC2420Radio) micaz.getDevice("radio"); trans = cc2420.getTransmitter(); recv = (CC2420Radio.Receiver) cc2420.getReceiver();