[Tinyos-2-commits] CVS: tinyos-2.x/tos/chips/rf2xx/util IEEE154Packet.h, NONE, 1.1 IEEE154Packet.nc, NONE, 1.1 IEEE154PacketC.nc, NONE, 1.1 IEEE154PacketP.nc, NONE, 1.1 Neighborhood.h, NONE, 1.1 Neighborhood.nc, NONE, 1.1 NeighborhoodC.nc, NONE, 1.1 NeighborhoodFlag.nc, NONE, 1.1 NeighborhoodFlagC.nc, NONE, 1.1 NeighborhoodP.nc, NONE, 1.1 PacketField.nc, NONE, 1.1 RadioAlarm.nc, NONE, 1.1 RadioAlarmC.nc, NONE, 1.1 RadioAlarmP.nc, NONE, 1.1 RadioAssert.h, NONE, 1.1 RadioCCA.nc, NONE, 1.1 RadioChannel.nc, NONE, 1.1 RadioReceive.nc, NONE, 1.1 RadioSend.nc, NONE, 1.1 RadioState.nc, NONE, 1.1 Tasklet.h, NONE, 1.1 Tasklet.nc, NONE, 1.1 TaskletC.nc, NONE, 1.1

Miklos Maroti mmaroti at users.sourceforge.net
Tue Mar 10 13:38:00 PDT 2009


Update of /cvsroot/tinyos/tinyos-2.x/tos/chips/rf2xx/util
In directory ddv4jf1.ch3.sourceforge.com:/tmp/cvs-serv25400/util

Added Files:
	IEEE154Packet.h IEEE154Packet.nc IEEE154PacketC.nc 
	IEEE154PacketP.nc Neighborhood.h Neighborhood.nc 
	NeighborhoodC.nc NeighborhoodFlag.nc NeighborhoodFlagC.nc 
	NeighborhoodP.nc PacketField.nc RadioAlarm.nc RadioAlarmC.nc 
	RadioAlarmP.nc RadioAssert.h RadioCCA.nc RadioChannel.nc 
	RadioReceive.nc RadioSend.nc RadioState.nc Tasklet.h 
	Tasklet.nc TaskletC.nc 
Log Message:
moving files from rf230 to rf2xx, prepare the support of rf212

--- NEW FILE: IEEE154Packet.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 __IEEE154PACKET_H__
#define __IEEE154PACKET_H__

typedef nx_struct ieee154_header_t
{
	nxle_uint8_t length;
	nxle_uint16_t fcf;
	nxle_uint8_t dsn;
	nxle_uint16_t destpan;
	nxle_uint16_t dest;
	nxle_uint16_t src;

// I-Frame 6LowPAN interoperability byte
#ifndef TFRAMES_ENABLED	
	nxle_uint8_t network;
#endif

	nxle_uint8_t type;
} ieee154_header_t;

// the actual radio driver might not use this
typedef nx_struct ieee154_footer_t
{ 
	nxle_uint16_t crc;
} ieee154_footer_t;

enum ieee154_fcf_enums {
	IEEE154_FCF_FRAME_TYPE = 0,
	IEEE154_FCF_SECURITY_ENABLED = 3,
	IEEE154_FCF_FRAME_PENDING = 4,
	IEEE154_FCF_ACK_REQ = 5,
	IEEE154_FCF_INTRAPAN = 6,
	IEEE154_FCF_DEST_ADDR_MODE = 10,
	IEEE154_FCF_SRC_ADDR_MODE = 14,
};

enum ieee154_fcf_type_enums {
	IEEE154_TYPE_BEACON = 0,
	IEEE154_TYPE_DATA = 1,
	IEEE154_TYPE_ACK = 2,
	IEEE154_TYPE_MAC_CMD = 3,
	IEEE154_TYPE_MASK = 7,
};

enum iee154_fcf_addr_mode_enums {
	IEEE154_ADDR_NONE = 0,
	IEEE154_ADDR_SHORT = 2,
	IEEE154_ADDR_EXT = 3,
	IEEE154_ADDR_MASK = 3,
};

#endif//__IEEE154PACKET_H__

--- NEW FILE: IEEE154Packet.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 <IEEE154Packet.h>
#include <message.h>

/**
 * This interface encapsulates IEEE 802.15.4 intrapan data frames with 
 * 16-bit destination pan, source and destination addresses. It also 
 * supports 6LowPan interoperability mode, and acknowledgement frames.
 * Note, that this interface does not support the CRC-16 value, which
 * should be verified before the data can be trusted.
 */
interface IEEE154Packet
{
	/**
	 * Returns the IEEE 802.15.4 header including the length field.
	 */
	async command ieee154_header_t* getHeader(message_t* msg);

	/**
	 * Returns the raw value (unadjusted) of the length field
	 */
	async command uint8_t getLength(message_t* msg);

	/**
	 * Sets the length field
	 */
	async command void setLength(message_t* msg, uint8_t length);

	/**
	 * Returns the frame control field. This method should not be used, 
	 * isDataFrame and isAckFrame should be used instead.
	 */
	async command uint16_t getFCF(message_t* msg);

	/**
	 * Sets the frame control field. This method should not be used, 
	 * createDataFrame and createAckFrame should be used instead.
	 */
	async command void setFCF(message_t* msg, uint16_t fcf);

	/**
	 * Returns TRUE if the message is a data frame supported by 
	 * this interface (based on the value of the FCF).
	 */
	async command bool isDataFrame(message_t* msg);

	/**
	 * Sets the FCF to create a data frame supported by this interface.
	 * You may call setAckRequired and setFramePending commands after this.
	 */
	async command void createDataFrame(message_t* msg);

	/**
	 * Returns TRUE if the message is an acknowledgement frame supported
	 * by this interface (based on the value of the FCF).
	 */
	async command bool isAckFrame(message_t* msg);

	/**
	 * Sets the FCF to create an acknowledgement frame supported by
	 * this interface. You may call setFramePending after this.
	 */
	async command void createAckFrame(message_t* msg);

	/**
	 * Creates an acknowledgement packet for the given data packet.
	 * This also sets the DSN value. The data message must be a 
	 * data frame, the ack message will be overwritten.
	 */
	async command void createAckReply(message_t* data, message_t* ack);

	/**
	 * Returns TRUE if the acknowledgement packet corresponds to the
	 * data packet. The data message must be a data packet.
	 */
	async command bool verifyAckReply(message_t* data, message_t* ack);

	/**
	 * Returns TRUE if the ACK required field is set in the FCF.
	 */
	async command bool getAckRequired(message_t* msg);

	/**
	 * Sets the ACK required field in the FCF, should never be set
	 * for acknowledgement frames.
	 */
	async command void setAckRequired(message_t* msg, bool ack);

	/**
	 * Returns TRUE if the frame pending field is set in the FCF.
	 */
	async command bool getFramePending(message_t* msg);

	/**
	 * Sets the frame pending field in the FCF.
	 */
	async command void setFramePending(message_t* msg, bool pending);

	/**
	 * Returns the data sequence number
	 */
	async command uint8_t getDSN(message_t* msg);

	/**
	 * Sets the data sequence number
	 */
	async command void setDSN(message_t* msg, uint8_t dsn);

	/**
	 * returns the destination PAN id, values <= 255 are tinyos groups,
	 * valid only for data frames
	 */
	async command uint16_t getDestPan(message_t* msg);

	/**
	 * Sets the destination PAN id, valid only for data frames
	 */
	async command void setDestPan(message_t* msg, uint16_t pan);

	/**
	 * Returns the destination address, valid only for data frames
	 */
	async command uint16_t getDestAddr(message_t* msg);

	/**
	 * Sets the destination address, valid only for data frames
	 */
	async command void setDestAddr(message_t* msg, uint16_t addr);

	/**
	 * Returns the source address, valid only for data frames
	 */
	async command uint16_t getSrcAddr(message_t* msg);

	/**
	 * Sets the source address, valid only for data frames
	 */
	async command void setSrcAddr(message_t* msg, uint16_t addr);

#ifndef TFRAMES_ENABLED

	/**
	 * Returns the value of the 6LowPan network field.
	 */
	async command uint8_t get6LowPan(message_t* msg);

	/**
	 * Sets the value of the 6LowPan network field.
	 */
	async command void set6LowPan(message_t* msg, uint8_t network);

#endif

	/**
	 * Returns the active message type of the message
	 */
	async command am_id_t getType(message_t* msg);

	/**
	 * Sets the active message type
	 */
	async command void setType(message_t* msg, am_id_t type);

	/**
	 * Returns TRUE if the packet is a data packet, the ACK_REQ field
	 * is set and the destination address is not the broadcast address.
	 */
	async command bool requiresAckWait(message_t* msg);

	/**
	 * Returns TRUE if the packet is a data packet, the ACK_REQ field
	 * is set and the destionation address is this node.
	 */
	async command bool requiresAckReply(message_t* msg);
}

--- NEW FILE: IEEE154PacketC.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 IEEE154PacketC
{
	provides
	{
		interface IEEE154Packet;
		interface AMPacket;
	}
}

implementation
{
	components IEEE154PacketP, ActiveMessageAddressC;
	IEEE154PacketP.ActiveMessageAddress -> ActiveMessageAddressC;

	IEEE154Packet = IEEE154PacketP;
	AMPacket = IEEE154PacketP;
}

--- NEW FILE: IEEE154PacketP.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 <IEEE154Packet.h>

module IEEE154PacketP
{
	provides 
	{
		interface IEEE154Packet;
		interface AMPacket;
	}

	uses interface ActiveMessageAddress;
}

implementation
{
/*----------------- IEEE154Packet -----------------*/

	enum
	{
		IEEE154_DATA_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE) 
			| (1 << IEEE154_FCF_INTRAPAN) 
			| (IEEE154_ADDR_MASK << IEEE154_FCF_DEST_ADDR_MODE) 
			| (IEEE154_ADDR_MASK << IEEE154_FCF_SRC_ADDR_MODE),

		IEEE154_DATA_FRAME_VALUE = (IEEE154_TYPE_DATA << IEEE154_FCF_FRAME_TYPE) 
			| (1 << IEEE154_FCF_INTRAPAN) 
			| (IEEE154_ADDR_SHORT << IEEE154_FCF_DEST_ADDR_MODE) 
			| (IEEE154_ADDR_SHORT << IEEE154_FCF_SRC_ADDR_MODE),

		IEEE154_ACK_FRAME_LENGTH = 5,	// includes the FCF, DSN and FCS
		IEEE154_ACK_FRAME_MASK = (IEEE154_TYPE_MASK << IEEE154_FCF_FRAME_TYPE), 
		IEEE154_ACK_FRAME_VALUE = (IEEE154_TYPE_ACK << IEEE154_FCF_FRAME_TYPE),
	};

	inline ieee154_header_t* getHeader(message_t* msg)
	{
		return (ieee154_header_t*)(msg->data - sizeof(ieee154_header_t));
	}

	inline async command ieee154_header_t* IEEE154Packet.getHeader(message_t* msg)
	{
		return getHeader(msg);
	}

	inline async command uint8_t IEEE154Packet.getLength(message_t* msg)
	{
		return getHeader(msg)->length;
	}

	inline async command void IEEE154Packet.setLength(message_t* msg, uint8_t length)
	{
		getHeader(msg)->length = length;
	}

	inline async command uint16_t IEEE154Packet.getFCF(message_t* msg)
	{
		return getHeader(msg)->fcf;
	}

	inline async command void IEEE154Packet.setFCF(message_t* msg, uint16_t fcf)
	{
		getHeader(msg)->fcf = fcf;
	}

	inline async command bool IEEE154Packet.isDataFrame(message_t* msg)
	{
		return (getHeader(msg)->fcf & IEEE154_DATA_FRAME_MASK) == IEEE154_DATA_FRAME_VALUE;
	}

	inline async command void IEEE154Packet.createDataFrame(message_t* msg)
	{
		getHeader(msg)->fcf = IEEE154_DATA_FRAME_VALUE;
	}

	inline async command bool IEEE154Packet.isAckFrame(message_t* msg)
	{
		return (getHeader(msg)->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE;
	}

	inline async command void IEEE154Packet.createAckFrame(message_t* msg)
	{
		ieee154_header_t* header = getHeader(msg);

		header->length = IEEE154_ACK_FRAME_LENGTH;
		header->fcf = IEEE154_ACK_FRAME_VALUE;
	}

	inline async command void IEEE154Packet.createAckReply(message_t* data, message_t* ack)
	{
		ieee154_header_t* header = getHeader(ack);

		header->length = IEEE154_ACK_FRAME_LENGTH;
		header->fcf = IEEE154_ACK_FRAME_VALUE;
		header->dsn = getHeader(data)->dsn;
	}

	inline async command bool IEEE154Packet.verifyAckReply(message_t* data, message_t* ack)
	{
		ieee154_header_t* header = getHeader(ack);

		return header->dsn == getHeader(data)->dsn
			&& (header->fcf & IEEE154_ACK_FRAME_MASK) == IEEE154_ACK_FRAME_VALUE;
	}

	inline async command bool IEEE154Packet.getAckRequired(message_t* msg)
	{
		return getHeader(msg)->fcf & (1 << IEEE154_FCF_ACK_REQ);
	}

	inline async command void IEEE154Packet.setAckRequired(message_t* msg, bool ack)
	{
		if( ack )
			getHeader(msg)->fcf |= (1 << IEEE154_FCF_ACK_REQ);
		else
			getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_ACK_REQ);
	}

	inline async command bool IEEE154Packet.getFramePending(message_t* msg)
	{
		return getHeader(msg)->fcf & (1 << IEEE154_FCF_FRAME_PENDING);
	}

	inline async command void IEEE154Packet.setFramePending(message_t* msg, bool pending)
	{
		if( pending )
			getHeader(msg)->fcf |= (1 << IEEE154_FCF_FRAME_PENDING);
		else
			getHeader(msg)->fcf &= ~(uint16_t)(1 << IEEE154_FCF_FRAME_PENDING);
	}

	inline async command uint8_t IEEE154Packet.getDSN(message_t* msg)
	{
		return getHeader(msg)->dsn;
	}

	inline async command void IEEE154Packet.setDSN(message_t* msg, uint8_t dsn)
	{
		getHeader(msg)->dsn = dsn;
	}

	inline async command uint16_t IEEE154Packet.getDestPan(message_t* msg)
	{
		return getHeader(msg)->destpan;
	}

	inline async command void IEEE154Packet.setDestPan(message_t* msg, uint16_t pan)
	{
		getHeader(msg)->destpan = pan;
	}

	inline async command uint16_t IEEE154Packet.getDestAddr(message_t* msg)
	{
		return getHeader(msg)->dest;
	}

	inline async command void IEEE154Packet.setDestAddr(message_t* msg, uint16_t addr)
	{
		getHeader(msg)->dest = addr;
	}

	inline async command uint16_t IEEE154Packet.getSrcAddr(message_t* msg)
	{
		return getHeader(msg)->src;
	}

	inline async command void IEEE154Packet.setSrcAddr(message_t* msg, uint16_t addr)
	{
		getHeader(msg)->src = addr;
	}

#ifndef TFRAMES_ENABLED

	inline async command uint8_t IEEE154Packet.get6LowPan(message_t* msg)
	{
		return getHeader(msg)->network;
	}

	inline async command void IEEE154Packet.set6LowPan(message_t* msg, uint8_t network)
	{
		getHeader(msg)->network = network;
	}

#endif

	inline async command am_id_t IEEE154Packet.getType(message_t* msg)
	{
		return getHeader(msg)->type;
	}

	inline async command void IEEE154Packet.setType(message_t* msg, am_id_t type)
	{
		getHeader(msg)->type = type;
	}

	async command bool IEEE154Packet.requiresAckWait(message_t* msg)
	{
		return call IEEE154Packet.getAckRequired(msg)
			&& call IEEE154Packet.isDataFrame(msg)
			&& call IEEE154Packet.getDestAddr(msg) != 0xFFFF;
	}

	async command bool IEEE154Packet.requiresAckReply(message_t* msg)
	{
		return call IEEE154Packet.getAckRequired(msg)
			&& call IEEE154Packet.isDataFrame(msg)
			&& call IEEE154Packet.getDestAddr(msg) == call ActiveMessageAddress.amAddress();
	}

	inline async event void ActiveMessageAddress.changed()
	{
	}

/*----------------- AMPacket -----------------*/

	inline command am_addr_t AMPacket.address()
	{
		return call ActiveMessageAddress.amAddress();
	}
 
	inline command am_group_t AMPacket.localGroup()
	{
		// TODO: check if this is correct
		return call ActiveMessageAddress.amGroup();
	}

	inline command am_addr_t AMPacket.destination(message_t* msg)
	{
		return call IEEE154Packet.getDestAddr(msg);
	}
 
	inline command am_addr_t AMPacket.source(message_t* msg)
	{
		return call IEEE154Packet.getSrcAddr(msg);
	}

	inline command void AMPacket.setDestination(message_t* msg, am_addr_t addr)
	{
		call IEEE154Packet.setDestAddr(msg, addr);
	}

	inline command void AMPacket.setSource(message_t* msg, am_addr_t addr)
	{
		call IEEE154Packet.setSrcAddr(msg, addr);
	}

	inline command bool AMPacket.isForMe(message_t* msg)
	{
		am_addr_t addr = call AMPacket.destination(msg);
		return addr == call AMPacket.address() || addr == AM_BROADCAST_ADDR;
	}

	inline command am_id_t AMPacket.type(message_t* msg)
	{
		return call IEEE154Packet.getType(msg);
	}

	inline command void AMPacket.setType(message_t* msg, am_id_t type)
	{
		call IEEE154Packet.setType(msg, type);
	}
  
	inline command am_group_t AMPacket.group(message_t* msg) 
	{
		return call IEEE154Packet.getDestPan(msg);
	}

	inline command void AMPacket.setGroup(message_t* msg, am_group_t grp)
	{
		call IEEE154Packet.setDestPan(msg, grp);
	}
}

--- NEW FILE: Neighborhood.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 __NEIGHBORHOOD_H__
#define __NEIGHBORHOOD_H__

#ifndef NEIGHBORHOOD_SIZE
#define NEIGHBORHOOD_SIZE	5
#endif

#endif//__NEIGHBORHOOD_H__

--- NEW FILE: Neighborhood.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>

/**
 * Every component maintains its own neighborhood data. The Neighboorhood
 * component maintains only the nodeids and ages of the neighbors, and
 * evicts old entries from the table when necessary.
 */
interface Neighborhood
{
	/**
	 * Returns the index of the neighbor in the table. If the node was not 
	 * found in the table, then the value NEIGHBORHOOD is  returned, 
	 * otherwise an index in the range [0, NEIGHBORHOOD-1] is returned.
	 */
	tasklet_async command uint8_t getIndex(am_addr_t id);

	/**
	 * Returns the age of the given entry. The age is incremented by one
	 * every time a new node is inserted into the neighborhood table that
	 * is not already at the very end. If the age would get too large to
	 * fit into a byte, then it is periodically reset to a smaller value.
	 */
	tasklet_async command uint8_t getAge(uint8_t index);

	/**
	 * Returns the node address for the given entry.
	 */
	tasklet_async command am_addr_t getNode(uint8_t index);

	/**
	 * Adds a new node into the neighborhood table. If this node was already
	 * in the table, then it is just brought to the front (its age is reset
	 * to zero). If the node was not in the table, then the oldest is evicted
	 * and its entry is replaced with this node. The index of the entry
	 * is returned in the range [0, NEIGHBORHOOD-1]. 
	 */
	tasklet_async command uint8_t insertNode(am_addr_t id);

	/**
	 * This event is fired when the oldest entry is replaced with a new
	 * node. The same interface is used by many users, so all of them
	 * will receive this event and can clear the corresponding entry.
	 * After this event is fired, all flags for this entry are cleared
	 * (see the NeighborhoodFlag interface)
	 */
	tasklet_async event void evicted(uint8_t index);
}

--- NEW FILE: NeighborhoodC.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 NeighborhoodC
{
	provides interface Neighborhood;
}

implementation
{
	components NeighborhoodP, MainC;

	Neighborhood = NeighborhoodP;
	MainC.SoftwareInit -> NeighborhoodP;
}

--- NEW FILE: NeighborhoodFlag.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>

/**
 * This interface provides one bit storage for each neighbor in a very
 * fast and conveint way (without using shifts for example). 
 */
interface NeighborhoodFlag
{
	/**
	 * Returns the value of the flag for the given index
	 */
	tasklet_async command bool get(uint8_t index);
	
	/**
	 * Sets the flag for the given index
	 */
	tasklet_async command void set(uint8_t index);

	/**
	 * Clears the flag for the given index. The flag is automatically
	 * cleared after the Neighborhood.evicted event is fired.
	 */
	tasklet_async command void clear(uint8_t index);

	/**
	 * Clears the flag for all indices
	 */
	tasklet_async command void clearAll();
}

--- NEW FILE: NeighborhoodFlagC.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 NeighborhoodFlagC()
{
	provides interface NeighborhoodFlag;
}

implementation
{
	components NeighborhoodP;

	// TODO: make sure that no more than 8 flags are used at a time
	NeighborhoodFlag = NeighborhoodP.NeighborhoodFlag[unique("NeighborhoodFlag")];
}

--- NEW FILE: NeighborhoodP.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 <Neighborhood.h>

module NeighborhoodP
{
	provides
	{
		interface Init;
		interface Neighborhood;
		interface NeighborhoodFlag[uint8_t bit];
	}
}

implementation
{
	tasklet_norace am_addr_t nodes[NEIGHBORHOOD_SIZE];
	tasklet_norace uint8_t ages[NEIGHBORHOOD_SIZE];
	tasklet_norace uint8_t flags[NEIGHBORHOOD_SIZE];
	tasklet_norace uint8_t time;
	tasklet_norace uint8_t last;

	command error_t Init.init()
	{
		uint8_t i;

		for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
			nodes[i] = AM_BROADCAST_ADDR;
	
		return SUCCESS;
	}

	inline tasklet_async command am_addr_t Neighborhood.getNode(uint8_t index)
	{
		return nodes[index];
	}

	inline tasklet_async command uint8_t Neighborhood.getAge(uint8_t index)
	{
		return time - ages[index];
	}

	tasklet_async uint8_t command Neighborhood.getIndex(am_addr_t node)
	{
		uint8_t i;

		if( nodes[last] == node )
			return last;

		for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
		{
			if( nodes[i] == node )
			{
				last = i;
				break;
			}
		}

		return i;
	}

	tasklet_async uint8_t command Neighborhood.insertNode(am_addr_t node)
	{
		uint8_t i;
		uint8_t maxAge;

		if( nodes[last] == node )
		{
			if( ages[last] == time )
				return last;

			ages[last] = ++time;
			maxAge = 0x80;
		}
		else
		{
			uint8_t oldest = 0;
			maxAge = 0;

			for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
			{
				uint8_t age;

				if( nodes[i] == node )
				{
					last = i;
					if( ages[i] == time )
						return i;

					ages[i] = ++time;
					maxAge = 0x80;
					break;
				}

				age = time - ages[i];
				if( age > maxAge )
				{
					maxAge = age;
					oldest = i;
				}
			}

			if( i == NEIGHBORHOOD_SIZE )
			{
				signal Neighborhood.evicted(oldest);

				last = oldest;
				nodes[oldest] = node;
				ages[oldest] = ++time;
				flags[oldest] = 0;
			}
		}

		if( (time & 0x7F) == 0x7F && maxAge >= 0x7F )
		{
			for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
			{
				if( (ages[i] | 0x7F) != time )
					ages[i] = time & 0x80;
			}
		}

		return last;
	}

	inline tasklet_async command bool NeighborhoodFlag.get[uint8_t bit](uint8_t index)
	{
		return flags[index] & (1 << bit);
	}

	inline tasklet_async command void NeighborhoodFlag.set[uint8_t bit](uint8_t index)
	{
		flags[index] |= (1 << bit);
	}

	inline tasklet_async command void NeighborhoodFlag.clear[uint8_t bit](uint8_t index)
	{
		flags[index] &= ~(1 << bit);
	}

	tasklet_async command void NeighborhoodFlag.clearAll[uint8_t bit]()
	{
		uint8_t i;

		bit = ~(1 << bit);

		for(i = 0; i < NEIGHBORHOOD_SIZE; ++i)
			flags[i] &= bit;
	}
}

--- NEW FILE: PacketField.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 PacketField<value_type>
{
	/**
	 * Returns TRUE if the value is set for this message.
	 */
	async command bool isSet(message_t* msg);

	/**
	 * Returns the stored value of this field in the message. If the
	 * value is not set, then the returned value is undefined.
	 */
	async command value_type get(message_t* msg);

	/**
	 * Clears the isSet flag.
	 */
	async command void clear(message_t* msg);

	/**
	 * Sets the isSet false to TRUE and the time stamp value to the 
	 * specified value.
	 */
	async command void set(message_t* msg, value_type value);
}

--- NEW FILE: RadioAlarm.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 RadioAlarm
{
	/**
	 * Returns TRUE if the alarm is free and ready to be used. Once the alarm
	 * is free, it cannot become nonfree in the same tasklet block. Note,
	 * if the alarm is currently set (even if for ourselves) then it is not free.
	 */
	tasklet_async command bool isFree();

	/**
	 * Waits till the specified timeout period expires. The alarm must be free.
	 */
	tasklet_async command void wait(uint16_t timeout);

	/**
	 * Cancels the running alarm. The alarm must be pending.
	 */
	tasklet_async command void cancel();

	/**
	 * This event is fired when the specified timeout period expires.
	 */
	tasklet_async event void fired();

	/**
	 * Returns the current time as measured by the radio stack.
	 */
	async command uint16_t getNow();
}

--- NEW FILE: RadioAlarmC.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 RadioAlarmC
{
	provides
	{
		interface RadioAlarm[uint8_t id]; // use unique("RadioAlarm")
	}

	uses
	{
		interface Alarm<TRadio, uint16_t> @exactlyonce();
	}
}

implementation
{
	components RadioAlarmP, TaskletC;

	RadioAlarm = RadioAlarmP;
	Alarm = RadioAlarmP;
	RadioAlarmP.Tasklet -> TaskletC;
}

--- NEW FILE: RadioAlarmP.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 RadioAlarmP
{
	provides
	{
		interface RadioAlarm[uint8_t id];
	}

	uses
	{
		interface Alarm<TRadio, uint16_t>;
		interface Tasklet;
	}
}

implementation
{
	norace uint8_t state;
	enum
	{
		STATE_READY = 0,
		STATE_WAIT = 1,
		STATE_FIRED = 2,
	};

	tasklet_norace uint8_t alarm;

	async event void Alarm.fired()
	{
		atomic
		{
			if( state == STATE_WAIT )
				state = STATE_FIRED;
		}

		call Tasklet.schedule();
	}

	inline async command uint16_t RadioAlarm.getNow[uint8_t id]()
	{
		return call Alarm.getNow();
	}

	tasklet_async event void Tasklet.run()
	{
		if( state == STATE_FIRED )
		{
			state = STATE_READY;
			signal RadioAlarm.fired[alarm]();
		}
	}

	default tasklet_async event void RadioAlarm.fired[uint8_t id]()
	{
	}

	inline tasklet_async command bool RadioAlarm.isFree[uint8_t id]()
	{
		return state == STATE_READY;
	}

	tasklet_async command void RadioAlarm.wait[uint8_t id](uint16_t timeout)
	{
		ASSERT( state == STATE_READY );

		alarm = id;
		state = STATE_WAIT;
		call Alarm.start(timeout);
	}

	tasklet_async command void RadioAlarm.cancel[uint8_t id]()
	{
		ASSERT( alarm == id );
		ASSERT( state != STATE_READY );

		call Alarm.stop();
		state = STATE_READY;
	}
}

--- NEW FILE: RadioAssert.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 __RADIOASSERT_H__
#define __RADIOASSERT_H__

#ifdef RADIO_DEBUG

	void assert(bool condition, const char* file, uint16_t line);
	#define ASSERT(COND) assert(COND, __FILE__, __LINE__)

#else

	#define ASSERT(COND) for(;0;)

#endif

#endif//__RADIOASSERT_H__

--- NEW FILE: RadioCCA.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 RadioCCA
{
	/**
	 * Starts the clear channel assesment procedure. Returns EBUSY if the radio
	 * is currently servicing a clear channel assesment, and SUCCESS otherwise.
	 * The check will be performed only in the RX_READY state.
	 */
	tasklet_async command error_t request();

	/**
	 * Signals the completion of the clear channel assesment send command.
	 * SUCCESS means the channel is clear, EBUSY means the channel is not
	 * clear, and FAIL means that the clear channel assesment could not
	 * be finished or the operation was cancelled.
	 */
	tasklet_async event void done(error_t error);
}

--- NEW FILE: RadioChannel.nc ---
/*
 * Copyright (c) 2009, Vanderbilt University
 * All rights reserved.
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 * 
 * IN NO EVENT SHALL THE VANDERBILT UNIVERSITY BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE VANDERBILT
 * UNIVERSITY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * THE VANDERBILT UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE VANDERBILT UNIVERSITY HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Author: Miklos Maroti
 */

interface RadioChannel
{
	/**
	 * Sets the current channel. Returns EBUSY if the stack is unable
	 * to change the channel this time (some other operation is in progress),
	 * EALREADY if the selected channel is already set, SUCCESS otherwise.
	 */
	command error_t setChannel(uint8_t channel);

	/**
	 * This event is signaled exactly once for each sucessfully posted state 
	 * setChannel command when it is completed.
	 */
	event void setChannelDone();

	/**
	 * Returns the currently selected channel.
	 */
	command uint8_t getChannel();
}

--- NEW FILE: RadioReceive.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 RadioReceive
{
	/**
	 * This event is fired when the header is received/downloaded and the 
	 * higher layers are consulted whether it needs to be downloaded and 
	 * further processed. Return FALSE if the message should be discarded.
	 * In particular, the message buffer layer returns FALSE if there is
	 * no space for a new message, so this message will not get acknowledged.
	 */
	tasklet_async event bool header(message_t* msg);

	/**
	 * Signals the reception of a message, but only for those messages for
	 * which SUCCESS was returned in the header event. The usual owner rules 
	 * apply to the message pointers.
	 */
	tasklet_async event message_t* receive(message_t* msg);
}

--- NEW FILE: RadioSend.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 RadioSend
{
	/**
	 * Starts the transmission of the given message. This command must not
	 * be called while another send is in progress (so one must wait for the
	 * sendDone event). Returns EBUSY if a reception is in progress or for
	 * some other reason the request cannot be temporarily satisfied (e.g.
	 * the SPI bus access could not be acquired). In this case the send 
	 * command could be retried from a tasklet. Returns SUCCESS if the 
	 * transmission could be started. In this case sendDone will be fired.
	 */
	tasklet_async command error_t send(message_t* msg);
	
	/**
	 * Signals the completion of the send command, exactly once for each 
	 * successfull send command. If the returned error code is SUCCESS, then 
	 * the message was sent (may not have been acknowledged), otherwise 
	 * the message was not transmitted over the air.
	 */
	tasklet_async event void sendDone(error_t error);

	/**
	 * This event is fired when the component is most likely able to accept 
	 * a send request. If the send command has returned with a failure, then
	 * this event will be called at least once in the near future.
	 */
	tasklet_async event void ready();
}

--- NEW FILE: RadioState.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 RadioState
{
	/**
	 * Moves to radio into sleep state with the lowest power consumption but 
	 * highest wakeup time. The radio cannot send or receive in this state 
	 * and releases all access to shared resources (e.g. SPI bus). 
	 */
	tasklet_async command error_t turnOff();

	/**
	 * The same as the turnOff command, except it is not as deep sleep, and
	 * it is quicker to recover from this state.
	 */
	tasklet_async command error_t standby();

	/**
	 * Goes into receive state. The radio continuously receive messages 
	 * and able to transmit.
	 */
	tasklet_async command error_t turnOn();

	/**
	 * Sets the current channel. Returns EBUSY if the stack is unable
	 * to change the channel this time (some other operation is in progress)
	 * SUCCESS otherwise.
	 */
	tasklet_async command error_t setChannel(uint8_t channel);

	/**
	 * This event is signaled exactly once for each sucessfully posted state 
	 * transition and setChannel command when it is completed.
	 */
	tasklet_async event void done();

	/**
	 * Returns the currently selected channel.
	 */
	tasklet_async command uint8_t getChannel();
}

--- NEW FILE: Tasklet.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 __TASKLET_H__
#define __TASKLET_H__

#ifdef	TASKLET_IS_TASK

	#define tasklet_async
	#define tasklet_norace

#else

	#define tasklet_async	async	
	#define tasklet_norace	norace

#endif

#endif//__TASKLET_H__

--- NEW FILE: Tasklet.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>

/**
 * This interface is useful in building state machines when the state 
 * transitions should be executed atomically but with interrupts enabled. 
 * All state transitions should take place in the run event handler or
 * in blocks protected by the suspend and resume commands.
 */
interface Tasklet
{
	/**
	 * This method is executed atomically. 
	 */
	tasklet_async event void run();

	/**
	 * Makes sure that the run event is called at least once more. If the 
	 * run event is currently not executing, then it  is called immediately 
	 * and this command returns only after the completion of the run event. 
	 * If the run event is currently executed, then this method returns at 
	 * once, and makes sure that the run event is called once more when 
	 * it is finished. If this method is called from a task, then by the 
	 * above rules, the run event will be called from a task as well.
	 */
	async command void schedule();

	/**
	 * Enters a critical section of the code and meakes sure that the
	 * run event is not called while in this section. No long running
	 * computation should be called from the critical session, and
	 * in particular no user event should be fired. This call is only
	 * possible from task context, otherwise we cannot guarantee that
	 * the run event is not currently running. The suspend calls
	 * can be nested. It is very important that the same number of
	 * resume commands must be called in all control paths, e.g. be very
	 * careful with the return and break commands.
	 */
	command void suspend();

	/**
	 * Leaves the critical section. This call is conly possible from 
	 * task context. If there were scheduled executions of the run
	 * event, then those will be called before this command returns.
	 */
	command void resume();
}

--- NEW FILE: TaskletC.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 TaskletC
{
	provides interface Tasklet;
}

implementation
{
#ifdef TASKLET_IS_TASK

	task void tasklet()
	{
		signal Tasklet.run();
	}

	inline async command void Tasklet.schedule()
	{
		post tasklet();
	}

	inline command void Tasklet.suspend()
	{
	}

	inline command void Tasklet.resume()
	{
	}

#else
	
	/**
	 * The lower 7 bits contain the number of suspends plus one if the run 
	 * event is currently beeing executed. The highest bit is set if the run 
	 * event needs to be called again when the suspend count goes down to zero.
	 */
	uint8_t state;

	void doit()
	{
		for(;;)
		{
			signal Tasklet.run();

			atomic
			{
				if( state == 1 )
				{
					state = 0;
					return;
				}

				ASSERT( state == 0x81 );
				state = 1;
			}
		}
	}

	inline command void Tasklet.suspend()
	{
		atomic ++state;
	}

	command void Tasklet.resume()
	{
		atomic
		{
			if( --state != 0x80 )
				return;

			state = 1;
		}

		doit();
	}

	async command void Tasklet.schedule()
	{
		atomic
		{
			if( state != 0 )
			{
				state |= 0x80;
				return;
			}

			state = 1;
		}

		doit();
	}

#endif
}



More information about the Tinyos-2-commits mailing list