requesting mote wakeup when receiving radio data + code cleanup (faster code)
This commit is contained in:
parent
51f210b37f
commit
36d09eaa69
|
@ -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.15 2009/10/28 15:58:43 fros4943 Exp $
|
* $Id: TR1001Radio.java,v 1.16 2009/12/02 16:39:42 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
package se.sics.cooja.mspmote.interfaces;
|
||||||
|
@ -47,6 +47,7 @@ import javax.swing.JPanel;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.jdom.Element;
|
import org.jdom.Element;
|
||||||
|
|
||||||
|
import se.sics.cooja.COOJARadioPacket;
|
||||||
import se.sics.cooja.ClassDescription;
|
import se.sics.cooja.ClassDescription;
|
||||||
import se.sics.cooja.Mote;
|
import se.sics.cooja.Mote;
|
||||||
import se.sics.cooja.MoteTimeEvent;
|
import se.sics.cooja.MoteTimeEvent;
|
||||||
|
@ -62,109 +63,96 @@ import se.sics.mspsim.core.USART;
|
||||||
import se.sics.mspsim.core.USARTListener;
|
import se.sics.mspsim.core.USARTListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TR1001 radio interface on ESB platform. Assumes driver specifics such as
|
* TR1001 radio interface on ESB platform.
|
||||||
* preambles, synchbytes, GCR coding, CRC16.
|
* Assumes Contiki driver specifics such as preambles, synchbytes, GCR coding, CRC16.
|
||||||
*
|
*
|
||||||
* @author Fredrik Osterlind
|
* @author Fredrik Osterlind
|
||||||
*/
|
*/
|
||||||
@ClassDescription("TR1001 Radio")
|
@ClassDescription("TR1001 Radio")
|
||||||
public class TR1001Radio extends Radio implements USARTListener,
|
public class TR1001Radio extends Radio implements USARTListener, CustomDataRadio {
|
||||||
CustomDataRadio {
|
|
||||||
private static Logger logger = Logger.getLogger(TR1001Radio.class);
|
private static Logger logger = Logger.getLogger(TR1001Radio.class);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delay used when feeding packet data to radio chip (us). 416us corresponds
|
* Cross-level:
|
||||||
* to 19200 bit/s with encoding.
|
* Delay used when feeding packet data to radio chip (us).
|
||||||
|
* 416us corresponds to 19200 bit/s with encoding.
|
||||||
*/
|
*/
|
||||||
public static final long DELAY_BETWEEN_BYTES = 3 * 416;
|
public static final long DELAY_BETWEEN_BYTES = 416;
|
||||||
|
|
||||||
private ESBMote mote;
|
private ESBMote mote;
|
||||||
|
|
||||||
private boolean radioOn = true;
|
|
||||||
|
|
||||||
private boolean isTransmitting = false;
|
private boolean isTransmitting = false;
|
||||||
|
|
||||||
private boolean isReceiving = false;
|
private boolean isReceiving = false;
|
||||||
|
|
||||||
private boolean isInterfered = false;
|
private boolean isInterfered = false;
|
||||||
|
|
||||||
private RadioEvent lastEvent = RadioEvent.UNKNOWN;
|
private RadioEvent lastEvent = RadioEvent.UNKNOWN;
|
||||||
|
|
||||||
private long lastEventTime = 0;
|
private long lastEventTime = 0;
|
||||||
|
|
||||||
private USART radioUSART = null;
|
private USART radioUSART = null;
|
||||||
|
|
||||||
private RadioPacket lastIncomingPacket = null;
|
private RadioPacket receivedPacket = null;
|
||||||
|
private RadioPacket sentPacket = null;
|
||||||
|
|
||||||
private RadioPacket packetFromMote = null;
|
private byte receivedByte, sentByte;
|
||||||
|
|
||||||
/* Outgoing packet data buffer */
|
|
||||||
private TR1001RadioByte[] outgoingData = new TR1001RadioByte[128]; /* TODO Adaptive max size */
|
|
||||||
|
|
||||||
private int outgoingDataLength = 0;
|
|
||||||
|
|
||||||
private int millisSinceLastSend = -1;
|
|
||||||
|
|
||||||
/* Outgoing byte data buffer */
|
|
||||||
private TR1001RadioByte tr1001ByteFromMote = null;
|
|
||||||
|
|
||||||
private TR1001RadioByte lastIncomingByte = null;
|
|
||||||
|
|
||||||
private long transmissionStartCycles = -1;
|
|
||||||
|
|
||||||
private TR1001RadioPacketConverter tr1001PacketConverter = null;
|
private TR1001RadioPacketConverter tr1001PacketConverter = null;
|
||||||
|
|
||||||
private double signalStrength = 0;
|
private boolean radioOn = true; /* TODO MSPSim: Not implemented */
|
||||||
|
private double signalStrength = 0; /* TODO MSPSim: Not implemented */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an interface to the TR1001 radio at mote.
|
* Creates an interface to the TR1001 radio at mote.
|
||||||
*
|
*
|
||||||
* @param mote
|
* @param mote Mote
|
||||||
* Radio's mote.
|
|
||||||
* @see Mote
|
|
||||||
* @see se.sics.cooja.MoteInterfaceHandler
|
|
||||||
*/
|
*/
|
||||||
public TR1001Radio(Mote mote) {
|
public TR1001Radio(Mote mote) {
|
||||||
this.mote = (ESBMote) mote;
|
this.mote = (ESBMote) 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");
|
||||||
if (usart instanceof USART) {
|
if (usart != null && usart instanceof USART) {
|
||||||
radioUSART = (USART) usart;
|
radioUSART = (USART) usart;
|
||||||
radioUSART.setUSARTListener(this);
|
radioUSART.setUSARTListener(this);
|
||||||
|
} else {
|
||||||
|
throw new RuntimeException("Bad TR1001 IO: " + usart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Packet radio support */
|
/* Packet radio support */
|
||||||
public RadioPacket getLastPacketTransmitted() {
|
public RadioPacket getLastPacketTransmitted() {
|
||||||
return packetFromMote;
|
return sentPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RadioPacket getLastPacketReceived() {
|
public RadioPacket getLastPacketReceived() {
|
||||||
return lastIncomingPacket;
|
return receivedPacket;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReceivedPacket(RadioPacket packet) {
|
public void setReceivedPacket(RadioPacket packet) {
|
||||||
lastIncomingPacket = packet;
|
receivedPacket = packet;
|
||||||
|
|
||||||
/* Convert to TR1001 packet data */
|
/* Convert to TR1001 packet data */
|
||||||
TR1001RadioByte[] byteArr = TR1001RadioPacketConverter.fromCoojaToTR1001(packet);
|
byte[] arr = TR1001RadioPacketConverter.fromCoojaToTR1001(packet);
|
||||||
final ArrayDeque<TR1001RadioByte> byteList = new ArrayDeque<TR1001RadioByte>();
|
final ArrayDeque<Byte> data = new ArrayDeque<Byte>();
|
||||||
for (TR1001RadioByte b : byteArr) {
|
for (Byte b : arr) {
|
||||||
byteList.addLast(b);
|
data.addLast(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Feed incoming bytes to radio "slowly" via time events */
|
/* Feed incoming bytes to radio "slowly" via time events */
|
||||||
TimeEvent receiveCrosslevelDataEvent = new MoteTimeEvent(mote, 0) {
|
TimeEvent receiveCrosslevelDataEvent = new MoteTimeEvent(mote, 0) {
|
||||||
public void execute(long t) {
|
public void execute(long t) {
|
||||||
/* Stop receiving data when buffer is empty */
|
/* Stop receiving data when buffer is empty */
|
||||||
if (byteList.isEmpty() || isInterfered) {
|
if (data.isEmpty()) {
|
||||||
byteList.clear();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
TR1001RadioByte b = byteList.pop();
|
byte b = data.pop();
|
||||||
radioUSART.byteReceived(b.getByte());
|
if (isInterfered) {
|
||||||
|
radioUSART.byteReceived(0xFF); /* Corrupted data */
|
||||||
|
} else {
|
||||||
|
radioUSART.byteReceived(b);
|
||||||
|
}
|
||||||
|
mote.requestImmediateWakeup();
|
||||||
|
|
||||||
mote.getSimulation().scheduleEvent(this, t + DELAY_BETWEEN_BYTES);
|
mote.getSimulation().scheduleEvent(this, t + DELAY_BETWEEN_BYTES);
|
||||||
}
|
}
|
||||||
|
@ -174,90 +162,83 @@ public class TR1001Radio extends Radio implements USARTListener,
|
||||||
|
|
||||||
/* Custom data radio support */
|
/* Custom data radio support */
|
||||||
public Object getLastCustomDataTransmitted() {
|
public Object getLastCustomDataTransmitted() {
|
||||||
return tr1001ByteFromMote;
|
return sentByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getLastCustomDataReceived() {
|
public Object getLastCustomDataReceived() {
|
||||||
return lastIncomingByte;
|
return receivedByte;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveCustomData(Object data) {
|
public void receiveCustomData(Object data) {
|
||||||
if (data instanceof TR1001RadioByte) {
|
if (!(data instanceof Byte)) {
|
||||||
lastIncomingByte = ((TR1001RadioByte) data);
|
logger.fatal("Received bad custom data: " + data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receivedByte = (Byte) data;
|
||||||
|
|
||||||
if (radioUSART.isReceiveFlagCleared()) {
|
mote.requestImmediateWakeup();
|
||||||
/*logger.info("----- TR1001 RECEIVED BYTE -----");*/
|
if (radioUSART.isReceiveFlagCleared()) {
|
||||||
radioUSART.byteReceived(lastIncomingByte.getByte());
|
/*logger.info("----- TR1001 RECEIVED BYTE -----");*/
|
||||||
|
if (isInterfered) {
|
||||||
|
radioUSART.byteReceived(0xFF); /* Corrupted data */
|
||||||
} else {
|
} else {
|
||||||
logger.warn("----- TR1001 RECEIVED BYTE DROPPED -----");
|
radioUSART.byteReceived(receivedByte);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn(mote.getSimulation().getSimulationTime() + ": ----- TR1001 RECEIVED BYTE DROPPED -----");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* USART listener support */
|
/* USART listener support */
|
||||||
public void dataReceived(USART source, int data) {
|
public void dataReceived(USART source, int data) {
|
||||||
if (outgoingDataLength == 0 && !isTransmitting()) {
|
if (!isTransmitting()) {
|
||||||
/* New transmission discovered */
|
/* New transmission discovered */
|
||||||
/*logger.info("----- NEW TR1001 TRANSMISSION DETECTED -----");*/
|
/*logger.info("----- NEW TR1001 TRANSMISSION DETECTED -----");*/
|
||||||
tr1001PacketConverter = new TR1001RadioPacketConverter();
|
tr1001PacketConverter = new TR1001RadioPacketConverter();
|
||||||
|
|
||||||
isTransmitting = true;
|
|
||||||
|
|
||||||
transmissionStartCycles = mote.getCPU().cycles;
|
|
||||||
|
|
||||||
lastEvent = RadioEvent.TRANSMISSION_STARTED;
|
lastEvent = RadioEvent.TRANSMISSION_STARTED;
|
||||||
lastEventTime = mote.getSimulation().getSimulationTime();
|
lastEventTime = mote.getSimulation().getSimulationTime();
|
||||||
|
isTransmitting = true;
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
}
|
|
||||||
|
|
||||||
// Remember recent radio activity
|
/* Timeout transmission after some time */
|
||||||
millisSinceLastSend = 0;
|
if (timeoutTransmission.isScheduled()) {
|
||||||
if (!followupTransmissionEvent.isScheduled()) {
|
logger.warn("Timeout TX event already scheduled");
|
||||||
|
timeoutTransmission.remove();
|
||||||
|
}
|
||||||
mote.getSimulation().scheduleEvent(
|
mote.getSimulation().scheduleEvent(
|
||||||
followupTransmissionEvent,
|
timeoutTransmission,
|
||||||
mote.getSimulation().getSimulationTime() + Simulation.MILLISECOND);
|
mote.getSimulation().getSimulationTime() + 40*Simulation.MILLISECOND
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outgoingDataLength >= outgoingData.length) {
|
/* Deliver custom data byte */
|
||||||
logger.warn("----- TR1001 DROPPING OUTGOING BYTE (buffer overflow) -----");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Deliver byte to radio medium as custom data
|
|
||||||
/* logger.debug("----- TR1001 SENT BYTE -----"); */
|
|
||||||
lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED;
|
lastEvent = RadioEvent.CUSTOM_DATA_TRANSMITTED;
|
||||||
tr1001ByteFromMote = new TR1001RadioByte((byte) data);
|
sentByte = (byte) data;
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
|
|
||||||
outgoingData[outgoingDataLength++] = tr1001ByteFromMote;
|
/* Detect full packet */
|
||||||
|
boolean finished = tr1001PacketConverter.fromTR1001ToCoojaAccumulated(sentByte);
|
||||||
// Feed to application level immediately
|
|
||||||
boolean finished = tr1001PacketConverter
|
|
||||||
.fromTR1001ToCoojaAccumulated(tr1001ByteFromMote);
|
|
||||||
if (finished) {
|
if (finished) {
|
||||||
|
timeoutTransmission.remove();
|
||||||
|
|
||||||
/* Transmission finished - deliver packet immediately */
|
/* Transmission finished - deliver packet immediately */
|
||||||
if (tr1001PacketConverter.accumulatedConversionIsOk()) {
|
if (tr1001PacketConverter.accumulatedConversionIsOk()) {
|
||||||
packetFromMote = tr1001PacketConverter.getAccumulatedConvertedCoojaPacket();
|
/* Deliver packet */
|
||||||
|
|
||||||
/* Notify observers of new prepared packet */
|
|
||||||
/* logger.info("----- TR1001 DELIVERED PACKET -----"); */
|
/* logger.info("----- TR1001 DELIVERED PACKET -----"); */
|
||||||
|
sentPacket = tr1001PacketConverter.getAccumulatedConvertedCoojaPacket();
|
||||||
lastEvent = RadioEvent.PACKET_TRANSMITTED;
|
lastEvent = RadioEvent.PACKET_TRANSMITTED;
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset counters and wait for next packet
|
/* Finish transmission */
|
||||||
outgoingDataLength = 0;
|
|
||||||
millisSinceLastSend = -1;
|
|
||||||
|
|
||||||
// Signal we are done transmitting
|
|
||||||
isTransmitting = false;
|
isTransmitting = false;
|
||||||
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
||||||
this.setChanged();
|
TR1001Radio.this.setChanged();
|
||||||
this.notifyObservers();
|
TR1001Radio.this.notifyObservers();
|
||||||
|
|
||||||
/* logger.info("----- TR1001 TRANSMISSION ENDED -----"); */
|
/* logger.info("----- TR1001 TRANSMISSION ENDED -----"); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,12 +260,14 @@ public class TR1001Radio extends Radio implements USARTListener,
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getChannel() {
|
public int getChannel() {
|
||||||
|
/* TODO Implement */
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void signalReceptionStart() {
|
public void signalReceptionStart() {
|
||||||
lastEvent = RadioEvent.RECEPTION_STARTED;
|
lastEvent = RadioEvent.RECEPTION_STARTED;
|
||||||
isReceiving = true;
|
isReceiving = true;
|
||||||
|
isInterfered = false;
|
||||||
this.setChanged();
|
this.setChanged();
|
||||||
this.notifyObservers();
|
this.notifyObservers();
|
||||||
}
|
}
|
||||||
|
@ -304,7 +287,7 @@ public class TR1001Radio extends Radio implements USARTListener,
|
||||||
public void interfereAnyReception() {
|
public void interfereAnyReception() {
|
||||||
if (!isInterfered()) {
|
if (!isInterfered()) {
|
||||||
isInterfered = true;
|
isInterfered = true;
|
||||||
lastIncomingPacket = null;
|
receivedPacket = null;
|
||||||
|
|
||||||
lastEventTime = mote.getSimulation().getSimulationTime();
|
lastEventTime = mote.getSimulation().getSimulationTime();
|
||||||
lastEvent = RadioEvent.RECEPTION_INTERFERED;
|
lastEvent = RadioEvent.RECEPTION_INTERFERED;
|
||||||
|
@ -340,33 +323,25 @@ public class TR1001Radio extends Radio implements USARTListener,
|
||||||
return mote.getInterfaces().getPosition();
|
return mote.getInterfaces().getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimeEvent followupTransmissionEvent = new MoteTimeEvent(mote, 0) {
|
private TimeEvent timeoutTransmission = new MoteTimeEvent(mote, 0) {
|
||||||
public void execute(long t) {
|
public void execute(long t) {
|
||||||
|
if (!isTransmitting()) {
|
||||||
if (isTransmitting()) {
|
/* Nothing to do */
|
||||||
millisSinceLastSend++;
|
return;
|
||||||
|
|
||||||
// Detect transmission end due to inactivity
|
|
||||||
if (millisSinceLastSend > 5) {
|
|
||||||
/* Dropping packet due to inactivity */
|
|
||||||
packetFromMote = null;
|
|
||||||
|
|
||||||
/* Reset counters and wait for next packet */
|
|
||||||
outgoingDataLength = 0;
|
|
||||||
millisSinceLastSend = -1;
|
|
||||||
|
|
||||||
/* Signal we are done transmitting */
|
|
||||||
isTransmitting = false;
|
|
||||||
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
|
||||||
TR1001Radio.this.setChanged();
|
|
||||||
TR1001Radio.this.notifyObservers();
|
|
||||||
|
|
||||||
/*logger.debug("----- NULL TRANSMISSION ENDED -----");*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reschedule as long as node is transmitting */
|
|
||||||
mote.getSimulation().scheduleEvent(this, t + Simulation.MILLISECOND);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.warn("TR1001 transmission timed out, delivering empty packet");
|
||||||
|
|
||||||
|
/* XXX Timeout: We may need to deliver an empty radio packet here */
|
||||||
|
sentPacket = new COOJARadioPacket(new byte[0]);
|
||||||
|
lastEvent = RadioEvent.PACKET_TRANSMITTED;
|
||||||
|
TR1001Radio.this.setChanged();
|
||||||
|
TR1001Radio.this.notifyObservers();
|
||||||
|
|
||||||
|
isTransmitting = false;
|
||||||
|
lastEvent = RadioEvent.TRANSMISSION_FINISHED;
|
||||||
|
TR1001Radio.this.setChanged();
|
||||||
|
TR1001Radio.this.notifyObservers();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2007, Swedish Institute of Computer Science.
|
|
||||||
* 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.
|
|
||||||
*
|
|
||||||
* $Id: TR1001RadioByte.java,v 1.2 2009/05/26 14:33:30 fros4943 Exp $
|
|
||||||
*/
|
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TR1001 radio byte.
|
|
||||||
*
|
|
||||||
* @author Fredrik Osterlind
|
|
||||||
*/
|
|
||||||
public class TR1001RadioByte {
|
|
||||||
|
|
||||||
private byte b;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates new TR1001 radio byte
|
|
||||||
*/
|
|
||||||
public TR1001RadioByte(byte b) {
|
|
||||||
this.b = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Byte
|
|
||||||
*/
|
|
||||||
public byte getByte() {
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -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: TR1001RadioPacketConverter.java,v 1.4 2009/05/26 14:33:30 fros4943 Exp $
|
* $Id: TR1001RadioPacketConverter.java,v 1.5 2009/12/02 16:39:42 fros4943 Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package se.sics.cooja.mspmote.interfaces;
|
package se.sics.cooja.mspmote.interfaces;
|
||||||
|
@ -68,7 +68,7 @@ public class TR1001RadioPacketConverter {
|
||||||
|
|
||||||
final static int ESB_FOOTER_LENGTH = 2;
|
final static int ESB_FOOTER_LENGTH = 2;
|
||||||
|
|
||||||
private ArrayList<TR1001RadioByte> originalData = new ArrayList<TR1001RadioByte>();
|
private ArrayList<Byte> originalData = new ArrayList<Byte>();
|
||||||
|
|
||||||
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,
|
||||||
|
@ -106,11 +106,10 @@ public class TR1001RadioPacketConverter {
|
||||||
* The returned array typically needs to be feeded to the emulated "slowly",
|
* The returned array typically needs to be feeded to the emulated "slowly",
|
||||||
* i.e. one by one and using interrupts.
|
* i.e. one by one and using interrupts.
|
||||||
*
|
*
|
||||||
* @param coojaPacket
|
* @param coojaPacket COOJA radio packet
|
||||||
* COOJA radio packet
|
|
||||||
* @return TR1001 radio packet
|
* @return TR1001 radio packet
|
||||||
*/
|
*/
|
||||||
public static TR1001RadioByte[] fromCoojaToTR1001(RadioPacket coojaPacket) {
|
public static byte[] fromCoojaToTR1001(RadioPacket coojaPacket) {
|
||||||
|
|
||||||
byte[] coojaPacketData = coojaPacket.getPacketData();
|
byte[] coojaPacketData = coojaPacket.getPacketData();
|
||||||
|
|
||||||
|
@ -142,10 +141,8 @@ 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;
|
||||||
|
|
||||||
TR1001RadioByte[] tr1001Bytes = new TR1001RadioByte[tr1001Frame.length];
|
byte[] tr1001Bytes = new byte[tr1001Frame.length];
|
||||||
for (int i=0; i < tr1001Frame.length; i++) {
|
System.arraycopy(tr1001Frame, 0, tr1001Bytes, 0, tr1001Frame.length);
|
||||||
tr1001Bytes[i] = new TR1001RadioByte(tr1001Frame[i]);
|
|
||||||
}
|
|
||||||
return tr1001Bytes;
|
return tr1001Bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,25 +156,22 @@ public class TR1001RadioPacketConverter {
|
||||||
* - Read length header
|
* - Read length header
|
||||||
* - Remove both length header and CRC footer
|
* - Remove both length header and CRC footer
|
||||||
*
|
*
|
||||||
* @param tr1001Bytes TR1001 bytes
|
* @param tr1001xxBytes TR1001 bytes
|
||||||
* @param tr1001DataLength TR1001 specified packet length
|
* @param tr1001DataLength TR1001 specified packet length
|
||||||
* @return COOJA radio packet
|
* @return COOJA radio packet
|
||||||
*/
|
*/
|
||||||
public static ConvertedRadioPacket fromTR1001ToCooja(TR1001RadioByte[] tr1001Bytes, int tr1001DataLength) {
|
public static ConvertedRadioPacket fromTR1001ToCooja(byte[] data, int tr1001DataLength) {
|
||||||
|
|
||||||
byte[] tr1001Data = new byte[tr1001Bytes.length];
|
|
||||||
for (int i=0; i < tr1001Bytes.length; i++) {
|
|
||||||
tr1001Data[i] = tr1001Bytes[i].getByte();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove TR1001 specifics: preamble, synch and trail bytes */
|
/* Remove TR1001 specifics: preamble, synch and trail bytes */
|
||||||
System.arraycopy(tr1001Data, TR1001_HEADER_LENGTH, tr1001Data, 0,
|
tr1001DataLength -= (TR1001_HEADER_LENGTH + TR1001_FOOTER_LENGTH);
|
||||||
tr1001DataLength - TR1001_HEADER_LENGTH - TR1001_FOOTER_LENGTH);
|
System.arraycopy(
|
||||||
tr1001DataLength = tr1001DataLength - TR1001_HEADER_LENGTH
|
data, TR1001_HEADER_LENGTH,
|
||||||
- TR1001_FOOTER_LENGTH;
|
data, 0,
|
||||||
|
tr1001DataLength
|
||||||
|
);
|
||||||
|
|
||||||
/* GCR decode */
|
/* GCR decode */
|
||||||
byte[] decodedData = gcrCoder.gcrDecode(tr1001Data, tr1001DataLength);
|
byte[] decodedData = gcrCoder.gcrDecode(data, tr1001DataLength);
|
||||||
|
|
||||||
if (decodedData != null) {
|
if (decodedData != null) {
|
||||||
/* Decoding succeded, fetch length from the two first bytes */
|
/* Decoding succeded, fetch length from the two first bytes */
|
||||||
|
@ -195,11 +189,11 @@ public class TR1001RadioPacketConverter {
|
||||||
System.arraycopy(decodedData, ESB_HEADER_LENGTH, packetData, 0,
|
System.arraycopy(decodedData, ESB_HEADER_LENGTH, packetData, 0,
|
||||||
dataLength);
|
dataLength);
|
||||||
|
|
||||||
return new ConvertedRadioPacket(packetData, tr1001Data);
|
return new ConvertedRadioPacket(packetData, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.warn("No cross-level conversion available: TR1001 GCR decoding failed");
|
logger.warn("No cross-level conversion available: TR1001 GCR decoding failed");
|
||||||
return new ConvertedRadioPacket(new byte[0], tr1001Data);
|
return new ConvertedRadioPacket(new byte[0], data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -242,9 +236,8 @@ public class TR1001RadioPacketConverter {
|
||||||
* @param tr1001Byte New TR1001 packet data byte
|
* @param tr1001Byte New TR1001 packet data byte
|
||||||
* @return True if conversion finished (either successful of failed)
|
* @return True if conversion finished (either successful of failed)
|
||||||
*/
|
*/
|
||||||
public boolean fromTR1001ToCoojaAccumulated(TR1001RadioByte tr1001Byte) {
|
public boolean fromTR1001ToCoojaAccumulated(byte b) {
|
||||||
byte b = tr1001Byte.getByte();
|
originalData.add(b);
|
||||||
originalData.add(tr1001Byte);
|
|
||||||
|
|
||||||
if (accumulatedConversionState == AccumulatedConversionState.TR1001_PREAMBLE) {
|
if (accumulatedConversionState == AccumulatedConversionState.TR1001_PREAMBLE) {
|
||||||
if (b == (byte) 0xaa || b == (byte) 0xff) {
|
if (b == (byte) 0xaa || b == (byte) 0xff) {
|
||||||
|
@ -323,7 +316,7 @@ public class TR1001RadioPacketConverter {
|
||||||
|
|
||||||
byte[] originalArr = new byte[originalData.size()];
|
byte[] originalArr = new byte[originalData.size()];
|
||||||
for (int i=0; i < originalArr.length; i++) {
|
for (int i=0; i < originalArr.length; i++) {
|
||||||
originalArr[i] = (byte) originalData.get(i).getByte();
|
originalArr[i] = originalData.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConvertedRadioPacket(dataArrayByte, originalArr);
|
return new ConvertedRadioPacket(dataArrayByte, originalArr);
|
||||||
|
|
Loading…
Reference in a new issue