Merge pull request #1056 from tim-ist/packet_sync

[Cooja/cc2420] Check the frame preamble and MPDU length before parsing an outgoing packet
This commit is contained in:
Fredrik Österlind 2015-09-07 14:36:15 +02:00
commit dde83500c9
4 changed files with 55 additions and 51 deletions

View file

@ -165,7 +165,7 @@ public class CC2420RadioPacketConverter {
} }
/* 1 byte length */ /* 1 byte length */
len = data[pos]; len = data[pos] & 0xFF;
originalLen = len; originalLen = len;
pos += 1; pos += 1;
@ -198,7 +198,7 @@ public class CC2420RadioPacketConverter {
System.arraycopy(data, 6 /* skipping preamble+synch+len */, originalData, 0, originalLen); System.arraycopy(data, 6 /* skipping preamble+synch+len */, originalData, 0, originalLen);
if (len < 0) { if (len < 0) {
/*logger.warn("No cross-level conversion available: negative packet length");*/ /*logger.warn("No cross-level conversion available: negative packet length");*/
return new ConvertedRadioPacket(new byte[0], originalData); return null;
} }
byte convertedData[] = new byte[len]; byte convertedData[] = new byte[len];
System.arraycopy(data, pos, convertedData, 0, len); System.arraycopy(data, pos, convertedData, 0, len);

View file

@ -75,6 +75,7 @@ public class Msp802154Radio extends Radio implements CustomDataRadio {
private boolean isInterfered = false; private boolean isInterfered = false;
private boolean isTransmitting = false; private boolean isTransmitting = false;
private boolean isReceiving = false; private boolean isReceiving = false;
private boolean isSynchronized = false;
private byte lastOutgoingByte; private byte lastOutgoingByte;
private byte lastIncomingByte; private byte lastIncomingByte;
@ -91,22 +92,20 @@ public class Msp802154Radio extends Radio implements CustomDataRadio {
radio.addRFListener(new RFListener() { radio.addRFListener(new RFListener() {
int len = 0; int len = 0;
int expLen = 0; int expMpduLen = 0;
byte[] buffer = new byte[127 + 15]; byte[] buffer = new byte[127 + 6];
final private byte[] syncSeq = {0,0,0,0,0x7A};
public void receivedByte(byte data) { public void receivedByte(byte data) {
if (!isTransmitting()) { if (!isTransmitting()) {
lastEvent = RadioEvent.TRANSMISSION_STARTED; lastEvent = RadioEvent.TRANSMISSION_STARTED;
lastOutgoingPacket = null;
isTransmitting = true; isTransmitting = true;
len = 0; len = 0;
/*logger.debug("----- 802.15.4 TRANSMISSION STARTED -----");*/ expMpduLen = 0;
setChanged(); setChanged();
notifyObservers(); notifyObservers();
} /*logger.debug("----- 802.15.4 TRANSMISSION STARTED -----");*/
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 */ /* send this byte to all nodes */
@ -115,31 +114,42 @@ public class Msp802154Radio extends Radio implements CustomDataRadio {
setChanged(); setChanged();
notifyObservers(); notifyObservers();
buffer[len++] = data; if (len < buffer.length)
buffer[len] = data;
if (len == 6) { len ++;
if (len == 5) {
isSynchronized = true;
for (int i=0; i<5; i++) {
if (buffer[i] != syncSeq[i]) {
// this should never happen, but it happens
logger.error(String.format("Bad outgoing sync sequence %x %x %x %x %x", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4]));
isSynchronized = false;
break;
}
}
}
else if (len == 6) {
// System.out.println("## CC2420 Packet of length: " + data + " expected..."); // System.out.println("## CC2420 Packet of length: " + data + " expected...");
expLen = data + 6; expMpduLen = data & 0xFF;
if ((expMpduLen & 0x80) != 0) {
logger.error("Outgoing length field is larger than 127: " + expMpduLen);
}
} }
if (len == expLen) { if (((expMpduLen & 0x80) == 0) && len == expMpduLen + 6 && isSynchronized) {
/*logger.debug("----- 802.15.4 CUSTOM DATA TRANSMITTED -----");*/
lastOutgoingPacket = CC2420RadioPacketConverter.fromCC2420ToCooja(buffer); lastOutgoingPacket = CC2420RadioPacketConverter.fromCC2420ToCooja(buffer);
if (lastOutgoingPacket != null) {
lastEvent = RadioEvent.PACKET_TRANSMITTED; lastEvent = RadioEvent.PACKET_TRANSMITTED;
/*logger.debug("----- 802.15.4 PACKET TRANSMITTED -----");*/ //logger.debug("----- 802.15.4 PACKET TRANSMITTED -----");
setChanged(); setChanged();
notifyObservers(); notifyObservers();
}
/*logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----");*/ finishTransmission();
isTransmitting = false;
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
setChanged();
notifyObservers();
len = 0;
} }
} }
}); }); /* addRFListener */
radio.addOperatingModeListener(new OperatingModeListener() { radio.addOperatingModeListener(new OperatingModeListener() {
public void modeChanged(Chip source, int mode) { public void modeChanged(Chip source, int mode) {
@ -148,7 +158,7 @@ public class Msp802154Radio extends Radio implements CustomDataRadio {
setChanged(); setChanged();
notifyObservers(); notifyObservers();
} else { } else {
radioOff(); radioOff(); // actually it is a state change, not necessarily to OFF
} }
} }
}); });
@ -163,32 +173,23 @@ public class Msp802154Radio extends Radio implements CustomDataRadio {
}); });
} }
private void radioOff() {
/* Radio was turned off during transmission. private void finishTransmission()
* May for example happen if watchdog triggers */ {
if (isTransmitting()) { if (isTransmitting()) {
logger.warn("Turning off radio while transmitting, ending packet prematurely"); //logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----");
/* Simulate end of packet */
lastOutgoingPacket = new RadioPacket() {
public byte[] getPacketData() {
return new byte[0];
}
};
lastEvent = RadioEvent.PACKET_TRANSMITTED;
/*logger.debug("----- 802.15.4 PACKET TRANSMITTED -----");*/
setChanged();
notifyObservers();
/* Register that transmission ended in radio medium */
/*logger.debug("----- 802.15.4 TRANSMISSION FINISHED -----");*/
isTransmitting = false; isTransmitting = false;
isSynchronized = false;
lastEvent = RadioEvent.TRANSMISSION_FINISHED; lastEvent = RadioEvent.TRANSMISSION_FINISHED;
setChanged(); setChanged();
notifyObservers(); notifyObservers();
} }
}
private void radioOff() {
if (isSynchronized)
logger.warn("Turning off radio while transmitting a packet");
finishTransmission();
lastEvent = RadioEvent.HW_OFF; lastEvent = RadioEvent.HW_OFF;
setChanged(); setChanged();
notifyObservers(); notifyObservers();

View file

@ -76,6 +76,7 @@ public abstract class AbstractApplicationMote extends AbstractWakeupMote impleme
if (radio.getLastPacketReceived() != null) if (radio.getLastPacketReceived() != null)
receivedPacket(radio.getLastPacketReceived()); receivedPacket(radio.getLastPacketReceived());
} else if (radio.getLastEvent() == Radio.RadioEvent.TRANSMISSION_FINISHED) { } else if (radio.getLastEvent() == Radio.RadioEvent.TRANSMISSION_FINISHED) {
if (radio.getLastPacketTransmitted() != null)
sentPacket(radio.getLastPacketTransmitted()); sentPacket(radio.getLastPacketTransmitted());
} }
} }

View file

@ -517,10 +517,12 @@ public class RadioLogger extends VisPlugin {
return; return;
} }
final RadioConnectionLog loggedConn = new RadioConnectionLog(); final RadioConnectionLog loggedConn = new RadioConnectionLog();
loggedConn.packet = conn.getSource().getLastPacketTransmitted();
if (loggedConn.packet == null)
return;
loggedConn.startTime = conn.getStartTime(); loggedConn.startTime = conn.getStartTime();
loggedConn.endTime = simulation.getSimulationTime(); loggedConn.endTime = simulation.getSimulationTime();
loggedConn.connection = conn; loggedConn.connection = conn;
loggedConn.packet = conn.getSource().getLastPacketTransmitted();
java.awt.EventQueue.invokeLater(new Runnable() { java.awt.EventQueue.invokeLater(new Runnable() {
@Override @Override
public void run() { public void run() {