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
This commit is contained in:
Atis Elsts 2015-04-03 21:08:36 +02:00
parent 6c706e53ee
commit 67427b9b86
5 changed files with 60 additions and 17 deletions

View file

@ -169,6 +169,7 @@ public class MRM extends AbstractRadioMedium {
if (sender.getChannel() >= 0 && if (sender.getChannel() >= 0 &&
recv.getChannel() >= 0 && recv.getChannel() >= 0 &&
sender.getChannel() != recv.getChannel()) { sender.getChannel() != recv.getChannel()) {
newConnection.addInterfered(recv);
continue; continue;
} }
final Radio recvFinal = recv; final Radio recvFinal = recv;
@ -313,15 +314,15 @@ public class MRM extends AbstractRadioMedium {
/* Interfering/colliding radio connections */ /* Interfering/colliding radio connections */
for (RadioConnection conn : conns) { for (RadioConnection conn : conns) {
for (Radio intfRadio : ((MRMRadioConnection) conn).getInterfered()) { for (Radio intfRadio : ((MRMRadioConnection) conn).getInterfered()) {
double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(intfRadio);
if (intfRadio.getCurrentSignalStrength() < signalStrength) {
intfRadio.setCurrentSignalStrength(signalStrength);
}
if (conn.getSource().getChannel() >= 0 && if (conn.getSource().getChannel() >= 0 &&
intfRadio.getChannel() >= 0 && intfRadio.getChannel() >= 0 &&
conn.getSource().getChannel() != intfRadio.getChannel()) { conn.getSource().getChannel() != intfRadio.getChannel()) {
continue; continue;
} }
double signalStrength = ((MRMRadioConnection) conn).getInterferenceSignalStrength(intfRadio);
if (intfRadio.getCurrentSignalStrength() < signalStrength) {
intfRadio.setCurrentSignalStrength(signalStrength);
}
if (!intfRadio.isInterfered()) { if (!intfRadio.isInterfered()) {
/*logger.warn("Radio was not interfered: " + intfRadio);*/ /*logger.warn("Radio was not interfered: " + intfRadio);*/

View file

@ -236,8 +236,9 @@ public abstract class AbstractRadioMedium extends RadioMedium {
case RECEPTION_STARTED: case RECEPTION_STARTED:
case RECEPTION_INTERFERED: case RECEPTION_INTERFERED:
case RECEPTION_FINISHED: case RECEPTION_FINISHED:
break;
case UNKNOWN: case UNKNOWN:
return;
case HW_ON: { case HW_ON: {
/* Update signal strengths */ /* Update signal strengths */
updateSignalStrengths(); updateSignalStrengths();
@ -292,7 +293,7 @@ public abstract class AbstractRadioMedium extends RadioMedium {
break; break;
case TRANSMISSION_FINISHED: { case TRANSMISSION_FINISHED: {
/* Remove radio connection */ /* Remove radio connection */
/* Connection */ /* Connection */
RadioConnection connection = getActiveConnectionFrom(radio); RadioConnection connection = getActiveConnectionFrom(radio);
if (connection == null) { if (connection == null) {
@ -322,7 +323,10 @@ public abstract class AbstractRadioMedium extends RadioMedium {
COUNTER_RX += connection.getDestinations().length; COUNTER_RX += connection.getDestinations().length;
COUNTER_INTERFERED += connection.getInterfered().length; COUNTER_INTERFERED += connection.getInterfered().length;
for (Radio intRadio : connection.getInterferedNonDestinations()) { for (Radio intRadio : connection.getInterferedNonDestinations()) {
intRadio.signalReceptionEnd();
if (intRadio.isInterfered()) {
intRadio.signalReceptionEnd();
}
} }
/* Update signal strengths */ /* Update signal strengths */

View file

@ -42,6 +42,7 @@ public class DGRMDestinationRadio extends DestinationRadio {
public double signal = AbstractRadioMedium.SS_STRONG; /* RSSI */ public double signal = AbstractRadioMedium.SS_STRONG; /* RSSI */
public long delay = 0; /* EXPERIMENTAL: Propagation delay (us). */ public long delay = 0; /* EXPERIMENTAL: Propagation delay (us). */
public int lqi = 105; public int lqi = 105;
public int channel = -1; /* not set by default */
public DGRMDestinationRadio() { public DGRMDestinationRadio() {
super(); super();
@ -50,12 +51,17 @@ public class DGRMDestinationRadio extends DestinationRadio {
super(dest); super(dest);
} }
public int getChannel() {
return channel;
}
protected Object clone() { protected Object clone() {
DGRMDestinationRadio clone = new DGRMDestinationRadio(this.radio); DGRMDestinationRadio clone = new DGRMDestinationRadio(this.radio);
clone.ratio = this.ratio; clone.ratio = this.ratio;
clone.delay = this.delay; clone.delay = this.delay;
clone.signal = this.signal; clone.signal = this.signal;
clone.lqi = this.lqi; clone.lqi = this.lqi;
clone.channel = this.channel;
return clone; return clone;
} }
@ -75,10 +81,13 @@ public class DGRMDestinationRadio extends DestinationRadio {
element.setText("" + lqi); element.setText("" + lqi);
config.add(element); config.add(element);
element = new Element("delay"); element = new Element("delay");
element.setText("" + delay); element.setText("" + delay);
config.add(element); config.add(element);
element = new Element("channel");
element.setText("" + channel);
config.add(element);
return config; return config;
} }
@ -96,6 +105,8 @@ public class DGRMDestinationRadio extends DestinationRadio {
lqi = Integer.parseInt(element.getText()); lqi = Integer.parseInt(element.getText());
} else if (element.getName().equals("delay")) { } else if (element.getName().equals("delay")) {
delay = Long.parseLong(element.getText()); delay = Long.parseLong(element.getText());
} else if (element.getName().equals("channel")) {
channel = Integer.parseInt(element.getText());
} }
} }
return true; return true;

View file

@ -166,6 +166,19 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
DGRMDestinationRadio dstRadios[] = getPotentialDestinations(conn.getSource()); DGRMDestinationRadio dstRadios[] = getPotentialDestinations(conn.getSource());
if (dstRadios == null) continue; if (dstRadios == null) continue;
for (DGRMDestinationRadio dstRadio : dstRadios) { 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) { if (dstRadio.radio.getCurrentSignalStrength() < dstRadio.signal) {
dstRadio.radio.setCurrentSignalStrength(dstRadio.signal); dstRadio.radio.setCurrentSignalStrength(dstRadio.signal);
} }
@ -247,13 +260,27 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
/*logger.info(source + ": " + destinations.length + " potential destinations");*/ /*logger.info(source + ": " + destinations.length + " potential destinations");*/
for (DGRMDestinationRadio dest: destinations) { for (DGRMDestinationRadio dest: destinations) {
if (dest.radio == source) { if (dest.radio == source) {
/* Fail: cannot receive our own transmission */ /* Fail: cannot receive our own transmission */
/*logger.info(source + ": Fail, receiver is sender");*/ /*logger.info(source + ": Fail, receiver is sender");*/
continue; 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()) { if (!dest.radio.isRadioOn()) {
/* Fail: radio is off */ /* Fail: radio is off */
@ -268,14 +295,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
newConn.addInterfered(dest.radio); newConn.addInterfered(dest.radio);
continue; 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()) { if (dest.radio.isReceiving()) {
/* Fail: radio is already actively receiving */ /* Fail: radio is already actively receiving */
/*logger.info(source + ": Fail, receiving");*/ /*logger.info(source + ": Fail, receiving");*/

View file

@ -192,6 +192,13 @@ public class UDGM extends AbstractRadioMedium {
if (sender.getChannel() >= 0 && if (sender.getChannel() >= 0 &&
recv.getChannel() >= 0 && recv.getChannel() >= 0 &&
sender.getChannel() != recv.getChannel()) { 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; continue;
} }
Position recvPos = recv.getPosition(); Position recvPos = recv.getPosition();