xe1205sendreceivep.nc
来自「tinyos-2.0源代码!转载而已!要的尽管拿!」· NC 代码 · 共 298 行
NC
298 行
/* * Copyright (c) 2006, Ecole Polytechnique Federale de Lausanne (EPFL), * Switzerland. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * - Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * - 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. * - Neither the name of the Ecole Polytechnique Federale de Lausanne (EPFL) * 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 COPYRIGHT HOLDERS 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 COPYRIGHT * OWNER 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. * * ======================================================================== *//* * @author Henri Dubois-Ferriere * */module XE1205SendReceiveP { provides interface Send; provides interface Packet; provides interface PacketAcknowledgements; provides interface Receive; uses interface XE1205PhyRxTx;}implementation { #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; 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 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 txIndex, txLen; // State for packet transmissions norace uint16_t txRunningCRC; // Crc for outgoing pkts is computed incrementally norace uint8_t txWhiteByte; uint8_t const pktPreamble[] = { 0x55, 0x55, 0x55, (data_pattern >> 16) & 0xff, (data_pattern >> 8) & 0xff, data_pattern & 0xff }; xe1205_header_t* getHeader( message_t* msg ) { return (xe1205_header_t*)( msg->data - sizeof(xe1205_header_t) ); } 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 uint8_t Send.maxPayloadLength() { return call Packet.maxPayloadLength(); } command void* Send.getPayload(message_t* m) { return call Packet.getPayload(m, NULL); } command void* Receive.getPayload(message_t* m, uint8_t* len) { return call Packet.getPayload(m, len); } command uint8_t Receive.payloadLength(message_t* m) { return call Packet.payloadLength(m); } command error_t Send.cancel(message_t* msg) { /* Cancel is unsupported for now. */ return FAIL; } 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; } } command error_t Send.send(message_t* msg, uint8_t len) { error_t err; if (txMsgPtr) return EBUSY; if (call XE1205PhyRxTx.busy()) return EBUSY; 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 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); } 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; } 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 *len = l; if (!l) return NULL; 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; } 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 (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; } 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; 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)) { checkCrcAndUnwhiten(rxBufPtr, rxPhyHdr.whitening, rxPhyHdr.length); if (!getFooter(rxMsgPtr)->crc) { atomic rxBufPtr = NULL; return; } getMetadata((message_t*) rxMsgPtr)->length = rxPhyHdr.length; atomic 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; // 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()); }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?