[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/rf2xx/layers ActiveMessageConfig.nc, NONE, 1.1 ActiveMessageLayerC.nc, NONE, 1.1 CsmaConfig.nc, NONE, 1.1 CsmaLayerC.nc, NONE, 1.1 CsmaLayerP.nc, NONE, 1.1 DummyConfig.nc, NONE, 1.1 DummyLayerC.nc, NONE, 1.1 DummyLayerP.nc, NONE, 1.1 GenericTimeSyncMessage.h, NONE, 1.1 GenericTimeSyncMessageC.nc, NONE, 1.1 GenericTimeSyncMessageP.nc, NONE, 1.1 IEEE154NetworkLayerC.nc, NONE, 1.1 IEEE154NetworkLayerP.nc, NONE, 1.1 LowPowerListeningLayerC.nc, NONE, 1.1 LowPowerListeningLayerP.nc, NONE, 1.1 MessageBufferLayerC.nc, NONE, 1.1 MessageBufferLayerP.nc, NONE, 1.1 RandomCollisionConfig.nc, NONE, 1.1 RandomCollisionLayerC.nc, NONE, 1.1 RandomCollisionLayerP.nc, NONE, 1.1 SlottedCollisionConfig.nc, NONE, 1.1 SlottedCollisionLayerC.nc, NONE, 1.1 SlottedCollisionLayerP.nc, NONE, 1.1 SoftwareAckConfig.nc, NONE, 1.1 SoftwareAckLayerC.nc, NONE, 1.1 SoftwareAckLayerP.nc, NONE, 1.1 TrafficMonitorConfig.nc, NONE, 1.1 TrafficMonitorLayerC.nc, NONE, 1.1 TrafficMonitorLayerP.nc, NONE, 1.1 UniqueConfig.nc, NONE, 1.1 UniqueLayerC.nc, NONE, 1.1 UniqueLayerP.nc, NONE, 1.1
Miklos Maroti
mmaroti at users.sourceforge.net
Tue Mar 10 13:38:00 PDT 2009
- Previous message: [Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/rf2xx/util - New directory
- Next message: [Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/rf2xx/rf230 RF230.h, NONE, 1.1 RF230ActiveMessageC.nc, NONE, 1.1 RF230ActiveMessageP.nc, NONE, 1.1 RF230DriverConfig.nc, NONE, 1.1 RF230DriverLayerC.nc, NONE, 1.1 RF230DriverLayerP.nc, NONE, 1.1 RF230Packet.h, NONE, 1.1 RF230PacketC.nc, NONE, 1.1 RF230PacketP.nc, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/rf2xx/layers
In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv25400/layers
Added Files:
ActiveMessageConfig.nc ActiveMessageLayerC.nc CsmaConfig.nc
CsmaLayerC.nc CsmaLayerP.nc DummyConfig.nc DummyLayerC.nc
DummyLayerP.nc GenericTimeSyncMessage.h
GenericTimeSyncMessageC.nc GenericTimeSyncMessageP.nc
IEEE154NetworkLayerC.nc IEEE154NetworkLayerP.nc
LowPowerListeningLayerC.nc LowPowerListeningLayerP.nc
MessageBufferLayerC.nc MessageBufferLayerP.nc
RandomCollisionConfig.nc RandomCollisionLayerC.nc
RandomCollisionLayerP.nc SlottedCollisionConfig.nc
SlottedCollisionLayerC.nc SlottedCollisionLayerP.nc
SoftwareAckConfig.nc SoftwareAckLayerC.nc SoftwareAckLayerP.nc
TrafficMonitorConfig.nc TrafficMonitorLayerC.nc
TrafficMonitorLayerP.nc UniqueConfig.nc UniqueLayerC.nc
UniqueLayerP.nc
Log Message:
moving files from rf230 to rf2xx, prepare the support of rf212
--- NEW FILE: ActiveMessageConfig.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
interface ActiveMessageConfig
{
/**
* This command is called when the message first enters the radio stack
* via the Send.send command. This should clear the packet if the user
* forgot to do so (or return EINVAL to be strict).
*/
command error_t checkPacket(message_t* msg);
}
--- NEW FILE: ActiveMessageLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
module ActiveMessageLayerC
{
provides
{
interface AMSend[am_id_t id];
interface Receive[am_id_t id];
interface Receive as Snoop[am_id_t id];
}
uses
{
interface Send as SubSend;
interface Receive as SubReceive;
interface AMPacket;
interface ActiveMessageConfig as Config;
}
}
implementation
{
/*----------------- Send -----------------*/
command error_t AMSend.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len)
{
error_t error;
error = call Config.checkPacket(msg);
if( error != SUCCESS )
return error;
call AMPacket.setSource(msg, call AMPacket.address());
call AMPacket.setGroup(msg, call AMPacket.localGroup());
call AMPacket.setType(msg, id);
call AMPacket.setDestination(msg, addr);
return call SubSend.send(msg, len);
}
inline event void SubSend.sendDone(message_t* msg, error_t error)
{
signal AMSend.sendDone[call AMPacket.type(msg)](msg, error);
}
inline command error_t AMSend.cancel[am_id_t id](message_t* msg)
{
return call SubSend.cancel(msg);
}
default event void AMSend.sendDone[am_id_t id](message_t* msg, error_t error)
{
}
inline command uint8_t AMSend.maxPayloadLength[am_id_t id]()
{
return call SubSend.maxPayloadLength();
}
inline command void* AMSend.getPayload[am_id_t id](message_t* msg, uint8_t len)
{
return call SubSend.getPayload(msg, len);
}
/*----------------- Receive -----------------*/
event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)
{
am_id_t type = call AMPacket.type(msg);
msg = call AMPacket.isForMe(msg)
? signal Receive.receive[type](msg, payload, len)
: signal Snoop.receive[type](msg, payload, len);
return msg;
}
default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len)
{
return msg;
}
default event message_t* Snoop.receive[am_id_t id](message_t* msg, void* payload, uint8_t len)
{
return msg;
}
}
--- NEW FILE: CsmaConfig.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
interface CsmaConfig
{
/**
* This command is called when the message is transmitted to
* check if it needs software clear channel assesment.
*/
async command bool requiresSoftwareCCA(message_t* msg);
}
--- NEW FILE: CsmaLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
configuration CsmaLayerC
{
provides
{
interface RadioSend;
}
uses
{
interface RadioSend as SubSend;
interface RadioCCA as SubCCA;
interface CsmaConfig as Config;
}
}
implementation
{
components CsmaLayerP;
RadioSend = CsmaLayerP;
SubSend = CsmaLayerP;
SubCCA = CsmaLayerP;
Config = CsmaLayerP;
}
--- NEW FILE: CsmaLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
#include <RadioAssert.h>
module CsmaLayerP
{
provides
{
interface RadioSend;
}
uses
{
interface CsmaConfig as Config;
interface RadioSend as SubSend;
interface RadioCCA as SubCCA;
}
}
implementation
{
tasklet_norace message_t *txMsg;
tasklet_norace uint8_t state;
enum
{
STATE_READY = 0,
STATE_CCA_WAIT = 1,
STATE_SEND = 2,
};
tasklet_async event void SubSend.ready()
{
if( state == STATE_READY )
signal RadioSend.ready();
}
tasklet_async command error_t RadioSend.send(message_t* msg)
{
error_t error;
if( state == STATE_READY )
{
if( call Config.requiresSoftwareCCA(msg) )
{
txMsg = msg;
if( (error = call SubCCA.request()) == SUCCESS )
state = STATE_CCA_WAIT;
}
else if( (error = call SubSend.send(msg)) == SUCCESS )
state = STATE_SEND;
}
else
error = EBUSY;
return error;
}
tasklet_async event void SubCCA.done(error_t error)
{
ASSERT( state == STATE_CCA_WAIT );
if( error == SUCCESS && (error = call SubSend.send(txMsg)) == SUCCESS )
state = STATE_SEND;
else
{
state = STATE_READY;
signal RadioSend.sendDone(EBUSY);
}
}
tasklet_async event void SubSend.sendDone(error_t error)
{
ASSERT( state == STATE_SEND );
state = STATE_READY;
signal RadioSend.sendDone(error);
}
}
--- NEW FILE: DummyConfig.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
interface DummyConfig
{
/**
* We need to put something here, but this is not going to get called
*/
async command void nothing();
}
--- NEW FILE: DummyLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
generic configuration DummyLayerC()
{
provides
{
interface SplitControl;
interface Send;
interface Receive;
interface LowPowerListening;
interface RadioState;
interface RadioSend;
interface RadioReceive;
interface RadioCCA;
interface DummyConfig as UnconnectedConfig;
}
uses
{
interface RadioState as SubState;
interface RadioSend as SubRadioSend;
interface RadioReceive as SubRadioReceive;
interface RadioCCA as SubRadioCCA;
interface SplitControl as SubControl;
interface Send as SubSend;
interface Receive as SubReceive;
interface DummyConfig as Config;
}
}
implementation
{
RadioState = SubState;
RadioSend = SubRadioSend;
RadioReceive = SubRadioReceive;
RadioCCA = SubRadioCCA;
SplitControl = SubControl;
Send = SubSend;
Receive = SubReceive;
Config = UnconnectedConfig;
components DummyLayerP;
LowPowerListening = DummyLayerP.LowPowerListening;
}
--- NEW FILE: DummyLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
module DummyLayerP
{
provides interface LowPowerListening;
}
implementation
{
command void LowPowerListening.setLocalSleepInterval(uint16_t sleepIntervalMs) { }
command uint16_t LowPowerListening.getLocalSleepInterval() { return 0; }
command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle) { }
command uint16_t LowPowerListening.getLocalDutyCycle() { return 10000; }
command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t sleepIntervalMs) { }
command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg) { return 0; }
command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle) { }
command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg) { return 10000; }
command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle) { return 0; }
command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t sleepInterval) { return 10000; }
}
--- NEW FILE: GenericTimeSyncMessage.h ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#ifndef __GENERICTIMESYNCMESSAGE_H__
#define __GENERICTIMESYNCMESSAGE_H__
// this value is sent in the air
typedef nx_int32_t timesync_relative_t;
// this value is stored in memory
typedef uint32_t timesync_absolute_t;
#endif//__GENERICTIMESYNCMESSAGE_H__
--- NEW FILE: GenericTimeSyncMessageC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Timer.h>
#include <AM.h>
#include <RadioConfig.h>
configuration GenericTimeSyncMessageC
{
provides
{
interface SplitControl;
interface Receive[uint8_t id];
interface Receive as Snoop[am_id_t id];
interface Packet;
interface AMPacket;
interface TimeSyncAMSend<TRadio, uint32_t> as TimeSyncAMSendRadio[am_id_t id];
interface TimeSyncPacket<TRadio, uint32_t> as TimeSyncPacketRadio;
interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[am_id_t id];
interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
}
uses
{
interface PacketField<uint8_t> as PacketTimeSyncOffset;
interface LocalTime<TRadio> as LocalTimeRadio;
}
}
implementation
{
components GenericTimeSyncMessageP, ActiveMessageC, LocalTimeMilliC;
TimeSyncAMSendRadio = GenericTimeSyncMessageP;
TimeSyncPacketRadio = GenericTimeSyncMessageP;
TimeSyncAMSendMilli = GenericTimeSyncMessageP;
TimeSyncPacketMilli = GenericTimeSyncMessageP;
Packet = GenericTimeSyncMessageP;
GenericTimeSyncMessageP.SubSend -> ActiveMessageC.AMSend;
GenericTimeSyncMessageP.SubPacket -> ActiveMessageC.Packet;
GenericTimeSyncMessageP.PacketTimeStampRadio -> ActiveMessageC;
GenericTimeSyncMessageP.PacketTimeStampMilli -> ActiveMessageC;
GenericTimeSyncMessageP.LocalTimeRadio = LocalTimeRadio;
GenericTimeSyncMessageP.LocalTimeMilli -> LocalTimeMilliC;
GenericTimeSyncMessageP.PacketTimeSyncOffset = PacketTimeSyncOffset;
SplitControl = ActiveMessageC;
Receive = ActiveMessageC.Receive;
Snoop = ActiveMessageC.Snoop;
AMPacket = ActiveMessageC;
}
--- NEW FILE: GenericTimeSyncMessageP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <GenericTimeSyncMessage.h>
#include <RadioConfig.h>
module GenericTimeSyncMessageP
{
provides
{
interface TimeSyncAMSend<TRadio, uint32_t> as TimeSyncAMSendRadio[uint8_t id];
interface TimeSyncAMSend<TMilli, uint32_t> as TimeSyncAMSendMilli[uint8_t id];
interface Packet;
interface TimeSyncPacket<TRadio, uint32_t> as TimeSyncPacketRadio;
interface TimeSyncPacket<TMilli, uint32_t> as TimeSyncPacketMilli;
}
uses
{
interface AMSend as SubSend[uint8_t id];
interface Packet as SubPacket;
interface PacketTimeStamp<TRadio, uint32_t> as PacketTimeStampRadio;
interface PacketTimeStamp<TMilli, uint32_t> as PacketTimeStampMilli;
interface LocalTime<TRadio> as LocalTimeRadio;
interface LocalTime<TMilli> as LocalTimeMilli;
interface PacketField<uint8_t> as PacketTimeSyncOffset;
}
}
implementation
{
inline void* getFooter(message_t* msg)
{
// we use the payload length that we export (the smaller one)
return msg->data + call Packet.payloadLength(msg);
}
/*----------------- Packet -----------------*/
command void Packet.clear(message_t* msg)
{
call SubPacket.clear(msg);
}
command void Packet.setPayloadLength(message_t* msg, uint8_t len)
{
call SubPacket.setPayloadLength(msg, len + sizeof(timesync_relative_t));
}
command uint8_t Packet.payloadLength(message_t* msg)
{
return call SubPacket.payloadLength(msg) - sizeof(timesync_relative_t);
}
command uint8_t Packet.maxPayloadLength()
{
return call SubPacket.maxPayloadLength() - sizeof(timesync_relative_t);
}
command void* Packet.getPayload(message_t* msg, uint8_t len)
{
return call SubPacket.getPayload(msg, len + sizeof(timesync_relative_t));
}
/*----------------- TimeSyncAMSendRadio -----------------*/
command error_t TimeSyncAMSendRadio.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
{
*(timesync_absolute_t*)(msg->data + len) = event_time;
call PacketTimeSyncOffset.set(msg, len);
return call SubSend.send[id](addr, msg, len + sizeof(timesync_relative_t));
}
command error_t TimeSyncAMSendRadio.cancel[am_id_t id](message_t* msg)
{
return call SubSend.cancel[id](msg);
}
default event void TimeSyncAMSendRadio.sendDone[am_id_t id](message_t* msg, error_t error)
{
}
command uint8_t TimeSyncAMSendRadio.maxPayloadLength[am_id_t id]()
{
return call SubSend.maxPayloadLength[id]() - sizeof(timesync_relative_t);
}
command void* TimeSyncAMSendRadio.getPayload[am_id_t id](message_t* msg, uint8_t len)
{
return call SubSend.getPayload[id](msg, len + sizeof(timesync_relative_t));
}
/*----------------- TimeSyncAMSendMilli -----------------*/
command error_t TimeSyncAMSendMilli.send[am_id_t id](am_addr_t addr, message_t* msg, uint8_t len, uint32_t event_time)
{
// compute elapsed time in millisecond
event_time = ((int32_t)(event_time - call LocalTimeMilli.get()) << RADIO_ALARM_MILLI_EXP) + call LocalTimeRadio.get();
return call TimeSyncAMSendRadio.send[id](addr, msg, len, event_time);
}
command error_t TimeSyncAMSendMilli.cancel[am_id_t id](message_t* msg)
{
return call TimeSyncAMSendRadio.cancel[id](msg);
}
default event void TimeSyncAMSendMilli.sendDone[am_id_t id](message_t* msg, error_t error)
{
}
command uint8_t TimeSyncAMSendMilli.maxPayloadLength[am_id_t id]()
{
return call TimeSyncAMSendRadio.maxPayloadLength[id]();
}
command void* TimeSyncAMSendMilli.getPayload[am_id_t id](message_t* msg, uint8_t len)
{
return call TimeSyncAMSendRadio.getPayload[id](msg, len);
}
/*----------------- SubSend.sendDone -------------------*/
event void SubSend.sendDone[am_id_t id](message_t* msg, error_t error)
{
signal TimeSyncAMSendRadio.sendDone[id](msg, error);
signal TimeSyncAMSendMilli.sendDone[id](msg, error);
}
/*----------------- TimeSyncPacketRadio -----------------*/
command bool TimeSyncPacketRadio.isValid(message_t* msg)
{
timesync_relative_t* timesync = getFooter(msg);
return call PacketTimeStampRadio.isValid(msg) && *timesync != 0x80000000L;
}
command uint32_t TimeSyncPacketRadio.eventTime(message_t* msg)
{
timesync_relative_t* timesync = getFooter(msg);
return (*timesync) + call PacketTimeStampRadio.timestamp(msg);
}
/*----------------- TimeSyncPacketMilli -----------------*/
command bool TimeSyncPacketMilli.isValid(message_t* msg)
{
timesync_relative_t* timesync = getFooter(msg);
return call PacketTimeStampMilli.isValid(msg) && *timesync != 0x80000000L;
}
command uint32_t TimeSyncPacketMilli.eventTime(message_t* msg)
{
timesync_relative_t* timesync = getFooter(msg);
return ((int32_t)(*timesync) >> RADIO_ALARM_MILLI_EXP) + call PacketTimeStampMilli.timestamp(msg);
}
}
--- NEW FILE: IEEE154NetworkLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
configuration IEEE154NetworkLayerC
{
provides
{
interface SplitControl;
interface Send;
interface Receive;
}
uses
{
interface SplitControl as SubControl;
interface Send as SubSend;
interface Receive as SubReceive;
}
}
implementation
{
components IEEE154NetworkLayerP, IEEE154PacketC;
SplitControl = SubControl;
Send = IEEE154NetworkLayerP;
Receive = IEEE154NetworkLayerP;
SubSend = IEEE154NetworkLayerP;
SubReceive = IEEE154NetworkLayerP;
IEEE154NetworkLayerP.IEEE154Packet -> IEEE154PacketC;
}
--- NEW FILE: IEEE154NetworkLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
module IEEE154NetworkLayerP
{
provides
{
interface Send;
interface Receive;
interface Receive as NonTinyosReceive[uint8_t network];
}
uses
{
interface Send as SubSend;
interface Receive as SubReceive;
interface IEEE154Packet;
}
}
implementation
{
#ifndef TINYOS_6LOWPAN_NETWORK_ID
#define TINYOS_6LOWPAN_NETWORK_ID 0x3f
#endif
command error_t Send.send(message_t* msg, uint8_t len)
{
call IEEE154Packet.set6LowPan(msg, TINYOS_6LOWPAN_NETWORK_ID);
return call SubSend.send(msg, len);
}
command error_t Send.cancel(message_t* msg)
{
return call SubSend.cancel(msg);
}
command uint8_t Send.maxPayloadLength()
{
return call SubSend.maxPayloadLength();
}
command void* Send.getPayload(message_t* msg, uint8_t len)
{
return call SubSend.getPayload(msg, len);
}
event void SubSend.sendDone(message_t* msg, error_t error)
{
signal Send.sendDone(msg, error);
}
event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len)
{
uint8_t network = call IEEE154Packet.get6LowPan(msg);
if( network == TINYOS_6LOWPAN_NETWORK_ID )
return signal Receive.receive(msg, payload, len);
else
return signal NonTinyosReceive.receive[network](msg, payload, len);
}
default event message_t *NonTinyosReceive.receive[uint8_t network](message_t *msg, void *payload, uint8_t len)
{
return msg;
}
}
--- NEW FILE: LowPowerListeningLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#warning "*** USING LOW POWER LISTENING LAYER"
configuration LowPowerListeningLayerC
{
provides
{
interface SplitControl;
interface Send;
interface Receive;
interface LowPowerListening;
}
uses
{
interface SplitControl as SubControl;
interface Send as SubSend;
interface Receive as SubReceive;
interface PacketField<uint16_t> as PacketSleepInterval;
interface IEEE154Packet;
interface PacketAcknowledgements;
}
}
implementation
{
components LowPowerListeningLayerP, new TimerMilliC();
SplitControl = LowPowerListeningLayerP;
Send = LowPowerListeningLayerP;
Receive = LowPowerListeningLayerP;
LowPowerListening = LowPowerListeningLayerP;
SubControl = LowPowerListeningLayerP;
SubSend = LowPowerListeningLayerP;
SubReceive = LowPowerListeningLayerP;
PacketSleepInterval = LowPowerListeningLayerP;
IEEE154Packet = LowPowerListeningLayerP;
PacketAcknowledgements = LowPowerListeningLayerP;
LowPowerListeningLayerP.Timer -> TimerMilliC;
}
--- NEW FILE: LowPowerListeningLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <RadioAssert.h>
module LowPowerListeningLayerP
{
provides
{
interface SplitControl;
interface Send;
interface Receive;
interface LowPowerListening;
}
uses
{
interface SplitControl as SubControl;
interface Send as SubSend;
interface Receive as SubReceive;
interface PacketField<uint16_t> as PacketSleepInterval;
interface IEEE154Packet;
interface PacketAcknowledgements;
interface Timer<TMilli>;
}
}
implementation
{
enum
{
// minimum wakeup time to catch a transmission in milliseconds
LISTEN_WAKEUP = 6U, // use xxxL if LISTEN_WAKEUP * 10000 > 65535
// extra wakeup time after receiving a message in milliseconds
AFTER_RECEIVE = 10U,
// extra wakeup time after transmitting a message in milliseconds
AFTER_TRANSMIT = 10U,
MIN_SLEEP = 2, // the minimum sleep interval in milliseconds
MAX_SLEEP = 30000, // the maximum sleep interval in milliseconds
MIN_DUTY = 2, // the minimum duty cycle
};
uint16_t sleepInterval;
message_t* txMsg;
uint8_t txLen;
error_t txError;
/*----------------- state machine -----------------*/
enum
{
OFF = 0,
OFF_SUBSTOP = 1, // must have consecutive indices
OFF_SUBSTOP_DONE = 2, // must have consecutive indices
OFF_STOP_END = 3, // must have consecutive indices
OFF_START_END = 4,
LISTEN_SUBSTART = 5, // must have consecutive indices
LISTEN_SUBSTART_DONE = 6, // must have consecutive indices
LISTEN_TIMER = 7, // must have consecutive indices
LISTEN = 8, // must have consecutive indices
SLEEP_SUBSTOP = 9, // must have consecutive indices
SLEEP_SUBSTOP_DONE = 10, // must have consecutive indices
SLEEP_TIMER = 11, // must have consecutive indices
SLEEP = 12, // must have consecutive indices
SEND_SUBSTART = 13, // must have consecutive indices
SEND_SUBSTART_DONE = 14, // must have consecutive indices
SEND_TIMER = 15, // must have consecutive indices
SEND_SUBSEND= 16,
SEND_SUBSEND_DONE = 17,
SEND_SUBSEND_DONE_LAST = 18,
SEND_DONE = 19,
};
uint8_t state;
task void transition()
{
error_t error;
uint16_t transmitInterval;
if( state == LISTEN_SUBSTART || state == SEND_SUBSTART )
{
error = call SubControl.start();
ASSERT( error == SUCCESS || error == EBUSY );
if( error == SUCCESS )
++state;
else
post transition();
}
else if( state == SLEEP_SUBSTOP || state == OFF_SUBSTOP )
{
error = call SubControl.stop();
ASSERT( error == SUCCESS || error == EBUSY );
if( error == SUCCESS )
++state;
else
post transition();
}
else if( state == OFF_START_END )
{
state = LISTEN_SUBSTART;
post transition();
signal SplitControl.startDone(SUCCESS);
}
else if( state == OFF_STOP_END )
{
state = OFF;
signal SplitControl.stopDone(SUCCESS);
}
else if( state == LISTEN_TIMER )
{
state = LISTEN;
if( sleepInterval > 0 )
call Timer.startOneShot(LISTEN_WAKEUP);
}
else if( state == SLEEP_TIMER )
{
if( sleepInterval > 0 )
{
state = SLEEP;
call Timer.startOneShot(sleepInterval);
}
else
{
state = LISTEN_SUBSTART;
post transition();
}
}
else if( state == SEND_TIMER )
{
transmitInterval = call LowPowerListening.getRxSleepInterval(txMsg);
if( transmitInterval > 0 )
call Timer.startOneShot(transmitInterval);
state = SEND_SUBSEND;
post transition();
}
else if( state == SEND_SUBSEND)
{
txError = call SubSend.send(txMsg, txLen);
if( txError == SUCCESS )
state = SEND_SUBSEND_DONE;
else
{
state = SEND_DONE;
post transition();
}
}
else if( state == SEND_DONE )
{
state = LISTEN;
if( sleepInterval > 0 )
call Timer.startOneShot(AFTER_TRANSMIT);
signal Send.sendDone(txMsg, txError);
}
}
command error_t SplitControl.start()
{
if( state == OFF_START_END )
return EBUSY;
else if( state != OFF )
return EALREADY;
state = OFF_START_END;
post transition();
return SUCCESS;
}
event void SubControl.startDone(error_t error)
{
ASSERT( error == SUCCESS || error == EBUSY );
ASSERT( state == LISTEN_SUBSTART_DONE || state == SEND_SUBSTART_DONE );
if( error == SUCCESS )
++state;
else
--state;
post transition();
}
command error_t SplitControl.stop()
{
if( state == SLEEP || state == LISTEN )
{
call Timer.stop();
post transition();
}
if( state == LISTEN_TIMER || state == LISTEN || state == SLEEP_SUBSTOP )
state = OFF_SUBSTOP;
else if( state == SLEEP_SUBSTOP_DONE )
state = OFF_SUBSTOP_DONE;
else if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP )
state = OFF_STOP_END;
else if( state == OFF )
return EALREADY;
else
return EBUSY;
return SUCCESS;
}
event void SubControl.stopDone(error_t error)
{
ASSERT( error == SUCCESS || error == EBUSY );
ASSERT( state == SLEEP_SUBSTOP_DONE || state == OFF_SUBSTOP_DONE );
if( error == SUCCESS )
++state;
else
--state;
post transition();
}
event void Timer.fired()
{
ASSERT( state == LISTEN || state == SLEEP || state == SEND_SUBSEND || state == SEND_SUBSEND_DONE );
if( state == LISTEN )
state = SLEEP_SUBSTOP;
else if( state == SLEEP )
state = LISTEN_SUBSTART;
else if( state == SEND_SUBSEND_DONE )
state = SEND_SUBSEND_DONE_LAST;
else if( state == SEND_SUBSEND)
state = SEND_DONE;
post transition();
}
event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len)
{
if( state == SLEEP_SUBSTOP )
state = LISTEN;
if( state == LISTEN && sleepInterval > 0 )
call Timer.startOneShot(AFTER_RECEIVE);
return signal Receive.receive(msg, payload, len);
}
command error_t Send.send(message_t* msg, uint8_t len)
{
if( state == LISTEN || state == SLEEP )
{
call Timer.stop();
post transition();
}
if( state == LISTEN_SUBSTART || state == SLEEP_TIMER || state == SLEEP )
state = SEND_SUBSTART;
else if( state == LISTEN_SUBSTART_DONE )
state = SEND_SUBSTART_DONE;
else if( state == LISTEN_TIMER || state == SLEEP_SUBSTOP || state == LISTEN )
state = SEND_TIMER;
else
return EBUSY;
txMsg = msg;
txLen = len;
txError = FAIL;
return SUCCESS;
}
command error_t Send.cancel(message_t* msg)
{
if( state == SEND_SUBSEND )
{
call Timer.stop();
state = SEND_DONE;
txError = ECANCEL;
post transition();
return SUCCESS;
}
else if( state == SEND_SUBSEND_DONE )
{
// we stop sending the message even if SubSend.cancel was not succesfull
state = SEND_SUBSEND_DONE_LAST;
return call SubSend.cancel(txMsg);
}
else
return FAIL;
}
event void SubSend.sendDone(message_t* msg, error_t error)
{
ASSERT( state == SEND_SUBSEND_DONE || state == SEND_SUBSEND_DONE_LAST );
ASSERT( msg == txMsg );
txError = error;
// TODO: extend the PacketAcknowledgements interface with getAckRequired
if( error != SUCCESS
|| call LowPowerListening.getRxSleepInterval(msg) == 0
|| state == SEND_SUBSEND_DONE_LAST
|| (call IEEE154Packet.getAckRequired(msg) && call PacketAcknowledgements.wasAcked(msg)) )
{
call Timer.stop();
state = SEND_DONE;
}
else
state = SEND_SUBSEND;
post transition();
}
command uint8_t Send.maxPayloadLength()
{
return call SubSend.maxPayloadLength();
}
command void* Send.getPayload(message_t* msg, uint8_t len)
{
return call SubSend.getPayload(msg, len);
}
/*----------------- LowPowerListening -----------------*/
command uint16_t LowPowerListening.dutyCycleToSleepInterval(uint16_t dutyCycle)
{
if( dutyCycle >= 10000 )
return 0;
else if( dutyCycle <= MIN_DUTY )
return MAX_SLEEP;
return ((10000U * LISTEN_WAKEUP) / dutyCycle) - LISTEN_WAKEUP;
}
command uint16_t LowPowerListening.sleepIntervalToDutyCycle(uint16_t interval)
{
if( interval < MIN_SLEEP )
return 10000;
else if( interval >= MAX_SLEEP )
return MIN_DUTY;
return (10000U * LISTEN_WAKEUP) / (LISTEN_WAKEUP + interval);
}
command void LowPowerListening.setLocalSleepInterval(uint16_t interval)
{
if( interval < MIN_SLEEP )
interval = 0;
else if( interval > MAX_SLEEP )
interval = MAX_SLEEP;
sleepInterval = interval;
if( (state == LISTEN && sleepInterval == 0) || state == SLEEP )
{
call Timer.stop();
--state;
post transition();
}
}
command uint16_t LowPowerListening.getLocalSleepInterval()
{
return sleepInterval;
}
command void LowPowerListening.setLocalDutyCycle(uint16_t dutyCycle)
{
call LowPowerListening.setLocalSleepInterval(
call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
}
command uint16_t LowPowerListening.getLocalDutyCycle()
{
return call LowPowerListening.sleepIntervalToDutyCycle(sleepInterval);
}
command void LowPowerListening.setRxSleepInterval(message_t *msg, uint16_t interval)
{
if( interval < MIN_SLEEP )
interval = 0;
else if( interval > MAX_SLEEP )
interval = MAX_SLEEP;
call PacketSleepInterval.set(msg, interval);
}
command uint16_t LowPowerListening.getRxSleepInterval(message_t *msg)
{
if( ! call PacketSleepInterval.isSet(msg) )
return sleepInterval;
return call PacketSleepInterval.get(msg);
}
command void LowPowerListening.setRxDutyCycle(message_t *msg, uint16_t dutyCycle)
{
call LowPowerListening.setRxSleepInterval(msg,
call LowPowerListening.dutyCycleToSleepInterval(dutyCycle));
}
command uint16_t LowPowerListening.getRxDutyCycle(message_t *msg)
{
return call LowPowerListening.sleepIntervalToDutyCycle(
call LowPowerListening.getRxSleepInterval(msg));
}
}
--- NEW FILE: MessageBufferLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
configuration MessageBufferLayerC
{
provides
{
interface SplitControl;
interface Send;
interface Receive;
interface RadioChannel;
}
uses
{
interface RadioState;
interface RadioSend;
interface RadioReceive;
interface Packet;
}
}
implementation
{
components MessageBufferLayerP, MainC, TaskletC;
MainC.SoftwareInit -> MessageBufferLayerP;
SplitControl = MessageBufferLayerP;
Send = MessageBufferLayerP;
Receive = MessageBufferLayerP;
RadioChannel = MessageBufferLayerP;
RadioState = MessageBufferLayerP;
MessageBufferLayerP.Tasklet -> TaskletC;
RadioSend = MessageBufferLayerP;
RadioReceive = MessageBufferLayerP;
Packet = MessageBufferLayerP;
}
--- NEW FILE: MessageBufferLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
#include <RadioAssert.h>
module MessageBufferLayerP
{
provides
{
interface SplitControl;
interface Init as SoftwareInit;
interface Send;
interface Receive;
interface RadioChannel;
}
uses
{
interface RadioState;
interface Tasklet;
interface RadioSend;
interface RadioReceive;
interface Packet;
}
}
implementation
{
/*----------------- State -----------------*/
norace uint8_t state; // written only from tasks
enum
{
STATE_READY = 0,
STATE_TX_PENDING = 1,
STATE_TX_SEND = 2,
STATE_TX_DONE = 3,
STATE_TURN_ON = 4,
STATE_TURN_OFF = 5,
STATE_CHANNEL = 6,
};
command error_t SplitControl.start()
{
error_t error;
call Tasklet.suspend();
if( state != STATE_READY )
error = EBUSY;
else
error = call RadioState.turnOn();
if( error == SUCCESS )
state = STATE_TURN_ON;
call Tasklet.resume();
return error;
}
command error_t SplitControl.stop()
{
error_t error;
call Tasklet.suspend();
if( state != STATE_READY )
error = EBUSY;
else
error = call RadioState.turnOff();
if( error == SUCCESS )
state = STATE_TURN_OFF;
call Tasklet.resume();
return error;
}
command error_t RadioChannel.setChannel(uint8_t channel)
{
error_t error;
call Tasklet.suspend();
if( state != STATE_READY )
error = EBUSY;
else
error = call RadioState.setChannel(channel);
if( error == SUCCESS )
state = STATE_CHANNEL;
call Tasklet.resume();
return error;
}
command uint8_t RadioChannel.getChannel()
{
return call RadioState.getChannel();
}
task void stateDoneTask()
{
uint8_t s;
s = state;
// change the state before so we can be reentered from the event
state = STATE_READY;
if( s == STATE_TURN_ON )
signal SplitControl.startDone(SUCCESS);
else if( s == STATE_TURN_OFF )
signal SplitControl.stopDone(SUCCESS);
else if( s == STATE_CHANNEL )
signal RadioChannel.setChannelDone();
else // not our event, ignore it
state = s;
}
tasklet_async event void RadioState.done()
{
post stateDoneTask();
}
default event void SplitControl.startDone(error_t error)
{
}
default event void SplitControl.stopDone(error_t error)
{
}
default event void RadioChannel.setChannelDone()
{
}
/*----------------- Send -----------------*/
message_t* txMsg;
error_t txError;
uint8_t retries;
// Many EBUSY replies from RadioSend are normal if the channel is cognested
enum { MAX_RETRIES = 5 };
task void sendTask()
{
error_t error;
ASSERT( state == STATE_TX_PENDING || state == STATE_TX_SEND );
atomic error = txError;
if( (state == STATE_TX_SEND && error == SUCCESS) || ++retries > MAX_RETRIES )
state = STATE_TX_DONE;
else
{
call Tasklet.suspend();
error = call RadioSend.send(txMsg);
if( error == SUCCESS )
state = STATE_TX_SEND;
else if( retries == MAX_RETRIES )
state = STATE_TX_DONE;
else
state = STATE_TX_PENDING;
call Tasklet.resume();
}
if( state == STATE_TX_DONE )
{
state = STATE_READY;
signal Send.sendDone(txMsg, error);
}
}
tasklet_async event void RadioSend.sendDone(error_t error)
{
ASSERT( state == STATE_TX_SEND );
atomic txError = error;
post sendTask();
}
command error_t Send.send(message_t* msg, uint8_t len)
{
if( len > call Packet.maxPayloadLength() )
return EINVAL;
else if( state != STATE_READY )
return EBUSY;
call Packet.setPayloadLength(msg, len);
txMsg = msg;
state = STATE_TX_PENDING;
retries = 0;
post sendTask();
return SUCCESS;
}
tasklet_async event void RadioSend.ready()
{
if( state == STATE_TX_PENDING )
post sendTask();
}
tasklet_async event void Tasklet.run()
{
}
command error_t Send.cancel(message_t* msg)
{
if( state == STATE_TX_PENDING )
{
state = STATE_READY;
// TODO: check if sendDone can be called before cancel returns
signal Send.sendDone(msg, ECANCEL);
return SUCCESS;
}
else
return FAIL;
}
default event void Send.sendDone(message_t* msg, error_t error)
{
}
inline command uint8_t Send.maxPayloadLength()
{
return call Packet.maxPayloadLength();
}
inline command void* Send.getPayload(message_t* msg, uint8_t len)
{
return call Packet.getPayload(msg, len);
}
/*----------------- Receive -----------------*/
enum
{
RECEIVE_QUEUE_SIZE = 3,
};
message_t receiveQueueData[RECEIVE_QUEUE_SIZE];
message_t* receiveQueue[RECEIVE_QUEUE_SIZE];
uint8_t receiveQueueHead;
uint8_t receiveQueueSize;
command error_t SoftwareInit.init()
{
uint8_t i;
for(i = 0; i < RECEIVE_QUEUE_SIZE; ++i)
receiveQueue[i] = receiveQueueData + i;
return SUCCESS;
}
tasklet_async event bool RadioReceive.header(message_t* msg)
{
bool notFull;
// this prevents undeliverable messages to be acknowledged
atomic notFull = receiveQueueSize < RECEIVE_QUEUE_SIZE;
return notFull;
}
task void deliverTask()
{
// get rid of as many messages as possible without interveining tasks
for(;;)
{
message_t* msg;
atomic
{
if( receiveQueueSize == 0 )
return;
msg = receiveQueue[receiveQueueHead];
}
msg = signal Receive.receive(msg,
call Packet.getPayload(msg, call Packet.maxPayloadLength()),
call Packet.payloadLength(msg));
atomic
{
receiveQueue[receiveQueueHead] = msg;
if( ++receiveQueueHead >= RECEIVE_QUEUE_SIZE )
receiveQueueHead = 0;
--receiveQueueSize;
}
}
}
tasklet_async event message_t* RadioReceive.receive(message_t* msg)
{
message_t *m;
atomic
{
if( receiveQueueSize >= RECEIVE_QUEUE_SIZE )
m = msg;
else
{
uint8_t index = receiveQueueHead + receiveQueueSize;
if( index >= RECEIVE_QUEUE_SIZE )
index -= RECEIVE_QUEUE_SIZE;
m = receiveQueue[index];
receiveQueue[index] = msg;
++receiveQueueSize;
post deliverTask();
}
}
return m;
}
default event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len)
{
return msg;
}
}
--- NEW FILE: RandomCollisionConfig.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
interface RandomCollisionConfig
{
/**
* Returns the initial amount of maximum backoff for this message.
*/
async command uint16_t getInitialBackoff(message_t* msg);
/**
* Returns the amount of maximum backoff when there is congestion
* (the channel was busy for the first try)
*/
async command uint16_t getCongestionBackoff(message_t* msg);
/**
* Returns the minimum ticks before the message could be sent.
*/
async command uint16_t getMinimumBackoff();
/**
* The provided message was just received, and this command should return
* the time till no transmission should be initiated.
*/
async command uint16_t getTransmitBarrier(message_t* msg);
}
--- NEW FILE: RandomCollisionLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
configuration RandomCollisionLayerC
{
provides
{
interface RadioSend;
interface RadioReceive;
}
uses
{
interface RadioSend as SubSend;
interface RadioReceive as SubReceive;
interface RandomCollisionConfig as Config;
}
}
implementation
{
components RandomCollisionLayerP, RadioAlarmC, RandomC;
RadioSend = RandomCollisionLayerP;
SubSend = RandomCollisionLayerP;
Config = RandomCollisionLayerP;
RadioReceive = RandomCollisionLayerP;
SubReceive = RandomCollisionLayerP;
RandomCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
RandomCollisionLayerP.Random -> RandomC;
}
--- NEW FILE: RandomCollisionLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
#include <RadioAssert.h>
module RandomCollisionLayerP
{
provides
{
interface RadioSend;
interface RadioReceive;
}
uses
{
interface RadioSend as SubSend;
interface RadioReceive as SubReceive;
interface RadioAlarm;
interface Random;
interface RandomCollisionConfig as Config;
}
}
implementation
{
tasklet_norace uint8_t state;
enum
{
STATE_READY = 0,
STATE_TX_PENDING_FIRST = 1,
STATE_TX_PENDING_SECOND = 2,
STATE_TX_SENDING = 3,
STATE_BARRIER = 0x80,
};
tasklet_norace message_t *txMsg;
tasklet_norace uint16_t txBarrier;
tasklet_async event void SubSend.ready()
{
if( state == STATE_READY && call RadioAlarm.isFree() )
signal RadioSend.ready();
}
uint16_t nextRandom;
task void calcNextRandom()
{
uint16_t a = call Random.rand16();
atomic nextRandom = a;
}
uint16_t getBackoff(uint16_t maxBackoff)
{
uint16_t a;
atomic
{
a = nextRandom;
nextRandom += 273;
}
post calcNextRandom();
return (a % maxBackoff) + call Config.getMinimumBackoff();
}
tasklet_async command error_t RadioSend.send(message_t* msg)
{
if( state != STATE_READY || ! call RadioAlarm.isFree() )
return EBUSY;
txMsg = msg;
state = STATE_TX_PENDING_FIRST;
call RadioAlarm.wait(getBackoff(call Config.getInitialBackoff(msg)));
return SUCCESS;
}
tasklet_async event void RadioAlarm.fired()
{
error_t error;
int16_t delay;
ASSERT( state != STATE_READY );
delay = (int16_t)txBarrier - call RadioAlarm.getNow();
if( state == STATE_BARRIER )
{
state = STATE_READY;
signal RadioSend.ready();
return;
}
else if( (state & STATE_BARRIER) && delay > 0 )
error = EBUSY;
else
error = call SubSend.send(txMsg);
if( error != SUCCESS )
{
if( (state & ~STATE_BARRIER) == STATE_TX_PENDING_FIRST )
{
state = (state & STATE_BARRIER) | STATE_TX_PENDING_SECOND;
call RadioAlarm.wait(getBackoff(call Config.getCongestionBackoff(txMsg)));
}
else
{
if( (state & STATE_BARRIER) && delay > 0 )
{
state = STATE_BARRIER;
call RadioAlarm.wait(delay);
}
else
state = STATE_READY;
signal RadioSend.sendDone(error);
}
}
else
state = STATE_TX_SENDING;
}
tasklet_async event void SubSend.sendDone(error_t error)
{
ASSERT( state == STATE_TX_SENDING );
state = STATE_READY;
signal RadioSend.sendDone(error);
}
tasklet_async event bool SubReceive.header(message_t* msg)
{
return signal RadioReceive.header(msg);
}
tasklet_async event message_t* SubReceive.receive(message_t* msg)
{
int16_t delay;
txBarrier = call Config.getTransmitBarrier(msg);
delay = txBarrier - call RadioAlarm.getNow();
if( delay > 0 )
{
if( state == STATE_READY )
{
call RadioAlarm.wait(delay);
state = STATE_BARRIER;
}
else
state |= STATE_BARRIER;
}
return signal RadioReceive.receive(msg);
}
}
--- NEW FILE: SlottedCollisionConfig.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
interface SlottedCollisionConfig
{
/**
* This command should return the approximate transmit delay between
* setting an alarm, waiting for the fire event, calling send and
* obtaining the timestamp for the transmitted message.
*/
async command uint16_t getInitialDelay();
/**
* Must return a binary exponent so that the collision avoidance layer
* can assign slots in the range of [0, 1 << exponent) of size collision
* window.
*/
async command uint8_t getScheduleExponent();
/**
* This command must return the time when the message was transmitted.
*/
async command uint16_t getTransmitTime(message_t* msg);
/**
* Returns the start of the collision window for this received message,
* so transmit times in this range would be considered possible collisions.
*/
async command uint16_t getCollisionWindowStart(message_t* msg);
/**
* Returns the size of the collision window for this received message.
*/
async command uint16_t getCollisionWindowLength(message_t* msg);
/**
* This event should be called periodically to indicate the passing of
* time (maybe we should use a timer)
*/
tasklet_async event void timerTick();
}
--- NEW FILE: SlottedCollisionLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
configuration SlottedCollisionLayerC
{
provides
{
interface RadioSend;
interface RadioReceive;
}
uses
{
interface RadioSend as SubSend;
interface RadioReceive as SubReceive;
interface SlottedCollisionConfig as Config;
}
}
implementation
{
components SlottedCollisionLayerP, MainC, RadioAlarmC, RandomC;
RadioSend = SlottedCollisionLayerP;
RadioReceive = SlottedCollisionLayerP;
SubSend = SlottedCollisionLayerP;
SubReceive = SlottedCollisionLayerP;
Config = SlottedCollisionLayerP;
SlottedCollisionLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
SlottedCollisionLayerP.Random -> RandomC;
MainC.SoftwareInit -> SlottedCollisionLayerP;
#ifdef RADIO_DEBUG
components DiagMsgC;
SlottedCollisionLayerP.DiagMsg -> DiagMsgC;
#endif
}
--- NEW FILE: SlottedCollisionLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
#include <RadioAssert.h>
module SlottedCollisionLayerP
{
provides
{
interface RadioSend;
interface RadioReceive;
interface Init;
}
uses
{
interface RadioSend as SubSend;
interface RadioReceive as SubReceive;
interface RadioAlarm;
interface Random;
interface SlottedCollisionConfig as Config;
#ifdef RADIO_DEBUG
interface DiagMsg;
#endif
}
}
implementation
{
/* ----- random ----- */
uint16_t nextRandom;
task void calcNextRandom()
{
uint16_t a = call Random.rand16();
atomic nextRandom = a;
}
uint16_t getNextRandom()
{
uint16_t a;
atomic
{
a = nextRandom;
nextRandom += 273;
}
post calcNextRandom();
return a;
}
/* ----- schedule selection ----- */
tasklet_async event bool SubReceive.header(message_t* msg)
{
return signal RadioReceive.header(msg);
}
// WARNING!!! Do not change these values, the error values can overflow
enum
{
ERROR_DECAY = 3,
ERROR_SWITCH = 30, // should be a multiple of (1 << decay)
ERROR_COLLISION = 20, // must be less than (255 - switch) >> decay
ERROR_BUSY = 1, // must be less than collision
ERROR_INITIAL = 80, // must be less than giveup
ERROR_GIVEUP = 120, // must be less than collision * (1 << decay)
ERROR_REPRESS = 40, // must be more than switch
ERROR_MAX = 255,
};
/**
* Returns TRUE if time is between start and start + window
* modulo the schedule size of (1 << exponent)
*/
inline bool isBetween(uint8_t exponent, uint16_t time, uint16_t start, uint16_t length)
{
return (uint16_t)((time - start) & ((1 << exponent) - 1)) < length;
}
tasklet_norace uint16_t schedule1;
tasklet_norace uint16_t schedule2;
tasklet_norace uint8_t error1;
tasklet_norace uint8_t error2;
tasklet_async event message_t* SubReceive.receive(message_t* msg)
{
uint8_t exponent = call Config.getScheduleExponent();
uint16_t start = call Config.getCollisionWindowStart(msg);
uint16_t length = call Config.getCollisionWindowLength(msg);
error1 -= error1 >> ERROR_DECAY;
if( isBetween(exponent, schedule1, start, length) )
error1 += ERROR_COLLISION;
error2 -= error2 >> ERROR_DECAY;
if( isBetween(exponent, schedule2, start, length) )
error2 += ERROR_COLLISION;
if( error2 + ERROR_SWITCH <= error1 )
{
error1 = error2;
schedule1 = schedule2;
error2 = ERROR_GIVEUP;
}
if( error2 >= ERROR_GIVEUP )
{
error2 = ERROR_INITIAL;
schedule2 = getNextRandom();
}
return signal RadioReceive.receive(msg);
}
void printStats();
tasklet_async event void Config.timerTick()
{
if( error1 >= (1 << ERROR_DECAY) )
error1 -= error1 >> ERROR_DECAY;
else if( error1 > 0 )
--error1;
if( error2 >= (1 << ERROR_DECAY) )
error2 -= error2 >> ERROR_DECAY;
else if( error2 > 0 )
--error2;
printStats();
}
/* ------ transmit ------ */
tasklet_norace uint8_t state;
enum
{
STATE_READY = 0,
STATE_PENDING = 1,
STATE_SENDING = 2,
};
enum { DELAY_DECAY = 2 };
tasklet_norace message_t *txMsg;
tasklet_norace uint16_t txDelay; // the averaged delay between schedule and timestamp
tasklet_norace uint16_t txTime; // the schedule time of transmission
tasklet_async event void SubSend.ready()
{
if( state == STATE_READY && call RadioAlarm.isFree() )
signal RadioSend.ready();
}
tasklet_async command error_t RadioSend.send(message_t* msg)
{
uint16_t backoff;
uint16_t time;
// TODO: we could supress transmission while error is large
if( state != STATE_READY || ! call RadioAlarm.isFree() || error1 >= ERROR_REPRESS )
return EBUSY;
txMsg = msg;
state = STATE_PENDING;
time = call RadioAlarm.getNow();
backoff = 1 + ((schedule1 - time - (txDelay >> DELAY_DECAY))
& ((1 << call Config.getScheduleExponent()) - 1));
backoff += getNextRandom() & (3 << call Config.getScheduleExponent());
call RadioAlarm.wait(backoff);
txTime = time + backoff;
return SUCCESS;
}
tasklet_async event void RadioAlarm.fired()
{
error_t error;
ASSERT( state == STATE_PENDING );
error = call SubSend.send(txMsg);
if( error == SUCCESS )
state = STATE_SENDING;
else
{
if( error2 + ERROR_SWITCH <= error1 )
{
error1 = error2;
schedule1 = schedule2;
error2 = ERROR_INITIAL;
schedule2 = getNextRandom();
}
else if( error1 < ERROR_MAX - ERROR_BUSY )
error1 = error1 + ERROR_BUSY;
state = STATE_READY;
signal RadioSend.sendDone(error);
}
}
tasklet_async event void SubSend.sendDone(error_t error)
{
ASSERT( state == STATE_SENDING );
if( error == SUCCESS )
{
txDelay += (call Config.getTransmitTime(txMsg) - txTime) - (txDelay >> DELAY_DECAY);
ASSERT( (txDelay >> DELAY_DECAY) < (1 << call Config.getScheduleExponent()) );
}
state = STATE_READY;
signal RadioSend.sendDone(error);
}
/* ------ init ------ */
command error_t Init.init()
{
// do not use Random here because it might not be initialized
schedule1 = (uint16_t)(TOS_NODE_ID * 1973);
schedule2 = schedule1 + 0117;
txDelay = call Config.getInitialDelay() << DELAY_DECAY;
return SUCCESS;
}
#ifdef RADIO_DEBUG
tasklet_norace uint8_t count;
void printStats()
{
if( ++count > 10 && call DiagMsg.record() )
{
count = 0;
call DiagMsg.str("slotted");
call DiagMsg.uint16(txDelay >> DELAY_DECAY);
call DiagMsg.uint16(schedule1);
call DiagMsg.uint8(error1);
call DiagMsg.uint16(schedule2);
call DiagMsg.uint8(error2);
call DiagMsg.send();
}
}
#else
void printStats() { }
#endif
}
--- NEW FILE: SoftwareAckConfig.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
interface SoftwareAckConfig
{
/**
* Returns the acknowledgement timeout (in the radio clock units),
* in which a sent packet must be acknowledged.
*/
async command uint16_t getAckTimeout();
/**
* Returns TRUE if the layer should wait for a software acknowledgement
* to be received after this packet was transmitted.
*/
async command bool requiresAckWait(message_t* msg);
/**
* Sets for the transmitted message whether it was acknowledged or not.
*/
async command void setAckReceived(message_t* msg, bool acked);
/**
* Returns TRUE if the received packet is an acknowledgement packet.
* The AckedSend layer will filter out all received acknowledgement
* packets and uses only the matching one for the acknowledgement.
*/
async command bool isAckPacket(message_t* msg);
/**
* Returns TRUE if the acknowledgement packet corresponds to the
* data packet. The acknowledgement packect was already verified
* to be a valid acknowledgement packet via the isAckPacket command.
*/
async command bool verifyAckPacket(message_t* data, message_t* ack);
/**
* Returns TRUE if the received packet needs software acknowledgements
* to be sent back to the sender.
*/
async command bool requiresAckReply(message_t* msg);
/**
* Creates an acknowledgement packet for the given data packet.
*/
async command void createAckPacket(message_t* data, message_t* ack);
/**
* This command is called when a sent packet did not receive an
* acknowledgement.
*/
tasklet_async command void reportChannelError();
}
--- NEW FILE: SoftwareAckLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
configuration SoftwareAckLayerC
{
provides
{
interface RadioSend;
interface RadioReceive;
}
uses
{
interface RadioSend as SubSend;
interface RadioReceive as SubReceive;
interface SoftwareAckConfig as Config;
}
}
implementation
{
components SoftwareAckLayerP, RadioAlarmC;
RadioSend = SoftwareAckLayerP;
RadioReceive = SoftwareAckLayerP;
SubSend = SoftwareAckLayerP;
SubReceive = SoftwareAckLayerP;
Config = SoftwareAckLayerP;
SoftwareAckLayerP.RadioAlarm -> RadioAlarmC.RadioAlarm[unique("RadioAlarm")];
}
--- NEW FILE: SoftwareAckLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
#include <RadioAssert.h>
module SoftwareAckLayerP
{
provides
{
interface RadioSend;
interface RadioReceive;
}
uses
{
interface RadioSend as SubSend;
interface RadioReceive as SubReceive;
interface RadioAlarm;
interface SoftwareAckConfig;
}
}
implementation
{
tasklet_norace uint8_t state;
enum
{
STATE_READY = 0,
STATE_DATA_SEND = 1,
STATE_ACK_WAIT = 2,
STATE_ACK_SEND = 3,
};
tasklet_norace message_t *txMsg;
tasklet_norace message_t ackMsg;
tasklet_async event void SubSend.ready()
{
if( state == STATE_READY )
signal RadioSend.ready();
}
tasklet_async command error_t RadioSend.send(message_t* msg)
{
error_t error;
if( state == STATE_READY )
{
if( (error = call SubSend.send(msg)) == SUCCESS )
{
call SoftwareAckConfig.setAckReceived(msg, FALSE);
state = STATE_DATA_SEND;
txMsg = msg;
}
}
else
error = EBUSY;
return error;
}
tasklet_async event void SubSend.sendDone(error_t error)
{
if( state == STATE_ACK_SEND )
{
// TODO: what if error != SUCCESS
ASSERT( error == SUCCESS );
state = STATE_READY;
}
else
{
ASSERT( state == STATE_DATA_SEND );
ASSERT( call RadioAlarm.isFree() );
if( error == SUCCESS && call SoftwareAckConfig.requiresAckWait(txMsg) && call RadioAlarm.isFree() )
{
call RadioAlarm.wait(call SoftwareAckConfig.getAckTimeout());
state = STATE_ACK_WAIT;
}
else
{
state = STATE_READY;
signal RadioSend.sendDone(error);
}
}
}
tasklet_async event void RadioAlarm.fired()
{
ASSERT( state == STATE_ACK_WAIT );
call SoftwareAckConfig.reportChannelError();
state = STATE_READY;
signal RadioSend.sendDone(SUCCESS); // we have sent it, but not acked
}
tasklet_async event bool SubReceive.header(message_t* msg)
{
if( call SoftwareAckConfig.isAckPacket(msg) )
return state == STATE_ACK_WAIT && call SoftwareAckConfig.verifyAckPacket(txMsg, msg);
else
return signal RadioReceive.header(msg);
}
tasklet_async event message_t* SubReceive.receive(message_t* msg)
{
bool ack = call SoftwareAckConfig.isAckPacket(msg);
ASSERT( state == STATE_ACK_WAIT || state == STATE_READY );
if( state == STATE_ACK_WAIT )
{
ASSERT( !ack || call SoftwareAckConfig.verifyAckPacket(txMsg, msg) );
call RadioAlarm.cancel();
call SoftwareAckConfig.setAckReceived(txMsg, ack);
state = STATE_READY;
signal RadioSend.sendDone(SUCCESS);
}
if( ack )
return msg;
if( call SoftwareAckConfig.requiresAckReply(msg) )
{
call SoftwareAckConfig.createAckPacket(msg, &ackMsg);
// TODO: what to do if we are busy and cannot send an ack
if( call SubSend.send(&ackMsg) == SUCCESS )
state = STATE_ACK_SEND;
else
ASSERT(FALSE);
}
return signal RadioReceive.receive(msg);
}
}
--- NEW FILE: TrafficMonitorConfig.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
interface TrafficMonitorConfig
{
/**
* Returns the frequency (in milliseconds) when the traffic averages
* should be updated.
*/
async command uint16_t getUpdatePeriod();
/**
* Returns the amount of time this message has occupied the channel.
*/
async command uint16_t getChannelTime(message_t* msg);
/**
* Returns the sender address of the message so we can calculate the
* average number of neighbors that send messages per update period.
*/
async command am_addr_t getSender(message_t* msg);
/**
* This event should be fired if we notice some anomalies in the operation
* of the channel, such as not receiving acknowledgements, missing
* sequence numbers or packets with corrupted CRC.
*/
tasklet_async event void channelError();
/**
* Returns the averaged (exponential decay) transmit channel time
* during one update period.
*/
tasklet_async event uint16_t getTransmitAverage();
/**
* Returns the averaged (exponential decay) receive channel time
* during one update period.
*/
tasklet_async event uint16_t getReceiveAverage();
/**
* Returns the averaged (exponential decay) number of neighbors
* whose messages this component receives during one update period.
*/
tasklet_async event uint8_t getNeighborAverage();
/**
* Returns the averaged error events during one update period.
*/
tasklet_async event uint8_t getErrorAverage();
/**
* This command is periodically called when the timer is fired and
* the averages are updated
*/
tasklet_async command void timerTick();
}
--- NEW FILE: TrafficMonitorLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
configuration TrafficMonitorLayerC
{
provides
{
interface RadioSend;
interface RadioReceive;
interface RadioState;
}
uses
{
interface RadioSend as SubSend;
interface RadioReceive as SubReceive;
interface RadioState as SubState;
interface TrafficMonitorConfig as Config;
}
}
implementation
{
components TrafficMonitorLayerP, new TimerMilliC() as UpdateTimerC;
components NeighborhoodC, new NeighborhoodFlagC(), TaskletC;
RadioSend = TrafficMonitorLayerP;
RadioReceive = TrafficMonitorLayerP;
RadioState = TrafficMonitorLayerP;
SubSend = TrafficMonitorLayerP;
SubReceive = TrafficMonitorLayerP;
SubState = TrafficMonitorLayerP;
Config = TrafficMonitorLayerP;
TrafficMonitorLayerP.Timer -> UpdateTimerC;
TrafficMonitorLayerP.Neighborhood -> NeighborhoodC;
TrafficMonitorLayerP.NeighborhoodFlag -> NeighborhoodFlagC;
TrafficMonitorLayerP.Tasklet -> TaskletC;
#ifdef RADIO_DEBUG
components DiagMsgC;
TrafficMonitorLayerP.DiagMsg -> DiagMsgC;
#endif
}
--- NEW FILE: TrafficMonitorLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, reportS, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
/*
* You have to make sure that the maximum channel time in one report
* period times (1 << TRAFFIC_MONITOR_DECAY) is less than 65535.
*/
#ifndef TRAFFIC_MONITOR_DECAY
#define TRAFFIC_MONITOR_DECAY 3
#endif
module TrafficMonitorLayerP
{
provides
{
interface RadioSend;
interface RadioReceive;
interface RadioState;
}
uses
{
interface TrafficMonitorConfig;
interface RadioSend as SubSend;
interface RadioReceive as SubReceive;
interface RadioState as SubState;
interface Timer<TMilli> as Timer;
interface Neighborhood;
interface NeighborhoodFlag;
interface Tasklet;
#ifdef RADIO_DEBUG
interface DiagMsg;
#endif
}
}
implementation
{
tasklet_norace message_t *txMsg;
tasklet_norace uint8_t neighborCount;
tasklet_norace uint16_t txAverage;
tasklet_norace uint16_t rxAverage;
tasklet_norace uint8_t neighborAverage;
tasklet_norace uint8_t errorAverage;
enum
{
// the maximum average value
TRAFFIC_MONITOR_UINT8_MAX = 1 << (7-TRAFFIC_MONITOR_DECAY),
// the unsignificant bits of the averaged values
TRAFFIC_MONITOR_MASK = (1 << TRAFFIC_MONITOR_DECAY) - 1,
// to get the ceiling integer value
TRAFFIC_MONITOR_ROUND_UP = (1 << TRAFFIC_MONITOR_DECAY) - 1,
};
tasklet_async event void SubSend.ready()
{
signal RadioSend.ready();
}
tasklet_async command error_t RadioSend.send(message_t* msg)
{
txMsg = msg;
return call SubSend.send(msg);
}
tasklet_async event void SubSend.sendDone(error_t error)
{
if( error == SUCCESS )
txAverage += call TrafficMonitorConfig.getChannelTime(txMsg);
signal RadioSend.sendDone(error);
}
tasklet_async event bool SubReceive.header(message_t* msg)
{
return signal RadioReceive.header(msg);
}
tasklet_async event message_t* SubReceive.receive(message_t* msg)
{
uint8_t index;
rxAverage += call TrafficMonitorConfig.getChannelTime(msg);
index = call Neighborhood.insertNode(call TrafficMonitorConfig.getSender(msg));
if( ! call NeighborhoodFlag.get(index) )
{
if( neighborCount < TRAFFIC_MONITOR_UINT8_MAX )
{
++neighborCount;
call NeighborhoodFlag.set(index);
}
}
return signal RadioReceive.receive(msg);
}
tasklet_async event void TrafficMonitorConfig.channelError()
{
if( errorAverage < 255 )
++errorAverage;
}
uint8_t debugCounter;
event void Timer.fired()
{
uint8_t fraction;
call Tasklet.suspend();
txAverage -= (txAverage >> TRAFFIC_MONITOR_DECAY);
rxAverage -= (rxAverage >> TRAFFIC_MONITOR_DECAY);
errorAverage -= (errorAverage >> TRAFFIC_MONITOR_DECAY);
// we could get stuck in the [1,7] range with no neighbors, so be more precise
fraction = neighborAverage >> TRAFFIC_MONITOR_DECAY;
if( fraction == neighborCount && (neighborAverage & TRAFFIC_MONITOR_MASK) != 0 )
--neighborAverage;
else
neighborAverage += neighborCount - fraction;
call NeighborhoodFlag.clearAll();
neighborCount = 0;
call TrafficMonitorConfig.timerTick();
call Tasklet.resume();
#ifdef RADIO_DEBUG
if( ++debugCounter >= 10 && call DiagMsg.record() )
{
debugCounter = 0;
call DiagMsg.str("traffic");
call DiagMsg.uint16(signal TrafficMonitorConfig.getTransmitAverage());
call DiagMsg.uint16(signal TrafficMonitorConfig.getReceiveAverage());
call DiagMsg.uint8(signal TrafficMonitorConfig.getNeighborAverage());
call DiagMsg.uint8(signal TrafficMonitorConfig.getErrorAverage());
call DiagMsg.send();
}
#endif
}
tasklet_async event void Tasklet.run()
{
}
tasklet_async event uint16_t TrafficMonitorConfig.getTransmitAverage()
{
return txAverage >> TRAFFIC_MONITOR_DECAY;
}
tasklet_async event uint16_t TrafficMonitorConfig.getReceiveAverage()
{
return rxAverage >> TRAFFIC_MONITOR_DECAY;
}
tasklet_async event uint8_t TrafficMonitorConfig.getNeighborAverage()
{
return (neighborAverage + TRAFFIC_MONITOR_ROUND_UP) >> TRAFFIC_MONITOR_DECAY;
}
tasklet_async event uint8_t TrafficMonitorConfig.getErrorAverage()
{
return errorAverage >> TRAFFIC_MONITOR_DECAY;
}
tasklet_async event void Neighborhood.evicted(uint8_t index) { }
enum
{
RADIO_CMD_NONE = 0,
RADIO_CMD_TURNON = 1,
RADIO_CMD_TURNOFF = 2,
};
tasklet_norace uint8_t radioCmd;
tasklet_async command error_t RadioState.turnOff()
{
radioCmd = RADIO_CMD_TURNOFF;
return call SubState.turnOff();
}
tasklet_async command error_t RadioState.standby()
{
radioCmd = RADIO_CMD_TURNOFF;
return call SubState.standby();
}
tasklet_async command error_t RadioState.turnOn()
{
radioCmd = RADIO_CMD_TURNON;
return call SubState.turnOn();
}
tasklet_async command error_t RadioState.setChannel(uint8_t channel)
{
radioCmd = RADIO_CMD_NONE;
return call SubState.setChannel(channel);
}
tasklet_async command uint8_t RadioState.getChannel()
{
return call SubState.getChannel();
}
task void startStopTimer()
{
if( radioCmd == RADIO_CMD_TURNON )
call Timer.startPeriodic(call TrafficMonitorConfig.getUpdatePeriod());
else if( radioCmd == RADIO_CMD_TURNOFF )
call Timer.stop();
}
tasklet_async event void SubState.done()
{
post startStopTimer();
signal RadioState.done();
}
}
--- NEW FILE: UniqueConfig.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
interface UniqueConfig
{
/**
* Returns the sequence number of the packet.
*/
async command uint8_t getSequenceNumber(message_t* msg);
/**
* Returns the sender of the packet.
*/
async command am_addr_t getSender(message_t* msg);
/**
* Sets the sequence number of the packet.
*/
async command void setSequenceNumber(message_t*msg, uint8_t number);
/**
* This command is called when the unqiue layer detects a missing (jump
* in the data sequence number) or a duplicate packet.
*/
tasklet_async command void reportChannelError();
}
--- NEW FILE: UniqueLayerC.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
configuration UniqueLayerC
{
provides
{
// NOTE, this is a combined layer, should be hooked up at two places
interface Send;
interface RadioReceive;
}
uses
{
interface Send as SubSend;
interface RadioReceive as SubReceive;
interface UniqueConfig as Config;
}
}
implementation
{
components UniqueLayerP, MainC, NeighborhoodC, new NeighborhoodFlagC();
MainC.SoftwareInit -> UniqueLayerP;
UniqueLayerP.Neighborhood -> NeighborhoodC;
UniqueLayerP.NeighborhoodFlag -> NeighborhoodFlagC;
Send = UniqueLayerP;
SubSend = UniqueLayerP;
RadioReceive = UniqueLayerP;
SubReceive = UniqueLayerP;
Config = UniqueLayerP;
}
--- NEW FILE: UniqueLayerP.nc ---
/*
* Copyright (c) 2007, Vanderbilt University
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose, without fee, and without written agreement is
* hereby granted, provided that the above copyright notice, the following
* two paragraphs and the author appear in all copies of this software.
*
* IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
* OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
* UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Author: Miklos Maroti
*/
#include <Tasklet.h>
#include <Neighborhood.h>
module UniqueLayerP
{
provides
{
interface Send;
interface RadioReceive;
interface Init;
}
uses
{
interface Send as SubSend;
interface RadioReceive as SubReceive;
interface UniqueConfig;
interface Neighborhood;
interface NeighborhoodFlag;
}
}
implementation
{
uint8_t sequenceNumber;
command error_t Init.init()
{
sequenceNumber = TOS_NODE_ID << 4;
return SUCCESS;
}
command error_t Send.send(message_t* msg, uint8_t len)
{
call UniqueConfig.setSequenceNumber(msg, ++sequenceNumber);
return call SubSend.send(msg, len);
}
command error_t Send.cancel(message_t* msg)
{
return call SubSend.cancel(msg);
}
event void SubSend.sendDone(message_t* msg, error_t error)
{
signal Send.sendDone(msg, error);
}
command uint8_t Send.maxPayloadLength()
{
return call SubSend.maxPayloadLength();
}
command void* Send.getPayload(message_t* msg, uint8_t len)
{
return call SubSend.getPayload(msg, len);
}
tasklet_async event bool SubReceive.header(message_t* msg)
{
// we could scan here, but better be lazy
return signal RadioReceive.header(msg);
}
tasklet_norace uint8_t receivedNumbers[NEIGHBORHOOD_SIZE];
tasklet_async event message_t* SubReceive.receive(message_t* msg)
{
uint8_t index = call Neighborhood.insertNode(call UniqueConfig.getSender(msg));
uint8_t dsn = call UniqueConfig.getSequenceNumber(msg);
if( call NeighborhoodFlag.get(index) )
{
uint8_t diff = dsn - receivedNumbers[index];
if( diff == 0 )
{
call UniqueConfig.reportChannelError();
return msg;
}
}
else
call NeighborhoodFlag.set(index);
receivedNumbers[index] = dsn;
return signal RadioReceive.receive(msg);
}
tasklet_async event void Neighborhood.evicted(uint8_t index) { }
}
- Previous message: [Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/rf2xx/util - New directory
- Next message: [Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/rf2xx/rf230 RF230.h, NONE, 1.1 RF230ActiveMessageC.nc, NONE, 1.1 RF230ActiveMessageP.nc, NONE, 1.1 RF230DriverConfig.nc, NONE, 1.1 RF230DriverLayerC.nc, NONE, 1.1 RF230DriverLayerP.nc, NONE, 1.1 RF230Packet.h, NONE, 1.1 RF230PacketC.nc, NONE, 1.1 RF230PacketP.nc, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Tinyos-2-commits
mailing list