a set of new cooja-mspsim mote types

This commit is contained in:
Fredrik Osterlind 2013-08-16 12:02:16 +02:00
parent 8041f66d8c
commit 7c125ced9a
19 changed files with 2913 additions and 0 deletions

View File

@ -0,0 +1,422 @@
/*
* Copyright (c) 2012, Thingsquare.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
package com.thingsquare.cooja.mspsim;
import java.util.Collection;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.RadioPacket;
import se.sics.cooja.Simulation;
import se.sics.cooja.interfaces.CustomDataRadio;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.Radio;
import se.sics.cooja.mspmote.MspMote;
import se.sics.cooja.mspmote.MspMoteTimeEvent;
import se.sics.mspsim.chip.CC1101;
import se.sics.mspsim.chip.CC1101.ReceiverListener;
import se.sics.mspsim.chip.ChannelListener;
import se.sics.mspsim.chip.RFListener;
import se.sics.mspsim.chip.Radio802154;
/**
* @author Fredrik Osterlind
*/
@ClassDescription("TI CC1101")
public class CC1101Radio extends Radio implements CustomDataRadio {
private static Logger logger = Logger.getLogger(CC1101Radio.class);
/**
* Cross-level:
* Inter-byte delay for delivering cross-level packet bytes.
*/
public static final long DELAY_BETWEEN_BYTES =
(long) (1000.0*Simulation.MILLISECOND/(250000.0/8.0)); /* us. Corresponds to 250kbit/s */
private RadioEvent lastEvent = RadioEvent.UNKNOWN;
private final MspMote mote;
private final CC1101 cc1101;
private boolean isInterfered = false;
private boolean isTransmitting = false;
private boolean isReceiving = false;
private byte lastOutgoingByte;
private byte lastIncomingByte;
private RadioPacket lastOutgoingPacket = null;
private RadioPacket lastIncomingPacket = null;
public CC1101Radio(Mote m) {
this.mote = (MspMote)m;
Radio802154 r = this.mote.getCPU().getChip(Radio802154.class);
if (r == null || !(r instanceof CC1101)) {
throw new IllegalStateException("Mote is not equipped with an CC1101 radio");
}
this.cc1101 = (CC1101) r;
cc1101.addRFListener(new RFListener() {
int len = 0;
int expLen = 0;
byte[] buffer = new byte[256 + 15];
private boolean gotSynchbyte = false;
public void receivedByte(byte data) {
if (!isTransmitting()) {
/* Start transmission */
lastEvent = RadioEvent.TRANSMISSION_STARTED;
isTransmitting = true;
len = 0;
gotSynchbyte = false;
/*logger.debug("----- CC1101 TRANSMISSION STARTED -----");*/
setChanged();
notifyObservers();
}
if (len >= buffer.length) {
/* Bad size packet, too large */
logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data);
return;
}
/* send this byte to all nodes */
lastOutgoingByte = data;
lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED;
setChanged();
notifyObservers();
/* Await synch byte */
if (!gotSynchbyte) {
if (lastOutgoingByte == CC1101.SYNCH_BYTE_LAST) {
gotSynchbyte = true;
}
return;
}
final int HEADERLEN = 1; /* 1x Length byte */
final int FOOTERLEN = 2; /* TODO Fix CRC in Mspsim's CC1101.java */
if (len == 0) {
expLen = (0xff&data) + HEADERLEN + FOOTERLEN;
}
buffer[len++] = data;
if (len == expLen) {
/*logger.debug("----- CC1101 CUSTOM DATA TRANSMITTED -----");*/
final byte[] buf = new byte[expLen];
System.arraycopy(buffer, 0, buf, 0, expLen);
lastOutgoingPacket = new RadioPacket() {
public byte[] getPacketData() {
return buf;
}
};
lastEvent = RadioEvent.PACKET_TRANSMITTED;
/*logger.debug("----- CC1101 PACKET TRANSMITTED -----");*/
setChanged();
notifyObservers();
/*logger.debug("----- CC1101 TRANSMISSION FINISHED -----");*/
isTransmitting = false;
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
setChanged();
notifyObservers();
len = 0;
}
}
});
cc1101.setReceiverListener(new ReceiverListener() {
public void newState(boolean on) {
if (cc1101.isReadyToReceive()) {
lastEvent = RadioEvent.HW_ON;
setChanged();
notifyObservers();
} else {
radioOff();
}
}
});
cc1101.addChannelListener(new ChannelListener() {
public void channelChanged(int channel) {
/* XXX Currently assumes zero channel switch time */
lastEvent = RadioEvent.UNKNOWN;
setChanged();
notifyObservers();
}
});
}
private void radioOff() {
/* Radio was turned off during transmission.
* May for example happen if watchdog triggers */
if (isTransmitting()) {
logger.warn("Turning off radio while transmitting, ending packet prematurely");
/* Simulate end of packet */
lastOutgoingPacket = new RadioPacket() {
public byte[] getPacketData() {
return new byte[0];
}
};
lastEvent = RadioEvent.PACKET_TRANSMITTED;
/*logger.debug("----- CC1101 PACKET TRANSMITTED -----");*/
setChanged();
notifyObservers();
/* Register that transmission ended in radio medium */
/*logger.debug("----- CC1101 TRANSMISSION FINISHED -----");*/
isTransmitting = false;
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
setChanged();
notifyObservers();
}
lastEvent = RadioEvent.HW_OFF;
setChanged();
notifyObservers();
}
/* Packet radio support */
public RadioPacket getLastPacketTransmitted() {
return lastOutgoingPacket;
}
public RadioPacket getLastPacketReceived() {
return lastIncomingPacket;
}
public void setReceivedPacket(RadioPacket packet) {
lastIncomingPacket = packet;
/* TODO XXX Need support in CC1101.java */
/*if (!radio.isReadyToReceive()) {
logger.warn("Radio receiver not ready, dropping packet data");
return;
}*/
/* Delivering packet bytes with delays */
byte[] packetData = packet.getPacketData();
long deliveryTime = getMote().getSimulation().getSimulationTime();
for (byte b: packetData) {
if (isInterfered()) {
b = (byte) 0xFF;
}
final byte byteToDeliver = b;
getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) {
public void execute(long t) {
super.execute(t);
cc1101.receivedByte(byteToDeliver);
mote.requestImmediateWakeup();
}
}, deliveryTime);
deliveryTime += DELAY_BETWEEN_BYTES;
}
}
/* Custom data radio support */
public Object getLastCustomDataTransmitted() {
return lastOutgoingByte;
}
public Object getLastCustomDataReceived() {
return lastIncomingByte;
}
public void receiveCustomData(Object data) {
if (!(data instanceof Byte)) {
logger.fatal("Bad custom data: " + data);
return;
}
lastIncomingByte = (Byte) data;
final byte inputByte;
if (isInterfered()) {
inputByte = (byte)0xFF;
} else {
inputByte = lastIncomingByte;
}
mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) {
public void execute(long t) {
super.execute(t);
cc1101.receivedByte(inputByte);
mote.requestImmediateWakeup();
}
}, mote.getSimulation().getSimulationTime());
}
/* General radio support */
public boolean isTransmitting() {
return isTransmitting;
}
public boolean isReceiving() {
return isReceiving;
}
public boolean isInterfered() {
return isInterfered;
}
public int getChannel() {
return cc1101.getActiveChannel();
}
public int getFrequency() {
return cc1101.getActiveFrequency();
}
public void signalReceptionStart() {
isReceiving = true;
lastEvent = RadioEvent.RECEPTION_STARTED;
/*logger.debug("----- CC1101 RECEPTION STARTED -----");*/
setChanged();
notifyObservers();
}
public void signalReceptionEnd() {
/* Deliver packet data */
isReceiving = false;
isInterfered = false;
lastEvent = RadioEvent.RECEPTION_FINISHED;
/*logger.debug("----- CC1101 RECEPTION FINISHED -----");*/
setChanged();
notifyObservers();
}
public RadioEvent getLastEvent() {
return lastEvent;
}
public void interfereAnyReception() {
isInterfered = true;
isReceiving = false;
lastIncomingPacket = null;
lastEvent = RadioEvent.RECEPTION_INTERFERED;
/*logger.debug("----- CC1101 RECEPTION INTERFERED -----");*/
setChanged();
notifyObservers();
}
public double getCurrentOutputPower() {
/* TODO XXX Need support in CC1101.java */
return 1;
}
public int getCurrentOutputPowerIndicator() {
/* TODO XXX Need support in CC1101.java */
return 10;
}
public int getOutputPowerIndicatorMax() {
/* TODO XXX Need support in CC1101.java */
return 10;
}
/**
* Last 8 received signal strengths
*/
double currentSignalStrength = 0;
private double[] rssiLast = new double[8];
private int rssiLastCounter = 0;
public double getCurrentSignalStrength() {
return currentSignalStrength;
}
public void setCurrentSignalStrength(final double signalStrength) {
if (signalStrength == currentSignalStrength) {
return; /* ignored */
}
currentSignalStrength = signalStrength;
if (rssiLastCounter == 0) {
getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) {
public void execute(long t) {
super.execute(t);
/* Update average */
System.arraycopy(rssiLast, 1, rssiLast, 0, 7);
rssiLast[7] = currentSignalStrength;
double avg = 0;
for (double v: rssiLast) {
avg += v;
}
avg /= rssiLast.length;
cc1101.setRSSI((int) avg);
rssiLastCounter--;
if (rssiLastCounter > 0) {
mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2);
}
}
}, mote.getSimulation().getSimulationTime());
}
rssiLastCounter = 8;
}
public Mote getMote() {
return mote;
}
public Position getPosition() {
return mote.getInterfaces().getPosition();
}
public Collection<Element> getConfigXML() {
return null;
}
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
}
public boolean isRadioOn() {
return cc1101.isReadyToReceive();
}
public boolean canReceiveFrom(CustomDataRadio radio) {
if (radio.getClass().equals(this.getClass())) {
return true;
}
if (radio.getClass().equals(CC430Radio.class)) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,421 @@
/*
* Copyright (c) 2012, Thingsquare.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
package com.thingsquare.cooja.mspsim;
import java.util.Collection;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.RadioPacket;
import se.sics.cooja.Simulation;
import se.sics.cooja.interfaces.CustomDataRadio;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.Radio;
import se.sics.cooja.mspmote.MspMote;
import se.sics.cooja.mspmote.MspMoteTimeEvent;
import se.sics.mspsim.chip.CC1120;
import se.sics.mspsim.chip.CC1120.ReceiverListener;
import se.sics.mspsim.chip.ChannelListener;
import se.sics.mspsim.chip.RFListener;
import se.sics.mspsim.chip.Radio802154;
/**
* @author Fredrik Osterlind
*/
@ClassDescription("TI CC1120")
public class CC1120Radio extends Radio implements CustomDataRadio {
private static Logger logger = Logger.getLogger(CC1120Radio.class);
/**
* Cross-level:
* Inter-byte delay for delivering cross-level packet bytes.
*/
/* TODO XXX Fix me as well as symbol duration in CC1120.java */
public static final long DELAY_BETWEEN_BYTES =
(long) (1000.0*Simulation.MILLISECOND/(200000.0/8.0)); /* us. Corresponds to 200kbit/s */
private RadioEvent lastEvent = RadioEvent.UNKNOWN;
private final MspMote mote;
private final CC1120 cc1120;
private boolean isInterfered = false;
private boolean isTransmitting = false;
private boolean isReceiving = false;
private byte lastOutgoingByte;
private byte lastIncomingByte;
private RadioPacket lastOutgoingPacket = null;
private RadioPacket lastIncomingPacket = null;
public CC1120Radio(Mote m) {
this.mote = (MspMote)m;
Radio802154 r = this.mote.getCPU().getChip(Radio802154.class);
if (r == null || !(r instanceof CC1120)) {
throw new IllegalStateException("Mote is not equipped with an CC1120 radio");
}
this.cc1120 = (CC1120) r;
cc1120.addRFListener(new RFListener() {
int len = 0;
int expLen = 0;
byte[] buffer = new byte[256 + 15];
private boolean gotSynchbyte = false;
public void receivedByte(byte data) {
if (!isTransmitting()) {
/* Start transmission */
lastEvent = RadioEvent.TRANSMISSION_STARTED;
isTransmitting = true;
len = 0;
gotSynchbyte = false;
/*logger.debug("----- CCC1120 TRANSMISSION STARTED -----");*/
setChanged();
notifyObservers();
}
if (len >= buffer.length) {
/* Bad size packet, too large */
logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data);
return;
}
/* send this byte to all nodes */
lastOutgoingByte = data;
lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED;
setChanged();
notifyObservers();
/* Await synch byte */
if (!gotSynchbyte) {
if (lastOutgoingByte == CC1120.SYNCH_BYTE_LAST) {
gotSynchbyte = true;
}
return;
}
final int HEADERLEN = 1; /* 1x Length byte */
final int FOOTERLEN = 2; /* TODO Fix CRC in Mspsim's CCC1120.java */
if (len == 0) {
expLen = (0xff&data) + HEADERLEN + FOOTERLEN;
}
buffer[len++] = data;
if (len == expLen) {
/*logger.debug("----- CCC1120 CUSTOM DATA TRANSMITTED -----");*/
final byte[] buf = new byte[expLen];
System.arraycopy(buffer, 0, buf, 0, expLen);
lastOutgoingPacket = new RadioPacket() {
public byte[] getPacketData() {
return buf;
}
};
lastEvent = RadioEvent.PACKET_TRANSMITTED;
/*logger.debug("----- CCC1120 PACKET TRANSMITTED -----");*/
setChanged();
notifyObservers();
/*logger.debug("----- CCC1120 TRANSMISSION FINISHED -----");*/
isTransmitting = false;
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
setChanged();
notifyObservers();
len = 0;
}
}
});
cc1120.setReceiverListener(new ReceiverListener() {
public void newState(boolean on) {
if (cc1120.isReadyToReceive()) {
lastEvent = RadioEvent.HW_ON;
setChanged();
notifyObservers();
} else {
radioOff();
}
}
});
cc1120.addChannelListener(new ChannelListener() {
public void channelChanged(int channel) {
/* XXX Currently assumes zero channel switch time */
lastEvent = RadioEvent.UNKNOWN;
setChanged();
notifyObservers();
}
});
}
private void radioOff() {
/* Radio was turned off during transmission.
* May for example happen if watchdog triggers */
if (isTransmitting()) {
logger.warn("Turning off radio while transmitting, ending packet prematurely");
/* Simulate end of packet */
lastOutgoingPacket = new RadioPacket() {
public byte[] getPacketData() {
return new byte[0];
}
};
lastEvent = RadioEvent.PACKET_TRANSMITTED;
/*logger.debug("----- CCC1120 PACKET TRANSMITTED -----");*/
setChanged();
notifyObservers();
/* Register that transmission ended in radio medium */
/*logger.debug("----- CCC1120 TRANSMISSION FINISHED -----");*/
isTransmitting = false;
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
setChanged();
notifyObservers();
}
lastEvent = RadioEvent.HW_OFF;
setChanged();
notifyObservers();
}
/* Packet radio support */
public RadioPacket getLastPacketTransmitted() {
return lastOutgoingPacket;
}
public RadioPacket getLastPacketReceived() {
return lastIncomingPacket;
}
public void setReceivedPacket(RadioPacket packet) {
lastIncomingPacket = packet;
/* TODO XXX Need support in CCC1120.java */
/*if (!radio.isReadyToReceive()) {
logger.warn("Radio receiver not ready, dropping packet data");
return;
}*/
/* Delivering packet bytes with delays */
byte[] packetData = packet.getPacketData();
long deliveryTime = getMote().getSimulation().getSimulationTime();
for (byte b: packetData) {
if (isInterfered()) {
b = (byte) 0xFF;
}
final byte byteToDeliver = b;
getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) {
public void execute(long t) {
super.execute(t);
cc1120.receivedByte(byteToDeliver);
mote.requestImmediateWakeup();
}
}, deliveryTime);
deliveryTime += DELAY_BETWEEN_BYTES;
}
}
/* Custom data radio support */
public Object getLastCustomDataTransmitted() {
return lastOutgoingByte;
}
public Object getLastCustomDataReceived() {
return lastIncomingByte;
}
public void receiveCustomData(Object data) {
if (!(data instanceof Byte)) {
logger.fatal("Bad custom data: " + data);
return;
}
lastIncomingByte = (Byte) data;
final byte inputByte;
if (isInterfered()) {
inputByte = (byte)0xFF;
} else {
inputByte = lastIncomingByte;
}
mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) {
public void execute(long t) {
super.execute(t);
cc1120.receivedByte(inputByte);
mote.requestImmediateWakeup();
}
}, mote.getSimulation().getSimulationTime());
}
/* General radio support */
public boolean isTransmitting() {
return isTransmitting;
}
public boolean isReceiving() {
return isReceiving;
}
public boolean isInterfered() {
return isInterfered;
}
public int getChannel() {
return cc1120.getActiveChannel()+1000;
}
public int getFrequency() {
return cc1120.getActiveFrequency();
}
public void signalReceptionStart() {
isReceiving = true;
lastEvent = RadioEvent.RECEPTION_STARTED;
/*logger.debug("----- CCC1120 RECEPTION STARTED -----");*/
setChanged();
notifyObservers();
}
public void signalReceptionEnd() {
/* Deliver packet data */
isReceiving = false;
isInterfered = false;
lastEvent = RadioEvent.RECEPTION_FINISHED;
/*logger.debug("----- CCC1120 RECEPTION FINISHED -----");*/
setChanged();
notifyObservers();
}
public RadioEvent getLastEvent() {
return lastEvent;
}
public void interfereAnyReception() {
isInterfered = true;
isReceiving = false;
lastIncomingPacket = null;
lastEvent = RadioEvent.RECEPTION_INTERFERED;
/*logger.debug("----- CCC1120 RECEPTION INTERFERED -----");*/
setChanged();
notifyObservers();
}
public double getCurrentOutputPower() {
/* TODO XXX Need support in CCC1120.java */
return 1;
}
public int getCurrentOutputPowerIndicator() {
/* TODO XXX Need support in CCC1120.java */
return 10;
}
public int getOutputPowerIndicatorMax() {
/* TODO XXX Need support in CCC1120.java */
return 10;
}
/**
* Last 8 received signal strengths
*/
double currentSignalStrength = 0;
private double[] rssiLast = new double[8];
private int rssiLastCounter = 0;
public double getCurrentSignalStrength() {
return currentSignalStrength;
}
public void setCurrentSignalStrength(final double signalStrength) {
if (signalStrength == currentSignalStrength) {
return; /* ignored */
}
currentSignalStrength = signalStrength;
if (rssiLastCounter == 0) {
getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) {
public void execute(long t) {
super.execute(t);
/* Update average */
System.arraycopy(rssiLast, 1, rssiLast, 0, 7);
rssiLast[7] = currentSignalStrength;
double avg = 0;
for (double v: rssiLast) {
avg += v;
}
avg /= rssiLast.length;
cc1120.setRSSI((int) avg);
rssiLastCounter--;
if (rssiLastCounter > 0) {
mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2);
}
}
}, mote.getSimulation().getSimulationTime());
}
rssiLastCounter = 8;
}
public Mote getMote() {
return mote;
}
public Position getPosition() {
return mote.getInterfaces().getPosition();
}
public Collection<Element> getConfigXML() {
return null;
}
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
}
public boolean isRadioOn() {
return cc1120.isReadyToReceive();
}
public boolean canReceiveFrom(CustomDataRadio radio) {
if (radio.getClass().equals(this.getClass())) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,377 @@
package com.thingsquare.cooja.mspsim;
import java.util.Collection;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.RadioPacket;
import se.sics.cooja.Simulation;
import se.sics.cooja.interfaces.CustomDataRadio;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.Radio;
import se.sics.cooja.mspmote.MspMote;
import se.sics.cooja.mspmote.MspMoteTimeEvent;
import se.sics.cooja.mspmote.interfaces.CC2420RadioPacketConverter;
import se.sics.mspsim.chip.CC2520;
import se.sics.mspsim.chip.ChannelListener;
import se.sics.mspsim.chip.RFListener;
import se.sics.mspsim.core.Chip;
import se.sics.mspsim.core.OperatingModeListener;
/**
* MSPSim CC2520 radio to COOJA wrapper.
*
* @author Fredrik Osterlind
*/
@ClassDescription("IEEE CC2520 Radio")
public class CC2520Radio extends Radio implements CustomDataRadio {
private static Logger logger = Logger.getLogger(CC2520Radio.class);
/**
* Cross-level:
* Inter-byte delay for delivering cross-level packet bytes.
*/
public static final long DELAY_BETWEEN_BYTES =
(long) (1000.0*Simulation.MILLISECOND/(250000.0/8.0)); /* us. Corresponds to 250kbit/s */
private RadioEvent lastEvent = RadioEvent.UNKNOWN;
private final MspMote mote;
private final CC2520 radio;
private boolean isInterfered = false;
private boolean isTransmitting = false;
private boolean isReceiving = false;
private byte lastOutgoingByte;
private byte lastIncomingByte;
private RadioPacket lastOutgoingPacket = null;
private RadioPacket lastIncomingPacket = null;
public CC2520Radio(Mote m) {
this.mote = (MspMote)m;
this.radio = this.mote.getCPU().getChip(CC2520.class);
if (radio == null) {
throw new IllegalStateException("Mote is not equipped with an IEEE CC2520 radio");
}
radio.addRFListener(new RFListener() {
int len = 0;
int expLen = 0;
byte[] buffer = new byte[127 + 15];
public void receivedByte(byte data) {
if (!isTransmitting()) {
lastEvent = RadioEvent.TRANSMISSION_STARTED;
isTransmitting = true;
len = 0;
/*logger.debug("----- CC2520 TRANSMISSION STARTED -----");*/
setChanged();
notifyObservers();
}
if (len >= buffer.length) {
/* Bad size packet, too large */
logger.debug("Error: bad size: " + len + ", dropping outgoing byte: " + data);
return;
}
/* send this byte to all nodes */
lastOutgoingByte = data;
lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED;
setChanged();
notifyObservers();
buffer[len++] = data;
if (len == 6) {
// System.out.println("## CC2520 Packet of length: " + data + " expected...");
expLen = data + 6;
}
if (len == expLen) {
/*logger.debug("----- CC2520 CUSTOM DATA TRANSMITTED -----");*/
len -= 4; /* preamble */
len -= 1; /* synch */
len -= radio.getFooterLength(); /* footer */
final byte[] packetdata = new byte[len];
System.arraycopy(buffer, 4+1, packetdata, 0, len);
lastOutgoingPacket = new RadioPacket() {
public byte[] getPacketData() {
return packetdata;
}
};
/*logger.debug("----- CC2520 PACKET TRANSMITTED -----");*/
setChanged();
notifyObservers();
/*logger.debug("----- CC2520 TRANSMISSION FINISHED -----");*/
isTransmitting = false;
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
setChanged();
notifyObservers();
len = 0;
}
}
});
radio.addOperatingModeListener(new OperatingModeListener() {
public void modeChanged(Chip source, int mode) {
if (radio.isReadyToReceive()) {
lastEvent = RadioEvent.HW_ON;
setChanged();
notifyObservers();
} else {
radioOff();
}
}
});
radio.addChannelListener(new ChannelListener() {
public void channelChanged(int channel) {
/* XXX Currently assumes zero channel switch time */
lastEvent = RadioEvent.UNKNOWN;
setChanged();
notifyObservers();
}
});
}
private void radioOff() {
/* Radio was turned off during transmission.
* May for example happen if watchdog triggers */
if (isTransmitting()) {
logger.warn("Turning off radio while transmitting, ending packet prematurely");
/* Simulate end of packet */
lastOutgoingPacket = new RadioPacket() {
public byte[] getPacketData() {
return new byte[0];
}
};
lastEvent = RadioEvent.PACKET_TRANSMITTED;
/*logger.debug("----- CC2520 PACKET TRANSMITTED -----");*/
setChanged();
notifyObservers();
/* Register that transmission ended in radio medium */
/*logger.debug("----- CC2520 TRANSMISSION FINISHED -----");*/
isTransmitting = false;
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
setChanged();
notifyObservers();
}
lastEvent = RadioEvent.HW_OFF;
setChanged();
notifyObservers();
}
/* Packet radio support */
public RadioPacket getLastPacketTransmitted() {
return lastOutgoingPacket;
}
public RadioPacket getLastPacketReceived() {
return lastIncomingPacket;
}
public void setReceivedPacket(RadioPacket packet) {
logger.fatal("TODO Implement me!");
}
/* Custom data radio support */
public Object getLastCustomDataTransmitted() {
return lastOutgoingByte;
}
public Object getLastCustomDataReceived() {
return lastIncomingByte;
}
public void receiveCustomData(Object data) {
if (!(data instanceof Byte)) {
logger.fatal("Bad custom data: " + data);
return;
}
lastIncomingByte = (Byte) data;
final byte inputByte;
if (isInterfered()) {
inputByte = (byte)0xFF;
} else {
inputByte = lastIncomingByte;
}
mote.getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) {
public void execute(long t) {
super.execute(t);
radio.receivedByte(inputByte);
mote.requestImmediateWakeup();
}
}, mote.getSimulation().getSimulationTime());
}
/* General radio support */
public boolean isTransmitting() {
return isTransmitting;
}
public boolean isReceiving() {
return isReceiving;
}
public boolean isInterfered() {
return isInterfered;
}
public int getChannel() {
return radio.getActiveChannel();
}
public int getFrequency() {
return radio.getActiveFrequency();
}
public void signalReceptionStart() {
isReceiving = true;
lastEvent = RadioEvent.RECEPTION_STARTED;
/*logger.debug("----- CC2520 RECEPTION STARTED -----");*/
setChanged();
notifyObservers();
}
public void signalReceptionEnd() {
/* Deliver packet data */
isReceiving = false;
isInterfered = false;
lastEvent = RadioEvent.RECEPTION_FINISHED;
/*logger.debug("----- CC2520 RECEPTION FINISHED -----");*/
setChanged();
notifyObservers();
}
public RadioEvent getLastEvent() {
return lastEvent;
}
public void interfereAnyReception() {
isInterfered = true;
isReceiving = false;
lastIncomingPacket = null;
lastEvent = RadioEvent.RECEPTION_INTERFERED;
/*logger.debug("----- CC2520 RECEPTION INTERFERED -----");*/
setChanged();
notifyObservers();
}
public double getCurrentOutputPower() {
return radio.getOutputPower();
}
public int getCurrentOutputPowerIndicator() {
return 100;
// return radio.getOutputPowerIndicator();
}
public int getOutputPowerIndicatorMax() {
return 100;
// return 31;
}
double currentSignalStrength = 0;
/**
* Last 8 received signal strengths
*/
private double[] rssiLast = new double[8];
private int rssiLastCounter = 0;
public double getCurrentSignalStrength() {
return currentSignalStrength;
}
public void setCurrentSignalStrength(final double signalStrength) {
if (signalStrength == currentSignalStrength) {
return; /* ignored */
}
currentSignalStrength = signalStrength;
if (rssiLastCounter == 0) {
getMote().getSimulation().scheduleEvent(new MspMoteTimeEvent(mote, 0) {
public void execute(long t) {
super.execute(t);
/* Update average */
System.arraycopy(rssiLast, 1, rssiLast, 0, 7);
rssiLast[7] = currentSignalStrength;
double avg = 0;
for (double v: rssiLast) {
avg += v;
}
avg /= rssiLast.length;
radio.setRSSI((int) avg);
rssiLastCounter--;
if (rssiLastCounter > 0) {
mote.getSimulation().scheduleEvent(this, t+DELAY_BETWEEN_BYTES/2);
}
}
}, mote.getSimulation().getSimulationTime());
}
rssiLastCounter = 8;
}
public void setLQI(int lqi){
radio.setLQI(lqi);
}
public int getLQI(){
return radio.getLQI();
}
public Mote getMote() {
return mote;
}
public Position getPosition() {
return mote.getInterfaces().getPosition();
}
public Collection<Element> getConfigXML() {
return null;
}
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
}
public boolean isRadioOn() {
if (radio.isReadyToReceive()) {
return true;
}
if (radio.getMode() == CC2520.MODE_POWER_OFF) {
return false;
}
if (radio.getMode() == CC2520.MODE_TXRX_OFF) {
return false;
}
return true;
}
public boolean canReceiveFrom(CustomDataRadio radio) {
if (radio.getClass().equals(this.getClass())) {
return true;
}
return false;
}
}

View File

@ -0,0 +1,76 @@
/*
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package com.thingsquare.cooja.mspsim;
import java.io.File;
import org.apache.log4j.Logger;
import se.sics.cooja.Simulation;
import se.sics.cooja.mspmote.MspMote;
import se.sics.cooja.mspmote.MspMoteType;
import se.sics.mspsim.platform.ti.CC430Node;
/**
* @author Fredrik Osterlind
*/
public class CC430Mote extends MspMote {
private static Logger logger = Logger.getLogger(CC430Mote.class);
public CC430Node cc430Node = null;
public CC430Mote(MspMoteType moteType, Simulation sim) {
super(moteType, sim);
}
protected boolean initEmulator(File fileELF) {
try {
cc430Node = new CC430Node();
registry = cc430Node.getRegistry();
prepareMote(fileELF, cc430Node);
} catch (Exception e) {
logger.fatal("Error when creating CC430 mote: ", e);
return false;
}
return true;
}
public void idUpdated(int newID) {
logger.fatal("idUpdated(" + newID + ") ignored");
}
public String toString() {
return "CC430 " + getID();
}
}

View File

@ -0,0 +1,215 @@
/*
* Copyright (c) 2012, Thingsquare, http://www.thingsquare.com/.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
package com.thingsquare.cooja.mspsim;
import java.awt.Container;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.io.File;
import java.net.URL;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import org.apache.log4j.Logger;
import se.sics.cooja.AbstractionLevelDescription;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.GUI;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.dialogs.MessageList.MessageContainer;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.interfaces.Mote2MoteRelations;
import se.sics.cooja.interfaces.MoteAttributes;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.RimeAddress;
import se.sics.cooja.mspmote.MspCompileDialog;
import se.sics.cooja.mspmote.MspMote;
import se.sics.cooja.mspmote.MspMoteType;
import se.sics.cooja.mspmote.interfaces.MspClock;
import se.sics.cooja.mspmote.interfaces.MspDebugOutput;
import se.sics.cooja.mspmote.interfaces.MspMoteID;
import se.sics.cooja.mspmote.interfaces.UsciA0Serial;
@ClassDescription("CC430 mote")
@AbstractionLevelDescription("Emulated level")
public class CC430MoteType extends MspMoteType {
private static Logger logger = Logger.getLogger(CC430MoteType.class);
protected MspMote createMote(Simulation simulation) {
return new CC430Mote(this, simulation);
}
public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable)
throws MoteTypeCreationException {
/* If visualized, show compile dialog and let user configure */
if (visAvailable) {
/* Create unique identifier */
if (getIdentifier() == null) {
int counter = 0;
boolean identifierOK = false;
while (!identifierOK) {
identifierOK = true;
counter++;
setIdentifier("cc430-" + counter);
for (MoteType existingMoteType : simulation.getMoteTypes()) {
if (existingMoteType == this) {
continue;
}
if (existingMoteType.getIdentifier().equals(getIdentifier())) {
identifierOK = false;
break;
}
}
}
}
/* Create initial description */
if (getDescription() == null) {
setDescription("CC430 Mote Type #" + getIdentifier());
}
return MspCompileDialog.showDialog(parentContainer, simulation, this, "cc430");
}
/* Not visualized: Compile Contiki immediately */
if (getIdentifier() == null) {
throw new MoteTypeCreationException("No identifier");
}
final MessageList compilationOutput = new MessageList();
if (getCompileCommands() != null) {
/* Handle multiple compilation commands one by one */
String[] arr = getCompileCommands().split("\n");
for (String cmd: arr) {
if (cmd.trim().isEmpty()) {
continue;
}
try {
CompileContiki.compile(
cmd,
null,
null /* Do not observe output firmware file */,
getContikiSourceFile().getParentFile(),
null,
null,
compilationOutput,
true
);
} catch (Exception e) {
MoteTypeCreationException newException =
new MoteTypeCreationException("Mote type creation failed: " + e.getMessage());
newException = (MoteTypeCreationException) newException.initCause(e);
newException.setCompilationOutput(compilationOutput);
/* Print last 10 compilation errors to console */
MessageContainer[] messages = compilationOutput.getMessages();
for (int i=messages.length-10; i < messages.length; i++) {
if (i < 0) {
continue;
}
logger.fatal(">> " + messages[i]);
}
logger.fatal("Compilation error: " + e.getMessage());
throw newException;
}
}
}
if (getContikiFirmwareFile() == null ||
!getContikiFirmwareFile().exists()) {
throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile());
}
return true;
}
public Icon getMoteTypeIcon() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
URL imageURL = this.getClass().getClassLoader().getResource("images/cc430.jpg");
Image image = toolkit.getImage(imageURL);
MediaTracker tracker = new MediaTracker(GUI.getTopParentContainer());
tracker.addImage(image, 1);
try {
tracker.waitForAll();
} catch (InterruptedException ex) {
}
if (image.getHeight(GUI.getTopParentContainer()) > 0 && image.getWidth(GUI.getTopParentContainer()) > 0) {
image = image.getScaledInstance((200*image.getWidth(GUI.getTopParentContainer())/image.getHeight(GUI.getTopParentContainer())), 200, Image.SCALE_DEFAULT);
return new ImageIcon(image);
}
return null;
}
public Class<? extends MoteInterface>[] getDefaultMoteInterfaceClasses() {
return getAllMoteInterfaceClasses();
}
public Class<? extends MoteInterface>[] getAllMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspDebugOutput.class,
MspClock.class,
MspMoteID.class,
UsciA0Serial.class,
CC430Radio.class,
};
}
public File getExpectedFirmwareFile(File source) {
File parentDir = source.getParentFile();
String sourceNoExtension = source.getName().substring(0, source.getName().length()-2);
return new File(parentDir, sourceNoExtension + ".cc430");
}
protected String getTargetName() {
return "cc430";
}
}

View File

@ -0,0 +1,50 @@
/*
* Copyright (c) 2012, Thingsquare.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
package com.thingsquare.cooja.mspsim;
import org.apache.log4j.Logger;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.interfaces.CustomDataRadio;
/**
* @author Fredrik Osterlind
*/
@ClassDescription("TI CC1101 (CC430)")
public class CC430Radio extends CC1101Radio implements CustomDataRadio {
private static Logger logger = Logger.getLogger(CC1101Radio.class);
public CC430Radio(Mote m) {
super(m);
}
}

View File

@ -0,0 +1,26 @@
package com.thingsquare.cooja.mspsim;
import java.io.File;
import se.sics.cooja.Simulation;
import se.sics.cooja.mspmote.Exp5438Mote;
import se.sics.cooja.mspmote.MspMoteType;
/**
* @author Fredrik Osterlind
*/
public class Eth1120Mote extends Exp5438Mote {
private String desc = "";
public Eth1120Mote(MspMoteType moteType, Simulation sim) {
super(moteType, sim);
}
protected boolean initEmulator(File fileELF) {
return super.initEmulator(fileELF);
}
public String toString() {
return desc + " " + getID();
}
}

View File

@ -0,0 +1,169 @@
package com.thingsquare.cooja.mspsim;
import java.awt.Container;
import java.io.File;
import org.apache.log4j.Logger;
import se.sics.cooja.AbstractionLevelDescription;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.dialogs.MessageList.MessageContainer;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.interfaces.Mote2MoteRelations;
import se.sics.cooja.interfaces.MoteAttributes;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.RimeAddress;
import se.sics.cooja.mspmote.Exp5438MoteType;
import se.sics.cooja.mspmote.MspCompileDialog;
import se.sics.cooja.mspmote.interfaces.Msp802154Radio;
import se.sics.cooja.mspmote.interfaces.MspClock;
import se.sics.cooja.mspmote.interfaces.MspDebugOutput;
import se.sics.cooja.mspmote.interfaces.MspMoteID;
import se.sics.cooja.mspmote.interfaces.UsciA1Serial;
@ClassDescription("Eth1120")
@AbstractionLevelDescription("Emulated level")
public class Eth1120MoteType extends Exp5438MoteType {
private static Logger logger = Logger.getLogger(Eth1120MoteType.class);
public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable)
throws MoteTypeCreationException {
/* If visualized, show compile dialog and let user configure */
if (visAvailable) {
/* Create unique identifier */
if (getIdentifier() == null) {
int counter = 0;
boolean identifierOK = false;
while (!identifierOK) {
identifierOK = true;
counter++;
setIdentifier("eth1120#" + counter);
for (MoteType existingMoteType : simulation.getMoteTypes()) {
if (existingMoteType == this) {
continue;
}
if (existingMoteType.getIdentifier().equals(getIdentifier())) {
identifierOK = false;
break;
}
}
}
}
/* Create initial description */
if (getDescription() == null) {
setDescription("Ethb1120 Mote Type " + getIdentifier());
}
return MspCompileDialog.showDialog(parentContainer, simulation, this, "eth1120");
}
/* Not visualized: Compile Contiki immediately */
if (getIdentifier() == null) {
throw new MoteTypeCreationException("No identifier");
}
final MessageList compilationOutput = new MessageList();
if (getCompileCommands() != null) {
/* Handle multiple compilation commands one by one */
String[] arr = getCompileCommands().split("\n");
for (String cmd: arr) {
if (cmd.trim().isEmpty()) {
continue;
}
try {
CompileContiki.compile(
cmd,
null,
null /* Do not observe output firmware file */,
getContikiSourceFile().getParentFile(),
null,
null,
compilationOutput,
true
);
} catch (Exception e) {
MoteTypeCreationException newException =
new MoteTypeCreationException("Mote type creation failed: " + e.getMessage());
newException = (MoteTypeCreationException) newException.initCause(e);
newException.setCompilationOutput(compilationOutput);
/* Print last 10 compilation errors to console */
MessageContainer[] messages = compilationOutput.getMessages();
for (int i=messages.length-10; i < messages.length; i++) {
if (i < 0) {
continue;
}
logger.fatal(">> " + messages[i]);
}
logger.fatal("Compilation error: " + e.getMessage());
throw newException;
}
}
}
if (getContikiFirmwareFile() == null ||
!getContikiFirmwareFile().exists()) {
throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile());
}
return true;
}
public Class<? extends MoteInterface>[] getDefaultMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
CC1120Radio.class,
UsciA1Serial.class,
TrxebLEDs.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public Class<? extends MoteInterface>[] getAllMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
Msp802154Radio.class,
CC1120Radio.class,
UsciA1Serial.class,
TrxebLEDs.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public File getExpectedFirmwareFile(File source) {
File parentDir = source.getParentFile();
String sourceNoExtension = source.getName().substring(0, source.getName().length()-2);
return new File(parentDir, sourceNoExtension + ".eth1120");
}
protected String getTargetName() {
return "eth1120";
}
}

View File

@ -0,0 +1,26 @@
package com.thingsquare.cooja.mspsim;
import java.io.File;
import se.sics.cooja.Simulation;
import se.sics.cooja.mspmote.Exp5438Mote;
import se.sics.cooja.mspmote.MspMoteType;
/**
* @author Fredrik Osterlind
*/
public class Exp1101Mote extends Exp5438Mote {
private String desc = "";
public Exp1101Mote(MspMoteType moteType, Simulation sim) {
super(moteType, sim);
}
protected boolean initEmulator(File fileELF) {
return super.initEmulator(fileELF);
}
public String toString() {
return desc + " " + getID();
}
}

View File

@ -0,0 +1,171 @@
package com.thingsquare.cooja.mspsim;
import java.awt.Container;
import java.io.File;
import org.apache.log4j.Logger;
import se.sics.cooja.AbstractionLevelDescription;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.dialogs.MessageList.MessageContainer;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.interfaces.Mote2MoteRelations;
import se.sics.cooja.interfaces.MoteAttributes;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.RimeAddress;
import se.sics.cooja.mspmote.Exp5438MoteType;
import se.sics.cooja.mspmote.MspCompileDialog;
import se.sics.cooja.mspmote.interfaces.Exp5438LED;
import se.sics.cooja.mspmote.interfaces.Msp802154Radio;
import se.sics.cooja.mspmote.interfaces.MspClock;
import se.sics.cooja.mspmote.interfaces.MspDebugOutput;
import se.sics.cooja.mspmote.interfaces.MspMoteID;
import se.sics.cooja.mspmote.interfaces.UsciA1Serial;
@ClassDescription("Exp1101 mote (MSP430F5438)")
@AbstractionLevelDescription("Emulated level")
public class Exp1101MoteType extends Exp5438MoteType {
private static Logger logger = Logger.getLogger(Exp1101MoteType.class);
public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable)
throws MoteTypeCreationException {
/* If visualized, show compile dialog and let user configure */
if (visAvailable) {
/* Create unique identifier */
if (getIdentifier() == null) {
int counter = 0;
boolean identifierOK = false;
while (!identifierOK) {
identifierOK = true;
counter++;
setIdentifier("exp1101#" + counter);
for (MoteType existingMoteType : simulation.getMoteTypes()) {
if (existingMoteType == this) {
continue;
}
if (existingMoteType.getIdentifier().equals(getIdentifier())) {
identifierOK = false;
break;
}
}
}
}
/* Create initial description */
if (getDescription() == null) {
setDescription("Exp1101 Mote Type " + getIdentifier());
}
return MspCompileDialog.showDialog(parentContainer, simulation, this, "exp1101");
}
/* Not visualized: Compile Contiki immediately */
if (getIdentifier() == null) {
throw new MoteTypeCreationException("No identifier");
}
final MessageList compilationOutput = new MessageList();
if (getCompileCommands() != null) {
/* Handle multiple compilation commands one by one */
String[] arr = getCompileCommands().split("\n");
for (String cmd: arr) {
if (cmd.trim().isEmpty()) {
continue;
}
try {
CompileContiki.compile(
cmd,
null,
null /* Do not observe output firmware file */,
getContikiSourceFile().getParentFile(),
null,
null,
compilationOutput,
true
);
} catch (Exception e) {
MoteTypeCreationException newException =
new MoteTypeCreationException("Mote type creation failed: " + e.getMessage());
newException = (MoteTypeCreationException) newException.initCause(e);
newException.setCompilationOutput(compilationOutput);
/* Print last 10 compilation errors to console */
MessageContainer[] messages = compilationOutput.getMessages();
for (int i=messages.length-10; i < messages.length; i++) {
if (i < 0) {
continue;
}
logger.fatal(">> " + messages[i]);
}
logger.fatal("Compilation error: " + e.getMessage());
throw newException;
}
}
}
if (getContikiFirmwareFile() == null ||
!getContikiFirmwareFile().exists()) {
throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile());
}
return true;
}
public Class<? extends MoteInterface>[] getDefaultMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
CC1101Radio.class,
UsciA1Serial.class,
Exp5438LED.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public Class<? extends MoteInterface>[] getAllMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
Msp802154Radio.class,
CC1101Radio.class,
CC1101Radio.class,
UsciA1Serial.class,
Exp5438LED.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public File getExpectedFirmwareFile(File source) {
File parentDir = source.getParentFile();
String sourceNoExtension = source.getName().substring(0, source.getName().length()-2);
return new File(parentDir, sourceNoExtension + ".exp1101");
}
protected String getTargetName() {
return "exp1101";
}
}

View File

@ -0,0 +1,26 @@
package com.thingsquare.cooja.mspsim;
import java.io.File;
import se.sics.cooja.Simulation;
import se.sics.cooja.mspmote.Exp5438Mote;
import se.sics.cooja.mspmote.MspMoteType;
/**
* @author Fredrik Osterlind
*/
public class Exp1120Mote extends Exp5438Mote {
private String desc = "";
public Exp1120Mote(MspMoteType moteType, Simulation sim) {
super(moteType, sim);
}
protected boolean initEmulator(File fileELF) {
return super.initEmulator(fileELF);
}
public String toString() {
return desc + " " + getID();
}
}

View File

@ -0,0 +1,171 @@
package com.thingsquare.cooja.mspsim;
import java.awt.Container;
import java.io.File;
import org.apache.log4j.Logger;
import se.sics.cooja.AbstractionLevelDescription;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.dialogs.MessageList.MessageContainer;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.interfaces.Mote2MoteRelations;
import se.sics.cooja.interfaces.MoteAttributes;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.RimeAddress;
import se.sics.cooja.mspmote.Exp5438MoteType;
import se.sics.cooja.mspmote.MspCompileDialog;
import se.sics.cooja.mspmote.interfaces.Exp5438LED;
import se.sics.cooja.mspmote.interfaces.Msp802154Radio;
import se.sics.cooja.mspmote.interfaces.MspClock;
import se.sics.cooja.mspmote.interfaces.MspDebugOutput;
import se.sics.cooja.mspmote.interfaces.MspMoteID;
import se.sics.cooja.mspmote.interfaces.UsciA1Serial;
@ClassDescription("Exp1120 mote (MSP430F5438)")
@AbstractionLevelDescription("Emulated level")
public class Exp1120MoteType extends Exp5438MoteType {
private static Logger logger = Logger.getLogger(Exp1120MoteType.class);
public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable)
throws MoteTypeCreationException {
/* If visualized, show compile dialog and let user configure */
if (visAvailable) {
/* Create unique identifier */
if (getIdentifier() == null) {
int counter = 0;
boolean identifierOK = false;
while (!identifierOK) {
identifierOK = true;
counter++;
setIdentifier("exp1120#" + counter);
for (MoteType existingMoteType : simulation.getMoteTypes()) {
if (existingMoteType == this) {
continue;
}
if (existingMoteType.getIdentifier().equals(getIdentifier())) {
identifierOK = false;
break;
}
}
}
}
/* Create initial description */
if (getDescription() == null) {
setDescription("Exp1120 Mote Type " + getIdentifier());
}
return MspCompileDialog.showDialog(parentContainer, simulation, this, "exp1120");
}
/* Not visualized: Compile Contiki immediately */
if (getIdentifier() == null) {
throw new MoteTypeCreationException("No identifier");
}
final MessageList compilationOutput = new MessageList();
if (getCompileCommands() != null) {
/* Handle multiple compilation commands one by one */
String[] arr = getCompileCommands().split("\n");
for (String cmd: arr) {
if (cmd.trim().isEmpty()) {
continue;
}
try {
CompileContiki.compile(
cmd,
null,
null /* Do not observe output firmware file */,
getContikiSourceFile().getParentFile(),
null,
null,
compilationOutput,
true
);
} catch (Exception e) {
MoteTypeCreationException newException =
new MoteTypeCreationException("Mote type creation failed: " + e.getMessage());
newException = (MoteTypeCreationException) newException.initCause(e);
newException.setCompilationOutput(compilationOutput);
/* Print last 10 compilation errors to console */
MessageContainer[] messages = compilationOutput.getMessages();
for (int i=messages.length-10; i < messages.length; i++) {
if (i < 0) {
continue;
}
logger.fatal(">> " + messages[i]);
}
logger.fatal("Compilation error: " + e.getMessage());
throw newException;
}
}
}
if (getContikiFirmwareFile() == null ||
!getContikiFirmwareFile().exists()) {
throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile());
}
return true;
}
public Class<? extends MoteInterface>[] getDefaultMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
CC1120Radio.class,
UsciA1Serial.class,
Exp5438LED.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public Class<? extends MoteInterface>[] getAllMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
Msp802154Radio.class,
CC1101Radio.class,
CC1120Radio.class,
UsciA1Serial.class,
Exp5438LED.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public File getExpectedFirmwareFile(File source) {
File parentDir = source.getParentFile();
String sourceNoExtension = source.getName().substring(0, source.getName().length()-2);
return new File(parentDir, sourceNoExtension + ".exp1120");
}
protected String getTargetName() {
return "exp1120";
}
}

View File

@ -0,0 +1,26 @@
package com.thingsquare.cooja.mspsim;
import java.io.File;
import se.sics.cooja.Simulation;
import se.sics.cooja.mspmote.Exp5438Mote;
import se.sics.cooja.mspmote.MspMoteType;
/**
* @author Fredrik Osterlind
*/
public class Exp2420Mote extends Exp5438Mote {
private String desc = "";
public Exp2420Mote(MspMoteType moteType, Simulation sim) {
super(moteType, sim);
}
protected boolean initEmulator(File fileELF) {
return super.initEmulator(fileELF);
}
public String toString() {
return desc + " " + getID();
}
}

View File

@ -0,0 +1,172 @@
package com.thingsquare.cooja.mspsim;
import java.awt.Container;
import java.io.File;
import org.apache.log4j.Logger;
import se.sics.cooja.AbstractionLevelDescription;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.dialogs.MessageList.MessageContainer;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.interfaces.Mote2MoteRelations;
import se.sics.cooja.interfaces.MoteAttributes;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.RimeAddress;
import se.sics.cooja.mspmote.Exp5438MoteType;
import se.sics.cooja.mspmote.MspCompileDialog;
import se.sics.cooja.mspmote.interfaces.Exp5438LED;
import se.sics.cooja.mspmote.interfaces.Msp802154Radio;
import se.sics.cooja.mspmote.interfaces.MspClock;
import se.sics.cooja.mspmote.interfaces.MspDebugOutput;
import se.sics.cooja.mspmote.interfaces.MspMoteID;
import se.sics.cooja.mspmote.interfaces.UsciA1Serial;
@ClassDescription("Exp2420 mote (MSP430F5438)")
@AbstractionLevelDescription("Emulated level")
public class Exp2420MoteType extends Exp5438MoteType {
private static Logger logger = Logger.getLogger(Exp2420MoteType.class);
public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable)
throws MoteTypeCreationException {
/* If visualized, show compile dialog and let user configure */
if (visAvailable) {
/* Create unique identifier */
if (getIdentifier() == null) {
int counter = 0;
boolean identifierOK = false;
while (!identifierOK) {
identifierOK = true;
counter++;
setIdentifier("exp2420#" + counter);
for (MoteType existingMoteType : simulation.getMoteTypes()) {
if (existingMoteType == this) {
continue;
}
if (existingMoteType.getIdentifier().equals(getIdentifier())) {
identifierOK = false;
break;
}
}
}
}
/* Create initial description */
if (getDescription() == null) {
setDescription("Exp2420 Mote Type " + getIdentifier());
}
return MspCompileDialog.showDialog(parentContainer, simulation, this, "exp2420");
}
/* Not visualized: Compile Contiki immediately */
if (getIdentifier() == null) {
throw new MoteTypeCreationException("No identifier");
}
final MessageList compilationOutput = new MessageList();
if (getCompileCommands() != null) {
/* Handle multiple compilation commands one by one */
String[] arr = getCompileCommands().split("\n");
for (String cmd: arr) {
if (cmd.trim().isEmpty()) {
continue;
}
try {
CompileContiki.compile(
cmd,
null,
null /* Do not observe output firmware file */,
getContikiSourceFile().getParentFile(),
null,
null,
compilationOutput,
true
);
} catch (Exception e) {
MoteTypeCreationException newException =
new MoteTypeCreationException("Mote type creation failed: " + e.getMessage());
newException = (MoteTypeCreationException) newException.initCause(e);
newException.setCompilationOutput(compilationOutput);
/* Print last 10 compilation errors to console */
MessageContainer[] messages = compilationOutput.getMessages();
for (int i=messages.length-10; i < messages.length; i++) {
if (i < 0) {
continue;
}
logger.fatal(">> " + messages[i]);
}
logger.fatal("Compilation error: " + e.getMessage());
throw newException;
}
}
}
if (getContikiFirmwareFile() == null ||
!getContikiFirmwareFile().exists()) {
throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile());
}
return true;
}
public Class<? extends MoteInterface>[] getDefaultMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
Msp802154Radio.class,
UsciA1Serial.class,
Exp5438LED.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public Class<? extends MoteInterface>[] getAllMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
Msp802154Radio.class,
CC1101Radio.class,
CC1120Radio.class,
Msp802154Radio.class,
UsciA1Serial.class,
Exp5438LED.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public File getExpectedFirmwareFile(File source) {
File parentDir = source.getParentFile();
String sourceNoExtension = source.getName().substring(0, source.getName().length()-2);
return new File(parentDir, sourceNoExtension + ".exp2420");
}
protected String getTargetName() {
return "exp2420";
}
}

View File

@ -0,0 +1,26 @@
package com.thingsquare.cooja.mspsim;
import java.io.File;
import se.sics.cooja.Simulation;
import se.sics.cooja.mspmote.Exp5438Mote;
import se.sics.cooja.mspmote.MspMoteType;
/**
* @author Fredrik Osterlind
*/
public class Trxeb1120Mote extends Exp5438Mote {
private String desc = "";
public Trxeb1120Mote(MspMoteType moteType, Simulation sim) {
super(moteType, sim);
}
protected boolean initEmulator(File fileELF) {
return super.initEmulator(fileELF);
}
public String toString() {
return desc + " " + getID();
}
}

View File

@ -0,0 +1,169 @@
package com.thingsquare.cooja.mspsim;
import java.awt.Container;
import java.io.File;
import org.apache.log4j.Logger;
import se.sics.cooja.AbstractionLevelDescription;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.dialogs.MessageList.MessageContainer;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.interfaces.Mote2MoteRelations;
import se.sics.cooja.interfaces.MoteAttributes;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.RimeAddress;
import se.sics.cooja.mspmote.Exp5438MoteType;
import se.sics.cooja.mspmote.MspCompileDialog;
import se.sics.cooja.mspmote.interfaces.Msp802154Radio;
import se.sics.cooja.mspmote.interfaces.MspClock;
import se.sics.cooja.mspmote.interfaces.MspDebugOutput;
import se.sics.cooja.mspmote.interfaces.MspMoteID;
import se.sics.cooja.mspmote.interfaces.UsciA1Serial;
@ClassDescription("Trxeb1120")
@AbstractionLevelDescription("Emulated level")
public class Trxeb1120MoteType extends Exp5438MoteType {
private static Logger logger = Logger.getLogger(Trxeb1120MoteType.class);
public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable)
throws MoteTypeCreationException {
/* If visualized, show compile dialog and let user configure */
if (visAvailable) {
/* Create unique identifier */
if (getIdentifier() == null) {
int counter = 0;
boolean identifierOK = false;
while (!identifierOK) {
identifierOK = true;
counter++;
setIdentifier("trxeb1120#" + counter);
for (MoteType existingMoteType : simulation.getMoteTypes()) {
if (existingMoteType == this) {
continue;
}
if (existingMoteType.getIdentifier().equals(getIdentifier())) {
identifierOK = false;
break;
}
}
}
}
/* Create initial description */
if (getDescription() == null) {
setDescription("Trxeb1120 Mote Type " + getIdentifier());
}
return MspCompileDialog.showDialog(parentContainer, simulation, this, "trxeb1120");
}
/* Not visualized: Compile Contiki immediately */
if (getIdentifier() == null) {
throw new MoteTypeCreationException("No identifier");
}
final MessageList compilationOutput = new MessageList();
if (getCompileCommands() != null) {
/* Handle multiple compilation commands one by one */
String[] arr = getCompileCommands().split("\n");
for (String cmd: arr) {
if (cmd.trim().isEmpty()) {
continue;
}
try {
CompileContiki.compile(
cmd,
null,
null /* Do not observe output firmware file */,
getContikiSourceFile().getParentFile(),
null,
null,
compilationOutput,
true
);
} catch (Exception e) {
MoteTypeCreationException newException =
new MoteTypeCreationException("Mote type creation failed: " + e.getMessage());
newException = (MoteTypeCreationException) newException.initCause(e);
newException.setCompilationOutput(compilationOutput);
/* Print last 10 compilation errors to console */
MessageContainer[] messages = compilationOutput.getMessages();
for (int i=messages.length-10; i < messages.length; i++) {
if (i < 0) {
continue;
}
logger.fatal(">> " + messages[i]);
}
logger.fatal("Compilation error: " + e.getMessage());
throw newException;
}
}
}
if (getContikiFirmwareFile() == null ||
!getContikiFirmwareFile().exists()) {
throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile());
}
return true;
}
public Class<? extends MoteInterface>[] getDefaultMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
CC1120Radio.class,
UsciA1Serial.class,
TrxebLEDs.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public Class<? extends MoteInterface>[] getAllMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
Msp802154Radio.class,
CC1120Radio.class,
UsciA1Serial.class,
TrxebLEDs.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public File getExpectedFirmwareFile(File source) {
File parentDir = source.getParentFile();
String sourceNoExtension = source.getName().substring(0, source.getName().length()-2);
return new File(parentDir, sourceNoExtension + ".trxeb1120");
}
protected String getTargetName() {
return "trxeb1120";
}
}

View File

@ -0,0 +1,26 @@
package com.thingsquare.cooja.mspsim;
import java.io.File;
import se.sics.cooja.Simulation;
import se.sics.cooja.mspmote.Exp5438Mote;
import se.sics.cooja.mspmote.MspMoteType;
/**
* @author Fredrik Osterlind
*/
public class Trxeb2520Mote extends Exp5438Mote {
private String desc = "";
public Trxeb2520Mote(MspMoteType moteType, Simulation sim) {
super(moteType, sim);
}
protected boolean initEmulator(File fileELF) {
return super.initEmulator(fileELF);
}
public String toString() {
return desc + " " + getID();
}
}

View File

@ -0,0 +1,170 @@
package com.thingsquare.cooja.mspsim;
import java.awt.Container;
import java.io.File;
import org.apache.log4j.Logger;
import se.sics.cooja.AbstractionLevelDescription;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.MoteInterface;
import se.sics.cooja.MoteType;
import se.sics.cooja.Simulation;
import se.sics.cooja.dialogs.CompileContiki;
import se.sics.cooja.dialogs.MessageList;
import se.sics.cooja.dialogs.MessageList.MessageContainer;
import se.sics.cooja.interfaces.IPAddress;
import se.sics.cooja.interfaces.Mote2MoteRelations;
import se.sics.cooja.interfaces.MoteAttributes;
import se.sics.cooja.interfaces.Position;
import se.sics.cooja.interfaces.RimeAddress;
import se.sics.cooja.mspmote.Exp5438MoteType;
import se.sics.cooja.mspmote.MspCompileDialog;
import se.sics.cooja.mspmote.interfaces.Exp5438LED;
import se.sics.cooja.mspmote.interfaces.Msp802154Radio;
import se.sics.cooja.mspmote.interfaces.MspClock;
import se.sics.cooja.mspmote.interfaces.MspDebugOutput;
import se.sics.cooja.mspmote.interfaces.MspMoteID;
import se.sics.cooja.mspmote.interfaces.UsciA1Serial;
@ClassDescription("Trxeb2520")
@AbstractionLevelDescription("Emulated level")
public class Trxeb2520MoteType extends Exp5438MoteType {
private static Logger logger = Logger.getLogger(Trxeb2520MoteType.class);
public boolean configureAndInit(Container parentContainer, Simulation simulation, boolean visAvailable)
throws MoteTypeCreationException {
/* If visualized, show compile dialog and let user configure */
if (visAvailable) {
/* Create unique identifier */
if (getIdentifier() == null) {
int counter = 0;
boolean identifierOK = false;
while (!identifierOK) {
identifierOK = true;
counter++;
setIdentifier("trxeb2520#" + counter);
for (MoteType existingMoteType : simulation.getMoteTypes()) {
if (existingMoteType == this) {
continue;
}
if (existingMoteType.getIdentifier().equals(getIdentifier())) {
identifierOK = false;
break;
}
}
}
}
/* Create initial description */
if (getDescription() == null) {
setDescription("Trxeb2520 Mote Type " + getIdentifier());
}
return MspCompileDialog.showDialog(parentContainer, simulation, this, "trxeb2520");
}
/* Not visualized: Compile Contiki immediately */
if (getIdentifier() == null) {
throw new MoteTypeCreationException("No identifier");
}
final MessageList compilationOutput = new MessageList();
if (getCompileCommands() != null) {
/* Handle multiple compilation commands one by one */
String[] arr = getCompileCommands().split("\n");
for (String cmd: arr) {
if (cmd.trim().isEmpty()) {
continue;
}
try {
CompileContiki.compile(
cmd,
null,
null /* Do not observe output firmware file */,
getContikiSourceFile().getParentFile(),
null,
null,
compilationOutput,
true
);
} catch (Exception e) {
MoteTypeCreationException newException =
new MoteTypeCreationException("Mote type creation failed: " + e.getMessage());
newException = (MoteTypeCreationException) newException.initCause(e);
newException.setCompilationOutput(compilationOutput);
/* Print last 10 compilation errors to console */
MessageContainer[] messages = compilationOutput.getMessages();
for (int i=messages.length-10; i < messages.length; i++) {
if (i < 0) {
continue;
}
logger.fatal(">> " + messages[i]);
}
logger.fatal("Compilation error: " + e.getMessage());
throw newException;
}
}
}
if (getContikiFirmwareFile() == null ||
!getContikiFirmwareFile().exists()) {
throw new MoteTypeCreationException("Contiki firmware file does not exist: " + getContikiFirmwareFile());
}
return true;
}
public Class<? extends MoteInterface>[] getDefaultMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
CC2520Radio.class,
UsciA1Serial.class,
TrxebLEDs.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public Class<? extends MoteInterface>[] getAllMoteInterfaceClasses() {
return new Class[] {
Position.class,
RimeAddress.class,
IPAddress.class,
Mote2MoteRelations.class,
MoteAttributes.class,
MspClock.class,
MspMoteID.class,
Msp802154Radio.class,
CC2520Radio.class,
UsciA1Serial.class,
TrxebLEDs.class,
/*Exp5438LCD.class,*/ /* TODO */
MspDebugOutput.class
};
}
public File getExpectedFirmwareFile(File source) {
File parentDir = source.getParentFile();
String sourceNoExtension = source.getName().substring(0, source.getName().length()-2);
return new File(parentDir, sourceNoExtension + ".trxeb2520");
}
protected String getTargetName() {
return "trxeb2520";
}
}

View File

@ -0,0 +1,174 @@
package com.thingsquare.cooja.mspsim;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Collection;
import java.util.Observable;
import java.util.Observer;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import org.jdom.Element;
import se.sics.cooja.ClassDescription;
import se.sics.cooja.Mote;
import se.sics.cooja.interfaces.LED;
import se.sics.cooja.mspmote.Exp5438Mote;
import se.sics.mspsim.core.IOPort;
import se.sics.mspsim.core.IOUnit;
import se.sics.mspsim.core.PortListener;
/**
* @author Fredrik Osterlind
*/
@ClassDescription("Trxeb LEDs")
public class TrxebLEDs extends LED {
private static Logger logger = Logger.getLogger(TrxebLEDs.class);
private Exp5438Mote mspMote;
private boolean redOn = false;
private boolean yellowOn = false;
private boolean greenOn = false;
private boolean blueOn = false;
private static final Color RED = new Color(255, 0, 0);
private static final Color DARK_RED = new Color(100, 0, 0);
private static final Color YELLOW = new Color(255, 255, 0);
private static final Color DARK_YELLOW = new Color(184,134,11);
private static final Color GREEN = new Color(0, 255, 0);
private static final Color DARK_GREEN = new Color(0, 100, 0);
private static final Color BLUE = new Color(0, 0, 255);
private static final Color DARK_BLUE = new Color(0, 0, 100);
public TrxebLEDs(Mote mote) {
mspMote = (Exp5438Mote) mote;
IOUnit unit = mspMote.getCPU().getIOUnit("P4");
if (unit instanceof IOPort) {
((IOPort) unit).addPortListener(new PortListener() {
public void portWrite(IOPort source, int data) {
redOn = (data & (1<<0)) == 0;
yellowOn = (data & (1<<1)) == 0;
greenOn = (data & (1<<2)) == 0;
blueOn = (data & (1<<3)) == 0;
setChanged();
notifyObservers();
}
});
}
}
public boolean isAnyOn() {
return redOn || yellowOn || greenOn || blueOn;
}
public boolean isGreenOn() {
return greenOn;
}
public boolean isRedOn() {
return redOn;
}
public boolean isYellowOn() {
return yellowOn;
}
public boolean isBlueOn() {
return blueOn;
}
public JPanel getInterfaceVisualizer() {
final JPanel panel = new JPanel() {
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 20;
int y = 25;
int d = 25;
if (isRedOn()) {
g.setColor(RED);
g.fillOval(x, y, d, d);
g.setColor(Color.BLACK);
g.drawOval(x, y, d, d);
} else {
g.setColor(DARK_RED);
g.fillOval(x + 5, y + 5, d-10, d-10);
}
x += 40;
if (isYellowOn()) {
g.setColor(YELLOW);
g.fillOval(x, y, d, d);
g.setColor(Color.BLACK);
g.drawOval(x, y, d, d);
} else {
g.setColor(DARK_YELLOW);
g.fillOval(x + 5, y + 5, d-10, d-10);
}
x += 40;
if (isGreenOn()) {
g.setColor(GREEN);
g.fillOval(x, y, d, d);
g.setColor(Color.BLACK);
g.drawOval(x, y, d, d);
} else {
g.setColor(DARK_GREEN);
g.fillOval(x + 5, y + 5, d-10, d-10);
}
x += 40;
if (isBlueOn()) {
g.setColor(BLUE);
g.fillOval(x, y, d, d);
g.setColor(Color.BLACK);
g.drawOval(x, y, d, d);
} else {
g.setColor(DARK_BLUE);
g.fillOval(x + 5, y + 5, d-10, d-10);
}
}
};
Observer observer;
this.addObserver(observer = new Observer() {
public void update(Observable obs, Object obj) {
panel.repaint();
}
});
// Saving observer reference for releaseInterfaceVisualizer
panel.putClientProperty("intf_obs", observer);
panel.setMinimumSize(new Dimension(140, 60));
panel.setPreferredSize(new Dimension(140, 60));
return panel;
}
public void releaseInterfaceVisualizer(JPanel panel) {
Observer observer = (Observer) panel.getClientProperty("intf_obs");
if (observer == null) {
logger.fatal("Error when releasing panel, observer is null");
return;
}
this.deleteObserver(observer);
}
public Collection<Element> getConfigXML() {
return null;
}
public void setConfigXML(Collection<Element> configXML, boolean visAvailable) {
}
}