radio medium updates: removed obsolete tick observer + notifying observers for each finished radio connection separately

This commit is contained in:
fros4943 2009-05-26 14:17:29 +00:00
parent 61c2ed2e1a
commit 633f9bb5ef
3 changed files with 43 additions and 90 deletions

View File

@ -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)

View File

@ -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<RadioConnection> activeConnections = new Vector<RadioConnection>();
private Vector<RadioConnection> finishedConnections = new Vector<RadioConnection>();
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 };
}
}

View File

@ -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);