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:
parent
6c706e53ee
commit
67427b9b86
|
@ -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);*/
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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");*/
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue