From 67427b9b8639d550362888d97899e122a6e6d647 Mon Sep 17 00:00:00 2001 From: Atis Elsts Date: Fri, 3 Apr 2015 21:08:36 +0200 Subject: [PATCH] Improve multichannel support for Cooja. * Fix CCA detection in Cooja in the case when the receiver swicthes on the right channel during an ongoing transmission. Always add a connection on transmission, even when the channel is not correct. Initially the connection is in a dormant state; this mimics what Cooja is doing when the receiver radio is turned off; when the receiver is turned on and switched to the right channel, `updateSignalStrengths()` is called, and the connection starts to recieve PHY-level traffic. * Add "channel" property for DGRM edges. * Avoid cross-channel interference on DGRM and MRM radio mediums --- .../apps/mrm/java/org/contikios/mrm/MRM.java | 9 +++-- .../radiomediums/AbstractRadioMedium.java | 10 +++-- .../radiomediums/DGRMDestinationRadio.java | 13 ++++++- .../radiomediums/DirectedGraphMedium.java | 38 ++++++++++++++----- .../contikios/cooja/radiomediums/UDGM.java | 7 ++++ 5 files changed, 60 insertions(+), 17 deletions(-) diff --git a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java index 70e304d02..a19dcee58 100644 --- a/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java +++ b/tools/cooja/apps/mrm/java/org/contikios/mrm/MRM.java @@ -169,6 +169,7 @@ public class MRM extends AbstractRadioMedium { if (sender.getChannel() >= 0 && recv.getChannel() >= 0 && sender.getChannel() != recv.getChannel()) { + newConnection.addInterfered(recv); continue; } final Radio recvFinal = recv; @@ -313,15 +314,15 @@ public class MRM extends AbstractRadioMedium { /* Interfering/colliding radio connections */ for (RadioConnection conn : conns) { for (Radio intfRadio : ((MRMRadioConnection) conn).getInterfered()) { - double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(intfRadio); - if (intfRadio.getCurrentSignalStrength() < signalStrength) { - intfRadio.setCurrentSignalStrength(signalStrength); - } if (conn.getSource().getChannel() >= 0 && intfRadio.getChannel() >= 0 && conn.getSource().getChannel() != intfRadio.getChannel()) { continue; } + double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(intfRadio); + if (intfRadio.getCurrentSignalStrength() < signalStrength) { + intfRadio.setCurrentSignalStrength(signalStrength); + } if (!intfRadio.isInterfered()) { /*logger.warn("Radio was not interfered: " + intfRadio);*/ diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java index 0aed97d52..fce97e927 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/AbstractRadioMedium.java @@ -236,8 +236,9 @@ public abstract class AbstractRadioMedium extends RadioMedium { case RECEPTION_STARTED: case RECEPTION_INTERFERED: case RECEPTION_FINISHED: + break; + case UNKNOWN: - return; case HW_ON: { /* Update signal strengths */ updateSignalStrengths(); @@ -292,7 +293,7 @@ public abstract class AbstractRadioMedium extends RadioMedium { break; case TRANSMISSION_FINISHED: { /* Remove radio connection */ - + /* Connection */ RadioConnection connection = getActiveConnectionFrom(radio); if (connection == null) { @@ -322,7 +323,10 @@ public abstract class AbstractRadioMedium extends RadioMedium { COUNTER_RX += connection.getDestinations().length; COUNTER_INTERFERED += connection.getInterfered().length; for (Radio intRadio : connection.getInterferedNonDestinations()) { - intRadio.signalReceptionEnd(); + + if (intRadio.isInterfered()) { + intRadio.signalReceptionEnd(); + } } /* Update signal strengths */ diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/DGRMDestinationRadio.java b/tools/cooja/java/org/contikios/cooja/radiomediums/DGRMDestinationRadio.java index fb182f2d4..1147890c8 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/DGRMDestinationRadio.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/DGRMDestinationRadio.java @@ -42,6 +42,7 @@ public class DGRMDestinationRadio extends DestinationRadio { public double signal = AbstractRadioMedium.SS_STRONG; /* RSSI */ public long delay = 0; /* EXPERIMENTAL: Propagation delay (us). */ public int lqi = 105; + public int channel = -1; /* not set by default */ public DGRMDestinationRadio() { super(); @@ -50,12 +51,17 @@ public class DGRMDestinationRadio extends DestinationRadio { super(dest); } + public int getChannel() { + return channel; + } + protected Object clone() { DGRMDestinationRadio clone = new DGRMDestinationRadio(this.radio); clone.ratio = this.ratio; clone.delay = this.delay; clone.signal = this.signal; clone.lqi = this.lqi; + clone.channel = this.channel; return clone; } @@ -75,10 +81,13 @@ public class DGRMDestinationRadio extends DestinationRadio { element.setText("" + lqi); config.add(element); - element = new Element("delay"); element.setText("" + delay); config.add(element); + + element = new Element("channel"); + element.setText("" + channel); + config.add(element); return config; } @@ -96,6 +105,8 @@ public class DGRMDestinationRadio extends DestinationRadio { lqi = Integer.parseInt(element.getText()); } else if (element.getName().equals("delay")) { delay = Long.parseLong(element.getText()); + } else if (element.getName().equals("channel")) { + channel = Integer.parseInt(element.getText()); } } return true; diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java index 23db83c3c..57876357c 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/DirectedGraphMedium.java @@ -166,6 +166,19 @@ public class DirectedGraphMedium extends AbstractRadioMedium { DGRMDestinationRadio dstRadios[] = getPotentialDestinations(conn.getSource()); if (dstRadios == null) continue; for (DGRMDestinationRadio dstRadio : dstRadios) { + + int activeSourceChannel = conn.getSource().getChannel(); + int edgeChannel = dstRadio.channel; + int activeDstChannel = dstRadio.radio.getChannel(); + if (activeSourceChannel != -1) { + if (edgeChannel != -1 && activeSourceChannel != edgeChannel) { + continue; + } + if (activeDstChannel != -1 && activeSourceChannel != activeDstChannel) { + continue; + } + } + if (dstRadio.radio.getCurrentSignalStrength() < dstRadio.signal) { dstRadio.radio.setCurrentSignalStrength(dstRadio.signal); } @@ -247,13 +260,27 @@ public class DirectedGraphMedium extends AbstractRadioMedium { /*logger.info(source + ": " + destinations.length + " potential destinations");*/ for (DGRMDestinationRadio dest: destinations) { - + if (dest.radio == source) { /* Fail: cannot receive our own transmission */ /*logger.info(source + ": Fail, receiver is sender");*/ continue; } + int srcc = source.getChannel(); + int dstc = dest.radio.getChannel(); + int edgeChannel = dest.getChannel(); + + if (edgeChannel >= 0 && dstc >= 0 && edgeChannel != dstc) { + /* Fail: the edge is configured for a different radio channel */ + continue; + } + + if (srcc >= 0 && dstc >= 0 && srcc != dstc) { + /* Fail: radios are on different (but configured) channels */ + newConn.addInterfered(dest.radio); + continue; + } if (!dest.radio.isRadioOn()) { /* Fail: radio is off */ @@ -268,14 +295,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium { newConn.addInterfered(dest.radio); 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");*/ diff --git a/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java b/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java index e0ff8af38..9d7b752fc 100644 --- a/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java +++ b/tools/cooja/java/org/contikios/cooja/radiomediums/UDGM.java @@ -192,6 +192,13 @@ public class UDGM extends AbstractRadioMedium { if (sender.getChannel() >= 0 && recv.getChannel() >= 0 && sender.getChannel() != recv.getChannel()) { + + /* Add the connection in a dormant state; + it will be activated later when the radio will be + turned on and switched to the right channel. This behavior + is consistent with the case when receiver is turned off. */ + newConnection.addInterfered(recv); + continue; } Position recvPos = recv.getPosition();