}
/* Loop through all potential destinations */
Position senderPos = sender.getPosition();
for (DestinationRadio dest: potentialDestinations) {
Radio recv = dest.radio;
/* Fail if radios are on different (but configured) channels */
if (sender.getChannel() >= 0 &&
recv.getChannel() >= 0 &&
sender.getChannel() != recv.getChannel()) {
continue;
}
Position recvPos = recv.getPosition();
/* Fail if radio is turned off */
// if (!recv.isReceiverOn()) {
// /* Special case: allow connection if source is Contiki radio,
// * and destination is something else (byte radio).
// * Allows cross-level communication with power-saving MACs. */
// if (sender instanceof ContikiRadio &&
// !(recv instanceof ContikiRadio)) {
// /*logger.info("Special case: creating connection to turned off radio");*/
// } else {
// recv.interfereAnyReception();
// continue;
// }
// }
double distance = senderPos.getDistanceTo(recvPos);
if (distance <= moteTransmissionRange) {
/* Within transmission range */
if (!recv.isRadioOn()) {
newConnection.addInterfered(recv);
recv.interfereAnyReception();
} else if (recv.isInterfered()) {
/* Was interfered: keep interfering */
newConnection.addInterfered(recv);
} else if (recv.isTransmitting()) {
newConnection.addInterfered(recv);
} else if (recv.isReceiving() ||
(random.nextDouble() > getRxSuccessProbability(sender, recv))) {
/* Was receiving, or reception failed: start interfering */
newConnection.addInterfered(recv);
recv.interfereAnyReception();
/* Interfere receiver in all other active radio connections */
for (RadioConnection conn : getActiveConnections()) {
if (conn.isDestination(recv)) {
conn.addInterfered(recv);
}
}
} else {
/* Success: radio starts receiving */
newConnection.addDestination(recv);
}
} else if (distance <= moteInterferenceRange) {
/* Within interference range */
newConnection.addInterfered(recv);
recv.interfereAnyReception();
}
}
return newConnection;
}