+ 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;
+ }