radio-related changes:
radios can belong to different abstraction levels for example byte of packet radios. => lots of changes in surrounding files
This commit is contained in:
parent
215df016b9
commit
54002df73b
13 changed files with 836 additions and 537 deletions
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: DummyRadioMedium.java,v 1.2 2007/01/09 10:10:18 fros4943 Exp $
|
* $Id: DummyRadioMedium.java,v 1.3 2007/02/28 09:51:11 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -57,7 +57,7 @@ public class DummyRadioMedium extends RadioMedium {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerRadioInterface(Radio radio, Position position, Simulation sim) {
|
public void registerRadioInterface(Radio radio, Simulation sim) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
logger.debug("I'm a dummy. Nothing will be registered by me.");
|
logger.debug("I'm a dummy. Nothing will be registered by me.");
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,14 +26,14 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: VisUAODV.java,v 1.2 2007/01/09 10:09:59 fros4943 Exp $
|
* $Id: VisUAODV.java,v 1.3 2007/02/28 09:50:51 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.*;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.*;
|
||||||
import se.sics.cooja.plugins.*;
|
import se.sics.cooja.plugins.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -62,28 +62,32 @@ public class VisUAODV extends VisTraffic {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintConnection(RadioConnection connection, Graphics g2d) {
|
protected void paintConnection(RadioConnection connection, Graphics g2d) {
|
||||||
Point sourcePixelPosition = transformPositionToPixel(connection.getSourcePosition());
|
Point sourcePixelPosition = transformPositionToPixel(connection.getSource().getPosition());
|
||||||
for (Position destPosition: connection.getDestinationPositons()) {
|
for (Radio destRadio: connection.getDestinations()) {
|
||||||
|
Position destPosition = destRadio.getPosition();
|
||||||
Point destPixelPosition = transformPositionToPixel(destPosition);
|
Point destPixelPosition = transformPositionToPixel(destPosition);
|
||||||
g2d.setColor(getColorOf(connection));
|
g2d.setColor(getColorOf(connection));
|
||||||
|
|
||||||
if (isRouteReply(connection.getSourceData())) {
|
byte[] packet = ((PacketRadio)destRadio).getLastPacketReceived();
|
||||||
|
if (isRouteReply(packet)) {
|
||||||
((Graphics2D) g2d).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
|
((Graphics2D) g2d).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
g2d.drawLine(sourcePixelPosition.x, sourcePixelPosition.y,
|
g2d.drawLine(sourcePixelPosition.x, sourcePixelPosition.y,
|
||||||
destPixelPosition.x, destPixelPosition.y);
|
destPixelPosition.x, destPixelPosition.y);
|
||||||
|
|
||||||
int hopCount = getHopCount(connection.getSourceData());
|
int hopCount = getHopCount(packet);
|
||||||
if (hopCount >= 0)
|
if (hopCount >= 0)
|
||||||
g2d.drawString("" + hopCount, sourcePixelPosition.x, sourcePixelPosition.y);
|
g2d.drawString("" + hopCount, sourcePixelPosition.x, sourcePixelPosition.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Color getColorOf(RadioConnection conn) {
|
protected Color getColorOf(RadioConnection conn) {
|
||||||
if (isRouteRequest(conn.getSourceData()))
|
byte[] packet = ((PacketRadio)conn.getSource()).getLastPacketReceived();
|
||||||
|
|
||||||
|
if (isRouteRequest(packet))
|
||||||
return Color.RED;
|
return Color.RED;
|
||||||
else if (isRouteReply(conn.getSourceData()))
|
else if (isRouteReply(packet))
|
||||||
return Color.GREEN;
|
return Color.GREEN;
|
||||||
else
|
else
|
||||||
return Color.BLACK;
|
return Color.BLACK;
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: ConnectionLogger.java,v 1.4 2007/01/10 14:57:42 fros4943 Exp $
|
* $Id: ConnectionLogger.java,v 1.5 2007/02/28 09:47:55 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
@ -33,12 +33,14 @@ import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
|
import se.sics.cooja.interfaces.PacketRadio;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
|
import se.sics.cooja.interfaces.Radio;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ConnectionLogger is a simple connection information outputter. All
|
* A connection logger is a simple connection information outputter. All
|
||||||
* connections given via the method logConnection will be written to either
|
* connections given to it will be written to either the currently configured
|
||||||
* default Log4J info stream, a log file or both.
|
* Log4J info stream, a log file or both.
|
||||||
*
|
*
|
||||||
* Log files have the following structure (seprated by tabs): SRC_POS [src_x]
|
* Log files have the following structure (seprated by tabs): SRC_POS [src_x]
|
||||||
* [src_y] [src_z] SRC_DATA [sent data bytes] DEST_POS [dest_x] [dest_y]
|
* [src_y] [src_z] SRC_DATA [sent data bytes] DEST_POS [dest_x] [dest_y]
|
||||||
|
@ -90,29 +92,29 @@ public class ConnectionLogger {
|
||||||
* Connection to output
|
* Connection to output
|
||||||
*/
|
*/
|
||||||
public void logConnection(RadioConnection conn) {
|
public void logConnection(RadioConnection conn) {
|
||||||
|
|
||||||
if (myType == LOG_TO_LOG4J || myType == LOG_TO_FILE_AND_LOG4J) {
|
if (myType == LOG_TO_LOG4J || myType == LOG_TO_FILE_AND_LOG4J) {
|
||||||
if (conn.getDestinationPositons() != null
|
Radio[] destinations = conn.getDestinations();
|
||||||
&& conn.getDestinationPositons().length > 0)
|
if (destinations != null && destinations.length > 0) {
|
||||||
for (Position destPos : conn.getDestinationPositons()) {
|
for (Radio destRadio : destinations) {
|
||||||
logger.info("RADIODATA from " + conn.getSourcePosition() + " to "
|
logger.info("RADIODATA from " + conn.getSource().getPosition()
|
||||||
+ destPos + "\tsize:" + conn.getSourceData().length);
|
+ " to " + destRadio.getPosition());
|
||||||
}
|
}
|
||||||
else
|
} else {
|
||||||
logger.info("RADIODATA from " + conn.getSourcePosition() + " to "
|
logger.info("RADIODATA from " + conn.getSource().getPosition()
|
||||||
+ "[NOWHERE]" + "\tsize:" + conn.getSourceData().length);
|
+ " to [NOWHERE]");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (myType == LOG_TO_FILE || myType == LOG_TO_FILE_AND_LOG4J) {
|
|
||||||
|
|
||||||
|
if (myType == LOG_TO_FILE || myType == LOG_TO_FILE_AND_LOG4J) {
|
||||||
try {
|
try {
|
||||||
FileOutputStream out = new FileOutputStream(myFile, true);
|
FileOutputStream out = new FileOutputStream(myFile, true);
|
||||||
|
|
||||||
if (conn.getDestinationPositons() != null
|
Radio[] destinations = conn.getDestinations();
|
||||||
&& conn.getDestinationPositons().length > 0) {
|
if (destinations != null && destinations.length > 0) {
|
||||||
for (int i = 0; i < conn.getDestinationPositons().length; i++) {
|
for (int i = 0; i < destinations.length; i++) {
|
||||||
// Source pos
|
// Source pos
|
||||||
out.write("SRC_POS\t".getBytes());
|
out.write("SRC_POS\t".getBytes());
|
||||||
Position pos = conn.getSourcePosition();
|
Position pos = conn.getSource().getPosition();
|
||||||
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
||||||
out.write("\t".getBytes());
|
out.write("\t".getBytes());
|
||||||
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
||||||
|
@ -122,7 +124,9 @@ public class ConnectionLogger {
|
||||||
|
|
||||||
// Source data
|
// Source data
|
||||||
out.write("SRC_DATA\t".getBytes());
|
out.write("SRC_DATA\t".getBytes());
|
||||||
for (byte b : conn.getSourceData()) {
|
// TODO We need to log destination data again...
|
||||||
|
for (byte b : ((PacketRadio) conn.getSource())
|
||||||
|
.getLastPacketTransmitted()) {
|
||||||
String hexString = Integer.toHexString((int) b);
|
String hexString = Integer.toHexString((int) b);
|
||||||
if (hexString.length() == 1)
|
if (hexString.length() == 1)
|
||||||
hexString = "0" + hexString;
|
hexString = "0" + hexString;
|
||||||
|
@ -132,7 +136,7 @@ public class ConnectionLogger {
|
||||||
|
|
||||||
// Destination pos
|
// Destination pos
|
||||||
out.write("DEST_POS\t".getBytes());
|
out.write("DEST_POS\t".getBytes());
|
||||||
pos = conn.getDestinationPositons()[i];
|
pos = destinations[i].getPosition();
|
||||||
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
||||||
out.write("\t".getBytes());
|
out.write("\t".getBytes());
|
||||||
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
||||||
|
@ -142,7 +146,9 @@ public class ConnectionLogger {
|
||||||
|
|
||||||
// Source data
|
// Source data
|
||||||
out.write("DEST_DATA\t".getBytes());
|
out.write("DEST_DATA\t".getBytes());
|
||||||
for (byte b : conn.getDestinationData()[i]) {
|
// TODO We need to log destination data again...
|
||||||
|
for (byte b : ((PacketRadio) destinations[i])
|
||||||
|
.getLastPacketReceived()) {
|
||||||
String hexString = Integer.toHexString((int) b);
|
String hexString = Integer.toHexString((int) b);
|
||||||
if (hexString.length() == 1)
|
if (hexString.length() == 1)
|
||||||
hexString = "0" + hexString;
|
hexString = "0" + hexString;
|
||||||
|
@ -156,7 +162,7 @@ public class ConnectionLogger {
|
||||||
} else {
|
} else {
|
||||||
// Source pos
|
// Source pos
|
||||||
out.write("SRC_POS\t".getBytes());
|
out.write("SRC_POS\t".getBytes());
|
||||||
Position pos = conn.getSourcePosition();
|
Position pos = conn.getSource().getPosition();
|
||||||
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
||||||
out.write("\t".getBytes());
|
out.write("\t".getBytes());
|
||||||
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
||||||
|
@ -166,12 +172,16 @@ public class ConnectionLogger {
|
||||||
|
|
||||||
// Source data
|
// Source data
|
||||||
out.write("SRC_DATA\t".getBytes());
|
out.write("SRC_DATA\t".getBytes());
|
||||||
for (byte b : conn.getSourceData()) {
|
// TODO We need to log destination data again...
|
||||||
|
for (byte b : ((PacketRadio) conn.getSource())
|
||||||
|
.getLastPacketTransmitted()) {
|
||||||
String hexString = Integer.toHexString((int) b);
|
String hexString = Integer.toHexString((int) b);
|
||||||
if (hexString.length() == 1)
|
if (hexString.length() == 1)
|
||||||
hexString = "0" + hexString;
|
hexString = "0" + hexString;
|
||||||
out.write(hexString.getBytes());
|
out.write(hexString.getBytes());
|
||||||
}
|
}
|
||||||
|
out.write("\t".getBytes());
|
||||||
|
out.write("[NOWHERE]".getBytes());
|
||||||
out.write("\n".getBytes());
|
out.write("\n".getBytes());
|
||||||
}
|
}
|
||||||
out.close();
|
out.close();
|
||||||
|
|
|
@ -26,139 +26,121 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: RadioConnection.java,v 1.3 2006/10/09 13:38:38 fros4943 Exp $
|
* $Id: RadioConnection.java,v 1.4 2007/02/28 09:47:55 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import se.sics.cooja.interfaces.Position;
|
|
||||||
import se.sics.cooja.interfaces.Radio;
|
import se.sics.cooja.interfaces.Radio;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RadioConnection represents a radio connection between a sending radio
|
* A radio connection represents a connection between a source radio and zero or
|
||||||
* and zero or more receiving radios.
|
* more destination and interfered radios. Typically the destinations are able
|
||||||
* By registering as an observer to the current radio medium, all
|
* to receive data sent by the source radio, and the interfered radios are not.
|
||||||
* radio connections and data sent in that medium can be accessed.
|
*
|
||||||
*
|
|
||||||
* Each radio is associated with a position and some radio data.
|
|
||||||
* Often the destinations' and source's data will refer to the same object,
|
|
||||||
* but some radio mediums may want to distort the transferred data, hence
|
|
||||||
* resulting in different data sent and received.
|
|
||||||
*
|
|
||||||
* @see RadioMedium
|
* @see RadioMedium
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
public class RadioConnection {
|
public class RadioConnection {
|
||||||
private Radio sourceRadio;
|
private Radio source;
|
||||||
private Position sourcePosition;
|
|
||||||
private byte[] sourceData;
|
|
||||||
|
|
||||||
private Vector<Radio> destinationRadios = new Vector<Radio>();
|
private Vector<Radio> destinations = new Vector<Radio>();
|
||||||
private Vector<Position> destinationPositions = new Vector<Position>();
|
|
||||||
private Vector<byte[]> destinationData = new Vector<byte[]>();
|
private Vector<Radio> interfered = new Vector<Radio>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new radio connection with given source and no destinations.
|
||||||
|
*
|
||||||
|
* @param sourceRadio
|
||||||
|
* Source radio
|
||||||
|
*/
|
||||||
|
public RadioConnection(Radio sourceRadio) {
|
||||||
|
this.source = sourceRadio;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set source of this connection.
|
* Set source of this connection.
|
||||||
*
|
*
|
||||||
* @param radio Source radio
|
* @param radio
|
||||||
* @param position Source position
|
* Source radio
|
||||||
* @param data Source data
|
|
||||||
*/
|
*/
|
||||||
public void setSource(Radio radio, Position position, byte[] data) {
|
public void setSource(Radio radio) {
|
||||||
sourceRadio = radio;
|
source = radio;
|
||||||
sourcePosition = position;
|
|
||||||
sourceData = data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a connection destination.
|
* Adds destination radio.
|
||||||
*
|
*
|
||||||
* @param radio Source radio
|
* @param radio
|
||||||
* @param position Source position
|
* Radio
|
||||||
* @param data Source data
|
|
||||||
*/
|
*/
|
||||||
public void addDestination(Radio radio, Position position, byte[] data) {
|
public void addDestination(Radio radio) {
|
||||||
destinationRadios.add(radio);
|
destinations.add(radio);
|
||||||
destinationPositions.add(position);
|
|
||||||
destinationData.add(data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a connection destination.
|
* Adds interfered radio.
|
||||||
*
|
*
|
||||||
* @param radio Destination to remove
|
* @param radio
|
||||||
|
* Radio
|
||||||
|
*/
|
||||||
|
public void addInterfered(Radio radio) {
|
||||||
|
interfered.add(radio);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes destination radio.
|
||||||
|
*
|
||||||
|
* @param radio
|
||||||
|
* Radio
|
||||||
*/
|
*/
|
||||||
public void removeDestination(Radio radio) {
|
public void removeDestination(Radio radio) {
|
||||||
int pos = destinationRadios.indexOf(radio);
|
destinations.remove(radio);
|
||||||
if (pos >= 0) {
|
}
|
||||||
destinationRadios.remove(pos);
|
|
||||||
destinationPositions.remove(pos);
|
/**
|
||||||
destinationData.remove(pos);
|
* Removes interfered radio.
|
||||||
}
|
*
|
||||||
|
* @param radio
|
||||||
|
* Radio
|
||||||
|
*/
|
||||||
|
public void removeInterfered(Radio radio) {
|
||||||
|
interfered.remove(radio);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Source radio
|
* @return Source radio
|
||||||
*/
|
*/
|
||||||
public Radio getSourceRadio() {
|
public Radio getSource() {
|
||||||
return sourceRadio;
|
return source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Source position
|
* @return All destinations of this connection
|
||||||
*/
|
*/
|
||||||
public Position getSourcePosition() {
|
public Radio[] getDestinations() {
|
||||||
return sourcePosition;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the data actually sent by source radio.
|
|
||||||
* @return Source data
|
|
||||||
*/
|
|
||||||
public byte[] getSourceData() {
|
|
||||||
return sourceData;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Array of destination radios
|
|
||||||
*/
|
|
||||||
public Radio[] getDestinationRadios() {
|
|
||||||
Radio[] radioArrayType;
|
Radio[] radioArrayType;
|
||||||
Radio[] radioArray;
|
Radio[] radioArray;
|
||||||
|
|
||||||
radioArrayType = new Radio[destinationRadios.size()];
|
radioArrayType = new Radio[destinations.size()];
|
||||||
radioArray = (Radio[]) destinationRadios.toArray(radioArrayType);
|
radioArray = (Radio[]) destinations.toArray(radioArrayType);
|
||||||
|
|
||||||
return radioArray;
|
return radioArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Array of destination positions
|
* @return All radios interfered by this connection
|
||||||
*/
|
*/
|
||||||
public Position[] getDestinationPositons() {
|
public Radio[] getInterfered() {
|
||||||
Position[] positionArrayType;
|
Radio[] radioArrayType;
|
||||||
Position[] positionArray;
|
Radio[] radioArray;
|
||||||
|
|
||||||
positionArrayType = new Position[destinationPositions.size()];
|
radioArrayType = new Radio[interfered.size()];
|
||||||
positionArray = (Position[]) destinationPositions.toArray(positionArrayType);
|
radioArray = (Radio[]) interfered.toArray(radioArrayType);
|
||||||
|
|
||||||
return positionArray;
|
return radioArray;
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of data actually received by each radio.
|
|
||||||
* @return Array of destination data
|
|
||||||
*/
|
|
||||||
public byte[][] getDestinationData() {
|
|
||||||
byte[][] dataArrayType;
|
|
||||||
byte[][] dataArray;
|
|
||||||
|
|
||||||
dataArrayType = new byte[destinationData.size()][];
|
|
||||||
dataArray = (byte[][]) destinationData.toArray(dataArrayType);
|
|
||||||
|
|
||||||
return dataArray;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: RadioMedium.java,v 1.4 2007/01/10 14:57:42 fros4943 Exp $
|
* $Id: RadioMedium.java,v 1.5 2007/02/28 09:47:45 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja;
|
package se.sics.cooja;
|
||||||
|
@ -36,7 +36,6 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.interfaces.Position;
|
|
||||||
import se.sics.cooja.interfaces.Radio;
|
import se.sics.cooja.interfaces.Radio;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,7 +78,7 @@ public abstract class RadioMedium {
|
||||||
public abstract void unregisterMote(Mote mote, Simulation sim);
|
public abstract void unregisterMote(Mote mote, Simulation sim);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a radio to this medium at a given position.
|
* Register a radio to this radio medium.
|
||||||
*
|
*
|
||||||
* Concerning radio data, this radio will be treated the same way as a mote's
|
* Concerning radio data, this radio will be treated the same way as a mote's
|
||||||
* radio. This method can be used to add non-mote radio devices, such as a
|
* radio. This method can be used to add non-mote radio devices, such as a
|
||||||
|
@ -87,16 +86,13 @@ public abstract class RadioMedium {
|
||||||
*
|
*
|
||||||
* @param radio
|
* @param radio
|
||||||
* Radio
|
* Radio
|
||||||
* @param position
|
|
||||||
* Position
|
|
||||||
* @param sim
|
* @param sim
|
||||||
* Simulation holding radio
|
* Simulation holding radio
|
||||||
*/
|
*/
|
||||||
public abstract void registerRadioInterface(Radio radio, Position position,
|
public abstract void registerRadioInterface(Radio radio, Simulation sim);
|
||||||
Simulation sim);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unregisters a radio interface from this medium.
|
* Unregister given radio interface from this medium.
|
||||||
*
|
*
|
||||||
* @param radio
|
* @param radio
|
||||||
* Radio interface to unregister
|
* Radio interface to unregister
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: ContikiRadio.java,v 1.10 2007/01/09 10:05:19 fros4943 Exp $
|
* $Id: ContikiRadio.java,v 1.11 2007/02/28 09:48:48 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.contikimote.interfaces;
|
package se.sics.cooja.contikimote.interfaces;
|
||||||
|
@ -39,6 +39,8 @@ import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.*;
|
||||||
import se.sics.cooja.contikimote.ContikiMoteInterface;
|
import se.sics.cooja.contikimote.ContikiMoteInterface;
|
||||||
|
import se.sics.cooja.interfaces.PacketRadio;
|
||||||
|
import se.sics.cooja.interfaces.Position;
|
||||||
import se.sics.cooja.interfaces.Radio;
|
import se.sics.cooja.interfaces.Radio;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,9 +48,9 @@ import se.sics.cooja.interfaces.Radio;
|
||||||
* transmission rates, the underlying Contiki system can be locked in either
|
* transmission rates, the underlying Contiki system can be locked in either
|
||||||
* transmission or reception states (using multi-threading). When a transmission
|
* transmission or reception states (using multi-threading). When a transmission
|
||||||
* is initiated, it will automatically lock the Contiki system. When a packet is
|
* is initiated, it will automatically lock the Contiki system. When a packet is
|
||||||
* received by this radio the Contiki system, the entitiy transfering the packet may explicitly
|
* received by this radio the Contiki system, the entitiy transferring the
|
||||||
* lock the radio in receiving mode. After some time it should then deliver the
|
* packet may explicitly lock the radio in receiving mode. After some time it
|
||||||
* packet.
|
* should then deliver the packet.
|
||||||
*
|
*
|
||||||
* It needs read/write access to the following core variables:
|
* It needs read/write access to the following core variables:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
@ -64,7 +66,7 @@ import se.sics.cooja.interfaces.Radio;
|
||||||
* <li>char simRadioHWOn (radio hardware status (on/off))
|
* <li>char simRadioHWOn (radio hardware status (on/off))
|
||||||
* <li>int simSignalStrength (heard radio signal strength)
|
* <li>int simSignalStrength (heard radio signal strength)
|
||||||
* <li>char simPower (number indicating power output)
|
* <li>char simPower (number indicating power output)
|
||||||
* <li>int simRadioChannel
|
* <li>int simRadioChannel (number indicating current channel)
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>
|
* <p>
|
||||||
* Dependency core interfaces are:
|
* Dependency core interfaces are:
|
||||||
|
@ -75,9 +77,12 @@ import se.sics.cooja.interfaces.Radio;
|
||||||
*
|
*
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
public class ContikiRadio extends Radio implements ContikiMoteInterface,
|
||||||
|
PacketRadio {
|
||||||
private Mote myMote;
|
private Mote myMote;
|
||||||
|
|
||||||
private SectionMoteMemory myMoteMemory;
|
private SectionMoteMemory myMoteMemory;
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(ContikiRadio.class);
|
private static Logger logger = Logger.getLogger(ContikiRadio.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,17 +103,18 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
|
|
||||||
private double myEnergyConsumption = 0.0;
|
private double myEnergyConsumption = 0.0;
|
||||||
|
|
||||||
private boolean transmitting = false;
|
private boolean isTransmitting = false;
|
||||||
|
|
||||||
|
private boolean isInterfered = false;
|
||||||
|
|
||||||
private int transmissionEndTime = -1;
|
private int transmissionEndTime = -1;
|
||||||
private int interferenceEndTime = -1;
|
|
||||||
private int receptionEndTime = -1;
|
|
||||||
|
|
||||||
private RadioEvent lastEvent = RadioEvent.UNKNOWN;
|
private RadioEvent lastEvent = RadioEvent.UNKNOWN;
|
||||||
|
|
||||||
private int lastEventTime = 0;
|
private int lastEventTime = 0;
|
||||||
|
|
||||||
private int oldOutputPowerIndicator = -1;
|
private int oldOutputPowerIndicator = -1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an interface to the radio at mote.
|
* Creates an interface to the radio at mote.
|
||||||
*
|
*
|
||||||
|
@ -135,10 +141,12 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
radioOn = myMoteMemory.getByteValueOf("simRadioHWOn") == 1;
|
radioOn = myMoteMemory.getByteValueOf("simRadioHWOn") == 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Contiki mote interface support */
|
||||||
public static String[] getCoreInterfaceDependencies() {
|
public static String[] getCoreInterfaceDependencies() {
|
||||||
return new String[] { "radio_interface" };
|
return new String[] { "radio_interface" };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Packet radio support */
|
||||||
public byte[] getLastPacketTransmitted() {
|
public byte[] getLastPacketTransmitted() {
|
||||||
return packetFromMote;
|
return packetFromMote;
|
||||||
}
|
}
|
||||||
|
@ -146,30 +154,110 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
public byte[] getLastPacketReceived() {
|
public byte[] getLastPacketReceived() {
|
||||||
return packetToMote;
|
return packetToMote;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isTransmitting() {
|
public void setReceivedPacket(byte[] data) {
|
||||||
return transmitting;
|
packetToMote = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTransmissionEndTime() {
|
/* General radio support */
|
||||||
return transmissionEndTime;
|
public boolean isTransmitting() {
|
||||||
|
return isTransmitting;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReceiving() {
|
public boolean isReceiving() {
|
||||||
if (isLockedAtReceiving())
|
if (isLockedAtReceiving())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return myMoteMemory.getIntValueOf("simInSize") != 0;
|
return myMoteMemory.getIntValueOf("simInSize") != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isInterfered() {
|
||||||
|
return isInterfered;
|
||||||
|
}
|
||||||
|
|
||||||
public int getChannel() {
|
public int getChannel() {
|
||||||
return myMoteMemory.getIntValueOf("simRadioChannel");
|
return myMoteMemory.getIntValueOf("simRadioChannel");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void signalReceptionStart() {
|
||||||
|
packetToMote = null;
|
||||||
|
if (isInterfered() || isReceiving() || isTransmitting()) {
|
||||||
|
interfereAnyReception();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lockInReceivingMode();
|
||||||
|
|
||||||
|
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||||
|
lastEvent = RadioEvent.RECEPTION_STARTED;
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void signalReceptionEnd() {
|
||||||
|
if (isInterfered() || packetToMote == null) {
|
||||||
|
// Reset interfered flag
|
||||||
|
isInterfered = false;
|
||||||
|
|
||||||
|
// Reset data
|
||||||
|
packetToMote = null;
|
||||||
|
myMoteMemory.setIntValueOf("simInSize", 0);
|
||||||
|
|
||||||
|
// Unlock (if locked)
|
||||||
|
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock (if locked)
|
||||||
|
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
|
||||||
|
|
||||||
|
// Set data
|
||||||
|
myMoteMemory.setIntValueOf("simInSize", packetToMote.length);
|
||||||
|
myMoteMemory.setByteArray("simInDataBuffer", packetToMote);
|
||||||
|
|
||||||
|
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||||
|
lastEvent = RadioEvent.RECEPTION_FINISHED;
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
|
||||||
public RadioEvent getLastEvent() {
|
public RadioEvent getLastEvent() {
|
||||||
return lastEvent;
|
return lastEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void interfereAnyReception() {
|
||||||
|
if (!isInterfered()) {
|
||||||
|
isInterfered = true;
|
||||||
|
|
||||||
|
lastEvent = RadioEvent.RECEPTION_INTERFERED;
|
||||||
|
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCurrentOutputPower() {
|
||||||
|
// TODO Implement method
|
||||||
|
logger.warn("Not implemeted, always returning 1.5 dBm");
|
||||||
|
return 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCurrentOutputPowerIndicator() {
|
||||||
|
return (int) myMoteMemory.getByteValueOf("simPower");
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getCurrentSignalStrength() {
|
||||||
|
return myMoteMemory.getIntValueOf("simSignalStrength");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCurrentSignalStrength(double signalStrength) {
|
||||||
|
myMoteMemory.setIntValueOf("simSignalStrength", (int) signalStrength);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Position getPosition() {
|
||||||
|
return myMote.getInterfaces().getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return True if locked at transmitting
|
* @return True if locked at transmitting
|
||||||
*/
|
*/
|
||||||
|
@ -201,98 +289,9 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
|
|
||||||
// Lock core radio in receiving loop
|
// Lock core radio in receiving loop
|
||||||
myMoteMemory.setByteValueOf("simReceiving", (byte) 1);
|
myMoteMemory.setByteValueOf("simReceiving", (byte) 1);
|
||||||
|
|
||||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
|
||||||
lastEvent = RadioEvent.RECEPTION_STARTED;
|
|
||||||
this.setChanged();
|
|
||||||
this.notifyObservers();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receivePacket(byte[] data, int endTime) {
|
|
||||||
if (isInterfered() || isReceiving() || isTransmitting()) {
|
|
||||||
interferReception(endTime);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
lockInReceivingMode();
|
|
||||||
|
|
||||||
receptionEndTime = endTime;
|
|
||||||
packetToMote = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void deliverPacket() {
|
|
||||||
// If mote is inactive, try to wake it up
|
|
||||||
if (myMote.getState() != Mote.State.ACTIVE) {
|
|
||||||
if (RAISES_EXTERNAL_INTERRUPT)
|
|
||||||
myMote.setState(Mote.State.ACTIVE);
|
|
||||||
if (myMote.getState() != Mote.State.ACTIVE) {
|
|
||||||
logger.fatal("Mote fell asleep during reception of packet, skipping packet!");
|
|
||||||
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
|
|
||||||
myMoteMemory.setIntValueOf("simInSize", 0);
|
|
||||||
this.setChanged();
|
|
||||||
this.notifyObservers();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlock (if locked)
|
|
||||||
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
|
|
||||||
|
|
||||||
// Set data
|
|
||||||
myMoteMemory.setIntValueOf("simInSize", packetToMote.length);
|
|
||||||
myMoteMemory.setByteArray("simInDataBuffer", packetToMote);
|
|
||||||
|
|
||||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
|
||||||
lastEvent = RadioEvent.RECEPTION_FINISHED;
|
|
||||||
this.setChanged();
|
|
||||||
this.notifyObservers();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void interferReception(int endTime) {
|
|
||||||
// Unlock (if locked)
|
|
||||||
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
|
|
||||||
|
|
||||||
// Reset data
|
|
||||||
myMoteMemory.setIntValueOf("simInSize", 0);
|
|
||||||
|
|
||||||
// Save interference end time (if updated)
|
|
||||||
interferenceEndTime = Math.max(interferenceEndTime, endTime);
|
|
||||||
|
|
||||||
if (lastEvent != RadioEvent.RECEPTION_INTERFERED) {
|
|
||||||
lastEvent = RadioEvent.RECEPTION_INTERFERED;
|
|
||||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
|
||||||
this.setChanged();
|
|
||||||
this.notifyObservers();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isInterfered() {
|
|
||||||
return interferenceEndTime >= myMote.getSimulation().getSimulationTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getCurrentOutputPower() {
|
|
||||||
// TODO Implement method
|
|
||||||
logger.warn("Not implemeted, always returning 1.5 dBm");
|
|
||||||
return 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentOutputPowerIndicator() {
|
|
||||||
return (int) myMoteMemory.getByteValueOf("simPower");
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getCurrentSignalStrength() {
|
|
||||||
return myMoteMemory.getIntValueOf("simSignalStrength");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCurrentSignalStrength(double signalStrength) {
|
|
||||||
myMoteMemory.setIntValueOf("simSignalStrength", (int) signalStrength);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void doActionsBeforeTick() {
|
public void doActionsBeforeTick() {
|
||||||
// Check if we need to release Contiki lock and deliver packet data
|
|
||||||
if (isLockedAtReceiving() && myMote.getSimulation().getSimulationTime() >= receptionEndTime) {
|
|
||||||
deliverPacket();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void doActionsAfterTick() {
|
public void doActionsAfterTick() {
|
||||||
|
@ -300,18 +299,18 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
if (radioOn != (myMoteMemory.getByteValueOf("simRadioHWOn") == 1)) {
|
if (radioOn != (myMoteMemory.getByteValueOf("simRadioHWOn") == 1)) {
|
||||||
// Radio changed
|
// Radio changed
|
||||||
radioOn = !radioOn;
|
radioOn = !radioOn;
|
||||||
|
|
||||||
if (!radioOn) {
|
if (!radioOn) {
|
||||||
// Reset status
|
// Reset status
|
||||||
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
|
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
|
||||||
myMoteMemory.setIntValueOf("simInSize", 0);
|
myMoteMemory.setIntValueOf("simInSize", 0);
|
||||||
myMoteMemory.setByteValueOf("simTransmitting", (byte) 0);
|
myMoteMemory.setByteValueOf("simTransmitting", (byte) 0);
|
||||||
myMoteMemory.setIntValueOf("simOutSize", 0);
|
myMoteMemory.setIntValueOf("simOutSize", 0);
|
||||||
transmitting = false;
|
isTransmitting = false;
|
||||||
lastEvent = RadioEvent.HW_OFF;
|
lastEvent = RadioEvent.HW_OFF;
|
||||||
} else
|
} else
|
||||||
lastEvent = RadioEvent.HW_ON;
|
lastEvent = RadioEvent.HW_ON;
|
||||||
|
|
||||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
|
@ -325,26 +324,28 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
// Check if radio output power changed
|
// Check if radio output power changed
|
||||||
if (myMoteMemory.getByteValueOf("simPower") != oldOutputPowerIndicator) {
|
if (myMoteMemory.getByteValueOf("simPower") != oldOutputPowerIndicator) {
|
||||||
oldOutputPowerIndicator = myMoteMemory.getByteValueOf("simPower");
|
oldOutputPowerIndicator = myMoteMemory.getByteValueOf("simPower");
|
||||||
|
lastEvent = RadioEvent.UNKNOWN;
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are we transmitting but should stop?
|
// Are we transmitting but should stop?
|
||||||
if (transmitting && myMote.getSimulation().getSimulationTime() >= transmissionEndTime) {
|
if (isTransmitting
|
||||||
|
&& myMote.getSimulation().getSimulationTime() >= transmissionEndTime) {
|
||||||
myMoteMemory.setByteValueOf("simTransmitting", (byte) 0);
|
myMoteMemory.setByteValueOf("simTransmitting", (byte) 0);
|
||||||
myMoteMemory.setIntValueOf("simOutSize", 0);
|
myMoteMemory.setIntValueOf("simOutSize", 0);
|
||||||
transmitting = false;
|
isTransmitting = false;
|
||||||
|
|
||||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||||
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
||||||
// TODO Energy consumption of transmitted packet?
|
// TODO Energy consumption of transmitted packet?
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a new transmission should be started
|
// Check if a new transmission should be started
|
||||||
if (!transmitting && myMoteMemory.getByteValueOf("simTransmitting") == 1) {
|
if (!isTransmitting && myMoteMemory.getByteValueOf("simTransmitting") == 1) {
|
||||||
transmitting = true;
|
isTransmitting = true;
|
||||||
int size = myMoteMemory.getIntValueOf("simOutSize");
|
int size = myMoteMemory.getIntValueOf("simOutSize");
|
||||||
packetFromMote = myMoteMemory.getByteArray("simOutDataBuffer", size);
|
packetFromMote = myMoteMemory.getByteArray("simOutDataBuffer", size);
|
||||||
|
|
||||||
|
@ -353,11 +354,17 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
int duration = (int) ((2 * size * 9) / 19.2); // ms
|
int duration = (int) ((2 * size * 9) / 19.2); // ms
|
||||||
transmissionEndTime = myMote.getSimulation().getSimulationTime()
|
transmissionEndTime = myMote.getSimulation().getSimulationTime()
|
||||||
+ Math.max(1, duration);
|
+ Math.max(1, duration);
|
||||||
|
|
||||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||||
|
|
||||||
lastEvent = RadioEvent.TRANSMISSION_STARTED;
|
lastEvent = RadioEvent.TRANSMISSION_STARTED;
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
|
|
||||||
|
// Deliver packet right away
|
||||||
|
lastEvent = RadioEvent.PACKET_TRANSMITTED;
|
||||||
|
this.setChanged();
|
||||||
|
this.notifyObservers();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,23 +372,24 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
// Location
|
// Location
|
||||||
JPanel panel = new JPanel();
|
JPanel panel = new JPanel();
|
||||||
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
||||||
|
|
||||||
final JLabel statusLabel = new JLabel("");
|
final JLabel statusLabel = new JLabel("");
|
||||||
final JLabel lastEventLabel = new JLabel("");
|
final JLabel lastEventLabel = new JLabel("");
|
||||||
final JLabel ssLabel = new JLabel("");
|
final JLabel ssLabel = new JLabel("");
|
||||||
final JButton updateButton = new JButton("Update SS");
|
final JButton updateButton = new JButton("Update SS");
|
||||||
|
|
||||||
panel.add(statusLabel);
|
panel.add(statusLabel);
|
||||||
panel.add(lastEventLabel);
|
panel.add(lastEventLabel);
|
||||||
panel.add(ssLabel);
|
panel.add(ssLabel);
|
||||||
panel.add(updateButton);
|
panel.add(updateButton);
|
||||||
|
|
||||||
updateButton.addActionListener(new ActionListener() {
|
updateButton.addActionListener(new ActionListener() {
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
ssLabel.setText("Signal strength (not auto-updated): " + getCurrentSignalStrength() + " dBm");
|
ssLabel.setText("Signal strength (not auto-updated): "
|
||||||
|
+ getCurrentSignalStrength() + " dBm");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Observer observer;
|
Observer observer;
|
||||||
this.addObserver(observer = new Observer() {
|
this.addObserver(observer = new Observer() {
|
||||||
public void update(Observable obs, Object obj) {
|
public void update(Observable obs, Object obj) {
|
||||||
|
@ -394,19 +402,21 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
else
|
else
|
||||||
statusLabel.setText("HW turned off");
|
statusLabel.setText("HW turned off");
|
||||||
|
|
||||||
lastEventLabel.setText("Last event (time=" + lastEventTime + "): " + lastEvent);
|
lastEventLabel.setText("Last event (time=" + lastEventTime + "): "
|
||||||
ssLabel.setText("Signal strength (not auto-updated): " + getCurrentSignalStrength() + " dBm");
|
+ lastEvent);
|
||||||
|
ssLabel.setText("Signal strength (not auto-updated): "
|
||||||
|
+ getCurrentSignalStrength() + " dBm");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
observer.update(null, null);
|
observer.update(null, null);
|
||||||
|
|
||||||
// Saving observer reference for releaseInterfaceVisualizer
|
// Saving observer reference for releaseInterfaceVisualizer
|
||||||
panel.putClientProperty("intf_obs", observer);
|
panel.putClientProperty("intf_obs", observer);
|
||||||
|
|
||||||
return panel;
|
return panel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void releaseInterfaceVisualizer(JPanel panel) {
|
public void releaseInterfaceVisualizer(JPanel panel) {
|
||||||
Observer observer = (Observer) panel.getClientProperty("intf_obs");
|
Observer observer = (Observer) panel.getClientProperty("intf_obs");
|
||||||
if (observer == null) {
|
if (observer == null) {
|
||||||
|
@ -416,7 +426,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
|
|
||||||
this.deleteObserver(observer);
|
this.deleteObserver(observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public double energyConsumptionPerTick() {
|
public double energyConsumptionPerTick() {
|
||||||
return myEnergyConsumption;
|
return myEnergyConsumption;
|
||||||
}
|
}
|
||||||
|
@ -424,7 +434,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||||
public Collection<Element> getConfigXML() {
|
public Collection<Element> getConfigXML() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
41
tools/cooja/java/se/sics/cooja/interfaces/ByteRadio.java
Normal file
41
tools/cooja/java/se/sics/cooja/interfaces/ByteRadio.java
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package se.sics.cooja.interfaces;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A byte radio is able to transmit and receive radio data on a byte level.
|
||||||
|
*
|
||||||
|
* The byte radio is a lower abstraction level than the packet radio and should,
|
||||||
|
* according to the bottom-up abstraction policy, implement the packet
|
||||||
|
* abstraction level.
|
||||||
|
*
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
public interface ByteRadio extends PacketRadio {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Radio receives given byte.
|
||||||
|
*
|
||||||
|
* @param b
|
||||||
|
* Byte
|
||||||
|
* @param timestamp
|
||||||
|
* Timestamp information
|
||||||
|
*/
|
||||||
|
public void receiveByte(byte b, long timestamp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Last byte transmitted by radio
|
||||||
|
*/
|
||||||
|
public byte getLastByteTransmitted();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns timestamp information of byte transmitted. This may for example be
|
||||||
|
* the number of cycles since transmission started.
|
||||||
|
*
|
||||||
|
* @return Timestamp info
|
||||||
|
*/
|
||||||
|
public long getLastByteTransmittedTimestamp();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Last byte received by radio
|
||||||
|
*/
|
||||||
|
public byte getLastByteReceived();
|
||||||
|
}
|
33
tools/cooja/java/se/sics/cooja/interfaces/PacketRadio.java
Normal file
33
tools/cooja/java/se/sics/cooja/interfaces/PacketRadio.java
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package se.sics.cooja.interfaces;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A packet radio is able to transmit and receive radio data on a packet level.
|
||||||
|
*
|
||||||
|
* The packet radio is the highest abstraction level of radios, and must
|
||||||
|
* therefore be implemented by all lower abstraction levels.
|
||||||
|
*
|
||||||
|
* @author Fredrik Osterlind
|
||||||
|
*/
|
||||||
|
public interface PacketRadio {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the packet data that is being received during a connection. Different
|
||||||
|
* radio may handle the data differently, but as a general rule this data
|
||||||
|
* should be supplied as soon as possible.
|
||||||
|
*
|
||||||
|
* @param p
|
||||||
|
* Packet dat
|
||||||
|
*/
|
||||||
|
public void setReceivedPacket(byte[] p);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Last packet transmitted by radio
|
||||||
|
*/
|
||||||
|
public byte[] getLastPacketTransmitted();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Last packet received by radio
|
||||||
|
*/
|
||||||
|
public byte[] getLastPacketReceived();
|
||||||
|
|
||||||
|
}
|
|
@ -24,7 +24,7 @@
|
||||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: Radio.java,v 1.5 2006/10/11 15:13:57 fros4943 Exp $
|
* $Id: Radio.java,v 1.6 2007/02/28 09:49:20 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.interfaces;
|
package se.sics.cooja.interfaces;
|
||||||
|
@ -32,8 +32,15 @@ package se.sics.cooja.interfaces;
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Radio represents a mote radio transceiver. An implementation should notify
|
* A Radio represents a mote radio transceiver.
|
||||||
* all observers both when packets are received and transmitted.
|
*
|
||||||
|
* A radio can support different abstraction levels such as transmitting and
|
||||||
|
* receiving on a byte or packet-basis. In order to support communication
|
||||||
|
* between different levels the general rule in COOJA is that all radios at a
|
||||||
|
* lower abstraction level must also implement all higher levels.
|
||||||
|
*
|
||||||
|
* @see PacketRadio
|
||||||
|
* @see ByteRadio
|
||||||
*
|
*
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
|
@ -44,84 +51,65 @@ public abstract class Radio extends MoteInterface {
|
||||||
* Events that radios should notify observers about.
|
* Events that radios should notify observers about.
|
||||||
*/
|
*/
|
||||||
public enum RadioEvent {
|
public enum RadioEvent {
|
||||||
UNKNOWN,
|
UNKNOWN, HW_OFF, HW_ON, RECEPTION_STARTED, RECEPTION_FINISHED, RECEPTION_INTERFERED, TRANSMISSION_STARTED, TRANSMISSION_FINISHED, PACKET_TRANSMITTED, BYTE_TRANSMITTED
|
||||||
HW_OFF, HW_ON,
|
|
||||||
RECEPTION_STARTED, RECEPTION_INTERFERED, RECEPTION_FINISHED,
|
|
||||||
TRANSMISSION_STARTED, TRANSMISSION_FINISHED
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns last significant event at this radio. Method may for example be
|
* Signal that a new reception just begun. This method should normally be
|
||||||
* used to learn the reason when a radio notifies a change to observers.
|
* called from the radio medium.
|
||||||
|
*
|
||||||
|
* @see #signalReceptionEnd()
|
||||||
|
*/
|
||||||
|
public abstract void signalReceptionStart();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signal that the current reception was ended. This method should normally be
|
||||||
|
* called from the radio medium.
|
||||||
|
*
|
||||||
|
* @see #signalReceptionStart()
|
||||||
|
*/
|
||||||
|
public abstract void signalReceptionEnd();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns last event at this radio. This method should be used to learn the
|
||||||
|
* reason when a radio notifies a change to observers.
|
||||||
*
|
*
|
||||||
* @return Last radio event
|
* @return Last radio event
|
||||||
*/
|
*/
|
||||||
public abstract RadioEvent getLastEvent();
|
public abstract RadioEvent getLastEvent();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Last packet data transmitted, or currently being transmitted, from
|
|
||||||
* this radio.
|
|
||||||
*/
|
|
||||||
public abstract byte[] getLastPacketTransmitted();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Last packet data received, or currently being received, by this
|
|
||||||
* radio.
|
|
||||||
*/
|
|
||||||
public abstract byte[] getLastPacketReceived();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Receive given packet. If reception is not interfered during
|
|
||||||
* this time, the packet will be delivered ok.
|
|
||||||
*
|
|
||||||
* @param data
|
|
||||||
* Packet data
|
|
||||||
* @param endTime
|
|
||||||
* Time (ms) when reception is finished
|
|
||||||
*/
|
|
||||||
public abstract void receivePacket(byte[] data, int endTime);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this radio is transmitting, or just finished transmitting,
|
* Returns true if this radio is transmitting, or just finished transmitting,
|
||||||
* data.
|
* data.
|
||||||
*
|
*
|
||||||
* @see #getLastPacketTransmitted()
|
* @see #isReceiving()
|
||||||
* @return True if radio is transmitting data
|
* @return True if radio is transmitting data
|
||||||
*/
|
*/
|
||||||
public abstract boolean isTransmitting();
|
public abstract boolean isTransmitting();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Transmission end time if any transmission active
|
|
||||||
*/
|
|
||||||
public abstract int getTransmissionEndTime();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this radio is receiving data.
|
* Returns true if this radio is receiving data.
|
||||||
*
|
*
|
||||||
* @see #getLastPacketReceived()
|
* @see #isTransmitting()
|
||||||
* @return True if radio is receiving data
|
* @return True if radio is receiving data
|
||||||
*/
|
*/
|
||||||
public abstract boolean isReceiving();
|
public abstract boolean isReceiving();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a packet is being received, it will be interfered and dropped. The
|
* Returns true if this radio had a connection that was dropped due to
|
||||||
* interference will continue until the given time, during which no other
|
* interference.
|
||||||
* radio traffic may be received. This method can be used to simulate
|
|
||||||
* significant interference during transmissions.
|
|
||||||
*
|
|
||||||
* @param endTime
|
|
||||||
* Time when interference stops
|
|
||||||
*/
|
|
||||||
public abstract void interferReception(int endTime);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true is this radio is currently hearing noise from another
|
|
||||||
* transmission.
|
|
||||||
*
|
*
|
||||||
* @return True if this radio is interfered
|
* @return True if this radio is interfered
|
||||||
*/
|
*/
|
||||||
public abstract boolean isInterfered();
|
public abstract boolean isInterfered();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interferes with any current reception. If this method is called, the packet
|
||||||
|
* will be dropped. This method can be used to simulate radio interference
|
||||||
|
* such as high background noise.
|
||||||
|
*/
|
||||||
|
public abstract void interfereAnyReception();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Current output power (dBm)
|
* @return Current output power (dBm)
|
||||||
*/
|
*/
|
||||||
|
@ -138,7 +126,8 @@ public abstract class Radio extends MoteInterface {
|
||||||
public abstract double getCurrentSignalStrength();
|
public abstract double getCurrentSignalStrength();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets surrounding signal strength.
|
* Sets surrounding signal strength. This method should normally be called by
|
||||||
|
* the radio medium.
|
||||||
*
|
*
|
||||||
* @param signalStrength
|
* @param signalStrength
|
||||||
* Current surrounding signal strength
|
* Current surrounding signal strength
|
||||||
|
@ -151,5 +140,13 @@ public abstract class Radio extends MoteInterface {
|
||||||
* @return Current channel number
|
* @return Current channel number
|
||||||
*/
|
*/
|
||||||
public abstract int getChannel();
|
public abstract int getChannel();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the radio position.
|
||||||
|
* This is typically the position of the mote.
|
||||||
|
*
|
||||||
|
* @return Radio position
|
||||||
|
*/
|
||||||
|
public abstract Position getPosition();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: DisturberRadio.java,v 1.2 2007/01/09 10:01:14 fros4943 Exp $
|
* $Id: DisturberRadio.java,v 1.3 2007/02/28 09:49:48 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.motes;
|
package se.sics.cooja.motes;
|
||||||
|
@ -40,14 +40,14 @@ import org.apache.log4j.Logger;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.*;
|
||||||
import se.sics.cooja.interfaces.Radio;
|
import se.sics.cooja.interfaces.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This radio periodically transmits data on a configurable channel.
|
* This radio periodically transmits data on a configurable channel.
|
||||||
*
|
*
|
||||||
* @author Fredrik Osterlind, Thiemo Voigt
|
* @author Fredrik Osterlind, Thiemo Voigt
|
||||||
*/
|
*/
|
||||||
public class DisturberRadio extends Radio {
|
public class DisturberRadio extends Radio implements PacketRadio {
|
||||||
private Mote myMote;
|
private Mote myMote;
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(DisturberRadio.class);
|
private static Logger logger = Logger.getLogger(DisturberRadio.class);
|
||||||
|
@ -78,7 +78,8 @@ public class DisturberRadio extends Radio {
|
||||||
public DisturberRadio(Mote mote) {
|
public DisturberRadio(Mote mote) {
|
||||||
this.myMote = mote;
|
this.myMote = mote;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Packet radio support */
|
||||||
public byte[] getLastPacketTransmitted() {
|
public byte[] getLastPacketTransmitted() {
|
||||||
return packetFromMote;
|
return packetFromMote;
|
||||||
}
|
}
|
||||||
|
@ -87,6 +88,17 @@ public class DisturberRadio extends Radio {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setReceivedPacket(byte[] data) {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* General radio support */
|
||||||
|
public void signalReceptionStart() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void signalReceptionEnd() {
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isTransmitting() {
|
public boolean isTransmitting() {
|
||||||
return transmitting;
|
return transmitting;
|
||||||
}
|
}
|
||||||
|
@ -96,8 +108,6 @@ public class DisturberRadio extends Radio {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReceiving() {
|
public boolean isReceiving() {
|
||||||
if (isLockedAtReceiving())
|
|
||||||
return true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,21 +115,15 @@ public class DisturberRadio extends Radio {
|
||||||
return distChannel;
|
return distChannel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Position getPosition() {
|
||||||
|
return myMote.getInterfaces().getPosition();
|
||||||
|
}
|
||||||
|
|
||||||
public RadioEvent getLastEvent() {
|
public RadioEvent getLastEvent() {
|
||||||
return lastEvent;
|
return lastEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public void interfereAnyReception() {
|
||||||
* @return True if locked at receiving
|
|
||||||
*/
|
|
||||||
private boolean isLockedAtReceiving() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void receivePacket(byte[] data, int endTime) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void interferReception(int endTime) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInterfered() {
|
public boolean isInterfered() {
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: VisTraffic.java,v 1.5 2007/01/09 09:49:24 fros4943 Exp $
|
* $Id: VisTraffic.java,v 1.6 2007/02/28 09:50:00 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.plugins;
|
package se.sics.cooja.plugins;
|
||||||
|
@ -38,6 +38,7 @@ import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import se.sics.cooja.*;
|
import se.sics.cooja.*;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
|
import se.sics.cooja.interfaces.Radio;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Traffic Visualizer visualizes radio traffic by painting lines between
|
* A Traffic Visualizer visualizes radio traffic by painting lines between
|
||||||
|
@ -124,11 +125,10 @@ public class VisTraffic extends Visualizer2D {
|
||||||
* Graphics to paint on
|
* Graphics to paint on
|
||||||
*/
|
*/
|
||||||
protected void paintConnection(PaintedConnection connection, Graphics g2d) {
|
protected void paintConnection(PaintedConnection connection, Graphics g2d) {
|
||||||
Point sourcePixelPosition = transformPositionToPixel(connection.radioConnection
|
Point sourcePixelPosition = transformPositionToPixel(connection.radioConnection.getSource().getPosition());
|
||||||
.getSourcePosition());
|
|
||||||
g2d.setColor(connection.getColor(simulation.isRunning()));
|
g2d.setColor(connection.getColor(simulation.isRunning()));
|
||||||
for (Position destPosition : connection.radioConnection
|
for (Radio destRadio : connection.radioConnection.getDestinations()) {
|
||||||
.getDestinationPositons()) {
|
Position destPosition = destRadio.getPosition();
|
||||||
Point destPixelPosition = transformPositionToPixel(destPosition);
|
Point destPixelPosition = transformPositionToPixel(destPosition);
|
||||||
g2d.drawLine(sourcePixelPosition.x, sourcePixelPosition.y,
|
g2d.drawLine(sourcePixelPosition.x, sourcePixelPosition.y,
|
||||||
destPixelPosition.x, destPixelPosition.y);
|
destPixelPosition.x, destPixelPosition.y);
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: SilentRadioMedium.java,v 1.2 2007/01/09 09:47:10 fros4943 Exp $
|
* $Id: SilentRadioMedium.java,v 1.3 2007/02/28 09:50:00 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.radiomediums;
|
package se.sics.cooja.radiomediums;
|
||||||
|
@ -57,7 +57,7 @@ public class SilentRadioMedium extends RadioMedium {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerRadioInterface(Radio radio, Position position, Simulation sim) {
|
public void registerRadioInterface(Radio radio, Simulation sim) {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: UDGM.java,v 1.1 2007/01/09 09:47:36 fros4943 Exp $
|
* $Id: UDGM.java,v 1.2 2007/02/28 09:50:00 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.radiomediums;
|
package se.sics.cooja.radiomediums;
|
||||||
|
@ -47,35 +47,41 @@ import se.sics.cooja.plugins.Visualizer2D;
|
||||||
* The Unit Disk Graph medium has two different range parameters; one for
|
* The Unit Disk Graph medium has two different range parameters; one for
|
||||||
* transmitting and one for interfering other transmissions.
|
* transmitting and one for interfering other transmissions.
|
||||||
*
|
*
|
||||||
* Radio data are analysed when all registered motes have ticked once (this
|
* The radio medium supports both byte and packet radios. Any transmitted bytes
|
||||||
* medium is registered as a tick observer). For every mote in transmission
|
* are forwarded TODO immediately with a timestamp (more fine-grained than
|
||||||
* range of a sending mote, current listen status is changed from hearing
|
* ticks).
|
||||||
* nothing to hearing packet, or hearing packet to hearing noise. This way, if a
|
|
||||||
* mote hears two packets during one tick loop, it will receive none (noise). If
|
|
||||||
* a mote is in the interference range, the current listen status will be set to
|
|
||||||
* hears noise immediately.
|
|
||||||
*
|
*
|
||||||
* This radio medium registers a temporary visual plugin class.
|
* The radio medium registers a visualizer plugin. Via this plugin the current
|
||||||
* Via this plugin ranges can be viewed and changed. Active connection may also
|
* radio states and range parameters can be viewed and changed.
|
||||||
* be viewed.
|
|
||||||
*
|
*
|
||||||
|
* The registered radios' signal strengths are updated whenever the radio medium
|
||||||
|
* changes. There are three fixed levels: no surrounding traffic heard, noise
|
||||||
|
* heard and data heard.
|
||||||
|
*
|
||||||
|
* The radio output power indicator (0-100) is used in a very simple way; the
|
||||||
|
* total transmission (and interfering) range is multiplied with [power_ind]%.
|
||||||
|
*
|
||||||
|
* @see #SS_OK
|
||||||
|
* @see #SS_NOISE
|
||||||
|
* @see #SS_NOTHING
|
||||||
|
*
|
||||||
|
* @see VisUDGM
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
@ClassDescription("Unit Disk Graph Medium (UDGM)")
|
@ClassDescription("Unit Disk Graph Medium (UDGM)")
|
||||||
public class UDGM extends RadioMedium {
|
public class UDGM extends RadioMedium {
|
||||||
private static Logger logger = Logger.getLogger(UDGM.class);
|
private static Logger logger = Logger.getLogger(UDGM.class);
|
||||||
|
|
||||||
private Vector<Position> registeredPositions = new Vector<Position>();
|
|
||||||
|
|
||||||
private Vector<Radio> registeredRadios = new Vector<Radio>();
|
private Vector<Radio> registeredRadios = new Vector<Radio>();
|
||||||
|
|
||||||
private Vector<Radio> transmissionEndedRadios = new Vector<Radio>();
|
// private Vector<Radio> transmissionEndedRadios = new Vector<Radio>();
|
||||||
|
private Vector<RadioConnection> finishedConnections = new Vector<RadioConnection>();
|
||||||
|
|
||||||
private static RadioMedium myRadioMedium;
|
private static RadioMedium myRadioMedium;
|
||||||
|
|
||||||
public static final double SS_NOTHING = -200;
|
public static final double SS_NOTHING = -200;
|
||||||
|
|
||||||
public static final double SS_BAD = -60;
|
public static final double SS_NOISE = -60;
|
||||||
|
|
||||||
public static final double SS_OK = 0;
|
public static final double SS_OK = 0;
|
||||||
|
|
||||||
|
@ -89,7 +95,7 @@ public class UDGM extends RadioMedium {
|
||||||
*
|
*
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
@ClassDescription("Radio Medium Visualizer")
|
@ClassDescription("UDGM Visualizer")
|
||||||
@PluginType(PluginType.SIM_PLUGIN)
|
@PluginType(PluginType.SIM_PLUGIN)
|
||||||
public static class VisUDGM extends Visualizer2D {
|
public static class VisUDGM extends Visualizer2D {
|
||||||
private Mote selectedMote = null;
|
private Mote selectedMote = null;
|
||||||
|
@ -118,7 +124,7 @@ public class UDGM extends RadioMedium {
|
||||||
|
|
||||||
public VisUDGM(Simulation sim, GUI gui) {
|
public VisUDGM(Simulation sim, GUI gui) {
|
||||||
super(sim, gui);
|
super(sim, gui);
|
||||||
setTitle("Radio Medium Visualizer");
|
setTitle("UDGM Visualizer");
|
||||||
|
|
||||||
// Create spinners for changing ranges
|
// Create spinners for changing ranges
|
||||||
SpinnerNumberModel transmissionModel = new SpinnerNumberModel();
|
SpinnerNumberModel transmissionModel = new SpinnerNumberModel();
|
||||||
|
@ -253,54 +259,57 @@ public class UDGM extends RadioMedium {
|
||||||
int y = pixelCoord.y;
|
int y = pixelCoord.y;
|
||||||
|
|
||||||
// Fetch current output power indicator (scale with as percent)
|
// Fetch current output power indicator (scale with as percent)
|
||||||
// TODO Probably not the best way to use indicator
|
if (selectedMote.getInterfaces().getRadio() != null) {
|
||||||
double moteInterferenceRange = INTERFERENCE_RANGE
|
double moteInterferenceRange = INTERFERENCE_RANGE
|
||||||
* (0.01 * (double) selectedMote.getInterfaces().getRadio()
|
* (0.01 * (double) selectedMote.getInterfaces().getRadio()
|
||||||
.getCurrentOutputPowerIndicator());
|
.getCurrentOutputPowerIndicator());
|
||||||
double moteTransmissionRange = TRANSMITTING_RANGE
|
double moteTransmissionRange = TRANSMITTING_RANGE
|
||||||
* (0.01 * (double) selectedMote.getInterfaces().getRadio()
|
* (0.01 * (double) selectedMote.getInterfaces().getRadio()
|
||||||
.getCurrentOutputPowerIndicator());
|
.getCurrentOutputPowerIndicator());
|
||||||
|
|
||||||
Point translatedZero = transformPositionToPixel(0.0, 0.0, 0.0);
|
Point translatedZero = transformPositionToPixel(0.0, 0.0, 0.0);
|
||||||
Point translatedInterference = transformPositionToPixel(
|
Point translatedInterference = transformPositionToPixel(
|
||||||
moteInterferenceRange, moteInterferenceRange, 0.0);
|
moteInterferenceRange, moteInterferenceRange, 0.0);
|
||||||
Point translatedTransmission = transformPositionToPixel(
|
Point translatedTransmission = transformPositionToPixel(
|
||||||
moteTransmissionRange, moteTransmissionRange, 0.0);
|
moteTransmissionRange, moteTransmissionRange, 0.0);
|
||||||
|
|
||||||
translatedInterference.x = Math.abs(translatedInterference.x
|
translatedInterference.x = Math.abs(translatedInterference.x
|
||||||
- translatedZero.x);
|
- translatedZero.x);
|
||||||
translatedInterference.y = Math.abs(translatedInterference.y
|
translatedInterference.y = Math.abs(translatedInterference.y
|
||||||
- translatedZero.y);
|
- translatedZero.y);
|
||||||
translatedTransmission.x = Math.abs(translatedTransmission.x
|
translatedTransmission.x = Math.abs(translatedTransmission.x
|
||||||
- translatedZero.x);
|
- translatedZero.x);
|
||||||
translatedTransmission.y = Math.abs(translatedTransmission.y
|
translatedTransmission.y = Math.abs(translatedTransmission.y
|
||||||
- translatedZero.y);
|
- translatedZero.y);
|
||||||
|
|
||||||
// Interference
|
// Interference
|
||||||
g.setColor(Color.DARK_GRAY);
|
g.setColor(Color.DARK_GRAY);
|
||||||
g.fillOval(x - translatedInterference.x, y - translatedInterference.y,
|
g.fillOval(x - translatedInterference.x,
|
||||||
2 * translatedInterference.x, 2 * translatedInterference.y);
|
y - translatedInterference.y, 2 * translatedInterference.x,
|
||||||
|
2 * translatedInterference.y);
|
||||||
// Transmission
|
|
||||||
g.setColor(Color.GREEN);
|
|
||||||
g.fillOval(x - translatedTransmission.x, y - translatedTransmission.y,
|
|
||||||
2 * translatedTransmission.x, 2 * translatedTransmission.y);
|
|
||||||
|
|
||||||
|
// Transmission
|
||||||
|
g.setColor(Color.GREEN);
|
||||||
|
g.fillOval(x - translatedTransmission.x,
|
||||||
|
y - translatedTransmission.y, 2 * translatedTransmission.x,
|
||||||
|
2 * translatedTransmission.y);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let parent paint motes
|
// Let parent paint motes
|
||||||
super.visualizeSimulation(g);
|
super.visualizeSimulation(g);
|
||||||
|
|
||||||
// Paint last tick connections
|
// Paint just finished connections
|
||||||
if (myRadioMedium != null
|
if (myRadioMedium != null
|
||||||
&& myRadioMedium.getLastTickConnections() != null) {
|
&& myRadioMedium.getLastTickConnections() != null) {
|
||||||
for (RadioConnection conn : myRadioMedium.getLastTickConnections()) {
|
for (RadioConnection conn : myRadioMedium.getLastTickConnections()) {
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
Point sourcePoint = transformPositionToPixel(conn
|
Point sourcePoint = transformPositionToPixel(conn.getSource()
|
||||||
.getSourcePosition());
|
.getPosition());
|
||||||
|
|
||||||
// Paint destinations
|
// Paint destinations
|
||||||
for (Position destPos : conn.getDestinationPositons()) {
|
for (Radio destRadio : conn.getDestinations()) {
|
||||||
|
Position destPos = destRadio.getPosition();
|
||||||
Point destPoint = transformPositionToPixel(destPos);
|
Point destPoint = transformPositionToPixel(destPos);
|
||||||
|
|
||||||
g.setColor(Color.BLACK);
|
g.setColor(Color.BLACK);
|
||||||
|
@ -338,205 +347,417 @@ public class UDGM extends RadioMedium {
|
||||||
|
|
||||||
private RadioConnection[] lastTickConnections = null;
|
private RadioConnection[] lastTickConnections = null;
|
||||||
|
|
||||||
private Vector<RadioConnection> pendingConnections = new Vector<RadioConnection>();
|
private Vector<RadioConnection> activeConnections = new Vector<RadioConnection>();
|
||||||
|
|
||||||
private ConnectionLogger myLogger = null;
|
private ConnectionLogger myLogger = null;
|
||||||
|
|
||||||
private Observer radioDataObserver = new Observer() {
|
/**
|
||||||
public void update(Observable radio, Object obj) {
|
* Creates and registers a new connection from given radio.
|
||||||
// This radio changed, let tick loop notify observers
|
*
|
||||||
radioMediumObservable.setRadioMediumChanged();
|
* @param radio
|
||||||
|
* Transmitting radio
|
||||||
|
* @return New registered connection
|
||||||
|
*/
|
||||||
|
private RadioConnection createConnections(Radio radio) {
|
||||||
|
Radio sendingRadio = radio;
|
||||||
|
Position sendingPosition = sendingRadio.getPosition();
|
||||||
|
|
||||||
// Register any new transmission
|
RadioConnection newConnection = new RadioConnection(sendingRadio);
|
||||||
if (((Radio) radio).getLastEvent() == Radio.RadioEvent.TRANSMISSION_STARTED) {
|
|
||||||
Radio sendingRadio = (Radio) radio;
|
|
||||||
|
|
||||||
// If obj is the position, use it directly (speeds up things)
|
// Fetch current output power indicator (scale with as percent)
|
||||||
// Otherwise we must search for the position ourselves
|
double moteTransmissionRange = TRANSMITTING_RANGE
|
||||||
Position sendingPosition = (Position) obj;
|
* (0.01 * (double) sendingRadio.getCurrentOutputPowerIndicator());
|
||||||
if (sendingPosition == null) {
|
double moteInterferenceRange = INTERFERENCE_RANGE
|
||||||
if (!registeredRadios.contains(radio)) {
|
* (0.01 * (double) sendingRadio.getCurrentOutputPowerIndicator());
|
||||||
logger.fatal("Sending radio not registered, skipping packet");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sendingPosition = registeredPositions.get(registeredRadios
|
// Loop through all radios
|
||||||
.indexOf(radio));
|
for (int listenNr = 0; listenNr < registeredRadios.size(); listenNr++) {
|
||||||
if (sendingPosition == null) {
|
Radio listeningRadio = registeredRadios.get(listenNr);
|
||||||
logger.fatal("Sending radio not registered, skipping packet");
|
Position listeningRadioPosition = listeningRadio.getPosition();
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] dataToSend = sendingRadio.getLastPacketTransmitted();
|
// Ignore sending radio and radios on different channels
|
||||||
|
if (sendingRadio == listeningRadio)
|
||||||
RadioConnection newConnection = new RadioConnection();
|
continue;
|
||||||
pendingConnections.add(newConnection);
|
if (sendingRadio.getChannel() != listeningRadio.getChannel())
|
||||||
newConnection.setSource(sendingRadio, sendingPosition, dataToSend);
|
continue;
|
||||||
|
|
||||||
// Fetch current output power indicator (scale with as percent)
|
double distance = sendingPosition.getDistanceTo(listeningRadioPosition);
|
||||||
// TODO Probably not the best way to use indicator
|
|
||||||
double moteInterferenceRange = INTERFERENCE_RANGE
|
|
||||||
* (0.01 * (double) sendingRadio.getCurrentOutputPowerIndicator());
|
|
||||||
double moteTransmissionRange = TRANSMITTING_RANGE
|
|
||||||
* (0.01 * (double) sendingRadio.getCurrentOutputPowerIndicator());
|
|
||||||
|
|
||||||
// Loop through all radios that are listening
|
if (distance <= moteTransmissionRange) {
|
||||||
for (int listenNr = 0; listenNr < registeredPositions.size(); listenNr++) {
|
// Check if this radio is able to receive transmission
|
||||||
Radio listeningRadio = registeredRadios.get(listenNr);
|
if (listeningRadio.isInterfered()) {
|
||||||
|
// Keep interfering radio
|
||||||
|
newConnection.addInterfered(listeningRadio);
|
||||||
|
|
||||||
if (sendingRadio == listeningRadio)
|
} else if (listeningRadio.isReceiving()) {
|
||||||
continue;
|
newConnection.addInterfered(listeningRadio);
|
||||||
if (sendingRadio.getChannel() != listeningRadio.getChannel())
|
|
||||||
continue;
|
// Start interfering radio
|
||||||
|
listeningRadio.interfereAnyReception();
|
||||||
|
|
||||||
// If not the sending radio..
|
// Update connection that is transmitting to this radio
|
||||||
double distance = sendingPosition.getDistanceTo(registeredPositions
|
RadioConnection existingConn = null;
|
||||||
.get(listenNr));
|
for (RadioConnection conn : activeConnections) {
|
||||||
|
for (Radio dstRadio : conn.getDestinations()) {
|
||||||
if (distance <= moteTransmissionRange) {
|
if (dstRadio == listeningRadio) {
|
||||||
newConnection.addDestination(registeredRadios.get(listenNr),
|
existingConn = conn;
|
||||||
registeredPositions.get(listenNr), dataToSend);
|
break;
|
||||||
|
}
|
||||||
// If close enough to transmit ok..
|
|
||||||
if (listeningRadio.isReceiving() || listeningRadio.isInterfered()) {
|
|
||||||
// .. but listening radio already received a packet
|
|
||||||
listeningRadio.interferReception(sendingRadio
|
|
||||||
.getTransmissionEndTime());
|
|
||||||
listeningRadio.setCurrentSignalStrength(SS_BAD);
|
|
||||||
} else {
|
|
||||||
// .. send packet
|
|
||||||
listeningRadio.receivePacket(dataToSend, sendingRadio
|
|
||||||
.getTransmissionEndTime());
|
|
||||||
listeningRadio.setCurrentSignalStrength(SS_OK);
|
|
||||||
}
|
}
|
||||||
} else if (distance <= moteInterferenceRange) {
|
|
||||||
// If close enough to sabotage other transmissions..
|
|
||||||
listeningRadio.interferReception(sendingRadio
|
|
||||||
.getTransmissionEndTime());
|
|
||||||
listeningRadio.setCurrentSignalStrength(SS_BAD);
|
|
||||||
}
|
}
|
||||||
// else too far away
|
if (existingConn != null) {
|
||||||
|
// Change radio from receiving to interfered
|
||||||
|
existingConn.removeDestination(listeningRadio);
|
||||||
|
existingConn.addInterfered(listeningRadio);
|
||||||
|
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Radio OK to receive
|
||||||
|
newConnection.addDestination(listeningRadio);
|
||||||
|
listeningRadio.signalReceptionStart();
|
||||||
|
}
|
||||||
|
} else if (distance <= moteInterferenceRange) {
|
||||||
|
// Interfere radio
|
||||||
|
newConnection.addInterfered(listeningRadio);
|
||||||
|
listeningRadio.interfereAnyReception();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register new connection
|
||||||
|
activeConnections.add(newConnection);
|
||||||
|
return newConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Forward given packet from source to all destinations in given connection.
|
||||||
|
*
|
||||||
|
* @param connection
|
||||||
|
* Radio connection
|
||||||
|
* @param packetData
|
||||||
|
* Packet data
|
||||||
|
*/
|
||||||
|
private void forwardPacket(RadioConnection connection, byte[] packetData) {
|
||||||
|
Radio sourceRadio = connection.getSource();
|
||||||
|
|
||||||
|
if (sourceRadio instanceof ByteRadio) {
|
||||||
|
// Byte radios only forwards packets to packet radios
|
||||||
|
for (Radio receivingRadio : connection.getDestinations()) {
|
||||||
|
if (receivingRadio instanceof ByteRadio) {
|
||||||
|
// Do nothing (data will be forwarded on byte-per-byte basis)
|
||||||
|
} else if (receivingRadio instanceof PacketRadio) {
|
||||||
|
// Forward packet data
|
||||||
|
((PacketRadio) receivingRadio).setReceivedPacket(packetData);
|
||||||
|
} else {
|
||||||
|
logger.warn("Packet was not forwarded correctly");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (sourceRadio instanceof PacketRadio) {
|
||||||
if (((Radio) radio).getLastEvent() == Radio.RadioEvent.TRANSMISSION_FINISHED) {
|
// Packet radios forwards packets to all packet radios
|
||||||
transmissionEndedRadios.add((Radio) radio);
|
for (Radio receivingRadio : connection.getDestinations()) {
|
||||||
|
if (receivingRadio instanceof PacketRadio) {
|
||||||
|
// Forward packet data
|
||||||
|
((PacketRadio) receivingRadio).setReceivedPacket(packetData);
|
||||||
|
} else {
|
||||||
|
logger.warn("Packet was not forwarded correctly");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeFromActiveConnections(Radio radio) {
|
||||||
|
// Abort any reception
|
||||||
|
if (radio.isReceiving()) {
|
||||||
|
radio.interfereAnyReception();
|
||||||
|
radio.signalReceptionEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove radio from all active connections
|
||||||
|
RadioConnection connToRemove = null;
|
||||||
|
for (RadioConnection conn : activeConnections) {
|
||||||
|
conn.removeDestination(radio);
|
||||||
|
conn.removeInterfered(radio);
|
||||||
|
|
||||||
|
if (conn.getSource() == radio) {
|
||||||
|
// Radio is currently transmitting
|
||||||
|
connToRemove = conn;
|
||||||
|
for (Radio dstRadio : conn.getDestinations()) {
|
||||||
|
dstRadio.interfereAnyReception();
|
||||||
|
dstRadio.signalReceptionEnd();
|
||||||
|
}
|
||||||
|
for (Radio dstRadio : conn.getInterfered()) {
|
||||||
|
dstRadio.signalReceptionEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (connToRemove != null)
|
||||||
|
activeConnections.remove(connToRemove);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates all radio signal strengths according to current transmissions. This
|
||||||
|
* method also updates earlier interfered radios.
|
||||||
|
*/
|
||||||
|
private void updateSignalStrengths() {
|
||||||
|
// // Save old signal strengths
|
||||||
|
// double[] oldSignalStrengths = new double[registeredRadios.size()];
|
||||||
|
// for (int i = 0; i < registeredRadios.size(); i++) {
|
||||||
|
// oldSignalStrengths[i] = registeredRadios.get(i)
|
||||||
|
// .getCurrentSignalStrength();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Reset signal strength on all radios
|
||||||
|
for (Radio radio : registeredRadios) {
|
||||||
|
radio.setCurrentSignalStrength(SS_NOTHING);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set signal strength on all OK transmissions
|
||||||
|
for (RadioConnection conn : activeConnections) {
|
||||||
|
conn.getSource().setCurrentSignalStrength(SS_OK);
|
||||||
|
for (Radio dstRadio : conn.getDestinations()) {
|
||||||
|
dstRadio.setCurrentSignalStrength(SS_OK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set signal strength on all interferences
|
||||||
|
for (RadioConnection conn : activeConnections) {
|
||||||
|
for (Radio dstRadio : conn.getInterfered()) {
|
||||||
|
dstRadio.setCurrentSignalStrength(SS_NOISE);
|
||||||
|
if (!dstRadio.isInterfered()) {
|
||||||
|
// Set to interfered again
|
||||||
|
dstRadio.interfereAnyReception();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// // Fetch new signal strengths
|
||||||
|
// double[] newSignalStrengths = new double[registeredRadios.size()];
|
||||||
|
// for (int i = 0; i < registeredRadios.size(); i++) {
|
||||||
|
// newSignalStrengths[i] = registeredRadios.get(i)
|
||||||
|
// .getCurrentSignalStrength();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // Compare new and old signal strengths
|
||||||
|
// for (int i = 0; i < registeredRadios.size(); i++) {
|
||||||
|
// if (oldSignalStrengths[i] != newSignalStrengths[i])
|
||||||
|
// logger.warn("Signal strengths changed on radio[" + i + "]: "
|
||||||
|
// + oldSignalStrengths[i] + " -> " + newSignalStrengths[i]);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
private Observer radioEventsObserver = new Observer() {
|
||||||
|
public void update(Observable obs, Object obj) {
|
||||||
|
if (!(obs instanceof Radio)) {
|
||||||
|
logger.fatal("Radio event dispatched by non-radio object");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Radio radio = (Radio) obs;
|
||||||
|
|
||||||
|
// Handle radio event
|
||||||
|
final Radio.RadioEvent event = radio.getLastEvent();
|
||||||
|
|
||||||
|
// Ignore reception events
|
||||||
|
if (event == Radio.RadioEvent.RECEPTION_STARTED
|
||||||
|
|| event == Radio.RadioEvent.RECEPTION_INTERFERED
|
||||||
|
|| event == Radio.RadioEvent.RECEPTION_FINISHED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (event == Radio.RadioEvent.HW_OFF) {
|
||||||
|
// Destroy any(?) transfers
|
||||||
|
removeFromActiveConnections(radio);
|
||||||
|
|
||||||
|
// Recalculate signal strengths on all radios
|
||||||
|
updateSignalStrengths();
|
||||||
|
|
||||||
|
// Wake up tick observer
|
||||||
|
radioMediumObservable.setRadioMediumChanged();
|
||||||
|
|
||||||
|
} else if (event == Radio.RadioEvent.HW_ON) {
|
||||||
|
// No action
|
||||||
|
// TODO Maybe set signal strength levels now?
|
||||||
|
|
||||||
|
// Recalculate signal strengths on all radios
|
||||||
|
updateSignalStrengths();
|
||||||
|
|
||||||
|
// Wake up tick observer
|
||||||
|
radioMediumObservable.setRadioMediumChanged();
|
||||||
|
|
||||||
|
} else if (event == Radio.RadioEvent.TRANSMISSION_STARTED) {
|
||||||
|
/* Create radio connections */
|
||||||
|
|
||||||
|
createConnections((Radio) radio);
|
||||||
|
|
||||||
|
// Recalculate signal strengths on all radios
|
||||||
|
updateSignalStrengths();
|
||||||
|
|
||||||
|
// Wake up tick observer
|
||||||
|
radioMediumObservable.setRadioMediumChanged();
|
||||||
|
|
||||||
|
} else if (event == Radio.RadioEvent.TRANSMISSION_FINISHED) {
|
||||||
|
/* Remove active connection */
|
||||||
|
|
||||||
|
// Find corresponding connection of radio
|
||||||
|
RadioConnection connection = null;
|
||||||
|
for (RadioConnection conn : activeConnections) {
|
||||||
|
if (conn.getSource() == radio) {
|
||||||
|
connection = conn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connection == null) {
|
||||||
|
logger.fatal("Can't find active connection to remove");
|
||||||
|
} else {
|
||||||
|
activeConnections.remove(connection);
|
||||||
|
finishedConnections.add(connection);
|
||||||
|
for (Radio dstRadio : connection.getDestinations()) {
|
||||||
|
dstRadio.signalReceptionEnd();
|
||||||
|
}
|
||||||
|
for (Radio dstRadio : connection.getInterfered()) {
|
||||||
|
dstRadio.signalReceptionEnd();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recalculate signal strengths on all radios
|
||||||
|
updateSignalStrengths();
|
||||||
|
|
||||||
|
// Wake up tick observer
|
||||||
|
radioMediumObservable.setRadioMediumChanged();
|
||||||
|
|
||||||
|
} else if (event == Radio.RadioEvent.BYTE_TRANSMITTED) {
|
||||||
|
/* Forward byte */
|
||||||
|
|
||||||
|
// Find corresponding connection of radio
|
||||||
|
RadioConnection connection = null;
|
||||||
|
for (RadioConnection conn : activeConnections) {
|
||||||
|
if (conn.getSource() == radio) {
|
||||||
|
connection = conn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connection == null) {
|
||||||
|
logger.fatal("Can't find active connection to forward byte in");
|
||||||
|
} else {
|
||||||
|
byte b = ((ByteRadio) radio).getLastByteTransmitted();
|
||||||
|
long timestamp = ((ByteRadio) radio).getLastByteTransmittedTimestamp();
|
||||||
|
|
||||||
|
for (Radio dstRadio : connection.getDestinations()) {
|
||||||
|
if (dstRadio instanceof ByteRadio) {
|
||||||
|
((ByteRadio) dstRadio).receiveByte(b, timestamp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (event == Radio.RadioEvent.PACKET_TRANSMITTED) {
|
||||||
|
/* Forward packet */
|
||||||
|
|
||||||
|
// Find corresponding connection of radio
|
||||||
|
RadioConnection connection = null;
|
||||||
|
for (RadioConnection conn : activeConnections) {
|
||||||
|
if (conn.getSource() == radio) {
|
||||||
|
connection = conn;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (connection == null) {
|
||||||
|
logger.fatal("Can't find active connection to forward byte in");
|
||||||
|
} else {
|
||||||
|
byte[] packetData = ((PacketRadio) radio).getLastPacketTransmitted();
|
||||||
|
forwardPacket(connection, packetData);
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (event == Radio.RadioEvent.UNKNOWN) {
|
||||||
|
// Do nothing
|
||||||
|
} else {
|
||||||
|
logger.fatal("Unsupported radio event: " + event);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This observer is resposible for making last tick connections available to
|
||||||
|
* external observers, as well as forwarding finished connections to any
|
||||||
|
* registered connection logger.
|
||||||
|
*
|
||||||
|
* @see #getLastTickConnections()
|
||||||
|
* @see #setConnectionLogger(ConnectionLogger)
|
||||||
|
*/
|
||||||
private Observer tickObserver = new Observer() {
|
private Observer tickObserver = new Observer() {
|
||||||
public void update(Observable obs, Object obj) {
|
public void update(Observable obs, Object obj) {
|
||||||
|
|
||||||
if (lastTickConnections != null)
|
// Reset any last tick connections
|
||||||
|
if (lastTickConnections != null) {
|
||||||
radioMediumObservable.setRadioMediumChanged();
|
radioMediumObservable.setRadioMediumChanged();
|
||||||
|
lastTickConnections = null;
|
||||||
|
}
|
||||||
|
|
||||||
// Reset last tick connections
|
// Do nothing if radio medium unchanged
|
||||||
lastTickConnections = null;
|
if (!radioMediumObservable.hasChanged())
|
||||||
|
return;
|
||||||
|
|
||||||
// Log finished connections if any
|
// Log any new finished connections
|
||||||
Vector<RadioConnection> updatedPendingConnections = new Vector<RadioConnection>();
|
if (finishedConnections.size() > 0) {
|
||||||
if (transmissionEndedRadios.size() > 0) {
|
lastTickConnections = new RadioConnection[finishedConnections.size()];
|
||||||
final int numberFinished = transmissionEndedRadios.size();
|
for (int i = 0; i < finishedConnections.size(); i++)
|
||||||
Vector<RadioConnection> newTickConnections = new Vector<RadioConnection>();
|
lastTickConnections[i] = finishedConnections.get(i);
|
||||||
|
finishedConnections.clear();
|
||||||
// Loop through all radios that finished transmitting data
|
|
||||||
for (int recvNr = 0; recvNr < numberFinished; recvNr++) {
|
|
||||||
Radio transmittingRadio = transmissionEndedRadios.get(recvNr);
|
|
||||||
|
|
||||||
for (RadioConnection pendingConnection : pendingConnections) {
|
|
||||||
|
|
||||||
// Log finished connection
|
|
||||||
if (pendingConnection.getSourceRadio() == transmittingRadio) {
|
|
||||||
for (Radio destRadio : pendingConnection.getDestinationRadios()) {
|
|
||||||
if (destRadio.getLastEvent() != Radio.RadioEvent.RECEPTION_FINISHED) {
|
|
||||||
// Radio was interfered
|
|
||||||
pendingConnection.removeDestination(destRadio);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newTickConnections.add(pendingConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove connection if old (don't keep)
|
|
||||||
if (pendingConnection.getSourceRadio().isTransmitting()) {
|
|
||||||
updatedPendingConnections.add(pendingConnection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
lastTickConnections = new RadioConnection[newTickConnections.size()];
|
|
||||||
for (int i = 0; i < lastTickConnections.length; i++)
|
|
||||||
lastTickConnections[i] = newTickConnections.get(i);
|
|
||||||
transmissionEndedRadios.clear();
|
|
||||||
|
|
||||||
pendingConnections = updatedPendingConnections;
|
|
||||||
|
|
||||||
|
// Notify radio medium logger of the finished transmissions
|
||||||
if (myLogger != null) {
|
if (myLogger != null) {
|
||||||
for (RadioConnection conn : lastTickConnections)
|
for (RadioConnection conn : lastTickConnections)
|
||||||
myLogger.logConnection(conn);
|
myLogger.logConnection(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Radio medium has changed, notifing below
|
|
||||||
radioMediumObservable.setRadioMediumChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set signal strengths on all radios
|
// Notify all other radio medium observers
|
||||||
for (Radio radio : registeredRadios) {
|
|
||||||
if (radio.isTransmitting())
|
|
||||||
radio.setCurrentSignalStrength(SS_OK);
|
|
||||||
else if (radio.isReceiving())
|
|
||||||
radio.setCurrentSignalStrength(SS_OK);
|
|
||||||
else if (radio.isInterfered())
|
|
||||||
radio.setCurrentSignalStrength(SS_BAD);
|
|
||||||
else
|
|
||||||
radio.setCurrentSignalStrength(SS_NOTHING);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Notify observers (if anything has changed)
|
|
||||||
radioMediumObservable.notifyObservers();
|
radioMediumObservable.notifyObservers();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
public void registerMote(Mote mote, Simulation sim) {
|
public void registerMote(Mote mote, Simulation sim) {
|
||||||
registerRadioInterface(mote.getInterfaces().getRadio(), mote
|
registerRadioInterface(mote.getInterfaces().getRadio(), sim);
|
||||||
.getInterfaces().getPosition(), sim);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregisterMote(Mote mote, Simulation sim) {
|
public void unregisterMote(Mote mote, Simulation sim) {
|
||||||
unregisterRadioInterface(mote.getInterfaces().getRadio(), sim);
|
unregisterRadioInterface(mote.getInterfaces().getRadio(), sim);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void registerRadioInterface(Radio radio, Position position,
|
public void registerRadioInterface(Radio radio, Simulation sim) {
|
||||||
Simulation sim) {
|
if (radio != null) {
|
||||||
if (radio != null && position != null) {
|
|
||||||
if (!isTickObserver) {
|
if (!isTickObserver) {
|
||||||
sim.addTickObserver(tickObserver);
|
sim.addTickObserver(tickObserver);
|
||||||
isTickObserver = true;
|
isTickObserver = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
registeredPositions.add(position);
|
// Warn if radio medium does not support radio
|
||||||
|
if (!(radio instanceof PacketRadio)) {
|
||||||
|
logger
|
||||||
|
.warn("Radio medium does not support radio (no transmission supported)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register and start observing radio
|
||||||
registeredRadios.add(radio);
|
registeredRadios.add(radio);
|
||||||
radio.addObserver(radioDataObserver);
|
radio.addObserver(radioEventsObserver);
|
||||||
|
|
||||||
// Set initial signal strenth
|
// Set initial signal strenth
|
||||||
radio.setCurrentSignalStrength(SS_NOTHING);
|
radio.setCurrentSignalStrength(SS_NOTHING);
|
||||||
|
}
|
||||||
} // else logger.warn("Radio Medium not registering mote");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unregisterRadioInterface(Radio radio, Simulation sim) {
|
public void unregisterRadioInterface(Radio radio, Simulation sim) {
|
||||||
for (int i = 0; i < registeredRadios.size(); i++) {
|
if (!registeredRadios.contains(radio)) {
|
||||||
if (registeredRadios.get(i).equals(radio)) {
|
logger.warn("Could not find radio: " + radio + " to unregister");
|
||||||
registeredRadios.remove(i);
|
return;
|
||||||
registeredPositions.remove(i);
|
|
||||||
radio.deleteObserver(radioDataObserver);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
logger.warn("Could not find radio: " + radio + " to unregister");
|
|
||||||
|
radio.deleteObserver(radioEventsObserver);
|
||||||
|
registeredRadios.remove(radio);
|
||||||
|
|
||||||
|
removeFromActiveConnections(radio);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addRadioMediumObserver(Observer observer) {
|
public void addRadioMediumObserver(Observer observer) {
|
||||||
|
@ -576,7 +797,8 @@ public class UDGM extends RadioMedium {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
public boolean setConfigXML(Collection<Element> configXML,
|
||||||
|
boolean visAvailable) {
|
||||||
for (Element element : configXML) {
|
for (Element element : configXML) {
|
||||||
if (element.getName().equals("transmitting_range")) {
|
if (element.getName().equals("transmitting_range")) {
|
||||||
TRANSMITTING_RANGE = Double.parseDouble(element.getText());
|
TRANSMITTING_RANGE = Double.parseDouble(element.getText());
|
||||||
|
|
Loading…
Reference in a new issue