* @author Henri Dubois-Ferriere
*
*/
+
+
module XE1205SendReceiveP {
provides interface Send;
provides interface Packet;
provides interface PacketAcknowledgements;
provides interface Receive;
- provides interface SplitControl @atleastonce();;
+ provides interface AckSendReceive;
+ provides interface SplitControl @atleastonce();
uses interface XE1205PhyRxTx;
+ uses interface XE1205PhyRssi;
uses interface SplitControl as PhySplitControl;
}
implementation {
- #include "crc.h"
- #include "xe1205debug.h"
+#include "crc.h"
+#include "xe1205debug.h"
#define min(X, Y) ((X) < (Y) ? (X) : (Y))
-
- // Phy header definition. This is not seen by anything above us.
- typedef nx_struct xe1205_phy_header_t {
- nx_uint8_t whitening;
- nx_uint8_t length;
- } xe1205_phy_header_t;
+ enum {
+ PKT_CODE = 0,
+ ACK_CODE = 1
+ };
+
+ // Phy header definition. This is not seen by anything above us.
+ typedef nx_struct xe1205_phy_header_t {
+ nx_uint8_t whitening;
+ nx_uint8_t length;
+ } xe1205_phy_header_t;
+
+ typedef struct ackMsg_t {
+ uint16_t pl;
+ } ackMsg_t;
- xe1205_phy_header_t txPhyHdr;
- norace xe1205_phy_header_t rxPhyHdr; // we don't accept an incoming packet until previous one has been copied into local buf
+ xe1205_phy_header_t txPhyHdr;
+ norace xe1205_phy_header_t rxPhyHdr; // we don't accept an incoming packet until previous one has been copied into local buf
- norace message_t *txMsgPtr=NULL; // message under transmission (non-null until after sendDone).
- norace char txBuf[16]; // buffer used to pass outgoing bytes to Phy
+ norace message_t ackMsg;
+ norace message_t *ackMsgPtr = &ackMsg;
- norace uint8_t *rxBufPtr=NULL; // pointer to raw frame received from Phy
- message_t rxMsg; // for rx path buffer swapping with upper modules
- message_t *rxMsgPtr=&rxMsg;
+ norace message_t *txMsgSendDonePtr=NULL;
+ norace message_t *txMsgPtr=NULL; // message under transmission (non-null until after sendDone).
+ norace uint8_t _len;
+ norace char txBuf[16]; // buffer used to pass outgoing bytes to Phy
- norace uint8_t txIndex, txLen; // State for packet transmissions
- norace uint16_t txRunningCRC; // Crc for outgoing pkts is computed incrementally
+ norace uint8_t *rxBufPtr=NULL; // pointer to raw frame received from Phy
+ message_t rxMsg; // for rx path buffer swapping with upper modules
+ message_t *rxMsgPtr=&rxMsg;
- norace uint8_t txWhiteByte;
+ norace uint8_t txIndex, txLen; // State for packet transmissions
+ norace uint16_t txRunningCRC; // Crc for outgoing pkts is computed incrementally
- uint8_t const pktPreamble[] = {
- 0x55, 0x55, 0x55,
- (data_pattern >> 16) & 0xff, (data_pattern >> 8) & 0xff, data_pattern & 0xff
- };
+ norace uint8_t txWhiteByte;
+ norace bool sendingAck=FALSE;
+ uint16_t ackPayload;
- xe1205_header_t* getHeader( message_t* msg ) {
- return (xe1205_header_t*)( msg->data - sizeof(xe1205_header_t) );
- }
+ bool warmUp=FALSE;
- xe1205_footer_t* getFooter(message_t* msg) {
- return (xe1205_footer_t*)(msg->footer);
- }
-
- xe1205_metadata_t* getMetadata(message_t* msg) {
- return (xe1205_metadata_t*)((uint8_t*)msg->footer + sizeof(xe1205_footer_t));
- }
-
+ uint8_t const pktPreamble[] = {
+ 0x55, 0x55, 0x55,
+ (data_pattern >> 16) & 0xff, (data_pattern >> 8) & 0xff, data_pattern & 0xff
+ };
+
+ uint8_t const ackPreamble[] = {
+ 0x55, 0x55, 0x55,
+ (ack_pattern >> 16) & 0xff, (ack_pattern >> 8) & 0xff, ack_pattern & 0xff
+ };
- command uint8_t Send.maxPayloadLength() {
- return call Packet.maxPayloadLength();
- }
+ task void signalPacketReceived();
- command void* Send.getPayload(message_t* m) {
- return call Packet.getPayload(m, NULL);
- }
+ error_t sendRadioOn(uint8_t preamble);
- command void* Receive.getPayload(message_t* m, uint8_t* len) {
- return call Packet.getPayload(m, len);
- }
+ xe1205_header_t* getHeader( message_t* msg ) {
+ return (xe1205_header_t*)( msg->data - sizeof(xe1205_header_t) );
+ }
- command uint8_t Receive.payloadLength(message_t* m) {
- return call Packet.payloadLength(m);
- }
+ xe1205_footer_t* getFooter(message_t* msg) {
+ return (xe1205_footer_t*)(msg->footer);
+ }
+
+ xe1205_metadata_t* getMetadata(message_t* msg) {
+ return (xe1205_metadata_t*)((uint8_t*)msg->footer + sizeof(xe1205_footer_t));
+ }
+
+ command void AckSendReceive.setAckPayload(uint16_t _pl) {
+ ackPayload = _pl;
+ }
+
+ command uint16_t AckSendReceive.getAckPayload() {
+ return ackPayload;
+ }
+ command uint8_t Send.maxPayloadLength() {
+ return call Packet.maxPayloadLength();
+ }
- command error_t SplitControl.start() {
- error_t err;
- err = call PhySplitControl.start();
+ command void* Send.getPayload(message_t* m) {
+ return call Packet.getPayload(m, NULL);
+ }
- return err;
- }
+ command void* Receive.getPayload(message_t* m, uint8_t* len) {
+ return call Packet.getPayload(m, len);
+ }
- command error_t SplitControl.stop() {
- error_t err;
+ command uint8_t Receive.payloadLength(message_t* m) {
+ return call Packet.payloadLength(m);
+ }
- // One could also argue that this is split phase so should cope and do the right thing.
- // Or one could argue that whatever the phy is doing underneath just gets interrupted.
- if (call XE1205PhyRxTx.busy()) return EBUSY;
+ task void sendDoneTask() {
+ txMsgSendDonePtr = txMsgPtr;
+ txMsgPtr=NULL;
+ signal Send.sendDone(txMsgSendDonePtr, SUCCESS);
- err = call PhySplitControl.stop();
+ }
- return err;
+ task void sendDoneFailTask() {
+ txMsgSendDonePtr = txMsgPtr;
+ txMsgPtr=NULL;
+ signal Send.sendDone(txMsgSendDonePtr, FAIL);
- }
+ }
- event void PhySplitControl.startDone(error_t error) {
- signal SplitControl.startDone(error);
- }
+ command error_t SplitControl.start() {
+ error_t err;
+ err = call PhySplitControl.start();
- event void PhySplitControl.stopDone(error_t error) {
- signal SplitControl.stopDone(error);
- }
+ return err;
+ }
+ command error_t SplitControl.stop() {
+ error_t err;
+ // One could also argue that this is split phase so should cope and do the right thing.
+ // Or one could argue that whatever the phy is doing underneath just gets interrupted.
+ if (call XE1205PhyRxTx.busy()) return EBUSY;
- command error_t Send.cancel(message_t* msg) {
- /* Cancel is unsupported for now. */
- return FAIL;
- }
+ err = call PhySplitControl.stop();
+ txMsgPtr=NULL;
+ rxBufPtr = NULL;
+ return err;
- void checkCrcAndUnwhiten(uint8_t* msg, uint8_t white, uint8_t len) {
- uint16_t crc = 0;
- uint8_t i, b;
- uint8_t* uwPtr = (uint8_t*) getHeader(rxMsgPtr);
- for(i = 0; i < sizeof(xe1205_header_t) + len; i++) {
- b = msg[i] ^ white;
- uwPtr[i] = b;
- crc = crcByte(crc, b);
- }
- getFooter(rxMsgPtr)->crc = (crc == (msg[i] | (msg[i+1] << 8)));
- }
-
- void updateCRCAndWhiten(char* src, char* dst, uint8_t len)
- {
- uint8_t i;
- for(i=0; i < len; i++) {
- txRunningCRC = crcByte(txRunningCRC, src[i]);
- dst[i] = src[i] ^ txWhiteByte;
}
- }
+ event void PhySplitControl.startDone(error_t error) {
+ if (txMsgPtr!=NULL) {
- command error_t Send.send(message_t* msg, uint8_t len) {
- error_t err;
+ sendRadioOn(PKT_CODE);
+ } else {
+ if (warmUp==TRUE) {
- if (txMsgPtr) return EBUSY;
+ post sendDoneFailTask();
+ }
+ }
+ warmUp=FALSE;
+ signal SplitControl.startDone(error);
+ }
- if (call XE1205PhyRxTx.busy()) return EBUSY;
- if (call XE1205PhyRxTx.off()) return EOFF;
+ event void PhySplitControl.stopDone(error_t error) {
+
+ signal SplitControl.stopDone(error);
+ }
- txWhiteByte++;
- txPhyHdr.whitening = txWhiteByte;
- txPhyHdr.length = len;
- txRunningCRC=0;
- getMetadata(msg)->length = len;
- txIndex = min(sizeof(xe1205_header_t) + len + sizeof(xe1205_footer_t),
- sizeof(txBuf) - sizeof(pktPreamble) - sizeof(xe1205_phy_header_t));
- txLen = len + sizeof(xe1205_header_t) + sizeof(xe1205_footer_t);
- if (txIndex == txLen - 1) txIndex--; // don't send a single last byte
+ task void sendAck() {
+ atomic {
+ ((xe1205_metadata_t*)((uint8_t*)ackMsgPtr->footer + sizeof(xe1205_footer_t)))->length = sizeof(ackMsg_t);
+ ((xe1205_header_t*)(&ackMsg.data - sizeof(xe1205_header_t)))->group = \
+ (getHeader((message_t*)rxMsgPtr))->group;
+ ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->type = \
+ ((xe1205_header_t*)(rxMsgPtr->data - sizeof(xe1205_header_t)))->type;
+ ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->dest = \
+ ((xe1205_header_t*)(rxMsgPtr->data - sizeof(xe1205_header_t)))->source;
+ ((xe1205_header_t*)(ackMsgPtr->data - sizeof(xe1205_header_t)))->source = TOS_NODE_ID;
+ ((ackMsg_t*)(ackMsgPtr->data))->pl = ackPayload;
+
+ txMsgPtr = ackMsgPtr;
+ }
+ _len = sizeof(ackMsg_t);
+ sendRadioOn(ACK_CODE);
+ }
+
+ command error_t Send.cancel(message_t* msg) {
+ /* Cancel is unsupported for now. */
+ return FAIL;
+ }
- memcpy(txBuf, pktPreamble, sizeof(pktPreamble));
- memcpy(txBuf + sizeof(pktPreamble), &txPhyHdr, sizeof(txPhyHdr));
-
- if (txIndex == txLen) { // slap on CRC if we're already at end of packet
- updateCRCAndWhiten((char*) getHeader(msg),
- txBuf + sizeof(pktPreamble) + sizeof(xe1205_phy_header_t),
- sizeof(xe1205_header_t) + len);
- txBuf[sizeof(pktPreamble) + sizeof(xe1205_phy_header_t) + txLen - 2] = txRunningCRC & 0xff;
- txBuf[sizeof(pktPreamble) + sizeof(xe1205_phy_header_t) + txLen - 1] = txRunningCRC >> 8;
- } else {
- updateCRCAndWhiten((char*) getHeader(msg),
- txBuf + sizeof(pktPreamble) + sizeof(xe1205_phy_header_t),
- txIndex);
+ void checkCrcAndUnwhiten(uint8_t* msg, uint8_t white, uint8_t len) {
+ uint16_t crc = 0;
+ uint8_t i, b;
+ uint8_t* uwPtr ;
+ atomic uwPtr= (uint8_t*) getHeader(rxMsgPtr);
+ for(i = 0; i < sizeof(xe1205_header_t) + len + offsetof(xe1205_footer_t,crc) ; i++) {
+ b = msg[i] ^ white;
+ uwPtr[i] = b;
+ crc = crcByte(crc, b);
+ }
+ atomic {
+ getFooter(rxMsgPtr)->crc = (crc == (msg[i] | (msg[i+1] << 8)));
+ }
}
-
-
- txMsgPtr = msg;
- // note that the continue send can come in before this instruction returns .
- err = call XE1205PhyRxTx.sendFrame(txBuf, txIndex + sizeof(pktPreamble) + sizeof(xe1205_phy_header_t));
- if (err != SUCCESS) txMsgPtr = NULL;
-
- return err;
- }
+ inline void updateCRCAndWhiten(char* src, char* dst, uint8_t len)
+ {
+ uint8_t i;
+ for(i=0; i < len; i++) {
+ txRunningCRC = crcByte(txRunningCRC, src[i]);
+ dst[i] = src[i] ^ txWhiteByte;
+ }
+ }
+
+ error_t sendRadioOn(uint8_t preamble) {
+ error_t err;
+ txWhiteByte++;
+ txPhyHdr.whitening = txWhiteByte;
+ txPhyHdr.length = _len;
+ txRunningCRC=0;
+ getMetadata(txMsgPtr)->length = _len;
+ if (((xe1205_header_t*)( (uint8_t*)txMsgPtr->data - sizeof(xe1205_header_t)))->ack==1) {
+ call XE1205PhyRxTx.enableAck(TRUE);
+ }
+ txIndex = min(sizeof(xe1205_header_t) + _len + sizeof(xe1205_footer_t),
+ sizeof(txBuf) - sizeof(pktPreamble) - sizeof(xe1205_phy_header_t));
+ txLen = _len + sizeof(xe1205_header_t) + sizeof(xe1205_footer_t);
+ if (txIndex == txLen - 1) txIndex--; // don't send a single last byte
+
+ switch (preamble) {
+ case PKT_CODE:
+ memcpy(txBuf, pktPreamble, sizeof(pktPreamble));
+ memcpy(txBuf + sizeof(pktPreamble), &txPhyHdr, sizeof(txPhyHdr));
+ break;
+ case ACK_CODE:
+ sendingAck=TRUE;
+ memcpy(txBuf, ackPreamble, sizeof(ackPreamble));
+ memcpy(txBuf + sizeof(pktPreamble), &txPhyHdr, sizeof(txPhyHdr));
+
+ post signalPacketReceived();
+ break;
+ }
+
+
+ if (txIndex == txLen) { // slap on CRC if we're already at end of packet
+ updateCRCAndWhiten((char*) getHeader(txMsgPtr),
+ txBuf + sizeof(pktPreamble) + sizeof(xe1205_phy_header_t),
+ sizeof(xe1205_header_t) + _len);
+ txBuf[sizeof(pktPreamble) + sizeof(xe1205_phy_header_t) + txLen - 2] = txRunningCRC & 0xff;
+ txBuf[sizeof(pktPreamble) + sizeof(xe1205_phy_header_t) + txLen - 1] = txRunningCRC >> 8;
+ } else {
+ updateCRCAndWhiten((char*) getHeader(txMsgPtr),
+ txBuf + sizeof(pktPreamble) + sizeof(xe1205_phy_header_t),
+ txIndex);
+ }
+ // note that the continue send can come in before this instruction returns .
+ err = call XE1205PhyRxTx.sendFrame(txBuf, txIndex + sizeof(pktPreamble) + sizeof(xe1205_phy_header_t));
+ if (err != SUCCESS) {
+ if (preamble==PKT_CODE)
+ post sendDoneFailTask();
+ txMsgPtr = NULL;
+ }
+ return err;
+ }
+ command error_t Send.send(message_t* msg, uint8_t len) {
+
+ atomic {
+ if (txMsgPtr){ return EBUSY;}
+ if (msg==NULL) { return FAIL;}
+ if (call XE1205PhyRxTx.busy()==TRUE){ return EBUSY;}
+
+ if (call XE1205PhyRxTx.off()) {
+ txMsgPtr = msg;
+ _len = len;
+ if(call PhySplitControl.start()==SUCCESS) {
+ warmUp=TRUE;
+ return SUCCESS;
+ } else {txMsgPtr=NULL;return EOFF;}
+ }
+ txMsgPtr = msg;
+ _len = len;
+ }
+
+ return sendRadioOn(PKT_CODE);
+ }
- task void sendDoneTask() {
- signal Send.sendDone(txMsgPtr, SUCCESS);
- txMsgPtr = NULL;
- }
- async event char* XE1205PhyRxTx.continueSend(uint8_t* len) __attribute__ ((noinline))
- {
- uint8_t curIndex = txIndex;
- uint8_t l = min(txLen - txIndex, sizeof(txBuf));
- if (txIndex + l == txLen - 1) l--; // don't send a single last byte
+ async event char* XE1205PhyRxTx.continueSend(uint8_t* len) __attribute__ ((noinline))
+ {
+
+ uint8_t curIndex = txIndex;
+ uint8_t l = min(txLen - txIndex, sizeof(txBuf));
+ if (txIndex + l == txLen - 1) l--; // don't send a single last byte
- *len = l;
- if (!l) return NULL;
+ *len = l;
+ if (!l) return NULL;
- txIndex += l;
+ txIndex += l;
- // if we're at end of packet, slap on CRC
- if (txIndex == txLen) {
- updateCRCAndWhiten(&((char*) (getHeader(txMsgPtr)))[curIndex], txBuf, l - 2);
- txBuf[l - 2] = txRunningCRC & 0xff;
- txBuf[l - 1] = txRunningCRC >> 8;
- } else {
- updateCRCAndWhiten(((char*) getHeader(txMsgPtr)) + curIndex, txBuf, l);
- }
-
- return txBuf;
- }
+ // if we're at end of packet, slap on CRC
+ if (txIndex == txLen) {
+ updateCRCAndWhiten(&((char*) (getHeader(txMsgPtr)))[curIndex], txBuf, l - 2);
+ txBuf[l - 2] = txRunningCRC & 0xff;
+ txBuf[l - 1] = txRunningCRC >> 8;
+ } else {
+ updateCRCAndWhiten(((char*) getHeader(txMsgPtr)) + curIndex, txBuf, l);
+ }
- uint8_t sendDones = 0;
- async event void XE1205PhyRxTx.sendFrameDone() __attribute__ ((noinline)) {
- sendDones++;
- if (post sendDoneTask() != SUCCESS)
- xe1205check(2, FAIL);
- }
- command void Packet.clear(message_t* msg) {
- memset(msg, 0, sizeof(message_t));
- }
-
- command uint8_t Packet.payloadLength(message_t* msg) {
- return getMetadata(msg)->length;
- }
-
- command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
- getMetadata(msg)->length = len;
- }
-
- command uint8_t Packet.maxPayloadLength() {
- return TOSH_DATA_LENGTH;
- }
-
- command void* Packet.getPayload(message_t* msg, uint8_t* len) {
- if (len != NULL) {
- *len = getMetadata(msg)->length;
+ return txBuf;
}
- return (void*)msg->data;
- }
-
- async command error_t PacketAcknowledgements.requestAck(message_t* msg) {
- xe1205_metadata_t* md = getMetadata(msg); // xxx this should move to header or footer, leaving it here for now for 1.x compat
- md->ack = 1;
- return SUCCESS;
- }
- async command error_t PacketAcknowledgements.noAck(message_t* msg) {
- xe1205_metadata_t* md = getMetadata(msg);
- md->ack = 1;
- return SUCCESS;
- }
- async command bool PacketAcknowledgements.wasAcked(message_t* msg) {
- xe1205_metadata_t* md = getMetadata(msg);
- return md->ack;
- }
+ uint8_t sendDones = 0;
+ async event void XE1205PhyRxTx.sendFrameDone(error_t err) __attribute__ ((noinline)) {
+ sendDones++;
+ if(sendingAck==FALSE)
+ if(err==SUCCESS) {
+ if (post sendDoneTask() != SUCCESS)
+ xe1205check(2, FAIL);
+ } else {
+ if (post sendDoneFailTask() != SUCCESS)
+ xe1205check(2, FAIL);
+ }
+ else {
+
+ txMsgPtr = NULL;
+ sendingAck=FALSE;
+ }
+ }
- default event void Send.sendDone(message_t* msg, error_t error) { }
+ command void Packet.clear(message_t* msg) {
+ memset(msg, 0, sizeof(message_t));
+ }
- async event uint8_t XE1205PhyRxTx.rxFrameBegin(char* data, uint8_t len) __attribute__ ((noinline)) {
+ command uint8_t Packet.payloadLength(message_t* msg) {
+ return getMetadata(msg)->length;
+ }
+
+ command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
+ getMetadata(msg)->length = len;
+ }
+
+ command uint8_t Packet.maxPayloadLength() {
+ return TOSH_DATA_LENGTH;
+ }
- uint8_t datalen;
+ command void* Packet.getPayload(message_t* msg, uint8_t* len) {
+ if (len != NULL) {
+ *len = getMetadata(msg)->length;
+ }
+ return (void*)msg->data;
+ }
- memcpy(&rxPhyHdr, data, sizeof(xe1205_phy_header_t));
- datalen = rxPhyHdr.length;
- if (datalen > TOSH_DATA_LENGTH || rxBufPtr) return len;
-
- return datalen + sizeof(xe1205_header_t) + sizeof(xe1205_footer_t) + sizeof(xe1205_phy_header_t);
- }
+ async command error_t PacketAcknowledgements.requestAck(message_t* msg) {
+ (getHeader(msg))-> ack |= 0x01;
+ return SUCCESS;
+ }
- task void signalPacketReceived() __attribute__ ((noinline)) {
+ async command error_t PacketAcknowledgements.noAck(message_t* msg) {
+ (getHeader(msg))-> ack &= 0xFE;
+ return SUCCESS;
+ }
- checkCrcAndUnwhiten(rxBufPtr, rxPhyHdr.whitening, rxPhyHdr.length);
- if (!getFooter(rxMsgPtr)->crc) {
- atomic rxBufPtr = NULL;
- return;
+ async command bool PacketAcknowledgements.wasAcked(message_t* msg) {
+ return (getHeader(msg))-> ack & 0x01;
}
- getMetadata((message_t*) rxMsgPtr)->length = rxPhyHdr.length;
- atomic rxBufPtr = NULL;
- rxMsgPtr = signal Receive.receive(rxMsgPtr, rxMsgPtr->data, getMetadata(rxMsgPtr)->length);
- }
+ default event void Send.sendDone(message_t* msg, error_t error) { }
+
+ async event uint8_t XE1205PhyRxTx.rxFrameBegin(char* data, uint8_t len) __attribute__ ((noinline)) {
+ uint8_t datalen;
- uint32_t nrxmsgs;
- async event void XE1205PhyRxTx.rxFrameEnd(char* data, uint8_t len, error_t status) __attribute__ ((noinline)) {
- if (status != SUCCESS) return;
- // nrxmsgs++;
- if (rxBufPtr) return; // this could happen whenever rxFrameBegin was called with rxBufPtr still active
- rxBufPtr = (data + sizeof(xe1205_phy_header_t));
- xe1205check(1, post signalPacketReceived());
- }
+ memcpy(&rxPhyHdr, data, sizeof(xe1205_phy_header_t));
+ datalen = rxPhyHdr.length;
+ if (datalen > TOSH_DATA_LENGTH || rxBufPtr) return len;
+
+ return datalen + sizeof(xe1205_header_t) + sizeof(xe1205_footer_t) + sizeof(xe1205_phy_header_t);
+ }
+
+ task void signalPacketReceived() __attribute__ ((noinline)) {
+
+ atomic {
+ getMetadata((message_t*) rxMsgPtr)->length = rxPhyHdr.length;
+
+ rxBufPtr = NULL;
+ rxMsgPtr = signal Receive.receive(rxMsgPtr, rxMsgPtr->data, getMetadata(rxMsgPtr)->length);
+ }
+ }
+
+
+ uint32_t nrxmsgs;
+ async event void XE1205PhyRxTx.rxFrameEnd(char* data, uint8_t len, error_t status) __attribute__ ((noinline)) {
+ if (status != SUCCESS){ return;}
+
+ if (rxBufPtr) return; // this could happen whenever rxFrameBegin was called with rxBufPtr still active
+ rxBufPtr = (data + sizeof(xe1205_phy_header_t));
+
+ checkCrcAndUnwhiten(rxBufPtr, rxPhyHdr.whitening, rxPhyHdr.length);
+
+ if (!getFooter(rxMsgPtr)->crc) {
+ atomic rxBufPtr = NULL;
+ return;
+ }
+
+ getMetadata((message_t*) rxMsgPtr)->strength = call XE1205PhyRssi.readRxRssi();
+ getMetadata((message_t*) rxMsgPtr)->length = rxPhyHdr.length;
+
+ if ((getHeader((message_t*)rxMsgPtr))->dest == TOS_NODE_ID &&
+ (((getHeader((message_t*)rxMsgPtr))->ack)& 0x01)==1) {
+ post sendAck();
+ } else {
+ atomic rxBufPtr = NULL;
+ rxMsgPtr = signal Receive.receive(rxMsgPtr, rxMsgPtr->data, getMetadata(rxMsgPtr)->length);
+ }
+
+ }
+ async event void XE1205PhyRssi.rssiDone(uint8_t _rssi) { }
}