interface handler support for new interface polling format

This commit is contained in:
fros4943 2008-10-28 12:40:35 +00:00
parent 7e864bd3c7
commit 1de0d38ccb

View file

@ -1,155 +1,119 @@
/* /*
* Copyright (c) 2006, Swedish Institute of Computer Science. All rights * Copyright (c) 2008, Swedish Institute of Computer Science.
* reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met: * modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright notice, * are met:
* this list of conditions and the following disclaimer. 2. Redistributions in * 1. Redistributions of source code must retain the above copyright
* binary form must reproduce the above copyright notice, this list of * notice, this list of conditions and the following disclaimer.
* conditions and the following disclaimer in the documentation and/or other * 2. Redistributions in binary form must reproduce the above copyright
* materials provided with the distribution. 3. Neither the name of the * notice, this list of conditions and the following disclaimer in the
* Institute nor the names of its contributors may be used to endorse or promote * documentation and/or other materials provided with the distribution.
* products derived from this software without specific prior written * 3. Neither the name of the Institute nor the names of its contributors
* permission. * 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 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE FOR ANY * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 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
* $Id: MoteInterfaceHandler.java,v 1.3 2008/09/22 16:18:22 joxe Exp $ * SUCH DAMAGE.
*
* $Id: MoteInterfaceHandler.java,v 1.4 2008/10/28 12:40:35 fros4943 Exp $
*/ */
package se.sics.cooja; package se.sics.cooja;
import java.util.*; import java.util.*;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import se.sics.cooja.interfaces.*; import se.sics.cooja.interfaces.*;
/** /**
* A mote interface handler holds all interfaces for a specific mote. Even * The mote interface handler holds all interfaces for a specific mote.
* though an interface handler strictly does not need any interfaces at all, a
* position interface is highly recommended. (A lot of plugins depend on a mote
* position, for example a typical visualizer.)
*
* Interfaces are divided into active and passive interfaces. Active interfaces
* are only polled if the mote is active, while passive interfaces are polled in
* all states except dead state.
*
* Interfaces should be polled via this class when the mote is ticked. * Interfaces should be polled via this class when the mote is ticked.
* *
* @author Fredrik Osterlind * @see #doActiveActionsAfterTick()
* @see #doActiveActionsBeforeTick()
* @see #doPassiveActionsAfterTick()
* @see #doPassiveActionsBeforeTick()
*
* @author Fredrik Österlind
*/ */
public class MoteInterfaceHandler { public class MoteInterfaceHandler {
private static Logger logger = Logger.getLogger(MoteInterfaceHandler.class); private static Logger logger = Logger.getLogger(MoteInterfaceHandler.class);
private Vector<MoteInterface> allInterfaces = new Vector<MoteInterface>();
/* Cached interfaces */
private Battery myBattery; private Battery myBattery;
private Beeper myBeeper; private Beeper myBeeper;
private Button myButton; private Button myButton;
private Clock myClock; private Clock myClock;
private IPAddress myIPAddress; private IPAddress myIPAddress;
private LED myLED; private LED myLED;
private Log myLog; private Log myLog;
private MoteID myMoteID; private MoteID myMoteID;
private PIR myPIR; private PIR myPIR;
private Position myPosition; private Position myPosition;
private Radio myRadio; private Radio myRadio;
private PolledBeforeActiveTicks[] polledBeforeActive = null;
private Vector<MoteInterface> myActiveInterfaces = new Vector<MoteInterface>(); private PolledAfterActiveTicks[] polledAfterActive = null;
private MoteInterface[] activeCache = null; private PolledBeforeAllTicks[] polledBeforeAll = null;
private PolledAfterAllTicks[] polledAfterAll = null;
private Vector<MoteInterface> myPassiveInterfaces = new Vector<MoteInterface>();
/** /**
* Creates a new empty mote interface handler. * Creates new empty mote interface handler.
*/ */
public MoteInterfaceHandler() { public MoteInterfaceHandler() {
} }
/** /**
* Creates a new mote interface handler. All given interfaces are loaded. * Creates new mote interface handler. All given interfaces are created.
* *
* @param mote * @param mote Mote
* The mote holding this interface handler * @param interfaceClasses Mote interface classes
* @param allInterfaces
* Simulation interfaces to load
*/ */
public MoteInterfaceHandler(Mote mote, public MoteInterfaceHandler(Mote mote, Vector<Class<? extends MoteInterface>> interfaceClasses) {
Vector<Class<? extends MoteInterface>> allInterfaces) { for (Class<? extends MoteInterface> interfaceClass : interfaceClasses) {
MoteInterface intf = MoteInterface.generateInterface(interfaceClass, mote);
// Load all interfaces if (intf != null) {
for (Class<? extends MoteInterface> interfaceClass : allInterfaces) { addInterface(intf);
boolean isPassive = false; } else {
logger.fatal("Could not load interface: " + interfaceClass);
// Check if interface is active or passive }
if (PassiveMoteInterface.class.isAssignableFrom(interfaceClass))
isPassive = true;
// Load interface
MoteInterface loadedInterface = MoteInterface.generateInterface(
interfaceClass, mote);
if (loadedInterface != null)
if (isPassive)
addPassiveInterface(loadedInterface);
else
addActiveInterface(loadedInterface);
else
logger.warn("Interface could not be loaded: " + interfaceClass);
} }
} }
/** /**
* Get an interface (active or passive) of the given type. Returns the first * Returns interface of given type. Returns the first interface found that
* loaded interface found, that is either of the given class or of a subclass. * is either of the given class or of a subclass.
* *
* For example, if the current radio interface is wanted, this method would be * Usage: getInterfaceOfType(Radio.class)
* called like the following: getInterfaceOfType(Radio.class) *
* * @param interfaceType Class of interface to return
* @param interfaceType * @return Mote interface, or null if no interface exists of given type
* Type of interface to return
* @return Interface or null if no interface loaded of given type
*/ */
public <N extends MoteInterface> N getInterfaceOfType(Class<N> interfaceType) { public <N extends MoteInterface> N getInterfaceOfType(Class<N> interfaceType) {
for (MoteInterface intf : allInterfaces) {
if (interfaceType.isAssignableFrom(intf.getClass())) {
return (N) intf;
}
}
Enumeration<? extends MoteInterface> allActive = myActiveInterfaces
.elements();
while (allActive.hasMoreElements()) {
N nextInterface = (N) allActive.nextElement();
if (interfaceType.isAssignableFrom(nextInterface.getClass()))
return nextInterface;
}
Enumeration<? extends MoteInterface> allPassive = myPassiveInterfaces
.elements();
while (allPassive.hasMoreElements()) {
N nextInterface = (N) allPassive.nextElement();
if (interfaceType.isAssignableFrom(nextInterface.getClass()))
return nextInterface;
}
return null; return null;
} }
/** /**
* Returns the battery interface (if any). * Returns the battery interface (if any).
* *
* @return Battery interface * @return Battery interface
*/ */
public Battery getBattery() { public Battery getBattery() {
@ -161,7 +125,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the beeper interface (if any). * Returns the beeper interface (if any).
* *
* @return Beeper interface * @return Beeper interface
*/ */
public Beeper getBeeper() { public Beeper getBeeper() {
@ -173,7 +137,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the button interface (if any). * Returns the button interface (if any).
* *
* @return Button interface * @return Button interface
*/ */
public Button getButton() { public Button getButton() {
@ -185,7 +149,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the clock interface (if any). * Returns the clock interface (if any).
* *
* @return Clock interface * @return Clock interface
*/ */
public Clock getClock() { public Clock getClock() {
@ -197,8 +161,8 @@ public class MoteInterfaceHandler {
/** /**
* Returns the IP address interface (if any). * Returns the IP address interface (if any).
* *
* @return IPAddress interface * @return IP Address interface
*/ */
public IPAddress getIPAddress() { public IPAddress getIPAddress() {
if (myIPAddress == null) { if (myIPAddress == null) {
@ -209,7 +173,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the LED interface (if any). * Returns the LED interface (if any).
* *
* @return LED interface * @return LED interface
*/ */
public LED getLED() { public LED getLED() {
@ -221,7 +185,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the log interface (if any). * Returns the log interface (if any).
* *
* @return Log interface * @return Log interface
*/ */
public Log getLog() { public Log getLog() {
@ -233,7 +197,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the mote ID interface (if any). * Returns the mote ID interface (if any).
* *
* @return Mote ID interface * @return Mote ID interface
*/ */
public MoteID getMoteID() { public MoteID getMoteID() {
@ -245,7 +209,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the PIR interface (if any). * Returns the PIR interface (if any).
* *
* @return PIR interface * @return PIR interface
*/ */
public PIR getPIR() { public PIR getPIR() {
@ -257,7 +221,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the position interface (if any). * Returns the position interface (if any).
* *
* @return Position interface * @return Position interface
*/ */
public Position getPosition() { public Position getPosition() {
@ -269,7 +233,7 @@ public class MoteInterfaceHandler {
/** /**
* Returns the radio interface (if any). * Returns the radio interface (if any).
* *
* @return Radio interface * @return Radio interface
*/ */
public Radio getRadio() { public Radio getRadio() {
@ -280,99 +244,104 @@ public class MoteInterfaceHandler {
} }
/** /**
* Polls all active interfaces. This method should be called during a mote * Polls active interfaces before mote tick.
* tick before the mote software is executed.
*/ */
public void doActiveActionsBeforeTick() { public void doActiveActionsBeforeTick() {
// Assuming only one caller!!! if (polledBeforeActive == null) {
if (activeCache == null) { ArrayList<PolledBeforeActiveTicks> intfs = new ArrayList<PolledBeforeActiveTicks>();
activeCache = (MoteInterface[]) myActiveInterfaces.toArray(new MoteInterface[myActiveInterfaces.size()]); for (MoteInterface intf: allInterfaces) {
} if (intf instanceof PolledBeforeActiveTicks) {
// for (int i = 0; i < myActiveInterfaces.size(); i++) intfs.add((PolledBeforeActiveTicks)intf);
// myActiveInterfaces.get(i).doActionsBeforeTick(); }
for (int i = 0, n = activeCache.length; i < n; i++) { }
activeCache[i].doActionsBeforeTick(); polledBeforeActive = intfs.toArray(new PolledBeforeActiveTicks[intfs.size()]);
}
for (PolledBeforeActiveTicks element : polledBeforeActive) {
element.doActionsBeforeTick();
} }
} }
/** /**
* Polls all active interfaces. This method should be called during a mote * Polls active interfaces after mote tick.
* tick after the mote software has executed.
*/ */
public void doActiveActionsAfterTick() { public void doActiveActionsAfterTick() {
for (int i = 0; i < myActiveInterfaces.size(); i++) if (polledAfterActive == null) {
myActiveInterfaces.get(i).doActionsAfterTick(); ArrayList<PolledAfterActiveTicks> intfs = new ArrayList<PolledAfterActiveTicks>();
for (MoteInterface intf: allInterfaces) {
if (intf instanceof PolledAfterActiveTicks) {
intfs.add((PolledAfterActiveTicks)intf);
}
}
polledAfterActive = intfs.toArray(new PolledAfterActiveTicks[intfs.size()]);
}
for (PolledAfterActiveTicks element : polledAfterActive) {
element.doActionsAfterTick();
}
} }
/** /**
* Polls all passive interfaces. This method should be called during a mote * Polls passive interfaces before mote tick.
* tick before the mote software is executed.
*/ */
public void doPassiveActionsBeforeTick() { public void doPassiveActionsBeforeTick() {
for (int i = 0; i < myPassiveInterfaces.size(); i++) if (polledBeforeAll == null) {
myPassiveInterfaces.get(i).doActionsBeforeTick(); ArrayList<PolledBeforeAllTicks> intfs = new ArrayList<PolledBeforeAllTicks>();
for (MoteInterface intf: allInterfaces) {
if (intf instanceof PolledBeforeAllTicks) {
intfs.add((PolledBeforeAllTicks)intf);
}
}
polledBeforeAll = intfs.toArray(new PolledBeforeAllTicks[intfs.size()]);
}
for (PolledBeforeAllTicks element : polledBeforeAll) {
element.doActionsBeforeTick();
}
} }
/** /**
* Polls all passive interfaces. This method should be called during a mote * Polls passive interfaces after mote tick.
* tick after the mote software has executed.
*/ */
public void doPassiveActionsAfterTick() { public void doPassiveActionsAfterTick() {
for (int i = 0; i < myPassiveInterfaces.size(); i++) if (polledAfterAll == null) {
myPassiveInterfaces.get(i).doActionsAfterTick(); ArrayList<PolledAfterAllTicks> intfs = new ArrayList<PolledAfterAllTicks>();
for (MoteInterface intf: allInterfaces) {
if (intf instanceof PolledAfterAllTicks) {
intfs.add((PolledAfterAllTicks)intf);
}
}
polledAfterAll = intfs.toArray(new PolledAfterAllTicks[intfs.size()]);
}
for (PolledAfterAllTicks element : polledAfterAll) {
element.doActionsAfterTick();
}
} }
/** /**
* Returns all passive mote interfaces. * @return Mote interfaces
*
* @return All passive mote interface
*/ */
public Vector<MoteInterface> getAllPassiveInterfaces() { public Vector<MoteInterface> getInterfaces() {
return myPassiveInterfaces; return allInterfaces;
} }
/** /**
* Returns all active mote interfaces. * Add mote interface.
* *
* @return All active mote interface * @param intf Mote interface
* @see PolledBeforeActiveTicks
* @see PolledBeforeAllTicks
* @see PolledAfterActiveTicks
* @see PolledAfterAllTicks
*/ */
public Vector<MoteInterface> getAllActiveInterfaces() { public void addInterface(MoteInterface intf) {
return myActiveInterfaces; allInterfaces.add(intf);
}
/** polledBeforeActive = null;
* Add an active interface to corresponding mote. An active interface is only polledAfterActive = null;
* allowed to act if the mote is in active state. However, since interfaces polledBeforeAll = null;
* may awaken a sleeping mote up via external interrupts, most of the polledAfterAll = null;
* interfaces should be active.
*
* For example a button interface should be active. When the button is
* pressed, the interface will wake the mote up (simulated external
* interrupt), and then that button will be allowed to act before next tick.
*
* A passive interface is an interface which will always act if the mote is
* not dead. For example a battery should always be allowed to act since a
* mote needs energy even if it is in sleep mode.
*
* @see #addPassiveInterface(MoteInterface)
* @param newInterface
* New interface
*/
public void addActiveInterface(MoteInterface newInterface) {
myActiveInterfaces.add(newInterface);
activeCache = null;
}
/**
* Add a passive interface to corresponding mote. For explanation of passive
* vs active interfaces, see addActiveInterface(MoteInterface).
*
* @see #addActiveInterface(MoteInterface)
* @param newInterface
* New interface
*/
public void addPassiveInterface(MoteInterface newInterface) {
myPassiveInterfaces.add(newInterface);
} }
} }