diff --git a/tools/cooja/apps/mspsim/cooja.config b/tools/cooja/apps/mspsim/cooja.config index 6aeef1496..f742a9895 100644 --- a/tools/cooja/apps/mspsim/cooja.config +++ b/tools/cooja/apps/mspsim/cooja.config @@ -1,3 +1,3 @@ -se.sics.cooja.GUI.MOTETYPES = + se.sics.cooja.mspmote.ESBMoteType se.sics.cooja.mspmote.SkyMoteType se.sics.cooja.mspmote.Exp5438MoteType +se.sics.cooja.GUI.MOTETYPES = + se.sics.cooja.mspmote.ESBMoteType se.sics.cooja.mspmote.SkyMoteType se.sics.cooja.mspmote.WismoteMoteType se.sics.cooja.mspmote.Exp5438MoteType se.sics.cooja.GUI.JARFILES = + cooja_mspsim.jar mspsim.jar coffee.jar jipv6.jar se.sics.cooja.GUI.PLUGINS = + se.sics.cooja.mspmote.plugins.MspCLI se.sics.cooja.mspmote.plugins.MspCodeWatcher se.sics.cooja.mspmote.plugins.MspStackWatcher se.sics.cooja.mspmote.plugins.MspCycleWatcher diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/AbstractMspMoteType.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/AbstractMspMoteType.java new file mode 100644 index 000000000..69a37ffe9 --- /dev/null +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/AbstractMspMoteType.java @@ -0,0 +1,205 @@ +/* + * Copyright (c) 2012, 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. + * + * ----------------------------------------------------------------- + * + * AbstractMspMoteType + * + * Authors : Fredrik Osterlind, Niclas Finne + */ + +package se.sics.cooja.mspmote; +import java.awt.Container; +import java.awt.Image; +import java.io.File; +import java.net.URL; + +import javax.swing.*; + +import org.apache.log4j.Logger; + +import se.sics.cooja.*; +import se.sics.cooja.dialogs.*; +import se.sics.cooja.dialogs.MessageList.MessageContainer; + +/** + * + */ +public abstract class AbstractMspMoteType extends MspMoteType { + + protected final Logger logger = Logger.getLogger(getClass()); + + public abstract String getMoteType(); + + public abstract String getMoteName(); + + protected abstract String getMoteImage(); + + @Override + public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable) + throws MoteTypeCreationException { + this.simulation = simulation; + + /* SPECIAL CASE: Cooja started in applet. + * Use preconfigured Contiki firmware */ + if (GUI.isVisualizedInApplet()) { + String firmware = GUI.getExternalToolsSetting(getMoteType().toUpperCase() + "_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; + } + } + + /* 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(getMoteType() + 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(getMoteName() + " Mote Type #" + getIdentifier()); + } + + return MspCompileDialog.showDialog(parentContainer, simulation, this, getMoteType()); + } + + /* 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 = Math.max(messages.length - 10, 0); i < messages.length; i++) { + logger.fatal(">> " + messages[i]); + } + + logger.fatal("Compilation error: " + e.getMessage()); + throw newException; + } + } + } + + if (getContikiFirmwareFile() == null + || !getContikiFirmwareFile().exists()) { + throw new MoteTypeCreationException( + "Contiki firmware file does not exist: " + + getContikiFirmwareFile()); + } + return true; + } + + @Override + public Icon getMoteTypeIcon() { + String imageName = getMoteImage(); + if (imageName == null) { + return null; + } + URL imageURL = this.getClass().getClassLoader().getResource(imageName); + if (imageURL == null) { + return null; + } + ImageIcon icon = new ImageIcon(imageURL); + if (icon.getIconHeight() > 0 && icon.getIconWidth() > 0) { + Image image = icon.getImage().getScaledInstance( + (200 * icon.getIconWidth() / icon.getIconHeight()), 200, + Image.SCALE_DEFAULT); + return new ImageIcon(image); + } + return null; + } + + @Override + public File getExpectedFirmwareFile(File source) { + File parentDir = source.getParentFile(); + String sourceNoExtension = source.getName(); + if (sourceNoExtension.endsWith(".c")) { + sourceNoExtension = sourceNoExtension.substring(0, source.getName().length() - 2); + } + return new File(parentDir, sourceNoExtension + '.' + getMoteType()); + } + + protected Class[] createMoteInterfaceList(Class... interfaceList) { + return interfaceList; + } + +} diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/WismoteMote.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/WismoteMote.java new file mode 100644 index 000000000..c228ab7a4 --- /dev/null +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/WismoteMote.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2012, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +package se.sics.cooja.mspmote; +import java.io.File; + +import org.apache.log4j.Logger; + +import se.sics.cooja.Simulation; +import se.sics.mspsim.platform.wismote.WismoteNode; + +/** + * @author Fredrik Osterlind, Niclas Finne + */ +public class WismoteMote extends MspMote { + + private static Logger logger = Logger.getLogger(WismoteMote.class); + + public WismoteMote() { + super(); + } + + public WismoteMote(MspMoteType moteType, Simulation sim) { + super(moteType, sim); + } + + @Override + protected boolean initEmulator(File fileELF) { + try { + WismoteNode wismoteNode = new WismoteNode(); + // TODO Should not MspMote handle the registry? + registry = wismoteNode.getRegistry(); + prepareMote(fileELF, wismoteNode); + } catch (Exception e) { + logger.fatal("Error when creating WiSMote mote: ", e); + return false; + } + return true; + } + + @Override + public String toString() { + return "Wismote " + getID(); + } + +} diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/WismoteMoteType.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/WismoteMoteType.java new file mode 100644 index 000000000..a73d44707 --- /dev/null +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/WismoteMoteType.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2012, Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +package se.sics.cooja.mspmote; +import se.sics.cooja.AbstractionLevelDescription; +import se.sics.cooja.ClassDescription; +import se.sics.cooja.MoteInterface; +import se.sics.cooja.Simulation; +import se.sics.cooja.interfaces.IPAddress; +import se.sics.cooja.interfaces.Mote2MoteRelations; +import se.sics.cooja.interfaces.MoteAttributes; +import se.sics.cooja.interfaces.Position; +import se.sics.cooja.interfaces.RimeAddress; +import se.sics.cooja.mspmote.interfaces.Msp802154Radio; +import se.sics.cooja.mspmote.interfaces.MspButton; +import se.sics.cooja.mspmote.interfaces.MspClock; +import se.sics.cooja.mspmote.interfaces.MspDebugOutput; +import se.sics.cooja.mspmote.interfaces.MspLED; +import se.sics.cooja.mspmote.interfaces.MspMoteID; +import se.sics.cooja.mspmote.interfaces.UsciA1Serial; + +@ClassDescription("Wismote Mote Type") +@AbstractionLevelDescription("Emulated level") +public class WismoteMoteType extends AbstractMspMoteType { + + @Override + public String getMoteType() { + return "wismote"; + } + + @Override + public String getMoteName() { + return "Wismote"; + } + + @Override + protected String getMoteImage() { + return "images/wismote.jpg"; + } + + @Override + protected MspMote createMote(Simulation simulation) { + return new WismoteMote(this, simulation); + } + + @Override + public Class[] getAllMoteInterfaceClasses() { + @SuppressWarnings("unchecked") + Class[] list = createMoteInterfaceList( + Position.class, + RimeAddress.class, + IPAddress.class, + Mote2MoteRelations.class, + MoteAttributes.class, + MspClock.class, + MspMoteID.class, + MspButton.class, +// SkyFlash.class, +// SkyCoffeeFilesystem.class, + Msp802154Radio.class, +// MspSerial.class, + UsciA1Serial.class, + MspLED.class, + MspDebugOutput.class /* EXPERIMENTAL: Enable me for COOJA_DEBUG(..) */ + ); + return list; + } + +}