typedef uint8_t cc2420_status_t;
-#ifndef TFRAMES_ENABLED
+#if !defined(TFRAMES_ENABLED) && !defined(IEEE154FRAMES_ENABLED)
#define CC2420_IFRAME_TYPE
#endif
+#if defined(TFRAMES_ENABLED) && defined(IEEE154FRAMES_ENABLED)
+#error "Both TFRAMES and IEEE154FRAMES enabled!"
+#endif
+
/**
* CC2420 header definition.
*
nxle_uint16_t destpan;
nxle_uint16_t dest;
nxle_uint16_t src;
-
-#ifdef CC2420_HW_SECURITY
- security_header_t secHdr;
-#endif
+ /** CC2420 802.15.4 header ends here */
- /** I-Frame 6LowPAN interoperability byte */
#ifdef CC2420_IFRAME_TYPE
+ /** I-Frame 6LowPAN interoperability byte */
nxle_uint8_t network;
#endif
-#ifndef TINYOS_IP
+#if defined(TFRAMES_ENABLED) || defined(CC2420_IFRAME_TYPE)
nxle_uint8_t type;
#endif
+#ifdef CC2420_HW_SECURITY
+ security_header_t secHdr;
+#endif
+
} cc2420_header_t;
/**
nx_uint16_t maxRetries;
nx_uint16_t retryDelay;
#endif
-
} cc2420_metadata_t;
#define TINYOS_6LOWPAN_NETWORK_ID 0x3f
#endif
-
enum {
// size of the header not including the length byte
MAC_HEADER_SIZE = sizeof( cc2420_header_t ) - 1,
// MDU
MAC_PACKET_SIZE = MAC_HEADER_SIZE + TOSH_DATA_LENGTH + MAC_FOOTER_SIZE,
- CC2420_SIZE = MAC_HEADER_SIZE + MAC_FOOTER_SIZE,
+ AM_OVERHEAD = 0
+#if defined(TFRAMES_ENABLED) || defined(CC2420_IFRAME_TYPE)
+ + 1 // add one for the AM byte
+#if defined(CC2420_IFRAME_TYPE)
+ + 1 // and one for the network byte
+#endif
+#endif
+ ,
+
+ CC2420_SIZE = MAC_HEADER_SIZE + MAC_FOOTER_SIZE - AM_OVERHEAD,
};
+#define CC2420_PAYLOAD(mbuf) (((uint8_t *)(mbuf)->data) - AM_OVERHEAD)
+
enum cc2420_enums {
CC2420_TIME_ACK_TURNAROUND = 7, // jiffies
CC2420_TIME_VREN = 20, // jiffies
#include "CC2420.h"
#include "AM.h"
+#include "Ieee154.h"
+
+#ifdef IEEE154FRAMES_ENABLED
+#error "CC2420 AM layer cannot work when IEEE 802.15.4 frames only are used"
+#endif
configuration CC2420ActiveMessageC {
provides {
}
}
implementation {
+ enum {
+ CC2420_AM_SEND_ID = unique(IEEE154_SEND_CLIENT),
+ };
+ components CC2420RadioC as Radio;
components CC2420ActiveMessageP as AM;
- components CC2420CsmaC as CsmaC;
components ActiveMessageAddressC;
- components UniqueSendC;
- components UniqueReceiveC;
- components CC2420TinyosNetworkC;
- components CC2420PacketC;
+ components CC2420CsmaC as CsmaC;
components CC2420ControlC;
+ components CC2420PacketC;
-#if defined(LOW_POWER_LISTENING) || defined(ACK_LOW_POWER_LISTENING)
- components DefaultLplC as LplC;
-#else
- components DummyLplC as LplC;
-#endif
-
-#if defined(PACKET_LINK)
- components PacketLinkC as LinkC;
-#else
- components PacketLinkDummyC as LinkC;
-#endif
-
-
+ SplitControl = Radio;
RadioBackoff = AM;
Packet = AM;
AMSend = AM;
Receive = AM.Receive;
Snoop = AM.Snoop;
AMPacket = AM;
- PacketLink = LinkC;
- LowPowerListening = LplC;
- CC2420Packet = CC2420PacketC;
- PacketAcknowledgements = CC2420PacketC;
- LinkPacketMetadata = CC2420PacketC;
+ PacketLink = Radio;
+ LowPowerListening = Radio;
+ CC2420Packet = Radio;
+ PacketAcknowledgements = Radio;
+ LinkPacketMetadata = Radio;
- // SplitControl Layers
- SplitControl = LplC;
- LplC.SubControl -> CsmaC;
-
- // Send Layers
- AM.SubSend -> UniqueSendC;
- UniqueSendC.SubSend -> LinkC;
- LinkC.SubSend -> LplC.Send;
- LplC.SubSend -> CC2420TinyosNetworkC.Send;
- CC2420TinyosNetworkC.SubSend -> CsmaC;
-
- // Receive Layers
- AM.SubReceive -> LplC;
- LplC.SubReceive -> UniqueReceiveC.Receive;
- UniqueReceiveC.SubReceive -> CC2420TinyosNetworkC.Receive;
- CC2420TinyosNetworkC.SubReceive -> CsmaC;
+ // Radio resource for the AM layer
+ AM.RadioResource -> Radio.Resource[CC2420_AM_SEND_ID];
+ AM.SubSend -> Radio.ActiveSend;
+ AM.SubReceive -> Radio.ActiveReceive;
AM.ActiveMessageAddress -> ActiveMessageAddressC;
AM.CC2420Packet -> CC2420PacketC;
AM.CC2420Config -> CC2420ControlC;
AM.SubBackoff -> CsmaC;
+
+ components LedsC;
+ AM.Leds -> LedsC;
}
interface CC2420Config;
interface ActiveMessageAddress;
interface RadioBackoff as SubBackoff;
+
+ interface Resource as RadioResource;
+ interface Leds;
}
}
implementation {
+ uint16_t pending_length;
+ message_t *pending_message = NULL;
+ /***************** Resource event ****************/
+ event void RadioResource.granted() {
+ uint8_t rc;
+ cc2420_header_t* header = call CC2420PacketBody.getHeader( pending_message );
+
+ signal SendNotifier.aboutToSend[header->type](header->dest, pending_message);
+ rc = call SubSend.send( pending_message, pending_length );
+ if (rc != SUCCESS) {
+ call RadioResource.release();
+ signal AMSend.sendDone[header->type]( pending_message, rc );
+ }
+ }
/***************** AMSend Commands ****************/
command error_t AMSend.send[am_id_t id](am_addr_t addr,
header->destpan = call CC2420Config.getPanAddr();
header->src = call AMPacket.address();
- signal SendNotifier.aboutToSend[id](addr, msg);
-
- return call SubSend.send( msg, len );
+ if (call RadioResource.immediateRequest() == SUCCESS) {
+ error_t rc;
+ signal SendNotifier.aboutToSend[id](addr, msg);
+
+ rc = call SubSend.send( msg, len );
+ if (rc != SUCCESS) {
+ call RadioResource.release();
+ }
+
+ return rc;
+ } else {
+ pending_length = len;
+ pending_message = msg;
+ return call RadioResource.request();
+ }
}
command error_t AMSend.cancel[am_id_t id](message_t* msg) {
}
command uint8_t Packet.payloadLength(message_t* msg) {
- return (call CC2420PacketBody.getHeader(msg))->length - CC2420_SIZE;
+ return (call CC2420PacketBody.getHeader(msg))->length - CC2420_SIZE - AM_OVERHEAD;
}
command void Packet.setPayloadLength(message_t* msg, uint8_t len) {
- (call CC2420PacketBody.getHeader(msg))->length = len + CC2420_SIZE;
+ (call CC2420PacketBody.getHeader(msg))->length = len + CC2420_SIZE + AM_OVERHEAD;
}
command uint8_t Packet.maxPayloadLength() {
- return TOSH_DATA_LENGTH;
+ return call SubSend.maxPayloadLength();
}
command void* Packet.getPayload(message_t* msg, uint8_t len) {
/***************** SubSend Events ****************/
event void SubSend.sendDone(message_t* msg, error_t result) {
+ call RadioResource.release();
signal AMSend.sendDone[call AMPacket.type(msg)](msg, result);
}
/***************** SubReceive Events ****************/
event message_t* SubReceive.receive(message_t* msg, void* payload, uint8_t len) {
- if(!(call CC2420PacketBody.getMetadata(msg))->crc) {
- return msg;
- }
-
if (call AMPacket.isForMe(msg)) {
return signal Receive.receive[call AMPacket.type(msg)](msg, payload, len);
}
async command void RadioBackoff.setCca[am_id_t amId](bool useCca) {
call SubBackoff.setCca(useCca);
}
-
-
/***************** Defaults ****************/
default event message_t* Receive.receive[am_id_t id](message_t* msg, void* payload, uint8_t len) {
}
default event void AMSend.sendDone[uint8_t id](message_t* msg, error_t err) {
+ call RadioResource.release();
}
default event void SendNotifier.aboutToSend[am_id_t amId](am_addr_t addr, message_t *msg) {
command void* Send.getPayload(message_t* m, uint8_t len) {
if (len <= call Send.maxPayloadLength()) {
- return (void* COUNT_NOK(len))m->data;
+ return (void* COUNT_NOK(len ))(CC2420_PAYLOAD(m));
}
else {
return NULL;
}
command uint8_t Send.maxPayloadLength() {
- return TOSH_DATA_LENGTH;
+ return TOSH_DATA_LENGTH + AM_OVERHEAD;
}
/**************** RadioBackoff Commands ****************/
* ack was received.
*/
async command uint8_t getLqi( message_t* p_msg );
+
+
+ async command uint8_t getNetwork( message_t* p_msg );
+
+ async command void setNetwork( message_t* p_msg, uint8_t networkId );
}
implementation {
components PacketLinkP,
- ActiveMessageC,
CC2420PacketC,
RandomC,
new StateC() as SendStateC,
PacketLinkP.SendState -> SendStateC;
PacketLinkP.DelayTimer -> DelayTimerC;
- PacketLinkP.PacketAcknowledgements -> ActiveMessageC;
- PacketLinkP.AMPacket -> ActiveMessageC;
+ PacketLinkP.PacketAcknowledgements -> CC2420PacketC;
PacketLinkP.CC2420PacketBody -> CC2420PacketC;
}
implementation {
components PacketLinkDummyP,
- ActiveMessageC;
+ CC2420RadioC;
PacketLink = PacketLinkDummyP;
Send = SubSend;
- PacketLinkDummyP.PacketAcknowledgements -> ActiveMessageC;
+ PacketLinkDummyP.PacketAcknowledgements -> CC2420RadioC;
}
interface State as SendState;
interface PacketAcknowledgements;
interface Timer<TMilli> as DelayTimer;
- interface AMPacket;
interface CC2420PacketBody;
}
}
void signalDone(error_t error) {
call DelayTimer.stop();
call SendState.toIdle();
+ (call CC2420PacketBody.getMetadata(currentSendMsg))->maxRetries = totalRetries;
signal Send.sendDone(currentSendMsg, error);
}
}
*/
#include "CC2420.h"
+#include "Ieee154.h"
configuration CC2420TinyosNetworkC {
provides {
+ interface Resource[uint8_t clientId];
interface Send;
interface Receive;
+
+ interface Send as ActiveSend;
+ interface Receive as ActiveReceive;
}
uses {
implementation {
-#ifdef CC2420_IFRAME_TYPE
+ enum {
+ TINYOS_N_NETWORKS = uniqueCount(IEEE154_SEND_CLIENT),
+ };
+
+ components MainC;
components CC2420TinyosNetworkP;
components CC2420PacketC;
-
- CC2420TinyosNetworkP.Send = Send;
- CC2420TinyosNetworkP.Receive = Receive;
+ components new FcfsResourceQueueC(TINYOS_N_NETWORKS);
+
+ CC2420TinyosNetworkP.BareSend = Send;
+ CC2420TinyosNetworkP.BareReceive = Receive;
CC2420TinyosNetworkP.SubSend = SubSend;
CC2420TinyosNetworkP.SubReceive = SubReceive;
-
- CC2420TinyosNetworkP.CC2420PacketBody -> CC2420PacketC;
+ CC2420TinyosNetworkP.Resource = Resource;
+ CC2420TinyosNetworkP.ActiveSend = ActiveSend;
+ CC2420TinyosNetworkP.ActiveReceive = ActiveReceive;
-#else
- Send = SubSend;
- Receive = SubReceive;
-#endif
+ CC2420TinyosNetworkP.CC2420Packet -> CC2420PacketC;
+ CC2420TinyosNetworkP.CC2420PacketBody -> CC2420PacketC;
+ CC2420TinyosNetworkP.Queue -> FcfsResourceQueueC;
+ MainC.SoftwareInit -> FcfsResourceQueueC;
}
*
* @author David Moss
*/
-
+
#include "CC2420.h"
+#include "Ieee154.h"
module CC2420TinyosNetworkP @safe() {
provides {
- interface Send;
- interface Receive;
-
- interface Receive as NonTinyosReceive[uint8_t networkId];
+ interface Resource[uint8_t client];
+
+ interface Send as BareSend;
+ interface Receive as BareReceive;
+
+ interface Send as ActiveSend;
+ interface Receive as ActiveReceive;
}
uses {
interface Send as SubSend;
interface Receive as SubReceive;
+ interface CC2420Packet;
interface CC2420PacketBody;
+ interface ResourceQueue as Queue;
}
}
implementation {
+ enum {
+ OWNER_NONE = 0xff,
+ TINYOS_N_NETWORKS = uniqueCount(IEEE154_SEND_CLIENT),
+ } state;
+
+ norace uint8_t resource_owner = OWNER_NONE, next_owner;
+
+ command error_t ActiveSend.send(message_t* msg, uint8_t len) {
+ call CC2420Packet.setNetwork(msg, TINYOS_6LOWPAN_NETWORK_ID);
+ return call BareSend.send(msg, len + AM_OVERHEAD);
+ }
+
+ command error_t ActiveSend.cancel(message_t* msg) {
+ return call BareSend.cancel(msg);
+ }
+
+ command uint8_t ActiveSend.maxPayloadLength() {
+ return call BareSend.maxPayloadLength() - AM_OVERHEAD;
+ }
+
+ command void* ActiveSend.getPayload(message_t* msg, uint8_t len) {
+ if (len <= call ActiveSend.maxPayloadLength()) {
+ return msg->data;
+ } else {
+ return NULL;
+ }
+ }
+
/***************** Send Commands ****************/
- command error_t Send.send(message_t* msg, uint8_t len) {
- (call CC2420PacketBody.getHeader(msg))->network = TINYOS_6LOWPAN_NETWORK_ID;
+ command error_t BareSend.send(message_t* msg, uint8_t len) {
return call SubSend.send(msg, len);
}
- command error_t Send.cancel(message_t* msg) {
+ command error_t BareSend.cancel(message_t* msg) {
return call SubSend.cancel(msg);
}
- command uint8_t Send.maxPayloadLength() {
+ command uint8_t BareSend.maxPayloadLength() {
return call SubSend.maxPayloadLength();
}
- command void* Send.getPayload(message_t* msg, uint8_t len) {
+ command void* BareSend.getPayload(message_t* msg, uint8_t len) {
return call SubSend.getPayload(msg, len);
}
/***************** SubSend Events *****************/
event void SubSend.sendDone(message_t* msg, error_t error) {
- signal Send.sendDone(msg, error);
+ if (call CC2420Packet.getNetwork(msg) == TINYOS_6LOWPAN_NETWORK_ID) {
+ signal ActiveSend.sendDone(msg, error);
+ } else {
+ signal BareSend.sendDone(msg, error);
+ }
}
/***************** SubReceive Events ***************/
event message_t *SubReceive.receive(message_t *msg, void *payload, uint8_t len) {
- if((call CC2420PacketBody.getHeader(msg))->network == TINYOS_6LOWPAN_NETWORK_ID) {
- return signal Receive.receive(msg, payload, len);
-
+
+ if(!(call CC2420PacketBody.getMetadata(msg))->crc) {
+ return msg;
+ }
+
+ if (call CC2420Packet.getNetwork(msg) == TINYOS_6LOWPAN_NETWORK_ID) {
+ return signal ActiveReceive.receive(msg, msg->data, len - AM_OVERHEAD);
} else {
- return signal NonTinyosReceive.receive[(call CC2420PacketBody.getHeader(msg))->network](msg, payload, len);
+ return signal BareReceive.receive(msg, payload, len);
}
}
-
+
+ /***************** Resource ****************/
+ // SDH : 8-7-2009 : testing if there's more then one client allows
+ // the compiler to eliminate most of the logic when there's only one
+ // client.
+ task void grantTask() {
+
+
+ if (TINYOS_N_NETWORKS > 1) {
+ if (resource_owner == OWNER_NONE && !(call Queue.isEmpty())) {
+ resource_owner = call Queue.dequeue();
+
+ if (resource_owner != OWNER_NONE) {
+ signal Resource.granted[resource_owner]();
+ }
+ }
+ } else {
+ if (next_owner != resource_owner) {
+ resource_owner = next_owner;
+ signal Resource.granted[resource_owner]();
+ }
+ }
+ }
+
+ async command error_t Resource.request[uint8_t id]() {
+
+ post grantTask();
+
+ if (TINYOS_N_NETWORKS > 1) {
+ return call Queue.enqueue(id);
+ } else {
+ if (id == resource_owner) {
+ return EALREADY;
+ } else {
+ next_owner = id;
+ return SUCCESS;
+ }
+ }
+ }
+
+ async command error_t Resource.immediateRequest[uint8_t id]() {
+ if (resource_owner == id) return EALREADY;
+
+ if (TINYOS_N_NETWORKS > 1) {
+ if (resource_owner == OWNER_NONE && call Queue.isEmpty()) {
+ resource_owner = id;
+ return SUCCESS;
+ }
+ return FAIL;
+ } else {
+ resource_owner = id;
+ return SUCCESS;
+ }
+ }
+ async command error_t Resource.release[uint8_t id]() {
+ if (TINYOS_N_NETWORKS > 1) {
+ post grantTask();
+ }
+ resource_owner = OWNER_NONE;
+ return SUCCESS;
+ }
+ async command bool Resource.isOwner[uint8_t id]() {
+ return (id == resource_owner);
+ }
+
/***************** Defaults ****************/
- default event message_t *NonTinyosReceive.receive[uint8_t networkId](message_t *msg, void *payload, uint8_t len) {
+ default event message_t *BareReceive.receive(message_t *msg, void *payload, uint8_t len) {
return msg;
}
-
+ default event void BareSend.sendDone(message_t *msg, error_t error) {
+
+ }
+ default event message_t *ActiveReceive.receive(message_t *msg, void *payload, uint8_t len) {
+ return msg;
+ }
+ default event void ActiveSend.sendDone(message_t *msg, error_t error) {
+
+ }
+ default event void Resource.granted[uint8_t client]() {
+ call Resource.release[client]();
+ }
+
}
components MainC,
DefaultLplP,
PowerCycleC,
- CC2420ActiveMessageC,
+ CC2420RadioC,
CC2420CsmaC,
CC2420TransmitC,
CC2420PacketC,
DefaultLplP.SendDoneTimer -> SendDoneTimerC;
DefaultLplP.PowerCycle -> PowerCycleC;
DefaultLplP.Resend -> CC2420TransmitC;
- DefaultLplP.PacketAcknowledgements -> CC2420ActiveMessageC;
- DefaultLplP.AMPacket -> CC2420ActiveMessageC;
+ DefaultLplP.PacketAcknowledgements -> CC2420RadioC;
DefaultLplP.CC2420PacketBody -> CC2420PacketC;
DefaultLplP.RadioBackoff -> CC2420CsmaC;
DefaultLplP.Random -> RandomC;
interface CC2420Transmit as Resend;
interface RadioBackoff;
interface Receive as SubReceive;
- interface AMPacket;
interface SplitControl as SubControl;
interface PowerCycle;
interface CC2420PacketBody;
if(call LowPowerListening.getRxSleepInterval(currentSendMsg)
> ONE_MESSAGE) {
- if(call AMPacket.destination(currentSendMsg) == AM_BROADCAST_ADDR) {
+ if((call CC2420PacketBody.getHeader(currentSendMsg))->dest == IEEE154_BROADCAST_ADDR) {
call PacketAcknowledgements.noAck(currentSendMsg);
} else {
// Send it repetitively within our transmit window
PacketTimeStampMilli = CC2420PacketP;
PacketTimeSyncOffset = CC2420PacketP;
- components CC2420ActiveMessageC;
- CC2420PacketP.Packet -> CC2420ActiveMessageC;
-
components Counter32khz32C, new CounterToLocalTimeC(T32khz);
CounterToLocalTimeC.Counter -> Counter32khz32C;
CC2420PacketP.LocalTime32khz -> CounterToLocalTimeC;
return (call CC2420PacketBody.getMetadata( p_msg ))->lqi;
}
+ async command uint8_t CC2420Packet.getNetwork( message_t* p_msg ) {
+#if defined(CC2420_IFRAME_TYPE)
+ return (call CC2420PacketBody.getHeader( p_msg ))->network;
+#elif defined(IEEE154FRAMES_ENABLED)
+ return 0;
+#else
+ return TINYOS_6LOWPAN_NETWORK_ID;
+#endif
+ }
+
+ async command void CC2420Packet.setNetwork( message_t* p_msg , uint8_t networkId ) {
+#if defined(CC2420_IFRAME_TYPE)
+ (call CC2420PacketBody.getHeader( p_msg ))->network = networkId;
+#endif
+ }
+
+
/***************** CC2420PacketBody Commands ****************/
async command cc2420_header_t * ONE CC2420PacketBody.getHeader( message_t* ONE msg ) {
return TCAST(cc2420_header_t* ONE, (uint8_t *)msg + offsetof(message_t, data) - sizeof( cc2420_header_t ));
message_t m_rx_buf;
#ifdef CC2420_HW_SECURITY
norace cc2420_receive_state_t m_state;
-#else
- cc2420_receive_state_t m_state;
-#endif
norace uint8_t packetLength = 0;
norace uint8_t pos = 0;
norace uint8_t secHdrPos = 0;
uint8_t flush_flag = 0;
uint16_t startTime = 0;
+ void beginDec();
+ void dec();
+#else
+ cc2420_receive_state_t m_state;
+#endif
+
/***************** Prototypes ****************/
void reset_state();
void beginReceive();
void waitForNextPacket();
void flush();
bool passesAddressCheck(message_t * ONE msg);
- void beginDec();
- void dec();
task void receiveDone_task();
case S_RX_LENGTH:
m_state = S_RX_FCF;
+#ifdef CC2420_HW_SECURITY
packetLength = rxFrameLength+1;
- if ( rxFrameLength + 1 > m_bytes_left || flush_flag == 1) {
+#endif
+ if ( rxFrameLength + 1 > m_bytes_left
+#ifdef CC2420_HW_SECURITY
+ || flush_flag == 1
+#endif
+ ) {
// Length of this packet is bigger than the RXFIFO, flush it out.
flush();
securityOn = 0;
authentication = 0;
#endif
- m_p_rx_buf = signal Receive.receive( m_p_rx_buf, m_p_rx_buf->data,
+ m_p_rx_buf = signal Receive.receive( m_p_rx_buf, CC2420_PAYLOAD(m_p_rx_buf),
length - CC2420_SIZE);
}
atomic receivingPacket = FALSE;
* Flush out the Rx FIFO
*/
void flush() {
+#ifdef CC2420_HW_SECURITY
flush_flag = 0;
pos =0;
packetLength =0;
micLength = 0;
securityOn = 0;
authentication = 0;
+#endif
reset_state();
call CSN.set();
CC2420_ABORT_PERIOD = 320
};
+#ifdef CC2420_HW_SECURITY
uint16_t startTime = 0;
norace uint8_t secCtrlMode = 0;
norace uint8_t nonceValue[16] = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01};
norace uint8_t skip;
norace uint16_t CTR_SECCTRL0, CTR_SECCTRL1;
+ uint8_t securityChecked = 0;
+
+ void securityCheck();
+#endif
norace message_t * ONE_NOK m_msg;
cc2420_transmit_state_t m_state = S_STOPPED;
- uint8_t securityChecked = 0;
-
bool m_receiving = FALSE;
uint16_t m_prev_time;
error_t resend( bool cca );
void loadTXFIFO();
void attemptSend();
- void securityCheck();
void congestionBackoff();
error_t acquireSpiResource();
error_t releaseSpiResource();
return FAIL;
}
+#ifdef CC2420_HW_SECURITY
securityChecked = 0;
+#endif
m_state = S_LOAD;
m_cca = cca;
m_msg = p_msg;