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 &&
|
||||
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);*/
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");*/
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue