commit
150cb33b94
|
@ -382,6 +382,20 @@ public class Msp802154Radio extends Radio implements CustomDataRadio {
|
||||||
rssiLastCounter = 8;
|
rssiLastCounter = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This will set the CORR-value of the CC2420
|
||||||
|
*
|
||||||
|
* @see se.sics.cooja.interfaces.Radio#setLQI(int)
|
||||||
|
*/
|
||||||
|
public void setLQI(int lqi){
|
||||||
|
radio.setLQI(lqi);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLQI(){
|
||||||
|
return radio.getLQI();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Mote getMote() {
|
public Mote getMote() {
|
||||||
return mote;
|
return mote;
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,25 @@ public abstract class Radio extends MoteInterface {
|
||||||
*/
|
*/
|
||||||
public abstract int getOutputPowerIndicatorMax();
|
public abstract int getOutputPowerIndicatorMax();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current LQI-value. This might differ from platform to platform
|
||||||
|
* @return Current LQI value.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public int getLQI() throws UnsupportedOperationException {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the LQI. This in not supported by all platforms. Also results may differ
|
||||||
|
* from platform to platform.
|
||||||
|
*
|
||||||
|
* @param lqi The current LQI
|
||||||
|
*/
|
||||||
|
public void setLQI(int lqi){
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current surrounding signal strength
|
* @return Current surrounding signal strength
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -91,9 +91,11 @@ public class DGRMConfigurator extends VisPlugin {
|
||||||
private final static int IDX_DST = 1;
|
private final static int IDX_DST = 1;
|
||||||
private final static int IDX_RATIO = 2;
|
private final static int IDX_RATIO = 2;
|
||||||
private final static int IDX_SIGNAL = 3;
|
private final static int IDX_SIGNAL = 3;
|
||||||
private final static int IDX_DELAY = 4;
|
private final static int IDX_LQI = 4;
|
||||||
|
private final static int IDX_DELAY = 5;
|
||||||
|
|
||||||
private final static String[] COLUMN_NAMES = new String[] {
|
private final static String[] COLUMN_NAMES = new String[] {
|
||||||
"Source", "Destination", "RX Ratio", "RSSI", "Delay"
|
"Source", "Destination", "RX Ratio", "RSSI","LQI", "Delay"
|
||||||
};
|
};
|
||||||
|
|
||||||
private GUI gui = null;
|
private GUI gui = null;
|
||||||
|
@ -128,6 +130,10 @@ public class DGRMConfigurator extends VisPlugin {
|
||||||
for (double d=AbstractRadioMedium.SS_STRONG; d >= AbstractRadioMedium.SS_WEAK; d -= 1) {
|
for (double d=AbstractRadioMedium.SS_STRONG; d >= AbstractRadioMedium.SS_WEAK; d -= 1) {
|
||||||
combo.addItem((int) d);
|
combo.addItem((int) d);
|
||||||
}
|
}
|
||||||
|
} else if (column == IDX_LQI) {
|
||||||
|
for (int d = 110; d > 50; d -= 5) {
|
||||||
|
combo.addItem((int) d);
|
||||||
|
}
|
||||||
} else if (column == IDX_DELAY) {
|
} else if (column == IDX_DELAY) {
|
||||||
for (double d=0; d <= 5; d++) {
|
for (double d=0; d <= 5; d++) {
|
||||||
combo.addItem(d);
|
combo.addItem(d);
|
||||||
|
@ -161,6 +167,17 @@ public class DGRMConfigurator extends VisPlugin {
|
||||||
setText(String.format("%1.1f dBm", v));
|
setText(String.format("%1.1f dBm", v));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
graphTable.getColumnModel().getColumn(IDX_LQI).setCellRenderer(new DefaultTableCellRenderer() {
|
||||||
|
private static final long serialVersionUID = -4669897764928372246L;
|
||||||
|
public void setValue(Object value) {
|
||||||
|
if (!(value instanceof Long)) {
|
||||||
|
setText(value.toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
long v = ((Long) value).longValue();
|
||||||
|
setText(String.valueOf(v));
|
||||||
|
}
|
||||||
|
});
|
||||||
graphTable.getColumnModel().getColumn(IDX_DELAY).setCellRenderer(new DefaultTableCellRenderer() {
|
graphTable.getColumnModel().getColumn(IDX_DELAY).setCellRenderer(new DefaultTableCellRenderer() {
|
||||||
private static final long serialVersionUID = -4669897764928372246L;
|
private static final long serialVersionUID = -4669897764928372246L;
|
||||||
public void setValue(Object value) {
|
public void setValue(Object value) {
|
||||||
|
@ -174,6 +191,7 @@ public class DGRMConfigurator extends VisPlugin {
|
||||||
});
|
});
|
||||||
graphTable.getColumnModel().getColumn(IDX_RATIO).setCellEditor(new DefaultCellEditor(combo));
|
graphTable.getColumnModel().getColumn(IDX_RATIO).setCellEditor(new DefaultCellEditor(combo));
|
||||||
graphTable.getColumnModel().getColumn(IDX_SIGNAL).setCellEditor(new DefaultCellEditor(combo));
|
graphTable.getColumnModel().getColumn(IDX_SIGNAL).setCellEditor(new DefaultCellEditor(combo));
|
||||||
|
graphTable.getColumnModel().getColumn(IDX_LQI).setCellEditor(new DefaultCellEditor(combo));
|
||||||
graphTable.getColumnModel().getColumn(IDX_DELAY).setCellEditor(new DefaultCellEditor(combo));
|
graphTable.getColumnModel().getColumn(IDX_DELAY).setCellEditor(new DefaultCellEditor(combo));
|
||||||
|
|
||||||
graphTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
|
graphTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
|
||||||
|
@ -411,6 +429,9 @@ public class DGRMConfigurator extends VisPlugin {
|
||||||
if (column == IDX_SIGNAL) {
|
if (column == IDX_SIGNAL) {
|
||||||
return ((DGRMDestinationRadio)edge.superDest).signal;
|
return ((DGRMDestinationRadio)edge.superDest).signal;
|
||||||
}
|
}
|
||||||
|
if (column == IDX_LQI) {
|
||||||
|
return ((DGRMDestinationRadio)edge.superDest).lqi;
|
||||||
|
}
|
||||||
if (column == IDX_DELAY) {
|
if (column == IDX_DELAY) {
|
||||||
return ((DGRMDestinationRadio)edge.superDest).delay / Simulation.MILLISECOND;
|
return ((DGRMDestinationRadio)edge.superDest).delay / Simulation.MILLISECOND;
|
||||||
}
|
}
|
||||||
|
@ -433,7 +454,10 @@ public class DGRMConfigurator extends VisPlugin {
|
||||||
} else if (column == IDX_DELAY) {
|
} else if (column == IDX_DELAY) {
|
||||||
((DGRMDestinationRadio)edge.superDest).delay =
|
((DGRMDestinationRadio)edge.superDest).delay =
|
||||||
((Number)value).longValue() * Simulation.MILLISECOND;
|
((Number)value).longValue() * Simulation.MILLISECOND;
|
||||||
} else {
|
} else if (column == IDX_LQI) {
|
||||||
|
((DGRMDestinationRadio)edge.superDest).lqi = ((Number)value).intValue();
|
||||||
|
}
|
||||||
|
else {
|
||||||
super.setValueAt(value, row, column);
|
super.setValueAt(value, row, column);
|
||||||
}
|
}
|
||||||
radioMedium.requestEdgeAnalysis();
|
radioMedium.requestEdgeAnalysis();
|
||||||
|
@ -461,6 +485,9 @@ public class DGRMConfigurator extends VisPlugin {
|
||||||
if (column == IDX_SIGNAL) {
|
if (column == IDX_SIGNAL) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (column == IDX_LQI) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (column == IDX_DELAY) {
|
if (column == IDX_DELAY) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,6 +117,15 @@ public class DGRMVisualizerSkin implements VisualizerSkin {
|
||||||
g.drawString(msg, x - msgWidth/2, y + 2*Visualizer.MOTE_RADIUS + 3);
|
g.drawString(msg, x - msgWidth/2, y + 2*Visualizer.MOTE_RADIUS + 3);
|
||||||
for (DestinationRadio r: dests) {
|
for (DestinationRadio r: dests) {
|
||||||
double prob = ((DGRMDestinationRadio)r).ratio;
|
double prob = ((DGRMDestinationRadio)r).ratio;
|
||||||
|
double rssi = ((DGRMDestinationRadio)r).signal;
|
||||||
|
double pos_rssi = rssi + 100;
|
||||||
|
int lqi = ((DGRMDestinationRadio)r).lqi;
|
||||||
|
float red = (float)(1 - prob*pos_rssi/90*lqi/100);
|
||||||
|
if(red > 1) red = 1;
|
||||||
|
if(red < 0) red = 0;
|
||||||
|
float green = (float)(prob*pos_rssi/90*lqi/100);
|
||||||
|
if(green > 1) green = 1;
|
||||||
|
if(green < 0) green = 0;
|
||||||
if (prob == 0.0d) {
|
if (prob == 0.0d) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -124,7 +133,8 @@ public class DGRMVisualizerSkin implements VisualizerSkin {
|
||||||
Position pos = r.radio.getPosition();
|
Position pos = r.radio.getPosition();
|
||||||
Point pixel = visualizer.transformPositionToPixel(pos);
|
Point pixel = visualizer.transformPositionToPixel(pos);
|
||||||
msgWidth = fm.stringWidth(msg);
|
msgWidth = fm.stringWidth(msg);
|
||||||
g.setColor(new Color(1-(float)prob, (float)prob, 0.0f));
|
g.setColor(new Color(red, green, 0.0f));
|
||||||
|
g.drawString("LQI: " + lqi + " RSSI: " + rssi,(x + pixel.x)/2,(y + pixel.y)/2);
|
||||||
g.drawLine(x, y, pixel.x, pixel.y);
|
g.drawLine(x, y, pixel.x, pixel.y);
|
||||||
g.setColor(Color.BLACK);
|
g.setColor(Color.BLACK);
|
||||||
g.drawString(msg, pixel.x - msgWidth/2, pixel.y + 2*Visualizer.MOTE_RADIUS + 3);
|
g.drawString(msg, pixel.x - msgWidth/2, pixel.y + 2*Visualizer.MOTE_RADIUS + 3);
|
||||||
|
|
|
@ -61,416 +61,410 @@ import se.sics.cooja.interfaces.Radio;
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractRadioMedium extends RadioMedium {
|
public abstract class AbstractRadioMedium extends RadioMedium {
|
||||||
private static Logger logger = Logger.getLogger(AbstractRadioMedium.class);
|
private static Logger logger = Logger.getLogger(AbstractRadioMedium.class);
|
||||||
|
|
||||||
/* Signal strengths in dBm.
|
/* Signal strengths in dBm.
|
||||||
* Approx. values measured on TmoteSky */
|
* Approx. values measured on TmoteSky */
|
||||||
public static final double SS_NOTHING = -100;
|
public static final double SS_NOTHING = -100;
|
||||||
public static final double SS_STRONG = -10;
|
public static final double SS_STRONG = -10;
|
||||||
public static final double SS_WEAK = -95;
|
public static final double SS_WEAK = -95;
|
||||||
|
|
||||||
private ArrayList<Radio> registeredRadios = new ArrayList<Radio>();
|
private ArrayList<Radio> registeredRadios = new ArrayList<Radio>();
|
||||||
|
|
||||||
private ArrayList<RadioConnection> activeConnections = new ArrayList<RadioConnection>();
|
private ArrayList<RadioConnection> activeConnections = new ArrayList<RadioConnection>();
|
||||||
|
|
||||||
private RadioConnection lastConnection = null;
|
private RadioConnection lastConnection = null;
|
||||||
|
|
||||||
private Simulation simulation = null;
|
private Simulation simulation = null;
|
||||||
|
|
||||||
/* Book-keeping */
|
/* Book-keeping */
|
||||||
public int COUNTER_TX = 0;
|
public int COUNTER_TX = 0;
|
||||||
public int COUNTER_RX = 0;
|
public int COUNTER_RX = 0;
|
||||||
public int COUNTER_INTERFERED = 0;
|
public int COUNTER_INTERFERED = 0;
|
||||||
|
|
||||||
public class RadioMediumObservable extends Observable {
|
public class RadioMediumObservable extends Observable {
|
||||||
public void setRadioMediumChanged() {
|
public void setRadioMediumChanged() {
|
||||||
setChanged();
|
setChanged();
|
||||||
}
|
}
|
||||||
public void setRadioMediumChangedAndNotify() {
|
public void setRadioMediumChangedAndNotify() {
|
||||||
setChanged();
|
setChanged();
|
||||||
notifyObservers();
|
notifyObservers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RadioMediumObservable radioMediumObservable = new RadioMediumObservable();
|
private RadioMediumObservable radioMediumObservable = new RadioMediumObservable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor should always be called from implemented radio mediums.
|
* This constructor should always be called from implemented radio mediums.
|
||||||
*
|
*
|
||||||
* @param simulation Simulation
|
* @param simulation Simulation
|
||||||
*/
|
*/
|
||||||
public AbstractRadioMedium(Simulation simulation) {
|
public AbstractRadioMedium(Simulation simulation) {
|
||||||
this.simulation = simulation;
|
this.simulation = simulation;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return All registered radios
|
* @return All registered radios
|
||||||
*/
|
*/
|
||||||
public Radio[] getRegisteredRadios() {
|
public Radio[] getRegisteredRadios() {
|
||||||
return registeredRadios.toArray(new Radio[0]);
|
return registeredRadios.toArray(new Radio[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return All active connections
|
* @return All active connections
|
||||||
*/
|
*/
|
||||||
public RadioConnection[] getActiveConnections() {
|
public RadioConnection[] getActiveConnections() {
|
||||||
/* NOTE: toArray([0]) creates array and handles synchronization */
|
/* NOTE: toArray([0]) creates array and handles synchronization */
|
||||||
return activeConnections.toArray(new RadioConnection[0]);
|
return activeConnections.toArray(new RadioConnection[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new connection from given radio.
|
* Creates a new connection from given radio.
|
||||||
*
|
*
|
||||||
* Determines which radios should receive or be interfered by the transmission.
|
* Determines which radios should receive or be interfered by the transmission.
|
||||||
*
|
*
|
||||||
* @param radio Source radio
|
* @param radio Source radio
|
||||||
* @return New connection
|
* @return New connection
|
||||||
*/
|
*/
|
||||||
abstract public RadioConnection createConnections(Radio radio);
|
abstract public RadioConnection createConnections(Radio radio);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates all radio interfaces' signal strengths according to
|
* Updates all radio interfaces' signal strengths according to
|
||||||
* the current active connections.
|
* the current active connections.
|
||||||
*/
|
*/
|
||||||
public void updateSignalStrengths() {
|
public void updateSignalStrengths() {
|
||||||
|
|
||||||
/* Reset signal strengths */
|
/* Reset signal strengths */
|
||||||
for (Radio radio : getRegisteredRadios()) {
|
for (Radio radio : getRegisteredRadios()) {
|
||||||
radio.setCurrentSignalStrength(SS_NOTHING);
|
radio.setCurrentSignalStrength(SS_NOTHING);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set signal strength to strong on destinations */
|
/* Set signal strength to strong on destinations */
|
||||||
RadioConnection[] conns = getActiveConnections();
|
RadioConnection[] conns = getActiveConnections();
|
||||||
for (RadioConnection conn : conns) {
|
for (RadioConnection conn : conns) {
|
||||||
if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) {
|
if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) {
|
||||||
conn.getSource().setCurrentSignalStrength(SS_STRONG);
|
conn.getSource().setCurrentSignalStrength(SS_STRONG);
|
||||||
}
|
}
|
||||||
for (Radio dstRadio : conn.getDestinations()) {
|
for (Radio dstRadio : conn.getDestinations()) {
|
||||||
if (conn.getSource().getChannel() >= 0 &&
|
if (conn.getSource().getChannel() >= 0 &&
|
||||||
dstRadio.getChannel() >= 0 &&
|
dstRadio.getChannel() >= 0 &&
|
||||||
conn.getSource().getChannel() != dstRadio.getChannel()) {
|
conn.getSource().getChannel() != dstRadio.getChannel()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (dstRadio.getCurrentSignalStrength() < SS_STRONG) {
|
if (dstRadio.getCurrentSignalStrength() < SS_STRONG) {
|
||||||
dstRadio.setCurrentSignalStrength(SS_STRONG);
|
dstRadio.setCurrentSignalStrength(SS_STRONG);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set signal strength to weak on interfered */
|
/* Set signal strength to weak on interfered */
|
||||||
for (RadioConnection conn : conns) {
|
for (RadioConnection conn : conns) {
|
||||||
for (Radio intfRadio : conn.getInterfered()) {
|
for (Radio intfRadio : conn.getInterfered()) {
|
||||||
if (intfRadio.getCurrentSignalStrength() < SS_STRONG) {
|
if (intfRadio.getCurrentSignalStrength() < SS_STRONG) {
|
||||||
intfRadio.setCurrentSignalStrength(SS_STRONG);
|
intfRadio.setCurrentSignalStrength(SS_STRONG);
|
||||||
}
|
}
|
||||||
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;
|
||||||
}
|
}
|
||||||
if (!intfRadio.isInterfered()) {
|
if (!intfRadio.isInterfered()) {
|
||||||
/*logger.warn("Radio was not interfered");*/
|
/*logger.warn("Radio was not interfered");*/
|
||||||
intfRadio.interfereAnyReception();
|
intfRadio.interfereAnyReception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove given radio from any active connections.
|
* Remove given radio from any active connections.
|
||||||
* This method can be called if a radio node falls asleep or is removed.
|
* This method can be called if a radio node falls asleep or is removed.
|
||||||
*
|
*
|
||||||
* @param radio Radio
|
* @param radio Radio
|
||||||
*/
|
*/
|
||||||
private void removeFromActiveConnections(Radio radio) {
|
private void removeFromActiveConnections(Radio radio) {
|
||||||
/* This radio must not be a connection source */
|
/* This radio must not be a connection source */
|
||||||
RadioConnection connection = getActiveConnectionFrom(radio);
|
RadioConnection connection = getActiveConnectionFrom(radio);
|
||||||
if (connection != null) {
|
if (connection != null) {
|
||||||
logger.fatal("Connection source turned off radio: " + radio);
|
logger.fatal("Connection source turned off radio: " + radio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set interfered if currently a connection destination */
|
/* Set interfered if currently a connection destination */
|
||||||
for (RadioConnection conn : activeConnections) {
|
for (RadioConnection conn : activeConnections) {
|
||||||
if (conn.isDestination(radio)) {
|
if (conn.isDestination(radio)) {
|
||||||
conn.addInterfered(radio);
|
conn.addInterfered(radio);
|
||||||
if (!radio.isInterfered()) {
|
if (!radio.isInterfered()) {
|
||||||
radio.interfereAnyReception();
|
radio.interfereAnyReception();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RadioConnection getActiveConnectionFrom(Radio source) {
|
private RadioConnection getActiveConnectionFrom(Radio source) {
|
||||||
for (RadioConnection conn : activeConnections) {
|
for (RadioConnection conn : activeConnections) {
|
||||||
if (conn.getSource() == source) {
|
if (conn.getSource() == source) {
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This observer is responsible for detecting radio interface events, for example
|
* This observer is responsible for detecting radio interface events, for example
|
||||||
* new transmissions.
|
* new transmissions.
|
||||||
*/
|
*/
|
||||||
private Observer radioEventsObserver = new Observer() {
|
private Observer radioEventsObserver = new Observer() {
|
||||||
public void update(Observable obs, Object obj) {
|
public void update(Observable obs, Object obj) {
|
||||||
if (!(obs instanceof Radio)) {
|
if (!(obs instanceof Radio)) {
|
||||||
logger.fatal("Radio event dispatched by non-radio object");
|
logger.fatal("Radio event dispatched by non-radio object");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Radio radio = (Radio) obs;
|
Radio radio = (Radio) obs;
|
||||||
|
|
||||||
final Radio.RadioEvent event = radio.getLastEvent();
|
final Radio.RadioEvent event = radio.getLastEvent();
|
||||||
if (event == Radio.RadioEvent.RECEPTION_STARTED ||
|
|
||||||
event == Radio.RadioEvent.RECEPTION_INTERFERED ||
|
switch (event) {
|
||||||
event == Radio.RadioEvent.RECEPTION_FINISHED ||
|
case RECEPTION_STARTED:
|
||||||
event == Radio.RadioEvent.UNKNOWN) {
|
case RECEPTION_INTERFERED:
|
||||||
/* Ignored */
|
case RECEPTION_FINISHED:
|
||||||
return;
|
case UNKNOWN:
|
||||||
}
|
return;
|
||||||
|
case HW_ON: {
|
||||||
if (event == Radio.RadioEvent.HW_ON) {
|
/* Update signal strengths */
|
||||||
|
updateSignalStrengths();
|
||||||
/* Update signal strengths */
|
}
|
||||||
updateSignalStrengths();
|
break;
|
||||||
|
case HW_OFF: {
|
||||||
} else if (event == Radio.RadioEvent.HW_OFF) {
|
/* Remove any radio connections from this radio */
|
||||||
|
removeFromActiveConnections(radio);
|
||||||
/* Remove any radio connections from this radio */
|
/* Update signal strengths */
|
||||||
removeFromActiveConnections(radio);
|
updateSignalStrengths();
|
||||||
|
}
|
||||||
/* Update signal strengths */
|
break;
|
||||||
updateSignalStrengths();
|
case TRANSMISSION_STARTED: {
|
||||||
|
/* Create new radio connection */
|
||||||
} else if (event == Radio.RadioEvent.TRANSMISSION_STARTED) {
|
if (radio.isReceiving()) {
|
||||||
/* Create new radio connection */
|
/*
|
||||||
|
* Radio starts transmitting when it should be
|
||||||
if (radio.isReceiving()) {
|
* receiving! Ok, but it won't receive the packet
|
||||||
/* Radio starts transmitting when it should be receiving!
|
*/
|
||||||
* Ok, but it won't receive the packet */
|
radio.interfereAnyReception();
|
||||||
for (RadioConnection conn : activeConnections) {
|
for (RadioConnection conn : activeConnections) {
|
||||||
if (conn.isDestination(radio)) {
|
if (conn.isDestination(radio)) {
|
||||||
conn.addInterfered(radio);
|
conn.addInterfered(radio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
radio.interfereAnyReception();
|
}
|
||||||
}
|
|
||||||
|
RadioConnection newConnection = createConnections(radio);
|
||||||
RadioConnection newConnection = createConnections(radio);
|
activeConnections.add(newConnection);
|
||||||
activeConnections.add(newConnection);
|
|
||||||
for (Radio r: newConnection.getAllDestinations()) {
|
for (Radio r : newConnection.getAllDestinations()) {
|
||||||
if (newConnection.getDestinationDelay(r) == 0) {
|
if (newConnection.getDestinationDelay(r) == 0) {
|
||||||
r.signalReceptionStart();
|
r.signalReceptionStart();
|
||||||
} else {
|
} else {
|
||||||
|
/* EXPERIMENTAL: Simulating propagation delay */
|
||||||
/* EXPERIMENTAL: Simulating propagation delay */
|
final Radio delayedRadio = r;
|
||||||
final Radio delayedRadio = r;
|
TimeEvent delayedEvent = new TimeEvent(0) {
|
||||||
TimeEvent delayedEvent = new TimeEvent(0) {
|
public void execute(long t) {
|
||||||
public void execute(long t) {
|
delayedRadio.signalReceptionStart();
|
||||||
delayedRadio.signalReceptionStart();
|
}
|
||||||
}
|
};
|
||||||
};
|
simulation.scheduleEvent(delayedEvent, simulation.getSimulationTime() + newConnection.getDestinationDelay(r));
|
||||||
simulation.scheduleEvent(
|
|
||||||
delayedEvent,
|
}
|
||||||
simulation.getSimulationTime() + newConnection.getDestinationDelay(r));
|
} /* Update signal strengths */
|
||||||
|
updateSignalStrengths();
|
||||||
}
|
|
||||||
}
|
/* Notify observers */
|
||||||
|
lastConnection = null;
|
||||||
/* Update signal strengths */
|
radioMediumObservable.setRadioMediumChangedAndNotify();
|
||||||
updateSignalStrengths();
|
}
|
||||||
|
break;
|
||||||
/* Notify observers */
|
case TRANSMISSION_FINISHED: {
|
||||||
lastConnection = null;
|
/* Remove radio connection */
|
||||||
radioMediumObservable.setRadioMediumChangedAndNotify();
|
|
||||||
|
/* Connection */
|
||||||
} else if (event == Radio.RadioEvent.TRANSMISSION_FINISHED) {
|
RadioConnection connection = getActiveConnectionFrom(radio);
|
||||||
/* Remove radio connection */
|
if (connection == null) {
|
||||||
|
logger.fatal("No radio connection found");
|
||||||
/* Connection */
|
return;
|
||||||
RadioConnection connection = getActiveConnectionFrom(radio);
|
}
|
||||||
if (connection == null) {
|
|
||||||
logger.fatal("No radio connection found");
|
activeConnections.remove(connection);
|
||||||
return;
|
lastConnection = connection;
|
||||||
}
|
COUNTER_TX++;
|
||||||
|
for (Radio dstRadio : connection.getAllDestinations()) {
|
||||||
activeConnections.remove(connection);
|
if (connection.getDestinationDelay(dstRadio) == 0) {
|
||||||
lastConnection = connection;
|
dstRadio.signalReceptionEnd();
|
||||||
COUNTER_TX++;
|
} else {
|
||||||
for (Radio dstRadio : connection.getAllDestinations()) {
|
|
||||||
if (connection.getDestinationDelay(dstRadio) == 0) {
|
/* EXPERIMENTAL: Simulating propagation delay */
|
||||||
dstRadio.signalReceptionEnd();
|
final Radio delayedRadio = dstRadio;
|
||||||
} else {
|
TimeEvent delayedEvent = new TimeEvent(0) {
|
||||||
|
public void execute(long t) {
|
||||||
/* EXPERIMENTAL: Simulating propagation delay */
|
delayedRadio.signalReceptionEnd();
|
||||||
final Radio delayedRadio = dstRadio;
|
}
|
||||||
TimeEvent delayedEvent = new TimeEvent(0) {
|
};
|
||||||
public void execute(long t) {
|
simulation.scheduleEvent(delayedEvent,
|
||||||
delayedRadio.signalReceptionEnd();
|
simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio));
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
simulation.scheduleEvent(
|
COUNTER_RX += connection.getDestinations().length;
|
||||||
delayedEvent,
|
COUNTER_INTERFERED += connection.getInterfered().length;
|
||||||
simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio));
|
for (Radio intRadio : connection.getInterferedNonDestinations()) {
|
||||||
}
|
intRadio.signalReceptionEnd();
|
||||||
}
|
}
|
||||||
COUNTER_RX += connection.getDestinations().length;
|
|
||||||
COUNTER_INTERFERED += connection.getInterfered().length;
|
/* Update signal strengths */
|
||||||
for (Radio intRadio : connection.getInterferedNonDestinations()) {
|
updateSignalStrengths();
|
||||||
intRadio.signalReceptionEnd();
|
|
||||||
}
|
/* Notify observers */
|
||||||
|
radioMediumObservable.setRadioMediumChangedAndNotify();
|
||||||
/* Update signal strengths */
|
}
|
||||||
updateSignalStrengths();
|
break;
|
||||||
|
case CUSTOM_DATA_TRANSMITTED: {
|
||||||
/* Notify observers */
|
|
||||||
radioMediumObservable.setRadioMediumChangedAndNotify();
|
/* Connection */
|
||||||
|
RadioConnection connection = getActiveConnectionFrom(radio);
|
||||||
} else if (event == Radio.RadioEvent.CUSTOM_DATA_TRANSMITTED) {
|
if (connection == null) {
|
||||||
|
logger.fatal("No radio connection found");
|
||||||
/* Connection */
|
return;
|
||||||
RadioConnection connection = getActiveConnectionFrom(radio);
|
}
|
||||||
if (connection == null) {
|
|
||||||
logger.fatal("No radio connection found");
|
/* Custom data object */
|
||||||
return;
|
Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted();
|
||||||
}
|
if (data == null) {
|
||||||
|
logger.fatal("No custom data object to forward");
|
||||||
/* Custom data object */
|
return;
|
||||||
Object data = ((CustomDataRadio) radio).getLastCustomDataTransmitted();
|
}
|
||||||
if (data == null) {
|
|
||||||
logger.fatal("No custom data object to forward");
|
for (Radio dstRadio : connection.getAllDestinations()) {
|
||||||
return;
|
|
||||||
}
|
if (!radio.getClass().equals(dstRadio.getClass()) || !(radio instanceof CustomDataRadio)) {
|
||||||
|
/* Radios communicate via radio packets */
|
||||||
for (Radio dstRadio : connection.getAllDestinations()) {
|
continue;
|
||||||
|
}
|
||||||
if (!radio.getClass().equals(dstRadio.getClass()) ||
|
|
||||||
!(radio instanceof CustomDataRadio)) {
|
if (connection.getDestinationDelay(dstRadio) == 0) {
|
||||||
/* Radios communicate via radio packets */
|
((CustomDataRadio) dstRadio).receiveCustomData(data);
|
||||||
continue;
|
} else {
|
||||||
}
|
|
||||||
|
/* EXPERIMENTAL: Simulating propagation delay */
|
||||||
if (connection.getDestinationDelay(dstRadio) == 0) {
|
final CustomDataRadio delayedRadio = (CustomDataRadio) dstRadio;
|
||||||
((CustomDataRadio) dstRadio).receiveCustomData(data);
|
final Object delayedData = data;
|
||||||
} else {
|
TimeEvent delayedEvent = new TimeEvent(0) {
|
||||||
|
public void execute(long t) {
|
||||||
/* EXPERIMENTAL: Simulating propagation delay */
|
delayedRadio.receiveCustomData(delayedData);
|
||||||
final CustomDataRadio delayedRadio = (CustomDataRadio) dstRadio;
|
}
|
||||||
final Object delayedData = data;
|
};
|
||||||
TimeEvent delayedEvent = new TimeEvent(0) {
|
simulation.scheduleEvent(delayedEvent,
|
||||||
public void execute(long t) {
|
simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio));
|
||||||
delayedRadio.receiveCustomData(delayedData);
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
simulation.scheduleEvent(
|
|
||||||
delayedEvent,
|
}
|
||||||
simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio));
|
break;
|
||||||
|
case PACKET_TRANSMITTED: {
|
||||||
}
|
/* Connection */
|
||||||
}
|
RadioConnection connection = getActiveConnectionFrom(radio);
|
||||||
|
if (connection == null) {
|
||||||
} else if (event == Radio.RadioEvent.PACKET_TRANSMITTED) {
|
logger.fatal("No radio connection found");
|
||||||
|
return;
|
||||||
/* Connection */
|
}
|
||||||
RadioConnection connection = getActiveConnectionFrom(radio);
|
|
||||||
if (connection == null) {
|
/* Radio packet */
|
||||||
logger.fatal("No radio connection found");
|
RadioPacket packet = radio.getLastPacketTransmitted();
|
||||||
return;
|
if (packet == null) {
|
||||||
}
|
logger.fatal("No radio packet to forward");
|
||||||
|
return;
|
||||||
/* Radio packet */
|
}
|
||||||
RadioPacket packet = radio.getLastPacketTransmitted();
|
|
||||||
if (packet == null) {
|
for (Radio dstRadio : connection.getAllDestinations()) {
|
||||||
logger.fatal("No radio packet to forward");
|
|
||||||
return;
|
if (radio.getClass().equals(dstRadio.getClass()) && radio instanceof CustomDataRadio) {
|
||||||
}
|
/* Radios instead communicate via custom data objects */
|
||||||
|
continue;
|
||||||
for (Radio dstRadio : connection.getAllDestinations()) {
|
}
|
||||||
|
|
||||||
if (radio.getClass().equals(dstRadio.getClass()) &&
|
/* Forward radio packet */
|
||||||
radio instanceof CustomDataRadio) {
|
if (connection.getDestinationDelay(dstRadio) == 0) {
|
||||||
/* Radios instead communicate via custom data objects */
|
dstRadio.setReceivedPacket(packet);
|
||||||
continue;
|
} else {
|
||||||
}
|
|
||||||
|
/* EXPERIMENTAL: Simulating propagation delay */
|
||||||
/* Forward radio packet */
|
final Radio delayedRadio = dstRadio;
|
||||||
if (connection.getDestinationDelay(dstRadio) == 0) {
|
final RadioPacket delayedPacket = packet;
|
||||||
dstRadio.setReceivedPacket(packet);
|
TimeEvent delayedEvent = new TimeEvent(0) {
|
||||||
} else {
|
public void execute(long t) {
|
||||||
|
delayedRadio.setReceivedPacket(delayedPacket);
|
||||||
/* EXPERIMENTAL: Simulating propagation delay */
|
}
|
||||||
final Radio delayedRadio = dstRadio;
|
};
|
||||||
final RadioPacket delayedPacket = packet;
|
simulation.scheduleEvent(delayedEvent,
|
||||||
TimeEvent delayedEvent = new TimeEvent(0) {
|
simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio));
|
||||||
public void execute(long t) {
|
}
|
||||||
delayedRadio.setReceivedPacket(delayedPacket);
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
simulation.scheduleEvent(
|
break;
|
||||||
delayedEvent,
|
default:
|
||||||
simulation.getSimulationTime() + connection.getDestinationDelay(dstRadio));
|
logger.fatal("Unsupported radio event: " + event);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
} else {
|
public void registerMote(Mote mote, Simulation sim) {
|
||||||
logger.fatal("Unsupported radio event: " + event);
|
registerRadioInterface(mote.getInterfaces().getRadio(), sim);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
public void unregisterMote(Mote mote, Simulation sim) {
|
||||||
|
unregisterRadioInterface(mote.getInterfaces().getRadio(), sim);
|
||||||
public void registerMote(Mote mote, Simulation sim) {
|
}
|
||||||
registerRadioInterface(mote.getInterfaces().getRadio(), sim);
|
|
||||||
}
|
public void registerRadioInterface(Radio radio, Simulation sim) {
|
||||||
|
if (radio == null) {
|
||||||
public void unregisterMote(Mote mote, Simulation sim) {
|
logger.warn("No radio to register");
|
||||||
unregisterRadioInterface(mote.getInterfaces().getRadio(), sim);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerRadioInterface(Radio radio, Simulation sim) {
|
registeredRadios.add(radio);
|
||||||
if (radio == null) {
|
radio.addObserver(radioEventsObserver);
|
||||||
logger.warn("No radio to register");
|
|
||||||
return;
|
/* Update signal strengths */
|
||||||
}
|
updateSignalStrengths();
|
||||||
|
}
|
||||||
registeredRadios.add(radio);
|
|
||||||
radio.addObserver(radioEventsObserver);
|
public void unregisterRadioInterface(Radio radio, Simulation sim) {
|
||||||
|
if (!registeredRadios.contains(radio)) {
|
||||||
/* Update signal strengths */
|
logger.warn("No radio to unregister: " + radio);
|
||||||
updateSignalStrengths();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregisterRadioInterface(Radio radio, Simulation sim) {
|
radio.deleteObserver(radioEventsObserver);
|
||||||
if (!registeredRadios.contains(radio)) {
|
registeredRadios.remove(radio);
|
||||||
logger.warn("No radio to unregister: " + radio);
|
|
||||||
return;
|
removeFromActiveConnections(radio);
|
||||||
}
|
|
||||||
|
/* Update signal strengths */
|
||||||
radio.deleteObserver(radioEventsObserver);
|
updateSignalStrengths();
|
||||||
registeredRadios.remove(radio);
|
}
|
||||||
|
|
||||||
removeFromActiveConnections(radio);
|
public void addRadioMediumObserver(Observer observer) {
|
||||||
|
radioMediumObservable.addObserver(observer);
|
||||||
/* Update signal strengths */
|
}
|
||||||
updateSignalStrengths();
|
|
||||||
}
|
public Observable getRadioMediumObservable() {
|
||||||
|
return radioMediumObservable;
|
||||||
public void addRadioMediumObserver(Observer observer) {
|
}
|
||||||
radioMediumObservable.addObserver(observer);
|
|
||||||
}
|
public void deleteRadioMediumObserver(Observer observer) {
|
||||||
|
radioMediumObservable.deleteObserver(observer);
|
||||||
public Observable getRadioMediumObservable() {
|
}
|
||||||
return radioMediumObservable;
|
|
||||||
}
|
public RadioConnection getLastConnection() {
|
||||||
|
return lastConnection;
|
||||||
public void deleteRadioMediumObserver(Observer observer) {
|
}
|
||||||
radioMediumObservable.deleteObserver(observer);
|
|
||||||
}
|
|
||||||
|
|
||||||
public RadioConnection getLastConnection() {
|
|
||||||
return lastConnection;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ public class DGRMDestinationRadio extends DestinationRadio {
|
||||||
public double ratio = 1.0; /* Link success ratio (per packet). */
|
public double ratio = 1.0; /* Link success ratio (per packet). */
|
||||||
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 DGRMDestinationRadio() {
|
public DGRMDestinationRadio() {
|
||||||
super();
|
super();
|
||||||
|
@ -54,6 +55,7 @@ public class DGRMDestinationRadio extends DestinationRadio {
|
||||||
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;
|
||||||
return clone;
|
return clone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +71,11 @@ public class DGRMDestinationRadio extends DestinationRadio {
|
||||||
element.setText("" + signal);
|
element.setText("" + signal);
|
||||||
config.add(element);
|
config.add(element);
|
||||||
|
|
||||||
|
element = new Element("lqi");
|
||||||
|
element.setText("" + lqi);
|
||||||
|
config.add(element);
|
||||||
|
|
||||||
|
|
||||||
element = new Element("delay");
|
element = new Element("delay");
|
||||||
element.setText("" + delay);
|
element.setText("" + delay);
|
||||||
config.add(element);
|
config.add(element);
|
||||||
|
@ -85,6 +92,8 @@ public class DGRMDestinationRadio extends DestinationRadio {
|
||||||
ratio = Double.parseDouble(element.getText());
|
ratio = Double.parseDouble(element.getText());
|
||||||
} else if (element.getName().equals("signal")) {
|
} else if (element.getName().equals("signal")) {
|
||||||
signal = Double.parseDouble(element.getText());
|
signal = Double.parseDouble(element.getText());
|
||||||
|
} else if (element.getName().equals("lqi")) {
|
||||||
|
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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Enumeration;
|
import java.util.Enumeration;
|
||||||
import java.util.Hashtable;
|
import java.util.Hashtable;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
@ -71,7 +72,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
private boolean edgesDirty = true;
|
private boolean edgesDirty = true;
|
||||||
|
|
||||||
/* Used for optimizing lookup time */
|
/* Used for optimizing lookup time */
|
||||||
private Hashtable<Radio,DestinationRadio[]> edgesTable = new Hashtable<Radio,DestinationRadio[]>();
|
private Hashtable<Radio,DGRMDestinationRadio[]> edgesTable = new Hashtable<Radio,DGRMDestinationRadio[]>();
|
||||||
|
|
||||||
public DirectedGraphMedium() {
|
public DirectedGraphMedium() {
|
||||||
/* Do not initialize radio medium: use only for hash table */
|
/* Do not initialize radio medium: use only for hash table */
|
||||||
|
@ -164,45 +165,42 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
/* Set signal strengths */
|
/* Set signal strengths */
|
||||||
RadioConnection[] conns = getActiveConnections();
|
RadioConnection[] conns = getActiveConnections();
|
||||||
for (RadioConnection conn : conns) {
|
for (RadioConnection conn : conns) {
|
||||||
|
/* When sending RSSI is Strong!
|
||||||
|
* TODO: is this reasonable
|
||||||
|
*/
|
||||||
if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) {
|
if (conn.getSource().getCurrentSignalStrength() < SS_STRONG) {
|
||||||
conn.getSource().setCurrentSignalStrength(SS_STRONG);
|
conn.getSource().setCurrentSignalStrength(SS_STRONG);
|
||||||
}
|
}
|
||||||
for (Radio dstRadio : conn.getDestinations()) {
|
//Maximum reception signal of all possible radios received
|
||||||
if (dstRadio.getCurrentSignalStrength() < SS_STRONG) {
|
DGRMDestinationRadio dstRadios[] = getPotentialDestinations(conn.getSource());
|
||||||
dstRadio.setCurrentSignalStrength(SS_STRONG);
|
if (dstRadios == null) continue;
|
||||||
|
for (DGRMDestinationRadio dstRadio : dstRadios) {
|
||||||
|
if (dstRadio.radio.getCurrentSignalStrength() < dstRadio.signal) {
|
||||||
|
dstRadio.radio.setCurrentSignalStrength(dstRadio.signal);
|
||||||
}
|
}
|
||||||
|
/* We can set this without further checks, as it will only be read
|
||||||
|
* if a packet is actually received. In that case it is set to the
|
||||||
|
* correct value */
|
||||||
|
dstRadio.radio.setLQI(dstRadio.lqi);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Set signal strength to weak on interfered */
|
|
||||||
for (RadioConnection conn : conns) {
|
|
||||||
for (Radio intfRadio : conn.getInterfered()) {
|
|
||||||
if (intfRadio.getCurrentSignalStrength() < SS_STRONG) {
|
|
||||||
intfRadio.setCurrentSignalStrength(SS_STRONG);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!intfRadio.isInterfered()) {
|
|
||||||
/*logger.warn("Radio was not interfered");*/
|
|
||||||
intfRadio.interfereAnyReception();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates hash table using current edges for efficient lookup.
|
* Generates hash table using current edges for efficient lookup.
|
||||||
*/
|
*/
|
||||||
protected void analyzeEdges() {
|
protected void analyzeEdges() {
|
||||||
Hashtable<Radio,ArrayList<DestinationRadio>> listTable =
|
Hashtable<Radio,ArrayList<DGRMDestinationRadio>> listTable =
|
||||||
new Hashtable<Radio,ArrayList<DestinationRadio>>();
|
new Hashtable<Radio,ArrayList<DGRMDestinationRadio>>();
|
||||||
|
|
||||||
/* Fill edge hash table with all edges */
|
/* Fill edge hash table with all edges */
|
||||||
for (Edge edge: getEdges()) {
|
for (Edge edge: getEdges()) {
|
||||||
ArrayList<DestinationRadio> destRadios;
|
ArrayList<DGRMDestinationRadio> destRadios;
|
||||||
if (!listTable.containsKey(edge.source)) {
|
if (!listTable.containsKey(edge.source)) {
|
||||||
destRadios = new ArrayList<DestinationRadio>();
|
destRadios = new ArrayList<DGRMDestinationRadio>();
|
||||||
} else {
|
} else {
|
||||||
destRadios = listTable.get(edge.source);
|
destRadios = listTable.get(edge.source);
|
||||||
}
|
}
|
||||||
|
@ -212,11 +210,11 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert to arrays */
|
/* Convert to arrays */
|
||||||
Hashtable<Radio,DestinationRadio[]> arrTable = new Hashtable<Radio,DestinationRadio[]>();
|
Hashtable<Radio,DGRMDestinationRadio[]> arrTable = new Hashtable<Radio,DGRMDestinationRadio[]>();
|
||||||
Enumeration<Radio> sources = listTable.keys();
|
Enumeration<Radio> sources = listTable.keys();
|
||||||
while (sources.hasMoreElements()) {
|
while (sources.hasMoreElements()) {
|
||||||
Radio source = sources.nextElement();
|
Radio source = sources.nextElement();
|
||||||
DestinationRadio[] arr = listTable.get(source).toArray(new DestinationRadio[0]);
|
DGRMDestinationRadio[] arr = listTable.get(source).toArray(new DGRMDestinationRadio[0]);
|
||||||
arrTable.put(source, arr);
|
arrTable.put(source, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,7 +229,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
* @param source Source radio
|
* @param source Source radio
|
||||||
* @return All potential destination radios
|
* @return All potential destination radios
|
||||||
*/
|
*/
|
||||||
public DestinationRadio[] getPotentialDestinations(Radio source) {
|
public DGRMDestinationRadio[] getPotentialDestinations(Radio source) {
|
||||||
if (edgesDirty) {
|
if (edgesDirty) {
|
||||||
analyzeEdges();
|
analyzeEdges();
|
||||||
}
|
}
|
||||||
|
@ -249,7 +247,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
|
|
||||||
/* Create new radio connection using edge hash table */
|
/* Create new radio connection using edge hash table */
|
||||||
RadioConnection newConn = new RadioConnection(source);
|
RadioConnection newConn = new RadioConnection(source);
|
||||||
DestinationRadio[] destinations = getPotentialDestinations(source);
|
DGRMDestinationRadio[] destinations = getPotentialDestinations(source);
|
||||||
if (destinations == null || destinations.length == 0) {
|
if (destinations == null || destinations.length == 0) {
|
||||||
/* No destinations */
|
/* No destinations */
|
||||||
/*logger.info(sendingRadio + ": No dest");*/
|
/*logger.info(sendingRadio + ": No dest");*/
|
||||||
|
@ -257,20 +255,14 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*logger.info(source + ": " + destinations.length + " potential destinations");*/
|
/*logger.info(source + ": " + destinations.length + " potential destinations");*/
|
||||||
for (DestinationRadio d: destinations) {
|
for (DGRMDestinationRadio dest: destinations) {
|
||||||
DGRMDestinationRadio dest = (DGRMDestinationRadio) d;
|
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Fail if radios are on different (but configured) channels */
|
|
||||||
if (source.getChannel() >= 0 &&
|
|
||||||
dest.radio.getChannel() >= 0 &&
|
|
||||||
source.getChannel() != dest.radio.getChannel()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dest.radio.isRadioOn()) {
|
if (!dest.radio.isRadioOn()) {
|
||||||
/* Fail: radio is off */
|
/* Fail: radio is off */
|
||||||
|
@ -279,52 +271,44 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest.ratio < 1.0 && random.nextDouble() > dest.ratio) {
|
if (dest.radio.isInterfered()) {
|
||||||
/*logger.info(source + ": Fail, randomly");*/
|
/* Fail: radio is interfered in another connection */
|
||||||
/* TODO Interfere now? */
|
/*logger.info(source + ": Fail, interfered");*/
|
||||||
newConn.addInterfered(dest.radio);
|
newConn.addInterfered(dest.radio);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
dest.radio.interfereAnyReception();
|
int srcc = source.getChannel();
|
||||||
RadioConnection otherConnection = null;
|
int dstc = dest.radio.getChannel();
|
||||||
for (RadioConnection conn : getActiveConnections()) {
|
if ( srcc >= 0 && dstc >= 0 && srcc != dstc) {
|
||||||
for (Radio dstRadio : conn.getDestinations()) {
|
/* Fail: radios are on different (but configured) channels */
|
||||||
if (dstRadio == dest.radio) {
|
|
||||||
otherConnection = conn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (otherConnection != null) {
|
|
||||||
otherConnection.addInterfered(dest.radio);
|
|
||||||
}
|
|
||||||
continue;
|
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");*/
|
||||||
newConn.addInterfered(dest.radio);
|
newConn.addInterfered(dest.radio);
|
||||||
|
|
||||||
/* We will also interfere with the other connection */
|
/* We will also interfere with the other connection */
|
||||||
dest.radio.interfereAnyReception();
|
dest.radio.interfereAnyReception();
|
||||||
RadioConnection otherConnection = null;
|
|
||||||
for (RadioConnection conn : getActiveConnections()) {
|
// Find connection, that is sending to that radio
|
||||||
for (Radio dstRadio : conn.getDestinations()) {
|
// and mark the destination as interfered
|
||||||
if (dstRadio == dest.radio) {
|
for (RadioConnection conn : getActiveConnections()) {
|
||||||
otherConnection = conn;
|
for (Radio dstRadio : conn.getDestinations()) {
|
||||||
break;
|
if (dstRadio == dest.radio) {
|
||||||
}
|
conn.addInterfered(dest.radio);;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
if (otherConnection != null) {
|
}
|
||||||
otherConnection.addInterfered(dest.radio);
|
}
|
||||||
}
|
continue;
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dest.radio.isInterfered()) {
|
if (dest.ratio < 1.0 && random.nextDouble() > dest.ratio) {
|
||||||
/* Fail: radio is interfered in another connection */
|
/* Fail: Reception ratio */
|
||||||
/*logger.info(source + ": Fail, interfered");*/
|
/*logger.info(source + ": Fail, randomly");*/
|
||||||
newConn.addInterfered(dest.radio);
|
newConn.addInterfered(dest.radio);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -358,7 +342,8 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
delayedConfiguration = configXML;
|
delayedConfiguration = configXML;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
public void simulationFinishedLoading() {
|
|
||||||
|
public void simulationFinishedLoading() {
|
||||||
if (delayedConfiguration == null) {
|
if (delayedConfiguration == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -366,9 +351,10 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
boolean oldConfig = false;
|
boolean oldConfig = false;
|
||||||
for (Element element : delayedConfiguration) {
|
for (Element element : delayedConfiguration) {
|
||||||
if (element.getName().equals("edge")) {
|
if (element.getName().equals("edge")) {
|
||||||
Collection<Element> edgeConfig = element.getChildren();
|
@SuppressWarnings("unchecked")
|
||||||
|
Collection<Element> edgeConfig = element.getChildren();
|
||||||
Radio source = null;
|
Radio source = null;
|
||||||
DestinationRadio dest = null;
|
DGRMDestinationRadio dest = null;
|
||||||
for (Element edgeElement : edgeConfig) {
|
for (Element edgeElement : edgeConfig) {
|
||||||
if (edgeElement.getName().equals("src")) {
|
if (edgeElement.getName().equals("src")) {
|
||||||
oldConfig = true;
|
oldConfig = true;
|
||||||
|
@ -387,7 +373,7 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
} else if (oldConfig && edgeElement.getName().equals("ratio")) {
|
} else if (oldConfig && edgeElement.getName().equals("ratio")) {
|
||||||
/* Old config: parse link ratio */
|
/* Old config: parse link ratio */
|
||||||
double ratio = Double.parseDouble(edgeElement.getText());
|
double ratio = Double.parseDouble(edgeElement.getText());
|
||||||
((DGRMDestinationRadio)dest).ratio = ratio;
|
dest.ratio = ratio;
|
||||||
} else if (edgeElement.getName().equals("dest")) {
|
} else if (edgeElement.getName().equals("dest")) {
|
||||||
if (oldConfig) {
|
if (oldConfig) {
|
||||||
/* Old config: create simple destination link */
|
/* Old config: create simple destination link */
|
||||||
|
@ -405,14 +391,16 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
if (destClassName == null || destClassName.isEmpty()) {
|
if (destClassName == null || destClassName.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Class<? extends DestinationRadio> destClass =
|
Class<? extends DGRMDestinationRadio> destClass =
|
||||||
simulation.getGUI().tryLoadClass(this, DestinationRadio.class, destClassName);
|
simulation.getGUI().tryLoadClass(this, DGRMDestinationRadio.class, destClassName);
|
||||||
if (destClass == null) {
|
if (destClass == null) {
|
||||||
throw new RuntimeException("Could not load class: " + destClassName);
|
throw new RuntimeException("Could not load class: " + destClassName);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
dest = destClass.newInstance();
|
dest = destClass.newInstance();
|
||||||
dest.setConfigXML(edgeElement.getChildren(), simulation);
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Element> children = edgeElement.getChildren();
|
||||||
|
dest.setConfigXML(children, simulation);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw (RuntimeException)
|
throw (RuntimeException)
|
||||||
new RuntimeException("Unknown class: " + destClassName).initCause(e);
|
new RuntimeException("Unknown class: " + destClassName).initCause(e);
|
||||||
|
@ -434,9 +422,9 @@ public class DirectedGraphMedium extends AbstractRadioMedium {
|
||||||
|
|
||||||
public static class Edge {
|
public static class Edge {
|
||||||
public Radio source = null;
|
public Radio source = null;
|
||||||
public DestinationRadio superDest = null;
|
public DGRMDestinationRadio superDest = null;
|
||||||
|
|
||||||
public Edge(Radio source, DestinationRadio dest) {
|
public Edge(Radio source, DGRMDestinationRadio dest) {
|
||||||
this.source = source;
|
this.source = source;
|
||||||
this.superDest = dest;
|
this.superDest = dest;
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ public class UDGM extends AbstractRadioMedium {
|
||||||
/* Add potential destination */
|
/* Add potential destination */
|
||||||
addEdge(
|
addEdge(
|
||||||
new DirectedGraphMedium.Edge(source,
|
new DirectedGraphMedium.Edge(source,
|
||||||
new DestinationRadio(dest)));
|
new DGRMDestinationRadio(dest)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue