+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-interface ActiveMessageConfig
-{
- /**
- * This command is called when the message first enters the radio stack
- * via the Send.send command. This should clear the packet if the user
- * forgot to do so (or return EINVAL to be strict).
- */
- command error_t checkPacket(message_t* msg);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-module ActiveMessageLayerC
-{
- provides
- {
- interface AMSend[am_id_t id];
- interface Receive[am_id_t id];
- interface Receive as Snoop[am_id_t id];
- }
- uses
- {
- interface Send as SubSend;
- interface Receive as SubReceive;
- interface AMPacket;
- interface ActiveMessageConfig as Config;
- }
-}
-
-implementation
-{
-/*----------------- Send -----------------*/
-
- command error_t AMSend.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len)
- {
- error_t error;
-
- error = call Config.checkPacket(msg);
- if( error != SUCCESS )
- return error;
-
- call AMPacket.setSource(msg, call AMPacket.address());
- call AMPacket.setGroup(msg, call AMPacket.localGroup());
- call AMPacket.setType(msg, id);
- call AMPacket.setDestination(msg, addr);
-
- return call SubSend.send(msg, len);
- }
-
- inline event void SubSend.sendDone(message_t* msg, error_t error)
- {
- signal AMSend.sendDone[call AMPacket.type(msg)](msg, error);
- }
-
- inline command error_t AMSend.cancel[am_id_t id](message_t* msg)
- {
- return call SubSend.cancel(msg);
- }
-
- default event void AMSend.sendDone[am_id_t id](message_t* msg, error_t error)
- {
- }
-
- inline command uint8_t AMSend.maxPayloadLength[am_id_t id]()
- {
- return call SubSend.maxPayloadLength();
- }
-
- inline command void* AMSend.getPayload[am_id_t id](message_t* msg, uint8_t len)
- {
- return call SubSend.getPayload(msg, len);
- }
-
-/*----------------- Receive -----------------*/
-
- event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)
- {
- am_id_t type = call AMPacket.type(msg);
-
- msg = call AMPacket.isForMe(msg)
- ? signal Receive.receive[type](msg, payload, len)
- : signal Snoop.receive[type](msg, payload, len);
-
- return msg;
- }
-
- default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len)
- {
- return msg;
- }
-
- default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len)
- {
- return msg;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-interface CsmaConfig
-{
- /**
- * This command is called when the message is transmitted to
- * check if it needs software clear channel assesment.
- */
- async command bool requiresSoftwareCCA(message_t* msg);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration CsmaLayerC
-{
- provides
- {
- interface RadioSend;
- }
- uses
- {
- interface RadioSend as SubSend;
- interface RadioCCA as SubCCA;
-
- interface CsmaConfig as Config;
- }
-}
-
-implementation
-{
- components CsmaLayerP;
-
- RadioSend = CsmaLayerP;
- SubSend = CsmaLayerP;
- SubCCA = CsmaLayerP;
- Config = CsmaLayerP;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-#include <RadioAssert.h>
-
-module CsmaLayerP
-{
- provides
- {
- interface RadioSend;
- }
-
- uses
- {
- interface CsmaConfig as Config;
-
- interface RadioSend as SubSend;
- interface RadioCCA as SubCCA;
- }
-}
-
-implementation
-{
- tasklet_norace message_t *txMsg;
-
- tasklet_norace uint8_t state;
- enum
- {
- STATE_READY = 0,
- STATE_CCA_WAIT = 1,
- STATE_SEND = 2,
- };
-
- tasklet_async event void SubSend.ready()
- {
- if( state == STATE_READY )
- signal RadioSend.ready();
- }
-
- tasklet_async command error_t RadioSend.send(message_t* msg)
- {
- error_t error;
-
- if( state == STATE_READY )
- {
- if( call Config.requiresSoftwareCCA(msg) )
- {
- txMsg = msg;
-
- if( (error = call SubCCA.request()) == SUCCESS )
- state = STATE_CCA_WAIT;
- }
- else if( (error = call SubSend.send(msg)) == SUCCESS )
- state = STATE_SEND;
- }
- else
- error = EBUSY;
-
- return error;
- }
-
- tasklet_async event void SubCCA.done(error_t error)
- {
- ASSERT( state == STATE_CCA_WAIT );
-
- if( error == SUCCESS && (error = call SubSend.send(txMsg)) == SUCCESS )
- state = STATE_SEND;
- else
- {
- state = STATE_READY;
- signal RadioSend.sendDone(EBUSY);
- }
- }
-
- tasklet_async event void SubSend.sendDone(error_t error)
- {
- ASSERT( state == STATE_SEND );
-
- state = STATE_READY;
- signal RadioSend.sendDone(error);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-interface DummyConfig
-{
- /**
- * We need to put something here, but this is not going to get called
- */
- async command void nothing();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-generic configuration DummyLayerC()
-{
- provides
- {
- interface SplitControl;
- interface Send;
- interface Receive;
- interface LowPowerListening;
-
- interface RadioState;
- interface RadioSend;
- interface RadioReceive;
- interface RadioCCA;
-
- interface DummyConfig as UnconnectedConfig;
- }
-
- uses
- {
- interface RadioState as SubState;
- interface RadioSend as SubRadioSend;
- interface RadioReceive as SubRadioReceive;
- interface RadioCCA as SubRadioCCA;
- interface SplitControl as SubControl;
- interface Send as SubSend;
- interface Receive as SubReceive;
-
- interface DummyConfig as Config;
- }
-}
-
-implementation
-{
- RadioState = SubState;
- RadioSend = SubRadioSend;
- RadioReceive = SubRadioReceive;
- RadioCCA = SubRadioCCA;
-
- SplitControl = SubControl;
- Send = SubSend;
- Receive = SubReceive;
-
- Config = UnconnectedConfig;
-
- components DummyLayerP;
- LowPowerListening = DummyLayerP.LowPowerListening;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-module DummyLayerP
-{
- provides interface LowPowerListening;
-}
-
-implementation
-{
- command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) { }
-
- command uint16_t LowPowerListening.getLocalSleepInterval() { return 0; }
-
- command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { }
-
- command uint16_t LowPowerListening.getLocalDutyCycle() { return 10000; }
-
- command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { }
-
- command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { return 0; }
-
- command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { }
-
- command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { return 10000; }
-
- command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) { return 0; }
-
- command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) { return 10000; }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration IEEE154NetworkLayerC
-{
- provides
- {
- interface SplitControl;
- interface Send;
- interface Receive;
- }
- uses
- {
- interface SplitControl as SubControl;
- interface Send as SubSend;
- interface Receive as SubReceive;
- }
-}
-
-implementation
-{
- components IEEE154NetworkLayerP, IEEE154PacketC;
-
- SplitControl = SubControl;
-
- Send = IEEE154NetworkLayerP;
- Receive = IEEE154NetworkLayerP;
-
- SubSend = IEEE154NetworkLayerP;
- SubReceive = IEEE154NetworkLayerP;
-
- IEEE154NetworkLayerP.IEEE154Packet -> IEEE154PacketC;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-module IEEE154NetworkLayerP
-{
- provides
- {
- interface Send;
- interface Receive;
- interface Receive as NonTinyosReceive[uint8_t network];
- }
-
- uses
- {
- interface Send as SubSend;
- interface Receive as SubReceive;
-
- interface IEEE154Packet;
- }
-}
-
-implementation
-{
-#ifndef TINYOS_6LOWPAN_NETWORK_ID
-#define TINYOS_6LOWPAN_NETWORK_ID 0x3f
-#endif
-
- command error_t Send.send(message_t* msg, uint8_t len)
- {
- call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID);
- return call SubSend.send(msg, len);
- }
-
- command error_t Send.cancel(message_t* msg)
- {
- return call SubSend.cancel(msg);
- }
-
- command uint8_t Send.maxPayloadLength()
- {
- return call SubSend.maxPayloadLength();
- }
-
- command void* Send.getPayload(message_t* msg, uint8_t len)
- {
- return call SubSend.getPayload(msg, len);
- }
-
- event void SubSend.sendDone(message_t* msg, error_t error)
- {
- signal Send.sendDone(msg, error);
- }
-
- event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len)
- {
- uint8_t network = call IEEE154Packet.get6LowPan(msg);
- if( network == TINYOS_6LOWPAN_NETWORK_ID )
- return signal Receive.receive(msg, payload, len);
- else
- return signal NonTinyosReceive.receive[network](msg, payload, len);
- }
-
- default event message_t *NonTinyosReceive.receive[uint8_t network](message_t *msg, void *payload, uint8_t len)
- {
- return msg;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __IEEE154PACKET_H__
-#define __IEEE154PACKET_H__
-
-typedef nx_struct ieee154_header_t
-{
- nxle_uint8_t length;
- nxle_uint16_t fcf;
- nxle_uint8_t dsn;
- nxle_uint16_t destpan;
- nxle_uint16_t dest;
- nxle_uint16_t src;
-
-// I-Frame 6LowPAN interoperability byte
-#ifndef TFRAMES_ENABLED
- nxle_uint8_t network;
-#endif
-
- nxle_uint8_t type;
-} ieee154_header_t;
-
-// the actual radio driver might not use this
-typedef nx_struct ieee154_footer_t
-{
- nxle_uint16_t crc;
-} ieee154_footer_t;
-
-enum ieee154_fcf_enums {
- IEEE154_FCF_FRAME_TYPE = 0,
- IEEE154_FCF_SECURITY_ENABLED = 3,
- IEEE154_FCF_FRAME_PENDING = 4,
- IEEE154_FCF_ACK_REQ = 5,
- IEEE154_FCF_INTRAPAN = 6,
- IEEE154_FCF_DEST_ADDR_MODE = 10,
- IEEE154_FCF_SRC_ADDR_MODE = 14,
-};
-
-enum ieee154_fcf_type_enums {
- IEEE154_TYPE_BEACON = 0,
- IEEE154_TYPE_DATA = 1,
- IEEE154_TYPE_ACK = 2,
- IEEE154_TYPE_MAC_CMD = 3,
- IEEE154_TYPE_MASK = 7,
-};
-
-enum iee154_fcf_addr_mode_enums {
- IEEE154_ADDR_NONE = 0,
- IEEE154_ADDR_SHORT = 2,
- IEEE154_ADDR_EXT = 3,
- IEEE154_ADDR_MASK = 3,
-};
-
-#endif//__IEEE154PACKET_H__
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <IEEE154Packet.h>
-#include <message.h>
-
-/**
- * This interface encapsulates IEEE 802.15.4 intrapan data frames with
- * 16-bit destination pan, source and destination addresses. It also
- * supports 6LowPan interoperability mode, and acknowledgement frames.
- * Note, that this interface does not support the CRC-16 value, which
- * should be verified before the data can be trusted.
- */
-interface IEEE154Packet
-{
- /**
- * Returns the IEEE 802.15.4 header including the length field.
- */
- async command ieee154_header_t* getHeader(message_t* msg);
-
- /**
- * Returns the raw value (unadjusted) of the length field
- */
- async command uint8_t getLength(message_t* msg);
-
- /**
- * Sets the length field
- */
- async command void setLength(message_t* msg, uint8_t length);
-
- /**
- * Returns the frame control field. This method should not be used,
- * isDataFrame and isAckFrame should be used instead.
- */
- async command uint16_t getFCF(message_t* msg);
-
- /**
- * Sets the frame control field. This method should not be used,
- * createDataFrame and createAckFrame should be used instead.
- */
- async command void setFCF(message_t* msg, uint16_t fcf);
-
- /**
- * Returns TRUE if the message is a data frame supported by
- * this interface (based on the value of the FCF).
- */
- async command bool isDataFrame(message_t* msg);
-
- /**
- * Sets the FCF to create a data frame supported by this interface.
- * You may call setAckRequired and setFramePending commands after this.
- */
- async command void createDataFrame(message_t* msg);
-
- /**
- * Returns TRUE if the message is an acknowledgement frame supported
- * by this interface (based on the value of the FCF).
- */
- async command bool isAckFrame(message_t* msg);
-
- /**
- * Sets the FCF to create an acknowledgement frame supported by
- * this interface. You may call setFramePending after this.
- */
- async command void createAckFrame(message_t* msg);
-
- /**
- * Creates an acknowledgement packet for the given data packet.
- * This also sets the DSN value. The data message must be a
- * data frame, the ack message will be overwritten.
- */
- async command void createAckReply(message_t* data, message_t* ack);
-
- /**
- * Returns TRUE if the acknowledgement packet corresponds to the
- * data packet. The data message must be a data packet.
- */
- async command bool verifyAckReply(message_t* data, message_t* ack);
-
- /**
- * Returns TRUE if the ACK required field is set in the FCF.
- */
- async command bool getAckRequired(message_t* msg);
-
- /**
- * Sets the ACK required field in the FCF, should never be set
- * for acknowledgement frames.
- */
- async command void setAckRequired(message_t* msg, bool ack);
-
- /**
- * Returns TRUE if the frame pending field is set in the FCF.
- */
- async command bool getFramePending(message_t* msg);
-
- /**
- * Sets the frame pending field in the FCF.
- */
- async command void setFramePending(message_t* msg, bool pending);
-
- /**
- * Returns the data sequence number
- */
- async command uint8_t getDSN(message_t* msg);
-
- /**
- * Sets the data sequence number
- */
- async command void setDSN(message_t* msg, uint8_t dsn);
-
- /**
- * returns the destination PAN id, values <= 255 are tinyos groups,
- * valid only for data frames
- */
- async command uint16_t getDestPan(message_t* msg);
-
- /**
- * Sets the destination PAN id, valid only for data frames
- */
- async command void setDestPan(message_t* msg, uint16_t pan);
-
- /**
- * Returns the destination address, valid only for data frames
- */
- async command uint16_t getDestAddr(message_t* msg);
-
- /**
- * Sets the destination address, valid only for data frames
- */
- async command void setDestAddr(message_t* msg, uint16_t addr);
-
- /**
- * Returns the source address, valid only for data frames
- */
- async command uint16_t getSrcAddr(message_t* msg);
-
- /**
- * Sets the source address, valid only for data frames
- */
- async command void setSrcAddr(message_t* msg, uint16_t addr);
-
-#ifndef TFRAMES_ENABLED
-
- /**
- * Returns the value of the 6LowPan network field.
- */
- async command uint8_t get6LowPan(message_t* msg);
-
- /**
- * Sets the value of the 6LowPan network field.
- */
- async command void set6LowPan(message_t* msg, uint8_t network);
-
-#endif
-
- /**
- * Returns the active message type of the message
- */
- async command am_id_t getType(message_t* msg);
-
- /**
- * Sets the active message type
- */
- async command void setType(message_t* msg, am_id_t type);
-
- /**
- * Returns TRUE if the packet is a data packet, the ACK_REQ field
- * is set and the destination address is not the broadcast address.
- */
- async command bool requiresAckWait(message_t* msg);
-
- /**
- * Returns TRUE if the packet is a data packet, the ACK_REQ field
- * is set and the destionation address is this node.
- */
- async command bool requiresAckReply(message_t* msg);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration IEEE154PacketC
-{
- provides
- {
- interface IEEE154Packet;
- interface AMPacket;
- }
-}
-
-implementation
-{
- components IEEE154PacketP, ActiveMessageAddressC;
- IEEE154PacketP.ActiveMessageAddress -> ActiveMessageAddressC;
-
- IEEE154Packet = IEEE154PacketP;
- AMPacket = IEEE154PacketP;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <IEEE154Packet.h>
-
-module IEEE154PacketP
-{
- provides
- {
- interface IEEE154Packet;
- interface AMPacket;
- }
-
- uses interface ActiveMessageAddress;
-}
-
-implementation
-{
-/*----------------- IEEE154Packet -----------------*/
-
- enum
- {
- IEEE154_DATA_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE)
- | (1 << IEEE154_FCF_INTRAPAN)
- | (IEEE154_ADDR_MASK << IEEE154_FCF_DEST_ADDR_MODE)
- | (IEEE154_ADDR_MASK << IEEE154_FCF_SRC_ADDR_MODE),
-
- IEEE154_DATA_FRAME_VALUE = (IEEE154_TYPE_DATA << IEEE154_FCF_FRAME_TYPE)
- | (1 << IEEE154_FCF_INTRAPAN)
- | (IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE)
- | (IEEE154_ADDR_SHORT << IEEE154_FCF_SRC_ADDR_MODE),
-
- IEEE154_ACK_FRAME_LENGTH = 5, // includes the FCF, DSN and FCS
- IEEE154_ACK_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE),
- IEEE154_ACK_FRAME_VALUE = (IEEE154_TYPE_ACK << IEEE154_FCF_FRAME_TYPE),
- };
-
- inline ieee154_header_t* getHeader(message_t* msg)
- {
- return (ieee154_header_t*)(msg->data - sizeof(ieee154_header_t));
- }
-
- inline async command ieee154_header_t* IEEE154Packet.getHeader(message_t* msg)
- {
- return getHeader(msg);
- }
-
- inline async command uint8_t IEEE154Packet.getLength(message_t* msg)
- {
- return getHeader(msg)->length;
- }
-
- inline async command void IEEE154Packet.setLength(message_t* msg, uint8_t length)
- {
- getHeader(msg)->length = length;
- }
-
- inline async command uint16_t IEEE154Packet.getFCF(message_t* msg)
- {
- return getHeader(msg)->fcf;
- }
-
- inline async command void IEEE154Packet.setFCF(message_t* msg, uint16_t fcf)
- {
- getHeader(msg)->fcf = fcf;
- }
-
- inline async command bool IEEE154Packet.isDataFrame(message_t* msg)
- {
- return (getHeader(msg)->fcf & IEEE154_DATA_FRAME_MASK) == IEEE154_DATA_FRAME_VALUE;
- }
-
- inline async command void IEEE154Packet.createDataFrame(message_t* msg)
- {
- getHeader(msg)->fcf = IEEE154_DATA_FRAME_VALUE;
- }
-
- inline async command bool IEEE154Packet.isAckFrame(message_t* msg)
- {
- return (getHeader(msg)->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE;
- }
-
- inline async command void IEEE154Packet.createAckFrame(message_t* msg)
- {
- ieee154_header_t* header = getHeader(msg);
-
- header->length = IEEE154_ACK_FRAME_LENGTH;
- header->fcf = IEEE154_ACK_FRAME_VALUE;
- }
-
- inline async command void IEEE154Packet.createAckReply(message_t* data, message_t* ack)
- {
- ieee154_header_t* header = getHeader(ack);
-
- header->length = IEEE154_ACK_FRAME_LENGTH;
- header->fcf = IEEE154_ACK_FRAME_VALUE;
- header->dsn = getHeader(data)->dsn;
- }
-
- inline async command bool IEEE154Packet.verifyAckReply(message_t* data, message_t* ack)
- {
- ieee154_header_t* header = getHeader(ack);
-
- return header->dsn == getHeader(data)->dsn
- && (header->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE;
- }
-
- inline async command bool IEEE154Packet.getAckRequired(message_t* msg)
- {
- return getHeader(msg)->fcf & (1 << IEEE154_FCF_ACK_REQ);
- }
-
- inline async command void IEEE154Packet.setAckRequired(message_t* msg, bool ack)
- {
- if( ack )
- getHeader(msg)->fcf |= (1 << IEEE154_FCF_ACK_REQ);
- else
- getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_ACK_REQ);
- }
-
- inline async command bool IEEE154Packet.getFramePending(message_t* msg)
- {
- return getHeader(msg)->fcf & (1 << IEEE154_FCF_FRAME_PENDING);
- }
-
- inline async command void IEEE154Packet.setFramePending(message_t* msg, bool pending)
- {
- if( pending )
- getHeader(msg)->fcf |= (1 << IEEE154_FCF_FRAME_PENDING);
- else
- getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_FRAME_PENDING);
- }
-
- inline async command uint8_t IEEE154Packet.getDSN(message_t* msg)
- {
- return getHeader(msg)->dsn;
- }
-
- inline async command void IEEE154Packet.setDSN(message_t* msg, uint8_t dsn)
- {
- getHeader(msg)->dsn = dsn;
- }
-
- inline async command uint16_t IEEE154Packet.getDestPan(message_t* msg)
- {
- return getHeader(msg)->destpan;
- }
-
- inline async command void IEEE154Packet.setDestPan(message_t* msg, uint16_t pan)
- {
- getHeader(msg)->destpan = pan;
- }
-
- inline async command uint16_t IEEE154Packet.getDestAddr(message_t* msg)
- {
- return getHeader(msg)->dest;
- }
-
- inline async command void IEEE154Packet.setDestAddr(message_t* msg, uint16_t addr)
- {
- getHeader(msg)->dest = addr;
- }
-
- inline async command uint16_t IEEE154Packet.getSrcAddr(message_t* msg)
- {
- return getHeader(msg)->src;
- }
-
- inline async command void IEEE154Packet.setSrcAddr(message_t* msg, uint16_t addr)
- {
- getHeader(msg)->src = addr;
- }
-
-#ifndef TFRAMES_ENABLED
-
- inline async command uint8_t IEEE154Packet.get6LowPan(message_t* msg)
- {
- return getHeader(msg)->network;
- }
-
- inline async command void IEEE154Packet.set6LowPan(message_t* msg, uint8_t network)
- {
- getHeader(msg)->network = network;
- }
-
-#endif
-
- inline async command am_id_t IEEE154Packet.getType(message_t* msg)
- {
- return getHeader(msg)->type;
- }
-
- inline async command void IEEE154Packet.setType(message_t* msg, am_id_t type)
- {
- getHeader(msg)->type = type;
- }
-
- async command bool IEEE154Packet.requiresAckWait(message_t* msg)
- {
- return call IEEE154Packet.getAckRequired(msg)
- && call IEEE154Packet.isDataFrame(msg)
- && call IEEE154Packet.getDestAddr(msg) != 0xFFFF;
- }
-
- async command bool IEEE154Packet.requiresAckReply(message_t* msg)
- {
- return call IEEE154Packet.getAckRequired(msg)
- && call IEEE154Packet.isDataFrame(msg)
- && call IEEE154Packet.getDestAddr(msg) == call ActiveMessageAddress.amAddress();
- }
-
- inline async event void ActiveMessageAddress.changed()
- {
- }
-
-/*----------------- AMPacket -----------------*/
-
- inline command am_addr_t AMPacket.address()
- {
- return call ActiveMessageAddress.amAddress();
- }
-
- inline command am_group_t AMPacket.localGroup()
- {
- // TODO: check if this is correct
- return call ActiveMessageAddress.amGroup();
- }
-
- inline command am_addr_t AMPacket.destination(message_t* msg)
- {
- return call IEEE154Packet.getDestAddr(msg);
- }
-
- inline command am_addr_t AMPacket.source(message_t* msg)
- {
- return call IEEE154Packet.getSrcAddr(msg);
- }
-
- inline command void AMPacket.setDestination(message_t* msg, am_addr_t addr)
- {
- call IEEE154Packet.setDestAddr(msg, addr);
- }
-
- inline command void AMPacket.setSource(message_t* msg, am_addr_t addr)
- {
- call IEEE154Packet.setSrcAddr(msg, addr);
- }
-
- inline command bool AMPacket.isForMe(message_t* msg)
- {
- am_addr_t addr = call AMPacket.destination(msg);
- return addr == call AMPacket.address() || addr == AM_BROADCAST_ADDR;
- }
-
- inline command am_id_t AMPacket.type(message_t* msg)
- {
- return call IEEE154Packet.getType(msg);
- }
-
- inline command void AMPacket.setType(message_t* msg, am_id_t type)
- {
- call IEEE154Packet.setType(msg, type);
- }
-
- inline command am_group_t AMPacket.group(message_t* msg)
- {
- return call IEEE154Packet.getDestPan(msg);
- }
-
- inline command void AMPacket.setGroup(message_t* msg, am_group_t grp)
- {
- call IEEE154Packet.setDestPan(msg, grp);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#warning "*** USING LOW POWER LISTENING LAYER"
-
-configuration LowPowerListeningLayerC
-{
- provides
- {
- interface SplitControl;
- interface Send;
- interface Receive;
-
- interface LowPowerListening;
- }
- uses
- {
- interface SplitControl as SubControl;
- interface Send as SubSend;
- interface Receive as SubReceive;
-
- interface PacketField<uint16_t> as PacketSleepInterval;
- interface IEEE154Packet;
- interface PacketAcknowledgements;
- }
-}
-
-implementation
-{
- components LowPowerListeningLayerP, new TimerMilliC();
-
- SplitControl = LowPowerListeningLayerP;
- Send = LowPowerListeningLayerP;
- Receive = LowPowerListeningLayerP;
- LowPowerListening = LowPowerListeningLayerP;
-
- SubControl = LowPowerListeningLayerP;
- SubSend = LowPowerListeningLayerP;
- SubReceive = LowPowerListeningLayerP;
- PacketSleepInterval = LowPowerListeningLayerP;
- IEEE154Packet = LowPowerListeningLayerP;
- PacketAcknowledgements = LowPowerListeningLayerP;
-
- LowPowerListeningLayerP.Timer -> TimerMilliC;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <RadioAssert.h>
-
-module LowPowerListeningLayerP
-{
- provides
- {
- interface SplitControl;
- interface Send;
- interface Receive;
-
- interface LowPowerListening;
- }
-
- uses
- {
- interface SplitControl as SubControl;
- interface Send as SubSend;
- interface Receive as SubReceive;
-
- interface PacketField<uint16_t> as PacketSleepInterval;
- interface IEEE154Packet;
- interface PacketAcknowledgements;
- interface Timer<TMilli>;
- }
-}
-
-implementation
-{
- enum
- {
- // minimum wakeup time to catch a transmission in milliseconds
- LISTEN_WAKEUP = 6U, // use xxxL if LISTEN_WAKEUP * 10000 > 65535
-
- // extra wakeup time after receiving a message in milliseconds
- AFTER_RECEIVE = 10U,
-
- // extra wakeup time after transmitting a message in milliseconds
- AFTER_TRANSMIT = 10U,
-
- MIN_SLEEP = 2, // the minimum sleep interval in milliseconds
- MAX_SLEEP = 30000, // the maximum sleep interval in milliseconds
- MIN_DUTY = 2, // the minimum duty cycle
- };
-
- uint16_t sleepInterval;
-
- message_t* txMsg;
- uint8_t txLen;
- error_t txError;
-
-/*----------------- state machine -----------------*/
-
- enum
- {
- OFF = 0,
- OFF_SUBSTOP = 1, // must have consecutive indices
- OFF_SUBSTOP_DONE = 2, // must have consecutive indices
- OFF_STOP_END = 3, // must have consecutive indices
- OFF_START_END = 4,
-
- LISTEN_SUBSTART = 5, // must have consecutive indices
- LISTEN_SUBSTART_DONE = 6, // must have consecutive indices
- LISTEN_TIMER = 7, // must have consecutive indices
- LISTEN = 8, // must have consecutive indices
-
- SLEEP_SUBSTOP = 9, // must have consecutive indices
- SLEEP_SUBSTOP_DONE = 10, // must have consecutive indices
- SLEEP_TIMER = 11, // must have consecutive indices
- SLEEP = 12, // must have consecutive indices
-
- SEND_SUBSTART = 13, // must have consecutive indices
- SEND_SUBSTART_DONE = 14, // must have consecutive indices
- SEND_TIMER = 15, // must have consecutive indices
- SEND_SUBSEND= 16,
- SEND_SUBSEND_DONE = 17,
- SEND_SUBSEND_DONE_LAST = 18,
- SEND_DONE = 19,
- };
-
- uint8_t state;
-
- task void transition()
- {
- error_t error;
- uint16_t transmitInterval;
-
- if( state == LISTEN_SUBSTART || state == SEND_SUBSTART )
- {
- error = call SubControl.start();
- ASSERT( error == SUCCESS || error == EBUSY );
-
- if( error == SUCCESS )
- ++state;
- else
- post transition();
- }
- else if( state == SLEEP_SUBSTOP || state == OFF_SUBSTOP )
- {
- error = call SubControl.stop();
- ASSERT( error == SUCCESS || error == EBUSY );
-
- if( error == SUCCESS )
- ++state;
- else
- post transition();
- }
- else if( state == OFF_START_END )
- {
- state = LISTEN_SUBSTART;
- post transition();
-
- signal SplitControl.startDone(SUCCESS);
- }
- else if( state == OFF_STOP_END )
- {
- state = OFF;
- signal SplitControl.stopDone(SUCCESS);
- }
- else if( state == LISTEN_TIMER )
- {
- state = LISTEN;
- if( sleepInterval > 0 )
- call Timer.startOneShot(LISTEN_WAKEUP);
- }
- else if( state == SLEEP_TIMER )
- {
- if( sleepInterval > 0 )
- {
- state = SLEEP;
- call Timer.startOneShot(sleepInterval);
- }
- else
- {
- state = LISTEN_SUBSTART;
- post transition();
- }
- }
- else if( state == SEND_TIMER )
- {
- transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg);
-
- if( transmitInterval > 0 )
- call Timer.startOneShot(transmitInterval);
-
- state = SEND_SUBSEND;
- post transition();
- }
- else if( state == SEND_SUBSEND)
- {
- txError = call SubSend.send(txMsg, txLen);
-
- if( txError == SUCCESS )
- state = SEND_SUBSEND_DONE;
- else
- {
- state = SEND_DONE;
- post transition();
- }
- }
- else if( state == SEND_DONE )
- {
- state = LISTEN;
- if( sleepInterval > 0 )
- call Timer.startOneShot(AFTER_TRANSMIT);
-
- signal Send.sendDone(txMsg, txError);
- }
- }
-
- command error_t SplitControl.start()
- {
- if( state == OFF_START_END )
- return EBUSY;
- else if( state != OFF )
- return EALREADY;
-
- state = OFF_START_END;
- post transition();
-
- return SUCCESS;
- }
-
- event void SubControl.startDone(error_t error)
- {
- ASSERT( error == SUCCESS || error == EBUSY );
- ASSERT( state == LISTEN_SUBSTART_DONE || state == SEND_SUBSTART_DONE );
-
- if( error == SUCCESS )
- ++state;
- else
- --state;
-
- post transition();
- }
-
- command error_t SplitControl.stop()
- {
- if( state == SLEEP || state == LISTEN )
- {
- call Timer.stop();
- post transition();
- }
-
- if( state == LISTEN_TIMER || state == LISTEN || state == SLEEP_SUBSTOP )
- state = OFF_SUBSTOP;
- else if( state == SLEEP_SUBSTOP_DONE )
- state = OFF_SUBSTOP_DONE;
- else if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP )
- state = OFF_STOP_END;
- else if( state == OFF )
- return EALREADY;
- else
- return EBUSY;
-
- return SUCCESS;
- }
-
- event void SubControl.stopDone(error_t error)
- {
- ASSERT( error == SUCCESS || error == EBUSY );
- ASSERT( state == SLEEP_SUBSTOP_DONE || state == OFF_SUBSTOP_DONE );
-
- if( error == SUCCESS )
- ++state;
- else
- --state;
-
- post transition();
- }
-
- event void Timer.fired()
- {
- ASSERT( state == LISTEN || state == SLEEP || state == SEND_SUBSEND || state == SEND_SUBSEND_DONE );
-
- if( state == LISTEN )
- state = SLEEP_SUBSTOP;
- else if( state == SLEEP )
- state = LISTEN_SUBSTART;
- else if( state == SEND_SUBSEND_DONE )
- state = SEND_SUBSEND_DONE_LAST;
- else if( state == SEND_SUBSEND)
- state = SEND_DONE;
-
- post transition();
- }
-
- event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)
- {
- if( state == SLEEP_SUBSTOP )
- state = LISTEN;
-
- if( state == LISTEN && sleepInterval > 0 )
- call Timer.startOneShot(AFTER_RECEIVE);
-
- return signal Receive.receive(msg, payload, len);
- }
-
- command error_t Send.send(message_t* msg, uint8_t len)
- {
- if( state == LISTEN || state == SLEEP )
- {
- call Timer.stop();
- post transition();
- }
-
- if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP )
- state = SEND_SUBSTART;
- else if( state == LISTEN_SUBSTART_DONE )
- state = SEND_SUBSTART_DONE;
- else if( state == LISTEN_TIMER || state == SLEEP_SUBSTOP || state == LISTEN )
- state = SEND_TIMER;
- else
- return EBUSY;
-
- txMsg = msg;
- txLen = len;
- txError = FAIL;
-
- return SUCCESS;
- }
-
- command error_t Send.cancel(message_t* msg)
- {
- if( state == SEND_SUBSEND )
- {
- call Timer.stop();
- state = SEND_DONE;
- txError = ECANCEL;
- post transition();
-
- return SUCCESS;
- }
- else if( state == SEND_SUBSEND_DONE )
- {
- // we stop sending the message even if SubSend.cancel was not succesfull
- state = SEND_SUBSEND_DONE_LAST;
-
- return call SubSend.cancel(txMsg);
- }
- else
- return FAIL;
- }
-
- event void SubSend.sendDone(message_t* msg, error_t error)
- {
- ASSERT( state == SEND_SUBSEND_DONE || state == SEND_SUBSEND_DONE_LAST );
- ASSERT( msg == txMsg );
-
- txError = error;
-
- // TODO: extend the PacketAcknowledgements interface with getAckRequired
- if( error != SUCCESS
- || call LowPowerListening.getRxSleepInterval(msg) == 0
- || state == SEND_SUBSEND_DONE_LAST
- || (call IEEE154Packet.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) )
- {
- call Timer.stop();
- state = SEND_DONE;
- }
- else
- state = SEND_SUBSEND;
-
- post transition();
- }
-
- command uint8_t Send.maxPayloadLength()
- {
- return call SubSend.maxPayloadLength();
- }
-
- command void* Send.getPayload(message_t* msg, uint8_t len)
- {
- return call SubSend.getPayload(msg, len);
- }
-
-/*----------------- LowPowerListening -----------------*/
-
- command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle)
- {
- if( dutyCycle >= 10000 )
- return 0;
- else if( dutyCycle <= MIN_DUTY )
- return MAX_SLEEP;
-
- return ((10000U * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP;
- }
-
- command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval)
- {
- if( interval < MIN_SLEEP )
- return 10000;
- else if( interval >= MAX_SLEEP )
- return MIN_DUTY;
-
- return (10000U * LISTEN_WAKEUP) / (LISTEN_WAKEUP + interval);
- }
-
- command void LowPowerListening.setLocalSleepInterval(uint16_t interval)
- {
- if( interval < MIN_SLEEP )
- interval = 0;
- else if( interval > MAX_SLEEP )
- interval = MAX_SLEEP;
-
- sleepInterval = interval;
-
- if( (state == LISTEN && sleepInterval == 0) || state == SLEEP )
- {
- call Timer.stop();
- --state;
- post transition();
- }
- }
-
- command uint16_t LowPowerListening.getLocalSleepInterval()
- {
- return sleepInterval;
- }
-
- command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle)
- {
- call LowPowerListening.setLocalSleepInterval(
- call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
- }
-
- command uint16_t LowPowerListening.getLocalDutyCycle()
- {
- return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval);
- }
-
- command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval)
- {
- if( interval < MIN_SLEEP )
- interval = 0;
- else if( interval > MAX_SLEEP )
- interval = MAX_SLEEP;
-
- call PacketSleepInterval.set(msg, interval);
- }
-
- command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg)
- {
- if( ! call PacketSleepInterval.isSet(msg) )
- return sleepInterval;
-
- return call PacketSleepInterval.get(msg);
- }
-
- command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle)
- {
- call LowPowerListening.setRxSleepInterval(msg,
- call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
- }
-
- command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg)
- {
- return call LowPowerListening.sleepIntervalToDutyCycle(
- call LowPowerListening.getRxSleepInterval(msg));
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration MessageBufferLayerC
-{
- provides
- {
- interface SplitControl;
- interface Send;
- interface Receive;
- interface RadioChannel;
- }
- uses
- {
- interface RadioState;
- interface RadioSend;
- interface RadioReceive;
-
- interface Packet;
- }
-}
-
-implementation
-{
- components MessageBufferLayerP, MainC, TaskletC;
-
- MainC.SoftwareInit -> MessageBufferLayerP;
-
- SplitControl = MessageBufferLayerP;
- Send = MessageBufferLayerP;
- Receive = MessageBufferLayerP;
- RadioChannel = MessageBufferLayerP;
-
- RadioState = MessageBufferLayerP;
- MessageBufferLayerP.Tasklet -> TaskletC;
- RadioSend = MessageBufferLayerP;
- RadioReceive = MessageBufferLayerP;
-
- Packet = MessageBufferLayerP;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-#include <RadioAssert.h>
-
-module MessageBufferLayerP
-{
- provides
- {
- interface SplitControl;
- interface Init as SoftwareInit;
-
- interface Send;
- interface Receive;
- interface RadioChannel;
- }
- uses
- {
- interface RadioState;
- interface Tasklet;
- interface RadioSend;
- interface RadioReceive;
-
- interface Packet;
- }
-}
-
-implementation
-{
-/*----------------- State -----------------*/
-
- norace uint8_t state; // written only from tasks
- enum
- {
- STATE_READY = 0,
- STATE_TX_PENDING = 1,
- STATE_TX_SEND = 2,
- STATE_TX_DONE = 3,
- STATE_TURN_ON = 4,
- STATE_TURN_OFF = 5,
- STATE_CHANNEL = 6,
- };
-
- command error_t SplitControl.start()
- {
- error_t error;
-
- call Tasklet.suspend();
-
- if( state != STATE_READY )
- error = EBUSY;
- else
- error = call RadioState.turnOn();
-
- if( error == SUCCESS )
- state = STATE_TURN_ON;
-
- call Tasklet.resume();
-
- return error;
- }
-
- command error_t SplitControl.stop()
- {
- error_t error;
-
- call Tasklet.suspend();
-
- if( state != STATE_READY )
- error = EBUSY;
- else
- error = call RadioState.turnOff();
-
- if( error == SUCCESS )
- state = STATE_TURN_OFF;
-
- call Tasklet.resume();
-
- return error;
- }
-
- command error_t RadioChannel.setChannel(uint8_t channel)
- {
- error_t error;
-
- call Tasklet.suspend();
-
- if( state != STATE_READY )
- error = EBUSY;
- else
- error = call RadioState.setChannel(channel);
-
- if( error == SUCCESS )
- state = STATE_CHANNEL;
-
- call Tasklet.resume();
-
- return error;
- }
-
- command uint8_t RadioChannel.getChannel()
- {
- return call RadioState.getChannel();
- }
-
- task void stateDoneTask()
- {
- uint8_t s;
-
- s = state;
-
- // change the state before so we can be reentered from the event
- state = STATE_READY;
-
- if( s == STATE_TURN_ON )
- signal SplitControl.startDone(SUCCESS);
- else if( s == STATE_TURN_OFF )
- signal SplitControl.stopDone(SUCCESS);
- else if( s == STATE_CHANNEL )
- signal RadioChannel.setChannelDone();
- else // not our event, ignore it
- state = s;
- }
-
- tasklet_async event void RadioState.done()
- {
- post stateDoneTask();
- }
-
- default event void SplitControl.startDone(error_t error)
- {
- }
-
- default event void SplitControl.stopDone(error_t error)
- {
- }
-
- default event void RadioChannel.setChannelDone()
- {
- }
-
-/*----------------- Send -----------------*/
-
- message_t* txMsg;
- error_t txError;
- uint8_t retries;
-
- // Many EBUSY replies from RadioSend are normal if the channel is cognested
- enum { MAX_RETRIES = 5 };
-
- task void sendTask()
- {
- error_t error;
-
- ASSERT( state == STATE_TX_PENDING || state == STATE_TX_SEND );
-
- atomic error = txError;
- if( (state == STATE_TX_SEND && error == SUCCESS) || ++retries > MAX_RETRIES )
- state = STATE_TX_DONE;
- else
- {
- call Tasklet.suspend();
-
- error = call RadioSend.send(txMsg);
- if( error == SUCCESS )
- state = STATE_TX_SEND;
- else if( retries == MAX_RETRIES )
- state = STATE_TX_DONE;
- else
- state = STATE_TX_PENDING;
-
- call Tasklet.resume();
- }
-
- if( state == STATE_TX_DONE )
- {
- state = STATE_READY;
- signal Send.sendDone(txMsg, error);
- }
- }
-
- tasklet_async event void RadioSend.sendDone(error_t error)
- {
- ASSERT( state == STATE_TX_SEND );
-
- atomic txError = error;
- post sendTask();
- }
-
- command error_t Send.send(message_t* msg, uint8_t len)
- {
- if( len > call Packet.maxPayloadLength() )
- return EINVAL;
- else if( state != STATE_READY )
- return EBUSY;
-
- call Packet.setPayloadLength(msg, len);
-
- txMsg = msg;
- state = STATE_TX_PENDING;
- retries = 0;
- post sendTask();
-
- return SUCCESS;
- }
-
- tasklet_async event void RadioSend.ready()
- {
- if( state == STATE_TX_PENDING )
- post sendTask();
- }
-
- tasklet_async event void Tasklet.run()
- {
- }
-
- command error_t Send.cancel(message_t* msg)
- {
- if( state == STATE_TX_PENDING )
- {
- state = STATE_READY;
-
- // TODO: check if sendDone can be called before cancel returns
- signal Send.sendDone(msg, ECANCEL);
-
- return SUCCESS;
- }
- else
- return FAIL;
- }
-
- default event void Send.sendDone(message_t* msg, error_t error)
- {
- }
-
- inline command uint8_t Send.maxPayloadLength()
- {
- return call Packet.maxPayloadLength();
- }
-
- inline command void* Send.getPayload(message_t* msg, uint8_t len)
- {
- return call Packet.getPayload(msg, len);
- }
-
-/*----------------- Receive -----------------*/
-
- enum
- {
- RECEIVE_QUEUE_SIZE = 3,
- };
-
- message_t receiveQueueData[RECEIVE_QUEUE_SIZE];
- message_t* receiveQueue[RECEIVE_QUEUE_SIZE];
-
- uint8_t receiveQueueHead;
- uint8_t receiveQueueSize;
-
- command error_t SoftwareInit.init()
- {
- uint8_t i;
-
- for(i = 0; i < RECEIVE_QUEUE_SIZE; ++i)
- receiveQueue[i] = receiveQueueData + i;
-
- return SUCCESS;
- }
-
- tasklet_async event bool RadioReceive.header(message_t* msg)
- {
- bool notFull;
-
- // this prevents undeliverable messages to be acknowledged
- atomic notFull = receiveQueueSize < RECEIVE_QUEUE_SIZE;
-
- return notFull;
- }
-
- task void deliverTask()
- {
- // get rid of as many messages as possible without interveining tasks
- for(;;)
- {
- message_t* msg;
-
- atomic
- {
- if( receiveQueueSize == 0 )
- return;
-
- msg = receiveQueue[receiveQueueHead];
- }
-
- msg = signal Receive.receive(msg,
- call Packet.getPayload(msg, call Packet.maxPayloadLength()),
- call Packet.payloadLength(msg));
-
- atomic
- {
- receiveQueue[receiveQueueHead] = msg;
-
- if( ++receiveQueueHead >= RECEIVE_QUEUE_SIZE )
- receiveQueueHead = 0;
-
- --receiveQueueSize;
- }
- }
- }
-
- tasklet_async event message_t* RadioReceive.receive(message_t* msg)
- {
- message_t *m;
-
- atomic
- {
- if( receiveQueueSize >= RECEIVE_QUEUE_SIZE )
- m = msg;
- else
- {
- uint8_t index = receiveQueueHead + receiveQueueSize;
- if( index >= RECEIVE_QUEUE_SIZE )
- index -= RECEIVE_QUEUE_SIZE;
-
- m = receiveQueue[index];
- receiveQueue[index] = msg;
-
- ++receiveQueueSize;
- post deliverTask();
- }
- }
-
- return m;
- }
-
- default event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len)
- {
- return msg;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __NEIGHBORHOOD_H__
-#define __NEIGHBORHOOD_H__
-
-#ifndef NEIGHBORHOOD_SIZE
-#define NEIGHBORHOOD_SIZE 5
-#endif
-
-#endif//__NEIGHBORHOOD_H__
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-/**
- * Every component maintains its own neighborhood data. The Neighboorhood
- * component maintains only the nodeids and ages of the neighbors, and
- * evicts old entries from the table when necessary.
- */
-interface Neighborhood
-{
- /**
- * Returns the index of the neighbor in the table. If the node was not
- * found in the table, then the value NEIGHBORHOOD is returned,
- * otherwise an index in the range [0, NEIGHBORHOOD-1] is returned.
- */
- tasklet_async command uint8_t getIndex(am_addr_t id);
-
- /**
- * Returns the age of the given entry. The age is incremented by one
- * every time a new node is inserted into the neighborhood table that
- * is not already at the very end. If the age would get too large to
- * fit into a byte, then it is periodically reset to a smaller value.
- */
- tasklet_async command uint8_t getAge(uint8_t index);
-
- /**
- * Returns the node address for the given entry.
- */
- tasklet_async command am_addr_t getNode(uint8_t index);
-
- /**
- * Adds a new node into the neighborhood table. If this node was already
- * in the table, then it is just brought to the front (its age is reset
- * to zero). If the node was not in the table, then the oldest is evicted
- * and its entry is replaced with this node. The index of the entry
- * is returned in the range [0, NEIGHBORHOOD-1].
- */
- tasklet_async command uint8_t insertNode(am_addr_t id);
-
- /**
- * This event is fired when the oldest entry is replaced with a new
- * node. The same interface is used by many users, so all of them
- * will receive this event and can clear the corresponding entry.
- * After this event is fired, all flags for this entry are cleared
- * (see the NeighborhoodFlag interface)
- */
- tasklet_async event void evicted(uint8_t index);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration NeighborhoodC
-{
- provides interface Neighborhood;
-}
-
-implementation
-{
- components NeighborhoodP, MainC;
-
- Neighborhood = NeighborhoodP;
- MainC.SoftwareInit -> NeighborhoodP;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-/**
- * This interface provides one bit storage for each neighbor in a very
- * fast and conveint way (without using shifts for example).
- */
-interface NeighborhoodFlag
-{
- /**
- * Returns the value of the flag for the given index
- */
- tasklet_async command bool get(uint8_t index);
-
- /**
- * Sets the flag for the given index
- */
- tasklet_async command void set(uint8_t index);
-
- /**
- * Clears the flag for the given index. The flag is automatically
- * cleared after the Neighborhood.evicted event is fired.
- */
- tasklet_async command void clear(uint8_t index);
-
- /**
- * Clears the flag for all indices
- */
- tasklet_async command void clearAll();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-generic configuration NeighborhoodFlagC()
-{
- provides interface NeighborhoodFlag;
-}
-
-implementation
-{
- components NeighborhoodP;
-
- // TODO: make sure that no more than 8 flags are used at a time
- NeighborhoodFlag = NeighborhoodP.NeighborhoodFlag[unique("NeighborhoodFlag")];
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Neighborhood.h>
-
-module NeighborhoodP
-{
- provides
- {
- interface Init;
- interface Neighborhood;
- interface NeighborhoodFlag[uint8_t bit];
- }
-}
-
-implementation
-{
- tasklet_norace am_addr_t nodes[NEIGHBORHOOD_SIZE];
- tasklet_norace uint8_t ages[NEIGHBORHOOD_SIZE];
- tasklet_norace uint8_t flags[NEIGHBORHOOD_SIZE];
- tasklet_norace uint8_t time;
- tasklet_norace uint8_t last;
-
- command error_t Init.init()
- {
- uint8_t i;
-
- for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
- nodes[i] = AM_BROADCAST_ADDR;
-
- return SUCCESS;
- }
-
- inline tasklet_async command am_addr_t Neighborhood.getNode(uint8_t index)
- {
- return nodes[index];
- }
-
- inline tasklet_async command uint8_t Neighborhood.getAge(uint8_t index)
- {
- return time - ages[index];
- }
-
- tasklet_async uint8_t command Neighborhood.getIndex(am_addr_t node)
- {
- uint8_t i;
-
- if( nodes[last] == node )
- return last;
-
- for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
- {
- if( nodes[i] == node )
- {
- last = i;
- break;
- }
- }
-
- return i;
- }
-
- tasklet_async uint8_t command Neighborhood.insertNode(am_addr_t node)
- {
- uint8_t i;
- uint8_t maxAge;
-
- if( nodes[last] == node )
- {
- if( ages[last] == time )
- return last;
-
- ages[last] = ++time;
- maxAge = 0x80;
- }
- else
- {
- uint8_t oldest = 0;
- maxAge = 0;
-
- for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
- {
- uint8_t age;
-
- if( nodes[i] == node )
- {
- last = i;
- if( ages[i] == time )
- return i;
-
- ages[i] = ++time;
- maxAge = 0x80;
- break;
- }
-
- age = time - ages[i];
- if( age > maxAge )
- {
- maxAge = age;
- oldest = i;
- }
- }
-
- if( i == NEIGHBORHOOD_SIZE )
- {
- signal Neighborhood.evicted(oldest);
-
- last = oldest;
- nodes[oldest] = node;
- ages[oldest] = ++time;
- flags[oldest] = 0;
- }
- }
-
- if( (time & 0x7F) == 0x7F && maxAge >= 0x7F )
- {
- for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
- {
- if( (ages[i] | 0x7F) != time )
- ages[i] = time & 0x80;
- }
- }
-
- return last;
- }
-
- inline tasklet_async command bool NeighborhoodFlag.get[uint8_t bit](uint8_t index)
- {
- return flags[index] & (1 << bit);
- }
-
- inline tasklet_async command void NeighborhoodFlag.set[uint8_t bit](uint8_t index)
- {
- flags[index] |= (1 << bit);
- }
-
- inline tasklet_async command void NeighborhoodFlag.clear[uint8_t bit](uint8_t index)
- {
- flags[index] &= ~(1 << bit);
- }
-
- tasklet_async command void NeighborhoodFlag.clearAll[uint8_t bit]()
- {
- uint8_t i;
-
- bit = ~(1 << bit);
-
- for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
- flags[i] &= bit;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-interface PacketField<value_type>
-{
- /**
- * Returns TRUE if the value is set for this message.
- */
- async command bool isSet(message_t* msg);
-
- /**
- * Returns the stored value of this field in the message. If the
- * value is not set, then the returned value is undefined.
- */
- async command value_type get(message_t* msg);
-
- /**
- * Clears the isSet flag.
- */
- async command void clear(message_t* msg);
-
- /**
- * Sets the isSet false to TRUE and the time stamp value to the
- * specified value.
- */
- async command void set(message_t* msg, value_type value);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __RF2XX_H__
-#define __RF2XX_H__
-
-/* Set RF2XX_CHIPSET to one of these to enable specific features */
-#define RF230_CHIPSET 0
-#define RF212_CHIPSET 1
-
-enum rf2xx_registers_enum
-{
- RF2XX_TRX_STATUS = 0x01,
- RF2XX_TRX_STATE = 0x02,
- RF2XX_TRX_CTRL_0 = 0x03,
- RF2XX_PHY_TX_PWR = 0x05,
- RF2XX_PHY_RSSI = 0x06,
- RF2XX_PHY_ED_LEVEL = 0x07,
- RF2XX_PHY_CC_CCA = 0x08,
- RF2XX_CCA_THRES = 0x09,
- RF2XX_IRQ_MASK = 0x0E,
- RF2XX_IRQ_STATUS = 0x0F,
- RF2XX_VREG_CTRL = 0x10,
- RF2XX_BATMON = 0x11,
- RF2XX_XOSC_CTRL = 0x12,
- RF2XX_PLL_CF = 0x1A,
- RF2XX_PLL_DCU = 0x1B,
- RF2XX_PART_NUM = 0x1C,
- RF2XX_VERSION_NUM = 0x1D,
- RF2XX_MAN_ID_0 = 0x1E,
- RF2XX_MAN_ID_1 = 0x1F,
- RF2XX_SHORT_ADDR_0 = 0x20,
- RF2XX_SHORT_ADDR_1 = 0x21,
- RF2XX_PAN_ID_0 = 0x22,
- RF2XX_PAN_ID_1 = 0x23,
- RF2XX_IEEE_ADDR_0 = 0x24,
- RF2XX_IEEE_ADDR_1 = 0x25,
- RF2XX_IEEE_ADDR_2 = 0x26,
- RF2XX_IEEE_ADDR_3 = 0x27,
- RF2XX_IEEE_ADDR_4 = 0x28,
- RF2XX_IEEE_ADDR_5 = 0x29,
- RF2XX_IEEE_ADDR_6 = 0x2A,
- RF2XX_IEEE_ADDR_7 = 0x2B,
- RF2XX_XAH_CTRL = 0x2C,
- RF2XX_CSMA_SEED_0 = 0x2D,
- RF2XX_CSMA_SEED_1 = 0x2E,
-};
-
-enum rf2xx_trx_register_enums
-{
- RF2XX_CCA_DONE = 1 << 7,
- RF2XX_CCA_STATUS = 1 << 6,
- RF2XX_TRX_STATUS_MASK = 0x1F,
- RF2XX_P_ON = 0,
- RF2XX_BUSY_RX = 1,
- RF2XX_BUSY_TX = 2,
- RF2XX_RX_ON = 6,
- RF2XX_TRX_OFF = 8,
- RF2XX_PLL_ON = 9,
- RF2XX_SLEEP = 15,
- RF2XX_BUSY_RX_AACK = 16,
- RF2XX_BUSR_TX_ARET = 17,
- RF2XX_RX_AACK_ON = 22,
- RF2XX_TX_ARET_ON = 25,
- RF2XX_RX_ON_NOCLK = 28,
- RF2XX_AACK_ON_NOCLK = 29,
- RF2XX_BUSY_RX_AACK_NOCLK = 30,
- RF2XX_STATE_TRANSITION_IN_PROGRESS = 31,
- RF2XX_TRAC_STATUS_MASK = 0xE0,
- RF2XX_TRAC_SUCCESS = 0,
- RF2XX_TRAC_CHANNEL_ACCESS_FAILURE = 3 << 5,
- RF2XX_TRAC_NO_ACK = 5 << 5,
- RF2XX_TRX_CMD_MASK = 0x1F,
- RF2XX_NOP = 0,
- RF2XX_TX_START = 2,
- RF2XX_FORCE_TRX_OFF = 3,
-};
-
-enum rf2xx_phy_register_enums
-{
- RF2XX_TX_AUTO_CRC_ON = 1 << 7,
- RF2XX_TX_PWR_MASK = 0x0F,
- RF2XX_TX_PWR_DEFAULT = 0,
- RF2XX_RSSI_MASK = 0x1F,
- RF2XX_CCA_REQUEST = 1 << 7,
- RF2XX_CCA_MODE_0 = 0 << 5,
- RF2XX_CCA_MODE_1 = 1 << 5,
- RF2XX_CCA_MODE_2 = 2 << 5,
- RF2XX_CCA_MODE_3 = 3 << 5,
- RF2XX_CHANNEL_DEFAULT = 11,
- RF2XX_CHANNEL_MASK = 0x1F,
- RF2XX_CCA_CS_THRES_SHIFT = 4,
- RF2XX_CCA_ED_THRES_SHIFT = 0,
-};
-
-enum rf2xx_irq_register_enums
-{
- RF2XX_IRQ_BAT_LOW = 1 << 7,
- RF2XX_IRQ_TRX_UR = 1 << 6,
- RF2XX_IRQ_TRX_END = 1 << 3,
- RF2XX_IRQ_RX_START = 1 << 2,
- RF2XX_IRQ_PLL_UNLOCK = 1 << 1,
- RF2XX_IRQ_PLL_LOCK = 1 << 0,
-};
-
-enum rf2xx_control_register_enums
-{
- RF2XX_AVREG_EXT = 1 << 7,
- RF2XX_AVDD_OK = 1 << 6,
- RF2XX_DVREG_EXT = 1 << 3,
- RF2XX_DVDD_OK = 1 << 2,
- RF2XX_BATMON_OK = 1 << 5,
- RF2XX_BATMON_VHR = 1 << 4,
- RF2XX_BATMON_VTH_MASK = 0x0F,
- RF2XX_XTAL_MODE_OFF = 0 << 4,
- RF2XX_XTAL_MODE_EXTERNAL = 4 << 4,
- RF2XX_XTAL_MODE_INTERNAL = 15 << 4,
-};
-
-enum rf2xx_pll_register_enums
-{
- RF2XX_PLL_CF_START = 1 << 7,
- RF2XX_PLL_DCU_START = 1 << 7,
-};
-
-enum rf2xx_spi_command_enums
-{
- RF2XX_CMD_REGISTER_READ = 0x80,
- RF2XX_CMD_REGISTER_WRITE = 0xC0,
- RF2XX_CMD_REGISTER_MASK = 0x3F,
- RF2XX_CMD_FRAME_READ = 0x20,
- RF2XX_CMD_FRAME_WRITE = 0x60,
- RF2XX_CMD_SRAM_READ = 0x00,
- RF2XX_CMD_SRAM_WRITE = 0x40,
-};
-
-#endif//__RF2XX_H__
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <RadioAlarm.h>
-
-configuration RF2xxActiveMessageC
-{
- provides
- {
- interface SplitControl;
-
- interface AMSend[am_id_t id];
- interface Receive[am_id_t id];
- interface Receive as Snoop[am_id_t id];
-
- interface Packet;
- interface AMPacket;
- interface PacketAcknowledgements;
- interface LowPowerListening;
- interface RadioChannel;
-
- interface PacketField<uint8_t> as PacketLinkQuality;
- interface PacketField<uint8_t> as PacketTransmitPower;
- interface PacketField<uint8_t> as PacketRSSI;
-
- interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
- interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
- }
-}
-
-implementation
-{
- components RF2xxActiveMessageP, RF2xxPacketC, IEEE154PacketC, RadioAlarmC;
-
-#ifdef RF2XX_DEBUG
- components AssertC;
-#endif
-
- RF2xxActiveMessageP.IEEE154Packet -> IEEE154PacketC;
- RF2xxActiveMessageP.Packet -> RF2xxPacketC;
- RF2xxActiveMessageP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
-
- Packet = RF2xxPacketC;
- AMPacket = RF2xxPacketC;
- PacketAcknowledgements = RF2xxPacketC;
- PacketLinkQuality = RF2xxPacketC.PacketLinkQuality;
- PacketTransmitPower = RF2xxPacketC.PacketTransmitPower;
- PacketRSSI = RF2xxPacketC.PacketRSSI;
- PacketTimeStampRadio = RF2xxPacketC;
- PacketTimeStampMilli = RF2xxPacketC;
- LowPowerListening = LowPowerListeningLayerC;
- RadioChannel = MessageBufferLayerC;
-
- components ActiveMessageLayerC;
-#ifdef TFRAMES_ENABLED
- components new DummyLayerC() as IEEE154NetworkLayerC;
-#else
- components IEEE154NetworkLayerC;
-#endif
-#ifdef LOW_POWER_LISTENING
- components LowPowerListeningLayerC;
-#else
- components new DummyLayerC() as LowPowerListeningLayerC;
-#endif
- components MessageBufferLayerC;
- components UniqueLayerC;
- components TrafficMonitorLayerC;
-#ifdef RF2XX_SLOTTED_MAC
- components SlottedCollisionLayerC as CollisionAvoidanceLayerC;
-#else
- components RandomCollisionLayerC as CollisionAvoidanceLayerC;
-#endif
- components SoftwareAckLayerC;
- components new DummyLayerC() as CsmaLayerC;
- components RF2xxDriverLayerC;
-
- SplitControl = LowPowerListeningLayerC;
- AMSend = ActiveMessageLayerC;
- Receive = ActiveMessageLayerC.Receive;
- Snoop = ActiveMessageLayerC.Snoop;
-
- ActiveMessageLayerC.Config -> RF2xxActiveMessageP;
- ActiveMessageLayerC.AMPacket -> IEEE154PacketC;
- ActiveMessageLayerC.SubSend -> IEEE154NetworkLayerC;
- ActiveMessageLayerC.SubReceive -> IEEE154NetworkLayerC;
-
- IEEE154NetworkLayerC.SubSend -> UniqueLayerC;
- IEEE154NetworkLayerC.SubReceive -> LowPowerListeningLayerC;
-
- // the UniqueLayer is wired at two points
- UniqueLayerC.Config -> RF2xxActiveMessageP;
- UniqueLayerC.SubSend -> LowPowerListeningLayerC;
-
- LowPowerListeningLayerC.SubControl -> MessageBufferLayerC;
- LowPowerListeningLayerC.SubSend -> MessageBufferLayerC;
- LowPowerListeningLayerC.SubReceive -> MessageBufferLayerC;
-#ifdef LOW_POWER_LISTENING
- LowPowerListeningLayerC.PacketSleepInterval -> RF2xxPacketC;
- LowPowerListeningLayerC.IEEE154Packet -> IEEE154PacketC;
- LowPowerListeningLayerC.PacketAcknowledgements -> RF2xxPacketC;
-#endif
-
- MessageBufferLayerC.Packet -> RF2xxPacketC;
- MessageBufferLayerC.RadioSend -> TrafficMonitorLayerC;
- MessageBufferLayerC.RadioReceive -> UniqueLayerC;
- MessageBufferLayerC.RadioState -> TrafficMonitorLayerC;
-
- UniqueLayerC.SubReceive -> TrafficMonitorLayerC;
-
- TrafficMonitorLayerC.Config -> RF2xxActiveMessageP;
- TrafficMonitorLayerC.SubSend -> CollisionAvoidanceLayerC;
- TrafficMonitorLayerC.SubReceive -> CollisionAvoidanceLayerC;
- TrafficMonitorLayerC.SubState -> RF2xxDriverLayerC;
-
- CollisionAvoidanceLayerC.Config -> RF2xxActiveMessageP;
- CollisionAvoidanceLayerC.SubSend -> SoftwareAckLayerC;
- CollisionAvoidanceLayerC.SubReceive -> SoftwareAckLayerC;
-
- SoftwareAckLayerC.Config -> RF2xxActiveMessageP;
- SoftwareAckLayerC.SubSend -> CsmaLayerC;
- SoftwareAckLayerC.SubReceive -> RF2xxDriverLayerC;
-
- CsmaLayerC.Config -> RF2xxActiveMessageP;
- CsmaLayerC -> RF2xxDriverLayerC.RadioSend;
- CsmaLayerC -> RF2xxDriverLayerC.RadioCCA;
-
- RF2xxDriverLayerC.RF2xxDriverConfig -> RF2xxActiveMessageP;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <RF2xxPacket.h>
-#include <RadioAlarm.h>
-#include <Tasklet.h>
-#include <HplRF2xx.h>
-
-module RF2xxActiveMessageP
-{
- provides
- {
- interface RF2xxDriverConfig;
- interface SoftwareAckConfig;
- interface UniqueConfig;
- interface CsmaConfig;
- interface TrafficMonitorConfig;
- interface RandomCollisionConfig;
- interface SlottedCollisionConfig;
- interface ActiveMessageConfig;
- interface DummyConfig;
- }
-
- uses
- {
- interface IEEE154Packet;
- interface Packet;
- interface RadioAlarm;
- }
-}
-
-implementation
-{
-/*----------------- RF2xxDriverConfig -----------------*/
-
- async command uint8_t RF2xxDriverConfig.getLength(message_t* msg)
- {
- return call IEEE154Packet.getLength(msg);
- }
-
- async command void RF2xxDriverConfig.setLength(message_t* msg, uint8_t len)
- {
- call IEEE154Packet.setLength(msg, len);
- }
-
- async command uint8_t* RF2xxDriverConfig.getPayload(message_t* msg)
- {
- return ((uint8_t*)(call IEEE154Packet.getHeader(msg))) + 1;
- }
-
- inline rf2xxpacket_metadata_t* getMeta(message_t* msg)
- {
- return (rf2xxpacket_metadata_t*)(msg->metadata);
- }
-
- async command uint8_t RF2xxDriverConfig.getHeaderLength()
- {
- // we need the fcf, dsn, destpan and dest
- return 7;
- }
-
- async command uint8_t RF2xxDriverConfig.getMaxLength()
- {
- // note, that the ieee154_footer_t is not stored, but we should include it here
- return sizeof(rf2xxpacket_header_t) - 1 + TOSH_DATA_LENGTH + sizeof(ieee154_footer_t);
- }
-
- async command uint8_t RF2xxDriverConfig.getDefaultChannel()
- {
- return RF2XX_DEF_CHANNEL;
- }
-
- async command bool RF2xxDriverConfig.requiresRssiCca(message_t* msg)
- {
- return call IEEE154Packet.isDataFrame(msg);
- }
-
-/*----------------- SoftwareAckConfig -----------------*/
-
- async command bool SoftwareAckConfig.requiresAckWait(message_t* msg)
- {
- return call IEEE154Packet.requiresAckWait(msg);
- }
-
- async command bool SoftwareAckConfig.isAckPacket(message_t* msg)
- {
- return call IEEE154Packet.isAckFrame(msg);
- }
-
- async command bool SoftwareAckConfig.verifyAckPacket(message_t* data, message_t* ack)
- {
- return call IEEE154Packet.verifyAckReply(data, ack);
- }
-
- async command bool SoftwareAckConfig.requiresAckReply(message_t* msg)
- {
- return call IEEE154Packet.requiresAckReply(msg);
- }
-
- async command void SoftwareAckConfig.createAckPacket(message_t* data, message_t* ack)
- {
- call IEEE154Packet.createAckReply(data, ack);
- }
-
- async command void SoftwareAckConfig.setAckReceived(message_t* msg, bool acked)
- {
- if( acked )
- getMeta(msg)->flags |= RF2XXPACKET_WAS_ACKED;
- else
- getMeta(msg)->flags &= ~RF2XXPACKET_WAS_ACKED;
- }
-
- async command uint16_t SoftwareAckConfig.getAckTimeout()
- {
- return (uint16_t)(800 * RADIO_ALARM_MICROSEC);
- }
-
- tasklet_async command void SoftwareAckConfig.reportChannelError()
- {
- signal TrafficMonitorConfig.channelError();
- }
-
-/*----------------- UniqueConfig -----------------*/
-
- async command uint8_t UniqueConfig.getSequenceNumber(message_t* msg)
- {
- return call IEEE154Packet.getDSN(msg);
- }
-
- async command void UniqueConfig.setSequenceNumber(message_t* msg, uint8_t dsn)
- {
- call IEEE154Packet.setDSN(msg, dsn);
- }
-
- async command am_addr_t UniqueConfig.getSender(message_t* msg)
- {
- return call IEEE154Packet.getSrcAddr(msg);
- }
-
- tasklet_async command void UniqueConfig.reportChannelError()
- {
- signal TrafficMonitorConfig.channelError();
- }
-
-/*----------------- ActiveMessageConfig -----------------*/
-
- command error_t ActiveMessageConfig.checkPacket(message_t* msg)
- {
- // the user forgot to call clear, we should return EINVAL
- if( ! call IEEE154Packet.isDataFrame(msg) )
- call Packet.clear(msg);
-
- return SUCCESS;
- }
-
-/*----------------- CsmaConfig -----------------*/
-
- async command bool CsmaConfig.requiresSoftwareCCA(message_t* msg)
- {
- return call IEEE154Packet.isDataFrame(msg);
- }
-
-/*----------------- TrafficMonitorConfig -----------------*/
-
- enum
- {
- TRAFFIC_UPDATE_PERIOD = 100, // in milliseconds
- TRAFFIC_MAX_BYTES = (uint16_t)(TRAFFIC_UPDATE_PERIOD * 1000UL / 32), // 3125
- };
-
- async command uint16_t TrafficMonitorConfig.getUpdatePeriod()
- {
- return TRAFFIC_UPDATE_PERIOD;
- }
-
- async command uint16_t TrafficMonitorConfig.getChannelTime(message_t* msg)
- {
- /* We count in bytes, one byte is 32 microsecond. We are conservative here.
- *
- * pure airtime: preable (4 bytes), SFD (1 byte), length (1 byte), payload + CRC (len bytes)
- * frame separation: 5-10 bytes
- * ack required: 8-16 byte separation, 11 bytes airtime, 5-10 bytes separation
- */
-
- uint8_t len = call IEEE154Packet.getLength(msg);
- return call IEEE154Packet.getAckRequired(msg) ? len + 6 + 16 + 11 + 10 : len + 6 + 10;
- }
-
- async command am_addr_t TrafficMonitorConfig.getSender(message_t* msg)
- {
- return call IEEE154Packet.getSrcAddr(msg);
- }
-
- tasklet_async command void TrafficMonitorConfig.timerTick()
- {
- signal SlottedCollisionConfig.timerTick();
- }
-
-/*----------------- RandomCollisionConfig -----------------*/
-
- /*
- * We try to use the same values as in CC2420
- *
- * CC2420_MIN_BACKOFF = 10 jiffies = 320 microsec
- * CC2420_BACKOFF_PERIOD = 10 jiffies
- * initial backoff = 0x1F * CC2420_BACKOFF_PERIOD = 310 jiffies = 9920 microsec
- * congestion backoff = 0x7 * CC2420_BACKOFF_PERIOD = 70 jiffies = 2240 microsec
- */
-
- async command uint16_t RandomCollisionConfig.getMinimumBackoff()
- {
- return (uint16_t)(320 * RADIO_ALARM_MICROSEC);
- }
-
- async command uint16_t RandomCollisionConfig.getInitialBackoff(message_t* msg)
- {
- return (uint16_t)(9920 * RADIO_ALARM_MICROSEC);
- }
-
- async command uint16_t RandomCollisionConfig.getCongestionBackoff(message_t* msg)
- {
- return (uint16_t)(2240 * RADIO_ALARM_MICROSEC);
- }
-
- async command uint16_t RandomCollisionConfig.getTransmitBarrier(message_t* msg)
- {
- uint16_t time;
-
- // TODO: maybe we should use the embedded timestamp of the message
- time = call RadioAlarm.getNow();
-
- // estimated response time (download the message, etc) is 5-8 bytes
- if( call IEEE154Packet.requiresAckReply(msg) )
- time += (uint16_t)(32 * (-5 + 16 + 11 + 5) * RADIO_ALARM_MICROSEC);
- else
- time += (uint16_t)(32 * (-5 + 5) * RADIO_ALARM_MICROSEC);
-
- return time;
- }
-
- tasklet_async event void RadioAlarm.fired() { }
-
-/*----------------- SlottedCollisionConfig -----------------*/
-
- async command uint16_t SlottedCollisionConfig.getInitialDelay()
- {
- return 300;
- }
-
- async command uint8_t SlottedCollisionConfig.getScheduleExponent()
- {
- return 11;
- }
-
- async command uint16_t SlottedCollisionConfig.getTransmitTime(message_t* msg)
- {
- // TODO: check if the timestamp is correct
- return getMeta(msg)->timestamp;
- }
-
- async command uint16_t SlottedCollisionConfig.getCollisionWindowStart(message_t* msg)
- {
- // the preamble (4 bytes), SFD (1 byte), plus two extra for safety
- return getMeta(msg)->timestamp - (uint16_t)(7 * 32 * RADIO_ALARM_MICROSEC);
- }
-
- async command uint16_t SlottedCollisionConfig.getCollisionWindowLength(message_t* msg)
- {
- return (uint16_t)(2 * 7 * 32 * RADIO_ALARM_MICROSEC);
- }
-
- default tasklet_async event void SlottedCollisionConfig.timerTick() { }
-
-/*----------------- Dummy -----------------*/
-
- async command void DummyConfig.nothing()
- {
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-/**
- * This interface needs to be implemented by the MAC to control the behaviour
- * of the RF2xxDriverLayerC component.
- */
-interface RF2xxDriverConfig
-{
- /**
- * Returns the length of the PHY payload (including the FCF field).
- * This value must be in the range [3, 127].
- */
- async command uint8_t getLength(message_t* msg);
-
- /**
- * Sets the length of the PHY payload.
- */
- async command void setLength(message_t* msg, uint8_t len);
-
- /**
- * Returns a pointer to the start of the PHY payload that contains
- * getLength()-2 number of bytes. The FCF field (CRC-16) is not stored,
- * but automatically appended / verified.
- */
- async command uint8_t* getPayload(message_t* msg);
-
- /**
- * Gets the number of bytes we should read before the RadioReceive.header
- * event is fired. If the length of the packet is less than this amount,
- * then that event is fired earlier. The header length must be at least one.
- */
- async command uint8_t getHeaderLength();
-
- /**
- * Returns the maximum PHY length that can be set via the setLength command
- */
- async command uint8_t getMaxLength();
-
- /**
- * This command is used at power up to set the default channel.
- * The default CC2420 channel is 26.
- */
- async command uint8_t getDefaultChannel();
-
- /**
- * Returns TRUE if before sending this message we should make sure that
- * the channel is clear via a very basic (and quick) RSSI check.
- */
- async command bool requiresRssiCca(message_t* msg);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration RF2xxDriverLayerC
-{
- provides
- {
- interface RadioState;
- interface RadioSend;
- interface RadioReceive;
- interface RadioCCA;
- }
-
- uses interface RF2xxDriverConfig;
-}
-
-implementation
-{
- components RF2xxDriverLayerP, HplRF2xxC, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC, RF2xxPacketC, LocalTimeMicroC as LocalTimeRadioC;
-
- RadioState = RF2xxDriverLayerP;
- RadioSend = RF2xxDriverLayerP;
- RadioReceive = RF2xxDriverLayerP;
- RadioCCA = RF2xxDriverLayerP;
-
- RF2xxDriverConfig = RF2xxDriverLayerP;
-
- RF2xxDriverLayerP.PacketLinkQuality -> RF2xxPacketC.PacketLinkQuality;
- RF2xxDriverLayerP.PacketTransmitPower -> RF2xxPacketC.PacketTransmitPower;
- RF2xxDriverLayerP.PacketRSSI -> RF2xxPacketC.PacketRSSI;
- RF2xxDriverLayerP.PacketTimeSyncOffset -> RF2xxPacketC.PacketTimeSyncOffset;
- RF2xxDriverLayerP.PacketTimeStamp -> RF2xxPacketC;
- RF2xxDriverLayerP.LocalTime -> LocalTimeRadioC;
-
- RF2xxDriverLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
- RadioAlarmC.Alarm -> HplRF2xxC.Alarm;
-
- RF2xxDriverLayerP.SELN -> HplRF2xxC.SELN;
- RF2xxDriverLayerP.SpiResource -> HplRF2xxC.SpiResource;
- RF2xxDriverLayerP.FastSpiByte -> HplRF2xxC;
-
- RF2xxDriverLayerP.SLP_TR -> HplRF2xxC.SLP_TR;
- RF2xxDriverLayerP.RSTN -> HplRF2xxC.RSTN;
-
- RF2xxDriverLayerP.IRQ -> HplRF2xxC.IRQ;
- RF2xxDriverLayerP.Tasklet -> TaskletC;
- RF2xxDriverLayerP.BusyWait -> BusyWaitMicroC;
-
-#ifdef RF2XX_DEBUG
- components DiagMsgC;
- RF2xxDriverLayerP.DiagMsg -> DiagMsgC;
-#endif
-
- MainC.SoftwareInit -> RF2xxDriverLayerP.SoftwareInit;
-
- components RealMainP;
- RealMainP.PlatformInit -> RF2xxDriverLayerP.PlatformInit;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <RF2xx.h>
-#include <HplRF2xx.h>
-#include <Tasklet.h>
-#include <RadioAssert.h>
-#include <TimeSyncMessage.h>
-#include <RadioAlarm.h>
-
-module RF2xxDriverLayerP
-{
- provides
- {
- interface Init as PlatformInit @exactlyonce();
- interface Init as SoftwareInit @exactlyonce();
-
- interface RadioState;
- interface RadioSend;
- interface RadioReceive;
- interface RadioCCA;
- }
-
- uses
- {
- interface GeneralIO as SELN;
- interface Resource as SpiResource;
-
- interface FastSpiByte;
-
- interface GeneralIO as SLP_TR;
- interface GeneralIO as RSTN;
-
- interface GpioCapture as IRQ;
-
- interface BusyWait<TMicro, uint16_t>;
-
- interface PacketField<uint8_t> as PacketLinkQuality;
- interface PacketField<uint8_t> as PacketTransmitPower;
- interface PacketField<uint8_t> as PacketRSSI;
- interface PacketField<uint8_t> as PacketTimeSyncOffset;
-
- interface PacketTimeStamp<TRadio, uint32_t>;
- interface LocalTime<TRadio>;
-
- interface RF2xxDriverConfig;
- interface Tasklet;
- interface RadioAlarm;
-
-#ifdef RF2XX_DEBUG
- interface DiagMsg;
-#endif
- }
-}
-
-implementation
-{
-/*----------------- STATE -----------------*/
-
- tasklet_norace uint8_t state;
- enum
- {
- STATE_P_ON = 0,
- STATE_SLEEP = 1,
- STATE_SLEEP_2_TRX_OFF = 2,
- STATE_TRX_OFF = 3,
- STATE_TRX_OFF_2_RX_ON = 4,
- STATE_RX_ON = 5,
- STATE_BUSY_TX_2_RX_ON = 6,
- STATE_PLL_ON_2_RX_ON = 7,
- };
-
- tasklet_norace uint8_t cmd;
- enum
- {
- CMD_NONE = 0, // the state machine has stopped
- CMD_TURNOFF = 1, // goto SLEEP state
- CMD_STANDBY = 2, // goto TRX_OFF state
- CMD_TURNON = 3, // goto RX_ON state
- CMD_TRANSMIT = 4, // currently transmitting a message
- CMD_RECEIVE = 5, // currently receiving a message
- CMD_CCA = 6, // performing clear chanel assesment
- CMD_CHANNEL = 7, // changing the channel
- CMD_SIGNAL_DONE = 8, // signal the end of the state transition
- CMD_DOWNLOAD = 9, // download the received message
- };
-
- norace bool radioIrq;
-
- tasklet_norace uint8_t txPower;
- tasklet_norace uint8_t channel;
-
- tasklet_norace message_t* rxMsg;
- message_t rxMsgBuffer;
-
- uint16_t capturedTime; // the current time when the last interrupt has occured
-
- tasklet_norace uint8_t rssiClear;
- tasklet_norace uint8_t rssiBusy;
-
-/*----------------- REGISTER -----------------*/
-
- inline void writeRegister(uint8_t reg, uint8_t value)
- {
- ASSERT( call SpiResource.isOwner() );
- ASSERT( reg == (reg & RF2XX_CMD_REGISTER_MASK) );
-
- call SELN.clr();
- call FastSpiByte.splitWrite(RF2XX_CMD_REGISTER_WRITE | reg);
- call FastSpiByte.splitReadWrite(value);
- call FastSpiByte.splitRead();
- call SELN.set();
- }
-
- inline uint8_t readRegister(uint8_t reg)
- {
- ASSERT( call SpiResource.isOwner() );
- ASSERT( reg == (reg & RF2XX_CMD_REGISTER_MASK) );
-
- call SELN.clr();
- call FastSpiByte.splitWrite(RF2XX_CMD_REGISTER_READ | reg);
- call FastSpiByte.splitReadWrite(0);
- reg = call FastSpiByte.splitRead();
- call SELN.set();
-
- return reg;
- }
-
-/*----------------- ALARM -----------------*/
-
- enum
- {
- SLEEP_WAKEUP_TIME = (uint16_t)(880 * RADIO_ALARM_MICROSEC),
- CCA_REQUEST_TIME = (uint16_t)(140 * RADIO_ALARM_MICROSEC),
-
- TX_SFD_DELAY = (uint16_t)(176 * RADIO_ALARM_MICROSEC),
- RX_SFD_DELAY = (uint16_t)(8 * RADIO_ALARM_MICROSEC),
- };
-
- tasklet_async event void RadioAlarm.fired()
- {
- if( state == STATE_SLEEP_2_TRX_OFF )
- state = STATE_TRX_OFF;
- else if( cmd == CMD_CCA )
- {
- uint8_t cca;
-
- ASSERT( state == STATE_RX_ON );
-
- cmd = CMD_NONE;
- cca = readRegister(RF2XX_TRX_STATUS);
-
- ASSERT( (cca & RF2XX_TRX_STATUS_MASK) == RF2XX_RX_ON );
-
- signal RadioCCA.done( (cca & RF2XX_CCA_DONE) ? ((cca & RF2XX_CCA_STATUS) ? SUCCESS : EBUSY) : FAIL );
- }
- else
- ASSERT(FALSE);
-
- // make sure the rest of the command processing is called
- call Tasklet.schedule();
- }
-
-/*----------------- INIT -----------------*/
-
- command error_t PlatformInit.init()
- {
- call SELN.makeOutput();
- call SELN.set();
- call SLP_TR.makeOutput();
- call SLP_TR.clr();
- call RSTN.makeOutput();
- call RSTN.set();
-
- rxMsg = &rxMsgBuffer;
-
- // these are just good approximates
- rssiClear = 0;
- rssiBusy = 90;
-
- return SUCCESS;
- }
-
- command error_t SoftwareInit.init()
- {
- // for powering up the radio
- return call SpiResource.request();
- }
-
- void initRadio()
- {
- call BusyWait.wait(510);
-
- call RSTN.clr();
- call SLP_TR.clr();
- call BusyWait.wait(6);
- call RSTN.set();
-
- writeRegister(RF2XX_TRX_CTRL_0, RF2XX_TRX_CTRL_0_VALUE);
- writeRegister(RF2XX_TRX_STATE, RF2XX_TRX_OFF);
-
- call BusyWait.wait(510);
-
- writeRegister(RF2XX_IRQ_MASK, RF2XX_IRQ_TRX_UR | RF2XX_IRQ_PLL_LOCK | RF2XX_IRQ_TRX_END | RF2XX_IRQ_RX_START);
- writeRegister(RF2XX_CCA_THRES, RF2XX_CCA_THRES_VALUE);
- writeRegister(RF2XX_PHY_TX_PWR, RF2XX_TX_AUTO_CRC_ON | RF2XX_TX_PWR_DEFAULT);
-
- txPower = RF2XX_TX_PWR_DEFAULT;
- channel = call RF2xxDriverConfig.getDefaultChannel() & RF2XX_CHANNEL_MASK;
- writeRegister(RF2XX_PHY_CC_CCA, RF2XX_CCA_MODE_VALUE | channel);
-
- call SLP_TR.set();
- state = STATE_SLEEP;
- }
-
-/*----------------- SPI -----------------*/
-
- event void SpiResource.granted()
- {
- call SELN.makeOutput();
- call SELN.set();
-
- if( state == STATE_P_ON )
- {
- initRadio();
- call SpiResource.release();
- }
- else
- call Tasklet.schedule();
- }
-
- bool isSpiAcquired()
- {
- if( call SpiResource.isOwner() )
- return TRUE;
-
- if( call SpiResource.immediateRequest() == SUCCESS )
- {
- call SELN.makeOutput();
- call SELN.set();
-
- return TRUE;
- }
-
- call SpiResource.request();
- return FALSE;
- }
-
-/*----------------- CHANNEL -----------------*/
-
- tasklet_async command uint8_t RadioState.getChannel()
- {
- return channel;
- }
-
- tasklet_async command error_t RadioState.setChannel(uint8_t c)
- {
- c &= RF2XX_CHANNEL_MASK;
-
- if( cmd != CMD_NONE )
- return EBUSY;
- else if( channel == c )
- return EALREADY;
-
- channel = c;
- cmd = CMD_CHANNEL;
- call Tasklet.schedule();
-
- return SUCCESS;
- }
-
- inline void changeChannel()
- {
- ASSERT( cmd == CMD_CHANNEL );
- ASSERT( state == STATE_SLEEP || state == STATE_TRX_OFF || state == STATE_RX_ON );
-
- if( isSpiAcquired() )
- {
- writeRegister(RF2XX_PHY_CC_CCA, RF2XX_CCA_MODE_VALUE | channel);
-
- if( state == STATE_RX_ON )
- state = STATE_TRX_OFF_2_RX_ON;
- else
- cmd = CMD_SIGNAL_DONE;
- }
- }
-
-/*----------------- TURN ON/OFF -----------------*/
-
- inline void changeState()
- {
- if( (cmd == CMD_STANDBY || cmd == CMD_TURNON)
- && state == STATE_SLEEP && call RadioAlarm.isFree() )
- {
- call SLP_TR.clr();
-
- call RadioAlarm.wait(SLEEP_WAKEUP_TIME);
- state = STATE_SLEEP_2_TRX_OFF;
- }
- else if( cmd == CMD_TURNON && state == STATE_TRX_OFF && isSpiAcquired() )
- {
- ASSERT( ! radioIrq );
-
- readRegister(RF2XX_IRQ_STATUS); // clear the interrupt register
- call IRQ.captureRisingEdge();
-
- // setChannel was ignored in SLEEP because the SPI was not working, so do it here
- writeRegister(RF2XX_PHY_CC_CCA, RF2XX_CCA_MODE_VALUE | channel);
-
- writeRegister(RF2XX_TRX_STATE, RF2XX_RX_ON);
- state = STATE_TRX_OFF_2_RX_ON;
- }
- else if( (cmd == CMD_TURNOFF || cmd == CMD_STANDBY)
- && state == STATE_RX_ON && isSpiAcquired() )
- {
- writeRegister(RF2XX_TRX_STATE, RF2XX_FORCE_TRX_OFF);
-
- call IRQ.disable();
- radioIrq = FALSE;
-
- state = STATE_TRX_OFF;
- }
-
- if( cmd == CMD_TURNOFF && state == STATE_TRX_OFF )
- {
- call SLP_TR.set();
- state = STATE_SLEEP;
- cmd = CMD_SIGNAL_DONE;
- }
- else if( cmd == CMD_STANDBY && state == STATE_TRX_OFF )
- cmd = CMD_SIGNAL_DONE;
- }
-
- tasklet_async command error_t RadioState.turnOff()
- {
- if( cmd != CMD_NONE )
- return EBUSY;
- else if( state == STATE_SLEEP )
- return EALREADY;
-
- cmd = CMD_TURNOFF;
- call Tasklet.schedule();
-
- return SUCCESS;
- }
-
- tasklet_async command error_t RadioState.standby()
- {
- if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) )
- return EBUSY;
- else if( state == STATE_TRX_OFF )
- return EALREADY;
-
- cmd = CMD_STANDBY;
- call Tasklet.schedule();
-
- return SUCCESS;
- }
-
- tasklet_async command error_t RadioState.turnOn()
- {
- if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) )
- return EBUSY;
- else if( state == STATE_RX_ON )
- return EALREADY;
-
- cmd = CMD_TURNON;
- call Tasklet.schedule();
-
- return SUCCESS;
- }
-
- default tasklet_async event void RadioState.done() { }
-
-/*----------------- TRANSMIT -----------------*/
-
- tasklet_async command error_t RadioSend.send(message_t* msg)
- {
- uint16_t time;
- uint8_t length;
- uint8_t* data;
- uint8_t header;
- uint32_t time32;
- void* timesync;
-
- if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq )
- return EBUSY;
-
- length = (call PacketTransmitPower.isSet(msg) ?
- call PacketTransmitPower.get(msg) : RF2XX_DEF_RFPOWER) & RF2XX_TX_PWR_MASK;
-
- if( length != txPower )
- {
- txPower = length;
- writeRegister(RF2XX_PHY_TX_PWR, RF2XX_TX_AUTO_CRC_ON | txPower);
- }
-
- if( call RF2xxDriverConfig.requiresRssiCca(msg)
- && (readRegister(RF2XX_PHY_RSSI) & RF2XX_RSSI_MASK) > ((rssiClear + rssiBusy) >> 3) )
- return EBUSY;
-
- writeRegister(RF2XX_TRX_STATE, RF2XX_PLL_ON);
-
- // do something useful, just to wait a little
- time32 = call LocalTime.get();
- timesync = call PacketTimeSyncOffset.isSet(msg) ? msg->data + call PacketTimeSyncOffset.get(msg) : 0;
-
- // we have missed an incoming message in this short amount of time
- if( (readRegister(RF2XX_TRX_STATUS) & RF2XX_TRX_STATUS_MASK) != RF2XX_PLL_ON )
- {
- ASSERT( (readRegister(RF2XX_TRX_STATUS) & RF2XX_TRX_STATUS_MASK) == RF2XX_BUSY_RX );
-
- state = STATE_PLL_ON_2_RX_ON;
- return EBUSY;
- }
-
- atomic
- {
- call SLP_TR.set();
- time = call RadioAlarm.getNow() + TX_SFD_DELAY;
- }
- call SLP_TR.clr();
-
- ASSERT( ! radioIrq );
-
- call SELN.clr();
- call FastSpiByte.splitWrite(RF2XX_CMD_FRAME_WRITE);
-
- length = call RF2xxDriverConfig.getLength(msg);
- data = call RF2xxDriverConfig.getPayload(msg);
-
- // length | data[0] ... data[length-3] | automatically generated FCS
- call FastSpiByte.splitReadWrite(length);
-
- // the FCS is atomatically generated (2 bytes)
- length -= 2;
-
- header = call RF2xxDriverConfig.getHeaderLength();
- if( header > length )
- header = length;
-
- length -= header;
-
- // first upload the header to gain some time
- do {
- call FastSpiByte.splitReadWrite(*(data++));
- }
- while( --header != 0 );
-
- time32 += (int16_t)(time) - (int16_t)(time32);
-
- if( timesync != 0 )
- *(timesync_relative_t*)timesync = (*(timesync_absolute_t*)timesync) - time32;
-
- do {
- call FastSpiByte.splitReadWrite(*(data++));
- }
- while( --length != 0 );
-
- // wait for the SPI transfer to finish
- call FastSpiByte.splitRead();
- call SELN.set();
-
- /*
- * There is a very small window (~1 microsecond) when the RF2xx went
- * into PLL_ON state but was somehow not properly initialized because
- * of an incoming message and could not go into BUSY_TX. I think the
- * radio can even receive a message, and generate a TRX_UR interrupt
- * because of concurrent access, but that message probably cannot be
- * recovered.
- *
- * TODO: this needs to be verified, and make sure that the chip is
- * not locked up in this case.
- */
-
- // go back to RX_ON state when finished
- writeRegister(RF2XX_TRX_STATE, RF2XX_RX_ON);
-
-#ifdef RF2XX_DEBUG_MESSAGES
- if( call DiagMsg.record() )
- {
- length = call RF2xxDriverConfig.getLength(msg);
-
- call DiagMsg.str("tx");
- call DiagMsg.uint16(time);
- call DiagMsg.uint8(length);
- call DiagMsg.hex8s(data, length - 2);
- call DiagMsg.send();
- }
-#endif
-
- if( timesync != 0 )
- *(timesync_absolute_t*)timesync = (*(timesync_relative_t*)timesync) + time32;
-
- call PacketTimeStamp.set(msg, time32);
-
- // wait for the TRX_END interrupt
- state = STATE_BUSY_TX_2_RX_ON;
- cmd = CMD_TRANSMIT;
-
- return SUCCESS;
- }
-
- default tasklet_async event void RadioSend.sendDone(error_t error) { }
- default tasklet_async event void RadioSend.ready() { }
-
-/*----------------- CCA -----------------*/
-
- tasklet_async command error_t RadioCCA.request()
- {
- if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || ! call RadioAlarm.isFree() )
- return EBUSY;
-
- // see Errata B7 of the datasheet
- // writeRegister(RF2XX_TRX_STATE, RF2XX_PLL_ON);
- // writeRegister(RF2XX_TRX_STATE, RF2XX_RX_ON);
-
- writeRegister(RF2XX_PHY_CC_CCA, RF2XX_CCA_REQUEST | RF2XX_CCA_MODE_VALUE | channel);
- call RadioAlarm.wait(CCA_REQUEST_TIME);
- cmd = CMD_CCA;
-
- return SUCCESS;
- }
-
- default tasklet_async event void RadioCCA.done(error_t error) { }
-
-/*----------------- RECEIVE -----------------*/
-
- inline void downloadMessage()
- {
- uint8_t length;
- uint16_t crc;
-
- call SELN.clr();
- call FastSpiByte.write(RF2XX_CMD_FRAME_READ);
-
- // read the length byte
- length = call FastSpiByte.write(0);
-
- // if correct length
- if( length >= 3 && length <= call RF2xxDriverConfig.getMaxLength() )
- {
- uint8_t read;
- uint8_t* data;
-
- // initiate the reading
- call FastSpiByte.splitWrite(0);
-
- call RF2xxDriverConfig.setLength(rxMsg, length);
- data = call RF2xxDriverConfig.getPayload(rxMsg);
- crc = 0;
-
- // we do not store the CRC field
- length -= 2;
-
- read = call RF2xxDriverConfig.getHeaderLength();
- if( length < read )
- read = length;
-
- length -= read;
-
- do {
- crc = RF2XX_CRCBYTE_COMMAND(crc, *(data++) = call FastSpiByte.splitReadWrite(0));
- }
- while( --read != 0 );
-
- if( signal RadioReceive.header(rxMsg) )
- {
- while( length-- != 0 )
- crc = RF2XX_CRCBYTE_COMMAND(crc, *(data++) = call FastSpiByte.splitReadWrite(0));
-
- crc = RF2XX_CRCBYTE_COMMAND(crc, call FastSpiByte.splitReadWrite(0));
- crc = RF2XX_CRCBYTE_COMMAND(crc, call FastSpiByte.splitReadWrite(0));
-
- call PacketLinkQuality.set(rxMsg, call FastSpiByte.splitRead());
- }
- else
- crc = 1;
- }
- else
- crc = 1;
-
- call SELN.set();
- state = STATE_RX_ON;
-
-#ifdef RF2XX_DEBUG_MESSAGES
- if( call DiagMsg.record() )
- {
- length = call RF2xxDriverConfig.getLength(rxMsg);
-
- call DiagMsg.str("rx");
- call DiagMsg.uint32(call PacketTimeStamp.isValid(rxMsg) ? call PacketTimeStamp.timestamp(rxMsg) : 0);
- call DiagMsg.uint16(call RadioAlarm.getNow());
- call DiagMsg.uint8(crc != 0);
- call DiagMsg.uint8(length);
- call DiagMsg.hex8s(call RF2xxDriverConfig.getPayload(rxMsg), length - 2);
- call DiagMsg.send();
- }
-#endif
-
- cmd = CMD_NONE;
-
- // signal only if it has passed the CRC check
- if( crc == 0 )
- rxMsg = signal RadioReceive.receive(rxMsg);
- }
-
-/*----------------- IRQ -----------------*/
-
- async event void IRQ.captured(uint16_t time)
- {
- ASSERT( ! radioIrq );
-
- atomic
- {
- capturedTime = time;
- radioIrq = TRUE;
- }
-
- call Tasklet.schedule();
- }
-
- void serviceRadio()
- {
- if( isSpiAcquired() )
- {
- uint16_t time;
- uint32_t time32;
- uint8_t irq;
- uint8_t temp;
-
- atomic time = capturedTime;
- radioIrq = FALSE;
- irq = readRegister(RF2XX_IRQ_STATUS);
-
-#ifdef RF2XX_DEBUG
- // TODO: handle this interrupt
- if( irq & RF2XX_IRQ_TRX_UR )
- {
- if( call DiagMsg.record() )
- {
- call DiagMsg.str("assert ur");
- call DiagMsg.uint16(call RadioAlarm.getNow());
- call DiagMsg.hex8(readRegister(RF2XX_TRX_STATUS));
- call DiagMsg.hex8(readRegister(RF2XX_TRX_STATE));
- call DiagMsg.hex8(irq);
- call DiagMsg.uint8(state);
- call DiagMsg.uint8(cmd);
- call DiagMsg.send();
- }
- }
-#endif
-
- if( irq & RF2XX_IRQ_PLL_LOCK )
- {
- if( cmd == CMD_TURNON || cmd == CMD_CHANNEL )
- {
- ASSERT( state == STATE_TRX_OFF_2_RX_ON );
-
- state = STATE_RX_ON;
- cmd = CMD_SIGNAL_DONE;
- }
- else if( cmd == CMD_TRANSMIT )
- {
- ASSERT( state == STATE_BUSY_TX_2_RX_ON );
- }
- else
- ASSERT(FALSE);
- }
-
- if( irq & RF2XX_IRQ_RX_START )
- {
- if( cmd == CMD_CCA )
- {
- signal RadioCCA.done(FAIL);
- cmd = CMD_NONE;
- }
-
- if( cmd == CMD_NONE )
- {
- ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON );
-
- // the most likely place for busy channel, with no TRX_END interrupt
- if( irq == RF2XX_IRQ_RX_START )
- {
- temp = readRegister(RF2XX_PHY_RSSI) & RF2XX_RSSI_MASK;
- rssiBusy += temp - (rssiBusy >> 2);
-#ifndef RF2XX_RSSI_ENERGY
- call PacketRSSI.set(rxMsg, temp);
- }
- else
- {
- call PacketRSSI.clear(rxMsg);
-#endif
- }
-
- /*
- * The timestamp corresponds to the first event which could not
- * have been a PLL_LOCK because then cmd != CMD_NONE, so we must
- * have received a message (and could also have received the
- * TRX_END interrupt in the mean time, but that is fine. Also,
- * we could not be after a transmission, because then cmd =
- * CMD_TRANSMIT.
- */
- if( irq == RF2XX_IRQ_RX_START ) // just to be cautious
- {
- time32 = call LocalTime.get();
- time32 += (int16_t)(time - RX_SFD_DELAY) - (int16_t)(time32);
- call PacketTimeStamp.set(rxMsg, time32);
- }
- else
- call PacketTimeStamp.clear(rxMsg);
-
- cmd = CMD_RECEIVE;
- }
- else
- ASSERT( cmd == CMD_TURNOFF );
- }
-
- if( irq & RF2XX_IRQ_TRX_END )
- {
- if( cmd == CMD_TRANSMIT )
- {
- ASSERT( state == STATE_BUSY_TX_2_RX_ON );
-
- state = STATE_RX_ON;
- cmd = CMD_NONE;
- signal RadioSend.sendDone(SUCCESS);
-
- // TODO: we could have missed a received message
- ASSERT( ! (irq & RF2XX_IRQ_RX_START) );
- }
- else if( cmd == CMD_RECEIVE )
- {
- ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON );
-#ifdef RF2XX_RSSI_ENERGY
- if( irq == RF2XX_IRQ_TRX_END )
- call PacketRSSI.set(rxMsg, readRegister(RF2XX_PHY_ED_LEVEL));
- else
- call PacketRSSI.clear(rxMsg);
-#endif
- if( state == STATE_PLL_ON_2_RX_ON )
- {
- ASSERT( (readRegister(RF2XX_TRX_STATUS) & RF2XX_TRX_STATUS_MASK) == RF2XX_PLL_ON );
-
- writeRegister(RF2XX_TRX_STATE, RF2XX_RX_ON);
- state = STATE_RX_ON;
- }
- else
- {
- // the most likely place for clear channel (hope to avoid acks)
- rssiClear += (readRegister(RF2XX_PHY_RSSI) & RF2XX_RSSI_MASK) - (rssiClear >> 2);
- }
-
- cmd = CMD_DOWNLOAD;
- }
- else
- ASSERT(FALSE);
- }
- }
- }
-
- default tasklet_async event bool RadioReceive.header(message_t* msg)
- {
- return TRUE;
- }
-
- default tasklet_async event message_t* RadioReceive.receive(message_t* msg)
- {
- return msg;
- }
-
-/*----------------- TASKLET -----------------*/
-
- tasklet_async event void Tasklet.run()
- {
- if( radioIrq )
- serviceRadio();
-
- if( cmd != CMD_NONE )
- {
- if( cmd == CMD_DOWNLOAD )
- downloadMessage();
- else if( CMD_TURNOFF <= cmd && cmd <= CMD_TURNON )
- changeState();
- else if( cmd == CMD_CHANNEL )
- changeChannel();
-
- if( cmd == CMD_SIGNAL_DONE )
- {
- cmd = CMD_NONE;
- signal RadioState.done();
- }
- }
-
- if( cmd == CMD_NONE && state == STATE_RX_ON && ! radioIrq )
- signal RadioSend.ready();
-
- if( cmd == CMD_NONE )
- call SpiResource.release();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __RF2XXPACKET_H__
-#define __RF2XXPACKET_H__
-
-#include <IEEE154Packet.h>
-
-typedef ieee154_header_t rf2xxpacket_header_t;
-
-typedef nx_struct rf2xxpacket_footer_t
-{
- // the time stamp is not recorded here, time stamped messaged cannot have max length
-} rf2xxpacket_footer_t;
-
-typedef struct rf2xxpacket_metadata_t
-{
- uint8_t flags;
- uint8_t lqi;
- uint8_t power; // shared between TXPOWER and RSSI
-#ifdef LOW_POWER_LISTENING
- uint16_t lpl_sleepint;
-#endif
- uint32_t timestamp;
-} rf2xxpacket_metadata_t;
-
-enum rf2xxpacket_metadata_flags
-{
- RF2XXPACKET_WAS_ACKED = 0x01, // PacketAcknowledgements
- RF2XXPACKET_TIMESTAMP = 0x02, // PacketTimeStamp
- RF2XXPACKET_TXPOWER = 0x04, // PacketTransmitPower
- RF2XXPACKET_RSSI = 0x08, // PacketRSSI
- RF2XXPACKET_TIMESYNC = 0x10, // PacketTimeSync (update timesync_footer)
- RF2XXPACKET_LPL_SLEEPINT = 0x20, // LowPowerListening
-
- RF2XXPACKET_CLEAR_METADATA = 0x00,
-};
-
-#endif//__RF2XXPACKET_H__
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration RF2xxPacketC
-{
- provides
- {
- interface Packet;
- interface AMPacket;
- interface PacketAcknowledgements;
- interface PacketField<uint8_t> as PacketLinkQuality;
- interface PacketField<uint8_t> as PacketTransmitPower;
- interface PacketField<uint8_t> as PacketRSSI;
- interface PacketField<uint16_t> as PacketSleepInterval;
- interface PacketField<uint8_t> as PacketTimeSyncOffset;
-
- interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
- interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
- }
-}
-
-implementation
-{
- components RF2xxPacketP, IEEE154PacketC, LocalTimeMicroC, LocalTimeMilliC;
-
- RF2xxPacketP.IEEE154Packet -> IEEE154PacketC;
- RF2xxPacketP.LocalTimeRadio -> LocalTimeMicroC;
- RF2xxPacketP.LocalTimeMilli -> LocalTimeMilliC;
-
- Packet = RF2xxPacketP;
- AMPacket = IEEE154PacketC;
-
- PacketAcknowledgements = RF2xxPacketP;
- PacketLinkQuality = RF2xxPacketP.PacketLinkQuality;
- PacketTransmitPower = RF2xxPacketP.PacketTransmitPower;
- PacketRSSI = RF2xxPacketP.PacketRSSI;
- PacketSleepInterval = RF2xxPacketP.PacketSleepInterval;
- PacketTimeSyncOffset = RF2xxPacketP.PacketTimeSyncOffset;
-
- PacketTimeStampRadio = RF2xxPacketP;
- PacketTimeStampMilli = RF2xxPacketP;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <RF2xxPacket.h>
-#include <TimeSyncMessage.h>
-
-module RF2xxPacketP
-{
- provides
- {
- interface PacketAcknowledgements;
- interface Packet;
- interface PacketField<uint8_t> as PacketLinkQuality;
- interface PacketField<uint8_t> as PacketTransmitPower;
- interface PacketField<uint8_t> as PacketRSSI;
- interface PacketField<uint16_t> as PacketSleepInterval;
- interface PacketField<uint8_t> as PacketTimeSyncOffset;
-
- interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
- interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
- }
-
- uses
- {
- interface IEEE154Packet;
-
- interface LocalTime<TRadio> as LocalTimeRadio;
- interface LocalTime<TMilli> as LocalTimeMilli;
- }
-}
-
-implementation
-{
- enum
- {
- PACKET_LENGTH_INCREASE =
- sizeof(rf2xxpacket_header_t) - 1 // the 8-bit length field is not counted
- + sizeof(ieee154_footer_t), // the CRC is not stored in memory
- };
-
- inline rf2xxpacket_metadata_t* getMeta(message_t* msg)
- {
- return (rf2xxpacket_metadata_t*)(msg->metadata);
- }
-
-/*----------------- Packet -----------------*/
-
- command void Packet.clear(message_t* msg)
- {
- call IEEE154Packet.createDataFrame(msg);
-
- getMeta(msg)->flags = RF2XXPACKET_CLEAR_METADATA;
- }
-
- inline command void Packet.setPayloadLength(message_t* msg, uint8_t len)
- {
- call IEEE154Packet.setLength(msg, len + PACKET_LENGTH_INCREASE);
- }
-
- inline command uint8_t Packet.payloadLength(message_t* msg)
- {
- return call IEEE154Packet.getLength(msg) - PACKET_LENGTH_INCREASE;
- }
-
- inline command uint8_t Packet.maxPayloadLength()
- {
- return TOSH_DATA_LENGTH;
- }
-
- command void* Packet.getPayload(message_t* msg, uint8_t len)
- {
- if( len > TOSH_DATA_LENGTH )
- return NULL;
-
- return msg->data;
- }
-
-/*----------------- PacketAcknowledgements -----------------*/
-
- async command error_t PacketAcknowledgements.requestAck(message_t* msg)
- {
- call IEEE154Packet.setAckRequired(msg, TRUE);
-
- return SUCCESS;
- }
-
- async command error_t PacketAcknowledgements.noAck(message_t* msg)
- {
- call IEEE154Packet.setAckRequired(msg, FALSE);
-
- return SUCCESS;
- }
-
- async command bool PacketAcknowledgements.wasAcked(message_t* msg)
- {
- return getMeta(msg)->flags & RF2XXPACKET_WAS_ACKED;
- }
-
-/*----------------- PacketLinkQuality -----------------*/
-
- async command bool PacketLinkQuality.isSet(message_t* msg)
- {
- return TRUE;
- }
-
- async command uint8_t PacketLinkQuality.get(message_t* msg)
- {
- return getMeta(msg)->lqi;
- }
-
- async command void PacketLinkQuality.clear(message_t* msg)
- {
- }
-
- async command void PacketLinkQuality.set(message_t* msg, uint8_t value)
- {
- getMeta(msg)->lqi = value;
- }
-
-/*----------------- PacketTimeStampRadio -----------------*/
-
- async command bool PacketTimeStampRadio.isValid(message_t* msg)
- {
- return getMeta(msg)->flags & RF2XXPACKET_TIMESTAMP;
- }
-
- async command uint32_t PacketTimeStampRadio.timestamp(message_t* msg)
- {
- return getMeta(msg)->timestamp;
- }
-
- async command void PacketTimeStampRadio.clear(message_t* msg)
- {
- getMeta(msg)->flags &= ~RF2XXPACKET_TIMESTAMP;
- }
-
- async command void PacketTimeStampRadio.set(message_t* msg, uint32_t value)
- {
- getMeta(msg)->flags |= RF2XXPACKET_TIMESTAMP;
- getMeta(msg)->timestamp = value;
- }
-
-/*----------------- PacketTimeStampMilli -----------------*/
-
- async command bool PacketTimeStampMilli.isValid(message_t* msg)
- {
- return call PacketTimeStampRadio.isValid(msg);
- }
-
- async command uint32_t PacketTimeStampMilli.timestamp(message_t* msg)
- {
- int32_t offset = call PacketTimeStampRadio.timestamp(msg) - call LocalTimeRadio.get();
-
- // TODO: Make the shift constant configurable
- return (offset >> 10) + call LocalTimeMilli.get();
- }
-
- async command void PacketTimeStampMilli.clear(message_t* msg)
- {
- call PacketTimeStampRadio.clear(msg);
- }
-
- async command void PacketTimeStampMilli.set(message_t* msg, uint32_t value)
- {
- // TODO: Make the shift constant configurable
- int32_t offset = (value - call LocalTimeMilli.get()) << 10;
-
- call PacketTimeStampRadio.set(msg, offset + call LocalTimeRadio.get());
- }
-
-/*----------------- PacketTransmitPower -----------------*/
-
- async command bool PacketTransmitPower.isSet(message_t* msg)
- {
- return getMeta(msg)->flags & RF2XXPACKET_TXPOWER;
- }
-
- async command uint8_t PacketTransmitPower.get(message_t* msg)
- {
- return getMeta(msg)->power;
- }
-
- async command void PacketTransmitPower.clear(message_t* msg)
- {
- getMeta(msg)->flags &= ~RF2XXPACKET_TXPOWER;
- }
-
- async command void PacketTransmitPower.set(message_t* msg, uint8_t value)
- {
- getMeta(msg)->flags &= ~RF2XXPACKET_RSSI;
- getMeta(msg)->flags |= RF2XXPACKET_TXPOWER;
- getMeta(msg)->power = value;
- }
-
-/*----------------- PacketRSSI -----------------*/
-
- async command bool PacketRSSI.isSet(message_t* msg)
- {
- return getMeta(msg)->flags & RF2XXPACKET_RSSI;
- }
-
- async command uint8_t PacketRSSI.get(message_t* msg)
- {
- return getMeta(msg)->power;
- }
-
- async command void PacketRSSI.clear(message_t* msg)
- {
- getMeta(msg)->flags &= ~RF2XXPACKET_RSSI;
- }
-
- async command void PacketRSSI.set(message_t* msg, uint8_t value)
- {
- getMeta(msg)->flags &= ~RF2XXPACKET_TXPOWER;
- getMeta(msg)->flags |= RF2XXPACKET_RSSI;
- getMeta(msg)->power = value;
- }
-
-/*----------------- PacketTimeSyncOffset -----------------*/
-
- async command bool PacketTimeSyncOffset.isSet(message_t* msg)
- {
- return getMeta(msg)->flags & RF2XXPACKET_TIMESYNC;
- }
-
- async command uint8_t PacketTimeSyncOffset.get(message_t* msg)
- {
- return call IEEE154Packet.getLength(msg) - PACKET_LENGTH_INCREASE - sizeof(timesync_absolute_t);
- }
-
- async command void PacketTimeSyncOffset.clear(message_t* msg)
- {
- getMeta(msg)->flags &= ~RF2XXPACKET_TIMESYNC;
- }
-
- async command void PacketTimeSyncOffset.set(message_t* msg, uint8_t value)
- {
- // the value is ignored, the offset always points to the timesync footer at the end of the payload
- getMeta(msg)->flags |= RF2XXPACKET_TIMESYNC;
- }
-
-/*----------------- PacketSleepInterval -----------------*/
-
- async command bool PacketSleepInterval.isSet(message_t* msg)
- {
- return getMeta(msg)->flags & RF2XXPACKET_LPL_SLEEPINT;
- }
-
- async command uint16_t PacketSleepInterval.get(message_t* msg)
- {
-#ifdef LOW_POWER_LISTENING
- return getMeta(msg)->lpl_sleepint;
-#else
- return 0;
-#endif
- }
-
- async command void PacketSleepInterval.clear(message_t* msg)
- {
- getMeta(msg)->flags &= ~RF2XXPACKET_LPL_SLEEPINT;
- }
-
- async command void PacketSleepInterval.set(message_t* msg, uint16_t value)
- {
- getMeta(msg)->flags |= RF2XXPACKET_LPL_SLEEPINT;
-
-#ifdef LOW_POWER_LISTENING
- getMeta(msg)->lpl_sleepint = value;
-#endif
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Timer.h>
-#include <AM.h>
-#include <RadioAlarm.h>
-
-configuration RF2xxTimeSyncMessageC
-{
- provides
- {
- interface SplitControl;
-
- interface Receive[uint8_t id];
- interface Receive as Snoop[am_id_t id];
- interface Packet;
- interface AMPacket;
-
- interface TimeSyncAMSend<TRadio, uint32_t> as TimeSyncAMSendRadio[am_id_t id];
- interface TimeSyncPacket<TRadio, uint32_t> as TimeSyncPacketRadio;
-
- interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
- interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
- }
-}
-
-implementation
-{
- components RF2xxTimeSyncMessageP, RF2xxActiveMessageC, LocalTimeMilliC, LocalTimeMicroC as LocalTimeRadioC, RF2xxPacketC;
-
- TimeSyncAMSendRadio = RF2xxTimeSyncMessageP;
- TimeSyncPacketRadio = RF2xxTimeSyncMessageP;
-
- TimeSyncAMSendMilli = RF2xxTimeSyncMessageP;
- TimeSyncPacketMilli = RF2xxTimeSyncMessageP;
-
- Packet = RF2xxTimeSyncMessageP;
- RF2xxTimeSyncMessageP.SubSend -> RF2xxActiveMessageC.AMSend;
- RF2xxTimeSyncMessageP.SubPacket -> RF2xxActiveMessageC.Packet;
-
- RF2xxTimeSyncMessageP.PacketTimeStampRadio -> RF2xxActiveMessageC;
- RF2xxTimeSyncMessageP.PacketTimeStampMilli -> RF2xxActiveMessageC;
- RF2xxTimeSyncMessageP.LocalTimeRadio -> LocalTimeRadioC;
- RF2xxTimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC;
-
- RF2xxTimeSyncMessageP.PacketTimeSyncOffset -> RF2xxPacketC.PacketTimeSyncOffset;
-
- SplitControl = RF2xxActiveMessageC;
- Receive = RF2xxActiveMessageC.Receive;
- Snoop = RF2xxActiveMessageC.Snoop;
- AMPacket = RF2xxActiveMessageC;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <TimeSyncMessage.h>
-#include <RadioAlarm.h>
-
-module RF2xxTimeSyncMessageP
-{
- provides
- {
- interface TimeSyncAMSend<TRadio, uint32_t> as TimeSyncAMSendRadio[uint8_t id];
- interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[uint8_t id];
- interface Packet;
-
- interface TimeSyncPacket<TRadio, uint32_t> as TimeSyncPacketRadio;
- interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
- }
-
- uses
- {
- interface AMSend as SubSend[uint8_t id];
- interface Packet as SubPacket;
-
- interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
- interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
-
- interface LocalTime<TRadio> as LocalTimeRadio;
- interface LocalTime<TMilli> as LocalTimeMilli;
-
- interface PacketField<uint8_t> as PacketTimeSyncOffset;
- }
-}
-
-implementation
-{
- inline void* getFooter(message_t* msg)
- {
- // we use the payload length that we export (the smaller one)
- return msg->data + call Packet.payloadLength(msg);
- }
-
-/*----------------- Packet -----------------*/
-
- command void Packet.clear(message_t* msg)
- {
- call SubPacket.clear(msg);
- }
-
- command void Packet.setPayloadLength(message_t* msg, uint8_t len)
- {
- call SubPacket.setPayloadLength(msg, len + sizeof(timesync_relative_t));
- }
-
- command uint8_t Packet.payloadLength(message_t* msg)
- {
- return call SubPacket.payloadLength(msg) - sizeof(timesync_relative_t);
- }
-
- command uint8_t Packet.maxPayloadLength()
- {
- return call SubPacket.maxPayloadLength() - sizeof(timesync_relative_t);
- }
-
- command void* Packet.getPayload(message_t* msg, uint8_t len)
- {
- return call SubPacket.getPayload(msg, len + sizeof(timesync_relative_t));
- }
-
-/*----------------- TimeSyncAMSendRadio -----------------*/
-
- command error_t TimeSyncAMSendRadio.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
- {
- *(timesync_absolute_t*)(msg->data + len) = event_time;
-
- call PacketTimeSyncOffset.set(msg, len);
-
- return call SubSend.send[id](addr, msg, len + sizeof(timesync_relative_t));
- }
-
- command error_t TimeSyncAMSendRadio.cancel[am_id_t id](message_t* msg)
- {
- return call SubSend.cancel[id](msg);
- }
-
- default event void TimeSyncAMSendRadio.sendDone[am_id_t id](message_t* msg, error_t error)
- {
- }
-
- command uint8_t TimeSyncAMSendRadio.maxPayloadLength[am_id_t id]()
- {
- return call SubSend.maxPayloadLength[id]() - sizeof(timesync_relative_t);
- }
-
- command void* TimeSyncAMSendRadio.getPayload[am_id_t id](message_t* msg, uint8_t len)
- {
- return call SubSend.getPayload[id](msg, len + sizeof(timesync_relative_t));
- }
-
-/*----------------- TimeSyncAMSendMilli -----------------*/
-
- command error_t TimeSyncAMSendMilli.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
- {
- // compute elapsed time in millisecond
- event_time = ((int32_t)(event_time - call LocalTimeMilli.get()) << 10) + call LocalTimeRadio.get();
-
- return call TimeSyncAMSendRadio.send[id](addr, msg, len, event_time);
- }
-
- command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg)
- {
- return call TimeSyncAMSendRadio.cancel[id](msg);
- }
-
- default event void TimeSyncAMSendMilli.sendDone[am_id_t id](message_t* msg, error_t error)
- {
- }
-
- command uint8_t TimeSyncAMSendMilli.maxPayloadLength[am_id_t id]()
- {
- return call TimeSyncAMSendRadio.maxPayloadLength[id]();
- }
-
- command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len)
- {
- return call TimeSyncAMSendRadio.getPayload[id](msg, len);
- }
-
- /*----------------- SubSend.sendDone -------------------*/
-
- event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error)
- {
- signal TimeSyncAMSendRadio.sendDone[id](msg, error);
- signal TimeSyncAMSendMilli.sendDone[id](msg, error);
- }
-
- /*----------------- TimeSyncPacketRadio -----------------*/
-
- command bool TimeSyncPacketRadio.isValid(message_t* msg)
- {
- timesync_relative_t* timesync = getFooter(msg);
-
- return call PacketTimeStampRadio.isValid(msg) && *timesync != 0x80000000L;
- }
-
- command uint32_t TimeSyncPacketRadio.eventTime(message_t* msg)
- {
- timesync_relative_t* timesync = getFooter(msg);
-
- return (*timesync) + call PacketTimeStampRadio.timestamp(msg);
- }
-
- /*----------------- TimeSyncPacketMilli -----------------*/
-
- command bool TimeSyncPacketMilli.isValid(message_t* msg)
- {
- timesync_relative_t* timesync = getFooter(msg);
-
- return call PacketTimeStampMilli.isValid(msg) && *timesync != 0x80000000L;
- }
-
- command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg)
- {
- timesync_relative_t* timesync = getFooter(msg);
-
- return ((int32_t)(*timesync) >> 10) + call PacketTimeStampMilli.timestamp(msg);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-interface RadioAlarm
-{
- /**
- * Returns TRUE if the alarm is free and ready to be used. Once the alarm
- * is free, it cannot become nonfree in the same tasklet block. Note,
- * if the alarm is currently set (even if for ourselves) then it is not free.
- */
- tasklet_async command bool isFree();
-
- /**
- * Waits till the specified timeout period expires. The alarm must be free.
- */
- tasklet_async command void wait(uint16_t timeout);
-
- /**
- * Cancels the running alarm. The alarm must be pending.
- */
- tasklet_async command void cancel();
-
- /**
- * This event is fired when the specified timeout period expires.
- */
- tasklet_async event void fired();
-
- /**
- * Returns the current time as measured by the radio stack.
- */
- async command uint16_t getNow();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration RadioAlarmC
-{
- provides
- {
- interface RadioAlarm[uint8_t id]; // use unique("RadioAlarm")
- }
-
- uses
- {
- interface Alarm<TRadio, uint16_t> @exactlyonce();
- }
-}
-
-implementation
-{
- components RadioAlarmP, TaskletC;
-
- RadioAlarm = RadioAlarmP;
- Alarm = RadioAlarmP;
- RadioAlarmP.Tasklet -> TaskletC;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-#include <RadioAssert.h>
-
-module RadioAlarmP
-{
- provides
- {
- interface RadioAlarm[uint8_t id];
- }
-
- uses
- {
- interface Alarm<TRadio, uint16_t>;
- interface Tasklet;
- }
-}
-
-implementation
-{
- norace uint8_t state;
- enum
- {
- STATE_READY = 0,
- STATE_WAIT = 1,
- STATE_FIRED = 2,
- };
-
- tasklet_norace uint8_t alarm;
-
- async event void Alarm.fired()
- {
- atomic
- {
- if( state == STATE_WAIT )
- state = STATE_FIRED;
- }
-
- call Tasklet.schedule();
- }
-
- inline async command uint16_t RadioAlarm.getNow[uint8_t id]()
- {
- return call Alarm.getNow();
- }
-
- tasklet_async event void Tasklet.run()
- {
- if( state == STATE_FIRED )
- {
- state = STATE_READY;
- signal RadioAlarm.fired[alarm]();
- }
- }
-
- default tasklet_async event void RadioAlarm.fired[uint8_t id]()
- {
- }
-
- inline tasklet_async command bool RadioAlarm.isFree[uint8_t id]()
- {
- return state == STATE_READY;
- }
-
- tasklet_async command void RadioAlarm.wait[uint8_t id](uint16_t timeout)
- {
- ASSERT( state == STATE_READY );
-
- alarm = id;
- state = STATE_WAIT;
- call Alarm.start(timeout);
- }
-
- tasklet_async command void RadioAlarm.cancel[uint8_t id]()
- {
- ASSERT( alarm == id );
- ASSERT( state != STATE_READY );
-
- call Alarm.stop();
- state = STATE_READY;
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __RADIOASSERT_H__
-#define __RADIOASSERT_H__
-
-#ifdef RF2XX_DEBUG
-
- void assert(bool condition, const char* file, uint16_t line);
- #define ASSERT(COND) assert(COND, __FILE__, __LINE__)
-
-#else
-
- #define ASSERT(COND) for(;0;)
-
-#endif
-
-#endif//__RADIOASSERT_H__
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-interface RadioCCA
-{
- /**
- * Starts the clear channel assesment procedure. Returns EBUSY if the radio
- * is currently servicing a clear channel assesment, and SUCCESS otherwise.
- * The check will be performed only in the RX_READY state.
- */
- tasklet_async command error_t request();
-
- /**
- * Signals the completion of the clear channel assesment send command.
- * SUCCESS means the channel is clear, EBUSY means the channel is not
- * clear, and FAIL means that the clear channel assesment could not
- * be finished or the operation was cancelled.
- */
- tasklet_async event void done(error_t error);
-}
+++ /dev/null
-/*
- * Copyright (c) 2009, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-interface RadioChannel
-{
- /**
- * Sets the current channel. Returns EBUSY if the stack is unable
- * to change the channel this time (some other operation is in progress),
- * EALREADY if the selected channel is already set, SUCCESS otherwise.
- */
- command error_t setChannel(uint8_t channel);
-
- /**
- * This event is signaled exactly once for each sucessfully posted state
- * setChannel command when it is completed.
- */
- event void setChannelDone();
-
- /**
- * Returns the currently selected channel.
- */
- command uint8_t getChannel();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-interface RadioReceive
-{
- /**
- * This event is fired when the header is received/downloaded and the
- * higher layers are consulted whether it needs to be downloaded and
- * further processed. Return FALSE if the message should be discarded.
- * In particular, the message buffer layer returns FALSE if there is
- * no space for a new message, so this message will not get acknowledged.
- */
- tasklet_async event bool header(message_t* msg);
-
- /**
- * Signals the reception of a message, but only for those messages for
- * which SUCCESS was returned in the header event. The usual owner rules
- * apply to the message pointers.
- */
- tasklet_async event message_t* receive(message_t* msg);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-interface RadioSend
-{
- /**
- * Starts the transmission of the given message. This command must not
- * be called while another send is in progress (so one must wait for the
- * sendDone event). Returns EBUSY if a reception is in progress or for
- * some other reason the request cannot be temporarily satisfied (e.g.
- * the SPI bus access could not be acquired). In this case the send
- * command could be retried from a tasklet. Returns SUCCESS if the
- * transmission could be started. In this case sendDone will be fired.
- */
- tasklet_async command error_t send(message_t* msg);
-
- /**
- * Signals the completion of the send command, exactly once for each
- * successfull send command. If the returned error code is SUCCESS, then
- * the message was sent (may not have been acknowledged), otherwise
- * the message was not transmitted over the air.
- */
- tasklet_async event void sendDone(error_t error);
-
- /**
- * This event is fired when the component is most likely able to accept
- * a send request. If the send command has returned with a failure, then
- * this event will be called at least once in the near future.
- */
- tasklet_async event void ready();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-interface RadioState
-{
- /**
- * Moves to radio into sleep state with the lowest power consumption but
- * highest wakeup time. The radio cannot send or receive in this state
- * and releases all access to shared resources (e.g. SPI bus).
- */
- tasklet_async command error_t turnOff();
-
- /**
- * The same as the turnOff command, except it is not as deep sleep, and
- * it is quicker to recover from this state.
- */
- tasklet_async command error_t standby();
-
- /**
- * Goes into receive state. The radio continuously receive messages
- * and able to transmit.
- */
- tasklet_async command error_t turnOn();
-
- /**
- * Sets the current channel. Returns EBUSY if the stack is unable
- * to change the channel this time (some other operation is in progress)
- * SUCCESS otherwise.
- */
- tasklet_async command error_t setChannel(uint8_t channel);
-
- /**
- * This event is signaled exactly once for each sucessfully posted state
- * transition and setChannel command when it is completed.
- */
- tasklet_async event void done();
-
- /**
- * Returns the currently selected channel.
- */
- tasklet_async command uint8_t getChannel();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-interface RandomCollisionConfig
-{
- /**
- * Returns the initial amount of maximum backoff for this message.
- */
- async command uint16_t getInitialBackoff(message_t* msg);
-
- /**
- * Returns the amount of maximum backoff when there is congestion
- * (the channel was busy for the first try)
- */
- async command uint16_t getCongestionBackoff(message_t* msg);
-
- /**
- * Returns the minimum ticks before the message could be sent.
- */
- async command uint16_t getMinimumBackoff();
-
- /**
- * The provided message was just received, and this command should return
- * the time till no transmission should be initiated.
- */
- async command uint16_t getTransmitBarrier(message_t* msg);
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration RandomCollisionLayerC
-{
- provides
- {
- interface RadioSend;
- interface RadioReceive;
- }
- uses
- {
- interface RadioSend as SubSend;
- interface RadioReceive as SubReceive;
- interface RandomCollisionConfig as Config;
- }
-}
-
-implementation
-{
- components RandomCollisionLayerP, RadioAlarmC, RandomC;
-
- RadioSend = RandomCollisionLayerP;
- SubSend = RandomCollisionLayerP;
- Config = RandomCollisionLayerP;
- RadioReceive = RandomCollisionLayerP;
- SubReceive = RandomCollisionLayerP;
-
- RandomCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
- RandomCollisionLayerP.Random -> RandomC;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-#include <RadioAssert.h>
-
-module RandomCollisionLayerP
-{
- provides
- {
- interface RadioSend;
- interface RadioReceive;
- }
- uses
- {
- interface RadioSend as SubSend;
- interface RadioReceive as SubReceive;
- interface RadioAlarm;
- interface Random;
- interface RandomCollisionConfig as Config;
- }
-}
-
-implementation
-{
- tasklet_norace uint8_t state;
- enum
- {
- STATE_READY = 0,
- STATE_TX_PENDING_FIRST = 1,
- STATE_TX_PENDING_SECOND = 2,
- STATE_TX_SENDING = 3,
-
- STATE_BARRIER = 0x80,
- };
-
- tasklet_norace message_t *txMsg;
- tasklet_norace uint16_t txBarrier;
-
- tasklet_async event void SubSend.ready()
- {
- if( state == STATE_READY && call RadioAlarm.isFree() )
- signal RadioSend.ready();
- }
-
- uint16_t nextRandom;
- task void calcNextRandom()
- {
- uint16_t a = call Random.rand16();
- atomic nextRandom = a;
- }
-
- uint16_t getBackoff(uint16_t maxBackoff)
- {
- uint16_t a;
-
- atomic
- {
- a = nextRandom;
- nextRandom += 273;
- }
- post calcNextRandom();
-
- return (a % maxBackoff) + call Config.getMinimumBackoff();
- }
-
- tasklet_async command error_t RadioSend.send(message_t* msg)
- {
- if( state != STATE_READY || ! call RadioAlarm.isFree() )
- return EBUSY;
-
- txMsg = msg;
- state = STATE_TX_PENDING_FIRST;
- call RadioAlarm.wait(getBackoff(call Config.getInitialBackoff(msg)));
-
- return SUCCESS;
- }
-
- tasklet_async event void RadioAlarm.fired()
- {
- error_t error;
- int16_t delay;
-
- ASSERT( state != STATE_READY );
-
- delay = (int16_t)txBarrier - call RadioAlarm.getNow();
-
- if( state == STATE_BARRIER )
- {
- state = STATE_READY;
-
- signal RadioSend.ready();
- return;
- }
- else if( (state & STATE_BARRIER) && delay > 0 )
- error = EBUSY;
- else
- error = call SubSend.send(txMsg);
-
- if( error != SUCCESS )
- {
- if( (state & ~STATE_BARRIER) == STATE_TX_PENDING_FIRST )
- {
- state = (state & STATE_BARRIER) | STATE_TX_PENDING_SECOND;
- call RadioAlarm.wait(getBackoff(call Config.getCongestionBackoff(txMsg)));
- }
- else
- {
- if( (state & STATE_BARRIER) && delay > 0 )
- {
- state = STATE_BARRIER;
- call RadioAlarm.wait(delay);
- }
- else
- state = STATE_READY;
-
- signal RadioSend.sendDone(error);
- }
- }
- else
- state = STATE_TX_SENDING;
- }
-
- tasklet_async event void SubSend.sendDone(error_t error)
- {
- ASSERT( state == STATE_TX_SENDING );
-
- state = STATE_READY;
- signal RadioSend.sendDone(error);
- }
-
- tasklet_async event bool SubReceive.header(message_t* msg)
- {
- return signal RadioReceive.header(msg);
- }
-
- tasklet_async event message_t* SubReceive.receive(message_t* msg)
- {
- int16_t delay;
-
- txBarrier = call Config.getTransmitBarrier(msg);
- delay = txBarrier - call RadioAlarm.getNow();
-
- if( delay > 0 )
- {
- if( state == STATE_READY )
- {
- call RadioAlarm.wait(delay);
- state = STATE_BARRIER;
- }
- else
- state |= STATE_BARRIER;
- }
-
- return signal RadioReceive.receive(msg);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-interface SlottedCollisionConfig
-{
- /**
- * This command should return the approximate transmit delay between
- * setting an alarm, waiting for the fire event, calling send and
- * obtaining the timestamp for the transmitted message.
- */
- async command uint16_t getInitialDelay();
-
- /**
- * Must return a binary exponent so that the collision avoidance layer
- * can assign slots in the range of [0, 1 << exponent) of size collision
- * window.
- */
- async command uint8_t getScheduleExponent();
-
- /**
- * This command must return the time when the message was transmitted.
- */
- async command uint16_t getTransmitTime(message_t* msg);
-
- /**
- * Returns the start of the collision window for this received message,
- * so transmit times in this range would be considered possible collisions.
- */
- async command uint16_t getCollisionWindowStart(message_t* msg);
-
- /**
- * Returns the size of the collision window for this received message.
- */
- async command uint16_t getCollisionWindowLength(message_t* msg);
-
- /**
- * This event should be called periodically to indicate the passing of
- * time (maybe we should use a timer)
- */
- tasklet_async event void timerTick();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration SlottedCollisionLayerC
-{
- provides
- {
- interface RadioSend;
- interface RadioReceive;
- }
- uses
- {
- interface RadioSend as SubSend;
- interface RadioReceive as SubReceive;
- interface SlottedCollisionConfig as Config;
- }
-}
-
-implementation
-{
- components SlottedCollisionLayerP, MainC, RadioAlarmC, RandomC;
-
- RadioSend = SlottedCollisionLayerP;
- RadioReceive = SlottedCollisionLayerP;
- SubSend = SlottedCollisionLayerP;
- SubReceive = SlottedCollisionLayerP;
- Config = SlottedCollisionLayerP;
-
- SlottedCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
- SlottedCollisionLayerP.Random -> RandomC;
- MainC.SoftwareInit -> SlottedCollisionLayerP;
-
-#ifdef RF2XX_DEBUG
- components DiagMsgC;
- SlottedCollisionLayerP.DiagMsg -> DiagMsgC;
-#endif
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-#include <RadioAssert.h>
-
-module SlottedCollisionLayerP
-{
- provides
- {
- interface RadioSend;
- interface RadioReceive;
- interface Init;
- }
- uses
- {
- interface RadioSend as SubSend;
- interface RadioReceive as SubReceive;
- interface RadioAlarm;
- interface Random;
- interface SlottedCollisionConfig as Config;
-#ifdef RF2XX_DEBUG
- interface DiagMsg;
-#endif
- }
-}
-
-implementation
-{
-/* ----- random ----- */
-
- uint16_t nextRandom;
-
- task void calcNextRandom()
- {
- uint16_t a = call Random.rand16();
- atomic nextRandom = a;
- }
-
- uint16_t getNextRandom()
- {
- uint16_t a;
-
- atomic
- {
- a = nextRandom;
- nextRandom += 273;
- }
- post calcNextRandom();
-
- return a;
- }
-
-/* ----- schedule selection ----- */
-
- tasklet_async event bool SubReceive.header(message_t* msg)
- {
- return signal RadioReceive.header(msg);
- }
-
- // WARNING!!! Do not change these values, the error values can overflow
- enum
- {
- ERROR_DECAY = 3,
- ERROR_SWITCH = 30, // should be a multiple of (1 << decay)
- ERROR_COLLISION = 20, // must be less than (255 - switch) >> decay
- ERROR_BUSY = 1, // must be less than collision
- ERROR_INITIAL = 80, // must be less than giveup
- ERROR_GIVEUP = 120, // must be less than collision * (1 << decay)
- ERROR_REPRESS = 40, // must be more than switch
- ERROR_MAX = 255,
- };
-
- /**
- * Returns TRUE if time is between start and start + window
- * modulo the schedule size of (1 << exponent)
- */
- inline bool isBetween(uint8_t exponent, uint16_t time, uint16_t start, uint16_t length)
- {
- return (uint16_t)((time - start) & ((1 << exponent) - 1)) < length;
- }
-
- tasklet_norace uint16_t schedule1;
- tasklet_norace uint16_t schedule2;
-
- tasklet_norace uint8_t error1;
- tasklet_norace uint8_t error2;
-
- tasklet_async event message_t* SubReceive.receive(message_t* msg)
- {
- uint8_t exponent = call Config.getScheduleExponent();
- uint16_t start = call Config.getCollisionWindowStart(msg);
- uint16_t length = call Config.getCollisionWindowLength(msg);
-
- error1 -= error1 >> ERROR_DECAY;
- if( isBetween(exponent, schedule1, start, length) )
- error1 += ERROR_COLLISION;
-
- error2 -= error2 >> ERROR_DECAY;
- if( isBetween(exponent, schedule2, start, length) )
- error2 += ERROR_COLLISION;
-
- if( error2 + ERROR_SWITCH <= error1 )
- {
- error1 = error2;
- schedule1 = schedule2;
- error2 = ERROR_GIVEUP;
- }
-
- if( error2 >= ERROR_GIVEUP )
- {
- error2 = ERROR_INITIAL;
- schedule2 = getNextRandom();
- }
-
- return signal RadioReceive.receive(msg);
- }
-
- void printStats();
-
- tasklet_async event void Config.timerTick()
- {
- if( error1 >= (1 << ERROR_DECAY) )
- error1 -= error1 >> ERROR_DECAY;
- else if( error1 > 0 )
- --error1;
-
- if( error2 >= (1 << ERROR_DECAY) )
- error2 -= error2 >> ERROR_DECAY;
- else if( error2 > 0 )
- --error2;
-
- printStats();
- }
-
-/* ------ transmit ------ */
-
- tasklet_norace uint8_t state;
- enum
- {
- STATE_READY = 0,
- STATE_PENDING = 1,
- STATE_SENDING = 2,
- };
-
- enum { DELAY_DECAY = 2 };
-
- tasklet_norace message_t *txMsg;
- tasklet_norace uint16_t txDelay; // the averaged delay between schedule and timestamp
- tasklet_norace uint16_t txTime; // the schedule time of transmission
-
- tasklet_async event void SubSend.ready()
- {
- if( state == STATE_READY && call RadioAlarm.isFree() )
- signal RadioSend.ready();
- }
-
- tasklet_async command error_t RadioSend.send(message_t* msg)
- {
- uint16_t backoff;
- uint16_t time;
-
- // TODO: we could supress transmission while error is large
- if( state != STATE_READY || ! call RadioAlarm.isFree() || error1 >= ERROR_REPRESS )
- return EBUSY;
-
- txMsg = msg;
- state = STATE_PENDING;
-
- time = call RadioAlarm.getNow();
- backoff = 1 + ((schedule1 - time - (txDelay >> DELAY_DECAY))
- & ((1 << call Config.getScheduleExponent()) - 1));
-
- backoff += getNextRandom() & (3 << call Config.getScheduleExponent());
-
- call RadioAlarm.wait(backoff);
- txTime = time + backoff;
-
- return SUCCESS;
- }
-
- tasklet_async event void RadioAlarm.fired()
- {
- error_t error;
-
- ASSERT( state == STATE_PENDING );
-
- error = call SubSend.send(txMsg);
- if( error == SUCCESS )
- state = STATE_SENDING;
- else
- {
- if( error2 + ERROR_SWITCH <= error1 )
- {
- error1 = error2;
- schedule1 = schedule2;
- error2 = ERROR_INITIAL;
- schedule2 = getNextRandom();
- }
- else if( error1 < ERROR_MAX - ERROR_BUSY )
- error1 = error1 + ERROR_BUSY;
-
- state = STATE_READY;
- signal RadioSend.sendDone(error);
- }
- }
-
- tasklet_async event void SubSend.sendDone(error_t error)
- {
- ASSERT( state == STATE_SENDING );
-
- if( error == SUCCESS )
- {
- txDelay += (call Config.getTransmitTime(txMsg) - txTime) - (txDelay >> DELAY_DECAY);
-
- ASSERT( (txDelay >> DELAY_DECAY) < (1 << call Config.getScheduleExponent()) );
- }
-
- state = STATE_READY;
- signal RadioSend.sendDone(error);
- }
-
-/* ------ init ------ */
-
- command error_t Init.init()
- {
- // do not use Random here because it might not be initialized
- schedule1 = (uint16_t)(TOS_NODE_ID * 1973);
- schedule2 = schedule1 + 0117;
- txDelay = call Config.getInitialDelay() << DELAY_DECAY;
-
- return SUCCESS;
- }
-
-#ifdef RF2XX_DEBUG
- tasklet_norace uint8_t count;
- void printStats()
- {
- if( ++count > 10 && call DiagMsg.record() )
- {
- count = 0;
-
- call DiagMsg.str("slotted");
- call DiagMsg.uint16(txDelay >> DELAY_DECAY);
- call DiagMsg.uint16(schedule1);
- call DiagMsg.uint8(error1);
- call DiagMsg.uint16(schedule2);
- call DiagMsg.uint8(error2);
- call DiagMsg.send();
- }
- }
-#else
- void printStats() { }
-#endif
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-interface SoftwareAckConfig
-{
- /**
- * Returns the acknowledgement timeout (in the radio clock units),
- * in which a sent packet must be acknowledged.
- */
- async command uint16_t getAckTimeout();
-
- /**
- * Returns TRUE if the layer should wait for a software acknowledgement
- * to be received after this packet was transmitted.
- */
- async command bool requiresAckWait(message_t* msg);
-
- /**
- * Sets for the transmitted message whether it was acknowledged or not.
- */
- async command void setAckReceived(message_t* msg, bool acked);
-
- /**
- * Returns TRUE if the received packet is an acknowledgement packet.
- * The AckedSend layer will filter out all received acknowledgement
- * packets and uses only the matching one for the acknowledgement.
- */
- async command bool isAckPacket(message_t* msg);
-
- /**
- * Returns TRUE if the acknowledgement packet corresponds to the
- * data packet. The acknowledgement packect was already verified
- * to be a valid acknowledgement packet via the isAckPacket command.
- */
- async command bool verifyAckPacket(message_t* data, message_t* ack);
-
- /**
- * Returns TRUE if the received packet needs software acknowledgements
- * to be sent back to the sender.
- */
- async command bool requiresAckReply(message_t* msg);
-
- /**
- * Creates an acknowledgement packet for the given data packet.
- */
- async command void createAckPacket(message_t* data, message_t* ack);
-
- /**
- * This command is called when a sent packet did not receive an
- * acknowledgement.
- */
- tasklet_async command void reportChannelError();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration SoftwareAckLayerC
-{
- provides
- {
- interface RadioSend;
- interface RadioReceive;
- }
- uses
- {
- interface RadioSend as SubSend;
- interface RadioReceive as SubReceive;
-
- interface SoftwareAckConfig as Config;
- }
-}
-
-implementation
-{
- components SoftwareAckLayerP, RadioAlarmC;
-
- RadioSend = SoftwareAckLayerP;
- RadioReceive = SoftwareAckLayerP;
- SubSend = SoftwareAckLayerP;
- SubReceive = SoftwareAckLayerP;
- Config = SoftwareAckLayerP;
-
- SoftwareAckLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-#include <RadioAssert.h>
-
-module SoftwareAckLayerP
-{
- provides
- {
- interface RadioSend;
- interface RadioReceive;
- }
- uses
- {
- interface RadioSend as SubSend;
- interface RadioReceive as SubReceive;
- interface RadioAlarm;
-
- interface SoftwareAckConfig;
- }
-}
-
-implementation
-{
- tasklet_norace uint8_t state;
- enum
- {
- STATE_READY = 0,
- STATE_DATA_SEND = 1,
- STATE_ACK_WAIT = 2,
- STATE_ACK_SEND = 3,
- };
-
- tasklet_norace message_t *txMsg;
- tasklet_norace message_t ackMsg;
-
- tasklet_async event void SubSend.ready()
- {
- if( state == STATE_READY )
- signal RadioSend.ready();
- }
-
- tasklet_async command error_t RadioSend.send(message_t* msg)
- {
- error_t error;
-
- if( state == STATE_READY )
- {
- if( (error = call SubSend.send(msg)) == SUCCESS )
- {
- call SoftwareAckConfig.setAckReceived(msg, FALSE);
- state = STATE_DATA_SEND;
- txMsg = msg;
- }
- }
- else
- error = EBUSY;
-
- return error;
- }
-
- tasklet_async event void SubSend.sendDone(error_t error)
- {
- if( state == STATE_ACK_SEND )
- {
- // TODO: what if error != SUCCESS
- ASSERT( error == SUCCESS );
-
- state = STATE_READY;
- }
- else
- {
- ASSERT( state == STATE_DATA_SEND );
- ASSERT( call RadioAlarm.isFree() );
-
- if( error == SUCCESS && call SoftwareAckConfig.requiresAckWait(txMsg) && call RadioAlarm.isFree() )
- {
- call RadioAlarm.wait(call SoftwareAckConfig.getAckTimeout());
- state = STATE_ACK_WAIT;
- }
- else
- {
- state = STATE_READY;
- signal RadioSend.sendDone(error);
- }
- }
- }
-
- tasklet_async event void RadioAlarm.fired()
- {
- ASSERT( state == STATE_ACK_WAIT );
-
- call SoftwareAckConfig.reportChannelError();
-
- state = STATE_READY;
- signal RadioSend.sendDone(SUCCESS); // we have sent it, but not acked
- }
-
- tasklet_async event bool SubReceive.header(message_t* msg)
- {
- if( call SoftwareAckConfig.isAckPacket(msg) )
- return state == STATE_ACK_WAIT && call SoftwareAckConfig.verifyAckPacket(txMsg, msg);
- else
- return signal RadioReceive.header(msg);
- }
-
- tasklet_async event message_t* SubReceive.receive(message_t* msg)
- {
- bool ack = call SoftwareAckConfig.isAckPacket(msg);
-
- ASSERT( state == STATE_ACK_WAIT || state == STATE_READY );
-
- if( state == STATE_ACK_WAIT )
- {
- ASSERT( !ack || call SoftwareAckConfig.verifyAckPacket(txMsg, msg) );
-
- call RadioAlarm.cancel();
- call SoftwareAckConfig.setAckReceived(txMsg, ack);
-
- state = STATE_READY;
- signal RadioSend.sendDone(SUCCESS);
- }
-
- if( ack )
- return msg;
-
- if( call SoftwareAckConfig.requiresAckReply(msg) )
- {
- call SoftwareAckConfig.createAckPacket(msg, &ackMsg);
-
- // TODO: what to do if we are busy and cannot send an ack
- if( call SubSend.send(&ackMsg) == SUCCESS )
- state = STATE_ACK_SEND;
- else
- ASSERT(FALSE);
- }
-
- return signal RadioReceive.receive(msg);
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __TASKLET_H__
-#define __TASKLET_H__
-
-#ifdef TASKLET_IS_TASK
-
- #define tasklet_async
- #define tasklet_norace
-
-#else
-
- #define tasklet_async async
- #define tasklet_norace norace
-
-#endif
-
-#endif//__TASKLET_H__
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-/**
- * This interface is useful in building state machines when the state
- * transitions should be executed atomically but with interrupts enabled.
- * All state transitions should take place in the run event handler or
- * in blocks protected by the suspend and resume commands.
- */
-interface Tasklet
-{
- /**
- * This method is executed atomically.
- */
- tasklet_async event void run();
-
- /**
- * Makes sure that the run event is called at least once more. If the
- * run event is currently not executing, then it is called immediately
- * and this command returns only after the completion of the run event.
- * If the run event is currently executed, then this method returns at
- * once, and makes sure that the run event is called once more when
- * it is finished. If this method is called from a task, then by the
- * above rules, the run event will be called from a task as well.
- */
- async command void schedule();
-
- /**
- * Enters a critical section of the code and meakes sure that the
- * run event is not called while in this section. No long running
- * computation should be called from the critical session, and
- * in particular no user event should be fired. This call is only
- * possible from task context, otherwise we cannot guarantee that
- * the run event is not currently running. The suspend calls
- * can be nested. It is very important that the same number of
- * resume commands must be called in all control paths, e.g. be very
- * careful with the return and break commands.
- */
- command void suspend();
-
- /**
- * Leaves the critical section. This call is conly possible from
- * task context. If there were scheduled executions of the run
- * event, then those will be called before this command returns.
- */
- command void resume();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-#include <RadioAssert.h>
-
-module TaskletC
-{
- provides interface Tasklet;
-}
-
-implementation
-{
-#ifdef TASKLET_IS_TASK
-
- task void tasklet()
- {
- signal Tasklet.run();
- }
-
- inline async command void Tasklet.schedule()
- {
- post tasklet();
- }
-
- inline command void Tasklet.suspend()
- {
- }
-
- inline command void Tasklet.resume()
- {
- }
-
-#else
-
- /**
- * The lower 7 bits contain the number of suspends plus one if the run
- * event is currently beeing executed. The highest bit is set if the run
- * event needs to be called again when the suspend count goes down to zero.
- */
- uint8_t state;
-
- void doit()
- {
- for(;;)
- {
- signal Tasklet.run();
-
- atomic
- {
- if( state == 1 )
- {
- state = 0;
- return;
- }
-
- ASSERT( state == 0x81 );
- state = 1;
- }
- }
- }
-
- inline command void Tasklet.suspend()
- {
- atomic ++state;
- }
-
- command void Tasklet.resume()
- {
- atomic
- {
- if( --state != 0x80 )
- return;
-
- state = 1;
- }
-
- doit();
- }
-
- async command void Tasklet.schedule()
- {
- atomic
- {
- if( state != 0 )
- {
- state |= 0x80;
- return;
- }
-
- state = 1;
- }
-
- doit();
- }
-
-#endif
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __TIMESYNCMESSAGE_H__
-#define __TIMESYNCMESSAGE_H__
-
-// this value is sent in the air
-typedef nx_int32_t timesync_relative_t;
-
-// this value is stored in memory
-typedef uint32_t timesync_absolute_t;
-
-#endif//__TIMESYNCMESSAGE_H__
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-interface TrafficMonitorConfig
-{
- /**
- * Returns the frequency (in milliseconds) when the traffic averages
- * should be updated.
- */
- async command uint16_t getUpdatePeriod();
-
- /**
- * Returns the amount of time this message has occupied the channel.
- */
- async command uint16_t getChannelTime(message_t* msg);
-
- /**
- * Returns the sender address of the message so we can calculate the
- * average number of neighbors that send messages per update period.
- */
- async command am_addr_t getSender(message_t* msg);
-
- /**
- * This event should be fired if we notice some anomalies in the operation
- * of the channel, such as not receiving acknowledgements, missing
- * sequence numbers or packets with corrupted CRC.
- */
- tasklet_async event void channelError();
-
- /**
- * Returns the averaged (exponential decay) transmit channel time
- * during one update period.
- */
- tasklet_async event uint16_t getTransmitAverage();
-
- /**
- * Returns the averaged (exponential decay) receive channel time
- * during one update period.
- */
- tasklet_async event uint16_t getReceiveAverage();
-
- /**
- * Returns the averaged (exponential decay) number of neighbors
- * whose messages this component receives during one update period.
- */
- tasklet_async event uint8_t getNeighborAverage();
-
- /**
- * Returns the averaged error events during one update period.
- */
- tasklet_async event uint8_t getErrorAverage();
-
- /**
- * This command is periodically called when the timer is fired and
- * the averages are updated
- */
- tasklet_async command void timerTick();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration TrafficMonitorLayerC
-{
- provides
- {
- interface RadioSend;
- interface RadioReceive;
- interface RadioState;
- }
- uses
- {
- interface RadioSend as SubSend;
- interface RadioReceive as SubReceive;
- interface RadioState as SubState;
-
- interface TrafficMonitorConfig as Config;
- }
-}
-
-implementation
-{
- components TrafficMonitorLayerP, new TimerMilliC() as UpdateTimerC;
- components NeighborhoodC, new NeighborhoodFlagC(), TaskletC;
-
- RadioSend = TrafficMonitorLayerP;
- RadioReceive = TrafficMonitorLayerP;
- RadioState = TrafficMonitorLayerP;
- SubSend = TrafficMonitorLayerP;
- SubReceive = TrafficMonitorLayerP;
- SubState = TrafficMonitorLayerP;
- Config = TrafficMonitorLayerP;
-
- TrafficMonitorLayerP.Timer -> UpdateTimerC;
- TrafficMonitorLayerP.Neighborhood -> NeighborhoodC;
- TrafficMonitorLayerP.NeighborhoodFlag -> NeighborhoodFlagC;
- TrafficMonitorLayerP.Tasklet -> TaskletC;
-
-#ifdef RF2XX_DEBUG
- components DiagMsgC;
- TrafficMonitorLayerP.DiagMsg -> DiagMsgC;
-#endif
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, reportS, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-/*
- * You have to make sure that the maximum channel time in one report
- * period times (1 << TRAFFIC_MONITOR_DECAY) is less than 65535.
- */
-#ifndef TRAFFIC_MONITOR_DECAY
-#define TRAFFIC_MONITOR_DECAY 3
-#endif
-
-module TrafficMonitorLayerP
-{
- provides
- {
- interface RadioSend;
- interface RadioReceive;
- interface RadioState;
- }
-
- uses
- {
- interface TrafficMonitorConfig;
- interface RadioSend as SubSend;
- interface RadioReceive as SubReceive;
- interface RadioState as SubState;
- interface Timer<TMilli> as Timer;
- interface Neighborhood;
- interface NeighborhoodFlag;
- interface Tasklet;
-#ifdef RF2XX_DEBUG
- interface DiagMsg;
-#endif
- }
-}
-
-implementation
-{
- tasklet_norace message_t *txMsg;
- tasklet_norace uint8_t neighborCount;
-
- tasklet_norace uint16_t txAverage;
- tasklet_norace uint16_t rxAverage;
- tasklet_norace uint8_t neighborAverage;
- tasklet_norace uint8_t errorAverage;
-
- enum
- {
- // the maximum average value
- TRAFFIC_MONITOR_UINT8_MAX = 1 << (7-TRAFFIC_MONITOR_DECAY),
-
- // the unsignificant bits of the averaged values
- TRAFFIC_MONITOR_MASK = (1 << TRAFFIC_MONITOR_DECAY) - 1,
-
- // to get the ceiling integer value
- TRAFFIC_MONITOR_ROUND_UP = (1 << TRAFFIC_MONITOR_DECAY) - 1,
- };
-
- tasklet_async event void SubSend.ready()
- {
- signal RadioSend.ready();
- }
-
- tasklet_async command error_t RadioSend.send(message_t* msg)
- {
- txMsg = msg;
- return call SubSend.send(msg);
- }
-
- tasklet_async event void SubSend.sendDone(error_t error)
- {
- if( error == SUCCESS )
- txAverage += call TrafficMonitorConfig.getChannelTime(txMsg);
-
- signal RadioSend.sendDone(error);
- }
-
- tasklet_async event bool SubReceive.header(message_t* msg)
- {
- return signal RadioReceive.header(msg);
- }
-
- tasklet_async event message_t* SubReceive.receive(message_t* msg)
- {
- uint8_t index;
-
- rxAverage += call TrafficMonitorConfig.getChannelTime(msg);
-
- index = call Neighborhood.insertNode(call TrafficMonitorConfig.getSender(msg));
- if( ! call NeighborhoodFlag.get(index) )
- {
- if( neighborCount < TRAFFIC_MONITOR_UINT8_MAX )
- {
- ++neighborCount;
- call NeighborhoodFlag.set(index);
- }
- }
-
- return signal RadioReceive.receive(msg);
- }
-
- tasklet_async event void TrafficMonitorConfig.channelError()
- {
- if( errorAverage < 255 )
- ++errorAverage;
- }
-
- uint8_t debugCounter;
-
- event void Timer.fired()
- {
- uint8_t fraction;
-
- call Tasklet.suspend();
-
- txAverage -= (txAverage >> TRAFFIC_MONITOR_DECAY);
- rxAverage -= (rxAverage >> TRAFFIC_MONITOR_DECAY);
- errorAverage -= (errorAverage >> TRAFFIC_MONITOR_DECAY);
-
- // we could get stuck in the [1,7] range with no neighbors, so be more precise
- fraction = neighborAverage >> TRAFFIC_MONITOR_DECAY;
- if( fraction == neighborCount && (neighborAverage & TRAFFIC_MONITOR_MASK) != 0 )
- --neighborAverage;
- else
- neighborAverage += neighborCount - fraction;
-
- call NeighborhoodFlag.clearAll();
- neighborCount = 0;
-
- call TrafficMonitorConfig.timerTick();
-
- call Tasklet.resume();
-
-#ifdef RF2XX_DEBUG
- if( ++debugCounter >= 10 && call DiagMsg.record() )
- {
- debugCounter = 0;
-
- call DiagMsg.str("traffic");
- call DiagMsg.uint16(signal TrafficMonitorConfig.getTransmitAverage());
- call DiagMsg.uint16(signal TrafficMonitorConfig.getReceiveAverage());
- call DiagMsg.uint8(signal TrafficMonitorConfig.getNeighborAverage());
- call DiagMsg.uint8(signal TrafficMonitorConfig.getErrorAverage());
- call DiagMsg.send();
- }
-#endif
- }
-
- tasklet_async event void Tasklet.run()
- {
- }
-
- tasklet_async event uint16_t TrafficMonitorConfig.getTransmitAverage()
- {
- return txAverage >> TRAFFIC_MONITOR_DECAY;
- }
-
- tasklet_async event uint16_t TrafficMonitorConfig.getReceiveAverage()
- {
- return rxAverage >> TRAFFIC_MONITOR_DECAY;
- }
-
- tasklet_async event uint8_t TrafficMonitorConfig.getNeighborAverage()
- {
- return (neighborAverage + TRAFFIC_MONITOR_ROUND_UP) >> TRAFFIC_MONITOR_DECAY;
- }
-
- tasklet_async event uint8_t TrafficMonitorConfig.getErrorAverage()
- {
- return errorAverage >> TRAFFIC_MONITOR_DECAY;
- }
-
- tasklet_async event void Neighborhood.evicted(uint8_t index) { }
-
- enum
- {
- RADIO_CMD_NONE = 0,
- RADIO_CMD_TURNON = 1,
- RADIO_CMD_TURNOFF = 2,
- };
- tasklet_norace uint8_t radioCmd;
-
- tasklet_async command error_t RadioState.turnOff()
- {
- radioCmd = RADIO_CMD_TURNOFF;
- return call SubState.turnOff();
- }
-
- tasklet_async command error_t RadioState.standby()
- {
- radioCmd = RADIO_CMD_TURNOFF;
- return call SubState.standby();
- }
-
- tasklet_async command error_t RadioState.turnOn()
- {
- radioCmd = RADIO_CMD_TURNON;
- return call SubState.turnOn();
- }
-
- tasklet_async command error_t RadioState.setChannel(uint8_t channel)
- {
- radioCmd = RADIO_CMD_NONE;
- return call SubState.setChannel(channel);
- }
-
- tasklet_async command uint8_t RadioState.getChannel()
- {
- return call SubState.getChannel();
- }
-
- task void startStopTimer()
- {
- if( radioCmd == RADIO_CMD_TURNON )
- call Timer.startPeriodic(call TrafficMonitorConfig.getUpdatePeriod());
- else if( radioCmd == RADIO_CMD_TURNOFF )
- call Timer.stop();
- }
-
- tasklet_async event void SubState.done()
- {
- post startStopTimer();
- signal RadioState.done();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-
-interface UniqueConfig
-{
- /**
- * Returns the sequence number of the packet.
- */
- async command uint8_t getSequenceNumber(message_t* msg);
-
- /**
- * Returns the sender of the packet.
- */
- async command am_addr_t getSender(message_t* msg);
-
- /**
- * Sets the sequence number of the packet.
- */
- async command void setSequenceNumber(message_t*msg, uint8_t number);
-
- /**
- * This command is called when the unqiue layer detects a missing (jump
- * in the data sequence number) or a duplicate packet.
- */
- tasklet_async command void reportChannelError();
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-configuration UniqueLayerC
-{
- provides
- {
- // NOTE, this is a combined layer, should be hooked up at two places
- interface Send;
- interface RadioReceive;
- }
- uses
- {
- interface Send as SubSend;
- interface RadioReceive as SubReceive;
-
- interface UniqueConfig as Config;
- }
-}
-
-implementation
-{
- components UniqueLayerP, MainC, NeighborhoodC, new NeighborhoodFlagC();
-
- MainC.SoftwareInit -> UniqueLayerP;
- UniqueLayerP.Neighborhood -> NeighborhoodC;
- UniqueLayerP.NeighborhoodFlag -> NeighborhoodFlagC;
-
- Send = UniqueLayerP;
- SubSend = UniqueLayerP;
-
- RadioReceive = UniqueLayerP;
- SubReceive = UniqueLayerP;
- Config = UniqueLayerP;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <Tasklet.h>
-#include <Neighborhood.h>
-
-module UniqueLayerP
-{
- provides
- {
- interface Send;
- interface RadioReceive;
-
- interface Init;
- }
-
- uses
- {
- interface Send as SubSend;
- interface RadioReceive as SubReceive;
-
- interface UniqueConfig;
- interface Neighborhood;
- interface NeighborhoodFlag;
- }
-}
-
-implementation
-{
- uint8_t sequenceNumber;
-
- command error_t Init.init()
- {
- sequenceNumber = TOS_NODE_ID << 4;
- return SUCCESS;
- }
-
- command error_t Send.send(message_t* msg, uint8_t len)
- {
- call UniqueConfig.setSequenceNumber(msg, ++sequenceNumber);
- return call SubSend.send(msg, len);
- }
-
- command error_t Send.cancel(message_t* msg)
- {
- return call SubSend.cancel(msg);
- }
-
- event void SubSend.sendDone(message_t* msg, error_t error)
- {
- signal Send.sendDone(msg, error);
- }
-
- command uint8_t Send.maxPayloadLength()
- {
- return call SubSend.maxPayloadLength();
- }
-
- command void* Send.getPayload(message_t* msg, uint8_t len)
- {
- return call SubSend.getPayload(msg, len);
- }
-
- tasklet_async event bool SubReceive.header(message_t* msg)
- {
- // we could scan here, but better be lazy
- return signal RadioReceive.header(msg);
- }
-
- tasklet_norace uint8_t receivedNumbers[NEIGHBORHOOD_SIZE];
-
- tasklet_async event message_t* SubReceive.receive(message_t* msg)
- {
- uint8_t index = call Neighborhood.insertNode(call UniqueConfig.getSender(msg));
- uint8_t dsn = call UniqueConfig.getSequenceNumber(msg);
-
- if( call NeighborhoodFlag.get(index) )
- {
- uint8_t diff = dsn - receivedNumbers[index];
-
- if( diff == 0 )
- {
- call UniqueConfig.reportChannelError();
- return msg;
- }
- }
- else
- call NeighborhoodFlag.set(index);
-
- receivedNumbers[index] = dsn;
-
- return signal RadioReceive.receive(msg);
- }
-
- tasklet_async event void Neighborhood.evicted(uint8_t index) { }
-}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+interface ActiveMessageConfig
+{
+ /**
+ * This command is called when the message first enters the radio stack
+ * via the Send.send command. This should clear the packet if the user
+ * forgot to do so (or return EINVAL to be strict).
+ */
+ command error_t checkPacket(message_t* msg);
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+module ActiveMessageLayerC
+{
+ provides
+ {
+ interface AMSend[am_id_t id];
+ interface Receive[am_id_t id];
+ interface Receive as Snoop[am_id_t id];
+ }
+ uses
+ {
+ interface Send as SubSend;
+ interface Receive as SubReceive;
+ interface AMPacket;
+ interface ActiveMessageConfig as Config;
+ }
+}
+
+implementation
+{
+/*----------------- Send -----------------*/
+
+ command error_t AMSend.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len)
+ {
+ error_t error;
+
+ error = call Config.checkPacket(msg);
+ if( error != SUCCESS )
+ return error;
+
+ call AMPacket.setSource(msg, call AMPacket.address());
+ call AMPacket.setGroup(msg, call AMPacket.localGroup());
+ call AMPacket.setType(msg, id);
+ call AMPacket.setDestination(msg, addr);
+
+ return call SubSend.send(msg, len);
+ }
+
+ inline event void SubSend.sendDone(message_t* msg, error_t error)
+ {
+ signal AMSend.sendDone[call AMPacket.type(msg)](msg, error);
+ }
+
+ inline command error_t AMSend.cancel[am_id_t id](message_t* msg)
+ {
+ return call SubSend.cancel(msg);
+ }
+
+ default event void AMSend.sendDone[am_id_t id](message_t* msg, error_t error)
+ {
+ }
+
+ inline command uint8_t AMSend.maxPayloadLength[am_id_t id]()
+ {
+ return call SubSend.maxPayloadLength();
+ }
+
+ inline command void* AMSend.getPayload[am_id_t id](message_t* msg, uint8_t len)
+ {
+ return call SubSend.getPayload(msg, len);
+ }
+
+/*----------------- Receive -----------------*/
+
+ event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)
+ {
+ am_id_t type = call AMPacket.type(msg);
+
+ msg = call AMPacket.isForMe(msg)
+ ? signal Receive.receive[type](msg, payload, len)
+ : signal Snoop.receive[type](msg, payload, len);
+
+ return msg;
+ }
+
+ default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len)
+ {
+ return msg;
+ }
+
+ default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len)
+ {
+ return msg;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+interface CsmaConfig
+{
+ /**
+ * This command is called when the message is transmitted to
+ * check if it needs software clear channel assesment.
+ */
+ async command bool requiresSoftwareCCA(message_t* msg);
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration CsmaLayerC
+{
+ provides
+ {
+ interface RadioSend;
+ }
+ uses
+ {
+ interface RadioSend as SubSend;
+ interface RadioCCA as SubCCA;
+
+ interface CsmaConfig as Config;
+ }
+}
+
+implementation
+{
+ components CsmaLayerP;
+
+ RadioSend = CsmaLayerP;
+ SubSend = CsmaLayerP;
+ SubCCA = CsmaLayerP;
+ Config = CsmaLayerP;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+#include <RadioAssert.h>
+
+module CsmaLayerP
+{
+ provides
+ {
+ interface RadioSend;
+ }
+
+ uses
+ {
+ interface CsmaConfig as Config;
+
+ interface RadioSend as SubSend;
+ interface RadioCCA as SubCCA;
+ }
+}
+
+implementation
+{
+ tasklet_norace message_t *txMsg;
+
+ tasklet_norace uint8_t state;
+ enum
+ {
+ STATE_READY = 0,
+ STATE_CCA_WAIT = 1,
+ STATE_SEND = 2,
+ };
+
+ tasklet_async event void SubSend.ready()
+ {
+ if( state == STATE_READY )
+ signal RadioSend.ready();
+ }
+
+ tasklet_async command error_t RadioSend.send(message_t* msg)
+ {
+ error_t error;
+
+ if( state == STATE_READY )
+ {
+ if( call Config.requiresSoftwareCCA(msg) )
+ {
+ txMsg = msg;
+
+ if( (error = call SubCCA.request()) == SUCCESS )
+ state = STATE_CCA_WAIT;
+ }
+ else if( (error = call SubSend.send(msg)) == SUCCESS )
+ state = STATE_SEND;
+ }
+ else
+ error = EBUSY;
+
+ return error;
+ }
+
+ tasklet_async event void SubCCA.done(error_t error)
+ {
+ ASSERT( state == STATE_CCA_WAIT );
+
+ if( error == SUCCESS && (error = call SubSend.send(txMsg)) == SUCCESS )
+ state = STATE_SEND;
+ else
+ {
+ state = STATE_READY;
+ signal RadioSend.sendDone(EBUSY);
+ }
+ }
+
+ tasklet_async event void SubSend.sendDone(error_t error)
+ {
+ ASSERT( state == STATE_SEND );
+
+ state = STATE_READY;
+ signal RadioSend.sendDone(error);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+interface DummyConfig
+{
+ /**
+ * We need to put something here, but this is not going to get called
+ */
+ async command void nothing();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+generic configuration DummyLayerC()
+{
+ provides
+ {
+ interface SplitControl;
+ interface Send;
+ interface Receive;
+ interface LowPowerListening;
+
+ interface RadioState;
+ interface RadioSend;
+ interface RadioReceive;
+ interface RadioCCA;
+
+ interface DummyConfig as UnconnectedConfig;
+ }
+
+ uses
+ {
+ interface RadioState as SubState;
+ interface RadioSend as SubRadioSend;
+ interface RadioReceive as SubRadioReceive;
+ interface RadioCCA as SubRadioCCA;
+ interface SplitControl as SubControl;
+ interface Send as SubSend;
+ interface Receive as SubReceive;
+
+ interface DummyConfig as Config;
+ }
+}
+
+implementation
+{
+ RadioState = SubState;
+ RadioSend = SubRadioSend;
+ RadioReceive = SubRadioReceive;
+ RadioCCA = SubRadioCCA;
+
+ SplitControl = SubControl;
+ Send = SubSend;
+ Receive = SubReceive;
+
+ Config = UnconnectedConfig;
+
+ components DummyLayerP;
+ LowPowerListening = DummyLayerP.LowPowerListening;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+module DummyLayerP
+{
+ provides interface LowPowerListening;
+}
+
+implementation
+{
+ command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) { }
+
+ command uint16_t LowPowerListening.getLocalSleepInterval() { return 0; }
+
+ command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { }
+
+ command uint16_t LowPowerListening.getLocalDutyCycle() { return 10000; }
+
+ command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { }
+
+ command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { return 0; }
+
+ command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { }
+
+ command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { return 10000; }
+
+ command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) { return 0; }
+
+ command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) { return 10000; }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __GENERICTIMESYNCMESSAGE_H__
+#define __GENERICTIMESYNCMESSAGE_H__
+
+// this value is sent in the air
+typedef nx_int32_t timesync_relative_t;
+
+// this value is stored in memory
+typedef uint32_t timesync_absolute_t;
+
+#endif//__GENERICTIMESYNCMESSAGE_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Timer.h>
+#include <AM.h>
+#include <RadioConfig.h>
+
+configuration GenericTimeSyncMessageC
+{
+ provides
+ {
+ interface SplitControl;
+
+ interface Receive[uint8_t id];
+ interface Receive as Snoop[am_id_t id];
+ interface Packet;
+ interface AMPacket;
+
+ interface TimeSyncAMSend<TRadio, uint32_t> as TimeSyncAMSendRadio[am_id_t id];
+ interface TimeSyncPacket<TRadio, uint32_t> as TimeSyncPacketRadio;
+
+ interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
+ interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+ }
+
+ uses
+ {
+ interface PacketField<uint8_t> as PacketTimeSyncOffset;
+ interface LocalTime<TRadio> as LocalTimeRadio;
+ }
+}
+
+implementation
+{
+ components GenericTimeSyncMessageP, ActiveMessageC, LocalTimeMilliC;
+
+ TimeSyncAMSendRadio = GenericTimeSyncMessageP;
+ TimeSyncPacketRadio = GenericTimeSyncMessageP;
+
+ TimeSyncAMSendMilli = GenericTimeSyncMessageP;
+ TimeSyncPacketMilli = GenericTimeSyncMessageP;
+
+ Packet = GenericTimeSyncMessageP;
+ GenericTimeSyncMessageP.SubSend -> ActiveMessageC.AMSend;
+ GenericTimeSyncMessageP.SubPacket -> ActiveMessageC.Packet;
+
+ GenericTimeSyncMessageP.PacketTimeStampRadio -> ActiveMessageC;
+ GenericTimeSyncMessageP.PacketTimeStampMilli -> ActiveMessageC;
+ GenericTimeSyncMessageP.LocalTimeRadio = LocalTimeRadio;
+ GenericTimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC;
+
+ GenericTimeSyncMessageP.PacketTimeSyncOffset = PacketTimeSyncOffset;
+
+ SplitControl = ActiveMessageC;
+ Receive = ActiveMessageC.Receive;
+ Snoop = ActiveMessageC.Snoop;
+ AMPacket = ActiveMessageC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <GenericTimeSyncMessage.h>
+#include <RadioConfig.h>
+
+module GenericTimeSyncMessageP
+{
+ provides
+ {
+ interface TimeSyncAMSend<TRadio, uint32_t> as TimeSyncAMSendRadio[uint8_t id];
+ interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[uint8_t id];
+ interface Packet;
+
+ interface TimeSyncPacket<TRadio, uint32_t> as TimeSyncPacketRadio;
+ interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
+ }
+
+ uses
+ {
+ interface AMSend as SubSend[uint8_t id];
+ interface Packet as SubPacket;
+
+ interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+
+ interface LocalTime<TRadio> as LocalTimeRadio;
+ interface LocalTime<TMilli> as LocalTimeMilli;
+
+ interface PacketField<uint8_t> as PacketTimeSyncOffset;
+ }
+}
+
+implementation
+{
+ inline void* getFooter(message_t* msg)
+ {
+ // we use the payload length that we export (the smaller one)
+ return msg->data + call Packet.payloadLength(msg);
+ }
+
+/*----------------- Packet -----------------*/
+
+ command void Packet.clear(message_t* msg)
+ {
+ call SubPacket.clear(msg);
+ }
+
+ command void Packet.setPayloadLength(message_t* msg, uint8_t len)
+ {
+ call SubPacket.setPayloadLength(msg, len + sizeof(timesync_relative_t));
+ }
+
+ command uint8_t Packet.payloadLength(message_t* msg)
+ {
+ return call SubPacket.payloadLength(msg) - sizeof(timesync_relative_t);
+ }
+
+ command uint8_t Packet.maxPayloadLength()
+ {
+ return call SubPacket.maxPayloadLength() - sizeof(timesync_relative_t);
+ }
+
+ command void* Packet.getPayload(message_t* msg, uint8_t len)
+ {
+ return call SubPacket.getPayload(msg, len + sizeof(timesync_relative_t));
+ }
+
+/*----------------- TimeSyncAMSendRadio -----------------*/
+
+ command error_t TimeSyncAMSendRadio.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
+ {
+ *(timesync_absolute_t*)(msg->data + len) = event_time;
+
+ call PacketTimeSyncOffset.set(msg, len);
+
+ return call SubSend.send[id](addr, msg, len + sizeof(timesync_relative_t));
+ }
+
+ command error_t TimeSyncAMSendRadio.cancel[am_id_t id](message_t* msg)
+ {
+ return call SubSend.cancel[id](msg);
+ }
+
+ default event void TimeSyncAMSendRadio.sendDone[am_id_t id](message_t* msg, error_t error)
+ {
+ }
+
+ command uint8_t TimeSyncAMSendRadio.maxPayloadLength[am_id_t id]()
+ {
+ return call SubSend.maxPayloadLength[id]() - sizeof(timesync_relative_t);
+ }
+
+ command void* TimeSyncAMSendRadio.getPayload[am_id_t id](message_t* msg, uint8_t len)
+ {
+ return call SubSend.getPayload[id](msg, len + sizeof(timesync_relative_t));
+ }
+
+/*----------------- TimeSyncAMSendMilli -----------------*/
+
+ command error_t TimeSyncAMSendMilli.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
+ {
+ // compute elapsed time in millisecond
+ event_time = ((int32_t)(event_time - call LocalTimeMilli.get()) << RADIO_ALARM_MILLI_EXP) + call LocalTimeRadio.get();
+
+ return call TimeSyncAMSendRadio.send[id](addr, msg, len, event_time);
+ }
+
+ command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg)
+ {
+ return call TimeSyncAMSendRadio.cancel[id](msg);
+ }
+
+ default event void TimeSyncAMSendMilli.sendDone[am_id_t id](message_t* msg, error_t error)
+ {
+ }
+
+ command uint8_t TimeSyncAMSendMilli.maxPayloadLength[am_id_t id]()
+ {
+ return call TimeSyncAMSendRadio.maxPayloadLength[id]();
+ }
+
+ command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len)
+ {
+ return call TimeSyncAMSendRadio.getPayload[id](msg, len);
+ }
+
+ /*----------------- SubSend.sendDone -------------------*/
+
+ event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error)
+ {
+ signal TimeSyncAMSendRadio.sendDone[id](msg, error);
+ signal TimeSyncAMSendMilli.sendDone[id](msg, error);
+ }
+
+ /*----------------- TimeSyncPacketRadio -----------------*/
+
+ command bool TimeSyncPacketRadio.isValid(message_t* msg)
+ {
+ timesync_relative_t* timesync = getFooter(msg);
+
+ return call PacketTimeStampRadio.isValid(msg) && *timesync != 0x80000000L;
+ }
+
+ command uint32_t TimeSyncPacketRadio.eventTime(message_t* msg)
+ {
+ timesync_relative_t* timesync = getFooter(msg);
+
+ return (*timesync) + call PacketTimeStampRadio.timestamp(msg);
+ }
+
+ /*----------------- TimeSyncPacketMilli -----------------*/
+
+ command bool TimeSyncPacketMilli.isValid(message_t* msg)
+ {
+ timesync_relative_t* timesync = getFooter(msg);
+
+ return call PacketTimeStampMilli.isValid(msg) && *timesync != 0x80000000L;
+ }
+
+ command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg)
+ {
+ timesync_relative_t* timesync = getFooter(msg);
+
+ return ((int32_t)(*timesync) >> RADIO_ALARM_MILLI_EXP) + call PacketTimeStampMilli.timestamp(msg);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration IEEE154NetworkLayerC
+{
+ provides
+ {
+ interface SplitControl;
+ interface Send;
+ interface Receive;
+ }
+ uses
+ {
+ interface SplitControl as SubControl;
+ interface Send as SubSend;
+ interface Receive as SubReceive;
+ }
+}
+
+implementation
+{
+ components IEEE154NetworkLayerP, IEEE154PacketC;
+
+ SplitControl = SubControl;
+
+ Send = IEEE154NetworkLayerP;
+ Receive = IEEE154NetworkLayerP;
+
+ SubSend = IEEE154NetworkLayerP;
+ SubReceive = IEEE154NetworkLayerP;
+
+ IEEE154NetworkLayerP.IEEE154Packet -> IEEE154PacketC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+module IEEE154NetworkLayerP
+{
+ provides
+ {
+ interface Send;
+ interface Receive;
+ interface Receive as NonTinyosReceive[uint8_t network];
+ }
+
+ uses
+ {
+ interface Send as SubSend;
+ interface Receive as SubReceive;
+
+ interface IEEE154Packet;
+ }
+}
+
+implementation
+{
+#ifndef TINYOS_6LOWPAN_NETWORK_ID
+#define TINYOS_6LOWPAN_NETWORK_ID 0x3f
+#endif
+
+ command error_t Send.send(message_t* msg, uint8_t len)
+ {
+ call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID);
+ return call SubSend.send(msg, len);
+ }
+
+ command error_t Send.cancel(message_t* msg)
+ {
+ return call SubSend.cancel(msg);
+ }
+
+ command uint8_t Send.maxPayloadLength()
+ {
+ return call SubSend.maxPayloadLength();
+ }
+
+ command void* Send.getPayload(message_t* msg, uint8_t len)
+ {
+ return call SubSend.getPayload(msg, len);
+ }
+
+ event void SubSend.sendDone(message_t* msg, error_t error)
+ {
+ signal Send.sendDone(msg, error);
+ }
+
+ event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len)
+ {
+ uint8_t network = call IEEE154Packet.get6LowPan(msg);
+ if( network == TINYOS_6LOWPAN_NETWORK_ID )
+ return signal Receive.receive(msg, payload, len);
+ else
+ return signal NonTinyosReceive.receive[network](msg, payload, len);
+ }
+
+ default event message_t *NonTinyosReceive.receive[uint8_t network](message_t *msg, void *payload, uint8_t len)
+ {
+ return msg;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#warning "*** USING LOW POWER LISTENING LAYER"
+
+configuration LowPowerListeningLayerC
+{
+ provides
+ {
+ interface SplitControl;
+ interface Send;
+ interface Receive;
+
+ interface LowPowerListening;
+ }
+ uses
+ {
+ interface SplitControl as SubControl;
+ interface Send as SubSend;
+ interface Receive as SubReceive;
+
+ interface PacketField<uint16_t> as PacketSleepInterval;
+ interface IEEE154Packet;
+ interface PacketAcknowledgements;
+ }
+}
+
+implementation
+{
+ components LowPowerListeningLayerP, new TimerMilliC();
+
+ SplitControl = LowPowerListeningLayerP;
+ Send = LowPowerListeningLayerP;
+ Receive = LowPowerListeningLayerP;
+ LowPowerListening = LowPowerListeningLayerP;
+
+ SubControl = LowPowerListeningLayerP;
+ SubSend = LowPowerListeningLayerP;
+ SubReceive = LowPowerListeningLayerP;
+ PacketSleepInterval = LowPowerListeningLayerP;
+ IEEE154Packet = LowPowerListeningLayerP;
+ PacketAcknowledgements = LowPowerListeningLayerP;
+
+ LowPowerListeningLayerP.Timer -> TimerMilliC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <RadioAssert.h>
+
+module LowPowerListeningLayerP
+{
+ provides
+ {
+ interface SplitControl;
+ interface Send;
+ interface Receive;
+
+ interface LowPowerListening;
+ }
+
+ uses
+ {
+ interface SplitControl as SubControl;
+ interface Send as SubSend;
+ interface Receive as SubReceive;
+
+ interface PacketField<uint16_t> as PacketSleepInterval;
+ interface IEEE154Packet;
+ interface PacketAcknowledgements;
+ interface Timer<TMilli>;
+ }
+}
+
+implementation
+{
+ enum
+ {
+ // minimum wakeup time to catch a transmission in milliseconds
+ LISTEN_WAKEUP = 6U, // use xxxL if LISTEN_WAKEUP * 10000 > 65535
+
+ // extra wakeup time after receiving a message in milliseconds
+ AFTER_RECEIVE = 10U,
+
+ // extra wakeup time after transmitting a message in milliseconds
+ AFTER_TRANSMIT = 10U,
+
+ MIN_SLEEP = 2, // the minimum sleep interval in milliseconds
+ MAX_SLEEP = 30000, // the maximum sleep interval in milliseconds
+ MIN_DUTY = 2, // the minimum duty cycle
+ };
+
+ uint16_t sleepInterval;
+
+ message_t* txMsg;
+ uint8_t txLen;
+ error_t txError;
+
+/*----------------- state machine -----------------*/
+
+ enum
+ {
+ OFF = 0,
+ OFF_SUBSTOP = 1, // must have consecutive indices
+ OFF_SUBSTOP_DONE = 2, // must have consecutive indices
+ OFF_STOP_END = 3, // must have consecutive indices
+ OFF_START_END = 4,
+
+ LISTEN_SUBSTART = 5, // must have consecutive indices
+ LISTEN_SUBSTART_DONE = 6, // must have consecutive indices
+ LISTEN_TIMER = 7, // must have consecutive indices
+ LISTEN = 8, // must have consecutive indices
+
+ SLEEP_SUBSTOP = 9, // must have consecutive indices
+ SLEEP_SUBSTOP_DONE = 10, // must have consecutive indices
+ SLEEP_TIMER = 11, // must have consecutive indices
+ SLEEP = 12, // must have consecutive indices
+
+ SEND_SUBSTART = 13, // must have consecutive indices
+ SEND_SUBSTART_DONE = 14, // must have consecutive indices
+ SEND_TIMER = 15, // must have consecutive indices
+ SEND_SUBSEND= 16,
+ SEND_SUBSEND_DONE = 17,
+ SEND_SUBSEND_DONE_LAST = 18,
+ SEND_DONE = 19,
+ };
+
+ uint8_t state;
+
+ task void transition()
+ {
+ error_t error;
+ uint16_t transmitInterval;
+
+ if( state == LISTEN_SUBSTART || state == SEND_SUBSTART )
+ {
+ error = call SubControl.start();
+ ASSERT( error == SUCCESS || error == EBUSY );
+
+ if( error == SUCCESS )
+ ++state;
+ else
+ post transition();
+ }
+ else if( state == SLEEP_SUBSTOP || state == OFF_SUBSTOP )
+ {
+ error = call SubControl.stop();
+ ASSERT( error == SUCCESS || error == EBUSY );
+
+ if( error == SUCCESS )
+ ++state;
+ else
+ post transition();
+ }
+ else if( state == OFF_START_END )
+ {
+ state = LISTEN_SUBSTART;
+ post transition();
+
+ signal SplitControl.startDone(SUCCESS);
+ }
+ else if( state == OFF_STOP_END )
+ {
+ state = OFF;
+ signal SplitControl.stopDone(SUCCESS);
+ }
+ else if( state == LISTEN_TIMER )
+ {
+ state = LISTEN;
+ if( sleepInterval > 0 )
+ call Timer.startOneShot(LISTEN_WAKEUP);
+ }
+ else if( state == SLEEP_TIMER )
+ {
+ if( sleepInterval > 0 )
+ {
+ state = SLEEP;
+ call Timer.startOneShot(sleepInterval);
+ }
+ else
+ {
+ state = LISTEN_SUBSTART;
+ post transition();
+ }
+ }
+ else if( state == SEND_TIMER )
+ {
+ transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg);
+
+ if( transmitInterval > 0 )
+ call Timer.startOneShot(transmitInterval);
+
+ state = SEND_SUBSEND;
+ post transition();
+ }
+ else if( state == SEND_SUBSEND)
+ {
+ txError = call SubSend.send(txMsg, txLen);
+
+ if( txError == SUCCESS )
+ state = SEND_SUBSEND_DONE;
+ else
+ {
+ state = SEND_DONE;
+ post transition();
+ }
+ }
+ else if( state == SEND_DONE )
+ {
+ state = LISTEN;
+ if( sleepInterval > 0 )
+ call Timer.startOneShot(AFTER_TRANSMIT);
+
+ signal Send.sendDone(txMsg, txError);
+ }
+ }
+
+ command error_t SplitControl.start()
+ {
+ if( state == OFF_START_END )
+ return EBUSY;
+ else if( state != OFF )
+ return EALREADY;
+
+ state = OFF_START_END;
+ post transition();
+
+ return SUCCESS;
+ }
+
+ event void SubControl.startDone(error_t error)
+ {
+ ASSERT( error == SUCCESS || error == EBUSY );
+ ASSERT( state == LISTEN_SUBSTART_DONE || state == SEND_SUBSTART_DONE );
+
+ if( error == SUCCESS )
+ ++state;
+ else
+ --state;
+
+ post transition();
+ }
+
+ command error_t SplitControl.stop()
+ {
+ if( state == SLEEP || state == LISTEN )
+ {
+ call Timer.stop();
+ post transition();
+ }
+
+ if( state == LISTEN_TIMER || state == LISTEN || state == SLEEP_SUBSTOP )
+ state = OFF_SUBSTOP;
+ else if( state == SLEEP_SUBSTOP_DONE )
+ state = OFF_SUBSTOP_DONE;
+ else if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP )
+ state = OFF_STOP_END;
+ else if( state == OFF )
+ return EALREADY;
+ else
+ return EBUSY;
+
+ return SUCCESS;
+ }
+
+ event void SubControl.stopDone(error_t error)
+ {
+ ASSERT( error == SUCCESS || error == EBUSY );
+ ASSERT( state == SLEEP_SUBSTOP_DONE || state == OFF_SUBSTOP_DONE );
+
+ if( error == SUCCESS )
+ ++state;
+ else
+ --state;
+
+ post transition();
+ }
+
+ event void Timer.fired()
+ {
+ ASSERT( state == LISTEN || state == SLEEP || state == SEND_SUBSEND || state == SEND_SUBSEND_DONE );
+
+ if( state == LISTEN )
+ state = SLEEP_SUBSTOP;
+ else if( state == SLEEP )
+ state = LISTEN_SUBSTART;
+ else if( state == SEND_SUBSEND_DONE )
+ state = SEND_SUBSEND_DONE_LAST;
+ else if( state == SEND_SUBSEND)
+ state = SEND_DONE;
+
+ post transition();
+ }
+
+ event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)
+ {
+ if( state == SLEEP_SUBSTOP )
+ state = LISTEN;
+
+ if( state == LISTEN && sleepInterval > 0 )
+ call Timer.startOneShot(AFTER_RECEIVE);
+
+ return signal Receive.receive(msg, payload, len);
+ }
+
+ command error_t Send.send(message_t* msg, uint8_t len)
+ {
+ if( state == LISTEN || state == SLEEP )
+ {
+ call Timer.stop();
+ post transition();
+ }
+
+ if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP )
+ state = SEND_SUBSTART;
+ else if( state == LISTEN_SUBSTART_DONE )
+ state = SEND_SUBSTART_DONE;
+ else if( state == LISTEN_TIMER || state == SLEEP_SUBSTOP || state == LISTEN )
+ state = SEND_TIMER;
+ else
+ return EBUSY;
+
+ txMsg = msg;
+ txLen = len;
+ txError = FAIL;
+
+ return SUCCESS;
+ }
+
+ command error_t Send.cancel(message_t* msg)
+ {
+ if( state == SEND_SUBSEND )
+ {
+ call Timer.stop();
+ state = SEND_DONE;
+ txError = ECANCEL;
+ post transition();
+
+ return SUCCESS;
+ }
+ else if( state == SEND_SUBSEND_DONE )
+ {
+ // we stop sending the message even if SubSend.cancel was not succesfull
+ state = SEND_SUBSEND_DONE_LAST;
+
+ return call SubSend.cancel(txMsg);
+ }
+ else
+ return FAIL;
+ }
+
+ event void SubSend.sendDone(message_t* msg, error_t error)
+ {
+ ASSERT( state == SEND_SUBSEND_DONE || state == SEND_SUBSEND_DONE_LAST );
+ ASSERT( msg == txMsg );
+
+ txError = error;
+
+ // TODO: extend the PacketAcknowledgements interface with getAckRequired
+ if( error != SUCCESS
+ || call LowPowerListening.getRxSleepInterval(msg) == 0
+ || state == SEND_SUBSEND_DONE_LAST
+ || (call IEEE154Packet.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) )
+ {
+ call Timer.stop();
+ state = SEND_DONE;
+ }
+ else
+ state = SEND_SUBSEND;
+
+ post transition();
+ }
+
+ command uint8_t Send.maxPayloadLength()
+ {
+ return call SubSend.maxPayloadLength();
+ }
+
+ command void* Send.getPayload(message_t* msg, uint8_t len)
+ {
+ return call SubSend.getPayload(msg, len);
+ }
+
+/*----------------- LowPowerListening -----------------*/
+
+ command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle)
+ {
+ if( dutyCycle >= 10000 )
+ return 0;
+ else if( dutyCycle <= MIN_DUTY )
+ return MAX_SLEEP;
+
+ return ((10000U * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP;
+ }
+
+ command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval)
+ {
+ if( interval < MIN_SLEEP )
+ return 10000;
+ else if( interval >= MAX_SLEEP )
+ return MIN_DUTY;
+
+ return (10000U * LISTEN_WAKEUP) / (LISTEN_WAKEUP + interval);
+ }
+
+ command void LowPowerListening.setLocalSleepInterval(uint16_t interval)
+ {
+ if( interval < MIN_SLEEP )
+ interval = 0;
+ else if( interval > MAX_SLEEP )
+ interval = MAX_SLEEP;
+
+ sleepInterval = interval;
+
+ if( (state == LISTEN && sleepInterval == 0) || state == SLEEP )
+ {
+ call Timer.stop();
+ --state;
+ post transition();
+ }
+ }
+
+ command uint16_t LowPowerListening.getLocalSleepInterval()
+ {
+ return sleepInterval;
+ }
+
+ command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle)
+ {
+ call LowPowerListening.setLocalSleepInterval(
+ call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
+ }
+
+ command uint16_t LowPowerListening.getLocalDutyCycle()
+ {
+ return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval);
+ }
+
+ command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval)
+ {
+ if( interval < MIN_SLEEP )
+ interval = 0;
+ else if( interval > MAX_SLEEP )
+ interval = MAX_SLEEP;
+
+ call PacketSleepInterval.set(msg, interval);
+ }
+
+ command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg)
+ {
+ if( ! call PacketSleepInterval.isSet(msg) )
+ return sleepInterval;
+
+ return call PacketSleepInterval.get(msg);
+ }
+
+ command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle)
+ {
+ call LowPowerListening.setRxSleepInterval(msg,
+ call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
+ }
+
+ command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg)
+ {
+ return call LowPowerListening.sleepIntervalToDutyCycle(
+ call LowPowerListening.getRxSleepInterval(msg));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration MessageBufferLayerC
+{
+ provides
+ {
+ interface SplitControl;
+ interface Send;
+ interface Receive;
+ interface RadioChannel;
+ }
+ uses
+ {
+ interface RadioState;
+ interface RadioSend;
+ interface RadioReceive;
+
+ interface Packet;
+ }
+}
+
+implementation
+{
+ components MessageBufferLayerP, MainC, TaskletC;
+
+ MainC.SoftwareInit -> MessageBufferLayerP;
+
+ SplitControl = MessageBufferLayerP;
+ Send = MessageBufferLayerP;
+ Receive = MessageBufferLayerP;
+ RadioChannel = MessageBufferLayerP;
+
+ RadioState = MessageBufferLayerP;
+ MessageBufferLayerP.Tasklet -> TaskletC;
+ RadioSend = MessageBufferLayerP;
+ RadioReceive = MessageBufferLayerP;
+
+ Packet = MessageBufferLayerP;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+#include <RadioAssert.h>
+
+module MessageBufferLayerP
+{
+ provides
+ {
+ interface SplitControl;
+ interface Init as SoftwareInit;
+
+ interface Send;
+ interface Receive;
+ interface RadioChannel;
+ }
+ uses
+ {
+ interface RadioState;
+ interface Tasklet;
+ interface RadioSend;
+ interface RadioReceive;
+
+ interface Packet;
+ }
+}
+
+implementation
+{
+/*----------------- State -----------------*/
+
+ norace uint8_t state; // written only from tasks
+ enum
+ {
+ STATE_READY = 0,
+ STATE_TX_PENDING = 1,
+ STATE_TX_SEND = 2,
+ STATE_TX_DONE = 3,
+ STATE_TURN_ON = 4,
+ STATE_TURN_OFF = 5,
+ STATE_CHANNEL = 6,
+ };
+
+ command error_t SplitControl.start()
+ {
+ error_t error;
+
+ call Tasklet.suspend();
+
+ if( state != STATE_READY )
+ error = EBUSY;
+ else
+ error = call RadioState.turnOn();
+
+ if( error == SUCCESS )
+ state = STATE_TURN_ON;
+
+ call Tasklet.resume();
+
+ return error;
+ }
+
+ command error_t SplitControl.stop()
+ {
+ error_t error;
+
+ call Tasklet.suspend();
+
+ if( state != STATE_READY )
+ error = EBUSY;
+ else
+ error = call RadioState.turnOff();
+
+ if( error == SUCCESS )
+ state = STATE_TURN_OFF;
+
+ call Tasklet.resume();
+
+ return error;
+ }
+
+ command error_t RadioChannel.setChannel(uint8_t channel)
+ {
+ error_t error;
+
+ call Tasklet.suspend();
+
+ if( state != STATE_READY )
+ error = EBUSY;
+ else
+ error = call RadioState.setChannel(channel);
+
+ if( error == SUCCESS )
+ state = STATE_CHANNEL;
+
+ call Tasklet.resume();
+
+ return error;
+ }
+
+ command uint8_t RadioChannel.getChannel()
+ {
+ return call RadioState.getChannel();
+ }
+
+ task void stateDoneTask()
+ {
+ uint8_t s;
+
+ s = state;
+
+ // change the state before so we can be reentered from the event
+ state = STATE_READY;
+
+ if( s == STATE_TURN_ON )
+ signal SplitControl.startDone(SUCCESS);
+ else if( s == STATE_TURN_OFF )
+ signal SplitControl.stopDone(SUCCESS);
+ else if( s == STATE_CHANNEL )
+ signal RadioChannel.setChannelDone();
+ else // not our event, ignore it
+ state = s;
+ }
+
+ tasklet_async event void RadioState.done()
+ {
+ post stateDoneTask();
+ }
+
+ default event void SplitControl.startDone(error_t error)
+ {
+ }
+
+ default event void SplitControl.stopDone(error_t error)
+ {
+ }
+
+ default event void RadioChannel.setChannelDone()
+ {
+ }
+
+/*----------------- Send -----------------*/
+
+ message_t* txMsg;
+ error_t txError;
+ uint8_t retries;
+
+ // Many EBUSY replies from RadioSend are normal if the channel is cognested
+ enum { MAX_RETRIES = 5 };
+
+ task void sendTask()
+ {
+ error_t error;
+
+ ASSERT( state == STATE_TX_PENDING || state == STATE_TX_SEND );
+
+ atomic error = txError;
+ if( (state == STATE_TX_SEND && error == SUCCESS) || ++retries > MAX_RETRIES )
+ state = STATE_TX_DONE;
+ else
+ {
+ call Tasklet.suspend();
+
+ error = call RadioSend.send(txMsg);
+ if( error == SUCCESS )
+ state = STATE_TX_SEND;
+ else if( retries == MAX_RETRIES )
+ state = STATE_TX_DONE;
+ else
+ state = STATE_TX_PENDING;
+
+ call Tasklet.resume();
+ }
+
+ if( state == STATE_TX_DONE )
+ {
+ state = STATE_READY;
+ signal Send.sendDone(txMsg, error);
+ }
+ }
+
+ tasklet_async event void RadioSend.sendDone(error_t error)
+ {
+ ASSERT( state == STATE_TX_SEND );
+
+ atomic txError = error;
+ post sendTask();
+ }
+
+ command error_t Send.send(message_t* msg, uint8_t len)
+ {
+ if( len > call Packet.maxPayloadLength() )
+ return EINVAL;
+ else if( state != STATE_READY )
+ return EBUSY;
+
+ call Packet.setPayloadLength(msg, len);
+
+ txMsg = msg;
+ state = STATE_TX_PENDING;
+ retries = 0;
+ post sendTask();
+
+ return SUCCESS;
+ }
+
+ tasklet_async event void RadioSend.ready()
+ {
+ if( state == STATE_TX_PENDING )
+ post sendTask();
+ }
+
+ tasklet_async event void Tasklet.run()
+ {
+ }
+
+ command error_t Send.cancel(message_t* msg)
+ {
+ if( state == STATE_TX_PENDING )
+ {
+ state = STATE_READY;
+
+ // TODO: check if sendDone can be called before cancel returns
+ signal Send.sendDone(msg, ECANCEL);
+
+ return SUCCESS;
+ }
+ else
+ return FAIL;
+ }
+
+ default event void Send.sendDone(message_t* msg, error_t error)
+ {
+ }
+
+ inline command uint8_t Send.maxPayloadLength()
+ {
+ return call Packet.maxPayloadLength();
+ }
+
+ inline command void* Send.getPayload(message_t* msg, uint8_t len)
+ {
+ return call Packet.getPayload(msg, len);
+ }
+
+/*----------------- Receive -----------------*/
+
+ enum
+ {
+ RECEIVE_QUEUE_SIZE = 3,
+ };
+
+ message_t receiveQueueData[RECEIVE_QUEUE_SIZE];
+ message_t* receiveQueue[RECEIVE_QUEUE_SIZE];
+
+ uint8_t receiveQueueHead;
+ uint8_t receiveQueueSize;
+
+ command error_t SoftwareInit.init()
+ {
+ uint8_t i;
+
+ for(i = 0; i < RECEIVE_QUEUE_SIZE; ++i)
+ receiveQueue[i] = receiveQueueData + i;
+
+ return SUCCESS;
+ }
+
+ tasklet_async event bool RadioReceive.header(message_t* msg)
+ {
+ bool notFull;
+
+ // this prevents undeliverable messages to be acknowledged
+ atomic notFull = receiveQueueSize < RECEIVE_QUEUE_SIZE;
+
+ return notFull;
+ }
+
+ task void deliverTask()
+ {
+ // get rid of as many messages as possible without interveining tasks
+ for(;;)
+ {
+ message_t* msg;
+
+ atomic
+ {
+ if( receiveQueueSize == 0 )
+ return;
+
+ msg = receiveQueue[receiveQueueHead];
+ }
+
+ msg = signal Receive.receive(msg,
+ call Packet.getPayload(msg, call Packet.maxPayloadLength()),
+ call Packet.payloadLength(msg));
+
+ atomic
+ {
+ receiveQueue[receiveQueueHead] = msg;
+
+ if( ++receiveQueueHead >= RECEIVE_QUEUE_SIZE )
+ receiveQueueHead = 0;
+
+ --receiveQueueSize;
+ }
+ }
+ }
+
+ tasklet_async event message_t* RadioReceive.receive(message_t* msg)
+ {
+ message_t *m;
+
+ atomic
+ {
+ if( receiveQueueSize >= RECEIVE_QUEUE_SIZE )
+ m = msg;
+ else
+ {
+ uint8_t index = receiveQueueHead + receiveQueueSize;
+ if( index >= RECEIVE_QUEUE_SIZE )
+ index -= RECEIVE_QUEUE_SIZE;
+
+ m = receiveQueue[index];
+ receiveQueue[index] = msg;
+
+ ++receiveQueueSize;
+ post deliverTask();
+ }
+ }
+
+ return m;
+ }
+
+ default event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len)
+ {
+ return msg;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+interface RandomCollisionConfig
+{
+ /**
+ * Returns the initial amount of maximum backoff for this message.
+ */
+ async command uint16_t getInitialBackoff(message_t* msg);
+
+ /**
+ * Returns the amount of maximum backoff when there is congestion
+ * (the channel was busy for the first try)
+ */
+ async command uint16_t getCongestionBackoff(message_t* msg);
+
+ /**
+ * Returns the minimum ticks before the message could be sent.
+ */
+ async command uint16_t getMinimumBackoff();
+
+ /**
+ * The provided message was just received, and this command should return
+ * the time till no transmission should be initiated.
+ */
+ async command uint16_t getTransmitBarrier(message_t* msg);
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration RandomCollisionLayerC
+{
+ provides
+ {
+ interface RadioSend;
+ interface RadioReceive;
+ }
+ uses
+ {
+ interface RadioSend as SubSend;
+ interface RadioReceive as SubReceive;
+ interface RandomCollisionConfig as Config;
+ }
+}
+
+implementation
+{
+ components RandomCollisionLayerP, RadioAlarmC, RandomC;
+
+ RadioSend = RandomCollisionLayerP;
+ SubSend = RandomCollisionLayerP;
+ Config = RandomCollisionLayerP;
+ RadioReceive = RandomCollisionLayerP;
+ SubReceive = RandomCollisionLayerP;
+
+ RandomCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
+ RandomCollisionLayerP.Random -> RandomC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+#include <RadioAssert.h>
+
+module RandomCollisionLayerP
+{
+ provides
+ {
+ interface RadioSend;
+ interface RadioReceive;
+ }
+ uses
+ {
+ interface RadioSend as SubSend;
+ interface RadioReceive as SubReceive;
+ interface RadioAlarm;
+ interface Random;
+ interface RandomCollisionConfig as Config;
+ }
+}
+
+implementation
+{
+ tasklet_norace uint8_t state;
+ enum
+ {
+ STATE_READY = 0,
+ STATE_TX_PENDING_FIRST = 1,
+ STATE_TX_PENDING_SECOND = 2,
+ STATE_TX_SENDING = 3,
+
+ STATE_BARRIER = 0x80,
+ };
+
+ tasklet_norace message_t *txMsg;
+ tasklet_norace uint16_t txBarrier;
+
+ tasklet_async event void SubSend.ready()
+ {
+ if( state == STATE_READY && call RadioAlarm.isFree() )
+ signal RadioSend.ready();
+ }
+
+ uint16_t nextRandom;
+ task void calcNextRandom()
+ {
+ uint16_t a = call Random.rand16();
+ atomic nextRandom = a;
+ }
+
+ uint16_t getBackoff(uint16_t maxBackoff)
+ {
+ uint16_t a;
+
+ atomic
+ {
+ a = nextRandom;
+ nextRandom += 273;
+ }
+ post calcNextRandom();
+
+ return (a % maxBackoff) + call Config.getMinimumBackoff();
+ }
+
+ tasklet_async command error_t RadioSend.send(message_t* msg)
+ {
+ if( state != STATE_READY || ! call RadioAlarm.isFree() )
+ return EBUSY;
+
+ txMsg = msg;
+ state = STATE_TX_PENDING_FIRST;
+ call RadioAlarm.wait(getBackoff(call Config.getInitialBackoff(msg)));
+
+ return SUCCESS;
+ }
+
+ tasklet_async event void RadioAlarm.fired()
+ {
+ error_t error;
+ int16_t delay;
+
+ ASSERT( state != STATE_READY );
+
+ delay = (int16_t)txBarrier - call RadioAlarm.getNow();
+
+ if( state == STATE_BARRIER )
+ {
+ state = STATE_READY;
+
+ signal RadioSend.ready();
+ return;
+ }
+ else if( (state & STATE_BARRIER) && delay > 0 )
+ error = EBUSY;
+ else
+ error = call SubSend.send(txMsg);
+
+ if( error != SUCCESS )
+ {
+ if( (state & ~STATE_BARRIER) == STATE_TX_PENDING_FIRST )
+ {
+ state = (state & STATE_BARRIER) | STATE_TX_PENDING_SECOND;
+ call RadioAlarm.wait(getBackoff(call Config.getCongestionBackoff(txMsg)));
+ }
+ else
+ {
+ if( (state & STATE_BARRIER) && delay > 0 )
+ {
+ state = STATE_BARRIER;
+ call RadioAlarm.wait(delay);
+ }
+ else
+ state = STATE_READY;
+
+ signal RadioSend.sendDone(error);
+ }
+ }
+ else
+ state = STATE_TX_SENDING;
+ }
+
+ tasklet_async event void SubSend.sendDone(error_t error)
+ {
+ ASSERT( state == STATE_TX_SENDING );
+
+ state = STATE_READY;
+ signal RadioSend.sendDone(error);
+ }
+
+ tasklet_async event bool SubReceive.header(message_t* msg)
+ {
+ return signal RadioReceive.header(msg);
+ }
+
+ tasklet_async event message_t* SubReceive.receive(message_t* msg)
+ {
+ int16_t delay;
+
+ txBarrier = call Config.getTransmitBarrier(msg);
+ delay = txBarrier - call RadioAlarm.getNow();
+
+ if( delay > 0 )
+ {
+ if( state == STATE_READY )
+ {
+ call RadioAlarm.wait(delay);
+ state = STATE_BARRIER;
+ }
+ else
+ state |= STATE_BARRIER;
+ }
+
+ return signal RadioReceive.receive(msg);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+interface SlottedCollisionConfig
+{
+ /**
+ * This command should return the approximate transmit delay between
+ * setting an alarm, waiting for the fire event, calling send and
+ * obtaining the timestamp for the transmitted message.
+ */
+ async command uint16_t getInitialDelay();
+
+ /**
+ * Must return a binary exponent so that the collision avoidance layer
+ * can assign slots in the range of [0, 1 << exponent) of size collision
+ * window.
+ */
+ async command uint8_t getScheduleExponent();
+
+ /**
+ * This command must return the time when the message was transmitted.
+ */
+ async command uint16_t getTransmitTime(message_t* msg);
+
+ /**
+ * Returns the start of the collision window for this received message,
+ * so transmit times in this range would be considered possible collisions.
+ */
+ async command uint16_t getCollisionWindowStart(message_t* msg);
+
+ /**
+ * Returns the size of the collision window for this received message.
+ */
+ async command uint16_t getCollisionWindowLength(message_t* msg);
+
+ /**
+ * This event should be called periodically to indicate the passing of
+ * time (maybe we should use a timer)
+ */
+ tasklet_async event void timerTick();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration SlottedCollisionLayerC
+{
+ provides
+ {
+ interface RadioSend;
+ interface RadioReceive;
+ }
+ uses
+ {
+ interface RadioSend as SubSend;
+ interface RadioReceive as SubReceive;
+ interface SlottedCollisionConfig as Config;
+ }
+}
+
+implementation
+{
+ components SlottedCollisionLayerP, MainC, RadioAlarmC, RandomC;
+
+ RadioSend = SlottedCollisionLayerP;
+ RadioReceive = SlottedCollisionLayerP;
+ SubSend = SlottedCollisionLayerP;
+ SubReceive = SlottedCollisionLayerP;
+ Config = SlottedCollisionLayerP;
+
+ SlottedCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
+ SlottedCollisionLayerP.Random -> RandomC;
+ MainC.SoftwareInit -> SlottedCollisionLayerP;
+
+#ifdef RADIO_DEBUG
+ components DiagMsgC;
+ SlottedCollisionLayerP.DiagMsg -> DiagMsgC;
+#endif
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+#include <RadioAssert.h>
+
+module SlottedCollisionLayerP
+{
+ provides
+ {
+ interface RadioSend;
+ interface RadioReceive;
+ interface Init;
+ }
+ uses
+ {
+ interface RadioSend as SubSend;
+ interface RadioReceive as SubReceive;
+ interface RadioAlarm;
+ interface Random;
+ interface SlottedCollisionConfig as Config;
+#ifdef RADIO_DEBUG
+ interface DiagMsg;
+#endif
+ }
+}
+
+implementation
+{
+/* ----- random ----- */
+
+ uint16_t nextRandom;
+
+ task void calcNextRandom()
+ {
+ uint16_t a = call Random.rand16();
+ atomic nextRandom = a;
+ }
+
+ uint16_t getNextRandom()
+ {
+ uint16_t a;
+
+ atomic
+ {
+ a = nextRandom;
+ nextRandom += 273;
+ }
+ post calcNextRandom();
+
+ return a;
+ }
+
+/* ----- schedule selection ----- */
+
+ tasklet_async event bool SubReceive.header(message_t* msg)
+ {
+ return signal RadioReceive.header(msg);
+ }
+
+ // WARNING!!! Do not change these values, the error values can overflow
+ enum
+ {
+ ERROR_DECAY = 3,
+ ERROR_SWITCH = 30, // should be a multiple of (1 << decay)
+ ERROR_COLLISION = 20, // must be less than (255 - switch) >> decay
+ ERROR_BUSY = 1, // must be less than collision
+ ERROR_INITIAL = 80, // must be less than giveup
+ ERROR_GIVEUP = 120, // must be less than collision * (1 << decay)
+ ERROR_REPRESS = 40, // must be more than switch
+ ERROR_MAX = 255,
+ };
+
+ /**
+ * Returns TRUE if time is between start and start + window
+ * modulo the schedule size of (1 << exponent)
+ */
+ inline bool isBetween(uint8_t exponent, uint16_t time, uint16_t start, uint16_t length)
+ {
+ return (uint16_t)((time - start) & ((1 << exponent) - 1)) < length;
+ }
+
+ tasklet_norace uint16_t schedule1;
+ tasklet_norace uint16_t schedule2;
+
+ tasklet_norace uint8_t error1;
+ tasklet_norace uint8_t error2;
+
+ tasklet_async event message_t* SubReceive.receive(message_t* msg)
+ {
+ uint8_t exponent = call Config.getScheduleExponent();
+ uint16_t start = call Config.getCollisionWindowStart(msg);
+ uint16_t length = call Config.getCollisionWindowLength(msg);
+
+ error1 -= error1 >> ERROR_DECAY;
+ if( isBetween(exponent, schedule1, start, length) )
+ error1 += ERROR_COLLISION;
+
+ error2 -= error2 >> ERROR_DECAY;
+ if( isBetween(exponent, schedule2, start, length) )
+ error2 += ERROR_COLLISION;
+
+ if( error2 + ERROR_SWITCH <= error1 )
+ {
+ error1 = error2;
+ schedule1 = schedule2;
+ error2 = ERROR_GIVEUP;
+ }
+
+ if( error2 >= ERROR_GIVEUP )
+ {
+ error2 = ERROR_INITIAL;
+ schedule2 = getNextRandom();
+ }
+
+ return signal RadioReceive.receive(msg);
+ }
+
+ void printStats();
+
+ tasklet_async event void Config.timerTick()
+ {
+ if( error1 >= (1 << ERROR_DECAY) )
+ error1 -= error1 >> ERROR_DECAY;
+ else if( error1 > 0 )
+ --error1;
+
+ if( error2 >= (1 << ERROR_DECAY) )
+ error2 -= error2 >> ERROR_DECAY;
+ else if( error2 > 0 )
+ --error2;
+
+ printStats();
+ }
+
+/* ------ transmit ------ */
+
+ tasklet_norace uint8_t state;
+ enum
+ {
+ STATE_READY = 0,
+ STATE_PENDING = 1,
+ STATE_SENDING = 2,
+ };
+
+ enum { DELAY_DECAY = 2 };
+
+ tasklet_norace message_t *txMsg;
+ tasklet_norace uint16_t txDelay; // the averaged delay between schedule and timestamp
+ tasklet_norace uint16_t txTime; // the schedule time of transmission
+
+ tasklet_async event void SubSend.ready()
+ {
+ if( state == STATE_READY && call RadioAlarm.isFree() )
+ signal RadioSend.ready();
+ }
+
+ tasklet_async command error_t RadioSend.send(message_t* msg)
+ {
+ uint16_t backoff;
+ uint16_t time;
+
+ // TODO: we could supress transmission while error is large
+ if( state != STATE_READY || ! call RadioAlarm.isFree() || error1 >= ERROR_REPRESS )
+ return EBUSY;
+
+ txMsg = msg;
+ state = STATE_PENDING;
+
+ time = call RadioAlarm.getNow();
+ backoff = 1 + ((schedule1 - time - (txDelay >> DELAY_DECAY))
+ & ((1 << call Config.getScheduleExponent()) - 1));
+
+ backoff += getNextRandom() & (3 << call Config.getScheduleExponent());
+
+ call RadioAlarm.wait(backoff);
+ txTime = time + backoff;
+
+ return SUCCESS;
+ }
+
+ tasklet_async event void RadioAlarm.fired()
+ {
+ error_t error;
+
+ ASSERT( state == STATE_PENDING );
+
+ error = call SubSend.send(txMsg);
+ if( error == SUCCESS )
+ state = STATE_SENDING;
+ else
+ {
+ if( error2 + ERROR_SWITCH <= error1 )
+ {
+ error1 = error2;
+ schedule1 = schedule2;
+ error2 = ERROR_INITIAL;
+ schedule2 = getNextRandom();
+ }
+ else if( error1 < ERROR_MAX - ERROR_BUSY )
+ error1 = error1 + ERROR_BUSY;
+
+ state = STATE_READY;
+ signal RadioSend.sendDone(error);
+ }
+ }
+
+ tasklet_async event void SubSend.sendDone(error_t error)
+ {
+ ASSERT( state == STATE_SENDING );
+
+ if( error == SUCCESS )
+ {
+ txDelay += (call Config.getTransmitTime(txMsg) - txTime) - (txDelay >> DELAY_DECAY);
+
+ ASSERT( (txDelay >> DELAY_DECAY) < (1 << call Config.getScheduleExponent()) );
+ }
+
+ state = STATE_READY;
+ signal RadioSend.sendDone(error);
+ }
+
+/* ------ init ------ */
+
+ command error_t Init.init()
+ {
+ // do not use Random here because it might not be initialized
+ schedule1 = (uint16_t)(TOS_NODE_ID * 1973);
+ schedule2 = schedule1 + 0117;
+ txDelay = call Config.getInitialDelay() << DELAY_DECAY;
+
+ return SUCCESS;
+ }
+
+#ifdef RADIO_DEBUG
+ tasklet_norace uint8_t count;
+ void printStats()
+ {
+ if( ++count > 10 && call DiagMsg.record() )
+ {
+ count = 0;
+
+ call DiagMsg.str("slotted");
+ call DiagMsg.uint16(txDelay >> DELAY_DECAY);
+ call DiagMsg.uint16(schedule1);
+ call DiagMsg.uint8(error1);
+ call DiagMsg.uint16(schedule2);
+ call DiagMsg.uint8(error2);
+ call DiagMsg.send();
+ }
+ }
+#else
+ void printStats() { }
+#endif
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+interface SoftwareAckConfig
+{
+ /**
+ * Returns the acknowledgement timeout (in the radio clock units),
+ * in which a sent packet must be acknowledged.
+ */
+ async command uint16_t getAckTimeout();
+
+ /**
+ * Returns TRUE if the layer should wait for a software acknowledgement
+ * to be received after this packet was transmitted.
+ */
+ async command bool requiresAckWait(message_t* msg);
+
+ /**
+ * Sets for the transmitted message whether it was acknowledged or not.
+ */
+ async command void setAckReceived(message_t* msg, bool acked);
+
+ /**
+ * Returns TRUE if the received packet is an acknowledgement packet.
+ * The AckedSend layer will filter out all received acknowledgement
+ * packets and uses only the matching one for the acknowledgement.
+ */
+ async command bool isAckPacket(message_t* msg);
+
+ /**
+ * Returns TRUE if the acknowledgement packet corresponds to the
+ * data packet. The acknowledgement packect was already verified
+ * to be a valid acknowledgement packet via the isAckPacket command.
+ */
+ async command bool verifyAckPacket(message_t* data, message_t* ack);
+
+ /**
+ * Returns TRUE if the received packet needs software acknowledgements
+ * to be sent back to the sender.
+ */
+ async command bool requiresAckReply(message_t* msg);
+
+ /**
+ * Creates an acknowledgement packet for the given data packet.
+ */
+ async command void createAckPacket(message_t* data, message_t* ack);
+
+ /**
+ * This command is called when a sent packet did not receive an
+ * acknowledgement.
+ */
+ tasklet_async command void reportChannelError();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration SoftwareAckLayerC
+{
+ provides
+ {
+ interface RadioSend;
+ interface RadioReceive;
+ }
+ uses
+ {
+ interface RadioSend as SubSend;
+ interface RadioReceive as SubReceive;
+
+ interface SoftwareAckConfig as Config;
+ }
+}
+
+implementation
+{
+ components SoftwareAckLayerP, RadioAlarmC;
+
+ RadioSend = SoftwareAckLayerP;
+ RadioReceive = SoftwareAckLayerP;
+ SubSend = SoftwareAckLayerP;
+ SubReceive = SoftwareAckLayerP;
+ Config = SoftwareAckLayerP;
+
+ SoftwareAckLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+#include <RadioAssert.h>
+
+module SoftwareAckLayerP
+{
+ provides
+ {
+ interface RadioSend;
+ interface RadioReceive;
+ }
+ uses
+ {
+ interface RadioSend as SubSend;
+ interface RadioReceive as SubReceive;
+ interface RadioAlarm;
+
+ interface SoftwareAckConfig;
+ }
+}
+
+implementation
+{
+ tasklet_norace uint8_t state;
+ enum
+ {
+ STATE_READY = 0,
+ STATE_DATA_SEND = 1,
+ STATE_ACK_WAIT = 2,
+ STATE_ACK_SEND = 3,
+ };
+
+ tasklet_norace message_t *txMsg;
+ tasklet_norace message_t ackMsg;
+
+ tasklet_async event void SubSend.ready()
+ {
+ if( state == STATE_READY )
+ signal RadioSend.ready();
+ }
+
+ tasklet_async command error_t RadioSend.send(message_t* msg)
+ {
+ error_t error;
+
+ if( state == STATE_READY )
+ {
+ if( (error = call SubSend.send(msg)) == SUCCESS )
+ {
+ call SoftwareAckConfig.setAckReceived(msg, FALSE);
+ state = STATE_DATA_SEND;
+ txMsg = msg;
+ }
+ }
+ else
+ error = EBUSY;
+
+ return error;
+ }
+
+ tasklet_async event void SubSend.sendDone(error_t error)
+ {
+ if( state == STATE_ACK_SEND )
+ {
+ // TODO: what if error != SUCCESS
+ ASSERT( error == SUCCESS );
+
+ state = STATE_READY;
+ }
+ else
+ {
+ ASSERT( state == STATE_DATA_SEND );
+ ASSERT( call RadioAlarm.isFree() );
+
+ if( error == SUCCESS && call SoftwareAckConfig.requiresAckWait(txMsg) && call RadioAlarm.isFree() )
+ {
+ call RadioAlarm.wait(call SoftwareAckConfig.getAckTimeout());
+ state = STATE_ACK_WAIT;
+ }
+ else
+ {
+ state = STATE_READY;
+ signal RadioSend.sendDone(error);
+ }
+ }
+ }
+
+ tasklet_async event void RadioAlarm.fired()
+ {
+ ASSERT( state == STATE_ACK_WAIT );
+
+ call SoftwareAckConfig.reportChannelError();
+
+ state = STATE_READY;
+ signal RadioSend.sendDone(SUCCESS); // we have sent it, but not acked
+ }
+
+ tasklet_async event bool SubReceive.header(message_t* msg)
+ {
+ if( call SoftwareAckConfig.isAckPacket(msg) )
+ return state == STATE_ACK_WAIT && call SoftwareAckConfig.verifyAckPacket(txMsg, msg);
+ else
+ return signal RadioReceive.header(msg);
+ }
+
+ tasklet_async event message_t* SubReceive.receive(message_t* msg)
+ {
+ bool ack = call SoftwareAckConfig.isAckPacket(msg);
+
+ ASSERT( state == STATE_ACK_WAIT || state == STATE_READY );
+
+ if( state == STATE_ACK_WAIT )
+ {
+ ASSERT( !ack || call SoftwareAckConfig.verifyAckPacket(txMsg, msg) );
+
+ call RadioAlarm.cancel();
+ call SoftwareAckConfig.setAckReceived(txMsg, ack);
+
+ state = STATE_READY;
+ signal RadioSend.sendDone(SUCCESS);
+ }
+
+ if( ack )
+ return msg;
+
+ if( call SoftwareAckConfig.requiresAckReply(msg) )
+ {
+ call SoftwareAckConfig.createAckPacket(msg, &ackMsg);
+
+ // TODO: what to do if we are busy and cannot send an ack
+ if( call SubSend.send(&ackMsg) == SUCCESS )
+ state = STATE_ACK_SEND;
+ else
+ ASSERT(FALSE);
+ }
+
+ return signal RadioReceive.receive(msg);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+interface TrafficMonitorConfig
+{
+ /**
+ * Returns the frequency (in milliseconds) when the traffic averages
+ * should be updated.
+ */
+ async command uint16_t getUpdatePeriod();
+
+ /**
+ * Returns the amount of time this message has occupied the channel.
+ */
+ async command uint16_t getChannelTime(message_t* msg);
+
+ /**
+ * Returns the sender address of the message so we can calculate the
+ * average number of neighbors that send messages per update period.
+ */
+ async command am_addr_t getSender(message_t* msg);
+
+ /**
+ * This event should be fired if we notice some anomalies in the operation
+ * of the channel, such as not receiving acknowledgements, missing
+ * sequence numbers or packets with corrupted CRC.
+ */
+ tasklet_async event void channelError();
+
+ /**
+ * Returns the averaged (exponential decay) transmit channel time
+ * during one update period.
+ */
+ tasklet_async event uint16_t getTransmitAverage();
+
+ /**
+ * Returns the averaged (exponential decay) receive channel time
+ * during one update period.
+ */
+ tasklet_async event uint16_t getReceiveAverage();
+
+ /**
+ * Returns the averaged (exponential decay) number of neighbors
+ * whose messages this component receives during one update period.
+ */
+ tasklet_async event uint8_t getNeighborAverage();
+
+ /**
+ * Returns the averaged error events during one update period.
+ */
+ tasklet_async event uint8_t getErrorAverage();
+
+ /**
+ * This command is periodically called when the timer is fired and
+ * the averages are updated
+ */
+ tasklet_async command void timerTick();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration TrafficMonitorLayerC
+{
+ provides
+ {
+ interface RadioSend;
+ interface RadioReceive;
+ interface RadioState;
+ }
+ uses
+ {
+ interface RadioSend as SubSend;
+ interface RadioReceive as SubReceive;
+ interface RadioState as SubState;
+
+ interface TrafficMonitorConfig as Config;
+ }
+}
+
+implementation
+{
+ components TrafficMonitorLayerP, new TimerMilliC() as UpdateTimerC;
+ components NeighborhoodC, new NeighborhoodFlagC(), TaskletC;
+
+ RadioSend = TrafficMonitorLayerP;
+ RadioReceive = TrafficMonitorLayerP;
+ RadioState = TrafficMonitorLayerP;
+ SubSend = TrafficMonitorLayerP;
+ SubReceive = TrafficMonitorLayerP;
+ SubState = TrafficMonitorLayerP;
+ Config = TrafficMonitorLayerP;
+
+ TrafficMonitorLayerP.Timer -> UpdateTimerC;
+ TrafficMonitorLayerP.Neighborhood -> NeighborhoodC;
+ TrafficMonitorLayerP.NeighborhoodFlag -> NeighborhoodFlagC;
+ TrafficMonitorLayerP.Tasklet -> TaskletC;
+
+#ifdef RADIO_DEBUG
+ components DiagMsgC;
+ TrafficMonitorLayerP.DiagMsg -> DiagMsgC;
+#endif
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, reportS, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+/*
+ * You have to make sure that the maximum channel time in one report
+ * period times (1 << TRAFFIC_MONITOR_DECAY) is less than 65535.
+ */
+#ifndef TRAFFIC_MONITOR_DECAY
+#define TRAFFIC_MONITOR_DECAY 3
+#endif
+
+module TrafficMonitorLayerP
+{
+ provides
+ {
+ interface RadioSend;
+ interface RadioReceive;
+ interface RadioState;
+ }
+
+ uses
+ {
+ interface TrafficMonitorConfig;
+ interface RadioSend as SubSend;
+ interface RadioReceive as SubReceive;
+ interface RadioState as SubState;
+ interface Timer<TMilli> as Timer;
+ interface Neighborhood;
+ interface NeighborhoodFlag;
+ interface Tasklet;
+#ifdef RADIO_DEBUG
+ interface DiagMsg;
+#endif
+ }
+}
+
+implementation
+{
+ tasklet_norace message_t *txMsg;
+ tasklet_norace uint8_t neighborCount;
+
+ tasklet_norace uint16_t txAverage;
+ tasklet_norace uint16_t rxAverage;
+ tasklet_norace uint8_t neighborAverage;
+ tasklet_norace uint8_t errorAverage;
+
+ enum
+ {
+ // the maximum average value
+ TRAFFIC_MONITOR_UINT8_MAX = 1 << (7-TRAFFIC_MONITOR_DECAY),
+
+ // the unsignificant bits of the averaged values
+ TRAFFIC_MONITOR_MASK = (1 << TRAFFIC_MONITOR_DECAY) - 1,
+
+ // to get the ceiling integer value
+ TRAFFIC_MONITOR_ROUND_UP = (1 << TRAFFIC_MONITOR_DECAY) - 1,
+ };
+
+ tasklet_async event void SubSend.ready()
+ {
+ signal RadioSend.ready();
+ }
+
+ tasklet_async command error_t RadioSend.send(message_t* msg)
+ {
+ txMsg = msg;
+ return call SubSend.send(msg);
+ }
+
+ tasklet_async event void SubSend.sendDone(error_t error)
+ {
+ if( error == SUCCESS )
+ txAverage += call TrafficMonitorConfig.getChannelTime(txMsg);
+
+ signal RadioSend.sendDone(error);
+ }
+
+ tasklet_async event bool SubReceive.header(message_t* msg)
+ {
+ return signal RadioReceive.header(msg);
+ }
+
+ tasklet_async event message_t* SubReceive.receive(message_t* msg)
+ {
+ uint8_t index;
+
+ rxAverage += call TrafficMonitorConfig.getChannelTime(msg);
+
+ index = call Neighborhood.insertNode(call TrafficMonitorConfig.getSender(msg));
+ if( ! call NeighborhoodFlag.get(index) )
+ {
+ if( neighborCount < TRAFFIC_MONITOR_UINT8_MAX )
+ {
+ ++neighborCount;
+ call NeighborhoodFlag.set(index);
+ }
+ }
+
+ return signal RadioReceive.receive(msg);
+ }
+
+ tasklet_async event void TrafficMonitorConfig.channelError()
+ {
+ if( errorAverage < 255 )
+ ++errorAverage;
+ }
+
+ uint8_t debugCounter;
+
+ event void Timer.fired()
+ {
+ uint8_t fraction;
+
+ call Tasklet.suspend();
+
+ txAverage -= (txAverage >> TRAFFIC_MONITOR_DECAY);
+ rxAverage -= (rxAverage >> TRAFFIC_MONITOR_DECAY);
+ errorAverage -= (errorAverage >> TRAFFIC_MONITOR_DECAY);
+
+ // we could get stuck in the [1,7] range with no neighbors, so be more precise
+ fraction = neighborAverage >> TRAFFIC_MONITOR_DECAY;
+ if( fraction == neighborCount && (neighborAverage & TRAFFIC_MONITOR_MASK) != 0 )
+ --neighborAverage;
+ else
+ neighborAverage += neighborCount - fraction;
+
+ call NeighborhoodFlag.clearAll();
+ neighborCount = 0;
+
+ call TrafficMonitorConfig.timerTick();
+
+ call Tasklet.resume();
+
+#ifdef RADIO_DEBUG
+ if( ++debugCounter >= 10 && call DiagMsg.record() )
+ {
+ debugCounter = 0;
+
+ call DiagMsg.str("traffic");
+ call DiagMsg.uint16(signal TrafficMonitorConfig.getTransmitAverage());
+ call DiagMsg.uint16(signal TrafficMonitorConfig.getReceiveAverage());
+ call DiagMsg.uint8(signal TrafficMonitorConfig.getNeighborAverage());
+ call DiagMsg.uint8(signal TrafficMonitorConfig.getErrorAverage());
+ call DiagMsg.send();
+ }
+#endif
+ }
+
+ tasklet_async event void Tasklet.run()
+ {
+ }
+
+ tasklet_async event uint16_t TrafficMonitorConfig.getTransmitAverage()
+ {
+ return txAverage >> TRAFFIC_MONITOR_DECAY;
+ }
+
+ tasklet_async event uint16_t TrafficMonitorConfig.getReceiveAverage()
+ {
+ return rxAverage >> TRAFFIC_MONITOR_DECAY;
+ }
+
+ tasklet_async event uint8_t TrafficMonitorConfig.getNeighborAverage()
+ {
+ return (neighborAverage + TRAFFIC_MONITOR_ROUND_UP) >> TRAFFIC_MONITOR_DECAY;
+ }
+
+ tasklet_async event uint8_t TrafficMonitorConfig.getErrorAverage()
+ {
+ return errorAverage >> TRAFFIC_MONITOR_DECAY;
+ }
+
+ tasklet_async event void Neighborhood.evicted(uint8_t index) { }
+
+ enum
+ {
+ RADIO_CMD_NONE = 0,
+ RADIO_CMD_TURNON = 1,
+ RADIO_CMD_TURNOFF = 2,
+ };
+ tasklet_norace uint8_t radioCmd;
+
+ tasklet_async command error_t RadioState.turnOff()
+ {
+ radioCmd = RADIO_CMD_TURNOFF;
+ return call SubState.turnOff();
+ }
+
+ tasklet_async command error_t RadioState.standby()
+ {
+ radioCmd = RADIO_CMD_TURNOFF;
+ return call SubState.standby();
+ }
+
+ tasklet_async command error_t RadioState.turnOn()
+ {
+ radioCmd = RADIO_CMD_TURNON;
+ return call SubState.turnOn();
+ }
+
+ tasklet_async command error_t RadioState.setChannel(uint8_t channel)
+ {
+ radioCmd = RADIO_CMD_NONE;
+ return call SubState.setChannel(channel);
+ }
+
+ tasklet_async command uint8_t RadioState.getChannel()
+ {
+ return call SubState.getChannel();
+ }
+
+ task void startStopTimer()
+ {
+ if( radioCmd == RADIO_CMD_TURNON )
+ call Timer.startPeriodic(call TrafficMonitorConfig.getUpdatePeriod());
+ else if( radioCmd == RADIO_CMD_TURNOFF )
+ call Timer.stop();
+ }
+
+ tasklet_async event void SubState.done()
+ {
+ post startStopTimer();
+ signal RadioState.done();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+interface UniqueConfig
+{
+ /**
+ * Returns the sequence number of the packet.
+ */
+ async command uint8_t getSequenceNumber(message_t* msg);
+
+ /**
+ * Returns the sender of the packet.
+ */
+ async command am_addr_t getSender(message_t* msg);
+
+ /**
+ * Sets the sequence number of the packet.
+ */
+ async command void setSequenceNumber(message_t*msg, uint8_t number);
+
+ /**
+ * This command is called when the unqiue layer detects a missing (jump
+ * in the data sequence number) or a duplicate packet.
+ */
+ tasklet_async command void reportChannelError();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration UniqueLayerC
+{
+ provides
+ {
+ // NOTE, this is a combined layer, should be hooked up at two places
+ interface Send;
+ interface RadioReceive;
+ }
+ uses
+ {
+ interface Send as SubSend;
+ interface RadioReceive as SubReceive;
+
+ interface UniqueConfig as Config;
+ }
+}
+
+implementation
+{
+ components UniqueLayerP, MainC, NeighborhoodC, new NeighborhoodFlagC();
+
+ MainC.SoftwareInit -> UniqueLayerP;
+ UniqueLayerP.Neighborhood -> NeighborhoodC;
+ UniqueLayerP.NeighborhoodFlag -> NeighborhoodFlagC;
+
+ Send = UniqueLayerP;
+ SubSend = UniqueLayerP;
+
+ RadioReceive = UniqueLayerP;
+ SubReceive = UniqueLayerP;
+ Config = UniqueLayerP;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+#include <Neighborhood.h>
+
+module UniqueLayerP
+{
+ provides
+ {
+ interface Send;
+ interface RadioReceive;
+
+ interface Init;
+ }
+
+ uses
+ {
+ interface Send as SubSend;
+ interface RadioReceive as SubReceive;
+
+ interface UniqueConfig;
+ interface Neighborhood;
+ interface NeighborhoodFlag;
+ }
+}
+
+implementation
+{
+ uint8_t sequenceNumber;
+
+ command error_t Init.init()
+ {
+ sequenceNumber = TOS_NODE_ID << 4;
+ return SUCCESS;
+ }
+
+ command error_t Send.send(message_t* msg, uint8_t len)
+ {
+ call UniqueConfig.setSequenceNumber(msg, ++sequenceNumber);
+ return call SubSend.send(msg, len);
+ }
+
+ command error_t Send.cancel(message_t* msg)
+ {
+ return call SubSend.cancel(msg);
+ }
+
+ event void SubSend.sendDone(message_t* msg, error_t error)
+ {
+ signal Send.sendDone(msg, error);
+ }
+
+ command uint8_t Send.maxPayloadLength()
+ {
+ return call SubSend.maxPayloadLength();
+ }
+
+ command void* Send.getPayload(message_t* msg, uint8_t len)
+ {
+ return call SubSend.getPayload(msg, len);
+ }
+
+ tasklet_async event bool SubReceive.header(message_t* msg)
+ {
+ // we could scan here, but better be lazy
+ return signal RadioReceive.header(msg);
+ }
+
+ tasklet_norace uint8_t receivedNumbers[NEIGHBORHOOD_SIZE];
+
+ tasklet_async event message_t* SubReceive.receive(message_t* msg)
+ {
+ uint8_t index = call Neighborhood.insertNode(call UniqueConfig.getSender(msg));
+ uint8_t dsn = call UniqueConfig.getSequenceNumber(msg);
+
+ if( call NeighborhoodFlag.get(index) )
+ {
+ uint8_t diff = dsn - receivedNumbers[index];
+
+ if( diff == 0 )
+ {
+ call UniqueConfig.reportChannelError();
+ return msg;
+ }
+ }
+ else
+ call NeighborhoodFlag.set(index);
+
+ receivedNumbers[index] = dsn;
+
+ return signal RadioReceive.receive(msg);
+ }
+
+ tasklet_async event void Neighborhood.evicted(uint8_t index) { }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __RF230_H__
+#define __RF230_H__
+
+enum rf230_registers_enum
+{
+ RF230_TRX_STATUS = 0x01,
+ RF230_TRX_STATE = 0x02,
+ RF230_TRX_CTRL_0 = 0x03,
+ RF230_PHY_TX_PWR = 0x05,
+ RF230_PHY_RSSI = 0x06,
+ RF230_PHY_ED_LEVEL = 0x07,
+ RF230_PHY_CC_CCA = 0x08,
+ RF230_CCA_THRES = 0x09,
+ RF230_IRQ_MASK = 0x0E,
+ RF230_IRQ_STATUS = 0x0F,
+ RF230_VREG_CTRL = 0x10,
+ RF230_BATMON = 0x11,
+ RF230_XOSC_CTRL = 0x12,
+ RF230_PLL_CF = 0x1A,
+ RF230_PLL_DCU = 0x1B,
+ RF230_PART_NUM = 0x1C,
+ RF230_VERSION_NUM = 0x1D,
+ RF230_MAN_ID_0 = 0x1E,
+ RF230_MAN_ID_1 = 0x1F,
+ RF230_SHORT_ADDR_0 = 0x20,
+ RF230_SHORT_ADDR_1 = 0x21,
+ RF230_PAN_ID_0 = 0x22,
+ RF230_PAN_ID_1 = 0x23,
+ RF230_IEEE_ADDR_0 = 0x24,
+ RF230_IEEE_ADDR_1 = 0x25,
+ RF230_IEEE_ADDR_2 = 0x26,
+ RF230_IEEE_ADDR_3 = 0x27,
+ RF230_IEEE_ADDR_4 = 0x28,
+ RF230_IEEE_ADDR_5 = 0x29,
+ RF230_IEEE_ADDR_6 = 0x2A,
+ RF230_IEEE_ADDR_7 = 0x2B,
+ RF230_XAH_CTRL = 0x2C,
+ RF230_CSMA_SEED_0 = 0x2D,
+ RF230_CSMA_SEED_1 = 0x2E,
+};
+
+enum rf230_trx_register_enums
+{
+ RF230_CCA_DONE = 1 << 7,
+ RF230_CCA_STATUS = 1 << 6,
+ RF230_TRX_STATUS_MASK = 0x1F,
+ RF230_P_ON = 0,
+ RF230_BUSY_RX = 1,
+ RF230_BUSY_TX = 2,
+ RF230_RX_ON = 6,
+ RF230_TRX_OFF = 8,
+ RF230_PLL_ON = 9,
+ RF230_SLEEP = 15,
+ RF230_BUSY_RX_AACK = 16,
+ RF230_BUSR_TX_ARET = 17,
+ RF230_RX_AACK_ON = 22,
+ RF230_TX_ARET_ON = 25,
+ RF230_RX_ON_NOCLK = 28,
+ RF230_AACK_ON_NOCLK = 29,
+ RF230_BUSY_RX_AACK_NOCLK = 30,
+ RF230_STATE_TRANSITION_IN_PROGRESS = 31,
+ RF230_TRAC_STATUS_MASK = 0xE0,
+ RF230_TRAC_SUCCESS = 0,
+ RF230_TRAC_CHANNEL_ACCESS_FAILURE = 3 << 5,
+ RF230_TRAC_NO_ACK = 5 << 5,
+ RF230_TRX_CMD_MASK = 0x1F,
+ RF230_NOP = 0,
+ RF230_TX_START = 2,
+ RF230_FORCE_TRX_OFF = 3,
+};
+
+enum rf230_phy_register_enums
+{
+ RF230_TX_AUTO_CRC_ON = 1 << 7,
+ RF230_TX_PWR_MASK = 0x0F,
+ RF230_TX_PWR_DEFAULT = 0,
+ RF230_RSSI_MASK = 0x1F,
+ RF230_CCA_REQUEST = 1 << 7,
+ RF230_CCA_MODE_0 = 0 << 5,
+ RF230_CCA_MODE_1 = 1 << 5,
+ RF230_CCA_MODE_2 = 2 << 5,
+ RF230_CCA_MODE_3 = 3 << 5,
+ RF230_CHANNEL_DEFAULT = 11,
+ RF230_CHANNEL_MASK = 0x1F,
+ RF230_CCA_CS_THRES_SHIFT = 4,
+ RF230_CCA_ED_THRES_SHIFT = 0,
+};
+
+enum rf230_irq_register_enums
+{
+ RF230_IRQ_BAT_LOW = 1 << 7,
+ RF230_IRQ_TRX_UR = 1 << 6,
+ RF230_IRQ_TRX_END = 1 << 3,
+ RF230_IRQ_RX_START = 1 << 2,
+ RF230_IRQ_PLL_UNLOCK = 1 << 1,
+ RF230_IRQ_PLL_LOCK = 1 << 0,
+};
+
+enum rf230_control_register_enums
+{
+ RF230_AVREG_EXT = 1 << 7,
+ RF230_AVDD_OK = 1 << 6,
+ RF230_DVREG_EXT = 1 << 3,
+ RF230_DVDD_OK = 1 << 2,
+ RF230_BATMON_OK = 1 << 5,
+ RF230_BATMON_VHR = 1 << 4,
+ RF230_BATMON_VTH_MASK = 0x0F,
+ RF230_XTAL_MODE_OFF = 0 << 4,
+ RF230_XTAL_MODE_EXTERNAL = 4 << 4,
+ RF230_XTAL_MODE_INTERNAL = 15 << 4,
+};
+
+enum rf230_pll_register_enums
+{
+ RF230_PLL_CF_START = 1 << 7,
+ RF230_PLL_DCU_START = 1 << 7,
+};
+
+enum rf230_spi_command_enums
+{
+ RF230_CMD_REGISTER_READ = 0x80,
+ RF230_CMD_REGISTER_WRITE = 0xC0,
+ RF230_CMD_REGISTER_MASK = 0x3F,
+ RF230_CMD_FRAME_READ = 0x20,
+ RF230_CMD_FRAME_WRITE = 0x60,
+ RF230_CMD_SRAM_READ = 0x00,
+ RF230_CMD_SRAM_WRITE = 0x40,
+};
+
+#endif//__RF230_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <RadioConfig.h>
+
+configuration RF230ActiveMessageC
+{
+ provides
+ {
+ interface SplitControl;
+
+ interface AMSend[am_id_t id];
+ interface Receive[am_id_t id];
+ interface Receive as Snoop[am_id_t id];
+
+ interface Packet;
+ interface AMPacket;
+ interface PacketAcknowledgements;
+ interface LowPowerListening;
+ interface RadioChannel;
+
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketField<uint8_t> as PacketTransmitPower;
+ interface PacketField<uint8_t> as PacketRSSI;
+
+ interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+ }
+}
+
+implementation
+{
+ components RF230ActiveMessageP, RF230PacketC, IEEE154PacketC, RadioAlarmC;
+
+#ifdef RADIO_DEBUG
+ components AssertC;
+#endif
+
+ RF230ActiveMessageP.IEEE154Packet -> IEEE154PacketC;
+ RF230ActiveMessageP.Packet -> RF230PacketC;
+ RF230ActiveMessageP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
+
+ Packet = RF230PacketC;
+ AMPacket = RF230PacketC;
+ PacketAcknowledgements = RF230PacketC;
+ PacketLinkQuality = RF230PacketC.PacketLinkQuality;
+ PacketTransmitPower = RF230PacketC.PacketTransmitPower;
+ PacketRSSI = RF230PacketC.PacketRSSI;
+ PacketTimeStampRadio = RF230PacketC;
+ PacketTimeStampMilli = RF230PacketC;
+ LowPowerListening = LowPowerListeningLayerC;
+ RadioChannel = MessageBufferLayerC;
+
+ components ActiveMessageLayerC;
+#ifdef TFRAMES_ENABLED
+ components new DummyLayerC() as IEEE154NetworkLayerC;
+#else
+ components IEEE154NetworkLayerC;
+#endif
+#ifdef LOW_POWER_LISTENING
+ components LowPowerListeningLayerC;
+#else
+ components new DummyLayerC() as LowPowerListeningLayerC;
+#endif
+ components MessageBufferLayerC;
+ components UniqueLayerC;
+ components TrafficMonitorLayerC;
+#ifdef SLOTTED_MAC
+ components SlottedCollisionLayerC as CollisionAvoidanceLayerC;
+#else
+ components RandomCollisionLayerC as CollisionAvoidanceLayerC;
+#endif
+ components SoftwareAckLayerC;
+ components new DummyLayerC() as CsmaLayerC;
+ components RF230DriverLayerC;
+
+ SplitControl = LowPowerListeningLayerC;
+ AMSend = ActiveMessageLayerC;
+ Receive = ActiveMessageLayerC.Receive;
+ Snoop = ActiveMessageLayerC.Snoop;
+
+ ActiveMessageLayerC.Config -> RF230ActiveMessageP;
+ ActiveMessageLayerC.AMPacket -> IEEE154PacketC;
+ ActiveMessageLayerC.SubSend -> IEEE154NetworkLayerC;
+ ActiveMessageLayerC.SubReceive -> IEEE154NetworkLayerC;
+
+ IEEE154NetworkLayerC.SubSend -> UniqueLayerC;
+ IEEE154NetworkLayerC.SubReceive -> LowPowerListeningLayerC;
+
+ // the UniqueLayer is wired at two points
+ UniqueLayerC.Config -> RF230ActiveMessageP;
+ UniqueLayerC.SubSend -> LowPowerListeningLayerC;
+
+ LowPowerListeningLayerC.SubControl -> MessageBufferLayerC;
+ LowPowerListeningLayerC.SubSend -> MessageBufferLayerC;
+ LowPowerListeningLayerC.SubReceive -> MessageBufferLayerC;
+#ifdef LOW_POWER_LISTENING
+ LowPowerListeningLayerC.PacketSleepInterval -> RF230PacketC;
+ LowPowerListeningLayerC.IEEE154Packet -> IEEE154PacketC;
+ LowPowerListeningLayerC.PacketAcknowledgements -> RF230PacketC;
+#endif
+
+ MessageBufferLayerC.Packet -> RF230PacketC;
+ MessageBufferLayerC.RadioSend -> TrafficMonitorLayerC;
+ MessageBufferLayerC.RadioReceive -> UniqueLayerC;
+ MessageBufferLayerC.RadioState -> TrafficMonitorLayerC;
+
+ UniqueLayerC.SubReceive -> TrafficMonitorLayerC;
+
+ TrafficMonitorLayerC.Config -> RF230ActiveMessageP;
+ TrafficMonitorLayerC.SubSend -> CollisionAvoidanceLayerC;
+ TrafficMonitorLayerC.SubReceive -> CollisionAvoidanceLayerC;
+ TrafficMonitorLayerC.SubState -> RF230DriverLayerC;
+
+ CollisionAvoidanceLayerC.Config -> RF230ActiveMessageP;
+ CollisionAvoidanceLayerC.SubSend -> SoftwareAckLayerC;
+ CollisionAvoidanceLayerC.SubReceive -> SoftwareAckLayerC;
+
+ SoftwareAckLayerC.Config -> RF230ActiveMessageP;
+ SoftwareAckLayerC.SubSend -> CsmaLayerC;
+ SoftwareAckLayerC.SubReceive -> RF230DriverLayerC;
+
+ CsmaLayerC.Config -> RF230ActiveMessageP;
+ CsmaLayerC -> RF230DriverLayerC.RadioSend;
+ CsmaLayerC -> RF230DriverLayerC.RadioCCA;
+
+ RF230DriverLayerC.RF230DriverConfig -> RF230ActiveMessageP;
+}
async command uint8_t SlottedCollisionConfig.getScheduleExponent()
{
- return 11;
+ return 1 + RADIO_ALARM_MILLI_EXP;
}
async command uint16_t SlottedCollisionConfig.getTransmitTime(message_t* msg)
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+/**
+ * This interface needs to be implemented by the MAC to control the behaviour
+ * of the RF230DriverLayerC component.
+ */
+interface RF230DriverConfig
+{
+ /**
+ * Returns the length of the PHY payload (including the FCF field).
+ * This value must be in the range [3, 127].
+ */
+ async command uint8_t getLength(message_t* msg);
+
+ /**
+ * Sets the length of the PHY payload.
+ */
+ async command void setLength(message_t* msg, uint8_t len);
+
+ /**
+ * Returns a pointer to the start of the PHY payload that contains
+ * getLength()-2 number of bytes. The FCF field (CRC-16) is not stored,
+ * but automatically appended / verified.
+ */
+ async command uint8_t* getPayload(message_t* msg);
+
+ /**
+ * Gets the number of bytes we should read before the RadioReceive.header
+ * event is fired. If the length of the packet is less than this amount,
+ * then that event is fired earlier. The header length must be at least one.
+ */
+ async command uint8_t getHeaderLength();
+
+ /**
+ * Returns the maximum PHY length that can be set via the setLength command
+ */
+ async command uint8_t getMaxLength();
+
+ /**
+ * This command is used at power up to set the default channel.
+ * The default CC2420 channel is 26.
+ */
+ async command uint8_t getDefaultChannel();
+
+ /**
+ * Returns TRUE if before sending this message we should make sure that
+ * the channel is clear via a very basic (and quick) RSSI check.
+ */
+ async command bool requiresRssiCca(message_t* msg);
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration RF230DriverLayerC
+{
+ provides
+ {
+ interface RadioState;
+ interface RadioSend;
+ interface RadioReceive;
+ interface RadioCCA;
+ }
+
+ uses interface RF230DriverConfig;
+}
+
+implementation
+{
+ components RF230DriverLayerP, HplRF230C, BusyWaitMicroC, TaskletC, MainC, RadioAlarmC, RF230PacketC, LocalTimeMicroC as LocalTimeRadioC;
+
+ RadioState = RF230DriverLayerP;
+ RadioSend = RF230DriverLayerP;
+ RadioReceive = RF230DriverLayerP;
+ RadioCCA = RF230DriverLayerP;
+
+ RF230DriverConfig = RF230DriverLayerP;
+
+ RF230DriverLayerP.PacketLinkQuality -> RF230PacketC.PacketLinkQuality;
+ RF230DriverLayerP.PacketTransmitPower -> RF230PacketC.PacketTransmitPower;
+ RF230DriverLayerP.PacketRSSI -> RF230PacketC.PacketRSSI;
+ RF230DriverLayerP.PacketTimeSyncOffset -> RF230PacketC.PacketTimeSyncOffset;
+ RF230DriverLayerP.PacketTimeStamp -> RF230PacketC;
+ RF230DriverLayerP.LocalTime -> LocalTimeRadioC;
+
+ RF230DriverLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
+ RadioAlarmC.Alarm -> HplRF230C.Alarm;
+
+ RF230DriverLayerP.SELN -> HplRF230C.SELN;
+ RF230DriverLayerP.SpiResource -> HplRF230C.SpiResource;
+ RF230DriverLayerP.FastSpiByte -> HplRF230C;
+
+ RF230DriverLayerP.SLP_TR -> HplRF230C.SLP_TR;
+ RF230DriverLayerP.RSTN -> HplRF230C.RSTN;
+
+ RF230DriverLayerP.IRQ -> HplRF230C.IRQ;
+ RF230DriverLayerP.Tasklet -> TaskletC;
+ RF230DriverLayerP.BusyWait -> BusyWaitMicroC;
+
+#ifdef RADIO_DEBUG
+ components DiagMsgC;
+ RF230DriverLayerP.DiagMsg -> DiagMsgC;
+#endif
+
+ MainC.SoftwareInit -> RF230DriverLayerP.SoftwareInit;
+
+ components RealMainP;
+ RealMainP.PlatformInit -> RF230DriverLayerP.PlatformInit;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <RF230.h>
+#include <Tasklet.h>
+#include <RadioAssert.h>
+#include <GenericTimeSyncMessage.h>
+#include <RadioConfig.h>
+
+module RF230DriverLayerP
+{
+ provides
+ {
+ interface Init as PlatformInit @exactlyonce();
+ interface Init as SoftwareInit @exactlyonce();
+
+ interface RadioState;
+ interface RadioSend;
+ interface RadioReceive;
+ interface RadioCCA;
+ }
+
+ uses
+ {
+ interface GeneralIO as SELN;
+ interface Resource as SpiResource;
+
+ interface FastSpiByte;
+
+ interface GeneralIO as SLP_TR;
+ interface GeneralIO as RSTN;
+
+ interface GpioCapture as IRQ;
+
+ interface BusyWait<TMicro, uint16_t>;
+
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketField<uint8_t> as PacketTransmitPower;
+ interface PacketField<uint8_t> as PacketRSSI;
+ interface PacketField<uint8_t> as PacketTimeSyncOffset;
+
+ interface PacketTimeStamp<TRadio, uint32_t>;
+ interface LocalTime<TRadio>;
+
+ interface RF230DriverConfig;
+ interface Tasklet;
+ interface RadioAlarm;
+
+#ifdef RADIO_DEBUG
+ interface DiagMsg;
+#endif
+ }
+}
+
+implementation
+{
+/*----------------- STATE -----------------*/
+
+ tasklet_norace uint8_t state;
+ enum
+ {
+ STATE_P_ON = 0,
+ STATE_SLEEP = 1,
+ STATE_SLEEP_2_TRX_OFF = 2,
+ STATE_TRX_OFF = 3,
+ STATE_TRX_OFF_2_RX_ON = 4,
+ STATE_RX_ON = 5,
+ STATE_BUSY_TX_2_RX_ON = 6,
+ STATE_PLL_ON_2_RX_ON = 7,
+ };
+
+ tasklet_norace uint8_t cmd;
+ enum
+ {
+ CMD_NONE = 0, // the state machine has stopped
+ CMD_TURNOFF = 1, // goto SLEEP state
+ CMD_STANDBY = 2, // goto TRX_OFF state
+ CMD_TURNON = 3, // goto RX_ON state
+ CMD_TRANSMIT = 4, // currently transmitting a message
+ CMD_RECEIVE = 5, // currently receiving a message
+ CMD_CCA = 6, // performing clear chanel assesment
+ CMD_CHANNEL = 7, // changing the channel
+ CMD_SIGNAL_DONE = 8, // signal the end of the state transition
+ CMD_DOWNLOAD = 9, // download the received message
+ };
+
+ norace bool radioIrq;
+
+ tasklet_norace uint8_t txPower;
+ tasklet_norace uint8_t channel;
+
+ tasklet_norace message_t* rxMsg;
+ message_t rxMsgBuffer;
+
+ uint16_t capturedTime; // the current time when the last interrupt has occured
+
+ tasklet_norace uint8_t rssiClear;
+ tasklet_norace uint8_t rssiBusy;
+
+/*----------------- REGISTER -----------------*/
+
+ inline void writeRegister(uint8_t reg, uint8_t value)
+ {
+ ASSERT( call SpiResource.isOwner() );
+ ASSERT( reg == (reg & RF230_CMD_REGISTER_MASK) );
+
+ call SELN.clr();
+ call FastSpiByte.splitWrite(RF230_CMD_REGISTER_WRITE | reg);
+ call FastSpiByte.splitReadWrite(value);
+ call FastSpiByte.splitRead();
+ call SELN.set();
+ }
+
+ inline uint8_t readRegister(uint8_t reg)
+ {
+ ASSERT( call SpiResource.isOwner() );
+ ASSERT( reg == (reg & RF230_CMD_REGISTER_MASK) );
+
+ call SELN.clr();
+ call FastSpiByte.splitWrite(RF230_CMD_REGISTER_READ | reg);
+ call FastSpiByte.splitReadWrite(0);
+ reg = call FastSpiByte.splitRead();
+ call SELN.set();
+
+ return reg;
+ }
+
+/*----------------- ALARM -----------------*/
+
+ enum
+ {
+ SLEEP_WAKEUP_TIME = (uint16_t)(880 * RADIO_ALARM_MICROSEC),
+ CCA_REQUEST_TIME = (uint16_t)(140 * RADIO_ALARM_MICROSEC),
+
+ TX_SFD_DELAY = (uint16_t)(176 * RADIO_ALARM_MICROSEC),
+ RX_SFD_DELAY = (uint16_t)(8 * RADIO_ALARM_MICROSEC),
+ };
+
+ tasklet_async event void RadioAlarm.fired()
+ {
+ if( state == STATE_SLEEP_2_TRX_OFF )
+ state = STATE_TRX_OFF;
+ else if( cmd == CMD_CCA )
+ {
+ uint8_t cca;
+
+ ASSERT( state == STATE_RX_ON );
+
+ cmd = CMD_NONE;
+ cca = readRegister(RF230_TRX_STATUS);
+
+ ASSERT( (cca & RF230_TRX_STATUS_MASK) == RF230_RX_ON );
+
+ signal RadioCCA.done( (cca & RF230_CCA_DONE) ? ((cca & RF230_CCA_STATUS) ? SUCCESS : EBUSY) : FAIL );
+ }
+ else
+ ASSERT(FALSE);
+
+ // make sure the rest of the command processing is called
+ call Tasklet.schedule();
+ }
+
+/*----------------- INIT -----------------*/
+
+ command error_t PlatformInit.init()
+ {
+ call SELN.makeOutput();
+ call SELN.set();
+ call SLP_TR.makeOutput();
+ call SLP_TR.clr();
+ call RSTN.makeOutput();
+ call RSTN.set();
+
+ rxMsg = &rxMsgBuffer;
+
+ // these are just good approximates
+ rssiClear = 0;
+ rssiBusy = 90;
+
+ return SUCCESS;
+ }
+
+ command error_t SoftwareInit.init()
+ {
+ // for powering up the radio
+ return call SpiResource.request();
+ }
+
+ void initRadio()
+ {
+ call BusyWait.wait(510);
+
+ call RSTN.clr();
+ call SLP_TR.clr();
+ call BusyWait.wait(6);
+ call RSTN.set();
+
+ writeRegister(RF230_TRX_CTRL_0, RF230_TRX_CTRL_0_VALUE);
+ writeRegister(RF230_TRX_STATE, RF230_TRX_OFF);
+
+ call BusyWait.wait(510);
+
+ writeRegister(RF230_IRQ_MASK, RF230_IRQ_TRX_UR | RF230_IRQ_PLL_LOCK | RF230_IRQ_TRX_END | RF230_IRQ_RX_START);
+ writeRegister(RF230_CCA_THRES, RF230_CCA_THRES_VALUE);
+ writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | RF230_TX_PWR_DEFAULT);
+
+ txPower = RF230_TX_PWR_DEFAULT;
+ channel = call RF230DriverConfig.getDefaultChannel() & RF230_CHANNEL_MASK;
+ writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel);
+
+ call SLP_TR.set();
+ state = STATE_SLEEP;
+ }
+
+/*----------------- SPI -----------------*/
+
+ event void SpiResource.granted()
+ {
+ call SELN.makeOutput();
+ call SELN.set();
+
+ if( state == STATE_P_ON )
+ {
+ initRadio();
+ call SpiResource.release();
+ }
+ else
+ call Tasklet.schedule();
+ }
+
+ bool isSpiAcquired()
+ {
+ if( call SpiResource.isOwner() )
+ return TRUE;
+
+ if( call SpiResource.immediateRequest() == SUCCESS )
+ {
+ call SELN.makeOutput();
+ call SELN.set();
+
+ return TRUE;
+ }
+
+ call SpiResource.request();
+ return FALSE;
+ }
+
+/*----------------- CHANNEL -----------------*/
+
+ tasklet_async command uint8_t RadioState.getChannel()
+ {
+ return channel;
+ }
+
+ tasklet_async command error_t RadioState.setChannel(uint8_t c)
+ {
+ c &= RF230_CHANNEL_MASK;
+
+ if( cmd != CMD_NONE )
+ return EBUSY;
+ else if( channel == c )
+ return EALREADY;
+
+ channel = c;
+ cmd = CMD_CHANNEL;
+ call Tasklet.schedule();
+
+ return SUCCESS;
+ }
+
+ inline void changeChannel()
+ {
+ ASSERT( cmd == CMD_CHANNEL );
+ ASSERT( state == STATE_SLEEP || state == STATE_TRX_OFF || state == STATE_RX_ON );
+
+ if( isSpiAcquired() )
+ {
+ writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel);
+
+ if( state == STATE_RX_ON )
+ state = STATE_TRX_OFF_2_RX_ON;
+ else
+ cmd = CMD_SIGNAL_DONE;
+ }
+ }
+
+/*----------------- TURN ON/OFF -----------------*/
+
+ inline void changeState()
+ {
+ if( (cmd == CMD_STANDBY || cmd == CMD_TURNON)
+ && state == STATE_SLEEP && call RadioAlarm.isFree() )
+ {
+ call SLP_TR.clr();
+
+ call RadioAlarm.wait(SLEEP_WAKEUP_TIME);
+ state = STATE_SLEEP_2_TRX_OFF;
+ }
+ else if( cmd == CMD_TURNON && state == STATE_TRX_OFF && isSpiAcquired() )
+ {
+ ASSERT( ! radioIrq );
+
+ readRegister(RF230_IRQ_STATUS); // clear the interrupt register
+ call IRQ.captureRisingEdge();
+
+ // setChannel was ignored in SLEEP because the SPI was not working, so do it here
+ writeRegister(RF230_PHY_CC_CCA, RF230_CCA_MODE_VALUE | channel);
+
+ writeRegister(RF230_TRX_STATE, RF230_RX_ON);
+ state = STATE_TRX_OFF_2_RX_ON;
+ }
+ else if( (cmd == CMD_TURNOFF || cmd == CMD_STANDBY)
+ && state == STATE_RX_ON && isSpiAcquired() )
+ {
+ writeRegister(RF230_TRX_STATE, RF230_FORCE_TRX_OFF);
+
+ call IRQ.disable();
+ radioIrq = FALSE;
+
+ state = STATE_TRX_OFF;
+ }
+
+ if( cmd == CMD_TURNOFF && state == STATE_TRX_OFF )
+ {
+ call SLP_TR.set();
+ state = STATE_SLEEP;
+ cmd = CMD_SIGNAL_DONE;
+ }
+ else if( cmd == CMD_STANDBY && state == STATE_TRX_OFF )
+ cmd = CMD_SIGNAL_DONE;
+ }
+
+ tasklet_async command error_t RadioState.turnOff()
+ {
+ if( cmd != CMD_NONE )
+ return EBUSY;
+ else if( state == STATE_SLEEP )
+ return EALREADY;
+
+ cmd = CMD_TURNOFF;
+ call Tasklet.schedule();
+
+ return SUCCESS;
+ }
+
+ tasklet_async command error_t RadioState.standby()
+ {
+ if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) )
+ return EBUSY;
+ else if( state == STATE_TRX_OFF )
+ return EALREADY;
+
+ cmd = CMD_STANDBY;
+ call Tasklet.schedule();
+
+ return SUCCESS;
+ }
+
+ tasklet_async command error_t RadioState.turnOn()
+ {
+ if( cmd != CMD_NONE || (state == STATE_SLEEP && ! call RadioAlarm.isFree()) )
+ return EBUSY;
+ else if( state == STATE_RX_ON )
+ return EALREADY;
+
+ cmd = CMD_TURNON;
+ call Tasklet.schedule();
+
+ return SUCCESS;
+ }
+
+ default tasklet_async event void RadioState.done() { }
+
+/*----------------- TRANSMIT -----------------*/
+
+ tasklet_async command error_t RadioSend.send(message_t* msg)
+ {
+ uint16_t time;
+ uint8_t length;
+ uint8_t* data;
+ uint8_t header;
+ uint32_t time32;
+ void* timesync;
+
+ if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || radioIrq )
+ return EBUSY;
+
+ length = (call PacketTransmitPower.isSet(msg) ?
+ call PacketTransmitPower.get(msg) : RF230_DEF_RFPOWER) & RF230_TX_PWR_MASK;
+
+ if( length != txPower )
+ {
+ txPower = length;
+ writeRegister(RF230_PHY_TX_PWR, RF230_TX_AUTO_CRC_ON | txPower);
+ }
+
+ if( call RF230DriverConfig.requiresRssiCca(msg)
+ && (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) > ((rssiClear + rssiBusy) >> 3) )
+ return EBUSY;
+
+ writeRegister(RF230_TRX_STATE, RF230_PLL_ON);
+
+ // do something useful, just to wait a little
+ time32 = call LocalTime.get();
+ timesync = call PacketTimeSyncOffset.isSet(msg) ? msg->data + call PacketTimeSyncOffset.get(msg) : 0;
+
+ // we have missed an incoming message in this short amount of time
+ if( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) != RF230_PLL_ON )
+ {
+ ASSERT( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) == RF230_BUSY_RX );
+
+ state = STATE_PLL_ON_2_RX_ON;
+ return EBUSY;
+ }
+
+ atomic
+ {
+ call SLP_TR.set();
+ time = call RadioAlarm.getNow() + TX_SFD_DELAY;
+ }
+ call SLP_TR.clr();
+
+ ASSERT( ! radioIrq );
+
+ call SELN.clr();
+ call FastSpiByte.splitWrite(RF230_CMD_FRAME_WRITE);
+
+ length = call RF230DriverConfig.getLength(msg);
+ data = call RF230DriverConfig.getPayload(msg);
+
+ // length | data[0] ... data[length-3] | automatically generated FCS
+ call FastSpiByte.splitReadWrite(length);
+
+ // the FCS is atomatically generated (2 bytes)
+ length -= 2;
+
+ header = call RF230DriverConfig.getHeaderLength();
+ if( header > length )
+ header = length;
+
+ length -= header;
+
+ // first upload the header to gain some time
+ do {
+ call FastSpiByte.splitReadWrite(*(data++));
+ }
+ while( --header != 0 );
+
+ time32 += (int16_t)(time) - (int16_t)(time32);
+
+ if( timesync != 0 )
+ *(timesync_relative_t*)timesync = (*(timesync_absolute_t*)timesync) - time32;
+
+ do {
+ call FastSpiByte.splitReadWrite(*(data++));
+ }
+ while( --length != 0 );
+
+ // wait for the SPI transfer to finish
+ call FastSpiByte.splitRead();
+ call SELN.set();
+
+ /*
+ * There is a very small window (~1 microsecond) when the RF230 went
+ * into PLL_ON state but was somehow not properly initialized because
+ * of an incoming message and could not go into BUSY_TX. I think the
+ * radio can even receive a message, and generate a TRX_UR interrupt
+ * because of concurrent access, but that message probably cannot be
+ * recovered.
+ *
+ * TODO: this needs to be verified, and make sure that the chip is
+ * not locked up in this case.
+ */
+
+ // go back to RX_ON state when finished
+ writeRegister(RF230_TRX_STATE, RF230_RX_ON);
+
+#ifdef RADIO_DEBUG_MESSAGES
+ if( call DiagMsg.record() )
+ {
+ length = call RF230DriverConfig.getLength(msg);
+
+ call DiagMsg.str("tx");
+ call DiagMsg.uint16(time);
+ call DiagMsg.uint8(length);
+ call DiagMsg.hex8s(data, length - 2);
+ call DiagMsg.send();
+ }
+#endif
+
+ if( timesync != 0 )
+ *(timesync_absolute_t*)timesync = (*(timesync_relative_t*)timesync) + time32;
+
+ call PacketTimeStamp.set(msg, time32);
+
+ // wait for the TRX_END interrupt
+ state = STATE_BUSY_TX_2_RX_ON;
+ cmd = CMD_TRANSMIT;
+
+ return SUCCESS;
+ }
+
+ default tasklet_async event void RadioSend.sendDone(error_t error) { }
+ default tasklet_async event void RadioSend.ready() { }
+
+/*----------------- CCA -----------------*/
+
+ tasklet_async command error_t RadioCCA.request()
+ {
+ if( cmd != CMD_NONE || state != STATE_RX_ON || ! isSpiAcquired() || ! call RadioAlarm.isFree() )
+ return EBUSY;
+
+ // see Errata B7 of the datasheet
+ // writeRegister(RF230_TRX_STATE, RF230_PLL_ON);
+ // writeRegister(RF230_TRX_STATE, RF230_RX_ON);
+
+ writeRegister(RF230_PHY_CC_CCA, RF230_CCA_REQUEST | RF230_CCA_MODE_VALUE | channel);
+ call RadioAlarm.wait(CCA_REQUEST_TIME);
+ cmd = CMD_CCA;
+
+ return SUCCESS;
+ }
+
+ default tasklet_async event void RadioCCA.done(error_t error) { }
+
+/*----------------- RECEIVE -----------------*/
+
+ inline void downloadMessage()
+ {
+ uint8_t length;
+ uint16_t crc;
+
+ call SELN.clr();
+ call FastSpiByte.write(RF230_CMD_FRAME_READ);
+
+ // read the length byte
+ length = call FastSpiByte.write(0);
+
+ // if correct length
+ if( length >= 3 && length <= call RF230DriverConfig.getMaxLength() )
+ {
+ uint8_t read;
+ uint8_t* data;
+
+ // initiate the reading
+ call FastSpiByte.splitWrite(0);
+
+ call RF230DriverConfig.setLength(rxMsg, length);
+ data = call RF230DriverConfig.getPayload(rxMsg);
+ crc = 0;
+
+ // we do not store the CRC field
+ length -= 2;
+
+ read = call RF230DriverConfig.getHeaderLength();
+ if( length < read )
+ read = length;
+
+ length -= read;
+
+ do {
+ crc = RF230_CRCBYTE_COMMAND(crc, *(data++) = call FastSpiByte.splitReadWrite(0));
+ }
+ while( --read != 0 );
+
+ if( signal RadioReceive.header(rxMsg) )
+ {
+ while( length-- != 0 )
+ crc = RF230_CRCBYTE_COMMAND(crc, *(data++) = call FastSpiByte.splitReadWrite(0));
+
+ crc = RF230_CRCBYTE_COMMAND(crc, call FastSpiByte.splitReadWrite(0));
+ crc = RF230_CRCBYTE_COMMAND(crc, call FastSpiByte.splitReadWrite(0));
+
+ call PacketLinkQuality.set(rxMsg, call FastSpiByte.splitRead());
+ }
+ else
+ crc = 1;
+ }
+ else
+ crc = 1;
+
+ call SELN.set();
+ state = STATE_RX_ON;
+
+#ifdef RADIO_DEBUG_MESSAGES
+ if( call DiagMsg.record() )
+ {
+ length = call RF230DriverConfig.getLength(rxMsg);
+
+ call DiagMsg.str("rx");
+ call DiagMsg.uint32(call PacketTimeStamp.isValid(rxMsg) ? call PacketTimeStamp.timestamp(rxMsg) : 0);
+ call DiagMsg.uint16(call RadioAlarm.getNow());
+ call DiagMsg.uint8(crc != 0);
+ call DiagMsg.uint8(length);
+ call DiagMsg.hex8s(call RF230DriverConfig.getPayload(rxMsg), length - 2);
+ call DiagMsg.send();
+ }
+#endif
+
+ cmd = CMD_NONE;
+
+ // signal only if it has passed the CRC check
+ if( crc == 0 )
+ rxMsg = signal RadioReceive.receive(rxMsg);
+ }
+
+/*----------------- IRQ -----------------*/
+
+ async event void IRQ.captured(uint16_t time)
+ {
+ ASSERT( ! radioIrq );
+
+ atomic
+ {
+ capturedTime = time;
+ radioIrq = TRUE;
+ }
+
+ call Tasklet.schedule();
+ }
+
+ void serviceRadio()
+ {
+ if( isSpiAcquired() )
+ {
+ uint16_t time;
+ uint32_t time32;
+ uint8_t irq;
+ uint8_t temp;
+
+ atomic time = capturedTime;
+ radioIrq = FALSE;
+ irq = readRegister(RF230_IRQ_STATUS);
+
+#ifdef RADIO_DEBUG
+ // TODO: handle this interrupt
+ if( irq & RF230_IRQ_TRX_UR )
+ {
+ if( call DiagMsg.record() )
+ {
+ call DiagMsg.str("assert ur");
+ call DiagMsg.uint16(call RadioAlarm.getNow());
+ call DiagMsg.hex8(readRegister(RF230_TRX_STATUS));
+ call DiagMsg.hex8(readRegister(RF230_TRX_STATE));
+ call DiagMsg.hex8(irq);
+ call DiagMsg.uint8(state);
+ call DiagMsg.uint8(cmd);
+ call DiagMsg.send();
+ }
+ }
+#endif
+
+ if( irq & RF230_IRQ_PLL_LOCK )
+ {
+ if( cmd == CMD_TURNON || cmd == CMD_CHANNEL )
+ {
+ ASSERT( state == STATE_TRX_OFF_2_RX_ON );
+
+ state = STATE_RX_ON;
+ cmd = CMD_SIGNAL_DONE;
+ }
+ else if( cmd == CMD_TRANSMIT )
+ {
+ ASSERT( state == STATE_BUSY_TX_2_RX_ON );
+ }
+ else
+ ASSERT(FALSE);
+ }
+
+ if( irq & RF230_IRQ_RX_START )
+ {
+ if( cmd == CMD_CCA )
+ {
+ signal RadioCCA.done(FAIL);
+ cmd = CMD_NONE;
+ }
+
+ if( cmd == CMD_NONE )
+ {
+ ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON );
+
+ // the most likely place for busy channel, with no TRX_END interrupt
+ if( irq == RF230_IRQ_RX_START )
+ {
+ temp = readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK;
+ rssiBusy += temp - (rssiBusy >> 2);
+#ifndef RF230_RSSI_ENERGY
+ call PacketRSSI.set(rxMsg, temp);
+ }
+ else
+ {
+ call PacketRSSI.clear(rxMsg);
+#endif
+ }
+
+ /*
+ * The timestamp corresponds to the first event which could not
+ * have been a PLL_LOCK because then cmd != CMD_NONE, so we must
+ * have received a message (and could also have received the
+ * TRX_END interrupt in the mean time, but that is fine. Also,
+ * we could not be after a transmission, because then cmd =
+ * CMD_TRANSMIT.
+ */
+ if( irq == RF230_IRQ_RX_START ) // just to be cautious
+ {
+ time32 = call LocalTime.get();
+ time32 += (int16_t)(time - RX_SFD_DELAY) - (int16_t)(time32);
+ call PacketTimeStamp.set(rxMsg, time32);
+ }
+ else
+ call PacketTimeStamp.clear(rxMsg);
+
+ cmd = CMD_RECEIVE;
+ }
+ else
+ ASSERT( cmd == CMD_TURNOFF );
+ }
+
+ if( irq & RF230_IRQ_TRX_END )
+ {
+ if( cmd == CMD_TRANSMIT )
+ {
+ ASSERT( state == STATE_BUSY_TX_2_RX_ON );
+
+ state = STATE_RX_ON;
+ cmd = CMD_NONE;
+ signal RadioSend.sendDone(SUCCESS);
+
+ // TODO: we could have missed a received message
+ ASSERT( ! (irq & RF230_IRQ_RX_START) );
+ }
+ else if( cmd == CMD_RECEIVE )
+ {
+ ASSERT( state == STATE_RX_ON || state == STATE_PLL_ON_2_RX_ON );
+#ifdef RF230_RSSI_ENERGY
+ if( irq == RF230_IRQ_TRX_END )
+ call PacketRSSI.set(rxMsg, readRegister(RF230_PHY_ED_LEVEL));
+ else
+ call PacketRSSI.clear(rxMsg);
+#endif
+ if( state == STATE_PLL_ON_2_RX_ON )
+ {
+ ASSERT( (readRegister(RF230_TRX_STATUS) & RF230_TRX_STATUS_MASK) == RF230_PLL_ON );
+
+ writeRegister(RF230_TRX_STATE, RF230_RX_ON);
+ state = STATE_RX_ON;
+ }
+ else
+ {
+ // the most likely place for clear channel (hope to avoid acks)
+ rssiClear += (readRegister(RF230_PHY_RSSI) & RF230_RSSI_MASK) - (rssiClear >> 2);
+ }
+
+ cmd = CMD_DOWNLOAD;
+ }
+ else
+ ASSERT(FALSE);
+ }
+ }
+ }
+
+ default tasklet_async event bool RadioReceive.header(message_t* msg)
+ {
+ return TRUE;
+ }
+
+ default tasklet_async event message_t* RadioReceive.receive(message_t* msg)
+ {
+ return msg;
+ }
+
+/*----------------- TASKLET -----------------*/
+
+ tasklet_async event void Tasklet.run()
+ {
+ if( radioIrq )
+ serviceRadio();
+
+ if( cmd != CMD_NONE )
+ {
+ if( cmd == CMD_DOWNLOAD )
+ downloadMessage();
+ else if( CMD_TURNOFF <= cmd && cmd <= CMD_TURNON )
+ changeState();
+ else if( cmd == CMD_CHANNEL )
+ changeChannel();
+
+ if( cmd == CMD_SIGNAL_DONE )
+ {
+ cmd = CMD_NONE;
+ signal RadioState.done();
+ }
+ }
+
+ if( cmd == CMD_NONE && state == STATE_RX_ON && ! radioIrq )
+ signal RadioSend.ready();
+
+ if( cmd == CMD_NONE )
+ call SpiResource.release();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __RF230PACKET_H__
+#define __RF230PACKET_H__
+
+#include <IEEE154Packet.h>
+
+typedef ieee154_header_t rf230packet_header_t;
+
+typedef nx_struct rf230packet_footer_t
+{
+ // the time stamp is not recorded here, time stamped messaged cannot have max length
+} rf230packet_footer_t;
+
+typedef struct rf230packet_metadata_t
+{
+ uint8_t flags;
+ uint8_t lqi;
+ uint8_t power; // shared between TXPOWER and RSSI
+#ifdef LOW_POWER_LISTENING
+ uint16_t lpl_sleepint;
+#endif
+ uint32_t timestamp;
+} rf230packet_metadata_t;
+
+enum rf230packet_metadata_flags
+{
+ RF230PACKET_WAS_ACKED = 0x01, // PacketAcknowledgements
+ RF230PACKET_TIMESTAMP = 0x02, // PacketTimeStamp
+ RF230PACKET_TXPOWER = 0x04, // PacketTransmitPower
+ RF230PACKET_RSSI = 0x08, // PacketRSSI
+ RF230PACKET_TIMESYNC = 0x10, // PacketTimeSync (update timesync_footer)
+ RF230PACKET_LPL_SLEEPINT = 0x20, // LowPowerListening
+
+ RF230PACKET_CLEAR_METADATA = 0x00,
+};
+
+#endif//__RF230PACKET_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration RF230PacketC
+{
+ provides
+ {
+ interface Packet;
+ interface AMPacket;
+ interface PacketAcknowledgements;
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketField<uint8_t> as PacketTransmitPower;
+ interface PacketField<uint8_t> as PacketRSSI;
+ interface PacketField<uint16_t> as PacketSleepInterval;
+ interface PacketField<uint8_t> as PacketTimeSyncOffset;
+
+ interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+ }
+}
+
+implementation
+{
+ components RF230PacketP, IEEE154PacketC, LocalTimeMicroC, LocalTimeMilliC;
+
+ RF230PacketP.IEEE154Packet -> IEEE154PacketC;
+ RF230PacketP.LocalTimeRadio -> LocalTimeMicroC;
+ RF230PacketP.LocalTimeMilli -> LocalTimeMilliC;
+
+ Packet = RF230PacketP;
+ AMPacket = IEEE154PacketC;
+
+ PacketAcknowledgements = RF230PacketP;
+ PacketLinkQuality = RF230PacketP.PacketLinkQuality;
+ PacketTransmitPower = RF230PacketP.PacketTransmitPower;
+ PacketRSSI = RF230PacketP.PacketRSSI;
+ PacketSleepInterval = RF230PacketP.PacketSleepInterval;
+ PacketTimeSyncOffset = RF230PacketP.PacketTimeSyncOffset;
+
+ PacketTimeStampRadio = RF230PacketP;
+ PacketTimeStampMilli = RF230PacketP;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <RF230Packet.h>
+#include <GenericTimeSyncMessage.h>
+#include <RadioConfig.h>
+
+module RF230PacketP
+{
+ provides
+ {
+ interface PacketAcknowledgements;
+ interface Packet;
+ interface PacketField<uint8_t> as PacketLinkQuality;
+ interface PacketField<uint8_t> as PacketTransmitPower;
+ interface PacketField<uint8_t> as PacketRSSI;
+ interface PacketField<uint16_t> as PacketSleepInterval;
+ interface PacketField<uint8_t> as PacketTimeSyncOffset;
+
+ interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
+ interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
+ }
+
+ uses
+ {
+ interface IEEE154Packet;
+
+ interface LocalTime<TRadio> as LocalTimeRadio;
+ interface LocalTime<TMilli> as LocalTimeMilli;
+ }
+}
+
+implementation
+{
+ enum
+ {
+ PACKET_LENGTH_INCREASE =
+ sizeof(rf230packet_header_t) - 1 // the 8-bit length field is not counted
+ + sizeof(ieee154_footer_t), // the CRC is not stored in memory
+ };
+
+ inline rf230packet_metadata_t* getMeta(message_t* msg)
+ {
+ return (rf230packet_metadata_t*)(msg->metadata);
+ }
+
+/*----------------- Packet -----------------*/
+
+ command void Packet.clear(message_t* msg)
+ {
+ call IEEE154Packet.createDataFrame(msg);
+
+ getMeta(msg)->flags = RF230PACKET_CLEAR_METADATA;
+ }
+
+ inline command void Packet.setPayloadLength(message_t* msg, uint8_t len)
+ {
+ call IEEE154Packet.setLength(msg, len + PACKET_LENGTH_INCREASE);
+ }
+
+ inline command uint8_t Packet.payloadLength(message_t* msg)
+ {
+ return call IEEE154Packet.getLength(msg) - PACKET_LENGTH_INCREASE;
+ }
+
+ inline command uint8_t Packet.maxPayloadLength()
+ {
+ return TOSH_DATA_LENGTH;
+ }
+
+ command void* Packet.getPayload(message_t* msg, uint8_t len)
+ {
+ if( len > TOSH_DATA_LENGTH )
+ return NULL;
+
+ return msg->data;
+ }
+
+/*----------------- PacketAcknowledgements -----------------*/
+
+ async command error_t PacketAcknowledgements.requestAck(message_t* msg)
+ {
+ call IEEE154Packet.setAckRequired(msg, TRUE);
+
+ return SUCCESS;
+ }
+
+ async command error_t PacketAcknowledgements.noAck(message_t* msg)
+ {
+ call IEEE154Packet.setAckRequired(msg, FALSE);
+
+ return SUCCESS;
+ }
+
+ async command bool PacketAcknowledgements.wasAcked(message_t* msg)
+ {
+ return getMeta(msg)->flags & RF230PACKET_WAS_ACKED;
+ }
+
+/*----------------- PacketLinkQuality -----------------*/
+
+ async command bool PacketLinkQuality.isSet(message_t* msg)
+ {
+ return TRUE;
+ }
+
+ async command uint8_t PacketLinkQuality.get(message_t* msg)
+ {
+ return getMeta(msg)->lqi;
+ }
+
+ async command void PacketLinkQuality.clear(message_t* msg)
+ {
+ }
+
+ async command void PacketLinkQuality.set(message_t* msg, uint8_t value)
+ {
+ getMeta(msg)->lqi = value;
+ }
+
+/*----------------- PacketTimeStampRadio -----------------*/
+
+ async command bool PacketTimeStampRadio.isValid(message_t* msg)
+ {
+ return getMeta(msg)->flags & RF230PACKET_TIMESTAMP;
+ }
+
+ async command uint32_t PacketTimeStampRadio.timestamp(message_t* msg)
+ {
+ return getMeta(msg)->timestamp;
+ }
+
+ async command void PacketTimeStampRadio.clear(message_t* msg)
+ {
+ getMeta(msg)->flags &= ~RF230PACKET_TIMESTAMP;
+ }
+
+ async command void PacketTimeStampRadio.set(message_t* msg, uint32_t value)
+ {
+ getMeta(msg)->flags |= RF230PACKET_TIMESTAMP;
+ getMeta(msg)->timestamp = value;
+ }
+
+/*----------------- PacketTimeStampMilli -----------------*/
+
+ async command bool PacketTimeStampMilli.isValid(message_t* msg)
+ {
+ return call PacketTimeStampRadio.isValid(msg);
+ }
+
+ async command uint32_t PacketTimeStampMilli.timestamp(message_t* msg)
+ {
+ int32_t offset = call PacketTimeStampRadio.timestamp(msg) - call LocalTimeRadio.get();
+
+ return (offset >> RADIO_ALARM_MILLI_EXP) + call LocalTimeMilli.get();
+ }
+
+ async command void PacketTimeStampMilli.clear(message_t* msg)
+ {
+ call PacketTimeStampRadio.clear(msg);
+ }
+
+ async command void PacketTimeStampMilli.set(message_t* msg, uint32_t value)
+ {
+ int32_t offset = (value - call LocalTimeMilli.get()) << RADIO_ALARM_MILLI_EXP;
+
+ call PacketTimeStampRadio.set(msg, offset + call LocalTimeRadio.get());
+ }
+
+/*----------------- PacketTransmitPower -----------------*/
+
+ async command bool PacketTransmitPower.isSet(message_t* msg)
+ {
+ return getMeta(msg)->flags & RF230PACKET_TXPOWER;
+ }
+
+ async command uint8_t PacketTransmitPower.get(message_t* msg)
+ {
+ return getMeta(msg)->power;
+ }
+
+ async command void PacketTransmitPower.clear(message_t* msg)
+ {
+ getMeta(msg)->flags &= ~RF230PACKET_TXPOWER;
+ }
+
+ async command void PacketTransmitPower.set(message_t* msg, uint8_t value)
+ {
+ getMeta(msg)->flags &= ~RF230PACKET_RSSI;
+ getMeta(msg)->flags |= RF230PACKET_TXPOWER;
+ getMeta(msg)->power = value;
+ }
+
+/*----------------- PacketRSSI -----------------*/
+
+ async command bool PacketRSSI.isSet(message_t* msg)
+ {
+ return getMeta(msg)->flags & RF230PACKET_RSSI;
+ }
+
+ async command uint8_t PacketRSSI.get(message_t* msg)
+ {
+ return getMeta(msg)->power;
+ }
+
+ async command void PacketRSSI.clear(message_t* msg)
+ {
+ getMeta(msg)->flags &= ~RF230PACKET_RSSI;
+ }
+
+ async command void PacketRSSI.set(message_t* msg, uint8_t value)
+ {
+ getMeta(msg)->flags &= ~RF230PACKET_TXPOWER;
+ getMeta(msg)->flags |= RF230PACKET_RSSI;
+ getMeta(msg)->power = value;
+ }
+
+/*----------------- PacketTimeSyncOffset -----------------*/
+
+ async command bool PacketTimeSyncOffset.isSet(message_t* msg)
+ {
+ return getMeta(msg)->flags & RF230PACKET_TIMESYNC;
+ }
+
+ async command uint8_t PacketTimeSyncOffset.get(message_t* msg)
+ {
+ return call IEEE154Packet.getLength(msg) - PACKET_LENGTH_INCREASE - sizeof(timesync_absolute_t);
+ }
+
+ async command void PacketTimeSyncOffset.clear(message_t* msg)
+ {
+ getMeta(msg)->flags &= ~RF230PACKET_TIMESYNC;
+ }
+
+ async command void PacketTimeSyncOffset.set(message_t* msg, uint8_t value)
+ {
+ // the value is ignored, the offset always points to the timesync footer at the end of the payload
+ getMeta(msg)->flags |= RF230PACKET_TIMESYNC;
+ }
+
+/*----------------- PacketSleepInterval -----------------*/
+
+ async command bool PacketSleepInterval.isSet(message_t* msg)
+ {
+ return getMeta(msg)->flags & RF230PACKET_LPL_SLEEPINT;
+ }
+
+ async command uint16_t PacketSleepInterval.get(message_t* msg)
+ {
+#ifdef LOW_POWER_LISTENING
+ return getMeta(msg)->lpl_sleepint;
+#else
+ return 0;
+#endif
+ }
+
+ async command void PacketSleepInterval.clear(message_t* msg)
+ {
+ getMeta(msg)->flags &= ~RF230PACKET_LPL_SLEEPINT;
+ }
+
+ async command void PacketSleepInterval.set(message_t* msg, uint16_t value)
+ {
+ getMeta(msg)->flags |= RF230PACKET_LPL_SLEEPINT;
+
+#ifdef LOW_POWER_LISTENING
+ getMeta(msg)->lpl_sleepint = value;
+#endif
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __IEEE154PACKET_H__
+#define __IEEE154PACKET_H__
+
+typedef nx_struct ieee154_header_t
+{
+ nxle_uint8_t length;
+ nxle_uint16_t fcf;
+ nxle_uint8_t dsn;
+ nxle_uint16_t destpan;
+ nxle_uint16_t dest;
+ nxle_uint16_t src;
+
+// I-Frame 6LowPAN interoperability byte
+#ifndef TFRAMES_ENABLED
+ nxle_uint8_t network;
+#endif
+
+ nxle_uint8_t type;
+} ieee154_header_t;
+
+// the actual radio driver might not use this
+typedef nx_struct ieee154_footer_t
+{
+ nxle_uint16_t crc;
+} ieee154_footer_t;
+
+enum ieee154_fcf_enums {
+ IEEE154_FCF_FRAME_TYPE = 0,
+ IEEE154_FCF_SECURITY_ENABLED = 3,
+ IEEE154_FCF_FRAME_PENDING = 4,
+ IEEE154_FCF_ACK_REQ = 5,
+ IEEE154_FCF_INTRAPAN = 6,
+ IEEE154_FCF_DEST_ADDR_MODE = 10,
+ IEEE154_FCF_SRC_ADDR_MODE = 14,
+};
+
+enum ieee154_fcf_type_enums {
+ IEEE154_TYPE_BEACON = 0,
+ IEEE154_TYPE_DATA = 1,
+ IEEE154_TYPE_ACK = 2,
+ IEEE154_TYPE_MAC_CMD = 3,
+ IEEE154_TYPE_MASK = 7,
+};
+
+enum iee154_fcf_addr_mode_enums {
+ IEEE154_ADDR_NONE = 0,
+ IEEE154_ADDR_SHORT = 2,
+ IEEE154_ADDR_EXT = 3,
+ IEEE154_ADDR_MASK = 3,
+};
+
+#endif//__IEEE154PACKET_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <IEEE154Packet.h>
+#include <message.h>
+
+/**
+ * This interface encapsulates IEEE 802.15.4 intrapan data frames with
+ * 16-bit destination pan, source and destination addresses. It also
+ * supports 6LowPan interoperability mode, and acknowledgement frames.
+ * Note, that this interface does not support the CRC-16 value, which
+ * should be verified before the data can be trusted.
+ */
+interface IEEE154Packet
+{
+ /**
+ * Returns the IEEE 802.15.4 header including the length field.
+ */
+ async command ieee154_header_t* getHeader(message_t* msg);
+
+ /**
+ * Returns the raw value (unadjusted) of the length field
+ */
+ async command uint8_t getLength(message_t* msg);
+
+ /**
+ * Sets the length field
+ */
+ async command void setLength(message_t* msg, uint8_t length);
+
+ /**
+ * Returns the frame control field. This method should not be used,
+ * isDataFrame and isAckFrame should be used instead.
+ */
+ async command uint16_t getFCF(message_t* msg);
+
+ /**
+ * Sets the frame control field. This method should not be used,
+ * createDataFrame and createAckFrame should be used instead.
+ */
+ async command void setFCF(message_t* msg, uint16_t fcf);
+
+ /**
+ * Returns TRUE if the message is a data frame supported by
+ * this interface (based on the value of the FCF).
+ */
+ async command bool isDataFrame(message_t* msg);
+
+ /**
+ * Sets the FCF to create a data frame supported by this interface.
+ * You may call setAckRequired and setFramePending commands after this.
+ */
+ async command void createDataFrame(message_t* msg);
+
+ /**
+ * Returns TRUE if the message is an acknowledgement frame supported
+ * by this interface (based on the value of the FCF).
+ */
+ async command bool isAckFrame(message_t* msg);
+
+ /**
+ * Sets the FCF to create an acknowledgement frame supported by
+ * this interface. You may call setFramePending after this.
+ */
+ async command void createAckFrame(message_t* msg);
+
+ /**
+ * Creates an acknowledgement packet for the given data packet.
+ * This also sets the DSN value. The data message must be a
+ * data frame, the ack message will be overwritten.
+ */
+ async command void createAckReply(message_t* data, message_t* ack);
+
+ /**
+ * Returns TRUE if the acknowledgement packet corresponds to the
+ * data packet. The data message must be a data packet.
+ */
+ async command bool verifyAckReply(message_t* data, message_t* ack);
+
+ /**
+ * Returns TRUE if the ACK required field is set in the FCF.
+ */
+ async command bool getAckRequired(message_t* msg);
+
+ /**
+ * Sets the ACK required field in the FCF, should never be set
+ * for acknowledgement frames.
+ */
+ async command void setAckRequired(message_t* msg, bool ack);
+
+ /**
+ * Returns TRUE if the frame pending field is set in the FCF.
+ */
+ async command bool getFramePending(message_t* msg);
+
+ /**
+ * Sets the frame pending field in the FCF.
+ */
+ async command void setFramePending(message_t* msg, bool pending);
+
+ /**
+ * Returns the data sequence number
+ */
+ async command uint8_t getDSN(message_t* msg);
+
+ /**
+ * Sets the data sequence number
+ */
+ async command void setDSN(message_t* msg, uint8_t dsn);
+
+ /**
+ * returns the destination PAN id, values <= 255 are tinyos groups,
+ * valid only for data frames
+ */
+ async command uint16_t getDestPan(message_t* msg);
+
+ /**
+ * Sets the destination PAN id, valid only for data frames
+ */
+ async command void setDestPan(message_t* msg, uint16_t pan);
+
+ /**
+ * Returns the destination address, valid only for data frames
+ */
+ async command uint16_t getDestAddr(message_t* msg);
+
+ /**
+ * Sets the destination address, valid only for data frames
+ */
+ async command void setDestAddr(message_t* msg, uint16_t addr);
+
+ /**
+ * Returns the source address, valid only for data frames
+ */
+ async command uint16_t getSrcAddr(message_t* msg);
+
+ /**
+ * Sets the source address, valid only for data frames
+ */
+ async command void setSrcAddr(message_t* msg, uint16_t addr);
+
+#ifndef TFRAMES_ENABLED
+
+ /**
+ * Returns the value of the 6LowPan network field.
+ */
+ async command uint8_t get6LowPan(message_t* msg);
+
+ /**
+ * Sets the value of the 6LowPan network field.
+ */
+ async command void set6LowPan(message_t* msg, uint8_t network);
+
+#endif
+
+ /**
+ * Returns the active message type of the message
+ */
+ async command am_id_t getType(message_t* msg);
+
+ /**
+ * Sets the active message type
+ */
+ async command void setType(message_t* msg, am_id_t type);
+
+ /**
+ * Returns TRUE if the packet is a data packet, the ACK_REQ field
+ * is set and the destination address is not the broadcast address.
+ */
+ async command bool requiresAckWait(message_t* msg);
+
+ /**
+ * Returns TRUE if the packet is a data packet, the ACK_REQ field
+ * is set and the destionation address is this node.
+ */
+ async command bool requiresAckReply(message_t* msg);
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration IEEE154PacketC
+{
+ provides
+ {
+ interface IEEE154Packet;
+ interface AMPacket;
+ }
+}
+
+implementation
+{
+ components IEEE154PacketP, ActiveMessageAddressC;
+ IEEE154PacketP.ActiveMessageAddress -> ActiveMessageAddressC;
+
+ IEEE154Packet = IEEE154PacketP;
+ AMPacket = IEEE154PacketP;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <IEEE154Packet.h>
+
+module IEEE154PacketP
+{
+ provides
+ {
+ interface IEEE154Packet;
+ interface AMPacket;
+ }
+
+ uses interface ActiveMessageAddress;
+}
+
+implementation
+{
+/*----------------- IEEE154Packet -----------------*/
+
+ enum
+ {
+ IEEE154_DATA_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE)
+ | (1 << IEEE154_FCF_INTRAPAN)
+ | (IEEE154_ADDR_MASK << IEEE154_FCF_DEST_ADDR_MODE)
+ | (IEEE154_ADDR_MASK << IEEE154_FCF_SRC_ADDR_MODE),
+
+ IEEE154_DATA_FRAME_VALUE = (IEEE154_TYPE_DATA << IEEE154_FCF_FRAME_TYPE)
+ | (1 << IEEE154_FCF_INTRAPAN)
+ | (IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE)
+ | (IEEE154_ADDR_SHORT << IEEE154_FCF_SRC_ADDR_MODE),
+
+ IEEE154_ACK_FRAME_LENGTH = 5, // includes the FCF, DSN and FCS
+ IEEE154_ACK_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE),
+ IEEE154_ACK_FRAME_VALUE = (IEEE154_TYPE_ACK << IEEE154_FCF_FRAME_TYPE),
+ };
+
+ inline ieee154_header_t* getHeader(message_t* msg)
+ {
+ return (ieee154_header_t*)(msg->data - sizeof(ieee154_header_t));
+ }
+
+ inline async command ieee154_header_t* IEEE154Packet.getHeader(message_t* msg)
+ {
+ return getHeader(msg);
+ }
+
+ inline async command uint8_t IEEE154Packet.getLength(message_t* msg)
+ {
+ return getHeader(msg)->length;
+ }
+
+ inline async command void IEEE154Packet.setLength(message_t* msg, uint8_t length)
+ {
+ getHeader(msg)->length = length;
+ }
+
+ inline async command uint16_t IEEE154Packet.getFCF(message_t* msg)
+ {
+ return getHeader(msg)->fcf;
+ }
+
+ inline async command void IEEE154Packet.setFCF(message_t* msg, uint16_t fcf)
+ {
+ getHeader(msg)->fcf = fcf;
+ }
+
+ inline async command bool IEEE154Packet.isDataFrame(message_t* msg)
+ {
+ return (getHeader(msg)->fcf & IEEE154_DATA_FRAME_MASK) == IEEE154_DATA_FRAME_VALUE;
+ }
+
+ inline async command void IEEE154Packet.createDataFrame(message_t* msg)
+ {
+ getHeader(msg)->fcf = IEEE154_DATA_FRAME_VALUE;
+ }
+
+ inline async command bool IEEE154Packet.isAckFrame(message_t* msg)
+ {
+ return (getHeader(msg)->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE;
+ }
+
+ inline async command void IEEE154Packet.createAckFrame(message_t* msg)
+ {
+ ieee154_header_t* header = getHeader(msg);
+
+ header->length = IEEE154_ACK_FRAME_LENGTH;
+ header->fcf = IEEE154_ACK_FRAME_VALUE;
+ }
+
+ inline async command void IEEE154Packet.createAckReply(message_t* data, message_t* ack)
+ {
+ ieee154_header_t* header = getHeader(ack);
+
+ header->length = IEEE154_ACK_FRAME_LENGTH;
+ header->fcf = IEEE154_ACK_FRAME_VALUE;
+ header->dsn = getHeader(data)->dsn;
+ }
+
+ inline async command bool IEEE154Packet.verifyAckReply(message_t* data, message_t* ack)
+ {
+ ieee154_header_t* header = getHeader(ack);
+
+ return header->dsn == getHeader(data)->dsn
+ && (header->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE;
+ }
+
+ inline async command bool IEEE154Packet.getAckRequired(message_t* msg)
+ {
+ return getHeader(msg)->fcf & (1 << IEEE154_FCF_ACK_REQ);
+ }
+
+ inline async command void IEEE154Packet.setAckRequired(message_t* msg, bool ack)
+ {
+ if( ack )
+ getHeader(msg)->fcf |= (1 << IEEE154_FCF_ACK_REQ);
+ else
+ getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_ACK_REQ);
+ }
+
+ inline async command bool IEEE154Packet.getFramePending(message_t* msg)
+ {
+ return getHeader(msg)->fcf & (1 << IEEE154_FCF_FRAME_PENDING);
+ }
+
+ inline async command void IEEE154Packet.setFramePending(message_t* msg, bool pending)
+ {
+ if( pending )
+ getHeader(msg)->fcf |= (1 << IEEE154_FCF_FRAME_PENDING);
+ else
+ getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_FRAME_PENDING);
+ }
+
+ inline async command uint8_t IEEE154Packet.getDSN(message_t* msg)
+ {
+ return getHeader(msg)->dsn;
+ }
+
+ inline async command void IEEE154Packet.setDSN(message_t* msg, uint8_t dsn)
+ {
+ getHeader(msg)->dsn = dsn;
+ }
+
+ inline async command uint16_t IEEE154Packet.getDestPan(message_t* msg)
+ {
+ return getHeader(msg)->destpan;
+ }
+
+ inline async command void IEEE154Packet.setDestPan(message_t* msg, uint16_t pan)
+ {
+ getHeader(msg)->destpan = pan;
+ }
+
+ inline async command uint16_t IEEE154Packet.getDestAddr(message_t* msg)
+ {
+ return getHeader(msg)->dest;
+ }
+
+ inline async command void IEEE154Packet.setDestAddr(message_t* msg, uint16_t addr)
+ {
+ getHeader(msg)->dest = addr;
+ }
+
+ inline async command uint16_t IEEE154Packet.getSrcAddr(message_t* msg)
+ {
+ return getHeader(msg)->src;
+ }
+
+ inline async command void IEEE154Packet.setSrcAddr(message_t* msg, uint16_t addr)
+ {
+ getHeader(msg)->src = addr;
+ }
+
+#ifndef TFRAMES_ENABLED
+
+ inline async command uint8_t IEEE154Packet.get6LowPan(message_t* msg)
+ {
+ return getHeader(msg)->network;
+ }
+
+ inline async command void IEEE154Packet.set6LowPan(message_t* msg, uint8_t network)
+ {
+ getHeader(msg)->network = network;
+ }
+
+#endif
+
+ inline async command am_id_t IEEE154Packet.getType(message_t* msg)
+ {
+ return getHeader(msg)->type;
+ }
+
+ inline async command void IEEE154Packet.setType(message_t* msg, am_id_t type)
+ {
+ getHeader(msg)->type = type;
+ }
+
+ async command bool IEEE154Packet.requiresAckWait(message_t* msg)
+ {
+ return call IEEE154Packet.getAckRequired(msg)
+ && call IEEE154Packet.isDataFrame(msg)
+ && call IEEE154Packet.getDestAddr(msg) != 0xFFFF;
+ }
+
+ async command bool IEEE154Packet.requiresAckReply(message_t* msg)
+ {
+ return call IEEE154Packet.getAckRequired(msg)
+ && call IEEE154Packet.isDataFrame(msg)
+ && call IEEE154Packet.getDestAddr(msg) == call ActiveMessageAddress.amAddress();
+ }
+
+ inline async event void ActiveMessageAddress.changed()
+ {
+ }
+
+/*----------------- AMPacket -----------------*/
+
+ inline command am_addr_t AMPacket.address()
+ {
+ return call ActiveMessageAddress.amAddress();
+ }
+
+ inline command am_group_t AMPacket.localGroup()
+ {
+ // TODO: check if this is correct
+ return call ActiveMessageAddress.amGroup();
+ }
+
+ inline command am_addr_t AMPacket.destination(message_t* msg)
+ {
+ return call IEEE154Packet.getDestAddr(msg);
+ }
+
+ inline command am_addr_t AMPacket.source(message_t* msg)
+ {
+ return call IEEE154Packet.getSrcAddr(msg);
+ }
+
+ inline command void AMPacket.setDestination(message_t* msg, am_addr_t addr)
+ {
+ call IEEE154Packet.setDestAddr(msg, addr);
+ }
+
+ inline command void AMPacket.setSource(message_t* msg, am_addr_t addr)
+ {
+ call IEEE154Packet.setSrcAddr(msg, addr);
+ }
+
+ inline command bool AMPacket.isForMe(message_t* msg)
+ {
+ am_addr_t addr = call AMPacket.destination(msg);
+ return addr == call AMPacket.address() || addr == AM_BROADCAST_ADDR;
+ }
+
+ inline command am_id_t AMPacket.type(message_t* msg)
+ {
+ return call IEEE154Packet.getType(msg);
+ }
+
+ inline command void AMPacket.setType(message_t* msg, am_id_t type)
+ {
+ call IEEE154Packet.setType(msg, type);
+ }
+
+ inline command am_group_t AMPacket.group(message_t* msg)
+ {
+ return call IEEE154Packet.getDestPan(msg);
+ }
+
+ inline command void AMPacket.setGroup(message_t* msg, am_group_t grp)
+ {
+ call IEEE154Packet.setDestPan(msg, grp);
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __NEIGHBORHOOD_H__
+#define __NEIGHBORHOOD_H__
+
+#ifndef NEIGHBORHOOD_SIZE
+#define NEIGHBORHOOD_SIZE 5
+#endif
+
+#endif//__NEIGHBORHOOD_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+/**
+ * Every component maintains its own neighborhood data. The Neighboorhood
+ * component maintains only the nodeids and ages of the neighbors, and
+ * evicts old entries from the table when necessary.
+ */
+interface Neighborhood
+{
+ /**
+ * Returns the index of the neighbor in the table. If the node was not
+ * found in the table, then the value NEIGHBORHOOD is returned,
+ * otherwise an index in the range [0, NEIGHBORHOOD-1] is returned.
+ */
+ tasklet_async command uint8_t getIndex(am_addr_t id);
+
+ /**
+ * Returns the age of the given entry. The age is incremented by one
+ * every time a new node is inserted into the neighborhood table that
+ * is not already at the very end. If the age would get too large to
+ * fit into a byte, then it is periodically reset to a smaller value.
+ */
+ tasklet_async command uint8_t getAge(uint8_t index);
+
+ /**
+ * Returns the node address for the given entry.
+ */
+ tasklet_async command am_addr_t getNode(uint8_t index);
+
+ /**
+ * Adds a new node into the neighborhood table. If this node was already
+ * in the table, then it is just brought to the front (its age is reset
+ * to zero). If the node was not in the table, then the oldest is evicted
+ * and its entry is replaced with this node. The index of the entry
+ * is returned in the range [0, NEIGHBORHOOD-1].
+ */
+ tasklet_async command uint8_t insertNode(am_addr_t id);
+
+ /**
+ * This event is fired when the oldest entry is replaced with a new
+ * node. The same interface is used by many users, so all of them
+ * will receive this event and can clear the corresponding entry.
+ * After this event is fired, all flags for this entry are cleared
+ * (see the NeighborhoodFlag interface)
+ */
+ tasklet_async event void evicted(uint8_t index);
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration NeighborhoodC
+{
+ provides interface Neighborhood;
+}
+
+implementation
+{
+ components NeighborhoodP, MainC;
+
+ Neighborhood = NeighborhoodP;
+ MainC.SoftwareInit -> NeighborhoodP;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+/**
+ * This interface provides one bit storage for each neighbor in a very
+ * fast and conveint way (without using shifts for example).
+ */
+interface NeighborhoodFlag
+{
+ /**
+ * Returns the value of the flag for the given index
+ */
+ tasklet_async command bool get(uint8_t index);
+
+ /**
+ * Sets the flag for the given index
+ */
+ tasklet_async command void set(uint8_t index);
+
+ /**
+ * Clears the flag for the given index. The flag is automatically
+ * cleared after the Neighborhood.evicted event is fired.
+ */
+ tasklet_async command void clear(uint8_t index);
+
+ /**
+ * Clears the flag for all indices
+ */
+ tasklet_async command void clearAll();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+generic configuration NeighborhoodFlagC()
+{
+ provides interface NeighborhoodFlag;
+}
+
+implementation
+{
+ components NeighborhoodP;
+
+ // TODO: make sure that no more than 8 flags are used at a time
+ NeighborhoodFlag = NeighborhoodP.NeighborhoodFlag[unique("NeighborhoodFlag")];
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Neighborhood.h>
+
+module NeighborhoodP
+{
+ provides
+ {
+ interface Init;
+ interface Neighborhood;
+ interface NeighborhoodFlag[uint8_t bit];
+ }
+}
+
+implementation
+{
+ tasklet_norace am_addr_t nodes[NEIGHBORHOOD_SIZE];
+ tasklet_norace uint8_t ages[NEIGHBORHOOD_SIZE];
+ tasklet_norace uint8_t flags[NEIGHBORHOOD_SIZE];
+ tasklet_norace uint8_t time;
+ tasklet_norace uint8_t last;
+
+ command error_t Init.init()
+ {
+ uint8_t i;
+
+ for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
+ nodes[i] = AM_BROADCAST_ADDR;
+
+ return SUCCESS;
+ }
+
+ inline tasklet_async command am_addr_t Neighborhood.getNode(uint8_t index)
+ {
+ return nodes[index];
+ }
+
+ inline tasklet_async command uint8_t Neighborhood.getAge(uint8_t index)
+ {
+ return time - ages[index];
+ }
+
+ tasklet_async uint8_t command Neighborhood.getIndex(am_addr_t node)
+ {
+ uint8_t i;
+
+ if( nodes[last] == node )
+ return last;
+
+ for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
+ {
+ if( nodes[i] == node )
+ {
+ last = i;
+ break;
+ }
+ }
+
+ return i;
+ }
+
+ tasklet_async uint8_t command Neighborhood.insertNode(am_addr_t node)
+ {
+ uint8_t i;
+ uint8_t maxAge;
+
+ if( nodes[last] == node )
+ {
+ if( ages[last] == time )
+ return last;
+
+ ages[last] = ++time;
+ maxAge = 0x80;
+ }
+ else
+ {
+ uint8_t oldest = 0;
+ maxAge = 0;
+
+ for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
+ {
+ uint8_t age;
+
+ if( nodes[i] == node )
+ {
+ last = i;
+ if( ages[i] == time )
+ return i;
+
+ ages[i] = ++time;
+ maxAge = 0x80;
+ break;
+ }
+
+ age = time - ages[i];
+ if( age > maxAge )
+ {
+ maxAge = age;
+ oldest = i;
+ }
+ }
+
+ if( i == NEIGHBORHOOD_SIZE )
+ {
+ signal Neighborhood.evicted(oldest);
+
+ last = oldest;
+ nodes[oldest] = node;
+ ages[oldest] = ++time;
+ flags[oldest] = 0;
+ }
+ }
+
+ if( (time & 0x7F) == 0x7F && maxAge >= 0x7F )
+ {
+ for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
+ {
+ if( (ages[i] | 0x7F) != time )
+ ages[i] = time & 0x80;
+ }
+ }
+
+ return last;
+ }
+
+ inline tasklet_async command bool NeighborhoodFlag.get[uint8_t bit](uint8_t index)
+ {
+ return flags[index] & (1 << bit);
+ }
+
+ inline tasklet_async command void NeighborhoodFlag.set[uint8_t bit](uint8_t index)
+ {
+ flags[index] |= (1 << bit);
+ }
+
+ inline tasklet_async command void NeighborhoodFlag.clear[uint8_t bit](uint8_t index)
+ {
+ flags[index] &= ~(1 << bit);
+ }
+
+ tasklet_async command void NeighborhoodFlag.clearAll[uint8_t bit]()
+ {
+ uint8_t i;
+
+ bit = ~(1 << bit);
+
+ for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
+ flags[i] &= bit;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+interface PacketField<value_type>
+{
+ /**
+ * Returns TRUE if the value is set for this message.
+ */
+ async command bool isSet(message_t* msg);
+
+ /**
+ * Returns the stored value of this field in the message. If the
+ * value is not set, then the returned value is undefined.
+ */
+ async command value_type get(message_t* msg);
+
+ /**
+ * Clears the isSet flag.
+ */
+ async command void clear(message_t* msg);
+
+ /**
+ * Sets the isSet false to TRUE and the time stamp value to the
+ * specified value.
+ */
+ async command void set(message_t* msg, value_type value);
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+interface RadioAlarm
+{
+ /**
+ * Returns TRUE if the alarm is free and ready to be used. Once the alarm
+ * is free, it cannot become nonfree in the same tasklet block. Note,
+ * if the alarm is currently set (even if for ourselves) then it is not free.
+ */
+ tasklet_async command bool isFree();
+
+ /**
+ * Waits till the specified timeout period expires. The alarm must be free.
+ */
+ tasklet_async command void wait(uint16_t timeout);
+
+ /**
+ * Cancels the running alarm. The alarm must be pending.
+ */
+ tasklet_async command void cancel();
+
+ /**
+ * This event is fired when the specified timeout period expires.
+ */
+ tasklet_async event void fired();
+
+ /**
+ * Returns the current time as measured by the radio stack.
+ */
+ async command uint16_t getNow();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+configuration RadioAlarmC
+{
+ provides
+ {
+ interface RadioAlarm[uint8_t id]; // use unique("RadioAlarm")
+ }
+
+ uses
+ {
+ interface Alarm<TRadio, uint16_t> @exactlyonce();
+ }
+}
+
+implementation
+{
+ components RadioAlarmP, TaskletC;
+
+ RadioAlarm = RadioAlarmP;
+ Alarm = RadioAlarmP;
+ RadioAlarmP.Tasklet -> TaskletC;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+#include <RadioAssert.h>
+
+module RadioAlarmP
+{
+ provides
+ {
+ interface RadioAlarm[uint8_t id];
+ }
+
+ uses
+ {
+ interface Alarm<TRadio, uint16_t>;
+ interface Tasklet;
+ }
+}
+
+implementation
+{
+ norace uint8_t state;
+ enum
+ {
+ STATE_READY = 0,
+ STATE_WAIT = 1,
+ STATE_FIRED = 2,
+ };
+
+ tasklet_norace uint8_t alarm;
+
+ async event void Alarm.fired()
+ {
+ atomic
+ {
+ if( state == STATE_WAIT )
+ state = STATE_FIRED;
+ }
+
+ call Tasklet.schedule();
+ }
+
+ inline async command uint16_t RadioAlarm.getNow[uint8_t id]()
+ {
+ return call Alarm.getNow();
+ }
+
+ tasklet_async event void Tasklet.run()
+ {
+ if( state == STATE_FIRED )
+ {
+ state = STATE_READY;
+ signal RadioAlarm.fired[alarm]();
+ }
+ }
+
+ default tasklet_async event void RadioAlarm.fired[uint8_t id]()
+ {
+ }
+
+ inline tasklet_async command bool RadioAlarm.isFree[uint8_t id]()
+ {
+ return state == STATE_READY;
+ }
+
+ tasklet_async command void RadioAlarm.wait[uint8_t id](uint16_t timeout)
+ {
+ ASSERT( state == STATE_READY );
+
+ alarm = id;
+ state = STATE_WAIT;
+ call Alarm.start(timeout);
+ }
+
+ tasklet_async command void RadioAlarm.cancel[uint8_t id]()
+ {
+ ASSERT( alarm == id );
+ ASSERT( state != STATE_READY );
+
+ call Alarm.stop();
+ state = STATE_READY;
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __RADIOASSERT_H__
+#define __RADIOASSERT_H__
+
+#ifdef RADIO_DEBUG
+
+ void assert(bool condition, const char* file, uint16_t line);
+ #define ASSERT(COND) assert(COND, __FILE__, __LINE__)
+
+#else
+
+ #define ASSERT(COND) for(;0;)
+
+#endif
+
+#endif//__RADIOASSERT_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+interface RadioCCA
+{
+ /**
+ * Starts the clear channel assesment procedure. Returns EBUSY if the radio
+ * is currently servicing a clear channel assesment, and SUCCESS otherwise.
+ * The check will be performed only in the RX_READY state.
+ */
+ tasklet_async command error_t request();
+
+ /**
+ * Signals the completion of the clear channel assesment send command.
+ * SUCCESS means the channel is clear, EBUSY means the channel is not
+ * clear, and FAIL means that the clear channel assesment could not
+ * be finished or the operation was cancelled.
+ */
+ tasklet_async event void done(error_t error);
+}
--- /dev/null
+/*
+ * Copyright (c) 2009, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+interface RadioChannel
+{
+ /**
+ * Sets the current channel. Returns EBUSY if the stack is unable
+ * to change the channel this time (some other operation is in progress),
+ * EALREADY if the selected channel is already set, SUCCESS otherwise.
+ */
+ command error_t setChannel(uint8_t channel);
+
+ /**
+ * This event is signaled exactly once for each sucessfully posted state
+ * setChannel command when it is completed.
+ */
+ event void setChannelDone();
+
+ /**
+ * Returns the currently selected channel.
+ */
+ command uint8_t getChannel();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+interface RadioReceive
+{
+ /**
+ * This event is fired when the header is received/downloaded and the
+ * higher layers are consulted whether it needs to be downloaded and
+ * further processed. Return FALSE if the message should be discarded.
+ * In particular, the message buffer layer returns FALSE if there is
+ * no space for a new message, so this message will not get acknowledged.
+ */
+ tasklet_async event bool header(message_t* msg);
+
+ /**
+ * Signals the reception of a message, but only for those messages for
+ * which SUCCESS was returned in the header event. The usual owner rules
+ * apply to the message pointers.
+ */
+ tasklet_async event message_t* receive(message_t* msg);
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+interface RadioSend
+{
+ /**
+ * Starts the transmission of the given message. This command must not
+ * be called while another send is in progress (so one must wait for the
+ * sendDone event). Returns EBUSY if a reception is in progress or for
+ * some other reason the request cannot be temporarily satisfied (e.g.
+ * the SPI bus access could not be acquired). In this case the send
+ * command could be retried from a tasklet. Returns SUCCESS if the
+ * transmission could be started. In this case sendDone will be fired.
+ */
+ tasklet_async command error_t send(message_t* msg);
+
+ /**
+ * Signals the completion of the send command, exactly once for each
+ * successfull send command. If the returned error code is SUCCESS, then
+ * the message was sent (may not have been acknowledged), otherwise
+ * the message was not transmitted over the air.
+ */
+ tasklet_async event void sendDone(error_t error);
+
+ /**
+ * This event is fired when the component is most likely able to accept
+ * a send request. If the send command has returned with a failure, then
+ * this event will be called at least once in the near future.
+ */
+ tasklet_async event void ready();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+interface RadioState
+{
+ /**
+ * Moves to radio into sleep state with the lowest power consumption but
+ * highest wakeup time. The radio cannot send or receive in this state
+ * and releases all access to shared resources (e.g. SPI bus).
+ */
+ tasklet_async command error_t turnOff();
+
+ /**
+ * The same as the turnOff command, except it is not as deep sleep, and
+ * it is quicker to recover from this state.
+ */
+ tasklet_async command error_t standby();
+
+ /**
+ * Goes into receive state. The radio continuously receive messages
+ * and able to transmit.
+ */
+ tasklet_async command error_t turnOn();
+
+ /**
+ * Sets the current channel. Returns EBUSY if the stack is unable
+ * to change the channel this time (some other operation is in progress)
+ * SUCCESS otherwise.
+ */
+ tasklet_async command error_t setChannel(uint8_t channel);
+
+ /**
+ * This event is signaled exactly once for each sucessfully posted state
+ * transition and setChannel command when it is completed.
+ */
+ tasklet_async event void done();
+
+ /**
+ * Returns the currently selected channel.
+ */
+ tasklet_async command uint8_t getChannel();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __TASKLET_H__
+#define __TASKLET_H__
+
+#ifdef TASKLET_IS_TASK
+
+ #define tasklet_async
+ #define tasklet_norace
+
+#else
+
+ #define tasklet_async async
+ #define tasklet_norace norace
+
+#endif
+
+#endif//__TASKLET_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+
+/**
+ * This interface is useful in building state machines when the state
+ * transitions should be executed atomically but with interrupts enabled.
+ * All state transitions should take place in the run event handler or
+ * in blocks protected by the suspend and resume commands.
+ */
+interface Tasklet
+{
+ /**
+ * This method is executed atomically.
+ */
+ tasklet_async event void run();
+
+ /**
+ * Makes sure that the run event is called at least once more. If the
+ * run event is currently not executing, then it is called immediately
+ * and this command returns only after the completion of the run event.
+ * If the run event is currently executed, then this method returns at
+ * once, and makes sure that the run event is called once more when
+ * it is finished. If this method is called from a task, then by the
+ * above rules, the run event will be called from a task as well.
+ */
+ async command void schedule();
+
+ /**
+ * Enters a critical section of the code and meakes sure that the
+ * run event is not called while in this section. No long running
+ * computation should be called from the critical session, and
+ * in particular no user event should be fired. This call is only
+ * possible from task context, otherwise we cannot guarantee that
+ * the run event is not currently running. The suspend calls
+ * can be nested. It is very important that the same number of
+ * resume commands must be called in all control paths, e.g. be very
+ * careful with the return and break commands.
+ */
+ command void suspend();
+
+ /**
+ * Leaves the critical section. This call is conly possible from
+ * task context. If there were scheduled executions of the run
+ * event, then those will be called before this command returns.
+ */
+ command void resume();
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <Tasklet.h>
+#include <RadioAssert.h>
+
+module TaskletC
+{
+ provides interface Tasklet;
+}
+
+implementation
+{
+#ifdef TASKLET_IS_TASK
+
+ task void tasklet()
+ {
+ signal Tasklet.run();
+ }
+
+ inline async command void Tasklet.schedule()
+ {
+ post tasklet();
+ }
+
+ inline command void Tasklet.suspend()
+ {
+ }
+
+ inline command void Tasklet.resume()
+ {
+ }
+
+#else
+
+ /**
+ * The lower 7 bits contain the number of suspends plus one if the run
+ * event is currently beeing executed. The highest bit is set if the run
+ * event needs to be called again when the suspend count goes down to zero.
+ */
+ uint8_t state;
+
+ void doit()
+ {
+ for(;;)
+ {
+ signal Tasklet.run();
+
+ atomic
+ {
+ if( state == 1 )
+ {
+ state = 0;
+ return;
+ }
+
+ ASSERT( state == 0x81 );
+ state = 1;
+ }
+ }
+ }
+
+ inline command void Tasklet.suspend()
+ {
+ atomic ++state;
+ }
+
+ command void Tasklet.resume()
+ {
+ atomic
+ {
+ if( --state != 0x80 )
+ return;
+
+ state = 1;
+ }
+
+ doit();
+ }
+
+ async command void Tasklet.schedule()
+ {
+ atomic
+ {
+ if( state != 0 )
+ {
+ state |= 0x80;
+ return;
+ }
+
+ state = 1;
+ }
+
+ doit();
+ }
+
+#endif
+}
%T/platforms/micaz
%T/platforms/mica
%T/platforms/iris/chips/rf230
- %T/chips/rf230
- %T/chips/cc2420
+ %T/chips/rf2xx/rf230
+ %T/chips/rf2xx/layers
+ %T/chips/rf2xx/util
%T/platforms/iris/chips/at45db
%T/platforms/mica2/chips/at45db
%T/platforms/mica/chips/at45db
implementation
{
- components RF2xxActiveMessageC as MAC;
+ components RF230ActiveMessageC as MAC;
SplitControl = MAC;
AMSend = MAC;
AMPacket = MAC;
PacketAcknowledgements = MAC;
- LowPowerListening = MAC;
+ LowPowerListening = MAC;
PacketTimeStampMilli = MAC;
PacketTimeStampMicro = MAC;
}
* Author: Miklos Maroti
*/
-#include <RadioAlarm.h>
+#include <RadioConfig.h>
configuration TimeSyncMessageC
{
implementation
{
- components RF2xxTimeSyncMessageC;
+ components GenericTimeSyncMessageC as MAC, LocalTimeMicroC, RF230PacketC;
- SplitControl = RF2xxTimeSyncMessageC;
-
- Receive = RF2xxTimeSyncMessageC.Receive;
- Snoop = RF2xxTimeSyncMessageC.Snoop;
- Packet = RF2xxTimeSyncMessageC;
- AMPacket = RF2xxTimeSyncMessageC;
-
- TimeSyncAMSendRadio = RF2xxTimeSyncMessageC;
- TimeSyncPacketRadio = RF2xxTimeSyncMessageC;
- TimeSyncAMSendMilli = RF2xxTimeSyncMessageC;
- TimeSyncPacketMilli = RF2xxTimeSyncMessageC;
+ SplitControl = MAC;
+ Receive = MAC.Receive;
+ Snoop = MAC.Snoop;
+ Packet = MAC;
+ AMPacket = MAC;
+
+ TimeSyncAMSendRadio = MAC;
+ TimeSyncPacketRadio = MAC;
+ TimeSyncAMSendMilli = MAC;
+ TimeSyncPacketMilli = MAC;
+
+ MAC.PacketTimeSyncOffset -> RF230PacketC.PacketTimeSyncOffset;
+ MAC.LocalTimeRadio -> LocalTimeMicroC;
}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#include <RadioConfig.h>
+
+configuration HplRF230C
+{
+ provides
+ {
+ interface GeneralIO as SELN;
+ interface Resource as SpiResource;
+ interface FastSpiByte;
+
+ interface GeneralIO as SLP_TR;
+ interface GeneralIO as RSTN;
+
+ interface GpioCapture as IRQ;
+ interface Alarm<TRadio, uint16_t> as Alarm;
+ }
+}
+
+implementation
+{
+ components HplRF230P;
+ IRQ = HplRF230P.IRQ;
+
+ HplRF230P.PortCLKM -> IO.PortD6;
+ HplRF230P.PortIRQ -> IO.PortD4;
+
+ components Atm128SpiC as SpiC;
+ SpiResource = SpiC.Resource[unique("Atm128SpiC.Resource")];
+ FastSpiByte = SpiC;
+
+ components HplAtm128GeneralIOC as IO;
+ SLP_TR = IO.PortB7;
+ RSTN = IO.PortA6;
+ SELN = IO.PortB0;
+
+ components HplAtm128Timer1C as TimerC;
+ HplRF230P.Capture -> TimerC.Capture;
+
+ components new AlarmOne16C() as AlarmC;
+ Alarm = AlarmC;
+
+ components RealMainP;
+ RealMainP.PlatformInit -> HplRF230P.PlatformInit;
+}
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+module HplRF230P
+{
+ provides
+ {
+ interface GpioCapture as IRQ;
+ interface Init as PlatformInit;
+ }
+
+ uses
+ {
+ interface HplAtm128Capture<uint16_t> as Capture;
+ interface GeneralIO as PortCLKM;
+ interface GeneralIO as PortIRQ;
+ }
+}
+
+implementation
+{
+ command error_t PlatformInit.init()
+ {
+ call PortCLKM.makeInput();
+ call PortCLKM.clr();
+ call PortIRQ.makeInput();
+ call PortIRQ.clr();
+ call Capture.stop();
+
+ return SUCCESS;
+ }
+
+ async event void Capture.captured(uint16_t time)
+ {
+ time = call Capture.get(); // TODO: ask Cory why time is not the captured time
+ signal IRQ.captured(time);
+ }
+
+ default async event void IRQ.captured(uint16_t time)
+ {
+ }
+
+ async command error_t IRQ.captureRisingEdge()
+ {
+ call Capture.setEdge(TRUE);
+ call Capture.reset();
+ call Capture.start();
+
+ return SUCCESS;
+ }
+
+ async command error_t IRQ.captureFallingEdge()
+ {
+ // falling edge comes when the IRQ_STATUS register of the RF230 is read
+ return FAIL;
+ }
+
+ async command void IRQ.disable()
+ {
+ call Capture.stop();
+ }
+}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __HPLRF2XX_H__
-#define __HPLRF2XX_H__
-
-#include <RF2xx.h>
-#include <util/crc16.h>
-
-enum
-{
- /**
- * This is the value of the TRX_CTRL_0 register
- * which configures the output pin currents and the CLKM clock
- */
- RF2XX_TRX_CTRL_0_VALUE = 0,
-
- /**
- * This is the default value of the CCA_MODE field in the PHY_CC_CCA register
- * which is used to configure the default mode of the clear channel assesment
- */
- RF2XX_CCA_MODE_VALUE = RF2XX_CCA_MODE_3,
-
- /**
- * This is the value of the CCA_THRES register that controls the
- * energy levels used for clear channel assesment
- */
- RF2XX_CCA_THRES_VALUE = 0xC7,
-};
-
-/* This is the default value of the TX_PWR field of the PHY_TX_PWR register. */
-#ifndef RF230_DEF_RFPOWER
-#define RF230_DEF_RFPOWER 0
-#endif
-
-#define RF2XX_DEF_RFPOWER RF230_DEF_RFPOWER
-
-/* This is the default value of the CHANNEL field of the PHY_CC_CCA register. */
-#ifndef RF230_DEF_CHANNEL
-#define RF230_DEF_CHANNEL 11
-#endif
-
-#define RF2XX_DEF_CHANNEL RF230_DEF_CHANNEL
-
-#define RF2XX_CHIPSET RF230_CHIPSET
-
-/*
- * This is the command used to calculate the CRC for the RF230 chip.
- * TODO: Check why the default crcByte implementation is in a different endianness
- */
-inline uint16_t RF2XX_CRCBYTE_COMMAND(uint16_t crc, uint8_t data)
-{
- return _crc_ccitt_update(crc, data);
-}
-
-#endif//__HPLRF2XX_H__
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include <RadioAlarm.h>
-
-configuration HplRF2xxC
-{
- provides
- {
- interface GeneralIO as SELN;
- interface Resource as SpiResource;
- interface FastSpiByte;
-
- interface GeneralIO as SLP_TR;
- interface GeneralIO as RSTN;
-
- interface GpioCapture as IRQ;
- interface Alarm<TRadio, uint16_t> as Alarm;
- }
-}
-
-implementation
-{
- components HplRF2xxP;
- IRQ = HplRF2xxP.IRQ;
-
- HplRF2xxP.PortCLKM -> IO.PortD6;
- HplRF2xxP.PortIRQ -> IO.PortD4;
-
- components Atm128SpiC as SpiC;
- SpiResource = SpiC.Resource[unique("Atm128SpiC.Resource")];
- FastSpiByte = SpiC;
-
- components HplAtm128GeneralIOC as IO;
- SLP_TR = IO.PortB7;
- RSTN = IO.PortA6;
- SELN = IO.PortB0;
-
- components HplAtm128Timer1C as TimerC;
- HplRF2xxP.Capture -> TimerC.Capture;
-
- components new AlarmOne16C() as AlarmC;
- Alarm = AlarmC;
-
- components RealMainP;
- RealMainP.PlatformInit -> HplRF2xxP.PlatformInit;
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#include "Atm128Spi.h"
-
-module HplRF2xxP
-{
- provides
- {
- interface GpioCapture as IRQ;
- interface Init as PlatformInit;
- }
-
- uses
- {
- interface HplAtm128Capture<uint16_t> as Capture;
- interface GeneralIO as PortCLKM;
- interface GeneralIO as PortIRQ;
- }
-}
-
-implementation
-{
- command error_t PlatformInit.init()
- {
- call PortCLKM.makeInput();
- call PortCLKM.clr();
- call PortIRQ.makeInput();
- call PortIRQ.clr();
- call Capture.stop();
-
- return SUCCESS;
- }
-
- async event void Capture.captured(uint16_t time)
- {
- time = call Capture.get(); // TODO: ask Cory why time is not the captured time
- signal IRQ.captured(time);
- }
-
- default async event void IRQ.captured(uint16_t time)
- {
- }
-
- async command error_t IRQ.captureRisingEdge()
- {
- call Capture.setEdge(TRUE);
- call Capture.reset();
- call Capture.start();
-
- return SUCCESS;
- }
-
- async command error_t IRQ.captureFallingEdge()
- {
- // falling edge comes when the IRQ_STATUS register of the RF230 is read
- return FAIL;
- }
-
- async command void IRQ.disable()
- {
- call Capture.stop();
- }
-}
+++ /dev/null
-/*
- * Copyright (c) 2007, Vanderbilt University
- * All rights reserved.
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose, without fee, and without written agreement is
- * hereby granted, provided that the above copyright notice, the following
- * two paragraphs and the author appear in all copies of this software.
- *
- * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
- * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
- * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Author: Miklos Maroti
- */
-
-#ifndef __RADIOALARM_H__
-#define __RADIOALARM_H__
-
-#include <MicaTimer.h>
-
-/**
- * This is the timer type of the radio alarm interface
- */
-typedef TOne TRadio;
-
-/**
- * The number of radio alarm ticks per one microsecond (0.9216).
- * We use integers and no parentheses just to make deputy happy.
- */
-#define RADIO_ALARM_MICROSEC (7372800UL / MHZ / 32) * (1 << MICA_DIVIDE_ONE_FOR_32KHZ_LOG2) / 1000000UL
-
-#endif//__RADIOALARM_H__
--- /dev/null
+/*
+ * Copyright (c) 2007, Vanderbilt University
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose, without fee, and without written agreement is
+ * hereby granted, provided that the above copyright notice, the following
+ * two paragraphs and the author appear in all copies of this software.
+ *
+ * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
+ * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Author: Miklos Maroti
+ */
+
+#ifndef __RADIOCONFIG_H__
+#define __RADIOCONFIG_H__
+
+#include <MicaTimer.h>
+#include <RF230.h>
+#include <util/crc16.h>
+
+enum
+{
+ /**
+ * This is the value of the TRX_CTRL_0 register
+ * which configures the output pin currents and the CLKM clock
+ */
+ RF230_TRX_CTRL_0_VALUE = 0,
+
+ /**
+ * This is the default value of the CCA_MODE field in the PHY_CC_CCA register
+ * which is used to configure the default mode of the clear channel assesment
+ */
+ RF230_CCA_MODE_VALUE = RF230_CCA_MODE_3,
+
+ /**
+ * This is the value of the CCA_THRES register that controls the
+ * energy levels used for clear channel assesment
+ */
+ RF230_CCA_THRES_VALUE = 0xC7,
+};
+
+/* This is the default value of the TX_PWR field of the PHY_TX_PWR register. */
+#ifndef RF230_DEF_RFPOWER
+#define RF230_DEF_RFPOWER 0
+#endif
+
+/* This is the default value of the CHANNEL field of the PHY_CC_CCA register. */
+#ifndef RF230_DEF_CHANNEL
+#define RF230_DEF_CHANNEL 11
+#endif
+
+/*
+ * This is the command used to calculate the CRC for the RF230 chip.
+ * TODO: Check why the default crcByte implementation is in a different endianness
+ */
+inline uint16_t RF230_CRCBYTE_COMMAND(uint16_t crc, uint8_t data)
+{
+ return _crc_ccitt_update(crc, data);
+}
+
+/**
+ * This is the timer type of the radio alarm interface
+ */
+typedef TOne TRadio;
+
+/**
+ * The number of radio alarm ticks per one microsecond (0.9216).
+ * We use integers and no parentheses just to make deputy happy.
+ */
+#define RADIO_ALARM_MICROSEC (7372800UL / MHZ / 32) * (1 << MICA_DIVIDE_ONE_FOR_32KHZ_LOG2) / 1000000UL
+
+/**
+ * The base two logarithm of the number of radio alarm ticks per one millisecond
+ */
+#define RADIO_ALARM_MILLI_EXP 10
+
+#endif//__RADIOCONFIG_H__
#ifndef PLATFORM_MESSAGE_H
#define PLATFORM_MESSAGE_H
-#include <RF2xxPacket.h>
+#include <RF230Packet.h>
#include <Serial.h>
typedef union message_header {
- rf2xxpacket_header_t rf2xx;
+ rf230packet_header_t rf230;
serial_header_t serial;
} message_header_t;
typedef union message_footer {
- rf2xxpacket_footer_t rf2xx;
+ rf230packet_footer_t rf230;
} message_footer_t;
typedef union message_metadata {
- rf2xxpacket_metadata_t rf2xx;
+ rf230packet_metadata_t rf230;
} message_metadata_t;
#endif