From 5cde97854996de622cedc2780b20f0f7024e1cb0 Mon Sep 17 00:00:00 2001 From: Fredrik Osterlind Date: Tue, 1 Nov 2011 11:52:34 +0100 Subject: [PATCH] try to restore edges loaded from old simulation configuration --- .../radiomediums/DirectedGraphMedium.java | 665 +++++++++--------- 1 file changed, 343 insertions(+), 322 deletions(-) diff --git a/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java index 55e812be8..f6ba39c3a 100644 --- a/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/se/sics/cooja/radiomediums/DirectedGraphMedium.java @@ -41,6 +41,7 @@ import org.apache.log4j.Logger; import org.jdom.Element; import se.sics.cooja.ClassDescription; +import se.sics.cooja.Mote; import se.sics.cooja.RadioConnection; import se.sics.cooja.Simulation; import se.sics.cooja.interfaces.Radio; @@ -62,382 +63,402 @@ import se.sics.cooja.plugins.skins.DGRMVisualizerSkin; */ @ClassDescription("Directed Graph Radio Medium (DGRM)") public class DirectedGraphMedium extends AbstractRadioMedium { - private static Logger logger = Logger.getLogger(DirectedGraphMedium.class); + private static Logger logger = Logger.getLogger(DirectedGraphMedium.class); - private Simulation simulation; - private Random random; + private Simulation simulation; + private Random random; - private ArrayList edges = new ArrayList(); - private boolean edgesDirty = true; + private ArrayList edges = new ArrayList(); + private boolean edgesDirty = true; - /* Used for optimizing lookup time */ - private Hashtable edgesTable = new Hashtable(); + /* Used for optimizing lookup time */ + private Hashtable edgesTable = new Hashtable(); - public DirectedGraphMedium() { - /* Do not initialize radio medium: use only for hash table */ - super(null); - } + public DirectedGraphMedium() { + /* Do not initialize radio medium: use only for hash table */ + super(null); + Visualizer.registerVisualizerSkin(DGRMVisualizerSkin.class); + } - public DirectedGraphMedium(Simulation simulation) { - super(simulation); - this.simulation = simulation; - random = simulation.getRandomGenerator(); + public DirectedGraphMedium(Simulation simulation) { + super(simulation); + this.simulation = simulation; + random = simulation.getRandomGenerator(); - requestEdgeAnalysis(); + requestEdgeAnalysis(); - /* Register plugin and visualizer skin */ - simulation.getGUI().registerPlugin(DGRMConfigurator.class); - Visualizer.registerVisualizerSkin(DGRMVisualizerSkin.class); - } - - public void removed() { - super.removed(); + /* Register plugin and visualizer skin */ + simulation.getGUI().registerPlugin(DGRMConfigurator.class); + Visualizer.registerVisualizerSkin(DGRMVisualizerSkin.class); + } - /* Unregister plugin and visualizer skin */ - simulation.getGUI().unregisterPlugin(DGRMConfigurator.class); - Visualizer.unregisterVisualizerSkin(DGRMVisualizerSkin.class); - } + public void removed() { + super.removed(); - public void addEdge(Edge e) { - edges.add(e); - requestEdgeAnalysis(); + /* Unregister plugin and visualizer skin */ + simulation.getGUI().unregisterPlugin(DGRMConfigurator.class); + Visualizer.unregisterVisualizerSkin(DGRMVisualizerSkin.class); + } - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); - } + public void addEdge(Edge e) { + edges.add(e); + requestEdgeAnalysis(); - public void removeEdge(Edge edge) { - if (!edges.contains(edge)) { - logger.fatal("Cannot remove edge: " + edge); - return; - } - edges.remove(edge); - requestEdgeAnalysis(); + ((AbstractRadioMedium.RadioMediumObservable) + this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + } - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); - } + public void removeEdge(Edge edge) { + if (!edges.contains(edge)) { + logger.fatal("Cannot remove edge: " + edge); + return; + } + edges.remove(edge); + requestEdgeAnalysis(); - public void clearEdges() { - edges.clear(); - requestEdgeAnalysis(); + ((AbstractRadioMedium.RadioMediumObservable) + this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + } - ((AbstractRadioMedium.RadioMediumObservable) - this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); - } + public void clearEdges() { + edges.clear(); + requestEdgeAnalysis(); - public Edge[] getEdges() { - return edges.toArray(new Edge[0]); - } + ((AbstractRadioMedium.RadioMediumObservable) + this.getRadioMediumObservable()).setRadioMediumChangedAndNotify(); + } - /** - * Signal that the configuration changed, and needs to be re-analyzed - * before used. - */ - public void requestEdgeAnalysis() { - edgesDirty = true; - } + public Edge[] getEdges() { + return edges.toArray(new Edge[0]); + } - public boolean needsEdgeAnalysis() { - return edgesDirty; - } + /** + * Signal that the configuration changed, and needs to be re-analyzed + * before used. + */ + public void requestEdgeAnalysis() { + edgesDirty = true; + } - public void unregisterRadioInterface(Radio radio, Simulation sim) { - super.unregisterRadioInterface(radio, sim); + public boolean needsEdgeAnalysis() { + return edgesDirty; + } - for (Edge edge: getEdges()) { - if (edge.source == radio || edge.superDest.radio == radio) { - removeEdge(edge); - requestEdgeAnalysis(); - } - } - } + public void unregisterRadioInterface(Radio radio, Simulation sim) { + super.unregisterRadioInterface(radio, sim); - public void updateSignalStrengths() { + for (Edge edge: getEdges()) { + if (edge.source == radio || edge.superDest.radio == radio) { + removeEdge(edge); + requestEdgeAnalysis(); + } + } + } - /* Reset signal strengths */ - for (Radio radio : getRegisteredRadios()) { - radio.setCurrentSignalStrength(SS_NOTHING); - } + public void updateSignalStrengths() { - /* Set signal strengths */ - RadioConnection[] conns = getActiveConnections(); - for (RadioConnection conn : conns) { - 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); - } - } - } + /* Reset signal strengths */ + for (Radio radio : getRegisteredRadios()) { + radio.setCurrentSignalStrength(SS_NOTHING); + } - /* 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); - } + /* Set signal strengths */ + RadioConnection[] conns = getActiveConnections(); + for (RadioConnection conn : conns) { + 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); + } + } + } - if (!intfRadio.isInterfered()) { - /*logger.warn("Radio was not interfered");*/ - intfRadio.interfereAnyReception(); - } - } - } - } + /* 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(); + } + } + } + } - /** - * Generates hash table using current edges for efficient lookup. - */ - protected void analyzeEdges() { - Hashtable> listTable = - new Hashtable>(); + /** + * Generates hash table using current edges for efficient lookup. + */ + protected void analyzeEdges() { + Hashtable> listTable = + new Hashtable>(); - /* Fill edge hash table with all edges */ - for (Edge edge: getEdges()) { - ArrayList destRadios; - if (!listTable.containsKey(edge.source)) { - destRadios = new ArrayList(); - } else { - destRadios = listTable.get(edge.source); - } + /* Fill edge hash table with all edges */ + for (Edge edge: getEdges()) { + ArrayList destRadios; + if (!listTable.containsKey(edge.source)) { + destRadios = new ArrayList(); + } else { + destRadios = listTable.get(edge.source); + } - destRadios.add(edge.superDest); - listTable.put(edge.source, destRadios); - } + destRadios.add(edge.superDest); + listTable.put(edge.source, destRadios); + } - /* Convert to arrays */ - Hashtable arrTable = new Hashtable(); - Enumeration sources = listTable.keys(); - while (sources.hasMoreElements()) { - Radio source = sources.nextElement(); - DestinationRadio[] arr = listTable.get(source).toArray(new DestinationRadio[0]); - arrTable.put(source, arr); - } + /* Convert to arrays */ + Hashtable arrTable = new Hashtable(); + Enumeration sources = listTable.keys(); + while (sources.hasMoreElements()) { + Radio source = sources.nextElement(); + DestinationRadio[] arr = listTable.get(source).toArray(new DestinationRadio[0]); + arrTable.put(source, arr); + } - this.edgesTable = arrTable; - edgesDirty = false; - } + this.edgesTable = arrTable; + edgesDirty = false; + } - /** - * Returns all potential destination radios, i.e. all radios "within reach". - * Does not consider radio channels, transmission success ratios etc. - * - * @param source Source radio - * @return All potential destination radios - */ - public DestinationRadio[] getPotentialDestinations(Radio source) { - if (edgesDirty) { - analyzeEdges(); - } - return edgesTable.get(source); - } + /** + * Returns all potential destination radios, i.e. all radios "within reach". + * Does not consider radio channels, transmission success ratios etc. + * + * @param source Source radio + * @return All potential destination radios + */ + public DestinationRadio[] getPotentialDestinations(Radio source) { + if (edgesDirty) { + analyzeEdges(); + } + return edgesTable.get(source); + } - public RadioConnection createConnections(Radio source) { - if (edgesDirty) { - analyzeEdges(); - } - if (edgesDirty) { - logger.fatal("Error when analyzing edges, aborting new radio connection"); - return new RadioConnection(source); - } + public RadioConnection createConnections(Radio source) { + if (edgesDirty) { + analyzeEdges(); + } + if (edgesDirty) { + logger.fatal("Error when analyzing edges, aborting new radio connection"); + return new RadioConnection(source); + } - /* Create new radio connection using edge hash table */ - RadioConnection newConn = new RadioConnection(source); - DestinationRadio[] destinations = getPotentialDestinations(source); - if (destinations == null || destinations.length == 0) { - /* No destinations */ - /*logger.info(sendingRadio + ": No dest");*/ - return newConn; - } + /* Create new radio connection using edge hash table */ + RadioConnection newConn = new RadioConnection(source); + DestinationRadio[] destinations = getPotentialDestinations(source); + if (destinations == null || destinations.length == 0) { + /* No destinations */ + /*logger.info(sendingRadio + ": No dest");*/ + return newConn; + } - /*logger.info(source + ": " + destinations.length + " potential destinations");*/ - for (DestinationRadio d: destinations) { - DGRMDestinationRadio dest = (DGRMDestinationRadio) d; - if (dest.radio == source) { - /* Fail: cannot receive our own transmission */ - /*logger.info(source + ": Fail, receiver is sender");*/ - continue; - } + /*logger.info(source + ": " + destinations.length + " potential destinations");*/ + for (DestinationRadio d: destinations) { + DGRMDestinationRadio dest = (DGRMDestinationRadio) d; + if (dest.radio == source) { + /* Fail: cannot receive our own transmission */ + /*logger.info(source + ": Fail, receiver is sender");*/ + continue; + } - /* Fail if radios are on different (but configured) channels */ - if (source.getChannel() >= 0 && - dest.radio.getChannel() >= 0 && - source.getChannel() != dest.radio.getChannel()) { - 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.isReceiverOn()) { - /* Fail: radio is off */ - /*logger.info(source + ": Fail, off");*/ - newConn.addInterfered(dest.radio); - continue; - } + if (!dest.radio.isReceiverOn()) { + /* Fail: radio is off */ + /*logger.info(source + ": Fail, off");*/ + 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); + 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; - } + 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); + 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; - } + /* 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");*/ - newConn.addInterfered(dest.radio); - continue; - } + if (dest.radio.isInterfered()) { + /* Fail: radio is interfered in another connection */ + /*logger.info(source + ": Fail, interfered");*/ + newConn.addInterfered(dest.radio); + continue; + } - /* Success: radio starts receiving */ - /*logger.info(source + ": OK: " + dest.radio);*/ - newConn.addDestination(dest.radio, dest.delay); - } + /* Success: radio starts receiving */ + /*logger.info(source + ": OK: " + dest.radio);*/ + newConn.addDestination(dest.radio, dest.delay); + } - return newConn; - } + return newConn; + } - public Collection getConfigXML() { - ArrayList config = new ArrayList(); - Element element; + public Collection getConfigXML() { + ArrayList config = new ArrayList(); + Element element; - for (Edge edge: getEdges()) { - element = new Element("edge"); - element.addContent(edge.getConfigXML()); - config.add(element); - } + for (Edge edge: getEdges()) { + element = new Element("edge"); + element.addContent(edge.getConfigXML()); + config.add(element); + } - return config; - } + return config; + } - private Collection delayedConfiguration = null; - public boolean setConfigXML(Collection configXML, boolean visAvailable) { - random = simulation.getRandomGenerator(); + private Collection delayedConfiguration = null; + public boolean setConfigXML(Collection configXML, boolean visAvailable) { + random = simulation.getRandomGenerator(); - /* Wait until simulation has been loaded */ - delayedConfiguration = configXML; - return true; - } - public void simulationFinishedLoading() { - if (delayedConfiguration == null) { - return; - } + /* Wait until simulation has been loaded */ + delayedConfiguration = configXML; + return true; + } + public void simulationFinishedLoading() { + if (delayedConfiguration == null) { + return; + } - boolean warnedOldConfig = false; - for (Element element : delayedConfiguration) { - if (element.getName().equals("edge")) { - Collection edgeConfig = element.getChildren(); - Radio source = null; - DestinationRadio dest = null; - for (Element edgeElement : edgeConfig) { - if (edgeElement.getName().equals("src")) { - /* Old version, ignore edge */ - if (!warnedOldConfig) { - logger.fatal("Old simulation config detected: DGRM links will not be imported"); - warnedOldConfig = true; - } - return; - } else if (edgeElement.getName().equals("source")) { - source = simulation.getMoteWithID( - Integer.parseInt(edgeElement.getText())).getInterfaces().getRadio(); - } else if (edgeElement.getName().equals("dest")) { - String destClassName = edgeElement.getText().trim(); - if (destClassName == null || destClassName.isEmpty()) { - continue; - } - Class destClass = - simulation.getGUI().tryLoadClass(this, DestinationRadio.class, destClassName); - if (destClass == null) { - throw new RuntimeException("Could not load class: " + destClassName); - } - try { - dest = destClass.newInstance(); - dest.setConfigXML(edgeElement.getChildren(), simulation); - } catch (Exception e) { - throw (RuntimeException) - new RuntimeException("Unknown class: " + destClassName).initCause(e); - } - } - } - if (source == null || dest == null) { - if (!warnedOldConfig) { - logger.fatal("Old simulation config detected: DGRM links will not be imported"); - warnedOldConfig = true; - } - } else { - addEdge(new Edge(source, dest)); - } - } - } - requestEdgeAnalysis(); - delayedConfiguration = null; - } + boolean oldConfig = false; + for (Element element : delayedConfiguration) { + if (element.getName().equals("edge")) { + Collection edgeConfig = element.getChildren(); + Radio source = null; + DestinationRadio dest = null; + for (Element edgeElement : edgeConfig) { + if (edgeElement.getName().equals("src")) { + oldConfig = true; - public static class Edge { - public Radio source = null; - public DestinationRadio superDest = null; + /* Old config: lookup source mote */ + for (Mote m: simulation.getMotes()) { + if (m.toString().equals(edgeElement.getText())) { + logger.info("Old config: mapping '" + edgeElement.getText() + "' to node " + m.getID()); + source = m.getInterfaces().getRadio(); + break; + } + } + } else if (edgeElement.getName().equals("source")) { + source = simulation.getMoteWithID( + Integer.parseInt(edgeElement.getText())).getInterfaces().getRadio(); + } else if (oldConfig && edgeElement.getName().equals("ratio")) { + /* Old config: parse link ratio */ + double ratio = Double.parseDouble(edgeElement.getText()); + ((DGRMDestinationRadio)dest).ratio = ratio; + } else if (edgeElement.getName().equals("dest")) { + if (oldConfig) { + /* Old config: create simple destination link */ + Radio destRadio = null; + for (Mote m: simulation.getMotes()) { + if (m.toString().equals(edgeElement.getText())) { + logger.info("Old config: mapping '" + edgeElement.getText() + "' to node " + m.getID()); + destRadio = m.getInterfaces().getRadio(); + break; + } + } + dest = new DGRMDestinationRadio(destRadio); + } else { + String destClassName = edgeElement.getText().trim(); + if (destClassName == null || destClassName.isEmpty()) { + continue; + } + Class destClass = + simulation.getGUI().tryLoadClass(this, DestinationRadio.class, destClassName); + if (destClass == null) { + throw new RuntimeException("Could not load class: " + destClassName); + } + try { + dest = destClass.newInstance(); + dest.setConfigXML(edgeElement.getChildren(), simulation); + } catch (Exception e) { + throw (RuntimeException) + new RuntimeException("Unknown class: " + destClassName).initCause(e); + } + } + } + } + if (source == null || dest == null) { + logger.fatal("Failed loading DGRM links, aborting"); + return; + } else { + addEdge(new Edge(source, dest)); + } + } + } + requestEdgeAnalysis(); + delayedConfiguration = null; + } - public Edge(Radio source, DestinationRadio dest) { - this.source = source; - this.superDest = dest; - } + public static class Edge { + public Radio source = null; + public DestinationRadio superDest = null; - private Collection getConfigXML() { - ArrayList config = new ArrayList(); - Element element; + public Edge(Radio source, DestinationRadio dest) { + this.source = source; + this.superDest = dest; + } - element = new Element("source"); - element.setText("" + source.getMote().getID()); - config.add(element); + private Collection getConfigXML() { + ArrayList config = new ArrayList(); + Element element; - element = new Element("dest"); - element.setText(superDest.getClass().getName()); - Collection destConfig = superDest.getConfigXML(); - if (destConfig != null) { - element.addContent(destConfig); - config.add(element); - } + element = new Element("source"); + element.setText("" + source.getMote().getID()); + config.add(element); - return config; - } - } + element = new Element("dest"); + element.setText(superDest.getClass().getName()); + Collection destConfig = superDest.getConfigXML(); + if (destConfig != null) { + element.addContent(destConfig); + config.add(element); + } + + return config; + } + } }