[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/cc2420 CC2420AckLpl.h,
NONE, 1.1 CC2420AckLplC.nc, NONE, 1.1 CC2420AckLplP.nc, NONE,
1.1 CC2420Cca.nc, NONE, 1.1 CC2420DutyCycle.nc, NONE,
1.1 CC2420DutyCycleC.nc, NONE, 1.1 CC2420DutyCycleP.nc, NONE,
1.1 CC2420LplDummyC.nc, NONE, 1.1 CC2420LplDummyP.nc, NONE,
1.1 CC2420NoAckLpl.h, NONE, 1.1 CC2420NoAckLplC.nc, NONE,
1.1 CC2420NoAckLplP.nc, NONE, 1.1 CC2420TinyosNetworkC.nc,
NONE, 1.1 CC2420TinyosNetworkP.nc, NONE, 1.1 PacketLink.nc,
NONE, 1.1 PacketLinkC.nc, NONE, 1.1 PacketLinkDummyC.nc, NONE,
1.1 PacketLinkDummyP.nc, NONE, 1.1 PacketLinkP.nc, NONE,
1.1 README.txt, NONE, 1.1 RadioBackoff.nc, NONE,
1.1 UniqueReceiveC.nc, NONE, 1.1 UniqueReceiveP.nc, NONE,
1.1 UniqueSendC.nc, NONE, 1.1 UniqueSendP.nc, NONE,
1.1 AlarmMultiplexC.nc, 1.4, 1.5 CC2420.h, 1.4,
1.5 CC2420ActiveMessageC.nc, 1.4, 1.5 CC2420ActiveMessageP.nc,
1.4, 1.5 CC2420Config.nc, 1.4, 1.5 CC2420ControlC.nc, 1.5,
1.6 CC2420ControlP.nc, 1.6, 1.7 CC2420CsmaC.nc, 1.4,
1.5 CC2420CsmaP.nc, 1.4, 1.5 CC2420Fifo.nc, 1.4,
1.5 CC2420Packet.nc, 1.5, 1.6 CC2420PacketC.nc, 1.5,
1.6 CC2420Power.nc, 1.4, 1.5 CC2420Ram.nc, 1.4,
1.5 CC2420Receive.nc, 1.4, 1.5 CC2420ReceiveC.nc, 1.4,
1.5 CC2420ReceiveP.nc, 1.4, 1.5 CC2420Register.nc, 1.4,
1.5 CC2420SpiC.nc, 1.5, 1.6 CC2420SpiImplP.nc, 1.4,
1.5 CC2420SpiP.nc, 1.4, 1.5 CC2420Strobe.nc, 1.4,
1.5 CC2420Transmit.nc, 1.4, 1.5 CC2420TransmitC.nc, 1.4,
1.5 CC2420TransmitP.nc, 1.4, 1.5 IEEE802154.h, 1.4, 1.5
dmm
rincon at users.sourceforge.net
Thu Apr 12 10:11:20 PDT 2007
Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/cc2420
In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv18491
Modified Files:
AlarmMultiplexC.nc CC2420.h CC2420ActiveMessageC.nc
CC2420ActiveMessageP.nc CC2420Config.nc CC2420ControlC.nc
CC2420ControlP.nc CC2420CsmaC.nc CC2420CsmaP.nc CC2420Fifo.nc
CC2420Packet.nc CC2420PacketC.nc CC2420Power.nc CC2420Ram.nc
CC2420Receive.nc CC2420ReceiveC.nc CC2420ReceiveP.nc
CC2420Register.nc CC2420SpiC.nc CC2420SpiImplP.nc
CC2420SpiP.nc CC2420Strobe.nc CC2420Transmit.nc
CC2420TransmitC.nc CC2420TransmitP.nc IEEE802154.h
Added Files:
CC2420AckLpl.h CC2420AckLplC.nc CC2420AckLplP.nc CC2420Cca.nc
CC2420DutyCycle.nc CC2420DutyCycleC.nc CC2420DutyCycleP.nc
CC2420LplDummyC.nc CC2420LplDummyP.nc CC2420NoAckLpl.h
CC2420NoAckLplC.nc CC2420NoAckLplP.nc CC2420TinyosNetworkC.nc
CC2420TinyosNetworkP.nc PacketLink.nc PacketLinkC.nc
PacketLinkDummyC.nc PacketLinkDummyP.nc PacketLinkP.nc
README.txt RadioBackoff.nc UniqueReceiveC.nc UniqueReceiveP.nc
UniqueSendC.nc UniqueSendP.nc
Log Message:
Update of the default CC2420 to the low power listening stack. The "acknowledgement" LPL version is the default, while the continuous-modulation "no-acknowledgement" LPL layer is still considered experimental. RSSI can be directly read from the radio through CC2420ConrolC.
--- NEW FILE: CC2420AckLpl.h ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* @author David Moss
*/
#ifndef CC2420ACKLPL_H
#define CC2420ACKLPL_H
/**
* Low Power Listening Send States
*/
typedef enum {
S_LPL_NOT_SENDING, // DEFAULT
S_LPL_FIRST_MESSAGE, // 1. Sending the first message
S_LPL_SENDING, // 2. Sending all other messages
S_LPL_CLEAN_UP, // 3. Clean up the transmission
} lpl_sendstate_t;
/**
* Amount of time, in milliseconds, to keep the radio on after
* a successful receive addressed to this node
* You don't want this too fast, or the off timer can accidentally
* fire due to delays in the system. The radio would shut off and
* possibly need to turn back on again immediately, which can lock up
* the CC2420 if it's in the middle of doing something.
*/
#ifndef DELAY_AFTER_RECEIVE
#define DELAY_AFTER_RECEIVE 100
#endif
/**
* This is a measured value of the time in ms the radio is actually on
* We round this up to err on the side of better performance ratios
*/
#ifndef DUTY_ON_TIME
#define DUTY_ON_TIME 5
#endif
/**
* The maximum number of CCA checks performed on each wakeup.
* If there are too few, the receiver may wake up between messages
* and not detect the transmitter.
*
* The on-time had to increase from the original version to allow multiple
* transmitters to co-exist. This is due to using ack's, which then requires us
* to extend the backoff period. In networks that transmit frequently, possibly
* with multiple transmitters, this power scheme makes sense.
*
* In networks that transmit very infrequently or without multiple transmitters,
* it makes more sense to go with no acks and no backoffs and make the
* receive check as short as possible.
*/
#ifndef MAX_LPL_CCA_CHECKS
#if defined(PLATFORM_TELOSB) || defined(PLATFORM_TMOTE)
#define MAX_LPL_CCA_CHECKS 500
#else
#define MAX_LPL_CCA_CHECKS 400
#endif
#endif
/**
* The minimum number of samples that must be taken in CC2420DutyCycleP
* that show the channel is not clear before a detection event is issued
*/
#ifndef MIN_SAMPLES_BEFORE_DETECT
#define MIN_SAMPLES_BEFORE_DETECT 3
#endif
#endif
--- NEW FILE: CC2420AckLplC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Low Power Listening for the CC2420
* @author David Moss
*/
#include "CC2420AckLpl.h"
#warning "*** USING ACK LOW POWER LISTENING LAYER"
configuration CC2420AckLplC {
provides {
interface LowPowerListening;
interface Send;
interface Receive;
interface SplitControl;
interface State as SendState;
}
uses {
interface Send as SubSend;
interface Receive as SubReceive;
interface SplitControl as SubControl;
}
}
implementation {
components MainC,
CC2420AckLplP,
CC2420DutyCycleC,
CC2420ActiveMessageC,
CC2420CsmaC,
CC2420TransmitC,
CC2420PacketC,
RandomC,
LedsC,
new StateC() as SendStateC,
new StateC() as RadioStateC,
new TimerMilliC() as OffTimerC,
new TimerMilliC() as SendDoneTimerC;
LowPowerListening = CC2420AckLplP;
Send = CC2420AckLplP;
Receive = CC2420AckLplP;
SplitControl = CC2420DutyCycleC;
SendState = SendStateC;
SubControl = CC2420AckLplP.SubControl;
SubReceive = CC2420AckLplP.SubReceive;
SubSend = CC2420AckLplP.SubSend;
MainC.SoftwareInit -> CC2420AckLplP;
CC2420AckLplP.Random -> RandomC;
CC2420AckLplP.SendState -> SendStateC;
CC2420AckLplP.RadioState -> RadioStateC;
CC2420AckLplP.SplitControlState -> CC2420DutyCycleC;
CC2420AckLplP.OffTimer -> OffTimerC;
CC2420AckLplP.SendDoneTimer -> SendDoneTimerC;
CC2420AckLplP.CC2420DutyCycle -> CC2420DutyCycleC;
CC2420AckLplP.Resend -> CC2420TransmitC;
CC2420AckLplP.PacketAcknowledgements -> CC2420ActiveMessageC;
CC2420AckLplP.AMPacket -> CC2420ActiveMessageC;
CC2420AckLplP.CC2420Packet -> CC2420PacketC;
CC2420AckLplP.Leds -> LedsC;
}
--- NEW FILE: CC2420AckLplP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Low Power Listening for the CC2420. This component is responsible for
* delivery of an LPL packet, and for turning off the radio when the radio
* has run out of tasks.
*
* The CC2420DutyCycle component is responsible for duty cycling the radio
* and performing receive detections.
*
* @author David Moss
*/
#include "CC2420AckLpl.h"
module CC2420AckLplP {
provides {
interface Init;
interface LowPowerListening;
interface Send;
interface Receive;
}
uses {
interface Send as SubSend;
interface CC2420Transmit as Resend;
interface Receive as SubReceive;
interface AMPacket;
interface SplitControl as SubControl;
interface CC2420DutyCycle;
interface CC2420Packet;
interface PacketAcknowledgements;
interface State as SendState;
interface State as RadioState;
interface State as SplitControlState;
interface Random;
interface Timer<TMilli> as OffTimer;
interface Timer<TMilli> as SendDoneTimer;
interface Leds;
}
}
implementation {
/** The message currently being sent */
message_t *currentSendMsg;
/** The length of the current send message */
uint8_t currentSendLen;
/** TRUE if the radio is duty cycling and not always on */
bool dutyCycling;
/**
* Radio State
*/
enum {
S_OFF,
S_ON,
};
/**
* Send States
*/
enum {
S_IDLE,
S_SENDING,
};
enum {
ONE_MESSAGE = 0,
};
/***************** Prototypes ***************/
task void send();
task void resend();
task void startRadio();
task void stopRadio();
void initializeSend();
void startOffTimer();
uint16_t getActualDutyCycle(uint16_t dutyCycle);
/***************** Init Commands ***************/
command error_t Init.init() {
dutyCycling = FALSE;
return SUCCESS;
}
/***************** LowPowerListening Commands ***************/
/**
* Set this this node's radio sleep interval, in milliseconds.
* Once every interval, the node will sleep and perform an Rx check
* on the radio. Setting the sleep interval to 0 will keep the radio
* always on.
*
* This is the equivalent of setting the local duty cycle rate.
*
* @param sleepIntervalMs the length of this node's Rx check interval, in [ms]
*/
command void LowPowerListening.setLocalSleepInterval(
uint16_t sleepIntervalMs) {
call CC2420DutyCycle.setSleepInterval(sleepIntervalMs);
}
/**
* @return the local node's sleep interval, in [ms]
*/
command uint16_t LowPowerListening.getLocalSleepInterval() {
return call CC2420DutyCycle.getSleepInterval();
}
/**
* Set this node's radio duty cycle rate, in units of [percentage*100].
* For example, to get a 0.05% duty cycle,
* <code>
* call LowPowerListening.setDutyCycle(5);
* </code>
*
* For a 100% duty cycle (always on),
* <code>
* call LowPowerListening.setDutyCycle(10000);
* </code>
*
* This is the equivalent of setting the local sleep interval explicitly.
*
* @param dutyCycle The duty cycle percentage, in units of [percentage*100]
*/
command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) {
call CC2420DutyCycle.setSleepInterval(
call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
}
/**
* @return this node's radio duty cycle rate, in units of [percentage*100]
*/
command uint16_t LowPowerListening.getLocalDutyCycle() {
return call LowPowerListening.sleepIntervalToDutyCycle(
call CC2420DutyCycle.getSleepInterval());
}
/**
* Configure this outgoing message so it can be transmitted to a neighbor mote
* with the specified Rx sleep interval.
* @param msg Pointer to the message that will be sent
* @param sleepInterval The receiving node's sleep interval, in [ms]
*/
command void LowPowerListening.setRxSleepInterval(message_t *msg,
uint16_t sleepIntervalMs) {
(call CC2420Packet.getMetadata(msg))->rxInterval = sleepIntervalMs;
}
/**
* @return the destination node's sleep interval configured in this message
*/
command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) {
return (call CC2420Packet.getMetadata(msg))->rxInterval;
}
/**
* Configure this outgoing message so it can be transmitted to a neighbor mote
* with the specified Rx duty cycle rate.
* Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25.
*
* @param msg Pointer to the message that will be sent
* @param dutyCycle The duty cycle of the receiving mote, in units of
* [percentage*100]
*/
command void LowPowerListening.setRxDutyCycle(message_t *msg,
uint16_t dutyCycle) {
(call CC2420Packet.getMetadata(msg))->rxInterval =
call LowPowerListening.dutyCycleToSleepInterval(dutyCycle);
}
/**
* @return the destination node's duty cycle configured in this message
* in units of [percentage*100]
*/
command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) {
return call LowPowerListening.sleepIntervalToDutyCycle(
(call CC2420Packet.getMetadata(msg))->rxInterval);
}
/**
* Convert a duty cycle, in units of [percentage*100], to
* the sleep interval of the mote in milliseconds
* @param dutyCycle The duty cycle in units of [percentage*100]
* @return The equivalent sleep interval, in units of [ms]
*/
command uint16_t LowPowerListening.dutyCycleToSleepInterval(
uint16_t dutyCycle) {
dutyCycle = getActualDutyCycle(dutyCycle);
if(dutyCycle == 10000) {
return 0;
}
return (DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle;
}
/**
* Convert a sleep interval, in units of [ms], to a duty cycle
* in units of [percentage*100]
* @param sleepInterval The sleep interval in units of [ms]
* @return The duty cycle in units of [percentage*100]
*/
command uint16_t LowPowerListening.sleepIntervalToDutyCycle(
uint16_t sleepInterval) {
if(sleepInterval == 0) {
return 10000;
}
return getActualDutyCycle((DUTY_ON_TIME * 10000)
/ (sleepInterval + DUTY_ON_TIME));
}
/***************** Send Commands ***************/
/**
* Each call to this send command gives the message a single
* DSN that does not change for every copy of the message
* sent out. For messages that are not acknowledged, such as
* a broadcast address message, the receiving end does not
* signal receive() more than once for that message.
*/
command error_t Send.send(message_t *msg, uint8_t len) {
if(call SplitControlState.getState() == S_OFF) {
// Everything is off right now, start SplitControl and try again
return EOFF;
}
if(call SendState.requestState(S_LPL_SENDING) == SUCCESS) {
currentSendMsg = msg;
currentSendLen = len;
// In case our off timer is running...
call OffTimer.stop();
call SendDoneTimer.stop();
if(call RadioState.getState() == S_ON) {
initializeSend();
return SUCCESS;
} else {
post startRadio();
}
return SUCCESS;
}
return FAIL;
}
command error_t Send.cancel(message_t *msg) {
if(currentSendMsg == msg) {
call SendState.toIdle();
call SendDoneTimer.stop();
startOffTimer();
return call SubSend.cancel(msg);
}
return FAIL;
}
command uint8_t Send.maxPayloadLength() {
return call SubSend.maxPayloadLength();
}
command void *Send.getPayload(message_t* msg) {
return call SubSend.getPayload(msg);
}
/***************** Receive Commands ***************/
command void *Receive.getPayload(message_t* msg, uint8_t* len) {
return call SubReceive.getPayload(msg, len);
}
command uint8_t Receive.payloadLength(message_t* msg) {
return call SubReceive.payloadLength(msg);
}
/***************** DutyCycle Events ***************/
/**
* A transmitter was detected. You must now take action to
* turn the radio off when the transaction is complete.
*/
event void CC2420DutyCycle.detected() {
// At this point, the duty cycling has been disabled temporary
// and it will be this component's job to turn the radio back off
// Wait long enough to see if we actually receive a packet, which is
// just a little longer in case there is more than one lpl transmitter on
// the channel.
if(call SendState.isIdle()) {
startOffTimer();
}
}
/***************** SubControl Events ***************/
event void SubControl.startDone(error_t error) {
if(!error) {
call RadioState.forceState(S_ON);
if(call SendState.getState() == S_LPL_FIRST_MESSAGE
|| call SendState.getState() == S_LPL_SENDING) {
initializeSend();
}
}
}
event void SubControl.stopDone(error_t error) {
if(!error) {
call RadioState.forceState(S_OFF);
if(call SendState.getState() == S_LPL_FIRST_MESSAGE
|| call SendState.getState() == S_LPL_SENDING) {
// We're in the middle of sending a message; start the radio back up
post startRadio();
} else {
call OffTimer.stop();
call SendDoneTimer.stop();
}
}
}
/***************** SubSend Events ***************/
event void SubSend.sendDone(message_t* msg, error_t error) {
switch(call SendState.getState()) {
case S_LPL_SENDING:
if(call SendDoneTimer.isRunning()) {
if(!call PacketAcknowledgements.wasAcked(msg)) {
post resend();
return;
}
}
break;
case S_LPL_CLEAN_UP:
/**
* We include this state so upper layers can't send a different message
* before the last message gets done sending
*/
break;
default:
break;
}
call SendState.toIdle();
call SendDoneTimer.stop();
startOffTimer();
signal Send.sendDone(msg, error);
}
/***************** SubReceive Events ***************/
/**
* If the received message is new, we signal the receive event and
* start the off timer. If the last message we received had the same
* DSN as this message, then the chances are pretty good
* that this message should be ignored, especially if the destination address
* as the broadcast address
*/
event message_t *SubReceive.receive(message_t* msg, void* payload,
uint8_t len) {
call CC2420DutyCycle.forceDetected();
startOffTimer();
return signal Receive.receive(msg, payload, len);
}
/***************** Timer Events ****************/
event void OffTimer.fired() {
/*
* Only stop the radio if the radio is supposed to be off permanently
* or if the duty cycle is on and our sleep interval is not 0
*/
if(call SplitControlState.getState() == S_OFF
|| (call CC2420DutyCycle.getSleepInterval() > 0
&& call SplitControlState.getState() == S_ON
&& call SendState.getState() == S_LPL_NOT_SENDING)) {
post stopRadio();
}
}
/**
* When this timer is running, that means we're sending repeating messages
* to a node that is receive check duty cycling.
*/
event void SendDoneTimer.fired() {
if(call SendState.getState() == S_LPL_SENDING) {
// The next time SubSend.sendDone is signaled, send is complete.
call SendState.forceState(S_LPL_CLEAN_UP);
}
}
/***************** Resend Events ****************/
/**
* Signal that a message has been sent
*
* @param p_msg message to send.
* @param error notifaction of how the operation went.
*/
async event void Resend.sendDone( message_t* p_msg, error_t error ) {
// This is actually caught by SubSend.sendDone
}
/***************** Tasks ***************/
task void send() {
if(call SubSend.send(currentSendMsg, currentSendLen) != SUCCESS) {
post send();
}
}
task void resend() {
if(call Resend.resend(TRUE) != SUCCESS) {
post resend();
}
}
task void startRadio() {
if(call SubControl.start() != SUCCESS) {
post startRadio();
}
}
task void stopRadio() {
if(call SendState.getState() == S_LPL_NOT_SENDING) {
if(call SubControl.stop() != SUCCESS) {
post stopRadio();
}
}
}
/***************** Functions ***************/
void initializeSend() {
if(call LowPowerListening.getRxSleepInterval(currentSendMsg)
> ONE_MESSAGE) {
if(call AMPacket.destination(currentSendMsg) == AM_BROADCAST_ADDR) {
call PacketAcknowledgements.noAck(currentSendMsg);
} else {
// Send it repetitively within our transmit window
call PacketAcknowledgements.requestAck(currentSendMsg);
}
call SendDoneTimer.startOneShot(
call LowPowerListening.getRxSleepInterval(currentSendMsg) + 20);
}
post send();
}
void startOffTimer() {
call OffTimer.startOneShot(DELAY_AFTER_RECEIVE);
}
/**
* Check the bounds on a given duty cycle
* We're never over 100%, and we're never at 0%
*/
uint16_t getActualDutyCycle(uint16_t dutyCycle) {
if(dutyCycle > 10000) {
return 10000;
} else if(dutyCycle == 0) {
return 1;
}
return dutyCycle;
}
}
--- NEW FILE: CC2420Cca.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Interface to obtain a CCA reading from the CC2420 radio
* to determine if a neighbor is transmitting
* @author David Moss
*/
interface CC2420Cca {
/**
* @return TRUE if the CCA pin shows a clear channel
*/
command bool isChannelClear();
}
--- NEW FILE: CC2420DutyCycle.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Manage the CC2420's duty cycle and power
* @author David Moss
*/
interface CC2420DutyCycle {
/**
* Set the sleep interval, in binary milliseconds
* @param sleepIntervalMs the sleep interval in [ms]
*/
command void setSleepInterval(uint16_t sleepIntervalMs);
/**
* @return the sleep interval in [ms]
*/
command uint16_t getSleepInterval();
/**
* Sometimes the radio kicks on and an Rx interrupt causes the CCA
* checking for-loop to stop doing its job. The upper layers receive
* a message, but the for-loop CCA check never got the detect because it
* got cut off. So, LPL can override the duty cycler and leave the radio in
* its current state. When the radio turns back off again, the duty cycling
* continues
*/
command void forceDetected();
/**
* A transmitter was detected. You must now take action to
* turn the radio off when the transaction is complete.
*/
event void detected();
}
--- NEW FILE: CC2420DutyCycleC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Use this component to duty cycle the radio. When a message is heard,
* disable DutyCycling.
*
* @author David Moss dmm at rincon.com
*/
configuration CC2420DutyCycleC {
provides {
interface CC2420DutyCycle;
interface SplitControl;
interface State as SplitControlState;
}
}
implementation {
components MainC,
CC2420DutyCycleP,
CC2420TransmitC,
CC2420CsmaC,
LedsC,
new StateC() as RadioPowerStateC,
new StateC() as DutyCycleStateC,
new StateC() as CheckStateC,
new StateC() as SplitControlStateC,
new TimerMilliC() as OnTimerC,
new TimerMilliC() as CheckTimerC,
RandomC;
#if defined(LOW_POWER_LISTENING) || defined(ACK_LOW_POWER_LISTENING)
components CC2420AckLplC as LplC;
#elif defined(NOACK_LOW_POWER_LISTENING)
components CC2420NoAckLplC as LplC;
#else
components CC2420LplDummyC as LplC;
#endif
CC2420DutyCycle = CC2420DutyCycleP;
SplitControl = CC2420DutyCycleP;
SplitControlState = SplitControlStateC;
MainC.SoftwareInit -> CC2420DutyCycleP;
CC2420DutyCycleP.Random -> RandomC;
CC2420DutyCycleP.CC2420Cca -> CC2420TransmitC;
CC2420DutyCycleP.SubControl -> CC2420CsmaC;
CC2420DutyCycleP.SendState -> LplC;
CC2420DutyCycleP.RadioPowerState -> RadioPowerStateC;
CC2420DutyCycleP.DutyCycleState -> DutyCycleStateC;
CC2420DutyCycleP.SplitControlState -> SplitControlStateC;
CC2420DutyCycleP.CheckState -> CheckStateC;
CC2420DutyCycleP.OnTimer -> OnTimerC;
CC2420DutyCycleP.Leds -> LedsC;
}
--- NEW FILE: CC2420DutyCycleP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Module to duty cycle the radio on and off, performing CCA receive checks.
* When a carrier is sensed, this will leave the radio on. It is then up
* to higher layers to turn the radio off again. Once the radio is turned
* off, this module will automatically continue duty cycling and looking for
* a modulated signal.
*
* @author David Moss
*/
module CC2420DutyCycleP {
provides {
interface CC2420DutyCycle;
interface Init;
interface SplitControl;
}
uses {
interface Timer<TMilli> as OnTimer;
interface SplitControl as SubControl;
interface State as RadioPowerState;
interface State as DutyCycleState;
interface State as SplitControlState;
interface State as CheckState;
interface State as SendState;
interface Leds;
interface CC2420Cca;
interface Random;
}
}
implementation {
/** The current period of the duty cycle, equivalent of wakeup interval */
uint16_t sleepInterval;
/** The number of times the CCA has been sampled in this wakeup period */
uint16_t ccaChecks;
/** TRUE if we get an Rx interrupt that stops our CCA checking loop */
bool detectionForced;
/**
* Radio Power, Check State, and Duty Cycling State
*/
enum {
S_OFF, // off by default
S_ON,
};
/***************** Prototypes ****************/
task void stopRadio();
task void startRadio();
task void getCca();
/***************** Init Commands ****************/
command error_t Init.init() {
sleepInterval = 0;
return SUCCESS;
}
/***************** CC2420DutyCycle Commands ****************/
/**
* Set the sleep interval, in binary milliseconds
* @param sleepIntervalMs the sleep interval in [ms]
*/
command void CC2420DutyCycle.setSleepInterval(uint16_t sleepIntervalMs) {
if (!sleepInterval && sleepIntervalMs) {
// We were always on, now lets duty cycle
call DutyCycleState.forceState(S_ON);
call CheckState.toIdle();
post stopRadio(); // Might want to delay turning off the radio
}
detectionForced = FALSE;
sleepInterval = sleepIntervalMs;
if(sleepInterval == 0 && call DutyCycleState.getState() == S_ON) {
call DutyCycleState.forceState(S_OFF);
call CheckState.toIdle();
/*
* Leave the radio on permanently if sleepInterval == 0 and the radio is
* supposed to be enabled
*/
if(call RadioPowerState.getState() == S_OFF) {
call SubControl.start();
}
}
}
/**
* @return the sleep interval in [ms]
*/
command uint16_t CC2420DutyCycle.getSleepInterval() {
return sleepInterval;
}
command void CC2420DutyCycle.forceDetected() {
detectionForced = TRUE;
}
/***************** SplitControl Commands ****************/
command error_t SplitControl.start() {
call SplitControlState.forceState(S_ON);
if(sleepInterval > 0) {
// Begin duty cycling
call DutyCycleState.forceState(S_ON);
call CheckState.toIdle();
post stopRadio();
signal SplitControl.startDone(SUCCESS);
} else {
call DutyCycleState.forceState(S_OFF);
call CheckState.toIdle();
/*
* Leave the radio on permanently if sleepInterval == 0 and the radio is
* supposed to be enabled
*/
if(call RadioPowerState.getState() == S_OFF) {
call SubControl.start();
// Here, SplitControl.startDone is signaled on SubControl.startDone
} else {
// Radio is already on
signal SplitControl.startDone(SUCCESS);
}
}
return SUCCESS;
}
command error_t SplitControl.stop() {
call SplitControlState.forceState(S_OFF);
call DutyCycleState.forceState(S_OFF);
call CheckState.toIdle();
return call SubControl.stop();
/*
* SubControl.stopDone signals SplitControl.stopDone when
* DutyCycleState is S_OFF
*/
}
/***************** Timer Events ****************/
event void OnTimer.fired() {
if(call DutyCycleState.getState() == S_ON) {
if(call RadioPowerState.getState() == S_OFF) {
call CheckState.forceState(S_ON);
ccaChecks = 0;
/*
* The MicaZ, running on an external oscillator I think, and
* returning the microcontroller out of a sleep state to immediately
* perform an ADC conversion, sucks. The first ADC conversion out
* of a sleep state lasts about a second. We don't want the radio
* on that long. Like the CC1000 RSSI pulse check implementation
* done in the Rincon CC1000Radio stack, we will perform
* a single ADC conversion and then flip on the radio to check
* the channel.
*/
post getCca();
} else {
// Someone else turned on the radio, try again in awhile
call OnTimer.startOneShot(sleepInterval);
}
}
}
/***************** SubControl Events ****************/
event void SubControl.startDone(error_t error) {
if(call DutyCycleState.getState() == S_ON && error) {
// My responsibility to try again
post startRadio();
return;
}
call RadioPowerState.forceState(S_ON);
//call Leds.led2On();
if(call DutyCycleState.getState() == S_ON) {
if(call CheckState.getState() == S_ON) {
post getCca();
}
} else {
// Must have turned the radio on manually
signal SplitControl.startDone(SUCCESS);
}
}
event void SubControl.stopDone(error_t error) {
if(error && call DutyCycleState.getState() == S_ON) {
// My responsibility to try again
post stopRadio();
return;
}
detectionForced = FALSE;
call RadioPowerState.forceState(S_OFF);
//call Leds.led2Off();
if(call DutyCycleState.getState() == S_ON) {
call OnTimer.startOneShot(sleepInterval);
} else {
// Must have turned off the radio manually
signal SplitControl.stopDone(error);
}
}
/***************** Tasks ****************/
task void stopRadio() {
if(call DutyCycleState.getState() == S_ON && !detectionForced) {
if(call SubControl.stop() != SUCCESS) {
// Already stopped?
call OnTimer.startOneShot(sleepInterval);
}
}
}
task void startRadio() {
if(call DutyCycleState.getState() == S_ON) {
if(call SubControl.start() != SUCCESS) {
post startRadio();
}
}
}
task void getCca() {
uint8_t detects = 0;
if(call DutyCycleState.getState() == S_ON) {
ccaChecks++;
if(ccaChecks == 1) {
// Microcontroller is ready, turn on the radio and sample a few times
post startRadio();
return;
}
atomic {
for( ; ccaChecks < MAX_LPL_CCA_CHECKS && call SendState.isIdle(); ccaChecks++) {
if(!call CC2420Cca.isChannelClear() || detectionForced) {
detects++;
if(detects > MIN_SAMPLES_BEFORE_DETECT) {
signal CC2420DutyCycle.detected();
return;
}
// Leave the radio on for upper layers to perform some transaction
}
}
}
call CheckState.toIdle();
if(call SendState.isIdle()) {
post stopRadio();
}
}
}
/**************** Defaults ****************/
default event void CC2420DutyCycle.detected() {
}
default event void SplitControl.startDone(error_t error) {
}
default event void SplitControl.stopDone(error_t error) {
}
}
--- NEW FILE: CC2420LplDummyC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Dummy low power listening interface used when LowPowerListening is not
* compiled in with the application.
* Sleep interval is always 0, and duty cycle is always 100%
* @author David Moss
*/
configuration CC2420LplDummyC {
provides {
interface Send;
interface Receive;
interface LowPowerListening;
interface SplitControl;
interface State as SendState;
}
uses {
interface Send as SubSend;
interface Receive as SubReceive;
interface SplitControl as SubControl;
}
}
implementation {
components CC2420LplDummyP;
components new StateC();
Send = SubSend;
Receive = SubReceive;
SplitControl = SubControl;
LowPowerListening = CC2420LplDummyP;
SendState = StateC;
}
--- NEW FILE: CC2420LplDummyP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Dummy low power listening interface used when LowPowerListening is not
* compiled in with the application.
* Sleep interval is always 0, and duty cycle is always 100%
* @author David Moss
*/
module CC2420LplDummyP {
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;
}
}
--- NEW FILE: CC2420NoAckLpl.h ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* @author David Moss
*/
#ifndef CC2420NOACKLPL_H
#define CC2420NOACKLPL_H
/**
* Low Power Listening Send States
*/
typedef enum {
S_LPL_NOT_SENDING, // DEFAULT
S_LPL_FIRST_MESSAGE, // 1. Initial backoffs, no acks, full CCA
S_LPL_LAST_MESSAGE, // 3. No backoffs, acknowledgement request, no CCA
} lpl_sendstate_t;
/**
* Amount of time, in milliseconds, to keep the radio on after
* a successful receive addressed to this node
* You don't want this too fast, or the off timer can accidentally
* fire due to delays in the system. The radio would shut off and
* possibly need to turn back on again immediately, which can lock up
* the CC2420 if it's in the middle of doing something.
*/
#ifndef DELAY_AFTER_RECEIVE
#define DELAY_AFTER_RECEIVE 100
#endif
/**
* This is a measured value of the time in ms the radio is actually on
* We round this up to err on the side of better performance ratios
*/
#ifndef DUTY_ON_TIME
#define DUTY_ON_TIME 1
#endif
/**
* The maximum number of CCA checks performed on each wakeup.
* The value is relative to the speed of transmission and speed of the
* microcontroller executing the receive check loop. If the transmission
* is ultimately back-to-back without break or the microcontroller
* is slow, we can do less samples. If the microcontroller is very
* fast, we must do more samples. Keep in mind the datasheet also
* specifies that the CCA pin is valid after 8 symbol periods of
* the radio being on.
*/
#ifndef MAX_LPL_CCA_CHECKS
#if defined(PLATFORM_TELOSB)
#define MAX_LPL_CCA_CHECKS 12
#else
#define MAX_LPL_CCA_CHECKS 12
#endif
#endif
/**
* The minimum number of samples that must be taken in CC2420DutyCycleP
* that show the channel is not clear before a detection event is issued
*/
#ifndef MIN_SAMPLES_BEFORE_DETECT
#define MIN_SAMPLES_BEFORE_DETECT 1
#endif
#endif
--- NEW FILE: CC2420NoAckLplC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Low Power Listening for the CC2420
* This is experimental because:
* > Acknowledgements really don't work at all, even on the last message
* which is supposed to return an acknowledgement from the receiver.
* > The CRC is not yet manually calculated, so the entire continuous
* modulation doesn't contain any useful information.
* By adding in the CRC calcuation functionality to TransmitP,
* we can better support mobile nodes that walk out of range and
* lossy connections. We could also put receivers back to sleep that
* the "preamble" is not destined for, because the actual preamble
* would have an address associated with it.
*
* @author David Moss
*/
#include "CC2420NoAckLpl.h"
#warning "*** USING EXPERIMENTAL NO-ACK LOW POWER LISTENING LAYER"
configuration CC2420NoAckLplC {
provides {
interface LowPowerListening;
interface Send;
interface Receive;
interface SplitControl;
interface State as SendState;
}
uses {
interface Send as SubSend;
interface Receive as SubReceive;
interface SplitControl as SubControl;
}
}
implementation {
components MainC,
CC2420NoAckLplP,
CC2420DutyCycleC,
CC2420ActiveMessageC,
CC2420CsmaC,
CC2420TransmitC,
CC2420PacketC,
RandomC,
LedsC,
new StateC() as SendStateC,
new StateC() as RadioStateC,
new TimerMilliC() as OffTimerC;
LowPowerListening = CC2420NoAckLplP;
Send = CC2420NoAckLplP;
Receive = CC2420NoAckLplP;
SplitControl = CC2420DutyCycleC;
SendState = SendStateC;
SubControl = CC2420NoAckLplP.SubControl;
SubReceive = CC2420NoAckLplP.SubReceive;
SubSend = CC2420NoAckLplP.SubSend;
MainC.SoftwareInit -> CC2420NoAckLplP;
CC2420NoAckLplP.Random -> RandomC;
CC2420NoAckLplP.SendState -> SendStateC;
CC2420NoAckLplP.RadioState -> RadioStateC;
CC2420NoAckLplP.SplitControlState -> CC2420DutyCycleC;
CC2420NoAckLplP.CC2420Cca -> CC2420TransmitC;
CC2420NoAckLplP.OffTimer -> OffTimerC;
CC2420NoAckLplP.CC2420DutyCycle -> CC2420DutyCycleC;
CC2420NoAckLplP.Resend -> CC2420TransmitC;
CC2420NoAckLplP.PacketAcknowledgements -> CC2420ActiveMessageC;
CC2420NoAckLplP.AMPacket -> CC2420ActiveMessageC;
CC2420NoAckLplP.CC2420Packet -> CC2420PacketC;
CC2420NoAckLplP.RadioBackoff -> CC2420CsmaC;
CC2420NoAckLplP.Leds -> LedsC;
}
--- NEW FILE: CC2420NoAckLplP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Low Power Listening for the CC2420. This component is responsible for
* delivery of an LPL packet, and for turning off the radio when the radio
* has run out of tasks.
*
* The CC2420DutyCycle component is responsible for duty cycling the radio
* and performing receive detections.
*
* @author David Moss
*/
#include "CC2420NoAckLpl.h"
module CC2420NoAckLplP {
provides {
interface Init;
interface LowPowerListening;
interface Send;
interface Receive;
}
uses {
interface Send as SubSend;
interface CC2420Transmit as Resend;
interface Receive as SubReceive;
interface AMPacket;
interface CC2420Cca;
interface SplitControl as SubControl;
interface CC2420DutyCycle;
interface CC2420Packet;
interface PacketAcknowledgements;
interface RadioBackoff[am_id_t amId];
interface State as SendState;
interface State as RadioState;
interface State as SplitControlState;
interface Random;
interface Timer<TMilli> as OffTimer;
interface Leds;
}
}
implementation {
/** The message currently being sent */
message_t *currentSendMsg;
/** The length of the current send message */
uint8_t currentSendLen;
/** TRUE if the radio is duty cycling and not always on */
bool dutyCycling;
/** TRUE if we have received a message after the last detect */
bool receivedMsg;
/**
* Radio State
*/
enum {
S_OFF,
S_ON,
};
/**
* Send States
*/
enum {
S_IDLE,
S_SENDING,
};
enum {
ONE_MESSAGE = 0,
};
/***************** Prototypes ***************/
task void send();
task void resend();
task void startRadio();
task void stopRadio();
task void detectTxDone();
void initializeSend();
void startOffTimer();
uint16_t getActualDutyCycle(uint16_t dutyCycle);
/***************** Init Commands ***************/
command error_t Init.init() {
dutyCycling = FALSE;
return SUCCESS;
}
/***************** LowPowerListening Commands ***************/
/**
* Set this this node's radio sleep interval, in milliseconds.
* Once every interval, the node will sleep and perform an Rx check
* on the radio. Setting the sleep interval to 0 will keep the radio
* always on.
*
* This is the equivalent of setting the local duty cycle rate.
*
* @param sleepIntervalMs the length of this node's Rx check interval, in [ms]
*/
command void LowPowerListening.setLocalSleepInterval(
uint16_t sleepIntervalMs) {
call CC2420DutyCycle.setSleepInterval(sleepIntervalMs);
}
/**
* @return the local node's sleep interval, in [ms]
*/
command uint16_t LowPowerListening.getLocalSleepInterval() {
return call CC2420DutyCycle.getSleepInterval();
}
/**
* Set this node's radio duty cycle rate, in units of [percentage*100].
* For example, to get a 0.05% duty cycle,
* <code>
* call LowPowerListening.setDutyCycle(5);
* </code>
*
* For a 100% duty cycle (always on),
* <code>
* call LowPowerListening.setDutyCycle(10000);
* </code>
*
* This is the equivalent of setting the local sleep interval explicitly.
*
* @param dutyCycle The duty cycle percentage, in units of [percentage*100]
*/
command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) {
call CC2420DutyCycle.setSleepInterval(
call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
}
/**
* @return this node's radio duty cycle rate, in units of [percentage*100]
*/
command uint16_t LowPowerListening.getLocalDutyCycle() {
return call LowPowerListening.sleepIntervalToDutyCycle(
call CC2420DutyCycle.getSleepInterval());
}
/**
* Configure this outgoing message so it can be transmitted to a neighbor mote
* with the specified Rx sleep interval.
* @param msg Pointer to the message that will be sent
* @param sleepInterval The receiving node's sleep interval, in [ms]
*/
command void LowPowerListening.setRxSleepInterval(message_t *msg,
uint16_t sleepIntervalMs) {
(call CC2420Packet.getMetadata(msg))->rxInterval = sleepIntervalMs;
}
/**
* @return the destination node's sleep interval configured in this message
*/
command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) {
return (call CC2420Packet.getMetadata(msg))->rxInterval;
}
/**
* Configure this outgoing message so it can be transmitted to a neighbor mote
* with the specified Rx duty cycle rate.
* Duty cycle is in units of [percentage*100], i.e. 0.25% duty cycle = 25.
*
* @param msg Pointer to the message that will be sent
* @param dutyCycle The duty cycle of the receiving mote, in units of
* [percentage*100]
*/
command void LowPowerListening.setRxDutyCycle(message_t *msg,
uint16_t dutyCycle) {
(call CC2420Packet.getMetadata(msg))->rxInterval =
call LowPowerListening.dutyCycleToSleepInterval(dutyCycle);
}
/**
* @return the destination node's duty cycle configured in this message
* in units of [percentage*100]
*/
command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) {
return call LowPowerListening.sleepIntervalToDutyCycle(
(call CC2420Packet.getMetadata(msg))->rxInterval);
}
/**
* Convert a duty cycle, in units of [percentage*100], to
* the sleep interval of the mote in milliseconds
* @param dutyCycle The duty cycle in units of [percentage*100]
* @return The equivalent sleep interval, in units of [ms]
*/
command uint16_t LowPowerListening.dutyCycleToSleepInterval(
uint16_t dutyCycle) {
dutyCycle = getActualDutyCycle(dutyCycle);
if(dutyCycle == 10000) {
return 0;
}
return (DUTY_ON_TIME * (10000 - dutyCycle)) / dutyCycle;
}
/**
* Convert a sleep interval, in units of [ms], to a duty cycle
* in units of [percentage*100]
* @param sleepInterval The sleep interval in units of [ms]
* @return The duty cycle in units of [percentage*100]
*/
command uint16_t LowPowerListening.sleepIntervalToDutyCycle(
uint16_t sleepInterval) {
if(sleepInterval == 0) {
return 10000;
}
return getActualDutyCycle((DUTY_ON_TIME * 10000)
/ (sleepInterval + DUTY_ON_TIME));
}
/***************** Send Commands ***************/
/**
* Each call to this send command gives the message a single
* DSN that does not change for every copy of the message
* sent out. For messages that are not acknowledged, such as
* a broadcast address message, the receiving end does not
* signal receive() more than once for that message.
*/
command error_t Send.send(message_t *msg, uint8_t len) {
if(call SplitControlState.getState() == S_OFF) {
// Everything is off right now, start SplitControl and try again
return EOFF;
}
if(call SendState.requestState(S_LPL_FIRST_MESSAGE) == SUCCESS) {
currentSendMsg = msg;
currentSendLen = len;
// In case our off timer is running...
call OffTimer.stop();
if(call RadioState.getState() == S_ON) {
initializeSend();
return SUCCESS;
} else {
post startRadio();
}
return SUCCESS;
}
return FAIL;
}
command error_t Send.cancel(message_t *msg) {
if(currentSendMsg == msg) {
call SendState.toIdle();
startOffTimer();
return call SubSend.cancel(msg);
}
return FAIL;
}
command uint8_t Send.maxPayloadLength() {
return call SubSend.maxPayloadLength();
}
command void *Send.getPayload(message_t* msg) {
return call SubSend.getPayload(msg);
}
/***************** Receive Commands ***************/
command void *Receive.getPayload(message_t* msg, uint8_t* len) {
return call SubReceive.getPayload(msg, len);
}
command uint8_t Receive.payloadLength(message_t* msg) {
return call SubReceive.payloadLength(msg);
}
/***************** DutyCycle Events ***************/
/**
* A transmitter was detected. You must now take action to
* turn the radio off when the transaction is complete.
*/
event void CC2420DutyCycle.detected() {
// At this point, the duty cycling has been disabled temporary
// and it will be this component's job to turn the radio back off
// Wait long enough to see if we actually receive a packet
receivedMsg = FALSE;
post detectTxDone();
}
/***************** SubControl Events ***************/
event void SubControl.startDone(error_t error) {
if(!error) {
call RadioState.forceState(S_ON);
if(call SendState.getState() == S_LPL_FIRST_MESSAGE) {
initializeSend();
}
}
}
event void SubControl.stopDone(error_t error) {
if(!error) {
call RadioState.forceState(S_OFF);
if(call SendState.getState() == S_LPL_FIRST_MESSAGE) {
// We're in the middle of sending a message; start the radio back up
post startRadio();
} else {
call OffTimer.stop();
}
}
}
/***************** SubSend Events ***************/
event void SubSend.sendDone(message_t* msg, error_t error) {
switch(call SendState.getState()) {
case S_LPL_FIRST_MESSAGE:
call SendState.forceState(S_LPL_LAST_MESSAGE);
call PacketAcknowledgements.requestAck(msg);
post send();
return;
case S_LPL_LAST_MESSAGE:
// Execute past the switch statement
break;
default:
// Execute past the switch statement
break;
}
call SendState.toIdle();
startOffTimer();
signal Send.sendDone(msg, error);
}
/***************** SubReceive Events ***************/
/**
* If the received message is new, we signal the receive event and
* start the off timer. If the last message we received had the same
* DSN as this message, then the chances are pretty good
* that this message should be ignored, especially if the destination address
* as the broadcast address
*/
event message_t *SubReceive.receive(message_t* msg, void* payload,
uint8_t len) {
/**
* Now wait for the next moment the channel is free before passing the
* packet up, and keep the radio on that whole time. That's when our
* transmitter is done transmitting, LPL or not.
*/
call CC2420DutyCycle.forceDetected();
receivedMsg = TRUE;
startOffTimer();
return signal Receive.receive(msg, payload, len);
}
/***************** Timer Events ****************/
event void OffTimer.fired() {
/*
* Only stop the radio if the radio is supposed to be off permanently
* or if the duty cycle is on and our sleep interval is not 0
*/
if(call SplitControlState.getState() == S_OFF
|| (call CC2420DutyCycle.getSleepInterval() > 0
&& call SplitControlState.getState() == S_ON
&& call SendState.getState() == S_LPL_NOT_SENDING)) {
post stopRadio();
}
}
/***************** RadioBackoff Events ****************/
/**
* Request for input on the initial backoff
* Reply using setInitialBackoff(..)
* @param msg pointer to the message being sent
*/
async event void RadioBackoff.requestInitialBackoff[am_id_t amId](message_t *msg) {
}
/**
* Request for input on the congestion backoff
* Reply using setCongestionBackoff(..)
* @param msg pointer to the message being sent
*/
async event void RadioBackoff.requestCongestionBackoff[am_id_t amId](message_t *msg) {
}
/**
* Request for input on the low power listening backoff
* This should be somewhat random, but as short as possible
* Reply using setLplBackoff(..)
* @param msg pointer to the message being sent
*/
async event void RadioBackoff.requestLplBackoff[am_id_t amId](message_t *msg) {
}
/**
* Request for input on whether or not to use CCA on the outbound packet.
* Replies should come in the form of setCca(..)
* @param msg pointer to the message being sent
*/
async event void RadioBackoff.requestCca[am_id_t amId](message_t *msg) {
if(call SendState.getState() == S_LPL_FIRST_MESSAGE) {
call RadioBackoff.setCca[amId](TRUE);
} else if(call SendState.getState() == S_LPL_LAST_MESSAGE) {
call RadioBackoff.setCca[amId](FALSE);
}
}
/***************** Resend Events ****************/
/**
* Signal that a message has been sent
*
* @param p_msg message to send.
* @param error notifaction of how the operation went.
*/
async event void Resend.sendDone( message_t* p_msg, error_t error ) {
// This is actually caught by SubSend.sendDone
}
/***************** Tasks ***************/
task void send() {
if(call SubSend.send(currentSendMsg, currentSendLen) != SUCCESS) {
post send();
}
}
task void resend() {
if(call Resend.resend(FALSE) != SUCCESS) {
post resend();
}
}
task void startRadio() {
if(call SubControl.start() != SUCCESS) {
post startRadio();
}
}
task void stopRadio() {
if(call SendState.getState() == S_LPL_NOT_SENDING) {
if(call SubControl.stop() != SUCCESS) {
post stopRadio();
}
}
}
/**
* Don't start the off-timer until the end of the transmitter's transmission.
*/
task void detectTxDone() {
uint16_t clearChannelSamples;
if(call SendState.getState() != S_LPL_FIRST_MESSAGE
&& call SendState.getState() != S_LPL_LAST_MESSAGE
&& !receivedMsg) {
for(clearChannelSamples = 0; clearChannelSamples < MAX_LPL_CCA_CHECKS * 8; clearChannelSamples++) {
// In one straight shot, sample the channel repetitively and verify that
// the transmitter is done transmitting
if(!call CC2420Cca.isChannelClear()) {
// Nope, start over from the beginning.
post detectTxDone();
return;
}
}
// Transmitter done, turn the radio off in a few...
startOffTimer();
}
}
/***************** Functions ***************/
void initializeSend() {
if(call LowPowerListening.getRxSleepInterval(currentSendMsg)
> ONE_MESSAGE) {
call PacketAcknowledgements.noAck(currentSendMsg);
}
post send();
}
void startOffTimer() {
call OffTimer.startOneShot(DELAY_AFTER_RECEIVE);
}
/**
* Check the bounds on a given duty cycle
* We're never over 100%, and we're never at 0%
*/
uint16_t getActualDutyCycle(uint16_t dutyCycle) {
if(dutyCycle > 10000) {
return 10000;
} else if(dutyCycle == 0) {
return 1;
}
return dutyCycle;
}
}
--- NEW FILE: CC2420TinyosNetworkC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Original TinyOS T-Frames use a packet header that is not compatible with
* other 6LowPAN networks. They do not include the network byte
* responsible for identifying the packing as being sourced from a TinyOS
* network.
*
* TinyOS I-Frames are interoperability packets that do include a network
* byte as defined by 6LowPAN specifications. The I-Frame header type is
* the default packet header used in TinyOS networks.
*
* Since either packet header is acceptable, this layer must do some
* preprocessing (sorry) to figure out whether or not it needs to include
* the functionality to process I-frames. If I-Frames are used, then
* the network byte is added on the way out and checked on the way in.
* If the packet came from a network different from a TinyOS network, the
* user may access it through the DispatchP's NonTinyosReceive[] Receive
* interface and process it in a different radio stack.
*
* If T-Frames are used instead, this layer is simply pass-through wiring to the
* layer beneath.
*
* Define "CC2420_IFRAME_TYPE" to use the interoperability frame and
* this layer
*
* @author David Moss
*/
#include "CC2420.h"
configuration CC2420TinyosNetworkC {
provides {
interface Send;
interface Receive;
}
uses {
interface Receive as SubReceive;
interface Send as SubSend;
}
}
implementation {
#ifdef CC2420_IFRAME_TYPE
components CC2420TinyosNetworkP;
components CC2420PacketC;
CC2420TinyosNetworkP.Send = Send;
CC2420TinyosNetworkP.Receive = Receive;
CC2420TinyosNetworkP.SubSend = SubSend;
CC2420TinyosNetworkP.SubReceive = SubReceive;
CC2420TinyosNetworkP.CC2420Packet -> CC2420PacketC;
#else
Send = SubSend;
Receive = SubReceive;
#endif
}
--- NEW FILE: CC2420TinyosNetworkP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Fills in the network ID byte for outgoing packets for compatibility with
* other 6LowPAN networks. Filters incoming packets that are not
* TinyOS network compatible. Provides the 6LowpanSnoop interface to
* sniff for packets that were not originated from TinyOS.
*
* @author David Moss
*/
#include "CC2420.h"
module CC2420TinyosNetworkP {
provides {
interface Send;
interface Receive;
interface Receive as NonTinyosReceive[uint8_t networkId];
}
uses {
interface Send as SubSend;
interface Receive as SubReceive;
interface CC2420Packet;
}
}
implementation {
/***************** Send Commands ****************/
command error_t Send.send(message_t* msg, uint8_t len) {
(call CC2420Packet.getHeader(msg))->network = 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) {
return call SubSend.getPayload(msg);
}
/***************** Receive Commands ****************/
command void* Receive.getPayload(message_t* msg, uint8_t* len) {
return call SubReceive.getPayload(msg, len);
}
command uint8_t Receive.payloadLength(message_t* msg) {
return call SubReceive.payloadLength(msg);
}
/***************** NonTinyosReceive Commands ****************/
command void* NonTinyosReceive.getPayload[uint8_t networkId](message_t* msg, uint8_t* len) {
return call SubReceive.getPayload(msg, len);
}
command uint8_t NonTinyosReceive.payloadLength[uint8_t networkId](message_t* msg) {
return call SubReceive.payloadLength(msg);
}
/***************** SubSend Events *****************/
event void SubSend.sendDone(message_t* msg, error_t error) {
signal Send.sendDone(msg, error);
}
/***************** SubReceive Events ***************/
event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len) {
if((call CC2420Packet.getHeader(msg))->network == TINYOS_6LOWPAN_NETWORK_ID) {
return signal Receive.receive(msg, payload, len);
} else {
return signal NonTinyosReceive.receive[(call CC2420Packet.getHeader(msg))->network](msg, payload, len);
}
}
/***************** Defaults ****************/
default event message_t *NonTinyosReceive.receive[uint8_t networkId](message_t *msg, void *payload, uint8_t len) {
return msg;
}
}
--- NEW FILE: PacketLink.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* @author David Moss
* @author Jon Wyant
*/
interface PacketLink {
/**
* Set the maximum number of times attempt message delivery
* Default is 0
* @param msg
* @param maxRetries the maximum number of attempts to deliver
* the message
*/
command void setRetries(message_t *msg, uint16_t maxRetries);
/**
* Set a delay between each retry attempt
* @param msg
* @param retryDelay the delay betweeen retry attempts, in milliseconds
*/
command void setRetryDelay(message_t *msg, uint16_t retryDelay);
/**
* @return the maximum number of retry attempts for this message
*/
command uint16_t getRetries(message_t *msg);
/**
* @return the delay between retry attempts in ms for this message
*/
command uint16_t getRetryDelay(message_t *msg);
/**
* @return TRUE if the message was delivered.
*/
command bool wasDelivered(message_t *msg);
}
--- NEW FILE: PacketLinkC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Reliable Packet Link Functionality
* @author David Moss
* @author Jon Wyant
*/
#warning "*** USING PACKET LINK LAYER"
configuration PacketLinkC {
provides {
interface Send;
interface PacketLink;
}
uses {
interface Send as SubSend;
}
}
implementation {
components PacketLinkP,
ActiveMessageC,
CC2420PacketC,
RandomC,
new StateC() as SendStateC,
new TimerMilliC() as DelayTimerC;
PacketLink = PacketLinkP;
Send = PacketLinkP.Send;
SubSend = PacketLinkP.SubSend;
PacketLinkP.SendState -> SendStateC;
PacketLinkP.DelayTimer -> DelayTimerC;
PacketLinkP.PacketAcknowledgements -> ActiveMessageC;
PacketLinkP.AMPacket -> ActiveMessageC;
PacketLinkP.CC2420Packet -> CC2420PacketC;
}
--- NEW FILE: PacketLinkDummyC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Dummy configuration for PacketLink Layer
* @author David Moss
* @author Jon Wyant
*/
configuration PacketLinkDummyC {
provides {
interface Send;
interface PacketLink;
}
uses {
interface Send as SubSend;
}
}
implementation {
components PacketLinkDummyP,
ActiveMessageC;
PacketLink = PacketLinkDummyP;
Send = SubSend;
PacketLinkDummyP.PacketAcknowledgements -> ActiveMessageC;
}
--- NEW FILE: PacketLinkDummyP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Dummy module for Packet Link layer
* @author David Moss
* @author Jon Wyant
*/
module PacketLinkDummyP {
provides {
interface PacketLink;
}
uses {
interface PacketAcknowledgements;
}
}
implementation {
/***************** PacketLink Commands ***************/
/**
* Set the maximum number of times attempt message delivery
* Default is 0
* @param msg
* @param maxRetries the maximum number of attempts to deliver
* the message
*/
command void PacketLink.setRetries(message_t *msg, uint16_t maxRetries) {
}
/**
* Set a delay between each retry attempt
* @param msg
* @param retryDelay the delay betweeen retry attempts, in milliseconds
*/
command void PacketLink.setRetryDelay(message_t *msg, uint16_t retryDelay) {
}
/**
* @return the maximum number of retry attempts for this message
*/
command uint16_t PacketLink.getRetries(message_t *msg) {
return 0;
}
/**
* @return the delay between retry attempts in ms for this message
*/
command uint16_t PacketLink.getRetryDelay(message_t *msg) {
return 0;
}
/**
* @return TRUE if the message was delivered.
* This should always be TRUE if the message was sent to the
* AM_BROADCAST_ADDR
*/
command bool PacketLink.wasDelivered(message_t *msg) {
return call PacketAcknowledgements.wasAcked(msg);
}
}
--- NEW FILE: PacketLinkP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Reliable Packet Link Functionality
* @author David Moss
* @author Jon Wyant
*/
#include "CC2420.h"
module PacketLinkP {
provides {
interface Send;
interface PacketLink;
}
uses {
interface Send as SubSend;
interface State as SendState;
interface PacketAcknowledgements;
interface Timer<TMilli> as DelayTimer;
interface AMPacket;
interface CC2420Packet;
}
}
implementation {
/** The message currently being sent */
message_t *currentSendMsg;
/** Length of the current send message */
uint8_t currentSendLen;
/** The length of the current send message */
uint16_t totalRetries;
/**
* Send States
*/
enum {
S_IDLE,
S_SENDING,
};
/***************** Prototypes ***************/
task void send();
void signalDone(error_t error);
/***************** PacketLink Commands ***************/
/**
* Set the maximum number of times attempt message delivery
* Default is 0
* @param msg
* @param maxRetries the maximum number of attempts to deliver
* the message
*/
command void PacketLink.setRetries(message_t *msg, uint16_t maxRetries) {
(call CC2420Packet.getMetadata(msg))->maxRetries = maxRetries;
}
/**
* Set a delay between each retry attempt
* @param msg
* @param retryDelay the delay betweeen retry attempts, in milliseconds
*/
command void PacketLink.setRetryDelay(message_t *msg, uint16_t retryDelay) {
(call CC2420Packet.getMetadata(msg))->retryDelay = retryDelay;
}
/**
* @return the maximum number of retry attempts for this message
*/
command uint16_t PacketLink.getRetries(message_t *msg) {
return (call CC2420Packet.getMetadata(msg))->maxRetries;
}
/**
* @return the delay between retry attempts in ms for this message
*/
command uint16_t PacketLink.getRetryDelay(message_t *msg) {
return (call CC2420Packet.getMetadata(msg))->retryDelay;
}
/**
* @return TRUE if the message was delivered.
*/
command bool PacketLink.wasDelivered(message_t *msg) {
return call PacketAcknowledgements.wasAcked(msg);
}
/***************** Send Commands ***************/
/**
* Each call to this send command gives the message a single
* DSN that does not change for every copy of the message
* sent out. For messages that are not acknowledged, such as
* a broadcast address message, the receiving end does not
* signal receive() more than once for that message.
*/
command error_t Send.send(message_t *msg, uint8_t len) {
error_t error;
if(call SendState.requestState(S_SENDING) == SUCCESS) {
currentSendMsg = msg;
currentSendLen = len;
totalRetries = 0;
if(call PacketLink.getRetries(msg) > 0) {
call PacketAcknowledgements.requestAck(msg);
}
if((error = call SubSend.send(msg, len)) != SUCCESS) {
call SendState.toIdle();
}
return error;
}
return EBUSY;
}
command error_t Send.cancel(message_t *msg) {
if(currentSendMsg == msg) {
call SendState.toIdle();
return call SubSend.cancel(msg);
}
return FAIL;
}
command uint8_t Send.maxPayloadLength() {
return call SubSend.maxPayloadLength();
}
command void *Send.getPayload(message_t* msg) {
return call SubSend.getPayload(msg);
}
/***************** SubSend Events ***************/
event void SubSend.sendDone(message_t* msg, error_t error) {
if(call SendState.getState() == S_SENDING) {
totalRetries++;
if(call PacketAcknowledgements.wasAcked(msg)) {
signalDone(SUCCESS);
return;
} else if(totalRetries < call PacketLink.getRetries(currentSendMsg)) {
if(call PacketLink.getRetryDelay(currentSendMsg) > 0) {
// Resend after some delay
call DelayTimer.startOneShot(call PacketLink.getRetryDelay(currentSendMsg));
} else {
// Resend immediately
post send();
}
return;
}
}
signalDone(error);
}
/***************** Timer Events ****************/
/**
* When this timer is running, that means we're sending repeating messages
* to a node that is receive check duty cycling.
*/
event void DelayTimer.fired() {
if(call SendState.getState() == S_SENDING) {
post send();
}
}
/***************** Tasks ***************/
task void send() {
if(call PacketLink.getRetries(currentSendMsg) > 0) {
call PacketAcknowledgements.requestAck(currentSendMsg);
}
if(call SubSend.send(currentSendMsg, currentSendLen) != SUCCESS) {
post send();
}
}
/***************** Functions ***************/
void signalDone(error_t error) {
call DelayTimer.stop();
call SendState.toIdle();
signal Send.sendDone(currentSendMsg, error);
}
}
--- NEW FILE: README.txt ---
CC2420 Release Notes 4/11/07
Known Issues
__________________________________________
> LPL Lockups when the node is also accessing the USART
> NoAck LPL doesn't ack at the end properly, and also isn't
finished being implemented. The CRC of the packet needs to
manually be loaded into TXFIFO before continuous modulation.
Low Power Listening Schemes and Preprocessor Variables
__________________________________________
There are two low power listening schemes.
The default is called "AckLpl", because it inserts acknowledgement gaps and
short backoffs during the packet retransmission process.
This allows the transmitter to stop transmitting early, but increases the
power consumption per receive check.
The second is called "NoAckLpl", because it does not insert acknowledgement
gaps or backoffs in the retransmission process, so the receive checks are
shorter but the transmissions are longer. This is more experimental than
the Ack LPL version.
To compile in the default Ack LPL version, #define the preprocessor variable:
LOW_POWER_LISTENING
-or-
ACK_LOW_POWER_LISTENING
To compile in the NoAck LPL version, #define:
NOACK_LOW_POWER_LISTENING
To compile in the PacketLink layer, #define:
PACKET_LINK
To remove SACK auto-acknowledgements, #define:
CC2420_NO_ACKNOWLEDGEMENTS
--- NEW FILE: RadioBackoff.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Interface to request and specify backoff periods for messages
* @author David Moss
*/
interface RadioBackoff {
/**
* Must be called within a requestInitialBackoff event
* @param backoffTime the amount of time in some unspecified units to backoff
*/
async command void setInitialBackoff(uint16_t backoffTime);
/**
* Must be called within a requestCongestionBackoff event
* @param backoffTime the amount of time in some unspecified units to backoff
*/
async command void setCongestionBackoff(uint16_t backoffTime);
/**
* Must be called within a requestLplBackoff event
* @param backoffTime the amount of time in some unspecified units to backoff
*/
async command void setLplBackoff(uint16_t backoffTime);
/**
* Enable CCA for the outbound packet. Must be called within a requestCca
* event
* @param ccaOn TRUE to enable CCA, which is the default.
*/
async command void setCca(bool ccaOn);
/**
* Request for input on the initial backoff
* Reply using setInitialBackoff(..)
* @param msg pointer to the message being sent
*/
async event void requestInitialBackoff(message_t *msg);
/**
* Request for input on the congestion backoff
* Reply using setCongestionBackoff(..)
* @param msg pointer to the message being sent
*/
async event void requestCongestionBackoff(message_t *msg);
/**
* Request for input on the low power listening backoff
* This should be somewhat random, but as short as possible
* Reply using setLplBackoff(..)
* @param msg pointer to the message being sent
*/
async event void requestLplBackoff(message_t *msg);
/**
* Request for input on whether or not to use CCA on the outbound packet.
* Replies should come in the form of setCca(..)
* @param msg pointer to the message being sent
*/
async event void requestCca(message_t *msg);
}
--- NEW FILE: UniqueReceiveC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* This layer keeps a history of the past RECEIVE_HISTORY_SIZE received messages
* If the source address and dsn number of a newly received message matches
* our recent history, we drop the message because we've already seen it.
* This should sit at the bottom of the stack
* @author David Moss
*/
configuration UniqueReceiveC {
provides {
interface Receive;
interface Receive as DuplicateReceive;
}
uses {
interface Receive as SubReceive;
}
}
implementation {
components UniqueReceiveP,
CC2420PacketC,
MainC;
Receive = UniqueReceiveP.Receive;
DuplicateReceive = UniqueReceiveP.DuplicateReceive;
SubReceive = UniqueReceiveP.SubReceive;
MainC.SoftwareInit -> UniqueReceiveP;
UniqueReceiveP.CC2420Packet -> CC2420PacketC;
}
--- NEW FILE: UniqueReceiveP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* This layer keeps a history of the past RECEIVE_HISTORY_SIZE received messages
* If the source address and dsn number of a newly received message matches
* our recent history, we drop the message because we've already seen it.
* @author David Moss
*/
#include "CC2420.h"
module UniqueReceiveP {
provides {
interface Receive;
interface Receive as DuplicateReceive;
interface Init;
}
uses {
interface Receive as SubReceive;
interface CC2420Packet;
}
}
implementation {
struct {
am_addr_t source;
uint8_t dsn;
} receivedMessages[RECEIVE_HISTORY_SIZE];
uint8_t writeIndex = 0;
/** History element containing info on a source previously received from */
uint8_t recycleSourceElement;
enum {
INVALID_ELEMENT = 0xFF,
};
/***************** Init Commands *****************/
command error_t Init.init() {
int i;
for(i = 0; i < RECEIVE_HISTORY_SIZE; i++) {
receivedMessages[i].source = (am_addr_t) 0xFFFF;
receivedMessages[i].dsn = 0;
}
return SUCCESS;
}
/***************** Prototypes Commands ***************/
bool hasSeen(uint16_t msgSource, uint8_t msgDsn);
void insert(uint16_t msgSource, uint8_t msgDsn);
/***************** Receive Commands ***************/
command void *Receive.getPayload(message_t* msg, uint8_t* len) {
return call SubReceive.getPayload(msg, len);
}
command uint8_t Receive.payloadLength(message_t* msg) {
return call SubReceive.payloadLength(msg);
}
/***************** DuplicateReceive Commands ****************/
command void *DuplicateReceive.getPayload(message_t* msg, uint8_t* len) {
return call SubReceive.getPayload(msg, len);
}
command uint8_t DuplicateReceive.payloadLength(message_t* msg) {
return call SubReceive.payloadLength(msg);
}
/***************** SubReceive Events *****************/
event message_t *SubReceive.receive(message_t* msg, void* payload,
uint8_t len) {
uint16_t msgSource = (call CC2420Packet.getHeader(msg))->src;
uint8_t msgDsn = (call CC2420Packet.getHeader(msg))->dsn;
if(hasSeen(msgSource, msgDsn)) {
return signal DuplicateReceive.receive(msg, payload, len);
} else {
insert(msgSource, msgDsn);
return signal Receive.receive(msg, payload, len);
}
}
/****************** Functions ****************/
/**
* This function does two things:
* 1. It loops through our entire receive history and detects if we've
* seen this DSN before from the given source (duplicate packet)
* 2. It detects if we've seen messages from this source before, so we know
* where to update our history if it turns out this is a new message.
*
* The global recycleSourceElement variable stores the location of the next insert
* if we've received a packet from that source before. Otherwise, it's up
* to the insert() function to decide who to kick out of our history.
*/
bool hasSeen(uint16_t msgSource, uint8_t msgDsn) {
int i;
recycleSourceElement = INVALID_ELEMENT;
atomic {
for(i = 0; i < RECEIVE_HISTORY_SIZE; i++) {
if(receivedMessages[i].source == msgSource) {
if(receivedMessages[i].dsn == msgDsn) {
// Only exit this loop if we found a duplicate packet
return TRUE;
}
recycleSourceElement = i;
}
}
}
return FALSE;
}
/**
* Insert the message into the history. If we received a message from this
* source before, insert it into the same location as last time and verify
* that the "writeIndex" is not pointing to that location. Otherwise,
* insert it into the "writeIndex" location.
*/
void insert(uint16_t msgSource, uint8_t msgDsn) {
uint8_t element = recycleSourceElement;
bool increment = FALSE;
atomic {
if(element == INVALID_ELEMENT || writeIndex == element) {
// Use the writeIndex element to insert this new message into
element = writeIndex;
increment = TRUE;
}
receivedMessages[element].source = msgSource;
receivedMessages[element].dsn = msgDsn;
if(increment) {
writeIndex++;
writeIndex %= RECEIVE_HISTORY_SIZE;
}
}
}
/***************** Defaults ****************/
default event message_t *DuplicateReceive.receive(message_t *msg, void *payload, uint8_t len) {
return msg;
}
}
--- NEW FILE: UniqueSendC.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* Generate a unique dsn byte for this outgoing packet
* This should sit at the top of the stack
* @author David Moss
*/
configuration UniqueSendC {
provides {
interface Send;
}
uses {
interface Send as SubSend;
}
}
implementation {
components UniqueSendP,
new StateC(),
RandomC,
CC2420PacketC,
MainC;
Send = UniqueSendP.Send;
SubSend = UniqueSendP.SubSend;
MainC.SoftwareInit -> UniqueSendP;
UniqueSendP.State -> StateC;
UniqueSendP.Random -> RandomC;
UniqueSendP.CC2420Packet -> CC2420PacketC;
}
--- NEW FILE: UniqueSendP.nc ---
/*
* Copyright (c) 2005-2006 Rincon Research Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the Rincon Research Corporation nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* RINCON RESEARCH OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE
*/
/**
* This layer is responsible for supplying a unique data sequence number (dsn)
* to each outgoing message.
* @author David Moss
*/
module UniqueSendP {
provides {
interface Send;
interface Init;
}
uses {
interface Send as SubSend;
interface State;
interface Random;
interface CC2420Packet;
}
}
implementation {
uint8_t localSendId;
enum {
S_IDLE,
S_SENDING,
};
/***************** Init Commands ****************/
command error_t Init.init() {
localSendId = call Random.rand16();
return SUCCESS;
}
/***************** Send Commands ****************/
/**
* Each call to this send command gives the message a single
* DSN that does not change for every copy of the message
* sent out. For messages that are not acknowledged, such as
* a broadcast address message, the receiving end does not
* signal receive() more than once for that message.
*/
command error_t Send.send(message_t *msg, uint8_t len) {
error_t error;
if(call State.requestState(S_SENDING) == SUCCESS) {
(call CC2420Packet.getHeader(msg))->dsn = localSendId++;
if((error = call SubSend.send(msg, len)) != SUCCESS) {
call State.toIdle();
}
return error;
}
return EBUSY;
}
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) {
return call SubSend.getPayload(msg);
}
/***************** SubSend Events ****************/
event void SubSend.sendDone(message_t *msg, error_t error) {
call State.toIdle();
signal Send.sendDone(msg, error);
}
}
Index: CC2420.h
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/cc2420/CC2420.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** CC2420.h 12 Dec 2006 18:23:05 -0000 1.4
--- CC2420.h 12 Apr 2007 17:11:11 -0000 1.5
***************
*** 30,33 ****
--- 30,34 ----
*
* @author Jonathan Hui <jhui at archrock.com>
+ * @author David Moss
* @version $Revision$ $Date$
*/
***************
*** 36,43 ****
#define __CC2420_H__
- //#include "message.h"
-
typedef uint8_t cc2420_status_t;
typedef nx_struct cc2420_header_t {
nxle_uint8_t length;
--- 37,46 ----
#define __CC2420_H__
typedef uint8_t cc2420_status_t;
+ /**
+ * CC2420 header. An I-frame (interoperability frame) header has an
+ * extra network byte specified by 6LowPAN
+ */
typedef nx_struct cc2420_header_t {
nxle_uint8_t length;
***************
*** 47,56 ****
nxle_uint16_t dest;
nxle_uint16_t src;
nxle_uint8_t type;
} cc2420_header_t;
!
typedef nx_struct cc2420_footer_t {
} cc2420_footer_t;
typedef nx_struct cc2420_metadata_t {
nx_uint8_t tx_power;
--- 50,72 ----
nxle_uint16_t dest;
nxle_uint16_t src;
+
+ /** I-Frame 6LowPAN interoperability byte */
+ #ifdef CC2420_IFRAME_TYPE
+ nxle_uint8_t network;
+ #endif
+
nxle_uint8_t type;
} cc2420_header_t;
!
! /**
! * CC2420 Packet Footer
! */
typedef nx_struct cc2420_footer_t {
} cc2420_footer_t;
+ /**
+ * CC2420 Packet metadata. Contains extra information about the message
+ * that will not be transmitted
+ */
typedef nx_struct cc2420_metadata_t {
nx_uint8_t tx_power;
***************
*** 60,65 ****
--- 76,90 ----
nx_bool ack;
nx_uint16_t time;
+ nx_uint16_t rxInterval;
+
+ /** Packet Link Metadata */
+ #ifdef PACKET_LINK
+ nx_uint16_t maxRetries;
+ nx_uint16_t retryDelay;
+ #endif
+
} cc2420_metadata_t;
+
typedef nx_struct cc2420_packet_t {
cc2420_header_t packet;
***************
*** 67,70 ****
--- 92,96 ----
} cc2420_packet_t;
+
#ifndef TOSH_DATA_LENGTH
#define TOSH_DATA_LENGTH 28
***************
*** 79,82 ****
--- 105,124 ----
#endif
+ /**
+ * Ideally, your receive history size should be equal to the number of
+ * RF neighbors your node will have
+ */
+ #ifndef RECEIVE_HISTORY_SIZE
+ #define RECEIVE_HISTORY_SIZE 4
+ #endif
+
+ /**
+ * The 6LowPAN ID has yet to be defined for a TinyOS network.
+ */
+ #ifndef TINYOS_6LOWPAN_NETWORK_ID
+ #define TINYOS_6LOWPAN_NETWORK_ID 0x0
+ #endif
+
+
enum {
// size of the header not including the length byte
***************
*** 93,96 ****
--- 135,139 ----
CC2420_TIME_SYMBOL = 2, // 2 symbols / jiffy
CC2420_BACKOFF_PERIOD = ( 20 / CC2420_TIME_SYMBOL ), // symbols
+ CC2420_MIN_BACKOFF = ( 20 / CC2420_TIME_SYMBOL ), // platform specific?
CC2420_ACK_WAIT_DELAY = 128, // jiffies
};
Index: CC2420ActiveMessageC.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x/tos/chips/cc2420/CC2420ActiveMessageC.nc,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** CC2420ActiveMessageC.nc 12 Dec 2006 18:23:05 -0000 1.4
--- CC2420ActiveMessageC.nc 12 Apr 2007 17:11:11 -0000 1.5
***************
*** 25,29 ****
* The Active Message layer for the CC2420 radio. This configuration
* just layers the AM dispatch (CC2420ActiveMessageM) on top of the
! * underlying CC2420 radio packet (CC2420CsmaRadioC), which is
* inherently an AM packet (acknowledgements based on AM destination
* addr and group). Note that snooping may not work, due to CC2420
--- 25,29 ----
* The Active Message layer for the CC2420 radio. This configuration
* just layers the AM dispatch (CC2420ActiveMessageM) on top of the
! * underlying CC2420 radio packet (CC2420CsmaCsmaCC), which is
* inherently an AM packet (acknowledgements based on AM destination
* addr and group). Note that snooping may not work, due to CC2420
***************
*** 31,34 ****
--- 31,35 ----
*
* @author Philip Levis
+ * @author David Moss
* @version $Revision$ $Date$
*/
***************
*** 46,49 ****
--- 47,53 ----
interface CC2420Packet;
interface PacketAcknowledgements;
+ interface RadioBackoff[am_id_t amId];
+ interface LowPowerListening;
+ interface PacketLink;
}
}
***************
*** 51,74 ****
components CC2420ActiveMessageP as AM;
! components CC2420CsmaC as Radio;
components ActiveMessageAddressC as Address;
! SplitControl = Radio;
! Packet = AM;
AMSend = AM;
Receive = AM.Receive;
Snoop = AM.Snoop;
AMPacket = AM;
!
! AM.SubSend -> Radio.Send;
! AM.SubReceive -> Radio.Receive;
! AM.amAddress -> Address;
! Radio.AMPacket -> AM;
!
! components CC2420PacketC;
CC2420Packet = CC2420PacketC;
PacketAcknowledgements = CC2420PacketC;
!
}
--- 55,111 ----
components CC2420ActiveMessageP as AM;
! components CC2420CsmaC as CsmaC;
components ActiveMessageAddressC as Address;
+ components UniqueSendC;
+ components UniqueReceiveC;
+ components CC2420TinyosNetworkC;
+ components CC2420PacketC;
! #if defined(LOW_POWER_LISTENING) || defined(ACK_LOW_POWER_LISTENING)
! components CC2420AckLplC as LplC;
! #elif defined(NOACK_LOW_POWER_LISTENING)
! components CC2420NoAckLplC as LplC;
! #else
! components CC2420LplDummyC as LplC;
! #endif
+ #if defined(PACKET_LINK)
+ components PacketLinkC as LinkC;
+ #else
+ components PacketLinkDummyC as LinkC;
+ #endif
+
+
+ RadioBackoff = CsmaC;
+ Packet = AM;
AMSend = AM;
Receive = AM.Receive;
Snoop = AM.Snoop;
AMPacket = AM;
! PacketLink = LinkC;
! LowPowerListening = LplC;
CC2420Packet = CC2420PacketC;
PacketAcknowledgements = CC2420PacketC;
+
+
+ // SplitControl Layers
+ SplitControl = LplC;
+ LplC.SubControl -> CsmaC;
+
+ // Send Layers
+ AM.SubSend -> UniqueSendC;
+ UniqueSendC.SubSend -> LinkC;
+ LinkC.SubSend -> LplC.Send;
+ LplC.SubSend -> CC2420TinyosNetworkC.Send;
+ CC2420TinyosNetworkC.SubSend -> CsmaC;
+
+ // Receive Layers
+ AM.SubReceive -> LplC;
+ LplC.SubReceive -> UniqueReceiveC.Receive;
+ UniqueReceiveC.SubReceive -> CC2420TinyosNetworkC.Receive;
+ CC2420TinyosNetworkC.SubReceive -> CsmaC;
! AM.amAddress -> Address;
! AM.CC2420Packet -> CC2420PacketC;
!
}
Index: CC2420ActiveMessageP.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-2.x