diff --git a/tools/cooja/java/se/sics/cooja/RadioMedium.java b/tools/cooja/java/se/sics/cooja/RadioMedium.java index df4403721..72089b0aa 100644 --- a/tools/cooja/java/se/sics/cooja/RadioMedium.java +++ b/tools/cooja/java/se/sics/cooja/RadioMedium.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: RadioMedium.java,v 1.6 2008/03/18 12:57:04 fros4943 Exp $ + * $Id: RadioMedium.java,v 1.7 2009/05/26 14:17:29 fros4943 Exp $ */ package se.sics.cooja; @@ -44,10 +44,6 @@ import se.sics.cooja.interfaces.Radio; * data. Depending on the implementation of this interface, more or less * accurate radio behaviour imitation is aquired. * - * Often a radio medium, at initialization, registers one or several dynamic - * plugins. These plugins shows the user some radio medium specific details, - * such as radio transmission radius etc. - * * @author Fredrik Osterlind */ public abstract class RadioMedium { @@ -102,12 +98,7 @@ public abstract class RadioMedium { public abstract void unregisterRadioInterface(Radio radio, Simulation sim); /** - * Adds an observer which is notified after the radio connections has been - * calculated. Often a radio medium is a tick observer and makes these - * calculations after each tick loop. A radio medium observer may then gather - * network data by being notified every time the radio medium has delivered - * data. The radio medium observable MUST notify observers every time the - * getLastTickConnections returns a new value, even if the new value is null. + * Adds an observer which is notified each time a radio connection has finished. * * @see #getLastTickConnections() * @see #deleteRadioMediumObserver(Observer) diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java index cf4b070c6..782143dc1 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: AbstractRadioMedium.java,v 1.9 2009/04/20 16:26:02 fros4943 Exp $ + * $Id: AbstractRadioMedium.java,v 1.10 2009/05/26 14:17:29 fros4943 Exp $ */ package se.sics.cooja.radiomediums; @@ -53,10 +53,8 @@ public abstract class AbstractRadioMedium extends RadioMedium { private Vector activeConnections = new Vector(); - private Vector finishedConnections = new Vector(); - - private boolean isTickObserver = false; - + private RadioConnection lastConnection = null; + private Simulation simulation = null; /* Book-keeping */ @@ -184,10 +182,6 @@ public abstract class AbstractRadioMedium extends RadioMedium { // Recalculate signal strengths on all radios updateSignalStrengths(); - - // Wake up tick observer - radioMediumObservable.setRadioMediumChanged(); - } else if (event == Radio.RadioEvent.HW_ON) { // No action // TODO Maybe set signal strength levels now? @@ -195,39 +189,34 @@ public abstract class AbstractRadioMedium extends RadioMedium { // Recalculate signal strengths on all radios updateSignalStrengths(); - // Wake up tick observer - radioMediumObservable.setRadioMediumChanged(); - } else if (event == Radio.RadioEvent.TRANSMISSION_STARTED) { /* Create radio connections */ RadioConnection newConnection = createConnections(radio); - if (newConnection != null) { - activeConnections.add(newConnection); - for (Radio r: newConnection.getDestinations()) { - if (newConnection.getDestinationDelay(r) == 0) { - r.signalReceptionStart(); - } else { + activeConnections.add(newConnection); + for (Radio r: newConnection.getDestinations()) { + if (newConnection.getDestinationDelay(r) == 0) { + r.signalReceptionStart(); + } else { - /* EXPERIMENTAL: Simulating propagation delay */ - final Radio delayedRadio = r; - TimeEvent delayedEvent = new TimeEvent(0) { - public void execute(long t) { - delayedRadio.signalReceptionStart(); - } - }; - simulation.scheduleEvent( - delayedEvent, - simulation.getSimulationTime() + newConnection.getDestinationDelay(r)); + /* EXPERIMENTAL: Simulating propagation delay */ + final Radio delayedRadio = r; + TimeEvent delayedEvent = new TimeEvent(0) { + public void execute(long t) { + delayedRadio.signalReceptionStart(); + } + }; + simulation.scheduleEvent( + delayedEvent, + simulation.getSimulationTime() + newConnection.getDestinationDelay(r)); - } } } // Recalculate signal strengths on all radios updateSignalStrengths(); - // Wake up tick observer + /* Notify observers */ radioMediumObservable.setRadioMediumChanged(); } else if (event == Radio.RadioEvent.TRANSMISSION_FINISHED) { @@ -243,10 +232,10 @@ public abstract class AbstractRadioMedium extends RadioMedium { } if (connection == null) { - logger.fatal("Can't find active connection to remove"); + logger.fatal("Can't find active connection to remove, source=" + radio); } else { activeConnections.remove(connection); - finishedConnections.add(connection); + lastConnection = connection; COUNTER_TX++; for (Radio dstRadio : connection.getDestinations()) { COUNTER_RX++; @@ -264,7 +253,6 @@ public abstract class AbstractRadioMedium extends RadioMedium { simulation.scheduleEvent( delayedEvent, simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); - } } for (Radio dstRadio : connection.getInterfered()) { @@ -272,12 +260,13 @@ public abstract class AbstractRadioMedium extends RadioMedium { dstRadio.signalReceptionEnd(); } } - + // Recalculate signal strengths on all radios updateSignalStrengths(); - // Wake up tick observer + /* Notify observers */ radioMediumObservable.setRadioMediumChanged(); + radioMediumObservable.notifyObservers(); } else if (event == Radio.RadioEvent.CUSTOM_DATA_TRANSMITTED) { /* Forward custom data, if any */ @@ -377,41 +366,6 @@ public abstract class AbstractRadioMedium extends RadioMedium { } }; - - /** - * This observer is responsible for making last tick connections available to - * external observers. - * - * @see #getLastTickConnections() - */ - private Observer tickObserver = new Observer() { - public void update(Observable obs, Object obj) { - - // Reset any last tick connections - if (lastTickConnections != null) { - radioMediumObservable.setRadioMediumChanged(); - lastTickConnections = null; - } - - // Do nothing if radio medium unchanged - if (!radioMediumObservable.hasChanged()) { - return; - } - - // Log any newly finished connections - if (finishedConnections.size() > 0) { - lastTickConnections = new RadioConnection[finishedConnections.size()]; - for (int i = 0; i < finishedConnections.size(); i++) { - lastTickConnections[i] = finishedConnections.get(i); - } - finishedConnections.clear(); - } - - // Notify all other radio medium observers - radioMediumObservable.notifyObservers(); - } - }; - public void registerMote(Mote mote, Simulation sim) { registerRadioInterface(mote.getInterfaces().getRadio(), sim); } @@ -422,11 +376,6 @@ public abstract class AbstractRadioMedium extends RadioMedium { public void registerRadioInterface(Radio radio, Simulation sim) { if (radio != null) { - if (!isTickObserver) { - sim.addTickObserver(tickObserver); - isTickObserver = true; - } - // Register and start observing radio registeredRadios.add(radio); radio.addObserver(radioEventsObserver); @@ -461,7 +410,12 @@ public abstract class AbstractRadioMedium extends RadioMedium { } public RadioConnection[] getLastTickConnections() { - return lastTickConnections; + if (lastConnection == null) { + return null; + } + + /* XXX Method only returns a single connection */ + return new RadioConnection[] { lastConnection }; } } diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/UDGM.java b/tools/cooja/java/se/sics/cooja/radiomediums/UDGM.java index d9d3709b1..d28d13cc7 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/UDGM.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/UDGM.java @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: UDGM.java,v 1.24 2009/04/16 14:26:35 fros4943 Exp $ + * $Id: UDGM.java,v 1.25 2009/05/26 14:17:29 fros4943 Exp $ */ package se.sics.cooja.radiomediums; @@ -36,6 +36,7 @@ import org.jdom.Element; import org.apache.log4j.Logger; import se.sics.cooja.*; +import se.sics.cooja.contikimote.interfaces.ContikiRadio; import se.sics.cooja.interfaces.*; import se.sics.cooja.plugins.Visualizer; import se.sics.cooja.plugins.skins.UDGMVisualizerSkin; @@ -92,7 +93,6 @@ public class UDGM extends AbstractRadioMedium { public RadioConnection createConnections(Radio sendingRadio) { Position sendingPosition = sendingRadio.getPosition(); - RadioConnection newConnection = new RadioConnection(sendingRadio); // Fetch current output power indicator (scale with as percent) @@ -121,7 +121,15 @@ public class UDGM extends AbstractRadioMedium { continue; } if (!listeningRadio.isReceiverOn()) { - continue; + /* Special case: allow connection if source is Contiki radio, + * and destination is something else (byte radio). + * Allows cross-level communication with power-saving MACs. */ + if (sendingRadio instanceof ContikiRadio && + !(listeningRadio instanceof ContikiRadio)) { + /*logger.info("Special case: creating connection to turned off radio");*/ + } else { + continue; + } } double distance = sendingPosition.getDistanceTo(listeningRadioPosition);