From 7f6593e3619ae70b05f38d738c40a3efb3c234e9 Mon Sep 17 00:00:00 2001 From: fros4943 Date: Thu, 31 May 2007 07:21:29 +0000 Subject: [PATCH] added abstract application motes can be used to rapidly implement new pure java application motes --- .../cooja/motes/AbstractApplicationMote.java | 225 ++++++++++++++++ .../motes/AbstractApplicationMoteType.java | 240 ++++++++++++++++++ 2 files changed, 465 insertions(+) create mode 100644 tools/cooja/java/se/sics/cooja/motes/AbstractApplicationMote.java create mode 100644 tools/cooja/java/se/sics/cooja/motes/AbstractApplicationMoteType.java diff --git a/tools/cooja/java/se/sics/cooja/motes/AbstractApplicationMote.java b/tools/cooja/java/se/sics/cooja/motes/AbstractApplicationMote.java new file mode 100644 index 000000000..7f01daa3c --- /dev/null +++ b/tools/cooja/java/se/sics/cooja/motes/AbstractApplicationMote.java @@ -0,0 +1,225 @@ +/* + * 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: AbstractApplicationMote.java,v 1.1 2007/05/31 07:21:29 fros4943 Exp $ + */ + +package se.sics.cooja.motes; + +import java.util.*; + +import org.apache.log4j.Logger; +import org.jdom.Element; + +import se.sics.cooja.*; +import se.sics.cooja.interfaces.ApplicationRadio; +import se.sics.cooja.interfaces.Position; +import se.sics.cooja.interfaces.Radio; + +public abstract class AbstractApplicationMote implements Mote { + + private static Logger logger = Logger.getLogger(AbstractApplicationMote.class); + + private MoteType myType = null; + + private SectionMoteMemory myMemory = null; + + protected MoteInterfaceHandler myInterfaceHandler = null; + + private Simulation mySim = null; + + protected ApplicationRadio myApplicationRadio; + + private Observer radioDataObserver = new Observer() { + public void update(Observable obs, Object obj) { + handleNewRadioData(obs, obj); + } + }; + + public void handleNewRadioData(Observable obs, Object obj) { + if (myApplicationRadio.getLastEvent() != Radio.RadioEvent.RECEPTION_FINISHED) + return; + + logger.info("Application mote received radio data:"); + byte[] packet = myApplicationRadio.getLastPacketReceived(); + String data = ""; + for (byte b: packet) + data += (char)b; + logger.info(data); + } + + public AbstractApplicationMote() { + } + + public AbstractApplicationMote(MoteType moteType, Simulation sim) { + mySim = sim; + myType = moteType; + + // Create memory + myMemory = new SectionMoteMemory(new Properties()); + + // Create position + myInterfaceHandler = new MoteInterfaceHandler(); + Position myPosition = new Position(this); + myInterfaceHandler.addPassiveInterface(myPosition); + + // Create radio + myApplicationRadio = new ApplicationRadio(this); + myApplicationRadio.addObserver(radioDataObserver); + myInterfaceHandler.addActiveInterface(myApplicationRadio); + } + + public void setState(State newState) { + logger.fatal("Application mote can not change state"); + } + + public State getState() { + return Mote.State.ACTIVE; + } + + public void addStateObserver(Observer newObserver) { + } + + public void deleteStateObserver(Observer newObserver) { + } + + public MoteInterfaceHandler getInterfaces() { + return myInterfaceHandler; + } + + public void setInterfaces(MoteInterfaceHandler moteInterfaceHandler) { + myInterfaceHandler = moteInterfaceHandler; + } + + public MoteMemory getMemory() { + return myMemory; + } + + public void setMemory(MoteMemory memory) { + myMemory = (SectionMoteMemory) memory; + } + + public MoteType getType() { + return myType; + } + + public void setType(MoteType type) { + myType = type; + } + + public Simulation getSimulation() { + return mySim; + } + + public void setSimulation(Simulation simulation) { + this.mySim = simulation; + } + + public Collection getConfigXML() { + Vector config = new Vector(); + + Element element; + + // We need to save the mote type identifier + element = new Element("motetype_identifier"); + element.setText(getType().getIdentifier()); + config.add(element); + + // The position interface should also save its config + element = new Element("interface_config"); + element.setText(myInterfaceHandler.getPosition().getClass().getName()); + + // Active interface configs (if any) + for (MoteInterface moteInterface: getInterfaces().getAllActiveInterfaces()) { + element = new Element("interface_config"); + element.setText(moteInterface.getClass().getName()); + + Collection interfaceXML = moteInterface.getConfigXML(); + if (interfaceXML != null) { + element.addContent(interfaceXML); + config.add(element); + } + } + + // Passive interface configs (if any) + for (MoteInterface moteInterface: getInterfaces().getAllPassiveInterfaces()) { + element = new Element("interface_config"); + element.setText(moteInterface.getClass().getName()); + + Collection interfaceXML = moteInterface.getConfigXML(); + if (interfaceXML != null) { + element.addContent(interfaceXML); + config.add(element); + } + } + + return config; + } + + public boolean setConfigXML(Simulation simulation, + Collection configXML, boolean visAvailable) { + + // Set initial configuration + mySim = simulation; + myMemory = new SectionMoteMemory(new Properties()); + myInterfaceHandler = new MoteInterfaceHandler(); + Position myPosition = new Position(this); + myInterfaceHandler.addPassiveInterface(myPosition); + myApplicationRadio = new ApplicationRadio(this); + myApplicationRadio.addObserver(radioDataObserver); + myInterfaceHandler.addActiveInterface(myApplicationRadio); + + for (Element element : configXML) { + String name = element.getName(); + + if (name.equals("motetype_identifier")) { + myType = simulation.getMoteType(element.getText()); + } else if (name.equals("interface_config")) { + Class moteInterfaceClass = simulation.getGUI() + .tryLoadClass(this, MoteInterface.class, element.getText().trim()); + + if (moteInterfaceClass == null) { + logger.warn("Can't find mote interface class: " + element.getText()); + return false; + } + + MoteInterface moteInterface = myInterfaceHandler + .getInterfaceOfType(moteInterfaceClass); + moteInterface.setConfigXML(element.getChildren(), visAvailable); + } + + } + return true; + } + + public String toString() { + if (getInterfaces().getMoteID() != null) { + return "Application Mote, ID=" + getInterfaces().getMoteID().getMoteID(); + } else + return "Application Mote, ID=null"; + } + +} diff --git a/tools/cooja/java/se/sics/cooja/motes/AbstractApplicationMoteType.java b/tools/cooja/java/se/sics/cooja/motes/AbstractApplicationMoteType.java new file mode 100644 index 000000000..cde545e03 --- /dev/null +++ b/tools/cooja/java/se/sics/cooja/motes/AbstractApplicationMoteType.java @@ -0,0 +1,240 @@ +/* + * 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: AbstractApplicationMoteType.java,v 1.1 2007/05/31 07:21:29 fros4943 Exp $ + */ + +package se.sics.cooja.motes; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.util.*; +import javax.swing.*; +import org.apache.log4j.Logger; +import org.jdom.Element; + +import se.sics.cooja.*; +import se.sics.cooja.interfaces.ApplicationRadio; +import se.sics.cooja.interfaces.Position; + +@ClassDescription("Application Mote Type") +public abstract class AbstractApplicationMoteType implements MoteType { + private static Logger logger = Logger.getLogger(AbstractApplicationMoteType.class); + + // Mote type specific data + private String identifier = null; + + private String description = null; + + private Vector> moteInterfaces = null; + + // Type specific class configuration + private ProjectConfig myConfig = null; + + public AbstractApplicationMoteType() { + } + + public AbstractApplicationMoteType(String identifier) { + this.identifier = identifier; + description = "Application Mote Type #" + identifier; + } + + public boolean configureAndInit(JFrame parentFrame, Simulation simulation, boolean visAvailable) { + + if (identifier == null) { + // Create unique identifier + int counter = 0; + boolean identifierOK = false; + while (!identifierOK) { + counter++; + identifier = "apptype" + counter; + identifierOK = true; + + // Check if identifier is already used by some other type + for (MoteType existingMoteType : simulation.getMoteTypes()) { + if (existingMoteType != this + && existingMoteType.getIdentifier().equals(identifier)) { + identifierOK = false; + break; + } + } + } + + if (description == null) { + // Create description + description = "Application Mote Type #" + counter; + } + + } + + if (description == null) { + // Create description + description = "Application Mote Type #" + identifier; + } + + moteInterfaces = new Vector>(); + moteInterfaces.add(Position.class); + moteInterfaces.add(ApplicationRadio.class); + + return true; + } + + /** + * Returns all mote interfaces of this mote type + * + * @return All mote interfaces + */ + public Vector> getMoteInterfaces() { + return moteInterfaces; + } + + /** + * Set mote interfaces of this mote type + * + * @param moteInterfaces + * New mote interfaces + */ + public void setMoteInterfaces( + Vector> moteInterfaces) { + this.moteInterfaces = moteInterfaces; + } + + 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; + } + + 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(identifier); + 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(description); + smallPane.add(BorderLayout.EAST, label); + panel.add(smallPane); + + // Mote Interfaces + smallPane = new JPanel(new BorderLayout()); + label = new JLabel("Mote interfaces"); + smallPane.add(BorderLayout.WEST, label); + panel.add(smallPane); + + for (Class moteInterface : moteInterfaces) { + smallPane = new JPanel(new BorderLayout()); + label = new JLabel(moteInterface.getSimpleName()); + smallPane.add(BorderLayout.EAST, label); + panel.add(smallPane); + } + + panel.add(Box.createRigidArea(new Dimension(0, 5))); + return panel; + } + + public ProjectConfig getConfig() { + return myConfig; + } + + 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); + + // Mote interfaces + for (Class moteInterface : getMoteInterfaces()) { + element = new Element("moteinterface"); + element.setText(moteInterface.getName()); + config.add(element); + } + + return config; + } + + public boolean setConfigXML(Simulation simulation, + Collection configXML, boolean visAvailable) { + for (Element element : configXML) { + moteInterfaces = new Vector>(); + + String name = element.getName(); + + if (name.equals("identifier")) { + identifier = element.getText(); + } else if (name.equals("description")) { + description = element.getText(); + } else if (name.equals("moteinterface")) { + Class moteInterfaceClass = simulation.getGUI() + .tryLoadClass(this, MoteInterface.class, element.getText().trim()); + + if (moteInterfaceClass == null) { + logger.warn("Can't find mote interface class: " + element.getText()); + } else { + moteInterfaces.add(moteInterfaceClass); + } + } else { + logger.fatal("Unrecognized entry in loaded configuration: " + name); + } + } + + boolean createdOK = configureAndInit(GUI.frame, simulation, visAvailable); + return createdOK; + } + +}