]> oss.titaniummirror.com Git - tinyos-2.x.git/blobdiff - tos/chips/xe1205/XE1205SendReceiveP.nc
added ack, received packet strength, LPL (compile with PFLAGS +=-DLOW_POWER_LISTENING)
[tinyos-2.x.git] / tos / chips / xe1205 / XE1205SendReceiveP.nc
index b86ce5cac672ccbc1a76dc204147129c4a7af32a..77bfff4aa7113c69c4f832f098c458c2e540cb42 100644 (file)
  * @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) { }
 
 }