// $Id$
-/* tab:4
+/*
* "Copyright (c) 2000-2005 The Regents of the University of California.
* All rights reserved.
*
interface Packet;
interface ByteRadio;
interface PacketAcknowledgements;
+ interface LinkPacketMetadata;
}
uses {
//interface PowerManagement;
interface CC1000Control;
interface HplCC1000Spi;
-
+ interface CC1000Squelch;
interface ReadNow<uint16_t> as RssiRx;
async command am_addr_t amAddress();
}
uint16_t rxShiftBuf;
message_t rxBuf;
- message_t *rxBufPtr = &rxBuf;
+ message_t * ONE rxBufPtr = &rxBuf;
uint16_t preambleLength;
- message_t *txBufPtr;
+ message_t * ONE_NOK txBufPtr;
uint8_t nextTxByte;
const_uint8_t ackCode[5] = { 0xab, ACK_BYTE1, ACK_BYTE2, 0xaa, 0xaa };
/* Packet structure accessor functions. Note that everything is
* relative to the data field. */
- cc1000_header_t *getHeader(message_t *amsg) {
- return (cc1000_header_t *)(amsg->data - sizeof(cc1000_header_t));
+ cc1000_header_t * ONE getHeader(message_t * ONE amsg) {
+ return TCAST(cc1000_header_t * ONE, (uint8_t *)amsg + offsetof(message_t, data) - sizeof(cc1000_header_t));
}
- cc1000_footer_t *getFooter(message_t *amsg) {
+ cc1000_footer_t *getFooter(message_t * ONE amsg) {
return (cc1000_footer_t *)(amsg->footer);
}
- cc1000_metadata_t *getMetadata(message_t *amsg) {
- return (cc1000_metadata_t *)((uint8_t *)amsg->footer + sizeof(cc1000_footer_t));
+ cc1000_metadata_t * ONE getMetadata(message_t * ONE amsg) {
+ return TCAST(cc1000_metadata_t * ONE, (uint8_t *)amsg + offsetof(message_t, footer) + sizeof(cc1000_footer_t));
}
/* State transition functions */
txBufPtr = msg;
}
}
- signal ByteRadio.rts();
+ signal ByteRadio.rts(msg);
return SUCCESS;
}
if (rxShiftBuf == ACK_WORD)
{
- getMetadata(txBufPtr)->ack = 1;
+ getMetadata(txBufPtr)->metadataBits |= CC1000_ACK_BIT;
enterTxDoneState();
return;
}
}
if (count >= MAX_ACK_WAIT)
{
- getMetadata(txBufPtr)->ack = 0;
+ getMetadata(txBufPtr)->metadataBits &= ~CC1000_ACK_BIT;
enterTxDoneState();
}
}
cc1000_metadata_t *rxMetadata = getMetadata(rxBufPtr);
if (result != SUCCESS)
- rxMetadata->strength = 0;
+ rxMetadata->strength_or_preamble = 0;
else
- rxMetadata->strength = data;
+ rxMetadata->strength_or_preamble = data;
}
void rxData(uint8_t in) {
uint8_t nextByte;
cc1000_header_t *rxHeader = getHeader(rxBufPtr);
-
- // rxLength is the offset into a message_t at which the packet
- // data ends: it is NOT equal to the number of bytes received,
- // as there may be padding in the message_t before the packet.
- uint8_t rxLength = rxHeader->length + offsetof(message_t, data);
+ uint8_t rxLength = rxHeader->length;
// Reject invalid length packets
- if (rxLength > TOSH_DATA_LENGTH + offsetof(message_t, data))
+ if (rxLength > TOSH_DATA_LENGTH)
{
// The packet's screwed up, so just dump it
enterListenState();
rxShiftBuf = rxShiftBuf << 8 | in;
nextByte = rxShiftBuf >> f.rxBitOffset;
- ((uint8_t *)rxBufPtr)[count++] = nextByte;
+ ((uint8_t *COUNT(sizeof(message_t)))rxBufPtr)[count++] = nextByte;
+ // Adjust rxLength to correspond to the corresponding offset in message_t
+ rxLength += offsetof(message_t, data);
if (count <= rxLength)
runningCrc = crcByte(runningCrc, nextByte);
if (f.ack &&
rxFooter->crc &&
- rxHeader->addr == call amAddress())
+ rxHeader->dest == call amAddress())
{
enterAckState();
call CC1000Control.txMode();
}
void packetReceiveDone() {
+ uint16_t snr;
+
+ snr = (uint16_t) getMetadata(rxBufPtr)->strength_or_preamble;
+ /* Higher signal strengths have lower voltages. So see if we're
+ CC1000_WHITE_BIT_THRESH *below* the noise floor. */
+ if ((snr + CC1000_WHITE_BIT_THRESH) < ((call CC1000Squelch.get()))) {
+ getMetadata(rxBufPtr)->metadataBits |= CC1000_WHITE_BIT;
+ }
+ else {
+ getMetadata(rxBufPtr)->metadataBits &= ~CC1000_WHITE_BIT;
+ }
+
post signalPacketReceived();
enterReceivedState();
}
return TOSH_DATA_LENGTH;
}
- command void* Packet.getPayload(message_t *msg, uint8_t *len) {
- if (len != NULL) {
- cc1000_header_t *header = getHeader(msg);
-
- *len = header->length;
+ command void* Packet.getPayload(message_t *msg, uint8_t len) {
+ if (len <= TOSH_DATA_LENGTH) {
+ return (void* COUNT_NOK(len))msg->data;
+ }
+ else {
+ return NULL;
}
- return (void*)msg->data;
}
async command error_t PacketAcknowledgements.requestAck(message_t *msg) {
return FAIL; /* We always ack */
}
- 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 uint8_t Send.maxPayloadLength() {
return call Packet.maxPayloadLength();
}
- command void* Send.getPayload(message_t *m) {
- return call Packet.getPayload(m, NULL);
+ command void* Send.getPayload(message_t *m, uint8_t len) {
+ return call Packet.getPayload(m, len);
}
async command bool PacketAcknowledgements.wasAcked(message_t *msg) {
- return getMetadata(msg)->ack;
+ return getMetadata(msg)->metadataBits & CC1000_ACK_BIT;
+ }
+
+ async command bool LinkPacketMetadata.highChannelQuality(message_t* msg) {
+ return getMetadata(msg)->metadataBits & CC1000_WHITE_BIT;
}
+
// Default events for radio send/receive coordinators do nothing.
// Be very careful using these, or you'll break the stack.
default async event void RadioTimeStamping.transmittedSFD(uint16_t time, message_t *msgBuff) { }