Better handling of cross-level radio packet. Minor code cleanup.
This commit is contained in:
parent
e207f89307
commit
01502926d0
2 changed files with 22 additions and 84 deletions
|
@ -26,7 +26,7 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: TR1001Radio.java,v 1.16 2009/12/02 16:39:42 fros4943 Exp $
|
* $Id: TR1001Radio.java,v 1.17 2010/02/03 13:47:33 nifi Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
package se.sics.cooja.mspmote.interfaces;
|
||||||
|
@ -57,7 +57,7 @@ import se.sics.cooja.TimeEvent;
|
||||||
import se.sics.cooja.interfaces.CustomDataRadio;
|
import se.sics.cooja.interfaces.CustomDataRadio;
|
||||||
import se.sics.cooja.interfaces.Position;
|
import se.sics.cooja.interfaces.Position;
|
||||||
import se.sics.cooja.interfaces.Radio;
|
import se.sics.cooja.interfaces.Radio;
|
||||||
import se.sics.cooja.mspmote.ESBMote;
|
import se.sics.cooja.mspmote.MspMote;
|
||||||
import se.sics.mspsim.core.IOUnit;
|
import se.sics.mspsim.core.IOUnit;
|
||||||
import se.sics.mspsim.core.USART;
|
import se.sics.mspsim.core.USART;
|
||||||
import se.sics.mspsim.core.USARTListener;
|
import se.sics.mspsim.core.USARTListener;
|
||||||
|
@ -79,7 +79,10 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
*/
|
*/
|
||||||
public static final long DELAY_BETWEEN_BYTES = 416;
|
public static final long DELAY_BETWEEN_BYTES = 416;
|
||||||
|
|
||||||
private ESBMote mote;
|
/* The data used when transmission is interfered */
|
||||||
|
private static final Byte CORRUPTED_DATA = (byte) 0xff;
|
||||||
|
|
||||||
|
private MspMote mote;
|
||||||
|
|
||||||
private boolean isTransmitting = false;
|
private boolean isTransmitting = false;
|
||||||
private boolean isReceiving = false;
|
private boolean isReceiving = false;
|
||||||
|
@ -107,7 +110,7 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
* @param mote Mote
|
* @param mote Mote
|
||||||
*/
|
*/
|
||||||
public TR1001Radio(Mote mote) {
|
public TR1001Radio(Mote mote) {
|
||||||
this.mote = (ESBMote) mote;
|
this.mote = (MspMote) mote;
|
||||||
|
|
||||||
/* Start listening to CPU's USART */
|
/* Start listening to CPU's USART */
|
||||||
IOUnit usart = this.mote.getCPU().getIOUnit("USART 0");
|
IOUnit usart = this.mote.getCPU().getIOUnit("USART 0");
|
||||||
|
@ -174,19 +177,16 @@ public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio
|
||||||
logger.fatal("Received bad custom data: " + data);
|
logger.fatal("Received bad custom data: " + data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
receivedByte = (Byte) data;
|
|
||||||
|
|
||||||
mote.requestImmediateWakeup();
|
receivedByte = isInterfered ? CORRUPTED_DATA : (Byte) data;
|
||||||
|
|
||||||
if (radioUSART.isReceiveFlagCleared()) {
|
if (radioUSART.isReceiveFlagCleared()) {
|
||||||
/*logger.info("----- TR1001 RECEIVED BYTE -----");*/
|
/*logger.info("----- TR1001 RECEIVED BYTE -----");*/
|
||||||
if (isInterfered) {
|
radioUSART.byteReceived(receivedByte);
|
||||||
radioUSART.byteReceived(0xFF); /* Corrupted data */
|
|
||||||
} else {
|
|
||||||
radioUSART.byteReceived(receivedByte);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
logger.warn(mote.getSimulation().getSimulationTime() + ": ----- TR1001 RECEIVED BYTE DROPPED -----");
|
logger.warn(mote.getSimulation().getSimulationTime() + ": ----- TR1001 RECEIVED BYTE DROPPED -----");
|
||||||
}
|
}
|
||||||
|
mote.requestImmediateWakeup();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USART listener support */
|
/* USART listener support */
|
||||||
|
|
|
@ -26,16 +26,13 @@
|
||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: TR1001RadioPacketConverter.java,v 1.5 2009/12/02 16:39:42 fros4943 Exp $
|
* $Id: TR1001RadioPacketConverter.java,v 1.6 2010/02/03 13:47:33 nifi Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
package se.sics.cooja.mspmote.interfaces;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.io.ByteArrayOutputStream;
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import se.sics.cooja.COOJARadioPacket;
|
import se.sics.cooja.COOJARadioPacket;
|
||||||
import se.sics.cooja.ConvertedRadioPacket;
|
|
||||||
import se.sics.cooja.RadioPacket;
|
import se.sics.cooja.RadioPacket;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +42,6 @@ import se.sics.cooja.RadioPacket;
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
public class TR1001RadioPacketConverter {
|
public class TR1001RadioPacketConverter {
|
||||||
private static Logger logger = Logger.getLogger(TR1001RadioPacketConverter.class);
|
|
||||||
|
|
||||||
private static GCRCoder gcrCoder = new GCRCoder();
|
private static GCRCoder gcrCoder = new GCRCoder();
|
||||||
|
|
||||||
|
@ -68,7 +64,7 @@ public class TR1001RadioPacketConverter {
|
||||||
|
|
||||||
final static int ESB_FOOTER_LENGTH = 2;
|
final static int ESB_FOOTER_LENGTH = 2;
|
||||||
|
|
||||||
private ArrayList<Byte> originalData = new ArrayList<Byte>();
|
private ByteArrayOutputStream originalData = new ByteArrayOutputStream();
|
||||||
|
|
||||||
private enum AccumulatedConversionState {
|
private enum AccumulatedConversionState {
|
||||||
TR1001_PREAMBLE, TR1001_SYNCH, ESB_LEN1, ESB_LEN2, ESB_DATA, ESB_CRC1, ESB_CRC2, ESB_POST,
|
TR1001_PREAMBLE, TR1001_SYNCH, ESB_LEN1, ESB_LEN2, ESB_DATA, ESB_CRC1, ESB_CRC2, ESB_POST,
|
||||||
|
@ -141,59 +137,7 @@ public class TR1001RadioPacketConverter {
|
||||||
tr1001Frame[TR1001_HEADER_LENGTH + encodedData.length + 2] = (byte) 0x33;
|
tr1001Frame[TR1001_HEADER_LENGTH + encodedData.length + 2] = (byte) 0x33;
|
||||||
tr1001Frame[TR1001_HEADER_LENGTH + encodedData.length + 3] = (byte) 0xcc;
|
tr1001Frame[TR1001_HEADER_LENGTH + encodedData.length + 3] = (byte) 0xcc;
|
||||||
|
|
||||||
byte[] tr1001Bytes = new byte[tr1001Frame.length];
|
return tr1001Frame;
|
||||||
System.arraycopy(tr1001Frame, 0, tr1001Bytes, 0, tr1001Frame.length);
|
|
||||||
return tr1001Bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts radio packet data from TR1001 to COOJA. This
|
|
||||||
* implementation is ESB platform and TR1001 driver specific.
|
|
||||||
*
|
|
||||||
* It consists of (in sequential order):
|
|
||||||
* - Removing TR1001 header and footer
|
|
||||||
* - GCR decode data
|
|
||||||
* - Read length header
|
|
||||||
* - Remove both length header and CRC footer
|
|
||||||
*
|
|
||||||
* @param tr1001xxBytes TR1001 bytes
|
|
||||||
* @param tr1001DataLength TR1001 specified packet length
|
|
||||||
* @return COOJA radio packet
|
|
||||||
*/
|
|
||||||
public static ConvertedRadioPacket fromTR1001ToCooja(byte[] data, int tr1001DataLength) {
|
|
||||||
|
|
||||||
/* Remove TR1001 specifics: preamble, synch and trail bytes */
|
|
||||||
tr1001DataLength -= (TR1001_HEADER_LENGTH + TR1001_FOOTER_LENGTH);
|
|
||||||
System.arraycopy(
|
|
||||||
data, TR1001_HEADER_LENGTH,
|
|
||||||
data, 0,
|
|
||||||
tr1001DataLength
|
|
||||||
);
|
|
||||||
|
|
||||||
/* GCR decode */
|
|
||||||
byte[] decodedData = gcrCoder.gcrDecode(data, tr1001DataLength);
|
|
||||||
|
|
||||||
if (decodedData != null) {
|
|
||||||
/* Decoding succeded, fetch length from the two first bytes */
|
|
||||||
int dataLength = ((decodedData[0] & 0xff) << 8) + (decodedData[1] & 0xff);
|
|
||||||
|
|
||||||
if (dataLength + ESB_HEADER_LENGTH + ESB_HEADER_LENGTH > decodedData.length) {
|
|
||||||
logger.fatal("Decoded data is smaller than specified data length: "
|
|
||||||
+ (dataLength + ESB_HEADER_LENGTH + ESB_HEADER_LENGTH) + " vs "
|
|
||||||
+ decodedData.length);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove ESB header and CRC footer */
|
|
||||||
byte[] packetData = new byte[dataLength];
|
|
||||||
System.arraycopy(decodedData, ESB_HEADER_LENGTH, packetData, 0,
|
|
||||||
dataLength);
|
|
||||||
|
|
||||||
return new ConvertedRadioPacket(packetData, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.warn("No cross-level conversion available: TR1001 GCR decoding failed");
|
|
||||||
return new ConvertedRadioPacket(new byte[0], data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -237,8 +181,8 @@ public class TR1001RadioPacketConverter {
|
||||||
* @return True if conversion finished (either successful of failed)
|
* @return True if conversion finished (either successful of failed)
|
||||||
*/
|
*/
|
||||||
public boolean fromTR1001ToCoojaAccumulated(byte b) {
|
public boolean fromTR1001ToCoojaAccumulated(byte b) {
|
||||||
originalData.add(b);
|
originalData.write(b);
|
||||||
|
|
||||||
if (accumulatedConversionState == AccumulatedConversionState.TR1001_PREAMBLE) {
|
if (accumulatedConversionState == AccumulatedConversionState.TR1001_PREAMBLE) {
|
||||||
if (b == (byte) 0xaa || b == (byte) 0xff) {
|
if (b == (byte) 0xaa || b == (byte) 0xff) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -270,8 +214,8 @@ public class TR1001RadioPacketConverter {
|
||||||
AccumulatedConversionGCRCoder.gcr_decode(0xff & b);
|
AccumulatedConversionGCRCoder.gcr_decode(0xff & b);
|
||||||
if (AccumulatedConversionGCRCoder.gcr_get_decoded(accumulatedConversionDataLengthArray, 1)) {
|
if (AccumulatedConversionGCRCoder.gcr_get_decoded(accumulatedConversionDataLengthArray, 1)) {
|
||||||
accumulatedConversionState = AccumulatedConversionState.ESB_DATA;
|
accumulatedConversionState = AccumulatedConversionState.ESB_DATA;
|
||||||
accumulatedConversionDataLength = (accumulatedConversionDataLengthArray[0] & 0xff) << 8;
|
accumulatedConversionDataLength = ((accumulatedConversionDataLengthArray[0] & 0xff) << 8) +
|
||||||
accumulatedConversionDataLength = (accumulatedConversionDataLengthArray[1] & 0xff);
|
(accumulatedConversionDataLengthArray[1] & 0xff);
|
||||||
accumulatedConversionDataArray = new int[accumulatedConversionDataLength];
|
accumulatedConversionDataArray = new int[accumulatedConversionDataLength];
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -298,7 +242,7 @@ public class TR1001RadioPacketConverter {
|
||||||
return false;
|
return false;
|
||||||
} else if (accumulatedConversionState == AccumulatedConversionState.ESB_POST) {
|
} else if (accumulatedConversionState == AccumulatedConversionState.ESB_POST) {
|
||||||
accumulatedConversionFooterLength++;
|
accumulatedConversionFooterLength++;
|
||||||
return accumulatedConversionFooterLength >= 4;
|
return accumulatedConversionFooterLength >= TR1001_FOOTER_LENGTH;
|
||||||
} else {
|
} else {
|
||||||
accumulatedConversionOK = false;
|
accumulatedConversionOK = false;
|
||||||
return true;
|
return true;
|
||||||
|
@ -308,18 +252,12 @@ public class TR1001RadioPacketConverter {
|
||||||
/**
|
/**
|
||||||
* @return Converted data (application level)
|
* @return Converted data (application level)
|
||||||
*/
|
*/
|
||||||
public ConvertedRadioPacket getAccumulatedConvertedCoojaPacket() {
|
public RadioPacket getAccumulatedConvertedCoojaPacket() {
|
||||||
byte[] dataArrayByte = new byte[accumulatedConversionDataArray.length];
|
byte[] dataArrayByte = new byte[accumulatedConversionDataArray.length];
|
||||||
for (int i=0; i < accumulatedConversionDataArray.length; i++) {
|
for (int i=0; i < accumulatedConversionDataArray.length; i++) {
|
||||||
dataArrayByte[i] = (byte) accumulatedConversionDataArray[i];
|
dataArrayByte[i] = (byte) accumulatedConversionDataArray[i];
|
||||||
}
|
}
|
||||||
|
return new COOJARadioPacket(dataArrayByte);
|
||||||
byte[] originalArr = new byte[originalData.size()];
|
|
||||||
for (int i=0; i < originalArr.length; i++) {
|
|
||||||
originalArr[i] = originalData.get(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new ConvertedRadioPacket(dataArrayByte, originalArr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue