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 &&
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);*/

View file

@ -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();
@ -322,8 +323,11 @@ public abstract class AbstractRadioMedium extends RadioMedium {
COUNTER_RX += connection.getDestinations().length;
COUNTER_INTERFERED += connection.getInterfered().length;
for (Radio intRadio : connection.getInterferedNonDestinations()) {
if (intRadio.isInterfered()) {
intRadio.signalReceptionEnd();
}
}
/* Update signal strengths */
updateSignalStrengths();

View file

@ -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,11 +81,14 @@ 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;

View file

@ -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);
}
@ -254,6 +267,20 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
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 */
@ -269,13 +296,6 @@ 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");*/

View file

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