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
|
||||
* 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;
|
||||
|
@ -57,7 +57,7 @@ public class DummyRadioMedium extends RadioMedium {
|
|||
// Do nothing
|
||||
}
|
||||
|
||||
public void registerRadioInterface(Radio radio, Position position, Simulation sim) {
|
||||
public void registerRadioInterface(Radio radio, Simulation sim) {
|
||||
// Do nothing
|
||||
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
|
||||
* 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 org.apache.log4j.Logger;
|
||||
|
||||
import se.sics.cooja.*;
|
||||
import se.sics.cooja.interfaces.Position;
|
||||
import se.sics.cooja.interfaces.*;
|
||||
import se.sics.cooja.plugins.*;
|
||||
|
||||
/**
|
||||
|
@ -62,28 +62,32 @@ public class VisUAODV extends VisTraffic {
|
|||
}
|
||||
|
||||
protected void paintConnection(RadioConnection connection, Graphics g2d) {
|
||||
Point sourcePixelPosition = transformPositionToPixel(connection.getSourcePosition());
|
||||
for (Position destPosition: connection.getDestinationPositons()) {
|
||||
Point sourcePixelPosition = transformPositionToPixel(connection.getSource().getPosition());
|
||||
for (Radio destRadio: connection.getDestinations()) {
|
||||
Position destPosition = destRadio.getPosition();
|
||||
Point destPixelPosition = transformPositionToPixel(destPosition);
|
||||
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));
|
||||
}
|
||||
|
||||
g2d.drawLine(sourcePixelPosition.x, sourcePixelPosition.y,
|
||||
destPixelPosition.x, destPixelPosition.y);
|
||||
|
||||
int hopCount = getHopCount(connection.getSourceData());
|
||||
int hopCount = getHopCount(packet);
|
||||
if (hopCount >= 0)
|
||||
g2d.drawString("" + hopCount, sourcePixelPosition.x, sourcePixelPosition.y);
|
||||
}
|
||||
}
|
||||
|
||||
protected Color getColorOf(RadioConnection conn) {
|
||||
if (isRouteRequest(conn.getSourceData()))
|
||||
byte[] packet = ((PacketRadio)conn.getSource()).getLastPacketReceived();
|
||||
|
||||
if (isRouteRequest(packet))
|
||||
return Color.RED;
|
||||
else if (isRouteReply(conn.getSourceData()))
|
||||
else if (isRouteReply(packet))
|
||||
return Color.GREEN;
|
||||
else
|
||||
return Color.BLACK;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* 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;
|
||||
|
@ -33,12 +33,14 @@ import java.io.File;
|
|||
import java.io.FileOutputStream;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import se.sics.cooja.interfaces.PacketRadio;
|
||||
import se.sics.cooja.interfaces.Position;
|
||||
import se.sics.cooja.interfaces.Radio;
|
||||
|
||||
/**
|
||||
* ConnectionLogger is a simple connection information outputter. All
|
||||
* connections given via the method logConnection will be written to either
|
||||
* default Log4J info stream, a log file or both.
|
||||
* A connection logger is a simple connection information outputter. All
|
||||
* connections given to it will be written to either the currently configured
|
||||
* Log4J info stream, a log file or both.
|
||||
*
|
||||
* 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]
|
||||
|
@ -90,29 +92,29 @@ public class ConnectionLogger {
|
|||
* Connection to output
|
||||
*/
|
||||
public void logConnection(RadioConnection conn) {
|
||||
|
||||
if (myType == LOG_TO_LOG4J || myType == LOG_TO_FILE_AND_LOG4J) {
|
||||
if (conn.getDestinationPositons() != null
|
||||
&& conn.getDestinationPositons().length > 0)
|
||||
for (Position destPos : conn.getDestinationPositons()) {
|
||||
logger.info("RADIODATA from " + conn.getSourcePosition() + " to "
|
||||
+ destPos + "\tsize:" + conn.getSourceData().length);
|
||||
Radio[] destinations = conn.getDestinations();
|
||||
if (destinations != null && destinations.length > 0) {
|
||||
for (Radio destRadio : destinations) {
|
||||
logger.info("RADIODATA from " + conn.getSource().getPosition()
|
||||
+ " to " + destRadio.getPosition());
|
||||
}
|
||||
else
|
||||
logger.info("RADIODATA from " + conn.getSourcePosition() + " to "
|
||||
+ "[NOWHERE]" + "\tsize:" + conn.getSourceData().length);
|
||||
} else {
|
||||
logger.info("RADIODATA from " + conn.getSource().getPosition()
|
||||
+ " 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 {
|
||||
FileOutputStream out = new FileOutputStream(myFile, true);
|
||||
|
||||
if (conn.getDestinationPositons() != null
|
||||
&& conn.getDestinationPositons().length > 0) {
|
||||
for (int i = 0; i < conn.getDestinationPositons().length; i++) {
|
||||
Radio[] destinations = conn.getDestinations();
|
||||
if (destinations != null && destinations.length > 0) {
|
||||
for (int i = 0; i < destinations.length; i++) {
|
||||
// Source pos
|
||||
out.write("SRC_POS\t".getBytes());
|
||||
Position pos = conn.getSourcePosition();
|
||||
Position pos = conn.getSource().getPosition();
|
||||
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
||||
out.write("\t".getBytes());
|
||||
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
||||
|
@ -122,7 +124,9 @@ public class ConnectionLogger {
|
|||
|
||||
// Source data
|
||||
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);
|
||||
if (hexString.length() == 1)
|
||||
hexString = "0" + hexString;
|
||||
|
@ -132,7 +136,7 @@ public class ConnectionLogger {
|
|||
|
||||
// Destination pos
|
||||
out.write("DEST_POS\t".getBytes());
|
||||
pos = conn.getDestinationPositons()[i];
|
||||
pos = destinations[i].getPosition();
|
||||
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
||||
out.write("\t".getBytes());
|
||||
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
||||
|
@ -142,7 +146,9 @@ public class ConnectionLogger {
|
|||
|
||||
// Source data
|
||||
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);
|
||||
if (hexString.length() == 1)
|
||||
hexString = "0" + hexString;
|
||||
|
@ -156,7 +162,7 @@ public class ConnectionLogger {
|
|||
} else {
|
||||
// Source pos
|
||||
out.write("SRC_POS\t".getBytes());
|
||||
Position pos = conn.getSourcePosition();
|
||||
Position pos = conn.getSource().getPosition();
|
||||
out.write(Double.toString(pos.getXCoordinate()).getBytes());
|
||||
out.write("\t".getBytes());
|
||||
out.write(Double.toString(pos.getYCoordinate()).getBytes());
|
||||
|
@ -166,12 +172,16 @@ public class ConnectionLogger {
|
|||
|
||||
// Source data
|
||||
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);
|
||||
if (hexString.length() == 1)
|
||||
hexString = "0" + hexString;
|
||||
out.write(hexString.getBytes());
|
||||
}
|
||||
out.write("\t".getBytes());
|
||||
out.write("[NOWHERE]".getBytes());
|
||||
out.write("\n".getBytes());
|
||||
}
|
||||
out.close();
|
||||
|
|
|
@ -26,139 +26,121 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import se.sics.cooja.interfaces.Position;
|
||||
import se.sics.cooja.interfaces.Radio;
|
||||
|
||||
/**
|
||||
* RadioConnection represents a radio connection between a sending radio
|
||||
* and zero or more receiving radios.
|
||||
* By registering as an observer to the current radio medium, all
|
||||
* 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.
|
||||
*
|
||||
* A radio connection represents a connection between a source radio and zero or
|
||||
* more destination and interfered radios. Typically the destinations are able
|
||||
* to receive data sent by the source radio, and the interfered radios are not.
|
||||
*
|
||||
* @see RadioMedium
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
public class RadioConnection {
|
||||
private Radio sourceRadio;
|
||||
private Position sourcePosition;
|
||||
private byte[] sourceData;
|
||||
private Radio source;
|
||||
|
||||
private Vector<Radio> destinationRadios = new Vector<Radio>();
|
||||
private Vector<Position> destinationPositions = new Vector<Position>();
|
||||
private Vector<byte[]> destinationData = new Vector<byte[]>();
|
||||
private Vector<Radio> destinations = new Vector<Radio>();
|
||||
|
||||
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.
|
||||
*
|
||||
* @param radio Source radio
|
||||
* @param position Source position
|
||||
* @param data Source data
|
||||
*
|
||||
* @param radio
|
||||
* Source radio
|
||||
*/
|
||||
public void setSource(Radio radio, Position position, byte[] data) {
|
||||
sourceRadio = radio;
|
||||
sourcePosition = position;
|
||||
sourceData = data;
|
||||
public void setSource(Radio radio) {
|
||||
source = radio;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a connection destination.
|
||||
*
|
||||
* @param radio Source radio
|
||||
* @param position Source position
|
||||
* @param data Source data
|
||||
* Adds destination radio.
|
||||
*
|
||||
* @param radio
|
||||
* Radio
|
||||
*/
|
||||
public void addDestination(Radio radio, Position position, byte[] data) {
|
||||
destinationRadios.add(radio);
|
||||
destinationPositions.add(position);
|
||||
destinationData.add(data);
|
||||
public void addDestination(Radio radio) {
|
||||
destinations.add(radio);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Remove a connection destination.
|
||||
*
|
||||
* @param radio Destination to remove
|
||||
* Adds interfered radio.
|
||||
*
|
||||
* @param radio
|
||||
* Radio
|
||||
*/
|
||||
public void addInterfered(Radio radio) {
|
||||
interfered.add(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes destination radio.
|
||||
*
|
||||
* @param radio
|
||||
* Radio
|
||||
*/
|
||||
public void removeDestination(Radio radio) {
|
||||
int pos = destinationRadios.indexOf(radio);
|
||||
if (pos >= 0) {
|
||||
destinationRadios.remove(pos);
|
||||
destinationPositions.remove(pos);
|
||||
destinationData.remove(pos);
|
||||
}
|
||||
destinations.remove(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes interfered radio.
|
||||
*
|
||||
* @param radio
|
||||
* Radio
|
||||
*/
|
||||
public void removeInterfered(Radio radio) {
|
||||
interfered.remove(radio);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Source radio
|
||||
*/
|
||||
public Radio getSourceRadio() {
|
||||
return sourceRadio;
|
||||
public Radio getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Source position
|
||||
* @return All destinations of this connection
|
||||
*/
|
||||
public Position getSourcePosition() {
|
||||
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() {
|
||||
public Radio[] getDestinations() {
|
||||
Radio[] radioArrayType;
|
||||
Radio[] radioArray;
|
||||
|
||||
radioArrayType = new Radio[destinationRadios.size()];
|
||||
radioArray = (Radio[]) destinationRadios.toArray(radioArrayType);
|
||||
radioArrayType = new Radio[destinations.size()];
|
||||
radioArray = (Radio[]) destinations.toArray(radioArrayType);
|
||||
|
||||
return radioArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Array of destination positions
|
||||
* @return All radios interfered by this connection
|
||||
*/
|
||||
public Position[] getDestinationPositons() {
|
||||
Position[] positionArrayType;
|
||||
Position[] positionArray;
|
||||
public Radio[] getInterfered() {
|
||||
Radio[] radioArrayType;
|
||||
Radio[] radioArray;
|
||||
|
||||
positionArrayType = new Position[destinationPositions.size()];
|
||||
positionArray = (Position[]) destinationPositions.toArray(positionArrayType);
|
||||
radioArrayType = new Radio[interfered.size()];
|
||||
radioArray = (Radio[]) interfered.toArray(radioArrayType);
|
||||
|
||||
return positionArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
return radioArray;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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;
|
||||
|
@ -36,7 +36,6 @@ import java.lang.reflect.InvocationTargetException;
|
|||
import java.util.*;
|
||||
import org.jdom.Element;
|
||||
|
||||
import se.sics.cooja.interfaces.Position;
|
||||
import se.sics.cooja.interfaces.Radio;
|
||||
|
||||
/**
|
||||
|
@ -79,7 +78,7 @@ public abstract class RadioMedium {
|
|||
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
|
||||
* 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
|
||||
* Radio
|
||||
* @param position
|
||||
* Position
|
||||
* @param sim
|
||||
* Simulation holding radio
|
||||
*/
|
||||
public abstract void registerRadioInterface(Radio radio, Position position,
|
||||
Simulation sim);
|
||||
public abstract void registerRadioInterface(Radio radio, Simulation sim);
|
||||
|
||||
/**
|
||||
* Unregisters a radio interface from this medium.
|
||||
* Unregister given radio interface from this medium.
|
||||
*
|
||||
* @param radio
|
||||
* Radio interface to unregister
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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;
|
||||
|
@ -39,6 +39,8 @@ import org.jdom.Element;
|
|||
|
||||
import se.sics.cooja.*;
|
||||
import se.sics.cooja.contikimote.ContikiMoteInterface;
|
||||
import se.sics.cooja.interfaces.PacketRadio;
|
||||
import se.sics.cooja.interfaces.Position;
|
||||
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 or reception states (using multi-threading). When a transmission
|
||||
* 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
|
||||
* lock the radio in receiving mode. After some time it should then deliver the
|
||||
* packet.
|
||||
* received by this radio the Contiki system, the entitiy transferring the
|
||||
* packet may explicitly lock the radio in receiving mode. After some time it
|
||||
* should then deliver the packet.
|
||||
*
|
||||
* It needs read/write access to the following core variables:
|
||||
* <ul>
|
||||
|
@ -64,7 +66,7 @@ import se.sics.cooja.interfaces.Radio;
|
|||
* <li>char simRadioHWOn (radio hardware status (on/off))
|
||||
* <li>int simSignalStrength (heard radio signal strength)
|
||||
* <li>char simPower (number indicating power output)
|
||||
* <li>int simRadioChannel
|
||||
* <li>int simRadioChannel (number indicating current channel)
|
||||
* </ul>
|
||||
* <p>
|
||||
* Dependency core interfaces are:
|
||||
|
@ -75,9 +77,12 @@ import se.sics.cooja.interfaces.Radio;
|
|||
*
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
||||
public class ContikiRadio extends Radio implements ContikiMoteInterface,
|
||||
PacketRadio {
|
||||
private Mote myMote;
|
||||
|
||||
private SectionMoteMemory myMoteMemory;
|
||||
|
||||
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 boolean transmitting = false;
|
||||
private boolean isTransmitting = false;
|
||||
|
||||
private boolean isInterfered = false;
|
||||
|
||||
private int transmissionEndTime = -1;
|
||||
private int interferenceEndTime = -1;
|
||||
private int receptionEndTime = -1;
|
||||
|
||||
private RadioEvent lastEvent = RadioEvent.UNKNOWN;
|
||||
|
||||
private int lastEventTime = 0;
|
||||
|
||||
|
||||
private int oldOutputPowerIndicator = -1;
|
||||
|
||||
|
||||
/**
|
||||
* Creates an interface to the radio at mote.
|
||||
*
|
||||
|
@ -135,10 +141,12 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
|||
radioOn = myMoteMemory.getByteValueOf("simRadioHWOn") == 1;
|
||||
}
|
||||
|
||||
/* Contiki mote interface support */
|
||||
public static String[] getCoreInterfaceDependencies() {
|
||||
return new String[] { "radio_interface" };
|
||||
}
|
||||
|
||||
/* Packet radio support */
|
||||
public byte[] getLastPacketTransmitted() {
|
||||
return packetFromMote;
|
||||
}
|
||||
|
@ -146,30 +154,110 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
|||
public byte[] getLastPacketReceived() {
|
||||
return packetToMote;
|
||||
}
|
||||
|
||||
public boolean isTransmitting() {
|
||||
return transmitting;
|
||||
|
||||
public void setReceivedPacket(byte[] data) {
|
||||
packetToMote = data;
|
||||
}
|
||||
|
||||
public int getTransmissionEndTime() {
|
||||
return transmissionEndTime;
|
||||
/* General radio support */
|
||||
public boolean isTransmitting() {
|
||||
return isTransmitting;
|
||||
}
|
||||
|
||||
|
||||
public boolean isReceiving() {
|
||||
if (isLockedAtReceiving())
|
||||
return true;
|
||||
|
||||
|
||||
return myMoteMemory.getIntValueOf("simInSize") != 0;
|
||||
}
|
||||
|
||||
public boolean isInterfered() {
|
||||
return isInterfered;
|
||||
}
|
||||
|
||||
public int getChannel() {
|
||||
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() {
|
||||
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
|
||||
*/
|
||||
|
@ -201,98 +289,9 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
|||
|
||||
// Lock core radio in receiving loop
|
||||
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() {
|
||||
// Check if we need to release Contiki lock and deliver packet data
|
||||
if (isLockedAtReceiving() && myMote.getSimulation().getSimulationTime() >= receptionEndTime) {
|
||||
deliverPacket();
|
||||
}
|
||||
}
|
||||
|
||||
public void doActionsAfterTick() {
|
||||
|
@ -300,18 +299,18 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
|||
if (radioOn != (myMoteMemory.getByteValueOf("simRadioHWOn") == 1)) {
|
||||
// Radio changed
|
||||
radioOn = !radioOn;
|
||||
|
||||
|
||||
if (!radioOn) {
|
||||
// Reset status
|
||||
myMoteMemory.setByteValueOf("simReceiving", (byte) 0);
|
||||
myMoteMemory.setIntValueOf("simInSize", 0);
|
||||
myMoteMemory.setIntValueOf("simInSize", 0);
|
||||
myMoteMemory.setByteValueOf("simTransmitting", (byte) 0);
|
||||
myMoteMemory.setIntValueOf("simOutSize", 0);
|
||||
transmitting = false;
|
||||
myMoteMemory.setIntValueOf("simOutSize", 0);
|
||||
isTransmitting = false;
|
||||
lastEvent = RadioEvent.HW_OFF;
|
||||
} else
|
||||
lastEvent = RadioEvent.HW_ON;
|
||||
|
||||
|
||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
|
@ -325,26 +324,28 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
|||
// Check if radio output power changed
|
||||
if (myMoteMemory.getByteValueOf("simPower") != oldOutputPowerIndicator) {
|
||||
oldOutputPowerIndicator = myMoteMemory.getByteValueOf("simPower");
|
||||
lastEvent = RadioEvent.UNKNOWN;
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
}
|
||||
|
||||
|
||||
// Are we transmitting but should stop?
|
||||
if (transmitting && myMote.getSimulation().getSimulationTime() >= transmissionEndTime) {
|
||||
if (isTransmitting
|
||||
&& myMote.getSimulation().getSimulationTime() >= transmissionEndTime) {
|
||||
myMoteMemory.setByteValueOf("simTransmitting", (byte) 0);
|
||||
myMoteMemory.setIntValueOf("simOutSize", 0);
|
||||
transmitting = false;
|
||||
|
||||
isTransmitting = false;
|
||||
|
||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
||||
// TODO Energy consumption of transmitted packet?
|
||||
this.setChanged();
|
||||
this.notifyObservers();
|
||||
}
|
||||
|
||||
|
||||
// Check if a new transmission should be started
|
||||
if (!transmitting && myMoteMemory.getByteValueOf("simTransmitting") == 1) {
|
||||
transmitting = true;
|
||||
if (!isTransmitting && myMoteMemory.getByteValueOf("simTransmitting") == 1) {
|
||||
isTransmitting = true;
|
||||
int size = myMoteMemory.getIntValueOf("simOutSize");
|
||||
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
|
||||
transmissionEndTime = myMote.getSimulation().getSimulationTime()
|
||||
+ Math.max(1, duration);
|
||||
|
||||
|
||||
lastEventTime = myMote.getSimulation().getSimulationTime();
|
||||
|
||||
lastEvent = RadioEvent.TRANSMISSION_STARTED;
|
||||
this.setChanged();
|
||||
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
|
||||
JPanel panel = new JPanel();
|
||||
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
|
||||
|
||||
|
||||
final JLabel statusLabel = new JLabel("");
|
||||
final JLabel lastEventLabel = new JLabel("");
|
||||
final JLabel ssLabel = new JLabel("");
|
||||
final JButton updateButton = new JButton("Update SS");
|
||||
|
||||
|
||||
panel.add(statusLabel);
|
||||
panel.add(lastEventLabel);
|
||||
panel.add(ssLabel);
|
||||
panel.add(updateButton);
|
||||
|
||||
|
||||
updateButton.addActionListener(new ActionListener() {
|
||||
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;
|
||||
this.addObserver(observer = new Observer() {
|
||||
public void update(Observable obs, Object obj) {
|
||||
|
@ -394,19 +402,21 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
|||
else
|
||||
statusLabel.setText("HW turned off");
|
||||
|
||||
lastEventLabel.setText("Last event (time=" + lastEventTime + "): " + lastEvent);
|
||||
ssLabel.setText("Signal strength (not auto-updated): " + getCurrentSignalStrength() + " dBm");
|
||||
lastEventLabel.setText("Last event (time=" + lastEventTime + "): "
|
||||
+ lastEvent);
|
||||
ssLabel.setText("Signal strength (not auto-updated): "
|
||||
+ getCurrentSignalStrength() + " dBm");
|
||||
}
|
||||
});
|
||||
|
||||
observer.update(null, null);
|
||||
|
||||
|
||||
// Saving observer reference for releaseInterfaceVisualizer
|
||||
panel.putClientProperty("intf_obs", observer);
|
||||
|
||||
return panel;
|
||||
|
||||
return panel;
|
||||
}
|
||||
|
||||
|
||||
public void releaseInterfaceVisualizer(JPanel panel) {
|
||||
Observer observer = (Observer) panel.getClientProperty("intf_obs");
|
||||
if (observer == null) {
|
||||
|
@ -416,7 +426,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
|||
|
||||
this.deleteObserver(observer);
|
||||
}
|
||||
|
||||
|
||||
public double energyConsumptionPerTick() {
|
||||
return myEnergyConsumption;
|
||||
}
|
||||
|
@ -424,7 +434,7 @@ public class ContikiRadio extends Radio implements ContikiMoteInterface {
|
|||
public Collection<Element> getConfigXML() {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
* 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;
|
||||
|
@ -32,8 +32,15 @@ package se.sics.cooja.interfaces;
|
|||
import se.sics.cooja.*;
|
||||
|
||||
/**
|
||||
* A Radio represents a mote radio transceiver. An implementation should notify
|
||||
* all observers both when packets are received and transmitted.
|
||||
* A Radio represents a mote radio transceiver.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
@ -44,84 +51,65 @@ public abstract class Radio extends MoteInterface {
|
|||
* Events that radios should notify observers about.
|
||||
*/
|
||||
public enum RadioEvent {
|
||||
UNKNOWN,
|
||||
HW_OFF, HW_ON,
|
||||
RECEPTION_STARTED, RECEPTION_INTERFERED, RECEPTION_FINISHED,
|
||||
TRANSMISSION_STARTED, TRANSMISSION_FINISHED
|
||||
UNKNOWN, HW_OFF, HW_ON, RECEPTION_STARTED, RECEPTION_FINISHED, RECEPTION_INTERFERED, TRANSMISSION_STARTED, TRANSMISSION_FINISHED, PACKET_TRANSMITTED, BYTE_TRANSMITTED
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns last significant event at this radio. Method may for example be
|
||||
* used to learn the reason when a radio notifies a change to observers.
|
||||
* Signal that a new reception just begun. This method should normally be
|
||||
* 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
|
||||
*/
|
||||
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,
|
||||
* data.
|
||||
*
|
||||
* @see #getLastPacketTransmitted()
|
||||
* @see #isReceiving()
|
||||
* @return True if radio is transmitting data
|
||||
*/
|
||||
public abstract boolean isTransmitting();
|
||||
|
||||
/**
|
||||
* @return Transmission end time if any transmission active
|
||||
*/
|
||||
public abstract int getTransmissionEndTime();
|
||||
|
||||
/**
|
||||
* Returns true if this radio is receiving data.
|
||||
*
|
||||
* @see #getLastPacketReceived()
|
||||
* @see #isTransmitting()
|
||||
* @return True if radio is receiving data
|
||||
*/
|
||||
public abstract boolean isReceiving();
|
||||
|
||||
/**
|
||||
* If a packet is being received, it will be interfered and dropped. The
|
||||
* interference will continue until the given time, during which no other
|
||||
* 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.
|
||||
* Returns true if this radio had a connection that was dropped due to
|
||||
* interference.
|
||||
*
|
||||
* @return True if this radio is interfered
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
|
@ -138,7 +126,8 @@ public abstract class Radio extends MoteInterface {
|
|||
public abstract double getCurrentSignalStrength();
|
||||
|
||||
/**
|
||||
* Sets surrounding signal strength.
|
||||
* Sets surrounding signal strength. This method should normally be called by
|
||||
* the radio medium.
|
||||
*
|
||||
* @param signalStrength
|
||||
* Current surrounding signal strength
|
||||
|
@ -151,5 +140,13 @@ public abstract class Radio extends MoteInterface {
|
|||
* @return Current channel number
|
||||
*/
|
||||
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
|
||||
* 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;
|
||||
|
@ -40,14 +40,14 @@ import org.apache.log4j.Logger;
|
|||
import org.jdom.Element;
|
||||
|
||||
import se.sics.cooja.*;
|
||||
import se.sics.cooja.interfaces.Radio;
|
||||
import se.sics.cooja.interfaces.*;
|
||||
|
||||
/**
|
||||
* This radio periodically transmits data on a configurable channel.
|
||||
*
|
||||
* @author Fredrik Osterlind, Thiemo Voigt
|
||||
*/
|
||||
public class DisturberRadio extends Radio {
|
||||
public class DisturberRadio extends Radio implements PacketRadio {
|
||||
private Mote myMote;
|
||||
|
||||
private static Logger logger = Logger.getLogger(DisturberRadio.class);
|
||||
|
@ -78,7 +78,8 @@ public class DisturberRadio extends Radio {
|
|||
public DisturberRadio(Mote mote) {
|
||||
this.myMote = mote;
|
||||
}
|
||||
|
||||
|
||||
/* Packet radio support */
|
||||
public byte[] getLastPacketTransmitted() {
|
||||
return packetFromMote;
|
||||
}
|
||||
|
@ -87,6 +88,17 @@ public class DisturberRadio extends Radio {
|
|||
return null;
|
||||
}
|
||||
|
||||
public void setReceivedPacket(byte[] data) {
|
||||
}
|
||||
|
||||
|
||||
/* General radio support */
|
||||
public void signalReceptionStart() {
|
||||
}
|
||||
|
||||
public void signalReceptionEnd() {
|
||||
}
|
||||
|
||||
public boolean isTransmitting() {
|
||||
return transmitting;
|
||||
}
|
||||
|
@ -96,8 +108,6 @@ public class DisturberRadio extends Radio {
|
|||
}
|
||||
|
||||
public boolean isReceiving() {
|
||||
if (isLockedAtReceiving())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -105,21 +115,15 @@ public class DisturberRadio extends Radio {
|
|||
return distChannel;
|
||||
}
|
||||
|
||||
public Position getPosition() {
|
||||
return myMote.getInterfaces().getPosition();
|
||||
}
|
||||
|
||||
public RadioEvent getLastEvent() {
|
||||
return lastEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return True if locked at receiving
|
||||
*/
|
||||
private boolean isLockedAtReceiving() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void receivePacket(byte[] data, int endTime) {
|
||||
}
|
||||
|
||||
public void interferReception(int endTime) {
|
||||
public void interfereAnyReception() {
|
||||
}
|
||||
|
||||
public boolean isInterfered() {
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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;
|
||||
|
@ -38,6 +38,7 @@ import org.apache.log4j.Logger;
|
|||
|
||||
import se.sics.cooja.*;
|
||||
import se.sics.cooja.interfaces.Position;
|
||||
import se.sics.cooja.interfaces.Radio;
|
||||
|
||||
/**
|
||||
* A Traffic Visualizer visualizes radio traffic by painting lines between
|
||||
|
@ -124,11 +125,10 @@ public class VisTraffic extends Visualizer2D {
|
|||
* Graphics to paint on
|
||||
*/
|
||||
protected void paintConnection(PaintedConnection connection, Graphics g2d) {
|
||||
Point sourcePixelPosition = transformPositionToPixel(connection.radioConnection
|
||||
.getSourcePosition());
|
||||
Point sourcePixelPosition = transformPositionToPixel(connection.radioConnection.getSource().getPosition());
|
||||
g2d.setColor(connection.getColor(simulation.isRunning()));
|
||||
for (Position destPosition : connection.radioConnection
|
||||
.getDestinationPositons()) {
|
||||
for (Radio destRadio : connection.radioConnection.getDestinations()) {
|
||||
Position destPosition = destRadio.getPosition();
|
||||
Point destPixelPosition = transformPositionToPixel(destPosition);
|
||||
g2d.drawLine(sourcePixelPosition.x, sourcePixelPosition.y,
|
||||
destPixelPosition.x, destPixelPosition.y);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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;
|
||||
|
@ -57,7 +57,7 @@ public class SilentRadioMedium extends RadioMedium {
|
|||
// Do nothing
|
||||
}
|
||||
|
||||
public void registerRadioInterface(Radio radio, Position position, Simulation sim) {
|
||||
public void registerRadioInterface(Radio radio, Simulation sim) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* 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;
|
||||
|
@ -47,35 +47,41 @@ import se.sics.cooja.plugins.Visualizer2D;
|
|||
* The Unit Disk Graph medium has two different range parameters; one for
|
||||
* transmitting and one for interfering other transmissions.
|
||||
*
|
||||
* Radio data are analysed when all registered motes have ticked once (this
|
||||
* medium is registered as a tick observer). For every mote in transmission
|
||||
* range of a sending mote, current listen status is changed from hearing
|
||||
* 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.
|
||||
* The radio medium supports both byte and packet radios. Any transmitted bytes
|
||||
* are forwarded TODO immediately with a timestamp (more fine-grained than
|
||||
* ticks).
|
||||
*
|
||||
* This radio medium registers a temporary visual plugin class.
|
||||
* Via this plugin ranges can be viewed and changed. Active connection may also
|
||||
* be viewed.
|
||||
* The radio medium registers a visualizer plugin. Via this plugin the current
|
||||
* radio states and range parameters can be viewed and changed.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
@ClassDescription("Unit Disk Graph Medium (UDGM)")
|
||||
public class UDGM extends RadioMedium {
|
||||
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> transmissionEndedRadios = new Vector<Radio>();
|
||||
// private Vector<Radio> transmissionEndedRadios = new Vector<Radio>();
|
||||
private Vector<RadioConnection> finishedConnections = new Vector<RadioConnection>();
|
||||
|
||||
private static RadioMedium myRadioMedium;
|
||||
|
||||
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;
|
||||
|
||||
|
@ -89,7 +95,7 @@ public class UDGM extends RadioMedium {
|
|||
*
|
||||
* @author Fredrik Osterlind
|
||||
*/
|
||||
@ClassDescription("Radio Medium Visualizer")
|
||||
@ClassDescription("UDGM Visualizer")
|
||||
@PluginType(PluginType.SIM_PLUGIN)
|
||||
public static class VisUDGM extends Visualizer2D {
|
||||
private Mote selectedMote = null;
|
||||
|
@ -118,7 +124,7 @@ public class UDGM extends RadioMedium {
|
|||
|
||||
public VisUDGM(Simulation sim, GUI gui) {
|
||||
super(sim, gui);
|
||||
setTitle("Radio Medium Visualizer");
|
||||
setTitle("UDGM Visualizer");
|
||||
|
||||
// Create spinners for changing ranges
|
||||
SpinnerNumberModel transmissionModel = new SpinnerNumberModel();
|
||||
|
@ -253,54 +259,57 @@ public class UDGM extends RadioMedium {
|
|||
int y = pixelCoord.y;
|
||||
|
||||
// Fetch current output power indicator (scale with as percent)
|
||||
// TODO Probably not the best way to use indicator
|
||||
double moteInterferenceRange = INTERFERENCE_RANGE
|
||||
* (0.01 * (double) selectedMote.getInterfaces().getRadio()
|
||||
.getCurrentOutputPowerIndicator());
|
||||
double moteTransmissionRange = TRANSMITTING_RANGE
|
||||
* (0.01 * (double) selectedMote.getInterfaces().getRadio()
|
||||
.getCurrentOutputPowerIndicator());
|
||||
if (selectedMote.getInterfaces().getRadio() != null) {
|
||||
double moteInterferenceRange = INTERFERENCE_RANGE
|
||||
* (0.01 * (double) selectedMote.getInterfaces().getRadio()
|
||||
.getCurrentOutputPowerIndicator());
|
||||
double moteTransmissionRange = TRANSMITTING_RANGE
|
||||
* (0.01 * (double) selectedMote.getInterfaces().getRadio()
|
||||
.getCurrentOutputPowerIndicator());
|
||||
|
||||
Point translatedZero = transformPositionToPixel(0.0, 0.0, 0.0);
|
||||
Point translatedInterference = transformPositionToPixel(
|
||||
moteInterferenceRange, moteInterferenceRange, 0.0);
|
||||
Point translatedTransmission = transformPositionToPixel(
|
||||
moteTransmissionRange, moteTransmissionRange, 0.0);
|
||||
Point translatedZero = transformPositionToPixel(0.0, 0.0, 0.0);
|
||||
Point translatedInterference = transformPositionToPixel(
|
||||
moteInterferenceRange, moteInterferenceRange, 0.0);
|
||||
Point translatedTransmission = transformPositionToPixel(
|
||||
moteTransmissionRange, moteTransmissionRange, 0.0);
|
||||
|
||||
translatedInterference.x = Math.abs(translatedInterference.x
|
||||
- translatedZero.x);
|
||||
translatedInterference.y = Math.abs(translatedInterference.y
|
||||
- translatedZero.y);
|
||||
translatedTransmission.x = Math.abs(translatedTransmission.x
|
||||
- translatedZero.x);
|
||||
translatedTransmission.y = Math.abs(translatedTransmission.y
|
||||
- translatedZero.y);
|
||||
translatedInterference.x = Math.abs(translatedInterference.x
|
||||
- translatedZero.x);
|
||||
translatedInterference.y = Math.abs(translatedInterference.y
|
||||
- translatedZero.y);
|
||||
translatedTransmission.x = Math.abs(translatedTransmission.x
|
||||
- translatedZero.x);
|
||||
translatedTransmission.y = Math.abs(translatedTransmission.y
|
||||
- translatedZero.y);
|
||||
|
||||
// Interference
|
||||
g.setColor(Color.DARK_GRAY);
|
||||
g.fillOval(x - translatedInterference.x, 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);
|
||||
// Interference
|
||||
g.setColor(Color.DARK_GRAY);
|
||||
g.fillOval(x - translatedInterference.x,
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// Let parent paint motes
|
||||
super.visualizeSimulation(g);
|
||||
|
||||
// Paint last tick connections
|
||||
// Paint just finished connections
|
||||
if (myRadioMedium != null
|
||||
&& myRadioMedium.getLastTickConnections() != null) {
|
||||
for (RadioConnection conn : myRadioMedium.getLastTickConnections()) {
|
||||
if (conn != null) {
|
||||
Point sourcePoint = transformPositionToPixel(conn
|
||||
.getSourcePosition());
|
||||
Point sourcePoint = transformPositionToPixel(conn.getSource()
|
||||
.getPosition());
|
||||
|
||||
// Paint destinations
|
||||
for (Position destPos : conn.getDestinationPositons()) {
|
||||
for (Radio destRadio : conn.getDestinations()) {
|
||||
Position destPos = destRadio.getPosition();
|
||||
Point destPoint = transformPositionToPixel(destPos);
|
||||
|
||||
g.setColor(Color.BLACK);
|
||||
|
@ -338,205 +347,417 @@ public class UDGM extends RadioMedium {
|
|||
|
||||
private RadioConnection[] lastTickConnections = null;
|
||||
|
||||
private Vector<RadioConnection> pendingConnections = new Vector<RadioConnection>();
|
||||
private Vector<RadioConnection> activeConnections = new Vector<RadioConnection>();
|
||||
|
||||
private ConnectionLogger myLogger = null;
|
||||
|
||||
private Observer radioDataObserver = new Observer() {
|
||||
public void update(Observable radio, Object obj) {
|
||||
// This radio changed, let tick loop notify observers
|
||||
radioMediumObservable.setRadioMediumChanged();
|
||||
/**
|
||||
* Creates and registers a new connection from given radio.
|
||||
*
|
||||
* @param radio
|
||||
* Transmitting radio
|
||||
* @return New registered connection
|
||||
*/
|
||||
private RadioConnection createConnections(Radio radio) {
|
||||
Radio sendingRadio = radio;
|
||||
Position sendingPosition = sendingRadio.getPosition();
|
||||
|
||||
// Register any new transmission
|
||||
if (((Radio) radio).getLastEvent() == Radio.RadioEvent.TRANSMISSION_STARTED) {
|
||||
Radio sendingRadio = (Radio) radio;
|
||||
RadioConnection newConnection = new RadioConnection(sendingRadio);
|
||||
|
||||
// If obj is the position, use it directly (speeds up things)
|
||||
// Otherwise we must search for the position ourselves
|
||||
Position sendingPosition = (Position) obj;
|
||||
if (sendingPosition == null) {
|
||||
if (!registeredRadios.contains(radio)) {
|
||||
logger.fatal("Sending radio not registered, skipping packet");
|
||||
return;
|
||||
}
|
||||
// Fetch current output power indicator (scale with as percent)
|
||||
double moteTransmissionRange = TRANSMITTING_RANGE
|
||||
* (0.01 * (double) sendingRadio.getCurrentOutputPowerIndicator());
|
||||
double moteInterferenceRange = INTERFERENCE_RANGE
|
||||
* (0.01 * (double) sendingRadio.getCurrentOutputPowerIndicator());
|
||||
|
||||
sendingPosition = registeredPositions.get(registeredRadios
|
||||
.indexOf(radio));
|
||||
if (sendingPosition == null) {
|
||||
logger.fatal("Sending radio not registered, skipping packet");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// Loop through all radios
|
||||
for (int listenNr = 0; listenNr < registeredRadios.size(); listenNr++) {
|
||||
Radio listeningRadio = registeredRadios.get(listenNr);
|
||||
Position listeningRadioPosition = listeningRadio.getPosition();
|
||||
|
||||
byte[] dataToSend = sendingRadio.getLastPacketTransmitted();
|
||||
|
||||
RadioConnection newConnection = new RadioConnection();
|
||||
pendingConnections.add(newConnection);
|
||||
newConnection.setSource(sendingRadio, sendingPosition, dataToSend);
|
||||
// Ignore sending radio and radios on different channels
|
||||
if (sendingRadio == listeningRadio)
|
||||
continue;
|
||||
if (sendingRadio.getChannel() != listeningRadio.getChannel())
|
||||
continue;
|
||||
|
||||
// Fetch current output power indicator (scale with as percent)
|
||||
// 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());
|
||||
double distance = sendingPosition.getDistanceTo(listeningRadioPosition);
|
||||
|
||||
// Loop through all radios that are listening
|
||||
for (int listenNr = 0; listenNr < registeredPositions.size(); listenNr++) {
|
||||
Radio listeningRadio = registeredRadios.get(listenNr);
|
||||
if (distance <= moteTransmissionRange) {
|
||||
// Check if this radio is able to receive transmission
|
||||
if (listeningRadio.isInterfered()) {
|
||||
// Keep interfering radio
|
||||
newConnection.addInterfered(listeningRadio);
|
||||
|
||||
if (sendingRadio == listeningRadio)
|
||||
continue;
|
||||
if (sendingRadio.getChannel() != listeningRadio.getChannel())
|
||||
continue;
|
||||
|
||||
|
||||
// If not the sending radio..
|
||||
double distance = sendingPosition.getDistanceTo(registeredPositions
|
||||
.get(listenNr));
|
||||
|
||||
if (distance <= moteTransmissionRange) {
|
||||
newConnection.addDestination(registeredRadios.get(listenNr),
|
||||
registeredPositions.get(listenNr), dataToSend);
|
||||
|
||||
// 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 (listeningRadio.isReceiving()) {
|
||||
newConnection.addInterfered(listeningRadio);
|
||||
|
||||
// Start interfering radio
|
||||
listeningRadio.interfereAnyReception();
|
||||
|
||||
// Update connection that is transmitting to this radio
|
||||
RadioConnection existingConn = null;
|
||||
for (RadioConnection conn : activeConnections) {
|
||||
for (Radio dstRadio : conn.getDestinations()) {
|
||||
if (dstRadio == listeningRadio) {
|
||||
existingConn = conn;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} 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");
|
||||
}
|
||||
}
|
||||
|
||||
if (((Radio) radio).getLastEvent() == Radio.RadioEvent.TRANSMISSION_FINISHED) {
|
||||
transmissionEndedRadios.add((Radio) radio);
|
||||
} else if (sourceRadio instanceof PacketRadio) {
|
||||
// Packet radios forwards packets to all packet radios
|
||||
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() {
|
||||
public void update(Observable obs, Object obj) {
|
||||
|
||||
if (lastTickConnections != null)
|
||||
// Reset any last tick connections
|
||||
if (lastTickConnections != null) {
|
||||
radioMediumObservable.setRadioMediumChanged();
|
||||
lastTickConnections = null;
|
||||
}
|
||||
|
||||
// Reset last tick connections
|
||||
lastTickConnections = null;
|
||||
// Do nothing if radio medium unchanged
|
||||
if (!radioMediumObservable.hasChanged())
|
||||
return;
|
||||
|
||||
// Log finished connections if any
|
||||
Vector<RadioConnection> updatedPendingConnections = new Vector<RadioConnection>();
|
||||
if (transmissionEndedRadios.size() > 0) {
|
||||
final int numberFinished = transmissionEndedRadios.size();
|
||||
Vector<RadioConnection> newTickConnections = new Vector<RadioConnection>();
|
||||
|
||||
// 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;
|
||||
// Log any new finished connections
|
||||
if (finishedConnections.size() > 0) {
|
||||
lastTickConnections = new RadioConnection[finishedConnections.size()];
|
||||
for (int i = 0; i < finishedConnections.size(); i++)
|
||||
lastTickConnections[i] = finishedConnections.get(i);
|
||||
finishedConnections.clear();
|
||||
|
||||
// Notify radio medium logger of the finished transmissions
|
||||
if (myLogger != null) {
|
||||
for (RadioConnection conn : lastTickConnections)
|
||||
myLogger.logConnection(conn);
|
||||
}
|
||||
|
||||
// Radio medium has changed, notifing below
|
||||
radioMediumObservable.setRadioMediumChanged();
|
||||
}
|
||||
|
||||
// Set signal strengths on all radios
|
||||
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)
|
||||
// Notify all other radio medium observers
|
||||
radioMediumObservable.notifyObservers();
|
||||
}
|
||||
};
|
||||
|
||||
public void registerMote(Mote mote, Simulation sim) {
|
||||
registerRadioInterface(mote.getInterfaces().getRadio(), mote
|
||||
.getInterfaces().getPosition(), sim);
|
||||
registerRadioInterface(mote.getInterfaces().getRadio(), sim);
|
||||
}
|
||||
|
||||
public void unregisterMote(Mote mote, Simulation sim) {
|
||||
unregisterRadioInterface(mote.getInterfaces().getRadio(), sim);
|
||||
}
|
||||
|
||||
public void registerRadioInterface(Radio radio, Position position,
|
||||
Simulation sim) {
|
||||
if (radio != null && position != null) {
|
||||
public void registerRadioInterface(Radio radio, Simulation sim) {
|
||||
if (radio != null) {
|
||||
if (!isTickObserver) {
|
||||
sim.addTickObserver(tickObserver);
|
||||
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);
|
||||
radio.addObserver(radioDataObserver);
|
||||
radio.addObserver(radioEventsObserver);
|
||||
|
||||
// Set initial signal strenth
|
||||
radio.setCurrentSignalStrength(SS_NOTHING);
|
||||
|
||||
} // else logger.warn("Radio Medium not registering mote");
|
||||
}
|
||||
}
|
||||
|
||||
public void unregisterRadioInterface(Radio radio, Simulation sim) {
|
||||
for (int i = 0; i < registeredRadios.size(); i++) {
|
||||
if (registeredRadios.get(i).equals(radio)) {
|
||||
registeredRadios.remove(i);
|
||||
registeredPositions.remove(i);
|
||||
radio.deleteObserver(radioDataObserver);
|
||||
return;
|
||||
}
|
||||
if (!registeredRadios.contains(radio)) {
|
||||
logger.warn("Could not find radio: " + radio + " to unregister");
|
||||
return;
|
||||
}
|
||||
logger.warn("Could not find radio: " + radio + " to unregister");
|
||||
|
||||
radio.deleteObserver(radioEventsObserver);
|
||||
registeredRadios.remove(radio);
|
||||
|
||||
removeFromActiveConnections(radio);
|
||||
}
|
||||
|
||||
public void addRadioMediumObserver(Observer observer) {
|
||||
|
@ -576,7 +797,8 @@ public class UDGM extends RadioMedium {
|
|||
return config;
|
||||
}
|
||||
|
||||
public boolean setConfigXML(Collection<Element> configXML, boolean visAvailable) {
|
||||
public boolean setConfigXML(Collection<Element> configXML,
|
||||
boolean visAvailable) {
|
||||
for (Element element : configXML) {
|
||||
if (element.getName().equals("transmitting_range")) {
|
||||
TRANSMITTING_RANGE = Double.parseDouble(element.getText());
|
||||
|
|
Loading…
Reference in a new issue