From bed3877984eaddfcab731c4c23becabc6696e506 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Tue, 30 Oct 2012 11:41:56 +0100 Subject: [PATCH 1/7] Cooja: Add LQI to DGRM --- .../sics/cooja/plugins/DGRMConfigurator.java | 33 +++++++++++++++++-- .../plugins/skins/DGRMVisualizerSkin.java | 8 ++++- .../radiomediums/DGRMDestinationRadio.java | 9 +++++ 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/plugins/DGRMConfigurator.java b/tools/cooja/java/se/sics/cooja/plugins/DGRMConfigurator.java index f33f73956..3bbc966ec 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/DGRMConfigurator.java +++ b/tools/cooja/java/se/sics/cooja/plugins/DGRMConfigurator.java @@ -92,9 +92,11 @@ public class DGRMConfigurator extends VisPlugin { private final static int IDX_DST = 1; private final static int IDX_RATIO = 2; private final static int IDX_SIGNAL = 3; - private final static int IDX_DELAY = 4; + private final static int IDX_LQI = 4; + private final static int IDX_DELAY = 5; + private final static String[] COLUMN_NAMES = new String[] { - "Source", "Destination", "RX Ratio", "RSSI", "Delay" + "Source", "Destination", "RX Ratio", "RSSI","LQI", "Delay" }; private GUI gui = null; @@ -129,6 +131,10 @@ public class DGRMConfigurator extends VisPlugin { for (double d=AbstractRadioMedium.SS_STRONG; d >= AbstractRadioMedium.SS_WEAK; d -= 1) { combo.addItem((int) d); } + } else if (column == IDX_LQI) { + for (int d = 110; d > 50; d -= 5) { + combo.addItem((int) d); + } } else if (column == IDX_DELAY) { for (double d=0; d <= 5; d++) { combo.addItem(d); @@ -162,6 +168,17 @@ public class DGRMConfigurator extends VisPlugin { setText(String.format("%1.1f dBm", v)); } }); + graphTable.getColumnModel().getColumn(IDX_LQI).setCellRenderer(new DefaultTableCellRenderer() { + private static final long serialVersionUID = -4669897764928372246L; + public void setValue(Object value) { + if (!(value instanceof Long)) { + setText(value.toString()); + return; + } + long v = ((Long) value).longValue(); + setText(String.valueOf(v)); + } + }); graphTable.getColumnModel().getColumn(IDX_DELAY).setCellRenderer(new DefaultTableCellRenderer() { private static final long serialVersionUID = -4669897764928372246L; public void setValue(Object value) { @@ -175,6 +192,7 @@ public class DGRMConfigurator extends VisPlugin { }); graphTable.getColumnModel().getColumn(IDX_RATIO).setCellEditor(new DefaultCellEditor(combo)); graphTable.getColumnModel().getColumn(IDX_SIGNAL).setCellEditor(new DefaultCellEditor(combo)); + graphTable.getColumnModel().getColumn(IDX_LQI).setCellEditor(new DefaultCellEditor(combo)); graphTable.getColumnModel().getColumn(IDX_DELAY).setCellEditor(new DefaultCellEditor(combo)); graphTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); @@ -412,6 +430,9 @@ public class DGRMConfigurator extends VisPlugin { if (column == IDX_SIGNAL) { return ((DGRMDestinationRadio)edge.superDest).signal; } + if (column == IDX_LQI) { + return ((DGRMDestinationRadio)edge.superDest).lqi; + } if (column == IDX_DELAY) { return ((DGRMDestinationRadio)edge.superDest).delay / Simulation.MILLISECOND; } @@ -434,7 +455,10 @@ public class DGRMConfigurator extends VisPlugin { } else if (column == IDX_DELAY) { ((DGRMDestinationRadio)edge.superDest).delay = ((Number)value).longValue() * Simulation.MILLISECOND; - } else { + } else if (column == IDX_LQI) { + ((DGRMDestinationRadio)edge.superDest).lqi = ((Number)value).intValue(); + } + else { super.setValueAt(value, row, column); } radioMedium.requestEdgeAnalysis(); @@ -462,6 +486,9 @@ public class DGRMConfigurator extends VisPlugin { if (column == IDX_SIGNAL) { return true; } + if (column == IDX_LQI) { + return true; + } if (column == IDX_DELAY) { return true; } diff --git a/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java b/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java index df2d86900..012d46f5c 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java +++ b/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java @@ -118,6 +118,11 @@ public class DGRMVisualizerSkin implements VisualizerSkin { g.drawString(msg, x - msgWidth/2, y + 2*Visualizer.MOTE_RADIUS + 3); for (DestinationRadio r: dests) { double prob = ((DGRMDestinationRadio)r).ratio; + double rssi = ((DGRMDestinationRadio)r).signal; + double pos_rssi = rssi + 100; + int lqi = ((DGRMDestinationRadio)r).lqi; + float red = (float)(1 - prob*pos_rssi/90*lqi/100); + float green = (float)(prob*pos_rssi/90*lqi/100); if (prob == 0.0d) { continue; } @@ -125,7 +130,8 @@ public class DGRMVisualizerSkin implements VisualizerSkin { Position pos = r.radio.getPosition(); Point pixel = visualizer.transformPositionToPixel(pos); msgWidth = fm.stringWidth(msg); - g.setColor(new Color(1-(float)prob, (float)prob, 0.0f)); + g.setColor(new Color(red, green, 0.0f)); + g.drawString("LQI: " + lqi + " RSSI: " + rssi,(x + pixel.x)/2,(y + pixel.y)/2); g.drawLine(x, y, pixel.x, pixel.y); g.setColor(Color.BLACK); g.drawString(msg, pixel.x - msgWidth/2, pixel.y + 2*Visualizer.MOTE_RADIUS + 3); diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/DGRMDestinationRadio.java b/tools/cooja/java/se/sics/cooja/radiomediums/DGRMDestinationRadio.java index cf1dc08ba..ac173537b 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/DGRMDestinationRadio.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/DGRMDestinationRadio.java @@ -42,6 +42,7 @@ public class DGRMDestinationRadio extends DestinationRadio { public double ratio = 1.0; /* Link success ratio (per packet). */ public double signal = AbstractRadioMedium.SS_STRONG; /* RSSI */ public long delay = 0; /* EXPERIMENTAL: Propagation delay (us). */ + public int lqi = 105; public DGRMDestinationRadio() { super(); @@ -55,6 +56,7 @@ public class DGRMDestinationRadio extends DestinationRadio { clone.ratio = this.ratio; clone.delay = this.delay; clone.signal = this.signal; + clone.lqi = this.lqi; return clone; } @@ -70,6 +72,11 @@ public class DGRMDestinationRadio extends DestinationRadio { element.setText("" + signal); config.add(element); + element = new Element("lqi"); + element.setText("" + lqi); + config.add(element); + + element = new Element("delay"); element.setText("" + delay); config.add(element); @@ -86,6 +93,8 @@ public class DGRMDestinationRadio extends DestinationRadio { ratio = Double.parseDouble(element.getText()); } else if (element.getName().equals("signal")) { signal = Double.parseDouble(element.getText()); + } else if (element.getName().equals("lqi")) { + lqi = Integer.parseInt(element.getText()); } else if (element.getName().equals("delay")) { delay = Long.parseLong(element.getText()); } From 9b1fb12a3fd93be7db06dd9e616aec0aa5743937 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Tue, 30 Oct 2012 11:42:02 +0100 Subject: [PATCH 2/7] Cooja, DGRM: Change DirectedGraphMedium over to DGRMDestinationRadio and fix RSSI --- .../radiomediums/DirectedGraphMedium.java | 60 +++++++++---------- .../java/se/sics/cooja/radiomediums/UDGM.java | 2 +- 2 files changed, 28 insertions(+), 34 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java index 78d48e50a..0ff5bbce7 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java @@ -72,7 +72,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { private boolean edgesDirty = true; /* Used for optimizing lookup time */ - private Hashtable edgesTable = new Hashtable(); + private Hashtable edgesTable = new Hashtable(); public DirectedGraphMedium() { /* Do not initialize radio medium: use only for hash table */ @@ -165,29 +165,23 @@ public class DirectedGraphMedium extends AbstractRadioMedium { /* Set signal strengths */ RadioConnection[] conns = getActiveConnections(); for (RadioConnection conn : conns) { + /* When sending RSSI is Strong! + * TODO: is this reasonable + */ if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) { conn.getSource().setCurrentSignalStrength(SS_STRONG); } - for (Radio dstRadio : conn.getDestinations()) { - if (dstRadio.getCurrentSignalStrength() < SS_STRONG) { - dstRadio.setCurrentSignalStrength(SS_STRONG); + //Maximum reception signal of all possible radios received + DGRMDestinationRadio dstRadios[] = edgesTable.get(conn.getSource()); + if (dstRadios == null) continue; + for (DGRMDestinationRadio dstRadio : dstRadios) { + if (dstRadio.radio.getCurrentSignalStrength() < dstRadio.signal) { + dstRadio.radio.setCurrentSignalStrength(dstRadio.signal); } } } - /* Set signal strength to weak on interfered */ - for (RadioConnection conn : conns) { - for (Radio intfRadio : conn.getInterfered()) { - if (intfRadio.getCurrentSignalStrength() < SS_STRONG) { - intfRadio.setCurrentSignalStrength(SS_STRONG); - } - - if (!intfRadio.isInterfered()) { - /*logger.warn("Radio was not interfered");*/ - intfRadio.interfereAnyReception(); - } - } - } + } @@ -196,14 +190,14 @@ public class DirectedGraphMedium extends AbstractRadioMedium { * Generates hash table using current edges for efficient lookup. */ protected void analyzeEdges() { - Hashtable> listTable = - new Hashtable>(); + Hashtable> listTable = + new Hashtable>(); /* Fill edge hash table with all edges */ for (Edge edge: getEdges()) { - ArrayList destRadios; + ArrayList destRadios; if (!listTable.containsKey(edge.source)) { - destRadios = new ArrayList(); + destRadios = new ArrayList(); } else { destRadios = listTable.get(edge.source); } @@ -213,11 +207,11 @@ public class DirectedGraphMedium extends AbstractRadioMedium { } /* Convert to arrays */ - Hashtable arrTable = new Hashtable(); + Hashtable arrTable = new Hashtable(); Enumeration sources = listTable.keys(); while (sources.hasMoreElements()) { Radio source = sources.nextElement(); - DestinationRadio[] arr = listTable.get(source).toArray(new DestinationRadio[0]); + DGRMDestinationRadio[] arr = listTable.get(source).toArray(new DGRMDestinationRadio[0]); arrTable.put(source, arr); } @@ -232,7 +226,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { * @param source Source radio * @return All potential destination radios */ - public DestinationRadio[] getPotentialDestinations(Radio source) { + public DGRMDestinationRadio[] getPotentialDestinations(Radio source) { if (edgesDirty) { analyzeEdges(); } @@ -250,7 +244,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { /* Create new radio connection using edge hash table */ RadioConnection newConn = new RadioConnection(source); - DestinationRadio[] destinations = getPotentialDestinations(source); + DGRMDestinationRadio[] destinations = getPotentialDestinations(source); if (destinations == null || destinations.length == 0) { /* No destinations */ /*logger.info(sendingRadio + ": No dest");*/ @@ -258,8 +252,8 @@ public class DirectedGraphMedium extends AbstractRadioMedium { } /*logger.info(source + ": " + destinations.length + " potential destinations");*/ - for (DestinationRadio d: destinations) { - DGRMDestinationRadio dest = (DGRMDestinationRadio) d; + for (DGRMDestinationRadio dest: destinations) { + if (dest.radio == source) { /* Fail: cannot receive our own transmission */ /*logger.info(source + ": Fail, receiver is sender");*/ @@ -369,7 +363,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { if (element.getName().equals("edge")) { Collection edgeConfig = element.getChildren(); Radio source = null; - DestinationRadio dest = null; + DGRMDestinationRadio dest = null; for (Element edgeElement : edgeConfig) { if (edgeElement.getName().equals("src")) { oldConfig = true; @@ -388,7 +382,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { } else if (oldConfig && edgeElement.getName().equals("ratio")) { /* Old config: parse link ratio */ double ratio = Double.parseDouble(edgeElement.getText()); - ((DGRMDestinationRadio)dest).ratio = ratio; + dest.ratio = ratio; } else if (edgeElement.getName().equals("dest")) { if (oldConfig) { /* Old config: create simple destination link */ @@ -406,8 +400,8 @@ public class DirectedGraphMedium extends AbstractRadioMedium { if (destClassName == null || destClassName.isEmpty()) { continue; } - Class destClass = - simulation.getGUI().tryLoadClass(this, DestinationRadio.class, destClassName); + Class destClass = + simulation.getGUI().tryLoadClass(this, DGRMDestinationRadio.class, destClassName); if (destClass == null) { throw new RuntimeException("Could not load class: " + destClassName); } @@ -435,9 +429,9 @@ public class DirectedGraphMedium extends AbstractRadioMedium { public static class Edge { public Radio source = null; - public DestinationRadio superDest = null; + public DGRMDestinationRadio superDest = null; - public Edge(Radio source, DestinationRadio dest) { + public Edge(Radio source, DGRMDestinationRadio dest) { this.source = source; this.superDest = dest; } diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/UDGM.java b/tools/cooja/java/se/sics/cooja/radiomediums/UDGM.java index 82865c6a4..0e035ab5d 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/UDGM.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/UDGM.java @@ -113,7 +113,7 @@ public class UDGM extends AbstractRadioMedium { /* Add potential destination */ addEdge( new DirectedGraphMedium.Edge(source, - new DestinationRadio(dest))); + new DGRMDestinationRadio(dest))); } } } From f34826f3f124cb51066c658ce364955102777ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Tue, 30 Oct 2012 11:42:02 +0100 Subject: [PATCH 3/7] Cooja: Change indention of AbstractRadioMedium to tabs --- .../radiomediums/AbstractRadioMedium.java | 824 +++++++++--------- 1 file changed, 412 insertions(+), 412 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java index b0b4d1e0a..3ae9b5246 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java @@ -62,416 +62,416 @@ import se.sics.cooja.interfaces.Radio; * @author Fredrik Osterlind */ public abstract class AbstractRadioMedium extends RadioMedium { - private static Logger logger = Logger.getLogger(AbstractRadioMedium.class); - - /* Signal strengths in dBm. - * Approx. values measured on TmoteSky */ - public static final double SS_NOTHING = -100; - public static final double SS_STRONG = -10; - public static final double SS_WEAK = -95; - - private ArrayList registeredRadios = new ArrayList(); - - private ArrayList activeConnections = new ArrayList(); - - private RadioConnection lastConnection = null; - - private Simulation simulation = null; - - /* Book-keeping */ - public int COUNTER_TX = 0; - public int COUNTER_RX = 0; - public int COUNTER_INTERFERED = 0; - - public class RadioMediumObservable extends Observable { - public void setRadioMediumChanged() { - setChanged(); - } - public void setRadioMediumChangedAndNotify() { - setChanged(); - notifyObservers(); - } - } - - private RadioMediumObservable radioMediumObservable = new RadioMediumObservable(); - - /** - * This constructor should always be called from implemented radio mediums. - * - * @param simulation Simulation - */ - public AbstractRadioMedium(Simulation simulation) { - this.simulation = simulation; - } - - /** - * @return All registered radios - */ - public Radio[] getRegisteredRadios() { - return registeredRadios.toArray(new Radio[0]); - } - - /** - * @return All active connections - */ - public RadioConnection[] getActiveConnections() { - /* NOTE: toArray([0]) creates array and handles synchronization */ - return activeConnections.toArray(new RadioConnection[0]); - } - - /** - * Creates a new connection from given radio. - * - * Determines which radios should receive or be interfered by the transmission. - * - * @param radio Source radio - * @return New connection - */ - abstract public RadioConnection createConnections(Radio radio); - - /** - * Updates all radio interfaces' signal strengths according to - * the current active connections. - */ - public void updateSignalStrengths() { - - /* Reset signal strengths */ - for (Radio radio : getRegisteredRadios()) { - radio.setCurrentSignalStrength(SS_NOTHING); - } - - /* Set signal strength to strong on destinations */ - RadioConnection[] conns = getActiveConnections(); - for (RadioConnection conn : conns) { - if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) { - conn.getSource().setCurrentSignalStrength(SS_STRONG); - } - for (Radio dstRadio : conn.getDestinations()) { - if (conn.getSource().getChannel() >= 0 && - dstRadio.getChannel() >= 0 && - conn.getSource().getChannel() != dstRadio.getChannel()) { - continue; - } - if (dstRadio.getCurrentSignalStrength() < SS_STRONG) { - dstRadio.setCurrentSignalStrength(SS_STRONG); - } - } - } - - /* Set signal strength to weak on interfered */ - for (RadioConnection conn : conns) { - for (Radio intfRadio : conn.getInterfered()) { - if (intfRadio.getCurrentSignalStrength() < SS_STRONG) { - intfRadio.setCurrentSignalStrength(SS_STRONG); - } - if (conn.getSource().getChannel() >= 0 && - intfRadio.getChannel() >= 0 && - conn.getSource().getChannel() != intfRadio.getChannel()) { - continue; - } - if (!intfRadio.isInterfered()) { - /*logger.warn("Radio was not interfered");*/ - intfRadio.interfereAnyReception(); - } - } - } - } - - - /** - * Remove given radio from any active connections. - * This method can be called if a radio node falls asleep or is removed. - * - * @param radio Radio - */ - private void removeFromActiveConnections(Radio radio) { - /* This radio must not be a connection source */ - RadioConnection connection = getActiveConnectionFrom(radio); - if (connection != null) { - logger.fatal("Connection source turned off radio: " + radio); - } - - /* Set interfered if currently a connection destination */ - for (RadioConnection conn : activeConnections) { - if (conn.isDestination(radio)) { - conn.addInterfered(radio); - if (!radio.isInterfered()) { - radio.interfereAnyReception(); - } - } - } - } - - private RadioConnection getActiveConnectionFrom(Radio source) { - for (RadioConnection conn : activeConnections) { - if (conn.getSource() == source) { - return conn; - } - } - return null; - } - - /** - * This observer is responsible for detecting radio interface events, for example - * new transmissions. - */ - private Observer radioEventsObserver = new Observer() { - public void update(Observable obs, Object obj) { - if (!(obs instanceof Radio)) { - logger.fatal("Radio event dispatched by non-radio object"); - return; - } - Radio radio = (Radio) obs; - - final Radio.RadioEvent event = radio.getLastEvent(); - if (event == Radio.RadioEvent.RECEPTION_STARTED || - event == Radio.RadioEvent.RECEPTION_INTERFERED || - event == Radio.RadioEvent.RECEPTION_FINISHED || - event == Radio.RadioEvent.UNKNOWN) { - /* Ignored */ - return; - } - - if (event == Radio.RadioEvent.HW_ON) { - - /* Update signal strengths */ - updateSignalStrengths(); - - } else if (event == Radio.RadioEvent.HW_OFF) { - - /* Remove any radio connections from this radio */ - removeFromActiveConnections(radio); - - /* Update signal strengths */ - updateSignalStrengths(); - - } else if (event == Radio.RadioEvent.TRANSMISSION_STARTED) { - /* Create new radio connection */ - - if (radio.isReceiving()) { - /* Radio starts transmitting when it should be receiving! - * Ok, but it won't receive the packet */ - for (RadioConnection conn : activeConnections) { - if (conn.isDestination(radio)) { - conn.addInterfered(radio); - } - } - radio.interfereAnyReception(); - } - - RadioConnection newConnection = createConnections(radio); - activeConnections.add(newConnection); - for (Radio r: newConnection.getAllDestinations()) { - 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)); - - } - } - - /* Update signal strengths */ - updateSignalStrengths(); - - /* Notify observers */ - lastConnection = null; - radioMediumObservable.setRadioMediumChangedAndNotify(); - - } else if (event == Radio.RadioEvent.TRANSMISSION_FINISHED) { - /* Remove radio connection */ - - /* Connection */ - RadioConnection connection = getActiveConnectionFrom(radio); - if (connection == null) { - logger.fatal("No radio connection found"); - return; - } - - activeConnections.remove(connection); - lastConnection = connection; - COUNTER_TX++; - for (Radio dstRadio : connection.getAllDestinations()) { - if (connection.getDestinationDelay(dstRadio) == 0) { - dstRadio.signalReceptionEnd(); - } else { - - /* EXPERIMENTAL: Simulating propagation delay */ - final Radio delayedRadio = dstRadio; - TimeEvent delayedEvent = new TimeEvent(0) { - public void execute(long t) { - delayedRadio.signalReceptionEnd(); - } - }; - simulation.scheduleEvent( - delayedEvent, - simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); - } - } - COUNTER_RX += connection.getDestinations().length; - COUNTER_INTERFERED += connection.getInterfered().length; - for (Radio intRadio : connection.getInterferedNonDestinations()) { - intRadio.signalReceptionEnd(); - } - - /* Update signal strengths */ - updateSignalStrengths(); - - /* Notify observers */ - radioMediumObservable.setRadioMediumChangedAndNotify(); - - } else if (event == Radio.RadioEvent.CUSTOM_DATA_TRANSMITTED) { - - /* Connection */ - RadioConnection connection = getActiveConnectionFrom(radio); - if (connection == null) { - logger.fatal("No radio connection found"); - return; - } - - /* Custom data object */ - Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted(); - if (data == null) { - logger.fatal("No custom data object to forward"); - return; - } - - for (Radio dstRadio : connection.getAllDestinations()) { - - if (!radio.getClass().equals(dstRadio.getClass()) || - !(radio instanceof CustomDataRadio)) { - /* Radios communicate via radio packets */ - continue; - } - - if (connection.getDestinationDelay(dstRadio) == 0) { - ((CustomDataRadio) dstRadio).receiveCustomData(data); - } else { - - /* EXPERIMENTAL: Simulating propagation delay */ - final CustomDataRadio delayedRadio = (CustomDataRadio) dstRadio; - final Object delayedData = data; - TimeEvent delayedEvent = new TimeEvent(0) { - public void execute(long t) { - delayedRadio.receiveCustomData(delayedData); - } - }; - simulation.scheduleEvent( - delayedEvent, - simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); - - } - } - - } else if (event == Radio.RadioEvent.PACKET_TRANSMITTED) { - - /* Connection */ - RadioConnection connection = getActiveConnectionFrom(radio); - if (connection == null) { - logger.fatal("No radio connection found"); - return; - } - - /* Radio packet */ - RadioPacket packet = radio.getLastPacketTransmitted(); - if (packet == null) { - logger.fatal("No radio packet to forward"); - return; - } - - for (Radio dstRadio : connection.getAllDestinations()) { - - if (radio.getClass().equals(dstRadio.getClass()) && - radio instanceof CustomDataRadio) { - /* Radios instead communicate via custom data objects */ - continue; - } - - /* Forward radio packet */ - if (connection.getDestinationDelay(dstRadio) == 0) { - dstRadio.setReceivedPacket(packet); - } else { - - /* EXPERIMENTAL: Simulating propagation delay */ - final Radio delayedRadio = dstRadio; - final RadioPacket delayedPacket = packet; - TimeEvent delayedEvent = new TimeEvent(0) { - public void execute(long t) { - delayedRadio.setReceivedPacket(delayedPacket); - } - }; - simulation.scheduleEvent( - delayedEvent, - simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); - } - - } - - } else { - logger.fatal("Unsupported radio event: " + event); - } - } - }; - - public void registerMote(Mote mote, Simulation sim) { - registerRadioInterface(mote.getInterfaces().getRadio(), sim); - } - - public void unregisterMote(Mote mote, Simulation sim) { - unregisterRadioInterface(mote.getInterfaces().getRadio(), sim); - } - - public void registerRadioInterface(Radio radio, Simulation sim) { - if (radio == null) { - logger.warn("No radio to register"); - return; - } - - registeredRadios.add(radio); - radio.addObserver(radioEventsObserver); - - /* Update signal strengths */ - updateSignalStrengths(); - } - - public void unregisterRadioInterface(Radio radio, Simulation sim) { - if (!registeredRadios.contains(radio)) { - logger.warn("No radio to unregister: " + radio); - return; - } - - radio.deleteObserver(radioEventsObserver); - registeredRadios.remove(radio); - - removeFromActiveConnections(radio); - - /* Update signal strengths */ - updateSignalStrengths(); - } - - public void addRadioMediumObserver(Observer observer) { - radioMediumObservable.addObserver(observer); - } - - public Observable getRadioMediumObservable() { - return radioMediumObservable; - } - - public void deleteRadioMediumObserver(Observer observer) { - radioMediumObservable.deleteObserver(observer); - } - - public RadioConnection getLastConnection() { - return lastConnection; - } - + private static Logger logger = Logger.getLogger(AbstractRadioMedium.class); + + /* Signal strengths in dBm. + * Approx. values measured on TmoteSky */ + public static final double SS_NOTHING = -100; + public static final double SS_STRONG = -10; + public static final double SS_WEAK = -95; + + private ArrayList registeredRadios = new ArrayList(); + + private ArrayList activeConnections = new ArrayList(); + + private RadioConnection lastConnection = null; + + private Simulation simulation = null; + + /* Book-keeping */ + public int COUNTER_TX = 0; + public int COUNTER_RX = 0; + public int COUNTER_INTERFERED = 0; + + public class RadioMediumObservable extends Observable { + public void setRadioMediumChanged() { + setChanged(); + } + public void setRadioMediumChangedAndNotify() { + setChanged(); + notifyObservers(); + } + } + + private RadioMediumObservable radioMediumObservable = new RadioMediumObservable(); + + /** + * This constructor should always be called from implemented radio mediums. + * + * @param simulation Simulation + */ + public AbstractRadioMedium(Simulation simulation) { + this.simulation = simulation; + } + + /** + * @return All registered radios + */ + public Radio[] getRegisteredRadios() { + return registeredRadios.toArray(new Radio[0]); + } + + /** + * @return All active connections + */ + public RadioConnection[] getActiveConnections() { + /* NOTE: toArray([0]) creates array and handles synchronization */ + return activeConnections.toArray(new RadioConnection[0]); + } + + /** + * Creates a new connection from given radio. + * + * Determines which radios should receive or be interfered by the transmission. + * + * @param radio Source radio + * @return New connection + */ + abstract public RadioConnection createConnections(Radio radio); + + /** + * Updates all radio interfaces' signal strengths according to + * the current active connections. + */ + public void updateSignalStrengths() { + + /* Reset signal strengths */ + for (Radio radio : getRegisteredRadios()) { + radio.setCurrentSignalStrength(SS_NOTHING); + } + + /* Set signal strength to strong on destinations */ + RadioConnection[] conns = getActiveConnections(); + for (RadioConnection conn : conns) { + if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) { + conn.getSource().setCurrentSignalStrength(SS_STRONG); + } + for (Radio dstRadio : conn.getDestinations()) { + if (conn.getSource().getChannel() >= 0 && + dstRadio.getChannel() >= 0 && + conn.getSource().getChannel() != dstRadio.getChannel()) { + continue; + } + if (dstRadio.getCurrentSignalStrength() < SS_STRONG) { + dstRadio.setCurrentSignalStrength(SS_STRONG); + } + } + } + + /* Set signal strength to weak on interfered */ + for (RadioConnection conn : conns) { + for (Radio intfRadio : conn.getInterfered()) { + if (intfRadio.getCurrentSignalStrength() < SS_STRONG) { + intfRadio.setCurrentSignalStrength(SS_STRONG); + } + if (conn.getSource().getChannel() >= 0 && + intfRadio.getChannel() >= 0 && + conn.getSource().getChannel() != intfRadio.getChannel()) { + continue; + } + if (!intfRadio.isInterfered()) { + /*logger.warn("Radio was not interfered");*/ + intfRadio.interfereAnyReception(); + } + } + } + } + + + /** + * Remove given radio from any active connections. + * This method can be called if a radio node falls asleep or is removed. + * + * @param radio Radio + */ + private void removeFromActiveConnections(Radio radio) { + /* This radio must not be a connection source */ + RadioConnection connection = getActiveConnectionFrom(radio); + if (connection != null) { + logger.fatal("Connection source turned off radio: " + radio); + } + + /* Set interfered if currently a connection destination */ + for (RadioConnection conn : activeConnections) { + if (conn.isDestination(radio)) { + conn.addInterfered(radio); + if (!radio.isInterfered()) { + radio.interfereAnyReception(); + } + } + } + } + + private RadioConnection getActiveConnectionFrom(Radio source) { + for (RadioConnection conn : activeConnections) { + if (conn.getSource() == source) { + return conn; + } + } + return null; + } + + /** + * This observer is responsible for detecting radio interface events, for example + * new transmissions. + */ + private Observer radioEventsObserver = new Observer() { + public void update(Observable obs, Object obj) { + if (!(obs instanceof Radio)) { + logger.fatal("Radio event dispatched by non-radio object"); + return; + } + Radio radio = (Radio) obs; + + final Radio.RadioEvent event = radio.getLastEvent(); + if (event == Radio.RadioEvent.RECEPTION_STARTED || + event == Radio.RadioEvent.RECEPTION_INTERFERED || + event == Radio.RadioEvent.RECEPTION_FINISHED || + event == Radio.RadioEvent.UNKNOWN) { + /* Ignored */ + return; + } + + if (event == Radio.RadioEvent.HW_ON) { + + /* Update signal strengths */ + updateSignalStrengths(); + + } else if (event == Radio.RadioEvent.HW_OFF) { + + /* Remove any radio connections from this radio */ + removeFromActiveConnections(radio); + + /* Update signal strengths */ + updateSignalStrengths(); + + } else if (event == Radio.RadioEvent.TRANSMISSION_STARTED) { + /* Create new radio connection */ + + if (radio.isReceiving()) { + /* Radio starts transmitting when it should be receiving! + * Ok, but it won't receive the packet */ + for (RadioConnection conn : activeConnections) { + if (conn.isDestination(radio)) { + conn.addInterfered(radio); + } + } + radio.interfereAnyReception(); + } + + RadioConnection newConnection = createConnections(radio); + activeConnections.add(newConnection); + for (Radio r: newConnection.getAllDestinations()) { + 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)); + + } + } + + /* Update signal strengths */ + updateSignalStrengths(); + + /* Notify observers */ + lastConnection = null; + radioMediumObservable.setRadioMediumChangedAndNotify(); + + } else if (event == Radio.RadioEvent.TRANSMISSION_FINISHED) { + /* Remove radio connection */ + + /* Connection */ + RadioConnection connection = getActiveConnectionFrom(radio); + if (connection == null) { + logger.fatal("No radio connection found"); + return; + } + + activeConnections.remove(connection); + lastConnection = connection; + COUNTER_TX++; + for (Radio dstRadio : connection.getAllDestinations()) { + if (connection.getDestinationDelay(dstRadio) == 0) { + dstRadio.signalReceptionEnd(); + } else { + + /* EXPERIMENTAL: Simulating propagation delay */ + final Radio delayedRadio = dstRadio; + TimeEvent delayedEvent = new TimeEvent(0) { + public void execute(long t) { + delayedRadio.signalReceptionEnd(); + } + }; + simulation.scheduleEvent( + delayedEvent, + simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); + } + } + COUNTER_RX += connection.getDestinations().length; + COUNTER_INTERFERED += connection.getInterfered().length; + for (Radio intRadio : connection.getInterferedNonDestinations()) { + intRadio.signalReceptionEnd(); + } + + /* Update signal strengths */ + updateSignalStrengths(); + + /* Notify observers */ + radioMediumObservable.setRadioMediumChangedAndNotify(); + + } else if (event == Radio.RadioEvent.CUSTOM_DATA_TRANSMITTED) { + + /* Connection */ + RadioConnection connection = getActiveConnectionFrom(radio); + if (connection == null) { + logger.fatal("No radio connection found"); + return; + } + + /* Custom data object */ + Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted(); + if (data == null) { + logger.fatal("No custom data object to forward"); + return; + } + + for (Radio dstRadio : connection.getAllDestinations()) { + + if (!radio.getClass().equals(dstRadio.getClass()) || + !(radio instanceof CustomDataRadio)) { + /* Radios communicate via radio packets */ + continue; + } + + if (connection.getDestinationDelay(dstRadio) == 0) { + ((CustomDataRadio) dstRadio).receiveCustomData(data); + } else { + + /* EXPERIMENTAL: Simulating propagation delay */ + final CustomDataRadio delayedRadio = (CustomDataRadio) dstRadio; + final Object delayedData = data; + TimeEvent delayedEvent = new TimeEvent(0) { + public void execute(long t) { + delayedRadio.receiveCustomData(delayedData); + } + }; + simulation.scheduleEvent( + delayedEvent, + simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); + + } + } + + } else if (event == Radio.RadioEvent.PACKET_TRANSMITTED) { + + /* Connection */ + RadioConnection connection = getActiveConnectionFrom(radio); + if (connection == null) { + logger.fatal("No radio connection found"); + return; + } + + /* Radio packet */ + RadioPacket packet = radio.getLastPacketTransmitted(); + if (packet == null) { + logger.fatal("No radio packet to forward"); + return; + } + + for (Radio dstRadio : connection.getAllDestinations()) { + + if (radio.getClass().equals(dstRadio.getClass()) && + radio instanceof CustomDataRadio) { + /* Radios instead communicate via custom data objects */ + continue; + } + + /* Forward radio packet */ + if (connection.getDestinationDelay(dstRadio) == 0) { + dstRadio.setReceivedPacket(packet); + } else { + + /* EXPERIMENTAL: Simulating propagation delay */ + final Radio delayedRadio = dstRadio; + final RadioPacket delayedPacket = packet; + TimeEvent delayedEvent = new TimeEvent(0) { + public void execute(long t) { + delayedRadio.setReceivedPacket(delayedPacket); + } + }; + simulation.scheduleEvent( + delayedEvent, + simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); + } + + } + + } else { + logger.fatal("Unsupported radio event: " + event); + } + } + }; + + public void registerMote(Mote mote, Simulation sim) { + registerRadioInterface(mote.getInterfaces().getRadio(), sim); + } + + public void unregisterMote(Mote mote, Simulation sim) { + unregisterRadioInterface(mote.getInterfaces().getRadio(), sim); + } + + public void registerRadioInterface(Radio radio, Simulation sim) { + if (radio == null) { + logger.warn("No radio to register"); + return; + } + + registeredRadios.add(radio); + radio.addObserver(radioEventsObserver); + + /* Update signal strengths */ + updateSignalStrengths(); + } + + public void unregisterRadioInterface(Radio radio, Simulation sim) { + if (!registeredRadios.contains(radio)) { + logger.warn("No radio to unregister: " + radio); + return; + } + + radio.deleteObserver(radioEventsObserver); + registeredRadios.remove(radio); + + removeFromActiveConnections(radio); + + /* Update signal strengths */ + updateSignalStrengths(); + } + + public void addRadioMediumObserver(Observer observer) { + radioMediumObservable.addObserver(observer); + } + + public Observable getRadioMediumObservable() { + return radioMediumObservable; + } + + public void deleteRadioMediumObserver(Observer observer) { + radioMediumObservable.deleteObserver(observer); + } + + public RadioConnection getLastConnection() { + return lastConnection; + } + } From 3c9e3e1b951d0344fee395faf3eefcee71da7a67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Tue, 30 Oct 2012 11:42:03 +0100 Subject: [PATCH 4/7] Cooja: Refactored AbstractRadioMedium:update(): if -> switch --- .../radiomediums/AbstractRadioMedium.java | 358 +++++++++--------- 1 file changed, 176 insertions(+), 182 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java index 3ae9b5246..b13176919 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/AbstractRadioMedium.java @@ -224,200 +224,194 @@ public abstract class AbstractRadioMedium extends RadioMedium { Radio radio = (Radio) obs; final Radio.RadioEvent event = radio.getLastEvent(); - if (event == Radio.RadioEvent.RECEPTION_STARTED || - event == Radio.RadioEvent.RECEPTION_INTERFERED || - event == Radio.RadioEvent.RECEPTION_FINISHED || - event == Radio.RadioEvent.UNKNOWN) { - /* Ignored */ - return; - } - if (event == Radio.RadioEvent.HW_ON) { - - /* Update signal strengths */ - updateSignalStrengths(); - - } else if (event == Radio.RadioEvent.HW_OFF) { - - /* Remove any radio connections from this radio */ - removeFromActiveConnections(radio); - - /* Update signal strengths */ - updateSignalStrengths(); - - } else if (event == Radio.RadioEvent.TRANSMISSION_STARTED) { - /* Create new radio connection */ - - if (radio.isReceiving()) { - /* Radio starts transmitting when it should be receiving! - * Ok, but it won't receive the packet */ - for (RadioConnection conn : activeConnections) { - if (conn.isDestination(radio)) { - conn.addInterfered(radio); + switch (event) { + case RECEPTION_STARTED: + case RECEPTION_INTERFERED: + case RECEPTION_FINISHED: + case UNKNOWN: + return; + case HW_ON: { + /* Update signal strengths */ + updateSignalStrengths(); + } + break; + case HW_OFF: { + /* Remove any radio connections from this radio */ + removeFromActiveConnections(radio); + /* Update signal strengths */ + updateSignalStrengths(); + } + break; + case TRANSMISSION_STARTED: { + /* Create new radio connection */ + if (radio.isReceiving()) { + /* + * Radio starts transmitting when it should be + * receiving! Ok, but it won't receive the packet + */ + radio.interfereAnyReception(); + for (RadioConnection conn : activeConnections) { + if (conn.isDestination(radio)) { + conn.addInterfered(radio); + } } } - radio.interfereAnyReception(); - } - - RadioConnection newConnection = createConnections(radio); - activeConnections.add(newConnection); - for (Radio r: newConnection.getAllDestinations()) { - 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)); - - } - } - - /* Update signal strengths */ - updateSignalStrengths(); - - /* Notify observers */ - lastConnection = null; - radioMediumObservable.setRadioMediumChangedAndNotify(); - - } else if (event == Radio.RadioEvent.TRANSMISSION_FINISHED) { - /* Remove radio connection */ - - /* Connection */ - RadioConnection connection = getActiveConnectionFrom(radio); - if (connection == null) { - logger.fatal("No radio connection found"); - return; - } - - activeConnections.remove(connection); - lastConnection = connection; - COUNTER_TX++; - for (Radio dstRadio : connection.getAllDestinations()) { - if (connection.getDestinationDelay(dstRadio) == 0) { - dstRadio.signalReceptionEnd(); - } else { - - /* EXPERIMENTAL: Simulating propagation delay */ - final Radio delayedRadio = dstRadio; - TimeEvent delayedEvent = new TimeEvent(0) { - public void execute(long t) { - delayedRadio.signalReceptionEnd(); - } - }; - simulation.scheduleEvent( - delayedEvent, - simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); - } - } - COUNTER_RX += connection.getDestinations().length; - COUNTER_INTERFERED += connection.getInterfered().length; - for (Radio intRadio : connection.getInterferedNonDestinations()) { - intRadio.signalReceptionEnd(); - } - - /* Update signal strengths */ - updateSignalStrengths(); - - /* Notify observers */ - radioMediumObservable.setRadioMediumChangedAndNotify(); - - } else if (event == Radio.RadioEvent.CUSTOM_DATA_TRANSMITTED) { - - /* Connection */ - RadioConnection connection = getActiveConnectionFrom(radio); - if (connection == null) { - logger.fatal("No radio connection found"); - return; - } - - /* Custom data object */ - Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted(); - if (data == null) { - logger.fatal("No custom data object to forward"); - return; - } - - for (Radio dstRadio : connection.getAllDestinations()) { - if (!radio.getClass().equals(dstRadio.getClass()) || - !(radio instanceof CustomDataRadio)) { - /* Radios communicate via radio packets */ - continue; + RadioConnection newConnection = createConnections(radio); + activeConnections.add(newConnection); + + for (Radio r : newConnection.getAllDestinations()) { + 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)); + + } + } /* Update signal strengths */ + updateSignalStrengths(); + + /* Notify observers */ + lastConnection = null; + radioMediumObservable.setRadioMediumChangedAndNotify(); + } + break; + case TRANSMISSION_FINISHED: { + /* Remove radio connection */ + + /* Connection */ + RadioConnection connection = getActiveConnectionFrom(radio); + if (connection == null) { + logger.fatal("No radio connection found"); + return; } - if (connection.getDestinationDelay(dstRadio) == 0) { - ((CustomDataRadio) dstRadio).receiveCustomData(data); - } else { - - /* EXPERIMENTAL: Simulating propagation delay */ - final CustomDataRadio delayedRadio = (CustomDataRadio) dstRadio; - final Object delayedData = data; - TimeEvent delayedEvent = new TimeEvent(0) { - public void execute(long t) { - delayedRadio.receiveCustomData(delayedData); - } - }; - simulation.scheduleEvent( - delayedEvent, - simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); - + activeConnections.remove(connection); + lastConnection = connection; + COUNTER_TX++; + for (Radio dstRadio : connection.getAllDestinations()) { + if (connection.getDestinationDelay(dstRadio) == 0) { + dstRadio.signalReceptionEnd(); + } else { + + /* EXPERIMENTAL: Simulating propagation delay */ + final Radio delayedRadio = dstRadio; + TimeEvent delayedEvent = new TimeEvent(0) { + public void execute(long t) { + delayedRadio.signalReceptionEnd(); + } + }; + simulation.scheduleEvent(delayedEvent, + simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); + } } - } - - } else if (event == Radio.RadioEvent.PACKET_TRANSMITTED) { - - /* Connection */ - RadioConnection connection = getActiveConnectionFrom(radio); - if (connection == null) { - logger.fatal("No radio connection found"); - return; - } - - /* Radio packet */ - RadioPacket packet = radio.getLastPacketTransmitted(); - if (packet == null) { - logger.fatal("No radio packet to forward"); - return; - } - - for (Radio dstRadio : connection.getAllDestinations()) { - - if (radio.getClass().equals(dstRadio.getClass()) && - radio instanceof CustomDataRadio) { - /* Radios instead communicate via custom data objects */ - continue; + COUNTER_RX += connection.getDestinations().length; + COUNTER_INTERFERED += connection.getInterfered().length; + for (Radio intRadio : connection.getInterferedNonDestinations()) { + intRadio.signalReceptionEnd(); } - /* Forward radio packet */ - if (connection.getDestinationDelay(dstRadio) == 0) { - dstRadio.setReceivedPacket(packet); - } else { + /* Update signal strengths */ + updateSignalStrengths(); + + /* Notify observers */ + radioMediumObservable.setRadioMediumChangedAndNotify(); + } + break; + case CUSTOM_DATA_TRANSMITTED: { + + /* Connection */ + RadioConnection connection = getActiveConnectionFrom(radio); + if (connection == null) { + logger.fatal("No radio connection found"); + return; + } + + /* Custom data object */ + Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted(); + if (data == null) { + logger.fatal("No custom data object to forward"); + return; + } + + for (Radio dstRadio : connection.getAllDestinations()) { - /* EXPERIMENTAL: Simulating propagation delay */ - final Radio delayedRadio = dstRadio; - final RadioPacket delayedPacket = packet; - TimeEvent delayedEvent = new TimeEvent(0) { - public void execute(long t) { - delayedRadio.setReceivedPacket(delayedPacket); - } - }; - simulation.scheduleEvent( - delayedEvent, - simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); + if (!radio.getClass().equals(dstRadio.getClass()) || !(radio instanceof CustomDataRadio)) { + /* Radios communicate via radio packets */ + continue; + } + + if (connection.getDestinationDelay(dstRadio) == 0) { + ((CustomDataRadio) dstRadio).receiveCustomData(data); + } else { + + /* EXPERIMENTAL: Simulating propagation delay */ + final CustomDataRadio delayedRadio = (CustomDataRadio) dstRadio; + final Object delayedData = data; + TimeEvent delayedEvent = new TimeEvent(0) { + public void execute(long t) { + delayedRadio.receiveCustomData(delayedData); + } + }; + simulation.scheduleEvent(delayedEvent, + simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); + + } } } - - } else { - logger.fatal("Unsupported radio event: " + event); + break; + case PACKET_TRANSMITTED: { + /* Connection */ + RadioConnection connection = getActiveConnectionFrom(radio); + if (connection == null) { + logger.fatal("No radio connection found"); + return; + } + + /* Radio packet */ + RadioPacket packet = radio.getLastPacketTransmitted(); + if (packet == null) { + logger.fatal("No radio packet to forward"); + return; + } + + for (Radio dstRadio : connection.getAllDestinations()) { + + if (radio.getClass().equals(dstRadio.getClass()) && radio instanceof CustomDataRadio) { + /* Radios instead communicate via custom data objects */ + continue; + } + + /* Forward radio packet */ + if (connection.getDestinationDelay(dstRadio) == 0) { + dstRadio.setReceivedPacket(packet); + } else { + + /* EXPERIMENTAL: Simulating propagation delay */ + final Radio delayedRadio = dstRadio; + final RadioPacket delayedPacket = packet; + TimeEvent delayedEvent = new TimeEvent(0) { + public void execute(long t) { + delayedRadio.setReceivedPacket(delayedPacket); + } + }; + simulation.scheduleEvent(delayedEvent, + simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio)); + } + + } + } + break; + default: + logger.fatal("Unsupported radio event: " + event); } } }; @@ -473,5 +467,5 @@ public abstract class AbstractRadioMedium extends RadioMedium { public RadioConnection getLastConnection() { return lastConnection; } - + } From 610f6cba14a9bd326710a8bf9887ab23e202f146 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Tue, 30 Oct 2012 11:42:03 +0100 Subject: [PATCH 5/7] Cooja, DRGM: Reordered interference checks: e.g. do not interfere if on different channel --- .../radiomediums/DirectedGraphMedium.java | 106 ++++++++---------- 1 file changed, 47 insertions(+), 59 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java index 0ff5bbce7..d130abf7a 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java @@ -35,6 +35,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Enumeration; import java.util.Hashtable; +import java.util.List; import java.util.Random; import org.apache.log4j.Logger; @@ -166,8 +167,8 @@ public class DirectedGraphMedium extends AbstractRadioMedium { RadioConnection[] conns = getActiveConnections(); for (RadioConnection conn : conns) { /* When sending RSSI is Strong! - * TODO: is this reasonable - */ + * TODO: is this reasonable + */ if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) { conn.getSource().setCurrentSignalStrength(SS_STRONG); } @@ -179,13 +180,10 @@ public class DirectedGraphMedium extends AbstractRadioMedium { dstRadio.radio.setCurrentSignalStrength(dstRadio.signal); } } - } - - + } } - /** * Generates hash table using current edges for efficient lookup. */ @@ -260,12 +258,6 @@ public class DirectedGraphMedium extends AbstractRadioMedium { continue; } - /* Fail if radios are on different (but configured) channels */ - if (source.getChannel() >= 0 && - dest.radio.getChannel() >= 0 && - source.getChannel() != dest.radio.getChannel()) { - continue; - } if (!dest.radio.isRadioOn()) { /* Fail: radio is off */ @@ -273,50 +265,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { newConn.addInterfered(dest.radio); continue; } - - if (dest.ratio < 1.0 && random.nextDouble() > dest.ratio) { - /*logger.info(source + ": Fail, randomly");*/ - /* TODO Interfere now? */ - newConn.addInterfered(dest.radio); - - dest.radio.interfereAnyReception(); - RadioConnection otherConnection = null; - for (RadioConnection conn : getActiveConnections()) { - for (Radio dstRadio : conn.getDestinations()) { - if (dstRadio == dest.radio) { - otherConnection = conn; - break; - } - } - } - if (otherConnection != null) { - otherConnection.addInterfered(dest.radio); - } - continue; - } - - if (dest.radio.isReceiving()) { - /* Fail: radio is already actively receiving */ - /*logger.info(source + ": Fail, receiving");*/ - newConn.addInterfered(dest.radio); - - /* We will also interfere with the other connection */ - dest.radio.interfereAnyReception(); - RadioConnection otherConnection = null; - for (RadioConnection conn : getActiveConnections()) { - for (Radio dstRadio : conn.getDestinations()) { - if (dstRadio == dest.radio) { - otherConnection = conn; - break; - } - } - } - if (otherConnection != null) { - otherConnection.addInterfered(dest.radio); - } - continue; - } - + if (dest.radio.isInterfered()) { /* Fail: radio is interfered in another connection */ /*logger.info(source + ": Fail, interfered");*/ @@ -324,6 +273,41 @@ public class DirectedGraphMedium extends AbstractRadioMedium { continue; } + int srcc = source.getChannel(); + int dstc = dest.radio.getChannel(); + if ( srcc >= 0 && dstc >= 0 && srcc != dstc) { + /* Fail: radios are on different (but configured) channels */ + continue; + } + + if (dest.radio.isReceiving()) { + /* Fail: radio is already actively receiving */ + /*logger.info(source + ": Fail, receiving");*/ + newConn.addInterfered(dest.radio); + + /* We will also interfere with the other connection */ + dest.radio.interfereAnyReception(); + + // Find connection, that is sending to that radio + // and mark the destination as interfered + for (RadioConnection conn : getActiveConnections()) { + for (Radio dstRadio : conn.getDestinations()) { + if (dstRadio == dest.radio) { + conn.addInterfered(dest.radio);; + break; + } + } + } + continue; + } + + if (dest.ratio < 1.0 && random.nextDouble() > dest.ratio) { + /* Fail: Reception ratio */ + /*logger.info(source + ": Fail, randomly");*/ + newConn.addInterfered(dest.radio); + continue; + } + /* Success: radio starts receiving */ /*logger.info(source + ": OK: " + dest.radio);*/ newConn.addDestination(dest.radio, dest.delay); @@ -353,7 +337,8 @@ public class DirectedGraphMedium extends AbstractRadioMedium { delayedConfiguration = configXML; return true; } - public void simulationFinishedLoading() { + +public void simulationFinishedLoading() { if (delayedConfiguration == null) { return; } @@ -361,7 +346,8 @@ public class DirectedGraphMedium extends AbstractRadioMedium { boolean oldConfig = false; for (Element element : delayedConfiguration) { if (element.getName().equals("edge")) { - Collection edgeConfig = element.getChildren(); + @SuppressWarnings("unchecked") + Collection edgeConfig = element.getChildren(); Radio source = null; DGRMDestinationRadio dest = null; for (Element edgeElement : edgeConfig) { @@ -407,7 +393,9 @@ public class DirectedGraphMedium extends AbstractRadioMedium { } try { dest = destClass.newInstance(); - dest.setConfigXML(edgeElement.getChildren(), simulation); + @SuppressWarnings("unchecked") + List children = edgeElement.getChildren(); + dest.setConfigXML(children, simulation); } catch (Exception e) { throw (RuntimeException) new RuntimeException("Unknown class: " + destClassName).initCause(e); From 80e7a6fd8c8146e30c0a079bced176feed42e041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Tue, 30 Oct 2012 11:42:04 +0100 Subject: [PATCH 6/7] Cooja: Add LQI-Support to DGRM --- .../mspmote/interfaces/Msp802154Radio.java | 14 ++++++++++++++ .../java/se/sics/cooja/interfaces/Radio.java | 19 +++++++++++++++++++ .../radiomediums/DirectedGraphMedium.java | 8 +++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/Msp802154Radio.java b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/Msp802154Radio.java index 59b444c3c..cc475ee23 100644 --- a/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/Msp802154Radio.java +++ b/tools/cooja/apps/mspsim/src/se/sics/cooja/mspmote/interfaces/Msp802154Radio.java @@ -381,7 +381,21 @@ public class Msp802154Radio extends Radio implements CustomDataRadio { } rssiLastCounter = 8; } + + + /* This will set the CORR-value of the CC2420 + * + * @see se.sics.cooja.interfaces.Radio#setLQI(int) + */ + public void setLQI(int lqi){ + radio.setLQI(lqi); + } + public int getLQI(){ + return radio.getLQI(); + } + + public Mote getMote() { return mote; } diff --git a/tools/cooja/java/se/sics/cooja/interfaces/Radio.java b/tools/cooja/java/se/sics/cooja/interfaces/Radio.java index 49dd82f4a..1f43a27e1 100644 --- a/tools/cooja/java/se/sics/cooja/interfaces/Radio.java +++ b/tools/cooja/java/se/sics/cooja/interfaces/Radio.java @@ -169,6 +169,25 @@ public abstract class Radio extends MoteInterface { * @return Maximum output power indicator */ public abstract int getOutputPowerIndicatorMax(); + + /** + * Returns the current LQI-value. This might differ from platform to platform + * @return Current LQI value. + * + * + */ + public int getLQI() throws UnsupportedOperationException { + throw new UnsupportedOperationException(); + } + + /** + * Sets the LQI. This in not supported by all platforms. Also results may differ + * from platform to platform. + * + * @param lqi The current LQI + */ + public void setLQI(int lqi){ + } /** * @return Current surrounding signal strength diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java index d130abf7a..0bb52d070 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java @@ -173,13 +173,19 @@ public class DirectedGraphMedium extends AbstractRadioMedium { conn.getSource().setCurrentSignalStrength(SS_STRONG); } //Maximum reception signal of all possible radios received - DGRMDestinationRadio dstRadios[] = edgesTable.get(conn.getSource()); + DGRMDestinationRadio dstRadios[] = getPotentialDestinations(conn.getSource()); if (dstRadios == null) continue; for (DGRMDestinationRadio dstRadio : dstRadios) { if (dstRadio.radio.getCurrentSignalStrength() < dstRadio.signal) { dstRadio.radio.setCurrentSignalStrength(dstRadio.signal); } + /* We can set this without further checks, as it will only be read + * if a packet is actually received. In that case it is set to the + * correct value */ + dstRadio.radio.setLQI(dstRadio.lqi); } + + } } From 3c3b25a54b5235e154a22cedfe3f7b5bb90a56c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=27Morty=27=20Str=C3=BCbe?= Date: Tue, 30 Oct 2012 11:42:06 +0100 Subject: [PATCH 7/7] Cooja, DGRM: Fix problems with out-of-range RSSI-Values. Certain values cause the DGRMVisualizerSkin to calculate color values that are out of range. --- .../java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java b/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java index 012d46f5c..5c30aa729 100644 --- a/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java +++ b/tools/cooja/java/se/sics/cooja/plugins/skins/DGRMVisualizerSkin.java @@ -122,7 +122,11 @@ public class DGRMVisualizerSkin implements VisualizerSkin { double pos_rssi = rssi + 100; int lqi = ((DGRMDestinationRadio)r).lqi; float red = (float)(1 - prob*pos_rssi/90*lqi/100); + if(red > 1) red = 1; + if(red < 0) red = 0; float green = (float)(prob*pos_rssi/90*lqi/100); + if(green > 1) green = 1; + if(green < 0) green = 0; if (prob == 0.0d) { continue; }